ref: ec46c4ef5d7ebfcd08de2b7f1d336075ce4be0b2
parent: fb9a4985351424bcc5f44efc36cb39d8bc45e33e
author: rodri <rgl@antares-labs.eu>
date: Thu Apr 3 12:57:42 EDT 2025
perform perspective division outside of the raster loop. also interpolate tangents for each vertex.
--- a/internal.h
+++ b/internal.h
@@ -71,6 +71,7 @@
Vertex _dupvertex(Vertex*);
void _lerpvertex(Vertex*, Vertex*, Vertex*, double);
void _berpvertex(Vertex*, Vertex*, Vertex*, Vertex*, Point3);
+void _perspdiv(Vertex*, double);
void _delvattrs(Vertex*);
void _fprintvattrs(int, Vertex*);
void _addvattr(Vertexattrs*, char*, int, void*);
--- a/render.c
+++ b/render.c
@@ -307,6 +307,10 @@
t.p1 = Pt2(prim->v[1].p.x, prim->v[1].p.y, 1);
t.p2 = Pt2(prim->v[2].p.x, prim->v[2].p.y, 1);
+ _perspdiv(prim->v+0, prim->v[0].p.w);
+ _perspdiv(prim->v+1, prim->v[1].p.w);
+ _perspdiv(prim->v+2, prim->v[2].p.w);
+
for(p.y = task->wr.min.y; p.y < task->wr.max.y; p.y++)
for(p.x = task->wr.min.x; p.x < task->wr.max.x; p.x++){
bc = _barycoords(t, Pt2(p.x+0.5,p.y+0.5,1));
@@ -322,9 +326,7 @@
pcz = 1.0/(pcz < ε1? ε1: pcz);
/* perspective-correct attribute interpolation */
- bc = modulapt3(bc, Vec3(prim->v[0].p.w*pcz,
- prim->v[1].p.w*pcz,
- prim->v[2].p.w*pcz));
+ bc = mulpt3(bc, pcz);
_berpvertex(fsp.v, &prim->v[0], &prim->v[1], &prim->v[2], bc);
fsp.p = p;
--- a/vertex.c
+++ b/vertex.c
@@ -57,6 +57,7 @@
v->n = lerp3(v0->n, v1->n, t);
v->c = lerp3(v0->c, v1->c, t);
v->uv = lerp2(v0->uv, v1->uv, t);
+ v->tangent = lerp3(v0->tangent, v1->tangent, t);
v->mtl = v0->mtl != nil? v0->mtl: v1->mtl;
for(i = 0; i < v0->nattrs; i++){
va.id = v0->attrs[i].id;
@@ -82,6 +83,7 @@
v->n = berp3(v0->n, v1->n, v2->n, bc);
v->c = berp3(v0->c, v1->c, v2->c, bc);
v->uv = berp2(v0->uv, v1->uv, v2->uv, bc);
+ v->tangent = berp3(v0->tangent, v1->tangent, v2->tangent, bc);
v->mtl = v0->mtl != nil? v0->mtl: v1->mtl != nil? v1->mtl: v2->mtl;
for(i = 0; i < v0->nattrs; i++){
va.id = v0->attrs[i].id;
@@ -91,6 +93,26 @@
else
va.n = fberp(v0->attrs[i].n, v1->attrs[i].n, v2->attrs[i].n, bc);
addvattr(v, &va);
+ }
+}
+
+/*
+ * perspective divide vertex attributes
+ */
+void
+_perspdiv(Vertex *v, double z⁻¹)
+{
+ Vertexattr *va;
+
+ v->n = mulpt3(v->n, z⁻¹);
+ v->c = mulpt3(v->c, z⁻¹);
+ v->uv = mulpt2(v->uv, z⁻¹);
+ v->tangent = mulpt3(v->tangent, z⁻¹);
+ for(va = v->attrs; va < v->attrs + v->nattrs; va++){
+ if(va->type == VAPoint)
+ va->p = mulpt3(va->p, z⁻¹);
+ else
+ va->n *= z⁻¹;
}
}