自定义渲染管线
前置工作
- 在PlayerSetting中奖颜色空间Color Space由Gamma空间换成Linear线性空间
- 在Window->PackageManager中安装Core RP Library包。这个包由Unity封装了底层C++渲染接口,还包含一些着色器文件,后面会依赖这个包做拓展功能。
创建管线资产和实例
using UnityEngine;
using UnityEngine.Rendering;
[CreateAssetMenu(menuName = "Rendering/CreateCustomRenderPipeline")]
public class CustomRenderPipelineAsset : RenderPipelineAsset
{
protected override RenderPipeline CreatePipeline()
{
return new CustomRenderPipeline();
}
}
using UnityEngine;
using UnityEngine.Rendering;
public class CustomRenderPipeline : RenderPipeline
{
protected override void Render(ScriptableRenderContext context, Camera[] cameras)
{
}
}
因为替换了新的渲染管线,而新的管线啥也没做,所以Game视图和Scene视图都是黑色的。
using UnityEngine;
using UnityEngine.Rendering;
public partial class CameraRenderer
{
private ScriptableRenderContext renderContext;
private Camera camera;
const string bufferName = "Render Camera CCC";
CommandBuffer buffer = new CommandBuffer
{
name = bufferName
};
// 存储剔除后的结果数据
CullingResults cullingResults;
public void Render(ScriptableRenderContext _renderContext, Camera _cam)
{
this.renderContext = _renderContext;
this.camera = _cam;
//设置命令缓冲区的名字
PrepareBuffer();
//在Game视图绘制的几何体也绘制到Scene视图中
PrepareForSceneWindow();
if (!Cull())
{
return;
}
Setup();
DrawVisibleGeometry();
//绘制SRP不支持的着色器类型
DrawUnsupportedShaders();
DrawGizmos();
Submit();
}
static ShaderTagId unlitShaderTagId = new ShaderTagId("SRPDefaultUnlit");
// 绘制可见物体 绘制顺序须遵循 不透明物体->绘制天空盒->透明物体(减少天空盒绘制像素的数量,透明物体不会进行深度测试)
private void DrawVisibleGeometry()
{
// 设置绘制顺序和指定渲染相机
var sortingSettings = new SortingSettings(camera)
{
criteria = SortingCriteria.CommonOpaque
};
//绘制几何体
var drawingSettings = new DrawingSettings(unlitShaderTagId, sortingSettings);
//设置哪些类型的渲染队列可以被绘制
var filteringSettings = new FilteringSettings(RenderQueueRange.opaque);
//1.绘制不透明物体
renderContext.DrawRenderers(cullingResults, ref drawingSettings, ref filteringSettings);
//2.绘制天空盒
renderContext.DrawSkybox(camera);
sortingSettings.criteria = SortingCriteria.CommonTransparent;
drawingSettings.sortingSettings = sortingSettings;
//只绘制RenderQueue为transparent透明的物体
filteringSettings.renderQueueRange = RenderQueueRange.transparent;
//3.绘制透明物体
renderContext.DrawRenderers(cullingResults, ref drawingSettings, ref filteringSettings);
}
// 提交缓冲区渲染命令
private void Submit()
{
buffer.EndSample(SampleName);
ExecuteBuffer();
renderContext.Submit();
}
// 设置相机矩阵
private void Setup()
{
renderContext.SetupCameraProperties(camera);
// 得到相机的clear flags
CameraClearFlags flags = camera.clearFlags;
buffer.ClearRenderTarget(flags <= CameraClearFlags.Depth, flags == CameraClearFlags.Color, flags == CameraClearFlags.Color ? camera.backgroundColor.linear : Color.clear);
buffer.BeginSample(SampleName);
ExecuteBuffer();
}
// 执行并清空缓冲区命令
private void ExecuteBuffer()
{
renderContext.ExecuteCommandBuffer(buffer);
buffer.Clear();
}
// 剔除
private bool Cull()
{
ScriptableCullingParameters p;
if (camera.TryGetCullingParameters(out p))
{
cullingResults = renderContext.Cull(ref p);
return true;
}
return false;
}
}
using UnityEngine;
using UnityEditor;
using UnityEngine.Rendering;
using UnityEngine.Profiling;
public partial class CameraRenderer
{
partial void DrawUnsupportedShaders();
partial void DrawGizmos();
partial void PrepareForSceneWindow();
partial void PrepareBuffer();
#if UNITY_EDITOR
//SRP不支持的着色器标签类型
static ShaderTagId[] legacyShaderTagIds =
{
new ShaderTagId("Always"),
new ShaderTagId("ForwardBase"),
new ShaderTagId("PrepassBase"),
new ShaderTagId("Vertex"),
new ShaderTagId("VertexLMRGBM"),
new ShaderTagId("VertexLM")
};
//绘制成使用错误材质的粉红颜色
static Material errorMaterial;
// 绘制SRP不支持的着色器类型
partial void DrawUnsupportedShaders()
{
if (errorMaterial == null)
{
errorMaterial = new Material(Shader.Find("Hidden/InternalErrorShader"));
}
//数组第一个元素用来构造DrawingSeting对象的时候设置
var drawingSettings = new DrawingSettings(legacyShaderTagIds[0], new SortingSettings(camera))
{
overrideMaterial = errorMaterial
};
for (int i = 1; i < legacyShaderTagIds.Length; i++)
{
//遍历数组逐个设置着色器的PassName,从i=1开始
drawingSettings.SetShaderPassName(i, legacyShaderTagIds[i]);
}
var filteringSettings = FilteringSettings.defaultValue;
//绘制不支持的ShaderTag类型的物体
renderContext.DrawRenderers(cullingResults, ref drawingSettings, ref filteringSettings);
}
//绘制Gizmos
partial void DrawGizmos()
{
if (Handles.ShouldRenderGizmos())
{
renderContext.DrawGizmos(camera, GizmoSubset.PreImageEffects);
renderContext.DrawGizmos(camera, GizmoSubset.PostImageEffects);
}
}
partial void PrepareForSceneWindow()
{
if (camera.cameraType == CameraType.SceneView)
{
//如果切换到Scene视图,调用此方法完成绘制
ScriptableRenderContext.EmitWorldGeometryForSceneView(camera);
}
}
string SampleName { get; set; }
partial void PrepareBuffer()
{
Profiler.BeginSample("Editor Only");
SampleName = camera.name;
buffer.name = SampleName;
Profiler.EndSample();
}
#else
const string SampleName = bufferName;
#endif
}
(未完待续)