shithub: 3dee

Download patch

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);