绘制物体
绘制物体,包括不透明的物体,透明物体,再加上之前的天空盒
Camera
void DrawVisibleGeometry()
{
//我们需要将不透明物体和透明物体分开绘制
//如果我们直接先绘制所有的物体,然后再绘制天空盒,我们就会看到对于透明的物体,如果其对于相机视线后面没有不透明的物体的话,就会被天空球给遮挡住
//我们的透明shader没有写入深度缓冲,绘制天空盒时,在这个片元上如果没有不透明的物体写入过深度的话,天空盒的绘制就会直接覆盖掉
//所以我们的绘制顺序是先不透明物体,再绘制天空盒,最后绘制透明物体
//先进行不透明物体的绘制
var sortingSettings = new SortingSettings(camera) //相机的透明排序取决于使用的是正交还是基于距离的排序
{
// 不给定排序规则的话,绘制排序是随机混乱的
// 这个排序是从前往后的,因为对于后面的不透明物体,当检测到其的深度大于缓冲区的深度时,说明被挡住了,可以直接丢弃不绘制
// 而如果从后往前的话,就会需要不断的覆盖绘制,性能不如从前往后
criteria = SortingCriteria.CommonOpaque,
};
var drawSettings = new DrawingSettings(unlitShaderTagId, sortingSettings); //DrawingSettings主要用于对物体的渲染顺序和使用哪个Shader Pass
var filteringSettings = new FilteringSettings(RenderQueueRange.opaque); //FilteringSettings主要决定哪些物体渲染,哪些不渲染根据LayerMask,RenderQueue,sortingLayer等
//在Cull中我们得到了cullingResults,因此我们知道了哪些物体是需要绘制的
context.DrawRenderers(cullingResults, ref drawSettings, ref filteringSettings);
context.DrawSkybox(camera); //添加绘制Skybox的命令
// 再进行透明物体的绘制
// 这个绘制顺序是从后往前的,与不透明的绘制顺序是相反的
// 不透明的物体并不写入深度缓冲,因此从前往后并没有性能更优
// 而且透明物体之间需要进行混合,从后往前才能得到正确的混合
// 但事实上并不能完全保证正确,因为排序是基于整个物体的位置的,但是对于复杂的大型物体间,可能会有部分穿插,有部分在前,有部分在后,这样子就会得到错误的效果
sortingSettings.criteria = SortingCriteria.CommonTransparent;
drawSettings.sortingSettings = sortingSettings;
filteringSettings.renderQueueRange = RenderQueueRange.transparent;
context.DrawRenderers(cullingResults, ref drawSettings, ref filteringSettings);
}
//使用Unity默认的一些Shader绘制出使用了不支持的Shader的物体
partial void DrawUnsupportedShaders() //如果不改成分部方法的定义和实现声明,打包就会出错,因为这部分代码是仅在编辑器下使用的
{
if (errorMaterial == null)
{
errorMaterial = new Material(Shader.Find("Hidden/InternalErrorShader"));
}
//我们将不支持的Shader用Unity默认的设置直接绘制出来
//没有设置好Shader的属性之前,绘制出来的物体是黑色的
var drawSettings = new DrawingSettings(legacyShaderTagIds[0], new SortingSettings(camera))
{
overrideMaterial = errorMaterial, //使用内置错误材质来绘制所有不支持的Shader的物体
}
;
for (int i = 1; i < legacyShaderTagIds.Length; i++)
{
drawSettings.SetShaderPassName(i, legacyShaderTagIds[i]);
}
var filteringSettings = FilteringSettings.defaultValue;
context.DrawRenderers(cullingResults, ref drawSettings, ref filteringSettings);
}
没有对绘制排序前

排序后

将不透明物体和透明物体分开渲染

先用默认Shader渲染不支持的Shader

用内置的错误材质在编辑器下绘制

分部代码,让代码更清晰,且可以让Editor代码不会出现打包错误

绘制Gizmos
partial void DrawGizmos()
{
if (Handles.ShouldRenderGizmos())

该文详细介绍了在Unity中自定义渲染管线时如何处理不透明物体和透明物体的绘制,确保正确的渲染顺序和效果。首先,先绘制不透明物体,再绘制天空盒,最后绘制透明物体,以解决透明物体被遮挡的问题。同时,文中还涉及了错误Shader的处理、Gizmos的绘制、相机的ClearFlags设置以及Editor下的特定处理。

2898

被折叠的 条评论
为什么被折叠?



