您的位置:首页 > 移动开发 > Unity3D

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

2016-11-09 17:25 471 查看
全屏特效 黑白(对于《着色器和屏幕特效开发秘籍》的学习) 

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

原理是通过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"
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐