1
0
Fork 0
forked from fte/fteqw

WIP: linear fog mode (required for Source Engine compatible fog) (#223)

* r_fog_linear implementation for GLSL and Vulkan path

* Linear fog in the non-GLSL backend
This commit is contained in:
Marco Cawthorne 2024-10-20 19:12:16 -07:00 committed by GitHub
parent a097b8a64a
commit 59d8d6914b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 130 additions and 49 deletions

View file

@ -511,6 +511,7 @@ cvar_t vid_desktopgamma = CVARFD ("vid_desktopgamma", "0",
CVAR_ARCHIVE | CVAR_RENDERERLATCH, "Apply gamma ramps upon the desktop rather than the window.");
cvar_t r_fog_cullentities = CVARD ("r_fog_cullentities", "1", "0: Never cull entities by fog...\n1: Automatically cull entities according to fog.\n2: Force fog culling regardless ");
cvar_t r_fog_linear = CVARD ("r_fog_linear", "0", "0: Use Exp/Exp2 fog. 1: Use linear fog.");
cvar_t r_fog_exp2 = CVARD ("r_fog_exp2", "1", "Expresses how fog fades with distance. 0 (matching DarkPlaces's default) is typically more realistic, while 1 (matching FitzQuake and others) is more common.");
cvar_t r_fog_permutation = CVARFD ("r_fog_permutation", "1", CVAR_SHADERSYSTEM, "Renders fog using a material permutation. 0 plays nicer with q3 shaders, but 1 is otherwise a better choice.");
@ -602,6 +603,7 @@ void GLRenderer_Init(void)
Cvar_Register (&gl_overbright_all, GRAPHICALNICETIES);
Cvar_Register (&gl_dither, GRAPHICALNICETIES);
Cvar_Register (&r_fog_cullentities, GRAPHICALNICETIES);
Cvar_Register (&r_fog_linear, GLRENDEREROPTIONS);
Cvar_Register (&r_fog_exp2, GLRENDEREROPTIONS);
Cvar_Register (&r_fog_permutation, GLRENDEREROPTIONS);

View file

@ -1270,9 +1270,12 @@ static void (D3D9_R_RenderView) (void)
if (!r_refdef.globalfog.density)
{
extern cvar_t r_fog_linear;
int fogtype = ((r_refdef.flags & RDF_UNDERWATER) && cl.fog[FOGTYPE_WATER].density)?FOGTYPE_WATER:FOGTYPE_AIR;
CL_BlendFog(&r_refdef.globalfog, &cl.oldfog[fogtype], realtime, &cl.fog[fogtype]);
r_refdef.globalfog.density /= 64; //FIXME
if (!r_fog_linear.ival)
r_refdef.globalfog.density /= 64; //FIXME
}
//check if we can do underwater warp

View file

@ -1441,6 +1441,8 @@ void Shader_LightPass(struct shaderparsestate_s *ps, const char *shortname, cons
Shader_DefaultScript(ps, shortname, shadertext);
}
extern cvar_t r_fog_linear;
extern cvar_t r_fog_exp2;
void GenerateFogTexture(texid_t *tex, float density, float zscale)
{
#define FOGS 256
@ -1460,12 +1462,15 @@ void GenerateFogTexture(texid_t *tex, float density, float zscale)
z = (float)s / (FOGS-1);
z *= zscale;
if (0)//q3
f = pow(z, 0.5);
else if (1)//GL_EXP
f = 1-exp(-density * z);
else //GL_EXP2
f = 1-exp(-(density*density) * z);
if (r_fog_linear.ival) {
f = 1.0 - ((density - z) / (density/* - r_refdef.globalfog.depthbias*/)); //pow(z, 0.5);
} else {
if (!r_fog_exp2.ival)//GL_EXP
f = 1-exp(-density * z);
else //GL_EXP2
f = 1-exp(-(density*density) * z);
}
if (f < 0)
f = 0;
if (f > 1)

View file

@ -2093,9 +2093,13 @@ void GLR_RenderView (void)
if (!r_refdef.globalfog.density)
{
extern cvar_t r_fog_linear;
int fogtype = ((r_refdef.flags & RDF_UNDERWATER) && cl.fog[FOGTYPE_WATER].density)?FOGTYPE_WATER:FOGTYPE_AIR;
CL_BlendFog(&r_refdef.globalfog, &cl.oldfog[fogtype], realtime, &cl.fog[fogtype]);
r_refdef.globalfog.density /= 64; //FIXME
if (!r_fog_linear.ival)
r_refdef.globalfog.density /= 64; //FIXME
}
if (!(r_refdef.flags & RDF_NOWORLDMODEL))

View file

@ -1830,23 +1830,35 @@ static const char *glsl_hdrs[] =
"vec3 fog3(in vec3 regularcolour)"
"{"
"float z = w_fogdensity * gl_FragCoord.z / gl_FragCoord.w;\n"
"z = max(0.0,z-w_fogdepthbias);\n"
"#if #include \"cvar/r_fog_exp2\"\n"
"z *= z;\n"
"float z, fac;\n"
"#if #include \"cvar/r_fog_linear\"\n"
"z = gl_FragCoord.z / gl_FragCoord.w;\n"
"fac = (w_fogdensity - z) / (w_fogdensity - w_fogdepthbias);\n"
"#else\n"
"z = w_fogdensity * gl_FragCoord.z / gl_FragCoord.w;\n"
"z = max(0.0,z-w_fogdepthbias);\n"
"#if #include \"cvar/r_fog_exp2\"\n"
"z *= z;\n"
"#endif\n"
"fac = exp2(-(z * 1.442695));\n"
"#endif\n"
"float fac = exp2(-(z * 1.442695));\n"
"fac = (1.0-w_fogalpha) + (clamp(fac, 0.0, 1.0)*w_fogalpha);\n"
"return mix(w_fogcolour, regularcolour, fac);\n"
"}\n"
"vec3 fog3additive(in vec3 regularcolour)"
"{"
"float z = w_fogdensity * gl_FragCoord.z / gl_FragCoord.w;\n"
"z = max(0.0,z-w_fogdepthbias);\n"
"#if #include \"cvar/r_fog_exp2\"\n"
"z *= z;\n"
"float z, fac;\n"
"#if #include \"cvar/r_fog_linear\"\n"
"z = gl_FragCoord.z / gl_FragCoord.w;\n"
"fac = (w_fogdensity - z) / (w_fogdensity - w_fogdepthbias);\n"
"#else\n"
"z = w_fogdensity * gl_FragCoord.z / gl_FragCoord.w;\n"
"z = max(0.0,z-w_fogdepthbias);\n"
"#if #include \"cvar/r_fog_exp2\"\n"
"z *= z;\n"
"#endif\n"
"fac = exp2(-(z * 1.442695));\n"
"#endif\n"
"float fac = exp2(-(z * 1.442695));\n"
"fac = (1.0-w_fogalpha) + (clamp(fac, 0.0, 1.0)*w_fogalpha);\n"
"return regularcolour * fac;\n"
"}\n"
@ -1856,23 +1868,35 @@ static const char *glsl_hdrs[] =
"}\n"
"vec4 fog4additive(in vec4 regularcolour)"
"{" //fog function for additive blends
"float z = w_fogdensity * gl_FragCoord.z / gl_FragCoord.w;\n"
"z = max(0.0,z-w_fogdepthbias);\n"
"#if #include \"cvar/r_fog_exp2\"\n"
"z *= z;\n"
"float z, fac;\n"
"#if #include \"cvar/r_fog_linear\"\n"
"z = gl_FragCoord.z / gl_FragCoord.w;\n"
"fac = (w_fogdensity - z) / (w_fogdensity - w_fogdepthbias);\n"
"#else\n"
"z = w_fogdensity * gl_FragCoord.z / gl_FragCoord.w;\n"
"z = max(0.0,z-w_fogdepthbias);\n"
"#if #include \"cvar/r_fog_exp2\"\n"
"z *= z;\n"
"#endif\n"
"fac = exp2(-(z * 1.442695));\n"
"#endif\n"
"float fac = exp2(-(z * 1.442695));\n"
"fac = (1.0-w_fogalpha) + (clamp(fac, 0.0, 1.0)*w_fogalpha);\n"
"return regularcolour * vec4(fac, fac, fac, 1.0);\n"
"}\n"
"vec4 fog4blend(in vec4 regularcolour)"
"{" //fog function for regular alpha blends (uses the blend for fading, to avoid fighting the surface behind)
"float z = w_fogdensity * gl_FragCoord.z / gl_FragCoord.w;\n"
"z = max(0.0,z-w_fogdepthbias);\n"
"#if #include \"cvar/r_fog_exp2\"\n"
"z *= z;\n"
"float z, fac;\n"
"#if #include \"cvar/r_fog_linear\"\n"
"z = gl_FragCoord.z / gl_FragCoord.w;\n"
"fac = (w_fogdensity - z) / (w_fogdensity - w_fogdepthbias);\n"
"#else\n"
"z = w_fogdensity * gl_FragCoord.z / gl_FragCoord.w;\n"
"z = max(0.0,z-w_fogdepthbias);\n"
"#if #include \"cvar/r_fog_exp2\"\n"
"z *= z;\n"
"#endif\n"
"fac = exp2(-(z * 1.442695));\n"
"#endif\n"
"float fac = exp2(-(z * 1.442695));\n"
"fac = (1.0-w_fogalpha) + (clamp(fac, 0.0, 1.0)*w_fogalpha);\n"
"return regularcolour * vec4(1.0, 1.0, 1.0, fac);\n"
"}\n"

View file

@ -6,11 +6,21 @@
{
if (!FOG)
return regularcolour;
float z = w_fogdensity * gl_FragCoord.z / gl_FragCoord.w;
z = max(0.0,z-w_fogdepthbias);
if (cvar_r_fog_exp2)
z *= z;
float fac = exp2(-(z * 1.442695));
float z;
float fac;
if (cvar_r_fog_linear) {
z = gl_FragCoord.z / gl_FragCoord.w;
fac = (w_fogdensity - z) / (w_fogdensity - w_fogdepthbias);
} else {
z = w_fogdensity * gl_FragCoord.z / gl_FragCoord.w;
z = max(0.0,z-w_fogdepthbias);
if (cvar_r_fog_exp2)
z *= z;
fac = exp2(-(z * 1.442695));
}
fac = (1.0-w_fogalpha) + (clamp(fac, 0.0, 1.0)*w_fogalpha);
return mix(w_fogcolour, regularcolour, fac);
}
@ -18,11 +28,21 @@
{
if (!FOG)
return regularcolour;
float z = w_fogdensity * gl_FragCoord.z / gl_FragCoord.w;
z = max(0.0,z-w_fogdepthbias);
if (cvar_r_fog_exp2)
z *= z;
float fac = exp2(-(z * 1.442695));
float z;
float fac;
if (cvar_r_fog_linear) {
z = gl_FragCoord.z / gl_FragCoord.w;
fac = (w_fogdensity - z) / (w_fogdensity - w_fogdepthbias);
} else {
z = w_fogdensity * gl_FragCoord.z / gl_FragCoord.w;
z = max(0.0,z-w_fogdepthbias);
if (cvar_r_fog_exp2)
z *= z;
fac = exp2(-(z * 1.442695));
}
fac = (1.0-w_fogalpha) + (clamp(fac, 0.0, 1.0)*w_fogalpha);
return regularcolour * fac;
}
@ -36,11 +56,21 @@
{
if (!FOG)
return regularcolour;
float z = w_fogdensity * gl_FragCoord.z / gl_FragCoord.w;
z = max(0.0,z-w_fogdepthbias);
if (cvar_r_fog_exp2)
z *= z;
float fac = exp2(-(z * 1.442695));
float z;
float fac;
if (cvar_r_fog_linear) {
z = gl_FragCoord.z / gl_FragCoord.w;
fac = (w_fogdensity - z) / (w_fogdensity - w_fogdepthbias);
} else {
z = w_fogdensity * gl_FragCoord.z / gl_FragCoord.w;
z = max(0.0,z-w_fogdepthbias);
if (cvar_r_fog_exp2)
z *= z;
fac = exp2(-(z * 1.442695));
}
fac = (1.0-w_fogalpha) + (clamp(fac, 0.0, 1.0)*w_fogalpha);
return regularcolour * vec4(fac, fac, fac, 1.0);
}
@ -48,11 +78,21 @@
{
if (!FOG)
return regularcolour;
float z = w_fogdensity * gl_FragCoord.z / gl_FragCoord.w;
z = max(0.0,z-w_fogdepthbias);
if (cvar_r_fog_exp2)
z *= z;
float fac = exp2(-(z * 1.442695));
float z;
float fac;
if (cvar_r_fog_linear) {
z = gl_FragCoord.z / gl_FragCoord.w;
fac = (w_fogdensity - z) / (w_fogdensity - w_fogdepthbias);
} else {
z = w_fogdensity * gl_FragCoord.z / gl_FragCoord.w;
z = max(0.0,z-w_fogdepthbias);
if (cvar_r_fog_exp2)
z *= z;
fac = exp2(-(z * 1.442695));
}
fac = (1.0-w_fogalpha) + (clamp(fac, 0.0, 1.0)*w_fogalpha);
return regularcolour * vec4(1.0, 1.0, 1.0, fac);
}

View file

@ -2949,9 +2949,12 @@ void VK_R_RenderView (void)
if (!r_refdef.globalfog.density)
{
extern cvar_t r_fog_linear;
int fogtype = ((r_refdef.flags & RDF_UNDERWATER) && cl.fog[FOGTYPE_WATER].density)?FOGTYPE_WATER:FOGTYPE_AIR;
CL_BlendFog(&r_refdef.globalfog, &cl.oldfog[fogtype], realtime, &cl.fog[fogtype]);
r_refdef.globalfog.density /= 64; //FIXME
if (!r_fog_linear.ival)
r_refdef.globalfog.density /= 64; //FIXME
}
custompostproc = NULL;