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/Lighting.fxh"
#include "../fxh/Transform.fxh"
#include "../fxh/Fog.fxh"
shared WorldTransforms g_WorldTransforms;
shared ViewTransforms g_ViewTransforms;
shared texture g_Texture0;
shared texture g_Texture1;
shared float4x4 g_WorldViewProjection;
shared float4x4 g_World;
shared texture g_Texture2;
shared float4x4 g_TexGenMatrix0;
shared float4x4 g_TexGenMatrix1;
shared float4x4 g_TexGenMatrix2;
shared float4 g_PointLightDiffuse[MAX_LIGHTS];
shared float3 g_PointLightPosition[MAX_LIGHTS];
shared float g_PointLightRange[MAX_LIGHTS];
shared int g_PointLightCount;
shared DirectionalLightInfo g_DirectionalLights;
shared PointLightInfo g_PointLights;
//float4x4 g_texGenMatrix2 : TexGenTransform2; // Shore texgen
shared FogParams g_Fog;
float g_DetailFadeStart = 150;
float g_DetailFadeEnd = 500;
//////////////////////////////////////////////////////
@ -45,108 +50,232 @@ sampler_state
MagFilter = LINEAR;
};
//sampler g_LandDetailTextureSampler =
//sampler_state
//{
// Texture = <g_LandDetailTexture>;
// MipFilter = LINEAR;
// MinFilter = LINEAR;
// MagFilter = LINEAR;
//};
//
//sampler g_ShoreTextureSampler =
//sampler_state
//{
// Texture = <g_LandBumpTexture>;
// MipFilter = LINEAR;
// MinFilter = LINEAR;
// MagFilter = LINEAR;
//};
sampler g_LandDetailTextureSampler =
sampler_state
{
Texture = <g_Texture2>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
};
//--------------------------------------------------------------------------------------
// Vertex shader output structure
//--------------------------------------------------------------------------------------
struct VS_OUTPUT_BUMP
struct LandBumpDetailVSOutput
{
float4 Position : POSITION;
float4 LandBumpDiffuse : COLOR1;
float4 LandDiffuse : COLOR0;
float2 LandBumpTextureUV : TEXCOORD0;
float2 LandTextureUV : TEXCOORD1;
float3 WorldPos : TEXCOORD2;
float3 Normal : TEXCOORD3;
//float3 ShoreTextureUV : TEXCOORD4;
float2 LandDetailTextureUV : TEXCOORD2;
float3 WorldPos : TEXCOORD3;
float3 Normal : TEXCOORD4;
float Fog : FOG;
};
float4 bx2(float4 x)
inline float4 bx2(float4 x)
{
return float4(2.0f * x.xyzw - 1.0f);
return float4(2.0f * x.xyzw - 1.0f);
}
VS_OUTPUT_BUMP LandBumpVS(
float4 vPos : POSITION,
float3 vNormal : NORMAL,
float4 vDiffuse : COLOR0,
float4 vDiffuse2 : COLOR1)
float4 CalculateDetailTexture(float3 worldPos, float4 originalColor, float2 detailTextureUV)
{
VS_OUTPUT_BUMP Output;
// Transform the position from object space to homogeneous projection space
Output.Position = mul(vPos, g_WorldViewProjection);
Output.LandBumpDiffuse = vDiffuse2 * .5f;
Output.LandBumpDiffuse.a = 1.0f;
Output.LandDiffuse.rgb = vDiffuse;
Output.LandDiffuse.a = 1.0f;
Output.WorldPos = mul(vPos, g_World);
// Set dynamically generated tex coords
Output.LandBumpTextureUV = mul(vPos, g_TexGenMatrix0);
Output.LandTextureUV = mul(vPos, g_TexGenMatrix1);
//Output.ShoreTextureUV = mul(vPos, g_texGenMatrix2);
// Transform the normal from object space to world space
Output.Normal = normalize(mul(vNormal, (float3x3)g_World)); // normal (world space)
return Output;
}
float4 LandBumpPS(VS_OUTPUT_BUMP input) : COLOR0
{
float4 normal = bx2(tex2D(g_LandBumpTextureSampler, input.LandBumpTextureUV));
float4 normalcol = bx2(input.LandDiffuse);
float3 normalMap;
normalMap = saturate((float4)dot((float3)normal, (float3)normalcol)).xyz;
float3 finalColor = 2.0 * (normalMap * (tex2D(g_LandTextureSampler, input.LandTextureUV)) + input.LandBumpDiffuse);
for (int i = 0; i < g_PointLightCount; i++)
if (detailTextureUV.x != 0 || detailTextureUV.y != 0)
{
// Get light direction for this fragment
float3 lightDir = normalize(input.WorldPos - g_PointLightPosition[i]); // per pixel diffuse lighting
float distance = length(worldPos - g_ViewTransforms.CameraPosition);
if (distance < g_DetailFadeEnd)
{
float4 detailTextureColor = tex2D(g_LandDetailTextureSampler, detailTextureUV) * 1.8f;
// Note: Non-uniform scaling not supported
float diffuseLighting = saturate(dot(input.Normal, -lightDir));
if (distance > g_DetailFadeStart)
{
float distNormalized = distance / (g_DetailFadeEnd - g_DetailFadeStart);
detailTextureColor = lerp(detailTextureColor, float4(1.f, 1.f, 1.f, 1.f), distNormalized);
}
// Introduce fall-off of light intensity
diffuseLighting *= (g_PointLightRange[i] / dot(g_PointLightPosition[i] - input.WorldPos, g_PointLightPosition[i] - input.WorldPos));
float4 diffuseColor = diffuseLighting * g_PointLightDiffuse[i];
finalColor += diffuseColor;
originalColor *= detailTextureColor;
}
}
return float4(finalColor, 1);
return originalColor;
}
technique LandBump
LandBumpDetailVSOutput LandBumpDetailVS(
float4 position : POSITION,
float3 normal : NORMAL,
float4 landBumpDiffuse : COLOR0,
float4 landDiffuse : COLOR1)
{
LandBumpDetailVSOutput output;
// Transform the position from object space to homogeneous projection space
output.Position = mul(position, g_WorldTransforms.WorldViewProjection);
output.LandDiffuse = landDiffuse * .5f;
output.LandDiffuse.a = 1.0f;
output.LandBumpDiffuse.rgb = landBumpDiffuse;
output.LandBumpDiffuse.a = 1.0f;
output.WorldPos = mul(position, g_WorldTransforms.World);
// Set dynamically generated tex coords
output.LandBumpTextureUV = mul(position, g_TexGenMatrix0);
output.LandTextureUV = mul(position, g_TexGenMatrix1);
output.LandDetailTextureUV = mul(position, g_TexGenMatrix2);
float3 P = mul(position, g_WorldTransforms.WorldView);
output.Fog = CalculateFogFactor(g_Fog.FogMax, g_Fog.FogMin, length(P));
// Transform the normal from object space to world space
output.Normal = normalize(mul(normal, (float3x3)g_WorldTransforms.World)); // normal (world space)
return output;
}
float4 CalculateDot3BumpMap(float4 diffuseColor, float2 uv)
{
float4 landBumpTextureColor = bx2(tex2D(g_LandBumpTextureSampler, uv));
diffuseColor = bx2(diffuseColor);
float4 bumpMapColor;
bumpMapColor.xyz = saturate(dot(landBumpTextureColor, diffuseColor.rgb));
bumpMapColor.w = 1.0f;
return bumpMapColor;
}
struct TNBFrame
{
float3 Tangent;
float3 Normal;
float3 Binormal;
};
/*
TNBFrame CalculateTNBFrame(float3 worldPos, float3 N, float2 uv)
{
float3 dp1 = ddx(worldPos);
float3 dp2 = ddy(worldPos);
float2 duv1 = ddx(uv);
float2 duv2 = ddy(uv);
float3 dp2perp = cross(dp2, N);
float3 dp1perp = cross(N, dp1);
float3 T = dp2perp * duv1.x + dp1perp * duv2.x;
float3 B = dp2perp * duv1.y + dp1perp * duv2.y;
float invmax = rsqrt(max(dot(T, T), dot(B, B)));
TNBFrame frame;
frame.Tangent = T * invmax;
frame.Normal = N;
frame.Binormal = B * invmax;
return frame;
}
*/
TNBFrame CalculateTNBFrame(float3 worldPos, float3 N, float2 uv)
{
float3 dp1 = ddx(worldPos);
float3 dp2 = ddy(worldPos);
float2 duv1 = ddx(uv);
float2 duv2 = ddy(uv);
float3 t = normalize(duv2.y * dp1 - duv1.y * dp2);
float3 b = normalize(duv2.x * dp1 - duv1.x * dp2);
float3 n = normalize(N);
float3 x = cross(n, t);
t = cross(x, n);
t = normalize(t);
x = cross(b, n);
b = cross(n, x);
b = normalize(b);
TNBFrame frame;
frame.Tangent = t;
frame.Normal = n;
frame.Binormal = b;
return frame;
}
float4 CalculateNormalMap(float3 worldPos, float3 normal, float2 uv, float4 diffuse)
{
TNBFrame tnbFrame = CalculateTNBFrame(worldPos, normal, uv);
// Sample the pixel in the bump map.
float4 bumpMap = tex2D(g_LandBumpTextureSampler, uv) + diffuse;
// Expand the range of the normal value from (0, +1) to (-1, +1).
bumpMap = (bumpMap * 2.0f) - 1.0f;
// Calculate the normal from the data in the bump map.
float3 bumpNormal = (bumpMap.x * tnbFrame.Tangent) + (bumpMap.y * tnbFrame.Binormal) + (bumpMap.z * tnbFrame.Normal);
// Normalize the resulting bump normal.
bumpNormal = normalize(bumpNormal);
// Invert the light direction for calculations.
float3 lightDir = -g_DirectionalLights.Direction[g_DirectionalLights.SunIndex];
// Calculate the amount of light on this pixel based on the bump map normal value.
float lightIntensity = saturate(dot(bumpNormal, lightDir));
// Determine the final diffuse color based on the diffuse color and the amount of light intensity.
float4 color = saturate(lightIntensity);
return color;
}
float4 LandBumpDetailPS(LandBumpDetailVSOutput input) : COLOR0
{
float4 landTextureColor = tex2D(g_LandTextureSampler, input.LandTextureUV);
#if 1
float4 bumpMapColor = CalculateDot3BumpMap(input.LandBumpDiffuse, input.LandBumpTextureUV);
float4 finalColor = 2.0 * (bumpMapColor * (landTextureColor) + input.LandDiffuse);
#else
float4 bumpMapColor = CalculateNormalMap(input.WorldPos, input.Normal, input.LandTextureUV, input.LandBumpDiffuse);
float4 bumpMapColor = CalculateDirectionalDiffuse(input.Normal, -g_DirectionalLights.Direction[g_DirectionalLights.SunIndex], float4(1, 1, 1, 1));
float4 finalColor = (bumpMapColor * landTextureColor) + input.LandDiffuse;
#endif
finalColor = CalculateDetailTexture(input.WorldPos, finalColor, input.LandDetailTextureUV);
for (int i = 0; i < g_PointLights.Count; i++)
{
float3 worldPos = g_PointLights.Position[i] - input.WorldPos;
float3 lightDirection = normalize(input.WorldPos - (g_PointLights.Position[i]));
finalColor += CalculatePointDiffuse(
worldPos,
input.Normal,
-lightDirection,
g_PointLights.Range[i],
g_PointLights.Diffuse[i]);
}
if (g_Fog.Enabled)
{
finalColor = ApplyPixelFog(finalColor, input.Fog, g_Fog.Color);
}
finalColor.a = 1.0f;
return finalColor;
}
technique LandBumpDetail
{
pass P0
{
VertexShader = compile vs_2_0 LandBumpVS();
PixelShader = compile ps_2_0 LandBumpPS();
{
VertexShader = compile vs_3_0 LandBumpDetailVS();
PixelShader = compile ps_3_0 LandBumpDetailPS();
}
}
@ -162,25 +291,43 @@ struct VS_OUTPUT
float3 WorldPos : TEXCOORD2;
};
matrix Identity =
{
{ 1, 0, 0, 0 },
{ 0, 1, 0, 0 },
{ 0, 0, 1, 0 },
{ 0, 0, 0, 1 }
};
VS_OUTPUT LandscapeVS(
float4 vPos : POSITION,
float3 vNormal : NORMAL,
float4 vDiffuse : COLOR0)
{
VS_OUTPUT Output;
// Transform the position from object space to homogeneous projection space
Output.Position = mul(vPos, g_WorldViewProjection);
Output.Position = mul(vPos, g_WorldTransforms.WorldViewProjection);
// Transform the normal from object space to world space
Output.Normal = normalize(mul(vNormal, (float3x3)g_World)); // normal (world space)
Output.Normal = normalize(mul(vNormal, (float3x3)g_WorldTransforms.World)); // normal (world space)
Output.Diffuse.rgb = vDiffuse;
Output.Diffuse.a = 1.0f;
Output.WorldPos = mul(vPos, g_World);
Output.WorldPos = mul(vPos, g_WorldTransforms.World);
//float3 P = mul(vPos, g_WorldView); //position in view space
// Set dynamically generated tex coords
//P* (iTexGenType == TEXGEN_TYPE_CAMERASPACEPOSITION), 0)
/*
float4x4 scaleMatrix = Identity;
int index = G_TexUaxis[g_PrimBufferIndex];
scaleMatrix[0][0] = g_TexUScale;
scaleMatrix[1][G_TexVaxis[g_PrimBufferIndex]] = g_TexVScale;
*/
//Output.TextureUV = mul(vPos, (scaleMatrix * g_World));
Output.TextureUV = mul(vPos, g_TexGenMatrix0);
return Output;
@ -190,20 +337,17 @@ float4 LandscapePS(VS_OUTPUT input) : COLOR0
{
float4 finalColor = 0;
for (int i = 0; i < g_PointLightCount; i++)
for (int i = 0; i < g_PointLights.Count; i++)
{
// Get light direction for this fragment
float3 lightDir = normalize(input.WorldPos - g_PointLightPosition[i]); // per pixel diffuse lighting
float3 worldPos = g_PointLights.Position[i] - input.WorldPos;
float3 lightDirection = normalize(input.WorldPos - (g_PointLights.Position[i]));
// Note: Non-uniform scaling not supported
float diffuseLighting = saturate(dot(input.Normal, -lightDir));
// Introduce fall-off of light intensity
diffuseLighting *= (g_PointLightRange[i] / dot(g_PointLightPosition[i] - input.WorldPos, g_PointLightPosition[i] - input.WorldPos));
float4 diffuseColor = diffuseLighting * g_PointLightDiffuse[i];
finalColor += diffuseColor;
finalColor += CalculatePointDiffuse(
worldPos,
input.Normal,
-lightDirection,
g_PointLights.Range[i],
g_PointLights.Diffuse[i]);
}
float3 texel = tex2D(g_LandTextureSampler, input.TextureUV);

View File

@ -1,23 +1,23 @@
#include "../fxh/Constants.fxh"
#include "../fxh/Lighting.fxh"
#include "../fxh/Transform.fxh"
#include "../fxh/Fog.fxh"
shared texture g_Texture0 : Texture0;
shared texture g_Texture0;
shared texture g_Texture1;
shared float4 g_DirectionalLightAmbientSum;
shared float4 g_DirectionalLightDiffuse[MAX_DIRECTIONAL_LIGHTS];
shared float3 g_DirectionalLightDirection[MAX_DIRECTIONAL_LIGHTS];
shared float4 g_DirectionalLightSpecular[MAX_DIRECTIONAL_LIGHTS];
shared int g_DirectionalLightCount;
shared DirectionalLightInfo g_DirectionalLights;
shared Material g_Material;
shared float4x4 g_WorldViewProjection;
shared float4x4 g_WorldView;
shared float4x4 g_World;
shared WorldTransforms g_WorldTransforms;
shared float4x4 g_EnvironmentTextureTransform;
shared float4 g_TextureFactor;
shared TextureBlendStage g_BlendStages[MAX_BLEND_STAGES];
shared int g_BlendStageCount;
shared float3 g_CameraPosition;
shared BlendStageInfo g_BlendStages;
shared ViewTransforms g_ViewTransforms;
shared ColorMixMode g_ColorMixMode;
sampler g_ObjTextureSampler : register(s0) =
sampler_state
@ -28,49 +28,35 @@ sampler_state
MagFilter = LINEAR;
};
sampler g_EnvTextureSampler =
sampler_state
{
Texture = <g_Texture1>;
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
};
shared FogParams g_Fog;
// =======================================================
// Pixel and vertex lighting techniques
//
float4 CalculateDiffuse(float3 N, float3 L, float4 diffuseColor)
{
float NDotL = dot(N, L);
float4 finalColor = 0;
if (NDotL > 0.0f)
{
finalColor = max(0, NDotL * diffuseColor);
}
return finalColor;
}
float4 CalculateSpecular(float3 worldPos, float3 N, float3 L, float4 specularColor)
{
float4 finalColor = 0;
if (g_Material.Power > 0)
{
float3 toEye = normalize(g_CameraPosition.xyz - worldPos);
float3 halfway = normalize(toEye + L);
float NDotH = saturate(dot(halfway, N));
finalColor = max(0, pow(NDotH, g_Material.Power) * specularColor);
}
return finalColor;
}
Lighting DoDirectionalLight(float3 worldPos, float3 N, int i)
{
Lighting Out;
Out.Diffuse = CalculateDiffuse(
Out.Diffuse = CalculateDirectionalDiffuse(
N,
-g_DirectionalLightDirection[i],
g_DirectionalLightDiffuse[i]);
Out.Specular = CalculateSpecular(
-g_DirectionalLights.Direction[i],
g_DirectionalLights.Diffuse[i]);
Out.Specular = CalculateDirectionalSpecular(
worldPos,
g_ViewTransforms.CameraPosition.xyz,
N,
-g_DirectionalLightDirection[i],
g_DirectionalLightSpecular[i]);
-g_DirectionalLights.Direction[i],
g_DirectionalLights.Specular[i],
g_Material.Power);
return Out;
}
@ -78,14 +64,14 @@ Lighting ComputeLighting(float3 worldPos, float3 N)
{
Lighting finalLighting = (Lighting)0;
for (int i = 0; i < g_DirectionalLightCount; i++)
for (int i = 0; i < g_DirectionalLights.Count; i++)
{
Lighting lighting = DoDirectionalLight(worldPos, N, i);
finalLighting.Diffuse += lighting.Diffuse;
finalLighting.Specular += lighting.Specular;
}
float4 ambient = g_Material.Ambient * g_DirectionalLightAmbientSum;
float4 ambient = g_Material.Ambient * g_DirectionalLights.Ambient;
float4 diffuse = g_Material.Diffuse * finalLighting.Diffuse;
float4 specular = g_Material.Specular * finalLighting.Specular;
@ -101,23 +87,11 @@ struct PixelLightingVSOutput
float2 Tex0 : TEXCOORD0;
float3 Normal : TEXCOORD1;
float3 WorldPos : TEXCOORD2;
float3 EnvMapTex : TEXCOORD3;
float4 BumpColor : TEXCOORD4;
float Fog : FOG;
};
PixelLightingVSOutput PixelLightingVS(
float4 vPosition : POSITION0,
float3 vNormal : NORMAL0,
float2 tc : TEXCOORD0)
{
// Simple transform, pre-compute as much as we can for the pixel shader
PixelLightingVSOutput output;
output.Pos = mul(vPosition, g_WorldViewProjection);
output.Normal = mul(normalize(vNormal), (float3x3)g_World);
output.WorldPos = mul(vPosition, g_World);
output.Tex0 = tc;
return output;
}
float4 GetColorArg(int colorArg, float4 textureColor, float4 diffuseColor)
{
float4 result;
@ -131,8 +105,8 @@ float4 GetColorArg(int colorArg, float4 textureColor, float4 diffuseColor)
float4 Modulate(int stageIndex, float4 textureColor, float4 diffuseColor, float factor)
{
float4 left = GetColorArg(g_BlendStages[stageIndex].colorArg1, textureColor, diffuseColor);
float4 right = GetColorArg(g_BlendStages[stageIndex].colorArg2, textureColor, diffuseColor);
float4 left = GetColorArg(g_BlendStages.BlendStages[stageIndex].colorArg1, textureColor, diffuseColor);
float4 right = GetColorArg(g_BlendStages.BlendStages[stageIndex].colorArg2, textureColor, diffuseColor);
return (left * right) * factor;
}
@ -140,15 +114,19 @@ float4 Modulate(int stageIndex, float4 textureColor, float4 diffuseColor, float
float4 ProcessStages(float4 textureColor, float4 diffuseColor)
{
float4 output = 0;
for (int i = 0; i < g_BlendStageCount; i++)
for (int i = 0; i < g_BlendStages.Count; i++)
{
if (g_BlendStages[i].colorOp == D3DTOP_MODULATE4X)
if (g_BlendStages.BlendStages[i].colorOp == D3DTOP_MODULATE4X || g_BlendStages.BlendStages[i].colorOp == D3DTOP_MODULATE)
{
output += Modulate(i, textureColor, diffuseColor, 4.0f);
float modulateFactor =
(4.0f * (g_BlendStages.BlendStages[i].colorOp == D3DTOP_MODULATE4X)) +
(1.0f * (g_BlendStages.BlendStages[i].colorOp == D3DTOP_MODULATE));
output += Modulate(i, textureColor, diffuseColor, modulateFactor);
}
else
else if (g_BlendStages.BlendStages[i].colorOp == D3DTOP_DOTPRODUCT3)
{
output += Modulate(i, textureColor, diffuseColor, 1.0f);
output = float4(1, 0, 0, 1);
}
}
@ -160,15 +138,73 @@ struct PixelLightingPSOutput
float4 Diffuse : COLOR0;
};
PixelLightingPSOutput PixelLightingPS(PixelLightingVSOutput input)
PixelLightingVSOutput PixelLightingVS(
float4 vPosition : POSITION0,
float3 vNormal : NORMAL0,
float4 color : COLOR0,
float2 tc : TEXCOORD0)
{
// Simple transform, pre-compute as much as we can for the pixel shader
PixelLightingVSOutput output = (PixelLightingVSOutput)0;
vNormal = normalize(vNormal);
output.Pos = mul(vPosition, g_WorldTransforms.WorldViewProjection);
output.Normal = mul(vNormal, (float3x3)g_WorldTransforms.World);
output.WorldPos = mul(vPosition, g_WorldTransforms.World);
output.Tex0 = tc;
output.BumpColor = color;
float3 P = mul(vPosition, g_WorldTransforms.WorldView);
float d = length(P);
output.Fog = CalculateFogFactor(g_Fog.FogMax, g_Fog.FogMin, d);
if (g_ColorMixMode.EnvironmentMappingEnabled)
{
// Generate cube texture coordinates
// DX9 FFP formula: R = 2(E dot N) * N - E
float3 E = normalize(g_ViewTransforms.CameraPosition.xyz - output.WorldPos);
float3 N = mul(vNormal, (float3x3)g_WorldTransforms.WorldView);
float4 R = float4((2.f * dot(E, N) * N - E), 0);
output.EnvMapTex = mul(g_EnvironmentTextureTransform, R);
}
return output;
}
float4 PixelLightingPS(PixelLightingVSOutput input) : COLOR0
{
float4 color = tex2D(g_ObjTextureSampler, input.Tex0);
Lighting lighting = ComputeLighting(input.WorldPos, input.Normal);
PixelLightingPSOutput output;
output.Diffuse = ProcessStages(color, lighting.Diffuse) + lighting.Specular;
return output;
// Emulate FFP texture stages
float4 finalColor = ProcessStages(color, lighting.Diffuse) + lighting.Specular;
// Apply cubic environment mapping if enabled
if (g_ColorMixMode.EnvironmentMappingEnabled)
{
float4 envMapColor = texCUBE(g_EnvTextureSampler, input.EnvMapTex);
if (g_BlendStages.BlendStages[1].colorOp == D3DTOP_BLENDFACTORALPHA)
finalColor = (finalColor * g_TextureFactor.a) + (envMapColor * (1 - g_TextureFactor.a));
else if (g_BlendStages.BlendStages[1].colorOp == D3DTOP_BLENDCURRENTALPHA)
finalColor = float4(1, 0, 0, 0);
}
// Apply linear pixel fog
if (g_Fog.Enabled)
{
finalColor = ApplyPixelFog(finalColor, input.Fog, g_Fog.Color);
}
/*
if (input.BumpColor.r != 0)
{
finalColor = float4(1, 1, 1, 1);
}
*/
return finalColor;
}
technique PixelLighting
@ -190,21 +226,18 @@ struct VertexLightingVSOutput
float Fog : FOG;
};
float fFogStart = 25.f;
float fFogEnd = 1525.f;
VertexLightingVSOutput VertexLightingVS(
float4 vPosition : POSITION0,
float3 vNormal : NORMAL0,
float4 color : COLOR0,
float2 tc : TEXCOORD0)
float2 tc : TEXCOORD0,
float fog : FOG)
{
VertexLightingVSOutput output;
output.Pos = mul(vPosition, g_WorldViewProjection);
output.Tex0 = tc;
output.Pos = mul(vPosition, g_WorldTransforms.WorldViewProjection);
float4 worldPos = mul(vPosition, g_World);
float3 normal = mul(normalize(vNormal), (float3x3)g_World);
float4 worldPos = mul(vPosition, g_WorldTransforms.World);
float3 normal = mul(normalize(vNormal), (float3x3)g_WorldTransforms.World);
Lighting lighting = ComputeLighting(worldPos, normal);
@ -212,10 +245,8 @@ VertexLightingVSOutput VertexLightingVS(
output.Specular = lighting.Specular;
output.BumpColor = color;
float3 P = mul(vPosition, g_WorldView);
float d = length(P);
output.Fog = saturate((fFogEnd - d) / (fFogEnd - fFogStart));
output.Fog = fog;
output.Tex0 = tc;
return output;
}
@ -223,7 +254,7 @@ technique VertexLighting
{
pass P0
{
VertexShader = compile vs_3_0 VertexLightingVS();
VertexShader = compile vs_2_0 VertexLightingVS();
}
}
@ -254,14 +285,14 @@ ColorPerVertexVSOutput ColorPerVertexVS(
// Simple transform, pre-compute as much as we can for the pixel shader
ColorPerVertexVSOutput output = (ColorPerVertexVSOutput)0;
output.Pos = mul(vPosition, g_WorldViewProjection);
output.Pos = mul(vPosition, g_WorldTransforms.WorldViewProjection);
output.Tex0 = tc;
output.Color = color;
float3 P = mul(vPosition, g_WorldView); //position in view space
float3 P = mul(vPosition, g_WorldTransforms.WorldView); //position in view space
float d = length(P);
output.Fog = saturate((fFogEnd - d) / (fFogEnd - fFogStart));
output.Fog = fog;
return output;
}
@ -270,6 +301,6 @@ technique ColorPerVertex
pass P0
{
//PixelShader = compile ps_3_0 ColorPerVertexPS();
VertexShader = compile vs_3_0 ColorPerVertexVS();
VertexShader = compile vs_2_0 ColorPerVertexVS();
}
}

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.
//--------------------------------------------------------------------------------------
/* Original asm code:
ps_1_1
tex t0
tex t1
lrp r0, -v0.w, t0, t1 // lrp = linear interpolate
*/
#include "../fxh/Transform.fxh"
#include "../fxh/Fog.fxh"
shared texture g_Texture0;
shared texture g_Texture1;
shared texture g_Texture0; // Seabed texture
shared texture g_Texture1; // Environment texture
shared WorldTransforms g_WorldTransforms;
shared ViewTransforms g_ViewTransforms;
shared FogParams g_Fog;
struct PS_INPUT
{
float4 color : COLOR0;
float4 texCoord0 : TEXCOORD0;
float4 texCoord1 : TEXCOORD1;
float Fog : FOG;
};
sampler s0, s1;
sampler g_SeabedSampler : register(s0) = sampler_state
{
Texture = <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
{
// Interpolate linearly between Environment Texture, seabed, and inverted alpha of current pixel
return lerp(tex2D(s1, input.texCoord1), tex2D(s0, input.texCoord0), 1-input.color.a);
float4 result = lerp(texCUBE(g_EnvironmentSampler, input.texCoord1), tex2D(g_SeabedSampler, input.texCoord0.xy), 1-input.color.a);
// Note: fog disabled for now as it doesn't quite match up with FFP fog.
/*
if (g_Fog.Enabled)
{
result = ApplyPixelFog(result, input.Fog, g_Fog.Color);
}
*/
return result;
}
// C45: {0.00333, 0, 0, 0}
// C44:
// C27: {0, 1.0, 0.5, 0.25}
// C26: {minfog, maxfog, 1.0f / (maxfog - minfog), 1.0}
// C44: (dynamic)
float4 const44 : register(c44);
shared matrix<float, 4, 4> g_OceanWorldViewProjection : OceanWorldViewProjection : register(c2);
float4 fog : register (c26);
struct VS_OUTPUT
{
float4 pos : POSITION;
float4 texCoord0 : TEXCOORD0;
float4 texCoord1 : TEXCOORD1;
float4 color : COLOR0;
float Fog : FOG;
};
struct VS_INPUT
{
float4 pos : POSITION;
float4 texCoord0 : TEXCOORD0;
};
VS_OUTPUT MainVS(const VS_INPUT input)
{
float4 const27 = {0.0f, 1.0f, 0.5f, 0.75f};
VS_OUTPUT output;
VS_OUTPUT output = (VS_OUTPUT)0;
output.pos = mul(input.pos, g_OceanWorldViewProjection);
output.pos = mul(input.pos, g_WorldTransforms.WorldViewProjection);
// add r0, v0, -c44
float4 r0 = input.pos + -const44;
float4 r0 : register(r0) = input.pos + -const44;
// mov r0.z, -r0.z
r0.z = -r0.z;
@ -68,78 +91,88 @@ VS_OUTPUT MainVS(const VS_INPUT input)
// rsq r0.w, r0.w
r0.w = rsqrt(r0.w);
// mul oT1.x, -r0, r0.w
// mul oT1.y, r0, r0.w
// mul oT1.z, r0, r0.w
// mov oT1.w, c27.y
output.texCoord1.x = -r0 * r0.w;
output.texCoord1.y = r0 * r0.w;
output.texCoord1.z = r0 * r0.w;
output.texCoord1.w = const27.y;
output.texCoord1.x = r0.w * -r0.x;
output.texCoord1.y = r0.w * r0.y;
output.texCoord1.z = r0.w * r0.z;
output.texCoord1.w = 1.0f;
//rcp r0.w, r0.w
r0.w = 1.0f / r0.w;
//mul r0.w, r0.w, c45.x
//max r0.x, r0.w, c27.x
//min oD0.w, r0.w, c27.y
//mov oT0, v2
r0.w = r0.w * 0.00033333333f;
output.color.a = min(r0.w, 1.0);
output.texCoord0 = input.texCoord0;
/*
float3 P = mul(input.pos, g_WorldTransforms.WorldView);
float d = length(P);
output.Fog = CalculateFogFactor(g_Fog.FogMax, g_Fog.FogMin, d);
*/
return output;
}
technique t0
technique ReflectionLow
{
pass p0
pass P0
{
Texture[0] = <g_Texture0>; // Seabed texture
Texture[1] = <g_Texture1>; // Environment texture
// All of these constants are set by the game engine before drawing the shader
// Each constant register (c# in the asm code) has 4 floating point values
// Special world * view * projection matrix for ocean shader
VertexShaderConstant[2] = <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
dcl_position v0
dcl_texcoord v2
/* Places the dot product of the world view matrix and v0 in the output register oPos */
dp4 oPos.x, v0, c2
dp4 oPos.y, v0, c3
dp4 oPos.z, v0, c4
dp4 oPos.w, v0, c5
// this is some kind of vector normalization or transform
add r0, v0, -c44
mov r0.z, -r0.z
dp3 r0.w, r0, r0
rsq r0.w, r0.w
/* Output register for texture 1 (environment texture) is modified by register 0 */
mul oT1.x, -r0, r0.w
mul oT1.y, r0, r0.w
mul oT1.z, r0, r0.w
mov oT1.w, c27.y
rcp r0.w, r0.w
mul r0.w, r0.w, c45.x
max r0.x, r0.w, c27.x
min oD0.w, r0.w, c27.y
mov oT0, v2
dp4 r0.z, v0, c5
add r0.x, -r0.z, c26.y
mul oFog, r0.x, c26.z
};
#else
VertexShader = compile vs_1_1 MainVS();
#endif
PixelShader = compile ps_1_3 MainPS(); // effect will not work > ps 1.3
VertexShader = compile vs_2_0 MainVS();
PixelShader = compile ps_2_0 MainPS();
}
}
struct ReflectionHighVSOutput
{
float4 pos : POSITION;
float4 texCoord0 : TEXCOORD0;
float4 texCoord1 : TEXCOORD1;
float4 color : COLOR0;
float Fog : FOG;
float3 Normal : TEXCOORD2;
float3 Reflection : TEXCOORD3;
};
struct ReflectionHighVSInput
{
float4 pos : POSITION;
float4 texCoord0 : TEXCOORD0;
float3 Normal : NORMAL0;
};
ReflectionHighVSOutput ReflectionHighVS(const ReflectionHighVSInput input)
{
ReflectionHighVSOutput output = (ReflectionHighVSOutput)0;
output.pos = mul(input.pos, g_WorldTransforms.WorldViewProjection);
output.Normal = normalize(input.Normal);
float3 normal = normalize(mul(input.Normal, g_WorldTransforms.WorldInverseTranspose));
float3 viewDirection = g_ViewTransforms.CameraPosition - mul(input.pos, g_WorldTransforms.World);
output.Reflection = reflect(-normalize(viewDirection), normal);
return output;
}
float4 ReflectionHighPS(ReflectionHighVSOutput input) : COLOR0
{
return texCUBE(g_EnvironmentSampler, normalize(input.Reflection));
}
technique ReflectionHigh
{
pass P0
{
VertexShader = compile vs_2_0 ReflectionHighVS();
PixelShader = compile ps_2_0 ReflectionHighPS();
//VertexShader = compile vs_2_0 MainVS();
//PixelShader = compile ps_2_0 MainPS();
}
}

View File

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

View File

@ -5,12 +5,24 @@
// the original fixed-function water rendering behavior.
//--------------------------------------------------------------------------------------
//#include "../fxh/SystemVariables.fxh"
#include "../fxh/Transform.fxh"
#include "../fxh/Lighting.fxh"
#include "../fxh/Fog.fxh"
shared texture g_Texture0;
shared float4x4 g_WorldViewProjection;
shared WorldTransforms g_WorldTransforms;
shared ViewTransforms g_ViewTransforms;
shared float4 g_TextureFactor;
const float3 g_WaterNormal = float3(0, 0, 1); // Water is always a flat plane currently, so we can just hardcode this to (0, 0, 1)
shared Material g_WaterMaterial;
shared PointLightInfo g_PointLights;
shared DirectionalLightInfo g_DirectionalLights;
shared FogParams g_Fog;
sampler2D g_WaterTextureSampler =
sampler_state
{
@ -22,31 +34,66 @@ struct VS_OUTPUT
float4 Position : POSITION; // vertex position
float2 TextureUV : TEXCOORD0; // vertex texture coords
float4 Color : COLOR0;
float Fog : FOG;
float3 WorldPos : TEXCOORD1;
/*float3 Normal : TEXCOORD1;*/
float3 ViewDirection : TEXCOORD2;
};
VS_OUTPUT RenderSceneVS(float4 inPos : POSITION,
float4 inDiffuse : COLOR0,
float4 inTextureUV : TEXCOORD0)
float4 inTextureUV : TEXCOORD0
/*float3 Normal : NORMAL*/)
{
VS_OUTPUT Output;
Output.Position = mul(inPos, g_WorldViewProjection);
Output.Position = mul(inPos, g_WorldTransforms.WorldViewProjection);
Output.TextureUV = inTextureUV;
Output.Color = inDiffuse;
// Don't think this is right, but we can use FFP fog unless this is compiled for SM 3.0
//float4 r0;
//r0.z = inPos.z * g_WorldViewProjection[3];
//r0.x = -r0.z + g_Fog.y;
//Output.Fog.x = r0.x * g_Fog.z;
float3 P = mul(inPos, g_WorldTransforms.WorldView);
float d = length(P);
Output.Fog = CalculateFogFactor(g_Fog.FogMax, g_Fog.FogMin, d);
//Output.Normal = mul(Normal, (float3x3)g_WorldTransforms.World);
Output.WorldPos = mul(inPos, g_WorldTransforms.World);
Output.ViewDirection = g_ViewTransforms.CameraPosition - Output.WorldPos;
return Output;
}
float4 RenderScenePS(VS_OUTPUT input) : COLOR0
{
{
float4 texel = tex2D(g_WaterTextureSampler, input.TextureUV);
float4 result = saturate(texel + (1 - texel) * g_TextureFactor); // equivalent to saturate((texel + g_TextureFactor) - (texel * g_TextureFactor));
float3 reflection = -reflect(normalize(-g_DirectionalLights.Direction[g_DirectionalLights.SunIndex]), g_WaterNormal);
float specular = dot(normalize(reflection), normalize(input.ViewDirection));
if (specular > 0.0f)
{
specular = pow(specular, g_WaterMaterial.Power);
result = saturate(result + (specular));
}
for (int i = 0; i < g_PointLights.Count; i++)
{
float3 worldPos = g_PointLights.Position[i] - input.WorldPos;
float3 lightDirection = normalize(input.WorldPos - (g_PointLights.Position[i]));
result += CalculatePointDiffuse(
worldPos,
g_WaterNormal,
-lightDirection,
g_PointLights.Range[i],
g_PointLights.Diffuse[i]);
}
if (g_Fog.Enabled)
{
result = ApplyPixelFog(result, input.Fog, g_Fog.Color);
}
result.a = input.Color.a * g_TextureFactor.a;
return result;
@ -56,7 +103,7 @@ technique RenderScene
{
pass P0
{
VertexShader = compile vs_2_0 RenderSceneVS();
PixelShader = compile ps_2_0 RenderScenePS();
VertexShader = compile vs_3_0 RenderSceneVS();
PixelShader = compile ps_3_0 RenderScenePS();
}
}

View File

@ -1,5 +1,5 @@
#define MAX_DIRECTIONAL_LIGHTS 3
#define MAX_LIGHTS 4
#define MAX_POINT_LIGHTS 4
#define MAX_BLEND_STAGES 2 // Giants does not currently use more than 2
@ -42,9 +42,9 @@
// where each component has been scaled and offset to make it signed.
// The result is replicated into all four (including alpha) channels.
// This is a valid COLOROP only.
#define D3DTOP_DOTPRODUCT3 24,
#define D3DTOP_DOTPRODUCT3 24
// Triadic ops
#define D3DTOP_MULTIPLYADD 25, // Arg0 + Arg1*Arg2
#define D3DTOP_MULTIPLYADD 25 // Arg0 + Arg1*Arg2
#define D3DTOP_LERP 26 // (Arg0)*Arg1 + (1-Arg0)*Arg2
/*

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
{
float4 Diffuse;
@ -13,6 +15,24 @@ struct Lighting
float4 Specular : COLOR1;
};
struct DirectionalLightInfo
{
int Count;
int SunIndex;
float4 Ambient;
float4 Diffuse[MAX_DIRECTIONAL_LIGHTS];
float4 Specular[MAX_DIRECTIONAL_LIGHTS];
float4 Direction[MAX_DIRECTIONAL_LIGHTS];
};
struct PointLightInfo
{
int Count;
float4 Position[MAX_POINT_LIGHTS];
float4 Diffuse[MAX_POINT_LIGHTS];
float Range[MAX_POINT_LIGHTS];
};
struct TextureBlendStage
{
int colorOp;
@ -21,4 +41,51 @@ struct TextureBlendStage
int alphaOp;
int alphaArg1;
int alphaArg2;
};
};
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;
};