137 lines
4.6 KiB
HLSL
137 lines
4.6 KiB
HLSL
#include "LVLiquidPassBase.cginc"
|
|
|
|
float _SparklingIntensity, _SparklingThreshold;
|
|
|
|
half4 raymarch(float4 vertex, float3 rd, float t0, float t1) {
|
|
|
|
float3 wpos = wsCameraPos + rd * t0;
|
|
|
|
float turbulence = (tex2D(_NoiseTex2D, vertex.xz).g - 0.5) * _Turbulence.x;
|
|
turbulence += sin(vertex.w) * _Turbulence.y;
|
|
turbulence *= 0.05 * _Size.y * _FoamTurbulence;
|
|
_LevelPos += turbulence;
|
|
_FoamMaxPos += turbulence;
|
|
|
|
// compute surface dist (t2)
|
|
float t2 = (_LevelPos - wsCameraPos.y) / rd.y;
|
|
t2 = clamp(t2, t0, t1);
|
|
|
|
// compute foam level (t3)
|
|
float t3 = (_FoamMaxPos - wsCameraPos.y) / rd.y;
|
|
t3 = clamp(t3, t0, t1);
|
|
|
|
// ray-march smoke
|
|
float tmin, tmax;
|
|
#if defined(LIQUID_VOLUME_SMOKE)
|
|
half4 sumSmoke = half4(0,0,0,0);
|
|
if (wpos.y > _LevelPos) {
|
|
tmin = t0;
|
|
tmax = rd.y<0 ? min(t2,t1) : t1;
|
|
float stepSize = (tmax - tmin) / (float)_SmokeRaySteps;
|
|
float4 dir = float4(rd * stepSize, 0);
|
|
float4 rpos = float4(wsCameraPos + rd * tmin, 0);
|
|
float4 disp = float4(0, _Time.x * _Turbulence.x * _Size.y * _SmokeSpeed, 0, 0);
|
|
BEGIN_LOOP(k,_SmokeRaySteps,5)
|
|
half n = SAMPLE_NOISE_3D(_NoiseTex, (rpos - disp) * _Scale.x).r;
|
|
float py = (_LevelPos - rpos.y)/_Size.y;
|
|
n = saturate(n + py * _SmokeHeightAtten);
|
|
half4 lc = half4(_SmokeColor.rgb, n * _SmokeColor.a);
|
|
lc.rgb *= lc.aaa;
|
|
half deep = exp(py * _SmokeAtten);
|
|
lc *= deep;
|
|
sumSmoke += lc * (1.0-sumSmoke.a);
|
|
rpos += dir;
|
|
END_LOOP
|
|
}
|
|
#endif
|
|
|
|
// ray-march foam
|
|
tmax = min(t3,t1), tmin = t0;
|
|
float sy = sign(rd.y);
|
|
if (wpos.y > _FoamMaxPos) {
|
|
tmin = tmax;
|
|
tmax = min(t2, t1) * -sy;
|
|
} else if (wpos.y < _LevelPos) {
|
|
tmin = min(t2,t1);
|
|
tmax *= _FoamBottom * sy;
|
|
} else if (rd.y<0) {
|
|
tmax = min(t2, t1);
|
|
}
|
|
half4 sumFoam = half4(0,0,0,0);
|
|
if (tmax>tmin) {
|
|
float stepSize = (tmax - tmin) / (float)_FoamRaySteps;
|
|
float4 dir = float4(rd * stepSize, 0);
|
|
float4 rpos = float4(wsCameraPos + rd * tmin, 0);
|
|
rpos.y -= _LevelPos;
|
|
float foamThickness = _FoamMaxPos - _LevelPos;
|
|
float4 disp = float4(_Time.x, 0, _Time.x, 0) * _Turbulence.x * _Size.w * _FoamTurbulence;
|
|
BEGIN_LOOP(k,_FoamRaySteps,7)
|
|
float h = saturate( rpos.y / foamThickness );
|
|
float n = saturate(SAMPLE_NOISE_3D(_NoiseTex, (rpos - disp) * _Scale.y ).r + _FoamDensity);
|
|
if (n>h) {
|
|
half4 lc = half4(_FoamColor.rgb, n-h);
|
|
lc.a *= _FoamColor.a;
|
|
lc.rgb *= lc.aaa;
|
|
half deep = saturate(rpos.y * _FoamWeight / foamThickness);
|
|
lc *= deep;
|
|
|
|
sumFoam += lc * (1.0 - sumFoam.a);
|
|
}
|
|
rpos += dir;
|
|
END_LOOP
|
|
sumFoam *= 1.0 + _FoamDensity;
|
|
}
|
|
|
|
// ray-march liquid
|
|
if (wpos.y > _LevelPos) {
|
|
tmin = t2;
|
|
tmax = t1 * -sy;
|
|
} else {
|
|
tmin = t0;
|
|
tmax = t1; // for raymarching texture we can ignore the fact that t2 could be nearer than t1 when viewed from below ( was min(t2,t1) )
|
|
}
|
|
half4 sum = half4(0,0,0,0);
|
|
if (tmax>tmin) {
|
|
float stepSize = (tmax-tmin) / (float)_LiquidRaySteps;
|
|
float4 dir = float4(rd * stepSize, 0);
|
|
float4 rpos = float4(wsCameraPos + rd * tmin, 0); // does not matter to move to level pos
|
|
rpos.y -= _LevelPos;
|
|
float4 disp = float4(_Time.x * _Turbulence.y, _Time.x * 1.5, _Time.x * _Turbulence.y, 0) * (_Turbulence.y + _Turbulence.x) * _Size.y;
|
|
float4 disp2 = float4(0,_Time.x*5.0* (_Turbulence.y + _Turbulence.x) * _Size.y,0,0);
|
|
BEGIN_LOOP(k,_LiquidRaySteps,10)
|
|
half deep = exp((rpos.y/_Size.y) * _DeepAtten);
|
|
half n = SAMPLE_NOISE_3D(_NoiseTex, (rpos - disp) * _Scale.z).r;
|
|
half4 lc = half4(_Color1.rgb, (1.0 - _Muddy) + n * _Muddy);
|
|
lc.a *= _Color1.a;
|
|
lc.rgb *= lc.aaa;
|
|
lc.rgb *= deep;
|
|
sum += lc * (1.0-sum.a);
|
|
|
|
n = SAMPLE_NOISE_3D(_NoiseTex, (rpos - disp2) * _Scale.w ).r;
|
|
lc = half4(_Color2.rgb + max(n-_SparklingThreshold, 0) * _SparklingIntensity, (1.0 - _Muddy) + n * _Muddy);
|
|
lc.a *= _Color2.a;
|
|
lc.rgb *= lc.aaa;
|
|
lc.rgb *= deep;
|
|
sum += lc * (1.0-sum.a);
|
|
|
|
rpos += dir;
|
|
END_LOOP
|
|
}
|
|
|
|
// Final blend
|
|
if (wpos.y>_LevelPos) {
|
|
#if defined(LIQUID_VOLUME_SMOKE)
|
|
half4 lfoam = sumFoam * (1.0 - sumSmoke.a);
|
|
half4 liquid = sum * (1.0 - lfoam.a) * (1.0 - sumSmoke.a);
|
|
sum = sumSmoke + lfoam + liquid;
|
|
#else
|
|
half4 liquid = sum * (1.0 - sumFoam.a);
|
|
sum = sumFoam + liquid;
|
|
#endif
|
|
} else {
|
|
half4 lfoam = sumFoam * (1.0 - sum.a);
|
|
sum = sum + lfoam;
|
|
}
|
|
return sum;
|
|
}
|