summaryrefslogtreecommitdiff
path: root/src/engine/shadowmap.cpp
diff options
context:
space:
mode:
authorxolatile2025-08-04 22:53:42 +0200
committerxolatile2025-08-04 22:53:42 +0200
commitd309df4ce4d8ad0ed995a8e1c4267412a7782021 (patch)
tree999ca8d785ecc1681e5eb7538ce2e6a18d244fa5 /src/engine/shadowmap.cpp
parent29d613d9cb65a0faa7e3f80e75bea0b6d910cb9a (diff)
downloadxolatile-badassbug-d309df4ce4d8ad0ed995a8e1c4267412a7782021.tar.xz
xolatile-badassbug-d309df4ce4d8ad0ed995a8e1c4267412a7782021.tar.zst
Bunch of small changes...
Diffstat (limited to 'src/engine/shadowmap.cpp')
-rw-r--r--src/engine/shadowmap.cpp400
1 files changed, 200 insertions, 200 deletions
diff --git a/src/engine/shadowmap.cpp b/src/engine/shadowmap.cpp
index 7b7f894..2216452 100644
--- a/src/engine/shadowmap.cpp
+++ b/src/engine/shadowmap.cpp
@@ -13,8 +13,8 @@ VARFP(shadowmapprecision, 0, 0, 1, cleanshadowmap());
bvec shadowmapambientcolor(0, 0, 0);
HVARFR(shadowmapambient, 0, 0, 0xFFFFFF,
{
- if(shadowmapambient <= 255) shadowmapambient |= (shadowmapambient<<8) | (shadowmapambient<<16);
- shadowmapambientcolor = bvec((shadowmapambient>>16)&0xFF, (shadowmapambient>>8)&0xFF, shadowmapambient&0xFF);
+ if(shadowmapambient <= 255) shadowmapambient |= (shadowmapambient<<8) | (shadowmapambient<<16);
+ shadowmapambientcolor = bvec((shadowmapambient>>16)&0xFF, (shadowmapambient>>8)&0xFF, shadowmapambient&0xFF);
});
VARP(shadowmapintensity, 0, 40, 100);
@@ -29,54 +29,54 @@ float shadowmapmaxz = 0;
void setshadowdir(int angle)
{
- shadowdir = vec(0, SHADOWSKEW, 1);
- shadowdir.rotate_around_z(angle*RAD);
+ shadowdir = vec(0, SHADOWSKEW, 1);
+ shadowdir.rotate_around_z(angle*RAD);
}
VARFR(shadowmapangle, 0, 0, 360, setshadowdir(shadowmapangle));
void guessshadowdir()
{
- if(shadowmapangle) return;
- vec dir;
- if(!sunlightcolor.iszero()) dir = sunlightdir;
- else
- {
- vec lightpos(0, 0, 0), casterpos(0, 0, 0);
- int numlights = 0, numcasters = 0;
- const vector<extentity *> &ents = entities::getents();
- loopv(ents)
- {
- extentity &e = *ents[i];
- switch(e.type)
- {
- case ET_LIGHT:
- if(!e.attr1) { lightpos.add(e.o); numlights++; }
- break;
-
- case ET_MAPMODEL:
- casterpos.add(e.o);
- numcasters++;
- break;
-
- default:
- if(e.type<ET_GAMESPECIFIC) break;
- casterpos.add(e.o);
- numcasters++;
- break;
- }
- }
- if(!numlights || !numcasters) return;
- lightpos.div(numlights);
- casterpos.div(numcasters);
- dir = vec(lightpos).sub(casterpos);
- }
- dir.z = 0;
- if(dir.iszero()) return;
- dir.normalize();
- dir.mul(SHADOWSKEW);
- dir.z = 1;
- shadowdir = dir;
+ if(shadowmapangle) return;
+ vec dir;
+ if(!sunlightcolor.iszero()) dir = sunlightdir;
+ else
+ {
+ vec lightpos(0, 0, 0), casterpos(0, 0, 0);
+ int numlights = 0, numcasters = 0;
+ const vector<extentity *> &ents = entities::getents();
+ loopv(ents)
+ {
+ extentity &e = *ents[i];
+ switch(e.type)
+ {
+ case ET_LIGHT:
+ if(!e.attr1) { lightpos.add(e.o); numlights++; }
+ break;
+
+ case ET_MAPMODEL:
+ casterpos.add(e.o);
+ numcasters++;
+ break;
+
+ default:
+ if(e.type<ET_GAMESPECIFIC) break;
+ casterpos.add(e.o);
+ numcasters++;
+ break;
+ }
+ }
+ if(!numlights || !numcasters) return;
+ lightpos.div(numlights);
+ casterpos.div(numcasters);
+ dir = vec(lightpos).sub(casterpos);
+ }
+ dir.z = 0;
+ if(dir.iszero()) return;
+ dir.normalize();
+ dir.mul(SHADOWSKEW);
+ dir.z = 1;
+ shadowdir = dir;
}
bool shadowmapping = false;
@@ -90,190 +90,190 @@ VAR(smoothshadowmappeel, 1, 0, 0);
static struct shadowmaptexture : rendertarget
{
- const GLenum *colorformats() const
- {
- static const GLenum rgbafmts[] = { GL_RGBA16F, GL_RGBA16, GL_RGBA, GL_RGBA8, GL_FALSE };
- return &rgbafmts[fpshadowmap && hasTF ? 0 : (shadowmapprecision ? 1 : 2)];
- }
-
- bool swaptexs() const { return true; }
-
- bool scissorblur(int &x, int &y, int &w, int &h)
- {
- x = max(int(floor((scissorx1+1)/2*vieww)) - 2*blursize, 2);
- y = max(int(floor((scissory1+1)/2*viewh)) - 2*blursize, 2);
- w = min(int(ceil((scissorx2+1)/2*vieww)) + 2*blursize, vieww-2) - x;
- h = min(int(ceil((scissory2+1)/2*viewh)) + 2*blursize, viewh-2) - y;
- return true;
- }
-
- bool scissorrender(int &x, int &y, int &w, int &h)
- {
- x = y = 2;
- w = vieww - 2*2;
- h = viewh - 2*2;
- return true;
- }
-
- void doclear()
- {
- glClearColor(0, 0, 0, 0);
- glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
- }
-
- bool dorender()
- {
- vec skewdir(shadowdir);
- skewdir.rotate_around_z(-camera1->yaw*RAD);
-
- vec dir;
- vecfromyawpitch(camera1->yaw, camera1->pitch, 1, 0, dir);
- dir.z = 0;
- dir.mul(shadowmapradius);
-
- vec dirx, diry;
- vecfromyawpitch(camera1->yaw, 0, 0, 1, dirx);
- vecfromyawpitch(camera1->yaw, 0, 1, 0, diry);
- shadowoffset.x = -fmod(dirx.dot(camera1->o) - skewdir.x*camera1->o.z, 2.0f*shadowmapradius/vieww);
- shadowoffset.y = -fmod(diry.dot(camera1->o) - skewdir.y*camera1->o.z, 2.0f*shadowmapradius/viewh);
-
- shadowmatrix.ortho(-shadowmapradius, shadowmapradius, -shadowmapradius, shadowmapradius, -shadowmapdist, shadowmapdist);
- shadowmatrix.mul(matrix3(vec(1, 0, 0), vec(0, 1, 0), vec(skewdir.x, skewdir.y, 1)));
- shadowmatrix.translate(skewdir.x*shadowmapheight + shadowoffset.x, skewdir.y*shadowmapheight + shadowoffset.y + dir.magnitude(), -shadowmapheight);
- shadowmatrix.rotate_around_z((camera1->yaw+180)*-RAD);
- shadowmatrix.translate(vec(camera1->o).neg());
- GLOBALPARAM(shadowmatrix, shadowmatrix);
-
- shadowfocus = camera1->o;
- shadowfocus.add(dir);
- shadowfocus.add(vec(shadowdir).mul(shadowmapheight));
- shadowfocus.add(dirx.mul(shadowoffset.x));
- shadowfocus.add(diry.mul(shadowoffset.y));
-
- gle::colorf(0, 0, 0);
-
- GLOBALPARAMF(shadowmapbias, -shadowmapbias/float(shadowmapdist), 1 - (shadowmapbias + (smoothshadowmappeel ? 0 : shadowmappeelbias))/float(shadowmapdist));
-
- shadowmapcasters = 0;
- shadowmapmaxz = shadowfocus.z - shadowmapdist;
- shadowmapping = true;
- rendergame();
- shadowmapping = false;
- shadowmapmaxz = min(shadowmapmaxz, shadowfocus.z);
-
- if(shadowmapcasters && smdepthpeel)
- {
- int sx, sy, sw, sh;
- bool scissoring = rtscissor && scissorblur(sx, sy, sw, sh) && sw > 0 && sh > 0;
- if(scissoring) glScissor(sx, sy, sw, sh);
- if(!rtscissor || scissoring) rendershadowmapreceivers();
- }
-
- return shadowmapcasters>0;
- }
+ const GLenum *colorformats() const
+ {
+ static const GLenum rgbafmts[] = { GL_RGBA16F, GL_RGBA16, GL_RGBA, GL_RGBA8, GL_FALSE };
+ return &rgbafmts[fpshadowmap && hasTF ? 0 : (shadowmapprecision ? 1 : 2)];
+ }
+
+ bool swaptexs() const { return true; }
+
+ bool scissorblur(int &x, int &y, int &w, int &h)
+ {
+ x = max(int(floor((scissorx1+1)/2*vieww)) - 2*blursize, 2);
+ y = max(int(floor((scissory1+1)/2*viewh)) - 2*blursize, 2);
+ w = min(int(ceil((scissorx2+1)/2*vieww)) + 2*blursize, vieww-2) - x;
+ h = min(int(ceil((scissory2+1)/2*viewh)) + 2*blursize, viewh-2) - y;
+ return true;
+ }
+
+ bool scissorrender(int &x, int &y, int &w, int &h)
+ {
+ x = y = 2;
+ w = vieww - 2*2;
+ h = viewh - 2*2;
+ return true;
+ }
+
+ void doclear()
+ {
+ glClearColor(0, 0, 0, 0);
+ glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
+ }
+
+ bool dorender()
+ {
+ vec skewdir(shadowdir);
+ skewdir.rotate_around_z(-camera1->yaw*RAD);
+
+ vec dir;
+ vecfromyawpitch(camera1->yaw, camera1->pitch, 1, 0, dir);
+ dir.z = 0;
+ dir.mul(shadowmapradius);
+
+ vec dirx, diry;
+ vecfromyawpitch(camera1->yaw, 0, 0, 1, dirx);
+ vecfromyawpitch(camera1->yaw, 0, 1, 0, diry);
+ shadowoffset.x = -fmod(dirx.dot(camera1->o) - skewdir.x*camera1->o.z, 2.0f*shadowmapradius/vieww);
+ shadowoffset.y = -fmod(diry.dot(camera1->o) - skewdir.y*camera1->o.z, 2.0f*shadowmapradius/viewh);
+
+ shadowmatrix.ortho(-shadowmapradius, shadowmapradius, -shadowmapradius, shadowmapradius, -shadowmapdist, shadowmapdist);
+ shadowmatrix.mul(matrix3(vec(1, 0, 0), vec(0, 1, 0), vec(skewdir.x, skewdir.y, 1)));
+ shadowmatrix.translate(skewdir.x*shadowmapheight + shadowoffset.x, skewdir.y*shadowmapheight + shadowoffset.y + dir.magnitude(), -shadowmapheight);
+ shadowmatrix.rotate_around_z((camera1->yaw+180)*-RAD);
+ shadowmatrix.translate(vec(camera1->o).neg());
+ GLOBALPARAM(shadowmatrix, shadowmatrix);
+
+ shadowfocus = camera1->o;
+ shadowfocus.add(dir);
+ shadowfocus.add(vec(shadowdir).mul(shadowmapheight));
+ shadowfocus.add(dirx.mul(shadowoffset.x));
+ shadowfocus.add(diry.mul(shadowoffset.y));
+
+ gle::colorf(0, 0, 0);
+
+ GLOBALPARAMF(shadowmapbias, -shadowmapbias/float(shadowmapdist), 1 - (shadowmapbias + (smoothshadowmappeel ? 0 : shadowmappeelbias))/float(shadowmapdist));
+
+ shadowmapcasters = 0;
+ shadowmapmaxz = shadowfocus.z - shadowmapdist;
+ shadowmapping = true;
+ rendergame();
+ shadowmapping = false;
+ shadowmapmaxz = min(shadowmapmaxz, shadowfocus.z);
+
+ if(shadowmapcasters && smdepthpeel)
+ {
+ int sx, sy, sw, sh;
+ bool scissoring = rtscissor && scissorblur(sx, sy, sw, sh) && sw > 0 && sh > 0;
+ if(scissoring) glScissor(sx, sy, sw, sh);
+ if(!rtscissor || scissoring) rendershadowmapreceivers();
+ }
+
+ return shadowmapcasters>0;
+ }
} shadowmaptex;
void cleanshadowmap()
{
- shadowmaptex.cleanup(true);
+ shadowmaptex.cleanup(true);
}
void calcshadowmapbb(const vec &o, float xyrad, float zrad, float &x1, float &y1, float &x2, float &y2)
{
- vec skewdir(shadowdir);
- skewdir.rotate_around_z(-camera1->yaw*RAD);
-
- vec ro(o);
- ro.sub(camera1->o);
- ro.rotate_around_z(-(camera1->yaw+180)*RAD);
- ro.x += ro.z * skewdir.x + shadowoffset.x;
- ro.y += ro.z * skewdir.y + shadowmapradius * cosf(camera1->pitch*RAD) + shadowoffset.y;
-
- vec high(ro), low(ro);
- high.x += zrad * skewdir.x;
- high.y += zrad * skewdir.y;
- low.x -= zrad * skewdir.x;
- low.y -= zrad * skewdir.y;
-
- x1 = (min(high.x, low.x) - xyrad) / shadowmapradius;
- y1 = (min(high.y, low.y) - xyrad) / shadowmapradius;
- x2 = (max(high.x, low.x) + xyrad) / shadowmapradius;
- y2 = (max(high.y, low.y) + xyrad) / shadowmapradius;
+ vec skewdir(shadowdir);
+ skewdir.rotate_around_z(-camera1->yaw*RAD);
+
+ vec ro(o);
+ ro.sub(camera1->o);
+ ro.rotate_around_z(-(camera1->yaw+180)*RAD);
+ ro.x += ro.z * skewdir.x + shadowoffset.x;
+ ro.y += ro.z * skewdir.y + shadowmapradius * cosf(camera1->pitch*RAD) + shadowoffset.y;
+
+ vec high(ro), low(ro);
+ high.x += zrad * skewdir.x;
+ high.y += zrad * skewdir.y;
+ low.x -= zrad * skewdir.x;
+ low.y -= zrad * skewdir.y;
+
+ x1 = (min(high.x, low.x) - xyrad) / shadowmapradius;
+ y1 = (min(high.y, low.y) - xyrad) / shadowmapradius;
+ x2 = (max(high.x, low.x) + xyrad) / shadowmapradius;
+ y2 = (max(high.y, low.y) + xyrad) / shadowmapradius;
}
bool addshadowmapcaster(const vec &o, float xyrad, float zrad)
{
- if(o.z + zrad <= shadowfocus.z - shadowmapdist || o.z - zrad >= shadowfocus.z) return false;
+ if(o.z + zrad <= shadowfocus.z - shadowmapdist || o.z - zrad >= shadowfocus.z) return false;
- shadowmapmaxz = max(shadowmapmaxz, o.z + zrad);
+ shadowmapmaxz = max(shadowmapmaxz, o.z + zrad);
- float x1, y1, x2, y2;
- calcshadowmapbb(o, xyrad, zrad, x1, y1, x2, y2);
+ float x1, y1, x2, y2;
+ calcshadowmapbb(o, xyrad, zrad, x1, y1, x2, y2);
- if(!shadowmaptex.addblurtiles(x1, y1, x2, y2, 2)) return false;
+ if(!shadowmaptex.addblurtiles(x1, y1, x2, y2, 2)) return false;
- shadowmapcasters++;
- return true;
+ shadowmapcasters++;
+ return true;
}
bool isshadowmapreceiver(vtxarray *va)
{
- if(!shadowmap || !shadowmapcasters) return false;
+ if(!shadowmap || !shadowmapcasters) return false;
- if(va->shadowmapmax.z <= shadowfocus.z - shadowmapdist || va->shadowmapmin.z >= shadowmapmaxz) return false;
+ if(va->shadowmapmax.z <= shadowfocus.z - shadowmapdist || va->shadowmapmin.z >= shadowmapmaxz) return false;
- float xyrad = SQRT2*0.5f*max(va->shadowmapmax.x-va->shadowmapmin.x, va->shadowmapmax.y-va->shadowmapmin.y),
- zrad = 0.5f*(va->shadowmapmax.z-va->shadowmapmin.z),
- x1, y1, x2, y2;
- if(xyrad<0 || zrad<0) return false;
+ float xyrad = SQRT2*0.5f*max(va->shadowmapmax.x-va->shadowmapmin.x, va->shadowmapmax.y-va->shadowmapmin.y),
+ zrad = 0.5f*(va->shadowmapmax.z-va->shadowmapmin.z),
+ x1, y1, x2, y2;
+ if(xyrad<0 || zrad<0) return false;
- vec center = vec(va->shadowmapmin).add(vec(va->shadowmapmax)).mul(0.5f);
- calcshadowmapbb(center, xyrad, zrad, x1, y1, x2, y2);
+ vec center = vec(va->shadowmapmin).add(vec(va->shadowmapmax)).mul(0.5f);
+ calcshadowmapbb(center, xyrad, zrad, x1, y1, x2, y2);
- return shadowmaptex.checkblurtiles(x1, y1, x2, y2, 2);
+ return shadowmaptex.checkblurtiles(x1, y1, x2, y2, 2);
#if 0
- // cheaper inexact test
- float dz = va->o.z + va->size/2 - shadowfocus.z;
- float cx = shadowfocus.x + dz*shadowdir.x, cy = shadowfocus.y + dz*shadowdir.y;
- float skew = va->size/2*SHADOWSKEW;
- if(!shadowmap || !shadowmaptex ||
- va->o.z + va->size <= shadowfocus.z - shadowmapdist || va->o.z >= shadowmapmaxz ||
- va->o.x + va->size <= cx - shadowmapradius-skew || va->o.x >= cx + shadowmapradius+skew ||
- va->o.y + va->size <= cy - shadowmapradius-skew || va->o.y >= cy + shadowmapradius+skew)
- return false;
- return true;
+ // cheaper inexact test
+ float dz = va->o.z + va->size/2 - shadowfocus.z;
+ float cx = shadowfocus.x + dz*shadowdir.x, cy = shadowfocus.y + dz*shadowdir.y;
+ float skew = va->size/2*SHADOWSKEW;
+ if(!shadowmap || !shadowmaptex ||
+ va->o.z + va->size <= shadowfocus.z - shadowmapdist || va->o.z >= shadowmapmaxz ||
+ va->o.x + va->size <= cx - shadowmapradius-skew || va->o.x >= cx + shadowmapradius+skew ||
+ va->o.y + va->size <= cy - shadowmapradius-skew || va->o.y >= cy + shadowmapradius+skew)
+ return false;
+ return true;
#endif
}
bool isshadowmapcaster(const vec &o, float rad)
{
- // cheaper inexact test
- float dz = o.z - shadowfocus.z;
- float cx = shadowfocus.x + dz*shadowdir.x, cy = shadowfocus.y + dz*shadowdir.y;
- float skew = rad*SHADOWSKEW;
- if(!shadowmapping ||
- o.z + rad <= shadowfocus.z - shadowmapdist || o.z - rad >= shadowfocus.z ||
- o.x + rad <= cx - shadowmapradius-skew || o.x - rad >= cx + shadowmapradius+skew ||
- o.y + rad <= cy - shadowmapradius-skew || o.y - rad >= cy + shadowmapradius+skew)
- return false;
- return true;
+ // cheaper inexact test
+ float dz = o.z - shadowfocus.z;
+ float cx = shadowfocus.x + dz*shadowdir.x, cy = shadowfocus.y + dz*shadowdir.y;
+ float skew = rad*SHADOWSKEW;
+ if(!shadowmapping ||
+ o.z + rad <= shadowfocus.z - shadowmapdist || o.z - rad >= shadowfocus.z ||
+ o.x + rad <= cx - shadowmapradius-skew || o.x - rad >= cx + shadowmapradius+skew ||
+ o.y + rad <= cy - shadowmapradius-skew || o.y - rad >= cy + shadowmapradius+skew)
+ return false;
+ return true;
}
void pushshadowmap()
{
- if(!shadowmap || !shadowmaptex.rendertex) return;
+ if(!shadowmap || !shadowmaptex.rendertex) return;
- glActiveTexture_(GL_TEXTURE7);
- glBindTexture(GL_TEXTURE_2D, shadowmaptex.rendertex);
+ glActiveTexture_(GL_TEXTURE7);
+ glBindTexture(GL_TEXTURE_2D, shadowmaptex.rendertex);
- matrix4 m = shadowmatrix;
- m.projective(-1, 1-shadowmapbias/float(shadowmapdist));
- GLOBALPARAM(shadowmapproject, m);
+ matrix4 m = shadowmatrix;
+ m.projective(-1, 1-shadowmapbias/float(shadowmapdist));
+ GLOBALPARAM(shadowmapproject, m);
- glActiveTexture_(GL_TEXTURE0);
+ glActiveTexture_(GL_TEXTURE0);
- float r, g, b;
+ float r, g, b;
if(!shadowmapambient)
{
if(skylightcolor[0] || skylightcolor[1] || skylightcolor[2])
@@ -283,24 +283,24 @@ void pushshadowmap()
b = max(25.0f, 0.4f*ambientcolor[2] + 0.6f*max(ambientcolor[2], skylightcolor[2]));
}
else
- {
- r = max(25.0f, 2.0f*ambientcolor[0]);
- g = max(25.0f, 2.0f*ambientcolor[1]);
- b = max(25.0f, 2.0f*ambientcolor[2]);
- }
- }
- else { r = shadowmapambientcolor[0]; g = shadowmapambientcolor[1]; b = shadowmapambientcolor[2]; }
- GLOBALPARAMF(shadowmapambient, r/255.0f, g/255.0f, b/255.0f);
+ {
+ r = max(25.0f, 2.0f*ambientcolor[0]);
+ g = max(25.0f, 2.0f*ambientcolor[1]);
+ b = max(25.0f, 2.0f*ambientcolor[2]);
+ }
+ }
+ else { r = shadowmapambientcolor[0]; g = shadowmapambientcolor[1]; b = shadowmapambientcolor[2]; }
+ GLOBALPARAMF(shadowmapambient, r/255.0f, g/255.0f, b/255.0f);
}
void popshadowmap()
{
- if(!shadowmap || !shadowmaptex.rendertex) return;
+ if(!shadowmap || !shadowmaptex.rendertex) return;
}
void rendershadowmap()
{
- if(!shadowmap) return;
+ if(!shadowmap) return;
- shadowmaptex.render(1<<shadowmapsize, 1<<shadowmapsize, blurshadowmap, blursmsigma/100.0f);
+ shadowmaptex.render(1<<shadowmapsize, 1<<shadowmapsize, blurshadowmap, blursmsigma/100.0f);
}