1、shader代码
Shader "xxx/ddd"
{
SubShader
{
pass
{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
#include "unitycg.cginc"
float r;
float g;
float b;
struct xxx
{
float4 pos:POSITION;
};
xxx vert(appdata_base data)
{
xxx x;
x.pos = mul(UNITY_MATRIX_MVP,data.vertex);
return x;
}
fixed4 frag():COLOR
{
return fixed4(r,g,b,1);
}
ENDCG
}
}
}
2、C#代码
using UnityEngine;
using System.Collections;
public class SetColorValue : MonoBehaviour
{
[Range(0,1)]
public float r;
[Range(0, 1)]
public float g;
[Range(0, 1)]
public float b;
public void Update()
{
this.GetComponent<Renderer>().material.SetFloat("r", r);
this.GetComponent<Renderer>().material.SetFloat("g", g);
this.GetComponent<Renderer>().material.SetFloat("b", b);
}
}
3、效果
注意点:
1/unity的顶点和片段着色器要求vertext函数和fragment函数都要存在,否则报错。
2/顶点程序负责处理顶点,包括几何变换等。变换之后,要把顶点数据传递给片段程序。
3/顶点程序需要处理顶点,那么顶点的数据从什么地方来?由谁提供给顶点程序。
在unity shader中使用in和out以及inout关键字来表明输入或者输出,inout兼输入和输出。同时unity将一些数据已经封装好,只需要使用in作为关键字,并从封装好的数据中取出即可使用,比如在Unity\Editor\Data\CGIncludes安装目录中,有一个UnityCG.cginc文件里面的appdata_base就包含了顶点的数据。我们使用的时候只需要#include “unitycg.cginc”即可在顶点程序中使用,如下面:
void vertex(appdata_data data, out float4 pos:POSITION)
{
pos = mul(UNITY_MATRIX_MVP, data.vertex);
}
4/数据类型和语义。
数据类型用于表明变量的存储方式;在shader中还引入了一个新的东西,就是语义,它用来表明数据的用途,比如同是float4可以用于color也可用于position。
5/unity shader中不同语义相同数据类型的变量是可以赋值的。比如:
float4 pos:POSITION
float4 col:COLOR
这个pos = col或者col = pos是合法的。
6/unity shader中向量最高阶为4,比如float4,fixed4,没有float5或者fixedr5,但是有float1,float2,float3和fixed1,fixed2,fixed3。
7/如果没有out作为输出,顶点程序的输出可以采取什么方式?采取函数返回值得方式,比如:
float4 vert(appdata_base data, out float4 pos:POSITION):COLOR
{
pos = mul(UNITY_MATRIX_MVP, data.vertex);
return pos;
}
这里有两点注意,其中顶点程序用于输出处理后的顶点,所以在参数中使用out关键字修饰pos。同时,我们还可以在顶点程序中直接处理颜色信息,比如这里将pos直接返回,其语义限定为COLOR。
8/与第7条重复,即函数带上返回值,带上语义,可以代替out作为输出。
9/
//输出了一个顶点和颜色
float4 vert(appdata_base data, out float4 pos:POSITION):COLOR
{
pos = mul(UNITY_MATRIX_MVP, data.vertex);
return pos;
}
//接收两个参数一个是顶点,一个是颜色;其中顶点的输出不需要接收可以省略。
void frag(out float4 col:COLOR)
{
col = float4(1,0,0,1);
}
10/使用结构体来优化代码
struct xxx
{
float4 pos:POSITION; //位置
float4 col:COLOR; //颜色
};
xxx vert(appdata_base data)
{
xxx x;
x.pos = mul(UNITY_MATRIX_MVP,data.vertex);
x.col = float4(1,1,0,1);
return x;
}
float4 frag(xxx x):COLOR
{
return x.col;
}
11/_Object2World这个是模型到世界变换矩阵,使用这个矩阵和模型相乘:
appdata_base data;
float4 pos = mul(_Object2World, data.vertex);
这个得到了模型的世界坐标。