参考的主要还是URP的代码,这里誊抄的主要目的是熟悉SRP的编写过程,最后完成一套框架。
参考地址:https://gitee.com/yichichunshui/srpframework.git
版本号:c33759e5a0b63024f3e81a9fd5a80486a202b8e1
本节是SRPFramework的第一节。
具体完成如下的任务:
1、实现SRPRenderPipeline入口类
2、实现render和pass的两个基类:ScriptRenderBase和RenderPassBase和子类:ForwardRender和DrawObjectPass
3、创建一个shader和材质球
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
using SRP;
public class SRPRenderPipeline : RenderPipeline
{
private ForwardRender m_forwardReneder;
public SRPRenderPipeline()
{
m_forwardReneder = new ForwardRender();
}
protected override void Render(ScriptableRenderContext context, Camera[] cameras)
{
for (int i = 0; i < cameras.Length; ++i)
{
RenderSingleCamera(context, cameras[i]);
}
}
private void RenderSingleCamera(ScriptableRenderContext context, Camera camera)
{
CameraData cameraData = new CameraData();
cameraData.m_camera = camera;
RenderData renderData = new RenderData();
renderData.m_cameraData = cameraData;
if (!camera.TryGetCullingParameters(out ScriptableCullingParameters cullingParameters))
{
return;
}
CullingResults cullingResults = context.Cull(ref cullingParameters);
renderData.m_cullingResults = cullingResults;
context.SetupCameraProperties(camera);
m_forwardReneder.Clear();
m_forwardReneder.Init(context, ref renderData);
m_forwardReneder.Execute(context, ref renderData);
context.Submit();
}
}
using SRP;
using System;
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEngine.Rendering;
public abstract class ScriptRenderBase
{
List<RenderPassBase> m_renderPasses = new List<RenderPassBase>(32);
public void AddPass(RenderPassBase pass)
{
m_renderPasses.Add(pass);
}
public void Clear()
{
m_renderPasses.Clear();
}
public abstract void Init(ScriptableRenderContext context, ref RenderData renderData);
public void Execute(ScriptableRenderContext context, ref RenderData renderData)
{
for (int i = 0; i < m_renderPasses.Count; ++i)
{
if (m_renderPasses[i] != null)
{
m_renderPasses[i].Execute(context, ref renderData);
}
}
}
}
using SRP;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using UnityEngine.Rendering;
public abstract class RenderPassBase
{
public abstract void Execute(ScriptableRenderContext context, ref RenderData renderData);
}
using System.Collections;
using System.Collections.Generic;
using SRP;
using UnityEngine;
using UnityEngine.Rendering;
public class ForwardRender : ScriptRenderBase
{
public DrawObjectPass m_drawObjectPass;
public DrawSkybox m_drawSkybox;
public ForwardRender()
{
m_drawObjectPass = new DrawObjectPass();
m_drawSkybox = new DrawSkybox();
}
public override void Init(ScriptableRenderContext context, ref RenderData renderData)
{
AddPass(m_drawObjectPass);
AddPass(m_drawSkybox);
}
}
using System.Collections;
using System.Collections.Generic;
using SRP;
using UnityEngine;
using UnityEngine.Rendering;
public class DrawObjectPass : RenderPassBase
{
private List<ShaderTagId> m_drawShaderIDs;
private FilteringSettings m_filterSettings;
private DrawingSettings m_drawSettings;
public DrawObjectPass()
{
m_drawShaderIDs = new List<ShaderTagId>();
m_drawShaderIDs.Add(new ShaderTagId("SRPRenderPipeline"));
//m_drawShaderIDs.Add(new ShaderTagId("SRPDefaultUnlit"));
LayerMask layerMask = -1;
m_filterSettings = new FilteringSettings(RenderQueueRange.opaque, layerMask);
}
public override void Execute(ScriptableRenderContext context, ref RenderData renderData)
{
SortingSettings sortingSettings = new SortingSettings(renderData.m_cameraData.m_camera) { criteria = SortingCriteria.CommonOpaque };
m_drawSettings = new DrawingSettings(m_drawShaderIDs[0], sortingSettings);
for (int i = 1; i < m_drawShaderIDs.Count; ++i)
{
m_drawSettings.SetShaderPassName(i, m_drawShaderIDs[i]);
}
context.DrawRenderers(renderData.m_cullingResults, ref m_drawSettings, ref m_filterSettings);
}
}
Shader "Unlit/Unlit"
{
Properties
{
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{
Tags { "RenderType"="Opaque" "LightMode"="SRPRenderPipeline"}
LOD 100
Pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "UnityCG.cginc"
struct appdata
{
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{
float2 uv : TEXCOORD0;
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{
return fixed4(1,0,0,1);
}
ENDCG
}
}
}