2012-12-06 50 views
0

我正在做的是使用普通地圖來點亮2D精靈。最初我打算在圖像紅色通道中使用凹凸/高度地圖,並使用另外兩個通道來存儲其他信息。 我的想法是,因爲我知道法線貼圖上的任何法線總是有[az]值在[0 .. 1]的範圍內,我可以從藍色通道中排除這些信息並計算基於長度的z值x和y值。 所以我試了一下,它似乎工作到目前爲止,它看起來幾乎與原來的相同。雙通道法線貼圖的性能成本和下降是多少?

我的問題是附加說明的成本是多少?有幾個額外的乘法和加法以及另外兩個sqrt調用。

下面是所使用的片段着色器:

// Input > 
// fc0 : Color to normal conversion factor - <2, 1, 0, 0> 
// fc1 : Light - <lightDirection.x, lightDirection.y, lightDirection.z> 
// v0 : texture coordinates - <u, v> 
// fs0 : color texture 
// fs1 : normal map 

// Sample normal map (fs1) at coordinates (v0) into temp register (ft0) 
tex ft0 v0 fs1 <2d,nearest> 
// Convert color values [0, 1] to normal values [-1, 1] 
mul ft0 ft0 fc0.xxx 
sub ft0 ft0 fc0.yyy 

// 
// The code below is used to calculate the z value from the 
// 2D x/y normal values 
// 

// <Start normal z calculation> 

// (ft0) should now hold a 2D vector - first find its length 
// - length = sqrt(x * x + y * y) 
mul ft1.x ft0.x ft0.x // x * x 
mul ft1.y ft0.y ft0.y // y * y 
add ft1.z ft1.x ft1.y // (x * x + y * y) 
sqt ft1.z ft1.z // ft1.z = sqrt(x * x + y * y) 
// Now using the length of the 2D normal find the z value 
// - z = sqrt(1 - length * length) 
mul ft1.z ft1.z ft1.z // length * length 
sub ft1.z fc0.y ft1.z // 1 - length * length 
sqt ft1.z ft1.z // ft1.z = sqrt(1 - length * length) 
// Now move the z value into temp register (ft0) along with the normal x and y value 
mov ft0.z ft1.z 

// <End normal z calculations> 

// The rest of the shader left out 
+0

只有您針對的實際硬件上的測試才能顯示哪種方法更好。如果您試圖節省GPU內存,那麼您可能會針對移動硬件。但是,通常,諸如mul和sqt等操作的成本在移動設備上要高得多(取決於設備)。 – skozin

回答

0

SQRT是操作非常慢。所以你應該儘可能避免它。實際上,在正常映射之前,只有代表高度的灰度圖像進行凹凸映射。在這種情況下,正常計算基於neightbor像素。但是當硬件內存增長時,不值得節約。但是在移動設備上