[實例] Unity Shader 逐像素漫反射與半蘭伯特光照

漫反射光照是Unity中最基本最簡單的光照模型,本篇將會介紹在片元著色器中實現反射效果,并會采用半蘭伯特光照技術對其進行改進。

1. 逐頂點光照與逐像素光照

在Unity Shader中,我們可以有兩個地方可以用來計算光照:在頂點著色器中計算,被稱為逐頂點光照(per-vertex lighting);在片元著色器中計算,被稱為逐像素光照(per-pixel lighting)

在逐像素光照中,我們會以每個像素為基礎,得到它的法線(可以是對頂點法線插值得到的,也可以是從法線紋理中采樣得到的),然后進行光照模型的計算。而逐頂點光照會在每個頂點上計算光照,然后會在渲染圖元內部進行線性插值,最后輸出成像素顏色。由于頂點數目往往遠小于像素數目,因此逐頂點光照的計算量往往要小于逐像素光照,性能較高;但由于逐頂點光照會在渲染圖元內部對頂點顏色進行插值,這又會導致渲染圖元內部的顏色總是暗于頂點處的最高顏色值,這在某些情況下會產生明顯的棱角現象,使渲染效果下降。

2. 初始定義

為了控制材質的漫反射顏色,首先要在Shader的Properties語義塊中聲明一個Color類型的屬性,并把它的初始值設為白色:

_Diffuse("Diffuse", Color) = (1, 1, 1, 1)

接下來在Pass語義塊中,指定我們的光照模式:

Tags {"LightMode" = "ForwardBase" // 指定光照模式
}

為了使用Unity內置的一些變量,如_LightColor0,還需要包含Unity的內置文件Lighting.cginc:

#include "Lighting.cginc"

為了在Shader中使用Properties語義塊中聲明的屬性,我們需要定義一個和該屬性類型相匹配的變量:

fixed4 _Diffuse;

然后定義頂點著色器的輸入和輸出結構體:

// 頂點著色器輸入 結構體
struct a2v
{float4 vertex: POSITION; // 頂點坐標float3 normal: NORMAL; // 法線方向float4 texcorrd: TEXCOORD0; // 模型的第一套紋理坐標
};// 頂點著色器向片元著色器的輸出 結構體
struct v2f
{float4 pos: POSITION; // 頂點在裁剪空間中的位置信息float3 worldNormal: TEXCOORD0; // 世界空間法線
};

3. 實現漫反射

首先我們要在頂點著色器函數中計算世界空間法線并輸出到片元著色器:

// 將法線從模型空間轉世界空間
outData.worldNormal = mul(appData.normal, (float3x3)unity_WorldToObject);return outData;

然后在片元著色器中,通過法線和光源計算輻照度:

// 規范化世界空間法線
fixed3 worldNormal = normalize(inputData.worldNormal);
// 規范化世界空間光源
fixed3 worldLightDir = normalize(_WorldSpaceLightPos0.xyz);
// 計算輻照度
fixed E = saturate(dot(worldNormal, worldLightDir));

有了輻照度,再混合光照色和反射色計算出漫反射:

// 漫反射 = 光照色 * 反射色 * 輻照度
fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * E;

最后加入環境光,計算出反射光:

// 獲取環境光
fixed3 ambient = UNITY_LIGHTMODEL_AMBIENT.xyz;
// 環境光 + 漫反射
fixed3 color = ambient + diffuse;return fixed4(color, 1);

渲染效果如下:

?

4. 使用半蘭伯特模型對代碼進行改進

我們發現該漫反射渲染有一個問題:在光照無法到達的區域,模型的表面呈現為全黑,沒有任何明暗變化,這會使模型的背光區域看起來就像一個平面一樣,失去了模型細節表現,因此我們需要引入半蘭伯特光照技術對其進行改進。

我們在片元著色器代碼中,將原先計算漫反射的部分,修改代碼如下:

// 半蘭伯特模型輻照度
fixed halfLambertE = E * 0.5 + 0.5;
// 漫反射 = 光照色 * 反射色 * 半蘭伯特模型輻照度
fixed3 diffuse = _LightColor0.rgb * _Diffuse.rgb * halfLambertE;

渲染效果如下:

不過需要注意的是,半蘭伯特是沒有任何物理依據的,它僅僅是一個視覺加強技術。?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/web/14954.shtml
繁體地址,請注明出處:http://hk.pswp.cn/web/14954.shtml
英文地址,請注明出處:http://en.pswp.cn/web/14954.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

數據結構:帶頭雙向循環鏈表

目錄 前言 鏈表實現 1.定義節點 2.接口實現 1.開辟新節點 2.初始化 3.打印鏈表 4.添加節點 頭插 尾插 在pos位置之前增加節點 5.刪除節點 判空 頭刪 尾刪 刪除pos位置的節點 6.查找 7.釋放 前言 帶頭雙向循環鏈表的結構最復雜,一般用在單獨存儲數…

z3-加法器實驗

補碼器加減法,運算方法簡介 我們要知道什么是補碼的加法,我們為什么要用補碼的加法? 補碼的加法其實就是將兩個補碼形式的二進制數字直接相加,處理的時候忽略超出固定位數的進位。補碼的加法運算和無符號二進制數的加法操作一樣&…

【最新區塊鏈論文錄用資訊】CCF A — SP 2024 共17篇

Conference:45th IEEE Symposium onSecurity and Privacy CCF level:CCF A Categories:網絡與信息安全 Year:2024 Num:17 Efficient Zero-Knowledge Arguments For Paillier Cryptosystem Paillier 加密系統的有效…

基于python的網頁自動刷新工具

1.下載webdriver https://msedgewebdriverstorage.z22.web.core.windows.net/?prefix122.0.2365.59/下載Edge的瀏覽器驅動 2.安裝selenium pip install selenium4.11.1 3.寫代碼 # -*- coding: utf-8 -*- import tkinter as tk from tkinter import messagebox import thr…

【halcon】set_part 實現平移和縮放 徹悟版

背景 之前寫了一篇關于set_part 的文章 ,確實也實現了平移和縮放。平移是對的,但是縮放其實有畸變。這個問題一直都困擾著我,知道昨天連續測試了好幾個小時,直到晚上11點終于完美解決。 坐標和高寬 坐標 再講set_part 之前&am…

免費擼gpt-4o和各種大模型實用經驗分享

項目 Github: https://github.com/MartialBE/one-api 先貼兩張圖: 說明 免費擼AI大模型,各位可以對照下面我給出的大模型記錄表來填,key需要自己去拿,國內都需要手機號驗證,如果你不介意。另外我在自己的博客放出免費API給大家…

模型評價指標筆記:混淆矩陣+F1+PR曲線+mAP

評價指標 二分類評價指標 混淆矩陣 TP: 正確預測為了正樣本,原來也是正樣本 FN: 錯誤的預測為負樣本,原來是正樣本 (漏報,沒有找到正確匹配的數目) FP: 錯誤的預測為正樣本,原來是負樣本 (誤報,沒有的匹配不正確) TN…

CIM模型

CIM 是 Esri 制圖信息模型。 它是一個地圖內容規范,用于記錄在保存、讀取、引用或打開時如何永久保留描述不同項目組件的信息。 該規范以 JSON 表示,適用于 ArcGIS 應用程序和 API 中的地圖、場景、布局、圖層、符號和樣式。 CIM 不僅限于制圖設置。 要了解屬性的組織方式以及…

【Tools】SpringBoot工程中,對于時間屬性從后端返回到前端的格式問題

Catalog 時間屬性格式問題一、需求二、怎么使用 時間屬性格式問題 一、需求 對于表中時間字段,后端創建對應的實體類的時間屬性需要設定格式(默認的格式不方便閱讀),再返回給前端。 二、怎么使用 導入jackson相關的坐標&#x…

Vue.js - Vue 的安裝 以及 常用的 Vue 指令 【0基礎向 Vue 基礎學習】

文章目錄 Vue 快速上手1、Vue.js 官網 & Vue.js 的獲取2、創建 Vue 實例,初始化渲染3、插值表達式 安裝 Vue 開發者工具:裝插件調試 Vue 應用Vue 指令1、v-show 指令2、v-if3、v-else & v-else-if4、v-onv-on 調用傳參 5、v-bindv-bind 對于樣式…

【算法】前綴和算法——和為k的子數組之和

題解:和為k的子數組之和(前綴和算法) 目錄 1.題目2.題解思路2.1前綴和 哈希表,算法步驟:2.2細節如下:2.3參考代碼: 3.總結及思考 1.題目 題目鏈接:LINK 2.題解思路 暴力求解自然不用多說,時…

【SQL】外連接 LEFT JOIN

目錄 一.內連接與外連接 1.內連接(inner join) 2.外連接(outer join) 二.兩表連接 1.我們先來試試看內連接: 2.我們再來試試外連接 三.單表外連接 四.總結 一.內連接與外連接 先得介紹內連接和外連接兩個概念&…

第199題|關于函數的周期性問題|函數強化訓練(六)|武忠祥老師每日一題 5月24日

解題思路:解這道題我們要用到下面這個結論 f(x)連續,以T為周期時,原函數以T為周期的充分必要條件是: (A) sin x顯然是以π為周期的,我們可以看到并不等于0,根據結論,A的原函數顯然不是周期函數。 (B) 的…

memmove使?和模擬實現

一:memmove的使? 這是memmove在庫里的定義,具體可在cplusplus.com查看 void * memmove ( void * destination, const void * source, size_t num ) ? 和memcpy的差別就是memmove函數處理的源內存塊和?標內存塊是可以重疊的。 ? 如果源空間和?標…

你以為的私域是真正的私域嘛??你的私域流量真的屬于你嘛?

大家好 我是一個軟件開發公司的產品經理 專注私域電商行業7年有余 您的私域流量是真正的屬于你自己嘛? 私域的定義 私域的界定:一個互聯網私有數據(資產)積蓄的載體。這個載體的數據權益私有,且具備用戶規則制定權…

Mysql 備份恢復 mysqldump與xtrabackup備份

1.1 備份的原因 備份是數據安全的最后一道防線,對于任何數據丟失的場景,備份雖然不一定能恢復百分之百的數據 (取決于備份周期),但至少能將損失降到最低。衡量備份恢復有兩個重要的指標:恢復點目標(RPO) 和恢復時間目標(RTO)&…

數據庫常用命令(1)

DML 1.添加數據(insert into) insert into 表名 values (值1,值2....); 表示成功運行: 2.修改數據(update) update 表名 set 字段名1值1,字段名2值2.....【where條件】 3.刪除數據&#xff0…

元年科技數據智能研發部負責人張亞東受邀為第十三屆中國PMO大會演講嘉賓

全國PMO專業人士年度盛會 北京元年科技股份有限公司數據智能研發部負責人張亞東先生受邀為PMO評論主辦的2024第十三屆中國PMO大會演講嘉賓,演講議題為“大模型時代,AI創新型工具提升項目管理效率”。大會將于6月29-30日在北京舉辦,敬請關注&a…

jmeter之HTTP請求和查看結果樹

一、HTTP請求作用: 可以發送post或get請求等請求可以向服務器發送參數或消息體數據可以進行文件上傳 HTTP請求:是線程組內的取樣器最常用的的一個原件 二、查看界面 添加一個HTTP請求:選擇線程組–添加–取樣器–HTTP請求 默認界面 名稱和…