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))
适用到其它平台复制代码1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67Shader "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)内容请搜索靠谱客的其他文章。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复