diff options
-rw-r--r-- | graphics.h | 7 | ||||
-rw-r--r-- | render.c | 8 | ||||
-rw-r--r-- | scene.c | 16 | ||||
-rw-r--r-- | shadeop.c | 18 | ||||
-rw-r--r-- | util.c | 12 | ||||
-rw-r--r-- | vertex.c | 5 |
6 files changed, 48 insertions, 18 deletions
@@ -104,8 +104,12 @@ struct Vertex struct LightSource { Point3 p; + Point3 dir; Color c; int type; + /* spotlights */ + double θu; /* umbra angle. anything beyond is unlit */ + double θp; /* penumbra angle. anything within is fully lit */ }; struct Material @@ -330,11 +334,14 @@ Color cubemaptexture(Cubemap*, Point3, Color(*)(Memimage*, Point2)); /* util */ double fmin(double, double); double fmax(double, double); +Point2 modulapt2(Point2, Point2); +Point3 modulapt3(Point3, Point3); Memimage *rgb(ulong); /* shadeop */ double sign(double); double step(double, double); double smoothstep(double, double, double); +Color getlightcolor(LightSource*, Point3); extern Rectangle UR; /* unit rectangle */ @@ -15,10 +15,10 @@ col2ul(Color c) { uchar cbuf[4]; - cbuf[0] = c.a*0xFF; - cbuf[1] = c.b*0xFF; - cbuf[2] = c.g*0xFF; - cbuf[3] = c.r*0xFF; + cbuf[0] = fclamp(c.a, 0, 1)*0xFF; + cbuf[1] = fclamp(c.b, 0, 1)*0xFF; + cbuf[2] = fclamp(c.g, 0, 1)*0xFF; + cbuf[3] = fclamp(c.r, 0, 1)*0xFF; return cbuf[3]<<24 | cbuf[2]<<16 | cbuf[1]<<8 | cbuf[0]; } @@ -159,18 +159,9 @@ loadobjmodel(Model *m, OBJ *obj) if(mtl->name == nil) sysfatal("strdup: %r"); } - mtl->ambient.r = objmtl->Ka.r; - mtl->ambient.g = objmtl->Ka.g; - mtl->ambient.b = objmtl->Ka.b; - mtl->ambient.a = 1; - mtl->diffuse.r = objmtl->Kd.r; - mtl->diffuse.g = objmtl->Kd.g; - mtl->diffuse.b = objmtl->Kd.b; - mtl->diffuse.a = 1; - mtl->specular.r = objmtl->Ks.r; - mtl->specular.g = objmtl->Ks.g; - mtl->specular.b = objmtl->Ks.b; - mtl->specular.a = 1; + mtl->ambient = Pt3(objmtl->Ka.r, objmtl->Ka.g, objmtl->Ka.b, 1); + mtl->diffuse = Pt3(objmtl->Kd.r, objmtl->Kd.g, objmtl->Kd.b, 1); + mtl->specular = Pt3(objmtl->Ks.r, objmtl->Ks.g, objmtl->Ks.b, 1); mtl->shininess = objmtl->Ns; if(objmtl->map_Kd != nil){ @@ -419,7 +410,6 @@ void clearscene(Scene *s) { Entity *e, *ne; - int i; for(e = s->ents.next; e != &s->ents; e = ne){ ne = e->next; @@ -30,3 +30,21 @@ smoothstep(double edge0, double edge1, double n) t = fclamp((n-edge0)/(edge1-edge0), 0, 1); return t*t * (3 - 2*t); } + +/* TODO apply attenuation for punctual lights */ +Color +getlightcolor(LightSource *l, Point3 dir) +{ + double cθs, cθu, cθp, t; + + /* see “Spotlights”, Real-Time Rendering 4th ed. § 5.2.2 */ + if(l->type == LIGHT_SPOT){ + cθs = dotvec3(mulpt3(dir, -1), l->dir); + cθu = cos(l->θu); + cθp = cos(l->θp); +// return mulpt3(l->c, smoothstep(cθu, cθp, cθs)); + t = fclamp((cθs - cθu)/(cθp - cθu), 0, 1); + return mulpt3(l->c, t*t); + } + return l->c; +} @@ -52,6 +52,18 @@ swappt(Point *a, Point *b) *b = t; } +Point2 +modulapt2(Point2 a, Point2 b) +{ + return (Point2){a.x*b.x, a.y*b.y, a.w*b.w}; +} + +Point3 +modulapt3(Point3 a, Point3 b) +{ + return (Point3){a.x*b.x, a.y*b.y, a.z*b.z, a.w*b.w}; +} + void memsetd(double *p, double v, usize len) { @@ -43,6 +43,9 @@ dupvertex(Vertex *v) return nv; } +/* + * linear attribute interpolation + */ void lerpvertex(Vertex *v, Vertex *v0, Vertex *v1, double t) { @@ -68,7 +71,7 @@ lerpvertex(Vertex *v, Vertex *v0, Vertex *v1, double t) } /* - * perspective-correct barycentric attribute interpolation + * barycentric attribute interpolation */ void berpvertex(Vertex *v, Vertex *v0, Vertex *v1, Vertex *v2, Point3 bc) |