Anime-Speed-Lines icon indicating copy to clipboard operation
Anime-Speed-Lines copied to clipboard

Not Working on Latest URP 14+, black screen on build

Open firdiar-mita opened this issue 7 months ago • 0 comments

For someone who's looking on it, but it's causing black screen on build. after URP update version 14. a lot of stuff is obsolete.

there's 2 things that causing this not working

  1. the urp isn't recommending to use cmd.Blit because it's obsolete not optimized and cause conflict on XR.
  2. the shader is using CGPROGRAM which not supported in URP.

for you guys who's using URP 14+ you can use my code below

RendererFeature

using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;

public class SpeedLineRenderPassFeature : ScriptableRendererFeature
{
    [System.Serializable]
    public class CustomRenderPassSettings
    {
        public Material material;
        public RenderPassEvent renderPassEvent = RenderPassEvent.AfterRenderingPostProcessing;
    }

    SpeedLineRenderPass m_ScriptablePass;
    
    public CustomRenderPassSettings settings = new CustomRenderPassSettings();

    /// <inheritdoc/>
    /// 
    public override void Create()
    {
        m_ScriptablePass = new SpeedLineRenderPass(settings);
    }

    // Here you can inject one or multiple render passes in the renderer.
    // This method is called when setting up the renderer once per-camera.

    public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
    {
        // we dont wan't to run the pass if there is no material
        if (settings.material == null)
        {
            Debug.LogError("Render Pass `SpeedLineRenderPassFeature` missing material");
            return;
        }

        //RenderTargetIdentifier source = renderer.cameraColorTarget;
        //m_ScriptablePass.Setup(source);
        if (renderingData.cameraData.cameraType == CameraType.Game)
            renderer.EnqueuePass(m_ScriptablePass);
    }

    public override void SetupRenderPasses(ScriptableRenderer renderer, in RenderingData renderingData)
    {
        if (renderingData.cameraData.cameraType == CameraType.Game)
        {
            // Calling ConfigureInput with the ScriptableRenderPassInput.Color argument
            // ensures that the opaque texture is available to the Render Pass.
            m_ScriptablePass.ConfigureInput(ScriptableRenderPassInput.Color | ScriptableRenderPassInput.Depth | ScriptableRenderPassInput.Normal | ScriptableRenderPassInput.Motion);
            m_ScriptablePass.SetTarget(renderer.cameraColorTargetHandle);
        }
    }

    class SpeedLineRenderPass : ScriptableRenderPass
    {
        RTHandle m_CameraColorTarget;

        // store settings instead of material itself
        SpeedLineRenderPassFeature.CustomRenderPassSettings settings;

        // name this what you want, it will be used to name the profile in frame debugger
        const string profilingName = "SpeedLineRender-Pass";


        public SpeedLineRenderPass(SpeedLineRenderPassFeature.CustomRenderPassSettings settings)
        {
            // storing the settings allows you to add more features faster without having to boiler plate code,
            // also ensures that any changes made in the render feature reflect in the pass
            this.settings = settings;
            renderPassEvent = settings.renderPassEvent;

            // create a new profiling sampler with are chosen name,
            // else you get just a generic "ScriptableRendererPass" name
            this.profilingSampler = new ProfilingSampler(profilingName);
        }

        public void SetTarget(RTHandle colorHandle)
        {
            // get the source target from rendering data every frame
            m_CameraColorTarget = colorHandle;
        }

        public override void OnCameraSetup(CommandBuffer cmd, ref RenderingData renderingData)
        {
            ConfigureTarget(m_CameraColorTarget);
        }

        public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
        {
            var cameraData = renderingData.cameraData;
            if (cameraData.camera.cameraType != CameraType.Game)
                return;

            CommandBuffer cmd = CommandBufferPool.Get(nameof(SpeedLineRenderPass));
            using (new ProfilingScope(cmd, profilingSampler))
            {
                Blitter.BlitCameraTexture(cmd, m_CameraColorTarget, m_CameraColorTarget, settings.material, 0);
            }
            context.ExecuteCommandBuffer(cmd);
            cmd.Clear();

            CommandBufferPool.Release(cmd);
        }
    }
}

Shader

Shader "Mirza/Anime Speed Lines"
{
    Properties
    {
        _MainTex("Screen", 2D) = "black" {}
        _Colour("Colour", Color) = (1, 1, 1, 1)
        _SpeedLinesTiling("Speed Lines Tiling", Float) = 200
        _SpeedLinesRadialScale("Speed Lines Radial Scale", Range(0, 10)) = 0.1
        _SpeedLinesPower("Speed Lines Power", Float) = 1
        _SpeedLinesRemap("Speed Lines Remap", Range(0, 1)) = 0.8
        _SpeedLinesAnimation("Speed Lines Animation", Float) = 3
        _MaskScale("Mask Scale", Range(0, 2)) = 1
        _MaskHardness("Mask Hardness", Range(0, 1)) = 0
        _MaskPower("Mask Power", Float) = 5
        [HideInInspector] _texcoord("", 2D) = "white" {}
        _SpeedLinesEnabled("Enable Speed Lines", Range(0, 1)) = 0
    }


    SubShader
    {
        LOD 0

        ZTest Always
        Cull Off
        ZWrite Off

        Pass
        {
            HLSLPROGRAM
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
            #include "Packages/com.unity.render-pipelines.core/Runtime/Utilities/Blit.hlsl"
            #pragma vertex vert
            #pragma fragment frag

            
            struct appdata_img_custom
            {
                #if SHADER_API_GLES
                float4 vertex : POSITION;
                half2 texcoord : TEXCOORD0;
                #else
                uint vertexID : SV_VertexID;
                #endif
            };

            struct v2f_img_custom
            {
                float4 pos : SV_POSITION;
                half2 uv : TEXCOORD0;
                half2 stereoUV : TEXCOORD2;

                #if UNITY_UV_STARTS_AT_TOP
                half4 uv2 : TEXCOORD1;
                half4 stereoUV2 : TEXCOORD3;
                #endif
            };

            sampler2D _MainTex;
            half4 _MainTex_TexelSize;
            half4 _MainTex_ST;

            TEXTURE2D_X(_CameraOpaqueTexture);
            SAMPLER(sampler_CameraOpaqueTexture);

            float _SpeedLinesRadialScale;
            float _SpeedLinesTiling;
            float _SpeedLinesAnimation;
            float _SpeedLinesPower;
            float _SpeedLinesRemap;
            float _MaskScale;
            float _MaskHardness;
            float _MaskPower;
            float4 _Colour;
            float _SpeedLinesEnabled;

            float3 mod2D289(float3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
            float2 mod2D289(float2 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
            float3 permute(float3 x) { return mod2D289(((x * 34.0) + 1.0) * x); }
            float snoise(float2 v)
            {
                const float4 C = float4(0.211324865405187, 0.366025403784439, -0.577350269189626, 0.024390243902439);
                float2 i = floor(v + dot(v, C.yy));
                float2 x0 = v - i + dot(i, C.xx);
                float2 i1;
                i1 = (x0.x > x0.y) ? float2(1.0, 0.0) : float2(0.0, 1.0);
                float4 x12 = x0.xyxy + C.xxzz;
                x12.xy -= i1;
                i = mod2D289(i);
                float3 p = permute(permute(i.y + float3(0.0, i1.y, 1.0)) + i.x + float3(0.0, i1.x, 1.0));
                float3 m = max(0.5 - float3(dot(x0, x0), dot(x12.xy, x12.xy), dot(x12.zw, x12.zw)), 0.0);
                m = m * m;
                m = m * m;
                float3 x = 2.0 * frac(p * C.www) - 1.0;
                float3 h = abs(x) - 0.5;
                float3 ox = floor(x + 0.5);
                float3 a0 = x - ox;
                m *= 1.79284291400159 - 0.85373472095314 * (a0 * a0 + h * h);
                float3 g;
                g.x = a0.x * x0.x + h.x * x0.y;
                g.yz = a0.yz * x12.xz + h.yz * x12.yw;
                return 130.0 * dot(m, g);
            }

            half4 ComputeGrabScreenPos(half2 uv, half4 screenPos)
            {
                return half4((screenPos.xy + uv * screenPos.zw), 0, 0);
            }

            v2f_img_custom vert(appdata_img_custom v)
            {
                v2f_img_custom output;
                UNITY_SETUP_INSTANCE_ID(input);
                UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
                
            #if SHADER_API_GLES
                float4 pos = v.vertex;
                float2 uv  = v.texcoord;
            #else
                float4 pos = GetFullScreenTriangleVertexPosition(v.vertexID);
                float2 uv  = GetFullScreenTriangleTexCoord(v.vertexID);
            #endif

                output.pos = pos;
                output.uv = uv * _BlitScaleBias.xy + _BlitScaleBias.zw;

                #if UNITY_UV_STARTS_AT_TOP
                output.uv2 = float4(pos.xy, 1, 1);
                output.stereoUV2 = ComputeGrabScreenPos(output.uv2, _MainTex_ST);

                if (_MainTex_TexelSize.y < 0.0)
                {
                    output.uv.y = 1.0 - output.uv.y;
                }
                #endif
                output.stereoUV = ComputeGrabScreenPos(output.uv, _MainTex_ST);

                return output;

            }


            half4 frag(v2f_img_custom i) : SV_Target
            {
                #ifdef UNITY_UV_STARTS_AT_TOP
                half2 uv = i.uv2;
                half2 stereoUV = i.stereoUV2;
                #else
                half2 uv = i.uv;
                half2 stereoUV = i.stereoUV;
                #endif

                half4 finalColor;

                // ase common template code
                float2 uv_MainTex = i.uv.xy * _MainTex_ST.xy + _MainTex_ST.zw;
                //float4 SceneColour7 = tex2D(_MainTex, uv_MainTex);
                float4 SceneColour7 = SAMPLE_TEXTURE2D_X(_CameraOpaqueTexture, sampler_CameraOpaqueTexture, i.uv);

                // Check if the shader effect is enabled
                if (_SpeedLinesEnabled > 0)
                {
                    // Your existing shader effect code here
                    // ...

                    // Your existing shader code for the effect
                    // ...
                    float2 CenteredUV15_g1 = (i.uv.xy - float2(0.5, 0.5));
                    float2 break17_g1 = CenteredUV15_g1;
                    float2 appendResult23_g1 = (float2((length(CenteredUV15_g1) * _SpeedLinesRadialScale * 2.0), (atan2(break17_g1.x, break17_g1.y) * (1.0 / 6.28318548202515) * _SpeedLinesTiling)));
                    float2 appendResult58 = (float2((-_SpeedLinesAnimation * _Time.y), 0.0));
                    float simplePerlin2D10 = snoise((appendResult23_g1 + appendResult58));
                    simplePerlin2D10 = simplePerlin2D10 * 0.5 + 0.5;
                    float temp_output_1_0_g6 = _SpeedLinesRemap;
                    float SpeedLines21 = saturate(((pow(simplePerlin2D10, _SpeedLinesPower) - temp_output_1_0_g6) / (1.0 - temp_output_1_0_g6)));
                    float2 texCoord60 = i.uv.xy * float2(2, 2) + float2(-1, -1);
                    float temp_output_1_0_g5 = _MaskScale;
                    float lerpResult71 = lerp(0.0, _MaskScale, _MaskHardness);
                    float Mask24 = pow((1.0 - saturate((length(texCoord60) - temp_output_1_0_g5) / ((lerpResult71 - 0.001) - temp_output_1_0_g5))), _MaskPower);
                    float MaskedSpeedLines29 = (SpeedLines21 * Mask24);
                    float3 ColourRGB38 = (_Colour).rgb;
                    float ColourA40 = _Colour.a;
                    float4 lerpResult2 = lerp(SceneColour7, float4((MaskedSpeedLines29 * ColourRGB38), 0.0), (MaskedSpeedLines29 * ColourA40));

                    finalColor = lerpResult2;
                }
                else
                {
                    // If the effect is disabled, simply output the original color
                    finalColor = SceneColour7;
                }
                
                //return finalColor;
                //float4 color = SAMPLE_TEXTURE2D_X(_CameraOpaqueTexture, sampler_CameraOpaqueTexture, i.uv);
                return finalColor;
            }

            ENDHLSL
        }
    }
}

Reference : Perform a full screen blit in URP | Universal RP | 14.0.9 (unity3d.com) Unity - Manual: ShaderLab: adding shader programs (unity3d.com)

firdiar-mita avatar Nov 15 '23 08:11 firdiar-mita