2017-04-17 57 views
1


我一直在研究將貼花投影到任何貼圖框封裝的東西。在閱讀並嘗試了很多代碼片段(通常在HLSL中)之後,我在GLSL中有一些工作方法用於投射貼圖。GBUFFER貼花投影和縮放

讓我從試圖解釋我在做什麼以及如何工作(到目前爲止)開始。
下面的代碼現在已修復並正常工作!

這一切都是在透視圖模式下進行的。
我發送2個制服到片段着色器「tr」和「bl」。這些是邊界框的兩個角落。我可以並且將用硬編碼大小替換它們,因爲它們是貼花原始邊界框的大小。 tr = vec3(.5,.5,.5)和br = vec3( - 。5,-.5,-.5)。我更願意找到一種方法來在貼圖轉換狀態下進行位置測試。 (最後更多關於這個)。

爲清楚起見,添加此項。從頂點程序發出的頂點是邊界框乘以貼花矩陣和模型視圖投影矩陣。我將其用於下一步:
使用該頂點,我從深度紋理獲得深度值,並且與它一起,使用投影矩陣的逆來計算世界空間中的位置。

接下來,我使用Decals矩陣的反轉來翻譯此位置。 (將1,1,1立方體縮放,旋轉並平移到其世界位置的矩陣,我認爲通過使用貼圖轉換矩陣的逆,屏幕點的正確大小和旋轉將被正確處理,但它是不

頂點程序:

//Decals color pass. 

#version 330 compatibility 

out mat4 matPrjInv; 

out vec4 positionSS; 
out vec4 positionWS; 
out mat4 invd_mat; 

uniform mat4 decal_matrix; 

void main(void) 
{ 

    gl_Position = decal_matrix * gl_Vertex; 
    gl_Position = gl_ModelViewProjectionMatrix * gl_Position; 

    positionWS = (decal_matrix * gl_Vertex);; 
    positionSS = gl_Position; 

    matPrjInv = inverse(gl_ModelViewProjectionMatrix); 

    invd_mat = inverse(decal_matrix); 

} 

片斷程序:

#version 330 compatibility 

layout (location = 0) out vec4 gPosition; 
layout (location = 1) out vec4 gNormal; 
layout (location = 2) out vec4 gColor; 


uniform sampler2D depthMap; 
uniform sampler2D colorMap; 
uniform sampler2D normalMap; 
uniform mat4 matrix; 

uniform vec3 tr; 
uniform vec3 bl; 
in vec2 TexCoords; 
in vec4 positionSS; // screen space 
in vec4 positionWS; // world space 

in mat4 invd_mat; // inverse decal matrix 

in mat4 matPrjInv; // inverse projection matrix 

void clip(vec3 v){ 
    if (v.x > tr.x || v.x < bl.x) { discard; } 
    if (v.y > tr.y || v.y < bl.y) { discard; } 
    if (v.z > tr.z || v.z < bl.z) { discard; } 
} 


vec2 postProjToScreen(vec4 position) 
{ 
    vec2 screenPos = position.xy/position.w; 
    return 0.5 * (vec2(screenPos.x, screenPos.y) + 1); 
} 
void main(){ 

    // Calculate UVs 
    vec2 UV = postProjToScreen(positionSS); 

    // sample the Depth from the Depthsampler 
    float Depth = texture2D(depthMap, UV).x * 2.0 - 1.0; 

    // Calculate Worldposition by recreating it out of the coordinates and depth-sample 
    vec4 ScreenPosition; 
    ScreenPosition.xy = UV * 2.0 - 1.0; 
    ScreenPosition.z = (Depth); 
    ScreenPosition.w = 1.0f; 

    // Transform position from screen space to world space 
    vec4 WorldPosition = matPrjInv * ScreenPosition ; 
    WorldPosition.xyz /= WorldPosition.w; 
    WorldPosition.w = 1.0f; 

    // transform to decal original position and size. 
    // 1 x 1 x 1 
    WorldPosition = invd_mat * WorldPosition; 
    clip (WorldPosition.xyz); 

    // Get UV for textures; 
    WorldPosition.xy += 0.5; 
    WorldPosition.y *= -1.0; 

    vec4 bump = texture2D(normalMap, WorldPosition.xy); 
    gColor = texture2D(colorMap, WorldPosition.xy); 

    //Going to have to do decals in 2 passes.. 
    //Blend doesn't work with GBUFFER. 
    //Lots more to sort out. 
    gNormal.xyz = bump; 
    gPosition = positionWS; 

    } 

這裏是上一對夫婦形象的什麼是錯 我得到什麼了投影: enter image description here

這是貼花的實際尺寸..比我的着色器創建的尺寸大得多! enter image description here

我曾嘗試使用貼花和投影矩陣,構建一種「LOOKAT」矩陣和翻譯到貼花屏幕位置生成一個新的矩陣郵政變換狀態下的..我一直沒能得到這工作。有些地方我錯過了什麼,但在哪裏?我認爲使用貼圖矩陣的反轉來處理轉換並將屏幕位置置於正確的轉換狀態。想法?

已更新紋理UV的代碼。您可能需要根據y和x是否在x或y上翻轉來調整y和x。我也修復了剪輯子,所以它能正常工作。事實上,這段代碼現在可以工作。如果需要,我會更新這些內容,這樣其他人就不必經歷我所做的工作。 需要解決的一些問題是貼花相互疊加。上面的那個寫下面的那個。我想我必須將顏色和法線聚集到默認的FBO中,然後在光照過程之前或過程中將它們混合(添加)到GBUFFER紋理。添加更多的屏幕尺寸紋理並不是一個好主意,因此我需要富有創造性並回收任何紋理。

我發現相互重疊的貼花解決方案。 關掉深度掩蔽在繪製貼花和INT重新打開算賬:

glDepthMask(GL_FALSE) 
+0

好了,從概念上講,你的方法可以工作。你的貼花矩陣是如何構造的,以及你的「貼花空間」是如何定義的,並不是很清楚。我沒有得到的是'clip'函數的組合,用於在文本中給出的值。它轉換爲「if(v.x <0.5 || v.x> -0.5)」,這總是正確的。你可能會混淆文本中的值... – derhass

+0

混淆主要是我最近的:)我可能有tr和bl切換的值.. id必須查看通過它們的代碼。 貼花矩陣只是從模型到世界空間的標準4x4變換矩陣。它實際上剪貼畫貼圖並在正確的位置繪製,只是它沒有投影到正確的大小。它基本上保留了剪輯的1x1大小。 –

+0

好吧..它不保留1x1的比例..我錯了。這是縮放,但不是我所期望的。在我發佈的第二張圖片中,這是邊界邊界框(1 x 1 x 1)乘以相關矩陣。如果我能以某種方式縮小剪輯測試的邊界框角度而不引發任何旋轉,那麼可以修復它。我會看看我是否能找到辦法做到這一點,並儘快回到這裏,並提供有關我的結果的信息。 –

回答

1

OK ..我太興奮了。我發現了這個問題。 我再次更新了上面的代碼。 我有什麼,我送着色器TR和BL的錯誤: 這裏是改變夾:

void clip(vec3 v){ 
    if (v.x > tr.x || v.x < bl.x) { discard; } 
    if (v.y > tr.y || v.y < bl.y) { discard; } 
    if (v.z > tr.z || v.z < bl.z) { discard; } 
}