unity, surface shader access world position and localposition

一,surface shader中访问worldposition

在surface shader中访问世界坐标,只需在Input结构体中声明float3 worldPos即可,如下:

     struct Input {
            float2 uv_MainTex;
            float3 worldPos;
        };
        void surf (Input IN, inout SurfaceOutputStandard o) {

    //access worldposition by using IN.worldPos

    ...
        }

参考:http://wiki.unity3d.com/index.php?title=Shader_Code

二,surface shader中访问localposition

没有直接的内置变量可用,需要把vert中的v.vertex引进surf中使用,如下:

        Tags { "RenderType"="Opaque" "DisableBatching"="True" }//DisableBatching tag,ref: http://docs.unity3d.com/Manual/SL-SubShaderTags.html
        
        #pragma surface surf Standard fullforwardshadows vertex:vert

        struct Input {
            float2 uv_MainTex;
            float3 my_vertPos;
        };

        void vert (inout appdata_full v, out Input o) {
            UNITY_INITIALIZE_OUTPUT(Input,o);//ref: http://forum.unity3d.com/threads/what-does-unity_initialize_output-do.186109/
            o.my_vertPos=v.vertex;
        }
        void surf (Input IN, inout SurfaceOutputStandard o) {

       //access localposition by using IN.my_vertPos
           ...
        }

需要注意的是应该加"DisableBatching"="True"标签,原因是:Some shaders (mostly ones that do object-space vertex deformations) do not work when Draw Call Batching is used – that’s because batching transforms all geometry into world space, so “object space” is lost.引自:http://docs.unity3d.com/Manual/SL-SubShaderTags.html

就是说,如果开启了自动网格合并,则vert中的v.vertex将直接就是世界坐标而不是局部坐标,可我们现在想用的是局部坐标,所以必须禁用自动网格合并。

 

posted on 2015-07-30 14:41  wantnon  阅读(1639)  评论(0编辑  收藏  举报

导航