I have custom effect for camera, that makes blur effect and splitting the screen (by offsetting it). So, I implemented custom render feature using Render Graph, but it doesn’t work. Can you say what’s wrong here?
Shader Code:
Shader "Custom/DamageEffect"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
_BlurAmount ("Blur Amount", Range(0, 1)) = 0
_DoubleVisionAmount ("Double Vision Amount", Range(0, 1)) = 0
_Offset ("Offset", Vector) = (0, 0, 0, 0)
}
SubShader
{
Tags
{
"RenderType"="Opaque"
}
Pass
{
ZTest Always Cull Off ZWrite Off
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
sampler2D _MainTex;
float4 _MainTex_TexelSize;
float _BlurAmount;
float _DoubleVisionAmount;
float4 _Offset;
struct Attributes {
float4 positionOS : POSITION;
float2 uv : TEXCOORD0;
};
struct Varyings {
float4 positionHCS : SV_POSITION;
float2 uv : TEXCOORD0;
};
Varyings vert(Attributes v)
{
Varyings o;
o.positionHCS = TransformObjectToHClip(v.positionOS);
o.uv = v.uv;
return o;
}
float4 frag(Varyings i) : SV_Target
{
float2 uv = i.uv;
// Apply double vision effect
float2 offsetUV = uv + _Offset.xy * _DoubleVisionAmount;
float4 color = tex2D(_MainTex, uv);
float4 offsetColor = tex2D(_MainTex, offsetUV);
color = lerp(color, offsetColor, _DoubleVisionAmount);
// Apply blur effect
if(_BlurAmount > 0)
{
float2 texelSize = _MainTex_TexelSize.xy;
float4 blurColor = float4(0, 0, 0, 0);
blurColor += tex2D(_MainTex, uv + texelSize * float2(-1, -1));
blurColor += tex2D(_MainTex, uv + texelSize * float2(0, -1));
blurColor += tex2D(_MainTex, uv + texelSize * float2(1, -1));
blurColor += tex2D(_MainTex, uv + texelSize * float2(-1, 0));
blurColor += tex2D(_MainTex, uv);
blurColor += tex2D(_MainTex, uv + texelSize * float2(1, 0));
blurColor += tex2D(_MainTex, uv + texelSize * float2(-1, 1));
blurColor += tex2D(_MainTex, uv + texelSize * float2(0, 1));
blurColor += tex2D(_MainTex, uv + texelSize * float2(1, 1));
blurColor /= 9;
color = lerp(color, blurColor, _BlurAmount);
}
return color;
}
ENDHLSL
}
}
}
Render Feature Code:
using System;
using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.RenderGraphModule;
using UnityEngine.Rendering.RenderGraphModule.Util;
using UnityEngine.Rendering.Universal;
public sealed class DamageEffectRendererFeature : ScriptableRendererFeature
{
private sealed class DamageEffectRenderPass : ScriptableRenderPass
{
private const string PassName = "Damage Effect";
private readonly Material _damageEffectMaterial;
public DamageEffectRenderPass(Material material)
{
_damageEffectMaterial = material;
requiresIntermediateTexture = true;
}
public override void RecordRenderGraph(RenderGraph renderGraph, ContextContainer frameData)
{
#if UNITY_EDITOR
if (_damageEffectMaterial == null)
{
throw new NullReferenceException($"Missing material: {nameof(_damageEffectMaterial)}");
}
#endif
var resourceData = frameData.Get<UniversalResourceData>();
var sourceTexture = resourceData.activeColorTexture;
var destinationDescriptor = renderGraph.GetTextureDesc(sourceTexture);
destinationDescriptor.name = $"CameraColor-{PassName}";
destinationDescriptor.clearBuffer = false;
destinationDescriptor.depthBufferBits = DepthBits.None;
destinationDescriptor.filterMode = FilterMode.Bilinear;
var destinationTexture = renderGraph.CreateTexture(destinationDescriptor);
var pass = new RenderGraphUtils.BlitMaterialParameters(sourceTexture, destinationTexture, _damageEffectMaterial, default(int));
renderGraph.AddBlitPass(pass, passName);
resourceData.cameraColor = destinationTexture;
}
}
[SerializeField] private RenderPassEvent renderPassEvent = RenderPassEvent.AfterRenderingPostProcessing;
[SerializeField] private Material damageEffectMaterial;
private DamageEffectRenderPass _renderPass;
public override void Create()
{
_renderPass = new DamageEffectRenderPass(damageEffectMaterial)
{
renderPassEvent = renderPassEvent,
};
}
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
renderer.EnqueuePass(_renderPass);
}
}