Files
bluflame/evoke-64k/trunk/ev10/cfg/psterrain.txt
2026-04-18 22:31:51 +02:00

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