Unity Shader 学习笔记 (一) 创建Shader自带代码解读

来源:互联网 发布:表格数据相同怎么合并 编辑:程序博客网 时间:2024/04/29 17:49

Unity Shader 学习笔记 (一)创建Shader自带代码解读

新建Shader代码解读

//"Example"  Shader的分类  "Tint Final Color" Shader名称Shader "Custom/Diffuse Texture" {//定义着色器的属性,在这里定义的属性将被作为输入提供给所有的子着色器Properties {//在Inspector面板中可以调整的变量定义格式/*_Name("Display Name", type) = defaultValue[{options}]_Name - 属性的名字,简单说就是变量名,在之后整个Shader代码中将使用这个名字来获取该属性的内容Display Name - 这个字符串将显示在Unity的材质编辑器中作为Shader的使用者可读的内容type - 这个属性的类型,可能的type所表示的内容有以下几种:Color - 一种颜色,由RGBA(红绿蓝和透明度)四个量来定义;2D - 一张2的阶数大小(256,512之类)的贴图。这张贴图将在采样后被转为对应基于模型UV的每个像素的颜色,最终被显示出来;Rect - 一个非2阶数大小的贴图;Cube - 即Cube map texture(立方体纹理),简单说就是6张有联系的2D贴图的组合,主要用来做反射效果(比如天空盒和动态反射),也会被转换为对应点的采样;Range(min, max) - 一个介于最小值和最大值之间的浮点数,一般用来当作调整Shader某些特性的参数(比如透明度渲染的截止值可以是从0至1的值等);Float - 任意一个浮点数;Vector - 一个四维数;defaultValue 定义了这个属性的默认值,通过输入一个符合格式的默认值来指定对应属性的初始值(某些效果可能需要某些特定的参数值来达到需要的效果,虽然这些值可以在之后在进行调整,但是如果默认就指定为想要的值的话就省去了一个个调整的时间,方便很多)。Color - 以0~1定义的rgba颜色,比如(1,1,1,1);2D/Rect/Cube - 对于贴图来说,默认值可以为一个代表默认tint颜色的字符串,可以是空字符串或者"white","black","gray","bump"中的一个Float,Range - 某个指定的浮点数Vector - 一个4维数,写为 (x,y,z,w)另外还有一个{option},它只对2D,Rect或者Cube贴图有关,在写输入时我们最少要在贴图之后写一对什么都不含的空白的{},当我们需要打开特定选项时可以把其写在这对花括号内。如果需要同时打开多个选项,可以使用空白分隔。可能的选择有ObjectLinear, EyeLinear, SphereMap, CubeReflect, CubeNormal中的一个,这些都是OpenGL中TexGen的模式各种类型的属性定义:_MainColor ("Main Color",Color) = (1,1,1,1)_MainTex ("Base (RGB)", 2D) = "white" {}_MainRect ("Main Rect",Rect) = "black" {}_MainCube ("Main Cube",Cube) = "gray" {}_MainRange ("Main Range",Range(0.0,1.0)) = 0.5_MainFloat ("Main Float",Float) = 0.314_MainVector ("Main Vector",Vector) = (0.1,0.2,0.3,0.4)*/_MainTex ("Base (RGB)", 2D) = "white" {}}//一个Shader中可以包含任意多个SubShader,但是只有一个SubShader被显卡选中并最终执行//如果我们写的SubShader最后都没有被选中的话, 这时候就会默认去执行FallBack后面跟着那个Shader了.    SubShader {//是告诉渲染设备,这个使用这个Shader的材质是一个不透明的物体Tags { "RenderType"="Opaque" }/*Tag 里面可以类似 "RenderType" = "XXX" 或者 "Quene" = "XXX"(指定渲染顺序队列) 或者 "ForceNoShadowCasting"="True"(从不产生阴影)预定义的Queue有:Background - 最早被调用的渲染,用来渲染天空盒或者背景Geometry - 这是默认值,用来渲染非透明物体(普通情况下,场景中的绝大多数物体应该是非透明的)AlphaTest - 用来渲染经过Alpha Test的像素,单独为AlphaTest设定一个Queue是出于对效率的考虑Transparent - 以从后往前的顺序渲染透明物体Overlay - 用来渲染叠加的效果,是渲染的最后阶段(比如镜头光晕等特效)这些预定义的值本质上是一组定义整数,Background = 1000, Geometry = 2000, AlphaTest = 2450, Transparent = 3000,最后Overlay = 4000。在我们实际设置Queue值时,不仅能使用上面的几个预定义值,我们也可以指定自己的Queue值,写成类似这样:"Queue"="Transparent+100",表示一个在Transparent之后100的Queue上进行调用。通过调整Queue值,我们可以确保某些物体一定在另一些物体之前或者之后渲染,这个技巧有时候很有用处{"RenderType" = “Transparent”},意味着我们的shader只会输出半透明或透明的像素值*///Level of DetailLOD 200/*VertexLit及其系列 = 100Decal, Reflective VertexLit = 150Diffuse = 200Diffuse Detail, Reflective Bumped Unlit, Reflective Bumped VertexLit = 250Bumped, Specular = 300Bumped Specular = 400Parallax = 500Parallax Specular = 600*///这是一个开始标记,表明从这里开始是一段CG程序CGPROGRAM//它声明了我们要写一个表面Shader,并指定了光照模型#pragma surface surf Lambert/*#pragma surface surfaceFunction lightModel [optionalparams]surface - 声明的是一个表面着色器surfaceFunction - 着色器代码的方法的名字lightModel - 使用的光照模型*///重新定义一个在Properties中定义的变量,名字必须要保持一致sampler2D _MainTex;//我们自定义的Input结构体,需要计算的数据需要放到这个结构体中struct Input {//在CG程序中,我们有这样的约定,在一个贴图变量(在我们例子中是_MainTex)之前加上uv两个字母,//就代表提取它的uv值,(其实就是两个代表贴图上点的二维坐标 )//提取_MainTex 这张贴图的uv值float2 uv_MainTex;};//CG规定了声明为表面着色器的方法(就是我们这里的surf)这个方法的参数是固定的 不可以随便更改//(表面函数)每个像素调用一次//Input其实是需要我们去定义的结构,SurfaceOutput是已经定义好了里面类型输出结构//struct SurfaceOutput {  //half3 Albedo;     //像素的颜色//half3 Normal;     //像素的法向值//half3 Emission;   //像素的发散颜色//half Specular;    //像素的镜面高光//half Gloss;       //像素的发光强度//half Alpha;       //像素的透明度//};//着色器函数void surf (Input IN, inout SurfaceOutput o) {//tex2d函数,这是CG程序中用来在一张贴图中对一个点进行采样的方法,//返回一个float4。这里对_MainTex在输入点上进行了采样,并将其颜色//的rbg值赋予了输出的像素颜色,将a值赋予透明度。//于是,着色器就明白了应当怎样工作://即找到贴图上对应的uv点,直接使用颜色信息来进行着色half4 c = tex2D (_MainTex, IN.uv_MainTex);//输出结构体中的 像素的颜色 这个字段 我们将其赋值为 _MainTex  UV采样后的rgb值o.Albedo = c.rgb;//输出结构体中的 像素的透明度 这个字段 我们将其赋值为 _MainTex  UV采样后的a值o.Alpha = c.a;}//ENDCG与CGPROGRAM是对应的,表明CG程序到此结束ENDCG} //如果这个shader在当前环境中运行失败后,会默认调用Unity自带的Diffuse ShaderFallBack "Diffuse"}


0 0
原创粉丝点击