【问题标题】:How to draw multiple textures per object如何为每个对象绘制多个纹理
【发布时间】:2014-02-18 09:09:11
【问题描述】:

如何将多个纹理应用到每个对象的不同面?

我具体画了一个立方体:

我希望能够在立方体的每个不同面上绘制不同的图像(或子图像)。我该怎么做?

顶点着色器:

#version 330 core

uniform vec3 position = vec3(0.0, 0.0, 0.0);
void main() {
    gl_Position = vec4(position, 1.0);
}

几何着色器:

#version 330 core

layout(points) in;
layout(triangle_strip, max_vertices=64) out;

out vec2 tex_coord;

uniform mat4x4 model;
uniform mat4x4 view;
uniform mat4x4 projection;

uniform float size = 1.0;

const vec2 texc[4] = vec2[](vec2(0, 0), // texture coordinates
                            vec2(1, 0),
                            vec2(0, 1),
                            vec2(1, 1));

void main() {
    float asize = size / 2;
    vec4 offset[24] = vec4[] (
                            vec4(-asize,  asize, -asize, 0.0), //top face
                            vec4( asize,  asize, -asize, 0.0),
                            vec4(-asize,  asize,  asize, 0.0),
                            vec4( asize,  asize,  asize, 0.0),

                            vec4(-asize, -asize, -asize, 0.0), //bottom face
                            vec4( asize, -asize,  asize, 0.0),
                            vec4(-asize, -asize, -asize, 0.0),
                            vec4( asize, -asize,  asize, 0.0),

                            vec4(-asize,  asize, -asize, 0.0), //left face
                            vec4(-asize,  asize,  asize, 0.0),
                            vec4(-asize, -asize, -asize, 0.0),
                            vec4(-asize, -asize,  asize, 0.0),

                            vec4( asize,  asize, -asize, 0.0), //right face
                            vec4( asize,  asize,  asize, 0.0),
                            vec4( asize, -asize, -asize, 0.0),
                            vec4( asize, -asize,  asize, 0.0),

                            vec4(-asize,  asize,  asize, 0.0), //rear face
                            vec4( asize,  asize,  asize, 0.0),
                            vec4(-asize, -asize,  asize, 0.0),
                            vec4( asize, -asize,  asize, 0.0),

                            vec4(-asize,  asize, -asize, 0.0), //front face
                            vec4( asize,  asize, -asize, 0.0),
                            vec4(-asize, -asize, -asize, 0.0),
                            vec4( asize, -asize, -asize, 0.0));

    int i, j, k;
    for(i = 0; i < gl_in.length(); ++i) {          // for each input vertex generate a cube
        for(k = 0; k < offset.length() / 4; ++k) { // for each face of the cube
            for(j = 0; j < 4; ++j) {               // for each vertex per face
                gl_Position = projection * view * model * (gl_in[i].gl_Position + offset[j + k*4]);
                tex_coord = texc[j];
                EmitVertex();
            }
            EndPrimitive();
        }
    }
}

片段着色器:

#version 330 core

out vec4 fragment_out;
uniform sampler2D tex;
in vec2 tex_coord;

void main() {
    fragment_out = texture(tex, tex_coord);
}

【问题讨论】:

  • 您想要每个对象有多个纹理吗?还是每个面有多个纹理?
  • @concept3d 我想在每个面上绘制不同的纹理;每个面一个纹理。

标签: opengl glsl


【解决方案1】:

首先您需要将两个纹理单元传递给着色器,并以某种方式调制或添加它们,例如:

#version 330 core

out vec4 fragment_out;
uniform sampler2D tex;
uniform sampler2D tex2;
in vec2 tex_coord;

void main() {
    fragment_out = texture(tex, tex_coord)*texture(tex2, tex_coord);
}

不幸的是,这样您将有 2 个纹理用于​​相同的面。如果你想要每张脸的纹理。

-您可以有多个纹理坐标,并在着色器中使用带有一组纹理坐标的每个纹理,因此您可以使用另一个tex_coord,而不是一个tex_coord2

#version 330 core    
out vec4 fragment_out;
uniform sampler2D tex;
uniform sampler2D tex2;
in vec2 tex_coord;
in vec2 tex_coord;

void main() {
    fragment_out = texture(tex, tex_coord) + texture(tex2, tex_coord2);
}

-另一种方法是将多个图像组合在一个图像中并点亮它,这样每张脸都具有大图像的单独部分。

-更简单的方法是将每个人脸作为一个单独的对象来处理,但这是非常不推荐的。

【讨论】:

    【解决方案2】:

    这是解决此问题的最简单方法,因为您有一个几何着色器:

    几何着色器:

    #version 330 core
    
    layout(points) in;
    layout(triangle_strip, max_vertices=64) out;
    
    out vec2 tex_coord;
    
    uniform mat4x4 model;
    uniform mat4x4 view;
    uniform mat4x4 projection;
    
    uniform float size = 1.0;
    
    const vec2 texc[4] = vec2[](vec2(0, 0), // texture coordinates
                                vec2(1, 0),
                                vec2(0, 1),
                                vec2(1, 1));
    
    void main() {
        float asize = size / 2;
        vec4 offset[24] = vec4[] (
                                vec4(-asize,  asize, -asize, 0.0), //top face
                                vec4( asize,  asize, -asize, 0.0),
                                vec4(-asize,  asize,  asize, 0.0),
                                vec4( asize,  asize,  asize, 0.0),
    
                                vec4(-asize, -asize, -asize, 0.0), //bottom face
                                vec4( asize, -asize,  asize, 0.0),
                                vec4(-asize, -asize, -asize, 0.0),
                                vec4( asize, -asize,  asize, 0.0),
    
                                vec4(-asize,  asize, -asize, 0.0), //left face
                                vec4(-asize,  asize,  asize, 0.0),
                                vec4(-asize, -asize, -asize, 0.0),
                                vec4(-asize, -asize,  asize, 0.0),
    
                                vec4( asize,  asize, -asize, 0.0), //right face
                                vec4( asize,  asize,  asize, 0.0),
                                vec4( asize, -asize, -asize, 0.0),
                                vec4( asize, -asize,  asize, 0.0),
    
                                vec4(-asize,  asize,  asize, 0.0), //rear face
                                vec4( asize,  asize,  asize, 0.0),
                                vec4(-asize, -asize,  asize, 0.0),
                                vec4( asize, -asize,  asize, 0.0),
    
                                vec4(-asize,  asize, -asize, 0.0), //front face
                                vec4( asize,  asize, -asize, 0.0),
                                vec4(-asize, -asize, -asize, 0.0),
                                vec4( asize, -asize, -asize, 0.0));
    
        int i, j, k;
        for(i = 0; i < gl_in.length(); ++i) {          // for each input vertex generate a cube
            for(k = 0; k < offset.length() / 4; ++k) { // for each face of the cube
    
              gl_PrimitiveID = k; // Must set this, otherwise it will be undefined in the FS
    
                for(j = 0; j < 4; ++j) {               // for each vertex per face
                    gl_Position = projection * view * model * (gl_in[i].gl_Position + offset[j + k*4]);
                    tex_coord = texc[j];
                    EmitVertex();
                }
                EndPrimitive();
            }
        }
    }
    

    片段着色器:

    #version 330 core
    
    out vec4 fragment_out;
    uniform sampler2D tex [6];
    in vec2 tex_coord;
    
    void main() {
        fragment_out = texture (tex [gl_PrimitiveID], tex_coord);
    }
    

    现在,只需设置 6 个不同的纹理图像单元即可。

    注意:您必须在几何着色器中写入gl_PrimitiveID,否则它将在片段着色器中未定义。所以 GS 里面多了 1 行,一般情况下 GL 会自动为你生成这个值。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2020-03-09
      • 1970-01-01
      • 1970-01-01
      • 2015-04-16
      • 1970-01-01
      相关资源
      最近更新 更多