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)
// 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++)
{ {
// Get light direction for this fragment float distance = length(worldPos - g_ViewTransforms.CameraPosition);
float3 lightDir = normalize(input.WorldPos - g_PointLightPosition[i]); // per pixel diffuse lighting if (distance < g_DetailFadeEnd)
{
float4 detailTextureColor = tex2D(g_LandDetailTextureSampler, detailTextureUV) * 1.8f;
// Note: Non-uniform scaling not supported if (distance > g_DetailFadeStart)
float diffuseLighting = saturate(dot(input.Normal, -lightDir)); {
float distNormalized = distance / (g_DetailFadeEnd - g_DetailFadeStart);
// Introduce fall-off of light intensity detailTextureColor = lerp(detailTextureColor, float4(1.f, 1.f, 1.f, 1.f), distNormalized);
diffuseLighting *= (g_PointLightRange[i] / dot(g_PointLightPosition[i] - input.WorldPos, g_PointLightPosition[i] - input.WorldPos));
float4 diffuseColor = diffuseLighting * g_PointLightDiffuse[i];
finalColor += diffuseColor;
} }
return float4(finalColor, 1); originalColor *= detailTextureColor;
}
}
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 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 }
// Each constant register (c# in the asm code) has 4 floating point values
struct ReflectionHighVSOutput
// Special world * view * projection matrix for ocean shader {
VertexShaderConstant[2] = <g_OceanWorldViewProjection[0]>; float4 pos : POSITION;
VertexShaderConstant[3] = <g_OceanWorldViewProjection[1]>; float4 texCoord0 : TEXCOORD0;
VertexShaderConstant[4] = <g_OceanWorldViewProjection[2]>; float4 texCoord1 : TEXCOORD1;
VertexShaderConstant[5] = <g_OceanWorldViewProjection[3]>; float4 color : COLOR0;
float Fog : FOG;
VertexShaderConstant[26] = <fog>; // This constant is calculated from the current fog min/max values float3 Normal : TEXCOORD2;
VertexShaderConstant[27] = {0.0f, 1.0f, 0.5f, 0.75f}; // I don't know what this does but it doesn't change float3 Reflection : TEXCOORD3;
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 struct ReflectionHighVSInput
VertexShader = {
asm float4 pos : POSITION;
{ float4 texCoord0 : TEXCOORD0;
vs_1_1 float3 Normal : NORMAL0;
dcl_position v0 };
dcl_texcoord v2
ReflectionHighVSOutput ReflectionHighVS(const ReflectionHighVSInput input)
/* Places the dot product of the world view matrix and v0 in the output register oPos */ {
dp4 oPos.x, v0, c2 ReflectionHighVSOutput output = (ReflectionHighVSOutput)0;
dp4 oPos.y, v0, c3
dp4 oPos.z, v0, c4 output.pos = mul(input.pos, g_WorldTransforms.WorldViewProjection);
dp4 oPos.w, v0, c5 output.Normal = normalize(input.Normal);
// this is some kind of vector normalization or transform float3 normal = normalize(mul(input.Normal, g_WorldTransforms.WorldInverseTranspose));
add r0, v0, -c44 float3 viewDirection = g_ViewTransforms.CameraPosition - mul(input.pos, g_WorldTransforms.World);
mov r0.z, -r0.z output.Reflection = reflect(-normalize(viewDirection), normal);
dp3 r0.w, r0, r0 return output;
rsq r0.w, r0.w }
/* Output register for texture 1 (environment texture) is modified by register 0 */ float4 ReflectionHighPS(ReflectionHighVSOutput input) : COLOR0
mul oT1.x, -r0, r0.w {
mul oT1.y, r0, r0.w return texCUBE(g_EnvironmentSampler, normalize(input.Reflection));
mul oT1.z, r0, r0.w
mov oT1.w, c27.y }
rcp r0.w, r0.w technique ReflectionHigh
mul r0.w, r0.w, c45.x {
max r0.x, r0.w, c27.x pass P0
min oD0.w, r0.w, c27.y {
mov oT0, v2 VertexShader = compile vs_2_0 ReflectionHighVS();
dp4 r0.z, v0, c5 PixelShader = compile ps_2_0 ReflectionHighPS();
add r0.x, -r0.z, c26.y //VertexShader = compile vs_2_0 MainVS();
mul oFog, r0.x, c26.z //PixelShader = compile ps_2_0 MainPS();
};
#else
VertexShader = compile vs_1_1 MainVS();
#endif
PixelShader = compile ps_1_3 MainPS(); // effect will not work > ps 1.3
} }
} }

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