Skip to content

Commit 8c24825

Browse files
committed
Fog: count full distance, not only along view axis
When calculating the distance from the viewer to a vertex in the fogQuake3 shader, use the full distance, instead of dotting the viewer-to-vertex vector with the view axis. So now all points on the screen will be rendered consistently, instead of for example a point 30 degrees away from the center having its fog distance multiplied by sqrt(2)/2 ~= 0.7.
1 parent 32d40f7 commit 8c24825

File tree

6 files changed

+33
-57
lines changed

6 files changed

+33
-57
lines changed

src/engine/renderer/Material.cpp

Lines changed: 4 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,15 +1089,6 @@ void BindShaderFog( Material* material ) {
10891089
// Set shader uniforms.
10901090
const fog_t* fog = tr.world->fogs + material->fog;
10911091

1092-
// all fogging distance is based on world Z units
1093-
vec4_t fogDistanceVector;
1094-
VectorCopy( backEnd.viewParms.orientation.axis[ 0 ], fogDistanceVector );
1095-
fogDistanceVector[ 3 ] = -DotProduct( fogDistanceVector, backEnd.viewParms.orientation.origin );
1096-
1097-
// scale the fog vectors based on the fog's thickness
1098-
VectorScale( fogDistanceVector, fog->tcScale, fogDistanceVector );
1099-
fogDistanceVector[3] *= fog->tcScale;
1100-
11011092
// rotate the gradient vector for this orientation
11021093
float eyeT;
11031094
vec4_t fogDepthVector;
@@ -1110,11 +1101,11 @@ void BindShaderFog( Material* material ) {
11101101
eyeT = 1; // non-surface fog always has eye inside
11111102
}
11121103

1113-
// see if the viewpoint is outside
1114-
// this is needed for clipping distance even for constant fog
1115-
fogDistanceVector[3] += 1.0 / 512;
1104+
// Note: things that seemingly should be per-shader or per-surface can be set as global uniforms
1105+
// since fognum is grouped with the GL state stuff, segregating each fognum in a separate draw call.
11161106

1117-
gl_fogQuake3ShaderMaterial->SetUniform_FogDistanceVector( fogDistanceVector );
1107+
gl_fogQuake3ShaderMaterial->SetUniform_ViewOrigin( backEnd.viewParms.orientation.origin );
1108+
gl_fogQuake3ShaderMaterial->SetUniform_FogDensity( fog->tcScale );
11181109
gl_fogQuake3ShaderMaterial->SetUniform_FogDepthVector( fogDepthVector );
11191110
gl_fogQuake3ShaderMaterial->SetUniform_FogEyeT( eyeT );
11201111

src/engine/renderer/gl_shader.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2587,7 +2587,8 @@ GLShader_fogQuake3::GLShader_fogQuake3() :
25872587
u_ColorGlobal_Uint( this ),
25882588
u_Bones( this ),
25892589
u_VertexInterpolation( this ),
2590-
u_FogDistanceVector( this ),
2590+
u_ViewOrigin( this ),
2591+
u_FogDensity( this ),
25912592
u_FogDepthVector( this ),
25922593
u_FogEyeT( this ),
25932594
GLDeformStage( this ),
@@ -2608,7 +2609,8 @@ GLShader_fogQuake3Material::GLShader_fogQuake3Material() :
26082609
u_ModelMatrix( this ),
26092610
u_ModelViewProjectionMatrix( this ),
26102611
u_ColorGlobal_Uint( this ),
2611-
u_FogDistanceVector( this ),
2612+
u_ViewOrigin( this ),
2613+
u_FogDensity( this ),
26122614
u_FogDepthVector( this ),
26132615
u_FogEyeT( this ),
26142616
GLDeformStage( this ) {

src/engine/renderer/gl_shader.h

Lines changed: 5 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -2112,7 +2112,7 @@ class u_FogDensity :
21122112
{
21132113
public:
21142114
u_FogDensity( GLShader *shader ) :
2115-
GLUniform1f( shader, "u_FogDensity" )
2115+
GLUniform1f( shader, "u_FogDensity", true )
21162116
{
21172117
}
21182118

@@ -2912,21 +2912,6 @@ template<typename Shader> void SetUniform_ColorModulateColorGen(
29122912
}
29132913
}
29142914

2915-
class u_FogDistanceVector :
2916-
GLUniform4f
2917-
{
2918-
public:
2919-
u_FogDistanceVector( GLShader *shader ) :
2920-
GLUniform4f( shader, "u_FogDistanceVector", true )
2921-
{
2922-
}
2923-
2924-
void SetUniform_FogDistanceVector( const vec4_t v )
2925-
{
2926-
this->SetValue( v );
2927-
}
2928-
};
2929-
29302915
class u_FogDepthVector :
29312916
GLUniform4f
29322917
{
@@ -3448,7 +3433,8 @@ class GLShader_fogQuake3 :
34483433
public u_ColorGlobal_Uint,
34493434
public u_Bones,
34503435
public u_VertexInterpolation,
3451-
public u_FogDistanceVector,
3436+
public u_ViewOrigin,
3437+
public u_FogDensity,
34523438
public u_FogDepthVector,
34533439
public u_FogEyeT,
34543440
public GLDeformStage,
@@ -3466,7 +3452,8 @@ class GLShader_fogQuake3Material :
34663452
public u_ModelMatrix,
34673453
public u_ModelViewProjectionMatrix,
34683454
public u_ColorGlobal_Uint,
3469-
public u_FogDistanceVector,
3455+
public u_ViewOrigin,
3456+
public u_FogDensity,
34703457
public u_FogDepthVector,
34713458
public u_FogEyeT,
34723459
public GLDeformStage {

src/engine/renderer/glsl_source/fogQuake3_fp.glsl

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -28,7 +28,8 @@ uniform sampler2D u_FogMap;
2828

2929
uniform float u_FogEyeT;
3030

31-
IN(smooth) vec2 var_TexCoords;
31+
IN(smooth) float var_FogPlaneDistance;
32+
IN(smooth) vec3 var_ScaledViewerOffset;
3233
IN(smooth) vec4 var_Color;
3334

3435
DECLARE_OUTPUT(vec4)
@@ -37,17 +38,21 @@ void main()
3738
{
3839
#insert material_fp
3940

40-
float t = step( 0, var_TexCoords.t );
41+
float s = length(var_ScaledViewerOffset);
42+
43+
s += 1.0 / 512.0;
44+
45+
float t = step( 0, var_FogPlaneDistance );
4146

4247
if ( u_FogEyeT < 0 ) // eye outside fog
4348
{
4449
// fraction of the viewer-to-vertex ray which is inside fog
45-
t *= var_TexCoords.t / ( max( 0, var_TexCoords.t ) - u_FogEyeT );
50+
t *= var_FogPlaneDistance / ( max( 0, var_FogPlaneDistance ) - u_FogEyeT );
4651
}
4752

4853
t = 1.0 / 32.0 + ( 30.0 / 32.0 ) * t;
4954

50-
vec4 color = texture2D(u_FogMap, vec2(var_TexCoords.s, t));
55+
vec4 color = texture2D(u_FogMap, vec2(s, t));
5156

5257
color *= var_Color;
5358

src/engine/renderer/glsl_source/fogQuake3_vp.glsl

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,15 @@ uniform colorPack u_ColorGlobal;
3333

3434
uniform mat4 u_ModelMatrix;
3535
uniform mat4 u_ModelViewProjectionMatrix;
36+
uniform vec3 u_ViewOrigin;
3637

37-
uniform vec4 u_FogDistanceVector; // view axis, scaled by fog density
38+
uniform float u_FogDensity;
3839
uniform vec4 u_FogDepthVector; // fog plane
3940

40-
// var_TexCoords.s is distance from viewer to vertex dotted with view axis
41-
// var_TexCoords.t is how far the vertex is under the fog plane
42-
OUT(smooth) vec2 var_TexCoords;
41+
// how far the vertex is under the fog plane
42+
OUT(smooth) float var_FogPlaneDistance;
43+
44+
OUT(smooth) vec3 var_ScaledViewerOffset;
4345
OUT(smooth) vec4 var_Color;
4446

4547
void DeformVertex( inout vec4 pos,
@@ -74,8 +76,9 @@ void main()
7476
position = u_ModelMatrix * position;
7577
position.xyz /= position.w;
7678

79+
var_ScaledViewerOffset = u_FogDensity * (position.xyz - u_ViewOrigin);
80+
7781
// calculate the length in fog
78-
float s = dot(position.xyz, u_FogDistanceVector.xyz) + u_FogDistanceVector.w;
7982
float t = dot(position.xyz, u_FogDepthVector.xyz) + u_FogDepthVector.w;
8083

8184
// HACK: increase cutoff to avoid dark lines at the edge of BSP triangles that stop
@@ -85,7 +88,7 @@ void main()
8588
t += 1.5;
8689
#endif
8790

88-
var_TexCoords = vec2(s, t);
91+
var_FogPlaneDistance = t;
8992

9093
var_Color = color;
9194
}

src/engine/renderer/tr_shade.cpp

Lines changed: 2 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1594,15 +1594,6 @@ void Render_fog( shaderStage_t* pStage )
15941594
GLIMP_LOGCOMMENT( "--- Render_fog( fogNum = %i, originalBrushNumber = %i ) ---",
15951595
tess.fogNum, fog->originalBrushNumber );
15961596

1597-
// all fogging distance is based on world Z units
1598-
vec4_t fogDistanceVector;
1599-
VectorCopy( backEnd.viewParms.orientation.axis[ 0 ], fogDistanceVector );
1600-
fogDistanceVector[ 3 ] = -DotProduct( fogDistanceVector, backEnd.viewParms.orientation.origin );
1601-
1602-
// scale the fog vectors based on the fog's thickness
1603-
VectorScale( fogDistanceVector, fog->tcScale, fogDistanceVector );
1604-
fogDistanceVector[3] *= fog->tcScale;
1605-
16061597
// rotate the gradient vector for this orientation
16071598
float eyeT;
16081599
vec4_t fogDepthVector;
@@ -1618,16 +1609,13 @@ void Render_fog( shaderStage_t* pStage )
16181609
eyeT = 1; // non-surface fog always has eye inside
16191610
}
16201611

1621-
// see if the viewpoint is outside
1622-
// this is needed for clipping distance even for constant fog
1623-
fogDistanceVector[ 3 ] += 1.0 / 512;
1624-
16251612
GL_State( pStage->stateBits );
16261613

16271614
ProcessShaderFog( pStage );
16281615
gl_fogQuake3Shader->BindProgram( 0 );
16291616

1630-
gl_fogQuake3Shader->SetUniform_FogDistanceVector( fogDistanceVector );
1617+
gl_fogQuake3Shader->SetUniform_ViewOrigin( backEnd.viewParms.orientation.origin );
1618+
gl_fogQuake3Shader->SetUniform_FogDensity( fog->tcScale );
16311619
gl_fogQuake3Shader->SetUniform_FogDepthVector( fogDepthVector );
16321620
gl_fogQuake3Shader->SetUniform_FogEyeT( eyeT );
16331621

0 commit comments

Comments
 (0)