ref: fb9a4985351424bcc5f44efc36cb39d8bc45e33e
parent: 6f9fea1fa77a4dbbc9cecff4d7961e74ef1bc959
author: rodri <rgl@antares-labs.eu>
date: Sat Mar 22 09:21:57 EDT 2025
control cutoff distance from the lights themselves
--- a/graphics.h
+++ b/graphics.h
@@ -143,10 +143,11 @@
struct LightSource
{
+ int type;
Point3 p;
Point3 dir;
Color c;
- int type;
+ double cutoff; /* distance */
/* spotlights */
double θu; /* umbra angle. anything beyond is unlit */
double θp; /* penumbra angle. anything within is fully lit */
--- a/shadeop.c
+++ b/shadeop.c
@@ -32,10 +32,12 @@
/* see Equation 5.16, Real-Time Rendering 4th ed. § 5.2.2 */
static double
-dfalloff(double d)
+dfalloff(LightSource *l, double d)
{
- enum { RMAX = 3000 }; /* cutoff distance */
- d = d/RMAX;
+ if(l->cutoff <= 0)
+ return 0;
+
+ d = d/l->cutoff;
d *= d;
d = max(0, 1 - d);
return d*d;
@@ -53,17 +55,17 @@
ldir = divpt3(ldir, r);
switch(l->type){
+ case LightDirectional:
+ t = max(0, dotvec3(mulpt3(l->dir, -1), n));
+ c = mulpt3(l->c, t);
+ break;
case LightPoint:
t = max(0, dotvec3(ldir, n));
c = mulpt3(l->c, t);
/* attenuation */
- c = mulpt3(c, dfalloff(r));
+ c = mulpt3(c, dfalloff(l, r));
break;
- case LightDirectional:
- t = max(0, dotvec3(mulpt3(l->dir, -1), n));
- c = mulpt3(l->c, t);
- break;
case LightSpot:
/* see “Spotlights”, Real-Time Rendering 4th ed. § 5.2.2 */
cθs = dotvec3(mulpt3(ldir, -1), l->dir);
@@ -76,7 +78,7 @@
c = mulpt3(l->c, t*t);
/* attenuation */
- c = mulpt3(c, dfalloff(r));
+ c = mulpt3(c, dfalloff(l, r));
break;
default: sysfatal("alien light form detected");
}