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

Unity3D - Shader - 顶点/片段着色器的基本结构

2017-12-05 21:07 453 查看

基本结构

Shader "MyShaderName" {
Properties {
// 属性
}

SubShader {
// 针对显卡A的SubShader
Pass {
// 设置渲染状态和标签

// 开始CG代码片段
CGPROGRAM

// 该段代码片段的编译指令,例如:
#pragma vertex vert
#pragma fragment frag

// CG代码写在这里

ENDCG

// 其他设置
}

// 其他需要的Pass
}

SubShader {
// 针对显卡B的SubShader
}

// 上述SubShader都失败后用于回调的Unity Shader
Fallback "VertexLit"
}


白色Shader

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Unity Shaders Book/Chapter 5/Simple Shader" {
SubShader {
Pass {
CGPROGRAM

// 两个重点的编译指令
// 更通用的表示, name是指定的函数名:
// #pragma vertex name
// #pragma fragment name
#pragma vertex vert         // 告诉Unity哪个函数包含了顶点着色器代码
#pragma fragment frag       // 告诉Unity哪个函数包含了片元着色器

// POSITION和SV_POSITION都是Cg/HLSL中的语义
// POSITION 告诉Unity把模型的顶点坐标填充到输入参数v中
// SV_POSITION 告诉Unity顶点着色器的输出是裁剪空间中的顶点坐标
float4 vert(float4 v : POSITION) : SV_POSITION {
// 把顶点坐标从模型空间转换到裁剪空间中
// UNITY_MATRIX_MVP矩阵是Unity内置的模型*观察*投影矩阵
// mul(UNITY_MATRIX_MVP,*)
return UnityObjectToClipPos(v);
}

// SV_Target是HLSL的一个系统语义,
// 把用户的输出颜色存储到一个渲染目标(render target),
// 这里输出到默认的帧缓冲中。
// 片元着色器输出的颜色每个分量在[0,1],其中(0,0,0)表示黑色
// (1,1,1)表示白色
fixed4 frag() : SV_Target {
return fixed4(1.0, 1.0, 1.0, 1.0);
}

ENDCG
}
}
}


传递更多数据

// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'

Shader "Unity Shaders Book/Chapter 5/Simple Shader1" {
SubShader {
Pass {
CGPROGRAM

#pragma vertex vert
#pragma fragment frag

// 使用一个结构体来定义顶点着色器
struct a2v {
// POSITION 语义告诉 Unity,用模型空间的顶点坐标填充vertex变量
float4 vertex : POSITION;
// NORMAL语义告诉 Unity,用模型空间的法线方向填充normal变量
float3 normal : NORMAL;
// TEXCOORD0语义告诉Unity,用模型的第一套纹理坐标填充texcoord变量
float4 texcoord : TEXCOORD0;
};

float4 vert(a2v v) : SV_POSITION {
// 使用v.vertex来访问模型空间的顶点坐标
return UnityObjectToClipPos(v.vertex);
}

fixed4 frag() : SV_Target {
return fixed4(1.0, 1.0, 1.0, 1.0);
}

ENDCG
}
}
}


顶点着色器和片元着色器通信

Shader "Unity Shaders Book/Chapter 5/Simple Shader2" {
SubShader {
Pass {
CGPROGRAM

#pragma vertex vert
#pragma fragment frag

struct a2v {
float4 vertex : POSITION;
float3 normal : NORMAL;
float4 texcoord : TEXCOORD0;
};

struct v2f {
// SV_POSITION语义告诉Unity,pos里包含了顶点在裁剪空间
// 中的位置信息
float4 pos : SV_POSITION;
// COLORO语义可以告诉用于存储颜色信息
fixed3 color: COLOR0;
};

v2f vert(a2v v)  {
// 声明输出结构
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
// v.normal 包含了顶点的法线方向,其分量范围在[-1.0, 1.0]
// 下面的代码把分量范围映射到了[0.0, 1.0]
// 存储到o.color中传递给片元着色器
o.color = v.normal * 0.5 + fixed3(0.5, 0.5, 0.5);
return o;
}

fixed4 frag(v2f i) : SV_Target {
// 将插值后的i.color显示到屏幕上
return fixed4(i.color, 1.0);
}

ENDCG
}
}
}


ShaderLab中属性的类型和Cg中变量的类型之间的匹配关系:

ShaderLab属性类型Cg变量类型
Color, Vectorfloat4, half4, fixed4
Range, Floatfloat, half, fixed
2Dsampler2D
CubesamplerCube
3Dsampler3D

float/half/fixed

Cg/HLSL中三种精度的数值类型:

类型Cg/HLSL中3个精度的数值类型
float最高精度的浮点值。通常使用32位来存储
half中等精度的浮点值。通常使用16位来存储,范围精度是-60000 ~ +60000
fixed最低精度的浮点值。通常使用11位来存储,经度范围是-2.0 ~ +2.0
可以使用fixed来存储颜色和单位矢量,如果要存储更大范围的数据可以选择half,最差的情况再选择float。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: