[unity shader/stylized water surface rendering/basic notes] urp code version 05-caustics simulation

foreword

The previous 4 chapters completed wave animation, coloring, and generation of shore foam. This chapter sorts out the caustic simulation of underwater.

Caustics simulation

insert image description here
We can use a similar water texture map for dispersion separation, or use a separate three-channel map directly.
The following code sets the macro _DISPERSION_ON, and if it is a three-channel separation texture, _getDispersionthe function is called

        real4 _getCausticReults(float2 uv)
        {
    
    
            uv = uv / _CausticsScale;
            float speed = _Time.y * _CausticsSpeed * 0.1;
           
            #ifdef  _DISPERSION_ON
            float3 channel_offset = _Channel_Offset.xyz*0.01;
            real4 caustics1 =  _getDispersion(_CausticsTex, sampler_CausticsTex, uv+speed,channel_offset );
            real4 caustics2 = _getDispersion(_CausticsTex, sampler_CausticsTex, speed*0.8-uv,channel_offset );
            #else
            real4 caustics1 =  SAMPLE_TEXTURE2D(_CausticsTex, sampler_CausticsTex, uv+speed);
            real4 caustics2 =  SAMPLE_TEXTURE2D(_CausticsTex, sampler_CausticsTex, speed*0.8-uv);
            #endif
            return real4(min(caustics1,  caustics2));
        }
  • _getDispersionfunction
        real4 _getDispersion(Texture2D tex,SamplerState _sampler,float2 uv,float3 channel_offset)
        {
    
    
            float r =  SAMPLE_TEXTURE2D(tex, _sampler, uv+channel_offset.x).r;
            float g =  SAMPLE_TEXTURE2D(tex, _sampler, uv+channel_offset.y).g;
            float b =  SAMPLE_TEXTURE2D(tex,  _sampler, uv+channel_offset.b).b;
            return real4(r, g, b, 1);
        }

insert image description here
The left is the case of no dispersion, the right is the case of dispersion

  • In order to make the ripples stick to the bottom of the water, we use the world coordinates reconstructed from the depth map in the first chapter to sample the texture
    . The final code is as follows. We also use the first chapter RawDepthto create the caustic maskcausticsMask
           real4 frag(v2f i) : SV_TARGET
           {
    
    
                // =========Get necessity=========== //
                float3 PosW = i.posW;
                float3 normalW = i.normalW;
                float3 viewW = i.viewDirW;

                float4 screenPos = i.scrPos / i.scrPos.w;
                // screenPos.z = (UNITY_NEAR_CLIP_VALUE >=0)?screenPos.z:screenPos.z* 0.5 + 0.5;
                float sceneRawDepth = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, sampler_CameraDepthTexture,screenPos.xy);
                float3 worldPos = ComputeWorldSpacePosition(screenPos.xy, sceneRawDepth, UNITY_MATRIX_I_VP);
                float RawDepth = PosW.y-worldPos.y;

                float waterDepth = _getNewDepthMask(RawDepth, _DepthRange);
                float causticsMask = _getNewDepthMask(RawDepth, _CausticsRange);
                // =========Foam=========== //
                float FoamDepth = smoothstep(_FoamBlend, 1, RawDepth);
                float wave_noise = SAMPLE_TEXTURE2D(_FoamNoiseMap, sampler_FoamNoiseMap, i.uv.xy).r
                                    *  _FoamNoiseStr;
               
                real4 sinWave = _getFoamWave(RawDepth, wave_noise) * _FoamCol;

                // =========Fresnel=========== //
                real4 base_col = lerp(_DeepCol, _ShallowCol, waterDepth);
                float F = _getfresnelMask(normalW, viewW);
                base_col = lerp(base_col, _FresnelCol, F);

                // =========Get Normals=========== //
                float3 normalTS = _getNormalTS(PosW.xz);
                float2 uvSS = screenPos.xy;
                uvSS += 0.01 * normalTS * _UWDistort;
                real4 grab_col = SAMPLE_TEXTURE2D(_CameraOpaqueTexture, sampler_CameraOpaqueTexture, uvSS);

                // =========Get Caustics=========== //
                real4 caustics_col = _getCausticReults(worldPos.xz) * _CausticsStr * causticsMask;

                // =========Mix Results=========== //
                base_col = lerp(grab_col+caustics_col, base_col, base_col.a);
                base_col = lerp(base_col, base_col+sinWave,  sinWave.a);

                // return real4(caustics_col.xyz, base_col.a);
                return base_col;
        
           }

insert image description here

Guess you like

Origin blog.csdn.net/qq_43544518/article/details/128759715
Recommended