diff --git a/Shaders/fx/LandBump.fx b/Shaders/fx/LandBump.fx index 667a12c..a82bc3f 100644 --- a/Shaders/fx/LandBump.fx +++ b/Shaders/fx/LandBump.fx @@ -6,21 +6,26 @@ #include "../fxh/Constants.fxh" #include "../fxh/Lighting.fxh" +#include "../fxh/Transform.fxh" +#include "../fxh/Fog.fxh" + +shared WorldTransforms g_WorldTransforms; +shared ViewTransforms g_ViewTransforms; shared texture g_Texture0; shared texture g_Texture1; -shared float4x4 g_WorldViewProjection; -shared float4x4 g_World; - +shared texture g_Texture2; shared float4x4 g_TexGenMatrix0; shared float4x4 g_TexGenMatrix1; +shared float4x4 g_TexGenMatrix2; -shared float4 g_PointLightDiffuse[MAX_LIGHTS]; -shared float3 g_PointLightPosition[MAX_LIGHTS]; -shared float g_PointLightRange[MAX_LIGHTS]; -shared int g_PointLightCount; +shared DirectionalLightInfo g_DirectionalLights; +shared PointLightInfo g_PointLights; -//float4x4 g_texGenMatrix2 : TexGenTransform2; // Shore texgen +shared FogParams g_Fog; + +float g_DetailFadeStart = 150; +float g_DetailFadeEnd = 500; ////////////////////////////////////////////////////// @@ -45,108 +50,232 @@ sampler_state MagFilter = LINEAR; }; -//sampler g_LandDetailTextureSampler = -//sampler_state -//{ -// Texture = ; -// MipFilter = LINEAR; -// MinFilter = LINEAR; -// MagFilter = LINEAR; -//}; -// -//sampler g_ShoreTextureSampler = -//sampler_state -//{ -// Texture = ; -// MipFilter = LINEAR; -// MinFilter = LINEAR; -// MagFilter = LINEAR; -//}; +sampler g_LandDetailTextureSampler = +sampler_state +{ + Texture = ; + MipFilter = LINEAR; + MinFilter = LINEAR; + MagFilter = LINEAR; +}; //-------------------------------------------------------------------------------------- // Vertex shader output structure //-------------------------------------------------------------------------------------- -struct VS_OUTPUT_BUMP +struct LandBumpDetailVSOutput { float4 Position : POSITION; float4 LandBumpDiffuse : COLOR1; float4 LandDiffuse : COLOR0; float2 LandBumpTextureUV : TEXCOORD0; float2 LandTextureUV : TEXCOORD1; - float3 WorldPos : TEXCOORD2; - float3 Normal : TEXCOORD3; - //float3 ShoreTextureUV : TEXCOORD4; + float2 LandDetailTextureUV : TEXCOORD2; + float3 WorldPos : TEXCOORD3; + float3 Normal : TEXCOORD4; + float Fog : FOG; }; -float4 bx2(float4 x) +inline float4 bx2(float4 x) { - return float4(2.0f * x.xyzw - 1.0f); + return float4(2.0f * x.xyzw - 1.0f); } -VS_OUTPUT_BUMP LandBumpVS( - float4 vPos : POSITION, - float3 vNormal : NORMAL, - float4 vDiffuse : COLOR0, - float4 vDiffuse2 : COLOR1) +float4 CalculateDetailTexture(float3 worldPos, float4 originalColor, float2 detailTextureUV) { - VS_OUTPUT_BUMP Output; - - // Transform the position from object space to homogeneous projection space - Output.Position = mul(vPos, g_WorldViewProjection); - - Output.LandBumpDiffuse = vDiffuse2 * .5f; - Output.LandBumpDiffuse.a = 1.0f; - - Output.LandDiffuse.rgb = vDiffuse; - Output.LandDiffuse.a = 1.0f; - - Output.WorldPos = mul(vPos, g_World); - - // Set dynamically generated tex coords - Output.LandBumpTextureUV = mul(vPos, g_TexGenMatrix0); - Output.LandTextureUV = mul(vPos, g_TexGenMatrix1); - //Output.ShoreTextureUV = mul(vPos, g_texGenMatrix2); - - // Transform the normal from object space to world space - Output.Normal = normalize(mul(vNormal, (float3x3)g_World)); // normal (world space) - - return Output; -} - -float4 LandBumpPS(VS_OUTPUT_BUMP input) : COLOR0 -{ - float4 normal = bx2(tex2D(g_LandBumpTextureSampler, input.LandBumpTextureUV)); - float4 normalcol = bx2(input.LandDiffuse); - - float3 normalMap; - normalMap = saturate((float4)dot((float3)normal, (float3)normalcol)).xyz; - float3 finalColor = 2.0 * (normalMap * (tex2D(g_LandTextureSampler, input.LandTextureUV)) + input.LandBumpDiffuse); - - for (int i = 0; i < g_PointLightCount; i++) + if (detailTextureUV.x != 0 || detailTextureUV.y != 0) { - // Get light direction for this fragment - float3 lightDir = normalize(input.WorldPos - g_PointLightPosition[i]); // per pixel diffuse lighting + float distance = length(worldPos - g_ViewTransforms.CameraPosition); + if (distance < g_DetailFadeEnd) + { + float4 detailTextureColor = tex2D(g_LandDetailTextureSampler, detailTextureUV) * 1.8f; - // Note: Non-uniform scaling not supported - float diffuseLighting = saturate(dot(input.Normal, -lightDir)); + if (distance > g_DetailFadeStart) + { + float distNormalized = distance / (g_DetailFadeEnd - g_DetailFadeStart); + detailTextureColor = lerp(detailTextureColor, float4(1.f, 1.f, 1.f, 1.f), distNormalized); + } - // Introduce fall-off of light intensity - diffuseLighting *= (g_PointLightRange[i] / dot(g_PointLightPosition[i] - input.WorldPos, g_PointLightPosition[i] - input.WorldPos)); - - float4 diffuseColor = diffuseLighting * g_PointLightDiffuse[i]; - - finalColor += diffuseColor; + originalColor *= detailTextureColor; + } } - return float4(finalColor, 1); + return originalColor; } -technique LandBump +LandBumpDetailVSOutput LandBumpDetailVS( + float4 position : POSITION, + float3 normal : NORMAL, + float4 landBumpDiffuse : COLOR0, + float4 landDiffuse : COLOR1) +{ + LandBumpDetailVSOutput output; + + // Transform the position from object space to homogeneous projection space + output.Position = mul(position, g_WorldTransforms.WorldViewProjection); + + output.LandDiffuse = landDiffuse * .5f; + output.LandDiffuse.a = 1.0f; + + output.LandBumpDiffuse.rgb = landBumpDiffuse; + output.LandBumpDiffuse.a = 1.0f; + + output.WorldPos = mul(position, g_WorldTransforms.World); + + // Set dynamically generated tex coords + output.LandBumpTextureUV = mul(position, g_TexGenMatrix0); + output.LandTextureUV = mul(position, g_TexGenMatrix1); + output.LandDetailTextureUV = mul(position, g_TexGenMatrix2); + + float3 P = mul(position, g_WorldTransforms.WorldView); + output.Fog = CalculateFogFactor(g_Fog.FogMax, g_Fog.FogMin, length(P)); + + // Transform the normal from object space to world space + output.Normal = normalize(mul(normal, (float3x3)g_WorldTransforms.World)); // normal (world space) + + return output; +} + +float4 CalculateDot3BumpMap(float4 diffuseColor, float2 uv) +{ + float4 landBumpTextureColor = bx2(tex2D(g_LandBumpTextureSampler, uv)); + diffuseColor = bx2(diffuseColor); + + float4 bumpMapColor; + bumpMapColor.xyz = saturate(dot(landBumpTextureColor, diffuseColor.rgb)); + bumpMapColor.w = 1.0f; + + return bumpMapColor; +} + +struct TNBFrame +{ + float3 Tangent; + float3 Normal; + float3 Binormal; +}; + +/* +TNBFrame CalculateTNBFrame(float3 worldPos, float3 N, float2 uv) +{ + float3 dp1 = ddx(worldPos); + float3 dp2 = ddy(worldPos); + float2 duv1 = ddx(uv); + float2 duv2 = ddy(uv); + + + float3 dp2perp = cross(dp2, N); + float3 dp1perp = cross(N, dp1); + float3 T = dp2perp * duv1.x + dp1perp * duv2.x; + float3 B = dp2perp * duv1.y + dp1perp * duv2.y; + + float invmax = rsqrt(max(dot(T, T), dot(B, B))); + + TNBFrame frame; + frame.Tangent = T * invmax; + frame.Normal = N; + frame.Binormal = B * invmax; + return frame; +} +*/ + +TNBFrame CalculateTNBFrame(float3 worldPos, float3 N, float2 uv) +{ + float3 dp1 = ddx(worldPos); + float3 dp2 = ddy(worldPos); + float2 duv1 = ddx(uv); + float2 duv2 = ddy(uv); + + float3 t = normalize(duv2.y * dp1 - duv1.y * dp2); + float3 b = normalize(duv2.x * dp1 - duv1.x * dp2); + float3 n = normalize(N); + float3 x = cross(n, t); + t = cross(x, n); + t = normalize(t); + + x = cross(b, n); + b = cross(n, x); + b = normalize(b); + + TNBFrame frame; + frame.Tangent = t; + frame.Normal = n; + frame.Binormal = b; + return frame; +} + +float4 CalculateNormalMap(float3 worldPos, float3 normal, float2 uv, float4 diffuse) +{ + TNBFrame tnbFrame = CalculateTNBFrame(worldPos, normal, uv); + + // Sample the pixel in the bump map. + float4 bumpMap = tex2D(g_LandBumpTextureSampler, uv) + diffuse; + + // Expand the range of the normal value from (0, +1) to (-1, +1). + bumpMap = (bumpMap * 2.0f) - 1.0f; + + // Calculate the normal from the data in the bump map. + float3 bumpNormal = (bumpMap.x * tnbFrame.Tangent) + (bumpMap.y * tnbFrame.Binormal) + (bumpMap.z * tnbFrame.Normal); + + // Normalize the resulting bump normal. + bumpNormal = normalize(bumpNormal); + + // Invert the light direction for calculations. + float3 lightDir = -g_DirectionalLights.Direction[g_DirectionalLights.SunIndex]; + + // Calculate the amount of light on this pixel based on the bump map normal value. + float lightIntensity = saturate(dot(bumpNormal, lightDir)); + + // Determine the final diffuse color based on the diffuse color and the amount of light intensity. + float4 color = saturate(lightIntensity); + + return color; +} + +float4 LandBumpDetailPS(LandBumpDetailVSOutput input) : COLOR0 +{ + float4 landTextureColor = tex2D(g_LandTextureSampler, input.LandTextureUV); + + +#if 1 + float4 bumpMapColor = CalculateDot3BumpMap(input.LandBumpDiffuse, input.LandBumpTextureUV); + float4 finalColor = 2.0 * (bumpMapColor * (landTextureColor) + input.LandDiffuse); +#else + float4 bumpMapColor = CalculateNormalMap(input.WorldPos, input.Normal, input.LandTextureUV, input.LandBumpDiffuse); + float4 bumpMapColor = CalculateDirectionalDiffuse(input.Normal, -g_DirectionalLights.Direction[g_DirectionalLights.SunIndex], float4(1, 1, 1, 1)); + + float4 finalColor = (bumpMapColor * landTextureColor) + input.LandDiffuse; +#endif + + finalColor = CalculateDetailTexture(input.WorldPos, finalColor, input.LandDetailTextureUV); + + for (int i = 0; i < g_PointLights.Count; i++) + { + float3 worldPos = g_PointLights.Position[i] - input.WorldPos; + float3 lightDirection = normalize(input.WorldPos - (g_PointLights.Position[i])); + + finalColor += CalculatePointDiffuse( + worldPos, + input.Normal, + -lightDirection, + g_PointLights.Range[i], + g_PointLights.Diffuse[i]); + } + + if (g_Fog.Enabled) + { + finalColor = ApplyPixelFog(finalColor, input.Fog, g_Fog.Color); + } + + finalColor.a = 1.0f; + return finalColor; +} + +technique LandBumpDetail { pass P0 - { - VertexShader = compile vs_2_0 LandBumpVS(); - PixelShader = compile ps_2_0 LandBumpPS(); + { + VertexShader = compile vs_3_0 LandBumpDetailVS(); + PixelShader = compile ps_3_0 LandBumpDetailPS(); } } @@ -162,25 +291,43 @@ struct VS_OUTPUT float3 WorldPos : TEXCOORD2; }; +matrix Identity = +{ + { 1, 0, 0, 0 }, + { 0, 1, 0, 0 }, + { 0, 0, 1, 0 }, + { 0, 0, 0, 1 } +}; + VS_OUTPUT LandscapeVS( float4 vPos : POSITION, float3 vNormal : NORMAL, float4 vDiffuse : COLOR0) { VS_OUTPUT Output; - + // Transform the position from object space to homogeneous projection space - Output.Position = mul(vPos, g_WorldViewProjection); + Output.Position = mul(vPos, g_WorldTransforms.WorldViewProjection); // Transform the normal from object space to world space - Output.Normal = normalize(mul(vNormal, (float3x3)g_World)); // normal (world space) + Output.Normal = normalize(mul(vNormal, (float3x3)g_WorldTransforms.World)); // normal (world space) Output.Diffuse.rgb = vDiffuse; Output.Diffuse.a = 1.0f; - Output.WorldPos = mul(vPos, g_World); + Output.WorldPos = mul(vPos, g_WorldTransforms.World); + //float3 P = mul(vPos, g_WorldView); //position in view space // Set dynamically generated tex coords + //P* (iTexGenType == TEXGEN_TYPE_CAMERASPACEPOSITION), 0) + /* + float4x4 scaleMatrix = Identity; + int index = G_TexUaxis[g_PrimBufferIndex]; + scaleMatrix[0][0] = g_TexUScale; + scaleMatrix[1][G_TexVaxis[g_PrimBufferIndex]] = g_TexVScale; + */ + + //Output.TextureUV = mul(vPos, (scaleMatrix * g_World)); Output.TextureUV = mul(vPos, g_TexGenMatrix0); return Output; @@ -190,20 +337,17 @@ float4 LandscapePS(VS_OUTPUT input) : COLOR0 { float4 finalColor = 0; - for (int i = 0; i < g_PointLightCount; i++) + for (int i = 0; i < g_PointLights.Count; i++) { - // Get light direction for this fragment - float3 lightDir = normalize(input.WorldPos - g_PointLightPosition[i]); // per pixel diffuse lighting + float3 worldPos = g_PointLights.Position[i] - input.WorldPos; + float3 lightDirection = normalize(input.WorldPos - (g_PointLights.Position[i])); - // Note: Non-uniform scaling not supported - float diffuseLighting = saturate(dot(input.Normal, -lightDir)); - - // Introduce fall-off of light intensity - diffuseLighting *= (g_PointLightRange[i] / dot(g_PointLightPosition[i] - input.WorldPos, g_PointLightPosition[i] - input.WorldPos)); - - float4 diffuseColor = diffuseLighting * g_PointLightDiffuse[i]; - - finalColor += diffuseColor; + finalColor += CalculatePointDiffuse( + worldPos, + input.Normal, + -lightDirection, + g_PointLights.Range[i], + g_PointLights.Diffuse[i]); } float3 texel = tex2D(g_LandTextureSampler, input.TextureUV); diff --git a/Shaders/fx/Object.fx b/Shaders/fx/Object.fx index d1df8cd..3dda853 100644 --- a/Shaders/fx/Object.fx +++ b/Shaders/fx/Object.fx @@ -1,23 +1,23 @@ #include "../fxh/Constants.fxh" #include "../fxh/Lighting.fxh" +#include "../fxh/Transform.fxh" +#include "../fxh/Fog.fxh" -shared texture g_Texture0 : Texture0; +shared texture g_Texture0; +shared texture g_Texture1; -shared float4 g_DirectionalLightAmbientSum; -shared float4 g_DirectionalLightDiffuse[MAX_DIRECTIONAL_LIGHTS]; -shared float3 g_DirectionalLightDirection[MAX_DIRECTIONAL_LIGHTS]; -shared float4 g_DirectionalLightSpecular[MAX_DIRECTIONAL_LIGHTS]; -shared int g_DirectionalLightCount; +shared DirectionalLightInfo g_DirectionalLights; shared Material g_Material; -shared float4x4 g_WorldViewProjection; -shared float4x4 g_WorldView; -shared float4x4 g_World; +shared WorldTransforms g_WorldTransforms; +shared float4x4 g_EnvironmentTextureTransform; shared float4 g_TextureFactor; -shared TextureBlendStage g_BlendStages[MAX_BLEND_STAGES]; -shared int g_BlendStageCount; -shared float3 g_CameraPosition; +shared BlendStageInfo g_BlendStages; + +shared ViewTransforms g_ViewTransforms; + +shared ColorMixMode g_ColorMixMode; sampler g_ObjTextureSampler : register(s0) = sampler_state @@ -28,49 +28,35 @@ sampler_state MagFilter = LINEAR; }; +sampler g_EnvTextureSampler = +sampler_state +{ + Texture = ; + MipFilter = LINEAR; + MinFilter = LINEAR; + MagFilter = LINEAR; +}; + +shared FogParams g_Fog; + // ======================================================= // Pixel and vertex lighting techniques // -float4 CalculateDiffuse(float3 N, float3 L, float4 diffuseColor) -{ - float NDotL = dot(N, L); - float4 finalColor = 0; - if (NDotL > 0.0f) - { - finalColor = max(0, NDotL * diffuseColor); - } - - return finalColor; -} - -float4 CalculateSpecular(float3 worldPos, float3 N, float3 L, float4 specularColor) -{ - float4 finalColor = 0; - if (g_Material.Power > 0) - { - float3 toEye = normalize(g_CameraPosition.xyz - worldPos); - float3 halfway = normalize(toEye + L); - float NDotH = saturate(dot(halfway, N)); - - finalColor = max(0, pow(NDotH, g_Material.Power) * specularColor); - } - - return finalColor; -} - Lighting DoDirectionalLight(float3 worldPos, float3 N, int i) { Lighting Out; - Out.Diffuse = CalculateDiffuse( + Out.Diffuse = CalculateDirectionalDiffuse( N, - -g_DirectionalLightDirection[i], - g_DirectionalLightDiffuse[i]); - Out.Specular = CalculateSpecular( + -g_DirectionalLights.Direction[i], + g_DirectionalLights.Diffuse[i]); + Out.Specular = CalculateDirectionalSpecular( worldPos, + g_ViewTransforms.CameraPosition.xyz, N, - -g_DirectionalLightDirection[i], - g_DirectionalLightSpecular[i]); + -g_DirectionalLights.Direction[i], + g_DirectionalLights.Specular[i], + g_Material.Power); return Out; } @@ -78,14 +64,14 @@ Lighting ComputeLighting(float3 worldPos, float3 N) { Lighting finalLighting = (Lighting)0; - for (int i = 0; i < g_DirectionalLightCount; i++) + for (int i = 0; i < g_DirectionalLights.Count; i++) { Lighting lighting = DoDirectionalLight(worldPos, N, i); finalLighting.Diffuse += lighting.Diffuse; finalLighting.Specular += lighting.Specular; } - float4 ambient = g_Material.Ambient * g_DirectionalLightAmbientSum; + float4 ambient = g_Material.Ambient * g_DirectionalLights.Ambient; float4 diffuse = g_Material.Diffuse * finalLighting.Diffuse; float4 specular = g_Material.Specular * finalLighting.Specular; @@ -101,23 +87,11 @@ struct PixelLightingVSOutput float2 Tex0 : TEXCOORD0; float3 Normal : TEXCOORD1; float3 WorldPos : TEXCOORD2; + float3 EnvMapTex : TEXCOORD3; + float4 BumpColor : TEXCOORD4; + float Fog : FOG; }; -PixelLightingVSOutput PixelLightingVS( - float4 vPosition : POSITION0, - float3 vNormal : NORMAL0, - float2 tc : TEXCOORD0) -{ - // Simple transform, pre-compute as much as we can for the pixel shader - PixelLightingVSOutput output; - - output.Pos = mul(vPosition, g_WorldViewProjection); - output.Normal = mul(normalize(vNormal), (float3x3)g_World); - output.WorldPos = mul(vPosition, g_World); - output.Tex0 = tc; - return output; -} - float4 GetColorArg(int colorArg, float4 textureColor, float4 diffuseColor) { float4 result; @@ -131,8 +105,8 @@ float4 GetColorArg(int colorArg, float4 textureColor, float4 diffuseColor) float4 Modulate(int stageIndex, float4 textureColor, float4 diffuseColor, float factor) { - float4 left = GetColorArg(g_BlendStages[stageIndex].colorArg1, textureColor, diffuseColor); - float4 right = GetColorArg(g_BlendStages[stageIndex].colorArg2, textureColor, diffuseColor); + float4 left = GetColorArg(g_BlendStages.BlendStages[stageIndex].colorArg1, textureColor, diffuseColor); + float4 right = GetColorArg(g_BlendStages.BlendStages[stageIndex].colorArg2, textureColor, diffuseColor); return (left * right) * factor; } @@ -140,15 +114,19 @@ float4 Modulate(int stageIndex, float4 textureColor, float4 diffuseColor, float float4 ProcessStages(float4 textureColor, float4 diffuseColor) { float4 output = 0; - for (int i = 0; i < g_BlendStageCount; i++) + for (int i = 0; i < g_BlendStages.Count; i++) { - if (g_BlendStages[i].colorOp == D3DTOP_MODULATE4X) + if (g_BlendStages.BlendStages[i].colorOp == D3DTOP_MODULATE4X || g_BlendStages.BlendStages[i].colorOp == D3DTOP_MODULATE) { - output += Modulate(i, textureColor, diffuseColor, 4.0f); + float modulateFactor = + (4.0f * (g_BlendStages.BlendStages[i].colorOp == D3DTOP_MODULATE4X)) + + (1.0f * (g_BlendStages.BlendStages[i].colorOp == D3DTOP_MODULATE)); + + output += Modulate(i, textureColor, diffuseColor, modulateFactor); } - else + else if (g_BlendStages.BlendStages[i].colorOp == D3DTOP_DOTPRODUCT3) { - output += Modulate(i, textureColor, diffuseColor, 1.0f); + output = float4(1, 0, 0, 1); } } @@ -160,15 +138,73 @@ struct PixelLightingPSOutput float4 Diffuse : COLOR0; }; -PixelLightingPSOutput PixelLightingPS(PixelLightingVSOutput input) +PixelLightingVSOutput PixelLightingVS( + float4 vPosition : POSITION0, + float3 vNormal : NORMAL0, + float4 color : COLOR0, + float2 tc : TEXCOORD0) +{ + // Simple transform, pre-compute as much as we can for the pixel shader + PixelLightingVSOutput output = (PixelLightingVSOutput)0; + + vNormal = normalize(vNormal); + output.Pos = mul(vPosition, g_WorldTransforms.WorldViewProjection); + output.Normal = mul(vNormal, (float3x3)g_WorldTransforms.World); + output.WorldPos = mul(vPosition, g_WorldTransforms.World); + output.Tex0 = tc; + output.BumpColor = color; + + float3 P = mul(vPosition, g_WorldTransforms.WorldView); + float d = length(P); + output.Fog = CalculateFogFactor(g_Fog.FogMax, g_Fog.FogMin, d); + + if (g_ColorMixMode.EnvironmentMappingEnabled) + { + // Generate cube texture coordinates + // DX9 FFP formula: R = 2(E dot N) * N - E + float3 E = normalize(g_ViewTransforms.CameraPosition.xyz - output.WorldPos); + float3 N = mul(vNormal, (float3x3)g_WorldTransforms.WorldView); + float4 R = float4((2.f * dot(E, N) * N - E), 0); + output.EnvMapTex = mul(g_EnvironmentTextureTransform, R); + } + + return output; +} + +float4 PixelLightingPS(PixelLightingVSOutput input) : COLOR0 { float4 color = tex2D(g_ObjTextureSampler, input.Tex0); Lighting lighting = ComputeLighting(input.WorldPos, input.Normal); - PixelLightingPSOutput output; - output.Diffuse = ProcessStages(color, lighting.Diffuse) + lighting.Specular; - return output; + // Emulate FFP texture stages + float4 finalColor = ProcessStages(color, lighting.Diffuse) + lighting.Specular; + + // Apply cubic environment mapping if enabled + if (g_ColorMixMode.EnvironmentMappingEnabled) + { + float4 envMapColor = texCUBE(g_EnvTextureSampler, input.EnvMapTex); + + if (g_BlendStages.BlendStages[1].colorOp == D3DTOP_BLENDFACTORALPHA) + finalColor = (finalColor * g_TextureFactor.a) + (envMapColor * (1 - g_TextureFactor.a)); + else if (g_BlendStages.BlendStages[1].colorOp == D3DTOP_BLENDCURRENTALPHA) + finalColor = float4(1, 0, 0, 0); + } + + // Apply linear pixel fog + if (g_Fog.Enabled) + { + finalColor = ApplyPixelFog(finalColor, input.Fog, g_Fog.Color); + } + + /* + if (input.BumpColor.r != 0) + { + finalColor = float4(1, 1, 1, 1); + } + */ + + return finalColor; } technique PixelLighting @@ -190,21 +226,18 @@ struct VertexLightingVSOutput float Fog : FOG; }; -float fFogStart = 25.f; -float fFogEnd = 1525.f; - VertexLightingVSOutput VertexLightingVS( float4 vPosition : POSITION0, float3 vNormal : NORMAL0, float4 color : COLOR0, - float2 tc : TEXCOORD0) + float2 tc : TEXCOORD0, + float fog : FOG) { VertexLightingVSOutput output; - output.Pos = mul(vPosition, g_WorldViewProjection); - output.Tex0 = tc; + output.Pos = mul(vPosition, g_WorldTransforms.WorldViewProjection); - float4 worldPos = mul(vPosition, g_World); - float3 normal = mul(normalize(vNormal), (float3x3)g_World); + float4 worldPos = mul(vPosition, g_WorldTransforms.World); + float3 normal = mul(normalize(vNormal), (float3x3)g_WorldTransforms.World); Lighting lighting = ComputeLighting(worldPos, normal); @@ -212,10 +245,8 @@ VertexLightingVSOutput VertexLightingVS( output.Specular = lighting.Specular; output.BumpColor = color; - float3 P = mul(vPosition, g_WorldView); - float d = length(P); - output.Fog = saturate((fFogEnd - d) / (fFogEnd - fFogStart)); - + output.Fog = fog; + output.Tex0 = tc; return output; } @@ -223,7 +254,7 @@ technique VertexLighting { pass P0 { - VertexShader = compile vs_3_0 VertexLightingVS(); + VertexShader = compile vs_2_0 VertexLightingVS(); } } @@ -254,14 +285,14 @@ ColorPerVertexVSOutput ColorPerVertexVS( // Simple transform, pre-compute as much as we can for the pixel shader ColorPerVertexVSOutput output = (ColorPerVertexVSOutput)0; - output.Pos = mul(vPosition, g_WorldViewProjection); + output.Pos = mul(vPosition, g_WorldTransforms.WorldViewProjection); output.Tex0 = tc; output.Color = color; - float3 P = mul(vPosition, g_WorldView); //position in view space + float3 P = mul(vPosition, g_WorldTransforms.WorldView); //position in view space float d = length(P); - output.Fog = saturate((fFogEnd - d) / (fFogEnd - fFogStart)); + output.Fog = fog; return output; } @@ -270,6 +301,6 @@ technique ColorPerVertex pass P0 { //PixelShader = compile ps_3_0 ColorPerVertexPS(); - VertexShader = compile vs_3_0 ColorPerVertexVS(); + VertexShader = compile vs_2_0 ColorPerVertexVS(); } } \ No newline at end of file diff --git a/Shaders/fx/ObjectVertexLighting.fx b/Shaders/fx/ObjectVertexLighting.fx deleted file mode 100644 index 2f0efce..0000000 --- a/Shaders/fx/ObjectVertexLighting.fx +++ /dev/null @@ -1,239 +0,0 @@ -#include "../fxh/Constants.fxh" -#include "../fxh/Lighting.fxh" - -// Lighting state -float4 g_DirectionalLightAmbient[MAX_DIRECTIONAL_LIGHTS] : DirectionalLightAmbient; -float4 g_DirectionalLightDiffuse[MAX_DIRECTIONAL_LIGHTS] : DirectionalLightDiffuse; -float3 g_DirectionalLightDirection[MAX_DIRECTIONAL_LIGHTS] : DirectionalLightDirection; -bool g_DirectionalLightEnabled[MAX_DIRECTIONAL_LIGHTS] : DirectionalLightEnabled; -float4 g_DirectionalLightSpecular[MAX_DIRECTIONAL_LIGHTS] : DirectionalLightSpecular; - -texture g_ObjTexture : ObjTexture; -sampler g_ObjTextureSampler = -sampler_state -{ - Texture = ; - MipFilter = LINEAR; - MinFilter = LINEAR; - MagFilter = LINEAR; -}; - -// Camera -float3 g_CameraPosition : CameraPosition; - -// Current material -Material g_Material : Material; - -// Transforms -float4x4 g_WorldViewProjection : WorldViewProjection; -float4x4 g_World : World; - -struct VSOutputLit -{ - float4 Pos : POSITION; - float4 Diffuse : COLOR0; - float4 Specular : COLOR1; - float4 Tex0 : TEXCOORD0; - float3 Normal : TEXCOORD1; - float3 WorldPos : TEXCOORD2; -}; - -struct VSOutput -{ - float4 Pos : POSITION; - float4 Tex0 : TEXCOORD0; - float3 Normal : TEXCOORD1; - float3 WorldPos : TEXCOORD2; -}; - -float4 CalculateAmbientLight() -{ - float4 ambient = 0; - for (int i = 0; i < MAX_DIRECTIONAL_LIGHTS; i++) - { - if (g_DirectionalLightEnabled[i]) - { - ambient += g_DirectionalLightAmbient[i]; - } - } - - return ambient; -} - -float4 CalculateDiffuse(float3 N, float3 L, float4 diffuseColor) -{ - float NDotL = dot(N, L); - float4 finalColor = 0; - if (NDotL > 0.0f) - { - finalColor = max(0, NDotL * diffuseColor); - } - - return finalColor; -} - -float4 CalculateSpecular(float3 worldPos, float3 N, float3 L, float4 specularColor) -{ - float4 finalColor = 0; - if (g_Material.Power > 0) - { - float3 toEye = normalize(g_CameraPosition.xyz - worldPos); - float3 halfway = normalize(toEye + L); - float NDotH = saturate(dot(halfway, N)); - - finalColor = max(0, pow(NDotH, g_Material.Power) * specularColor); - } - - return finalColor; -} - -Lighting DoDirectionalLight(float3 worldPos, float3 N, int i) -{ - Lighting Out; - Out.Diffuse = CalculateDiffuse( - N, - -g_DirectionalLightDirection[i], - g_DirectionalLightDiffuse[i]); - Out.Specular = CalculateSpecular( - worldPos, - N, - -g_DirectionalLightDirection[i], - g_DirectionalLightSpecular[i]); - return Out; -} - -Lighting ComputeLighting(float3 worldPos, float3 N) -{ - Lighting finalLighting = (Lighting)0; - - for (int i = 0; i < MAX_DIRECTIONAL_LIGHTS; i++) - { - if (g_DirectionalLightEnabled[i]) - { - Lighting lighting = DoDirectionalLight(worldPos, N, i); - finalLighting.Diffuse += lighting.Diffuse; - finalLighting.Specular += lighting.Specular; - } - } - - float4 ambient = g_Material.Ambient * CalculateAmbientLight(); - float4 diffuse = g_Material.Diffuse * finalLighting.Diffuse; - float4 specular = g_Material.Specular * finalLighting.Specular; - - finalLighting.Diffuse = saturate(ambient + diffuse); - finalLighting.Specular = saturate(specular); - - return finalLighting; -} - -//----------------------------------------------------------------------------- -// Name: DoPointLight() -// Desc: Point light computation -//----------------------------------------------------------------------------- -//COLOR_PAIR DoPointLight(float4 vPosition, float3 N, float3 V, int i) -//{ -// float3 L = mul((float3x3)matViewIT, normalize((lights[i].vPos-(float3)mul(matWorld,vPosition)))); -// COLOR_PAIR Out; -// float NdotL = dot(N, L); -// Out.Color = lights[i].vAmbient; -// Out.Specular = 0; -// float fAtten = 1.f; -// if(NdotL >= 0.f) -// { -// //compute diffuse color -// Out.Color += NdotL * lights[i].vDiffuse; -// -// //add specular component -// if(bSpecular) -// { -// float3 H = normalize(L + V); //half vector -// Out.Specular = pow(max(0, dot(H, N)), fMaterialPower) * lights[i].vSpecular; -// } -// -// float LD = length(lights[i].vPos-(float3)mul(matWorld,vPosition)); -// if(LD > lights[i].fRange) -// { -// fAtten = 0.f; -// } -// else -// { -// fAtten *= 1.f/(lights[i].vAttenuation.x + lights[i].vAttenuation.y*LD + lights[i].vAttenuation.z*LD*LD); -// } -// Out.Color *= fAtten; -// Out.Specular *= fAtten; -// } -// return Out; -//} - -VSOutputLit VSMainLighting( - float4 vPosition : POSITION0, - float3 vNormal : NORMAL0, - float2 tc : TEXCOORD0) -{ - VSOutputLit Out = (VSOutputLit)0; - - vNormal = normalize(vNormal); - Out.Pos = mul(vPosition, g_WorldViewProjection); - - //automatic texture coordinate generation - Out.Tex0.xy = tc; - - //directional lights - float4 worldPos = mul(vPosition, g_World); //position in view space - float3 normal = mul(vNormal, (float3x3)g_World); - Lighting lighting = ComputeLighting(worldPos, normal); - - ////point lights - //for(int i = 0; i < iLightPointNum; i++) - //{ - // COLOR_PAIR ColOut = DoPointLight(vPosition, N, V, i+iLightPointIni); - // Out.Color += ColOut.Color; - // Out.Specular += ColOut.Specular; - //} - - Out.Diffuse = lighting.Diffuse; - Out.Specular = lighting.Specular; - - return Out; -} - -VSOutput VSMain( - float4 vPosition : POSITION0, - float3 vNormal : NORMAL0, - float2 tc : TEXCOORD0) -{ - VSOutput Out = (VSOutput)0; - Out.Pos = mul(vPosition, g_WorldViewProjection); - Out.Normal = normalize(vNormal); - Out.WorldPos = mul(vPosition, g_World); - Out.Tex0.xy = tc; - return Out; -} - -float4 PSMain(VSOutput input) : COLOR0 -{ - float4 color = tex2D(g_ObjTextureSampler, input.Tex0); - - Lighting lighting = ComputeLighting(input.WorldPos, input.Normal); - - color = (lighting.Diffuse + lighting.Specular) * color; - return color; -} - -technique TexturedVertexLighting -{ - pass P0 - { - //PixelShader = compile ps_2_0 ps_main(); - VertexShader = compile vs_2_0 VSMainLighting(); - } -} - -technique TexturedPixelLighting -{ - pass P0 - { - PixelShader = compile ps_2_0 PSMain(); - VertexShader = compile vs_2_0 VSMain(); - } -} \ No newline at end of file diff --git a/Shaders/fx/Ocean.fx b/Shaders/fx/Ocean.fx index 7fafe8f..da905e9 100644 --- a/Shaders/fx/Ocean.fx +++ b/Shaders/fx/Ocean.fx @@ -1,63 +1,86 @@ //-------------------------------------------------------------------------------------- -// Water.fx +// Ocean.fx // Ocean water reflection shader. //-------------------------------------------------------------------------------------- -/* Original asm code: - ps_1_1 - tex t0 - tex t1 - lrp r0, -v0.w, t0, t1 // lrp = linear interpolate -*/ +#include "../fxh/Transform.fxh" +#include "../fxh/Fog.fxh" -shared texture g_Texture0; -shared texture g_Texture1; +shared texture g_Texture0; // Seabed texture +shared texture g_Texture1; // Environment texture + +shared WorldTransforms g_WorldTransforms; +shared ViewTransforms g_ViewTransforms; + +shared FogParams g_Fog; struct PS_INPUT { float4 color : COLOR0; float4 texCoord0 : TEXCOORD0; float4 texCoord1 : TEXCOORD1; + float Fog : FOG; }; -sampler s0, s1; +sampler g_SeabedSampler : register(s0) = sampler_state +{ + Texture = ; + MipFilter = LINEAR; + MinFilter = LINEAR; + MagFilter = LINEAR; +}; + +sampler g_EnvironmentSampler = sampler_state +{ + Texture = ; + MipFilter = LINEAR; + MinFilter = LINEAR; + MagFilter = LINEAR; +}; float4 MainPS(const PS_INPUT input) : COLOR0 { // Interpolate linearly between Environment Texture, seabed, and inverted alpha of current pixel - return lerp(tex2D(s1, input.texCoord1), tex2D(s0, input.texCoord0), 1-input.color.a); + float4 result = lerp(texCUBE(g_EnvironmentSampler, input.texCoord1), tex2D(g_SeabedSampler, input.texCoord0.xy), 1-input.color.a); + + // Note: fog disabled for now as it doesn't quite match up with FFP fog. + /* + if (g_Fog.Enabled) + { + result = ApplyPixelFog(result, input.Fog, g_Fog.Color); + } + */ + + return result; } -// C45: {0.00333, 0, 0, 0} -// C44: -// C27: {0, 1.0, 0.5, 0.25} -// C26: {minfog, maxfog, 1.0f / (maxfog - minfog), 1.0} - +// C44: (dynamic) float4 const44 : register(c44); -shared matrix g_OceanWorldViewProjection : OceanWorldViewProjection : register(c2); -float4 fog : register (c26); struct VS_OUTPUT { float4 pos : POSITION; + float4 texCoord0 : TEXCOORD0; float4 texCoord1 : TEXCOORD1; + float4 color : COLOR0; + float Fog : FOG; }; struct VS_INPUT { float4 pos : POSITION; + float4 texCoord0 : TEXCOORD0; }; VS_OUTPUT MainVS(const VS_INPUT input) { - float4 const27 = {0.0f, 1.0f, 0.5f, 0.75f}; - VS_OUTPUT output; + VS_OUTPUT output = (VS_OUTPUT)0; - output.pos = mul(input.pos, g_OceanWorldViewProjection); + output.pos = mul(input.pos, g_WorldTransforms.WorldViewProjection); // add r0, v0, -c44 - float4 r0 = input.pos + -const44; + float4 r0 : register(r0) = input.pos + -const44; // mov r0.z, -r0.z r0.z = -r0.z; @@ -68,78 +91,88 @@ VS_OUTPUT MainVS(const VS_INPUT input) // rsq r0.w, r0.w r0.w = rsqrt(r0.w); - // mul oT1.x, -r0, r0.w // mul oT1.y, r0, r0.w // mul oT1.z, r0, r0.w // mov oT1.w, c27.y - output.texCoord1.x = -r0 * r0.w; - output.texCoord1.y = r0 * r0.w; - output.texCoord1.z = r0 * r0.w; - output.texCoord1.w = const27.y; - + output.texCoord1.x = r0.w * -r0.x; + output.texCoord1.y = r0.w * r0.y; + output.texCoord1.z = r0.w * r0.z; + output.texCoord1.w = 1.0f; + + //rcp r0.w, r0.w + r0.w = 1.0f / r0.w; + + //mul r0.w, r0.w, c45.x + //max r0.x, r0.w, c27.x + //min oD0.w, r0.w, c27.y + //mov oT0, v2 + r0.w = r0.w * 0.00033333333f; + output.color.a = min(r0.w, 1.0); + output.texCoord0 = input.texCoord0; + + /* + float3 P = mul(input.pos, g_WorldTransforms.WorldView); + float d = length(P); + output.Fog = CalculateFogFactor(g_Fog.FogMax, g_Fog.FogMin, d); + */ + return output; } -technique t0 +technique ReflectionLow { - pass p0 + pass P0 { - Texture[0] = ; // Seabed texture - Texture[1] = ; // Environment texture - - // All of these constants are set by the game engine before drawing the shader - // Each constant register (c# in the asm code) has 4 floating point values - - // Special world * view * projection matrix for ocean shader - VertexShaderConstant[2] = ; - VertexShaderConstant[3] = ; - VertexShaderConstant[4] = ; - VertexShaderConstant[5] = ; - - VertexShaderConstant[26] = ; // This constant is calculated from the current fog min/max values - VertexShaderConstant[27] = {0.0f, 1.0f, 0.5f, 0.75f}; // I don't know what this does but it doesn't change - VertexShaderConstant[44] = ; // I don't know what this is - VertexShaderConstant[45] = {0.00033333333f, 0, 0, 0}; // I don't know what this does but it doesn't change -#if 1 // 1 to use asm shader - VertexShader = - asm - { - vs_1_1 - dcl_position v0 - dcl_texcoord v2 - - /* Places the dot product of the world view matrix and v0 in the output register oPos */ - dp4 oPos.x, v0, c2 - dp4 oPos.y, v0, c3 - dp4 oPos.z, v0, c4 - dp4 oPos.w, v0, c5 - - // this is some kind of vector normalization or transform - add r0, v0, -c44 - mov r0.z, -r0.z - dp3 r0.w, r0, r0 - rsq r0.w, r0.w - - /* Output register for texture 1 (environment texture) is modified by register 0 */ - mul oT1.x, -r0, r0.w - mul oT1.y, r0, r0.w - mul oT1.z, r0, r0.w - mov oT1.w, c27.y - - rcp r0.w, r0.w - mul r0.w, r0.w, c45.x - max r0.x, r0.w, c27.x - min oD0.w, r0.w, c27.y - mov oT0, v2 - dp4 r0.z, v0, c5 - add r0.x, -r0.z, c26.y - mul oFog, r0.x, c26.z - }; -#else - VertexShader = compile vs_1_1 MainVS(); -#endif - - PixelShader = compile ps_1_3 MainPS(); // effect will not work > ps 1.3 + VertexShader = compile vs_2_0 MainVS(); + PixelShader = compile ps_2_0 MainPS(); } } + +struct ReflectionHighVSOutput +{ + float4 pos : POSITION; + float4 texCoord0 : TEXCOORD0; + float4 texCoord1 : TEXCOORD1; + float4 color : COLOR0; + float Fog : FOG; + float3 Normal : TEXCOORD2; + float3 Reflection : TEXCOORD3; +}; + +struct ReflectionHighVSInput +{ + float4 pos : POSITION; + float4 texCoord0 : TEXCOORD0; + float3 Normal : NORMAL0; +}; + +ReflectionHighVSOutput ReflectionHighVS(const ReflectionHighVSInput input) +{ + ReflectionHighVSOutput output = (ReflectionHighVSOutput)0; + + output.pos = mul(input.pos, g_WorldTransforms.WorldViewProjection); + output.Normal = normalize(input.Normal); + + float3 normal = normalize(mul(input.Normal, g_WorldTransforms.WorldInverseTranspose)); + float3 viewDirection = g_ViewTransforms.CameraPosition - mul(input.pos, g_WorldTransforms.World); + output.Reflection = reflect(-normalize(viewDirection), normal); + return output; +} + +float4 ReflectionHighPS(ReflectionHighVSOutput input) : COLOR0 +{ + return texCUBE(g_EnvironmentSampler, normalize(input.Reflection)); + +} + +technique ReflectionHigh +{ + pass P0 + { + VertexShader = compile vs_2_0 ReflectionHighVS(); + PixelShader = compile ps_2_0 ReflectionHighPS(); + //VertexShader = compile vs_2_0 MainVS(); + //PixelShader = compile ps_2_0 MainPS(); + } +} \ No newline at end of file diff --git a/Shaders/fx/Sky.fx b/Shaders/fx/Sky.fx index c3ddc6c..7f8f43f 100644 --- a/Shaders/fx/Sky.fx +++ b/Shaders/fx/Sky.fx @@ -4,10 +4,9 @@ // Experimental sky shader. Does nothing currently. //-------------------------------------------------------------------------------------- -float4x4 g_mWorldViewProjection : WorldViewProjection; -float4x4 g_World : World; -float4x4 g_View : View; -float4x4 g_Projection : Projection; +#include "../fxh/Transform.fxh" + +shared WorldTransforms g_WorldTransforms; float intensityThreshold = 1.f; float colorMultiplier = 1.f; texture g_SkyTexture; @@ -28,7 +27,7 @@ void RenderSceneVS( out float4 oColor0 : COLOR0, out float2 oTexCoord0 : TEXCOORD0 ) { - oPosition = mul(iPosition, g_mWorldViewProjection); + oPosition = mul(iPosition, g_WorldTransforms.WorldViewProjection); oColor0 = float4(1, 1, 1, 1); oTexCoord0 = iTexCoord0; } diff --git a/Shaders/fx/Water.fx b/Shaders/fx/Water.fx index 3a9d070..ee25087 100644 --- a/Shaders/fx/Water.fx +++ b/Shaders/fx/Water.fx @@ -5,12 +5,24 @@ // the original fixed-function water rendering behavior. //-------------------------------------------------------------------------------------- -//#include "../fxh/SystemVariables.fxh" +#include "../fxh/Transform.fxh" +#include "../fxh/Lighting.fxh" +#include "../fxh/Fog.fxh" shared texture g_Texture0; -shared float4x4 g_WorldViewProjection; +shared WorldTransforms g_WorldTransforms; +shared ViewTransforms g_ViewTransforms; + shared float4 g_TextureFactor; +const float3 g_WaterNormal = float3(0, 0, 1); // Water is always a flat plane currently, so we can just hardcode this to (0, 0, 1) +shared Material g_WaterMaterial; + +shared PointLightInfo g_PointLights; +shared DirectionalLightInfo g_DirectionalLights; + +shared FogParams g_Fog; + sampler2D g_WaterTextureSampler = sampler_state { @@ -22,31 +34,66 @@ struct VS_OUTPUT float4 Position : POSITION; // vertex position float2 TextureUV : TEXCOORD0; // vertex texture coords float4 Color : COLOR0; + float Fog : FOG; + float3 WorldPos : TEXCOORD1; + /*float3 Normal : TEXCOORD1;*/ + float3 ViewDirection : TEXCOORD2; }; VS_OUTPUT RenderSceneVS(float4 inPos : POSITION, float4 inDiffuse : COLOR0, - float4 inTextureUV : TEXCOORD0) + float4 inTextureUV : TEXCOORD0 + /*float3 Normal : NORMAL*/) { VS_OUTPUT Output; - Output.Position = mul(inPos, g_WorldViewProjection); + Output.Position = mul(inPos, g_WorldTransforms.WorldViewProjection); Output.TextureUV = inTextureUV; Output.Color = inDiffuse; - // Don't think this is right, but we can use FFP fog unless this is compiled for SM 3.0 - //float4 r0; - //r0.z = inPos.z * g_WorldViewProjection[3]; - //r0.x = -r0.z + g_Fog.y; - //Output.Fog.x = r0.x * g_Fog.z; + float3 P = mul(inPos, g_WorldTransforms.WorldView); + float d = length(P); + Output.Fog = CalculateFogFactor(g_Fog.FogMax, g_Fog.FogMin, d); + //Output.Normal = mul(Normal, (float3x3)g_WorldTransforms.World); + + Output.WorldPos = mul(inPos, g_WorldTransforms.World); + Output.ViewDirection = g_ViewTransforms.CameraPosition - Output.WorldPos; return Output; } float4 RenderScenePS(VS_OUTPUT input) : COLOR0 -{ +{ float4 texel = tex2D(g_WaterTextureSampler, input.TextureUV); float4 result = saturate(texel + (1 - texel) * g_TextureFactor); // equivalent to saturate((texel + g_TextureFactor) - (texel * g_TextureFactor)); + + float3 reflection = -reflect(normalize(-g_DirectionalLights.Direction[g_DirectionalLights.SunIndex]), g_WaterNormal); + float specular = dot(normalize(reflection), normalize(input.ViewDirection)); + + if (specular > 0.0f) + { + specular = pow(specular, g_WaterMaterial.Power); + result = saturate(result + (specular)); + } + + for (int i = 0; i < g_PointLights.Count; i++) + { + float3 worldPos = g_PointLights.Position[i] - input.WorldPos; + float3 lightDirection = normalize(input.WorldPos - (g_PointLights.Position[i])); + + result += CalculatePointDiffuse( + worldPos, + g_WaterNormal, + -lightDirection, + g_PointLights.Range[i], + g_PointLights.Diffuse[i]); + } + + if (g_Fog.Enabled) + { + result = ApplyPixelFog(result, input.Fog, g_Fog.Color); + } + result.a = input.Color.a * g_TextureFactor.a; return result; @@ -56,7 +103,7 @@ technique RenderScene { pass P0 { - VertexShader = compile vs_2_0 RenderSceneVS(); - PixelShader = compile ps_2_0 RenderScenePS(); + VertexShader = compile vs_3_0 RenderSceneVS(); + PixelShader = compile ps_3_0 RenderScenePS(); } } \ No newline at end of file diff --git a/Shaders/fxh/Constants.fxh b/Shaders/fxh/Constants.fxh index 9bfc462..479cf55 100644 --- a/Shaders/fxh/Constants.fxh +++ b/Shaders/fxh/Constants.fxh @@ -1,5 +1,5 @@ #define MAX_DIRECTIONAL_LIGHTS 3 -#define MAX_LIGHTS 4 +#define MAX_POINT_LIGHTS 4 #define MAX_BLEND_STAGES 2 // Giants does not currently use more than 2 @@ -42,9 +42,9 @@ // where each component has been scaled and offset to make it signed. // The result is replicated into all four (including alpha) channels. // This is a valid COLOROP only. -#define D3DTOP_DOTPRODUCT3 24, +#define D3DTOP_DOTPRODUCT3 24 // Triadic ops -#define D3DTOP_MULTIPLYADD 25, // Arg0 + Arg1*Arg2 +#define D3DTOP_MULTIPLYADD 25 // Arg0 + Arg1*Arg2 #define D3DTOP_LERP 26 // (Arg0)*Arg1 + (1-Arg0)*Arg2 /* diff --git a/Shaders/fxh/Fog.fxh b/Shaders/fxh/Fog.fxh new file mode 100644 index 0000000..216908c --- /dev/null +++ b/Shaders/fxh/Fog.fxh @@ -0,0 +1,17 @@ +struct FogParams +{ + float FogMin; + float FogMax; + float3 Color; + int Enabled; +}; + +float CalculateFogFactor(float fogMax, float fogMin, float d) +{ + return saturate((fogMax - d) / (fogMax - fogMin)); +} + +float4 ApplyPixelFog(float4 pixelColor, float fogFactor, float3 fogColor) +{ + return (fogFactor * pixelColor) + (1.0 - fogFactor) * float4(fogColor, 1); +} \ No newline at end of file diff --git a/Shaders/fxh/Lighting.fxh b/Shaders/fxh/Lighting.fxh index fea7e28..d5981a8 100644 --- a/Shaders/fxh/Lighting.fxh +++ b/Shaders/fxh/Lighting.fxh @@ -1,3 +1,5 @@ +#include "Constants.fxh" + struct Material { float4 Diffuse; @@ -13,6 +15,24 @@ struct Lighting float4 Specular : COLOR1; }; +struct DirectionalLightInfo +{ + int Count; + int SunIndex; + float4 Ambient; + float4 Diffuse[MAX_DIRECTIONAL_LIGHTS]; + float4 Specular[MAX_DIRECTIONAL_LIGHTS]; + float4 Direction[MAX_DIRECTIONAL_LIGHTS]; +}; + +struct PointLightInfo +{ + int Count; + float4 Position[MAX_POINT_LIGHTS]; + float4 Diffuse[MAX_POINT_LIGHTS]; + float Range[MAX_POINT_LIGHTS]; +}; + struct TextureBlendStage { int colorOp; @@ -21,4 +41,51 @@ struct TextureBlendStage int alphaOp; int alphaArg1; int alphaArg2; -}; \ No newline at end of file +}; + +struct BlendStageInfo +{ + int Count; + TextureBlendStage BlendStages[MAX_BLEND_STAGES]; +}; + +struct ColorMixMode +{ + int BumpMappingEnabled; + int EnvironmentMappingEnabled; +}; + +float4 CalculateDirectionalDiffuse(float3 N, float3 L, float4 diffuseColor) +{ + float NDotL = dot(N, L); + float4 finalColor = 0; + if (NDotL > 0.0f) + { + finalColor = max(0, NDotL * diffuseColor); + } + + return finalColor; +} + +float4 CalculateDirectionalSpecular(float3 worldPos, float3 cameraPosition, float3 N, float3 L, float4 specularColor, float specularPower) +{ + float4 finalColor = 0; + if (specularPower) + { + float3 toEye = normalize(cameraPosition - worldPos); + float3 halfway = normalize(toEye + L); + float NDotH = saturate(dot(halfway, N)); + + finalColor = max(0, pow(NDotH, specularPower) * specularColor); + } + + return finalColor; +} + +inline float4 CalculatePointDiffuse(float3 worldPos, float3 N, float3 L, float range, float4 diffuseColor) +{ + float diffuseLighting = saturate(dot(N, L)); + + diffuseLighting *= (range / dot(worldPos, worldPos)); + return diffuseLighting * diffuseColor; +} \ No newline at end of file diff --git a/Shaders/fxh/Transform.fxh b/Shaders/fxh/Transform.fxh new file mode 100644 index 0000000..adee79b --- /dev/null +++ b/Shaders/fxh/Transform.fxh @@ -0,0 +1,16 @@ +struct WorldTransforms +{ + float4x4 World; + float4x4 WorldInverse; + float4x4 WorldInverseTranspose; + float4x4 WorldView; + float4x4 WorldViewProjection; + float4x4 WorldViewProjectionTranspose; +}; + +struct ViewTransforms +{ + float4x4 View; + float4x4 ViewInverse; + float3 CameraPosition; +}; \ No newline at end of file