区分Unity 中3大Shader
没有嵌套CG语言,也就是代码段中没有CGPROGARAM和ENDCG关键字的,就是固定功能着色器。
嵌套了CG语言,代码段中有surf函数的,就是表面着色器。
嵌套了CG语言,代码段中有#pragma vertex name和 #pragma fragment frag声明的,就是顶点着色器&片段着色器。
从这里开始不加;会报错
Shader "Sbin/vf" {
SubShader {
pass{
//CG代码写到限定范围内
CGPROGRAM
//CG类似类的声明 都要小写不然不报错也不显示
#pragma vertex vert
#pragma fragment frag
//顶点 //变量 传入 2阶向量 //传出一个四阶 pos
void vert(in float2 objPos:POSITION,out float4 pos:POSITION)
{
pos=float4(objPos,0,1);
}
//COLOR=COLOR0
void frag(out float4 col:COLOR0)
{
col=float4(1,0,0,1);
}
ENDCG
}
}
}
然后成了这样 说是以后再解释 我的Game视图什么也看不见 视屏却有
Shader "Sbin/vf" {
SubShader {
pass{
//CG代码写到限定范围内
CGPROGRAM
//CG类似类的声明 都要小写不然不报错也不显示
#pragma vertex vert
#pragma fragment frag
//顶点 //变量 传入 2阶向量 //传出一个四阶 pos
void vert(in float2 objPos:POSITION,out float4 pos:POSITION,out float4 col:COLOR)
{
pos=float4(objPos,0,1);
col=float4(0,0,1,1);//也可以这样赋值 不过frag里的col赋值会覆盖这个
}
//COLOR=COLOR0 片段着色器
void frag(inout float4 col:COLOR)
{
col=float4(0,1,0,1);
}
ENDCG
}
}
}
还是显示不出来 运行会报错但是不知道哪里错了
找到原因了
把matrail的渲染队列调为transparent
然后就Game视图有图了 但是还是运行会报
右边显示没有错误 很神奇
这是人家视频的效果
Shader "Sbin/vf" {
SubShader{
pass {
//CG代码写到限定范围内
CGPROGRAM
//CG类似类的声明 都要小写不然不报错也不显示
#pragma vertex vert
#pragma fragment frag
//顶点 //变量 传入 2阶向量 //传出一个四阶 pos
void vert(in float2 objPos:POSITION,out float4 pos : POSITION,out float4 col : COLOR)
{
pos = float4(objPos,0,1);
col = pos;//也可以这样赋值 不过frag里的col赋值会覆盖这个
}
//COLOR=COLOR0 片段着色器
void frag(inout float4 col:COLOR)
{
//col = float4(0,1,0,1);
}
ENDCG
}
}
}
我换了2018版本的就好了但是图是反过来的
CG基本数据类型
float half fixed bool int sampler*
顶点和片段profile是某硬件可支持的预算的一种特性
Shader "Sbin/vf" {
SubShader{
pass {
//CG代码写到限定范围内
CGPROGRAM
//CG类似类的声明 都要小写不然不报错也不显示
#pragma vertex vert
#pragma fragment frag
//顶点 //变量 传入 2阶向量 //传出一个四阶 pos
void vert(in float2 objPos:POSITION,out float4 pos : POSITION,out float4 col : COLOR)
{
pos = float4(objPos,0,1);
col = pos;//也可以这样赋值 不过frag里的col赋值会覆盖这个
}
//COLOR=COLOR0 片段着色器
void frag(inout float4 col:COLOR)
{
//col = float4(0,1,0,1);
fixed r=-0.5;
fixed g=-0.5;
fixed b=0;
fixed a=0;
//CG里的构造器
col=float4(r,g,b,a);
//CG的基本类型 根据不同精度定义的数据类型 CG不含有指针
//fixed1=fixed 描述的是9位整数被规格化到-1到1 就是2的8次方 256跟颜色的最大值对应
//fixed2=fixed(1,0);
//float可以变为float2 float3 float4 没有五阶
//half half2 half3 half4
//fixed fixed2 fixed3 fixed4
}
ENDCG
}
}
}
![image.png](https://upload-images.jianshu.io/upload_images/15146729-5666734f1a3c801e.png?imageMogr2/auto-orient/strip%7CimageView2/2/w/1240)
官方已经到了5.0 DX11
Shader "Sbin/vf" {
SubShader{
pass {
//CG代码写到限定范围内
CGPROGRAM
#include "UnityCG.cginc"
//CG类似类的声明 都要小写不然不报错也不显示
#pragma vertex vert
#pragma fragment frag
//定义宏
#define MACROFL FL4(fl4.ab,fl3.zy);
typedef float4 FL4;//声明别名
//结构体 2018新版本不能为空
struct v2f{
float4 pos:POSITION;
float2 uv:TEXCOORD0;
};
//顶点 //变量 传入 2阶向量 //传出一个四阶 pos
void vert(in float2 objPos:POSITION,out float4 pos : POSITION,out float4 col : COLOR)
{
pos = float4(objPos,0,1);
col = pos;//也可以这样赋值 不过frag里的col赋值会覆盖这个
}
//COLOR=COLOR0 片段着色器
void frag(inout float4 col:COLOR)
{
//col = float4(0,1,0,1);
fixed r=-0.5;
fixed g=-0.5;
fixed b=0;
fixed a=0;
//CG里的构造器
col=float4(r,g,b,a);
bool bl=false;
col=bl?col:fixed4(0,1,0,1);//true是黑 false是绿
//int 一般会被当作float使用
//描述是几维向量
float2 fl2=float2(1,0);
float3 fl3=float3(1,0,1);
float4 fl4=float4(1,1,0,1);
//Swizzle操作
//float4 fl=float4(fl2,0,1);//红色
//float4 fl=float4(fl2.xy,0,1);//xyzw 或者 rgba按照一定顺序去取可以截取这个值
//float4 fl=float4(fl4.wzyx);//紫色
//float4 fl=float4(fl4.ab,fl3.zy);//紫色
//宏的使用
FL4 fl=MACROFL //紫色
col=fl;
//CG的基本类型 根据不同精度定义的数据类型 CG不含有指针
//fixed1=fixed 描述的是9位整数被规格化到-1到1 就是2的8次方 256跟颜色的最大值对应
//fixed2=fixed(1,0);
//float可以变为float2 float3 float4 没有五阶
//half half2 half3 half4
//fixed fixed2 fixed3 fixed4
//2行4列的矩阵 通常用4x4不会报错但是会黄色警告
// float2x4 M2x4={1,0,0,1,0,1,0,1};//便于阅读也可以{(1,0,0,1),(0,1,0,1)}
float4x4 M2x4={1,0,0,1,0,1,0,1,0,0,0,0,0,0,0,0};
col=M2x4[0];//取矩阵第一行 红色
col=M2x4[1];//取矩阵第二行 绿色
//数组
float arr[4]={1,0.5,0.5,1};//橙红色
col=float4(arr[0],arr[1],arr[2],arr[3]);
//结构体赋值 改值操作
v2f o;
o.pos=fl4;
o.uv=fl2;
}
ENDCG
}
}
}
CG的条件语句
if..else
while
Do...while
for
switch...case(有用但是最好别用,没有良好的支持,容易乱)
我这边试的也有错
Shader "Sbin/vf1" {
SubShader {
pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
void vert(in float2 objPos:POSITION,out float4 pos:POSITION,out float4 col:COLOR)
{
pos=float4(objPos,0,1);
if(pos.x<0 && pos.y<0)
{
col=float4(1,0,0,1);
}
else if(pos.x<0)
{
col=float4(0,1,0,1);
}
else if(pos.y>0)
{
col=float4(1,1,0,1);
}
else
{
col=float4(0,0,1,1);
}
//col=pos;
}
void frag(inout float4 col:COLOR)
{
//最好别用有一定问题 用if else代替
// int i=0;
// switch(i)
// {
// case 0:
// col=float4(1,0,0,1);
// break;
// case 1:
// col=float4(0,1,0,1);
// break;
// case 2:
// col=float4(0,0,1,1);
// break;
// }
}
ENDCG
}
}
}
老师是这样的我的进不来
之后的还可以
Shader "Sbin/vf1" {
SubShader {
pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
void vert(in float2 objPos:POSITION,out float4 pos:POSITION,out float4 col:COLOR)
{
pos=float4(objPos,0,1);
col=pos;
}
void frag(inout float4 col:COLOR)
{
//测试while
int i=0;
while(i<10)
{
i++;
}
if(i==10)
{
col=float4(0,0,0,1);
}
//看下do while
i=0;
do{
i++;
}
while(i<10);
if(i=10)
col=float4(1,1,1,1);
//for 循环有上限 老师的是1023 我的直接报黄说被迫执行一次循环
i=0;
for(i=0;i<10;i++)
{
if(i=10)
col=float4(0.5f,0.5f,0,1);
}
}
ENDCG
}
}
}
这个也动不了 之后把上面提示的错误信息删掉就好了
// Upgrade NOTE: excluded shader from DX11, OpenGL ES 2.0 because it uses unsized arrays
#pragma exclude_renderers d3d11 gles
Shader "Sbin/vf1" {
SubShader {
pass{
CGPROGRAM
// Upgrade NOTE: excluded shader from DX11, OpenGL ES 2.0 because it uses unsized arrays
#pragma exclude_renderers d3d11 gles
#pragma vertex vert
#pragma fragment frag
void Func(out float4 c);
float Func2(float arr[2])
{
float sum=0;
for (int i=0;i
自定义函数
这样每次在头声明函数很麻烦
创建一个cginc的文件
里面放自己的函数
//函数必须在调用之前 或者在之前声明
void Func(out float4 c)
{
//CG参数以值拷贝进行传递
c=float4(0,1,0,1);
}
float Func2(float arr[2])
{
float sum=0;
for (int i=0;i
Shader "Sbin/vf1" {
SubShader {
pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
//自定义函数
#include "sbin.cginc"
void vert(in float2 objPos:POSITION,out float4 pos:POSITION,out float4 col:COLOR)
{
pos=float4(objPos,0,1);
col=pos;
}
void frag(inout float4 col:COLOR)
{
Func(col);
//维度必须相同传递 没有维度不行
float arr[2]={0.5,0.5};
//我的Func2挂掉了 说我的GPU不支持明暗编辑器 把上面自动生成的提示删了就好了
col.x= Func2(arr);
}
ENDCG
}
}
}
是黄色
当Shader和.cginc在同一目录情况下可以直接名字引用
如果放在不同文件夹 应该是安路径找 但是我的就可以直接用 回报黄 然后多试了几下还是会报错 第一个是我放的文件夹 建议这么写
include "Cginc/sbin.cginc"
找到unity安装包路径 这个就是unity自带的CG库 我们可以调用 为我们节省很多时间
Editor/Data/CGIncludes(MAC下是Content/CGIncludes)
Unity函数
这个文库很全
https://wenku.baidu.com/view/3a9db318fad6195f312ba675.html
常用的lerp(a,b,f)是个差值
感觉像是个max()min()结合体
还有这个sin cos结合函数
就是把矩阵行变成列
这个模 就是向量v开平方相加除根号
为什么这么简单的要封装起来,因为他们的算是优化速度最快的,自己写的话不一定有他们快 就跟自己Json写的序列化反序列化 不如人家谷歌那群人写的Protobuf得快
这个是Shader源码
https://github.com/1004019267/ShaderTest/tree/master