找回密码
 注册帐号

扫一扫,访问微社区

提供顶点数据给顶点程序

2015-1-8 15:54| 发布者: 杨炎| 查看: 2661| 评论: 0|原作者: 蛮牛|来自: unity3d脚本manual

摘要: 提供顶点数据给顶点程序顶点数据必须以一个结构的形式提交给 cg/hlsl顶点程序。几个常用的顶点结构定义在unitycg.cginc包含文件,大多数情况下只使用它们就足够了。这些结构是:appdata_base: 顶点由位置、法线和一 ...

提供顶点数据给顶点程序

顶点数据必须以一个结构的形式提交给 cg/hlsl顶点程序。几个常用的顶点结构定义在unitycg.cginc包含文件,大多数情况下只使用它们就足够了。这些结构是:

appdata_base: 顶点由位置、法线和一个纹理坐标构成。

appdata_tan: 顶点由位置、切线、法线和一个纹理坐标构成。

appdata_full: 顶点由位置、切线、法线、两个纹理坐标以及颜色构成。

例如,该着色器基于网格的法线来着色网格,且只使用appdata_base作为顶点程序输入:

shader "vertexinputsimple" {

subshader {

pass {

cgprogram

#pragma vertex vert

#pragma fragment frag

#include "unitycg.cginc"

struct v2f {

float4 pos : sv_position;

fixed4 color : color;

};

v2f vert (appdata_base v)

{

v2f o;

o.pos = mul (unity_matrix_mvp, v.vertex);

o.color.xyz = v.normal * 0.5 + 0.5;

o.color.w = 1.0;

return o;

}

fixed4 frag (v2f i) : color0 { return i.color; }

endcg

}

}

}

如果您想访问不同的顶点数据,您就必须自己声明顶点结构。结构成员必须是下面列出的成员:

float4 vertex是顶点位置

float3 normal是顶点法线

float4 texcoord是第一个 uv 坐标

float4 texcoord1是第二个 uv 坐标

float4 tangent是切线向量(用于法线贴图

float4 color是逐顶点颜色

示例

可视化 uv

以下着色器示例使用顶点位置和第一个纹理坐标作为顶点着色器输入(定义在结构appdata中)。调试网格的 uv 坐标是非常有用的。uv 坐标被可视化为红色和绿色,0..1 范围外的坐标额外应用蓝色色调。

shader "!debug/uv 1" {

subshader {

pass {

fog { mode off }

cgprogram

#pragma vertex vert

#pragma fragment frag

// 顶点输入:位置、uv

struct appdata {

float4 vertex : position;

float4 texcoord : texcoord0;

};

struct v2f {

float4 pos : sv_position;

float4 uv : texcoord0;

};

v2f vert (appdata v) {

v2f o;

o.pos = mul( unity_matrix_mvp, v.vertex );

o.uv = float4( v.texcoord.xy, 0, 0 );

return o;

}

half4 frag( v2f i ) : color {

half4 c = frac( i.uv );

if (any(saturate(i.uv) - i.uv))

c.b = 0.5;

return c;

}

endcg

}

}

}

调试着色器应用于一个环面纽结体模型的 uv1

类似地,这个着色器使模型的第二个 uv 集可视化:

shader "!debug/uv 2" {

subshader {

pass {

fog { mode off }

cgprogram

#pragma vertex vert

#pragma fragment frag

// 顶点输入:位置、第二个 uv

struct appdata {

float4 vertex : position;

float4 texcoord1 : texcoord1;

};

struct v2f {

float4 pos : sv_position;

float4 uv : texcoord0;

};

v2f vert (appdata v) {

v2f o;

o.pos = mul( unity_matrix_mvp, v.vertex );

o.uv = float4( v.texcoord1.xy, 0, 0 );

return o;

}

half4 frag( v2f i ) : color {

half4 c = frac( i.uv );

if (any(saturate(i.uv) - i.uv))

c.b = 0.5;

return c;

}

endcg

}

}

}

可视化顶点颜色

以下着色器使用顶点位置和逐顶点颜色作为顶点着色器输入(定义在结构appdata中)。

shader "!debug/vertex color" {

subshader {

pass {

fog { mode off }

cgprogram

#pragma vertex vert

#pragma fragment frag

// 顶点输入:位置、颜色

struct appdata {

float4 vertex : position;

fixed4 color : color;

};

struct v2f {

float4 pos : sv_position;

fixed4 color : color;

};

v2f vert (appdata v) {

v2f o;

o.pos = mul( unity_matrix_mvp, v.vertex );

o.color = v.color;

return o;

}

fixed4 frag (v2f i) : color0 { return i.color; }

endcg

}

}

}

调试着色器应用于一个将照明烘焙成颜色的模型的颜色 (color)

可视化法线

以下着色器使用顶点位置和法线作为顶点着色器输入(定义在结构appdata中)。法线的 x、y、z 组件被可视化为 r、g、b 颜色。因为法线组件在 -1..1 范围内,所以我们对其进行缩放和偏移,使得输出颜色在可显示的 0..1 范围内。

shader "!debug/normals" {

subshader {

pass {

fog { mode off }

cgprogram

#pragma vertex vert

#pragma fragment frag

// 顶点输入:位置、法线

struct appdata {

float4 vertex : position;

float3 normal : normal;

};

struct v2f {

float4 pos : sv_position;

fixed4 color : color;

};

v2f vert (appdata v) {

v2f o;

o.pos = mul( unity_matrix_mvp, v.vertex );

o.color.xyz = v.normal * 0.5 + 0.5;

o.color.w = 1.0;

return o;

}

fixed4 frag (v2f i) : color0 { return i.color; }

endcg

}

}

}

调试着色器应用于一个模型的法线 (normal)。您可以看见该模型具有硬着色边缘。

可视化切线和副法线

切线和副法线向量用于法线贴图。在 unity 中,只有切线向量储存在顶点中,副法线衍生自法线和切线。

以下着色器使用顶点位置和切线作为顶点着色器输入(定义在结构appdata中)。切线的 x、y、z 组件被可视化为 r、g、b 颜色。因为法线组件在 -1..1 范围内,所以我们对其进行缩放和偏移,使得输出颜色在可显示的 0..1 范围内。

shader "!debug/tangents" {

subshader {

pass {

fog { mode off }

cgprogram

#pragma vertex vert

#pragma fragment frag

// 顶点输入:位置、切线

struct appdata {

float4 vertex : position;

float4 tangent : tangent;

};

struct v2f {

float4 pos : sv_position;

fixed4 color : color;

};

v2f vert (appdata v) {

v2f o;

o.pos = mul( unity_matrix_mvp, v.vertex );

o.color = v.tangent * 0.5 + 0.5;

return o;

}

fixed4 frag (v2f i) : color0 { return i.color; }

endcg

}

}

}

调试着色器应用于一个模型切线 (tangent)。

以下着色器使副法线可视化。它使用顶点位置、法线和切线作为顶点输入。副法线是从法线和切线计算出的。就像法线和切线一样,需要将其缩放并偏移到可显示的 0..1 范围内。

shader "!debug/binormals" {

subshader {

pass {

fog { mode off }

cgprogram

#pragma vertex vert

#pragma fragment frag

// 顶点输入:位置、法线、切线

struct appdata {

float4 vertex : position;

float3 normal : normal;

float4 tangent : tangent;

};

struct v2f {

float4 pos : sv_position;

float4 color : color;

};

v2f vert (appdata v) {

v2f o;

o.pos = mul( unity_matrix_mvp, v.vertex );

// 计算副法线

float3 binormal = cross( v.normal, v.tangent.xyz ) * v.tangent.w;

o.color.xyz = binormal * 0.5 + 0.5;

o.color.w = 1.0;

return o;

}

fixed4 frag (v2f i) : color0 { return i.color; }

endcg

}

}

}

调试着色器应用于一个模型的副法线 (binormal)。漂亮!

相关阅读

文章点评
相关文章
关注游戏蛮牛公众号送vip