【URP】[法線貼圖]為什么主要是藍色的?

【從UnityURP開始探索游戲渲染】專欄-直達

法線貼圖呈現藍紫色調(尤其以藍色為主)是由其?存儲原理、切線空間坐標系設計及顏色編碼規則共同決定的?。

核心原因:法線向量的存儲規則?

?法線向量的物理范圍?

法線是單位向量,每個分量(X, Y, Z)的取值范圍為 ?[-1, 1],分別代表切線空間中的方向:

  • ?X(紅色通道):左右偏移(左為負,右為正)
  • ?Y(綠色通道):上下偏移(下為負,上為正)
  • ?Z(藍色通道):垂直表面的方向(指向外部為正)?。

?顏色空間的映射限制?

圖像顏色值范圍是 ?[0, 1](對應0~255),因此需要進行轉換:

RGB=(Normalxyz+1)/2

  • ?默認法線方向?:當表面完全垂直(無傾斜)時,法線向量為 ?(0, 0, 1)。
  • ?轉換結果?:
    • R=20+1=0.5 (128)
    • G=20+1=0.5 (128)
    • B=21+1=1 (255)
    • 最終顏色為 ?(128, 128, 255),即 ?藍紫色?(藍色占主導)?。

?現實模型的主導方向

  • 大多數模型表面(如墻面、地面)以?垂直方向為主?(Z≈1),因此藍色通道值接近255,而XY通道接近128(中性灰),整體呈現藍色基調?。

?顏色變化的場景解釋?

?顏色表現??對應的法線方向??表面形態?
?深藍色 (0,0,1)完全垂直向外平坦表面(如地板)
?藍紫色 (0.5,0.5,1)輕微傾斜緩坡、弧形表面
?青色/綠色 (低R,高G,中B)明顯上/下傾斜(Y≠0)邊緣、陡坡
?紅色/粉色 (高R,中G,中B)?明顯左/右傾斜(X≠0)側壁、凹凸邊緣

💎 ?示例?:墻面法線貼圖中,磚縫凹陷處因法線指向側方(X/Y增大),可能呈現紅綠色調,但整體仍以藍紫色為基底?。


? ?技術實現驗證?

?生成與解碼邏輯?

  • ?生成法線貼圖?:通過公式?color = (normal + 1) / 2?將高模法線烘焙為貼圖?。

  • ?Shader解碼?:在著色器中逆向計算還原法線向量:此步驟是光照計算的基礎?。

    glsl
    vec3 normal = texture(normalMap, uv).rgb * 2.0 - 1.0; // [0,1] → [-1,1]
    

?切線空間的意義?

法線貼圖通常在? 切線空間(Tangent Space)中定義:

  • 以頂點法線為Z軸,切線為X軸,副切線為Y軸構建坐標系。
  • ?優勢?:無論模型如何旋轉,法線方向始終相對于表面本地坐標,確保凹凸效果穩定?。

常見誤區澄清?

  • ?誤區1?:藍色是人為設定的美術風格。?真相?:藍色是數學映射的必然結果,由垂直方向(0,0,1)的編碼規則決定?。
  • ?誤區2?:法線貼圖的顏色代表凹凸高度。?真相?:它存儲的是?方向?而非高度,凹凸感通過光照模擬實現?。

實際應用案例?

  • ?Unity 工作流?:將法線貼圖拖入材質球的 ?Normal Map? 插槽,通過?UnpackNormal()?函數解碼(內置管線見?UnityCG.cginc,URP管線UnpackNormalScale()見Packing.hlsl)?。
  • ?效果增強?:調整 ?Normal Scale? 參數控制凹凸強度(值>1增強凸起,<1弱化)?。

?URP中的法線貼圖

法線貼圖設置流程

  • ?導入法線貼圖?
    • 紋理類型設為"Default/Normal map"
    • 壓縮格式推薦BC5(DXT5nm)或BC7
    • 勾選"sRGB"選項確保正確色彩空間轉換
  • ?創建URP材質?
    • 使用Shader路徑:Universal Render Pipeline/Lit
    • 將法線貼圖拖拽到Normal Map插槽
    • 調整Normal Scale參數(建議0.5-1.5)

完整Shader代碼實現

  • NormalMapURP.shader

    Shader "Custom/URPNormalMap"
    {Properties{_BaseMap("Albedo", 2D) = "white" {}_BaseColor("Color", Color) = (1,1,1,1)_NormalMap("Normal Map", 2D) = "bump" {}_NormalScale("Normal Scale", Range(0,2)) = 1_Metallic("Metallic", Range(0,1)) = 0_Smoothness("Smoothness", Range(0,1)) = 0.5}SubShader{Tags { "RenderType"="Opaque" "RenderPipeline"="UniversalPipeline"}HLSLINCLUDE#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"TEXTURE2D(_BaseMap);SAMPLER(sampler_BaseMap);TEXTURE2D(_NormalMap);SAMPLER(sampler_NormalMap);CBUFFER_START(UnityPerMaterial)float4 _BaseMap_ST;half4 _BaseColor;half _Metallic;half _Smoothness;half _NormalScale;CBUFFER_ENDstruct Attributes{float4 positionOS : POSITION;float3 normalOS : NORMAL;float4 tangentOS : TANGENT;float2 uv : TEXCOORD0;};struct Varyings{float4 positionCS : SV_POSITION;float2 uv : TEXCOORD0;float3 normalWS : TEXCOORD1;float4 tangentWS : TEXCOORD2;float3 positionWS : TEXCOORD3;};ENDHLSLPass{Name "ForwardLit"Tags { "LightMode"="UniversalForward" }HLSLPROGRAM#pragma vertex vert#pragma fragment fragVaryings vert(Attributes input){Varyings output;VertexPositionInputs vertexInput = GetVertexPositionInputs(input.positionOS.xyz);VertexNormalInputs normalInput = GetVertexNormalInputs(input.normalOS, input.tangentOS);output.positionCS = vertexInput.positionCS;output.positionWS = vertexInput.positionWS;output.uv = TRANSFORM_TEX(input.uv, _BaseMap);output.normalWS = normalInput.normalWS;output.tangentWS = float4(normalInput.tangentWS, input.tangentOS.w);return output;}half4 frag(Varyings input) : SV_Target{// 采樣基礎貼圖half4 baseColor = SAMPLE_TEXTURE2D(_BaseMap, sampler_BaseMap, input.uv) * _BaseColor;// 采樣和解壓法線貼圖half4 normalSample = SAMPLE_TEXTURE2D(_NormalMap, sampler_NormalMap, input.uv);half3 normalTS = UnpackNormalScale(normalSample, _NormalScale);// 構建TBN矩陣half3 bitangentWS = cross(input.normalWS, input.tangentWS.xyz) * input.tangentWS.w;half3x3 TBN = half3x3(input.tangentWS.xyz, bitangentWS, input.normalWS);half3 normalWS = TransformTangentToWorld(normalTS, TBN);// 光照計算Light mainLight = GetMainLight();half3 lightDir = normalize(mainLight.direction);half NdotL = saturate(dot(normalWS, lightDir));half3 diffuse = baseColor.rgb * NdotL * mainLight.color;// 高光計算half3 viewDir = normalize(_WorldSpaceCameraPos - input.positionWS);half3 halfVec = normalize(lightDir + viewDir);half NdotH = saturate(dot(normalWS, halfVec));half specular = pow(NdotH, _Smoothness * 256) * _Metallic;half3 finalColor = diffuse + specular * mainLight.color;return half4(finalColor, baseColor.a);}ENDHLSL}}
    }
    

關鍵實現說明

  • ?法線解壓?:使用UnpackNormalScale函數處理法線貼圖數據,支持強度調節
  • ?TBN矩陣?:通過切線、副切線和法線構建轉換矩陣,將切線空間法線轉到世界空間
  • ?光照模型?:采用Blinn-Phong模型計算漫反射和高光
  • ?URP適配?:使用URP特有的GetVertexPositionInputs等函數替代傳統Shader寫法

常見問題解決方案

  • ?法線效果異常?:檢查切線空間計算是否正確,確保模型導入時勾選"Calculate Tangents"
  • ?性能優化?:移動端可考慮在切線空間計算光照減少矩陣運算
  • ?多光源支持?:需添加AdditionalLights Pass處理額外光源

總結?

法線貼圖的藍色基調本質是?垂直方向向量(0,0,1)經歸一化映射后的顏色表達?,這種方法平衡了存儲效率與光照計算需求,是3D渲染中模擬表面細節的核心技術?,直觀的顏色樣式只是數據可視化的一種直觀顯示。


【從UnityURP開始探索游戲渲染】專欄-直達
(歡迎點贊留言探討,更多人加入進來能更加完善這個探索的過程,🙏)

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

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

相關文章

驅動開發系列63 - NVIDIA 開源GPU驅動open-gpu-kernel-modules編譯調試

目錄 一:通過apt方式安裝nvidia 驅動 二:通過 .run 方式安裝nvidia驅動 三:編譯安裝nvidia開源內核驅動 四:驗證和調試 五:卸載驅動 1. 以apt方式安裝nvidia 驅動的卸載方法 2. 以.run方式安裝nvidia驅動的卸載方法 六:安裝CUDA環境 一:通過apt方式安裝nvidia 驅動…

對KingbaseES架構的解析:從讀寫分離到異地災備的技術實現與保障機制

聲明&#xff1a;文章為本人真實測評博客&#xff0c;非廣告&#xff0c;并沒有推廣該平臺 &#xff0c;為用戶體驗文章 本人旨在分享最真實的用戶體驗&#xff0c;為關注此類產品的朋友們提供一個客觀的參考。 文章目錄一、架構全景&#xff1a;四級高可用構建數字基礎1.1 物…

Visual Studio中的常用調試功能(上)

1、利用斷點進行調試添加斷點的方式有以下幾種1.鍵盤快捷鍵F92.通過菜單【Debug&#xff08;調試&#xff09;】-》【Toggle BreakPoint&#xff08;切換斷點&#xff09;】3.點擊代碼行左邊的空白處&#xff08;推薦&#xff09;設置斷點后&#xff0c;按F5運行程序&#xff0…

Linux -- 線程同步

1.1條件變量 (1)當?個線程互斥地訪問某個變量時&#xff0c;它可能發現在其它線程改變狀態之前&#xff0c;它什么也做不了。 (2)例如?個線程訪問隊列時&#xff0c;發現隊列為空&#xff0c;它只能等待&#xff0c;只到其它線程將?個節點添加到隊列 中。這種情況就需要?到…

前端進階指南:JavaScript性能優化實戰全解析

深入剖析 JavaScript 性能瓶頸&#xff0c;分享優化技巧與最佳實踐&#xff0c;讓你的前端應用更快、更穩、更流暢。 &#x1f4d1; 目錄 一、前言 二、性能瓶頸的常見來源 三、JavaScript代碼優化技巧 1. 避免重復計算 2. 合理使用防抖與節流 3. 使用事件委托 四、渲染…

RabbitMQ:SpringAMQP Direct Exchange(直連型交換機)

目錄一、案例需求二、基礎配置三、代碼實現直連型交換機也叫做定向交換機&#xff0c;通過RoutingKey綁定交換機與隊列直接的關系。 生產者源碼 消費者源碼 一、案例需求 在RabbitMQ控制臺中&#xff0c;聲明隊列direct.queue1和direct.queue2。在RabbitMQ控制臺中&#xff…

implement libtime on Windows

因為Windows的time命令和Linux的time命令不一樣&#xff0c;嘗試實現libtime libtime.h /** libtime.h - 跨平臺時間測量庫* 功能&#xff1a;執行外部命令并測量其運行時間和資源使用*/#ifndef LIBTIME_H #define LIBTIME_H#include <stdio.h> #include <stdlib.h>…

Unity進階--C#補充知識點--【C#各版本的新功能新語法】C#1~4與C#5

來源于唐老獅的視頻教學&#xff0c;僅作記錄和感悟記錄&#xff0c;方便日后復習或者查找 一.C#版本與Unity的關系 1.各Unity版本支持的C#版本 更多信息可以在Untiy官網說明查看 https://docs.unity3d.com/2020.3/Documentation/Manual/CSharpCompiler.html&#xff08;這個好…

水閘安全綜合監測系統解決方案

一、方案概述 水閘作為重要的水利工程設施&#xff0c;承擔著防洪、排澇、供水和灌溉等關鍵功能。其安全性直接關系到下游人民群眾的生命財產安全以及區域經濟的穩定發展。近年來&#xff0c;隨著極端天氣頻發和工程老化問題日益突出&#xff0c;水閘安全監測工作顯得尤為重要。…

基于單片機智能點滴輸液系統

傳送門 &#x1f449;&#x1f449;&#x1f449;&#x1f449;其他作品題目速選一覽表 &#x1f449;&#x1f449;&#x1f449;&#x1f449;其他作品題目功能速覽 概述 該系統基于單片機控制技術&#xff0c;結合傳感器和無線通信模塊&#xff0c;實現對輸液過程的實…

AI數據倉庫管理提升效率

內容概要在數字化轉型浪潮中&#xff0c;AI數據倉庫管理正重塑企業數據處理格局。本部分簡要介紹其核心機制&#xff0c;即通過智能API接入外部數據源實現多平臺數據無縫整合&#xff0c;隨后應用數據清洗技術去除冗余信息&#xff0c;確保數據質量。同時&#xff0c;加密存儲機…

使用 Docker 安裝長安鏈管理平臺 + 部署區塊鏈與示例合約

文章目錄簡介登錄官網GithubPodman 配置&#xff08;Docker 配置 registry 地址&#xff09;安裝長安鏈管理平臺下載源碼docker-compose.yml登錄管理平臺部署區塊鏈Dockerfile構建鏡像部署長安鏈訂閱區塊鏈部署合約下載示例合約部署示例合約投票管理文件哈希存證查找存證信息區…

Python訓練營打卡 DAY 41 簡單CNN

知識回顧 數據增強卷積神經網絡定義的寫法batch歸一化&#xff1a;調整一個批次的分布&#xff0c;常用與圖像數據特征圖&#xff1a;只有卷積操作輸出的才叫特征圖調度器&#xff1a;直接修改基礎學習率 卷積操作常見流程如下&#xff1a; 1. 輸入 → 卷積層 → Batch歸一化層…

云端賦能,智慧運維:分布式光伏電站一體化監控平臺研究

摘要 本文針對分布式光伏電站存在的監管困難、火災隱患、系統繁雜及運維不規范等行業痛點&#xff0c;提出AcrelCloud-1200光伏運維云平臺解決方案。平臺通過ANet-1E2S-4G網關集成多品牌逆變器數據&#xff0c;結合視頻監控與氣象站&#xff0c;實現電站全域監測&#xff1b;開…

CVPR 2025 | 具身智能 | HOLODECK:一句話召喚3D世界,智能體的“元宇宙練功房”來了

關注gongzhonghao【CVPR頂會精選】1.導讀1.1 論文基本信息論文標題&#xff1a;《HOLODECK: Language Guided Generation of 3D Embodied AI Environments》作者&#xff1a;Yue Yang*1, Fan-Yun Sun*2, Luca Weihs*4, Eli Vanderbilt4, Alvaro Herrasti4,Winson Han4, Jiajun …

迅為RK3568開發板搭建Ubuntu環境

本小節介紹開發所需 Ubuntu 環境的搭建方法。系統要求:Ubuntu 系統要求&#xff1a;Ubuntu18.04~21.10 版本。推薦使用 20.04 版本&#xff0c;內存 16GB 及以上&#xff0c;硬盤 100GB 及以上。Ubuntu 系統的用戶名不能包含中文字符。建議 Ubuntu 和 Windows 系統上安裝的 Dev…

【數據結構】用堆解決TOPK問題

設計一個算法&#xff0c;找出數組中最小的k個數。以任意順序返回這k個數均可。示例&#xff1a;輸入&#xff1a; arr [1,3,5,7,2,4,6,8], k 4 輸出&#xff1a; [1,2,3,4]比較替換堆頂的數時&#xff0c;不需要讓堆頂與數組的每一個數再進行比較&#xff0c;比較數組減去k個…

【深度長文】Anthropic發布Prompt Engineering全新指南

目錄 1.什么時候適合用提示工程? 2.如何進行提示工程 2.1 使用提示模板 2.1.1 使用提示模板和變量 2.1.2 何時使用提示模板和變量 2.1.3 提示模板示例 2.2 保持清晰和直接 2.2.1 如何保持清晰、具有上下文和具體 2.2.2 示例 ?2.3 使用示例&#xff08;多示例提示…

【基礎-判斷】HarmonyOS提供了基礎的應用加固安全能力,包括混淆、加密和代碼簽名能力

正確 解釋如下: 應用加固: 這是指對應用程序進行保護,使其更難被逆向工程、篡改或盜版。HarmonyOS 作為現代操作系統,確實提供了這樣的基礎安全能力。 混淆: HarmonyOS 的 SDK 提供了代碼混淆工具(通常基于 ProGuard 或類似技術)。開發者在構建應用時啟用混淆,可以將類…

HTML 框架:構建網頁布局的基石

HTML 框架&#xff1a;構建網頁布局的基石 引言 HTML 框架是網頁設計中不可或缺的一部分&#xff0c;它為網頁內容的布局提供了強大的支持。本文將深入探討 HTML 框架的概念、種類、應用以及如何有效地使用它們來構建網頁布局。 什么是 HTML 框架&#xff1f; HTML 框架是一種網…