您当前的位置: 首页 >  unity

Jave.Lin

暂无认证

  • 2浏览

    0关注

    704博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

Unity Shader PostProcessing - 10 - ColorSpreading 颜色传播后效

Jave.Lin 发布时间:2020-04-16 13:08:30 ,浏览量:2

文章目录
  • 效果
  • 实践
    • 准备一个颜色鲜艳的场景
    • 灰化图像
    • 2D屏幕颜色传播效果
    • 3D世界坐标颜色传播效果
      • 确定世界坐标传播中心点
      • 将屏幕深度转为世界坐标
      • 世界坐标半径才着色
      • 添加边缘柔和
      • 添加噪点来过渡
    • 给0~1边缘的着色
    • 给0~1边缘添加亮度
    • 最后添加整体应用的强度
  • Project
  • References

看到Color Spread Post-Processing Effect Tutorial in Unity上的颜色传播效果图还不错,看到效果图那刻,就知道如何实现了。

先来看看我们实现的最终效果

效果

在这里插入图片描述

实践 准备一个颜色鲜艳的场景

在这里插入图片描述

灰化图像
            fixed4 frag (v2f i) : SV_Target {
                fixed4 col = tex2D(_MainTex, i.uv);
                return LinearRgbToLuminance(col);
            }

在这里插入图片描述

2D屏幕颜色传播效果

简单的添加一个2D屏幕UV中心的效果,是个最简单的思路 在这里插入图片描述

                float2 centerPos = 0.5;
                float dist = length(i.uv - centerPos);
                bool color = false;
                if (_SpreadingRadius != 0) {
                    color = step(dist, _SpreadingRadius);
                }
                fixed4 col = tex2D(_MainTex, i.uv);
                return lerp(LinearRgbToLuminance(col), col, color);
3D世界坐标颜色传播效果

接下来是扩展到3D坐标

确定世界坐标传播中心点
            float3 _SpreadingCenterPos;
将屏幕深度转为世界坐标

之前写的一篇:Unity Shader - 根据片段深度重建片段的世界坐标

核心Shader伪代码:

float depth = Linear01Depth(tex2D(_DepthTex, i.uv).r);
wp = _camWorldPos.xyz + _frustumCornerRay.xyz * depth;
世界坐标半径才着色
            fixed4 frag (v2f i) : SV_Target {
                // depth to world pos
                float depth = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv));
                float3 wp = _WorldSpaceCameraPos.xyz + i.ray * depth;
                float3 centerPos = _SpreadingCenterPos;
                float3 vec = wp - centerPos;
                // 判断半径着色
                float dist = dot(vec, vec);
                bool color = false;
                if (_SpreadingRadius != 0) {
                    color = step(dist, _SpreadingRadius * _SpreadingRadius);
                }
                fixed4 col = tex2D(_MainTex, i.uv);
                return lerp(LinearRgbToLuminance(col), col, color);
            }

在这里插入图片描述

添加边缘柔和
            fixed4 frag (v2f i) : SV_Target {
                // depth to world pos
                float depth = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv));
                float3 wp = _WorldSpaceCameraPos.xyz + i.ray * depth;
                float3 centerPos = _SpreadingCenterPos;
                float3 vec = wp - centerPos;
                // 判断半径着色
                float dist = length(vec);
                float tint = 0;
                tint = step(dist, _SpreadingRadius);
                float fadeOutWidth = _BoundaryFadeOutWidth;
                if (tint == 0 && fadeOutWidth != 0) {
                    tint = 1 - saturate((dist - _SpreadingRadius) / fadeOutWidth); // 这里可以优化为乘法
                }
                fixed4 col = tex2D(_MainTex, i.uv);
                return lerp(LinearRgbToLuminance(col), col, tint);
            }

在这里插入图片描述

添加噪点来过渡

用回我自己的Noise 在这里插入图片描述

                // depth to world pos
                float depth = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv));
                float3 wp = _WorldSpaceCameraPos.xyz + i.ray * depth;
                float3 centerPos = _SpreadingCenterPos;
                float3 vec = wp - centerPos;
                // 判断半径着色
                float dist = length(vec);
                float radius = _SpreadingRadius;

                float2 noiseUV = wp.xz * _WorldPosScale;
                float noise = tex2D(_NoiseTex, noiseUV).r * _NoiseScale;
                return noise;

看看效果 在这里插入图片描述 混合效果

只要用我们的着色半径减去看似随机的噪点值即可。

            fixed4 frag (v2f i) : SV_Target {
                // depth to world pos
                float depth = Linear01Depth(SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, i.uv));
                float3 wp = _WorldSpaceCameraPos.xyz + i.ray * depth;
                float3 centerPos = _SpreadingCenterPos;
                float3 vec = wp - centerPos;
                // 判断半径着色
                float dist = length(vec);
                float radius = _SpreadingRadius;

                float2 noiseUV = wp.xz * _WorldPosScale;
                float noise = tex2D(_NoiseTex, noiseUV).r * _NoiseScale;
                // return noise;

                radius -= noise;

                float tint = 0;
                tint = step(dist, radius);
                float fadeOutWidth = _BoundaryFadeOutWidth;
                if (tint == 0 && fadeOutWidth != 0) {
                    tint = 1 - saturate((dist - radius) / fadeOutWidth); // 这里可以优化为乘法
                }

                fixed4 col = tex2D(_MainTex, i.uv);
                return lerp(LinearRgbToLuminance(col), col, tint);
            }

在这里插入图片描述

给0~1边缘的着色
                // boundary color
                bool isBoundary = tint > 0 && tint             
关注
打赏
1664331872
查看更多评论
0.0444s