一、Shader 程序的基本结构##
首先是一些属性定义,用来指定这段代码将有哪些输入。接下来是一个或者多个的子着色器,在实际运行中,哪一个子着色器被使用是由运行的平台所决定的。子着色器是代码的主体,每一个子着色器中包含一个或者多个的Pass。在计算着色时,平台先选择最优先可以使用的着色器,然后依次运行其中的Pass,然后得到输出的结果。最后指定一个回滚,用来处理所有Subshader都不能运行的情况(比如目标设备实在太老,所有Subshader中都有其不支持的特性)。
需要提前说明的是,在实际进行表面着色器的开发时,我们将直接在Subshader这个层次上写代码,系统将把我们的代码编译成若干个合适的Pass。废话到此为止,下面让我们真正实际进入Shader的世界吧。
二、进入Shader内部代码结构熟悉##
属性定义
SuberShader(子着色器)
三、简单Shader展示##
Shader "Custom/ShaderTest" {
Properties {
_Color ("Color", Color) = (1,1,1,1)
//在输入贴图时候,必须要写一个什么都不含的{}
//需要打开特定选项时可以把其写在这对花括号内.
//如果需要同时打开多个选项,可以使用空白分隔
_MainTex ("Albedo (RGB)", 2D) = "white" {}
_Glossiness ("Smoothness", Range(0,1)) = 0.5
_Metallic ("Metallic", Range(0,1)) = 0.0
_MainColor("Main Color",Color)=(0,0,0,1)
_Testure("Texture",2D)="White"{}
}
SubShader {
//表面着色器可以被若干的标签(tags)所修饰
//硬件将通过判定这些标签来决定什么时候调用该着色器
Tags { "RenderType"="Opaque" }//标签内部就是告诉系统渲染非透明的物体调用我们
//Tags { "RenderType"="Transparent" }//渲染透明物体调用
//Tags { "IgnoreProjector"="True" }//不被Projectors影响
//Tags{ "ForceNoShadowCasting"="True" }//不产生阴影
//指定渲染队列(下面有系统预设的队列)
//Tags{ "Queue"="Geometry" }
//Background--最早被调用的渲染,用来渲染天空盒或者背景
//Geometry--默认值,用来渲染非透明物体(普通情况下,场景中的绝大多数物体应该是非透明的)
//AlphaTest--用来渲染经过Alpha Test的像素,单独为AlphaTest设定一个Queue是出于对效率的考虑
//Overlay--用来渲染叠加的效果,是渲染的最后阶段(比如镜头光晕等特效)
//Transparent--以从后往前的顺序渲染透明物体
//预设的队列本质就是定义的整数(有点像枚举值)
//Background=1000,Geometry=2000,AlphaTest=2450
//Transparent=3000,最后Overlay=4000
//如何自定义列表
//Tags{ "Queue"="Transparent+200" }//通过调用Queue值,确保渲染的先后顺序
//Unity的内建Diffuse着色器的设定值,这个数值决定了我们能用什么样的Shader
//这个数值可以在unity中的质量设定中设定
LOD 200//着色器的设定值
//Decal, Reflective VertexLit = 150
//Diffuse = 200
//Diffuse Detail, Reflective Bumped Unlit, Reflective Bumped VertexLit = 250
//Bumped, Specular = 300
//Bumped Specular = 400
//Parallax = 500
//Parallax Specular = 600
//Shader字体:也就是将输入转变成输出的代码部分
CGPROGRAM//开始CG语言的编写
// Physically based Standard lighting model, and enable shadows on all light types
//surface:申明的是一个表面着色器
//surf:着色器代码的方法的名字,下方的代码有这个函数
//Standard:标准
//fullforwardshadows:光照模型
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
//在CG中,sampler2D就是和texture所绑定的一个数据容器接口
//其实就是内存存储的RGB通道,sampler2D:就是GLSL中的2D贴图的类型
//其他类型:sampler1D,sampler3D,samplerCube
// 图片
sampler2D _MainTex;
// 用来获取MainTex的UV信息
struct Input {
float2 uv_MainTex; // 用来获取MainTex的UV信息
vec2 coordinate;//float和vec都可以在之后加入一个2到4的数字,来表示被打包在一起的2到4个同类型数
float4 color;
};
half _Glossiness;//half指的是半精度浮点数,精度最低,运算性能相对比高精度浮点数高一些
half _Metallic;
// 颜色属性
fixed4 _Color;
// SurfaceOutputStandard 表面着色器输出一个标准的结构体
//着色器的工作核心,着色器就是给定了输入,然后给出输出进行着色的代码,第一个参数是Input结果,第二个参数是一个inout的SurfaceOutput结构
void surf (Input IN, inout SurfaceOutputStandard o) {
// Albedo comes from a texture tinted by color
// 获取图片 * 我们选定的颜色
//fixed4:定点书:整形数据类型,作用就是把所有数进行转换,得到相应类型的整形表达
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
// 输出的像素的颜色 = 图像的颜色(RGB)
o.Albedo = c.rgb;
// Metallic and smoothness come from slider variables
// 输出的颜色效果(金属方面) = 设定的金属值
o.Metallic = _Metallic;
// 输出的光滑粗糙程度 = 设置的光滑粗燥程度
o.Smoothness = _Glossiness;
// 输出的透明通道 = 图像的透明通道
o.Alpha = c.a;
}
ENDCG//结束CG语言的编写
}
FallBack "Diffuse"
}
四、参考##
https://docs.unity3d.com/Manual/SL-SurfaceShaderExamples.html
https://onevcat.com/2013/08/shader-tutorial-2/
http://www.tuicool.com/articles/JvYJ3em
http://www.itnose.net/detail/6143450.html
五、CG语音学习资料##
http://blog.csdn.net/liu_lin_xm?viewmode=contents
https://developer.nvidia.com/cg-toolkit