我是靠谱客的博主 爱笑乌冬面,最近开发中收集的这篇文章主要介绍unity-shader-SignedDistanceField(SDF),觉得挺不错的,现在分享给大家,希望可以做个参考。

概述


title: unity-shader-SignedDistanceField(SDF)
categories: Unity3d-Shader
tags: [unity, shader, sdf]
date: 2019-06-21 13:14:46
comments: false

unity-shader-SignedDistanceField(SDF)


前篇

  • Signed Distance Field - https://zhuanlan.zhihu.com/p/26217154
  • unity画个多边形如何用shader抗锯齿? - https://www.zhihu.com/question/267382412
  • Unity Anti-aliasing shader (SDF) - https://www.jianshu.com/p/2171db34ce58

Signed Distance Field : Signed,正负号,Distance,点到点的距离,Field,区域,其实就是 判断一个点是否在一个区域内


抗锯齿方面的使用

原理

利用的是 uv 值做的 SDF,多边形中心点,uv值为(0,0),边上的点uv值为(1,0)。这时候,从中心到边缘,uv的x值边缘为1,非边缘在0~1之间。这时候只要利用 uv.x在x和y方向上的偏导数来取出 几个像素做下边缘 alpha 模糊即可。

应为利用了 alpha 做混合, 所以渲染队列必须在 Transparent

参考测试工程中的 SignedDistanceField02.shader

  • 模型 uv 分布

    所以可以考虑用多一套 uv 去存储这个值, 这里我直接用第一套

  • 效果

    左下角的为 unity 内置的 quad, 正常的 方形uv分布.

  • shader 代码

    需要注意的是 fwidth 是 dx11 的函数, 可以用 abs(ddx(x)) + abs(ddy(x)) 适用到其它平台

    Shader "test/sdf/SignedDistanceField02"
    {
        Properties
        {
            _MainTex ("Texture", 2D) = "white" {}
            _Width ("Width", Range(0.0001, 15)) = 5
        }
        SubShader
        {
            Tags { 
                "Queue"="Transparent" 
                "RenderType"="Transparent" 
            }
    
            ZWrite Off
            Blend SrcAlpha OneMinusSrcAlpha
    
            Pass
            {
                CGPROGRAM
                #pragma vertex vert
                #pragma fragment frag
    
                #include "UnityCG.cginc"
                // #define fwidth(x) (abs(ddx(x)) + abs(ddy(x))) // fwidth 是 dx11 的函数, 可以这样定义才能使用到其它平台
    
                struct appdata
                {
                    float4 vertex : POSITION;
                    float2 texcoord : TEXCOORD0;
                    // float2 texcoord2 : TEXCOORD1; 可以考虑用多一套uv
                };
    
                struct v2f
                {
                    float4 pos : SV_POSITION;
                    float2 uv : TEXCOORD0;
                };
    
                sampler2D _MainTex;
                float4 _MainTex_ST;
                float _Width;
    
                v2f vert (appdata v) {
                    v2f o;
                    o.pos = UnityObjectToClipPos(v.vertex);
                    o.uv = TRANSFORM_TEX(v.texcoord, _MainTex);
                    return o;
                }
    
                fixed4 frag (v2f IN) : COLOR {
                    float smoothValue = 0;
                    //fwidth 必须dx11. 因为是UI,可以用CPU算好一个像素的_Delta,用uniform传给GPU;
                    float delta = _Width * fwidth(IN.uv.x);//fwidth(IN.uv.x);
                    float v = IN.uv.x + delta;
                    //if(v >= 1.0f){
                        // smoothValue = (v -1) / delta;
                    //}
                    smoothValue = step(1.0, v) * (v -1) / delta;
                    float a = smoothstep(1, 0.0f, smoothValue);
                    return float4(1, 1, 1, a);
                }
                ENDCG
            }
        }
    }
    

最后

以上就是爱笑乌冬面为你收集整理的unity-shader-SignedDistanceField(SDF)的全部内容,希望文章能够帮你解决unity-shader-SignedDistanceField(SDF)所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(46)

评论列表共有 0 条评论

立即
投稿
返回
顶部