2017-10-16 86 views
1

我在C++ OpengL程序和GLSL頂點和片段着色器上工作。從GLSL着色器直接位置計算轉換mattrix

我正在創建同一個對象的幾個實例。我只需要改變實例之間的對象位置。

這是我所做的:我正在使用一個統一的變量,這是一個變換矩陣的數組。每個矩陣代表一個對象實例。

MVP也是一個變換矩陣,但MVP是由相機的位置,方向和屬性設置的。

這裏是我的頂點着色器:

#version 330 core 
    layout(location = 0) in vec3 vertex_position; 
    layout(location = 1) in vec3 vertex_color; 

    uniform mat4 object_positions[20]; 
    out vec3 fragment_color; 
    uniform mat4 MVP; 

    void main() 
    { 
     gl_Position = object_positions[gl_InstanceID] * MVP * vec4(vertex_position,1.0); 
     fragment_color = vertex_color; 
    } 

以下是我在C++程序做設置目標位置:

glm::mat4 object_positions[20]; 
    object_positions[0] = glm::translate(glm::mat4(1), glm::vec3(0.4f,0.2f,0.0f)); 
    object_positions[1] = glm::translate(glm::mat4(1), glm::vec3(0.5f,1.4f,0.0f)); 
    ... 
    object_positions[19] = glm::translate(glm::mat4(1), glm::vec3(-10.6f,0.2f,0.0f)); 
    GLuint object_positions_id = glGetUniformLocation(program_id, "object_positions"); 
    ... 
    glUniformMatrix4fv(object_positions_id, 7, GL_FALSE, glm::value_ptr(object_positions[0])); 

您認爲GLM的第二個參數的VEC 3 :: translate包含每個對象的位置。 在這一點上,每件事情都很好。

我想要做的是在着色器中計算glm :: translte。我其實想要的是發送一個vec3而不是每個位置的mat4。我希望GPU能夠計算轉換矩陣而不是CPU。我試過的所有東西都不起作用。

由於

+0

不,它不工作。這是完全一樣的結果。 object_positions在這種情況下應該是一個轉換矩陣,而不是一個位置 – Bob5421

+1

爲什麼只需要添加偏移量時需要一個矩陣更簡單快捷? –

+0

是的,這是一個好主意,但我應該把什麼w? – Bob5421

回答

0

你絕對不能做object_positions[gl_InstanceID] * MVP * vec4(vertex_position,1.0);(即使object_positions是矩陣)後因投影矩陣已被應用,這將是翻譯。

如果你不這樣做的情況下的任何旋轉,沒有理由不只是這樣做

gl_Position = MVP * vec4(vertex_position + object_positions[gl_InstanceID],1.0); 
1

對於OpenGL的變換矩陣僅僅是一個16個條目(4X4矩陣說起)的二維陣列。在這個矩陣中,第13,14,15條定義了你的翻譯組件。因此,如果要將矩陣存儲在第4行第0行的主行中,則第1條和第2條應該是要發送到着色器的向量x,y,z分量。您可以用這種方式在着色器中構建翻譯矩陣。請確定如果你有行主矩陣,然後轉換您預先乘以矩陣的頂點以查看翻譯的效果。

gl_Position = Translation Matrix * gl_Vertex; 

如果您的矩陣是列主要,您將張貼乘法。

3

一個4 * 4矩陣如下所示:

c0 c1 c2 c3   c0 c1 c2 c3 
[ Xx Yx Zx Tx ]  [ 0 4 8 12 ]  
[ Xy Yy Zy Ty ]  [ 1 5 9 13 ]  
[ Xz Yz Zz Tz ]  [ 2 6 10 14 ]  
[ 0 0 0 1 ]  [ 3 7 11 15 ] 

在GLSL一個mat4 m;的列解決這樣的:

vec4 c0 = m[0].xyzw; 
vec4 c1 = m[1].xyzw; 
vec4 c2 = m[2].xyzw; 
vec4 c3 = m[3].xyzw; 

您可以設置在頂點着色器mat4像此:

#version 330 core 
layout(location = 0) in vec3 vertex_position; 
layout(location = 1) in vec3 vertex_color; 

out vec3 fragment_color; 
uniform mat4 MVP; 

uniform vec3 object_positions[20]; 

void main() 
{ 
    mat4 posMat = mat4(
     vec4(1.0, 0.0, 0.0, 0.0), 
     vec4(0.0, 1.0, 0.0, 0.0), 
     vec4(0.0, 0.0, 1.0, 0.0), 
     vec4(object_positions[gl_InstanceID], 1.0)); 

    gl_Position = MVP * posMat * vec4(vertex_position,1.0); 
    fragment_color = vertex_color; 
} 


但是,如果您只想通過偏移量操作頂點位置,則不需要轉換矩陣。你可以簡單地添加偏移到頂點位置(提供的偏移是一個直角座標,而不是齊次座標,如你的情況):

void main() 
{ 
    gl_Position = MVP * vec4(object_positions[gl_InstanceID] + vertex_position, 1.0); 
    fragment_color = vertex_color; 
} 


而且你必須建立均勻這樣的:

glm::vec3 object_positions[20]; 
object_positions[0] = glm::vec3(0.4f,0.2f,0.0f); 
object_positions[1] = glm::vec3(0.5f,1.4f,0.0f); 
... 
object_positions[19] = glm::vec3(-10.6f,0.2f,0.0f); 
GLuint object_positions_id = glGetUniformLocation(program_id, "object_positions"); 
... 
glUniform3fv(object_positions_id, 20, glm::value_ptr(object_positions[0])); 


進一步參見:

+1

不等於'vec4(object_position [gl_InstanceID] + vertex_position,1.0)'posMat * vec4(vertex_position,1.0)'? – Jherico