Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion src/engine/renderer/GeometryOptimiser.h
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,6 @@ void MarkShaderBuildScreen( const shaderStage_t* pStage );
void MarkShaderBuildPortal( const shaderStage_t* pStage );
void MarkShaderBuildHeatHaze( const shaderStage_t* pStage );
void MarkShaderBuildLiquid( const shaderStage_t* pStage );
void MarkShaderBuildFog( const shaderStage_t* pStage );

void MarkShaderBuildIQM( const IQModel_t* model );
void MarkShaderBuildMDV( const mdvModel_t* model );
Expand Down
5 changes: 3 additions & 2 deletions src/engine/renderer/Material.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1114,11 +1114,12 @@ void BindShaderFog( Material* material ) {
// since fognum is grouped with the GL state stuff, segregating each fognum in a separate draw call.

gl_fogQuake3ShaderMaterial->SetUniform_ViewOrigin( backEnd.viewParms.orientation.origin );
gl_fogQuake3ShaderMaterial->SetUniform_FogDensity( fog->tcScale );
gl_fogQuake3ShaderMaterial->SetUniform_FogGradient(
1.0f / fog->shader->fogParms.depthForOpaque, fog->shader->fogParms.falloffExp );
gl_fogQuake3ShaderMaterial->SetUniform_FogDepthVector( fogDepthVector );
gl_fogQuake3ShaderMaterial->SetUniform_FogEyeT( eyeT );

gl_fogQuake3ShaderMaterial->SetUniform_ColorGlobal_Uint( fog->color );
gl_fogQuake3ShaderMaterial->SetUniform_ColorGlobal_Uint( fog->shader->fogParms.color );

gl_fogQuake3ShaderMaterial->SetUniform_ModelMatrix( backEnd.orientation.transformMatrix );
gl_fogQuake3ShaderMaterial->SetUniform_ModelViewProjectionMatrix( glState.modelViewProjectionMatrix[glState.stackIndex] );
Expand Down
4 changes: 2 additions & 2 deletions src/engine/renderer/gl_shader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2697,7 +2697,7 @@ GLShader_fogQuake3::GLShader_fogQuake3() :
u_Bones( this ),
u_VertexInterpolation( this ),
u_ViewOrigin( this ),
u_FogDensity( this ),
u_FogGradient( this ),
u_FogDepthVector( this ),
u_FogEyeT( this ),
GLDeformStage( this ),
Expand All @@ -2713,7 +2713,7 @@ GLShader_fogQuake3Material::GLShader_fogQuake3Material() :
u_ModelViewProjectionMatrix( this ),
u_ColorGlobal_Uint( this ),
u_ViewOrigin( this ),
u_FogDensity( this ),
u_FogGradient( this ),
u_FogDepthVector( this ),
u_FogEyeT( this ),
GLDeformStage( this ) {
Expand Down
20 changes: 18 additions & 2 deletions src/engine/renderer/gl_shader.h
Original file line number Diff line number Diff line change
Expand Up @@ -1859,6 +1859,22 @@ class u_FogDensity :
}
};

class u_FogGradient :
GLUniform2f
{
public:
u_FogGradient( GLShader *shader ) :
GLUniform2f( shader, "u_FogGradient", PUSH )
{
}

void SetUniform_FogGradient( float density, float falloffExp )
{
vec2_t value{ density, falloffExp };
this->SetValue( value );
}
};

class u_FogColor :
GLUniform3f
{
Expand Down Expand Up @@ -3166,7 +3182,7 @@ class GLShader_fogQuake3 :
public u_Bones,
public u_VertexInterpolation,
public u_ViewOrigin,
public u_FogDensity,
public u_FogGradient,
public u_FogDepthVector,
public u_FogEyeT,
public GLDeformStage,
Expand All @@ -3183,7 +3199,7 @@ class GLShader_fogQuake3Material :
public u_ModelViewProjectionMatrix,
public u_ColorGlobal_Uint,
public u_ViewOrigin,
public u_FogDensity,
public u_FogGradient,
public u_FogDepthVector,
public u_FogEyeT,
public GLDeformStage {
Expand Down
30 changes: 27 additions & 3 deletions src/engine/renderer/glsl_source/fogEquation_fp.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -32,11 +32,35 @@ SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
===========================================================================
*/

float GetFogAlpha(float s, float t)
float FogGradientFunction(float k, float t)
{
t = clamp(t, 0.0, 1.0);
return 1 - exp(-k * t);
}

float x = min(1, s * t);
float FogGradientAntiderivative(float k, float t)
{
return t + exp(-k * t) / k;
}

float GetFogGradientModifier(float k, float t0, float t1)
{
t0 = max(0.0, t0);
t1 = max(0.0, t1);

float deltaT = t1 - t0;
if (abs(deltaT) > 0.1)
{
return ( FogGradientAntiderivative(k, t1) - FogGradientAntiderivative(k, t0) ) / deltaT;
}
else
{
return FogGradientFunction(k, t0);
}
}

float GetFogAlpha(float x)
{
x = clamp(x, 0.0, 1.0);

// sqrt(x) is bad near 0 because it increases too quickly resulting in sharp edges.
// x ≤ 1/32: √32 * x
Expand Down
4 changes: 2 additions & 2 deletions src/engine/renderer/glsl_source/fogGlobal_fp.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -49,10 +49,10 @@ void main()
vec4 P = u_UnprojectMatrix * vec4(gl_FragCoord.xy, depth, 1.0);
P.xyz /= P.w;

// calculate the length in fog (t is always 1 if eye is in fog)
// calculate the length in fog
float s = distance(u_ViewOrigin, P.xyz) * u_FogDensity;

vec4 color = vec4(1, 1, 1, GetFogAlpha(s, 1.0));
vec4 color = vec4(1, 1, 1, GetFogAlpha(s));

outputColor = UnpackColor( u_Color ) * color;
}
17 changes: 12 additions & 5 deletions src/engine/renderer/glsl_source/fogQuake3_fp.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -26,10 +26,11 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA

#define DEPTHMAP_GLSL

uniform vec2 u_FogGradient;
uniform float u_FogEyeT;

IN(smooth) float var_FogPlaneDistance;
IN(smooth) vec3 var_ScaledViewerOffset;
IN(smooth) vec3 var_ViewerOffset;
IN(smooth) vec4 var_Color;

DECLARE_OUTPUT(vec4)
Expand All @@ -38,16 +39,22 @@ void main()
{
#insert material_fp

float s = length(var_ScaledViewerOffset);
float t = step( 0, var_FogPlaneDistance );
if ( var_FogPlaneDistance < -0.01 )
{
discard;
}

float distInFog = length(var_ViewerOffset);

if ( u_FogEyeT < 0 ) // eye outside fog
{
// fraction of the viewer-to-vertex ray which is inside fog
t *= var_FogPlaneDistance / ( max( 0, var_FogPlaneDistance ) - u_FogEyeT );
distInFog *= var_FogPlaneDistance / ( max( 0, var_FogPlaneDistance ) - u_FogEyeT );
}

vec4 color = vec4(1, 1, 1, GetFogAlpha(s, t));
float gradient = GetFogGradientModifier(u_FogGradient.y, u_FogEyeT, var_FogPlaneDistance);

vec4 color = vec4(1, 1, 1, GetFogAlpha(gradient * u_FogGradient.x * distInFog));

color *= var_Color;

Expand Down
5 changes: 2 additions & 3 deletions src/engine/renderer/glsl_source/fogQuake3_vp.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -35,13 +35,12 @@ uniform mat4 u_ModelMatrix;
uniform mat4 u_ModelViewProjectionMatrix;
uniform vec3 u_ViewOrigin;

uniform float u_FogDensity;
uniform vec4 u_FogDepthVector; // fog plane

// how far the vertex is under the fog plane
OUT(smooth) float var_FogPlaneDistance;

OUT(smooth) vec3 var_ScaledViewerOffset;
OUT(smooth) vec3 var_ViewerOffset;
OUT(smooth) vec4 var_Color;

void DeformVertex( inout vec4 pos,
Expand Down Expand Up @@ -76,7 +75,7 @@ void main()
position = u_ModelMatrix * position;
position.xyz /= position.w;

var_ScaledViewerOffset = u_FogDensity * (position.xyz - u_ViewOrigin);
var_ViewerOffset = position.xyz - u_ViewOrigin;

// calculate the length in fog
var_FogPlaneDistance = dot(position.xyz, u_FogDepthVector.xyz) + u_FogDepthVector.w;
Expand Down
4 changes: 2 additions & 2 deletions src/engine/renderer/tr_backend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1458,9 +1458,9 @@ void RB_RenderGlobalFog()

GL_State( GLS_DEPTHTEST_DISABLE | GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA );

gl_fogGlobalShader->SetUniform_FogDensity( fog->tcScale );
gl_fogGlobalShader->SetUniform_FogDensity( 1.0f / fog->shader->fogParms.depthForOpaque );
gl_fogGlobalShader->SetUniform_ViewOrigin( backEnd.viewParms.orientation.origin );
SetUniform_Color( gl_fogGlobalShader, fog->color );
SetUniform_Color( gl_fogGlobalShader, fog->shader->fogParms.color );
}

gl_fogGlobalShader->SetUniform_UnprojectMatrix( backEnd.viewParms.unprojectionMatrix );
Expand Down
21 changes: 1 addition & 20 deletions src/engine/renderer/tr_bsp.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -3217,8 +3217,6 @@ static void R_LoadFogs( lump_t *l, lump_t *brushesLump, lump_t *sidesLump )
int count, brushesCount, sidesCount;
int sideNum;
int planeNum;
shader_t *shader;
float d;
int firstSide = 0;

Log::Debug("...loading fogs" );
Expand Down Expand Up @@ -3316,26 +3314,9 @@ static void R_LoadFogs( lump_t *l, lump_t *brushesLump, lump_t *sidesLump )
out->bounds[ 1 ][ 2 ] = s_worldData.planes[ planeNum ].dist;
}

// get information from the shader for fog parameters
// it says RSF_3D but if there is no shader text found it should probably just error instead
// of trying to create an implicit shader from an image...
shader = R_FindShader( fogs->shader, RSF_3D );

out->fogParms = shader->fogParms;

out->color = Color::Adapt( shader->fogParms.color );

if ( tr.worldLinearizeTexture )
{
out->color = out->color.ConvertFromSRGB();
}

out->color *= tr.identityLight;

out->color.SetAlpha( 1 );

d = shader->fogParms.depthForOpaque < 1 ? 1 : shader->fogParms.depthForOpaque;
out->tcScale = 1.0f / d;
out->shader = R_FindShader( fogs->shader, RSF_3D );

// ydnar: global fog sets clearcolor/zfar
if ( out->originalBrushNumber == -1 )
Expand Down
7 changes: 3 additions & 4 deletions src/engine/renderer/tr_local.h
Original file line number Diff line number Diff line change
Expand Up @@ -1116,8 +1116,9 @@ enum

struct fogParms_t
{
vec3_t color;
Color::Color color;
float depthForOpaque;
float falloffExp;
};

struct shader_t
Expand Down Expand Up @@ -1340,9 +1341,7 @@ enum
int originalBrushNumber;
vec3_t bounds[ 2 ];

Color::Color color; // in packed byte format
float tcScale; // texture coordinate vector scales
fogParms_t fogParms;
shader_t *shader; // has the fog parms

// for clipping distance in fog when outside
bool hasSurface;
Expand Down
5 changes: 3 additions & 2 deletions src/engine/renderer/tr_shade.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1646,12 +1646,13 @@ void Render_fog( shaderStage_t* pStage )
gl_fogQuake3Shader->BindProgram();

gl_fogQuake3Shader->SetUniform_ViewOrigin( backEnd.viewParms.orientation.origin );
gl_fogQuake3Shader->SetUniform_FogDensity( fog->tcScale );
gl_fogQuake3Shader->SetUniform_FogGradient(
1.0f / fog->shader->fogParms.depthForOpaque, fog->shader->fogParms.falloffExp );
gl_fogQuake3Shader->SetUniform_FogDepthVector( fogDepthVector );
gl_fogQuake3Shader->SetUniform_FogEyeT( eyeT );

// u_Color
SetUniform_ColorGlobal( gl_fogQuake3Shader, fog->color );
SetUniform_ColorGlobal( gl_fogQuake3Shader, fog->shader->fogParms.color );

gl_fogQuake3Shader->SetUniform_ModelMatrix( backEnd.orientation.transformMatrix );
gl_fogQuake3Shader->SetUniform_ModelViewProjectionMatrix( glState.modelViewProjectionMatrix[ glState.stackIndex ] );
Expand Down
57 changes: 50 additions & 7 deletions src/engine/renderer/tr_shader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4398,17 +4398,23 @@ static bool ParseShader( const char *_text )
// fogParms
else if ( !Q_stricmp( token, "fogParms" ) )
{
/*
Log::Warn("fogParms keyword not supported in shader '%s'", shader.name);
SkipRestOfLine(text);
vec3_t fogColor;

*/

if ( !ParseVector( text, 3, shader.fogParms.color ) )
if ( !ParseVector( text, 3, fogColor ) )
{
return false;
}

shader.fogParms.color = Color::Adapt( fogColor );

if ( tr.worldLinearizeTexture )
{
shader.fogParms.color = shader.fogParms.color.ConvertFromSRGB();
}

shader.fogParms.color *= tr.identityLight;
shader.fogParms.color.SetAlpha( 1 );

token = COM_ParseExt2( text, false );

if ( !token[ 0 ] )
Expand All @@ -4417,14 +4423,46 @@ static bool ParseShader( const char *_text )
continue;
}

shader.fogParms.depthForOpaque = atof( token );
shader.fogParms.depthForOpaque = std::max( 1.0, atof( token ) );

shader.sort = Util::ordinal(shaderSort_t::SS_FOG);

// skip any old gradient directions
SkipRestOfLine( text );
continue;
}
// fogGradient
// Default: fogGradient expFalloff 5
else if ( !Q_stricmp( token, "fogGradient" ) )
{
token = COM_ParseExt2( text, false );

if ( !Q_stricmp( token, "const" ) )
{
shader.fogParms.falloffExp = 9999;
}
// fogGradient expFalloff <dist from edge at which density is 50% of max>
// scales density by 1 - exp(-k*t) where t is distance under fog plane
else if ( !Q_stricmp( token, "expFalloff" ) )
{
token = COM_ParseExt2( text, false );
float val = atof( token );

if ( val > 0.0f )
{
shader.fogParms.falloffExp = M_LN2 / val;
}
else
{
Log::Warn( "bad expFalloff value in shader '%s'", shader.name );
}
}
else
{
Log::Warn( "invalid fogGradient type '%s' in shader '%s'", token, shader.name );
}
continue;
}
// noFog
else if ( !Q_stricmp( token, "noFog" ) )
{
Expand Down Expand Up @@ -5780,6 +5818,11 @@ static shader_t *FinishShader()
shader.portalRange = r_portalDefaultRange.Get();
}

if ( shader.fogParms.falloffExp == 0.0f )
{
shader.fogParms.falloffExp = M_LN2 / 5;
}

numStages = MAX_SHADER_STAGES;
GroupActiveStages();

Expand Down
Loading