入门图形学:光照模型(四)
首先为了系统的学习unity cg的一些自定义代码规则,我们需要先去下载unity cgbuildin文件,具体下载方法就是去unity官网选择unity旧版本,然后选择要下载的unity版本的内置着色器文件,截图和地址如下:
因为我暂时用的5.x版本,所以一切以5.x版本来讲解,下载完毕后打开CGIncludes文件夹,其中有很多.cginc文件,这些就是unity编译器能识别编译的c源码文件,这些源码文件的作用就很大了:
①.让你查看unity内部着色器这块一些实现代码。
②.因为这些代码包含我们编写.shader文件的函数接口和数据结构,比如UnityCG.cginc这个代码文件,可以很清晰的看出.shader文件中使用的各种数据结构体和字段,以及各种计算辅助函数。
③.再比如打开UnityStandardInput.cginc这个文件(以及其包含的头文件),可以看到很多.shader中使用的数据定义以及其含义。
...
因为文件太多暂时讲不完,我会在额外开一个unity c for graphic栏目详细讲解,这个栏目会从基础语法到unity着色器源码进行学习。
言归正传,接下来找到UnityPBSLighting.cginc打开,你会看到一个名为SurfaceOutputStandard的结构体,结构体的如下:
上面的注释写着用于物理上的表面着色器输出结构体。
顺便看下结构体下面的LightingStandard函数,如下图:
这就是一个unity自定义的标准光照通用函数。这个函数具体怎么用呢?我就来写CGshader代码演示一下,如下图:
-
Shader "Custom/StandardSurfaceShader" {
-
Properties {
-
_Color ("Color", Color) = (1,1,1,1)
-
_MainTex ("Texture", 2D) = "white" {}
-
_Glossiness ("Smoothness", Range(0,1)) = 0.5
-
_Metallic ("Metallic", Range(0,1)) = 0.0
-
}
-
SubShader {
-
Tags { "RenderType"="Opaque" }
-
-
CGPROGRAM
-
#pragma surface surf Standard
-
-
#include "UnityPBSLighting.cginc"
-
-
#pragma target 3.0
-
-
struct Input {
-
float2 uv_MainTex;
-
};
-
-
sampler2D _MainTex;
-
half _Glossiness;
-
half _Metallic;
-
fixed4 _Color;
-
-
void surf (Input IN, inout SurfaceOutputStandard o) {
-
fixed4 c = tex2D (_MainTex, IN.uv_MainTex) * _Color;
-
o.Albedo = c.rgb;
-
o.Metallic = _Metallic;
-
o.Smoothness = _Glossiness;
-
o.Alpha = c.a;
-
}
-
ENDCG
-
}
-
FallBack "Diffuse"
-
}
这里我就要详细讲解一下这个标准StandardSurfaceShader一些让人迷惑的地方。
1.Properties字段定义
①._Color,定义材质基本颜色
②._MainTex,材质表面贴图
③._Glossiness,材质表面平滑性
④._Metallic,材质金属光泽
2.#pragma surface surf Standard预处理指令,这个是什么意思呢?作用和c预处理指令一样,语法上经过了unity自己的着色器编译器的规范化处理,比如surface代表我这是一个surface着色函数,surf就是需要调用的程序员们实现的函数,Standard就是标准光照模型LightingStandard,这里特别提示一下,这个就是unity官方自己的编译规范,Standard隐去了Lighting这个字符串,实际上就是LightingStandard,可以这么说,官方就是这么任性,就是要去掉Lighting前缀,不爽咬我啊!
3.Surf函数
①.SurfaceOutputStandard这个参数的作用就很大了,这是unity标准光照模型LightingStandard处理需要的封装结构体,结构体数据我上面有截图,可以翻上去详细看一下。
②.inout形参修饰符,这个修饰符的作用跟c#的ref out差不多,直接传递一个引用结构体给我们填充数据,填充完毕就被拿回去使用。
③.我们将SurfaceOutputStandard的几个重要参数填充完毕后,提交给标准光照模型LightingStandard去计算最终光照效果。
最后发下,这个标准surface着色器的最终效果,如下图:
可以明显感觉到这些参数提供的具体效果变化。
最后,当我们学习理解完毕这种cg写法后,下一篇我们要自己实现通用自定义光照模型,亲自感受一下。