ici_recycle_vr/Assets/LiquidVolumePro/Resources/Shaders/LVLiquidPass3DMultiple.cginc
Diaconescu Andrei-Alexandru 19674bfe5d Am adaugat ICI Recycle
2025-05-26 12:54:36 +03:00

234 lines
8.6 KiB
HLSL

#include "LVLiquidPassBase.cginc"
float _DitherStrength;
float _SizeWorld;
float _MurkinessSpeed;
float3 _BubblesData; // x = scale, y = vertical speed, z = brightness
#if defined(WEBGL_OR_LEGACY)
sampler2D _LayersPropertiesTex;
sampler2D _LayersColorsTex;
sampler2D _LayersColors2Tex;
sampler2D _NoiseTexUnwrapped;
// Lower quality with a single texture fetch
/*
inline float4 GetNoiseUnwrapped(float4 pos) {
float4 f = frac(pos);
f.z = (floor(f.y * 64.0) + 0.5) / 64.0 + f.z / 64.0;
return tex2Dlod(_NoiseTexUnwrapped, float4(f.xz,0,0));
}
*/
inline float4 GetNoiseUnwrapped(float4 pos) {
float4 f = frac(pos);
float t = f.y * 64.0;
float by = floor(t);
float4 n0 = tex2Dlod(_NoiseTexUnwrapped, float4(f.x, (by + f.z) / 64.0,0,0));
float4 n1 = tex2Dlod(_NoiseTexUnwrapped, float4(f.x, (by + 1.0 + f.z) / 64.0,0,0));
return lerp(n0, n1, t-by);
}
#define SET_LAYER_INDEX(y) float layerIndex = -y / _SizeWorld;
#define UPDATE_LAYER_INDEX(y) layerIndex = -y / _SizeWorld;
#define SAMPLE_LAYER_PROPERTIES(index) tex2Dlod(_LayersPropertiesTex, float4(0,index,0,0))
#define SAMPLE_LAYER_COLOR(index) tex2Dlod(_LayersColorsTex, float4(0,index,0,0))
#define SAMPLE_LAYER_COLOR2(index) tex2Dlod(_LayersColors2Tex, float4(0,index,0,0))
#define SAMPLE_NOISE_UNWRAPPED(pos) GetNoiseUnwrapped(pos)
#else
half4 _LayersColors[256];
half4 _LayersColors2[256];
float4 _LayersProperties[256];
#define SET_LAYER_INDEX(y) int layerIndex = clamp((int)(-255.0 * y / _SizeWorld), 0, 255);
#define UPDATE_LAYER_INDEX(y) layerIndex = clamp((int)(-255.0 * y / _SizeWorld), 0, 255);
#define SAMPLE_LAYER_PROPERTIES(index) _LayersProperties[index]
#define SAMPLE_LAYER_COLOR(index) _LayersColors[index]
#define SAMPLE_LAYER_COLOR2(index) _LayersColors2[index]
#define SAMPLE_NOISE_UNWRAPPED(pos) tex3Dlod(_NoiseTex, pos)
#endif
inline float getRandomFast(float2 uv) {
float2 p = uv; // + _Time.ww;
p -= floor(p * 0.01408450704) * 71.0;
p += float2( 26.0, 161.0 );
p *= p;
return frac(p.x * p.y * 0.001051374728);
}
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 level of surface liquid (t2)
float2 rdy = rd.xz / rd.y;
float delta = sqrt(1.0 + dot (rdy, rdy));
float h = abs(wpos.y - _LevelPos);
float t2 = t0 + h * delta; // length(delta * h.xx);;
// compute foam level (t3)
float hf = abs(wpos.y - _FoamMaxPos);
float t3 = t0 + hf * delta;
// 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; // address case where ray does not cross liquid; this makes tmax < tmin in this case skipping the whole if block below
} else {
tmin = t0;
tmax = min(t2,t1);
}
half4 sum = half4(0,0,0,0);
if (tmax>tmin) {
float4 rpos = float4(wsCameraPos + rd * tmin, 0); // tmin or t0 ? does not matter to move to level pos; tmin will make bubbles position correct, so we stick with tmin (t0 may reduce banding on certain cases)
float stepSize = (t1-t0) / (float)_LiquidRaySteps;
float4 dir = float4(rd * stepSize, 0);
rpos += dir * (getRandomFast(rpos.xy * 100.0) * _DitherStrength);
float4 disp = float4(_Turbulence.y, 1.5, _Turbulence.y, 0) * (_MurkinessSpeed * _Size.y);
disp.y -= _LevelPos - turbulence;
rpos.y -= _LevelPos - turbulence;
BEGIN_LOOP(k,_LiquidRaySteps,10)
SET_LAYER_INDEX(rpos.y);
// turbulence
float layerTurbulence = SAMPLE_LAYER_PROPERTIES(layerIndex).z;
float4 xpos = float4(rpos.x, rpos.y + layerTurbulence * turbulence, rpos.z, 0);
UPDATE_LAYER_INDEX(xpos.y);
xpos.xyz -= _Center;
// murkiness
float4 properties = SAMPLE_LAYER_PROPERTIES(layerIndex);
float layerScale = properties.y;
half n = SAMPLE_NOISE_3D(_NoiseTex, (xpos - disp * layerTurbulence) * layerScale).r;
// accumulate color
half muddy = properties.x;
half4 layerColor = SAMPLE_LAYER_COLOR(layerIndex);
half4 layerColor2 = SAMPLE_LAYER_COLOR2(layerIndex);
half4 lc = lerp(layerColor, layerColor2, smoothstep(0, 1.0, n) * muddy);
lc.a = layerColor.a;
lc.rgb *= lc.aaa;
sum += lc * (1.0-sum.a);
// bubbles; uses tex3Dlod
#if defined(LIQUID_VOLUME_BUBBLES)
half4 ba = SAMPLE_NOISE_UNWRAPPED ( (xpos - float4(turbulence, 0, turbulence, 0)) * _BubblesData.x - float4(0, _BubblesData.y, 0,0) );
half4 bb = SAMPLE_NOISE_UNWRAPPED ( (xpos + float4(turbulence, 0, turbulence, 0)) * _BubblesData.x - float4(0.5, _BubblesData.y * 1.5 + 0.5, 0.5, 0) );
half4 b = ba+bb;
half3 bnorm = b.yzw - 1.0;
half fresnel = abs(dot(rd, bnorm));
lc.rgb += fresnel * _BubblesData.z;
lc.a = fresnel;
lc.rgb *= lc.aaa; // 0.1
lc *= properties.w;
sum += lc * (1.0-sum.a);
#endif
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;
}
#if !UNITY_COLORSPACE_GAMMA
sum.rgb = SRGBToLinear(sum.rgb);
#endif
return sum;
}