Skip to content
Merged
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: 1 addition & 0 deletions src.cmake
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ set(GLSLSOURCELIST
${ENGINE_DIR}/renderer/glsl_source/blurY_vp.glsl
${ENGINE_DIR}/renderer/glsl_source/cameraEffects_fp.glsl
${ENGINE_DIR}/renderer/glsl_source/cameraEffects_vp.glsl
${ENGINE_DIR}/renderer/glsl_source/computeLight_fp.glsl
${ENGINE_DIR}/renderer/glsl_source/contrast_fp.glsl
${ENGINE_DIR}/renderer/glsl_source/contrast_vp.glsl
${ENGINE_DIR}/renderer/glsl_source/debugShadowMap_fp.glsl
Expand Down
30 changes: 23 additions & 7 deletions src/engine/renderer/gl_shader.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -579,6 +579,21 @@ static std::string GenEngineConstants() {
AddDefine( str, "r_showLightTiles", 1 );
}

if ( r_normalMapping->integer )
{
AddDefine( str, "r_normalMapping", 1 );
}

if ( r_specularMapping->integer )
{
AddDefine( str, "r_specularMapping", 1 );
}

if ( r_glowMapping->integer )
{
AddDefine( str, "r_glowMapping", 1 );
}

return str;
}

Expand Down Expand Up @@ -1449,6 +1464,7 @@ GLShader_lightMapping::GLShader_lightMapping( GLShaderManager *manager ) :
u_numLights( this ),
u_Lights( this ),
GLDeformStage( this ),
GLCompileMacro_USE_DELUXE_MAPPING( this ),
GLCompileMacro_USE_PARALLAX_MAPPING( this ),
GLCompileMacro_USE_PHYSICAL_SHADING( this )
{
Expand All @@ -1461,7 +1477,7 @@ void GLShader_lightMapping::BuildShaderVertexLibNames( std::string& vertexInline

void GLShader_lightMapping::BuildShaderFragmentLibNames( std::string& fragmentInlines )
{
fragmentInlines += "reliefMapping";
fragmentInlines += "computeLight reliefMapping";
}

void GLShader_lightMapping::BuildShaderCompileMacros( std::string& /*compileMacros*/ )
Expand Down Expand Up @@ -1520,7 +1536,7 @@ void GLShader_vertexLighting_DBS_entity::BuildShaderVertexLibNames( std::string&

void GLShader_vertexLighting_DBS_entity::BuildShaderFragmentLibNames( std::string& fragmentInlines )
{
fragmentInlines += "reliefMapping";
fragmentInlines += "computeLight reliefMapping";
}

void GLShader_vertexLighting_DBS_entity::BuildShaderCompileMacros( std::string& )
Expand Down Expand Up @@ -1580,7 +1596,7 @@ void GLShader_vertexLighting_DBS_world::BuildShaderVertexLibNames( std::string&
}
void GLShader_vertexLighting_DBS_world::BuildShaderFragmentLibNames( std::string& fragmentInlines )
{
fragmentInlines += "reliefMapping";
fragmentInlines += "computeLight reliefMapping";
}

void GLShader_vertexLighting_DBS_world::BuildShaderCompileMacros( std::string& )
Expand Down Expand Up @@ -1642,7 +1658,7 @@ void GLShader_forwardLighting_omniXYZ::BuildShaderVertexLibNames( std::string& v

void GLShader_forwardLighting_omniXYZ::BuildShaderFragmentLibNames( std::string& fragmentInlines )
{
fragmentInlines += "reliefMapping";
fragmentInlines += "computeLight reliefMapping";
}

void GLShader_forwardLighting_omniXYZ::BuildShaderCompileMacros( std::string& /*compileMacros*/ )
Expand Down Expand Up @@ -1703,7 +1719,7 @@ void GLShader_forwardLighting_projXYZ::BuildShaderVertexLibNames( std::string& v

void GLShader_forwardLighting_projXYZ::BuildShaderFragmentLibNames( std::string& fragmentInlines )
{
fragmentInlines += "reliefMapping";
fragmentInlines += "computeLight reliefMapping";
}

void GLShader_forwardLighting_projXYZ::BuildShaderCompileMacros( std::string& compileMacros )
Expand Down Expand Up @@ -1767,7 +1783,7 @@ void GLShader_forwardLighting_directionalSun::BuildShaderVertexLibNames( std::st

void GLShader_forwardLighting_directionalSun::BuildShaderFragmentLibNames( std::string& fragmentInlines )
{
fragmentInlines += "reliefMapping";
fragmentInlines += "computeLight reliefMapping";
}

void GLShader_forwardLighting_directionalSun::BuildShaderCompileMacros( std::string& compileMacros )
Expand Down Expand Up @@ -2112,7 +2128,7 @@ GLShader_liquid::GLShader_liquid( GLShaderManager *manager ) :

void GLShader_liquid::BuildShaderFragmentLibNames( std::string& fragmentInlines )
{
fragmentInlines += "reliefMapping";
fragmentInlines += "computeLight reliefMapping";
}

void GLShader_liquid::SetShaderProgramUniforms( shaderProgram_t *shaderProgram )
Expand Down
27 changes: 27 additions & 0 deletions src/engine/renderer/gl_shader.h
Original file line number Diff line number Diff line change
Expand Up @@ -783,6 +783,7 @@ class GLCompileMacro
USE_VERTEX_SPRITE,
USE_TCGEN_ENVIRONMENT,
USE_TCGEN_LIGHTMAP,
USE_DELUXE_MAPPING,
USE_PARALLAX_MAPPING,
USE_REFLECTIVE_SPECULAR,
USE_SHADOWING,
Expand Down Expand Up @@ -983,6 +984,31 @@ class GLCompileMacro_USE_TCGEN_LIGHTMAP :
}
};

class GLCompileMacro_USE_DELUXE_MAPPING :
GLCompileMacro
{
public:
GLCompileMacro_USE_DELUXE_MAPPING( GLShader *shader ) :
GLCompileMacro( shader )
{
}

const char *GetName() const
{
return "USE_DELUXE_MAPPING";
}

EGLCompileMacro GetType() const
{
return EGLCompileMacro::USE_DELUXE_MAPPING;
}

void SetDeluxeMapping( bool enable )
{
SetMacro( enable );
}
};

class GLCompileMacro_USE_PARALLAX_MAPPING :
GLCompileMacro
{
Expand Down Expand Up @@ -2201,6 +2227,7 @@ class GLShader_lightMapping :
public u_numLights,
public u_Lights,
public GLDeformStage,
public GLCompileMacro_USE_DELUXE_MAPPING,
public GLCompileMacro_USE_PARALLAX_MAPPING,
public GLCompileMacro_USE_PHYSICAL_SHADING
{
Expand Down
202 changes: 202 additions & 0 deletions src/engine/renderer/glsl_source/computeLight_fp.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,202 @@
/*
===========================================================================
Copyright (C) 2009-2011 Robert Beckebans <trebor_7@users.sourceforge.net>

This file is part of XreaL source code.

XreaL source code is free software; you can redistribute it
and/or modify it under the terms of the GNU General Public License as
published by the Free Software Foundation; either version 2 of the License,
or (at your option) any later version.

XreaL source code is distributed in the hope that it will be
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
along with XreaL source code; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
// computeLight_fp.glsl - Light computing helper functions

struct light {
vec4 center_radius;
vec4 color_type;
vec4 direction_angle;
};

#ifdef HAVE_ARB_uniform_buffer_object
layout(std140) uniform u_Lights {
light lights[ MAX_REF_LIGHTS ];
};
#define GetLight(idx, component) lights[idx].component
#else // !HAVE_ARB_uniform_buffer_object
uniform sampler2D u_Lights;
#define idxToTC( idx, w, h ) vec2( floor( ( idx * ( 1.0 / w ) ) + 0.5 ) * ( 1.0 / h ), \
fract( ( idx + 0.5 ) * (1.0 / w ) ) )
const struct GetLightOffsets {
int center_radius;
int color_type;
int direction_angle;
} getLightOffsets = GetLightOffsets(0, 1, 2);
#define GetLight(idx, component) texture2D( u_Lights, idxToTC(3 * idx + getLightOffsets.component, 64.0, float( 3 * MAX_REF_LIGHTS / 64 ) ) )
#endif // HAVE_ARB_uniform_buffer_object

uniform int u_numLights;

uniform vec2 u_SpecularExponent;

// lighting helper functions
void computeLight( vec3 lightDir, vec3 normal, vec3 eyeDir, vec3 lightColor,
vec4 diffuseColor, vec4 specularColor,
inout vec4 accumulator ) {
vec3 H = normalize( lightDir + eyeDir );
float NdotH = clamp( dot( normal, H ), 0.0, 1.0 );

#if defined(USE_PHYSICAL_SHADING)
float metalness = specularColor.x;
float roughness = specularColor.y;

float NdotV = clamp( dot( normal, eyeDir ), 0.0, 1.0);
float VdotH = clamp( dot( eyeDir, H ), 0.0, 1.0);
float NdotL = clamp( dot( normal, lightDir ), 0.0, 1.0 );

float alpha = roughness * roughness;
float k = 0.125 * (roughness + 1.0) * (roughness + 1.0);

float D = alpha / ((NdotH * NdotH) * (alpha * alpha - 1.0) + 1.0);
D *= D;

float FexpNH = pow(1.0 - NdotH, 5.0);
float FexpNV = pow(1.0 - NdotV, 5.0);
vec3 F = mix(vec3(0.04), diffuseColor.xyz, metalness);
F = F + (1.0 - F) * FexpNH;

float G = NdotL / (NdotL * (1.0 - k) + k);
G *= NdotV / (NdotV * (1.0 - k) + k);

accumulator.xyz += lightColor.xyz * (1.0 - metalness) * NdotL * diffuseColor.xyz;
accumulator.xyz += lightColor.xyz * vec3((D * F * G) / (4.0 * NdotV));
accumulator.a = mix(diffuseColor.a, 1.0, FexpNV);
#else // !USE_PHYSICAL_SHADING
float NdotL = dot( normal, lightDir );
#if defined(r_HalfLambertLighting)
// http://developer.valvesoftware.com/wiki/Half_Lambert
NdotL = NdotL * 0.5 + 0.5;
NdotL *= NdotL;
#elif defined(r_WrapAroundLighting)
NdotL = clamp( NdotL + r_WrapAroundLighting, 0.0, 1.0) / clamp(1.0 + r_WrapAroundLighting, 0.0, 1.0);
#else
NdotL = clamp( NdotL, 0.0, 1.0 );
#endif

accumulator.xyz += diffuseColor.xyz * lightColor.xyz * NdotL;
#if defined(r_specularMapping)
accumulator.xyz += specularColor.xyz * lightColor.xyz * pow( NdotH, u_SpecularExponent.x * specularColor.w + u_SpecularExponent.y) * r_SpecularScale;
#endif // r_specularMapping
#endif // USE_PHYSICAL_SHADING
}

#if defined(TEXTURE_INTEGER)
const int lightsPerLayer = 16;
uniform usampler3D u_LightTiles;
#define idxs_t uvec4
idxs_t fetchIdxs( in vec3 coords ) {
return texture3D( u_LightTiles, coords );
}
int nextIdx( inout idxs_t idxs ) {
uvec4 tmp = ( idxs & uvec4( 3 ) ) * uvec4( 0x40, 0x10, 0x04, 0x01 );
idxs = idxs >> 2;
return int( tmp.x + tmp.y + tmp.z + tmp.w );
}
#else // !TEXTURE INTEGER
const int lightsPerLayer = 4;
uniform sampler3D u_LightTiles;
#define idxs_t vec4
idxs_t fetchIdxs( in vec3 coords ) {
return texture3D( u_LightTiles, coords ) * 255.0;
}
int nextIdx( inout idxs_t idxs ) {
vec4 tmp = idxs;
idxs = floor(idxs * 0.25);
tmp -= 4.0 * idxs;
return int( dot( tmp, vec4( 64.0, 16.0, 4.0, 1.0 ) ) );
}
#endif // TEXTURE_INTEGER

const int numLayers = MAX_REF_LIGHTS / 256;

void computeDLight( int idx, vec3 P, vec3 N, vec3 I, vec4 diffuse,
vec4 specular, inout vec4 color ) {
vec4 center_radius = GetLight( idx, center_radius );
vec4 color_type = GetLight( idx, color_type );
vec3 L;
float attenuation;

if( color_type.w == 0.0 ) {
// point light
L = center_radius.xyz - P;
attenuation = 1.0 / (1.0 + 8.0 * length(L) / center_radius.w);
L = normalize(L);
} else if( color_type.w == 1.0 ) {
// spot light
vec4 direction_angle = GetLight( idx, direction_angle );
L = center_radius.xyz - P;
attenuation = 1.0 / (1.0 + 8.0 * length(L) / center_radius.w);
L = normalize( L );

if( dot( L, direction_angle.xyz ) <= direction_angle.w ) {
attenuation = 0.0;
}
} else if( color_type.w == 2.0 ) {
// sun (directional) light
L = GetLight( idx, direction_angle ).xyz;
attenuation = 1.0;
}
computeLight( L, N, I,
attenuation * attenuation * color_type.xyz,
diffuse, specular, color );
}

void computeDLights( vec3 P, vec3 N, vec3 I, vec4 diffuse, vec4 specular,
inout vec4 color ) {
vec2 tile = floor( gl_FragCoord.xy * (1.0 / float( TILE_SIZE ) ) ) + 0.5;
vec3 tileScale = vec3( r_tileStep, 1.0/numLayers );

#if defined(r_showLightTiles)
float numLights = 0.0;
#endif

for( int layer = 0; layer < numLayers; layer++ ) {
idxs_t idxs = fetchIdxs( tileScale * vec3( tile, float( layer ) + 0.5 ) );
for( int i = 0; i < lightsPerLayer; i++ ) {
int idx = numLayers * nextIdx( idxs ) + layer;

if( idx > u_numLights )
{
#if defined(r_showLightTiles)
if (numLights > 0.0)
{
color = vec4(numLights/(lightsPerLayer*numLayers), numLights/(lightsPerLayer*numLayers), numLights/(lightsPerLayer*numLayers), 1.0);
}
#endif
return;
}

computeDLight( idx, P, N, I, diffuse, specular, color );

#if defined(r_showLightTiles)
numLights++;
#endif
}
}

#if defined(r_showLightTiles)
if (numLights > 0.0)
{
color = vec4(numLights/(lightsPerLayer*numLayers), numLights/(lightsPerLayer*numLayers), numLights/(lightsPerLayer*numLayers), 1.0);
}
#endif
}
Loading