生活随笔
收集整理的這篇文章主要介紹了
Unity3D URP中使用Render Feature实现后处理效果
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
unity urp 自帶了一個后處理組件Volume,提供了不少后處理效果:
除此之外,Render Feature 也可以實(shí)現(xiàn)類似的效果,并且自由度更高。
使用方式是,在RenderPiplineAsset 中的Renderer中新增Feature,下面舉例說明如何通過Feature增加一個KawaseBlur的后處理效果。
首先寫一個自定義的Feature腳本:
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;public class KawaseBlur : ScriptableRendererFeature
{[System.Serializable]public class KawaseBlurSettings{public RenderPassEvent renderPassEvent
= RenderPassEvent
.AfterRenderingTransparents
;public Material blurMaterial
= null;[Range(2,15)]public int blurPasses
= 2;[Range(1,4)]public int downsample
= 1;public bool copyToFramebuffer
= true;public string targetName
= "_blurTexture";}public KawaseBlurSettings settings
= new KawaseBlurSettings();class CustomRenderPass : ScriptableRenderPass{public Material blurMaterial
;public int passes
;public int downsample
;public bool copyToFramebuffer
;public string targetName
; string profilerTag
;int tmpId1
;int tmpId2
;RenderTargetIdentifier tmpRT1
;RenderTargetIdentifier tmpRT2
;RenderTargetIdentifier cameraColorTexture
;public CustomRenderPass(string profilerTag
){this.profilerTag
= profilerTag
;}public override void Configure(CommandBuffer cmd
, RenderTextureDescriptor cameraTextureDescriptor
){var width
= cameraTextureDescriptor
.width
/ downsample
;var height
= cameraTextureDescriptor
.height
/ downsample
;tmpId1
= Shader
.PropertyToID("tmpBlurRT1");tmpId2
= Shader
.PropertyToID("tmpBlurRT2");cmd
.GetTemporaryRT(tmpId1
, width
, height
, 0, FilterMode
.Bilinear
, RenderTextureFormat
.ARGB32
);cmd
.GetTemporaryRT(tmpId2
, width
, height
, 0, FilterMode
.Bilinear
, RenderTextureFormat
.ARGB32
);tmpRT1
= new RenderTargetIdentifier(tmpId1
);tmpRT2
= new RenderTargetIdentifier(tmpId2
);ConfigureTarget(tmpRT1
);ConfigureTarget(tmpRT2
);}public override void Execute(ScriptableRenderContext context
, ref RenderingData renderingData
){cameraColorTexture
= renderingData
.cameraData
.renderer
.cameraColorTarget
;CommandBuffer cmd
= CommandBufferPool
.Get(profilerTag
);RenderTextureDescriptor opaqueDesc
= renderingData
.cameraData
.cameraTargetDescriptor
;opaqueDesc
.depthBufferBits
= 0;cmd
.SetGlobalFloat("_offset", 1.5f);cmd
.Blit(cameraColorTexture
, tmpRT1
, blurMaterial
);for (var i
=1; i
<passes
-1; i
++) {cmd
.SetGlobalFloat("_offset", 0.5f + i
);cmd
.Blit(tmpRT1
, tmpRT2
, blurMaterial
);(tmpRT1
, tmpRT2
) = (tmpRT2
, tmpRT1
);}cmd
.SetGlobalFloat("_offset", 0.5f + passes
- 1f);if (copyToFramebuffer
) {cmd
.Blit(tmpRT1
, cameraColorTexture
, blurMaterial
);} else {cmd
.Blit(tmpRT1
, tmpRT2
, blurMaterial
);cmd
.SetGlobalTexture(targetName
, tmpRT2
);}context
.ExecuteCommandBuffer(cmd
);cmd
.Clear();CommandBufferPool
.Release(cmd
);}public override void FrameCleanup(CommandBuffer cmd
){}}CustomRenderPass scriptablePass
;public override void Create(){scriptablePass
= new CustomRenderPass("KawaseBlur");scriptablePass
.blurMaterial
= settings
.blurMaterial
;scriptablePass
.passes
= settings
.blurPasses
;scriptablePass
.downsample
= settings
.downsample
;scriptablePass
.copyToFramebuffer
= settings
.copyToFramebuffer
;scriptablePass
.targetName
= settings
.targetName
;scriptablePass
.renderPassEvent
= settings
.renderPassEvent
;}public override void AddRenderPasses(ScriptableRenderer renderer
, ref RenderingData renderingData
){renderer
.EnqueuePass(scriptablePass
);}
}
再加上一個Blur Shader:
Shader
"Custom/RenderFeature/KawaseBlur"
{Properties
{_MainTex ("Texture", 2D
) = "white" {}}SubShader
{Tags
{ "RenderType"="Opaque" }LOD
100Pass
{CGPROGRAM
#pragma vertex vert#pragma fragment frag#pragma multi_compile_fog#include "UnityCG.cginc"struct appdata{float4 vertex
: POSITION
;float2 uv
: TEXCOORD0
;};struct v2f{float2 uv
: TEXCOORD0
;UNITY_FOG_COORDS(1)float4 vertex
: SV_POSITION
;};sampler2D _MainTex
;float4 _MainTex_TexelSize
;float4 _MainTex_ST
;float _offset
;v2f
vert (appdata v
){v2f o
;o
.vertex
= UnityObjectToClipPos(v
.vertex
);o
.uv
= TRANSFORM_TEX(v
.uv
, _MainTex
);return o
;}fixed4
frag (v2f input
) : SV_Target
{float2 res
= _MainTex_TexelSize
.xy
;float i
= _offset
;fixed4 col
; col
.rgb
= tex2D( _MainTex
, input
.uv
).rgb
;col
.rgb
+= tex2D( _MainTex
, input
.uv
+ float2( i
, i
) * res
).rgb
;col
.rgb
+= tex2D( _MainTex
, input
.uv
+ float2( i
, -i
) * res
).rgb
;col
.rgb
+= tex2D( _MainTex
, input
.uv
+ float2( -i
, i
) * res
).rgb
;col
.rgb
+= tex2D( _MainTex
, input
.uv
+ float2( -i
, -i
) * res
).rgb
;col
.rgb
/= 5.0f;return col
;}ENDCG
}}
}
其次新增一個Forward Render asset:
點(diǎn)擊Add Renderer Feature,把前面寫的自定義Blur添加進(jìn)來,新建一個材質(zhì)球,材質(zhì)球使用上面寫的shader,并把材質(zhì)球掛到 Feature 的Blur Material上,調(diào)整一下Blur Passes等參數(shù),然后勾上Copy To Framebuffer。這樣我們的自定義 Forward Render 就做好了。
之后把自定義的 Forward Render 添加到當(dāng)前使用的URP Render Pipeline Asset 上面:
注意如果點(diǎn)了Set Default,那么相機(jī)就會自動使用這個Feature,這里我們不把它當(dāng)做默認(rèn),只是加上此Feature。然后在游戲中如果使用的是當(dāng)前的 Render Pipeline Asset ,那么相機(jī)是可以選擇Renderer的,我們選上新增的自定義Renderer:
好了,此時當(dāng)前相機(jī)渲染到FrameBuffer的圖像就會帶有Blur效果啦。另外,上面的Shader 也可以選擇將渲染出的圖片不輸出到 FrameBuffer 中,而是儲存在一個臨時Buffer中,供其他Shader使用。就是在Feature的參數(shù)中,不勾選 Copy to Framebuffer選項(xiàng),并在Target Name中填上渲染的Buffer名字。像上圖中寫的 _blurTexture,這樣之后就可以在其他shader中直接使用_blurTexture啦,可以實(shí)現(xiàn)一些毛玻璃之類的效果,當(dāng)然需要使用一個調(diào)整好視角的單獨(dú)相機(jī),另外渲染時機(jī)(Render Pass Event)可能需要修改一下。使用Feature的好處是可以調(diào)整渲染時機(jī),針對某幾個相機(jī)使用,并且可以挑選渲染對象(參考URP自帶的Feature:Render Objects),相對來說自由度更高。
總結(jié)
以上是生活随笔為你收集整理的Unity3D URP中使用Render Feature实现后处理效果的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。