TA志望学生の備忘録

テクニカルアーティストを志望する学生の備忘録

SRP作成(1)

SRPとは

SRP(Scriptable Render Pipeline)

Unityのc#を使用してレンダリングの制御ができる機能です。

スクリプタブルレンダーパイプラインの基礎 - Unity マニュアル

URPとHDRPもSRPの一種のようです。

カスタムSRPを利用するには、描画用のインスタンスレンダリングパイプラインアセットを作成し、Project Settingで適用する必要があるようです。

docs.unity3d.com

こちらを参考にインスタンスレンダリングパイプラインアセットを作成します。

SRP作成

 

using UnityEngine;
using UnityEngine.Rendering;

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

    protected override void Render (ScriptableRenderContext context, Camera cameras) {
     
    }
}

こちらがレンダリングパイプラインアセットの中身になるコードです。

現在は何も処理を入れていません。このままでは使えないのでいったんアセット化できるようにします。

 

using UnityEngine;
using UnityEngine.Rendering;

// レンダリングパイプラインアセットの作成
[CreateAssetMenu(menuName = "Rendering/ExampleRenderPipelineAsset")]
public class ExampleRenderPipelineAsset : RenderPipelineAsset
{
    protected override RenderPipeline CreatePipeline() {
 
        return new ExampleRenderPipelineInstance();
    }
}

これでProjectWindowから右クリック/作成/レンダリングにExampleRenderPipelineAssetが表示されるようになり、アセットの作成が可能になりました。

 

一度このまま適用してみます。

ProjectSettingから品質の中にあるレンダーパイプラインアセットを作成したものに変更します。

シーンビューに何も表示されなくなったら成功です。

 

オブジェクトも一切描画されませんし、スカイボックスなども表示されなくなりました。

中身を書いていないので正しい状態です。

ここから処理を書いて描画できるようにしていきます。

 

中身の作成

ここからは以下を参考に進みます。

learning.unity3d.jp

 

using UnityEngine;
using UnityEngine.Rendering;

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


    //描画処理
    protected override void Render (ScriptableRenderContext context, Camera cameras) {

        //カメラごとに処理
        foreach ( var camera in cameras) //foreach (型 変数名 in コレクション)
        {
            //カメラプロパティ
            context.SetupCameraProperties( camera );

            //カリング設定
            CullingResults          cullingResults = new CullingResults();
            ScriptableCullingParameters cullingParameters;
            if ( !camera.TryGetCullingParameters( false, out cullingParameters ))continue;
            cullingResults = context.Cull( ref cullingParameters );

            //フィルタリング、ソート
            SortingSettings sortingSettings = new SortingSettings( camera ) { criteria = SortingCriteria.CommonOpaque };
            var settings  = new DrawingSettings( new ShaderTagId( "IdDeferred" ), sortingSettings);
            var filterSettings = new FilteringSettings(
                                    new RenderQueueRange( 0,(int)RenderQueue.GeometryLast ),
                                    camera.cullingMask
                                );
           
            //描画処理
            context.DrawRenderers( cullingResults, ref settings, ref filterSettings );

        }
        context.Submit();
    }    
}

カメラは一つずつ呼び出して、処理を行いそれをforeachでカメラの数だけ実行していますね。

 

カリングやフィルタリングのあたりは現状よくわからないです。

ScriptableRenderContextは以下の公式ドキュメントを参照して記述できそうですね。

Unity - Scripting API: ScriptableRenderContext

 

いったんこれでUnity側を確認してみます。

グリッドが表示されるようになりました。

オブジェクトは専用のシェーダーを記述する必要があるので、次回にやります。

最後にスカイボックスの描画までやって今回は終わりにします。

 

catlikecoding.com

ここからはこちらの記事を参考に進みます。

スカイボックスはScriptableRenderContextのDrawSkyboxで描画できるようなので、書き加えていきます。

using UnityEngine;
using UnityEngine.Rendering;

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


    //描画処理
    protected override void Render (ScriptableRenderContext context, Camera[] cameras) {

        //カメラごとに処理
        foreach ( var camera in cameras) //foreach (型 変数名 in コレクション)
        {
            //カメラプロパティ
            context.SetupCameraProperties( camera );

            //カリング設定
            CullingResults          cullingResults = new CullingResults();
            ScriptableCullingParameters cullingParameters;
            if ( !camera.TryGetCullingParameters( false, out cullingParameters ))continue;
            cullingResults = context.Cull( ref cullingParameters );

            //フィルタリング、ソート
            SortingSettings sortingSettings = new SortingSettings( camera ) { criteria = SortingCriteria.CommonOpaque };
            var settings  = new DrawingSettings( new ShaderTagId( "IdDeferred" ), sortingSettings);
            var filterSettings = new FilteringSettings(
                                    new RenderQueueRange( 0,(int)RenderQueue.GeometryLast ),
                                    camera.cullingMask
                                );
           
            //描画処理
            context.DrawRenderers( cullingResults, ref settings, ref filterSettings );

            context.DrawSkybox(camera);

            context.SetupCameraProperties(camera);
        }
        context.Submit();
    }    
}

DrawSkyboxとSetUpCameraPropertiesを書き加えました。

SetUpCameraPropertiesはシーンを正しくレンダリングするため、カメラのプロパティをコンテキストに適用するために必要らしいです。

これでUnityを確認するとSkyBoxが描画されているはず。

 

いけました。

今回はここまでにします。

次はもう少し詳しいことやシェーダーを作成してオブジェクトを描画などを目標に進みます。

 

c#レンダリングあたりのことを同時に勉強しているのでなかなか大変ですね。

 


あとがき

CEDEC+KYUSYUに行ったりしていたので更新が遅くなりました。。。

UEFESTとかにも目を通していて、いろいろやりたいことが蓄積中です。

もう少し形になったものができたらgithubなんかも活用していきたいです。