您当前的位置: 首页 >  unity

Jave.Lin

暂无认证

  • 4浏览

    0关注

    704博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

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

Jave.Lin 发布时间:2019-07-04 14:22:00 ,浏览量:4

使用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

这两个参数,可以参考:

  • 参考ShaderLab: Culling & Depth Testing中的Offset。
  • 调用glPolygonOffset()中的两个参数是什么?它们是什么意思?
  • Shader Depth Offset [Polygon Offset]
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
  • Vulkan Tutoiral - Fixed func - Rasterizer - depth bias
  • [OpenGL][SharpGL]用Polygon Offset解决z-fighting和stitching问题
  • OpenGL - Drawing Lines over Polygons and Using Polygon Offset 在多边形上画线并使用多边形偏移量
  • Shader Depth Offset [Polygon Offset]
关注
打赏
1664331872
查看更多评论
立即登录/注册

微信扫码登录

0.0790s