1
0
mirror of https://gitlab.com/OpenMW/openmw.git synced 2025-01-18 13:12:50 +00:00

Switched objects shaders to vertex lighting, to accomodate badly placed lights in morrowind.

Fixed a very obvious land <-> water seam.
This commit is contained in:
scrawl 2013-02-14 19:45:07 +01:00
parent 6a49ea9b4f
commit 492e0f2ccf
2 changed files with 81 additions and 15 deletions

View File

@ -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

View File

@ -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);