簡體   English   中英

將 2D 和 3D 陰影貼圖發送到着色器

[英]Sending 2D and 3D shadowmaps to shaders

我正在嘗試為我的簡單引擎實現陰影貼圖,我發現我應該將全向陰影貼圖(點光源的立方體貼圖)與二維貼圖(方向燈和聚光燈)結合起來。

我的統一塊看起來像這樣:

#define MAX_LIGHTS 128
//...
struct Light
{
   //light data...
};
//...
layout (std140) uniform Lights
{
    int lightCount; //how many lights were passed into the shader (from 0 to MAX_LIGHTS)
    Light lights[MAX_LIGHTS];
};

我有兩個問題要問你。

  1. 采樣器對象成本高嗎? 以下代碼是否適用於多個燈?

     sampler2D shadowMaps2D[MAX_LIGHTS]; samplerCube shadowCubemaps[MAX_LIGHTS]; //... if (lights[index].type == POINT_LIGHT) CalculateShadow(shadowCubemaps[lights[index].shadowMapNr]); else CalculateShadow(shadowMaps2D[lights[index].shadowMapNr]);

    只有lightCount數量的對象會實際填充紋理。 我們遇到了很多未定義的采樣器,我認為這會導致一些問題。

  2. 如果我理解正確,我不能在統一塊中聲明采樣器 那么,每次陰影貼圖更新時,我真的被迫循環遍歷所有着色器並更新采樣器嗎? 這是浪費時間!

采樣器對象成本高嗎?

這個問題有點誤導,因為 GLSL 中的sampler數據類型只是引用紋理單元的不透明句柄 代價高昂的是實際的采樣操作。 此外,特定陰影階段的紋理單元數量是有限的。 該規范僅保證 16 個。由於您不能為不同的采樣器類型重復使用相同的單元,這會將您的MAX_LIGHTS限制為僅 8 個。

然而,很少需要采樣器陣列。 相反,您可以使用數組 textures ,這將允許您將所有陰影貼圖(每種紋理類型)存儲在單個紋理對象中,並且您只需要一個采樣器。

說了這么多我還是覺得你的光數是完全不現實的。 即使在最快的 GPU 上,實時應用 128 個陰影貼圖也行不通……

如果我理解正確,我不能在統一塊中聲明采樣器

正確的。

那么,每次陰影貼圖更新時,我真的被迫循環遍歷所有着色器並更新采樣器嗎? 這是浪費時間!

不。僅當您要從中采樣的紋理單元索引發生變化(理想情況下永遠不會)時,才需要更新采樣器制服。 不是當綁定不同的紋理時,也不是當某些紋理內容更改時。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM