【unity shader/风格化水表面渲染/基础笔记】urp代码版02-岸边泡沫的生成

前言


上一节,达成了水面与水底的深度判断,结果用RawDepth表示。这一节梳理利用深度关系生成岸边的泡沫。
设计函数_getFoam(RawDepth)

float sinWave = _getFoam(RawDepth) ;

_getFoam函数


这个函数的作用是生成岸边的泡沫,使用sin函数利用RawDepth生成岸边的条纹,同时RawDepth改承担mask的任务,迫使条纹只在岸边生成

变量设计

        [Space][Header(_______BlendCtrl_______)][Space]
         _FoamBlend("Water-Shore mixture", Range(0,1)) = 0 //水面和岸边的衔接柔和程度,在这里用作mask过度控制

        [Space][Header(_______FoamCtrl_______)][Space]
         _FoamRange("Foam Range", Range(0,1)) = 0
         _FoamFreq("Foam Freq", Float) = 10
         _FoamSpeed("Foam Speed", Float) = 1

sin函数生成wave

  • _FoamRange整体微调波长
  • _FoamFreq频率调整,泡沫生成间隔
  • _FoamSpeed速度
        float _getFoam(float depth)
        {
    
    
            depth =  clamp(depth/_FoamRange,0,1);
            float a = depth * _FoamFreq + _Time.y * _FoamSpeed;
            float sinWave = sin(a)
            return sinWave;
        }

在这里插入图片描述
fig1 clamp(depth/_FoamRange,0,1)

在这里插入图片描述
fig2 多余的波峰

删除多余的波峰

float FoamDepth = smoothstep(_FoamBlend, 1, depth);

在这里插入图片描述
fig3 根据depth做简单的计算,生成对比度更高的mask
mask加入计算后 _getFoam函数如下所示

        float _getFoam(float depth)
        {
    
    
            depth =  clamp(depth/_FoamRange,0,1);
            float a = depth * _FoamFreq + _Time.y * _FoamSpeed;
            float FoamDepth = smoothstep(_FoamBlend, 1, depth);
            float sinWave = sin(a) * (1-FoamDepth);
            return sinWave;
        }

在这里插入图片描述

异形条纹

添加采样噪声的选项

        float _getFoamWave(float depth, float wave_noise)
        {
    
    
            depth =  clamp(depth/_FoamRange,0,1);
            float a = depth * _FoamFreq + _Time.y * _FoamSpeed;
            float FoamDepth = smoothstep(_FoamBlend, 1, depth);
            float sinWave = sin(a) +  wave_noise;
            sinWave = sinWave * (1-FoamDepth);
            return sinWave;
        }

函数_getFoamWave的新的变量wave_noise就是我们采样的noise数据
在这里插入图片描述

泡沫消融和增强

处理方式不唯一

现在得到了边缘不平以及明暗各异的条纹现在所做的是加入_FoamDissolve这一控制变量
depth- _FoamDissolve这一算式代表:离岸越近,消融程度越高

        float _getFoamWave(float depth, float wave_noise)
        {
    
    
            depth =  clamp(depth/_FoamRange,0,1);
            float a = depth * _FoamFreq + _Time.y * _FoamSpeed;
            float FoamDepth = smoothstep(_FoamBlend, 1, depth);
            float FoamDepth_oneminus = 1-FoamDepth;
            float sinWave = sin(a) +  wave_noise  + (depth- _FoamDissolve);
            sinWave = sinWave * FoamDepth_oneminus;
            return sinWave;
        }

极端地将 _FoamDissolve归0,条纹之间过度生硬
在这里插入图片描述
为了解决这一问题将二分处填充0-1的插值

        float _getFoamWave(float depth, float wave_noise)
        {
    
    
            depth =  clamp(depth/_FoamRange,0,1);
            float a = depth * _FoamFreq + _Time.y * _FoamSpeed;
            float FoamDepth = smoothstep(_FoamBlend, 1, depth);
            float FoamDepth_oneminus = 1-FoamDepth;
            float sinWave = sin(a) +  wave_noise + depth - _FoamDissolve;
            sinWave = smoothstep(FoamDepth_oneminus-_FoamFade,1,sinWave);
            sinWave = sinWave * FoamDepth_oneminus;
            return sinWave;
        }

在这里插入图片描述
最后的结果如上图所示

猜你喜欢

转载自blog.csdn.net/qq_43544518/article/details/128756436