Unity3D SRP 学习笔记

自定义SRP

  • 自定义RenderPipelineAsset:
    作用:自定义SRP配置文件,可以创建、配置管线和管线参数。
public class MyRenderPipelineAsset : RenderPipelineAsset
{
	//创建自定义SRP。
    protected override RenderPipeline CreatePipeline()
    {
        return new MyRenderPipeline(this);
    }

#if UNITY_EDITOR
	//创建管线配置文件。
    public static MyRenderPipelineAsset Create()
    {
        return = CreateInstance<MyRenderPipelineAsset>();
    }

	//创建管线配置文件。
    [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1812")]
    internal class CreateMyPipelineAsset : EndNameEditAction
    {
        public override void Action(int instanceId, string pathName, string resourceFile)
        {
            AssetDatabase.CreateAsset(Create(), pathName);
        }
    }
	
	//创建管线配置文件。
    [MenuItem("Assets/Create/Rendering/My Render Pipeline/Pipeline Asset", priority = CoreUtils.assetCreateMenuPriority1)]
    static void CreateLightweightPipeline()
    {
        ProjectWindowUtil.StartNameEditingIfProjectWindowExists(0, CreateInstance<CreateMyPipelineAsset>(), "MyRenderPiplineAsset.asset", null, null);
    }
#endif
}
  • 自定义RenderPipeline:
    作用:负责渲染场景
public class MyRenderPipeline : RenderPipeline
{
    public MyRenderPipeline(MyRenderPipelineAsset asset)
    {}
    
	//每一帧渲染都会调用一次这个函数进行具体渲染。
    protected override void Render(ScriptableRenderContext context, Camera[] cameras)
    {
        BeginFrameRendering(cameras);
        CommandBuffer commandBuffer = CommandBufferPool.Get();
        foreach (var camera in cameras)
        {
        	//将camera中的一些参数传递给Shader的全局变量。
            context.SetupCameraProperties(camera);

            BeginCameraRendering(camera);

            ScriptableCullingParameters cullingParameters;
            camera.TryGetCullingParameters(out cullingParameters);
            var cullingResults = context.Cull(ref cullingParameters);

			//设置(渲染到摄像机)并清理渲染目标。
            commandBuffer.SetRenderTarget(BuiltinRenderTextureType.CameraTarget);
            commandBuffer.ClearRenderTarget(true, true, new Color(0, 0, 0));

            context.ExecuteCommandBuffer(commandBuffer);
            commandBuffer.Clear();

            var drawingSettings = new DrawingSettings(new ShaderTagId("MyPass"), new  SortingSettings(camera));
            var filteringSettings = FilteringSettings.defaultValue;
            context.DrawRenderers(cullingResults, ref drawingSettings, ref filteringSettings);

            context.DrawSkybox(camera);

            ScriptableRenderContext.EmitWorldGeometryForSceneView(camera);

            EndCameraRendering(context, camera);
        }

		//提交渲染命令。
        context.Submit();
        CommandBufferPool.Release(commandBuffer);

        EndFrameRendering(context, cameras);
    }
}

  • 重要的数据结构:
//渲染设置
struct DrawingSettings{
	bool enableDynamicBatching;//是否动态渲染。
	bool enableInstancing;//是否实例渲染。
	int mainLightIndex;//配置哪个灯光作为主光源。
	Material overrideMaterial;//	Sets the Material to use for all drawers that would render in this group.
	int overrideMaterialPassIndex;//	Selects which pass of the override material to use.
	PerObjectData perObjectData;//在渲染时给每个物体设置的参数(系统内置参数)。
	SortingSettings	sortingSettings;//在渲染时如何排序物体。
}

//这些参数可以叠加
enum PerObjectData{
	None,//Do not setup any particular per-object data besides the transformation matrix.
	LightProbe,//Setup per-object light probe SH data.
	ReflectionProbes,//Setup per-object reflection probe data.
	LightProbeProxyVolume,//Setup per-object light probe proxy volume data.
	Lightmaps,//Setup per-object lightmaps.
	LightData,//Setup per-object light data.
	MotionVectors,//Setup per-object motion vectors.
	LightIndices,//Setup per-object light indices.
	ReflectionProbeData,//Setup per-object reflection probe index offset and count.
	OcclusionProbe,//Setup per-object occlusion probe data.
	OcclusionProbeProxyVolume,//Setup per-object occlusion probe proxy volume data (occlusion in alpha channels).
	ShadowMask,//Setup per-object shadowmask.
}

//排序设置
struct SortingSettings{
	Vector3 cameraPosition;//Used to calculate the distance to objects.
	SortingCriteria criteria;//What kind of sorting to do while rendering.
	Vector3 customAxis;//Used to calculate distance to objects, by comparing the positions of objects to this axis.
	DistanceMetric distanceMetric;//Type of sorting to use while rendering.
	Matrix4x4 worldToCameraMatrix;//Used to calculate the distance to objects.
}

//排序方式
enum SortingCriteria{
	None,//不排序。
	SortingLayer,//Sort by renderer sorting layer.
	RenderQueue,//按照材质渲染队列排序。
	BackToFront,//从后到钱排序。
	QuantizedFrontToBack,//Sort objects in rough front-to-back buckets.
	OptimizeStateChanges,//对物体排序来减少渲染状态的更改。
	CanvasOrder,//根据画布顺序对物体排序。
	RendererPriority,//根据物体优先级排序。
	CommonOpaque,//不透明物体经典排序。
	CommonTransparent,//透明物体经典排序。
}

//排序方式
enum DistanceMetric{
	Perspective,//沿着相机位置到物体中心点的距离排序。
	Orthographic,//根据沿相机视图方向的距离进行排序。
	CustomAxis,//沿着自定义方向排序(相机空间)。
}

//过滤模式
struct FilterSettings{
	bool excludeMotionVectorObjects,//Set to true to exclude objects that are currently in motion from rendering. The default value is false.
	int layerMask,//Only render objects in the given layer mask.
	int renderingLayerMask,//The rendering layer mask to use when filtering available renderers for drawing.
	RenderQueueRange renderQueueRange,//Render objects whose material render queue in inside this range.
	SortingLayerRange sortingLayerRange,//Render objects whose sorting layer is inside this range.
}
  • Shader:
    配合自定义SRP。
Shader "Custom/MyShader"{
    Properties {}
    
    SubShader {
		Tags { "RenderType" = "Opaque" }

		Pass{
			Tags { "LightMode"="MyPass" }

			HLSLPROGRAM

			#pragma vertex VertexMain
			#pragma fragment FragmentMain

			#include "Packages/com.unity.render-pipelines.lightweight/ShaderLibrary/Core.hlsl"
			
			struct VertexInput {
				float4 position : POSITION;
			};

			struct VertexOut {
				float4 position : SV_POSITION;
			};

			VertexOut VertexMain(VertexInput input) {
				VertexOut vertexOut;
				vertexOut.position = TransformObjectToHClip(input.position.xyz);
				return vertexOut;
			}

			float4 FragmentMain() : SV_TARGET{
				return float4(1,0,0,1);
			}

			ENDHLSL
		}
    }
}
  • Shader中的矩阵变换:
    都在Core RP Library/ShaderLibrary/SpaceTransform.hlsl中定义
float4x4 GetObjectToWorldMatrix() UNITY_MATRIX_M 世界矩阵
float4x4 GetWorldToObjectMatrix() UNITY_MATRIX_I_M 世界逆矩阵
float4x4 GetWorldToViewMatrix() UNITY_MATRIX_V 视角矩阵
float4x4 GetWorldToHClipMatrix() UNITY_MATRIX_VP 视角投影矩阵
float4x4 GetViewToHClipMatrix() UNITY_MATRIX_P 投影矩阵
float4x4 GetOddNegativeScale() unity_WorldTransformParams.w
float4x4 TransformObjectToWorld(float3 positionOS) 本地到世界
float3 TransformWorldToObject(float3 positionWS) 世界到本地
float3 TransformWorldToView(float3 positionWS) 世界到视角
float4 TransformObjectToHClip(float3 positionOS) 本地到投影
float4 TransformWorldToHClip(float3 positionWS) 世界到投影
float4 TransformWViewToHClip(float3 positionVS) 视角到投影
real3 TransformObjectToWorldDir(real3 dirOS)
real3 TransformWorldToObjectDir(real3 dirWS)
real3 TransformWorldToViewDir(real3 dirWS)
real3 TransformWorldToHClipDir(real3 directionWS)
float3 TransformObjectToWorldNormal(float3 normalOS)
real3x3 CreateTangentToWorld(real3 normal, real3 tangent, real flipSign)
real3 TransformTangentToWorld(real3 dirTS, real3x3 tangentToWorld)
real3 TransformWorldToTangent(real3 dirWS, real3x3 tangentToWorld)
real3 TransformTangentToObject(real3 dirTS, real3x3 tangentToWorld)
real3 TransformObjectToTangent(real3 dirOS, real3x3 tangentToWorld)
发布了41 篇原创文章 · 获赞 4 · 访问量 3899

猜你喜欢

转载自blog.csdn.net/weixin_42487874/article/details/103199213