簡體   English   中英

Qt / OpenGL中着色器的問題

[英]Issues with shaders in Qt/OpenGL

如何在片段着色器中使用不同的顏色輸出?

說,我的vshader看起來像這樣:

#version 330

uniform mat4 mvpmatrix;

layout(location=0) in vec4 position;
layout(location=1) in vec2 texcoord;

out vec2 out_texcoord;

void main()
{

    gl_Position = mvpmatrix * position;    

    out_texcoord = texcoord;
}

// fshader

#version 330

uniform sampler2D texture;
in vec2 out_texcoord;
out vec4 out_color;
out vec4 out_color2;

void main()
{        
    out_color = texture2D(texture, out_texcoord);
   // out_color2 = vec3(1.0, 1.0, 1.0, 1.0);
}

像這樣訪問它們:

m_program->enableAttributeArray(0);  // position
m_program->setAttributeBuffer(0, GL_FLOAT, 0, 3, sizeof(Data));

m_program->enableAttributeArray(1); // texture
m_program->setAttributeBuffer(1, GL_FLOAT, sizeof(QVector3D), 2, sizeof(Data));

到目前為止,所有內容都使用片段着色器的默認輸出,即紋理。 但是如何訪問不同的片段輸出呢? 我還必須使用布局嗎? 而且,它可能是一個愚蠢的問題......但是vshader / fshader的布局位置是否相互綁定? 那么,如果我在AttributeArray(1)上啟用緩沖區,我將被迫使用BOTH着色器的布局位置1?

您可以綁定另一個屬性位置,以便隨時向片段着色器發送顏色信息,但讓我告訴您另一個技巧:)

我使用2屬性位置,一個用於表示頂點的位置,另一個用於表示頂點的顏色。

glBindAttribLocation(program_, 0, "vs_in_pos");
glBindAttribLocation(program_, 1, "vs_in_col");

這是我的網格定義,其中Vertex包含兩個3D矢量:

Vertex vertices[] = {
        {glm::vec3(-1, -1,  1), glm::vec3(1, 0, 0)},
        {glm::vec3(1, -1,  1), glm::vec3(1, 0, 0)},
        {glm::vec3(-1,  1,  1), glm::vec3(1, 0, 0)},
        {glm::vec3(1,  1,  1), glm::vec3(1, 0, 0)},
        {glm::vec3(-1, -1, -1), glm::vec3(0, 1, 0)},
        {glm::vec3(1, -1, -1), glm::vec3(0, 1, 0)},
        {glm::vec3(-1,  1, -1), glm::vec3(0, 1, 0)},
        {glm::vec3(1,  1, -1), glm::vec3(0, 1, 0)},
    };
    GLushort indices[] = {
        // Front
        0, 1, 2,  2, 1, 3,
        // Back
        4, 6, 5,  6, 7, 5,
        // Top
        2, 3, 7,  2, 7, 6,
        // Bottom
        0, 5, 1,  0, 4, 5,
        // Left
        0, 2, 4,  4, 2, 6,
        // Right
        1, 5, 3,  5, 7, 3
    };

這將代表一個立方體。 我將這個預定義的顏色與計算值混合。 這意味着立方體的顏色會因其位置而改變。 為RGB值設置3D矢量並設置為在片段着色器中使用它:

loc_col_ = glGetUniformLocation(program_, "color");

現在在我的渲染功能中,我將立方體放在2D圓圈中,移動它們,旋轉它們:

for (int i = 0; i < num_of_cubes_; ++i) {
        double fi = 2 * PI * (i / (double) num_of_cubes_);
        glm::mat4 position = glm::translate<float>(cubes_radius_ * cos(fi), cubes_radius_ * sin(fi), 0);
        glm::mat4 crackle = glm::translate<float>(0, 0.1 * (sin(2 * PI * (SDL_GetTicks() / 500.0) + i)), 0);
        glm::mat4 rotate = glm::rotate<float>(360 * (SDL_GetTicks() / 16000.0), 0, 0, 1);
        world_ = position * crackle * rotate;
        glm::vec3 color = glm::vec3((1 + cos(fi)) * 0.5, (1 + sin(fi)) * 0.5, 1 - ((1 + cos(fi)) * 0.5));
        glUniformMatrix4fv(loc_world_, 1, GL_FALSE, &(world_[0][0]));
        glUniform3fv(loc_col_, 1, &(color[0]));
        glDrawElements(GL_TRIANGLES, 36, GL_UNSIGNED_SHORT, 0);
    }

你可以在這里看到我不僅發送世界矩陣,還發送顏色矢量。 片段着色器中的線性插值由mix()函數實現:

#version 130

in vec3 vs_out_col;
in vec3 vs_out_pos;
out vec4 fs_out_col;

uniform vec3 color;

void main() {
        fs_out_col = vec4(mix(color, vs_out_col, 0.5), 1);
}

顏色是渲染中傳遞的值,而vs_out_col來自頂點着色器,它是在“通道”1中到達的。

我希望你能理解我。

頂點和片段着色器上的布局位置是獨立的。 QT可能會誤導enableAttributeArray因為在OpenGL中這個函數叫做glEnableVertexAttribArray - vertex是這里的關鍵字。 因此,您只能將每個頂點數據傳遞到頂點着色器,然后使用輸入/輸出(插值)將其傳遞到片段着色器。

如果要使用片段着色器中的多個輸出,則必須使用位置和輸出緩沖區

這個鏈接也應該有用,稍后我將對其進行總結。

暫無
暫無

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

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