[Unity]游戏Inside中的Chromatic Aberration效果学习

Chromatic Aberration效果指的是模拟摄像机的拍摄瑕疵导致rgb三个通道的颜色发生了偏移,如

传统的Chromatic Aberration实现往往是基于一个后处理,将rgb采样的坐标各自稍微偏移一点后叠加得到效果,如

可以看到这种实现在偏移较大的情况下,跟理想效果差别较大。

在GDC2016上,Playdead做了个关于Inside中的各种效果的presentation。包括了它们实现的Chroamtic Aberration

大体的思想依然是做若干次不同偏移的采样。但是采样次数不局限于3次(即采样1*r + 采样2 *g * 采样3 * b),而是在中心点到偏移点的连线上采样若干次。每次采样乘以一个过滤系数(存在一张LUT中),最后加起来即可。

unity官方的post-process stack中的实现效果也是同样的,代码如下,去掉了一些和效果无关的代码。

                float2 coords = 2.0 * uv - 1.0;	//屏幕空间坐标
                float2 end = uv - coords * dot(coords, coords) * _ChromaticAberration_Amount;	//稍微靠近中心的偏移点

                float2 diff = end - uv; //总偏移量
                int samples = clamp(int(length(_MainTex_TexelSize.zw * diff / 2.0)), 3, 16); //采样次数
                float2 delta = diff / samples;  //每次采样步长
                float2 pos = uv; //采样起点
                half3 sum = (0.0).xxx, filterSum = (0.0).xxx;

                for (int i = 0; i < samples; i++)
                {
                    half t = (i + 0.5) / samples;
                    half3 s = tex2Dlod(_MainTex, float4(pos, 0, 0)).rgb;
                    half3 filter = tex2Dlod(_ChromaticAberration_Spectrum, float4(t, 0, 0, 0)).rgb;  //过滤贴图采样。

                    sum += s * filter;
                    filterSum += filter;
                    pos += delta;
                }

                color = sum / filterSum;

另外过滤的LUT可以使用一个3*1像素大小的贴图。其中三个像素分别为红色、绿色、蓝色。在使用的时候设置为线性过滤,即可获得平滑的过滤效果。(见上文ppt图)

posted @ 2017-05-20 10:07  yangrc1234  阅读(3770)  评论(1编辑  收藏  举报