您的位置:首页 > 移动开发 > Unity3D

Unity Shader中顶点坐标的大小似乎会受到Draw Call合批的影响

2016-01-12 13:11 435 查看
最近美术同事希望我能帮忙做一个由内而外流光的shader,效果类似下图:



我最初的思路是利用模型的顶点坐标:美术***模型的时候就将模型的原点设在中心。这样我在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合批影响的。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: