标签:des style blog http color io os 使用 ar
本系列主要参考《Unity Shaders and Effects Cookbook》一书(感谢原书作者),同时会加上一点个人理解或拓展。
这里是本书所有的插图。这里是本书所需的代码和资源(当然你也可以从官网下载)。
========================================== 分割线 ==========================================
呜呼,这本书最后一篇了有木有!!!想想就有点小激动呢。。。(可是还有很多隔过去了。)技术文章里就不说太多废话了,之后会写一篇总结的,坑也会慢慢补上的(我希望吧。)。
好啦!我们本节要学习的特效是一个更加常见的画面特效。在市场上很多的第一人称射击游戏(FPS)中,我们都可以看到夜视效果的身影,比如《使命召唤》、《光晕》等等。这种效果使屏幕蒙上一层非常独特的黄绿色。下面是《使命召唤》中的夜视效果:
为了实现这种夜视效果,我们需要使用Photoshop来分解上述效果的实现。我们可以从网上找一些参考图片,然后和已有图层合并,看看我们需要哪种混合效果,以及我们要怎样组合不同的图层。下面的图像显示了在Photoshop中进行上述过程的最后结果:
而最后Shader实现的结果像下面这样:
下面,我们开始将Photoshop中的最终图像分解成几个部分,来更好的理解这些资源是如何被整合在一起的。而后,我们会深入讲解实现过程。
之前说过,使用Photoshop可以让我们方便地构分层图像,以便我们可以更好地理解如何得到一个夜视效果。现在,我们就把夜视效果分解成几个组成图层。
#region Variables public Shader nightVisionShader; public float contrast = 2.0f; public float brightness = 1.0f; public Color nightVisionColor = Color.white; public Texture2D vignetteTexture; public Texture2D scanLineTexture; public float scanLineTileAmount = 4.0f; public Texture2D nightVisionNoise; public float noiseXSpeed = 100.0f; public float noiseYSpeed = 100.0f; public float distortion = 0.2f; public float scale = 0.8f; private Material curMaterial; private float randomValue = 0.0f; #endregion
void OnRenderImage (RenderTexture sourceTexture, RenderTexture destTexture){ if (nightVisionShader != null) { material.SetFloat("_Contrast", contrast); material.SetFloat("_Brightness", brightness); material.SetColor("_NightVisionColor", nightVisionColor); material.SetFloat("_RandomValue", randomValue); material.SetFloat("_Distortion", distortion); material.SetFloat("_Scale", scale); if (vignetteTexture) { material.SetTexture("_VignetteTex", vignetteTexture); } if (scanLineTexture) { material.SetTexture("_ScanLineTex", scanLineTexture); material.SetFloat("_ScanLineTileAmount", scanLineTileAmount); } if (nightVisionNoise) { material.SetTexture("_NoiseTex", nightVisionNoise); material.SetFloat("_NoiseXSpeed", noiseXSpeed); material.SetFloat("_NoiseYSpeed", noiseYSpeed); } Graphics.Blit(sourceTexture, destTexture, material); } else { Graphics.Blit(sourceTexture, destTexture); } }
void Update () { contrast = Mathf.Clamp(contrast, 0.0f, 4.0f); brightness = Mathf.Clamp(brightness, 0.0f, 2.0f); distortion = Mathf.Clamp(distortion, -1.0f, 1.0f); scale = Mathf.Clamp(scale, 0.0f, 3.0f); randomValue = Random.Range(-1.0f, 1.0f); }
Properties { _MainTex ("Base (RGB)", 2D) = "white" {} _VignetteTex ("Vignette Texture", 2D) = "white" {} _ScanLineTex ("Scan Line Texture", 2D) = "white" {} _ScanLineTileAmount ("Scale Line Tile Amount", Float) = 4.0 _NoiseTex ("Noise Texture", 2D) = "white" {} _NoiseXSpeed ("Noise X Speed", Float) = 100.0 _NoiseYSpeed ("Noise Y Speed", Float) = 100.0 _NightVisionColor ("Night Vision Color", Color) = (1, 1, 1, 1) _Contrast ("Contrast", Range(0, 4)) = 2 _Brightness ("Brightness", Range(0, 2)) = 1 _RandomValue ("Random Value", Float) = 0 _Distortion ("Distortion", Float) = 0.2 _Scale ("Scale (Zoom)", Float) = 0.8 }
SubShader { Pass { CGPROGRAM #pragma vertex vert_img #pragma fragment frag #include "UnityCG.cginc" uniform sampler2D _MainTex; uniform sampler2D _VignetteTex; uniform sampler2D _ScanLineTex; fixed _ScanLineTileAmount; uniform sampler2D _NoiseTex; fixed _NoiseXSpeed; fixed _NoiseYSpeed; fixed4 _NightVisionColor; fixed _Contrast; fixed _Brightness; fixed _RandomValue; fixed _Distortion; fixed _Scale;
float2 barrelDistortion(float2 coord) { // Lens distortion algorithm // See http://www.ssontech.com/content/lensalg.htm float2 h = coord.xy - float2(0.5, 0.5); float r2 = h.x * h.x + h.y * h.y; float f = 1.0 + r2 * (_Distortion * sqrt(r2)); return f * _Scale * h + 0.5; }
fixed4 frag(v2f_img i) : COLOR { // Get the colors from the Render Texture and the uv‘s // from the v2f_img struct half2 distortedUV = barrelDistortion(i.uv); fixed4 renderTex = tex2D(_MainTex, distortedUV); fixed4 vignetteTex = tex2D(_VignetteTex, i.uv);
// Process scan lines and noise half2 scanLinesUV = half2(i.uv.x * _ScanLineTileAmount, i.uv.y * _ScanLineTileAmount); fixed4 scanLineTex = tex2D(_ScanLineTex, scanLinesUV); half2 noiseUV = half2(i.uv.x + (_RandomValue * _SinTime.z * _NoiseXSpeed), i.uv.y + (_Time.x * _NoiseYSpeed)); fixed4 noiseTex = tex2D(_NoiseTex, noiseUV);
// Get the luminosity values from the render texture using the YIQ values fixed lum = dot(fixed3(0.299, 0.587, 0.114), renderTex.rgb); lum += _Brightness; fixed4 finalColor = (lum * 2) + _NightVisionColor;
// Final output finalColor = pow(finalColor, _Contrast); finalColor *= vignetteTex; finalColor *= scanLineTex * noiseTex; return finalColor; }
using UnityEngine; using System.Collections; [ExecuteInEditMode] public class NightVisionEffect : MonoBehaviour { #region Variables public Shader nightVisionShader; public float contrast = 2.0f; public float brightness = 1.0f; public Color nightVisionColor = Color.white; public Texture2D vignetteTexture; public Texture2D scanLineTexture; public float scanLineTileAmount = 4.0f; public Texture2D nightVisionNoise; public float noiseXSpeed = 100.0f; public float noiseYSpeed = 100.0f; public float distortion = 0.2f; public float scale = 0.8f; private Material curMaterial; private float randomValue = 0.0f; #endregion #region Properties public Material material { get { if (curMaterial == null) { curMaterial = new Material(nightVisionShader); curMaterial.hideFlags = HideFlags.HideAndDontSave; } return curMaterial; } } #endregion // Use this for initialization void Start () { if (SystemInfo.supportsImageEffects == false) { enabled = false; return; } if (nightVisionShader != null && nightVisionShader.isSupported == false) { enabled = false; } } void OnRenderImage (RenderTexture sourceTexture, RenderTexture destTexture){ if (nightVisionShader != null) { material.SetFloat("_Contrast", contrast); material.SetFloat("_Brightness", brightness); material.SetColor("_NightVisionColor", nightVisionColor); material.SetFloat("_RandomValue", randomValue); material.SetFloat("_Distortion", distortion); material.SetFloat("_Scale", scale); if (vignetteTexture) { material.SetTexture("_VignetteTex", vignetteTexture); } if (scanLineTexture) { material.SetTexture("_ScanLineTex", scanLineTexture); material.SetFloat("_ScanLineTileAmount", scanLineTileAmount); } if (nightVisionNoise) { material.SetTexture("_NoiseTex", nightVisionNoise); material.SetFloat("_NoiseXSpeed", noiseXSpeed); material.SetFloat("_NoiseYSpeed", noiseYSpeed); } Graphics.Blit(sourceTexture, destTexture, material); } else { Graphics.Blit(sourceTexture, destTexture); } } // Update is called once per frame void Update () { contrast = Mathf.Clamp(contrast, 0.0f, 4.0f); brightness = Mathf.Clamp(brightness, 0.0f, 2.0f); distortion = Mathf.Clamp(distortion, -1.0f, 1.0f); scale = Mathf.Clamp(scale, 0.0f, 3.0f); randomValue = Random.Range(-1.0f, 1.0f); } void OnDisable () { if (curMaterial != null) { DestroyImmediate(curMaterial); } } }
Shader "Custom/NightVisionEffectShader" { Properties { _MainTex ("Base (RGB)", 2D) = "white" {} _VignetteTex ("Vignette Texture", 2D) = "white" {} _ScanLineTex ("Scan Line Texture", 2D) = "white" {} _ScanLineTileAmount ("Scale Line Tile Amount", Float) = 4.0 _NoiseTex ("Noise Texture", 2D) = "white" {} _NoiseXSpeed ("Noise X Speed", Float) = 100.0 _NoiseYSpeed ("Noise Y Speed", Float) = 100.0 _NightVisionColor ("Night Vision Color", Color) = (1, 1, 1, 1) _Contrast ("Contrast", Range(0, 4)) = 2 _Brightness ("Brightness", Range(0, 2)) = 1 _RandomValue ("Random Value", Float) = 0 _Distortion ("Distortion", Float) = 0.2 _Scale ("Scale (Zoom)", Float) = 0.8 } SubShader { Pass { CGPROGRAM #pragma vertex vert_img #pragma fragment frag #include "UnityCG.cginc" uniform sampler2D _MainTex; uniform sampler2D _VignetteTex; uniform sampler2D _ScanLineTex; fixed _ScanLineTileAmount; uniform sampler2D _NoiseTex; fixed _NoiseXSpeed; fixed _NoiseYSpeed; fixed4 _NightVisionColor; fixed _Contrast; fixed _Brightness; fixed _RandomValue; fixed _Distortion; fixed _Scale; float2 barrelDistortion(float2 coord) { // Lens distortion algorithm // See http://www.ssontech.com/content/lensalg.htm float2 h = coord.xy - float2(0.5, 0.5); float r2 = h.x * h.x + h.y * h.y; float f = 1.0 + r2 * (_Distortion * sqrt(r2)); return f * _Scale * h + 0.5; } fixed4 frag(v2f_img i) : COLOR { // Get the colors from the Render Texture and the uv‘s // from the v2f_img struct half2 distortedUV = barrelDistortion(i.uv); fixed4 renderTex = tex2D(_MainTex, distortedUV); fixed4 vignetteTex = tex2D(_VignetteTex, i.uv); // Process scan lines and noise half2 scanLinesUV = half2(i.uv.x * _ScanLineTileAmount, i.uv.y * _ScanLineTileAmount); fixed4 scanLineTex = tex2D(_ScanLineTex, scanLinesUV); half2 noiseUV = half2(i.uv.x + (_RandomValue * _SinTime.z * _NoiseXSpeed), i.uv.y + (_Time.x * _NoiseYSpeed)); fixed4 noiseTex = tex2D(_NoiseTex, noiseUV); // Get the luminosity values from the render texture using the YIQ values fixed lum = dot(fixed3(0.299, 0.587, 0.114), renderTex.rgb); lum += _Brightness; fixed4 finalColor = (lum * 2) + _NightVisionColor; // Final output finalColor = pow(finalColor, _Contrast); finalColor *= vignetteTex; finalColor *= scanLineTex * noiseTex; return finalColor; } ENDCG } } FallBack "Diffuse" }
关于透镜形变效果:
【Unity Shaders】游戏性和画面特效——创建一个夜视效果的画面特效
标签:des style blog http color io os 使用 ar
原文地址:http://blog.csdn.net/candycat1992/article/details/39482593