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

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

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

      【光照】UnityURP[屏幕空間環境光遮蔽SSAO]原理剖析實踐

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

      SSAO(Screen Space Ambient Occlusion,屏幕空間環境光遮蔽)是Unity URP中用于模擬物體間環境光遮蔽效果的技術,通過計算像素周圍幾何體的遮擋關系增強場景深度感和真實感。

      技術發展進程

      • ?早期階段?:傳統SSAO算法如Crytek SSAO(2007年)采用半球采樣和深度比較,計算開銷較大。
      • ?優化階段?:2010年后出現基于屏幕空間法線的改進算法(如HBAO),減少采樣噪聲。
      • ?URP集成?:Unity 2019年將SSAO作為URP核心后處理效果,支持移動端優化實現。

      核心原理

      • ?采樣階段?:在屏幕空間隨機采樣當前像素周圍的深度值,計算遮擋系數。
      • ?遮蔽計算?:通過比較采樣點與當前像素的深度差,確定光線被阻擋的概率。
      • ?模糊處理?:使用雙邊濾波消除噪聲,保留邊緣細節。

      URP實現機制

      URP通過ScreenSpaceAmbientOcclusion渲染特性實現:

      原理示例

      1. 像素P的深度值為Dp,法線為Np
      2. 在半球范圍內隨機采樣點S(深度Ds)
      3. 若(Ds > Dp)則累計遮蔽值
      4. 最終遮蔽強度 = 1 - (可見采樣點/總采樣點)

      采樣階段

      深度紋理獲取?:

      • 通過_CameraDepthTexture獲取屏幕空間深度值,將像素坐標轉換為視圖空間位置

      • 深度紋理獲取原理

        在URP中,_CameraDepthTexture通過以下方式生成:

        • ?深度圖來源?:URP會在渲染不透明物體后通過CopyDepth Pass將場景深度復制到_CameraDepthTexture,若無法直接復制則啟用PreDepthPass逐物體渲染深度
        • ?紋理聲明?:需在Shader中正確定義TEXTURE2D(_CameraDepthTexture)或引用URP內置頭文件DeclareDepthTexture.hlsl
        • ?采樣方式?:使用SAMPLE_TEXTURE2D函數結合屏幕UV坐標獲取非線性深度值,需通過Linear01Depth()轉換為[0,1]范圍的線性深度
      • 像素坐標到視圖空間轉換流程

        • ?屏幕坐標計算?:

          hlsl
          float2 screenUV = i.positionCS.xy / _ScreenParams.xy; // 歸一化到[0,1]范圍
          
        • ?深度值解碼?:

          hlsl
          float depth = SAMPLE_TEXTURE2D(_CameraDepthTexture, sampler_CameraDepthTexture, screenUV);
          float linearDepth = Linear01Depth(depth, _ZBufferParams); // 轉換為線性深度
          
        • ?視圖空間重建?:

          • ?方法一?:通過攝像機射線插值

            hlsl
            float3 viewPos = _CameraInvProjectionMatrix * float4(screenUV * 2 - 1, linearDepth * 2 - 1, 1);
            viewPos /= viewPos.w; // 透視除法
            
          • ?方法二?:使用URP內置函數

            hlsl
            float3 viewPos = ComputeViewSpacePosition(screenUV, linearDepth); // 需包含Core.hlsl
            
      • ?坐標系統轉換?:

        • 屏幕坐標 → NDC坐標 → 裁剪空間 → 視圖空間,需注意不同API的NDC范圍差異(OpenGL為[-1,1],DirectX為[0,1])
      • ?深度值特性?:

        • 原始深度值為非線性分布(透視投影),Linear01Depth通過_ZBufferParams參數處理平臺差異
      • ?性能優化?:

        • 移動端建議使用SampleSceneDepth()封裝方法,自動處理平臺兼容性問題

      完整實現可參考URP的ScreenSpaceAmbientOcclusion.hlsl文件,其中包含深度采樣和空間轉換的標準流程

      ?法線重建?:

      • 利用深度差計算相鄰像素的法線向量,形成法線半球采樣空間

      • ?深度差計算?

        • 對當前像素的上下左右四個相鄰像素進行深度采樣,計算水平/垂直方向的高度差:
        hlsl
        float u = rightDepth - leftDepth;  // 水平差分
        float v = bottomDepth - topDepth;  // 垂直差分
        
        • 該過程通過_CameraDepthTexture獲取深度值,并轉換為線性深度?。
      • ?法線向量生成?

        • 將深度差轉換為向量后叉乘得到法線:
        hlsl
        Vector3 vec_u = (1, 0, u);  // 水平方向向量
        Vector3 vec_v = (0, 1, v);  // 垂直方向向量
        Vector3 normal = cross(vec_u, vec_v);  // 叉乘結果
        

        最終法線需歸一化處理,確保長度為1。

      • ?法線半球采樣空間?

        • 以重建的法線為基準,在其半球空間內均勻分布采樣點,用于環境光遮蔽計算。該空間滿足:
          • 采樣方向與法線夾角≤90°(max(0, N·S)
          • 采樣點深度差決定遮蔽強度(1-saturate(Ds-Dp)/半徑)?
      • 技術實現細節

        • ?深度紋理采樣?:需在URP中啟用DepthTextureMode.Depth,通過SAMPLE_DEPTH_TEXTURE獲取非線性深度?
        • ?坐標轉換?:屏幕坐標需通過ComputeScreenPos()轉換為NDC坐標,再通過_CameraInvProjectionMatrix還原視圖空間位置?
        • ?性能優化?:移動端建議使用SampleSceneDepth()封裝方法,避免平臺兼容性問題?

      ?隨機采樣?:

      • 在法線半球內生成隨機向量(如64個采樣點),通過旋轉噪聲紋理避免帶狀偽影
      • 偽影(Artifacts)的成因
        • 在屏幕空間環境光遮蔽(SSAO)等算法中,?帶狀偽影?(Banding Artifacts)通常表現為采樣點分布不均勻導致的明暗條紋。這種偽影主要由以下原因引起:
          • ?固定采樣模式?:當使用固定網格或規則模式生成采樣點時,相鄰像素的采樣方向過于相似,導致光照計算出現周期性重復?
          • ?噪聲紋理重復?:直接使用靜態噪聲紋理(如Perlin噪聲)作為采樣方向偏移時,紋理的周期性重復會放大采樣點的規律性?
      • 旋轉噪聲紋理的解決方案
        • 通過旋轉噪聲紋理避免偽影的核心原理是?破壞采樣方向的周期性?,具體實現方式如下:
          • ?動態旋轉噪聲?

            • 為每個像素生成唯一的旋轉角度(如基于UV坐標或隨機種子)
            • 將噪聲紋理的UV坐標與旋轉矩陣相乘,使噪聲圖案在空間上動態變化?
            hlsl
            // 示例:基于UV坐標的旋轉
            float2 rotatedUV = mul(noiseUV, rotationMatrix);
            float noiseValue = tex2D(_NoiseTex, rotatedUV);
            
          • ?采樣點分布優化?

            • 在法線半球內生成隨機向量時,將噪聲值作為方向偏移量:

            隨機向量s = normalize(noiseOffset × baseSampleDirection)

            • 通過旋轉噪聲紋理,使相鄰像素的采樣方向差異最大化,避免重復模式?
          • ?技術優勢?

            • ?消除周期性?:旋轉后的噪聲紋理在空間上無重復規律,破壞帶狀偽影的數學基礎?
            • ?計算高效?:僅需一次紋理采樣和矩陣運算,適合實時渲染?
      • 實現參考
        • URP中可通過以下步驟實現:
          • 定義噪聲紋理_NoiseTex并設置_NoiseUVScale控制縮放
          • 在片元著色器中計算旋轉后的噪聲值,用于調整采樣方向?

      示例

      • 對像素P(深度1.0)生成采樣點S(隨機偏移0.2,0.3),轉換后深度為1.15

      遮蔽計算階段

      ?深度比較?:

      • 將采樣點投影回屏幕空間,比較采樣深度與原深度

      • 若采樣深度更近(如S深度0.9 < P深度1.0),累計遮蔽值

      • 深度值還原?:將采樣的非線性深度值通過Linear01Depth()函數轉換為線性空間值(范圍[0,1])

        關鍵代碼

        hlsl
        float sampledDepth = Linear01Depth(SAMPLE_TEXTURE2D(_CameraDepthTexture, sampler_CameraDepthTexture, uv), _ZBufferParams);
        
      • ?深度差計算?:比較采樣點深度與原像素深度,通常結合采樣半徑進行歸一化處理

        判定邏輯

        hlsl
        if (sampledDepth < currentDepth)
            occlusion += (currentDepth - sampledDepth) / _Radius;
        
      • ?邊緣處理?:當采樣點超出屏幕邊界時,默認按無遮擋處理或使用邊緣像素值

      • 在URP管線中,上述流程通過以下步驟完成:

        • 使用ComputeScreenPos()函數生成屏幕坐標
        • 通過SampleSceneDepth()方法采樣深度紋理
        • 最終比較采用視圖空間Z值而非線性深度,避免透視畸變影響

      ?法線權重?:

      • 根據采樣點與法線夾角衰減貢獻,排除背面無效采樣

      公式

      遮蔽因子 = max(0, N·S) * (1-saturate(Ds-Dp)/半徑)

      • 法線權重部分(N·S)
        • ?點積運算?:N·S表示表面法線向量N與采樣方向向量S的點積,用于評估采樣點與法線的夾角關系
        • ?背面剔除?:max(0, N·S)確保只有法線半球內的采樣點(夾角小于90°)產生貢獻,排除背面無效采樣示例:當N=(0,1,0)且S=(0.3,0.8,0)時,點積結果為0.8,有效權重為0.8
      • 深度差部分(Ds-Dp)
        • ?深度比較?:Ds-Dp計算采樣點深度與原像素深度的差值,正值表示采樣點更近(產生遮擋)
        • ?歸一化處理?:saturate(Ds-Dp)將差值鉗制在[0,1]范圍,避免極端值干擾
        • ?半徑歸一化?:除以采樣半徑_Radius使結果與采樣范圍無關,保證不同尺度下的一致性
      • 綜合計算
        • ?遮蔽強度?:1-saturate(Ds-Dp)/半徑將深度差轉換為可見性系數(0完全遮蔽,1完全可見)
        • ?最終乘積?:法線權重與可見性系數相乘,實現物理正確的遮蔽衰減應用場景:當采樣點S在法線后方(N·S<0)或未被遮擋(Ds>Dp)時,該點貢獻為0

      該公式在URP中通過ScreenSpaceAmbientOcclusion.hlsl實現,核心代碼段如下:

      hlsl
      float occlusion = 0;
      for (int i = 0; i < _SampleCount; i++) {
          float3 sampleDir = normalize(_Samples[i]);
          float weight = max(dot(normal, sampleDir), 0);
          float depthDiff = (SampleDepth(samplePos) - centerDepth) / _Radius;
          occlusion += weight * (1 - saturate(depthDiff));
      }
      

      模糊處理階段

      • 雙邊濾波?:結合空間距離和顏色差異保留邊緣
        • 水平/垂直兩次高斯模糊,權重計算包含深度差閾值
      • ?降噪優化?:使用低差異序列采樣減少噪聲,或通過Temporal AA累積幀數據

      實際應用

      代碼說明:

      • 動態啟用URP后處理管線

      • 配置SSAO強度、采樣半徑等關鍵參數

      • 支持運行時參數調整

      • SSAOSetup.cs

        using UnityEngine;
        using UnityEngine.Rendering.Universal;
        
        public class SSAOSetup : MonoBehaviour {
            void Start() {
                var urpAsset = GraphicsSettings.renderPipelineAsset 
                    as UniversalRenderPipelineAsset;
        
                // 啟用SSAO后處理
                urpAsset.GetComponent<UniversalAdditionalCameraData>()
                    .renderPostProcessing = true;
        
                // 參數配置示例
                var ssao = ScriptableObject.CreateInstance<ScreenSpaceAmbientOcclusion>();
                ssao.Intensity = 1.2f;
                ssao.Radius = 0.3f;
                ssao.SampleCount = 16;
            }
        }
        

      使用建議

      • ?移動端優化?:降低SampleCount至8-12,使用Downsample模式。
      • ?美術控制?:通過材質參數控制不同區域的遮蔽強度。
      • ?性能監控?:在Profiler中觀察SSAO.Pass的耗時

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

      posted @ 2025-10-17 12:40  SmalBox  閱讀(82)  評論(0)    收藏  舉報
      主站蜘蛛池模板: 精品国产一区二区三区av性色| 亚洲高潮喷水无码AV电影| 亚洲综合一区二区三区视频| 好姑娘高清影视在线观看| 亚洲色大成网站www永久男同| 亚洲国产精品综合一区二区| 久久亚洲综合精品成人网| 99中文字幕精品国产| 性色欲情网站| 国产互换人妻xxxx69| 少妇人妻偷人精品系列| 国产成人精品无码免费看| 狠狠色综合网站久久久久久久| 惠来县| 婷婷99视频精品全部在线观看| 亚洲精品爆乳一区二区H| 久久a级片| 久久天天躁夜夜躁狠狠| 久久精品国产一区二区三区| 国产精品美女AV免费观看| 国产免费又黄又爽又色毛| 美日韩不卡一区二区三区| 国产色无码专区在线观看| 精品精品亚洲高清a毛片| 精品中文人妻在线不卡| 渑池县| 国产亚洲精品成人av久| 久久久久成人片免费观看蜜芽| 精品人妻二区中文字幕| 精品日韩精品国产另类专区| 人妻无码中文字幕免费视频蜜桃| 综合人妻久久一区二区精品| 亚洲精品777| 又大又硬又爽免费视频| 国产自拍偷拍视频在线观看| 国产95在线 | 欧美| 国厂精品114福利电影免费| 亚洲高潮喷水无码AV电影| 国产在线国偷精品产拍| 丁香五月激情图片| 亚洲免费观看一区二区三区|