因为我也是个Shader的新手入门着,其实感觉找到门还是挺麻烦的,所以本着自己感觉已经入门了的经验分享一下,如有不对,请指示:
首先可以把Shader看成一个标准的框架:我对新的那个不熟悉所以分享的是旧版的Shader写法;
框架结构:
一、首先从属性中先介绍各个属性的声明及类型:
拿第一个为例子
_Color("Color",Color)=(1,1,1,1) _Color和括号里的字符串“Color”是自己随意定义的名字_Color是在Shader内部用的名字;字符串是在Unity界面显示的名字(尽量统一方便外部获取);
=号后面是默认值;fiex4类型声明
_Vector("Vector",Vector)=(1,2,3,4) Float4类型声明
_Int("Int",Int)= 34234 Int类型声明
_Float("Float",Float) = 4.5 Float类型接收
_Range("Range",Range(1,11))=6 float类型声明
_2D("Texture",2D) ="red"{} Sampler2D声明
_Cube("Cube",Cube) ="white"{} samplerCUBE声明
_3D("Texure",3D) ="black"{} Sampler3D 声明
二、SubShader的Pass块外面没有东西了 至少入门是:
Pass块在需要时 需要一个标签:Tags{"LightMode"="ForwardBase" }
只有定义了正确的LightMode才能得到一些Unity的内置光照变量
其他的东西暂时还没用过;
#include"Lighting.cginc"
标注了包含unity的内置的文件,才可以使用unity内置的一些变量;
这两个导入可以使用
_LightColor0.RGB 第一个直射光的颜色 0一般只有一个直射光;
_WorldSpaceLightPos0.xyz; 第一个直射光的位置=对于每一个顶点的光的方向记得标准化:
UNITY_LIGHTMODEL_AMBIENT.rgb 获取Unity内置的光照模型的设置环境光;
_WorldSpaceCameraPos.xyz
然后是编译指示两个函数,这里我叫做声明抽象方法。。。
#pragma vertex vert 这个是顶点操作的方法体(所有的顶点操作尽量放在这里而且这个函数比下面的像素函数效率要高一些);
#pragma fragment frag 这个是片元函数;操作一些像素点的计算量比较大;计算光照反射的颜色渲染都在这里;
在顶点函数中是可以代替外面的Mesh顶点变形直接更改顶点位置的;(毕竟这里是GPU);
然后我还会定义两个结构体:一个是接收系统返回的各项数据;另一个用来把这些数据转换到片元函数中;
Struct a2v{}:注意这里需要加分号;结构体的命名虽然可以自己定义但是尽量保持这个因为有的一些宏设置会调用这个名字;
我先介绍一下需要从系统返回的数据类型:
float4 POSITION 顶点坐标
float3 NORMAL 模型空间下的法线方向
float4 TEXCOORD0~n 第一套纹理坐标
TANGENT 切线
COLOR 顶点颜色
Struct V2f{};上面同理;
我在介绍一下能传输变量的数据写法:
TEXCOORD0~7 传递纹理坐标
float4/float3 COLOR0 传递4个值或者3个值 (一组值)
float4/float3 COLOR1 传递4个值或者3个值
完善方法体内容自构:
既然已经声明了抽象方法就需要实现它:
v2f vert(a2v v){ v2f f;return f;F的内容需要全被赋值在这里函数里能调用V的系统数据 }
Void frag(v2f f):SV_Target(这个是必须写的是Float4的值为颜色值输出到平面的颜色){
}
然后按照最初的结构完善,然后直接就能运行了:
贴一段代码 现在应该都能看懂了 看不懂的全是规定写法的定义直接查就好了: