HDRP图形入门:HDRP渲染管线depth翻转

      新项目开坑HDRP渲染管线,花了些时间把项目开发框架和图形工作流更新到最新版本,其间发现HDRP中深度信息和buildin渲染管线翻转了。
      以前的buildin渲染管线,距离摄像机越近depth->0,越远depth->1,这也很好理解,离得越近距离越小,颜色值->(0,0,0,0)黑色,如下:
HDRP图形入门:HDRP渲染管线depth翻转_第1张图片
      而新HDRP中,深度如下:
      可以看的出来是反过来的,也就是距离摄像机越近depth->1,越远depth->0。
      unity说是因为HDRP本身是为了支持高级图形硬件的图形语言比如hlsl设定的(比如dx和opengl的坐标系也是反的,同时uv也可能上下颠倒),当然这也不是什么大事,无非刚开始搞反了导致效果出问题,测试出来后改一改就好了。
HDRP图形入门:HDRP渲染管线depth翻转_第2张图片
      接下来根据新的规范实现一个遮挡剔除和不剔除的外发光特效,因为以前写过外发光特效的原理,所以这里从简,只叙述一下大纲:
      1.采样物体的轮廓纹理,进行纯色渲染。
      2.高斯滤波进行后处理得到轮廓像素外扩的纯色渲染。
      3.根据当前pixel片段所在的摄像机深度缓冲和物体轮廓纹理的深度相比较,如果片段轮廓纹理depth值更小,则代表距离摄像机更远,则被剔除渲染。

//滤波矩阵
    static float _GaussMatrix[9] = { 0.07511362, 0.1238414, 0.07511362, 0.1238414, 0.20418, 0.1238414, 0.07511362, 0.1238414, 0.07511362 };

    VaryingsEx VertBlur(AttributesEx input)
    {
        VaryingsEx output;
        UNITY_SETUP_INSTANCE_ID(input);
        UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(output);
        //必须采样屏幕坐标
        output.positionCS = GetFullScreenTriangleVertexPosition(input.vertexID);
        //采样uv坐标,用于纹理采样
        output.uv = GetFullScreenTriangleTexCoord(input.vertexID);
        float c = 1;
        for(int x=0;x<3;x++)
        {
            for(int y=0;y<3;y++)
            {   
                output.uvs[x*3+y] = (output.uv+_CustomColorTexture_TexelSize.xy*float2((y-c)*_BlurSpread,(x-c)*_BlurSpread));
            }
        }
        return output;
    }

    float4 FragBlur(VaryingsEx input) : SV_Target
    {
        UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(input);

        float4 col = float4(0,0,0,0);

        for(int k=0;k<9;k++)
        {
            col+=(CustomPassSampleCustomColor(input.uvs[k])*_GaussMatrix[k]);
        }

        col*=_Brightness;

        //采样上一个custompass纹理
        //如果纹理有颜色数据,则剔除掉,就可以显示最底层的模型渲染纹理
        float4 ocol = CustomPassSampleCustomColor(input.uv);

        if(ocol.a>0)
        {
            discard;
        }

        return col;
    }

      以上是进行高斯滤波和原始纹理裁剪得到轮廓外发光效果。

			void GetSurfaceAndBuiltinData(FragInputs fragInputs, float3 viewDirection, inout PositionInputs posInput, out SurfaceData surfaceData, out BuiltinData builtinData)
            {
                float2 colorMapUv = TRANSFORM_TEX(fragInputs.texCoord0.xy, _ColorMap);
                float4 result = SAMPLE_TEXTURE2D(_ColorMap, s_trilinear_clamp_sampler, colorMapUv);
                //hdrp摄像机深度值由近到远1->0深度图采样near=1,far=0
                //通过像素坐标xy值采样深度信息
                float camdepth = LoadCameraDepth(fragInputs.positionSS.xy);
                //当前像素深度信息由近到远
                //1->0
                float vertexdepth = posInput.deviceDepth;

                if(_OcclutionDiscard == 1)
                {
                    //如果当前像素的深度值<深度图深度值
                    //则表示当前像素距离摄像机更远
                    //则被剔除渲染
                    if(vertexdepth<camdepth)
                    {
                        discard;
                    }
                }
                // Write back the data to the output structures
                ZERO_BUILTIN_INITIALIZE(builtinData); // No call to InitBuiltinData as we don't have any lighting
                ZERO_INITIALIZE(SurfaceData, surfaceData);
                builtinData.opacity = result.a;
                builtinData.emissiveColor = float3(0, 0, 0);
                surfaceData.color = camdepth;
            }

      以上是根据深度缓冲进行剔除和非剔除采样。


      可以看到添加物体外发光和选择遮挡剔除完成需要的效果。
      ps:因为现在更加倾向于自身健康和家庭生活,所以博客只会偶尔花最多半个小时对一些技术要点(或坑点)进行说明。

你可能感兴趣的:(入门图形学之C,for,Graphic,unity3d,数学,shader,HDRP)