首页 > 代码库 > Unity3d 屏幕特效实现类似死亡之后的全屏黑白效果

Unity3d 屏幕特效实现类似死亡之后的全屏黑白效果

全屏特效 黑白(对于《着色器和屏幕特效开发秘籍》的学习)


可实现死亡效果或需要黑白特效的效果

原理是通过OnRenderImage()函数在摄像机渲染的时候,改变颜色(饱和度)


新建一个c#脚本,将要放在摄像机中

[ExecuteInEditMode]
就是让这个脚本不开始也直接运行,方便观察效果


using UnityEngine;
using System.Collections;
[ExecuteInEditMode]
public class ShaderTest : MonoBehaviour
{



开始声明所需变量

curshader 需要用到的shader;
grayscaleAmount 灰度大小;


	public Shader curShader;
	public float grayScaleAmount = 1.0f;
	private Material curMaterial;
开始时检测
如果!SystemInfo.supportsImageEffects(如果计算机不支持图像处理的话)
或者无curshader(一会会用到)再或者!curShader.isSupported(不能在终端用户的图形卡上运行这个着色器)
就取消这个脚本
enabled = false;


void Start () {
		if (SystemInfo.supportsImageEffects == false) {
			enabled = false;
			return;
		}

		if (curShader != null && curShader.isSupported == false) {
			enabled = false;
		}
	}
OnRenderImage()抓取摄像机的渲染图像(我们在里面改动它)
往材质里传灰度值

然后改动完毕就Graphics.Blit()(拷贝源纹理到目的渲染纹理)


	void OnRenderImage (RenderTexture sourceTexture, RenderTexture destTexture){
		if (curShader != null) {
			material.SetFloat("_LuminosityAmount", grayScaleAmount);

			Graphics.Blit(sourceTexture, destTexture, material);
		} else {
			Graphics.Blit(sourceTexture, destTexture);
		}
	}

在update中放入这句
grayScaleAmount = Mathf.Clamp(grayScaleAmount, 0.0f, 1.0f);
的目的是,方便你随时改动灰度值。如果灰度值确定了这句可以不要。

	void Update () {
		grayScaleAmount = Mathf.Clamp(grayScaleAmount, 0.0f, 1.0f);
	}


便于删除回收

	void OnDisable () {
		if (curMaterial != null) {
			DestroyImmediate(curMaterial);
		}
	}


再看shader



书上用的是纯CG代码,不是UNITY内置着色器语言,所以屏幕特效会更加优化,因为只需要对渲染纹理的像素进行处理操作。

首先在Properties 中声明变量
包括maintex和灰度值

	Properties {
		_MainTex ("Base (RGB)", 2D) = "white" {}
		_LuminosityAmount ("GrayScale Amount", Range(0.0, 1.0)) = 1.0
	}

加入pass模块
用#pragma声明一些新的


SubShader {
		Pass {
			CGPROGRAM
			#pragma vertex vert_img
			#pragma fragment frag
			
			#include "UnityCG.cginc"

核心就在这个frag函数中
tex2d()返回一个纹理的数据
把红*0.299,绿*0.587,蓝*0.114,来获取一个亮度值(也就是颜色深浅值)luminosity

最终的颜色值  finalColor   是renderTex与灰度值的一个线性插值,根据亮度值(颜色深浅值)
ok,死亡效果的屏幕特效就这么完成了


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 Luminosity values to our render texture
				float luminosity = 0.299 * renderTex.r + 0.587 * renderTex.g + 0.114 * renderTex.b;
				fixed4 finalColor = lerp(renderTex, luminosity, _LuminosityAmount);
				
				return finalColor;
			}


以下全部代码


using UnityEngine;
using System.Collections;
[ExecuteInEditMode]
public class ShaderTest : MonoBehaviour
{
	#region Variables
	public Shader curShader;
	public float grayScaleAmount = 1.0f;
	private Material curMaterial;
	#endregion

	#region Properties
	public Material material {
		get {
			if (curMaterial == null) {
				curMaterial = new Material(curShader);
				curMaterial.hideFlags = HideFlags.HideAndDontSave;
			}
			return curMaterial;
		}
	}
	#endregion

	// Use this for initialization
	void Start () {
		if (SystemInfo.supportsImageEffects == false) {
			enabled = false;
			return;
		}

		if (curShader != null && curShader.isSupported == false) {
			enabled = false;
		}
	}

	void OnRenderImage (RenderTexture sourceTexture, RenderTexture destTexture){
		if (curShader != null) {
			material.SetFloat("_LuminosityAmount", grayScaleAmount);

			Graphics.Blit(sourceTexture, destTexture, material);
		} else {
			Graphics.Blit(sourceTexture, destTexture);
		}
	}
	
	// Update is called once per frame
	void Update () {
		grayScaleAmount = Mathf.Clamp(grayScaleAmount, 0.0f, 1.0f);
	}

	void OnDisable () {
		if (curMaterial != null) {
			DestroyImmediate(curMaterial);
		}
	}
}

shader

Shader "Custom/imageTest" {
	Properties {
		_MainTex ("Base (RGB)", 2D) = "white" {}
		_LuminosityAmount ("GrayScale Amount", Range(0.0, 1.0)) = 1.0
	}
	SubShader {
		Pass {
			CGPROGRAM
			#pragma vertex vert_img
			#pragma fragment frag
			
			#include "UnityCG.cginc"
			
			uniform sampler2D _MainTex;
			fixed _LuminosityAmount;
			
			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 Luminosity values to our render texture
				float luminosity = 0.299 * renderTex.r + 0.587 * renderTex.g + 0.114 * renderTex.b;
				fixed4 finalColor = lerp(renderTex, luminosity, _LuminosityAmount);
				
				return finalColor;
			}
			
			ENDCG
		}
	}
	FallBack "Diffuse"
}



                                                                                                                        ---------by wolf96



Unity3d 屏幕特效实现类似死亡之后的全屏黑白效果