Hi everyone,
I’m learning scriptable render feature,my URP version is 14.0.8.I’m trying to coding a multiPass scriptable render feature,the first pass will draw a normal texture in render texture,it works,but in the second pass,no matter what I want to do,the render texture is always black,I guess the second pass do not get the render texture which the first pass drew,but I don’t know where I went wrong
here is the scriptable render feature code:
public class NormalOutLineFeature : ScriptableRendererFeature
{
[System.Serializable]
public class Settings
{
public LayerMask layer;
public Material normalTexMat;
public Material normalOutLineMat;
public RenderPassEvent passEvent = RenderPassEvent.AfterRenderingPrePasses;
}
public Settings settings = new Settings();
public class DrawNormalTexPass : ScriptableRenderPass
{
private Settings settings;
ShaderTagId shaderTag = new ShaderTagId("DepthOnly");
FilteringSettings filter;
NormalOutLineFeature feature;
private RTHandle normalRTHC;
private RTHandle normalRTHD;
public DrawNormalTexPass(Settings settings,NormalOutLineFeature feature)
{
this.settings = settings;
this.feature = feature;
RenderQueueRange queue = new RenderQueueRange();
queue.lowerBound = 1000;
queue.upperBound = 3500;
filter = new FilteringSettings(queue,settings.layer);
}
public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
{
base.Configure(cmd, cameraTextureDescriptor);
RenderTextureDescriptor desc = cameraTextureDescriptor;
RenderingUtils.ReAllocateIfNeeded(ref normalRTHD, desc, wrapMode: TextureWrapMode.Clamp, name:"_NormalTex");
desc.depthBufferBits = 0;
RenderingUtils.ReAllocateIfNeeded(ref normalRTHC, desc, wrapMode: TextureWrapMode.Clamp, name: "_NormalTex");
ConfigureTarget(normalRTHC,normalRTHD);
ConfigureClear(ClearFlag.All, Color.black);
}
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
CommandBuffer cmd = CommandBufferPool.Get("DrawNormalTex");
var draw = CreateDrawingSettings(shaderTag, ref renderingData, renderingData.cameraData.defaultOpaqueSortFlags);
draw.overrideMaterial = settings.normalTexMat;
draw.overrideMaterialPassIndex = 0;
context.DrawRenderers(renderingData.cullResults, ref draw, ref filter);
CommandBufferPool.Release(cmd);
}
}
public class DrawNormalLinePass : ScriptableRenderPass
{
private Settings settings;
NormalOutLineFeature feature;
private RTHandle sourceRTH;
private RTHandle destinationRTH;
private RTHandle destinationRTHD;
public DrawNormalLinePass(Settings settings,NormalOutLineFeature feature)
{
this.settings = settings;
this.feature = feature;
}
public override void FrameCleanup(CommandBuffer cmd)
{
cmd.ReleaseTemporaryRT(Shader.PropertyToID("_NormalOutLine"));
cmd.ReleaseTemporaryRT(Shader.PropertyToID("_NormalTex"));
}
public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
{
base.Configure(cmd, cameraTextureDescriptor);
RenderTextureDescriptor desc = cameraTextureDescriptor;
RenderingUtils.ReAllocateIfNeeded(ref destinationRTHD, desc, wrapMode: TextureWrapMode.Clamp, name: "_NormalOutLine");
desc.depthBufferBits = 0;
RenderingUtils.ReAllocateIfNeeded(ref destinationRTH, desc, wrapMode: TextureWrapMode.Clamp, name: "_NormalOutLine");
ConfigureTarget(destinationRTH, destinationRTHD);
ConfigureClear(ClearFlag.All, Color.black);
}
public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
{
CommandBuffer cmd = CommandBufferPool.Get("DrawOutLine");
Blitter.BlitCameraTexture(cmd, destinationRTH, destinationRTH, settings.normalOutLineMat, 0);
context.ExecuteCommandBuffer(cmd);
CommandBufferPool.Release(cmd);
}
}
private DrawNormalTexPass _DrawNormalTexPass;
private DrawNormalLinePass _DrawNormalLinePass;
public override void Create()
{
_DrawNormalTexPass = new DrawNormalTexPass(settings, this);
_DrawNormalTexPass.renderPassEvent = settings.passEvent;
_DrawNormalLinePass= new DrawNormalLinePass(settings, this);
_DrawNormalLinePass.renderPassEvent = settings.passEvent;
}
public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
{
renderer.EnqueuePass(_DrawNormalTexPass);
renderer.EnqueuePass(_DrawNormalLinePass);
}
}
and here is the first shader and second shader:
Shader "Unlit/NormalTex"
{
Properties
{
}
SubShader
{
Tags
{
"RenderPipeline" = "UniversalPipeline"
"RenderType"="Opaque"
}
LOD 100
Pass
{
HLSLPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
struct Attributes
{
float4 positionOS : POSITION;
float3 normalOS : NORMAL;
};
struct Varyings
{
float4 positionHCS : SV_POSITION;
float3 normalWS : TEXCOORD0;
float3 normalVS : TEXCOORD1;
};
Varyings vert (Attributes v)
{
Varyings o;
o.positionHCS = TransformObjectToHClip(v.positionOS);
o.normalWS = TransformObjectToWorldNormal(v.normalOS);
o.normalVS = TransformWorldToViewDir(o.normalWS,true);
return o;
}
half4 frag (Varyings i) : SV_Target
{
half4 col = 0;
col.rgb = i.normalVS;
return col;
}
ENDHLSL
}
}
}
Shader "Unlit/TestShader"
{
Properties
{
}
SubShader
{
Tags
{
"RenderPipeline" = "UniversalPipeline"
"RenderType"="Opaque"
}
LOD 100
Pass
{
HLSLPROGRAM
#pragma vertex Vert
#pragma fragment frag
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
#include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
SAMPLER(sampler_BlitTexture);
half4 frag (Varyings input) : SV_Target
{
half4 col = SAMPLE_TEXTURE2D_X(_BlitTexture,sampler_BlitTexture,input.texcoord);
return col;
}
ENDHLSL
}
}
and here is the frame debugger: