1
0
mirror of https://github.com/ncblakely/GiantsTools synced 2024-11-21 21:55:38 +01:00

Update shaders

This commit is contained in:
Nick Blakely 2020-11-30 17:40:33 -08:00
parent 11625b367c
commit ac7a8eb4ba
10 changed files with 652 additions and 537 deletions

View File

@ -6,21 +6,26 @@
#include "../fxh/Constants.fxh" #include "../fxh/Constants.fxh"
#include "../fxh/Lighting.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_Texture0;
shared texture g_Texture1; shared texture g_Texture1;
shared float4x4 g_WorldViewProjection; shared texture g_Texture2;
shared float4x4 g_World;
shared float4x4 g_TexGenMatrix0; shared float4x4 g_TexGenMatrix0;
shared float4x4 g_TexGenMatrix1; shared float4x4 g_TexGenMatrix1;
shared float4x4 g_TexGenMatrix2;
shared float4 g_PointLightDiffuse[MAX_LIGHTS]; shared DirectionalLightInfo g_DirectionalLights;
shared float3 g_PointLightPosition[MAX_LIGHTS]; shared PointLightInfo g_PointLights;
shared float g_PointLightRange[MAX_LIGHTS];
shared int g_PointLightCount;
//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; MagFilter = LINEAR;
}; };
//sampler g_LandDetailTextureSampler = sampler g_LandDetailTextureSampler =
//sampler_state sampler_state
//{ {
// Texture = <g_LandDetailTexture>; Texture = <g_Texture2>;
// MipFilter = LINEAR; MipFilter = LINEAR;
// MinFilter = LINEAR; MinFilter = LINEAR;
// MagFilter = LINEAR; MagFilter = LINEAR;
//}; };
//
//sampler g_ShoreTextureSampler =
//sampler_state
//{
// Texture = <g_LandBumpTexture>;
// MipFilter = LINEAR;
// MinFilter = LINEAR;
// MagFilter = LINEAR;
//};
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
// Vertex shader output structure // Vertex shader output structure
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
struct VS_OUTPUT_BUMP struct LandBumpDetailVSOutput
{ {
float4 Position : POSITION; float4 Position : POSITION;
float4 LandBumpDiffuse : COLOR1; float4 LandBumpDiffuse : COLOR1;
float4 LandDiffuse : COLOR0; float4 LandDiffuse : COLOR0;
float2 LandBumpTextureUV : TEXCOORD0; float2 LandBumpTextureUV : TEXCOORD0;
float2 LandTextureUV : TEXCOORD1; float2 LandTextureUV : TEXCOORD1;
float3 WorldPos : TEXCOORD2; float2 LandDetailTextureUV : TEXCOORD2;
float3 Normal : TEXCOORD3; float3 WorldPos : TEXCOORD3;
//float3 ShoreTextureUV : TEXCOORD4; 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 CalculateDetailTexture(float3 worldPos, float4 originalColor, float2 detailTextureUV)
float4 vPos : POSITION,
float3 vNormal : NORMAL,
float4 vDiffuse : COLOR0,
float4 vDiffuse2 : COLOR1)
{ {
VS_OUTPUT_BUMP Output; if (detailTextureUV.x != 0 || detailTextureUV.y != 0)
{
float distance = length(worldPos - g_ViewTransforms.CameraPosition);
if (distance < g_DetailFadeEnd)
{
float4 detailTextureColor = tex2D(g_LandDetailTextureSampler, detailTextureUV) * 1.8f;
if (distance > g_DetailFadeStart)
{
float distNormalized = distance / (g_DetailFadeEnd - g_DetailFadeStart);
detailTextureColor = lerp(detailTextureColor, float4(1.f, 1.f, 1.f, 1.f), distNormalized);
}
originalColor *= detailTextureColor;
}
}
return originalColor;
}
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 // Transform the position from object space to homogeneous projection space
Output.Position = mul(vPos, g_WorldViewProjection); output.Position = mul(position, g_WorldTransforms.WorldViewProjection);
Output.LandBumpDiffuse = vDiffuse2 * .5f; output.LandDiffuse = landDiffuse * .5f;
Output.LandBumpDiffuse.a = 1.0f; output.LandDiffuse.a = 1.0f;
Output.LandDiffuse.rgb = vDiffuse; output.LandBumpDiffuse.rgb = landBumpDiffuse;
Output.LandDiffuse.a = 1.0f; output.LandBumpDiffuse.a = 1.0f;
Output.WorldPos = mul(vPos, g_World); output.WorldPos = mul(position, g_WorldTransforms.World);
// Set dynamically generated tex coords // Set dynamically generated tex coords
Output.LandBumpTextureUV = mul(vPos, g_TexGenMatrix0); output.LandBumpTextureUV = mul(position, g_TexGenMatrix0);
Output.LandTextureUV = mul(vPos, g_TexGenMatrix1); output.LandTextureUV = mul(position, g_TexGenMatrix1);
//Output.ShoreTextureUV = mul(vPos, g_texGenMatrix2); 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 // Transform the normal from object space to world space
Output.Normal = normalize(mul(vNormal, (float3x3)g_World)); // normal (world space) output.Normal = normalize(mul(normal, (float3x3)g_WorldTransforms.World)); // normal (world space)
return Output; return output;
} }
float4 LandBumpPS(VS_OUTPUT_BUMP input) : COLOR0 float4 CalculateDot3BumpMap(float4 diffuseColor, float2 uv)
{ {
float4 normal = bx2(tex2D(g_LandBumpTextureSampler, input.LandBumpTextureUV)); float4 landBumpTextureColor = bx2(tex2D(g_LandBumpTextureSampler, uv));
float4 normalcol = bx2(input.LandDiffuse); diffuseColor = bx2(diffuseColor);
float3 normalMap; float4 bumpMapColor;
normalMap = saturate((float4)dot((float3)normal, (float3)normalcol)).xyz; bumpMapColor.xyz = saturate(dot(landBumpTextureColor, diffuseColor.rgb));
float3 finalColor = 2.0 * (normalMap * (tex2D(g_LandTextureSampler, input.LandTextureUV)) + input.LandBumpDiffuse); bumpMapColor.w = 1.0f;
for (int i = 0; i < g_PointLightCount; i++) return bumpMapColor;
}
struct TNBFrame
{ {
// Get light direction for this fragment float3 Tangent;
float3 lightDir = normalize(input.WorldPos - g_PointLightPosition[i]); // per pixel diffuse lighting float3 Normal;
float3 Binormal;
};
// Note: Non-uniform scaling not supported /*
float diffuseLighting = saturate(dot(input.Normal, -lightDir)); TNBFrame CalculateTNBFrame(float3 worldPos, float3 N, float2 uv)
{
float3 dp1 = ddx(worldPos);
float3 dp2 = ddy(worldPos);
float2 duv1 = ddx(uv);
float2 duv2 = ddy(uv);
// 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]; 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;
finalColor += diffuseColor; 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;
} }
return float4(finalColor, 1); 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;
} }
technique LandBump 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 pass P0
{ {
VertexShader = compile vs_2_0 LandBumpVS(); VertexShader = compile vs_3_0 LandBumpDetailVS();
PixelShader = compile ps_2_0 LandBumpPS(); PixelShader = compile ps_3_0 LandBumpDetailPS();
} }
} }
@ -162,6 +291,14 @@ struct VS_OUTPUT
float3 WorldPos : TEXCOORD2; float3 WorldPos : TEXCOORD2;
}; };
matrix Identity =
{
{ 1, 0, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 0, 1, 0 },
{ 0, 0, 0, 1 }
};
VS_OUTPUT LandscapeVS( VS_OUTPUT LandscapeVS(
float4 vPos : POSITION, float4 vPos : POSITION,
float3 vNormal : NORMAL, float3 vNormal : NORMAL,
@ -170,17 +307,27 @@ VS_OUTPUT LandscapeVS(
VS_OUTPUT Output; VS_OUTPUT Output;
// Transform the position from object space to homogeneous projection space // 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 // 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.rgb = vDiffuse;
Output.Diffuse.a = 1.0f; 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 // 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); Output.TextureUV = mul(vPos, g_TexGenMatrix0);
return Output; return Output;
@ -190,20 +337,17 @@ float4 LandscapePS(VS_OUTPUT input) : COLOR0
{ {
float4 finalColor = 0; 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 worldPos = g_PointLights.Position[i] - input.WorldPos;
float3 lightDir = normalize(input.WorldPos - g_PointLightPosition[i]); // per pixel diffuse lighting float3 lightDirection = normalize(input.WorldPos - (g_PointLights.Position[i]));
// Note: Non-uniform scaling not supported finalColor += CalculatePointDiffuse(
float diffuseLighting = saturate(dot(input.Normal, -lightDir)); worldPos,
input.Normal,
// Introduce fall-off of light intensity -lightDirection,
diffuseLighting *= (g_PointLightRange[i] / dot(g_PointLightPosition[i] - input.WorldPos, g_PointLightPosition[i] - input.WorldPos)); g_PointLights.Range[i],
g_PointLights.Diffuse[i]);
float4 diffuseColor = diffuseLighting * g_PointLightDiffuse[i];
finalColor += diffuseColor;
} }
float3 texel = tex2D(g_LandTextureSampler, input.TextureUV); float3 texel = tex2D(g_LandTextureSampler, input.TextureUV);

View File

@ -1,23 +1,23 @@
#include "../fxh/Constants.fxh" #include "../fxh/Constants.fxh"
#include "../fxh/Lighting.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 DirectionalLightInfo g_DirectionalLights;
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 Material g_Material; shared Material g_Material;
shared float4x4 g_WorldViewProjection; shared WorldTransforms g_WorldTransforms;
shared float4x4 g_WorldView; shared float4x4 g_EnvironmentTextureTransform;
shared float4x4 g_World;
shared float4 g_TextureFactor; shared float4 g_TextureFactor;
shared TextureBlendStage g_BlendStages[MAX_BLEND_STAGES]; shared BlendStageInfo g_BlendStages;
shared int g_BlendStageCount;
shared float3 g_CameraPosition; shared ViewTransforms g_ViewTransforms;
shared ColorMixMode g_ColorMixMode;
sampler g_ObjTextureSampler : register(s0) = sampler g_ObjTextureSampler : register(s0) =
sampler_state sampler_state
@ -28,49 +28,35 @@ sampler_state
MagFilter = LINEAR; MagFilter = LINEAR;
}; };
sampler g_EnvTextureSampler =
sampler_state
{
Texture = <g_Texture1>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
};
shared FogParams g_Fog;
// ======================================================= // =======================================================
// Pixel and vertex lighting techniques // 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 DoDirectionalLight(float3 worldPos, float3 N, int i)
{ {
Lighting Out; Lighting Out;
Out.Diffuse = CalculateDiffuse( Out.Diffuse = CalculateDirectionalDiffuse(
N, N,
-g_DirectionalLightDirection[i], -g_DirectionalLights.Direction[i],
g_DirectionalLightDiffuse[i]); g_DirectionalLights.Diffuse[i]);
Out.Specular = CalculateSpecular( Out.Specular = CalculateDirectionalSpecular(
worldPos, worldPos,
g_ViewTransforms.CameraPosition.xyz,
N, N,
-g_DirectionalLightDirection[i], -g_DirectionalLights.Direction[i],
g_DirectionalLightSpecular[i]); g_DirectionalLights.Specular[i],
g_Material.Power);
return Out; return Out;
} }
@ -78,14 +64,14 @@ Lighting ComputeLighting(float3 worldPos, float3 N)
{ {
Lighting finalLighting = (Lighting)0; 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); Lighting lighting = DoDirectionalLight(worldPos, N, i);
finalLighting.Diffuse += lighting.Diffuse; finalLighting.Diffuse += lighting.Diffuse;
finalLighting.Specular += lighting.Specular; 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 diffuse = g_Material.Diffuse * finalLighting.Diffuse;
float4 specular = g_Material.Specular * finalLighting.Specular; float4 specular = g_Material.Specular * finalLighting.Specular;
@ -101,23 +87,11 @@ struct PixelLightingVSOutput
float2 Tex0 : TEXCOORD0; float2 Tex0 : TEXCOORD0;
float3 Normal : TEXCOORD1; float3 Normal : TEXCOORD1;
float3 WorldPos : TEXCOORD2; 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 GetColorArg(int colorArg, float4 textureColor, float4 diffuseColor)
{ {
float4 result; 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 Modulate(int stageIndex, float4 textureColor, float4 diffuseColor, float factor)
{ {
float4 left = GetColorArg(g_BlendStages[stageIndex].colorArg1, textureColor, diffuseColor); float4 left = GetColorArg(g_BlendStages.BlendStages[stageIndex].colorArg1, textureColor, diffuseColor);
float4 right = GetColorArg(g_BlendStages[stageIndex].colorArg2, textureColor, diffuseColor); float4 right = GetColorArg(g_BlendStages.BlendStages[stageIndex].colorArg2, textureColor, diffuseColor);
return (left * right) * factor; return (left * right) * factor;
} }
@ -140,15 +114,19 @@ float4 Modulate(int stageIndex, float4 textureColor, float4 diffuseColor, float
float4 ProcessStages(float4 textureColor, float4 diffuseColor) float4 ProcessStages(float4 textureColor, float4 diffuseColor)
{ {
float4 output = 0; 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; 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); float4 color = tex2D(g_ObjTextureSampler, input.Tex0);
Lighting lighting = ComputeLighting(input.WorldPos, input.Normal); Lighting lighting = ComputeLighting(input.WorldPos, input.Normal);
PixelLightingPSOutput output; // Emulate FFP texture stages
output.Diffuse = ProcessStages(color, lighting.Diffuse) + lighting.Specular; float4 finalColor = ProcessStages(color, lighting.Diffuse) + lighting.Specular;
return output;
// 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 technique PixelLighting
@ -190,21 +226,18 @@ struct VertexLightingVSOutput
float Fog : FOG; float Fog : FOG;
}; };
float fFogStart = 25.f;
float fFogEnd = 1525.f;
VertexLightingVSOutput VertexLightingVS( VertexLightingVSOutput VertexLightingVS(
float4 vPosition : POSITION0, float4 vPosition : POSITION0,
float3 vNormal : NORMAL0, float3 vNormal : NORMAL0,
float4 color : COLOR0, float4 color : COLOR0,
float2 tc : TEXCOORD0) float2 tc : TEXCOORD0,
float fog : FOG)
{ {
VertexLightingVSOutput output; VertexLightingVSOutput output;
output.Pos = mul(vPosition, g_WorldViewProjection); output.Pos = mul(vPosition, g_WorldTransforms.WorldViewProjection);
output.Tex0 = tc;
float4 worldPos = mul(vPosition, g_World); float4 worldPos = mul(vPosition, g_WorldTransforms.World);
float3 normal = mul(normalize(vNormal), (float3x3)g_World); float3 normal = mul(normalize(vNormal), (float3x3)g_WorldTransforms.World);
Lighting lighting = ComputeLighting(worldPos, normal); Lighting lighting = ComputeLighting(worldPos, normal);
@ -212,10 +245,8 @@ VertexLightingVSOutput VertexLightingVS(
output.Specular = lighting.Specular; output.Specular = lighting.Specular;
output.BumpColor = color; output.BumpColor = color;
float3 P = mul(vPosition, g_WorldView); output.Fog = fog;
float d = length(P); output.Tex0 = tc;
output.Fog = saturate((fFogEnd - d) / (fFogEnd - fFogStart));
return output; return output;
} }
@ -223,7 +254,7 @@ technique VertexLighting
{ {
pass P0 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 // Simple transform, pre-compute as much as we can for the pixel shader
ColorPerVertexVSOutput output = (ColorPerVertexVSOutput)0; ColorPerVertexVSOutput output = (ColorPerVertexVSOutput)0;
output.Pos = mul(vPosition, g_WorldViewProjection); output.Pos = mul(vPosition, g_WorldTransforms.WorldViewProjection);
output.Tex0 = tc; output.Tex0 = tc;
output.Color = color; 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); float d = length(P);
output.Fog = saturate((fFogEnd - d) / (fFogEnd - fFogStart)); output.Fog = fog;
return output; return output;
} }
@ -270,6 +301,6 @@ technique ColorPerVertex
pass P0 pass P0
{ {
//PixelShader = compile ps_3_0 ColorPerVertexPS(); //PixelShader = compile ps_3_0 ColorPerVertexPS();
VertexShader = compile vs_3_0 ColorPerVertexVS(); VertexShader = compile vs_2_0 ColorPerVertexVS();
} }
} }

View File

@ -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 = <g_ObjTexture>;
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();
}
}

View File

@ -1,63 +1,86 @@
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
// Water.fx // Ocean.fx
// Ocean water reflection shader. // Ocean water reflection shader.
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
/* Original asm code: #include "../fxh/Transform.fxh"
ps_1_1 #include "../fxh/Fog.fxh"
tex t0
tex t1
lrp r0, -v0.w, t0, t1 // lrp = linear interpolate
*/
shared texture g_Texture0; shared texture g_Texture0; // Seabed texture
shared texture g_Texture1; shared texture g_Texture1; // Environment texture
shared WorldTransforms g_WorldTransforms;
shared ViewTransforms g_ViewTransforms;
shared FogParams g_Fog;
struct PS_INPUT struct PS_INPUT
{ {
float4 color : COLOR0; float4 color : COLOR0;
float4 texCoord0 : TEXCOORD0; float4 texCoord0 : TEXCOORD0;
float4 texCoord1 : TEXCOORD1; float4 texCoord1 : TEXCOORD1;
float Fog : FOG;
}; };
sampler s0, s1; sampler g_SeabedSampler : register(s0) = sampler_state
{
Texture = <g_Texture0>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
};
sampler g_EnvironmentSampler = sampler_state
{
Texture = <g_Texture1>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
};
float4 MainPS(const PS_INPUT input) : COLOR0 float4 MainPS(const PS_INPUT input) : COLOR0
{ {
// Interpolate linearly between Environment Texture, seabed, and inverted alpha of current pixel // 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: (dynamic)
// C44:
// C27: {0, 1.0, 0.5, 0.25}
// C26: {minfog, maxfog, 1.0f / (maxfog - minfog), 1.0}
float4 const44 : register(c44); float4 const44 : register(c44);
shared matrix<float, 4, 4> g_OceanWorldViewProjection : OceanWorldViewProjection : register(c2);
float4 fog : register (c26);
struct VS_OUTPUT struct VS_OUTPUT
{ {
float4 pos : POSITION; float4 pos : POSITION;
float4 texCoord0 : TEXCOORD0;
float4 texCoord1 : TEXCOORD1; float4 texCoord1 : TEXCOORD1;
float4 color : COLOR0;
float Fog : FOG;
}; };
struct VS_INPUT struct VS_INPUT
{ {
float4 pos : POSITION; float4 pos : POSITION;
float4 texCoord0 : TEXCOORD0;
}; };
VS_OUTPUT MainVS(const VS_INPUT input) VS_OUTPUT MainVS(const VS_INPUT input)
{ {
float4 const27 = {0.0f, 1.0f, 0.5f, 0.75f}; VS_OUTPUT output = (VS_OUTPUT)0;
VS_OUTPUT output;
output.pos = mul(input.pos, g_OceanWorldViewProjection); output.pos = mul(input.pos, g_WorldTransforms.WorldViewProjection);
// add r0, v0, -c44 // add r0, v0, -c44
float4 r0 = input.pos + -const44; float4 r0 : register(r0) = input.pos + -const44;
// mov r0.z, -r0.z // mov r0.z, -r0.z
r0.z = -r0.z; r0.z = -r0.z;
@ -68,78 +91,88 @@ VS_OUTPUT MainVS(const VS_INPUT input)
// rsq r0.w, r0.w // rsq r0.w, r0.w
r0.w = rsqrt(r0.w); r0.w = rsqrt(r0.w);
// mul oT1.x, -r0, r0.w // mul oT1.x, -r0, r0.w
// mul oT1.y, r0, r0.w // mul oT1.y, r0, r0.w
// mul oT1.z, r0, r0.w // mul oT1.z, r0, r0.w
// mov oT1.w, c27.y // mov oT1.w, c27.y
output.texCoord1.x = -r0 * r0.w; output.texCoord1.x = r0.w * -r0.x;
output.texCoord1.y = r0 * r0.w; output.texCoord1.y = r0.w * r0.y;
output.texCoord1.z = r0 * r0.w; output.texCoord1.z = r0.w * r0.z;
output.texCoord1.w = const27.y; 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; return output;
} }
technique t0 technique ReflectionLow
{ {
pass p0 pass P0
{ {
Texture[0] = <g_Texture0>; // Seabed texture VertexShader = compile vs_2_0 MainVS();
Texture[1] = <g_Texture1>; // Environment texture PixelShader = compile ps_2_0 MainPS();
}
}
// All of these constants are set by the game engine before drawing the shader struct ReflectionHighVSOutput
// Each constant register (c# in the asm code) has 4 floating point values
// Special world * view * projection matrix for ocean shader
VertexShaderConstant[2] = <g_OceanWorldViewProjection[0]>;
VertexShaderConstant[3] = <g_OceanWorldViewProjection[1]>;
VertexShaderConstant[4] = <g_OceanWorldViewProjection[2]>;
VertexShaderConstant[5] = <g_OceanWorldViewProjection[3]>;
VertexShaderConstant[26] = <fog>; // 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] = <const44>; // 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 float4 pos : POSITION;
dcl_position v0 float4 texCoord0 : TEXCOORD0;
dcl_texcoord v2 float4 texCoord1 : TEXCOORD1;
float4 color : COLOR0;
/* Places the dot product of the world view matrix and v0 in the output register oPos */ float Fog : FOG;
dp4 oPos.x, v0, c2 float3 Normal : TEXCOORD2;
dp4 oPos.y, v0, c3 float3 Reflection : TEXCOORD3;
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 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();
} }
} }

View File

@ -4,10 +4,9 @@
// Experimental sky shader. Does nothing currently. // Experimental sky shader. Does nothing currently.
//-------------------------------------------------------------------------------------- //--------------------------------------------------------------------------------------
float4x4 g_mWorldViewProjection : WorldViewProjection; #include "../fxh/Transform.fxh"
float4x4 g_World : World;
float4x4 g_View : View; shared WorldTransforms g_WorldTransforms;
float4x4 g_Projection : Projection;
float intensityThreshold = 1.f; float intensityThreshold = 1.f;
float colorMultiplier = 1.f; float colorMultiplier = 1.f;
texture g_SkyTexture; texture g_SkyTexture;
@ -28,7 +27,7 @@ void RenderSceneVS(
out float4 oColor0 : COLOR0, out float4 oColor0 : COLOR0,
out float2 oTexCoord0 : TEXCOORD0 ) out float2 oTexCoord0 : TEXCOORD0 )
{ {
oPosition = mul(iPosition, g_mWorldViewProjection); oPosition = mul(iPosition, g_WorldTransforms.WorldViewProjection);
oColor0 = float4(1, 1, 1, 1); oColor0 = float4(1, 1, 1, 1);
oTexCoord0 = iTexCoord0; oTexCoord0 = iTexCoord0;
} }

View File

@ -5,12 +5,24 @@
// the original fixed-function water rendering behavior. // 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 texture g_Texture0;
shared float4x4 g_WorldViewProjection; shared WorldTransforms g_WorldTransforms;
shared ViewTransforms g_ViewTransforms;
shared float4 g_TextureFactor; 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 = sampler2D g_WaterTextureSampler =
sampler_state sampler_state
{ {
@ -22,23 +34,30 @@ struct VS_OUTPUT
float4 Position : POSITION; // vertex position float4 Position : POSITION; // vertex position
float2 TextureUV : TEXCOORD0; // vertex texture coords float2 TextureUV : TEXCOORD0; // vertex texture coords
float4 Color : COLOR0; float4 Color : COLOR0;
float Fog : FOG;
float3 WorldPos : TEXCOORD1;
/*float3 Normal : TEXCOORD1;*/
float3 ViewDirection : TEXCOORD2;
}; };
VS_OUTPUT RenderSceneVS(float4 inPos : POSITION, VS_OUTPUT RenderSceneVS(float4 inPos : POSITION,
float4 inDiffuse : COLOR0, float4 inDiffuse : COLOR0,
float4 inTextureUV : TEXCOORD0) float4 inTextureUV : TEXCOORD0
/*float3 Normal : NORMAL*/)
{ {
VS_OUTPUT Output; VS_OUTPUT Output;
Output.Position = mul(inPos, g_WorldViewProjection); Output.Position = mul(inPos, g_WorldTransforms.WorldViewProjection);
Output.TextureUV = inTextureUV; Output.TextureUV = inTextureUV;
Output.Color = inDiffuse; Output.Color = inDiffuse;
// Don't think this is right, but we can use FFP fog unless this is compiled for SM 3.0 float3 P = mul(inPos, g_WorldTransforms.WorldView);
//float4 r0; float d = length(P);
//r0.z = inPos.z * g_WorldViewProjection[3]; Output.Fog = CalculateFogFactor(g_Fog.FogMax, g_Fog.FogMin, d);
//r0.x = -r0.z + g_Fog.y; //Output.Normal = mul(Normal, (float3x3)g_WorldTransforms.World);
//Output.Fog.x = r0.x * g_Fog.z;
Output.WorldPos = mul(inPos, g_WorldTransforms.World);
Output.ViewDirection = g_ViewTransforms.CameraPosition - Output.WorldPos;
return Output; return Output;
} }
@ -47,6 +66,34 @@ float4 RenderScenePS(VS_OUTPUT input) : COLOR0
{ {
float4 texel = tex2D(g_WaterTextureSampler, input.TextureUV); float4 texel = tex2D(g_WaterTextureSampler, input.TextureUV);
float4 result = saturate(texel + (1 - texel) * g_TextureFactor); // equivalent to saturate((texel + g_TextureFactor) - (texel * g_TextureFactor)); 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; result.a = input.Color.a * g_TextureFactor.a;
return result; return result;
@ -56,7 +103,7 @@ technique RenderScene
{ {
pass P0 pass P0
{ {
VertexShader = compile vs_2_0 RenderSceneVS(); VertexShader = compile vs_3_0 RenderSceneVS();
PixelShader = compile ps_2_0 RenderScenePS(); PixelShader = compile ps_3_0 RenderScenePS();
} }
} }

View File

@ -1,5 +1,5 @@
#define MAX_DIRECTIONAL_LIGHTS 3 #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 #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. // where each component has been scaled and offset to make it signed.
// The result is replicated into all four (including alpha) channels. // The result is replicated into all four (including alpha) channels.
// This is a valid COLOROP only. // This is a valid COLOROP only.
#define D3DTOP_DOTPRODUCT3 24, #define D3DTOP_DOTPRODUCT3 24
// Triadic ops // 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 #define D3DTOP_LERP 26 // (Arg0)*Arg1 + (1-Arg0)*Arg2
/* /*

17
Shaders/fxh/Fog.fxh Normal file
View File

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

View File

@ -1,3 +1,5 @@
#include "Constants.fxh"
struct Material struct Material
{ {
float4 Diffuse; float4 Diffuse;
@ -13,6 +15,24 @@ struct Lighting
float4 Specular : COLOR1; 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 struct TextureBlendStage
{ {
int colorOp; int colorOp;
@ -22,3 +42,50 @@ struct TextureBlendStage
int alphaArg1; int alphaArg1;
int alphaArg2; int alphaArg2;
}; };
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;
}

16
Shaders/fxh/Transform.fxh Normal file
View File

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