网站首页 全球最实用的IT互联网站!

人工智能P2P分享Wind搜索发布信息网站地图标签大全

当前位置:诺佳网 > 软件工程 > 其他技术区 > 游戏开发 >

【渲染流水线】[逐片元阶段]-[模版测试]以Unity

时间:2025-08-22 10:01

人气:

作者:admin

标签:

导读:本文介绍了Unity URP中模板缓冲区的使用,通过8位整数/像素实现精确像素控制。详细解析了模板测试流程:包括缓冲区初始化、测试阶段比较函数(如Always、Equal等)和缓冲操作(如Rep...
  • 用于精确控制像素丢弃的逐片元操作,通过模板缓冲区(8位整数/像素)实现复杂遮罩效果。
  • 支持8种比较函数和6种缓冲操作‌
  • 当前模版操作,只能在Shader文件中书写操作,ShaderGraph中无法直接使用模版指令。

【从UnityURP开始探索游戏渲染】专栏-直达

  • 核心配置所有配置列出(非全必要):
Stencil {
    Ref 2 // 必要模版数值
    ReadMask 255
    WriteMask 255
    Comp Greater // 必要比较操作符
    Pass Replace // 必要通过后的操作
    Fail Keep
    ZFail DecrSat
}

1. 核心配置命令

  • Ref:设置参考值(0-255整数),用于与模板缓冲区比较
  • ReadMask:读取掩码(0-255),按位与操作后比较(默认255)
  • WriteMask:写入掩码(0-255),控制可修改的缓冲区位(默认255)

2. 比较函数命令

Comp支持以下枚举值:

  • Always/Never:始终通过/拒绝
  • Less/Greater:小于/大于时通过
  • Equal/NotEqual:等于/不等于时通过
  • LessEqual/GreaterEqual:小于等于/大于等于时通过

3. 操作命令

Pass/Fail/ZFail支持的操作:

  • Keep:保持原值
  • Zero:置零
  • Replace:用Ref值替换
  • IncrSat/DecrSat:饱和增减(0/255边界)
  • IncrWrap/DecrWrap:循环增减
  • Invert:按位取反
  1. 缓冲区初始化

    • 清除模板缓冲:GL.Clear(ClearBufferMask.StencilBufferBit)
    • 设置初始值:GL.StencilMask(0xFF)(默认全255)
  2. 测试阶段-逐片元

    plaintext
    if (片元模板值 [比较函数] 参考值) {
        执行通过操作(如保留像素)
    } else {
        执行失败操作(如丢弃像素)
    }
    
  3. 缓冲更新

    • 根据测试结果修改模板缓冲值(可选)
函数 含义 OpenGL常量
Never 永远不通过 GL_NEVER
Always 永远通过 GL_ALWAYS
Less 模板值 < 参考值 GL_LESS
LEqual 模板值 ≤ 参考值 GL_LEQUAL
Greater 模板值 > 参考值 GL_GREATER
GEqual 模板值 ≥ 参考值 GL_GEQUAL
Equal 模板值 == 参考值 GL_EQUAL
NotEqual 模板值 != 参考值 GL_NOTEQUAL
操作组合 含义
Keep 保持当前模板值不变(默认)
Zero 将模板值设为0
Replace 用参考值替换模板值
Incr/IncrWrap 模板值+1(超过255时,前者截断后者循环)
Decr/DecrWrap 模板值-1(低于0时,前者截断后者循环)
Invert 按位取反(~操作)
  • 遮罩区域shader
Shader "Custom/StencilMask" {
    SubShader {
        Tags { "Queue"="Geometry-1" } // 优先渲染
        ColorMask 0 // 不写入颜色
        ZWrite Off

        Stencil {
            Ref 1
            Comp Always
            Pass Replace // 将模板值设为1
        }
        Pass {} // 空Pass仅用于写入模板
    }
}
  • 物体模版测试shader,该Shader仅在模板值为1的区域内渲染物体。
Shader "Custom/StencilObject" {
    SubShader {
        Stencil {
            Ref 1
            Comp Equal // 仅渲染模板值=1的区域
            Pass Keep
        }
        Pass {
            // 正常着色代码...
        }
    }
}
Shader "Custom/StencilOutline" {
    Properties {
        _MainTex ("Base Texture", 2D) = "white" {}
        _OutlineColor ("Outline Color", Color) = (1,0,0,1)
        _OutlineWidth ("Outline Width", Range(0, 0.1)) = 0.05
    }

    SubShader {
        Tags { 
            "RenderPipeline"="UniversalRenderPipeline"
            "RenderType"="Opaque"
        }

        // Pass 1: 正常渲染角色并写入模板
        Pass {
            Name "Character"
            Tags
            {
                "LightMode" = "UniversalForward"
            } 
            Stencil {
                Ref 1
                Comp Always
                Pass Replace
                ZFail Keep
            }

            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"

            struct Attributes {
                float4 positionOS : POSITION;
                float2 uv : TEXCOORD0;
            };

            struct Varyings {
                float4 positionCS : SV_POSITION;
                float2 uv : TEXCOORD0;
            };

            TEXTURE2D(_MainTex);
            SAMPLER(sampler_MainTex);

            Varyings vert(Attributes IN) {
                Varyings OUT;
                OUT.positionCS = TransformObjectToHClip(IN.positionOS.xyz);
                OUT.uv = IN.uv;
                return OUT;
            }

            half4 frag(Varyings IN) : SV_Target {
                return SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, IN.uv);
            }
            ENDHLSL
        }

        // Pass 2: 渲染轮廓
        Pass {
            Name "Outline"
            Cull Front
            Stencil {
                Ref 1
                Comp NotEqual
                Pass Keep
            }

            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"

            struct Attributes {
                float4 positionOS : POSITION;
                float3 normalOS : NORMAL;
            };

            struct Varyings {
                float4 positionCS : SV_POSITION;
            };

            CBUFFER_START(UnityPerMaterial)
                float4 _OutlineColor;
                float _OutlineWidth;
            CBUFFER_END

            Varyings vert(Attributes IN) {
                Varyings OUT;
                float3 posWS = TransformObjectToWorld(IN.positionOS.xyz * (1 + _OutlineWidth));
                float3 normalWS = TransformObjectToWorldNormal(IN.normalOS);
                // posWS += normalWS * _OutlineWidth; // 沿法线方向扩展
                OUT.positionCS = TransformWorldToHClip(posWS);
                return OUT;
            }

            half4 frag(Varyings IN) : SV_Target {
                return _OutlineColor;
            }
            ENDHLSL
        }
    }
}

【从UnityURP开始探索游戏渲染】专栏-直达

(欢迎点赞留言探讨,更多人加入进来能更加完善这个探索的过程,????)

温馨提示:以上内容整理于网络,仅供参考,如果对您有帮助,留下您的阅读感言吧!
相关阅读
  • 便捷打包Instant Asset脚本

    便捷打包Instant Asset脚本

    使用说明 将脚本放在Assets/Editor目录下 在需要打包同一个table的资源要放在同一...
  • Tuanjie InstantAsset

    Tuanjie InstantAsset

    InstantAsset InstantAsset 是一套全新的资产解决方案,旨在提升开发者的开发和运行...
本类排行
相关标签
本类推荐

CPU | 内存 | 硬盘 | 显卡 | 显示器 | 主板 | 电源 | 键鼠 | 网站地图

Copyright © 2025-2035 诺佳网 版权所有 备案号:赣ICP备2025066733号
本站资料均来源互联网收集整理,作品版权归作者所有,如果侵犯了您的版权,请跟我们联系。

关注微信