查看: 1800|回复: 2
打印 上一主题 下一主题

[经验分享] Unity3d 使用DX11的曲面细分(一)

[复制链接]

100

主题

3

听众

7683

积分

高级设计师

Rank: 6Rank: 6

纳金币
2378
精华
0

最佳新人 活跃会员 热心会员 灌水之王 突出贡献

跳转到指定楼层
楼主
发表于 2015-4-30 08:50:35 |只看该作者 |倒序浏览

unity3d surface Shaderswith DX11 Tessellation

Unity3d surface shader 在DX11上的曲面细分

I write this article, according to the unity3d official document, and look up some data in the web, and add to some idea by myself.

根据官方文档,并查阅了一些资料加上我个人的理解写出此文。

I write in two languages. One passage write in Chineseone passage translate into English, If I write some thing wrong, welcome to correct my article.

我用了两种语言,一段英文一段中文,英语语法错误,或者写的不对的各位可以告诉我及时改正

Thanks for my teacher correct my article.

感谢我的老师对本文写的不对的地方进行了一些修改

Surface Shadershave some support for Direct 11 GPU Tessellation,

1.     Tessellation is indicated by tessellate:FunctionName modifier. That function computes triangleedge and inside tessellation factors.

2.     When tessellation is used, “vertex modifier” (vertex:FunctionName) is invokedafter tessellation,for each generated vertex in the domain shader. Here you’d typically todisplacement mapping.

3.     Surface shaders can optionally compute Phong Tessellation  to smooth model surface even without anydisplacement mapping.

Unity中Surface shader 支持 DX11 GPU曲面细分的原因在于:

1.     曲面细分函数用 tessellate:FunctionName 表示。这个函数能计算三角形边缘和一些曲面细分的内部因素。

2.     当曲面细分被使用时,“顶点函数”(vertex:FunctionName)在曲面细分之后被调用,在shader包括的物体之内的每个顶点都是如此。因此你可以再次进行贴图置换。

3.     surface shader 能随意地计算 phong 曲面细分 来光滑模型的表面,甚至不需要贴图置换。

Current limitationsof tessellation support:

1.    Only triangle domain - no quads, no isoline tessellation.

2. When tessellation is used,shader is automatically compiled intoShader Model 5.0 target, which means itwill only work on DX11.

现在unity3d对曲面细分支持的局限性:

1.    只有三角形面片可以而四边形的不行,等值线曲面细分也不支持(isoline tessellation)。

2.    当使用曲面细分时,shader自动编译成 shader model 5.0 版本,因此曲面细分只能用在DX11上(ShaderModel 5.0 → DirectX 11)。

The Displacement can be usedto instead the Bump Maping technique.The Bump Maping is illusion that can have concave-convex feeling, but the model is flat like before. The Displacement mapping can changemesh’s vertex transposition, chang the model that make it have trueconcave-convex.

贴图置换(Displacement mapping),可被用做现有凹凸贴图技术的临时替代技术,bumpmap只是假象,模型并没有真正凹凸,贴图置换是移动模型顶点,使模型真正产生了凹凸。

无细分,只有贴图置换的shader(No GPU tessellation, displacement in the vertex modifier)

Let’s start with a surface shader that does some displacement mapping without using tessellion.Base-on the amount come from Displacement mapping, move the vertex along their normals.
我们先在不使用曲面细分的情况下贴图置换。基于贴图置换的数值,沿着法线移动顶点。

let's see the shader:

让我们看看shader

Shader 'Custom/testShader' { Properties {            _MainTex ('Base (RGB)', 2D) = 'white' {}            _DispTex ('Disp Texture', 2D) = 'gray' {}            _NormalMap ('Normalmap', 2D) = 'bump' {}            _Displacement ('Displacement', Range(0, 1.0)) = 0.3            _Color ('Color', color) = (1,1,1,0)            _SpecColor ('Spec color', color) = (0.5,0.5,0.5,0.5)        }        SubShader {            Tags { 'RenderType'='Opaque' }            LOD 300                        CGPROGRAM            #pragma surface surf BlinnPhong addshadow fullforwardshadows vertex:disp nolightmap            #pragma target 5.0            struct appdata {                float4 vertex : POSITION;                float4 tangent : TANGENT;                float3 normal : NORMAL;                float2 texcoord : TEXCOORD0;            };            sampler2D _DispTex;            float _Displacement;            void disp (inout appdata v)            {                float d = tex2Dlod(_DispTex, float4(v.texcoord.xy,0,0)).r * _Displacement;                v.vertex.xyz += v.normal * d;            }            struct Input {                float2 uv_MainTex;            };            sampler2D _MainTex;            sampler2D _NormalMap;            fixed4 _Color;            void surf (Input IN, inout SurfaceOutput o) {                half4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;                o.Albedo = c.rgb;                o.Specular = 0.2;                o.Gloss = 1.0;                o.Normal = UnpackNormal(tex2D(_NormalMap, IN.uv_MainTex));            }            ENDCG        }        FallBack 'Diffuse'    }

tex2Dlod - 2D texture lookup with specified level of detail and optional texel offset.
tex2Dlod 以指定的细节级别和可选的位移来解析贴图


In this vertex function,we move each vertex along their normals(depend on the  _Displacement value);
在这个顶点函数中,把每个顶点都向着法线方向偏移一些(取决于_Displacement的值)


The above shader is fairly standard:
1. Vertex modifier disp samples the displacement map and moves vertices along their normals.
2. It uses custom “vertex data input” structure (appdata) instead of default appdata_full. This is not needed yet, but it’s more efficient for tessellation to use as small structure as possible.
3. Since our vertex data does not have 2nd UV coordinate, we add nolightmap directive to exclude lightmaps.

上面的shader非常标准:
1.    在定点函数disp内,每个顶点都根据displacement的值的大小沿着该点的法线移动
2.    使用了自定义的顶点输出的结构体appdata,而不是默认值appdata_full。这个现在还用不到,但是结构体尽可能的小,会提高曲面细分的效率。
3.    顶点数据没有uv坐标,在#pragma处加上nolightmap指令,就不包含光照贴图了

固定数量的曲面细分(Fixed amount of tessellation)细化算法 The Refinement Algorithms

Let’s see how the vertex produce, according to the kinds of beginning cell, there are triangle and quads, as mentioned before, unity just support triangle, not quads. Its just refinement each layer with regulation. The base rule add new vertex to form new edges and planes in the low resolving.(Or though “cut corner” method),use recursion to smooth and refinement.DX11 used thePN-Triangles Algorithms to converts low resolution models into curved surfaces which are then redrawn as a mesh of finely tessellated triangles. Then eliminate the feint and the artificial things in games.

让我们看看这些点是怎么生成的
按照初始单元网格分类,包括三角形网格细分和四边形网格细分,前面已经提到了,unity只支持三角形网格细分,而不支持四边形。
曲面细分就是用一定的规则对多边形网格进行逐层细化。细分模式的基本规则是从粗糙的大网格,通过添加新的顶点来形成新的边和面(或通过削角的办法形成新的边和面),这样递归地平滑细分,直到最终获得光滑曲面,DX11采用了PN-Triangles算法能将低分辨率模型转化为弯曲表面,该表面之后可以被重新绘制成“高精度曲面细分”的三角形网格。用来消除游戏中本该是圆滑却是多边形的假象。

This approach is suitable if your model’s faces are roughly the same size on screen. Some script could then change the tessellation level from code, based on distance to the camera.


如果整个模型在屏幕上的细分程度一样,使用这个方法很合适。有些脚本基于模型与相机的的距离来改变细分程度。

Shader 'Custom/testShader' { Properties {            _Tess ('Tessellation', Range(1,32)) = 4            _MainTex ('Base (RGB)', 2D) = 'white' {}            _DispTex ('Disp Texture', 2D) = 'gray' {}            _NormalMap ('Normalmap', 2D) = 'bump' {}            _Displacement ('Displacement', Range(0, 1.0)) = 0.3            _Color ('Color', color) = (1,1,1,0)            _SpecColor ('Spec color', color) = (0.5,0.5,0.5,0.5)        }        SubShader {            Tags { 'RenderType'='Opaque' }            LOD 300                        CGPROGRAM            #pragma surface surf BlinnPhong addshadow fullforwardshadows vertex:disp tessellate:tessFixed nolightmap            #pragma target 5.0            struct appdata {                float4 vertex : POSITION;                float4 tangent : TANGENT;                float3 normal : NORMAL;                float2 texcoord : TEXCOORD0;            };            float _Tess;            float4 tessFixed()            {                return _Tess;            }            sampler2D _DispTex;            float _Displacement;            void disp (inout appdata v)            {                float d = tex2Dlod(_DispTex, float4(v.texcoord.xy,0,0)).r * _Displacement;                v.vertex.xyz += v.normal * d;            }            struct Input {                float2 uv_MainTex;            };            sampler2D _MainTex;            sampler2D _NormalMap;            fixed4 _Color;            void surf (Input IN, inout SurfaceOutput o) {                half4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;                o.Albedo = c.rgb;                o.Specular = 0.2;                o.Gloss = 1.0;                o.Normal = UnpackNormal(tex2D(_NormalMap, IN.uv_MainTex));            }            ENDCG        }        FallBack 'Diffuse'    }

分享到: QQ好友和群QQ好友和群 腾讯微博腾讯微博 腾讯朋友腾讯朋友 微信微信
转播转播0 分享淘帖0 收藏收藏0 支持支持0 反对反对0
回复

使用道具 举报

rvan    

0

主题

2

听众

262

积分

设计实习生

Rank: 2

纳金币
1
精华
0

最佳新人

沙发
发表于 2015-5-27 14:58:00 |只看该作者
感谢分享,
回复

使用道具 举报

0

主题

1

听众

141

积分

设计实习生

Rank: 2

纳金币
8
精华
0

最佳新人

板凳
发表于 2015-5-27 16:56:58 |只看该作者
学习了··
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

关闭

站长推荐上一条 /1 下一条

手机版|纳金网 ( 闽ICP备08008928号

GMT+8, 2024-5-4 00:42 , Processed in 0.091049 second(s), 27 queries .

Powered by Discuz!-创意设计 X2.5

© 2008-2019 Narkii Inc.

回顶部