我需要幫助,在我的遊戲中組織着色器。HLSL - 組織着色器和技術,不會迷路
遊戲使用頂點和像素着色器進行紋理和照明。一些物體紋理,其他只是有色,然後有幾個照明算法 - 光照貼圖,漫反射和鏡面光照,一些只有一些物體得到的影子等。
我的第一個想法是有一個大的,漂亮的着色技術它可以根據參數處理所有事情。這是偉大的,以保持(僞代碼給想法):
float4 PixelShaderFunction(input)
{
if (UseTexture)
objectColor = tex2D(...)
else
objectColor = ObjectColor;
if (UseAmbient)
...
if (UseDiffuseLight)
...
// etc...
}
但是表現得很差。
然後我創建了多種技術來避免if
分支,所以每種技術只使用特定對象所需的東西。所以如果對象不接受陰影,那裏沒有代碼。如果它沒有使鏡面光線,沒有代碼。另外我將通用功能分組到功能中。像這樣(真實代碼現在):
float4 Textured_PixelShader(Textured_VsOut input) : COLOR0
{
float4 lightLevel = 0;
float4 objectColor = GetObjColorTex(input.TexUV);
// calculate main table lighting
PsAddTableLight(input.WorldPosition, input.Normal, lightLevel);
// calculate cloth lighting
PsAddClothLight(input.WorldPosition, input.Normal, lightLevel);
// calculate fill light - do we need it?
PsAddFillLight(input.Normal, lightLevel);
// add ambient light
PsAddAmbientLight(lightLevel);
// apply light
PsApplyDiffuseLight(lightLevel, objectColor);
// add speculars
PsAddSpecularBlurred(input.WorldPosition, input.Normal, objectColor);
// final work
return PsFinalize(objectColor);
}
性能的提高是巨大的。
但是我在維護着色器時迷路了。每隔一天我需要添加一項新技術,因爲還沒有組合texture + lightmap + this_kind_of_shadow + specular
或任何我需要的。他們中的一些人得到這樣的名字,另一些人則以他們所使用的對象命名,因爲只有一個具有這種組合的對象。它變得一團糟。
我有那麼兩個問題:
- 爲什麼我不能有那些
if
報表?我讀了很多關於條件執行如何傷害GPU的內容,但是我的ifs只依賴於所有渲染像素(或vert)具有相同值的着色器參數。爲什麼他們不能很快?我真的很想念他們。 - 將此代碼分成不同的着色器/技術/文件的最佳方式是什麼?有沒有好的標準或規則?
不幸的是,我似乎無法按照自己的方式(動態編譯),因爲monogame不支持它,即使它只會限於某些平臺。但這是我認可的偉大而有價值的答案 - 謝謝。 – Arek
至於爲什麼'如果'很慢 - 我仍然不確定,但很快就會做一些複驗來驗證性能放緩。根據所有來源,它應該是快速的,因爲對於所有呈現的東西,「if」條件是相同的。 – Arek