342 lines
14 KiB
Plaintext
342 lines
14 KiB
Plaintext
float4x4 viewProj : register(c31);
|
|
float4 resolution : register(c0);
|
|
float3 lightDir : register(c1);
|
|
|
|
sampler2D waveSampler : register(s0);
|
|
sampler3D randomSampler : register(s1);
|
|
|
|
sampler1D dif : register(s2);
|
|
sampler1D spec : register(s3);
|
|
sampler2D shadowSampler : register(s4);
|
|
sampler2D depthSampler : register(s5);
|
|
samplerCUBE envSampler : register(s6);
|
|
|
|
static float3 lightSources[] = {
|
|
float3(19.6f, 8.9f, 2.0f),
|
|
float3(40.3f, 0.7f, 26.1f),
|
|
float3(22.5f, -6.2f, -9.2f),
|
|
float3(-15.9f, 6.8f, -23.9f),
|
|
float3(-5.2f, 8.9f, -29.2f),
|
|
float3(10.1f, 11.4f, -13.6f) };
|
|
static float4 lightColors[] = {
|
|
8.0 * float4(0.7f, 0.6f, 1.0f, 1.0f),
|
|
8.0 * float4(0.7f, 0.6f, 1.0f, 1.0f),
|
|
8.0 * float4(0.7f, 0.6f, 1.0f, 1.0f),
|
|
8.0 * float4(0.7f, 0.6f, 1.0f, 1.0f),
|
|
8.0 * float4(0.7f, 0.6f, 1.0f, 1.0f),
|
|
8.0 * float4(0.7f, 0.6f, 1.0f, 1.0f) };
|
|
static float lightRanges[] = {
|
|
3.0f / 2.6f,
|
|
3.0f / 3.5f,
|
|
3.0f / 5.3f,
|
|
3.0f / 1.0f,
|
|
3.0f / 1.2f,
|
|
3.0f / 1.6f };
|
|
static int lightCount = 6;
|
|
|
|
struct psIn
|
|
{
|
|
float4 c : COLOR0;
|
|
float2 t : TEXCOORD0;
|
|
float3 n : TEXCOORD1;
|
|
float3 v : TEXCOORD2;
|
|
float4 s : TEXCOORD3;
|
|
float3 w : TEXCOORD4;
|
|
};
|
|
|
|
float4 tex2D_3D(uniform sampler2D smplr, in float3 t, in float3 n)
|
|
{
|
|
float4 front = tex2D(smplr, t.xy);
|
|
float4 side = tex2D(smplr, t.zy);
|
|
float4 floor = tex2D(smplr, t.xz);
|
|
|
|
return lerp( lerp(side, front, abs(n.z)), floor, abs(n.y) );
|
|
}
|
|
|
|
float4 ps_main(psIn i, uniform bool bCrystalLight) : color0
|
|
{
|
|
// Shadow AA
|
|
float2 sc = i.s.xy / i.s.w;
|
|
float aa = abs( tex2D(depthSampler, sc).x - i.s.z );
|
|
float2 ddaa = float2(ddx(aa), ddy(aa));
|
|
float2 aaetc = sign(-ddaa) * resolution.zw;
|
|
sc += aaetc * saturate(4.f * aa);
|
|
|
|
float3 t = i.w / 128;
|
|
float3 n = normalize(i.n);
|
|
float3 v = normalize(i.v);
|
|
|
|
// Composition
|
|
float iceAmount = 0.68f;
|
|
float rock = smoothstep(iceAmount - 0.05f, iceAmount, tex2D_3D(waveSampler, 0.6f * t, n).a);
|
|
float rockBlend = smoothstep( -0.7f, 1.0f, rock );
|
|
float transition = 1.0f - abs( 2.0f * rock - 1.0f );
|
|
|
|
// Surface
|
|
float3 vSurfacePoint = i.w - n * rock;
|
|
float3 vSurfacePointDDX = ddx(vSurfacePoint), vSurfacePointDDY = ddy(vSurfacePoint);
|
|
float3 vSurfaceNormal = normalize( cross(vSurfacePointDDX, vSurfacePointDDY) );
|
|
float3 vFlatSurfaceNormal = vSurfaceNormal - n * dot(n, vSurfaceNormal);
|
|
|
|
float4 fShadow = float4(0.2f, 0.4f, 0.6f, 0.8f) + float4(0.8f, 0.6f, 0.4f, 0.2f) * tex2D(shadowSampler, sc).x;
|
|
|
|
float3 tc = (i.w - v) * 8;
|
|
|
|
float3 vCellCoord1 = tc + 1.5f * tex3D(randomSampler, tc / 48).xyz;
|
|
float3 vCellCoord2 = 1.25f * tc + 3.0f * tex3D(randomSampler, tc / 32).xyz;
|
|
float3 vCellCoord1Frac = frac(vCellCoord1) * 2.0f - 1.0f;
|
|
float3 vCellCoord2Frac = frac(vCellCoord2) * 2.0f - 1.0f;
|
|
vCellCoord1 = floor(vCellCoord1) + sign(vCellCoord1Frac) * pow( abs(vCellCoord1Frac), 8 ) * 0.5f + 0.5f;
|
|
vCellCoord2 = floor(vCellCoord2) + sign(vCellCoord2Frac) * pow( abs(vCellCoord2Frac), 8 ) * 0.5f + 0.5f;
|
|
|
|
float3 vCellNormal1 = normalize( tex3D(randomSampler, vCellCoord1 / 32).xyz * 2.0f - 1.0f );
|
|
float3 vCellNormal2 = normalize( tex3D(randomSampler, vCellCoord2 / 32).xyz * 2.0f - 1.0f );
|
|
float3 vFlatCellNormal1 = vCellNormal1 - n * dot(n, vCellNormal1);
|
|
float3 vFlatCellNormal2 = vCellNormal2 - n * dot(n, vCellNormal2);
|
|
|
|
float3 rockN = tex2D_3D(waveSampler, t, n).xyz
|
|
* (0.5 - abs( cos( (t.x + 0.1 * tex2D_3D(waveSampler, t * 2, n).a) * 20 ) ) );
|
|
float3 roughN = tex2D_3D(waveSampler, t * 10, n).xyz * 0.3
|
|
+ tex2D_3D(waveSampler, t * 100, n).xyz * 0.4;
|
|
|
|
float3 fIceNormal = normalize( n + 0.2f * roughN + transition * vFlatSurfaceNormal );
|
|
float3 fIceNormalEx = normalize(fIceNormal - 0.7f * n * dot(fIceNormal, n));
|
|
float3 fRockNormal = normalize( n + 0.4f * (roughN + rockN) );
|
|
float3 fRockNormalEx = normalize(fRockNormal - 0.6f * n * dot(fRockNormal, n));
|
|
|
|
float3 fIceCellNormal1 = normalize(fIceNormalEx - 0.1f * vFlatCellNormal1);
|
|
float3 fIceCellNormal2 = vCellNormal2; // normalize(fIceNormalEx - 0.7f * vFlatCellNormal2);
|
|
|
|
float2 fLight = float2( dot(fIceNormal, -lightDir), dot(fRockNormal, -lightDir) );
|
|
float2 fRimLight = 1.0f - abs(fLight); // * saturate( dot(lightDir, v) );
|
|
fLight = min(fShadow.y * fLight, fLight); // Occlude only direct lighting (back-shadowing artifacts otherwise)
|
|
fLight = saturate( 0.2f * saturate(1.0f + 2.0f * fLight) + 0.8f * saturate(fLight) ); // Ambient, Diffuse
|
|
fRimLight *= fShadow.w;
|
|
|
|
float3 h = normalize( v + -lightDir );
|
|
float4 hdn = float4( abs( dot( h, fIceNormalEx ) ), dot( h, fRockNormalEx ), dot( h, fIceCellNormal1 ), dot( h, fIceCellNormal2 ) );
|
|
float4 fSpecularity = fShadow.ywww * pow( saturate( hdn ), float4(8.0f, 4.0f, 4.0f, 8.0f) );
|
|
|
|
float4 fIceCrystalLight = 0.0f;
|
|
float4 fRockCrystalLight = 0.0f;
|
|
|
|
if(bCrystalLight)
|
|
{
|
|
for (int l = 0; l < lightCount; l++)
|
|
{
|
|
float3 toW = (i.w - lightSources[l]) * lightRanges[l];
|
|
float3 dirToW = normalize(toW);
|
|
float2 lgt = 1.0f / ( 1.0f + dot(toW, toW) );
|
|
lgt *= saturate( float2( dot(-dirToW, fIceNormal) , dot(-dirToW, fRockNormal) ) );
|
|
|
|
fIceCrystalLight += lgt.x * lightColors[l];
|
|
fRockCrystalLight += lgt.y * lightColors[l];
|
|
}
|
|
}
|
|
|
|
// Ice
|
|
float fIceSpecBoost = 0.4f * saturate( 0.5f - 0.5f * dot(lightDir, v) );
|
|
// return float2(fIceSpecBoost, 1).xxxy;
|
|
float fIceSpecularity = dot( fSpecularity.xzw, float3(0.35f, 0.35f, 0.4f + fIceSpecBoost) ); // float3(0.35f, 0.35f, 0.5f)
|
|
float4 fIceSpecLighting = 0.4f * tex1D(spec, 0.85f + 0.15f * fIceSpecularity) * fIceSpecularity;
|
|
|
|
float4 fIceLighting = tex1D(dif, fLight.x) + fIceCrystalLight;
|
|
float4 fIceRimLighting = tex1D(dif, fRimLight.x);
|
|
|
|
float fIceRimFresnel = pow( saturate( 1.0f - dot(fIceNormal, v) ), 8 ) * saturate( 0.5f + 0.5f * dot(lightDir, v) );
|
|
|
|
float fIceFresnel = 0.5f + dot(0.5f / 3, float3( dot(v, fIceNormalEx), dot(v, fIceCellNormal1), dot(v, fIceCellNormal2) ));
|
|
float fPlaneIceFresnel = 0.5f + 0.5f * dot(v, n);
|
|
fIceFresnel = lerp(fPlaneIceFresnel, max(fIceFresnel, fPlaneIceFresnel), 0.5f);
|
|
fIceFresnel = pow(fIceFresnel, 4);
|
|
|
|
float4 fIceColor = lerp(
|
|
float4(0.665f, 0.738f, 0.901f, 1.0f),
|
|
float4(0.965f, 0.938f, 0.901f, 1.0f),
|
|
fIceFresnel );
|
|
fIceSpecLighting *= fIceColor;
|
|
fIceColor *= fIceLighting;
|
|
fIceColor += float4(0.905f, 0.908f, 0.901f, 1.0f) * fIceRimFresnel * fIceRimLighting;
|
|
|
|
fIceColor.w *= saturate( 1.0f - dot( float2(0.3f, 0.7f), fSpecularity.zw ) );
|
|
|
|
// Rock
|
|
float4 fRockLighting = tex1D(dif, fLight.y) + fRockCrystalLight
|
|
+ 0.2f * tex1D(spec, 0.75f + 0.25f * fSpecularity.y) * fSpecularity.y;
|
|
float4 fRockColor = float4(0.45f, 0.4f, 0.5f, 1.0f);
|
|
fRockColor *= fRockLighting;
|
|
|
|
// Compose
|
|
float4 fColor = lerp( fIceColor, fRockColor, saturate(rockBlend) ); // saturate(rock)
|
|
fColor += fIceSpecLighting * (rock < 0.5f);
|
|
|
|
return fColor;
|
|
}
|
|
|
|
static float3 g_fLightFilterColor = float3(0.3f, 0.45f, 0.5f);
|
|
|
|
float4 ps_main_isle(psIn i) : color0
|
|
{
|
|
// Shadow AA
|
|
float2 sc = i.s.xy / i.s.w;
|
|
float aa = abs( tex2D(depthSampler, sc).x - i.s.z );
|
|
float2 ddaa = float2(ddx(aa), ddy(aa));
|
|
float2 aaetc = sign(-ddaa) * resolution.zw;
|
|
sc += aaetc * saturate(4.f * aa);
|
|
|
|
float3 t = i.w / 128;
|
|
float3 n = normalize(i.n);
|
|
float3 v = normalize(i.v);
|
|
|
|
// Composition
|
|
float shore = 0.4f * (i.w.y - 5) + tex2D_3D(waveSampler, t * 3, n).a;
|
|
// shore = max(0.02, smoothstep(0.0, 1.5, shore) * (smoothstep(0.6, 0.7, n.y)) * 0.5);
|
|
shore = saturate(1.0f - shore);
|
|
|
|
float rock = (1 - smoothstep(0.6, 0.8, n.y)) * smoothstep(0.5, 0.7, tex2D_3D(waveSampler, t * 2, n).a);
|
|
rock += (1 - smoothstep(0.4, 0.8, n.y)) * smoothstep(0.35, 0.45, tex2D_3D(waveSampler, t * 2, n).a);
|
|
rock = rock / 2 + shore;
|
|
float rockBlend = smoothstep( -0.7f, 1.0f, rock );
|
|
float transition = saturate( 1.0f - 5.0f * abs( 2.0f * rock - 1.0f ) );
|
|
|
|
// Surface
|
|
float3 vSurfacePoint = i.w - n * rock;
|
|
float3 vSurfacePointDDX = ddx(vSurfacePoint), vSurfacePointDDY = ddy(vSurfacePoint);
|
|
float3 vSurfaceNormal = normalize( cross(vSurfacePointDDX, vSurfacePointDDY) );
|
|
float3 vFlatSurfaceNormal = vSurfaceNormal - n * dot(n, vSurfaceNormal);
|
|
|
|
float4 fShadow = float4(0.2f, 0.4f, 0.6f, 0.8f) + float4(0.8f, 0.6f, 0.4f, 0.2f) * tex2D(shadowSampler, sc).x;
|
|
|
|
float3 tc = (i.w - v) * 8;
|
|
|
|
float3 vCellCoord1 = tc + 1.5f * tex3D(randomSampler, tc / 48).xyz;
|
|
float3 vCellCoord2 = 1.25f * tc + 3.0f * tex3D(randomSampler, tc / 32).xyz;
|
|
float3 vCellCoord1Frac = frac(vCellCoord1) * 2.0f - 1.0f;
|
|
float3 vCellCoord2Frac = frac(vCellCoord2) * 2.0f - 1.0f;
|
|
vCellCoord1 = floor(vCellCoord1) + sign(vCellCoord1Frac) * pow( abs(vCellCoord1Frac), 8 ) * 0.5f + 0.5f;
|
|
vCellCoord2 = floor(vCellCoord2) + sign(vCellCoord2Frac) * pow( abs(vCellCoord2Frac), 8 ) * 0.5f + 0.5f;
|
|
|
|
float3 vCellNormal1 = normalize( tex3D(randomSampler, vCellCoord1 / 32).xyz * 2.0f - 1.0f );
|
|
float3 vCellNormal2 = normalize( tex3D(randomSampler, vCellCoord2 / 32).xyz * 2.0f - 1.0f );
|
|
float3 vFlatCellNormal1 = vCellNormal1 - n * dot(n, vCellNormal1);
|
|
float3 vFlatCellNormal2 = vCellNormal2 - n * dot(n, vCellNormal2);
|
|
|
|
float3 rockN = tex2D_3D(waveSampler, t, n).xyz
|
|
* (0.5 - abs( cos( (t.x + 0.1 * tex2D_3D(waveSampler, t * 2, n).a) * 20 ) ) );
|
|
float3 roughN = tex2D_3D(waveSampler, t * 10, n).xyz * 0.3
|
|
+ tex2D_3D(waveSampler, t * 100, n).xyz * 0.4;
|
|
|
|
float3 fIceNormal = normalize( n + 0.2f * roughN + transition * vFlatSurfaceNormal );
|
|
float3 fIceNormalEx = normalize(fIceNormal - 0.7f * n * dot(fIceNormal, n));
|
|
float3 fRockNormal = normalize( n + 0.4f * (roughN + rockN) );
|
|
float3 fRockNormalEx = normalize(fRockNormal - 0.6f * n * dot(fRockNormal, n));
|
|
|
|
float3 fIceCellNormal1 = normalize(fIceNormalEx - 0.1f * vFlatCellNormal1);
|
|
float3 fIceCellNormal2 = vCellNormal2; // normalize(fIceNormalEx - 0.7f * vFlatCellNormal2);
|
|
|
|
float2 fLight = float2( dot(fIceNormal, -lightDir), dot(fRockNormal, -lightDir) );
|
|
float2 fRimLight = 1.0f - abs(fLight); // * saturate( dot(lightDir, v) );
|
|
fLight = min(fShadow.y * fLight, fLight); // Occlude only direct lighting (back-shadowing artifacts otherwise)
|
|
fLight = saturate( 0.2f * saturate(1.0f + 2.0f * fLight) + 0.8f * saturate(fLight) ); // Ambient, Diffuse
|
|
fRimLight *= fShadow.w;
|
|
|
|
float3 h = normalize( v + -lightDir );
|
|
float4 hdn = float4( abs( dot( h, fIceNormalEx ) ), dot( h, fRockNormalEx ), dot( h, fIceCellNormal1 ), dot( h, fIceCellNormal2 ) );
|
|
float4 fSpecularity = fShadow.ywww * pow( saturate( hdn ), float4(8.0f, 4.0f, 4.0f, 8.0f) );
|
|
|
|
// Ice
|
|
float fIceSpecBoost = 0.4f * saturate( 0.5f - 0.5f * dot(lightDir, v) );
|
|
// return float2(fIceSpecBoost, 1).xxxy;
|
|
float fIceSpecularity = dot( fSpecularity.xzw, float3(0.35f, 0.35f, 0.4f + fIceSpecBoost) ); // float3(0.35f, 0.35f, 0.5f)
|
|
float4 fIceSpecLighting = 0.4f * tex1D(spec, 0.85f + 0.15f * fIceSpecularity) * fIceSpecularity;
|
|
|
|
float4 fIceLighting = tex1D(dif, fLight.x);
|
|
float4 fIceRimLighting = tex1D(dif, fRimLight.x);
|
|
|
|
float fIceRimFresnel = pow( saturate( 1.0f - dot(fIceNormal, v) ), 8 ) * saturate( 0.5f + 0.5f * dot(lightDir, v) );
|
|
|
|
float fIceFresnel = 0.5f + dot(0.5f / 3, float3( dot(v, fIceNormalEx), dot(v, fIceCellNormal1), dot(v, fIceCellNormal2) ));
|
|
float fPlaneIceFresnel = 0.5f + 0.5f * dot(v, n);
|
|
fIceFresnel = lerp(fPlaneIceFresnel, max(fIceFresnel, fPlaneIceFresnel), 0.5f);
|
|
fIceFresnel = pow(fIceFresnel, 4);
|
|
|
|
float4 fIceColor = lerp(
|
|
float4(0.665f, 0.738f, 0.901f, 1.0f),
|
|
float4(0.965f, 0.938f, 0.901f, 1.0f),
|
|
fIceFresnel );
|
|
fIceSpecLighting *= fIceColor;
|
|
fIceColor *= fIceLighting;
|
|
fIceColor += float4(0.905f, 0.908f, 0.901f, 1.0f) * fIceRimFresnel * fIceRimLighting;
|
|
|
|
fIceColor.w *= saturate( 1.0f - dot( float2(0.3f, 0.7f), fSpecularity.zw ) );
|
|
|
|
// Rock
|
|
float4 fRockLighting = tex1D(dif, fLight.y)
|
|
+ 0.2f * tex1D(spec, 0.75f + 0.25f * fSpecularity.y) * fSpecularity.y;
|
|
float4 fRockColor = float4(0.45f, 0.4f, 0.5f, 1.0f);
|
|
fRockColor *= fRockLighting;
|
|
|
|
// Compose
|
|
float4 fColor = lerp( fIceColor, fRockColor, saturate(rockBlend) ); // saturate(rock)
|
|
fColor += fIceSpecLighting * (rock < 0.5f);
|
|
|
|
// Fade edge
|
|
fColor.xyz *= pow(g_fLightFilterColor, max(-15 - i.w.y, 0) * 0.2f);
|
|
|
|
return fColor;
|
|
}
|
|
|
|
float4 ps_main_old(psIn i) : color0
|
|
{
|
|
return ps_main_isle(i);
|
|
|
|
// Shadow AA
|
|
float2 sc = i.s.xy / i.s.w;
|
|
float aa = abs( tex2D(depthSampler, sc).x - i.s.z );
|
|
float2 ddaa = float2(ddx(aa), ddy(aa));
|
|
float2 aaetc = sign(-ddaa) * resolution.zw;
|
|
sc += aaetc * saturate(4.f * aa);
|
|
|
|
float fShadow = 0.2f + 0.8f * tex2D(shadowSampler, sc);
|
|
float3 n = normalize(i.n);
|
|
float3 t = i.w / 128;
|
|
|
|
float shore = i.w.y - 5 + tex2D_3D(waveSampler, t * 3, n).a;
|
|
shore = 0.2 + max(0.02, smoothstep(0.0, 1.5, shore) * (smoothstep(0.6, 0.7, n.y)) * 0.5);
|
|
|
|
float rock = 1-((1-smoothstep(0.6, 0.7, n.y)) * smoothstep(0.5, 0.7, tex2D_3D(waveSampler, t * 2, n).a));
|
|
return shore;
|
|
|
|
float3 pn = n;
|
|
pn += shore * tex2D_3D(waveSampler, t, n).xyz * (0.5-abs(cos((t.x + 0.1 * tex2D_3D(waveSampler, t * 2, n).a) * 20)));
|
|
pn += shore * tex2D_3D(waveSampler, t * 10, n).xyz * 0.3;
|
|
pn += shore * tex2D_3D(waveSampler, t * 100, n).xyz * 0.4;
|
|
pn = normalize(pn);
|
|
float3 pnn = normalize(pn - 0.9f * n * dot(pn, n));
|
|
|
|
float fIceSpecularity = 0.003f * pow( texCUBE(envSampler, reflect(-i.v, pnn)).g, 16.0f) * fShadow;
|
|
float fSnowSpecularity = 0.3f * saturate( pow( texCUBE(envSampler, reflect(-i.v, pnn)).g, 6.0f) * fShadow );
|
|
|
|
float fLight = dot( pn, -lightDir);
|
|
fLight = min(fShadow * fLight, fLight); // Occlude only direct lighting (back-shadowing artifacts otherwise)
|
|
fLight = saturate( 0.2f * saturate(1.0f + 2.0f * fLight) + 0.8f * saturate(fLight) ); // Ambient, Diffuse
|
|
|
|
float light = tex1D( dif, 0.3f * (1 - min(0.3, pow(dot(pn, n), 8))) + 0.7f * fLight );
|
|
float4 reflection = texCUBE(envSampler, reflect(-i.v, pn));
|
|
float4 fColor = lerp(i.c,
|
|
light * float4(0.15, 0.2, 0.25, 0.0) + 0.4 * rock * smoothstep(-0.5, 0.5, pn.y),
|
|
(1.0 - shore));
|
|
return float4(fColor.xyz, 1.0f);
|
|
|
|
// Lighting
|
|
fColor.xyz *= light;
|
|
fColor += lerp(fSnowSpecularity, fIceSpecularity, rock * (1.0 - shore));
|
|
|
|
return float4(fColor.xyz, 1.0f);
|
|
}
|
|
|
|
float4 ps_terrain(psIn i) : color0 { return ps_main_old(i); };
|
|
|
|
float4 ps_cave(psIn i) : color0 { return ps_main(i, true); };
|
|
|
|
float4 ps_cave_ground(psIn i) : color0 { return ps_main(i, false); }; |