当前位置:网站首页>Unity Shader入门精要初级篇(一)-- 基础光照笔记
Unity Shader入门精要初级篇(一)-- 基础光照笔记
2022-07-07 06:19:00 【零子若】
一篇个人Shader笔记,主要是通过分析Shader代码来总结几个光照模型。
目录
0. 标准光照模型
标准模型主要是分为四个部分,自发光 + 高光反射 + 漫反射 + 环境光
根据不同的光照模型,计算不同的光线进行相加
逐顶点和逐像素
模型光照计算主要分为两种,逐像素和逐顶点 ,即Grouraud Shading 和 Phone Shading
逐顶点
在每个顶点上计算光照,在渲染图元内部进行线性插值,最后输出成像素颜色
缺点:顶点计算光照内部进行插值,图元内部总会比顶点处最高颜色值更暗,而且会出现棱角
不过这也告诉我们,光照计算在顶点着色器
逐像素
以每个像素为基础,得到他的法线, (可以是顶点法线插值,可以是从法线纹理中采样),进行光照计算
因此,光照计算在片元着色器
1.漫反射模型
Lambert漫反射模型的基础,主要是满足Lambert定律:即反射光线的强度与表面法线和光源方向之间的夹角的余弦值成正比
写成公式就是:
Cdiffuse = ( Clight · mdiffuse )max (0, n · l)
Clight :光源颜色
mdiffuse:材质漫反射颜色
n : 表面法线
l : 指向光源单位矢量
1.1 逐顶点漫反射
mdiffuse材质的漫反射颜色的定义,颜色可以在unity中自取
Properties
{
_Diffuse("Diffuse", Color) = (1, 1, 1, 1)
}
分别是a2v和v2f,即application to vertex shader 和 vertex shader 到 fragment shader 的定义。
在顶点着色器中计算光照,因此需要在a2v中访问到顶点和法线;要将顶点着色器中的光照颜色传递给片元着色器,因此,v2f中需要将顶点转换裁剪空间和储存color值
struct a2v
{
float4 vertex : POSITION;
float3 normal : NORMAL;
};
struct v2f
{
float4 pos : SV_POSITION;
float3 worldNormal : TEXCOORD0;
};
这就是顶点着色器中具体的计算了。Clight和mdiffuse一个是直接得到一个是之前定义了,需要解决的只有n · l 。需要把这两个值都先转换到世界空间进行点乘。
世界坐标下的法线:unity内置的
unity_WorldToObject
可以从世界坐标转换到局部坐标,那么运用矩阵的逆运算,得到法线的世界坐标。
其他的带入公式
v2f vert(a2v v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
fixed3 worldNormal = normalize(mul(v.normal,(float3x3)unity_WorldToObject));
fixed3 worldLight = normalize(_WorldSpaceLightPos0.xyz);
fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb *saturate(dot(worldNormal,worldLight));
o.color = ambient + diffuse;
return o;
}
片元着色器中直接输出就好了
fixed4 frag(v2f i) : SV_TARGET
{
return fixed4(i.color, 1.0);
}
1.2 逐像素漫反射
主要是两个着色器中计算的内容不一样。
在顶点着色器中,不需要计算光照,只需要把世界空间下的顶点和法线传递给片元着色器即可。
v2f vert(a2v v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
o.worldNormal = mul(v.normal, (float3x3)unity_WorldToObject);
return o;
}
重点都在片元着色器中计算光照了。,思路都是一致的,注意各种矢量的单位化。
fixed4 frag(v2f i) : SV_TARGET
{
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
fixed3 worldNormal = normalize(i.worldNormal);
fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal, worldLightDir));
fixed3 color = ambient + diffuse;
return fixed4(color, 1.0);
}
2. 高光反射模型
高光反射模型分Phone 和 Blinn Phone 两种
前者模型方式是,高光反射与视角方向和反射方向的点乘值相关, 后者认为是法线方向与视角方向的半程向量与法线的点乘值相关。
Phone高光模型:
Cspecular = (Clight · mspecular) max(0, v, r)mgloss
Clight : 入射光线的颜色与强度
mspecular: 材质的高光反射系数
v: 视角方向
r : 反射方向
mgloss: 光泽度,反光度
Blinn Phone高光模型:
Cspecular = (Clight · mspecular) max(0, n, h)mgloss
n : 法线,h 是半程向量
其他大致是一样的
2.1 逐顶点Phone高光反射
漫反射颜色,高光反射系数和光泽度都是自定义的如下
Properties
{
_Diffuse("Diffuse", Color) = (1, 1, 1, 1)
_Specular("Specular", Color) = (1, 1, 1, 1)
_Gloss ("Gloss", Range(8.0, 256)) = 20
}
在顶点着色器计算光照,主要是计算高光,所以环境光我们直接获取。漫反射的计算方式不多写了,高光带入公式一顿计算,加上环境光返回
reflectDir是直接通过内置函数,写入光线入射方向和顶点法线方向得到出射方向
viewDir 通过相机的世界位置 - 顶点的世界位置得到视野向量
v2f vert(a2v v)
{
v2f o;
o.pos = UnityObjectToClipPos(v.vertex);
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
fixed3 worldNormal = normalize(mul(v.normal, (float3x3)unity_WorldToObject));
fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal, worldLightDir));
fixed3 reflectDir = normalize(reflect(-worldLightDir, worldNormal));
fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - mul(unity_ObjectToWorld, v.vertex).xyz);
fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(reflectDir, viewDir)), _Gloss);
o.color = ambient + diffuse + specular;
return o;
最后再片元着色器中直接将颜色输出就好,与上面的一致。
2.2 逐像素Phone高光反射
显然是在片元着色器中计算光照,思路一致。在顶点着色器中,只需要计算出顶点的世界坐标和法线的世界下的位置
fixed4 frag(v2f i) : SV_TARGET
{
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
fixed3 worldNormal = normalize(i.worldNormal);
fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * saturate(dot(worldNormal, worldLightDir));
fixed3 reflectDir = normalize(reflect(-worldLightDir, worldNormal));
fixed3 viewDir = normalize(_WorldSpaceCameraPos.xyz - i.worldPos.xyz);
fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(saturate(dot(reflectDir, viewDir)), _Gloss);
return fixed4(ambient + diffuse + specular, 1.0);
}
2.3 逐像素Blinn Phone 高光模型
大致一样的,主要是片元计算光照,多一个半程向量的计算并使用
fixed3 halfDir = normalize(worldLightDir + viewDir);
fixed3 specular = _LightColor0.rgb * _Specular.rgb * pow(max(0, dot(reflectDir, viewDir)), _Gloss);
边栏推荐
- Greenplum6.x搭建_环境配置
- Speaking of a software entrepreneurship project, is there anyone willing to invest?
- 年薪50w阿里P8亲自下场,教你如何从测试进阶
- Find the original code, inverse code and complement of signed numbers [C language]
- Greenplum 6.x reinitialization
- Explain Huawei's application market in detail, and gradually reduce 32-bit package applications and strategies in 2022
- Why choose cloud native database
- Esp32-ulp coprocessor low power mode RTC GPIO interrupt wake up
- LeetCode 736. LISP syntax parsing
- Greenplum 6.x build_ install
猜你喜欢
[step on the pit] Nacos registration has been connected to localhost:8848, no available server
Introduction to data fragmentation
最长上升子序列模型 AcWing 1017. 怪盗基德的滑翔翼
Componentspace2022, assertions, protocols, bindings, and configuration files
Data analysis methodology and previous experience summary 2 [notes dry goods]
Calling the creation engine interface of Huawei game multimedia service returns error code 1002, error message: the params is error
数字三角形模型 AcWing 1027. 方格取数
Nanjing commercial housing sales enabled electronic contracts, and Junzi sign assisted in the online signing and filing of housing transactions
调用华为游戏多媒体服务的创建引擎接口返回错误码1002,错误信息:the params is error
Analysis of using jsonp cross domain vulnerability and XSS vulnerability in honeypot
随机推荐
MySQL主从延迟的解决方案
Output a spiral matrix C language
[Chongqing Guangdong education] organic electronics (Bilingual) reference materials of Nanjing University of Posts and Telecommunications
[Yugong series] February 2022 U3D full stack class 007 - production and setting skybox resources
go mod module declares its path as: gtihub. com/xxx-xx but was required as:xx-xx
LeetCode 736. Lisp 语法解析
Tronapi wave field interface - source code without encryption - can be opened twice - interface document attached - package based on thinkphp5 - detailed guidance of the author - July 6, 2022 - Novice
路由信息协议——RIP
JS operation
Count sort (diagram)
Calling the creation engine interface of Huawei game multimedia service returns error code 1002, error message: the params is error
Greenplum 6.x version change record common manual
模拟卷Leetcode【普通】1705. 吃苹果的最大数目
[Yu Yue education] higher vocational English reference materials of Nanjing Polytechnic University
Category of IP address
Sign and authenticate API interface or H5 interface
MAC OSX php dyld: Library not loaded: /usr/local/xxxx. dylib
Required String parameter ‘XXX‘ is not present
Frequently Asked Coding Problems
调用华为游戏多媒体服务的创建引擎接口返回错误码1002,错误信息:the params is error