From a7931514c5e216f8b1f6f13497c6813f68118f1c Mon Sep 17 00:00:00 2001 From: "C.." Date: Wed, 12 Dec 2018 12:17:43 +0100 Subject: [PATCH] renderer2: r2 update #2 --- src/renderer2/glsl/forwardLighting_fp.glsl | 218 ++++++------- src/renderer2/glsl/forwardLighting_vp.glsl | 109 ++++--- src/renderer2/glsl/lib/normalMapping_fp.glsl | 49 +-- src/renderer2/glsl/lib/reliefMapping_fp.glsl | 2 +- src/renderer2/glsl/lib/vertexSkinning_vp.glsl | 7 +- src/renderer2/glsl/lightMapping_fp.glsl | 115 ++++--- src/renderer2/glsl/lightMapping_vp.glsl | 38 ++- src/renderer2/glsl/liquid_fp.glsl | 305 +++++------------- src/renderer2/glsl/liquid_vp.glsl | 55 +++- src/renderer2/glsl/reflection_CB_fp.glsl | 82 +++-- src/renderer2/glsl/reflection_CB_vp.glsl | 68 +++- src/renderer2/glsl/reflection_C_fp.glsl | 18 +- src/renderer2/glsl/reflection_C_vp.glsl | 9 +- .../glsl/vertexLighting_DBS_entity_fp.glsl | 132 ++++---- .../glsl/vertexLighting_DBS_entity_vp.glsl | 56 +++- .../glsl/vertexLighting_DBS_world_fp.glsl | 119 ++++--- .../glsl/vertexLighting_DBS_world_vp.glsl | 43 ++- src/renderer2/tr_glsl.c | 4 +- src/renderer2/tr_init.c | 9 +- src/renderer2/tr_local.h | 2 +- src/renderer2/tr_shade.c | 242 ++++++++------ 21 files changed, 888 insertions(+), 794 deletions(-) diff --git a/src/renderer2/glsl/forwardLighting_fp.glsl b/src/renderer2/glsl/forwardLighting_fp.glsl index ae76993c3..cf51e1016 100644 --- a/src/renderer2/glsl/forwardLighting_fp.glsl +++ b/src/renderer2/glsl/forwardLighting_fp.glsl @@ -1,12 +1,20 @@ /* forwardLighting_fp.glsl */ -#include "lib/reliefMapping" +//#if defined(USE_NORMAL_MAPPING) #include "lib/normalMapping" +//#if defined(USE_PARALLAX_MAPPING) +#include "lib/reliefMapping" +//#endif // USE_PARALLAX_MAPPING +//#endif // USE_NORMAL_MAPPING uniform sampler2D u_DiffuseMap; -uniform sampler2D u_NormalMap; -uniform sampler2D u_SpecularMap; +uniform int u_AlphaTest; +uniform mat4 u_ViewMatrix; uniform sampler2D u_AttenuationMapXY; uniform sampler2D u_AttenuationMapZ; +#if defined(USE_NORMAL_MAPPING) +uniform sampler2D u_NormalMap; +uniform sampler2D u_SpecularMap; +#endif // USE_NORMAL_MAPPING #if defined(LIGHT_DIRECTIONAL) uniform sampler2D u_ShadowMap0; @@ -20,10 +28,6 @@ uniform sampler2D u_ShadowMap0; uniform samplerCube u_ShadowMap; #endif -//uniform sampler2D u_RandomMap; // random normals - -uniform vec3 u_ViewOrigin; - #if defined(LIGHT_DIRECTIONAL) uniform vec3 u_LightDir; #else @@ -33,32 +37,40 @@ uniform vec3 u_LightColor; uniform float u_LightRadius; uniform float u_LightScale; uniform float u_LightWrapAround; -uniform int u_AlphaTest; uniform mat4 u_ShadowMatrix[MAX_SHADOWMAPS]; uniform vec4 u_ShadowParallelSplitDistances; uniform float u_ShadowTexelSize; uniform float u_ShadowBlur; -uniform mat4 u_ViewMatrix; - -uniform vec4 u_PortalPlane; - -uniform float u_DepthScale; - varying vec3 var_Position; varying vec4 var_TexDiffuse; varying vec4 var_TexNormal; -#if defined(USE_NORMAL_MAPPING) -varying vec2 var_TexSpecular; -#endif varying vec4 var_TexAttenuation; -#if defined(USE_NORMAL_MAPPING) -varying vec4 var_Tangent; -varying vec4 var_Binormal; -#endif varying vec4 var_Normal; -//varying vec4 var_Color; +#if defined(USE_NORMAL_MAPPING) +varying mat3 var_tangentMatrix; +varying vec2 var_TexSpecular; +varying vec3 var_ViewOrigin; // vieworigin - position ! +varying vec3 var_ViewOrigin2; // vieworigin in worldspace +#if defined(USE_PARALLAX_MAPPING) +varying vec2 var_S; // size and start position of search in texture space +#endif // USE_PARALLAX_MAPPING +#endif // USE_NORMAL_MAPPING +#if defined(USE_PORTAL_CLIPPING) +varying float var_BackSide; // in front, or behind, the portalplane +#endif // USE_PORTAL_CLIPPING + + +/* + VSM Variance Shadow Mapping + ESM Exponential Shadow Maps + EVSM Exponential Variance Shadow Mapping + PCF Percentage-Closer Filtering + PCSS Percentage-Closer Soft Shadow +*/ + + /* ================ @@ -68,6 +80,7 @@ Given a normalized forward vector, create two other perpendicular vectors ================ */ + void MakeNormalVectors(const vec3 forward, inout vec3 right, inout vec3 up) { // this rotate and negate guarantees a vector @@ -140,9 +153,9 @@ float ChebyshevUpperBound(vec2 shadowMoments, float vertexDistance, float minVar float pMax = variance / (variance + (d * d)); /* - #if defined(r_LightBleedReduction) - pMax = smoothstep(r_LightBleedReduction, 1.0, pMax); - #endif +// #if defined(r_LightBleedReduction) +// pMax = smoothstep(r_LightBleedReduction, 1.0, pMax); +// #endif */ // one-tailed Chebyshev with k > 0 @@ -581,24 +594,20 @@ float log_conv(float x0, float X, float y0, float Y) void main() { #if defined(USE_PORTAL_CLIPPING) + if (var_BackSide < 0.0) { - float dist = dot(var_Position.xyz, u_PortalPlane.xyz) - u_PortalPlane.w; - if (dist < 0.0) - { - discard; - return; - } + discard; + return; } #endif -#if 0 - // create random noise vector - vec3 rand = RandomVec3(gl_FragCoord.st * r_FBufScale); - - gl_FragColor = vec4(rand * 0.5 + 0.5, 1.0); - return; -#endif +//#if 0 +// // create random noise vector +// vec3 rand = RandomVec3(gl_FragCoord.st * r_FBufScale); +// gl_FragColor = vec4(rand * 0.5 + 0.5, 1.0); +// return; +//#endif float shadow = 1.0; @@ -611,15 +620,15 @@ void main() vec4 shadowMoments; FetchShadowMoments(var_Position.xyz, shadowVert, shadowMoments); - // FIXME - #if 0 // defined(r_PCFSamples) - shadowMoments = PCF(var_Position.xyz, u_ShadowTexelSize * u_ShadowBlur, r_PCFSamples); - #endif +// // FIXME +// #if 0 // defined(r_PCFSamples) +// shadowMoments = PCF(var_Position.xyz, u_ShadowTexelSize * u_ShadowBlur, r_PCFSamples); +// #endif -#if 0 - gl_FragColor = vec4(u_ShadowTexelSize * u_ShadowBlur * u_LightRadius, 0.0, 0.0, 1.0); - return; -#endif +//#if 0 +// gl_FragColor = vec4(u_ShadowTexelSize * u_ShadowBlur * u_LightRadius, 0.0, 0.0, 1.0); +// return; +//#endif #if defined(r_ShowParallelShadowSplits) // transform to camera space @@ -776,10 +785,10 @@ void main() // const float SHADOW_BIAS = 0.01; // float vertexDistance = length(I) / u_LightRadius - 0.01; -#if 0 - gl_FragColor = vec4(u_ShadowTexelSize * u_ShadowBlur * length(I), 0.0, 0.0, 1.0); - return; -#endif +//#if 0 +// gl_FragColor = vec4(u_ShadowTexelSize * u_ShadowBlur * length(I), 0.0, 0.0, 1.0); +// return; +//#endif #if defined(r_PCFSamples) vec4 shadowMoments = PCF(I, u_ShadowTexelSize * u_ShadowBlur * length(I), r_PCFSamples); @@ -936,57 +945,50 @@ void main() vec2 texDiffuse = var_TexDiffuse.st; -#if defined(USE_NORMAL_MAPPING) - - // invert tangent space for twosided surfaces - mat3 tangentToWorldMatrix; -#if defined(TWOSIDED) - // positive check (don't use tangentToWorldMatrix function) - if (gl_FrontFacing) - { - tangentToWorldMatrix = mat3(-var_Tangent.xyz, -var_Binormal.xyz, -var_Normal.xyz); - } - else -#endif - { - tangentToWorldMatrix = mat3(var_Tangent.xyz, var_Binormal.xyz, var_Normal.xyz); - } + float dotNL; + vec3 specular; +#if defined(USE_NORMAL_MAPPING) vec2 texNormal = var_TexNormal.st; vec2 texSpecular = var_TexSpecular.st; // compute view direction in world space - vec3 V = normalize(u_ViewOrigin - var_Position.xyz); + vec3 V = var_ViewOrigin.xyz; // tangentspace //vec3 V = normalize(u_ViewOrigin - var_Position.xyz); #if defined(USE_PARALLAX_MAPPING) // ray intersect in view direction - - mat3 worldToTangentMatrix = transpose(tangentToWorldMatrix); - - // compute view direction in tangent space - vec3 Vts = normalize(worldToTangentMatrix * V); - - // size and start position of search in texture space - vec2 S = Vts.xy * -u_DepthScale / Vts.z; - - float depth = RayIntersectDisplaceMap(texNormal, S, u_NormalMap); - + float depth = RayIntersectDisplaceMap(texNormal, var_S, u_NormalMap); // compute texcoords offset - vec2 texOffset = S * depth; + vec2 texOffset = var_S * depth; - texDiffuse.st += texOffset; - texNormal.st += texOffset; - texSpecular.st += texOffset; + texDiffuse += texOffset; + texNormal += texOffset; + texSpecular += texOffset; #endif // USE_PARALLAX_MAPPING - // compute half angle in world space - vec3 H = normalize(L + V); + // normal + vec3 Ntex = texture2D(u_NormalMap, texNormal).xyz * 2.0 - 1.0; + // transform normal from tangentspace to worldspace + vec3 N = normalize(var_tangentMatrix * Ntex); // we must normalize to get a vector of unit-length.. reflect() needs it - // compute normal - vec3 N = computeNormal(texture2D(u_NormalMap, texNormal).xyz, tangentToWorldMatrix); + // the cosine of the angle between N & L (if N & L are vectors of unit length (normalized)) + dotNL = dot(N, L); - vec3 R = reflect(-L, N); + // compute the specular term + if (dotNL > 0.0) + { + vec3 H = normalize(L + V); // the half-vector + float dotNH = max(0.0, dot(N, H)); + vec4 map = texture2D(u_SpecularMap, texSpecular); + float exponent = map.a * r_SpecularExponent; + float intensity = pow(dotNH, exponent); + specular = map.rgb * u_LightColor * intensity; // * r_SpecularScale; + } + else + { + specular = vec3(0.0); + } #else // else USE_NORMAL_MAPPING @@ -994,25 +996,20 @@ void main() #if defined(TWOSIDED) if (!gl_FrontFacing) { - N = -normalize(var_Normal.xyz); + N = normalize(-var_Normal.xyz); } else #endif { N = normalize(var_Normal.xyz); } + dotNL = dot(N, L); #endif // end USE_NORMAL_MAPPING - // compute the light term -#if defined(r_WrapAroundLighting) - float NL = clamp(dot(N, L) + u_LightWrapAround, 0.0, 1.0) / clamp(1.0 + u_LightWrapAround, 0.0, 1.0); -#else - float NL = clamp(dot(N, L), 0.0, 1.0); -#endif - // compute the diffuse term vec4 diffuse = texture2D(u_DiffuseMap, texDiffuse.st); + #if defined(USE_ALPHA_TESTING) if (u_AlphaTest == ATEST_GT_0 && diffuse.a <= 0.0) { @@ -1030,24 +1027,23 @@ void main() return; } #endif - diffuse.rgb *= u_LightColor * NL; -#if defined(USE_NORMAL_MAPPING) - // compute the specular term - //vec3 specular = texture2D(u_SpecularMap, texSpecular).rgb * u_LightColor * pow(clamp(dot(N, H), 0.0, 1.0), r_SpecularExponent) * r_SpecularScale; - vec3 specular = texture2D(u_SpecularMap, texSpecular).rgb * u_LightColor * pow(max(dot(V, R), 0.0), r_SpecularExponent) * r_SpecularScale; + // compute the light term +#if defined(r_WrapAroundLighting) + float NL = clamp(dotNL + u_LightWrapAround, 0.0, 1.0) / clamp(1.0 + u_LightWrapAround, 0.0, 1.0); +#else + float NL = clamp(dotNL, 0.0, 1.0); #endif + diffuse.rgb *= (u_LightColor * NL); // compute light attenuation #if defined(LIGHT_PROJ) vec3 attenuationXY = texture2DProj(u_AttenuationMapXY, var_TexAttenuation.xyw).rgb; vec3 attenuationZ = texture2D(u_AttenuationMapZ, vec2(var_TexAttenuation.z + 0.5, 0.0)).rgb; // FIXME - #elif defined(LIGHT_DIRECTIONAL) vec3 attenuationXY = vec3(1.0); vec3 attenuationZ = vec3(1.0); - #else vec3 attenuationXY = texture2D(u_AttenuationMapXY, var_TexAttenuation.xy).rgb; vec3 attenuationZ = texture2D(u_AttenuationMapZ, vec2(var_TexAttenuation.z, 0)).rgb; @@ -1072,24 +1068,4 @@ void main() color.gb *= var_TexNormal.pq; gl_FragColor = color; - -#if 0 -#if defined(USE_PARALLAX_MAPPING) - gl_FragColor = vec4(vec3(1.0, 0.0, 0.0), diffuse.a); -#elif defined(USE_NORMAL_MAPPING) - gl_FragColor = vec4(vec3(0.0, 0.0, 1.0), diffuse.a); -#else - gl_FragColor = vec4(vec3(0.0, 1.0, 0.0), diffuse.a); -#endif -#endif - -#if 0 -#if defined(USE_VERTEX_SKINNING) - gl_FragColor = vec4(vec3(1.0, 0.0, 0.0), diffuse.a); -#elif defined(USE_VERTEX_ANIMATION) - gl_FragColor = vec4(vec3(0.0, 0.0, 1.0), diffuse.a); -#else - gl_FragColor = vec4(vec3(0.0, 1.0, 0.0), diffuse.a); -#endif -#endif } diff --git a/src/renderer2/glsl/forwardLighting_vp.glsl b/src/renderer2/glsl/forwardLighting_vp.glsl index 67d2e0201..3e7f97633 100644 --- a/src/renderer2/glsl/forwardLighting_vp.glsl +++ b/src/renderer2/glsl/forwardLighting_vp.glsl @@ -1,60 +1,84 @@ /* forwardLighting_vp.glsl */ +#if defined(USE_VERTEX_SKINNING) #include "lib/vertexSkinning" +#endif // USE_VERTEX_SKINNING +#if defined(USE_VERTEX_ANIMATION) #include "lib/vertexAnimation" +#endif // USE_VERTEX_ANIMATION +#if defined(USE_DEFORM_VERTEXES) #include "lib/deformVertexes" +#endif // USE_DEFORM_VERTEXES attribute vec4 attr_Position; +attribute vec4 attr_Color; attribute vec4 attr_TexCoord0; +attribute vec3 attr_Normal; +#if defined(USE_NORMAL_MAPPING) attribute vec3 attr_Tangent; attribute vec3 attr_Binormal; -attribute vec3 attr_Normal; -attribute vec4 attr_Color; - +#endif // USE_NORMAL_MAPPING +#if defined(USE_VERTEX_ANIMATION) attribute vec4 attr_Position2; +attribute vec3 attr_Normal2; +#if defined(USE_NORMAL_MAPPING) attribute vec3 attr_Tangent2; attribute vec3 attr_Binormal2; -attribute vec3 attr_Normal2; - -uniform float u_VertexInterpolation; +#endif // USE_NORMAL_MAPPING +#endif // USE_VERTEX_ANIMATION uniform mat4 u_DiffuseTextureMatrix; -uniform mat4 u_NormalTextureMatrix; -uniform mat4 u_SpecularTextureMatrix; - -uniform vec4 u_ColorModulate; -uniform vec4 u_Color; - uniform mat4 u_LightAttenuationMatrix; uniform mat4 u_ModelMatrix; uniform mat4 u_ModelViewProjectionMatrix; - +uniform vec4 u_ColorModulate; +uniform vec4 u_Color; +#if defined(USE_NORMAL_MAPPING) +uniform mat4 u_NormalTextureMatrix; +uniform mat4 u_SpecularTextureMatrix; +uniform vec3 u_ViewOrigin; +#endif // USE_NORMAL_MAPPING +#if defined(USE_DEFORM_VERTEXES) uniform float u_Time; +#endif // USE_DEFORM_VERTEXES +#if defined(USE_VERTEX_ANIMATION) +uniform float u_VertexInterpolation; +#endif // USE_VERTEX_ANIMATION +#if defined(USE_PARALLAX_MAPPING) +uniform float u_DepthScale; +#endif // USE_PARALLAX_MAPPING +#if defined(USE_PORTAL_CLIPPING) +uniform vec4 u_PortalPlane; +#endif // USE_PORTAL_CLIPPING varying vec3 var_Position; varying vec4 var_TexDiffuse; varying vec4 var_TexNormal; +varying vec4 var_TexAttenuation; +varying vec4 var_Normal; #if defined(USE_NORMAL_MAPPING) +varying mat3 var_tangentMatrix; varying vec2 var_TexSpecular; -#endif +varying vec3 var_ViewOrigin; // vieworigin - position ! +varying vec3 var_ViewOrigin2; // vieworigin in worldspace +#if defined(USE_PARALLAX_MAPPING) +varying vec2 var_S; // size and start position of search in texture space +#endif // USE_PARALLAX_MAPPING +#endif // USE_NORMAL_MAPPING +#if defined(USE_PORTAL_CLIPPING) +varying float var_BackSide; // in front, or behind, the portalplane +#endif // USE_PORTAL_CLIPPING -varying vec4 var_TexAttenuation; - -#if defined(USE_NORMAL_MAPPING) -varying vec4 var_Tangent; -varying vec4 var_Binormal; -#endif -varying vec4 var_Normal; -//varying vec4 var_Color; // maximum vars reached void main() { vec4 position; + vec3 normal; +#if defined(USE_NORMAL_MAPPING) vec3 tangent; vec3 binormal; - vec3 normal; +#endif // USE_NORMAL_MAPPING #if defined(USE_VERTEX_SKINNING) - #if defined(USE_NORMAL_MAPPING) VertexSkinning_P_TBN(attr_Position, attr_Tangent, attr_Binormal, attr_Normal, position, tangent, binormal, normal); @@ -62,9 +86,7 @@ void main() VertexSkinning_P_N(attr_Position, attr_Normal, position, normal); #endif - #elif defined(USE_VERTEX_ANIMATION) - #if defined(USE_NORMAL_MAPPING) VertexAnimation_P_TBN(attr_Position, attr_Position2, attr_Tangent, attr_Tangent2, @@ -78,15 +100,12 @@ void main() u_VertexInterpolation, position, normal); #endif - #else position = attr_Position; - #if defined(USE_NORMAL_MAPPING) tangent = attr_Tangent; binormal = attr_Binormal; #endif - normal = attr_Normal; #endif @@ -103,31 +122,45 @@ void main() // transform position into world space var_Position = (u_ModelMatrix * position).xyz; -#if defined(USE_NORMAL_MAPPING) - var_Tangent.xyz = (u_ModelMatrix * vec4(tangent, 0.0)).xyz; - var_Binormal.xyz = (u_ModelMatrix * vec4(binormal, 0.0)).xyz; -#endif - - var_Normal.xyz = mat3(u_ModelMatrix) * normal; - // calc light xy,z attenuation in light space var_TexAttenuation = u_LightAttenuationMatrix * position; // transform diffusemap texcoords var_TexDiffuse.xy = (u_DiffuseTextureMatrix * attr_TexCoord0).st; + var_Normal.xyz = mat3(u_ModelMatrix) * normal; + #if defined(USE_NORMAL_MAPPING) + tangent = (u_ModelMatrix * vec4(tangent, 0.0)).xyz; + binormal = (u_ModelMatrix * vec4(binormal, 0.0)).xyz; + + // in a vertex-shader there exists no gl_FrontFacing + var_tangentMatrix = mat3(tangent, binormal, var_Normal.xyz); + // transpose(inverse()) ? on a rotationmatrix? for a rotationmatrix, the transpose is equal to the inverse. + //var_tangentMatrix = transpose(inverse(mat3(tangent, binormal, var_Normal.xyz))); + // transform normalmap texcoords var_TexNormal.xy = (u_NormalTextureMatrix * attr_TexCoord0).st; // transform specularmap texture coords var_TexSpecular = (u_SpecularTextureMatrix * attr_TexCoord0).st; -#endif + + var_ViewOrigin = normalize(u_ViewOrigin - var_Position.xyz); + var_ViewOrigin2 = normalize(var_tangentMatrix * var_ViewOrigin); + +#if defined(USE_PARALLAX_MAPPING) + var_S = var_ViewOrigin2.xy * -u_DepthScale / var_ViewOrigin2.z; +#endif // USE_PARALLAX_MAPPING +#endif // USE_NORMAL_MAPPING // assign color vec4 color = attr_Color * u_ColorModulate + u_Color; - // color = vec4(1.0); var_TexDiffuse.p = color.r; var_TexNormal.pq = color.gb; + +#if defined(USE_PORTAL_CLIPPING) + // in front, or behind, the portalplane + var_BackSide = dot(var_Position.xyz, u_PortalPlane.xyz) - u_PortalPlane.w; +#endif // USE_PORTAL_CLIPPING } diff --git a/src/renderer2/glsl/lib/normalMapping_fp.glsl b/src/renderer2/glsl/lib/normalMapping_fp.glsl index 4a1df13fd..cd24e2772 100644 --- a/src/renderer2/glsl/lib/normalMapping_fp.glsl +++ b/src/renderer2/glsl/lib/normalMapping_fp.glsl @@ -6,7 +6,7 @@ // The matrix depends on how the surface is faced (front or back), and if the surface is rendered two-sided. // In case the surface is two-sided, and we view the back-side of that surface, we flip tangentspace axis.. // ..that way, we handle the back-facing-side as if it's the front we're viewing (so the surface gets drawn, and not culled) - mat3 tangetToWorldMatrix(vec3 tangent, vec3 binormal, vec3 normal) + mat3 tangentToWorldMatrix(vec3 tangent, vec3 binormal, vec3 normal) { #if defined(TWOSIDED) if (!gl_FrontFacing) @@ -56,40 +56,51 @@ #if defined(USE_SPECULAR) // Compute the specular lighting // Specular highlights are only visible if you look into the light. - vec3 computeSpecular(vec3 viewDir, vec3 normal, vec3 lightDir, float exponent) + vec3 computeSpecular2(float dotNL, vec3 viewDir, vec3 normal, vec3 lightDir, vec3 lightColor, float exponent) + { + if (dotNL <= 0.0) return vec3(0.0); + vec3 H = normalize(lightDir + viewDir); // the half-vector + float dotNH = max(0.0, dot(normal, H)); + float intensity = pow(dotNH, exponent); + return vec3(intensity); + } + vec3 computeSpecular(vec3 viewDir, vec3 normal, vec3 lightDir, vec3 lightColor, float exponent) { float dotNL = dot(normal, lightDir); - if (dotNL > 0.0) - { - vec3 H = normalize(lightDir + viewDir); // the half-vector - float dotNH = max(0.0, dot(normal, H)); - float intensity = pow(dotNH, exponent); - return vec3(intensity); - } - return vec3(0.0); + return computeSpecular2(dotNL, viewDir, normal, lightDir, lightColor, exponent); } #endif // USE_SPECULAR +#if defined(r_diffuseLighting) // compute the diffuse light term + // https://en.wikipedia.org/wiki/Lambert%27s_cosine_law // It renders surfaces darker when they are less facing the light. // Diffuse lighting is very much visible: If the diffuse light value is 0, the surface will be rendered black. // If we don't want pitch black surfaces, we must take care that this value is always >0. // The half-Lambert method keeps the diffuse lighting value in the range 0.5 to 1.0 // You don't have to stick to half-Lambert; You can choose how dark your world should be.. // ..Just keep the value in a range 0.0 to 1.0 (0=black and dark, higher values = less dark, 1.0 = effectively disabling Lambertian.. the dark is gone) - float computeDiffuseLighting(vec3 normal, vec3 lightDir) + float computeDiffuseLighting2(float dotNL) { - float dotNL = dot(normal, lightDir); - #if defined(r_HalfLambertLighting) - // half-Lambert starts at 0.5, and fills the range 0.5 to 1.0 - // We want it a bit brighter, so we start at 0.875 (to 1.0) - float lambert = dotNL * 0.125 + 0.875; - return lambert*lambert; // square the result (this also makes the result always >0) + #if defined(r_diffuseLighting) + // half-Lambert starts at 0.5, and fills the range 0.5 to 1.0 (dotNL*0.5+0.5) + // example: We want it a bit brighter, so we start at 0.875 (to 1.0) //float lambert = dotNL * 0.125 + 0.875; + float lambert = (1.0 - r_diffuseLighting) + (dotNL * r_diffuseLighting); + + //return lambert*lambert; // square the result (this also makes the result always >0) + return abs(lambert); // don't square, but abs instead. (the most useful values are so low already. squaring them lowers them even more) #elif defined(r_WrapAroundLighting) return clamp(dotNL + u_LightWrapAround, 0.0, 1.0) / clamp(1.0 + u_LightWrapAround, 0.0, 1.0); #else // r_WrapAroundLighting - return clamp(dotNL, 0.0, 1.0); // maximum Lambertian applied - #endif // r_WrapAroundLighting, r_HalfLambertLighting + //return clamp(dotNL, 0.0, 1.0); // maximum Lambertian applied + return 1.0; // effectively no diffuseLighting + #endif // r_WrapAroundLighting, r_diffuseLighting + } + float computeDiffuseLighting(vec3 normal, vec3 lightDir) + { + float dotNL = dot(normal, lightDir); + return computeDiffuseLighting2(dotNL); } +#endif // r_diffuseLighting #endif diff --git a/src/renderer2/glsl/lib/reliefMapping_fp.glsl b/src/renderer2/glsl/lib/reliefMapping_fp.glsl index 131f6ff6e..3e702f733 100644 --- a/src/renderer2/glsl/lib/reliefMapping_fp.glsl +++ b/src/renderer2/glsl/lib/reliefMapping_fp.glsl @@ -56,4 +56,4 @@ float RayIntersectDisplaceMap(vec2 dp, vec2 ds, sampler2D normalMap) return bestDepth; } -#endif \ No newline at end of file +#endif diff --git a/src/renderer2/glsl/lib/vertexSkinning_vp.glsl b/src/renderer2/glsl/lib/vertexSkinning_vp.glsl index 18dcebdb6..501bc894b 100644 --- a/src/renderer2/glsl/lib/vertexSkinning_vp.glsl +++ b/src/renderer2/glsl/lib/vertexSkinning_vp.glsl @@ -7,7 +7,6 @@ uniform mat4 u_BoneMatrix[MAX_GLSL_BONES]; void VertexSkinning_P_N(const vec4 inPosition, const vec3 inNormal, - inout vec4 position, inout vec3 normal) { @@ -61,6 +60,8 @@ void VertexSkinning_P_N(const vec4 inPosition, normal += (boneMatrix * vec4(inNormal, 0.0)).xyz * boneWeight; #endif + + normal = normalize(normal); } void VertexSkinning_P_TBN(const vec4 inPosition, @@ -91,4 +92,8 @@ void VertexSkinning_P_TBN(const vec4 inPosition, binormal += (boneMatrix * vec4(inBinormal, 0.0)).xyz * boneWeight; normal += (boneMatrix * vec4(inNormal, 0.0)).xyz * boneWeight; } + + tangent = normalize(tangent); + binormal = normalize(binormal); + normal = normalize(normal); } diff --git a/src/renderer2/glsl/lightMapping_fp.glsl b/src/renderer2/glsl/lightMapping_fp.glsl index 700eb4e43..13e54ae28 100644 --- a/src/renderer2/glsl/lightMapping_fp.glsl +++ b/src/renderer2/glsl/lightMapping_fp.glsl @@ -1,14 +1,16 @@ /* lightMapping_fp.glsl */ -#include "lib/reliefMapping" +#if defined(USE_NORMAL_MAPPING) #include "lib/normalMapping" +#if defined(USE_PARALLAX_MAPPING) +#include "lib/reliefMapping" +#endif // USE_PARALLAX_MAPPING +#endif // USE_NORMAL_MAPPING uniform bool SHOW_LIGHTMAP; //uniform bool SHOW_DELUXEMAP; -uniform vec3 u_ViewOrigin; uniform int u_AlphaTest; -uniform vec4 u_PortalPlane; -uniform vec3 u_LightDir; +uniform vec3 u_LightColor; uniform sampler2D u_DiffuseMap; uniform sampler2D u_LightMap; #if defined(USE_NORMAL_MAPPING) @@ -35,30 +37,40 @@ varying vec4 var_TexDiffuseNormal; varying vec2 var_TexLight; varying vec3 var_Normal; #if defined(USE_NORMAL_MAPPING) -varying vec3 var_Tangent; -varying vec3 var_Binormal; +varying mat3 var_tangentMatrix; #if defined(USE_REFLECTIONS) || defined(USE_SPECULAR) varying vec2 var_TexSpecular; #endif // USE_REFLECTIONS || USE_SPECULAR +varying vec3 var_LightDirection; +varying vec3 var_ViewOrigin; // position - vieworigin +#if defined(USE_PARALLAX_MAPPING) +varying vec2 var_S; // size and start position of search in texture space +#endif // USE_PARALLAX_MAPPING #endif // USE_NORMAL_MAPPING +#if defined(USE_PORTAL_CLIPPING) +varying float var_BackSide; // in front, or behind, the portalplane +#endif // USE_PORTAL_CLIPPING + void main() { #if defined(USE_PORTAL_CLIPPING) - float dist = dot(var_Position.xyz, u_PortalPlane.xyz) - u_PortalPlane.w; - if (dist < 0.0) { + if (var_BackSide < 0.0) + { discard; return; } #endif // USE_PORTAL_CLIPPING + // get the color from the lightmap vec4 lightmapColor = texture2D(u_LightMap, var_TexLight); //#if defined(USE_DELUXE_MAPPING) // //fixme: must be done when there IS a deluxemap. not when we want-to-see (show) deluxemaps (and just pass -some- normalmap as a substitude :S) // vec4 deluxemapColor = vec4(0.0, 0.0, 0.0, 1.0); -// if (SHOW_DELUXEMAP) { +// if (SHOW_DELUXEMAP) +// { // deluxemapColor = texture2D(u_DeluxeMap, var_TexLight); // } //#endif // USE_DELUXE_MAPPING @@ -73,34 +85,21 @@ void main() vec2 texSpecular = var_TexSpecular.st; #endif // USE_REFLECTIONS || USE_SPECULAR - // compute view direction in world space - vec3 V = normalize(var_Position - u_ViewOrigin); - - // Create the matrix that will transform coordinates to worldspace. - mat3 tangentSpaceMatrix = tangetToWorldMatrix(var_Tangent.xyz, var_Binormal.xyz, var_Normal.xyz); - #if defined(USE_PARALLAX_MAPPING) // ray intersect in view direction - - // We invert the view vector V, so we end up with a vector Vts that points away from the surface (to the camera/eye/view).. like the normal N - vec3 Vts = normalize(tangentSpaceMatrix * V); - - // size and start position of search in texture space - vec2 S = Vts.xy * -u_DepthScale / Vts.z; - - float depth = RayIntersectDisplaceMap(texNormal, S, u_NormalMap); - + float depth = RayIntersectDisplaceMap(texNormal, var_S, u_NormalMap); // compute texcoords offset - vec2 texOffset = S * depth; + vec2 texOffset = var_S * depth; - texDiffuse.st += texOffset; - texNormal.st += texOffset; + texDiffuse += texOffset; + texNormal += texOffset; #if defined(USE_REFLECTIONS) || defined(USE_SPECULAR) - texSpecular.st += texOffset; + texSpecular += texOffset; #endif // USE_REFLECTIONS || USE_SPECULAR #endif // USE_PARALLAX_MAPPING + // compute the diffuse term vec4 diffuse = texture2D(u_DiffuseMap, texDiffuse); @@ -123,41 +122,58 @@ void main() #endif - // compute normal (from tangentspace, to worldspace) - vec3 N = computeNormal(texture2D(u_NormalMap, texNormal).xyz, tangentSpaceMatrix); + // view direction + vec3 V = var_ViewOrigin; + + // light direction in world space + vec3 L = var_LightDirection; - // compute light direction in world space. invert the direction so the vector points away from the surface. - vec3 L = -normalize(u_LightDir); + // normal + vec3 Ntex = texture2D(u_NormalMap, texNormal).xyz * 2.0 - 1.0; + // transform normal from tangentspace to worldspace + vec3 N = normalize(var_tangentMatrix * Ntex); // we must normalize to get a vector of unit-length.. reflect() needs it // the angle between the normal- & light-directions (needs normalized vectors to return the cosine of the angle) float dotNL = dot(N, L); -#if defined(USE_REFLECTIONS) || defined(USE_SPECULAR) // compute the specular term (and reflections) - vec3 reflections = vec3(0.0); - vec3 specular = vec3(0.0); -#if defined(USE_REFLECTIONS) - // reflections - reflections = computeReflections(V, N, u_EnvironmentMap0, u_EnvironmentMap1, u_EnvironmentInterpolation); -#endif // end USE_REFLECTIONS -#if defined(USE_SPECULAR) - // the specular highlights - specular = computeSpecular(V, N, L, 64.0); //r_SpecularExponent -#endif // USE_SPECULAR - specular += reflections; - specular *= texture2D(u_SpecularMap, texSpecular).rgb; // shininess factor -#endif // USE_REFLECTIONS || USE_SPECULAR + //! https://en.wikipedia.org/wiki/Specular_highlight + //! "The number n is called the Phong exponent, and is a user-chosen value that controls the apparent smoothness of the surface" +#if defined(USE_SPECULAR) && !defined(USE_REFLECTIONS) + vec4 map = texture2D(u_SpecularMap, texSpecular); + vec3 shininess = map.rgb; + // alpha values in range 0 to 1.0. exponent range is 0 to 256 (or whatever maximum value you want. ..perhaps r_SpecularExponent?). + float exponent = map.a * r_SpecularExponent; + vec3 specular = computeSpecular2(dotNL, V, N, L, u_LightColor, exponent) + * shininess; +#elif defined(USE_SPECULAR) && defined(USE_REFLECTIONS) + vec4 map = texture2D(u_SpecularMap, texSpecular); + vec3 shininess = map.rgb; + float exponent = map.a * r_SpecularExponent; + vec3 specular = (computeReflections(V, N, u_EnvironmentMap0, u_EnvironmentMap1, u_EnvironmentInterpolation) + + computeSpecular2(dotNL, V, N, L, u_LightColor, exponent)) + * shininess; +#elif !defined(USE_SPECULAR) && defined(USE_REFLECTIONS) + vec4 map = texture2D(u_SpecularMap, texSpecular); + vec3 shininess = map.rgb; + vec3 specular = computeReflections(V, N, u_EnvironmentMap0, u_EnvironmentMap1, u_EnvironmentInterpolation) + * shininess; +#endif + +#if defined(r_diffuseLighting) // compute the diffuse light term - // https://en.wikipedia.org/wiki/Lambert%27s_cosine_law - diffuse.rgb *= computeDiffuseLighting(N, L); + diffuse.rgb *= computeDiffuseLighting2(dotNL); +#endif // r_diffuseLighting + // compute final color vec4 color = diffuse; #if defined(USE_NORMAL_MAPPING) #if defined(USE_REFLECTIONS) || defined(USE_SPECULAR) color.rgb += specular; + //color.rgb += (vec4(specular,1.0) * lightmapColor).rgb; #endif // USE_REFLECTIONS || USE_SPECULAR #endif // USE_NORMAL_MAPPING color *= lightmapColor; // we must blend using the lightmap.a @@ -201,7 +217,8 @@ void main() //#if defined(USE_DELUXE_MAPPING) // // show only the deluxemap? -// if (SHOW_DELUXEMAP) { +// if (SHOW_DELUXEMAP) +// { // gl_FragColor = texture2D(u_DeluxeMap, var_TexLight); // return; // } diff --git a/src/renderer2/glsl/lightMapping_vp.glsl b/src/renderer2/glsl/lightMapping_vp.glsl index 9a7b467b0..36fc32d49 100644 --- a/src/renderer2/glsl/lightMapping_vp.glsl +++ b/src/renderer2/glsl/lightMapping_vp.glsl @@ -17,7 +17,9 @@ uniform mat4 u_ModelViewProjectionMatrix; uniform vec4 u_ColorModulate; uniform vec4 u_Color; uniform vec3 u_LightDir; +uniform vec3 u_LightColor; uniform float u_Time; +uniform vec3 u_ViewOrigin; #if defined(USE_NORMAL_MAPPING) uniform mat4 u_NormalTextureMatrix; #if defined(USE_REFLECTIONS) || defined(USE_SPECULAR) @@ -29,6 +31,9 @@ uniform float u_EnvironmentInterpolation; #endif // USE_REFLECTIONS #endif // USE_REFLECTIONS || USE_SPECULAR #endif // USE_NORMAL_MAPPING +#if defined(USE_PORTAL_CLIPPING) +uniform vec4 u_PortalPlane; +#endif // USE_PORTAL_CLIPPING varying vec3 var_Position; varying vec4 var_TexDiffuseNormal; @@ -36,12 +41,19 @@ varying vec2 var_TexLight; varying vec4 var_Color; varying vec3 var_Normal; #if defined(USE_NORMAL_MAPPING) -varying vec3 var_Tangent; -varying vec3 var_Binormal; +varying mat3 var_tangentMatrix; #if defined(USE_REFLECTIONS) || defined(USE_SPECULAR) varying vec2 var_TexSpecular; #endif // USE_REFLECTIONS || USE_SPECULAR +varying vec3 var_LightDirection; +varying vec3 var_ViewOrigin; // position - vieworigin +#if defined(USE_PARALLAX_MAPPING) +varying vec2 var_S; // size and start position of search in texture space +#endif // USE_PARALLAX_MAPPING #endif // USE_NORMAL_MAPPING +#if defined(USE_PORTAL_CLIPPING) +varying float var_BackSide; // in front, or behind, the portalplane +#endif // USE_PORTAL_CLIPPING void main() @@ -72,8 +84,11 @@ void main() // transform tangentspace axis var_Normal.xyz = (u_ModelMatrix * vec4(attr_Normal, 0.0)).xyz; #if defined(USE_NORMAL_MAPPING) - var_Tangent.xyz = (u_ModelMatrix * vec4(attr_Tangent, 0.0)).xyz; - var_Binormal.xyz = (u_ModelMatrix * vec4(attr_Binormal, 0.0)).xyz; + vec3 tangent = (u_ModelMatrix * vec4(attr_Tangent, 0.0)).xyz; + vec3 binormal = (u_ModelMatrix * vec4(attr_Binormal, 0.0)).xyz; + + // in a vertex-shader there exists no gl_FrontFacing + var_tangentMatrix = mat3(-tangent, -binormal, -var_Normal.xyz); // transform normalmap texcoords var_TexDiffuseNormal.pq = (u_NormalTextureMatrix * attr_TexCoord0).st; @@ -82,8 +97,23 @@ void main() // transform specularmap texcoords var_TexSpecular = (u_SpecularTextureMatrix * attr_TexCoord0).st; #endif // USE_REFLECTIONS || USE_SPECULAR + + var_LightDirection = -normalize(u_LightDir); + + // the vieworigin + var_ViewOrigin = normalize(var_Position - u_ViewOrigin); + +#if defined(USE_PARALLAX_MAPPING) + vec3 viewOrigin2 = normalize(var_tangentMatrix * var_ViewOrigin); + var_S = viewOrigin2.xy * -u_DepthScale / viewOrigin2.z; +#endif // USE_PARALLAX_MAPPING #endif // USE_NORMAL_MAPPING +#if defined(USE_PORTAL_CLIPPING) + // in front, or behind, the portalplane + var_BackSide = dot(var_Position.xyz, u_PortalPlane.xyz) - u_PortalPlane.w; +#endif // USE_PORTAL_CLIPPING + // assign color var_Color = attr_Color * u_ColorModulate + u_Color; } diff --git a/src/renderer2/glsl/liquid_fp.glsl b/src/renderer2/glsl/liquid_fp.glsl index 37554bd84..acbcfd84b 100644 --- a/src/renderer2/glsl/liquid_fp.glsl +++ b/src/renderer2/glsl/liquid_fp.glsl @@ -1,116 +1,64 @@ /* liquid_fp.glsl */ +#if defined(USE_NORMAL_MAPPING) +#include "lib/normalMapping" +#if defined(USE_PARALLAX_MAPPING) +#include "lib/reliefMapping" +#endif // USE_PARALLAX_MAPPING +#endif // USE_NORMAL_MAPPING -uniform mat4 u_UnprojectMatrix; -uniform vec3 u_ViewOrigin; -uniform vec3 u_LightDir; -uniform vec4 u_PortalPlane; -uniform sampler2D u_CurrentMap; +// fog uniform sampler2D u_DepthMap; -uniform float u_FogDensity; +uniform mat4 u_UnprojectMatrix; uniform vec3 u_FogColor; +uniform float u_FogDensity; +uniform float u_NormalScale; +// +uniform sampler2D u_CurrentMap; #if defined(USE_NORMAL_MAPPING) uniform sampler2D u_NormalMap; -uniform float u_NormalScale; -uniform float u_RefractionIndex; +// fresnel +uniform float u_FresnelBias; uniform float u_FresnelPower; uniform float u_FresnelScale; -uniform float u_FresnelBias; -#if defined(USE_PARALLAX_MAPPING) -uniform float u_DepthScale; -#endif // USE_PARALLAX_MAPPING +// refraction +uniform float u_RefractionIndex; +// reflection #if defined(USE_REFLECTIONS) -#if 0 -uniform samplerCube u_PortalMap; -#else // 0 +#if 1 uniform samplerCube u_EnvironmentMap0; uniform samplerCube u_EnvironmentMap1; uniform float u_EnvironmentInterpolation; -#endif // 0 +#else // 1 +uniform samplerCube u_PortalMap; +#endif // 1 #endif // USE_REFLECTIONS #endif // USE_NORMAL_MAPPING varying vec3 var_Position; varying vec4 var_LightColor; +varying vec3 var_ViewOrigin; // position - vieworigin varying vec3 var_Normal; #if defined(USE_NORMAL_MAPPING) -varying vec3 var_Tangent; -varying vec3 var_Binormal; +varying mat3 var_tangentMatrix; varying vec2 var_TexNormal; #if defined(USE_WATER) varying vec2 var_TexNormal2; #endif -#endif // USE_NORMAL_MAPPING - - -// We define a compiler directive if we want the faster transform code. -// If you comment the next line, a matrix is created and used. -#define transformFast - - +varying vec3 var_LightDirection; +varying vec3 var_ViewOrigin2; // vieworigin in worldspace #if defined(USE_PARALLAX_MAPPING) -float RayIntersectDisplaceMap(vec2 dp, vec2 ds) -{ - const int linearSearchSteps = 16; - const int binarySearchSteps = 6; - - float depthStep = 1.0 / float(linearSearchSteps); - - // current size of search window - float size = depthStep; - - // current depth position - float depth = 0.0; - - // best match found (starts with last position 1.0) - float bestDepth = 1.0; - - // search front to back for first point inside object - for (int i = 0; i < linearSearchSteps - 1; ++i) - { - depth += size; - - vec4 t = texture2D(u_NormalMap, dp + ds * depth); - - if (bestDepth > 0.996) // if no depth found yet - { - if (depth >= t.w) - { - bestDepth = depth; // store best depth - } - } - } - - depth = bestDepth; - - // recurse around first point (depth) for closest match - for (int i = 0; i < binarySearchSteps; ++i) - { - size *= 0.5; - - vec4 t = texture2D(u_NormalMap, dp + ds * depth); - - if (depth >= t.w) - #ifdef RM_DOUBLEDEPTH - if (depth <= t.z) - #endif - { - bestDepth = depth; - depth -= 2.0 * size; - } - - depth += size; - } - - return bestDepth; -} -#endif //USE_PARALLAX_MAPPING +varying vec2 var_S; // size and start position of search in texture space +#endif // USE_PARALLAX_MAPPING +#endif // USE_NORMAL_MAPPING +#if defined(USE_PORTAL_CLIPPING) +varying float var_BackSide; // in front, or behind, the portalplane +#endif // USE_PORTAL_CLIPPING void main() { #if defined(USE_PORTAL_CLIPPING) - float dist = dot(var_Position.xyz, u_PortalPlane.xyz) - u_PortalPlane.w; - if (dist < 0.0) + if (var_BackSide < 0.0) { discard; return; @@ -120,175 +68,67 @@ void main() #if defined(USE_NORMAL_MAPPING) - // compute light direction in world space - vec3 L = -normalize(u_LightDir); - - // compute view direction in world space/incident ray - vec3 V = normalize(u_ViewOrigin - var_Position); - - - // compute view direction in tangent space -#if defined(transformFast) // do not use a matrix, but do the necesarry calculations. it should be just a bit faster. - vec3 Vts; -#if defined(TWOSIDED) - if (!gl_FrontFacing) - { - Vts.x = -dot(V, -var_Tangent); - Vts.y = -dot(V, -var_Binormal); - Vts.z = -dot(V, -var_Normal); - } - else -#endif// TWOSIDED - { - Vts.x = dot(V, var_Tangent); - Vts.y = dot(V, var_Binormal); - Vts.z = dot(V, var_Normal); - } -#else // transformFast - // invert tangent space for two sided surfaces which are looked at on the back side of that surface (surfaces which are backfacing). - // Create the usual tangent space matrix in case we're dealing with a front-facing surface, or when the surface is not two-sided (the usual case). - mat3 tangentSpaceMatrix; -#if defined(TWOSIDED) - if (!gl_FrontFacing) - { - tangentSpaceMatrix = mat3(-var_Tangent.xyz, -var_Binormal.xyz, -var_Normal.xyz); - } - else -#endif // end TWOSIDED - { - tangentSpaceMatrix = mat3(var_Tangent.xyz, var_Binormal.xyz, var_Normal.xyz); - } - vec3 Vts = normalize(tangentSpaceMatrix * V); -#endif // transformFast + // light direction in world space + vec3 L = var_LightDirection; + // view direction + vec3 V = var_ViewOrigin.xyz; // tangentspace + vec3 Vw = var_ViewOrigin2.xyz; // worldspace // calculate the screen texcoord in the 0.0 to 1.0 range vec2 texScreen = gl_FragCoord.st * r_FBufScale * r_NPOTScale; - vec2 texNormal = var_TexNormal.st; + vec2 texNormal = var_TexNormal; #if defined(USE_PARALLAX_MAPPING) // ray intersect in view direction - - //mat3 worldToTangentMatrix = transpose(tangentSpaceMatrix); - - // compute view direction in tangent space - //vec3 Vts = normalize(worldToTangentMatrix * V); - - // size and start position of search in texture space - vec2 S = Vts.xy * -u_DepthScale / Vts.z; - - float depth = RayIntersectDisplaceMap(texNormal, S); - + float depth = RayIntersectDisplaceMap(texNormal, var_S, u_NormalMap); // compute texcoords offset - vec2 texOffset = S * depth; + vec2 texOffset = var_S * depth; - texScreen.st += texOffset; - texNormal.st += texOffset; + texScreen += texOffset; + texNormal += texOffset; #endif //USE_PARALLAX_MAPPING - // normal(s) + + // normal vec3 Ntex = texture2D(u_NormalMap, texNormal).xyz * 2.0 - 1.0; // static bumpmap #if defined(USE_WATER) vec3 Ntex2 = texture2D(u_NormalMap, var_TexNormal2).xyz * 2.0 - 1.0; // possibly moving bumpmap - Ntex += Ntex2; + Ntex += Ntex2; // add the waves. interference will cause the final wave's amplitude to vary #endif + // transform normal from tangentspace to worldspace + vec3 N = normalize(var_tangentMatrix * Ntex); // we must normalize to get a vector of unit-length.. reflect() needs it - vec3 N; -#if defined(transformFast) // do not use a matrix, but do the necesarry calculations. it should be just a bit faster. - // transform Ntex to tangent space -#if defined(TWOSIDED) - if (!gl_FrontFacing) - { - N.x = dot(Ntex, -var_Tangent); - N.y = dot(Ntex, -var_Binormal); - N.z = dot(Ntex, -var_Normal); - } - else -#endif // TWOSIDED - { - N.x = dot(Ntex, var_Tangent); - N.y = dot(Ntex, var_Binormal); - N.z = dot(Ntex, var_Normal); - } - // we must normalize N because otherwise we see white artifacts visible in game - N = normalize(N); -#else // transformFast - N = normalize(tangentSpaceMatrix * Ntex); // we must normalize to get a vector of unit-length.. reflect() needs it -#endif // transformFast + + // the final color + vec4 color; // compute fresnel term - // (The fresnel values from cvars produce an opaque water surface.. default values need adjustment) - float dotNV = dot(N, Vts); - float amount; - if (dotNV > 0) - { - amount = max(0.0, dotNV); // amount of reflection (distant water reflects more than water nearby, because angle of incedence is greater) - } - else - { - amount = 1.0; // no reflections when underwater - } - //float fresnel = clamp(u_FresnelBias + pow(1.0 - dot(N, N3), u_FresnelPower) * u_FresnelScale, 0.0, 1.0); - //float fresnel = clamp(u_FresnelBias + pow(1.0 - amount, u_FresnelPower) * u_FresnelScale, 0.0, 1.0); - float fresnel = 1.0 - amount; + // ratio reflection/refraction + float dotNV = max(0.0, dot(N, V)); // float dotNV = dot(var_Normal, V); + float fresnel = clamp(u_FresnelBias + pow(dotNV, u_FresnelPower) * u_FresnelScale, 0.0, 1.0); // refraction - texScreen += u_NormalScale * N.xy; + vec3 T = refract(V, N, u_RefractionIndex); + texScreen += (N.xy - T.xy) * u_NormalScale; vec3 refractColor = texture2D(u_CurrentMap, texScreen).rgb; -#if defined(USE_REFLECTIONS) // reflection - vec3 R = reflect(V, N); -#if 0 +#if defined(USE_REFLECTIONS) +#if 1 + // use the cubeProbes + vec3 reflectColor = computeReflections(V, N, u_EnvironmentMap0, u_EnvironmentMap1, u_EnvironmentInterpolation); +#else // 1 + // use a portalmap vec3 reflectColor = textureCube(u_PortalMap, R).rgb; -#else // 0 - vec4 envColor0 = textureCube(u_EnvironmentMap0, R).rgba; - vec4 envColor1 = textureCube(u_EnvironmentMap1, R).rgba; - vec3 reflectColor = mix(envColor0, envColor1, u_EnvironmentInterpolation).rgb; -#endif // 0 +#endif // 1 + color.rgb = mix(refractColor, reflectColor, fresnel); #else // USE_REFLECTIONS - vec3 reflectColor = vec3(0.0); + // reflections disabled + color.rgb = refractColor; #endif // USE_REFLECTIONS - vec4 color; - color.rgb = mix(refractColor, reflectColor, fresnel); - color.a = 1.0; - - if (u_FogDensity > 0.0) - { - // reconstruct vertex position in world space - float depth = texture2D(u_DepthMap, texScreen).r; - vec4 P = u_UnprojectMatrix * vec4(gl_FragCoord.xy, depth, 1.0); - P.xyz /= P.w; - - // calculate fog distance - float fogDistance = distance(P.xyz, var_Position); - - // calculate fog exponent - float fogExponent = fogDistance * u_FogDensity; - - // calculate fog factor - float fogFactor = exp2(-abs(fogExponent)); - - color.rgb = mix(u_FogColor, color.rgb, fogFactor); - } - -#if defined(USE_SPECULAR) - // compute the specular term - vec3 specular = vec3(0.0); - if (dot(-N, L) > 0.0) - { - vec3 R = reflect(L, -N); - float reflectance = pow(max(0.0, dot(R, V)), 64.0); // ,r_SpecularExponent) // * r_SpecularScale; - specular = vec3(reflectance); - } - color.rgb += specular; -#endif // USE_SPECULAR - - // compute the light term - color.rgb *= var_LightColor.rgb; // * max(dot(-N2, L), 0.0); - - gl_FragColor = color; + color.a = 1.0; // do not blend (it would blend the currentMap with the water-surface, and you'd see things double) #else // USE_NORMAL_MAPPING @@ -301,12 +141,14 @@ void main() color.rgb = texture2D(u_CurrentMap, texScreen).rgb; color.a = 1.0; +#endif // USE_NORMAL_MAPPING + if (u_FogDensity > 0.0) { // reconstruct vertex position in world space float depth = texture2D(u_DepthMap, texScreen).r; - vec4 P = u_UnprojectMatrix * vec4(gl_FragCoord.xy, depth, 1.0); + vec4 P = u_UnprojectMatrix * vec4(gl_FragCoord.xy, depth, 1.0); P.xyz /= P.w; // calculate fog distance @@ -321,10 +163,13 @@ void main() color.rgb = mix(u_FogColor, color.rgb, fogFactor); } +#if defined(USE_SPECULAR) + // compute the specular term + color.rgb += computeSpecular(V, N, L, vec3(1.0), 512.0); +#endif // USE_SPECULAR + // compute the light term - color.rgb *= var_LightColor.rgb; // * max(dot(-N2, L), 0.0); + color.rgb *= var_LightColor.rgb; gl_FragColor = color; - -#endif // USE_NORMAL_MAPPING } diff --git a/src/renderer2/glsl/liquid_vp.glsl b/src/renderer2/glsl/liquid_vp.glsl index 9c3f9ff06..d5145e1fd 100644 --- a/src/renderer2/glsl/liquid_vp.glsl +++ b/src/renderer2/glsl/liquid_vp.glsl @@ -11,21 +11,38 @@ attribute vec4 attr_TexCoord0; uniform mat4 u_ModelMatrix; uniform mat4 u_ModelViewProjectionMatrix; -uniform vec3 u_LightDir; uniform mat4 u_NormalTextureMatrix; +uniform vec3 u_ViewOrigin; +#if defined(USE_NORMAL_MAPPING) +uniform vec3 u_LightDir; +#if defined(USE_PARALLAX_MAPPING) +uniform float u_DepthScale; +#endif // USE_PARALLAX_MAPPING +#endif // USE_NORMAL_MAPPING +#if defined(USE_PORTAL_CLIPPING) +uniform vec4 u_PortalPlane; +#endif // USE_PORTAL_CLIPPING varying vec4 var_LightColor; -varying vec3 var_LightDirection; varying vec3 var_Position; +varying vec3 var_ViewOrigin; // position - vieworigin varying vec3 var_Normal; #if defined(USE_NORMAL_MAPPING) -varying vec3 var_Tangent; -varying vec3 var_Binormal; +varying mat3 var_tangentMatrix; varying vec2 var_TexNormal; // these coords are never moving #if defined(USE_WATER) varying vec2 var_TexNormal2; // these coords might be moving (tcMod) #endif // USE_WATER +varying vec3 var_LightDirection; +varying vec3 var_ViewOrigin2; // vieworigin in worldspace +#if defined(USE_PARALLAX_MAPPING) +varying vec2 var_S; // size and start position of search in texture space +#endif // USE_PARALLAX_MAPPING #endif // USE_NORMAL_MAPPING +#if defined(USE_PORTAL_CLIPPING) +varying float var_BackSide; // in front, or behind, the portalplane +#endif // USE_PORTAL_CLIPPING + void main() { @@ -35,20 +52,36 @@ void main() // transform position into world space var_Position = (u_ModelMatrix * attr_Position).xyz; + // the vieworigin + var_ViewOrigin = normalize(var_Position - u_ViewOrigin); + + // transform normal into world space + var_Normal = (u_ModelMatrix * vec4(attr_Normal, 0.0)).xyz; + #if defined(USE_NORMAL_MAPPING) + vec3 tangent = (u_ModelMatrix * vec4(attr_Tangent, 0.0)).xyz; + vec3 binormal = (u_ModelMatrix * vec4(attr_Binormal, 0.0)).xyz; + + // in a vertex-shader there exists no gl_FrontFacing + var_tangentMatrix = mat3(-tangent, -binormal, -var_Normal.xyz); + // transform normalmap texcoords var_TexNormal.xy = attr_TexCoord0.st; #if defined(USE_WATER) var_TexNormal2.xy = (u_NormalTextureMatrix * attr_TexCoord0).st; #endif // USE_WATER - var_Tangent.xyz = (u_ModelMatrix * vec4(attr_Tangent, 0.0)).xyz; - var_Binormal.xyz = (u_ModelMatrix * vec4(attr_Binormal, 0.0)).xyz; + var_LightColor = attr_Color; + var_LightDirection = -normalize(u_LightDir); + // the view origin in worldspace + var_ViewOrigin2 = normalize(var_tangentMatrix * var_ViewOrigin); +#if defined(USE_PARALLAX_MAPPING) + var_S = var_ViewOrigin2.xy * -u_DepthScale / var_ViewOrigin2.z; +#endif // USE_PARALLAX_MAPPING #endif // USE_NORMAL_MAPPING - // transform normal into world space - var_Normal = (u_ModelMatrix * vec4(attr_Normal, 0.0)).xyz; - - var_LightColor = attr_Color; - var_LightDirection = u_LightDir; +#if defined(USE_PORTAL_CLIPPING) + // in front, or behind, the portalplane + var_BackSide = dot(var_Position.xyz, u_PortalPlane.xyz) - u_PortalPlane.w; +#endif // USE_PORTAL_CLIPPING } diff --git a/src/renderer2/glsl/reflection_CB_fp.glsl b/src/renderer2/glsl/reflection_CB_fp.glsl index 92a79d83c..9af490576 100644 --- a/src/renderer2/glsl/reflection_CB_fp.glsl +++ b/src/renderer2/glsl/reflection_CB_fp.glsl @@ -1,82 +1,72 @@ /* reflection_CB_fp.glsl */ +#include "lib/normalMapping" #if 1 uniform samplerCube u_EnvironmentMap0; uniform samplerCube u_EnvironmentMap1; uniform float u_EnvironmentInterpolation; -#else +#else // 1 uniform samplerCube u_ColorMap; -#endif -uniform sampler2D u_NormalMap; -uniform vec3 u_ViewOrigin; +#endif // 1 uniform mat4 u_ModelMatrix; -uniform vec4 u_PortalPlane; +#if defined(USE_NORMAL_MAPPING) +uniform sampler2D u_NormalMap; +#endif // USE_NORMAL_MAPPING varying vec3 var_Position; -varying vec2 var_TexNormal; +varying vec3 var_ViewOrigin; // position - vieworigin +varying vec4 var_Normal; +#if defined(USE_NORMAL_MAPPING) varying vec4 var_Tangent; varying vec4 var_Binormal; -varying vec4 var_Normal; +varying vec2 var_TexNormal; +#endif // USE_NORMAL_MAPPING +#if defined(USE_PORTAL_CLIPPING) +varying float var_BackSide; // in front, or behind, the portalplane +#endif // USE_PORTAL_CLIPPING + void main() { #if defined(USE_PORTAL_CLIPPING) + if (var_BackSide < 0.0) { - float dist = dot(var_Position.xyz, u_PortalPlane.xyz) - u_PortalPlane.w; - if (dist < 0.0) - { - discard; - return; - } + discard; + return; } -#endif +#endif // USE_PORTAL_CLIPPING - // compute incident ray in world space - //vec3 V = normalize(var_Position - u_ViewOrigin); - vec3 V = normalize(u_ViewOrigin - var_Position); + // compute incident ray + vec3 V = var_ViewOrigin.xyz; #if defined(USE_NORMAL_MAPPING) - // compute normal in tangent space from normalmap - vec3 N = normalize(texture2D(u_NormalMap, var_TexNormal.st).xyz * 2.0 - 1.0); - -#if defined(r_NormalScale) - if (r_NormalScale != 1.0) N.z *= r_NormalScale; -#endif - - // invert tangent space for twosided surfaces - mat3 tangentToWorldMatrix; -#if defined(TWOSIDED) - if (!gl_FrontFacing) - { - tangentToWorldMatrix = mat3(-var_Tangent.xyz, -var_Binormal.xyz, -var_Normal.xyz); - } - else -#endif - tangentToWorldMatrix = mat3(var_Tangent.xyz, var_Binormal.xyz, var_Normal.xyz); - - // transform normal into world space - N = normalize(tangentToWorldMatrix * N); - -#else - + // Create the matrix that will transform coordinates to worldspace. + mat3 tangentSpaceMatrix = tangentToWorldMatrix(var_Tangent.xyz, var_Binormal.xyz, var_Normal.xyz); + // compute normal + vec3 N = computeNormal(texture2D(u_NormalMap, var_TexNormal.st).xyz, tangentSpaceMatrix); +#else // USE_NORMAL_MAPPING vec3 N = normalize(var_Normal.xyz); -#endif +#endif // USE_NORMAL_MAPPING // compute reflection ray vec3 R = reflect(V, N); - R.z = -R.z; - + R.x = -R.x; //todo:check + R.y = -R.y; + //R.z = -R.z; // flip vertically #if 1 // This is the cubeProbes way of rendering reflections. vec4 envColor0 = textureCube(u_EnvironmentMap0, R).rgba; vec4 envColor1 = textureCube(u_EnvironmentMap1, R).rgba; gl_FragColor = mix(envColor0, envColor1, u_EnvironmentInterpolation).rgba; -#else +#else // 1 gl_FragColor = textureCube(u_ColorMap, R).rgba; -#endif - // gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); +#endif // 1 + +//#if 0 +// gl_FragColor = computeReflections(V, N, u_EnvironmentMap0, u_EnvironmentMap1, u_EnvironmentInterpolation); // this returns only .rgb (no alpha) +//#endif // 0 } diff --git a/src/renderer2/glsl/reflection_CB_vp.glsl b/src/renderer2/glsl/reflection_CB_vp.glsl index 3e3372184..8e1717dab 100644 --- a/src/renderer2/glsl/reflection_CB_vp.glsl +++ b/src/renderer2/glsl/reflection_CB_vp.glsl @@ -1,38 +1,65 @@ /* reflection_CB_vp.glsl */ +#if defined(USE_VERTEX_SKINNING) #include "lib/vertexSkinning" +#endif USE_VERTEX_SKINNING +#if defined(USE_VERTEX_ANIMATION) #include "lib/vertexAnimation" +#endif // USE_DEFORM_VERTEXES +#if defined(USE_DEFORM_VERTEXES) #include "lib/deformVertexes" +#endif // USE_DEFORM_VERTEXES -attribute vec4 attr_Position; attribute vec4 attr_TexCoord0; +attribute vec4 attr_Position; +attribute vec3 attr_Normal; +#if defined(USE_NORMAL_MAPPING) attribute vec3 attr_Tangent; attribute vec3 attr_Binormal; -attribute vec3 attr_Normal; +#endif // USE_NORMAL_MAPPING +#if defined(USE_VERTEX_ANIMATION) attribute vec4 attr_Position2; +attribute vec3 attr_Normal2; +#if defined(USE_NORMAL_MAPPING) attribute vec3 attr_Tangent2; attribute vec3 attr_Binormal2; -attribute vec3 attr_Normal2; +#endif // USE_NORMAL_MAPPING uniform float u_VertexInterpolation; +#endif // USE_VERTEX_ANIMATION uniform mat4 u_NormalTextureMatrix; uniform mat4 u_ModelMatrix; uniform mat4 u_ModelViewProjectionMatrix; - +uniform vec3 u_ViewOrigin; +#if defined(USE_DEFORM_VERTEXES) uniform float u_Time; +#endif // USE_DEFORM_VERTEXES +#if defined(USE_PORTAL_CLIPPING) +uniform vec4 u_PortalPlane; +#endif // USE_PORTAL_CLIPPING varying vec3 var_Position; -varying vec2 var_TexNormal; +varying vec3 var_ViewOrigin; // position - vieworigin +varying vec4 var_Normal; +#if defined(USE_NORMAL_MAPPING) varying vec4 var_Tangent; varying vec4 var_Binormal; -varying vec4 var_Normal; +varying vec2 var_TexNormal; +#endif // USE_NORMAL_MAPPING +#if defined(USE_PORTAL_CLIPPING) +varying float var_BackSide; // in front, or behind, the portalplane +#endif // USE_PORTAL_CLIPPING + void main() { vec4 position; + vec3 normal; +#if defined(USE_NORMAL_MAPPING) vec3 tangent; vec3 binormal; - vec3 normal; +#endif // USE_NORMAL_MAPPING + #if defined(USE_VERTEX_SKINNING) @@ -42,7 +69,8 @@ void main() #else VertexSkinning_P_N(attr_Position, attr_Normal, position, normal); -#endif +#endif // USE_NORMAL_MAPPING + #elif defined(USE_VERTEX_ANIMATION) @@ -58,36 +86,46 @@ void main() attr_Normal, attr_Normal2, u_VertexInterpolation, position, normal); -#endif +#endif // USE_NORMAL_MAPPING -#else - position = attr_Position; +#else // USE_VERTEX_SKINNING,USE_VERTEX_ANIMATION + position = attr_Position; #if defined(USE_NORMAL_MAPPING) tangent = attr_Tangent; binormal = attr_Binormal; -#endif - +#endif // USE_NORMAL_MAPPING normal = attr_Normal; -#endif + +#endif // USE_VERTEX_SKINNING,USE_VERTEX_ANIMATION + #if defined(USE_DEFORM_VERTEXES) position = DeformPosition2(position, normal, attr_TexCoord0.st, u_Time); #endif + // transform vertex position into homogenous clip-space gl_Position = u_ModelViewProjectionMatrix * position; // transform position into world space var_Position = (u_ModelMatrix * position).xyz; + // the vieworigin + var_ViewOrigin = normalize(var_Position - u_ViewOrigin); + #if defined(USE_NORMAL_MAPPING) // transform normalmap texcoords var_TexNormal = (u_NormalTextureMatrix * attr_TexCoord0).st; var_Tangent.xyz = (u_ModelMatrix * vec4(tangent, 0.0)).xyz; var_Binormal.xyz = (u_ModelMatrix * vec4(binormal, 0.0)).xyz; -#endif +#endif // USE_NORMAL_MAPPING var_Normal.xyz = (u_ModelMatrix * vec4(normal, 0.0)).xyz; + +#if defined(USE_PORTAL_CLIPPING) + // in front, or behind, the portalplane + var_BackSide = dot(var_Position.xyz, u_PortalPlane.xyz) - u_PortalPlane.w; +#endif // USE_PORTAL_CLIPPING } diff --git a/src/renderer2/glsl/reflection_C_fp.glsl b/src/renderer2/glsl/reflection_C_fp.glsl index 9be295f18..9f6a5b806 100644 --- a/src/renderer2/glsl/reflection_C_fp.glsl +++ b/src/renderer2/glsl/reflection_C_fp.glsl @@ -1,37 +1,39 @@ /* reflection_C_fp.glsl */ #if 1 +uniform samplerCube u_ColorMap; +#else uniform samplerCube u_EnvironmentMap0; uniform samplerCube u_EnvironmentMap1; uniform float u_EnvironmentInterpolation; -#else -uniform samplerCube u_ColorMap; #endif -uniform vec3 u_ViewOrigin; varying vec3 var_Position; varying vec3 var_Normal; +varying vec3 var_ViewOrigin; // position - vieworigin void main() { // compute incident ray - //vec3 I = normalize(var_Position - u_ViewOrigin); - vec3 I = normalize(u_ViewOrigin - var_Position); + //vec3 V = normalize(var_Position - u_ViewOrigin); + //vec3 V = normalize(u_ViewOrigin - var_Position); + vec3 V = var_ViewOrigin.xyz; // compute normal vec3 N = normalize(var_Normal); // compute reflection ray - vec3 R = reflect(I, N); + vec3 R = reflect(V, N); R.z = -R.z; // compute reflection color #if 1 + // only 1 colormap is used (tcGen environment) + gl_FragColor = textureCube(u_ColorMap, R).rgba; +#else // This is the cubeProbes way of rendering reflections. vec4 envColor0 = textureCube(u_EnvironmentMap0, R).rgba; vec4 envColor1 = textureCube(u_EnvironmentMap1, R).rgba; gl_FragColor = mix(envColor0, envColor1, u_EnvironmentInterpolation).rgba; -#else - gl_FragColor = textureCube(u_ColorMap, R).rgba; #endif } diff --git a/src/renderer2/glsl/reflection_C_vp.glsl b/src/renderer2/glsl/reflection_C_vp.glsl index ffa9d84e6..ebe943af9 100644 --- a/src/renderer2/glsl/reflection_C_vp.glsl +++ b/src/renderer2/glsl/reflection_C_vp.glsl @@ -3,18 +3,20 @@ attribute vec4 attr_Position; attribute vec3 attr_Normal; -#if defined(r_VertexSkinning) // FIXME/REMOVE +#if defined(r_VertexSkinning) attribute vec4 attr_BoneIndexes; attribute vec4 attr_BoneWeights; + uniform int u_VertexSkinning; uniform mat4 u_BoneMatrix[MAX_GLSL_BONES]; #endif - uniform mat4 u_ModelMatrix; uniform mat4 u_ModelViewProjectionMatrix; +uniform vec3 u_ViewOrigin; varying vec3 var_Position; varying vec3 var_Normal; +varying vec3 var_ViewOrigin; // position - vieworigin void main() { @@ -55,4 +57,7 @@ void main() // transform normal into world space var_Normal = (u_ModelMatrix * vec4(attr_Normal, 0.0)).xyz; } + + // the vieworigin + var_ViewOrigin = normalize(var_Position - u_ViewOrigin); } diff --git a/src/renderer2/glsl/vertexLighting_DBS_entity_fp.glsl b/src/renderer2/glsl/vertexLighting_DBS_entity_fp.glsl index d07646980..147bb61b1 100644 --- a/src/renderer2/glsl/vertexLighting_DBS_entity_fp.glsl +++ b/src/renderer2/glsl/vertexLighting_DBS_entity_fp.glsl @@ -1,16 +1,16 @@ /* vertexLighting_DBS_entity_fp.glsl */ -#include "lib/reliefMapping" +#if defined(USE_NORMAL_MAPPING) #include "lib/normalMapping" +#if defined(USE_PARALLAX_MAPPING) +#include "lib/reliefMapping" +#endif // USE_PARALLAX_MAPPING +#endif // USE_NORMAL_MAPPING uniform sampler2D u_DiffuseMap; -uniform vec4 u_PortalPlane; uniform int u_AlphaTest; -uniform vec3 u_ViewOrigin; -uniform vec3 u_LightDir; uniform vec3 u_LightColor; uniform float u_LightWrapAround; uniform vec3 u_AmbientColor; -uniform float u_DepthScale; #if defined(USE_NORMAL_MAPPING) uniform sampler2D u_NormalMap; #if defined(USE_REFLECTIONS) || defined(USE_SPECULAR) @@ -25,31 +25,36 @@ uniform float u_EnvironmentInterpolation; varying vec3 var_Position; varying vec2 var_TexDiffuse; -varying vec4 var_LightColor; varying vec3 var_Normal; #if defined(USE_NORMAL_MAPPING) +varying mat3 var_tangentMatrix; varying vec2 var_TexNormal; -varying vec3 var_Tangent; -varying vec3 var_Binormal; #if defined(USE_REFLECTIONS) || defined(USE_SPECULAR) varying vec2 var_TexSpecular; #endif // USE_REFLECTIONS || USE_SPECULAR +varying vec3 var_LightDirection; +varying vec3 var_ViewOrigin; // position - vieworigin +#if defined(USE_PARALLAX_MAPPING) +varying vec2 var_S; // size and start position of search in texture space +#endif // USE_PARALLAX_MAPPING #endif // USE_NORMAL_MAPPING +#if defined(USE_PORTAL_CLIPPING) +varying float var_BackSide; // in front, or behind, the portalplane +#endif // USE_PORTAL_CLIPPING void main() { #if defined(USE_PORTAL_CLIPPING) + if (var_BackSide < 0.0) { - float dist = dot(var_Position.xyz, u_PortalPlane.xyz) - u_PortalPlane.w; - if (dist < 0.0) - { - discard; - return; - } + discard; + return; } #endif // end USE_PORTAL_CLIPPING + + // compute the diffuse term vec2 texDiffuse = var_TexDiffuse.st; // diffuse texture coordinates st vec4 diffuse = texture2D(u_DiffuseMap, texDiffuse); // the color at coords(st) of the diffuse texture @@ -83,75 +88,64 @@ void main() vec2 texSpecular = var_TexSpecular.st; // the current texture coordinates st for the specularmap #endif // USE_REFLECTIONS || USE_SPECULAR - // compute view direction in world space - //vec3 V = normalize(u_ViewOrigin - var_Position); - vec3 V = normalize(var_Position - u_ViewOrigin); - - // compute light direction in world space - // invert the direction, so we end up with a vector that is pointing away from the surface. - // We must also normalize the vector, because the reflect() function needs it. - vec3 L = -normalize(u_LightDir); - - // Create the matrix that will transform coordinates to worldspace. - mat3 tangentSpaceMatrix = tangetToWorldMatrix(var_Tangent.xyz, var_Binormal.xyz, var_Normal.xyz); - #if defined(USE_PARALLAX_MAPPING) -//!!!DEBUG!!! check this parallax stuff <-- todo // ray intersect in view direction - - // compute view direction in tangent space - vec3 Vts = normalize(tangentSpaceMatrix * V); - - - // size and start position of search in texture space - vec2 S = Vts.xy * -u_DepthScale / Vts.z; - - float depth = RayIntersectDisplaceMap(texNormal, S, u_NormalMap); - + float depth = RayIntersectDisplaceMap(texNormal, var_S, u_NormalMap); // compute texcoords offset - vec2 texOffset = S * depth; - - texDiffuse.st += texOffset; - texNormal.st += texOffset; + vec2 texOffset = var_S * depth; + texDiffuse += texOffset; + texNormal += texOffset; #if defined(USE_REFLECTIONS) || defined(USE_SPECULAR) - texSpecular.st += texOffset; + texSpecular += texOffset; #endif // USE_REFLECTIONS || USE_SPECULAR #endif // end USE_PARALLAX_MAPPING + // view direction + vec3 V = var_ViewOrigin; - // compute normal (from normalmap texture) - // N is the normal (at every .st of the normalmap texture) - // We convert normalmap texture values from range[0.0,1.0] to range[-1.0,1.0] - // and then tranform N into worldspace. - // compute normal (from tangentspace, to worldspace) - vec3 N = computeNormal(texture2D(u_NormalMap, texNormal).xyz, tangentSpaceMatrix); + // light direction + vec3 L = var_LightDirection; + + // normal + vec3 Ntex = texture2D(u_NormalMap, texNormal).xyz * 2.0 - 1.0; + // transform normal from tangentspace to worldspace + vec3 N = normalize(var_tangentMatrix * Ntex); // we must normalize to get a vector of unit-length.. reflect() needs it // the cosine of the angle N L float dotNL = dot(N, L); -#if defined(USE_REFLECTIONS) || defined(USE_SPECULAR) // compute the specular term (and reflections) - vec3 reflections = vec3(0.0); - vec3 specular = vec3(0.0); -#if defined(USE_REFLECTIONS) - // reflections - reflections = computeReflections(V, N, u_EnvironmentMap0, u_EnvironmentMap1, u_EnvironmentInterpolation); -#endif // end USE_REFLECTIONS -#if defined(USE_SPECULAR) - // the specular highlights - specular = computeSpecular(V, N, L, 64.0); //r_SpecularExponent -#endif // USE_SPECULAR - specular += reflections; - specular *= texture2D(u_SpecularMap, texSpecular).rgb; // shininess factor -#endif // USE_REFLECTIONS || USE_SPECULAR - - + //! https://en.wikipedia.org/wiki/Specular_highlight + //! "The number n is called the Phong exponent, and is a user-chosen value that controls the apparent smoothness of the surface" +#if defined(USE_SPECULAR) && !defined(USE_REFLECTIONS) + vec4 map = texture2D(u_SpecularMap, texSpecular); + vec3 shininess = map.rgb; + // alpha values in range 0 to 1.0. exponent range is 0 to 256 (or whatever maximum value you want. ..perhaps r_SpecularExponent?). + float exponent = map.a * r_SpecularExponent; + vec3 specular = computeSpecular2(dotNL, V, N, L, u_LightColor, exponent) + * shininess; +#elif defined(USE_SPECULAR) && defined(USE_REFLECTIONS) + vec4 map = texture2D(u_SpecularMap, texSpecular); + vec3 shininess = map.rgb; + float exponent = map.a * r_SpecularExponent; + vec3 specular = (computeReflections(V, N, u_EnvironmentMap0, u_EnvironmentMap1, u_EnvironmentInterpolation) + + computeSpecular2(dotNL, V, N, L, u_LightColor, exponent)) + * shininess; +#elif !defined(USE_SPECULAR) && defined(USE_REFLECTIONS) + vec4 map = texture2D(u_SpecularMap, texSpecular); + vec3 shininess = map.rgb; + vec3 specular = computeReflections(V, N, u_EnvironmentMap0, u_EnvironmentMap1, u_EnvironmentInterpolation) + * shininess; +#endif + + +#if defined(r_diffuseLighting) // compute the diffuse light term - // https://en.wikipedia.org/wiki/Lambert%27s_cosine_law - diffuse.rgb *= computeDiffuseLighting(N, L); + diffuse.rgb *= computeDiffuseLighting2(dotNL); +#endif // r_diffuseLighting // add Rim Lighting to highlight the edges @@ -164,7 +158,7 @@ void main() // compute final color - vec4 color = vec4(diffuse.rgb, var_LightColor.a); + vec4 color = vec4(diffuse.rgb, 1.0); #if defined(USE_REFLECTIONS) || defined(USE_SPECULAR) color.rgb += specular; #endif // end USE_REFLECTIONS || USE_SPECULAR @@ -178,7 +172,7 @@ void main() #endif // end USE_NORMAL_MAPPING - //color.rgb *= (var_LightColor.rgb + u_AmbientColor); // i really think mapper's ambient values are too high.. - color.rgb *= (var_LightColor.rgb); + //color.rgb *= (u_LightColor + u_AmbientColor); // i really think mapper's ambient values are too high..use this if you want "glowing" entities :P + color.rgb *= u_LightColor; gl_FragColor = color; } diff --git a/src/renderer2/glsl/vertexLighting_DBS_entity_vp.glsl b/src/renderer2/glsl/vertexLighting_DBS_entity_vp.glsl index d18f9429e..b2fc85050 100644 --- a/src/renderer2/glsl/vertexLighting_DBS_entity_vp.glsl +++ b/src/renderer2/glsl/vertexLighting_DBS_entity_vp.glsl @@ -23,31 +23,43 @@ uniform mat4 u_ModelMatrix; uniform mat4 u_ModelViewProjectionMatrix; uniform mat4 u_DiffuseTextureMatrix; uniform vec3 u_LightColor; -#if defined(USE_DEFORM_VERTEXES) -uniform float u_Time; -#endif // USE_DEFORM_VERTEXES -#if defined(USE_VERTEX_ANIMATION) -uniform float u_VertexInterpolation; -#endif // USE_VERTEX_ANIMATION +uniform vec3 u_LightDir; +uniform vec3 u_ViewOrigin; +uniform float u_DepthScale; #if defined(USE_NORMAL_MAPPING) uniform mat4 u_NormalTextureMatrix; #if defined(USE_REFLECTIONS) || defined(USE_SPECULAR) uniform mat4 u_SpecularTextureMatrix; #endif // USE_REFLECTIONS || USE_SPECULAR #endif // USE_NORMAL_MAPPING +#if defined(USE_PORTAL_CLIPPING) +uniform vec4 u_PortalPlane; +#endif // USE_PORTAL_CLIPPING +#if defined(USE_DEFORM_VERTEXES) +uniform float u_Time; +#endif // USE_DEFORM_VERTEXES +#if defined(USE_VERTEX_ANIMATION) +uniform float u_VertexInterpolation; +#endif // USE_VERTEX_ANIMATION varying vec3 var_Position; varying vec2 var_TexDiffuse; -varying vec4 var_LightColor; varying vec3 var_Normal; #if defined(USE_NORMAL_MAPPING) -varying vec3 var_Tangent; -varying vec3 var_Binormal; +varying mat3 var_tangentMatrix; varying vec2 var_TexNormal; #if defined(USE_REFLECTIONS) || defined(USE_SPECULAR) varying vec2 var_TexSpecular; #endif // USE_REFLECTIONS || USE_SPECULAR +varying vec3 var_LightDirection; +varying vec3 var_ViewOrigin; // position - vieworigin +#if defined(USE_PARALLAX_MAPPING) +varying vec2 var_S; // size and start position of search in texture space +#endif // USE_PARALLAX_MAPPING #endif // USE_NORMAL_MAPPING +#if defined(USE_PORTAL_CLIPPING) +varying float var_BackSide; // in front, or behind, the portalplane +#endif // USE_PORTAL_CLIPPING void main() @@ -87,13 +99,12 @@ void main() #endif // USE_NORMAL_MAPPING #else // USE_VERTEX_ANIMATION - position = attr_Position; + position = attr_Position; #if defined(USE_NORMAL_MAPPING) tangent = attr_Tangent; binormal = attr_Binormal; #endif // USE_NORMAL_MAPPING - normal = attr_Normal; #endif // USE_VERTEX_ANIMATION, USE_VERTEX_SKINNING @@ -116,8 +127,11 @@ void main() // transform tangentspace axis var_Normal.xyz = (u_ModelMatrix * vec4(normal, 0.0)).xyz; #if defined(USE_NORMAL_MAPPING) - var_Tangent.xyz = (u_ModelMatrix * vec4(tangent, 0.0)).xyz; - var_Binormal.xyz = (u_ModelMatrix * vec4(binormal, 0.0)).xyz; + tangent = (u_ModelMatrix * vec4(tangent, 0.0)).xyz; + binormal = (u_ModelMatrix * vec4(binormal, 0.0)).xyz; + + // in a vertex-shader there exists no gl_FrontFacing + var_tangentMatrix = mat3(-tangent, -binormal, -var_Normal.xyz); // transform normalmap texcoords var_TexNormal = (u_NormalTextureMatrix * attr_TexCoord0).st; @@ -126,8 +140,20 @@ void main() // transform specularmap texture coords var_TexSpecular = (u_SpecularTextureMatrix * attr_TexCoord0).st; #endif // USE_REFLECTIONS || USE_SPECULAR + + var_LightDirection = -normalize(u_LightDir); + + var_ViewOrigin = normalize(var_Position - u_ViewOrigin); + +#if defined(USE_PARALLAX_MAPPING) + // transform the vieworigin from tangentspace to worldspace + vec3 viewOrigin2 = normalize(var_tangentMatrix * var_ViewOrigin); + var_S = viewOrigin2.xy * -u_DepthScale / viewOrigin2.z; +#endif // USE_PARALLAX_MAPPING #endif // USE_NORMAL_MAPPING - // assign color - var_LightColor = vec4(u_LightColor, 1.0); +#if defined(USE_PORTAL_CLIPPING) + // in front, or behind, the portalplane + var_BackSide = dot(var_Position.xyz, u_PortalPlane.xyz) - u_PortalPlane.w; +#endif // USE_PORTAL_CLIPPING } diff --git a/src/renderer2/glsl/vertexLighting_DBS_world_fp.glsl b/src/renderer2/glsl/vertexLighting_DBS_world_fp.glsl index 01241eb48..c1875bd7d 100644 --- a/src/renderer2/glsl/vertexLighting_DBS_world_fp.glsl +++ b/src/renderer2/glsl/vertexLighting_DBS_world_fp.glsl @@ -1,14 +1,14 @@ /* vertexLighting_DBS_world_fp.glsl */ -#include "lib/reliefMapping" +#if defined(USE_NORMAL_MAPPING) #include "lib/normalMapping" +#if defined(USE_PARALLAX_MAPPING) +#include "lib/reliefMapping" +#endif // USE_PARALLAX_MAPPING +#endif // USE_NORMAL_MAPPING uniform sampler2D u_DiffuseMap; uniform int u_AlphaTest; -uniform vec3 u_ViewOrigin; -uniform float u_DepthScale; -uniform vec4 u_PortalPlane; uniform float u_LightWrapAround; -uniform vec3 u_LightDir; uniform vec3 u_LightColor; #if defined(USE_NORMAL_MAPPING) uniform sampler2D u_NormalMap; @@ -27,20 +27,25 @@ varying vec4 var_TexDiffuseNormal; varying vec4 var_LightColor; varying vec3 var_Normal; #if defined(USE_NORMAL_MAPPING) -varying vec3 var_Tangent; -varying vec3 var_Binormal; +varying mat3 var_tangentMatrix; #if defined(USE_REFLECTIONS) || defined(USE_SPECULAR) varying vec2 var_TexSpecular; #endif // USE_REFLECTIONS || USE_SPECULAR +varying vec3 var_LightDirection; +varying vec3 var_ViewOrigin; // position - vieworigin +#if defined(USE_PARALLAX_MAPPING) +varying vec2 var_S; // size and start position of search in texture space +#endif // USE_PARALLAX_MAPPING #endif // USE_NORMAL_MAPPING - +#if defined(USE_PORTAL_CLIPPING) +varying float var_BackSide; // in front, or behind, the portalplane +#endif // USE_PORTAL_CLIPPING void main() { #if defined(USE_PORTAL_CLIPPING) - float dist = dot(var_Position.xyz, u_PortalPlane.xyz) - u_PortalPlane.w; - if (dist < 0.0) + if (var_BackSide < 0.0) { discard; return; @@ -48,7 +53,6 @@ void main() #endif - #if defined(USE_NORMAL_MAPPING) // texture coordinates @@ -59,49 +63,32 @@ void main() #endif // USE_REFLECTIONS || USE_SPECULAR - // compute view direction in world space - vec3 V = normalize(var_Position - u_ViewOrigin); - - // construct the matrix that transforms from tangentspace to worldspace - mat3 tangentSpaceMatrix = tangetToWorldMatrix(var_Tangent.xyz, var_Binormal.xyz, var_Normal.xyz); - - #if defined(USE_PARALLAX_MAPPING) // ray intersect in view direction - - // compute view direction (from tangentspace, to worldspace) - vec3 Vts = normalize(tangentSpaceMatrix * V); - - // size and start position of search in texture space - vec2 S = Vts.xy * -u_DepthScale / Vts.z; -#if 0 +#if 1 + float depth = RayIntersectDisplaceMap(texNormal, var_S, u_NormalMap); + // compute texcoords offset + vec2 texOffset = var_S * depth; +#else // 1 vec2 texOffset = vec2(0.0); for (int i = 0; i < 4; i++) { - vec4 Normal = texture2D(u_NormalMap, texNormal.st + texOffset); + vec4 Normal = texture2D(u_NormalMap, texNormal + texOffset); float height = Normal.a * 0.2 - 0.0125; - texOffset += height * Normal.z * S; + texOffset += height * Normal.z * var_S; } -#else // 0 - float depth = RayIntersectDisplaceMap(texNormal, S, u_NormalMap); - // compute texcoords offset - vec2 texOffset = S * depth; -#endif // 0 - - texDiffuse.st += texOffset; - texNormal.st += texOffset; +#endif // 1 + texDiffuse += texOffset; + texNormal += texOffset; #if defined(USE_REFLECTIONS) || defined(USE_SPECULAR) - texSpecular.st += texOffset; + texSpecular += texOffset; #endif // USE_REFLECTIONS || USE_SPECULAR #endif // USE_PARALLAX_MAPPING - // compute the diffuse term vec4 diffuse = texture2D(u_DiffuseMap, texDiffuse); - - // alpha masking #if defined(USE_ALPHA_TESTING) if (u_AlphaTest == ATEST_GT_0 && diffuse.a <= 0.0) @@ -122,37 +109,50 @@ void main() #endif // USE_ALPHA_TESTING + // view direction + vec3 V = var_ViewOrigin; - // compute normal (to worldspace) - vec3 N = computeNormal(texture2D(u_NormalMap, texNormal).xyz, tangentSpaceMatrix); + // light direction + vec3 L = var_LightDirection; - // compute light direction (this is also in world space) - vec3 L = -normalize(u_LightDir); // reverse the direction + // normal + vec3 Ntex = texture2D(u_NormalMap, texNormal).xyz * 2.0 - 1.0; + // transform normal from tangentspace to worldspace + vec3 N = normalize(var_tangentMatrix * Ntex); // we must normalize to get a vector of unit-length.. reflect() needs it // the cosine of the angle N L (needs unit-vectors) float dotNL = dot(N, L); -#if defined(USE_REFLECTIONS) || defined(USE_SPECULAR) // compute the specular term (and reflections) - vec3 reflections = vec3(0.0); - vec3 specular = vec3(0.0); -#if defined(USE_REFLECTIONS) - // reflections - reflections = computeReflections(V, N, u_EnvironmentMap0, u_EnvironmentMap1, u_EnvironmentInterpolation); -#endif // end USE_REFLECTIONS -#if defined(USE_SPECULAR) - // the specular highlights - specular = computeSpecular(V, N, L, 64.0); //r_SpecularExponent -#endif // USE_SPECULAR - specular += reflections; - specular *= texture2D(u_SpecularMap, texSpecular).rgb; // shininess factor -#endif // USE_REFLECTIONS || USE_SPECULAR + //! https://en.wikipedia.org/wiki/Specular_highlight + //! "The number n is called the Phong exponent, and is a user-chosen value that controls the apparent smoothness of the surface" +#if defined(USE_SPECULAR) && !defined(USE_REFLECTIONS) + vec4 map = texture2D(u_SpecularMap, texSpecular); + vec3 shininess = map.rgb; + // alpha values in range 0 to 1.0. exponent range is 0 to 256 (or whatever maximum value you want. ..perhaps r_SpecularExponent?). + float exponent = map.a * r_SpecularExponent; + vec3 specular = computeSpecular2(dotNL, V, N, L, u_LightColor, exponent) + * shininess; +#elif defined(USE_SPECULAR) && defined(USE_REFLECTIONS) + vec4 map = texture2D(u_SpecularMap, texSpecular); + vec3 shininess = map.rgb; + float exponent = map.a * r_SpecularExponent; + vec3 specular = (computeReflections(V, N, u_EnvironmentMap0, u_EnvironmentMap1, u_EnvironmentInterpolation) + + computeSpecular2(dotNL, V, N, L, u_LightColor, exponent)) + * shininess; +#elif !defined(USE_SPECULAR) && defined(USE_REFLECTIONS) + vec4 map = texture2D(u_SpecularMap, texSpecular); + vec3 shininess = map.rgb; + vec3 specular = computeReflections(V, N, u_EnvironmentMap0, u_EnvironmentMap1, u_EnvironmentInterpolation) + * shininess; +#endif +#if defined(r_diffuseLighting) // compute the diffuse light term - // https://en.wikipedia.org/wiki/Lambert%27s_cosine_law - diffuse.rgb *= computeDiffuseLighting(N, L); + diffuse.rgb *= computeDiffuseLighting2(dotNL); +#endif // r_diffuseLighting @@ -166,7 +166,6 @@ void main() - #else // no normal mapping diff --git a/src/renderer2/glsl/vertexLighting_DBS_world_vp.glsl b/src/renderer2/glsl/vertexLighting_DBS_world_vp.glsl index 431ca1d64..21f4e3257 100644 --- a/src/renderer2/glsl/vertexLighting_DBS_world_vp.glsl +++ b/src/renderer2/glsl/vertexLighting_DBS_world_vp.glsl @@ -16,7 +16,6 @@ uniform mat4 u_ModelMatrix; uniform float u_Time; uniform vec4 u_ColorModulate; uniform vec4 u_Color; -uniform vec3 u_LightDir; uniform vec3 u_LightColor; #if defined(USE_NORMAL_MAPPING) uniform mat4 u_NormalTextureMatrix; @@ -28,19 +27,34 @@ uniform samplerCube u_EnvironmentMap1; uniform float u_EnvironmentInterpolation; #endif // USE_REFLECTIONS #endif // USE_REFLECTIONS || USE_SPECULAR +uniform vec3 u_LightDir; +uniform vec3 u_ViewOrigin; +#if defined(USE_PARALLAX_MAPPING) +uniform float u_DepthScale; +#endif // USE_PARALLAX_MAPPING #endif // USE_NORMAL_MAPPING +#if defined(USE_PORTAL_CLIPPING) +uniform vec4 u_PortalPlane; +#endif // USE_PORTAL_CLIPPING varying vec3 var_Position; varying vec4 var_LightColor; varying vec4 var_TexDiffuseNormal; varying vec3 var_Normal; #if defined(USE_NORMAL_MAPPING) -varying vec3 var_Tangent; -varying vec3 var_Binormal; +varying mat3 var_tangentMatrix; #if defined(USE_REFLECTIONS) || defined(USE_SPECULAR) varying vec2 var_TexSpecular; #endif // USE_REFLECTIONS || USE_SPECULAR +varying vec3 var_LightDirection; +varying vec3 var_ViewOrigin; // position - vieworigin +#if defined(USE_PARALLAX_MAPPING) +varying vec2 var_S; // size and start position of search in texture space +#endif // USE_PARALLAX_MAPPING #endif // USE_NORMAL_MAPPING +#if defined(USE_PORTAL_CLIPPING) +varying float var_BackSide; // in front, or behind, the portalplane +#endif // USE_PORTAL_CLIPPING void main() { @@ -61,8 +75,11 @@ void main() // transform tangentspace axis var_Normal.xyz = (u_ModelMatrix * vec4(attr_Normal, 0.0)).xyz; #if defined(USE_NORMAL_MAPPING) - var_Tangent.xyz = (u_ModelMatrix * vec4(attr_Tangent, 0.0)).xyz; - var_Binormal.xyz = (u_ModelMatrix * vec4(attr_Binormal, 0.0)).xyz; + vec3 tangent = (u_ModelMatrix * vec4(attr_Tangent, 0.0)).xyz; + vec3 binormal = (u_ModelMatrix * vec4(attr_Binormal, 0.0)).xyz; + + // in a vertex-shader there exists no gl_FrontFacing + var_tangentMatrix = mat3(-tangent, -binormal, -var_Normal.xyz); // transform normalmap texcoords var_TexDiffuseNormal.pq = (u_NormalTextureMatrix * attr_TexCoord0).st; @@ -71,8 +88,22 @@ void main() // transform specularmap texture coords var_TexSpecular = (u_SpecularTextureMatrix * attr_TexCoord0).st; #endif // USE_REFLECTIONS || USE_SPECULAR -#endif // USE_NORMAL_MAPPING // assign color var_LightColor = attr_Color * u_ColorModulate + u_Color; + var_LightDirection = -normalize(u_LightDir); + + var_ViewOrigin = normalize(var_Position - u_ViewOrigin); + +#if defined(USE_PARALLAX_MAPPING) + // transform the vieworigin from tangentspace to worldspace + vec3 viewOrigin2 = normalize(var_tangentMatrix * var_ViewOrigin); + var_S = viewOrigin2.xy * -u_DepthScale / viewOrigin2.z; +#endif // USE_PARALLAX_MAPPING +#endif // USE_NORMAL_MAPPING + +#if defined(USE_PORTAL_CLIPPING) + // in front, or behind, the portalplane + var_BackSide = dot(var_Position.xyz, u_PortalPlane.xyz) - u_PortalPlane.w; +#endif // USE_PORTAL_CLIPPING } diff --git a/src/renderer2/tr_glsl.c b/src/renderer2/tr_glsl.c index 4d2e3281e..a51dee89e 100644 --- a/src/renderer2/tr_glsl.c +++ b/src/renderer2/tr_glsl.c @@ -1076,9 +1076,9 @@ static void GLSL_BuildShaderExtraDef() BUFFEXT("#ifndef r_WrapAroundLighting\n#define r_WrapAroundLighting %i\n#endif\n", r_wrapAroundLighting->integer); } - if (r_halfLambertLighting->integer) + if (r_diffuseLighting->value >= 0.0) // && r_diffuseLighting->value <= 1.0 { - BUFFEXT("#ifndef r_HalfLambertLighting\n#define r_HalfLambertLighting 1\n#endif\n"); + BUFFEXT("#ifndef r_diffuseLighting\n#define r_diffuseLighting %f\n#endif\n", r_diffuseLighting->value); } if (r_rimLighting->integer) diff --git a/src/renderer2/tr_init.c b/src/renderer2/tr_init.c index d1aa265a5..5c7a52156 100644 --- a/src/renderer2/tr_init.c +++ b/src/renderer2/tr_init.c @@ -177,7 +177,7 @@ cvar_t *r_specularScale; cvar_t *r_normalScale; cvar_t *r_normalMapping; cvar_t *r_wrapAroundLighting; -cvar_t *r_halfLambertLighting; +cvar_t *r_diffuseLighting; cvar_t *r_rimLighting; cvar_t *r_rimExponent; cvar_t *r_gamma; @@ -1240,7 +1240,8 @@ void R_Register(void) r_drawSun = ri.Cvar_Get("r_drawSun", "1", CVAR_ARCHIVE); r_finish = ri.Cvar_Get("r_finish", "0", CVAR_CHEAT); r_textureMode = ri.Cvar_Get("r_textureMode", "GL_LINEAR_MIPMAP_NEAREST", CVAR_ARCHIVE); - r_gamma = ri.Cvar_Get("r_gamma", "1.3", CVAR_ARCHIVE); + // FIXME: r1 & r2 default values differ + r_gamma = ri.Cvar_Get("r_gamma", "1.0", CVAR_ARCHIVE); r_facePlaneCull = ri.Cvar_Get("r_facePlaneCull", "1", CVAR_ARCHIVE); r_railWidth = ri.Cvar_Get("r_railWidth", "96", CVAR_ARCHIVE); @@ -1348,7 +1349,7 @@ void R_Register(void) r_offsetUnits = ri.Cvar_Get("r_offsetUnits", "-2", CVAR_CHEAT); r_forceSpecular = ri.Cvar_Get("r_forceSpecular", "0", CVAR_CHEAT); //These makes the spec spot bigger or smaller, the higher the number the smaller the dot - r_specularExponent = ri.Cvar_Get("r_specularExponent", "16", CVAR_CHEAT | CVAR_LATCH); + r_specularExponent = ri.Cvar_Get("r_specularExponent", "1024.0", CVAR_ARCHIVE | CVAR_LATCH); // cheat? r_specularExponent2 = ri.Cvar_Get("r_specularExponent2", "3", CVAR_CHEAT | CVAR_LATCH); //this one sets the power of specular, the higher the brighter r_specularScale = ri.Cvar_Get("r_specularScale", "0.2", CVAR_CHEAT | CVAR_LATCH); @@ -1357,7 +1358,7 @@ void R_Register(void) r_parallaxDepthScale = ri.Cvar_Get("r_parallaxDepthScale", "0.03", CVAR_CHEAT); // toon lightning r_wrapAroundLighting = ri.Cvar_Get("r_wrapAroundLighting", "0", CVAR_CHEAT | CVAR_LATCH); - r_halfLambertLighting = ri.Cvar_Get("r_halfLambertLighting", "1", CVAR_CHEAT | CVAR_LATCH); + r_diffuseLighting = ri.Cvar_Get("r_diffuseLighting", "0.0625", CVAR_ARCHIVE | CVAR_LATCH); // cheat? //rim light gives your shading a nice volumentric effect which can greatly enhance the contrast with the background r_rimLighting = ri.Cvar_Get("r_rimLighting", "0", CVAR_CHEAT | CVAR_LATCH); // was CVAR_ARCHIVE | CVAR_LATCH // FIXME: make rim lighting work with diffuse maps/textures diff --git a/src/renderer2/tr_local.h b/src/renderer2/tr_local.h index 0fd9942e8..1a5542e51 100644 --- a/src/renderer2/tr_local.h +++ b/src/renderer2/tr_local.h @@ -3781,7 +3781,7 @@ extern cvar_t *r_specularScale; extern cvar_t *r_normalScale; extern cvar_t *r_normalMapping; extern cvar_t *r_wrapAroundLighting; -extern cvar_t *r_halfLambertLighting; +extern cvar_t *r_diffuseLighting; extern cvar_t *r_rimLighting; extern cvar_t *r_rimExponent; diff --git a/src/renderer2/tr_shade.c b/src/renderer2/tr_shade.c index a27b2d56e..093947199 100644 --- a/src/renderer2/tr_shade.c +++ b/src/renderer2/tr_shade.c @@ -614,12 +614,13 @@ static void Render_generic(int stage) static void Render_vertexLighting_DBS_entity(int stage) { shaderStage_t *pStage = tess.surfaceStages[stage]; - qboolean normalMapping = (r_normalMapping->integer) ? qtrue : qfalse; - qboolean use_parallaxMapping = (normalMapping && r_parallaxMapping->integer && tess.surfaceShader->parallax); - qboolean use_specular = (normalMapping && qtrue); - qboolean use_reflections = (normalMapping && r_reflectionMapping->integer && tr.cubeProbes.currentElements > 0 && !tr.refdef.pixelTarget); + qboolean use_parallaxMapping = (r_normalMapping->integer && r_parallaxMapping->integer && tess.surfaceShader->parallax); + qboolean use_specular = (r_normalMapping->integer && qtrue); + qboolean use_reflections = (r_normalMapping->integer && r_reflectionMapping->integer && tr.cubeProbes.currentElements > 0 && !tr.refdef.pixelTarget); // !tr.refdef.pixelTarget to prevent using reflections before buildcubemaps() has finished. This is anti eye-cancer.. // TODO: && when surface has NOT assigned tcGen environment (because that will execute a reflection_cb stage). + qboolean use_vertex_skinning = (glConfig2.vboVertexSkinningAvailable && tess.vboVertexSkinning); + qboolean use_vertex_animation = (glState.vertexAttribsInterpolation > 0); Ren_LogComment("--- Render_vertexLighting_DBS_entity ---\n"); @@ -628,10 +629,10 @@ static void Render_vertexLighting_DBS_entity(int stage) SetMacrosAndSelectProgram(trProg.gl_vertexLightingShader_DBS_entity, USE_PORTAL_CLIPPING, backEnd.viewParms.isPortal, USE_ALPHA_TESTING, (pStage->stateBits & GLS_ATEST_BITS) != 0, - USE_VERTEX_SKINNING, glConfig2.vboVertexSkinningAvailable && tess.vboVertexSkinning, - USE_VERTEX_ANIMATION, glState.vertexAttribsInterpolation > 0, + USE_VERTEX_SKINNING, use_vertex_skinning, + USE_VERTEX_ANIMATION, use_vertex_animation, USE_DEFORM_VERTEXES, tess.surfaceShader->numDeforms, // && !ShaderRequiresCPUDeforms(tess.surfaceShader), - USE_NORMAL_MAPPING, normalMapping, + USE_NORMAL_MAPPING, r_normalMapping->integer, USE_PARALLAX_MAPPING, use_parallaxMapping, USE_REFLECTIONS, use_reflections, USE_SPECULAR, use_specular); @@ -644,29 +645,34 @@ static void Render_vertexLighting_DBS_entity(int stage) SetUniformFloat(UNIFORM_TIME, tess.shaderTime); // u_time } - if (glConfig2.vboVertexSkinningAvailable && tess.vboVertexSkinning) + if (use_vertex_skinning) { SetUniformMatrix16ARR(UNIFORM_BONEMATRIX, tess.boneMatrices, MAX_BONES); + //SetUniformMatrix16ARR(UNIFORM_BONEMATRIX, tess.boneMatrices, glConfig2.maxVertexSkinningBones); } - if (r_wrapAroundLighting->integer) + if (use_vertex_animation) { - SetUniformFloat(UNIFORM_LIGHTWRAPAROUND, RB_EvalExpression(&pStage->wrapAroundLightingExp, 0)); + SetUniformFloat(UNIFORM_VERTEXINTERPOLATION, glState.vertexAttribsInterpolation); } GLSL_SetUniform_AlphaTest(pStage->stateBits); - //SetUniformVec3(UNIFORM_VIEWORIGIN, backEnd.viewParms.orientation.viewOrigin); - SetUniformVec3(UNIFORM_VIEWORIGIN, backEnd.viewParms.orientation.origin); // in world space - SetUniformMatrix16(UNIFORM_MODELMATRIX, backEnd.orientation.transformMatrix); + if (r_normalMapping->integer) + { + SetUniformVec3(UNIFORM_VIEWORIGIN, backEnd.viewParms.orientation.origin); // in world space + } + + SetUniformMatrix16(UNIFORM_MODELMATRIX, MODEL_MATRIX); // same as backEnd.orientation.transformMatrix); SetUniformMatrix16(UNIFORM_MODELVIEWPROJECTIONMATRIX, GLSTACK_MVPM); + SetUniformVec3(UNIFORM_AMBIENTCOLOR, backEnd.currentEntity->ambientLight); SetUniformVec3(UNIFORM_LIGHTDIR, backEnd.currentEntity->lightDir); SetUniformVec3(UNIFORM_LIGHTCOLOR, backEnd.currentEntity->directedLight); - if (glState.vertexAttribsInterpolation > 0) + if (r_wrapAroundLighting->integer) { - SetUniformFloat(UNIFORM_VERTEXINTERPOLATION, glState.vertexAttribsInterpolation); + SetUniformFloat(UNIFORM_LIGHTWRAPAROUND, RB_EvalExpression(&pStage->wrapAroundLightingExp, 0)); } if (use_parallaxMapping) @@ -684,7 +690,7 @@ static void Render_vertexLighting_DBS_entity(int stage) GL_Bind(pStage->bundle[TB_DIFFUSEMAP].image[0]); SetUniformMatrix16(UNIFORM_DIFFUSETEXTUREMATRIX, tess.svars.texMatrices[TB_DIFFUSEMAP]); - if (normalMapping) + if (r_normalMapping->integer) { // bind u_NormalMap SelectTexture(TEX_NORMAL); @@ -715,14 +721,14 @@ static void Render_vertexLighting_DBS_entity(int stage) /** * @brief Sets light related uniforms (currently sun related only) * @param[in] - * - * @fixme this should set current light direction (and color) on not always the sun + * + * @fixme this should set current light direction (and color) on not always the sun * @fixme deal with tess.svars.color? */ void SetLightUniforms(qboolean setLightColor) { // note: there is always a default sunDirection set in RE_LoadWorldMap - // but sunLight is depending on real sun shader + // but sunLight is depending on real sun shader { SetUniformVec3(UNIFORM_LIGHTDIR, tr.sunDirection); // i need to provide _some_ direction.. not all world is lit by the sun.. if (setLightColor) @@ -740,9 +746,8 @@ static void Render_vertexLighting_DBS_world(int stage) { shaderStage_t *pStage = tess.surfaceStages[stage]; rgbaGen_t rgbaGen; - qboolean normalMapping = (r_normalMapping->integer) ? qtrue : qfalse; - qboolean use_parallaxMapping = (normalMapping && r_parallaxMapping->integer && tess.surfaceShader->parallax); - qboolean use_specular = (normalMapping && qtrue); + qboolean use_parallaxMapping = (r_normalMapping->integer && r_parallaxMapping->integer && tess.surfaceShader->parallax); + qboolean use_specular = (r_normalMapping->integer && qtrue); qboolean use_reflections = qfalse; //(normalMapping && r_reflectionMapping->integer && tr.cubeProbes.currentElements > 0 && !tr.refdef.pixelTarget); Ren_LogComment("--- Render_vertexLighting_DBS_world ---\n"); @@ -753,7 +758,7 @@ static void Render_vertexLighting_DBS_world(int stage) USE_PORTAL_CLIPPING, backEnd.viewParms.isPortal, USE_ALPHA_TESTING, (pStage->stateBits & GLS_ATEST_BITS) != 0, USE_DEFORM_VERTEXES, tess.surfaceShader->numDeforms, // && !ShaderRequiresCPUDeforms(tess.surfaceShader), - USE_NORMAL_MAPPING, normalMapping, + USE_NORMAL_MAPPING, r_normalMapping->integer, USE_PARALLAX_MAPPING, use_parallaxMapping, USE_REFLECTIONS, use_reflections, USE_SPECULAR, use_specular); @@ -778,9 +783,10 @@ static void Render_vertexLighting_DBS_world(int stage) SetUniformMatrix16(UNIFORM_MODELVIEWPROJECTIONMATRIX, GLSTACK_MVPM); SetUniformMatrix16(UNIFORM_MODELMATRIX, MODEL_MATRIX); // same as backEnd.orientation.transformMatrix - //SetUniformVec3(UNIFORM_VIEWORIGIN, backEnd.viewParms.orientation.viewOrigin); - SetUniformVec3(UNIFORM_VIEWORIGIN, backEnd.viewParms.orientation.origin); // in world space - + if (r_normalMapping->integer) + { + SetUniformVec3(UNIFORM_VIEWORIGIN, backEnd.viewParms.orientation.origin); // in world space + } // SetUniformVec3(UNIFORM_LIGHTDIR, backEnd.currentEntity->lightDir); // SetUniformVec3(UNIFORM_LIGHTCOLOR, backEnd.currentEntity->directedLight); @@ -814,7 +820,7 @@ static void Render_vertexLighting_DBS_world(int stage) GL_Bind(pStage->bundle[TB_DIFFUSEMAP].image[0]); SetUniformMatrix16(UNIFORM_DIFFUSETEXTUREMATRIX, tess.svars.texMatrices[TB_DIFFUSEMAP]); - if (normalMapping) + if (r_normalMapping->integer) { // bind u_NormalMap SelectTexture(TEX_NORMAL); @@ -887,7 +893,11 @@ static void Render_lightMapping(int stage, qboolean asColorMap, qboolean normalM } // set uniforms - SetUniformVec3(UNIFORM_VIEWORIGIN, backEnd.viewParms.orientation.origin); // in world space + if (normalMapping) + { + SetUniformVec3(UNIFORM_VIEWORIGIN, backEnd.viewParms.orientation.origin); // in world space + } + SetUniformMatrix16(UNIFORM_MODELMATRIX, backEnd.orientation.transformMatrix); SetUniformMatrix16(UNIFORM_MODELVIEWPROJECTIONMATRIX, GLSTACK_MVPM); @@ -913,10 +923,11 @@ static void Render_lightMapping(int stage, qboolean asColorMap, qboolean normalM //SetUniformVec3(UNIFORM_LIGHTDIR, backEnd.currentEntity->lightDir); SetUniformVec3(UNIFORM_LIGHTDIR, tr.sunDirection); + SetUniformVec3(UNIFORM_LIGHTCOLOR, tr.sunLight); SelectTexture(TEX_DIFFUSE); image_t* image = pStage->bundle[TB_DIFFUSEMAP].image[0]; - + if (image) { GL_Bind(image); @@ -959,7 +970,7 @@ static void Render_lightMapping(int stage, qboolean asColorMap, qboolean normalM BindLightMap(); // bind lightMap } else //if (tess.lightmapNum == LIGHTMAP_WHITEIMAGE) - { + { GL_Bind(tr.whiteImage); } @@ -1151,22 +1162,24 @@ static void Render_shadowFill(int stage) } else { - if (!image) + image = pStage->bundle[TB_DIFFUSEMAP].image[0]; + + if (image) { - image = pStage->bundle[TB_DIFFUSEMAP].image[0]; + SetUniformMatrix16(UNIFORM_COLORTEXTUREMATRIX, tess.svars.texMatrices[TB_DIFFUSEMAP]); } - - if (!image) - { + else + { image = tr.whiteImage; + SetUniformMatrix16(UNIFORM_COLORTEXTUREMATRIX, matrixIdentity); } - SetUniformMatrix16(UNIFORM_DIFFUSETEXTUREMATRIX, tess.svars.texMatrices[TB_DIFFUSEMAP]); } GL_Bind(image); } else { GL_Bind(tr.whiteImage); + SetUniformMatrix16(UNIFORM_COLORTEXTUREMATRIX, matrixIdentity); } Tess_DrawElements(); @@ -1232,7 +1245,10 @@ static void Render_forwardLighting_DBS_omni(shaderStage_t *diffuseStage, shadowTexelSize = 1.0f; } - SetUniformVec3(UNIFORM_VIEWORIGIN, backEnd.viewParms.orientation.origin); + if (r_normalMapping->integer) + { + SetUniformVec3(UNIFORM_VIEWORIGIN, backEnd.viewParms.orientation.origin); + } SetUniformVec3(UNIFORM_LIGHTORIGIN, light->origin); SetUniformVec3(UNIFORM_LIGHTCOLOR, tess.svars.color); SetUniformFloat(UNIFORM_LIGHTRADIUS, light->sphereRadius); @@ -1392,7 +1408,10 @@ static void Render_forwardLighting_DBS_proj(shaderStage_t *diffuseStage, shadowTexelSize = 1.0f; } - SetUniformVec3(UNIFORM_VIEWORIGIN, backEnd.viewParms.orientation.origin); + if (r_normalMapping->integer) + { + SetUniformVec3(UNIFORM_VIEWORIGIN, backEnd.viewParms.orientation.origin); + } SetUniformVec3(UNIFORM_LIGHTORIGIN, light->origin); SetUniformVec3(UNIFORM_LIGHTCOLOR, tess.svars.color); SetUniformFloat(UNIFORM_LIGHTRADIUS, light->sphereRadius); @@ -1560,7 +1579,10 @@ static void Render_forwardLighting_DBS_directional(shaderStage_t *diffuseStage, shadowTexelSize = 1.0f; } - SetUniformVec3(UNIFORM_VIEWORIGIN, backEnd.viewParms.orientation.origin); + if (r_normalMapping->integer) + { + SetUniformVec3(UNIFORM_VIEWORIGIN, backEnd.viewParms.orientation.origin); + } SetUniformVec3(UNIFORM_LIGHTCOLOR, tess.svars.color); SetUniformFloat(UNIFORM_LIGHTRADIUS, light->sphereRadius); @@ -1615,7 +1637,6 @@ static void Render_forwardLighting_DBS_directional(shaderStage_t *diffuseStage, // bind u_DiffuseMap SelectTexture(TEX_DIFFUSE); GL_Bind(diffuseStage->bundle[TB_DIFFUSEMAP].image[0]); - SetUniformMatrix16(UNIFORM_DIFFUSETEXTUREMATRIX, tess.svars.texMatrices[TB_DIFFUSEMAP]); if (r_normalMapping->integer) @@ -1682,7 +1703,7 @@ static void Render_forwardLighting_DBS_directional(shaderStage_t *diffuseStage, */ static void Render_reflection_CB(int stage) { - shaderStage_t *pStage = tess.surfaceStages[stage]; + shaderStage_t *pStage = tess.surfaceStages[stage]; Ren_LogComment("--- Render_reflection_CB ---\n"); @@ -2147,13 +2168,14 @@ static void Render_heatHaze(int stage) */ static void Render_liquid(int stage) { - shaderStage_t *pStage = tess.surfaceStages[stage]; - qboolean normalMapping = (r_normalMapping->integer) ? qtrue : qfalse; - qboolean use_parallaxMapping = (normalMapping && r_parallaxMapping->integer && tess.surfaceShader->parallax); - qboolean use_specular = (normalMapping && qtrue); - //qboolean use_reflections = normalMapping && r_reflectionMapping->integer && tr.cubeHashTable; - qboolean use_reflections = (normalMapping && r_reflectionMapping->integer && tr.cubeProbes.currentElements > 0); - qboolean use_water = normalMapping && (pStage->bundle[TB_DIFFUSEMAP].texMods[0].type != TMOD_NONE); // fancy water with moving waves.. only when the diffuse texture has some tcMod assigned + shaderStage_t *pStage = tess.surfaceStages[stage]; + qboolean use_parallaxMapping = (r_normalMapping->integer && r_parallaxMapping->integer && tess.surfaceShader->parallax); + qboolean use_specular = (r_normalMapping->integer && qtrue); + qboolean use_reflections = (r_normalMapping->integer && r_reflectionMapping->integer && tr.cubeProbes.currentElements > 0); + qboolean use_water = r_normalMapping->integer && (pStage->bundle[TB_DIFFUSEMAP].texMods[0].type != TMOD_NONE); // fancy water with moving waves.. only when the diffuse texture has some tcMod assigned + float fogDensity; + + fogDensity = RB_EvalExpression(&pStage->fogDensityExp, 0.0005f); Ren_LogComment("--- Render_liquid ---\n"); @@ -2162,13 +2184,13 @@ static void Render_liquid(int stage) // choose right shader program ---------------------------------- SetMacrosAndSelectProgram(trProg.gl_liquidShader, USE_PORTAL_CLIPPING, backEnd.viewParms.isPortal, - USE_NORMAL_MAPPING, normalMapping, + USE_NORMAL_MAPPING, r_normalMapping->integer, USE_PARALLAX_MAPPING, use_parallaxMapping, USE_SPECULAR, use_specular, USE_REFLECTIONS, use_reflections, USE_WATER, use_water); - if (normalMapping) + if (r_normalMapping->integer) { GLSL_VertexAttribsState(ATTR_POSITION | ATTR_TEXCOORD | ATTR_TANGENT | ATTR_BINORMAL | ATTR_NORMAL | ATTR_COLOR); } @@ -2178,45 +2200,66 @@ static void Render_liquid(int stage) } // set uniforms - SetUniformMatrix16(UNIFORM_UNPROJECTMATRIX, backEnd.viewParms.unprojectionMatrix); SetUniformMatrix16(UNIFORM_MODELMATRIX, backEnd.orientation.transformMatrix); SetUniformMatrix16(UNIFORM_MODELVIEWPROJECTIONMATRIX, GLSTACK_MVPM); SetUniformVec3(UNIFORM_VIEWORIGIN, backEnd.viewParms.orientation.origin); // in world space - SetUniformFloat(UNIFORM_FOGDENSITY, RB_EvalExpression(&pStage->fogDensityExp, 0.0005f)); - SetUniformVec3(UNIFORM_FOGCOLOR, tess.svars.color); +// SetUniformFloat(UNIFORM_FOGDENSITY, RB_EvalExpression(&pStage->fogDensityExp, 0.0005f)); + SetUniformFloat(UNIFORM_FOGDENSITY, fogDensity); + if (fogDensity > 0.0) + { + SetUniformVec3(UNIFORM_FOGCOLOR, tess.svars.color); + SetUniformMatrix16(UNIFORM_UNPROJECTMATRIX, backEnd.viewParms.unprojectionMatrix); + + // bind u_DepthMap + SelectTexture(TEX_DEPTH); + if (HDR_ENABLED()) + { + GL_Bind(tr.depthRenderImage); + } + else + { + ImageCopyBackBuffer(tr.depthRenderImage); // depth texture is not bound to a FBO + } + } + + if (r_normalMapping->integer) + { + // light direction #if 1 - SetLightUniforms(qfalse); + SetLightUniforms(qfalse); #else - SetUniformVec3(UNIFORM_LIGHTDIR, light->direction); + SetUniformVec3(UNIFORM_LIGHTDIR, light->direction); #endif - if (normalMapping) - { - SetUniformFloat(UNIFORM_REFRACTIONINDEX, RB_EvalExpression(&pStage->refractionIndexExp, 1.3f)); + // fresnel + SetUniformFloat(UNIFORM_FRESNELBIAS, RB_EvalExpression(&pStage->fresnelBiasExp, 0.05f)); SetUniformFloat(UNIFORM_FRESNELPOWER, RB_EvalExpression(&pStage->fresnelPowerExp, 2.0f)); SetUniformFloat(UNIFORM_FRESNELSCALE, RB_EvalExpression(&pStage->fresnelScaleExp, 0.85f)); - SetUniformFloat(UNIFORM_FRESNELBIAS, RB_EvalExpression(&pStage->fresnelBiasExp, 0.05f)); SetUniformFloat(UNIFORM_NORMALSCALE, RB_EvalExpression(&pStage->normalScaleExp, 0.05f)); - if (use_parallaxMapping) - { - SetUniformFloat(UNIFORM_DEPTHSCALE, RB_EvalExpression(&pStage->depthScaleExp, r_parallaxDepthScale->value)); - } + // refraction + SetUniformFloat(UNIFORM_REFRACTIONINDEX, 1.0 / RB_EvalExpression(&pStage->refractionIndexExp, 1.3f)); // 1/refractionIndex - // bind u_PortalMap - // This is used to make the reflections on the water surface -#if 0 - SelectTexture(TEX_PORTAL); - GL_Bind(tr.portalRenderImage); // check this texture.. it's woot now -#else + // reflection +#if 1 if (use_reflections) { BindCubeMaps(); } //else // GL_Bind(tr.blackCubeImage); +#else + // bind u_PortalMap + // This is used to make the reflections on the water surface + SelectTexture(TEX_PORTAL); + GL_Bind(tr.portalRenderImage); // check this texture.. it's woot now #endif + + if (use_parallaxMapping) + { + SetUniformFloat(UNIFORM_DEPTHSCALE, RB_EvalExpression(&pStage->depthScaleExp, r_parallaxDepthScale->value)); + } } // portal plane @@ -2236,22 +2279,12 @@ static void Render_liquid(int stage) ImageCopyBackBuffer(tr.currentRenderImage); } - // bind u_DepthMap - SelectTexture(TEX_DEPTH); - if (HDR_ENABLED()) - { - GL_Bind(tr.depthRenderImage); - } - else - { - ImageCopyBackBuffer(tr.depthRenderImage); // depth texture is not bound to a FBO - } - // bind u_NormalMap - if (normalMapping) + if (r_normalMapping->integer) { SelectTexture(TEX_NORMAL); BindTexture(pStage->bundle[TB_NORMALMAP].image[0], tr.flatImage); + if (use_water) { SetUniformMatrix16(UNIFORM_NORMALTEXTUREMATRIX, tess.svars.texMatrices[TB_DIFFUSEMAP]); // make the bumps move along with the diffuse texture (in case tcMod changes something) @@ -3438,7 +3471,7 @@ void Tess_StageIteratorShadowFill() break; } - case ST_LIGHTMAP: + //case ST_LIGHTMAP: case ST_DIFFUSEMAP: case ST_COLLAPSE_lighting_DB: case ST_COLLAPSE_lighting_DBS: @@ -3466,6 +3499,8 @@ void Tess_StageIteratorLighting() trRefLight_t *light = backEnd.currentLight; shaderStage_t *attenuationXYStage; shaderStage_t *attenuationZStage; + qboolean renderStage; + qboolean diffuseStageTexMatrices; Ren_LogComment("--- Tess_StageIteratorLighting( %s, %s, %i vertices, %i triangles ) ---\n", tess.surfaceShader->name, tess.lightShader->name, tess.numVertexes, tess.numIndexes / 3); @@ -3523,7 +3558,7 @@ void Tess_StageIteratorLighting() continue; } - Tess_ComputeTexMatrices(diffuseStage); + diffuseStageTexMatrices = qfalse; for (j = 1; j < MAX_SHADER_STAGES; j++) { @@ -3544,6 +3579,9 @@ void Tess_StageIteratorLighting() continue; } + + renderStage = qfalse; + switch (diffuseStage->type) { case ST_DIFFUSEMAP: @@ -3551,26 +3589,20 @@ void Tess_StageIteratorLighting() case ST_COLLAPSE_lighting_DBS: if (light->l.rlType == RL_OMNI) { - Tess_ComputeColor(attenuationXYStage); - R_ComputeFinalAttenuation(attenuationXYStage, light); - Render_forwardLighting_DBS_omni(diffuseStage, attenuationXYStage, attenuationZStage, light); + renderStage = qtrue; } else if (light->l.rlType == RL_PROJ) { if (!light->l.inverseShadows) { - Tess_ComputeColor(attenuationXYStage); - R_ComputeFinalAttenuation(attenuationXYStage, light); - Render_forwardLighting_DBS_proj(diffuseStage, attenuationXYStage, attenuationZStage, light); + renderStage = qtrue; } } else if (light->l.rlType == RL_DIRECTIONAL) { //if(!light->l.inverseShadows) { - Tess_ComputeColor(attenuationXYStage); - R_ComputeFinalAttenuation(attenuationXYStage, light); - Render_forwardLighting_DBS_directional(diffuseStage, attenuationXYStage, attenuationZStage, light); + renderStage = qtrue; } } break; @@ -3578,6 +3610,32 @@ void Tess_StageIteratorLighting() default: break; } + + // only calculate matrices and attenuation when we need to render + if (renderStage) + { + // do we have the diffuseStage TexMatrices calculated? + if (!diffuseStageTexMatrices) + { + Tess_ComputeTexMatrices(diffuseStage); + diffuseStageTexMatrices = qtrue; // now we have.. + } + Tess_ComputeColor(attenuationXYStage); + R_ComputeFinalAttenuation(attenuationXYStage, light); + // render the appropriate light + if (light->l.rlType == RL_OMNI) + { + Render_forwardLighting_DBS_omni(diffuseStage, attenuationXYStage, attenuationZStage, light); + } + else if (light->l.rlType == RL_DIRECTIONAL) + { + Render_forwardLighting_DBS_directional(diffuseStage, attenuationXYStage, attenuationZStage, light); + } + else + { + Render_forwardLighting_DBS_proj(diffuseStage, attenuationXYStage, attenuationZStage, light); + } + } } }