才发现源码,自行参考:原文链接
总结:
0.可编程渲染管线的设置及流程。
1.物体渲染顺序:不透明物体(从前往后)->天空盒->透明物体(从后往前)->UI(overlay)。
2.分部类和分部方法的使用,包括没有声明分部方法打包不了的解决方法。
3.多相机渲染:根据depth值从小到大渲染(内部遵循物体的渲染顺序),最后进行混合。
代码记录:
代码:
渲染管线资源:
using UnityEngine;
using UnityEngine.Rendering;
[CreateAssetMenu(menuName ="Rendering/Custom Render Pipeline")]
public class CustomRenderPipelineAsset : RenderPipelineAsset
{
protected override RenderPipeline CreatePipeline()
{
return new CustomRenderPipeline();
}
}
渲染管线
using UnityEngine;
using UnityEngine.Rendering;
public class CustomRenderPipeline : RenderPipeline
{
CameraRender renderer = new CameraRender();
protected override void Render(ScriptableRenderContext context, Camera[] cameras)
{
foreach (Camera camera in cameras)
{
renderer.Render(context, camera);
}
}
}
渲染器:
using UnityEngine;
using UnityEngine.Rendering;
public partial class CameraRender
{
private ScriptableRenderContext context;
private Camera camera;
private const string bufferName = "Render Camera";
private CommandBuffer buffer = new CommandBuffer()
{
name = bufferName
};
private CullingResults cullingResults;
private static ShaderTagId unlitShaderTagId = new ShaderTagId("SRPDefaultUnlit");
public void Render(ScriptableRenderContext context, Camera camera)
{
this.context = context;
this.camera = camera;
PrepareBuffer();
PrepareForSceneWindow();
if (!Cull())
{
return;
}
Setup();
DrawVisibleGeometry();
DrawUnsupportedShaders();
DrawGizmos();
Submit();
}
private void Setup()
{
context.SetupCameraProperties(camera);
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 DrawVisibleGeometry()
{
SortingSettings sortingSettings = new SortingSettings(camera)
{
criteria = SortingCriteria.CommonOpaque
};
DrawingSettings drawingSettings = new DrawingSettings(unlitShaderTagId, sortingSettings);
FilteringSettings filteringSettings = new FilteringSettings(RenderQueueRange.opaque);
context.DrawRenderers(cullingResults, ref drawingSettings, ref filteringSettings);
context.DrawSkybox(camera);
sortingSettings = new SortingSettings(camera)
{
criteria = SortingCriteria.CommonTransparent
};
drawingSettings = new DrawingSettings(unlitShaderTagId, sortingSettings);
filteringSettings = new FilteringSettings(RenderQueueRange.transparent);
context.DrawRenderers(cullingResults, ref drawingSettings, ref filteringSettings);
}
private void Submit()
{
buffer.EndSample(SampleName);
ExecuteBuffer();
context.Submit();
}
private void ExecuteBuffer()
{
context.ExecuteCommandBuffer(buffer);
buffer.Clear();
}
private bool Cull()
{
if (camera.TryGetCullingParameters(out ScriptableCullingParameters p))
{
cullingResults = context.Cull(ref p);
return true;
}
return false;
}
}
渲染器编辑器代码:
using UnityEditor;
using UnityEngine;
using UnityEngine.Profiling;
using UnityEngine.Rendering;
public partial class CameraRender
{
partial void DrawUnsupportedShaders();
partial void DrawGizmos();
partial void PrepareForSceneWindow();
partial void PrepareBuffer();
#if UNITY_EDITOR
private static ShaderTagId[] legacyShaderTagIds = {
new ShaderTagId("Always"),
new ShaderTagId("ForwardBase"),
new ShaderTagId("PrepassBase"),
new ShaderTagId("Vertex"),
new ShaderTagId("VertexLMRGBM"),
new ShaderTagId("VertexLM")
};
private static Material errorMaterial;
private string SampleName { get; set; }
partial void DrawUnsupportedShaders()
{
if (errorMaterial == null)
{
errorMaterial = new Material(Shader.Find("Hidden/InternalErrorShader"));
}
DrawingSettings drawingSettings = new DrawingSettings(legacyShaderTagIds[0], new SortingSettings(camera))
{
overrideMaterial = errorMaterial
};
for (int i = 1; i < legacyShaderTagIds.Length; i++)
{
drawingSettings.SetShaderPassName(i, legacyShaderTagIds[i]);
}
FilteringSettings filteringSettings = FilteringSettings.defaultValue;
context.DrawRenderers(cullingResults, ref drawingSettings, ref filteringSettings);
}
partial void DrawGizmos()
{
if (Handles.ShouldRenderGizmos())
{
context.DrawGizmos(camera, GizmoSubset.PreImageEffects);
context.DrawGizmos(camera, GizmoSubset.PostImageEffects);
}
}
partial void PrepareForSceneWindow()
{
if (camera.cameraType == CameraType.SceneView)
{
//场景窗口显示
ScriptableRenderContext.EmitWorldGeometryForSceneView(camera);
}
}
partial void PrepareBuffer()
{
Profiler.BeginSample("Editor Only");
buffer.name = SampleName = camera.name;//会产生GC
Profiler.EndSample();
}
#else
const string SampleName = bufferName;//运行时用常量
#endif
}