27

フラグメントシェーダーでレイキャスティングをしています。この目的のためにフルスクリーンのクワッドを描画する方法はいくつか考えられます。射影行列を単位行列に設定してクリップ空間にクワッドを描画するか、ジオメトリ シェーダーを使用してポイントを三角形ストリップに変換します。前者は、OpenGL 3.2 で廃止された即時モードを使用します。後者は目新しさから使用していますが、それでも即時モードを使用してポイントを描画します.

4

6 に答える 6

20

頂点属性をそれぞれ-1/1に設定して、クワッドを作成する2つの三角形を送信できます。

頂点/フラグメントシェーダーでそれらにマトリックスを掛ける必要はありません。

ここにいくつかのコードサンプルがありますが、それは単純です:)

頂点シェーダー:

const vec2 madd=vec2(0.5,0.5);
attribute vec2 vertexIn;
varying vec2 textureCoord;
void main() {
   textureCoord = vertexIn.xy*madd+madd; // scale vertex attribute to [0-1] range
   gl_Position = vec4(vertexIn.xy,0.0,1.0);
}

フラグメントシェーダー:

varying vec2 textureCoord;
void main() {
   vec4 color1 = texture2D(t,textureCoord);
   gl_FragColor = color1;
}
于 2010-04-07T10:21:47.550 に答える
13

フルスクリーン クワッド ジオメトリ シェーダーを出力するには、次のように使用できます。

#version 330 core

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

out vec2 texcoord;

void main() 
{
    gl_Position = vec4( 1.0, 1.0, 0.5, 1.0 );
    texcoord = vec2( 1.0, 1.0 );
    EmitVertex();

    gl_Position = vec4(-1.0, 1.0, 0.5, 1.0 );
    texcoord = vec2( 0.0, 1.0 ); 
    EmitVertex();

    gl_Position = vec4( 1.0,-1.0, 0.5, 1.0 );
    texcoord = vec2( 1.0, 0.0 ); 
    EmitVertex();

    gl_Position = vec4(-1.0,-1.0, 0.5, 1.0 );
    texcoord = vec2( 0.0, 0.0 ); 
    EmitVertex();

    EndPrimitive(); 
}

頂点シェーダーは空です:

#version 330 core

void main()
{
}

このシェーダーを使用するには、空の VBO でダミー描画コマンドを使用できます。

glDrawArrays(GL_POINTS, 0, 1);
于 2012-02-18T16:47:09.703 に答える
4

これはdemanzeによる回答に似ていますが、理解しやすいと思います。これもTRIANGLE_STRIPを使って4頂点だけで描いています。

#version 300 es
out vec2 textureCoords;

void main() {
    const vec2 positions[4] = vec2[](
        vec2(-1, -1),
        vec2(+1, -1),
        vec2(-1, +1),
        vec2(+1, +1)
    );
    const vec2 coords[4] = vec2[](
        vec2(0, 0),
        vec2(1, 0),
        vec2(0, 1),
        vec2(1, 1)
    );

    textureCoords = coords[gl_VertexID];
    gl_Position = vec4(positions[gl_VertexID], 0.0, 1.0);
}
于 2020-01-14T16:30:17.400 に答える
2

以下は、fbo テクスチャを画面に合わせたクワッドに描画するクラスの draw 関数からのものです。

Gl.glUseProgram(shad);      

Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, vbo);           
Gl.glEnableVertexAttribArray(0);
Gl.glEnableVertexAttribArray(1);
Gl.glVertexAttribPointer(0, 3, Gl.GL_FLOAT, Gl.GL_FALSE, 0, voff);
Gl.glVertexAttribPointer(1, 2, Gl.GL_FLOAT, Gl.GL_FALSE, 0, coff);  

Gl.glActiveTexture(Gl.GL_TEXTURE0);
Gl.glBindTexture(Gl.GL_TEXTURE_2D, fboc);
Gl.glUniform1i(tileLoc, 0);

Gl.glDrawArrays(Gl.GL_QUADS, 0, 4);

Gl.glBindTexture(Gl.GL_TEXTURE_2D, 0);
Gl.glBindBuffer(Gl.GL_ARRAY_BUFFER, 0); 

Gl.glUseProgram(0); 

実際のクワッド自体と座標は次から取得されます。

private float[] v=new float[]{  -1.0f, -1.0f, 0.0f,
                                1.0f, -1.0f, 0.0f,
                                1.0f, 1.0f, 0.0f,
                                -1.0f, 1.0f, 0.0f,

                                0.0f, 0.0f,
                                1.0f, 0.0f,
                                1.0f, 1.0f,
                                0.0f, 1.0f
};

vbo のバインディングとセットアップはあなたに任せます。

頂点シェーダー:

#version 330

layout(location = 0) in vec3 pos;
layout(location = 1) in vec2 coord;

out vec2 coords;

void main() {
    coords=coord.st;
    gl_Position=vec4(pos, 1.0);
}

位置はそのままなので、つまり、行列を乗算していないため、クワッドの -1、-1::1、1 がビューポートに収まります。openGL.org の彼の投稿からリンクされている Alfonse のチュートリアルを探してください。

于 2011-10-13T02:40:39.063 に答える