在OpenGL中,需要顶点着色器和片段着色器的支持才能进行正确的渲染,在顶点着色器中,每一帧 对 场景中物体的每个顶点都要执行一次处理。
如果自己使用OpenGL,需要在C++ 代码读取模型数据,将顶点坐标、顶点颜色、UV坐标传递到顶点着色器中。
所以在顶点着色器中 ,是可以对顶点数据进行修改的。
在Unity3d中,将FBX 或者其它模型 导入编辑器,默认会创建一个 Diffuse 材质。这个材质中是 没有顶点函数的,也就是说不能 对 顶点数据进行处理,所以导进来的 模型都是灰色的没有颜色的。
新建材质 VertexColor.mat ,新建 VertexColor.shader 。
下面给 Shader 添加 vert()函数 (顶点函数) ,来获取模型中的顶点颜色。
1、声明 vertex 参数,告诉Unity 我们的着色器中包含有一个顶点函数
pragma surface surf Lambert vertex:vert
2、编写顶点函数 vert()
void vert(inout appdata_full v,out Input o) { };
struct Input { float2 uv_MainTex; float4 vertexColor; };
void vert(inout appdata_full v,out Input o) { UNITY_INITIALIZE_OUTPUT(Input,o); o.vertexColor=v.color; }
在UnityCG.cginc 文件中可以找到 appdata_full 的定义
struct appdata_full { float4 vertex : POSITION; float4 tangent : TANGENT; float3 normal : NORMAL; float4 texcoord : TEXCOORD0; float4 texcoord1 : TEXCOORD1; fixed4 color : COLOR; #if defined(SHADER_API_XBOX360) half4 texcoord2 : TEXCOORD2; half4 texcoord3 : TEXCOORD3; half4 texcoord4 : TEXCOORD4; half4 texcoord5 : TEXCOORD5; #endif };
同时法线还有下面两个版本,可以根据需求选取。
struct appdata_base { float4 vertex : POSITION; float3 normal : NORMAL; float4 texcoord : TEXCOORD0; }; struct appdata_tan { float4 vertex : POSITION; float4 tangent : TANGENT; float3 normal : NORMAL; float4 texcoord : TEXCOORD0; };
void surf (Input IN, inout SurfaceOutput o) { o.Albedo=IN.vertexColor; }
完整Shader 代码
Shader "CookBookShaders/Chapt7-1/VertexColor" { Properties { _MainTex ("Base (RGB)", 2D) = "white" {} } SubShader { Tags { "RenderType"="Opaque" } LOD 200 CGPROGRAM #pragma surface surf Lambert vertex:vert sampler2D _MainTex; struct Input { float2 uv_MainTex; float4 vertexColor; }; void vert(inout appdata_full v,out Input o) { UNITY_INITIALIZE_OUTPUT(Input,o); o.vertexColor=v.color; } void surf (Input IN, inout SurfaceOutput o) { o.Albedo=IN.vertexColor; } ENDCG } FallBack "Diffuse" }
将材质赋值给 模型,查看效果如下
测试工程下载:
http://pan.baidu.com/s/1pL3pkmv