Unity SRP自定义渲染管线学习1.2:初步绘制

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

绘制物体

绘制物体,包括不透明的物体,透明物体,再加上之前的天空盒
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()) 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值