UnityShader 屏幕特效 模糊

xiaoxiao2021-02-28  91

上一篇文章写了屏幕特效必须的几个要素,这边通过一个 脚本继承与PostEffectsBase .以及通过shader 交互实现屏幕模糊特效。

下面通过添加在摄像机,引用3的shader。

using UnityEngine; using System.Collections; [ExecuteInEditMode] public class Test : PostEffectsBase { public Shader edgeDetectShader; private Material edgeDetectMaterial = null; public Material material { get { edgeDetectMaterial = CheckShaderAndCreateMaterial(edgeDetectShader, edgeDetectMaterial); return edgeDetectMaterial; } } [Range(0.0f, 1.0f)] public float Parameter = 0.0f; //类似Update,也是会不断通过输入,输出结果 void OnRenderImage(RenderTexture src, RenderTexture dest) { if (material != null) { material.SetFloat("_BlurAmount", Parameter); Graphics.Blit(src, dest, material); } else { Graphics.Blit(src, dest); } } }

3.下面Shader

Shader "Futile/Blur" { Properties { _MainTex("Base (RGB) Trans (A)", 2D) = "white" {} _Color("Main Color", Color) = (0.2,0,1,1.5) _BlurAmount("Blur Amount", Range(0,02)) = 0.0005 } Category { Tags{ "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Opaque" } ZWrite Off //Alphatest Greater 0 Cull Off SubShader { Pass { CGPROGRAM #pragma vertex vert #pragma fragment frag #include "UnityCG.cginc" #pragma profileoption NumTemps=64 float4 _Color; sampler2D _MainTex; float _BlurAmount; struct v2f { float4 pos : SV_POSITION; float2 uv : TEXCOORD0; }; float4 _MainTex_ST; v2f vert(appdata_base v) { v2f o; o.pos = mul(UNITY_MATRIX_MVP, v.vertex); o.uv = TRANSFORM_TEX(v.texcoord, _MainTex); return o; } half4 frag(v2f i) : COLOR { half4 texcol = half4(0,0,0,0); float remaining = 1.0f; float coef = 1.0; float fI = 0; for (int j = 0; j < 3; j++) { fI++; coef *= 0.32; texcol += tex2D(_MainTex, float2(i.uv.x, i.uv.y - fI * _BlurAmount)) * coef; texcol += tex2D(_MainTex, float2(i.uv.x - fI * _BlurAmount, i.uv.y)) * coef; texcol += tex2D(_MainTex, float2(i.uv.x + fI * _BlurAmount, i.uv.y)) * coef; texcol += tex2D(_MainTex, float2(i.uv.x, i.uv.y + fI * _BlurAmount)) * coef; remaining -= 4 * coef; } //return texcol; texcol += tex2D(_MainTex, float2(i.uv.x, i.uv.y)) * remaining; return texcol; } ENDCG } } } }

4.简单介绍Category :就是同一个Shader,如果下面有多个Shader的话,都会套用下面这一套

Tags{ "Queue" = "Transparent" "IgnoreProjector" = "True" "RenderType" = "Opaque" } ZWrite Off //Alphatest Greater 0 Cull Off

5.简单讲一下这个算法,这个通过在片元着色器进行上下左右进行像素微偏移

for (int j = 0; j < 3; j++) { fI++; coef *= 0.32; texcol += tex2D(_MainTex, float2(i.uv.x, i.uv.y - fI * _BlurAmount)) * coef; texcol += tex2D(_MainTex, float2(i.uv.x - fI * _BlurAmount, i.uv.y)) * coef; texcol += tex2D(_MainTex, float2(i.uv.x + fI * _BlurAmount, i.uv.y)) * coef; texcol += tex2D(_MainTex, float2(i.uv.x, i.uv.y + fI * _BlurAmount)) * coef; remaining -= 4 * coef; }

原图 模糊图,通过调参数Parameter 这边的Remaining为了 在下面保证迭代后基数为1。这样不会影响原本图像的亮度。比如这边基数默认设置10。就会锐化图像


总结: 这边计算可以在顶点v2f vert(appdata_base v)里面计算,这样一位顶点计算量数比片元着色器计算更少。

转载请注明原文地址: https://www.6miu.com/read-44127.html

最新回复(0)