Unity Shader——夜晚视觉屏幕特效(night vision Screen Effect)

Posted 御雪妃舞

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Unity Shader——夜晚视觉屏幕特效(night vision Screen Effect)相关的知识,希望对你有一定的参考价值。

本文参考《Unity Shaders and Effects CookBook》。


这一篇夜晚视觉的效果跟上篇的老电影特效效果很类似,首先看下什么是夜晚视觉的效果:




分析下操作思路:



需要的图片素材如下:




下面的脚本处理跟前面的几篇一样的模式,一个shader一个cs脚本:


Shader脚本:

Shader "MyShaders/NightVisionEffectShader" 

	Properties 
	
		_MainTex ("Base (RGB)", 2D) = "white" 
		_VignetteTex ("Vignette Texture", 2D) = "white"
		_ScanLineTex ("Scan Line Texture", 2D) = "white"
		_NoiseTex ("Noise Texture", 2D) = "white"
		_NoiseXSpeed ("Noise X Speed", Float) = 100.0
		_NoiseYSpeed ("Noise Y Speed", Float) = 100.0
		_ScanLineTileAmount ("Scan Line Tile Amount", Float) = 4.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
			#pragma fragmentoption ARB_precision_hint_fastest
			#include "UnityCG.cginc"
			
			uniform sampler2D _MainTex;
			uniform sampler2D _VignetteTex;
			uniform sampler2D _ScanLineTex;
			uniform sampler2D _NoiseTex;
			fixed4 _NightVisionColor;
			fixed _Contrast;
			fixed _ScanLineTileAmount;
			fixed _Brightness;
			fixed _RandomValue;
			fixed _NoiseXSpeed;
			fixed _NoiseYSpeed;
			fixed _distortion;
			fixed _scale;
			
			float2 barrelDistortion(float2 coord) 
			

				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 RenderTexture 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 off


Cs脚本:

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 float randomValue = 0.0f;
	private Material curMaterial;
	#endregion
	
	#region Properties
	Material material
	
		get
		
			if(curMaterial == null)
			
				curMaterial = new Material(nightVisionShader);
				curMaterial.hideFlags = HideFlags.HideAndDontSave;
			
			return curMaterial;
		
	
	#endregion
	
	void Start()
	
		if(!SystemInfo.supportsImageEffects)
		
			enabled = false;
			return;
		
		
		if(!nightVisionShader && !nightVisionShader.isSupported)
		
			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);
		
	
	
	void Update()
	
		contrast = Mathf.Clamp(contrast, 0f,4f);
		brightness = Mathf.Clamp(brightness, 0f, 2f);
		randomValue = Random.Range(-1f,1f);
		distortion = Mathf.Clamp(distortion, -1f,1f);
		scale = Mathf.Clamp(scale, 0f, 3f);
	
	
	void OnDisable()
	
		if(curMaterial)
		
			DestroyImmediate(curMaterial);
		
	



最终调控的面板参数如图:



最终的效果如图:





贴图素材下载


以上是关于Unity Shader——夜晚视觉屏幕特效(night vision Screen Effect)的主要内容,如果未能解决你的问题,请参考以下文章

Unity3D Shader编程之十一 深入理解Unity5中的Standard Shader&屏幕像素化特效的实现

Unity Shader入门精要学习笔记 - 第12章 屏幕后处理效果

unity shader 人物走入草丛,草的晃动特效特效怎么做

Unity Shader屏幕后处理3.0:均值模糊和高斯模糊

蛋哥的学习笔记之-基于Unity的Shader编程:X-1 音乐水波特效

Unity3D激光灯碰撞特效