1

使用シェーダー: http://www.gamerendering.com/2008/12/20/radial-blur-filter/

私の問題はこれです:シーン全体が画面スペースの4分の1しか占有せず(これは、これらの座標の長方形です:幅/ 2,0幅、高さ/ 2)、文字通り切り取られた(スケーリングされていない)ようです. また、Y を反転させてレンダリングしました (ただし、-9 行目から記号を削除することでこれを修正できましたgl_Position.y)。

頂点配列の代わりに基本を使用することを除いて、このチュートリアルを使用して後処理を行いました。glBegin(GL_QUADS)


編集 2 : 別のシェーダー ( http://www.geeks3d.com/20110428/shader-library-swirl-post-processing-filter-in-glsl/ ) を使用してみましたが、完全に正常に機能しました。クリッピングなし。

編集: シェーダーのソースは次のとおりです (いくつかのマイナーな編集を行いました)。

フラグメント シェーダ:

#version 140

// This texture should hold the image to blur.
// This can perhaps be a previous rendered scene.
uniform sampler2D tex;

// texture coordinates passed from the vertex shader
varying vec2 uv;

// some const, tweak for best look
const float sampleDist = 1.0;
const float sampleStrength = 20.2; 

void main(void)
{
   // some sample positions
   float samples[10] =
   float[](-0.08,-0.05,-0.03,-0.02,-0.01,0.01,0.02,0.03,0.05,0.08);

    // 0.5,0.5 is the center of the screen
    // so substracting uv from it will result in
    // a vector pointing to the middle of the screen
    vec2 dir = 0.5 - uv; 

    // calculate the distance to the center of the screen
    float dist = sqrt(dir.x*dir.x + dir.y*dir.y); 

    // normalize the direction (reuse the distance)
    //dir = dir/dist; 
    dir /= dist;

    // this is the original colour of this fragment
    // using only this would result in a nonblurred version
    vec4 color = texture2D(tex,uv); 

    vec4 sum = color;

    // take 10 additional blur samples in the direction towards
    // the center of the screen
    for (int i = 0; i < 10; i++)
    {
      sum += texture2D( tex, uv + dir * samples[i] * sampleDist );
    }

    // we have taken eleven samples
    sum *= 1.0/11.0;

    // weighten the blur effect with the distance to the
    // center of the screen ( further out is blurred more)
    float t = dist * sampleStrength;
    t = clamp( t ,0.0,1.0); //0 <= t <= 1

    //Blend the original color with the averaged pixels
    gl_FragColor = mix( color, sum, t );
}

頂点シェーダー:

#version 140

varying vec2  uv;
// this vertex shader is from AMD RenderMonkey
void main(void)
{
   gl_Position = vec4( gl_Vertex.xy, 0.0, 1.0 );
   gl_Position = sign( gl_Position );

   // Texture coordinate for screen aligned (in correct range):
   uv = (vec2( gl_Position.x, gl_Position.y ) + vec2(1.0 )) / vec2( 2.0 );
}

ポストプロセッサー:

#include "std/opengl.h"

#include "postprocess.h"

Post::Post(Pos2D res) {
        this->res = res;
        glActiveTexture(GL_TEXTURE0);
        glGenTextures(1, &this->texture);
        glBindTexture(GL_TEXTURE_2D, this->texture);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, res.x, res.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
        glBindTexture(GL_TEXTURE_2D, 0);
        glGenRenderbuffers(1, &this->rbo);
        glBindRenderbuffer(GL_RENDERBUFFER, this->rbo);
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, res.x, res.y);
        glBindRenderbuffer(GL_RENDERBUFFER, 0);
        glGenFramebuffers(1, &this->fbo);
        glBindFramebuffer(GL_FRAMEBUFFER, this->fbo);
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, this->texture, 0);
        glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT, GL_RENDERBUFFER, this->rbo);
        GLenum status;
        if ((status = glCheckFramebufferStatus(GL_FRAMEBUFFER)) != GL_FRAMEBUFFER_COMPLETE) {
                fprintf(stderr, "Framebuffer error! %i", status);
        }
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

Post::~Post() {
        glDeleteRenderbuffers(1, &this->rbo);
        glDeleteTextures(1, &this->texture);
        glDeleteFramebuffers(1, &this->fbo);
}

void Post::update(Pos2D res) {
        this->res = res;
        glBindTexture(GL_TEXTURE_2D, this->texture);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, res.x, res.y, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
        glBindTexture(GL_TEXTURE_2D, 0);
        glBindRenderbuffer(GL_RENDERBUFFER, this->rbo);
        glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH24_STENCIL8, res.x, res.y);
        glBindRenderbuffer(GL_RENDERBUFFER, 0);
}

void Post::bind() {
        glBindFramebuffer(GL_FRAMEBUFFER, this->fbo);
}

void Post::unbind() {
        glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

void Post::render(Shader* shader) {
        glClear(GL_COLOR_BUFFER_BIT);
        glClearColor(0.0, 0.0, 0.0, 1.0);

        shader->run();
        auto tex = glGetUniformLocation(shader->program_handle, "tex");
        glBindTexture(GL_TEXTURE_2D, this->texture);
        glUniform1i(tex, 0);
        glBegin(GL_QUADS);
          glTexCoord2f(0.0, 0.0);
          glVertex2f(0, 0);
          glTexCoord2f(0.0, 1.0);
          glVertex2f(0, this->res.y);
          glTexCoord2f(1.0, 1.0);
          glVertex2f(this->res.x, this->res.y);
          glTexCoord2f(1.0, 0.0);
          glVertex2f(this->res.x, 0);
        glEnd();
        glBindTexture(GL_TEXTURE_2D, 0);
        glUseProgram(0);
}

問題のスクリーンショット (ご覧のとおり、切り取られています) :バギーブラー

シェーダーを無効にしたときのスクリーンショット (ご覧のとおり、ウィンドウ全体にレンダリングでき、クリップされていません) :ブレなし バグなし

4

1 に答える 1

4

問題は、頂点座標を定義する方法に起因します。

    glTexCoord2f(0.0, 0.0);
    glVertex2f(0, 0);
    glTexCoord2f(0.0, 1.0);
    glVertex2f(0, this->res.y);
    glTexCoord2f(1.0, 1.0);
    glVertex2f(this->res.x, this->res.y);
    glTexCoord2f(1.0, 0.0);
    glVertex2f(this->res.x, 0);

ウィンドウ解像度を頂点座標として使用する代わりに、( -1, -1 )、( -1, 1 )、( 1, 1 )、( 1, -1 ) の頂点を持つクワッドを描画してみてください。 opengl のネイティブ座標系のフルスクリーン クワッドで。あなたの頂点シェーダーでは、符号関数を使用して頂点座標をこの座標系に変換しようとしているように見えます:

   gl_Position = vec4( gl_Vertex.xy, 0.0, 1.0 );
   gl_Position = sign( gl_Position );

しかしもちろん、コーナー ポイント ( 0, 0 )、( 0, 1 )、( 1, 1 ) および ( 1, 0 ) を持つクワッドが代わりに得られます。その結果、次の行でシェーダーで計算するテクスチャ座標:

uv = (vec2( gl_Position.x, gl_Position.y ) + vec2(1.0 )) / vec2( 2.0 );

も間違っており、あなたが経験している「切り取られた」外観になります-あなたのtexcoordsは0から1ではなく0.5から1の範囲です。シェーダーでそれらを再度計算する必要があります。組み込みの gl_MultiTexcoord を使用するだけです。

于 2013-05-08T06:52:01.863 に答える