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

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

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

      【光照】Unity如何在Cubemap中采樣反射信息?

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

      介紹與發展歷史

      Cubemap(立方體貼圖)是一種由六個獨立的正方形紋理組成的集合,它將多個紋理組合起來映射到一個單一紋理。Cubemap包含6個2D紋理,每個2D紋理代表立方體的一個面,形成一個有貼圖的立方體。

      Cubemap技術起源于早期的3D圖形學,最初用于實現天空盒效果。隨著硬件性能的提升和圖形API的發展,Cubemap逐漸被廣泛應用于環境映射、反射和折射等高級渲染效果中。

      應用領域

      Cubemap在Unity中主要有以下應用場景:

      • ?環境反射?:用于模擬金屬、玻璃等具有反射屬性物體的反射效果
      • ?天空盒?:創建環境背景,提供場景的全局光照信息
      • ?折射效果?:模擬透明材質的折射現象
      • ?全局光照?:作為間接光照的來源之一

      采樣反射信息原理

      基本原理

      Cubemap采樣的核心原理是使用方向向量進行索引和采樣。想象一個1×1×1的單位立方體,中心位于原點。當從原點發出一個方向向量時,該向量會與立方體的某個面相交,交點處的紋理就是采樣結果。

      反射計算原理

      • 反射效果的計算過程如下:
      • 計算相機指向物體表面點的向量(視線向量)
      • 根據表面法線計算反射向量
      • 使用反射向量在Cubemap中進行采樣(URP中使用宏SAMPLE_TEXTURECUBE實現采樣,這個宏實際調用PLATFORM_SAMPLE_TEXTURECUBE宏來處理不同圖形API的采樣方法,下面有詳細講原理講解。)
      • 將采樣顏色與物體本身的顏色混合

      數學上,反射向量R可以通過以下公式計算:

      R = I - 2 * dot(N, I) * N

      其中I是入射向量(視線向量取反),N是表面法線。

      PLATFORM_SAMPLE_TEXTURECUBE的實現原理

      PLATFORM_SAMPLE_TEXTURECUBE是Unity URP中用于跨平臺Cubemap采樣的關鍵宏,它封裝了不同圖形API(Direct3D、OpenGL、Metal)下Cubemap采樣的實現差異,為開發者提供統一的采樣接口。

      數學原理基礎

      Cubemap是一個由6個2D紋理組成的立方體,每個面代表一個方向(±X, ±Y, ±Z)。使用反射向量作為方向索引,可以獲取立方體相應位置的紋理顏色

      1. 方向向量確定采樣面

      Cubemap采樣基于3D方向向量,通過以下步驟確定采樣面:

      數學表達式:

      主面 = max(|x|, |y|, |z|)
      if (主面 == |x|)
      if (x > 0) → +X面
      else → -X面
      else if (主面 == |y|)
      if (y > 0) → +Y面
      else → -Y面
      else
      if (z > 0) → +Z面
      else → -Z面

      ## **2. 方向向量到UV坐標轉換**
      
      確定采樣面后,將3D方向向量轉換為2D UV坐標的數學過程:
      
      對于+X面(右面):
      

      u = 0.5 * (1 - (z / |x|))
      v = 0.5 * (1 - (y / |x|))

      對于-Y面(下面):
      

      u = 0.5 * (1 - (x / |y|))
      v = 0.5 * (1 + (z / |y|))

      其他面的轉換類似,但需要考慮不同面的坐標系差異。
      
      ## **URP中的具體實現**
      
      ### **PLATFORM_SAMPLE_TEXTURECUBE宏定義**
      
      在URP Core.hlsl中,該宏通常定義為:
      
      ```c
      hlsl
      #define PLATFORM_SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) \
          SampleTexture(textureName, samplerName, coord3)
      

      實際采樣函數會根據平臺不同而有所區別,但對外提供統一接口。

      反射向量計算示例

      在URP Shader中計算反射向量并采樣Cubemap的完整過程:

      • 計算視線向量(從表面點到相機):
      hlsl
      float3 viewDir = GetWorldSpaceViewDir(positionWS);
      
      • 計算反射向量:
      hlsl
      float3 reflectDir = reflect(-viewDir, normalWS);
      
      • 采樣Cubemap:
      hlsl
      float4 cubemapColor = PLATFORM_SAMPLE_TEXTURECUBE(_Cubemap, sampler_Cubemap, reflectDir);
      
      • 解碼HDR顏色(如果需要):
      hlsl
      float3 reflection = DecodeHDREnvironment(cubemapColor, _Cubemap_HDR);
      
      • 混合反射顏色與表面顏色:
      hlsl
      float3 finalColor = lerp(diffuseColor, reflection, _ReflectAmount);
      

      不同圖形API的實現差異

      Direct3D

      • 面順序:+X, -X, +Y, -Y, +Z, -Z
      • UV坐標系:左上角為(0,0),右下角為(1,1)
      • 需要特別注意Y軸的朝向

      OpenGL

      • 面順序:+X, -X, +Y, -Y, +Z, -Z
      • UV坐標系:左下角為(0,0),右上角為(1,1)
      • 通常需要翻轉Y軸坐標

      Metal

      • 使用MTLTextureTypeCube類型
      • 面順序與Direct3D類似
      • 采樣時需要考慮坐標系轉換

      數學示例:具體采樣過程

      假設有一個方向向量(0.5, -0.3, 0.8),計算其在Cubemap中的采樣位置:

      • 確定主分量:
        • |x|=0.5, |y|=0.3, |z|=0.8 → 主分量為z
      • 確定采樣面:
        • z=0.8 > 0 → +Z面
      • 計算UV坐標:
        • u = 0.5 * (1 + (x/|z|)) = 0.5 * (1 + (0.5/0.8)) ≈ 0.8125
        • v = 0.5 * (1 - (y/|z|)) = 0.5 * (1 - (-0.3/0.8)) ≈ 0.6875
      • 在+Z面紋理上采樣(0.8125, 0.6875)處的顏色

      性能優化考慮

      • ?粗糙度與Mipmap?:根據表面粗糙度選擇適當的Mipmap級別,粗糙表面使用更高層級的Mipmap

        float perceptualRoughness = 1.0 - _Smoothness;
        float mip = PerceptualRoughnessToMipmapLevel(perceptualRoughness);
        float4 envColor = SAMPLE_TEXTURECUBE_LOD(_Cubemap, sampler_Cubemap, reflectDir, mip);
        

      URP中的PLATFORM_SAMPLE_TEXTURECUBE宏通過統一這些復雜操作,使開發者能夠專注于材質效果本身,而無需關心底層平臺差異

      實現示例

      以下是一個簡單的反射Cubemap的Shader實現:

      • 定義Shader屬性,包括顏色、反射顏色、反射強度和Cubemap紋理

      • 頂點著色器計算世界空間的位置、法線、視線方向和反射方向

      • 片元著色器計算環境光、漫反射和反射顏色

      • 使用lerp函數混合漫反射和反射顏色,控制反射強度

      • 最終輸出混合后的顏色

      • URPReflection.shader

        Shader "Custom/URPReflection"
        {
            Properties
            {
                _BaseColor("Base Color", Color) = (1,1,1,1)
                _ReflectColor("Reflection Color", Color) = (1,1,1,1)
                _ReflectAmount("Reflect Amount", Range(0,1)) = 0.5
                _Cubemap("Reflection Cubemap", Cube) = "_Skybox" {}
                _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"
        
                struct Attributes
                {
                    float4 positionOS : POSITION;
                    float3 normalOS : NORMAL;
                };
        
                struct Varyings
                {
                    float4 positionHCS : SV_POSITION;
                    float3 positionWS : TEXCOORD0;
                    float3 normalWS : TEXCOORD1;
                    float3 viewDirWS : TEXCOORD2;
                    float3 reflectDir : TEXCOORD3;
                };
        
                CBUFFER_START(UnityPerMaterial)
                half4 _BaseColor;
                half4 _ReflectColor;
                half _ReflectAmount;
                half _Smoothness;
                CBUFFER_END
        
                TEXTURECUBE(_Cubemap);
                SAMPLER(sampler_Cubemap);
        
                Varyings vert(Attributes IN)
                {
                    Varyings OUT;
        
                    // 頂點變換
                    OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
                    OUT.positionWS = TransformObjectToWorld(IN.positionOS.xyz);
                    OUT.normalWS = TransformObjectToWorldNormal(IN.normalOS);
        
                    // 計算視線方向(從表面點到相機)
                    OUT.viewDirWS = GetWorldSpaceViewDir(OUT.positionWS);
        
                    // 計算反射方向
                    float3 viewDir = normalize(OUT.viewDirWS);
                    OUT.reflectDir = reflect(-viewDir, normalize(OUT.normalWS));
        
                    return OUT;
                }
        
                half4 frag(Varyings IN) : SV_Target
                {
                    // 標準化法線和反射方向
                    float3 normalWS = normalize(IN.normalWS);
                    float3 reflectDir = normalize(IN.reflectDir);
        
                    // 計算漫反射光照
                    Light light = GetMainLight();
                    float3 lightDir = normalize(light.direction);
                    float NdotL = saturate(dot(normalWS, lightDir));
                    half3 diffuse = _BaseColor.rgb * light.color * NdotL;
        
                    // 采樣Cubemap
                    half perceptualRoughness = 1.0 - _Smoothness;
                    half mip = PerceptualRoughnessToMipmapLevel(perceptualRoughness);
                    half4 cubemapColor = SAMPLE_TEXTURECUBE_LOD(_Cubemap, sampler_Cubemap, reflectDir, mip);
                    half3 reflection = DecodeHDREnvironment(cubemapColor, unity_SpecCube0_HDR) * _ReflectColor.rgb;
        
                    // 混合漫反射和反射
                    half3 color = lerp(diffuse, reflection, _ReflectAmount);
        
                    return half4(color, 1.0);
                }
                ENDHLSL
            }
        }
        

      Cubemap生成方法

      在Unity中可以通過以下步驟生成Cubemap:

      • 創建空物體作為觀察位置
      • 在Project視圖右鍵創建Legacy/Cubemap
      • 使用腳本調用Camera.RenderToCubemap方法生成
      • 確保Cubemap勾選Readable選項以便腳本讀取

      Cubemap技術為Unity中的環境反射和高級材質效果提供了強大的支持,通過合理使用可以顯著提升場景的真實感和視覺質量


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

      posted @ 2025-10-05 11:39  SmalBox  閱讀(96)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 西西午夜无码大胆啪啪国模| 国产超碰人人做人人爰| 国产国产久热这里只有精品| 欧美性插b在线视频网站| 国产精品亚洲国际在线看| 免费看欧美全黄成人片| 欧美大bbbb流白水| 亚洲欧美日韩综合一区在线| 日韩有码中文字幕一区二区| 亚洲中文字幕第二十三页| 男女猛烈激情xx00免费视频| 无遮无挡爽爽免费视频| 人人妻人人澡人人爽人人精品电影| 色吊丝一区二区中文字幕| 东明县| 亚洲中文字幕久久精品品| 国产精品有码在线观看| 长白| 潘金莲高清dvd碟片| 性色欲情网站iwww| 久久综合色之久久综合色| 亚洲国产综合精品 在线 一区| 无码人妻精品一区二区三区蜜桃| 国产激情一区二区三区成人| 激情国产av做激情国产爱| 99热在线观看| 老司机免费的精品视频| 国产肥臀视频一区二区三区| 国产伦码精品一区二区| 溧阳市| 国产乱妇乱子视频在播放| 蜜芽亚洲AV无码精品国产午夜| 人妻中文字幕亚洲精品| 国产一区二区三区色视频| 亚洲香蕉伊综合在人在线| 中字幕人妻一区二区三区| 国内精品无码一区二区三区| 波多野结衣一区二区三区高清av| 精品久久久无码中文字幕| 无码人妻丰满熟妇区毛片18| 2021国产精品视频网站|