Unity Shader - Offset 的测试,解决简单的z-fighting情况

141 篇文章 35 订阅

使用OpenGL Polygon Offset解决简单的z-fighting,复杂的就没办法了,只能使用其他方法,如:模板缓存

其对应Unity中使用的是Shader中的Subshader/Pass Tags中的Offset factors, units
参考ShaderLab: Culling & Depth Testing中的Offset。

z-fighting

z-fighting(直译,就是z值的竞争)

原因是因为我们的不同的多边形共面时,在光栅阶段生成的fragment的屏幕xy坐标一样,但depth值又不一样的浮点误差引起的问题,然后浮点round-off的四舍五入,导致z-fighting。

来看个GIF了解一下它的表现:
在这里插入图片描述

这两个绿色、蓝色的平面与红色的矩形的平面,都是共面的(z-fighting未处理)
在这里插入图片描述
下面是z-fighting处理后
在这里插入图片描述
在这里插入图片描述

Shader

Shader "Test/Quad"
{
    Properties
    {
        _OffsetFactor ("Offset Factor", Float) = 0
        _OffsetUnits ("Offset Units", Float) = 0
        _Color ("Main Color", Color) = (1,1,1,1)
    }
    SubShader
    {
        Tags { "RenderType"="Opaque" }
        Offset [_OffsetFactor], [_OffsetUnits]
        Pass
        {
            CGPROGRAM
            #pragma vertex vert
            #pragma fragment frag
            #include "UnityCG.cginc"
            struct appdata
            {
                float4 vertex : POSITION;
                float3 normal : NORMAL;
            };
            struct v2f
            {
                float4 vertex : SV_POSITION;
                float3 wnormal : NORMAL;
            };
            fixed4 _Color;
            v2f vert (appdata v)
            {
                v2f o;
                o.vertex = UnityObjectToClipPos(v.vertex);
                o.wnormal = UnityObjectToWorldNormal(v.normal);
                return o;
            }
            fixed4 frag (v2f i) : SV_Target
            {
                return _Color * (dot(normalize(_WorldSpaceLightPos0.xyz), i.wnormal) * 0.5 + 0.5);
            }
            ENDCG
        }
    }
}

从shader代码中我们可以看到在pass tags中设置了这么一句:

Offset [_OffsetFactor], [_OffsetUnits]

两个factor,unit分别在:properties中

_OffsetFactor ("Offset Factor", Float) = 0
_OffsetUnits ("Offset Units", Float) = 0

这两个参数,可以参考:

finalOffset = s * Factor + d * Unit;
//看上面的连接了解详情,这里我就不说了

所以最终我们在绿色正方形中,将设置:

_OffsetFactor = -1,_OffsetUnits = -1

在这里插入图片描述

蓝色应用设置:

_OffsetFactor = -2,_OffsetUnits = -2

在这里插入图片描述

偶然发现Vulkan中的设置类似的效果

Vulkan Tutoiral - Fixed func - Rasterizer - depth bias

rasterizer.depthBiasEnable = VK_FALSE;
rasterizer.depthBiasConstantFactor = 0.0f; // Optional
rasterizer.depthBiasClamp = 0.0f; // Optional
rasterizer.depthBiasSlopeFactor = 0.0f; // Optional

References

  • 9
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值