Unity SRP初识笔记

https://docs.unity3d.com/Manual/ScriptableRenderPipeline.html

可编程渲染管线(SRP)是Unity内置渲染管线的替代方法。

Unity提供了HDRP(高清渲染管线)URP(通用渲染管线)两种模板

  • 更自由灵活的自定义管线

    使用SRP,可以通过C#脚本控制和定制渲染 。 这样,您可以根据需要稍微修改或完全构建和自定义渲染管道。

与内置的Unity渲染管道相比,SRP提供了更多的粒度和自定义选项。 可以使用一种预先构建的SRP来满足您的特定需求。

  • 着色器不同

    使用SRP与使用内置的Unity渲染管道不同。 例如,预建的SRP使用自己的着色器库。 这是因为内置渲染管道中的Lit着色器和自定义Lit着色器不适用于SRP。 您可以将内置的Lit着色器升级到URP和HDRP。

LWRP 在Unity2019.3版本后已更名为Universal Render Pipleline,通用渲染管线。可在创建工程面板直接看到URP的工程模板

  • 安装

    Unity已构建了两个可编写脚本的渲染管道:高清晰度渲染管道(HDRP)和轻量级渲染管道(URP)。 每个渲染管道都针对一组特定的用例场景和硬件需求。 预构建的渲染管道可作为项目模板使用。
    URP项目模板包含了一个示例演示

注意:HDRP和URP彼此不兼容,因为它们使用不同的照明模型。 您的项目必须使用其中一个。 但是,您可以在同一渲染管道中使用不同的资源。 这意味着可以通过在不同资产之间交换来测试不同的设置,而不用更改各个设置。

两个关键元素:

使用SRP必须在工程中包含两个关键脚本

  • 渲染管线实例(Render Pipeline Instance)

    • 定义渲染管线的功能
    • 继承自 RenderPipeline,
    • 重写 Render() 函数
using UnityEngine;
using UnityEngine.Rendering;
    
public class ExampleRenderPipelineInstance : RenderPipeline
{
    // Use this variable to a reference to the Render Pipeline Asset that was passed to the constructor
    private ExampleRenderPipelineAsset renderPipelineAsset;
    
    // The constructor has an instance of the ExampleRenderPipelineAsset class as its parameter.
    public ExampleRenderPipelineInstance(ExampleRenderPipelineAsset asset) {
        renderPipelineAsset = asset;
    }
    
    protected override void Render(ScriptableRenderContext context, Camera[] cameras) {
        // This is an example of using the data from the Render Pipeline Asset.
        Debug.Log(renderPipelineAsset.exampleString);
            
        // This is where you can write custom rendering code. Customize this method to customize your SRP.
    }
}
  • 渲染管线配置资产 (Render Pipeline Asset)

    • 存储管线配置数据,并通过资产创建一个管线实例
    • 继承自 RenderPipelineAsset , 重写CreatePipeline() 函数
using UnityEngine;
using UnityEngine.Rendering;
    
// The CreateAssetMenu attribute lets you create instances of this class in the Unity Editor.
[CreateAssetMenu(menuName = "Rendering/ExampleRenderPipelineAsset")]
public class ExampleRenderPipelineAsset : RenderPipelineAsset
{
    // This data can be defined in the Inspector for each Render Pipeline Asset
    public Color exampleColor;
    public string exampleString;
    
        // Unity calls this method before rendering the first frame.
       // If a setting on the Render Pipeline Asset changes, Unity destroys the current Render Pipeline Instance and calls this method again before rendering the next frame.
    protected override RenderPipeline CreatePipeline() {
        // Instantiate the Render Pipeline that this custom SRP uses for rendering, and pass a reference to this Render Pipeline Asset.
        // The Render Pipeline Instance can then access the configuration data defined above.
        return new ExampleRenderPipelineInstance(this);
    }
}
  • 通过在工程图形设置里指定管线配置文件,来设置工程的渲染管线

    也可以在质量设置里对不同品质指定不同的管线配置文件

 

可编程渲染上下文 ScriptableRenderContext

using UnityEngine;
using UnityEngine.Rendering;

public class ExampleRenderPipeline : RenderPipeline
{
        public ExampleRenderPipeline() {
        }

    protected override void Render(ScriptableRenderContext context, Camera[] cameras) {
        // Create and schedule a command to clear the current render target
        var cmd = new CommandBuffer();
        cmd.ClearRenderTarget(true, true, Color.red);
        context.ExecuteCommandBuffer(cmd);
        cmd.Release();

         // Tell the Scriptable Render Context to tell the graphics API to perform the scheduled commands
        context.Submit();
    }
}

另一种执行渲染命令的方法是直接执行CommandBuffers: Graphics.ExecuteCommandBuffer

CommandBuffer文档


入口和回调

beginFrameRendering

beginCameraRendering

endCameraRendering

endFrameRendering

实例


默认内置管线


使用上面例子的管线后,可以看到只剩一个缓冲清理操作了。

 

渲染循环的构建

  • 1·清除渲染目标
 // Create and schedule a command to clear the current render target
        var cmd = new CommandBuffer();
        cmd.ClearRenderTarget(true, true, Color.black);
        context.ExecuteCommandBuffer(cmd);
        cmd.Release();

        // Instruct the graphics API to perform all scheduled commands
        context.Submit();
  • 2·剔除
foreach (Camera camera in cameras)
{
    // Get the culling parameters from the current Camera
    // 从相机中获取剔除参数
    camera.TryGetCullingParameters(out var cullingParameters);

    // Use the culling parameters to perform a cull operation, and store the results
    //使用剔除参数执行剔除,并保存结果
    var cullingResults = context.Cull(ref cullingParameters);
}

  • 3·绘制
    • 创建并设置过滤设置(FilteringSettings):过滤剔除结果
    • 创建并设置绘制设置(DrawingSettings):描述哪些几何体需要绘制已经绘制的方式
    • (可选)重写渲染状态设置
    • 调用 ScriptableRenderContext.DrawRenderers进行绘制
/* 
This is a simplified example of a custom Scriptable Render Pipeline.
It demonstrates how a basic render loop works.
It shows the clearest workflow, rather than the most efficient runtime performance.
*/

using UnityEngine;
using UnityEngine.Rendering;

public class ExampleRenderPipeline : RenderPipeline {
    public ExampleRenderPipeline() {
    }

    protected override void Render (ScriptableRenderContext context, Camera[] cameras) {
        // 清理渲染目标
        var cmd = new CommandBuffer();
        cmd.ClearRenderTarget(true, true, Color.black);
        context.ExecuteCommandBuffer(cmd);
        //释放CommandBuffer
        cmd.Release();

        // 遍历所有相机
        foreach (Camera camera in cameras)
        {
            //从相机中获取剔除参数
            camera.TryGetCullingParameters(out var cullingParameters);

            // 使用剔除参数执行剔除操作,并保存结果
            var cullingResults = context.Cull(ref cullingParameters);

            // Update the value of built-in shader variables, based on the current Camera
            // 用相机更新shader内置变量
            context.SetupCameraProperties(camera);

            // Tell Unity which geometry to draw, based on its LightMode Pass tag value
            // 创建ShaderTagId,告诉Unity要绘制的几何体:基于LightMode设置
            ShaderTagId shaderTagId = new ShaderTagId("ExampleLightModeTag");

            // Tell Unity how to sort the geometry, based on the current Camera
            // 创建排序设置,基于相机
            var sortingSettings = new SortingSettings(camera);

            // Create a DrawingSettings struct that describes which geometry to draw and how to draw it
            // 使用ShaderTagId和排序设置构建DrawingSettings
            DrawingSettings drawingSettings = new DrawingSettings(shaderTagId, sortingSettings);

            // Tell Unity how to filter the culling results, to further specify which geometry to draw
            // Use FilteringSettings.defaultValue to specify no filtering
            // 剔除结果的过滤设置
            FilteringSettings filteringSettings = FilteringSettings.defaultValue;
        
            // Schedule a command to draw the geometry, based on the settings you have defined
            //组织渲染命令进行绘制
            context.DrawRenderers(cullingResults, ref drawingSettings, ref filteringSettings);

            // Schedule a command to draw the Skybox if required
            // 绘制天空盒(如果需要)
            if (camera.clearFlags == CameraClearFlags.Skybox && RenderSettings.skybox != null)
            {
                context.DrawSkybox(camera);
            }

            // Instruct the graphics API to perform all scheduled commands
            context.Submit();
        }
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值