mirror of
https://github.com/ncblakely/GiantsTools
synced 2024-11-21 21:55:38 +01:00
Update shaders
This commit is contained in:
parent
11625b367c
commit
ac7a8eb4ba
@ -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);
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
// 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;
|
||||
if (distance > g_DetailFadeStart)
|
||||
{
|
||||
float distNormalized = distance / (g_DetailFadeEnd - g_DetailFadeStart);
|
||||
detailTextureColor = lerp(detailTextureColor, float4(1.f, 1.f, 1.f, 1.f), distNormalized);
|
||||
}
|
||||
|
||||
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
|
||||
{
|
||||
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,6 +291,14 @@ 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,
|
||||
@ -170,17 +307,27 @@ VS_OUTPUT LandscapeVS(
|
||||
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);
|
||||
|
@ -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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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();
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
@ -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,23 +34,30 @@ 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;
|
||||
}
|
||||
@ -47,6 +66,34 @@ 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();
|
||||
}
|
||||
}
|
@ -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
17
Shaders/fxh/Fog.fxh
Normal 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);
|
||||
}
|
@ -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;
|
||||
@ -22,3 +42,50 @@ struct TextureBlendStage
|
||||
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
16
Shaders/fxh/Transform.fxh
Normal 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;
|
||||
};
|
Loading…
Reference in New Issue
Block a user