Version: 2020.3
커스텀 렌더 파이프라인에서 렌더 파이프라인 에셋과 렌더 파이프라인 인스턴스 생성
카메라

커스텀 렌더 파이프라인에서 단순한 렌더 루프 생성

렌더 루프는 단일 프레임에서 발생하는 모든 렌더링 작업을 지칭하는 용어입니다. 이 페이지에서는 Unity의 스크립터블 렌더 파이프라인에 기반한 커스텀 렌더 파이프라인에서 간단한 렌더 루프를 만드는 방법에 대해 설명합니다.

이 페이지의 코드 예제는 스크립터블 렌더 파이프라인 사용의 기본 원칙을 보여줍니다. 이 정보를 사용하여 커스텀 스크립터블 렌더 파이프라인을 빌드하거나 Unity의 사전 빌드된 스크립터블 렌더 파이프라인이 작동하는 방식을 이해할 수 있습니다.

프로젝트 준비

렌더 루프용 코드를 작성하려면 먼저 프로젝트를 준비해야 합니다.

이를 위한 단계는 다음과 같습니다.

  1. Create an SRP-compatible shader.
  2. 렌더링할 게임 오브젝트를 하나 이상 생성합니다.
  3. 커스텀 SRP의 기본 구조를 생성합니다.
  4. Optional: If you plan to extend your simple custom SRP to add more complex functionality, install the SRP Core package. The SRP Core package includes the SRP Core shader library (which you can use to make your shaders SRP Batcher compatible), and utility functions for common operations. For more information, see the SRP Core package documentation.

Creating an SRP-compatible shader

In the Scriptable Render Pipeline, you use the LightMode Pass tag to determine how to draw geometry. For more information on Pass tags, see ShaderLab: assigning tags to a Pass.

This task shows you how to create a very simple unlit Shader object with a LightMode Pass tag value of ExampleLightModeTag.

  1. Create a new shader asset in your project. For instructions on creating a shader asset, see Shader assets.
  2. In your Project view, double click the shader asset to open the shader source code in a text editor.
  3. Replace the existing code with the following:
// This defines a simple unlit Shader object that is compatible with a custom Scriptable Render Pipeline.
// It applies a hardcoded color, and demonstrates the use of the LightMode Pass tag.
// It is not compatible with SRP Batcher.

Shader "Examples/SimpleUnlitColor"
{
    SubShader
    {
        Pass
        {
            // The value of the LightMode Pass tag must match the ShaderTagId in ScriptableRenderContext.DrawRenderers
            Tags { "LightMode" = "ExampleLightModeTag"}

            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag

    float4x4 unity_MatrixVP;
            float4x4 unity_ObjectToWorld;

            struct Attributes
            {
                float4 positionOS   : POSITION;
            };

            struct Varyings
            {
                float4 positionCS : SV_POSITION;
            };

            Varyings vert (Attributes IN)
            {
                Varyings OUT;
                float4 worldPos = mul(unity_ObjectToWorld, IN.positionOS);
                OUT.positionCS = mul(unity_MatrixVP, worldPos);
                return OUT;
            }

            float4 frag (Varyings IN) : SV_TARGET
            {
                return float4(0.5,1,0.5,1);
            }
            ENDHLSL
        }
    }
}

렌더링할 게임 오브젝트 생성

To test that your render loop works, you must create something to render. This task shows you how to put GameObjects in your scene that use the SRP-compatible shader that you created in the previous task.

  1. Create a new material asset in your Unity project. For instructions see Materials.
  2. Assign the shader asset to the material asset. For instructions, see Materials.
  3. Create a cube in your scene. For instructions, see Primitive objects.
  4. Assign the material to it. For instructions, see Materials.

커스텀 SRP의 기본 구조 생성

준비의 마지막 단계는 커스텀 SRP에 필요한 기본 소스 파일을 생성하고, 커스텀 SRP를 사용하여 렌더링을 시작하도록 Unity에 지시하는 것입니다.

  1. 렌더 파이프라인 인스턴스와 렌더 파이프라인 에셋 생성의 지침에 따라 RenderPipeline과 호환 가능 렌더 파이프라인 에셋에서 상속되는 클래스를 생성합니다.
  2. 활성 렌더 파이프라인 에셋 설정의 지침에 따라 활성 렌더 파이프라인 에셋을 생성합니다. Unity는 커스텀 SRP를 사용하여 즉시 렌더링을 시작합니다. 즉 커스텀 SRP에 코드를 추가하기 전까지 씬 뷰와 게임 뷰는 비어 있습니다.

렌더 루프 생성

렌더 루프에서 기본 작업은 다음과 같습니다.

  • 렌더 타겟 지우기 - 마지막 프레임 동안 그린 지오메트리를 제거합니다.
  • 컬링 - 카메라에 보이지 않는 지오메트리를 필터링합니다.
  • 그리기 - 그리려는 지오메트리와 그리는 방법을 GPU에 알립니다.

렌더 타겟 지우기

지우기는 마지막 프레임 동안 그린 대상을 지우는 작업을 의미합니다. 렌더 타겟은 대개 화면입니다. 하지만 텍스처로 렌더링하여 “화면 속 화면(PIP)” 효과를 구현할 수도 있습니다. 이 예제는 화면에 렌더링하는 방법(Unity의 기본 동작)을 보여줍니다.

스크립터블 렌더 파이프라인에서 렌더 타겟을 지우려면 다음 단계를 따르십시오.

  1. Clear 커맨드를 사용하여 CommandBuffer를 설정합니다.
  2. ScriptableRenderContext의 커맨드 대기열에 CommandBuffer를 추가합니다. 이렇게 하려면 ScriptableRenderContext.ExecuteCommandBuffer를 호출합니다.
  3. ScriptableRenderContext의 커맨드 대기열을 수행하도록 그래픽스 API에 지시합니다. 이렇게 하려면 ScriptableRenderContext.Submit를 호출하십시오.

다른 모든 스크립터블 렌더 파이프라인 작업과 마찬가지로, RenderPipeline.Render 메서드를 이 코드의 엔트리 포인트로 사용합니다. 다음 예제 코드는 이를 수행하는 방법을 보여줍니다.

/* 
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) {
        // 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();
    }
}

컬링

컬링은 카메라에 보이지 않는 지오메트리를 필터링하는 프로세스입니다.

스크립터블 렌더 파이프라인에서 컬링을 수행하려면 다음 단계를 따르십시오.

  1. ScriptableCullingParameters 구조체를 카메라에 대한 데이터로 채웁니다. 이렇게 하려면 Camera.TryGetCullingParameters를 호출하십시오.
  2. 선택 사항: ScriptableCullingParameters 구조체의 값을 수동으로 업데이트합니다.
  3. ScriptableRenderContext.Cull을 호출하고, 그 결과를 CullingResults 구조체에 저장합니다.

다음 예제 코드는 위 예제 코드의 확장으로, 렌더 타겟을 지운 후 컬링 작업을 수행하는 방법을 보여줍니다.

/* 
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) {
        // 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();

        // Iterate over all Cameras
        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);
        }

        // Instruct the graphics API to perform all scheduled commands
        context.Submit();
    }
}

그리기

그리기는 특정 설정으로 특정 지오메트리 집합을 그리도록 그래픽스 API에 지시하는 프로세스입니다.

SRP에서 그리기를 수행하려면 다음 단계를 따르십시오.

  1. 위 설명대로 컬링 작업을 수행하고 그 결과를 CullingResults 구조체에 저장합니다.
  2. FilteringSettings 구조체를 생성하고 설정합니다. 이 구조체는 컬링 결과를 필터링하는 방법을 설명합니다.
  3. DrawingSettings 구조체를 생성하고 설정합니다. 이 구조체는 그리려는 지오메트리와 그리는 방법을 설명합니다.
  4. Optional: By default, Unity sets the render state based on the Shader object. If you want to override the render state for some or all of the geometry that you are about to draw, you can use a RenderStateBlock struct to do this.
  5. ScriptableRenderContext.DrawRenderers를 호출하고 파라미터로 생성한 구조체를 전달합니다. Unity는 해당 설정에 따라 필터링된 지오메트리 집합을 그립니다.

다음 예제 코드는 위 예제 코드의 확장으로, 렌더 타겟을 지우고 컬링 작업을 수행한 후 결과 지오메트리를 그리는 방법을 보여줍니다.

/* 
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) {
        // 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();

        // Iterate over all Cameras
        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);

            // Update the value of built-in shader variables, based on the current Camera
            context.SetupCameraProperties(camera);

            // Tell Unity which geometry to draw, based on its LightMode Pass tag value
            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
            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();
        }
    }
}
커스텀 렌더 파이프라인에서 렌더 파이프라인 에셋과 렌더 파이프라인 인스턴스 생성
카메라
Copyright © 2023 Unity Technologies
优美缔软件(上海)有限公司 版权所有
"Unity"、Unity 徽标及其他 Unity 商标是 Unity Technologies 或其附属机构在美国及其他地区的商标或注册商标。其他名称或品牌是其各自所有者的商标。
公安部备案号:
31010902002961