summaryrefslogtreecommitdiff
path: root/med.c
diff options
context:
space:
mode:
Diffstat (limited to 'med.c')
-rw-r--r--med.c99
1 files changed, 47 insertions, 52 deletions
diff --git a/med.c b/med.c
index 19eee54..d5682db 100644
--- a/med.c
+++ b/med.c
@@ -218,41 +218,31 @@ gouraudvshader(VSparams *sp)
double spec;
Point3 pos, lightdir, lookdir;
Material *m;
- Color ambient, diffuse, specular;
+ Color ambient, diffuse, specular, lightc;
sp->v->n = model2world(sp->su->entity, sp->v->n);
sp->v->p = model2world(sp->su->entity, sp->v->p);
pos = sp->v->p;
m = sp->v->mtl;
- ambient = mulpt3(light.c, Ka);
- if(m != nil){
- ambient.r *= m->ambient.r;
- ambient.g *= m->ambient.g;
- ambient.b *= m->ambient.b;
- ambient.a *= m->ambient.a;
- }
-
lightdir = normvec3(subpt3(light.p, pos));
+ lightc = getlightcolor(&light, lightdir);
+
+ ambient = mulpt3(lightc, Ka);
+ if(m != nil)
+ ambient = modulapt3(ambient, m->ambient);
+
Kd = fmax(0, dotvec3(sp->v->n, lightdir));
- diffuse = mulpt3(light.c, Kd);
- if(m != nil){
- diffuse.r *= m->diffuse.r;
- diffuse.g *= m->diffuse.g;
- diffuse.b *= m->diffuse.b;
- diffuse.a *= m->diffuse.a;
- }
+ diffuse = mulpt3(lightc, Kd);
+ if(m != nil)
+ diffuse = modulapt3(diffuse, m->diffuse);
lookdir = normvec3(subpt3(sp->su->camera->p, pos));
lightdir = qrotate(lightdir, sp->v->n, PI);
spec = pow(fmax(0, dotvec3(lookdir, lightdir)), m? m->shininess: 1);
- specular = mulpt3(light.c, spec*Ks);
- if(m != nil){
- specular.r *= m->specular.r;
- specular.g *= m->specular.g;
- specular.b *= m->specular.b;
- specular.a *= m->specular.a;
- }
+ specular = mulpt3(lightc, spec*Ks);
+ if(m != nil)
+ specular = modulapt3(specular, m->specular);
sp->v->c = addpt3(ambient, addpt3(diffuse, specular));
return world2clip(sp->su->camera, pos);
@@ -270,10 +260,8 @@ gouraudshader(FSparams *sp)
else
tc = Pt3(1,1,1,1);
+ c = modulapt3(sp->v.c, tc);
c.a = 1;
- c.b = fclamp(sp->v.c.b*tc.b, 0, 1);
- c.g = fclamp(sp->v.c.g*tc.g, 0, 1);
- c.r = fclamp(sp->v.c.r*tc.r, 0, 1);
return c;
}
@@ -309,9 +297,10 @@ phongshader(FSparams *sp)
static double Ks = 0.5; /* specular factor */
double Kd; /* diffuse factor */
double spec;
- Color ambient, diffuse, specular, tc, c;
- Point3 pos, lookdir, lightdir;
+ Color ambient, diffuse, specular, tc, c, lightc;
+ Point3 pos, n, lightdir, lookdir;
Material m;
+ RFrame3 TBN;
Vertexattr *va;
va = getvattr(&sp->v, "pos");
@@ -326,28 +315,38 @@ phongshader(FSparams *sp)
va = getvattr(&sp->v, "shininess");
m.shininess = va != nil? va->n: 1;
- ambient = mulpt3(light.c, Ka);
- ambient.r *= m.ambient.r;
- ambient.g *= m.ambient.g;
- ambient.b *= m.ambient.b;
- ambient.a *= m.ambient.a;
-
lightdir = normvec3(subpt3(light.p, pos));
- Kd = fmax(0, dotvec3(sp->v.n, lightdir));
- diffuse = mulpt3(light.c, Kd);
- diffuse.r *= m.diffuse.r;
- diffuse.g *= m.diffuse.g;
- diffuse.b *= m.diffuse.b;
- diffuse.a *= m.diffuse.a;
+ lightc = getlightcolor(&light, lightdir);
+
+ ambient = mulpt3(lightc, Ka);
+ ambient = modulapt3(ambient, m.ambient);
+
+ /* normal mapping */
+ va = getvattr(&sp->v, "tangent");
+ if(va == nil)
+ n = sp->v.n;
+ else{
+ /* TODO implement this on the VS instead and apply Gram-Schmidt here */
+ n = texture(sp->v.mtl->normalmap, sp->v.uv, neartexsampler);
+ n = normvec3(subpt3(mulpt3(n, 2), Vec3(1,1,1)));
+
+ TBN.p = Pt3(0,0,0,1);
+ TBN.bx = va->p; /* T */
+ TBN.bz = sp->v.n; /* N */
+ TBN.by = crossvec3(TBN.bz, TBN.bx); /* B */
+
+ n = normvec3(invrframexform3(n, TBN));
+ }
+
+ Kd = fmax(0, dotvec3(n, lightdir));
+ diffuse = mulpt3(lightc, Kd);
+ diffuse = modulapt3(diffuse, m.diffuse);
lookdir = normvec3(subpt3(sp->su->camera->p, pos));
- lightdir = qrotate(lightdir, sp->v.n, PI);
+ lightdir = qrotate(lightdir, n, PI);
spec = pow(fmax(0, dotvec3(lookdir, lightdir)), m.shininess);
- specular = mulpt3(light.c, spec*Ks);
- specular.r *= m.specular.r;
- specular.g *= m.specular.g;
- specular.b *= m.specular.b;
- specular.a *= m.specular.a;
+ specular = mulpt3(lightc, spec*Ks);
+ specular = modulapt3(specular, m.specular);
if(sp->v.mtl != nil && sp->v.mtl->diffusemap != nil && sp->v.uv.w != 0)
tc = texture(sp->v.mtl->diffusemap, sp->v.uv, tsampler);
@@ -357,10 +356,8 @@ phongshader(FSparams *sp)
tc = Pt3(1,1,1,1);
c = addpt3(ambient, addpt3(diffuse, specular));
+ c = modulapt3(c, tc);
c.a = 1;
- c.b = fclamp(c.b*tc.b, 0, 1);
- c.g = fclamp(c.g*tc.g, 0, 1);
- c.r = fclamp(c.r*tc.r, 0, 1);
return c;
}
@@ -387,10 +384,8 @@ identshader(FSparams *sp)
else
tc = Pt3(1,1,1,1);
+ c = modulapt3(sp->v.c, tc);
c.a = 1;
- c.b = fclamp(sp->v.c.b*tc.b, 0, 1);
- c.g = fclamp(sp->v.c.g*tc.g, 0, 1);
- c.r = fclamp(sp->v.c.r*tc.r, 0, 1);
return c;
}