AMD Leo Demo 背後的技術

來源:互聯網
上載者:User

前幾天,想看看AMD以前的技術示範,看到了這個demo。可惜沒有AMD的顯卡,看不到的實際效果。網上資料找了半天沒有找到,昨天剛剛在案頭上發現了一個ppt,Technology Behind AMD’s “Leo Demo”。去年在GDC上發布的ppt,關於leo Demo的光照。

Leo Demo沒有選擇延遲渲染,原因有三點,一是材質太複雜,二是燈光總類都,三是支援半透明。其中用到了light culling,思想是將全局座標系內的燈光在螢幕座標系內進行分割,分成一個個小的tile,每個tile儲存自己的光照資訊。其實和戰地3裡的方法差不多,只不過戰地3用的是延遲渲染。

然後在渲染像素的時候找到對應的tile取裡面的光照資訊,完成光照計算,輸出結果。其中很重要的一點事使用了UAV(unorder access view)來儲存光照資訊,沒有這個功能是無法實現的。其實很簡單,看看就可以了。

代碼如下:

//1. preparefloat4 frustum[4];float minZ, maxZ;{ConstructFrustum( frustum );minZ = thread_REDUCE(MIN, depth );maxZ = thread_REDUCE(MAX, depth );ldsMinZ = SIMD_REDUCE(MIN, minZ );ldsMaxZ = SIMD_REDUCE(MAX, maxZ );minZ = ldsMinZ;maxZ = ldsMaxZ;}

_local u32 ldsNLights = 0;__local u32 ldsLightBuffer[MAX];//2. overlap check, accumulate in LDSfor(int i=threadIdx; i<nLights; i+=WG_SIZE){Light light = fetchAndTransform( lightBuffer[ i ] );if( overlaps( light, frustum ) && overlaps ( light, minZ, maxZ ) ){AtomicAppend( ldsLightBuffer, i );}}

//3. export to global__local u32 ldsOffset;if( threadIdx == 0 ){ldsOffset  = AtomAdd( ldsNLights );globalLightStart[tileIdx] = ldsOffset;globalLightEnd[tileIdx] = ldsOffset + ldsNLights;}for(int i=threadIdx; i< ldsNLights; i+=WG_SIZE){int dstIdx = ldsOffset + i;globalLightIndexBuffer[dstIdx] = ldsLightBuffer[i];}
// BaseLighting.inc     // THIS INC FILE IS ALL THE COMMON LIGHTING CODEStructuredBuffer<float4>  LightParams          : register(u0);StructuredBuffer<uint>    LowerBoundLights  : register(u1);StructuredBuffer<uint>    UpperBoundLights  : register(u2);StructuredBuffer<int2>    LightIndexBuffer     : register(u3);uint GetTileIndex(float2 screenPos){   float tileRes  = (float)m_tileRes;   uint numCellsX = (m_width + m_tileRes - 1)/m_tileRes;   uint tileIdx   = floor(screenPos.x/tileRes)+floor(screenPos.y/tileRes)*numCellsX;   return tileIdx;}

StartHLSL BaseLightLoopBegin// THIS IS A MACRO, INCLUDED IN MATERIAL SHADERS uint tileIdx    = GetTileIndex( pixelScreenPos ); uint startIdx  = LowerBoundLights[tileIdx];  uint endIdx   = UppweBoundLights[tileIdx]; [loop] for ( uint lightListIdx = startIdx; lightListIdx < endIdx; lightListIdx++ ) {int lightIdx = LightIndexBuffer[lightListIdx];// Set common light parametersfloat ndotl = max(0, dot(normal, lightVec));float3 directLight   = 0;float3 indirectLight = 0;    if( lightIdx >= numDirectLightsThisFrame )    {       CalculateIndirectLight(lightIdx , indirectLight);    }    else      {        if( IsConeLight( lightIdx ) )        {        //    <<==  Can add more light types here            CalculateDirectSpotlight(lightIdx , directLight);        }     else     {         CalculateDirectSpherelight(lightIdx , directLight);     } } float3 incomingLight = (directLight + indirectLight)*ndotl; float shadowTerm = CalcShadow();EndHLSLStartHLSL BaseLightLoopEnd         }EndHLSL

#include "BaseLighting.inc"float4 PS ( PSInput i ) : SV_TARGET{     float3 totalDiffuse = 0;     float3 totalSpec    = GetEnvLighting();;$include BaseLightLoopBegin// unique material code goes here!! Light accumulation on the pixel for a given light// we have total incoming light and direct/indirect light components as well as material params and shadow term// use these building blocks to integrate lighting terms         totalDiffuse += GetDiffuse(incomingLight);        totalSpec    += CalcPhong(incomingLight);$include  BaseLightLoopEnd   float3 finalColor = totalDiffuse + totalSpec;   return float4( finalColor, 1 );}

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.