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



Unity 3D是一款功能强大的游戏引擎,为开发者提供了丰富的特效全屏特效功能。全屏特效是一种在整个屏幕上展示出的动态效果,可以增强游戏的视觉效果和沉浸感。 在Unity 3D中,实现全屏特效的方法有很多种。一种常用的方式是使用Shader编程,通过编写自定义的Shader代码来实现特定的效果。Unity 3D提供了内置的Shader库,也可以创建自定义的Shader实现各种炫酷的特效,比如全屏模糊、折射、反射等。 除了Shader编程之外,Unity 3D还提供了一些内置的特效组件和工具,可以方便地实现全屏特效。例如,Post-Processing Stack是一款强大的后期处理工具,可以通过简单的配置实现各种全屏特效,如色彩调整、景深、运动模糊等。这些特效可以使游戏画面更加生动和真实,提升玩家的游戏体验。 除了使用内置的特效组件和工具之外,Unity Asset Store还有许多第三方插件和资源包,可以方便地实现各种全屏特效。这些资源包包含了各种特效的预设和脚本,可以直接引用并进行调整,从而快速实现全屏特效而无需自行编写代码。 总而言之,Unity 3D是一款非常适合开发游戏的引擎,提供了丰富的特效全屏特效功能。通过使用Shader编程、内置的特效组件和工具,以及第三方资源包,开发者可以轻松实现各种炫酷的全屏特效,为游戏增添视觉上的吸引力和沉浸感。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值