描边教程:基于几何生成方法 VR资源

慕容小匹夫 2017-09-15 12:53:00

0x00 前言

进入金秋九月之后,周末参加的社区活动反而多了起来。因此不像之前一样有富余的时间来写一些长文了,在考虑写点什么的时候突然想到了上一篇文章《利用GPU实现翻页效果》中利用shader实现了一个有趣的翻书的效果。那么这篇文章不妨也来效仿一下写一个shader来实现某种效果,只不过篇幅上可能更短、效果更简单,当然写作的时间也更碎片化了,所以《小随笔》似乎是一个不错的标题。
 

0x01 先来点理论知识

 

本文要实现的内容是一个很常见的描边效果。
(本文的模型来自:RTS Mini Legion Lich)
实现的思路来自《Real Time Rendering》的相关章节,即基于几何生成方法的描边。相关的理论内容已经有不少文章都提到过,这里简单概况一下就是在绘制模型时用两个pass,第一遍正常绘制模型;第二遍绘制则要将模型正面剔除——正面剔除的原因在下面的演示中我会告诉各位原因——接着在vs中修改顶点位置,将顶点沿着法线方向膨胀一定距离,然后在fs中将模型用纯色输出即可。

(图片来自:【翻译】西川善司「实验做出的游戏图形」「GUILTY GEAR Xrd -SIGN-」中实现的「纯卡通动画的实时3D图形」的秘密,前篇(2))
 

0x02 再来点实际操作

 

好了,现在就让我们来实现这个效果吧。
首先我们显然总共需要两个pass,但是我们先实现一个pass,将模型正常的绘制出来。
 
 
01
02
03
04
05
06
07
08
09
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
// 第一个pass用来渲染正常的模型
    Pass
    {
        CGPROGRAM
        #pragma vertex vert
        #pragma fragment frag
 
        #include "UnityCG.cginc"
 
        struct appdata
        {
            float4 vertex : POSITION;
            float2 uv : TEXCOORD0;
        };
 
        struct v2f
        {
            float2 uv : TEXCOORD0;
            float4 vertex : SV_POSITION;
        };
 
        sampler2D _MainTex;
        float4 _MainTex_ST;
 
        v2f vert (appdata v)
        {
            v2f o;
            o.vertex = UnityObjectToClipPos(v.vertex);
            o.uv = TRANSFORM_TEX(v.uv, _MainTex);
            return o;
        }
 
        fixed4 frag (v2f i) : SV_Target
        {
            fixed4 col = tex2D(_MainTex, i.uv);
            return col;
        }
        ENDCG
经过这次绘制,屏幕上出现了正常的模型。
OK,下面第二个pass要来了。
由于这次我们需要使用法线信息,所以我们可以直接使用Unity内建的appdata_base作为vs的输入,它包含了顶点的法线信息。而由于这次vs和fs之间并没有数据的传递,因此vs只需要输出位置到SV_POSITION,而fs只需要输出纯色到SV_Target即可。
 
 
1
2
3
4
5
6
7
float4 vert(appdata_base v) : SV_POSITION
 {
     ...
 }
 
 fixed4 frag() : SV_Target {
     return _OutlineColor;
 }
除此之外,在vs中我们不能直接使用在model空间的法线信息,因此还要将顶点的法线信息从model空间转换到clip空间。
 
 
float3 normal = mul((float3x3) UNITY_MATRIX_MVP, v.normal);
然后将顶点沿着法线方向膨胀一定距离:
 
 
pos.xy += _OutlineFactor * normal.xy;
嗯。现在的效果有点赞了。
最后再来看看为什么要打开正面剔除,如果没有正面剔除我们将看到的是一个颜色错误的模型。
就像下面这样:
好了,到此一个常见而又简单的效果就实现了。
99VR视界二维码
热门推荐
Hot Recommended
在线客服