DYT/Tool/TritonSDK/Resources/godrays.fx
2024-12-25 22:48:51 +08:00

259 lines
5.2 KiB
HLSL

uniform float4x4 mvProj;
uniform float3 origin;
uniform float spacing;
uniform float3 extinction;
uniform float3 sunDir;
uniform float3 sunColor;
uniform float3 viewer;
uniform float3x3 basis;
uniform float3x3 invBasis;
uniform float2 textureSize;
uniform float3 viewDir;
uniform float visibility;
uniform float fade;
struct VSInput {
float4 position :
POSITION;
};
#ifdef DX9
struct VSOutput {
float4 position :
POSITION;
float3 intensity :
TEXCOORD0;
float3 view :
TEXCOORD1;
};
struct PSSceneIn {
float4 pos :
POSITION0;
float3 intensity :
TEXCOORD0;
float3 view :
TEXCOORD1;
};
struct PSSceneOut {
float4 color :
COLOR;
};
TEXTURE displacementMap;
TEXTURE slopeFoamMap;
sampler2D gDisplacementSampler = sampler_state {
Texture = (displacementMap);
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
AddressU = WRAP;
AddressV = WRAP;
};
sampler2D gSlopeFoamSampler = sampler_state {
Texture = (slopeFoamMap);
MipFilter = LINEAR;
MinFilter = LINEAR;
MagFilter = LINEAR;
AddressU = WRAP;
AddressV = WRAP;
};
#else
struct VSOutput {
float4 position :
SV_Position;
float3 intensity :
TEXCOORD0;
float3 view :
TEXCOORD1;
};
struct PSSceneIn {
float4 pos :
SV_Position;
float3 intensity :
TEXCOORD0;
float3 view :
TEXCOORD1;
};
struct PSSceneOut {
float4 color :
SV_Target;
};
Texture2D displacementMap;
Texture2D slopeFoamMap;
SamplerState gTriLinearSamWrap {
Filter = MIN_MAG_MIP_LINEAR;
AddressU = WRAP;
AddressV = WRAP;
};
#endif
float3 CalculateWaterNormal(inout float3 v)
{
float3 localV = mul(v, basis);
float2 texCoords = localV.xy / textureSize;
#ifdef DX9
float4 tc4 = float4(texCoords.x, texCoords.y, 0.0f, 0.0f);
float3 slopesAndFoam = tex2Dlod(gSlopeFoamSampler, tc4).xyz;
float3 displacement = tex2Dlod(gDisplacementSampler, tc4).xyz;
#else
float3 slopesAndFoam = slopeFoamMap.SampleLevel(gTriLinearSamWrap, texCoords, 0).xyz;
float3 displacement = displacementMap.SampleLevel(gTriLinearSamWrap, texCoords, 0).xyz;
#endif
localV += displacement;
v = mul(localV, invBasis);
float3 sx = float3(1.0, 0.0, slopesAndFoam.x);
float3 sy = float3(0.0, 1.0, slopesAndFoam.y);
float3 nNorm = mul(normalize(cross(sx, sy)), invBasis);
return nNorm;
}
float FastFresnel(float3 I, float3 N)
{
const float R0 = 0.0204;
return R0 + (1.0 - R0) * pow(1 - dot(I, N), 5.0);
}
VSOutput VS(VSInput Input)
{
VSOutput Out;
float4 position = Input.position;
float3 worldPos = position.xyz * float3(spacing, 1, spacing);
worldPos += origin;
float3 normal = CalculateWaterNormal(worldPos);
float vertDist = length(worldPos - viewer);
float totalDist = position.w + vertDist;
if (position.w > 0) {
float3 refr = refract(-sunDir, normal, 1.0 / 1.333);
worldPos += refr * position.w;
Out.intensity = float3(0, 0, 0);
} else {
float tr = 1.0 - FastFresnel(sunDir, normal);
Out.intensity = exp(-totalDist * extinction) * tr * fade;
}
Out.view = worldPos - viewer;
float4 clipPos = mul(float4(worldPos, 1.0), mvProj);
clipPos.z = 0.01;
Out.position = clipPos;
return Out;
}
float ComputeMieScattering(in float3 V, in float3 sunDir)
{
const float g = 0.924;
// const float g = 0.7;
float cosTheta = dot(normalize(V), normalize(sunDir));
float num = 1.0 - g * g;
float den = (1.0 + g * g - 2.0 * g * cosTheta);
den = sqrt(den);
den = den * den * den;
float phase = (1.0 / (4.0 * 3.14159)) * (num / den);
return phase;
}
#ifdef DX9
PSSceneOut PS(float4 pos : VPOS, float3 pIntensity : TEXCOORD0, float3 pView : TEXCOORD1)
{
#else
PSSceneOut PS(PSSceneIn input)
{
float3 pView = input.view;
float3 pIntensity = input.intensity;
#endif
float3 up = mul(float3(0, 0, 1), invBasis);
float3 refractedLight = refract(-sunDir, up, 1.0 / 1.333);
float phase = ComputeMieScattering(-normalize(pView), refractedLight);
float3 finalIntensity = pIntensity * float3(phase, phase, phase);
finalIntensity *= exp(-length(pView) * (3.912 / visibility) * 8.0);
finalIntensity *= sunColor;
float4 color = float4(finalIntensity, 1.0);
color = clamp(color, 0.0, 1.0);
PSSceneOut output;
output.color = color;
return output;
}
#ifdef DX11
technique11 ColorTech {
pass P0
{
SetVertexShader(CompileShader(vs_5_0, VS()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_5_0, PS()));
}
}
#endif
#ifdef DX10
technique10 ColorTech {
pass P0
{
SetVertexShader(CompileShader(vs_4_0, VS()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_4_0, PS()));
}
}
#endif
#ifdef DX10LEVEL9
technique10 ColorTech {
pass P0
{
SetVertexShader(CompileShader(vs_4_0_level_9_1, VS()));
SetGeometryShader(NULL);
SetPixelShader(CompileShader(ps_4_0_level_9_1, PS()));
}
}
#endif
#ifdef DX9
technique {
pass P0
{
SetVertexShader(CompileShader(vs_3_0, VS()));
#ifdef PS30
SetPixelShader(CompileShader(ps_3_0, PS()));
#else
SetPixelShader(CompileShader(ps_2_0, PS()));
#endif
}
}
#endif