[LWRP] Custom ScriptableRenderFeature shader works in editor, goes pink in build?

Hello!

I’m running in a bit of an issue with ScriptableRendererFeatures and at this point I don’t know if I’m doing something wrong or if it’s an issue with the pipeline itself.

Basically I’m trying to port some rendering features of our SSAA plugin from HDRP to LWRP, and I’m stuck at the shaders.

The issue is, everything renders correctly in editor, but if I run a build, screen goes pink (seems like our shaders go invalid/missing in build?) Already tried to add the shaders to the always included shader list in Graphics settings with no luck, there are no compilation errors or warnings within our shaders, and all of them work correctly in editor - its just the builds where the problem appears.

Tried with latest LWRP on 2019.2 and with URP on 2019.3 - same results

In editor

In build

Anyways this is one of the shaders we have (supposed to only blit a texture over the screen). It’s straight up copy-paste from our HDRP variant. Wondering if there is anything that needs to be changed for LWRP? Oddly it works perfectly on LWRP in editor…

Shader "Hidden/SSAA_Def_HDRP"
{
    Properties
    {
        [HideInInspector] _MainTex("Base (RGB)", 2D) = "white" {}
    }
    HLSLINCLUDE

    #include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
    #include "UnityShaderVariables.cginc"
    float2 FixVFlip(float2 texcoord)
    {
#if UNITY_UV_STARTS_AT_TOP
        bool flip = _ProjectionParams.x > 0;
#else
        bool flip = _ProjectionParams.x < 0;
#endif
        if (flip) texcoord.y = 1 - texcoord.y;
        return texcoord;
    }
    TEXTURE2D(_MainTex);
    SAMPLER(sampler_MainTex);
    // Vertex shader (procedural fullscreen triangle)
    void Vertex(
        uint vertexID : SV_VertexID,
        out float4 positionCS : SV_POSITION,
        out float2 texcoord : TEXCOORD0
    )
    {
        positionCS = GetFullScreenTriangleVertexPosition(vertexID);
        texcoord = FixVFlip(GetFullScreenTriangleTexCoord(vertexID));
    }
    // Fragment shader
    float4 Fragment(
        float4 positionCS : SV_POSITION,
        float2 texcoord : TEXCOORD0
    ) : SV_Target
    {
        // just output the texture
        return SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, texcoord);
    }
    ENDHLSL
    SubShader
    {
        Cull Off ZWrite Off ZTest Always
        Pass
        {
            HLSLPROGRAM
            #pragma vertex Vertex
            #pragma fragment Fragment
            ENDHLSL
        }
    }
}

This is the Execute() method of our custom render feature:

        public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
        {
            var ssaa = renderingData.cameraData.camera.GetComponent<MadGoat.SSAA.MadGoatSSAA>();

            if (ssaa == null) return;
            if (!ssaa.enabled) return;

            var isVR = ssaa is MadGoat.SSAA.MadGoatSSAA_VR;

#if UNITY_EDITOR
            if (!UnityEditor.EditorApplication.isPlaying && isVR) return;
#endif

            var material = ssaa.MaterialCurrent;

            // set blending - no stacking support on lwrp/urp
            material.SetOverrideTag("RenderType", "Opaque");
            material.SetInt("_SrcBlend", (int)BlendMode.One);
            material.SetInt("_DstBlend", (int)BlendMode.Zero);
            material.SetInt("_ZWrite", 1);
            material.renderQueue = -1;

            // update values
            material.SetFloat("_ResizeWidth", ssaa.CameraTargetWidth);
            material.SetFloat("_ResizeHeight", ssaa.CameraTargetHeight);
            material.SetFloat("_Sharpness", ssaa.DownsamplerSharpness);
            material.SetFloat("_SampleDistance", ssaa.DownsamplerDistance);

            if (!isVR) {
                ssaa.OnBeginCameraRender(renderingData.cameraData.camera);
                material.SetTexture("_MainTex", ssaa.RenderCamera.targetTexture);

                // setup command buffer
                var cmd = CommandBufferPool.Get("SSAA_HDRP_DOWNSAMPLER");
                var camera = renderingData.cameraData.camera;

                CoreUtils.ClearRenderTarget(cmd, ClearFlag.All, Color.clear);
                CoreUtils.SetRenderTarget(cmd, BuiltinRenderTextureType.CurrentActive);

                Blit(cmd, ssaa.RenderCamera.targetTexture, BuiltinRenderTextureType.CurrentActive, material, 0);

                context.ExecuteCommandBuffer(cmd);
                CommandBufferPool.Release(cmd);
            } else { ... }
        }
    }

Any help/suggestion would be appreciated. Thanks :slight_smile:

Just figured out I probably posted this in the wrong forum.

Is it possible for someone with moderator rights to move the thread on the Universal Render Pipeline forums?

Thanks :slight_smile:

Im stumbling across the same issue. Did you find a solution? (:

Hey, haven’t touched that code in a long time so not sure exactly what solved it (our asset got deprecated some years ago, then acquired by another publisher on which I freelanced on again at some point briefly but not on SRP stuff, then deprecated again by them recently) but this is the latest version as per my personal git, prior to initial deprecation, of that bit of code that iirc worked correctly

            // set blending - no stacking support on lwrp/urp
            material.SetOverrideTag("RenderType", "Opaque");
            material.SetInt("_SrcBlend", (int)BlendMode.One);
            material.SetInt("_DstBlend", (int)BlendMode.Zero);
            material.SetInt("_ZWrite", 1);
            material.renderQueue = -1;

            // update values
            material.SetFloat("_ResizeWidth", ssaa.CameraTargetWidth);
            material.SetFloat("_ResizeHeight", ssaa.CameraTargetHeight);
            material.SetFloat("_Sharpness", ssaa.DownsamplerSharpness);
            material.SetFloat("_SampleDistance", ssaa.DownsamplerDistance);

            if (!isVR) {
                // setup command buffer
                var cmd = CommandBufferPool.Get("SSAA_URP_DOWNSAMPLER");
                CoreUtils.ClearRenderTarget(cmd, ClearFlag.All, Color.clear);
                CoreUtils.SetRenderTarget(cmd, BuiltinRenderTextureType.CurrentActive);

                Blit(cmd, ssaa.RenderCamera.targetTexture, BuiltinRenderTextureType.CurrentActive, material, 0);

                // execute command buffer
                context.ExecuteCommandBuffer(cmd);
                CommandBufferPool.Release(cmd);
            }

And shader updated to use unity’s macros for sampling and everything (iirc this was mostly for VR but not sure if it’s this or the previous changes in renderpass code that solved it)

Shader "Hidden/SSAA_Def"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "" {}
    }
    SubShader {
        Tags{ "RenderType" = "Opaque"  "Queue" = "Geometry+0" }
        Blend [_SrcBlend] [_DstBlend]
        Pass {
             ZTest Always Cull Off ZWrite On

            CGPROGRAM
            // Includes
            #include "UnityCG.cginc"
            #include "Include/_SSAA_Utils.cginc"

            // Shader Construct
            #pragma vertex vert
            #pragma fragment frag

            // Samplers
            UNITY_DECLARE_SCREENSPACE_TEXTURE(_MainTex);

            struct Input{
                float4 vertex : POSITION;
                float2 uv : TEXCOORD0;
                UNITY_VERTEX_INPUT_INSTANCE_ID
            };

            struct Varying{
                float4 vertex : SV_POSITION;
                float2 uv : TEXCOORD0;
                UNITY_VERTEX_OUTPUT_STEREO
            };

            Varying vert(Input input){
                Varying o;
                UNITY_SETUP_INSTANCE_ID(input);
                UNITY_INITIALIZE_OUTPUT(Varying, o);
                UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);

                o.vertex = UnityObjectToClipPos(input.vertex);
                o.uv = input.uv;
                return o;
            }

            float4 frag(Varying i) : SV_Target {
                UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
                return UNITY_SAMPLE_SCREENSPACE_TEXTURE(_MainTex, i.uv);
            }
            ENDCG
        }
    }
    Fallback Off
}

Note that I haven’t tested any of this on LWRP/URP versions newer than 2020.1-2020.2