我正在使用高斯模糊资产,该资产使用附加到相机的此脚本来使其着色器模糊UI背后的内容:
public class BlurRenderer : MonoBehaviour
{
[Range(0, 25)]
/// <summary>
/// how many Iterations should the blur be applied for
/// </summary>
public int Iterations;
[Range(0, 5)]
/// <summary>
/// Lowers the resolution of the texture, thus allowing for a larger blur without so many iterations
/// </summary>
public int DownRes;
/// <summary>
/// Weather to update the blur
/// </summary>
public bool UpdateBlur = true;
/// <summary>
/// amount of time that will pass before re-rendering the blur
/// </summary>
public float UpdateRate = 0.02f;
/// <summary>
/// last time we rendered the blur
/// </summary>
private float lastUpdate = 0.0f;
/// <summary>
/// Stores the blur texture between renders
/// </summary>
public RenderTexture BlurTexture;
/// <summary>
/// The material where we'll pass the screen texture though to create the blur
/// </summary>
private Material mat;
private void Start()
{
//set up the blur texture
BlurTexture = new RenderTexture(256, 256, 16, RenderTextureFormat.ARGB32);
/*
//we can swap the code above for a texture that will take up less ram...if needed.
BlurTexture = new RenderTexture(128, 128, 4, RenderTextureFormat.ARGB4444);
*/
//create the texture
BlurTexture.Create();
//create our material if we have not already
if (mat == null)
{
mat = new Material(Shader.Find("Hidden/GaussianBlur_Mobile"));
}
}
#region BlurScaleSlider
//this section will enable a slider that controls both the Iterations and DownRes
//Uncomment the code below to use it
/*
[Range(0, 100)]
/// <summary>
/// The blur scale.
/// </summary>
public int blurScale;
private void Update()
{
int tempBlurScale = blurScale;
Iterations = 0;
DownRes = 0;
while (tempBlurScale > 20 && DownRes < 5)
{
DownRes += 1;
tempBlurScale -= 15;
}
Iterations = tempBlurScale;
tempBlurScale = 0;
}
*/
#endregion
//OnRenderImage will execute before each frame renders
void OnRenderImage(RenderTexture src, RenderTexture dst)
{
// if we need to re-render
if (Time.time - lastUpdate >= UpdateRate
&& UpdateBlur)
{
//set the width and height
int width = src.width >> DownRes;
int height = src.height >> DownRes;
//create a temp texture
RenderTexture rt = RenderTexture.GetTemporary(width, height);
//move the screen image to our temp texture
Graphics.Blit(src, rt);
//loop to add the blur to our temp texture
for (int i = 0; i < Iterations; i++)
{
RenderTexture rt2 = RenderTexture.GetTemporary(width, height);
Graphics.Blit(rt, rt2, mat);
RenderTexture.ReleaseTemporary(rt);
rt = rt2;
}
//store our texture in BlurTexture
Graphics.Blit(rt, BlurTexture);
//set the global texture for our shader to use
Shader.SetGlobalTexture("_MobileBlur", rt);
//remove the temp texture
RenderTexture.ReleaseTemporary(rt);
//set lastUpdate
lastUpdate = Time.time;
}
else
{
//set the global texture again...must be done for each frame
Shader.SetGlobalTexture("_MobileBlur", BlurTexture);
}
//make sure the camera renders as normal.
Graphics.Blit(src, dst);
}
/// <summary>
/// Creates a BlurRenderer_Mobile on the main camera
/// </summary>
static public BlurRenderer Create()
{
BlurRenderer BRM = Camera.main.gameObject.GetComponent<BlurRenderer>();
if (BRM == null)
{
BRM = Camera.main.gameObject.AddComponent<BlurRenderer>();
}
return BRM;
}
//override to allow different camera
static public BlurRenderer Create(Camera ThisCamera)
{
BlurRenderer BRM = ThisCamera.gameObject.GetComponent<BlurRenderer>();
if (BRM == null)
{
BRM = ThisCamera.gameObject.AddComponent<BlurRenderer>();
}
return BRM;
}
}
}
它创建相机在世界空间中渲染的渲染纹理。这适用于大多数游戏对象,但是使用我的天空盒背景或淡入淡出的标准着色器(插槽中有透明图像)时,没有任何渲染。
如何解决此问题/导致此问题的原因?
着色器:
Properties
{
[PerRendererData] _MainTex ("_MainTex", 2D) = "white" {}
_Lightness ("_Lightness", Range(0,2)) = 1
_Saturation ("_Saturation", Range(-10,10)) = 1
_TintColor ("_TintColor",Color) = (1.0,1.0,1.0,0.0)
// required for UI.Mask
[HideInInspector] _StencilComp ("Stencil Comparison", Float) = 8
[HideInInspector] _Stencil ("Stencil ID", Float) = 0
[HideInInspector] _StencilOp ("Stencil Operation", Float) = 0
[HideInInspector] _StencilWriteMask ("Stencil Write Mask", Float) = 255
[HideInInspector] _StencilReadMask ("Stencil Read Mask", Float) = 255
[HideInInspector] _ColorMask ("Color Mask", Float) = 15
}
SubShader
{
Tags
{
"Queue" = "Transparent"
"PreviewType" = "Plane"
"DisableBatching" = "True"
}
// required for UI.Mask
Stencil
{
Ref [_Stencil]
Comp [_StencilComp]
Pass [_StencilOp]
ReadMask [_StencilReadMask]
WriteMask [_StencilWriteMask]
}
ColorMask [_ColorMask]
Pass
{
ZWrite Off
Cull Off
Blend SrcAlpha OneMinusSrcAlpha
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
half4 color : COLOR;
half4 screenpos : TEXCOORD2;
};
struct v2f
{
float4 vertex : SV_POSITION;
float2 uv : TEXCOORD0;
float2 screenuv : TEXCOORD1;
half4 color : COLOR;
float2 screenpos : TEXCOORD2;
};
v2f vert(appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
o.screenuv = ((o.vertex.xy / o.vertex.w) + 1) * 0.5;
o.color = v.color;
o.screenpos = ComputeScreenPos(o.vertex);
return o;
}
float2 safemul(float4x4 M, float4 v)
{
float2 r;
r.x = dot(M._m00_m01_m02, v);
r.y = dot(M._m10_m11_m12, v);
return r;
}
sampler2D _MainTex;
float4 _MainTex_TexelSize;
// x contains 1.0/width
// y contains 1.0/height
// z contains width
// w contains height
uniform float _Lightness;
uniform float _Saturation;
uniform fixed4 _TintColor;
uniform sampler2D _MobileBlur;
float4 frag(v2f i) : SV_Target
{
float4 m = tex2D(_MainTex, i.uv);
float2 uvWH = float2(_MainTex_TexelSize.z / _ScreenParams.x,_MainTex_TexelSize.w / _ScreenParams.y);
uvWH.x *= _MainTex_TexelSize.x;
uvWH.y *= _MainTex_TexelSize.y;
float2 buv = float2(i.screenpos.x - (uvWH.x / 2),i.screenpos.y - (uvWH.y / 2));
float4 blurColor = float4(0,0,0,0);
blurColor = tex2D(_MobileBlur,buv);
//blurColor = tex2D(_MobileBlur,buv);
blurColor.a *= m.a;
float4 finalColor = blurColor * i.color;
finalColor.a = i.color.a * m.a * blurColor.a;
finalColor.rgb *= _Lightness;
finalColor.rgb *= _TintColor;
float3 intensity = dot(finalColor.rgb, float3(0.299,0.587,0.114));
finalColor.rgb = lerp(intensity, finalColor.rgb , _Saturation);
return finalColor;
}
ENDCG
}