Unity Shader中顶点坐标的大小似乎会受到Draw Call合批的影响
2016-01-12 13:11
435 查看
最近美术同事希望我能帮忙做一个由内而外流光的shader,效果类似下图:
我最初的思路是利用模型的顶点坐标:美术***模型的时候就将模型的原点设在中心。这样我在vertex shader中用length(i.vertex)求出每个顶点到中心的距离,进而在fragment shader中求出每个像素是否该显示流光。
于是就想做个实验,看看Unity中的模型顶点的分布规律。我写了一个shader,让离原点越近的顶点颜色越偏黑,离原点越远的顶点越偏红。
在Unity中创建一个Unity自带的Plane,应用这个shader,效果如下:
看来Unity自带Plane的坐标原点正好是在Plane的中心。
不过接下来问题来了。当我将Plane复制一个之后,屏幕中的两个Plane就都变成了纯红色。
但是如果将其中一个Plane换个Shader,比如换成Diffuse,另外一个Plane就又恢复成之前中间黑色的样子了。
两个Plane使用同一个材质同一个Shader时,它们俩的Draw Call会合批。因此可以推测Draw Call的合批会对顶点坐标的大小产生影响。
还可以进一步印证这个推测。把其中一个Plane换成Cylinder,用同一个Shader,也是两个模型都变成了纯红色。Stats显示Draw Calls为1,有1个Draw Call被合批。
转动摄像机,让Plane或Cylinder移出摄像机视椎体外,留在视椎体内的模型的颜色就会发生变化。当只有Cylinder留在视椎体内时,Cylinder的颜色就变成了更接近黑色的暗红。
不过值得一提的是,并不是说两个模型使用同一个材质同一个Shader时,它们俩的Draw Call会合批。
比如,添加一个Sphere并不会对已有的模型颜色产生影响。
就此请教了另一位同事,看来是因为Sphere顶点数太多,无法与Plane的Draw Call合批。从Stats看也的确如此,Draw Calls是2,没有合批:
另外,如果两个模型的缩放(Scale)不相等,这两个模型的Draw Call也无法合批。在上面两个Plane使用相同材质相同shader的情况中,如果把其中一个Plane的Scale改成(0.5, 0.5, 0.5),那么Draw Calls也是2,它们又会恢复成中心是黑色的样子。
看来还不能基于顶点坐标来做这个需求,只好采用纹理坐标(TEXCOORD0)了。后来的实验表明,纹理坐标的大小是不会受Draw Call合批影响的。
我最初的思路是利用模型的顶点坐标:美术***模型的时候就将模型的原点设在中心。这样我在vertex shader中用length(i.vertex)求出每个顶点到中心的距离,进而在fragment shader中求出每个像素是否该显示流光。
于是就想做个实验,看看Unity中的模型顶点的分布规律。我写了一个shader,让离原点越近的顶点颜色越偏黑,离原点越远的顶点越偏红。
Shader "Custom/VisualizeVertexPos" { SubShader { Pass { Tags { "Queue"="Transparent" "IgnoreProjector"="True" "RenderType"="Transparent" } Blend SrcAlpha OneMinusSrcAlpha Cull Off Lighting Off Fog { Color (0,0,0,0) } CGPROGRAM #pragma vertex vert #pragma fragment frag #pragma only_renderers gles d3d9 gles3 metal struct vertexInput { float4 vertex : POSITION; }; struct vertexOutput { float4 pos : POSITION; fixed4 col : COLOR; }; vertexOutput vert(vertexInput i) { vertexOutput o; o.pos = mul(UNITY_MATRIX_MVP, i.vertex); o.col = fixed4(length(i.vertex / 10), 0, 0, 1); return o; } float4 frag(vertexOutput i) : COLOR { return i.col; } ENDCG } } //调试过程中注释掉Fallback以便发现错误 //FallBack "Diffuse" }
在Unity中创建一个Unity自带的Plane,应用这个shader,效果如下:
看来Unity自带Plane的坐标原点正好是在Plane的中心。
不过接下来问题来了。当我将Plane复制一个之后,屏幕中的两个Plane就都变成了纯红色。
但是如果将其中一个Plane换个Shader,比如换成Diffuse,另外一个Plane就又恢复成之前中间黑色的样子了。
两个Plane使用同一个材质同一个Shader时,它们俩的Draw Call会合批。因此可以推测Draw Call的合批会对顶点坐标的大小产生影响。
还可以进一步印证这个推测。把其中一个Plane换成Cylinder,用同一个Shader,也是两个模型都变成了纯红色。Stats显示Draw Calls为1,有1个Draw Call被合批。
转动摄像机,让Plane或Cylinder移出摄像机视椎体外,留在视椎体内的模型的颜色就会发生变化。当只有Cylinder留在视椎体内时,Cylinder的颜色就变成了更接近黑色的暗红。
不过值得一提的是,并不是说两个模型使用同一个材质同一个Shader时,它们俩的Draw Call会合批。
比如,添加一个Sphere并不会对已有的模型颜色产生影响。
就此请教了另一位同事,看来是因为Sphere顶点数太多,无法与Plane的Draw Call合批。从Stats看也的确如此,Draw Calls是2,没有合批:
另外,如果两个模型的缩放(Scale)不相等,这两个模型的Draw Call也无法合批。在上面两个Plane使用相同材质相同shader的情况中,如果把其中一个Plane的Scale改成(0.5, 0.5, 0.5),那么Draw Calls也是2,它们又会恢复成中心是黑色的样子。
看来还不能基于顶点坐标来做这个需求,只好采用纹理坐标(TEXCOORD0)了。后来的实验表明,纹理坐标的大小是不会受Draw Call合批影响的。
相关文章推荐
- Unity3d导出Recast geomset.txt
- Unity3d导出Recast geomset.txt
- 【Unity】关于一个材质球有多个属性
- Unity 3D Quaternion的使用
- 【Unity ImageEffect】一个用于角色遮挡透视轮廓的效果
- 【Unity3d】火炬之光的X射线效果
- unity 在ios上的 c#键值对数据排序
- Unity 中的C#脚本
- unity, editorWindow update计时
- Unity 3d Admob 集成教程
- 【Unity入门】场景编辑与场景漫游快捷键
- Unity中Camera的Clear flags,Culling Mask,Depth参数
- 【Unity入门】场景编辑与场景漫游快捷键
- Unity使用Kinect FaceBasics表情识别API
- 用opengl方式打开unity
- Unity 字符串按自然数排序
- 从unity4升级到unity5模型显示问题
- Unity日常技巧
- unity 调用C#类将文字转换为语音
- Unity3D游戏开发之不同层级可视范围不同