From cdb4aca6643ebde7cfb7af332cb323ba2afacf15 Mon Sep 17 00:00:00 2001 From: rodri Date: Sat, 21 Sep 2024 11:44:08 +0000 Subject: put all the shaders in a single file. --- vis.c | 423 +----------------------------------------------------------------- 1 file changed, 2 insertions(+), 421 deletions(-) (limited to 'vis.c') diff --git a/vis.c b/vis.c index 5ebd3af..fae1465 100644 --- a/vis.c +++ b/vis.c @@ -98,6 +98,8 @@ static int depthon; static int abuffon; Color (*tsampler)(Texture*,Point2); +#include "shaders.inc" + static Point3 Vecquat(Quaternion q) { @@ -110,427 +112,6 @@ Ptquat(Quaternion q, double w) return Pt3(q.i, q.j, q.k, w); } -Point3 -gouraudvshader(Shaderparams *sp) -{ - static double Ka = 0.1; /* ambient factor */ - static double Ks = 0.5; /* specular factor */ - double Kd; /* diffuse factor */ - double spec; - Point3 pos, lightdir, lookdir; - Material m; - 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; - - if(sp->v->mtl != nil) - m = *sp->v->mtl; - else{ - memset(&m, 0, sizeof m); - m.diffuse = sp->v->c; - m.specular = Pt3(1,1,1,1); - m.shininess = 1; - } - - lightdir = normvec3(subpt3(light.p, pos)); - lightc = getlightcolor(&light, lightdir); - - ambient = mulpt3(lightc, Ka); - ambient = modulapt3(ambient, m.diffuse); - - Kd = max(0, dotvec3(sp->v->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); - spec = pow(max(0, dotvec3(lookdir, lightdir)), m.shininess); - specular = mulpt3(lightc, spec*Ks); - specular = modulapt3(specular, m.specular); - - sp->v->c = addpt3(ambient, addpt3(diffuse, specular)); - sp->v->c.a = m.diffuse.a; - return world2clip(sp->su->camera, pos); -} - -Color -gouraudshader(Shaderparams *sp) -{ - Color tc; - - if(sp->su->entity->mdl->tex != nil && sp->v->uv.w != 0) - tc = sampletexture(sp->su->entity->mdl->tex, sp->v->uv, tsampler); - else if(sp->v->mtl != nil && sp->v->mtl->diffusemap != nil && sp->v->uv.w != 0) - tc = sampletexture(sp->v->mtl->diffusemap, sp->v->uv, tsampler); - else - tc = Pt3(1,1,1,1); - - sp->v->n.w = 1; - sp->toraster(sp, "normals", &sp->v->n); - - return modulapt3(sp->v->c, tc); -} - -Point3 -phongvshader(Shaderparams *sp) -{ - Point3 pos; - Color a, d, s; - double ss; - - sp->v->n = model2world(sp->su->entity, sp->v->n); - sp->v->p = model2world(sp->su->entity, sp->v->p); - pos = sp->v->p; - sp->setattr(sp, "pos", VAPoint, &pos); - if(sp->v->mtl != nil && sp->v->mtl->normalmap != nil && sp->v->uv.w != 0){ - sp->v->tangent = model2world(sp->su->entity, sp->v->tangent); - sp->setattr(sp, "tangent", VAPoint, &sp->v->tangent); - } - if(sp->v->mtl != nil){ - a = sp->v->mtl->ambient; - d = sp->v->mtl->diffuse; - s = sp->v->mtl->specular; - ss = sp->v->mtl->shininess; - sp->setattr(sp, "ambient", VAPoint, &a); - sp->setattr(sp, "diffuse", VAPoint, &d); - sp->setattr(sp, "specular", VAPoint, &s); - sp->setattr(sp, "shininess", VANumber, &ss); - } - return world2clip(sp->su->camera, pos); -} - -Color -phongshader(Shaderparams *sp) -{ - static double Ka = 0.1; /* ambient factor */ - static double Ks = 0.5; /* specular factor */ - double Kd; /* diffuse factor */ - double spec; - Color ambient, diffuse, specular, lightc, c; - Point3 pos, n, lightdir, lookdir; - Material m; - RFrame3 TBN; - Vertexattr *va; - - va = sp->getattr(sp, "pos"); - pos = va->p; - - va = sp->getattr(sp, "ambient"); - m.ambient = va != nil? va->p: Pt3(1,1,1,1); - va = sp->getattr(sp, "diffuse"); - m.diffuse = va != nil? va->p: sp->v->c; - va = sp->getattr(sp, "specular"); - m.specular = va != nil? va->p: Pt3(1,1,1,1); - va = sp->getattr(sp, "shininess"); - m.shininess = va != nil? va->n: 1; - - lightdir = normvec3(subpt3(light.p, pos)); - lightc = getlightcolor(&light, lightdir); - - /* normal mapping */ - va = sp->getattr(sp, "tangent"); - if(va == nil) - n = sp->v->n; - else{ - /* TODO implement this on the VS instead and apply Gram-Schmidt here */ - n = sampletexture(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)); - sp->v->n = n; - } - - if(sp->su->entity->mdl->tex != nil && sp->v->uv.w != 0) - m.diffuse = sampletexture(sp->su->entity->mdl->tex, sp->v->uv, tsampler); - else if(sp->v->mtl != nil && sp->v->mtl->diffusemap != nil && sp->v->uv.w != 0) - m.diffuse = sampletexture(sp->v->mtl->diffusemap, sp->v->uv, tsampler); - - ambient = mulpt3(lightc, Ka); - ambient = modulapt3(ambient, m.diffuse); - - Kd = max(0, dotvec3(n, lightdir)); - diffuse = mulpt3(lightc, Kd); - diffuse = modulapt3(diffuse, m.diffuse); - - if(sp->v->mtl != nil && sp->v->mtl->specularmap != nil && sp->v->uv.w != 0) - m.specular = sampletexture(sp->v->mtl->specularmap, sp->v->uv, tsampler); - - lookdir = normvec3(subpt3(sp->su->camera->p, pos)); - lightdir = qrotate(lightdir, n, PI); - spec = pow(max(0, dotvec3(lookdir, lightdir)), m.shininess); - specular = mulpt3(lightc, spec*Ks); - specular = modulapt3(specular, m.specular); - - sp->v->n.w = 1; - sp->toraster(sp, "normals", &sp->v->n); - - c = addpt3(ambient, addpt3(diffuse, specular)); - c.a = m.diffuse.a; - return c; -} - -Color -blinnshader(Shaderparams *sp) -{ - static double Ka = 0.1; /* ambient factor */ - static double Ks = 0.5; /* specular factor */ - double Kd; /* diffuse factor */ - double spec; - Color ambient, diffuse, specular, lightc, c; - Point3 pos, n, lightdir, lookdir; - Material m; - RFrame3 TBN; - Vertexattr *va; - - va = sp->getattr(sp, "pos"); - pos = va->p; - - va = sp->getattr(sp, "ambient"); - m.ambient = va != nil? va->p: Pt3(1,1,1,1); - va = sp->getattr(sp, "diffuse"); - m.diffuse = va != nil? va->p: sp->v->c; - va = sp->getattr(sp, "specular"); - m.specular = va != nil? va->p: Pt3(1,1,1,1); - va = sp->getattr(sp, "shininess"); - m.shininess = va != nil? va->n: 1; - - lightdir = normvec3(subpt3(light.p, pos)); - lightc = getlightcolor(&light, lightdir); - - /* normal mapping */ - va = sp->getattr(sp, "tangent"); - if(va == nil) - n = sp->v->n; - else{ - /* TODO implement this on the VS instead and apply Gram-Schmidt here */ - n = sampletexture(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)); - sp->v->n = n; - } - - if(sp->su->entity->mdl->tex != nil && sp->v->uv.w != 0) - m.diffuse = sampletexture(sp->su->entity->mdl->tex, sp->v->uv, tsampler); - else if(sp->v->mtl != nil && sp->v->mtl->diffusemap != nil && sp->v->uv.w != 0) - m.diffuse = sampletexture(sp->v->mtl->diffusemap, sp->v->uv, tsampler); - - ambient = mulpt3(lightc, Ka); - ambient = modulapt3(ambient, m.diffuse); - - Kd = max(0, dotvec3(n, lightdir)); - diffuse = mulpt3(lightc, Kd); - diffuse = modulapt3(diffuse, m.diffuse); - - if(sp->v->mtl != nil && sp->v->mtl->specularmap != nil && sp->v->uv.w != 0) - m.specular = sampletexture(sp->v->mtl->specularmap, sp->v->uv, tsampler); - - lookdir = normvec3(subpt3(sp->su->camera->p, pos)); - lightdir = normvec3(addpt3(lookdir, lightdir)); /* half vector */ - spec = pow(max(0, dotvec3(n, lightdir)), m.shininess); - specular = mulpt3(lightc, spec*Ks); - specular = modulapt3(specular, m.specular); - - sp->v->n.w = 1; - sp->toraster(sp, "normals", &sp->v->n); - - c = addpt3(ambient, addpt3(diffuse, specular)); - c.a = m.diffuse.a; - return c; -} - -Point3 -toonvshader(Shaderparams *sp) -{ - Point3 pos, lightdir; - double intens; - - sp->v->n = model2world(sp->su->entity, sp->v->n); - pos = model2world(sp->su->entity, sp->v->p); - lightdir = normvec3(subpt3(light.p, pos)); - intens = max(0, dotvec3(sp->v->n, lightdir)); - sp->setattr(sp, "intensity", VANumber, &intens); - if(sp->v->mtl != nil) - sp->v->c = sp->v->mtl->diffuse; - return world2clip(sp->su->camera, pos); -} - -Color -toonshader(Shaderparams *sp) -{ - Vertexattr *va; - double intens; - - va = sp->getattr(sp, "intensity"); - intens = va->n; - intens = intens > 0.85? 1: - intens > 0.60? 0.80: - intens > 0.45? 0.60: - intens > 0.30? 0.45: - intens > 0.15? 0.30: 0.15; - - sp->v->n.w = 1; - sp->toraster(sp, "normals", &sp->v->n); - - return Pt3(intens, 0.6*intens, 0, 1); -} - -Point3 -identvshader(Shaderparams *sp) -{ - if(sp->v->mtl != nil) - sp->v->c = sp->v->mtl->diffuse; - return world2clip(sp->su->camera, model2world(sp->su->entity, sp->v->p)); -} - -Color -identshader(Shaderparams *sp) -{ - Color tc; - - if(sp->su->entity->mdl->tex != nil && sp->v->uv.w != 0) - tc = sampletexture(sp->su->entity->mdl->tex, sp->v->uv, tsampler); - else if(sp->v->mtl != nil && sp->v->mtl->diffusemap != nil && sp->v->uv.w != 0) - tc = sampletexture(sp->v->mtl->diffusemap, sp->v->uv, tsampler); - else - tc = Pt3(1,1,1,1); - - sp->v->n.w = 1; - sp->toraster(sp, "normals", &sp->v->n); - - return modulapt3(sp->v->c, tc); -} - -Point3 -ivshader(Shaderparams *sp) -{ - sp->v->n = model2world(sp->su->entity, sp->v->n); - sp->v->p = model2world(sp->su->entity, sp->v->p); - return world2clip(sp->su->camera, sp->v->p); -} - -Color -triangleshader(Shaderparams *sp) -{ - Triangle2 t; - Rectangle bbox; - Point3 bc; - - t.p0 = Pt2(240,200,1); - t.p1 = Pt2(400,40,1); - t.p2 = Pt2(240,40,1); - - bbox = Rect( - min(min(t.p0.x, t.p1.x), t.p2.x), min(min(t.p0.y, t.p1.y), t.p2.y), - max(max(t.p0.x, t.p1.x), t.p2.x), max(max(t.p0.y, t.p1.y), t.p2.y) - ); - if(!ptinrect(sp->p, bbox)) - return Vec3(0,0,0); - - bc = barycoords(t, Pt2(sp->p.x,sp->p.y,1)); - if(bc.x < 0 || bc.y < 0 || bc.z < 0) - return Vec3(0,0,0); - - return Pt3(bc.x, bc.y, bc.z, 1); -} - -Color -circleshader(Shaderparams *sp) -{ - Point2 uv; - double r, d; - - uv = Pt2(sp->p.x,sp->p.y,1); - uv.x /= Dx(sp->su->fb->r); - uv.y /= Dy(sp->su->fb->r); -// r = 0.3; - r = 0.3*fabs(sin(sp->su->uni_time/1e9)); - d = vec2len(subpt2(uv, Vec2(0.5,0.5))); - - if(d > r + r*0.05 || d < r - r*0.05) - return Vec3(0,0,0); - - return Pt3(uv.x, uv.y, 0, 1); -} - -/* some shaping functions from The Book of Shaders, Chapter 5 */ -Color -sfshader(Shaderparams *sp) -{ - Point2 uv; - double y, pct; - - uv = Pt2(sp->p.x,sp->p.y,1); - uv.x /= Dx(sp->su->fb->r); - uv.y /= Dy(sp->su->fb->r); - uv.y = 1 - uv.y; /* make [0 0] the bottom-left corner */ - -// y = step(0.5, uv.x); -// y = pow(uv.x, 5); -// y = sin(uv.x); - y = sin(uv.x*sp->su->uni_time/1e8)/2.0 + 0.5; -// y = smoothstep(0.1, 0.9, uv.x); - pct = smoothstep(y-0.02, y, uv.y) - smoothstep(y, y+0.02, uv.y); - - return Pt3(flerp(y, 0, pct), flerp(y, 1, pct), flerp(y, 0, pct), 1); -} - -Color -boxshader(Shaderparams *sp) -{ - Point2 uv, p; - Point2 r; - - uv = Pt2(sp->p.x,sp->p.y,1); - uv.x /= Dx(sp->su->fb->r); - uv.y /= Dy(sp->su->fb->r); - r = Vec2(0.2,0.4); - - p = Pt2(fabs(uv.x - 0.5), fabs(uv.y - 0.5), 1); - p = subpt2(p, r); - p.x = max(p.x, 0); - p.y = max(p.y, 0); - - if(vec2len(p) > 0) - return Vec3(0,0,0); - - return Pt3(uv.x, uv.y, smoothstep(0,1,uv.x+uv.y), 1); -} - -Shadertab shadertab[] = { - { "triangle", ivshader, triangleshader }, - { "circle", ivshader, circleshader }, - { "box", ivshader, boxshader }, - { "sf", ivshader, sfshader }, - { "toon", toonvshader, toonshader }, - { "ident", identvshader, identshader }, - { "gouraud", gouraudvshader, gouraudshader }, - { "phong", phongvshader, phongshader }, - { "blinn", phongvshader, blinnshader }, -}; -Shadertab * -getshader(char *name) -{ - int i; - - for(i = 0; i < nelem(shadertab); i++) - if(strcmp(shadertab[i].name, name) == 0) - return &shadertab[i]; - return nil; -} - void zoomin(void) { -- cgit v1.2.3