106 lines
3.1 KiB
HLSL

TEXTURE2D(_BlueNoise);
float4 _BlueNoise_TexelSize;
void SetJitter(float2 uv) {
uv *= _ScreenParams.xy / (_Downscaling + 1);
#if VL_BLUENOISE
float2 noiseUV = uv * _BlueNoise_TexelSize.xy + _WindDirection.ww;
jitter = SAMPLE_TEXTURE2D_LOD(_BlueNoise, sampler_PointRepeat, noiseUV, 0).r;
#else
const float3 magic = float3( 0.06711056, 0.00583715, 52.9829189 );
jitter = frac( magic.z * frac( dot( uv, magic.xy ) ) );
#endif
}
inline float3 ProjectOnPlane(float3 v, float3 planeNormal) {
float sqrMag = dot(planeNormal, planeNormal);
float dt = dot(v, planeNormal);
return v - planeNormal * dt / sqrMag;
}
inline float3 GetRayStart(float3 wpos) {
float3 cameraPosition = GetCameraPositionWS();
#if defined(ORTHO_SUPPORT)
float3 cameraForward = UNITY_MATRIX_V[2].xyz;
float3 rayStart = ProjectOnPlane(wpos - cameraPosition, cameraForward) + cameraPosition;
return lerp(cameraPosition, rayStart, unity_OrthoParams.w);
#else
return cameraPosition;
#endif
}
half SampleDensity(float3 wpos) {
#if VL_NOISE
half density = tex3Dlod(_NoiseTex, float4(wpos * _NoiseScale - _WindDirection.xyz, 0)).r;
density = saturate( (1.0 - density * _NoiseStrength) * _NoiseFinalMultiplier);
#else
half density = 1.0;
#endif
return density * DistanceAttenuation(wpos);
}
void AddFog(float3 wpos, float energyStep, half4 baseColor, inout half4 sum) {
half density = SampleDensity(wpos);
half4 fgCol = half4(baseColor.rgb, baseColor.a * density);
fgCol.rgb *= fgCol.aaa;
fgCol.a = min(1.0, fgCol.a);
fgCol *= energyStep;
sum += fgCol * (1.0 - sum.a);
}
half4 Raymarch(float3 rayStart, float3 rayDir, float t0, float t1) {
// diffusion
#if VL_POINT
half spec = dot(rayDir, normalize(_ConeTipData.xyz - _WorldSpaceCameraPos));
#else
half spec = dot(rayDir, _ToLightDir.xyz);
#endif
half diffusion = 1.0 + spec * spec * _ToLightDir.w;
half4 lightColor = half4(_LightColor.rgb * diffusion, _LightColor.a);
// compute raymarch step
float rs = MIN_STEPPING + max(0, log(t1-t0)) / FOG_STEPPING;
half4 sum = half4(0,0,0,0);
// raymarch
float3 wpos = rayStart + rayDir * t0;
rayDir *= rs;
half energyStep = min(1.0, _Density * half(rs));
float t = 0;
t1 -= t0;
for (int k=0;k<_RayMarchMaxSteps;k++) {
if (t >= t1) break;
#if VL_SHADOWS_CUBEMAP
half atten = GetShadowCubemapAtten(wpos);
half4 baseColor = lerp(_ShadowColor, lightColor, atten);
AddFog(wpos, energyStep, baseColor, sum);
#elif VL_SHADOWS || VL_SPOT_COOKIE || VL_SHADOWS_TRANSLUCENCY
half3 atten = GetShadowAtten(t / t1);
#if VL_SHADOWS
half4 baseColor = lerp(_ShadowColor, lightColor, atten.r);
#else
half4 baseColor = half4(lightColor.rgb * atten, lightColor.a);
#endif
AddFog(wpos, energyStep, baseColor, sum);
#else
AddFog(wpos, energyStep, lightColor, sum);
#endif
if (sum.a > 0.99) break;
t += rs;
wpos += rayDir;
}
return sum;
}