From 492e0f2ccfbf9b069346e738f9145359a036335e Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 14 Feb 2013 19:45:07 +0100 Subject: [PATCH] Switched objects shaders to vertex lighting, to accomodate badly placed lights in morrowind. Fixed a very obvious land <-> water seam. --- files/materials/objects.shader | 83 +++++++++++++++++++++++++++++++--- files/materials/terrain.shader | 13 ++---- 2 files changed, 81 insertions(+), 15 deletions(-) diff --git a/files/materials/objects.shader b/files/materials/objects.shader index 1e9c4a3343..af596b779a 100644 --- a/files/materials/objects.shader +++ b/files/materials/objects.shader @@ -22,6 +22,8 @@ #define HAS_VERTEXCOLOR @shPropertyBool(has_vertex_colour) +#define VERTEX_LIGHTING 1 + #ifdef SH_VERTEX_SHADER // ------------------------------------- VERTEX --------------------------------------- @@ -42,8 +44,24 @@ #if HAS_VERTEXCOLOR shColourInput(float4) +#if !VERTEX_LIGHTING shOutput(float4, colourPassthrough) #endif +#endif + +#if VERTEX_LIGHTING + shUniform(float, lightCount) @shAutoConstant(lightCount, light_count) + shUniform(float4, lightPosition[8]) @shAutoConstant(lightPosition, light_position_object_space_array, 8) + shUniform(float4, lightDiffuse[8]) @shAutoConstant(lightDiffuse, light_diffuse_colour_array, 8) + shUniform(float4, lightAttenuation[8]) @shAutoConstant(lightAttenuation, light_attenuation_array, 8) + shUniform(float4, lightAmbient) @shAutoConstant(lightAmbient, ambient_light_colour) +#if !HAS_VERTEXCOLOUR + shUniform(float4, materialAmbient) @shAutoConstant(materialAmbient, surface_ambient_colour) +#endif + shUniform(float4, materialDiffuse) @shAutoConstant(materialDiffuse, surface_diffuse_colour) + shUniform(float4, materialEmissive) @shAutoConstant(materialEmissive, surface_emissive_colour) + +#endif #if SHADOWS shOutput(float4, lightSpacePos0) @@ -58,6 +76,11 @@ @shEndForeach shUniform(float4x4, worldMatrix) @shAutoConstant(worldMatrix, world_matrix) #endif + +#if VERTEX_LIGHTING + shOutput(float3, lightResult) + shOutput(float3, directionalResult) +#endif SH_START_PROGRAM { shOutputPosition = shMatrixMult(wvp, shInputPosition); @@ -74,7 +97,7 @@ objSpacePositionPassthrough = shInputPosition.xyz; #endif -#if HAS_VERTEXCOLOR +#if HAS_VERTEXCOLOR && !VERTEX_LIGHTING colourPassthrough = colour; #endif @@ -86,6 +109,36 @@ @shForeach(3) lightSpacePos@shIterator = shMatrixMult(texViewProjMatrix@shIterator, wPos); @shEndForeach +#endif + + +#if VERTEX_LIGHTING + float3 lightDir; + float d; + + @shForeach(@shGlobalSettingString(num_lights)) + lightDir = lightPosition[@shIterator].xyz - (shInputPosition.xyz * lightPosition[@shIterator].w); + d = length(lightDir); + lightDir = normalize(lightDir); + + lightResult += materialDiffuse.xyz * lightDiffuse[@shIterator].xyz + * (1.0 / ((lightAttenuation[@shIterator].y) + (lightAttenuation[@shIterator].z * d) + (lightAttenuation[@shIterator].w * d * d))) + * max(dot(normalize(normal.xyz), normalize(lightDir)), 0); + +#if @shIterator == 0 + directionalResult = lightResult; +#endif + + @shEndForeach + +#if HAS_VERTEXCOLOR + // ambient vertex colour tracking, FFP behaviour + lightResult += lightAmbient.xyz * colour.xyz + materialEmissive.xyz; + +#else + lightResult += lightAmbient.xyz * materialAmbient.xyz + materialEmissive.xyz; +#endif + #endif } @@ -115,25 +168,29 @@ #if LIGHTING shInput(float3, normalPassthrough) shInput(float3, objSpacePositionPassthrough) - shUniform(float4, lightAmbient) @shAutoConstant(lightAmbient, ambient_light_colour) #if !HAS_VERTEXCOLOR shUniform(float4, materialAmbient) @shAutoConstant(materialAmbient, surface_ambient_colour) #endif shUniform(float4, materialDiffuse) @shAutoConstant(materialDiffuse, surface_diffuse_colour) shUniform(float4, materialEmissive) @shAutoConstant(materialEmissive, surface_emissive_colour) + shUniform(float4, lightAmbient) @shAutoConstant(lightAmbient, ambient_light_colour) +#if !VERTEX_LIGHTING + @shForeach(@shGlobalSettingString(num_lights)) shUniform(float4, lightPosObjSpace@shIterator) @shAutoConstant(lightPosObjSpace@shIterator, light_position_object_space, @shIterator) shUniform(float4, lightAttenuation@shIterator) @shAutoConstant(lightAttenuation@shIterator, light_attenuation, @shIterator) shUniform(float4, lightDiffuse@shIterator) @shAutoConstant(lightDiffuse@shIterator, light_diffuse_colour, @shIterator) @shEndForeach #endif + +#endif #if FOG shUniform(float3, fogColour) @shAutoConstant(fogColour, fog_colour) shUniform(float4, fogParams) @shAutoConstant(fogParams, fog_params) #endif -#if HAS_VERTEXCOLOR +#if HAS_VERTEXCOLOR && !VERTEX_LIGHTING shInput(float4, colourPassthrough) #endif @@ -175,6 +232,11 @@ shUniform(float3, windDir_windSpeed) @shSharedParameter(windDir_windSpeed) #endif +#if VERTEX_LIGHTING + shInput(float3, lightResult) + shInput(float3, directionalResult) +#endif + SH_START_PROGRAM { shOutputColour(0) = shSample(diffuseMap, UV); @@ -187,9 +249,9 @@ #if HAS_VERTEXCOLOR // ambient vertex colour tracking, FFP behaviour - float3 ambient = colourPassthrough.xyz * lightAmbient.xyz; + //float3 ambient = colourPassthrough.xyz * lightAmbient.xyz; #else - float3 ambient = materialAmbient.xyz * lightAmbient.xyz; + //float3 ambient = materialAmbient.xyz * lightAmbient.xyz; #endif // shadows only for the first (directional) light @@ -228,6 +290,7 @@ caustics = float3(1,1,1); #endif +#if !VERTEX_LIGHTING @shForeach(@shGlobalSettingString(num_lights)) @@ -253,9 +316,16 @@ @shEndForeach - shOutputColour(0).xyz *= (ambient + diffuse + materialEmissive.xyz); + lightResult = (ambient + diffuse + materialEmissive.xyz); #endif +#if SHADOWS + shOutputColour(0).xyz *= (lightResult - directionalResult * (1.0-shadow)); +#else + shOutputColour(0).xyz *= (lightResult); +#endif + +#endif // IF LIGHTING #if HAS_VERTEXCOLOR && !LIGHTING shOutputColour(0).xyz *= colourPassthrough.xyz; @@ -303,7 +373,6 @@ #if MRT shOutputColour(1) = float4(depthPassthrough / far,1,1,1); #endif - } #endif diff --git a/files/materials/terrain.shader b/files/materials/terrain.shader index 9b891e1e80..d62bb4035e 100644 --- a/files/materials/terrain.shader +++ b/files/materials/terrain.shader @@ -32,7 +32,7 @@ @shAllocatePassthrough(2, UV) #if LIGHTING -@shAllocatePassthrough(3, objSpacePosition) +@shAllocatePassthrough(3, worldPos) #endif #if SHADOWS @@ -101,7 +101,7 @@ @shPassthroughAssign(UV, uv0); #if LIGHTING - @shPassthroughAssign(objSpacePosition, shInputPosition.xyz); + @shPassthroughAssign(worldPos, worldPos.xyz); #endif #if SHADOWS @@ -162,7 +162,7 @@ #if LIGHTING shUniform(float4, lightAmbient) @shAutoConstant(lightAmbient, ambient_light_colour) @shForeach(@shGlobalSettingString(terrain_num_lights)) - shUniform(float4, lightPosObjSpace@shIterator) @shAutoConstant(lightPosObjSpace@shIterator, light_position_object_space, @shIterator) + shUniform(float4, lightPosObjSpace@shIterator) @shAutoConstant(lightPosObjSpace@shIterator, light_position, @shIterator) shUniform(float4, lightAttenuation@shIterator) @shAutoConstant(lightAttenuation@shIterator, light_attenuation, @shIterator) shUniform(float4, lightDiffuse@shIterator) @shAutoConstant(lightDiffuse@shIterator, light_diffuse_colour, @shIterator) @shEndForeach @@ -213,7 +213,7 @@ float2 UV = @shPassthroughReceive(UV); #if LIGHTING - float3 objSpacePosition = @shPassthroughReceive(objSpacePosition); + float3 worldPos = @shPassthroughReceive(worldPos); float3 normal = shSample(normalMap, UV).rgb * 2 - 1; normal = normalize(normal); @@ -222,9 +222,6 @@ float3 caustics = float3(1,1,1); -#if (UNDERWATER) || (FOG) - float3 worldPos = shMatrixMult(worldMatrix, float4(objSpacePosition,1)).xyz; -#endif #if UNDERWATER @@ -306,7 +303,7 @@ @shForeach(@shGlobalSettingString(terrain_num_lights)) - lightDir = lightPosObjSpace@shIterator.xyz - (objSpacePosition.xyz * lightPosObjSpace@shIterator.w); + lightDir = lightPosObjSpace@shIterator.xyz - (worldPos.xyz * lightPosObjSpace@shIterator.w); d = length(lightDir);