2012-04-05 143 views
1

我渲染動畫幾何。在每一幀中,我都希望使用前一幀中的屏幕空間紋理對幾何進行紋理映射(投影到前一幀中的幾何圖形)。所以結果應該是這樣的,如果屏幕空間紋理在一幀前投影到幾何圖形上,然後通過幾何動畫轉換爲當前幀。紋理投影+透視校正,獲得數學權

計算每個頂點的正確紋理座標並不困難。在GLSL那乾脆:

void main(void) 
{ 
    vPos = currentMVP * vec4(position,1); 
    gl_Position = vPos; 
    vec4 oldPos = previousMVP * vec4(position,1); 
    vec2 UV = vec2(((oldPos.x/oldPos.w)+1)*0.5f, ((oldPos.y/oldPos.w)+1)*0.5f); 
    ... 
} 

但得到texturecoordinates正確地插在幾何形狀比我thoght更加棘手。通常情況下,投影紋理座標應該在屏幕空間內線性插值 - 所以要實現這一點,他們會將它們乘以頂點着色器中的vPos.w,然後再由碎片着色器中的vPos.w進行分割。但是,如果紋理是從cameraview投影的,則這是正確的。在這種情況下,我需要別的東西。我需要一個插值,該插值屬性用於前一幀中的前視角正確插值和當前幀中的後視角正確插值。

該圖形示出了三種不同的情況: enter image description here

- 案例A爲簡單。在這裏我可以離開紋理座標的正常透視校正插值(由光柵器默認執行)。但是,我需要紋理座標的線性插值來獲得正確的結果(通過在vertexShader中乘以vPos.w並在片段着色器中除以vPos.w,或者在較新的GLSL版本中通過使用「noperspective」插值限定符)。

- 在情況C我需要透視校正插值,但根據oldPos.w值。所以我必須通過將u'與頂點的currentPos.w相乘來線性化u'=(u/oldPos.w)和v'=(v/oldPos.w)的插值,並將插值後的值除以currentPos.w in分段。我也需要以相同的方式線性插入w'=(1/oldPos.w),然後通過將插入的u'除以插入的w'(並且分別對於v「)來計算片段中的最終u」' )。

所以 - 現在的問題是,在這兩種情況下獲得正確結果的恰當數學是什麼?

再次,計算頂點的正確uv是不是問題。這是關於在三角形上實現正確的插值。

//也許相關:在相同的通我也想這樣做使用非投射對象的一些規則紋理,透視修正紋理。這意味着我不能改變gl_Position.w的值。

+1

請解釋(簡單地)_通常情況下,投影的texturecoordinates應該在screenspace_和_non投影,透視校正texturing_線性插值。 – 2012-04-05 15:27:46

回答

2
vec2 UV = vec2(((oldPos.x/oldPos.w)+1)*0.5f, ((oldPos.y/oldPos.w)+1)*0.5f); 

錯了。你需要的W;你不想分裂。你想要的是這樣的:

vec4 oldPos = previousMVP * vec4(position,1); 
oldPos = clipToTexture * oldPos; 
vec3 UV = oldPos.xyw; 

clipToScreen矩陣是一個4x4矩陣,可以做從剪輯到屏幕空間所需要的規模和翻譯。這就是你的規模0.5和加入1.0在做什麼。這裏是矩陣形式;通常情況下,你只是左乘「previousMVP」這一點,所以這都將是一個矩陣乘法。

在你的片段着色器中,你需要做投影紋理查找。我不記得了GLSL 1.20的功能,但我知道the 1.30+ function:

vec4 color = textureProj(samplerName, UV.stp); 

正是這種功能,將做必要的分工,由-W一步。

+0

這條線只是頂點UV的正確計算。爲了正確插入它,它仍然必須乘以oldPos.w(撤銷/oldPos.w),然後在它的片段中進行分割(這意味着......)。你的建議會得到正確的結果案例B,但不是情況A(和C我認爲) – Mat 2012-04-05 09:57:32

+1

@Mat:你的數學是錯誤的。透視正確的投影紋理座標插值是你想要的。 – 2012-04-05 10:01:35