<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      【URP】Unity[法線貼圖]原理與實踐

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

      法線貼圖(Normal Mapping)是一種通過修改表面法線方向來模擬凹凸細節的紋理技術,無需增加模型幾何復雜度,顯著提升渲染效率同時保持視覺真實感。

      解決的問題

      • ?性能優化?:用低多邊形模型配合法線貼圖替代高模,減少計算開銷
      • ?細節增強?:通過RGB通道存儲法線方向,模擬表面凹凸、劃痕等微觀結構
      • ?動態光照響應?:每個像素的法線獨立參與光照計算,實現更真實的明暗變化

      歷史發展節點

      • ?1998年?:首次由Crytek在游戲《Far Cry》中大規模應用
      • ?2004年?:成為DirectX 9標準特性,進入主流游戲引擎
      • ?2018年?:Unity URP管線整合法線貼圖標準化工作流,支持移動端優化
      • ?2022年?:HLSL語法改進,分離紋理對象與采樣器聲明

      生成與使用流程

      生成方法

      • ?高模烘焙?:通過ZBrush等工具將高模細節烘焙到低模法線貼圖
      • ?程序生成?:Substance Designer等工具從高度圖轉換生成
      • ?手動繪制?:Photoshop使用濾鏡生成基礎法線紋理

      詳細存儲原理參看了解具體如何計算和存儲的。

      URP實現步驟

      • ?紋理導入?
        • 類型設為Default,勾選Bump Map自動切換模式
        • 壓縮格式推薦BC5 (DXT5nm)BC7
      • ?材質配置
        • Shader選擇:URP > Lit 或 Simple Lit
          法線貼圖拖拽至Normal Map插槽
          調整Normal Scale參數控制凹凸強度(0.5-1.5為常用范圍?
      • ?Shader核心原理?
        • ?切線空間轉換?:通過TBN矩陣將法線從切線空間轉到世界空間
        • ?光照計算?:轉換后的法線與光源方向點積決定漫反射強度

      完整示例代碼

      以下URP Shader實現法線貼圖與基礎光照:

      • ?頂點著色器?:計算世界空間法線和切線

      • ?片段著色器?:采樣法線貼圖并通過TBN矩陣轉換

      • ?光照模型?:采用Lambert漫反射計算

      • NormalMapShader.shader

        Shader "Custom/NormalMapShader" {
            Properties {
                _MainTex("Albedo", 2D) = "white" {}
                _NormalMap("Normal Map", 2D) = "bump" {}
                _NormalScale("Normal Scale", Range(0,2)) = 1
            }
            SubShader {
                Tags { "RenderPipeline"="UniversalPipeline" }
                HLSLINCLUDE
                #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
                ENDHLSL
                Pass {
                    HLSLPROGRAM
                    #pragma vertex vert
                    #pragma fragment frag
                    struct Attributes {
                        float4 positionOS : POSITION;
                        float2 uv : TEXCOORD0;
                        float3 normalOS : NORMAL;
                        float4 tangentOS : TANGENT;
                    };
                    struct Varyings {
                        float4 positionCS : SV_POSITION;
                        float2 uv : TEXCOORD0;
                        float3 normalWS : TEXCOORD1;
                        float4 tangentWS : TEXCOORD2;
                    };
                    sampler2D _MainTex;
                    sampler2D _NormalMap;
                    float _NormalScale;
                    Varyings vert(Attributes IN) {
                        Varyings OUT;
                        VertexPositionInputs posInput = GetVertexPositionInputs(IN.positionOS.xyz);
                        OUT.positionCS = posInput.positionCS;
                        OUT.uv = IN.uv;
                        VertexNormalInputs normInput = GetVertexNormalInputs(IN.normalOS, IN.tangentOS);
                        OUT.normalWS = normInput.normalWS;
                        OUT.tangentWS = float4(normInput.tangentWS, IN.tangentOS.w);
                        return OUT;
                    }
                    half4 frag(Varyings IN) : SV_Target {
                        float4 normalSample = tex2D(_NormalMap, IN.uv);
                        float3 tangentNormal = UnpackNormalScale(normalSample, _NormalScale);
                        float3 normalWS = IN.normalWS;
                        float3 tangentWS = IN.tangentWS.xyz;
                        float3 bitangentWS = cross(normalWS, tangentWS) * IN.tangentWS.w;
                        float3x3 TBN = float3x3(tangentWS, bitangentWS, normalWS);
                        float3 finalNormal = mul(tangentNormal, TBN);
                        Light mainLight = GetMainLight();
                        float NdotL = saturate(dot(finalNormal, mainLight.direction));
                        half3 albedo = tex2D(_MainTex, IN.uv).rgb;
                        half3 diffuse = albedo * NdotL * mainLight.color;
                        return half4(diffuse, 1);
                    }
                    ENDHLSL
                }
            }
        }
        

      數據結構定義

      • Attributes結構體:聲明頂點輸入數據
      • positionOS:模型空間頂點位置
      • uv:紋理坐標
      • normalOS:模型空間法線
      • tangentOS:模型空間切線(含手性信息)
      • Varyings結構體:定義頂點到片段的傳遞數據
      • positionCS:裁剪空間位置
      • normalWS:世界空間法線(通過URP內置函數轉換)
      • tangentWS:世界空間切線(保留手性分量)

      頂點著色器實現

      • 核心流程:
        • 調用GetVertexPositionInputs轉換模型空間到裁剪空間
        • 通過GetVertexNormalInputs計算世界空間法線和切線
        • 保持原始UV坐標傳遞

      片段著色器實現

      • 法線貼圖處理:
        • float4 normalSample = tex2D(_NormalMap, IN.uv); float3 tangentNormal = UnpackNormalScale(normalSample, _NormalScale);
        • 使用UnpackNormalScale函數解壓法線貼圖(范圍從[0,1]映射到[-1,1])并應用強度參數。
      • TBN矩陣構建:
        • float3x3 TBN = float3x3(tangentWS, bitangentWS, normalWS); float3 finalNormal = mul(tangentNormal, TBN);
        • 通過切向量、副法線和法線構建正交基,將切線空間法線轉換到世界空間。

      光照計算:

      • Light mainLight = GetMainLight(); float NdotL = saturate(dot(finalNormal, mainLight.direction)); half3 diffuse = albedo * NdotL * mainLight.color;
      • 采用Lambert漫反射模型,計算法線與光源方向的點積作為光照強度因子。

      關鍵函數說明

      • GetVertexPositionInputs:URP內置函數,處理頂點位置變換
      • UnpackNormalScale:URP提供的法線貼圖解壓函數
      • GetMainLight:獲取場景主光源信息(需配合URP的Lightweight Render Pipeline使用)

      小結

      • 坐標空間轉換:完整實現模型空間→世界空間→切線空間的轉換鏈
      • 光照模型:基于物理的簡單漫反射計算
      • 性能優化:使用half類型減少內存占用,適合移動端
      • 擴展性:通過_NormalScale參數可動態調整法線貼圖強度

      實際項目應用

      • ?角色模型?:增強皮膚皺紋或服裝褶皺細節
      • ?環境場景?:表現磚墻縫隙或金屬表面劃痕
      • ?性能權衡?:移動端建議使用Simple Lit簡化版著色器

      關鍵注意事項:

      • 確保模型具有正確的UV和切線數據
      • 避免sRGB模式導入法線貼圖
      • 多光源場景需在Shader中添加額外光照循環

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

      posted @ 2025-10-27 10:47  SmalBox  閱讀(90)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 日韩中文字幕人妻精品| 激情97综合亚洲色婷婷五| 九九热在线视频只有精品| 无码午夜福利片| 欧美成人精品| 亚洲av首页在线| 最近中文字幕免费手机版| 国内精品自产拍在线播放| 亚洲色无码专区一区| 国产微拍一区二区三区四区| 精品成人免费自拍视频| 日本亚洲一区二区精品久久| 国产亚洲一区二区三区四区| 日本毛茸茸的丰满熟妇| 国产一区二区不卡91| 美女爽到高潮嗷嗷嗷叫免费网站 | 国产激情一区二区三区在线| 99热精品毛片全部国产无缓冲| 91中文字幕在线一区| 亚洲午夜福利精品无码不卡| 成人亚洲国产精品一区不卡| 人妻精品动漫h无码| 亚洲人成网站免费播放| 日本黄色三级一区二区三区| 97色伦97色伦国产| 国产欧美另类久久久精品不卡 | 97精品伊人久久大香线蕉APP| 中文字幕久久六月色综合| 亚洲韩国精品无码一区二区三区| 欧美成人精品手机在线| 色噜噜久久综合伊人一本| 日韩人妻一区中文字幕| 国产suv精品一区二区883| 熟女亚洲综合精品伊人久久| 国产精品久久露脸蜜臀| 久久先锋男人AV资源网站| 免费看黄色亚洲一区久久| 久久精品一本到99热免费| 超碰伊人久久大香线蕉综合| 97免费公开在线视频| 四虎永久精品在线视频|