赞
踩
先来看下我们的实现效果:
感觉还不错
本次shader需要用到三种贴图:
1.晕影贴图:
给人一种正带着夜视仪的感觉
2.噪波贴图:
产生雪花状噪波
3.扫描线贴图:
增加夜视仪的真实感
先建立一个shader
先浏览一下变量:
_ScanLineTileTex; 扫描线效果的贴图
噪波贴图:
基于两种颜色或材质的交互创建曲面的随机扰动
通过对两种颜色随机混合,生成噪波效果
_NoiseTex; 噪波贴图
_VignetteTex;晕影贴图
_Contrast;对比度
颜色的鲜明程度
_Brightness;亮度
_RandomValue;随机值,用在噪波贴图随机uv扰动
_distortion;桶形畸变的扭曲程度
_scale;屏幕放缩比例
_ScanLineTileAmount;扫描线数量(不是确切数量,指程度大小)
_NoiseXSpeed;噪波x方向速度
_NoiseYSpeed;噪波y方向速度
_NightVisionColor;夜视仪颜色
- Properties {
- _MainTex ("Base (RGB)", 2D) = "white" {}
-
- _Contrast("Contrast", Range(0, 4)) = 2
- _Brightness ("Brightness", Range(0, 2)) = 1
- _NightVisionColor ("Night Vision Color", Color) = (1, 1, 1, 1)
- _RandomValue ("RandomValue", Float) = 0
- _distortion("distortion", Float) = 0.2
- _scale("scale", Float) = 0.8
- _VignetteTex("Vignette Texture", 2D) = "white" {}
- _ScanLineTileTex("Scan Line Tile Texture", 2D) = "white" {}
- _ScanLineTileAmount("Scan 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
- }
- SubSha
我们还要声明一下:
#pragma vertex vert_img 传入的像素信息为vert_img
#pragma fragment frag
片元着色函数为frag
#pragma fragmentoption ARB_precision_hint_fastest
片元着色选项。ARB_precision_hint_fastest使用这个标志可以fp16的对像素进行运算,加快渲染
- #pragma vertex vert_img
- #pragma fragment frag
- #pragma fragmentoption ARB_precision_hint_fastest
- 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;
- }
然后我们开始在frag函数中对片元进行着色
从刚才的桶形畸变函数传出经过处理得uv值distortedUV
获得当前传入摄像头的像素信息renderTex
获取晕影贴图像素信息
vignetteTex = tex2D(_VignetteTex, distortedUV);
扫描线uv 可控扫描线数量
scanLinesUV = half2(i.uv.x * _ScanLineTileAmount, i.uv.y * _ScanLineTileAmount);
获取扫描线贴图像素信息
scanLineTex = tex2D(_ScanLineTileTex, scanLinesUV);
噪波贴图uv
根据时间与随机值变换uv产生扰动效果
noiseUV = half2(i.uv.x + (_RandomValue * _SinTime.z * _NoiseXSpeed),i.uv.y + (_Time.x * _NoiseYSpeed));
获取噪波贴图像素信息
fixed4 noiseTex = tex2D(_NoiseTex, noiseUV);
lum 即 luminosity 亮度值
lum = dot (fixed3(0.299, 0.587, 0.114), renderTex.rgb);
lum += _Brightness;//加上可自控的亮度
使饱和度调为零,变成黑白效果,再与夜视镜颜色混合
fixed4 finalColor = (lum *2) + _NightVisionColor;
再与三种贴图颜色混合得到最终颜色值
finalColor = pow(finalColor, _Contrast);
finalColor *= vignetteTex;
finalColor *= scanLineTex * noiseTex;
shader就ok了
- fixed4 frag(v2f_img i/*像素信息*/) : COLOR// 片元着色函数
- {
- half2 distortedUV = barrelDistortion(i.uv); //桶形畸变uv
- fixed4 renderTex = tex2D(_MainTex, distortedUV);
- fixed4 vignetteTex = tex2D(_VignetteTex, distortedUV); //晕影贴图
-
-
-
- //扫描线uv 可控扫描线数量
- half2 scanLinesUV = half2(i.uv.x * _ScanLineTileAmount, i.uv.y * _ScanLineTileAmount);//_ScanLineTileAmount大小无限制
- fixed4 scanLineTex = tex2D(_ScanLineTileTex, scanLinesUV);
- //噪波贴图uv
- half2 noiseUV = half2(i.uv.x + (_RandomValue * _SinTime.z * _NoiseXSpeed),i.uv.y + (_Time.x * _NoiseYSpeed));
- fixed4 noiseTex = tex2D(_NoiseTex, noiseUV);
-
-
-
- //lum = luminosity 亮度
- fixed lum = dot (fixed3(0.299, 0.587, 0.114), renderTex.rgb);
- lum += _Brightness;//加上可自控的亮度
- //饱和度调为零,变成黑白效果,再与夜视镜颜色混合
- fixed4 finalColor = (lum *2) + _NightVisionColor;//
-
-
-
- finalColor = pow(finalColor, _Contrast);//对比度
- finalColor *= vignetteTex;//与晕影贴图混合
- finalColor *= scanLineTex * noiseTex;
-
- return finalColor;
- }
接下来看看放入摄像头中的c#脚本
建立一个c#脚本
先赋予变量,与上面的shader的变量都差不多,
这就是一会要传入shader的值
- <span style="font-size:12px;"> #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</span>
动态建立一个纹理
- <span style="font-size:12px;"> #region Properties
- Material material
- {
- get
- {
- if(curMaterial == null)
- {
- curMaterial = new Material(nightVisionShader);
- curMaterial.hideFlags = HideFlags.HideAndDontSave;
- }
- return curMaterial;
- }
- }
- #endregion</span>
依旧需要 OnRenderImage()这个函数抓取摄像机的图像
然后我们把各种变量传入shader
通过 Graphics.Blit() 这个函数
可以经过shader的变换处理在输出到我们的显示器中
- <span style="font-size:12px;">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("_ScanLineTileTex", 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);
- }
- }</span>
以下全部代码:
c#:
- <span style="font-size:12px;">using UnityEngine;
- using System.Collections;
-
- public class night : 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("_ScanLineTileTex", 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);
- }
- }
- }</span>
-
shader:
- <span style="font-size:12px;">Shader "Custom/shaderTest" {
- Properties {
- _MainTex ("Base (RGB)", 2D) = "white" {}
-
- _Contrast("Contrast", Range(0, 4)) = 2
- _Brightness ("Brightness", Range(0, 2)) = 1
- _NightVisionColor ("Night Vision Color", Color) = (1, 1, 1, 1)
- _RandomValue ("RandomValue", Float) = 0
- _distortion("distortion", Float) = 0.2
- _scale("scale", Float) = 0.8
- _VignetteTex("Vignette Texture", 2D) = "white" {}
- _ScanLineTileTex("Scan Line Tile Texture", 2D) = "white" {}
- _ScanLineTileAmount("Scan 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
- }
- SubShader {
- Pass {
- Tags { "RenderType"="Opaque" }
- LOD 200
- CGPROGRAM
- #pragma vertex vert_img
- #pragma fragment frag
- #pragma fragmentoption ARB_precision_hint_fastest//使用这个标志可以fp16的对像素进行运算
- #include "UnityCG.cginc"
-
- uniform sampler2D _MainTex;
- uniform sampler2D _ScanLineTileTex;//扫描线效果的贴图
- //噪波贴图基于两种颜色或材质的交互创建曲面的随机扰动
- //通过对两种颜色随机混合,生成噪波效果
- uniform sampler2D _NoiseTex;//噪波贴图
- uniform sampler2D _VignetteTex;//装饰图案,小插图,此处为晕影贴图
- fixed _Contrast;//对比度
- fixed _Brightness;//亮度
- fixed _RandomValue;//随机值,用在噪波贴图随机uv扰动
- fixed _distortion;//扭曲
- fixed _scale;//屏幕比例
- fixed _ScanLineTileAmount;//扫描线数量
- fixed _NoiseXSpeed;//噪波x方向速度
- fixed _NoiseYSpeed;//噪波y方向速度
- fixed4 _NightVisionColor;//夜视镜颜色
-
- struct Input {
- float2 uv_MainTex;
- };
- 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// 片元着色函数
- {
- half2 distortedUV = barrelDistortion(i.uv); //桶形畸变uv
- fixed4 renderTex = tex2D(_MainTex, distortedUV);
- fixed4 vignetteTex = tex2D(_VignetteTex, distortedUV); //晕影贴图
-
-
-
- //扫描线uv 可控扫描线数量
- half2 scanLinesUV = half2(i.uv.x * _ScanLineTileAmount, i.uv.y * _ScanLineTileAmount);//_ScanLineTileAmount大小无限制
- fixed4 scanLineTex = tex2D(_ScanLineTileTex, scanLinesUV);
- //噪波贴图uv
- half2 noiseUV = half2(i.uv.x + (_RandomValue * _SinTime.z * _NoiseXSpeed),i.uv.y + (_Time.x * _NoiseYSpeed));
- fixed4 noiseTex = tex2D(_NoiseTex, noiseUV);
-
-
-
- //lum = luminosity 亮度
- fixed lum = dot (fixed3(0.299, 0.587, 0.114), renderTex.rgb);
- lum += _Brightness;//加上可自控的亮度
- //饱和度调为零,变成黑白效果,再与夜视镜颜色混合
- fixed4 finalColor = (lum *2) + _NightVisionColor;//
-
-
-
- finalColor = pow(finalColor, _Contrast);//对比度
- finalColor *= vignetteTex;//与晕影贴图混合
- finalColor *= scanLineTex * noiseTex;
-
- return finalColor;
- }
- ENDCG
- }
- }
- FallBack "Diffuse"
- } </span>
------------- by wolf96
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。