最近看了siki老师的shader教程,感谢siki老师,讲课真好。之前看了一些Shader的书,因为没有图形学的基础,所以看的挺痛苦的。然后看了siki老师的视频后,结合以前看的书一下子明了了。
在这里我写下笔记和视频的代码,方便自己以后查看。
在这篇文章里主要介绍了Unity Shader的基本类型和内置的两个方法。代码里有很多注释了,如果想更深入地学习的话建议去看siki老师的视频,讲得非常明白。在这里就不啰唆了。
//这里指定shader的名字,不要求跟文件名保持一致 Shader "TMoon/01-Basic Shader" { // 属性 类似C#的属性,可以在面板复制修改 Properties{ // 属性名字("面板显示的名字",属性的类型) = (属性的默认值) // 这里基本例举了Shader所有的属性(类型) _Color("Color",Color) = (1,1,1,1) // float类型 _Vector("Vector",Vector) = (1,2,3,4) // float类型 _Int("Int",Int) = 1234 // float类型 _Float("Float",Float) = 1.2 // float类型 _Range("Range",Range(1,11)) = 6 // float类型 _2D("Texture",2D) = "red" {} // sampler2D类型 _3D("Texture",3D) = "black"{} // sampler3D类型 _Cube("Cube",Cube) = "white"{} // samplerCUBE类型 例子:天空盒子,6个面 } //SubShader可以写很多个 显卡运行效果的时候,从第一个SubShader开始 //如果第一个SubShader里面的效果都可以实现,那么就使用第一个SubShader, //如果显卡这个SubShader里面某些效果它实现不了,它会自动去运行下一个SubShader SubShader{ //类似Unity的MonoBehaviour,Shader所有的代码放在Pass里执行 //所以至少有一个Pass Pass{ //在这里编写Shader代码 CGPROGRAM // Properties的值需要在这里再声明一次才可以Shader里使用 // 这里有个细节,类似C#的int float double类型,他们精度不一样 // Shader里也有关于数字的精度不一样的类型,分别是float half fixed // float 32位 half 16位 fixed 11位(-2到+2) // 所以关于颜色可以用fixed来存储 fixed4 _Color; float4 _Vector; float _Int; float _Float; half _Range; sampler2D _2D; sampler3D _3D; samplerCUBE _Cube; // 类似MonoBehaviour的Start Update这些内置方法 // 只不过Shader可以让我们自定义这些方法参数,返回值,方法名。 // vertex声明顶点函数 vert为函数名 // 顶点函数的基本作用:完成顶点坐标从模型空间到剪裁空间的转换(从游戏环境转换到视野相机屏幕上) // 调用时机:模型上拥有多少顶点就调用多少次 #pragma vertex vert // fragment声明片元函数 frag为函数名 // 片元函数基本作用:返回模型对应的屏幕上的每一个像素的颜色值(显示模型) // 调用时机:模型上拥有多少像素就调用多少次,所以调用次数和细节大于顶点函数 #pragma fragment frag //一般参数传值方式(比较直接) 后面介绍利用结构体去传值 //通过语义告诉系统,我这个参数是干嘛的 //比如POSITION是告诉系统我需要自动传入模型的顶点坐标 //SV_POSITION这个语义用来解释说明返回值, 意思是返回值是剪裁空间下的顶点坐标 float4 vert(float4 v : POSITION) : SV_POSITION{ //通过矩阵变换将模型顶点坐标变换到裁剪空间(线性代数的知识,或者记住矩阵的作用一般用于变换坐标) return mul(UNITY_MATRIX_MVP,v); } float4 frag() : SV_Target{ // 返回模型每个像素的颜色值 return fixed4(0.5,0.5,1,1); } ENDCG } } // 如果所有的SubShader都失败则使用VertexLit 这里是系统默认的 Fallback "VertexLit" }
Shader的编写基本可以按照这个结构来填充。