ref: d5efccfa229a5bc62c8065c0e66ce09f591d9afa
parent: 7667c666663dbe35c8dcb783670e3c083c5c4ce8
author: rodri <rgl@antares-labs.eu>
date: Thu Jun 13 15:12:59 EDT 2024
use the new modulapt3 functions. don't clamp in the shaders.
--- a/med.c
+++ b/med.c
@@ -218,7 +218,7 @@
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);
@@ -225,34 +225,24 @@
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 @@
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 @@
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 @@
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 @@
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 @@
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;
}
--- a/solar.c
+++ b/solar.c
@@ -151,7 +151,7 @@
0,0,0,1,
0,0,0,1,
0,1,0,0,
- 80*DEG, 0.01, 1e12, PERSPECTIVE
+ 80*DEG, 1, 1e12, PERSPECTIVE
};
Point3 center = {0,0,0,1};
double speed = 10;
@@ -349,19 +349,9 @@
Color
identshader(FSparams *sp)
{
- Color tc, c;
-
if(sp->v.mtl != nil && sp->v.mtl->diffusemap != nil && sp->v.uv.w != 0)
- tc = texture(sp->v.mtl->diffusemap, sp->v.uv, neartexsampler);
- else
- tc = sp->v.c;
-
- c.a = 1;
- c.b = fclamp(tc.b, 0, 1);
- c.g = fclamp(tc.g, 0, 1);
- c.r = fclamp(tc.r, 0, 1);
-
- return c;
+ return texture(sp->v.mtl->diffusemap, sp->v.uv, neartexsampler);
+ return sp->v.c;
}
Shadertab shader = { "ident", identvshader, identshader };
--- a/vis.c
+++ b/vis.c
@@ -125,7 +125,7 @@
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);
@@ -132,34 +132,24 @@
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);
@@ -177,10 +167,8 @@
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;
}
@@ -220,7 +208,7 @@
static double Ks = 0.5; /* specular factor */
double Kd; /* diffuse factor */
double spec;
- Color ambient, diffuse, specular, tc, c;
+ Color ambient, diffuse, specular, tc, c, lightc;
Point3 pos, n, lightdir, lookdir;
Material m;
RFrame3 TBN;
@@ -238,12 +226,12 @@
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));
+ lightc = getlightcolor(&light, lightdir);
+ ambient = mulpt3(lightc, Ka);
+ ambient = modulapt3(ambient, m.ambient);
+
/* normal mapping */
va = getvattr(&sp->v, "tangent");
if(va == nil)
@@ -261,22 +249,15 @@
n = normvec3(invrframexform3(n, TBN));
}
- lightdir = normvec3(subpt3(light.p, pos));
Kd = fmax(0, dotvec3(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;
+ diffuse = mulpt3(lightc, Kd);
+ diffuse = modulapt3(diffuse, m.diffuse);
lookdir = normvec3(subpt3(sp->su->camera->p, pos));
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);
@@ -286,10 +267,8 @@
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;
}
@@ -336,10 +315,8 @@
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;
}
@@ -881,8 +858,12 @@
}
maincam = &cams[3];
light.p = Pt3(0,100,100,1);
+// light.dir = Vec3(0,-1,0);
light.c = Pt3(1,1,1,1);
light.type = LIGHT_POINT;
+// light.type = LIGHT_SPOT;
+// light.θu = 30*DEG;
+// light.θp = 5*DEG;
tsampler = neartexsampler;
kctl = emalloc(sizeof *kctl);