LWRP学習 レンダリングパスを追加する

そろそろUnityも触らないとなぁと思ったので、LWRPを少しずつ学習していこうと思います。

手始めに、目標を達成するためにレンダリングパスを追加してみます。

今回はいずれシャドウマップを使ってエフェクトを作成したかったので、Screen Space Shadowパスをコピーして追加したパスでもう一度シャドウを生成するということをやったので雑なメモを残します。

大体こちらの記事の通りに進めればできました!

connect.unity.com

ScriptableRenderPassを作る

Scriptable Render Pipelineのリポジトリから該当の処理を探してほぼ丸コピしました。

github.com

using UnityEngine;
using UnityEngine.Rendering;
using UnityEngine.Rendering.LWRP;


public sealed class MyShadowPass : ScriptableRenderPass
{
    Material m_ScreenSpaceShadowsMaterial;
    RenderTargetHandle m_ScreenSpaceShadowmap;
    RenderTextureDescriptor m_RenderTextureDescriptor;
    const string m_ProfilerTag = "Kaneta Shadows";

    public MyShadowPass(RenderPassEvent evt, Material screenspaceShadowsMaterial)
    {
        m_ScreenSpaceShadowsMaterial = screenspaceShadowsMaterial;
        m_ScreenSpaceShadowmap.Init("_ScreenSpaceShadowmapTexture");
        renderPassEvent = evt;
    }

    public void Setup(RenderTextureDescriptor baseDescriptor)
    {
        m_RenderTextureDescriptor = baseDescriptor;
        m_RenderTextureDescriptor.depthBufferBits = 0;
        m_RenderTextureDescriptor.msaaSamples = 1;
        m_RenderTextureDescriptor.colorFormat = true
            ? RenderTextureFormat.R8
            : RenderTextureFormat.ARGB32;
    }

    public override void Configure(CommandBuffer cmd, RenderTextureDescriptor cameraTextureDescriptor)
    {
        cmd.GetTemporaryRT(m_ScreenSpaceShadowmap.id, m_RenderTextureDescriptor, FilterMode.Bilinear);

        RenderTargetIdentifier screenSpaceOcclusionTexture = m_ScreenSpaceShadowmap.Identifier();
        ConfigureTarget(screenSpaceOcclusionTexture);
        ConfigureClear(ClearFlag.All, Color.white);
    }

    /// <inheritdoc/>
    public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
    {
        if (m_ScreenSpaceShadowsMaterial == null)
        {
            Debug.LogErrorFormat("Missing {0}. {1} render pass will not execute. Check for missing reference in the renderer resources.", m_ScreenSpaceShadowsMaterial, GetType().Name);
            return;
        }

        if (renderingData.lightData.mainLightIndex == -1)
            return;

        Camera camera = renderingData.cameraData.camera;
        bool stereo = renderingData.cameraData.isStereoEnabled;

        CommandBuffer cmd = CommandBufferPool.Get(m_ProfilerTag);
        if (!stereo)
        {
            cmd.SetViewProjectionMatrices(Matrix4x4.identity, Matrix4x4.identity);
            cmd.DrawMesh(RenderingUtils.fullscreenMesh, Matrix4x4.identity, m_ScreenSpaceShadowsMaterial);
            cmd.SetViewProjectionMatrices(camera.worldToCameraMatrix, camera.projectionMatrix);
        }
        else
        {
            // Avoid setting and restoring camera view and projection matrices when in stereo.
            RenderTargetIdentifier screenSpaceOcclusionTexture = m_ScreenSpaceShadowmap.Identifier();
            Blit(cmd, screenSpaceOcclusionTexture, screenSpaceOcclusionTexture, m_ScreenSpaceShadowsMaterial);
        }

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

    /// <inheritdoc/>
    public override void FrameCleanup(CommandBuffer cmd)
    {

        cmd.ReleaseTemporaryRT(m_ScreenSpaceShadowmap.id);
    }
}

ScriptableRendererFeatureを作る

元のシャドウパス生成処理を真似てScriptableRendererFeatureを作ります。

github.com

using UnityEngine;
using UnityEngine.Rendering.LWRP;

[CreateAssetMenu(fileName = "MyShadowPassFeature",
    menuName = "Sample/MyShadowPassFeature", order = 1)]
public sealed class MyShadowPassFeature : ScriptableRendererFeature
{
    private MyShadowPass currentPass;

    public override void Create()
    {
        var screenspaceShadowsMaterial = new Material(Shader.Find("Hidden/Lightweight Render Pipeline/ScreenSpaceShadows"));
        if (currentPass == null)
            currentPass = new MyShadowPass(RenderPassEvent.BeforeRenderingPrepasses, screenspaceShadowsMaterial);
    }

    public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
    {
        RenderTextureDescriptor cameraTargetDescriptor = renderingData.cameraData.cameraTargetDescriptor;
        currentPass.Setup(cameraTargetDescriptor);
        renderer.EnqueuePass(currentPass);
    }
}

多分動いてるはず... f:id:kaneta1011:20190630234549p:plain