Unity 黑白闪效果
游戏中经常会使用将画面通过短暂的黑白闪来实现激烈的表现效果.如下图:为了让特效有跟好的控制,目前使用较大粒子片盖在相机前实现 整体思路如下:
1、截取画面Pass
URP中自带了屏幕颜色_CameraOpaqueTexture, 使用SampleSceneColor来获取,但是这个只是不透明层的.如果需要加入透明层物体,需要在不透明渲染之后插入一个CopyColorPass来实现. 这里_CameraTransparentTexture就是包含了透明物体的颜色缓冲.
public class TransparentTextureFeature:ScriptableRendererFeature
{
private CustomCopyColorPass _copyColorPass;
private Material m_SamplingMaterial;
RenderTargetHandle m_TransparentColor;
RenderTargetHandle m_CameraColorAttachment;
public override void Create()
{
m_SamplingMaterial = CoreUtils.CreateEngineMaterial(Shader.Find("Hidden/Universal Render Pipeline/Sampling"));
_copyColorPass = new CustomCopyColorPass(RenderPassEvent.AfterRenderingTransparents, m_SamplingMaterial);
m_TransparentColor.Init("_CameraTransparentTexture");
m_CameraColorAttachment.Init("_CameraColorTexture");
}
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
if ( renderingData.cameraData.renderType == CameraRenderType.Base)
{
_copyColorPass.Setup(m_CameraColorAttachment.Identifier(), m_TransparentColor, UniversalRenderPipeline.asset.opaqueDownsampling);
renderer.EnqueuePass(_copyColorPass);
}
}
}2、黑白闪shader
这里计算原理就是, 先计算当前像素在屏幕中的位置,然后采样_CameraTransparentTexture纹理,得到屏幕像素. 然后计算灰度值, 通过step控制黑白阀值. 在用oneminus 得到黑白相反的颜色.
Shader "Effect/Effect_GJ_URP_BlackWhite"
{
Properties
{
_BlackWhiteBlend ("【BlackWhiteBlend】", range (0,1) ) = 0
_BlackWhitePower ("BlackWhitePower", range(0.1,30) ) = 1
_BlackWhiteAphaStrength ("BlackWhiteAphaStrength", range (0,5) ) = 5
}
SubShader
{
Tags
{
"IgnoreProjector"="True"
"Queue"="Transparent"
"RenderType"="Transparent"
}
Pass
{
Tags
{
"LightMode" = "UniversalForward_BlackWhite"
}
ZWrite On
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
CBUFFER_START (UnityPerMaterial)
float _BlackWhiteBlend;
float _BlackWhitePower;
float _BlackWhiteAphaStrength;
CBUFFER_END
SAMPLER(_CameraTransparentTexture);
struct VertexInput
{
float4 vertex : POSITION;
};
struct VertexOutput
{
float4 pos : SV_POSITION;
};
VertexOutput vert(VertexInput v)
{
VertexOutput o = (VertexOutput)0;
o.pos = TransformObjectToHClip( v.vertex.xyz);
return o;
}
float4 frag(VertexOutput i, float facing : VFACE) : COLOR
{
//BlackWhite
//float4 blackwhite = float4(SampleSceneColor(i.pos.xy / _ScreenParams.xy), 1);
float4 blackwhite = tex2D(_CameraTransparentTexture, i.pos.xy / _ScreenParams.xy);
float grey = dot(blackwhite.rgb, float3(0.22, 0.707, 0.071));
blackwhite.rgb = step(0.5, pow(grey, _BlackWhitePower));
blackwhite.a = _BlackWhiteAphaStrength;
return lerp(blackwhite, float4((1 - blackwhite).rgb, blackwhite.a), _BlackWhiteBlend);
}
ENDHLSL
}
}
}3、效果调试
再UniversalPipelineAsset中设置TransparentTextureFeature抓取颜色缓冲, 然后再beforerenderpostprocess阶段渲染单独该粒子即可(正常渲染通过shadertag排除该粒子的渲染),配置如下
粒子系统控制_BlackWhiteBlend来实现效果,
直接用URP中的CopyColorPass一样效果, 大佬可以分享一下工程吗
页:
[1]