Skip to content

Commit 01d7e72

Browse files
committed
Fix wrong coordinate system used for fog
The fogQuake3 shader used the model coordinate system for some calculations, which is not right since it may be scaled (entities using nonNormalizedAxes). Do calculations in world space instead. In Unvanquished I believe this only affects some player models. Models that use IQM skeleton scaling are not affected.
1 parent 59ebf7b commit 01d7e72

File tree

3 files changed

+14
-29
lines changed

3 files changed

+14
-29
lines changed

src/engine/renderer/Material.cpp

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1091,12 +1091,8 @@ void BindShaderFog( Material* material ) {
10911091

10921092
// all fogging distance is based on world Z units
10931093
vec4_t fogDistanceVector;
1094-
vec3_t local;
1095-
VectorSubtract( backEnd.orientation.origin, backEnd.viewParms.orientation.origin, local );
1096-
fogDistanceVector[0] = -backEnd.orientation.modelViewMatrix[2];
1097-
fogDistanceVector[1] = -backEnd.orientation.modelViewMatrix[6];
1098-
fogDistanceVector[2] = -backEnd.orientation.modelViewMatrix[10];
1099-
fogDistanceVector[3] = DotProduct( local, backEnd.viewParms.orientation.axis[0] );
1094+
VectorCopy( backEnd.viewParms.orientation.axis[ 0 ], fogDistanceVector );
1095+
fogDistanceVector[ 3 ] = -DotProduct( fogDistanceVector, backEnd.viewParms.orientation.origin );
11001096

11011097
// scale the fog vectors based on the fog's thickness
11021098
VectorScale( fogDistanceVector, fog->tcScale, fogDistanceVector );
@@ -1106,12 +1102,9 @@ void BindShaderFog( Material* material ) {
11061102
float eyeT;
11071103
vec4_t fogDepthVector;
11081104
if ( fog->hasSurface ) {
1109-
fogDepthVector[0] = DotProduct( fog->surface, backEnd.orientation.axis[ 0 ] );
1110-
fogDepthVector[1] = DotProduct( fog->surface, backEnd.orientation.axis[ 1 ] );
1111-
fogDepthVector[2] = DotProduct( fog->surface, backEnd.orientation.axis[ 2 ] );
1112-
fogDepthVector[3] = -fog->surface[3] + DotProduct( backEnd.orientation.origin, fog->surface );
1113-
1114-
eyeT = DotProduct( backEnd.orientation.viewOrigin, fogDepthVector ) + fogDepthVector[3];
1105+
VectorCopy( fog->surface, fogDepthVector );
1106+
fogDepthVector[ 3 ] = -fog->surface[ 3 ];
1107+
eyeT = DotProduct( backEnd.viewParms.orientation.origin, fogDepthVector ) + fogDepthVector[ 3 ];
11151108
} else {
11161109
Vector4Set( fogDepthVector, 0, 0, 0, 1 );
11171110
eyeT = 1; // non-surface fog always has eye inside

src/engine/renderer/glsl_source/fogQuake3_vp.glsl

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -34,12 +34,10 @@ uniform colorPack u_ColorGlobal;
3434
uniform mat4 u_ModelMatrix;
3535
uniform mat4 u_ModelViewProjectionMatrix;
3636

37-
uniform vec4 u_FogDistanceVector; // view axis in model coordinates, scaled by fog density
38-
uniform vec4 u_FogDepthVector; // fog plane in model coordinates
37+
uniform vec4 u_FogDistanceVector; // view axis, scaled by fog density
38+
uniform vec4 u_FogDepthVector; // fog plane
3939
uniform float u_FogEyeT;
4040

41-
OUT(smooth) vec3 var_Position;
42-
4341
// var_TexCoords.s is distance from viewer to vertex dotted with view axis
4442
// var_TexCoords.t is the fraction of the viewer-to-vertex ray which is inside fog
4543
OUT(smooth) vec2 var_TexCoords;
@@ -74,7 +72,8 @@ void main()
7472
gl_Position = u_ModelViewProjectionMatrix * position;
7573

7674
// transform position into world space
77-
var_Position = (u_ModelMatrix * position).xyz;
75+
position = u_ModelMatrix * position;
76+
position.xyz /= position.w;
7877

7978
// calculate the length in fog
8079
float s = dot(position.xyz, u_FogDistanceVector.xyz) + u_FogDistanceVector.w;

src/engine/renderer/tr_shade.cpp

Lines changed: 5 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1597,12 +1597,8 @@ void Render_fog( shaderStage_t* pStage )
15971597

15981598
// all fogging distance is based on world Z units
15991599
vec4_t fogDistanceVector;
1600-
vec3_t local;
1601-
VectorSubtract( backEnd.orientation.origin, backEnd.viewParms.orientation.origin, local );
1602-
fogDistanceVector[ 0 ] = -backEnd.orientation.modelViewMatrix[ 2 ];
1603-
fogDistanceVector[ 1 ] = -backEnd.orientation.modelViewMatrix[ 6 ];
1604-
fogDistanceVector[ 2 ] = -backEnd.orientation.modelViewMatrix[ 10 ];
1605-
fogDistanceVector[ 3 ] = DotProduct( local, backEnd.viewParms.orientation.axis[ 0 ] );
1600+
VectorCopy( backEnd.viewParms.orientation.axis[ 0 ], fogDistanceVector );
1601+
fogDistanceVector[ 3 ] = -DotProduct( fogDistanceVector, backEnd.viewParms.orientation.origin );
16061602

16071603
// scale the fog vectors based on the fog's thickness
16081604
VectorScale( fogDistanceVector, fog->tcScale, fogDistanceVector );
@@ -1613,12 +1609,9 @@ void Render_fog( shaderStage_t* pStage )
16131609
vec4_t fogDepthVector;
16141610
if ( fog->hasSurface )
16151611
{
1616-
fogDepthVector[ 0 ] = DotProduct( fog->surface, backEnd.orientation.axis[ 0 ] );
1617-
fogDepthVector[ 1 ] = DotProduct( fog->surface, backEnd.orientation.axis[ 1 ] );
1618-
fogDepthVector[ 2 ] = DotProduct( fog->surface, backEnd.orientation.axis[ 2 ] );
1619-
fogDepthVector[ 3 ] = -fog->surface[ 3 ] + DotProduct( backEnd.orientation.origin, fog->surface );
1620-
1621-
eyeT = DotProduct( backEnd.orientation.viewOrigin, fogDepthVector ) + fogDepthVector[ 3 ];
1612+
VectorCopy( fog->surface, fogDepthVector );
1613+
fogDepthVector[ 3 ] = -fog->surface[ 3 ];
1614+
eyeT = DotProduct( backEnd.viewParms.orientation.origin, fogDepthVector ) + fogDepthVector[ 3 ];
16221615
}
16231616
else
16241617
{

0 commit comments

Comments
 (0)