SurfaceShader入门,Unity2019.3自创建SurfaceShader初始代码注释解析
程序员文章站
2022-03-02 10:21:48
...
啊哈哈哈,咱今天也开始Shader入门啦,各种高大上的咱也不会用,这也就是给自己写的备忘录,有需要的小伙伴可以参照一下,
我用的是Unity推荐的SurfaceShader!
Shader "Custom/TrySurfaceShader"
{
//定义着色器属性,在这里定义的属性将被作为输入提供给所有的子着色器。
Properties
{
// _Name代表属性名,如Color,MainTex,Glossiness ,Metallic 等
// ”Display Name”则是在Inspector中显示名字
// type代表属性:
// Color - 一种颜色,由RGBA(红绿蓝和透明度)四个量来定义;
// 2D - 一张2的阶数大小(256,512之类)的贴图。这张贴图将在采样后被转为对应基于模型UV的每个像素的颜色,最终被显示出来.对于贴图来说,默认值可以为一个代表默认tint颜色的字符串,可以是空字符串或者”white”,”black”,”gray”,”bump”中的一个;
// Rect - 一个非2阶数大小的贴图;
// Cube - 即Cube map texture(立方体纹理),简单说就是6张有联系的2D贴图的组合,主要用来做反射效果(比如天空盒和动态反射),也会被转换为对应点的采样;
// Range(min, max) - 一个介于最小值和最大值之间的浮点数,一般用来当作调整Shader某些特性的参数(比如透明度渲染的截止值可以是从0至1的值等);
// Float - 任意一个浮点数;
// Vector - 一个四维数;
// defaultValue 定义了这个属性的默认值,通过输入一个符合格式的默认值来指定对应属性的初始值(某些效果可能需要某些特定的参数值来达到需要的效果, 这些值可以在之后在进行调整,但是如果默认就指定为想要的值的话就省去了一个个调整的时间)。
// _Name("Display Name",type) = defaultValue[{potions}]
_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 //金属光泽度
}
SubShader
{
// Tags :tags标签是三种类型的shader都具有的标签,决定硬件什么调用该子着色器
// Tags标签里面默认的“RenderType” = ”Opaque”,是告诉系统应该在渲染非透明物体时调用这个SubShader
// “RenderType” = ”Transparent”表示在渲染含有透明效果的物体时调用该Sunshader,
// ①.”Queue”:定义渲染顺序。预制的值有这些
// ”Background”。值为1000。比如用于天空盒,最早被调用的渲染,用来渲染天空盒或者背景。
// ”Geometry”。值为2000。大部分物体在这个队列。不透明的物体也在这里,这是默认值,用来渲染非透明物体(普通情况下,场景中的绝大多数物体应该是非透明的)。
// ”AlphaTest”。值为2450。已进行AlphaTest的物体在这个队列。
// ”Transparent”。值为3000。以从后往前的顺序渲染透明物体。
// ”Overlay”。值为4000。比如镜头光晕。
// 用户可以定义任意值,比如”Queue” = ”Geometry + 10”
// ②“RenderType”:定义渲染类型。预制的值有这些
// ”Opaque”:绝大部分不透明的物体都使用这个;
// ”Transparent”:绝大部分透明的物体、包括粒子特效都用这个;
// ”Background”:天空盒都使用这个;
// ”Overlay”:GUI、镜头光晕都使用这个;
// ③”ForceNoShadowCasting”:定义物体是否有阴影效果
// “true”。表示有阴影
// “false”。表示没有阴影
Tags { "RenderType" = "Opaque" }
// LOD:Level of Detail的缩写,它表示着色器的细节层次效果。在某些硬件比较差的系统上,可以设置低一点的值,减少细节的显示。Unity内置shader的LOD值如下
// VertexLit kind of shaders = 100
// 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
LOD 200
CGPROGRAM
// 这段编译指令声明了我们要写一个Surface Shader,并指定了光照模型。写法是这样的
// surface - 声明的是一个表面着色器
// surfaceFunction - 着色器代码的方法的名字
// lightModel - 使用的光照模型。
// 这段代码默认的surfaceFunction为surf,在源码的底部看到在这儿声明了的surf函数。默认的lightModel为Standard。
//#pragma surface surfaceFunction lightModel [optionalparams]
// lightModel光照模型
// Lambert:该光照模型能很好的表示粗糙表面的光照,但不能表现出镜面反射高光
// Toon:这是Toon shading(又称 cel shading).这是一种非逼真渲染风格,通过改变了光在一个模型上反射实际情况来给人以手绘的感觉
// BlinnPhong:仿真镜面反射材料
// Standard:Unity5中默认的光照模式是Standard, 其引入了 物理渲染(PBR), 但是与其它光照模型没有什么不同。相比于朗伯反射, PBR提供了一个更加逼真的光线物体作用模型,PBR考虑了材料的物理属性, 比如能量守恒以及光的散射
// Physically based Standard lighting model, and enable shadows on all light types
// 水波纹效果
#pragma surface surf Standard fullforwardshadows
// Use shader model 3.0 target, to get nicer looking lighting
#pragma target 3.0
// shader中常用的数据类型
// 3种基本数值类型:float、half和fixed。
// 这3种基本数值类型可以再组成vector和matrix,比如half3是由3个half组成、float4x4是由16个float组成。
// float:32位高精度浮点数。
// half:16位中精度浮点数。范围是[-6万, +6万],能精确到十进制的小数点后3.3位。
// fixed:11位低精度浮点数。范围是[-2, 2],精度是1 / 256。
// Sampler2D:2D纹理属性
sampler2D _MainTex;// sampler2D就是和texture所绑定的一个数据容器接口,sampler2D就是GLSL中的2D贴图的类型,相应的,还有sampler1D,sampler3D,samplerCube等等。
half _Glossiness;
half _Metallic;
fixed4 _Color;
// 这个结构体和surf函数中的另一个参数inout结构体是相对的,一个代表输入,一个代表输出。
// 可以这样理解这两个结构体,定义输入数据结构(Inputs Struct)、编写自己的Surface函数处理输入、最终输出修改过后的SurfaceOutput。
// Input是需要去定义的结构,可以把所需要参与计算的数据都放到这个Input结构中,传入surf函数使用
// 默认的Input结构体中有一个uv_MainTex参数,代表了纹理的UV值,便可以在surf函数中直接使用这个参数了。
struct Input
{
float2 uv_MainTex;
};
//Output的结构体
struct Output
{
fixed3 Albedo; // diffuse color 漫反射的颜色值。
fixed3 Normal; // tangent space normal, if written 法线坐标
fixed3 Emission; //自发光颜色
half Specular; // specular power in 0..1 range 镜面反射系数
fixed Gloss; // specular intensity 光泽系数
fixed Alpha; // alpha for transparencies 透明度系数
};
// Add instancing support for this shader. You need to check 'Enable Instancing' on materials that use the shader.
// See https://docs.unity3d.com/Manual/GPUInstancing.html for more information about instancing.
// #pragma instancing_options assumeuniformscaling
UNITY_INSTANCING_BUFFER_START(Props)
// put more per-instance properties here
UNITY_INSTANCING_BUFFER_END(Props)
void surf(Input IN, inout SurfaceOutputStandard o)
{
// Albedo comes from a texture tinted by color
fixed4 c = tex2D(_MainTex, IN.uv_MainTex) * _Color;
o.Albedo = c.rgb; //将物体显示的漫反射颜色设置成在纹理的颜色值
// Metallic and smoothness come from slider variables
o.Metallic = _Metallic; //将物体显示的金属光泽设置成在properties中定义的光泽
o.Smoothness = _Glossiness; //设置物体显示的光滑度
o.Alpha = c.a; //设置物体显示的透明度
}
ENDCG
}
FallBack "Diffuse"
}