本系列主要參考《Unity Shaders and Effects Cookbook》一书(感谢原书作者),同一时候会加上一点个人理解或拓展。
这里是本书全部的插图。
这里是本书所需的代码和资源(当然你也能够从官网下载)。
========================================== 切割线 ==========================================
通过上一篇我们建立了一个简化的屏幕特效系统,在这一篇,我们開始学习创建更复杂的像素操作来实现一些在当代游戏中常见的屏幕特效。
使用屏幕特效来调整游戏的总体色彩是非常重要的,这给了设计师控制游戏最后全貌的能力。
比方,通过颜色调整条来调整游戏终于画面的红蓝绿三色的密度,或者通过加入一定的色调使整个屏幕看起来像是老电影那样的效果。
这篇文章里,我们将会很多其它地学习关于调整图像颜色方面的内容。也就是,亮度、饱和度和对照度。学习这些调整颜色的方法能够让我们对屏幕特效有一个非常好的理解。
这一篇非常多代码是建立在上一篇的基础上,所以非常多代码不用写啦~
创建一个新的脚本,命名为BSC_ImageEffect;创建一个新的Shader。命名为BSC_Effect。把上一篇中的C#代码拷贝到第一步中创建的脚本中,我们仅仅须要关注亮度、饱和度和对照度效果的运算。把上一篇中的Shader代码拷贝到第二步中创建的Shader中。把新的脚本加入到Camera上,并使用新的Shader给脚本中的Cur Shader赋值。创建一个新的场景,命名为BSC_Effect。加入一个平行光,三个球体。以及一个平面。创建4个新材质,使用自带的Specular Shader就可以,随意选择四种颜色为它们赋值,这能够使我们更好地检验我们的画面特效。最后。把4个材质赋给球体和平面。
最后,你会得到相似于以下的效果:函数一開始。声明了一些常量。它们被用于定义一个最主要的颜色值,以便和改动后的进行比較。
书上讲这个函数的实现的地方比較含糊不清,看不懂。我按自己的理解解释一下。这事实上是一个叠加的过程:先计算当前亮度值下的像素,再在此基础上计算当前饱和度值下的像素。最后再在此基础上计算当前对照度下的像素,并输出:—— 当前亮度值下的像素是通过使用render texture上原始的像素乘以亮度值实现的,这非常好理解,brt越大(能够大于1),图像越偏向白色,也就越亮。
—— 计算当前饱和度值下的像素。须要使用lerp函数。当中,lerp的右边界值就是上一步得到的像素值,而左边界值是当前亮度下饱和度最低的像素值。计算方法是在当前亮度的基础上,点乘LuminanceCoeff常量系数。这些系数是基于CIE颜色匹配函数的,也是业界公认的标准。
最后,sat參数在两者之间进行线性插值。sat越大(能够大于1),brtColor的份重越大。
—— 计算当前对照度下的像素是相似的过程。相同使用lerp函数。当中。lerp的右边界是上一步得到的像素值,左边界值是对照度最低的像素值。这里使用了常量avgLumin。最后,con參数在两者之间进行线性插值。con越大(能够大于1),satColor的份重越大。
最后。我们须要略微改动下frag函数。使得它能够逐像素处理render texture中的每一个像素。然后再又一次输出,返回给脚本: fixed4 frag(v2f_img i) : COLOR { //Get the colors from the RenderTexture and the uv's //from the v2f_img struct fixed4 renderTex = tex2D(_MainTex, i.uv); //Apply the brightness, saturation, contrast operations renderTex.rgb = ContrastSaturationBrightness (renderTex.rgb, _BrightnessAmount, _SaturationAmount, _ContrastAmount); return renderTex; } 以下是编写脚本。我们须要在脚本中加入新的代码,以便能够向Shader发送合适的数据信息: 首先加入合适的变量来控制亮度、饱和度和对照度: #region Variables public Shader curShader; public float brightnessAmount = 1.0f; public float saturationAmount = 1.0f; public float contrastAmount = 1.0f; private Material curMaterial; #endregion然后,在OnRenderImage函数中。将新的值传递给Shader: void OnRenderImage (RenderTexture sourceTexture, RenderTexture destTexture){ if (curShader != null) { material.SetFloat("_BrightnessAmount", brightnessAmount); material.SetFloat("_SaturationAmount", saturationAmount); material.SetFloat("_ContrastAmount", contrastAmount); Graphics.Blit(sourceTexture, destTexture, material); } else { Graphics.Blit(sourceTexture, destTexture); } }最后。我们仅仅须要在函数中,确保各变量的范围就可以。这些范围能够依据须要随意设置: // Update is called once per frame void Update () { brightnessAmount = Mathf.Clamp(brightnessAmount, 0.0f, 2.0f); saturationAmount = Mathf.Clamp(saturationAmount, 0.0f, 2.0f); contrastAmount = Mathf.Clamp(contrastAmount, 0.0f, 3.0f); } 完毕后,返回Unity。我们这时能够在面板中更改亮度、饱和度和对照度了。以下的图显示了它的结果:
转载于:https://www.cnblogs.com/bhlsheji/p/5098465.html
相关资源:数据结构—成绩单生成器