1

OpenGL で HDR 画像にトーン マッピングを実装しようとしています。

以前、HDR 画像の手動ミップ マッピングを作成RGBA32Fして、輝度の平均値を持つ 1x1 テクスチャ (形式) を取得しました。

トーン マッピング関数の例を見つけて、フラグメント シェーダーに配置しました。

私のレンダー コードではGL_TEXTURE0、HDR イメージ (フォーマットGL_RGBA32F)、GL_TEXTURE1平均値の 1x1 テクスチャを使用しています。

RGBA8レンダリングしたいLDR テクスチャ (形式) は、上の FrameBuffer (fboTN) に割り当てられますGL_COLOR_ATTACHMENT0

FreeImage ライブラリを使用して、HDR イメージ (OpenEXR 形式) をアップロードします。

コードは次のとおりです。

void toneMapping(){
  glBindFramebuffer(GL_FRAMEBUFFER, fboTN);
  glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
  // Set viewport and textures

  setMVP();
  glActiveTexture(GL_TEXTURE0); HDRtex->bind();     // Source HDR tex
  glActiveTexture(GL_TEXTURE1); DSavgTex0->bind();  // 1x1 tex with avgLum
  toneMappingShad->bind();
    float key = 0.18f, Ywhite = 1e6f, sat = 1.0f;
    toneMappingShad->setUniformValue1f("key", key);
    toneMappingShad->setUniformValue1f("Ywhite", Ywhite);
    toneMappingShad->setUniformValue1f("sat", sat);
    toneMappingShad->setUniformValue("width", im->getWidth());
    toneMappingShad->setUniformValue("height", im->getHeight());
    toneMappingShad->setUniformValue4f("MVP", glm::value_ptr(MVP));
    drawQuad(toneMappingShad);
  toneMappingShad->unbind();
  glActiveTexture(GL_TEXTURE1); DSavgTex0->unbind();    // 1x1 tex with avgLum
  glActiveTexture(GL_TEXTURE0); HDRtex->unbind();   // Source HDR tex
  glBindFramebuffer(GL_FRAMEBUFFER, 0);
}

// RENDER CODE
toneMapping();
texShad->bind();
    texShad->setUniformValue4f("MVP", glm::value_ptr(MVP));
    LDRtex->bind();
    drawQuad(texShad);
    LDRtex->unbind();
texShad->bind();

私の出力はほとんど黒い画面です(私が描いたクワッドを推測できます)。 texShadシェーダーは非常に単純です。画面にテクスチャを描画するだけです。

トーン マッピング シェーダーを示します。

頂点シェーダーは次のとおりです (シンプル)。

#version 420

in vec2 vUV;
in vec4 vVertex;
uniform int width;  // size of texture
uniform int height;
smooth out vec2 vTexCoord;

uniform mat4 MVP;
void main()
{
  gl_Position = MVP*vVertex;
  vTexCoord = vec2(vUV.x*width,vUV.y*height);
}

そしてフラグメント:

#version 420

uniform float key;
uniform float Ywhite;
uniform float sat;
layout(binding=0) uniform sampler2D hdrSampler;     // HDR texture
layout(binding=1) uniform sampler2D downSampler;    // Texture 1x1 with average of luminance
smooth in vec2 vTexCoord;           
layout(location=0) out vec4 color;  // LDR sample output (tone mapped image)

const mat3 RGB2XYZ = mat3(0.4124, 0.3576, 0.1805,
                           0.2126, 0.7152, 0.0722,
                           0.0193, 0.1192, 0.9505);


vec3 tonemap(vec3 RGB, float logAvgLum){
    vec3 XYZ = RGB2XYZ * RGB;
    float Y = (key / logAvgLum) * XYZ.y;
    float Yd = (Y * (1.0 + Y /(Ywhite * Ywhite))) / (1.0 + Y);
    return pow(RGB / XYZ.y, vec3(sat,sat,sat)) * Yd;
}   


void main(){
    vec3 hdr = texture(hdrSampler, vTexCoord).rgb;
    float logAvgLum = exp(texture(downSampler,vec2(0.0,0.0)).a);
    color.rgb = tonemap(hdr, logAvgLum);
}

出力のようなものを入れてcolor.a = Xも変化しません。

texture(downSampler,vec2(0.0,0.0)).a1 つの重要な疑問:平均値を取得するには、この ( ) は正しいでしょうか? 0,0テクスチャのサイズが 1x1 であるため、取得する座標が正しいかどうかはわかりません。

これに多くの時間を費やしましたが、何が問題なのかわかりません。

出力は次のとおりです。

出力

4

0 に答える 0