赞
踩
2017/8/29第一次记录笔记。
1.Shader能干什么{
通过写Shader可以对渲染过程进行配置,从而达到想要实现的画面效果
}
2.如何在Unity中创建Shader文件{
或者
在新版的Unity中,创建Shader时会有四个预定义Shader可以选择,分别是Standard Surface Shader,Unlit Shader,Image Effect Shader,Computer Shader.
差别:创建的四类Shader文件中,Unity已经替我们写好的代码不同。
}
3.开始学习Shader代码{
a/Shader代码的基本结构{
}
b/了解结构中每一小块{
先按照2小节所示创建一个UnlitShader,通过分析其中的代码,对Shader代码的结构有个更清晰的了解。
Shader "Unlit/NewUnlitShader"
{<!-- -->
Properties
{<!-- -->
_MainTex ("Texture", 2D) = "white" {}
}
SubShader
{<!-- -->
Tags { "RenderType"="Opaque" }
LOD 100
Pass
{<!-- -->
CGPROGRAM
#pragma vertex vert
#pragma fragment frag
// make fog work
#pragma multi_compile_fog
#include "UnityCG.cginc"
struct appdata
{<!-- -->
float4 vertex : POSITION;
float2 uv : TEXCOORD0;
};
struct v2f
{<!-- -->
float2 uv : TEXCOORD0;
UNITY_FOG_COORDS(1)
float4 vertex : SV_POSITION;
};
sampler2D _MainTex;
float4 _MainTex_ST;
v2f vert (appdata v)
{<!-- -->
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
UNITY_TRANSFER_FOG(o,o.vertex);
return o;
}
fixed4 frag (v2f i) : SV_Target
{<!-- -->
// sample the texture
fixed4 col = tex2D(_MainTex, i.uv);
// apply fog
UNITY_APPLY_FOG(i.fogCoord, col);
return col;
}
ENDCG
}
}
}
①先看第一行代码Shader "Unlit/NewUnlitShader"
Shader后面的字符串是什么呢,也许我们先创建 一个材质 会更容易明白
在Project面板中,把我们的Shader拖拽到新建的Material上
观察New Material的Inspector面板
我们可以看到材质的Shader栏中显示的和我们第一行代码Shader "Unlit/NewUnlitShader"中的字符串是一样的
所以这段字符串描述的就是材质Shader栏中的路径,我们可以在Shader栏中选择我们要赋给材质的Shader
②Properties属性定义:顾名思义——在这个位置,我们可以定义一些属性,与其说属性,不如说变量更明了,但这里
定义的变量不可以直接使用,关于如何使用,后面我会记下(忘了的话,自打30大板= =)。那么定义属性的语法是什么?
属性值(property)定义的形式:
_Name(“Displayed Name”,type) = default value{options}
嗯。。。第一次见的话,看起来确实挺奇怪的
Name——属性名,一般会在属性名前加上下划线标识。
Displayer Name——显示名称,后面再详细说
type——属性类型
default value{options}——默认值
这里先记一下type类型和default value默认值相关的:
这里定义的属性类型比较特别,和我们一般写代码时定义的变量类型不太一样。属性类型有下列几种:
属性对应的defult value形式:
而{option}只和2D,Rect或者Cube有关,在设置默认值时我们在这个位置至少要写一对空的花括号{},嗯,那么暂且先只写一对花括号好了,至于括号内具体可以填什么值留到之后再来研究。到这,对属性定义有了一个大概的了解,那么接下来来实践一下,先清空Properties块中的代码,然后把所有的属性类型都写一遍。
Properties
{<!-- -->
_Color("Color_", Color) = (1,1,1,1)
_2D("2D_", 2D) = "white"{}
_Rect("Rect_", Rect) = "black"{}
_Cube("Cube_", Cube) = "gray"{}
_Range("Range_", Range(0.0,2.0)) = 1.0
_Float("Float_", Float) = 2.0
_Vector("Vector_", Vector) = (2,2,2,2)
}
除了定义变量,它有一个更重要的作用,作为Shader代码和Unity沟通的一个媒介。。。嗯。。。其实这里定义的变量有点像我们在Unity写脚本的时
候定义的public变量,可以直接在Unity界面中直接赋值。我们只需要把Shader拖拽到Material上(当然,前面已经那么做过了,就像把脚本拖拽到
GameObject上一样),然后我们就可以在该Material的Inspector上直接给那些属性赋值了(就像可以在前面的GameObject的Inspector上直接给public
变量赋值)
好的,属性定义小节暂时结束
③子着色器的介绍:
回顾我们的Shader的代码,在子着色器SubShader中的第一行代码是:Tags { "RenderType"="Opaque" }
What!怎么又蹦出一个Tags来了?好吧好吧。。。冷静
Tags标签,是什么的标签?是子着色器的标签,子着色器可以有若干标签,硬件根据子着色器的标签来判断是否要使用该子着色器,什么时候使用
该着色器
此处的Tags { "RenderType"="Opaque" }表示在我们的程序渲染 不透明 的物体时,将调用这个子着色器,另一个类似的标签是Tags {“RenderType” = “Transparent”}
显而易见的,这个标签表示我们的程序渲染 透明 的物体时,将调用这个子着色器。
其他的一些常用的标签:
"IgnoreProjector"="True" 忽略Projector的影响
"ForceNoShadowCasting"="True" 从不产生阴影
"Queue"="XXX"系列 XXX:
Background - 最早被调用的渲染,用来渲染天空盒或者背景
Geometry - 这是默认值,用来渲染非透明物体(普通情况下,场景中的绝大多数物体应该是非透明的)
AlphaTest – 顺利通过alpha测试的像素(alpha-test是指当前像素的alpha小于一定的值就舍弃该像素)使用该渲染顺序。单独设置该渲
染顺序是因为在所有实体渲染过后,该渲染顺序将对渲染经过alpha测试的物体更有效率。
Transparent – 该渲染标签所属的物体将在标签为Geometry和AlphaTest之后的物体渲染,并且这些贴着Transparent的所有物体本身是
从后往前依次渲染的。
Overlay - 用来渲染叠加的效果,是渲染的最后阶段(比如镜头光晕等特效)
实际上这里的标签都分别对应一个整数,Background = 1000, Geometry = 2000, AlphaTest = 2450, Transparent = 3000 ,Overlay = 4000。我们还可以通过写成形如 ”Queue" = "Transparent+100" (表示在Transparent之后100的Queue上调用)的形式,来指定我们自己的Queue值,从而确保一些物体在另一些物体之前或之后渲染。
Tags完了,后面又来了个LOD。。。。。。
LOD,Level of detail(细节层次)的缩写,当我们SubShader中LOD值大于Unity设置的最大LOD值时,这个SubShader就不可用了。
Unity设置最大LOD值位置:
太好了,终于到了我们前面提到过的Pass块了。
可以看到,Pass块中第一行代码和最后一行代码分别为CGPROGRAM,ENCG。这两行代码作为一个界限,它俩中间的代码是主要的Shader代码部分。这部分代码使用的是CG/HLSL代码,下一次,将学习主要的CG语法。然后再分析接下来的代码。
}
}
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。