TEXTURE2D_FLOAT(_GMSTraxBuffer); #if _TRAXSINGLE TEXTURE2D(_TraxDiff); TEXTURE2D(_TraxNSAO); #endif #if _TRAXARRAY TEXTURE2D_ARRAY(_TraxArrayDiff); TEXTURE2D_ARRAY(_TraxArrayNSAO); #endif #define TRAXSAMPLEQUADRATIC2D(tex, uv, texelSize, ret) \ { \ float2 q = frac(uv * texelSize.zw); \ float2 c = (q*(q - 1.0) + 0.5) / texelSize.zw; \ float2 w0 = uv - c; \ float2 w1 = uv + c; \ half4 s = SAMPLE_TEXTURE2D(tex, shared_linear_clamp_sampler, float2(w0.x, w0.y)) \ + SAMPLE_TEXTURE2D(tex, shared_linear_clamp_sampler, float2(w0.x, w1.y)) \ + SAMPLE_TEXTURE2D(tex, shared_linear_clamp_sampler, float2(w1.x, w1.y)) \ + SAMPLE_TEXTURE2D(tex, shared_linear_clamp_sampler, float2(w1.x, w0.y)); \ ret = s / 4.0; \ } \ float SampleTraxBufferLOD(float3 worldPos, float3 vertexNormal, float h) { // generate UVs for the buffer, which is moving float2 uv = worldPos.xz; uv -= _GMSTraxBufferPosition.xz; uv /= max(_GMSTraxBufferWorldSize, 1); float fade = saturate(distance(uv, float2(0.0, 0.0))); fade = 1 - pow(fade, 8); uv *= 0.5; uv += 0.5; float vn = saturate(sign(dot(vertexNormal, float3(0, 1, 0)))); #if _TRAXQUADRATIC float2 q = frac(uv * _GMSTraxBuffer_TexelSize.zw); float2 c = (q*(q - 1.0) + 0.5) / _GMSTraxBuffer_TexelSize.zw; float2 w0 = uv - c; float2 w1 = uv + c; half s = SAMPLE_TEXTURE2D_LOD(_GMSTraxBuffer, shared_linear_clamp_sampler, w0.xy, 0).r + + SAMPLE_TEXTURE2D_LOD(_GMSTraxBuffer, shared_linear_clamp_sampler, float2(w0.x, w1.y), 0).r + SAMPLE_TEXTURE2D_LOD(_GMSTraxBuffer, shared_linear_clamp_sampler, float2(w1.x, w1.y), 0).r + SAMPLE_TEXTURE2D_LOD(_GMSTraxBuffer, shared_linear_clamp_sampler, float2(w1.x, w0.y), 0).r; s /= 4; #else float s = SAMPLE_TEXTURE2D_LOD(_GMSTraxBuffer, shared_linear_clamp_sampler, uv, 0).r; #endif return 1.0 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn; } float SampleTraxBuffer(float3 worldPos, float3 vertexNormal, out float3 norm) { float2 uv = worldPos.xz; uv -= _GMSTraxBufferPosition.xz; uv /= max(_GMSTraxBufferWorldSize, 1); float fade = saturate(distance(uv, float2(0.0, 0.0))); fade = 1 - pow(fade, 3); uv *= 0.5; uv += 0.5; float2 offset = _GMSTraxBuffer_TexelSize.xy; float vn = saturate(sign(dot(vertexNormal, float3(0, 1, 0)))); #if _TRAXQUADRATIC float4 sr, sr1, sr2, sr3, sr4; TRAXSAMPLEQUADRATIC2D(_GMSTraxBuffer, uv, _GMSTraxBuffer_TexelSize, sr); TRAXSAMPLEQUADRATIC2D(_GMSTraxBuffer, uv + offset * float2(0, -1), _GMSTraxBuffer_TexelSize, sr1); TRAXSAMPLEQUADRATIC2D(_GMSTraxBuffer, uv + offset * float2(-1, 0), _GMSTraxBuffer_TexelSize, sr2); TRAXSAMPLEQUADRATIC2D(_GMSTraxBuffer, uv + offset * float2(1, 0), _GMSTraxBuffer_TexelSize, sr3); TRAXSAMPLEQUADRATIC2D(_GMSTraxBuffer, uv + offset * float2(0, 1), _GMSTraxBuffer_TexelSize, sr4); float s = sr.r; float s1 = sr1.r; float s2 = sr2.r; float s3 = sr3.r; float s4 = sr4.r; #else float s = SAMPLE_TEXTURE2D(_GMSTraxBuffer, shared_linear_clamp_sampler, uv).r; float s1 = SAMPLE_TEXTURE2D(_GMSTraxBuffer, shared_linear_clamp_sampler, uv + offset * float2(0, -1)).r; float s2 = SAMPLE_TEXTURE2D(_GMSTraxBuffer, shared_linear_clamp_sampler, uv + offset * float2(-1, 0)).r; float s3 = SAMPLE_TEXTURE2D(_GMSTraxBuffer, shared_linear_clamp_sampler, uv + offset * float2(1, 0)).r; float s4 = SAMPLE_TEXTURE2D(_GMSTraxBuffer, shared_linear_clamp_sampler, uv + offset * float2(0, 1)).r; #endif float r = 1 - saturate((worldPos.y + _GMSTraxFudgeFactor) - s) * fade * vn; // generate normals norm.x = (s1 - s4) * 0.25; norm.y = (s2 - s3) * 0.25; norm.z = 2; norm = normalize(norm); norm.xy *= 1 - r; return r; } #if _TRAXSINGLE || _TRAXARRAY || _TRAXNOTEXTURE || _SNOWFOOTSTEPS void ApplyTrax(inout RawSamples samples, Config config, float3 worldPos, float traxBuffer, float3 traxNormal) { #if _PERTEXTRAXOPACITY || _PERTEXTRAXNORMALSTR SAMPLE_PER_TEX(strs, 20.5, config, half4(1.0, 1.0, 1.0, 0.0)); #else half4 strs0 = half4(1,1,1,1); half4 strs1 = half4(1,1,1,1); half4 strs2 = half4(1,1,1,1); half4 strs3 = half4(1,1,1,1); #endif #if _PERTEXTRAXTINT SAMPLE_PER_TEX(ptTint, 21.5, config, half4(0.5, 0.5, 0.5, 1.0)); ptTint0 *= 2; ptTint1 *= 2; ptTint2 *= 2; ptTint3 *= 2; #else half4 ptTint0 = half4(1,1,1,1); half4 ptTint1 = half4(1,1,1,1); half4 ptTint2 = half4(1,1,1,1); half4 ptTint3 = half4(1,1,1,1); #endif half texBlend = _TraxTextureBlend; #if _TRAXNOTEXTURE texBlend = 1; #endif float traxBuffer0 = 1 - ((1 - traxBuffer) * texBlend * strs0.y); float traxBuffer1 = 1 - ((1 - traxBuffer) * texBlend * strs1.y); float traxBuffer2 = 1 - ((1 - traxBuffer) * texBlend * strs2.y); float traxBuffer3 = 1 - ((1 - traxBuffer) * texBlend * strs3.y); float3 traxNormal0 = traxNormal * _TraxNormalStrength * strs0.z; float3 traxNormal1 = traxNormal * _TraxNormalStrength * strs1.z; float3 traxNormal2 = traxNormal * _TraxNormalStrength * strs2.z; float3 traxNormal3 = traxNormal * _TraxNormalStrength * strs3.z; #if _TRAXNOTEXTURE // just tint.. samples.albedo0 = lerp(samples.albedo0 * ptTint0, samples.albedo0, traxBuffer0); samples.albedo1 = lerp(samples.albedo1 * ptTint1, samples.albedo1, traxBuffer1); samples.albedo2 = lerp(samples.albedo2 * ptTint2, samples.albedo2, traxBuffer2); samples.albedo3 = lerp(samples.albedo3 * ptTint3, samples.albedo3, traxBuffer3); samples.normSAO0 = lerp(samples.normSAO0 + half4(traxNormal0.xy, 0, 0), samples.normSAO0, traxBuffer0); samples.normSAO1 = lerp(samples.normSAO1 + half4(traxNormal1.xy, 0, 0), samples.normSAO1, traxBuffer1); samples.normSAO2 = lerp(samples.normSAO2 + half4(traxNormal2.xy, 0, 0), samples.normSAO2, traxBuffer2); samples.normSAO3 = lerp(samples.normSAO3 + half4(traxNormal3.xy, 0, 0), samples.normSAO3, traxBuffer3); #if _SURFACENORMALS samples.surf0 = lerp(samples.surf0 + ConvertNormal2ToGradient(traxNormal0.xy), traxBuffer0); samples.surf1 = lerp(samples.surf1 + ConvertNormal2ToGradient(traxNormal1.xy), traxBuffer1); samples.surf2 = lerp(samples.surf2 + ConvertNormal2ToGradient(traxNormal2.xy), traxBuffer2); samples.surf3 = lerp(samples.surf3 + ConvertNormal2ToGradient(traxNormal3.xy), traxBuffer3); #endif #elif _TRAXSINGLE float2 uv = config.uv * _TraxUVScales; float2 fsdx = ddx(config.uv) * _TraxUVScales; float2 fsdy = ddy(config.uv) * _TraxUVScales; half4 albedo = SAMPLE_TEXTURE2D_GRAD(_TraxDiff, sampler_Diffuse, uv, fsdx, fsdy); half4 normSAO = SAMPLE_TEXTURE2D_GRAD(_TraxNSAO, sampler_NormalSAO, uv, fsdx, fsdy).agrb; normSAO.xy = normSAO.xy * 2 - 1; COUNTSAMPLE COUNTSAMPLE half h0 = HeightBlend(albedo.a, samples.albedo0.a, traxBuffer0, _Contrast); half h1 = HeightBlend(albedo.a, samples.albedo1.a, traxBuffer1, _Contrast); half h2 = HeightBlend(albedo.a, samples.albedo2.a, traxBuffer2, _Contrast); half h3 = HeightBlend(albedo.a, samples.albedo3.a, traxBuffer3, _Contrast); h0 = lerp(traxBuffer0, h0, _TraxInterpContrast); h1 = lerp(traxBuffer1, h1, _TraxInterpContrast); h2 = lerp(traxBuffer2, h2, _TraxInterpContrast); h3 = lerp(traxBuffer3, h3, _TraxInterpContrast); samples.albedo0.rgba = lerp(albedo * ptTint0, samples.albedo0, h0); samples.normSAO0.rgba = lerp(normSAO + half4(traxNormal0.xy, 0, 0), samples.normSAO0, h0); samples.albedo1.rgba = lerp(albedo * ptTint1, samples.albedo1, h1); samples.normSAO1.rgba = lerp(normSAO + half4(traxNormal1.xy, 0, 0), samples.normSAO1, h1); samples.albedo2.rgba = lerp(albedo * ptTint2, samples.albedo2, h2); samples.normSAO2.rgba = lerp(normSAO + half4(traxNormal2.xy, 0, 0), samples.normSAO2, h2); samples.albedo3.rgba = lerp(albedo * ptTint3, samples.albedo3, h3); samples.normSAO3.rgba = lerp(normSAO + half4(traxNormal3.xy, 0, 0), samples.normSAO3, h3); #if _SURFACENORMALS samples.surf0 = lerp(ConvertNormal2ToGradient(normSAO.xy + traxNormal0.xy), samples.surf0, h0); samples.surf1 = lerp(ConvertNormal2ToGradient(normSAO.xy + traxNormal1.xy), samples.surf1, h1); samples.surf2 = lerp(ConvertNormal2ToGradient(normSAO.xy + traxNormal2.xy), samples.surf2, h2); samples.surf3 = lerp(ConvertNormal2ToGradient(normSAO.xy + traxNormal3.xy), samples.surf3, h3); #endif #elif _TRAXARRAY float2 uv = config.uv * _TraxUVScales; float2 fsdx = ddx(config.uv) * _TraxUVScales; float2 fsdy = ddy(config.uv) * _TraxUVScales; half4 albedo0 = SAMPLE_TEXTURE2D_ARRAY_GRAD(_TraxArrayDiff, sampler_Diffuse, uv, config.uv0.z, fsdx, fsdy); half4 normSAO0 = SAMPLE_TEXTURE2D_ARRAY_GRAD(_TraxArrayNSAO, sampler_NormalSAO, uv, config.uv0.z, fsdx, fsdy).agrb; normSAO0.xy = normSAO0.xy * 2 - 1; half4 albedo1 = SAMPLE_TEXTURE2D_ARRAY_GRAD(_TraxArrayDiff, sampler_Diffuse, uv, config.uv1.z, fsdx, fsdy); half4 normSAO1 = SAMPLE_TEXTURE2D_ARRAY_GRAD(_TraxArrayNSAO, sampler_NormalSAO, uv, config.uv1.z, fsdx, fsdy).agrb; normSAO1.xy = normSAO1.xy * 2 - 1; COUNTSAMPLE COUNTSAMPLE COUNTSAMPLE COUNTSAMPLE half h0 = HeightBlend(albedo0.a, samples.albedo0.a, traxBuffer0, _Contrast); half h1 = HeightBlend(albedo1.a, samples.albedo1.a, traxBuffer1, _Contrast); h0 = lerp(traxBuffer0, h0, _TraxInterpContrast); h1 = lerp(traxBuffer1, h1, _TraxInterpContrast); #if !_MAX2LAYER half4 albedo2 = SAMPLE_TEXTURE2D_ARRAY_GRAD(_TraxArrayDiff, sampler_Diffuse, uv, config.uv2.z, fsdx, fsdy); half4 normSAO2 = SAMPLE_TEXTURE2D_ARRAY_GRAD(_TraxArrayNSAO, sampler_NormalSAO, uv, config.uv2.z, fsdx, fsdy).agrb; half h2 = HeightBlend(albedo2.a, samples.albedo2.a, traxBuffer2, _Contrast); h2 = lerp(traxBuffer2, h2, _TraxInterpContrast); normSAO2.xy = normSAO2.xy * 2 - 1; COUNTSAMPLE COUNTSAMPLE #endif #if !_MAX3LAYER || !_MAX2LAYER half4 albedo3 = SAMPLE_TEXTURE2D_ARRAY_GRAD(_TraxArrayDiff, sampler_Diffuse, uv, config.uv3.z, fsdx, fsdy); half4 normSAO3 = SAMPLE_TEXTURE2D_ARRAY_GRAD(_TraxArrayNSAO, sampler_NormalSAO, uv, config.uv3.z, fsdx, fsdy).agrb; normSAO3.xy = normSAO3.xy * 2 - 1; half h3 = HeightBlend(albedo3.a, samples.albedo3.a, traxBuffer3, _Contrast); h3 = lerp(traxBuffer3, h3, _TraxInterpContrast); COUNTSAMPLE COUNTSAMPLE #endif samples.albedo0.rgba = lerp(albedo0 * ptTint0, samples.albedo0, h0); samples.normSAO0.rgba = lerp(normSAO0 + half4(traxNormal0.xy, 0, 0), samples.normSAO0, h0); samples.albedo1.rgba = lerp(albedo1 * ptTint1, samples.albedo1, h1); samples.normSAO1.rgba = lerp(normSAO0 + half4(traxNormal1.xy, 0, 0), samples.normSAO1, h1); #if !_MAX2LAYER samples.albedo2.rgba = lerp(albedo2 * ptTint2, samples.albedo2, h2); samples.normSAO2.rgba = lerp(normSAO2 + half4(traxNormal2.xy, 0, 0), samples.normSAO2, h2); #endif #if !_MAX3LAYER || !_MAX2LAYER samples.albedo3.rgba = lerp(albedo3 * ptTint3, samples.albedo3, h3); samples.normSAO3.rgba = lerp(normSAO3 + half4(traxNormal3.xy, 0, 0), samples.normSAO3, h3); #endif #if _SURFACENORMALS samples.surf0 = lerp(ConvertNormal2ToGradient(normSAO0.xy + traxNormal0.xy), samples.surf0, h0); samples.surf1 = lerp(ConvertNormal2ToGradient(normSAO1.xy + traxNormal1.xy), samples.surf1, h1); #if !_MAX2LAYER samples.surf2 = lerp(ConvertNormal2ToGradient(normSAO2.xy + traxNormal2.xy), samples.surf2, h2); #endif #if !_MAX3LAYER || !_MAX2LAYER samples.surf3 = lerp(ConvertNormal2ToGradient(normSAO3.xy + traxNormal3.xy), samples.surf3, h3); #endif #endif #endif } void ApplyTraxTess(inout half h0, inout half h1, inout half h2, inout half h3, Config config, float3 worldPos, float traxBuffer, float mipLevel, float offset) { #if (_PERTEXTRAXDIGDEPTH || _PERTEXTRAXOPACITY) SAMPLE_PER_TEX(strs, 20.5, config, half4(1.0, 1.0, 1.0, 0.0)); #else half4 strs0 = half4(1,1,1,1); half4 strs1 = half4(1,1,1,1); half4 strs2 = half4(1,1,1,1); half4 strs3 = half4(1,1,1,1); #endif float traxBuffer0 = traxBuffer = 1 - ((1 - traxBuffer) * _TraxTextureBlend * strs0.y); float traxBuffer1 = traxBuffer = 1 - ((1 - traxBuffer) * _TraxTextureBlend * strs1.y); float traxBuffer2 = traxBuffer = 1 - ((1 - traxBuffer) * _TraxTextureBlend * strs2.y); float traxBuffer3 = traxBuffer = 1 - ((1 - traxBuffer) * _TraxTextureBlend * strs3.y); float offset0 = offset - strs0.r; float offset1 = offset - strs1.r; float offset2 = offset - strs2.r; float offset3 = offset - strs3.r; #if _TRAXNOTEXTURE h0 = lerp(h0 - offset, h0, traxBuffer0); h1 = lerp(h1 - offset, h1, traxBuffer1); h2 = lerp(h2 - offset, h2, traxBuffer2); h3 = lerp(h3 - offset, h3, traxBuffer3); #elif _TRAXSINGLE float2 uv = config.uv * _TraxUVScales.xy; half albedo = SAMPLE_TEXTURE2D_LOD(_TraxDiff, sampler_Diffuse, uv, mipLevel).a; h0 = lerp(albedo - offset0, h0, traxBuffer0); h1 = lerp(albedo - offset1, h1, traxBuffer1); h2 = lerp(albedo - offset2, h2, traxBuffer2); h3 = lerp(albedo - offset3, h3, traxBuffer3); #elif _TRAXARRAY float2 uv = config.uv * _TraxUVScales.xy; traxBuffer = 1 - ((1 - traxBuffer) * _TraxTextureBlend); half albedo0 = SAMPLE_TEXTURE2D_ARRAY_LOD(_TraxArrayDiff, sampler_Diffuse, uv, config.uv0.z, mipLevel).a; half albedo1 = SAMPLE_TEXTURE2D_ARRAY_LOD(_TraxArrayDiff, sampler_Diffuse, uv, config.uv1.z, mipLevel).a; half albedo2 = SAMPLE_TEXTURE2D_ARRAY_LOD(_TraxArrayDiff, sampler_Diffuse, uv, config.uv2.z, mipLevel).a; half albedo3 = SAMPLE_TEXTURE2D_ARRAY_LOD(_TraxArrayDiff, sampler_Diffuse, uv, config.uv3.z, mipLevel).a; h0 = lerp(albedo0 - offset0, h0, traxBuffer0); h1 = lerp(albedo1 - offset1, h1, traxBuffer1); h2 = lerp(albedo2 - offset2, h2, traxBuffer2); h3 = lerp(albedo3 - offset3, h3, traxBuffer3); #endif } #endif