opengl 如何在自定义通道中渲染基本游戏对象(Unity:ScriptableRenderPass)?

14ifxucb  于 2023-05-17  发布在  其他
关注(0)|答案(1)|浏览(204)

**我尝试做的是:**渲染特定图层的游戏对象(S)在我的自定义通道中渲染。我想做更多的事情后,但我只是想让它呈现完全一样的URP会现在。

我正在学习ScriptableRenderPass/ScriptableRendererFeature,所以我开始使用基本的。
我想要的是

我得到的是

这是我的pass的Execute看起来的样子:

public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
    {
        CommandBuffer cmd = CommandBufferPool.Get("EnemyClearDepthPass"); // Take this outside if you don't need this to change at all.

        foreach (var renderer in _associatedObjects)
        {
            if (renderer.isVisible)
            {
                cmd.DrawRenderer(renderer, renderer.sharedMaterial);
            }
        }

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

看起来它的旋转(因此,它的MVP矩阵)是正确的……但没有灯光我不知道第二个黑暗方块是什么。所以:

**选项#1)**找出我需要传递到命令缓冲区的命令,以便应用照明...解决黑暗方块的问题希望我开始画更复杂的着色器的时候就是这样。

但后来我有个想法:

**选项#2)**也许我可以使用ScriptableRenderContext.DrawRenderers(...)来绘制它,因为我认为它会更“开箱即用”。

这就是我得到的,无论我尝试用这种方法做什么:

(我知道我可以什么都不说……)但是......)
为了开始这种方法,我只是想做一个吸引一切的传球。但我可以让它画任何东西。为什么?

using System;
using UnityEngine.Rendering;
using UnityEngine.Rendering.Universal;
public class JustDrawSomethingPls : ScriptableRendererFeature
{
    // https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@12.1/manual/containers/create-custom-renderer-feature-1.html
    class DrawEverythingPass : ScriptableRenderPass
    {
        public DrawEverythingPass() { }

        public override void Execute(ScriptableRenderContext context, ref RenderingData renderingData)
        {
            CommandBuffer cmd = CommandBufferPool.Get("DrawEverythingPass");
            // https://docs.unity3d.com/ScriptReference/Rendering.DrawingSettings.html
            DrawingSettings drawingSettings = new DrawingSettings();
            drawingSettings.mainLightIndex = 0;
                SortingSettings sortingSettings = new SortingSettings();
                sortingSettings.criteria = SortingCriteria.None;
            drawingSettings.sortingSettings = sortingSettings;
            // https://docs.unity3d.com/ScriptReference/Rendering.FilteringSettings.html
            FilteringSettings filteringSettings = new FilteringSettings();
            filteringSettings.excludeMotionVectorObjects = false;
            filteringSettings.layerMask = int.MaxValue;
            filteringSettings.renderingLayerMask = uint.MaxValue;
            filteringSettings.renderQueueRange = new RenderQueueRange(0, 5000); // The upper bound must be at least 0 and at most 5000
            filteringSettings.sortingLayerRange = new SortingLayerRange(0, Int16.MaxValue);
            // https://docs.unity3d.com/ScriptReference/Rendering.RenderStateBlock.html
            RenderStateBlock renderStateBlock = new RenderStateBlock(RenderStateMask.Everything);

            context.DrawRenderers(renderingData.cullResults, ref drawingSettings, ref filteringSettings, ref renderStateBlock);

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

    private DrawEverythingPass _drawEverythingPass;
    public override void Create()
    {
        _drawEverythingPass = new DrawEverythingPass();
    }
    public override void AddRenderPasses(ScriptableRenderer renderer, ref RenderingData renderingData)
    {
        renderer.EnqueuePass(_drawEverythingPass);
    }
}
vi4fp9gy

vi4fp9gy1#

虽然我还没有完全实现我想通过命令缓冲区完成的任务,但一个很大的步骤就是不使用

cmd.DrawRenderer(renderer, renderer.sharedMaterial);

因为它将在彼此之上绘制所有着色器过程,而是使用特定的着色器过程(“myShaderPass”):

cmd.DrawRenderer(renderer, renderer.sharedMaterial, 0, myShaderPass);

这篇文章的主要问题是它在其他所有东西之上绘制阴影通行证。请注意,使亮起的着色器工作将比通过命令缓冲区使未亮起的着色器工作更多。

相关问题