參考《Unity Shaders and Effects CookBook》
屏幕特效不僅僅限於顏色控制RenderTexture,同事還可以結合圖片和RenderTexture的混合,這種技術和PhotoShop新建一個 層級,然後選擇混合模式,混合兩張圖片是一樣的,但是Untiy裏的效果更藝術,整個場景的立體效果都蒙上這種效果,混合模式有Multiplay,Add,Overlay三種模式。
然後基本的原理和動作跟上一篇灰度屏幕特效類似。
下面我們分別看下三種混合模式的屏幕特效:
1.Multiply混合模式
首先看腳本:
Shader腳本:
Shader "MyShaders/BlendImageEffect"
{
Properties
{
_MainTex("Base (RGB)", 2D) = "white" {}
_BlendTex("Blend Texture", 2D) = "white"{}
_Opacity("Blend Opacity", Range(0,1)) = 1
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
uniform sampler2D _BlendTex;
fixed _Opacity;
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);
fixed4 blendTex = tex2D(_BlendTex, i.uv);
//Perform a multiply Blend mode
fixed4 blendedMultiply = renderTex * blendTex;
//Adjust amount of Blend Mode with a lerp
renderTex = lerp(renderTex, blendedMultiply, _Opacity);
return renderTex;
}
ENDCG
}
}
FallBack off
}
cs腳本:
using UnityEngine;
using System.Collections;
[ExecuteInEditMode]
public class BlendImageEffect : MonoBehaviour
{
#region Variables
public Shader curShader;
public Texture2D blendTexture;
public float blendOpacity = 1.0f;
private Material curMaterial;
#endregion
#region Properties
Material material
{
get
{
if (curMaterial == null)
{
curMaterial = new Material(curShader);
curMaterial.hideFlags = HideFlags.HideAndDontSave;
}
return curMaterial;
}
}
#endregion
void Start()
{
if (!SystemInfo.supportsImageEffects)
{
enabled = false;
return;
}
if (!curShader && !curShader.isSupported)
{
enabled = false;
}
}
void OnRenderImage(RenderTexture sourceTexture, RenderTexture destTexture)
{
if (curShader != null)
{
material.SetTexture("_BlendTex", blendTexture);
material.SetFloat("_Opacity", blendOpacity);
Graphics.Blit(sourceTexture, destTexture, material);
}
else
{
Graphics.Blit(sourceTexture, destTexture);
}
}
void Update()
{
blendOpacity = Mathf.Clamp(blendOpacity, 0.0f, 1.0f);
}
void OnDisable()
{
if (curMaterial)
{
DestroyImmediate(curMaterial);
}
}
}
最終效果如圖:(混合圖片的Opacity可以調)
Opacity=1
Opacity=0.5
與之混合的是如下的圖片:
2.Add Blend模式
3.Overlay混合模式
Shader "MyShaders/Overlay_Effect"
{
Properties
{
_MainTex ("Base (RGB)", 2D) = "white" {}
_BlendTex ("Blend Texture", 2D) = "white"{}
_Opacity ("Blend Opacity", Range(0,1)) = 1
}
SubShader
{
Pass
{
CGPROGRAM
#pragma vertex vert_img
#pragma fragment frag
#pragma fragmentoption ARB_precision_hint_fastest
#include "UnityCG.cginc"
uniform sampler2D _MainTex;
uniform sampler2D _BlendTex;
fixed _Opacity;
fixed OverlayBlendMode(fixed basePixel, fixed blendPixel)
{
if(basePixel < 0.5)
{
return (2.0 * basePixel * blendPixel);
}
else
{
return (1.0 - 2.0 * (1.0 - basePixel) * (1.0 - blendPixel));
}
}
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);
fixed4 blendTex = tex2D(_BlendTex, i.uv);
fixed4 blendedImage = renderTex;
blendedImage.r = OverlayBlendMode(renderTex.r, blendTex.r);
blendedImage.g = OverlayBlendMode(renderTex.g, blendTex.g);
blendedImage.b = OverlayBlendMode(renderTex.b, blendTex.b);
//Adjust amount of Blend Mode with a lerp
renderTex = lerp(renderTex, blendedImage, _Opacity);
return renderTex;
}
ENDCG
}
}
FallBack off
}
using UnityEngine;
using System.Collections;
[ExecuteInEditMode]
public class Overlay_ImageEffect : MonoBehaviour
{
#region Variables
public Shader curShader;
public Texture2D blendTexture;
public float blendOpacity = 1.0f;
private Material curMaterial;
#endregion
#region Properties
Material material
{
get
{
if(curMaterial == null)
{
curMaterial = new Material(curShader);
curMaterial.hideFlags = HideFlags.HideAndDontSave;
}
return curMaterial;
}
}
#endregion
void Start()
{
if(!SystemInfo.supportsImageEffects)
{
enabled = false;
return;
}
if(!curShader && !curShader.isSupported)
{
enabled = false;
}
}
void OnRenderImage(RenderTexture sourceTexture, RenderTexture destTexture)
{
if(curShader != null)
{
material.SetTexture("_BlendTex", blendTexture);
material.SetFloat("_Opacity", blendOpacity);
Graphics.Blit(sourceTexture, destTexture, material);
}
else
{
Graphics.Blit(sourceTexture, destTexture);
}
}
void Update()
{
blendOpacity = Mathf.Clamp(blendOpacity, 0.0f, 1.0f);
}
void OnDisable()
{
if(curMaterial)
{
DestroyImmediate(curMaterial);
}
}
}