OpenGL DirectX
OpenGL 使用GLSL编写shader DirectX 使用HLSL编写shader 英伟达 使用CG编写shder
shader分类
1.表面着色器 surface shader 2.顶点/片元着色器 Vertex/Fragment shader 3.固定函数着色器 Fixed Function shader
shader基本代码
Shader "ym/ymshader01"{//此处是指定shader的名字,不要求跟文件名一致,且在选择shader时会按照这个路径选择
Properties{
//属性
// _Color是在接下来的subshader里面用到
//color是在unity里面的名字
//Color则是属性类型名
//其他属性都是这种命名格式
_Color("color",Color)=(1,1,1,1)
_Vector("vector",vector)=(1,2,3,4)
}
//子Shader,可以有很多个
//显卡运行效果的时候,会从第一个SubShader进行判断,如果第一个效果都可以实现,那么就使用第一个
//如果显卡对于当前SubShader一些效果实现不了,会自动去判断下一个子Shader
SubShader{
//必须要有一个pass
pass{
//要在CGPROGRAM和ENDCG之间用CG语言编写shader代码
CGPROGRAM
ENDCG
}
}
//如果所有的SubShader都无法实现,便实现此Shader
Fallback "VertexLit"
}
常见属性类型
Properties{
//属性
// _Color是在接下来的subshader里面用到
//color是在unity里面的名字
//Color则是属性类型名
//其他属性都是这种命名格式
_Color("color",Color)=(1,1,1,1)
_Vector("vector",vector)=(1,2,3,4)
//常见的属性类型
//int类型
_int("int",int)=123
//float类型
_float("float",float)=2.3
//范围类型 限定好了范围
_range("range",Range(1,11))=3
//2D图片类型 前面的"red"是默认颜色
_2d("texture",2D)="red"{}
//cube类型 ??
_cube("cube",Cube)="white"{}
//3D类型
_3d("3d",3D)="black"{}
}
属性的使用
属性在用之前,要再定义一遍
SubShader{
pass{
CGPROGRAM
float4 _Color;
float4 _Vector;
float _int;
float _float;
float _range;
sampler2D _2d;
sampler3D _3d;
samplerCUBE _cube;
ENDCG
}
}
小tips
fixed half float 基本可以互换,只不过float范围大于half大于fixed
顶点函数与片元函数
Shader "ym/shader02"{
SubShader{
pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
xxx vert(xxx){
}
xxx frag(xxx){
}
ENDCG
}
}
Fallback "VertexLit"
}
完善顶点函数
float4 vert(float4 v : POSITION) : SV_POSITION{
return mul(Unity_Matrix_MVP,v);
}
完善片元函数
此处可以有能看得到的效果了
fixed4 frag() :SV_TARGET{
return fixed4(0.5,1,0.5,1);
}
法线方向和纹理坐标
struct a2v{
float4 vertex:POSITION;
float3 normal:NORMAL;
float4 texcoord0:TEXCOORD0;
}
float4 vert(a2v a2v) : SV_POSITION{
return mul(Unity_Matrix_MVP,a2v.vertex);
}
此处踩了一个坑,该加分号的地方不要忘记
片元函数与顶点函数之间数据传递
此处采取将顶点函数获得的法线方向传给片元函数并展示成颜色的形式
Shader "ym/shader01"{
SubShader{
pass{
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
struct a2v{
float4 vertex:POSITION;
float3 normal:NORMAL;
float4 texcoord0:TEXCOORD0;
};
struct v2f{
float4 position:SV_POSITION;
float3 temp:COLOR0;
};
v2f vert(a2v v){
v2f f;
f.position= UnityObjectToClipPos(v.vertex);
f.temp = v.normal;
return f;
}
fixed4 frag(v2f f) :SV_TARGET{
return fixed4(f.temp,1);
}
ENDCG
}
}
Fallback "VertexLit"
}
此处有个坑:mul(Unity_Matrix_MVP,a2v.vertex);不能用了,要改成UnityObjectToClipPos(v.vertex);
标准光照模型
光照模型是一个公式,使用这个公式来计算在某个点的光照效果 光分为四部分: 自发光 高光反射 漫反射 环境光
漫反射公式
Diffuse = 直射光颜色 * max(0,cos(光和法线的夹角)) 其中,夹角的计算是使用点乘来得到的,即 同时还需要定义正确的LightMode来得到Unity的内置光照变量
Tags{"LightMode" = "ForwardBase"}
CGPROGRAM
#include "Lighting.cginc"
Tags{“LightMode” = “ForwardBase”}在pass内部,CGPROGRAM外部 #include "Lighting.cginc"在CGPROGRAM内部
|