4

私がやろうとしているのは、明るい赤 (1,0,0,1) の上にアルファ (0.1,0,0,0.2) の濃い赤を追加することです。最初のレイヤーでは問題なく動作し、結果は (0.9 ,0 ,0, 1) です。ただし、赤の値が 0.5 になると、その値を下回ることはできません。

最初のレイヤーは次の式で示され、正常に機能します。

glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
ColorBuffer color = (1,0,0,1)      Bright Red
SourceColor color = (0.1,0,0,0.2)  Dark Red

GL_ONE = 1   ,  GL_ONE_MINUS_SRC_ALPHA = 1 - 0.2 = 0.8

Cf = (ColorSource * One) + (ColorBuffer * One Minus Src Alpha);
Cf = ((0.1,0,0)*1 )   +  ((1,0,0) * 0.8);
Cf =   0.1,0,0        +     0.8,0,0;
Cf =   0.9,0,0  // Here is the result

多くのレイヤーの後、線をさらに下ると、目的の色がより暗いポイントに到達します: 0.5、以下に示すように、色は決して暗くなりません 0.5,0,0 で始まりますが、結果は 0.5,0 になります。 0:

Cf = ((0.1,0,0)*1 )   +  ((0.5,0,0) * 0.8);
Cf =    0.1,0,0       +       0.4,0,0;
Cf =    0.5,0,0 

これは、カラー バッファが変更されておらず、オーバーレイしている色が影響を与えていないことを意味する結果です。

濃い赤が明るい赤に置き換わるまで重ねるにはどうすればよいですか?

SIMPLE PROCESSING SKETCH DEMONSTRATING THE PROBLEM - ここで GL_SRC_ALPHA を試していますが、まだ問題があることに気付くでしょう:

http://studionu.net/files/OPENGL_test.zip

下の画像は、左に問題があり、右に問題があることを示しています。

赤に赤の問題

編集ここにコードがあります

だからここに私のコードがあります:

テクスチャ バッファ オブジェクトをセットアップし、FBO にアタッチします。

 'gl.glGenTextures(1, drawTex, 0);    
  gl.glBindTexture(GL.GL_TEXTURE_2D, drawTex[0]);
  gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MIN_FILTER, GL.GL_LINEAR);
  gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_MAG_FILTER, GL.GL_LINEAR);
  gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_S, GL.GL_CLAMP_TO_EDGE);
  gl.glTexParameteri(GL.GL_TEXTURE_2D, GL.GL_TEXTURE_WRAP_T, GL.GL_CLAMP_TO_EDGE);
  gl.glTexImage2D(GL.GL_TEXTURE_2D, 0, GL.GL_RGBA8, 1000, 500, 0, GL.GL_BGRA,    GL.GL_UNSIGNED_BYTE, null);  '

' // Creating FBO.
  gl.glGenFramebuffersEXT(1, drawFBO, 0);
  gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, drawFBO[0]);
  gl.glFramebufferTexture2DEXT(GL.GL_FRAMEBUFFER_EXT, GL.GL_COLOR_ATTACHMENT0_EXT, GL.GL_TEXTURE_2D, drawTex[0], 0);
  int stat = gl.glCheckFramebufferStatusEXT(GL.GL_FRAMEBUFFER_EXT);
  if (stat != GL.GL_FRAMEBUFFER_COMPLETE_EXT) System.out.println("FBO error");
  gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, 0);'

次に、フレーム バッファをクリアします。

' gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, drawFBO[0]);

  // Drawing to the first color attachement of drawFBO (this is where drawTex is attached to).
  gl.glDrawBuffer(GL.GL_COLOR_ATTACHMENT0_EXT);    
  gl.glViewport(0, 0, 1000, 500);

    gl.glColor4f(0.0, 0.0, 0.0, 0.0);   

  gl.glClear(gl.GL_COLOR_BUFFER_BIT);

  // Unbinding drawFBO. Now drawing to screen again.
  gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, 0);   '

ここで、フレームバッファをバインドして描画し、ここで色を設定します:

'  gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, drawFBO[0]);
  // Drawing to the first color attachement of drawFBO (this is where drawTex is attached to).
  gl.glDrawBuffer(GL.GL_COLOR_ATTACHMENT0_EXT);    

 // Setting orthographic projection.   
  gl.glMatrixMode(GL.GL_PROJECTION);
  gl.glPushMatrix();      
  gl.glLoadIdentity();
  gl.glOrtho(0.0, 1000, 0.0, 500, -100.0, +100.0);
  gl.glMatrixMode(GL.GL_MODELVIEW);
 gl.glPushMatrix();   
 gl.glLoadIdentity();

  gl.glViewport(0, 0, 1000, 500);

  gl.glDisable(GL.GL_TEXTURE_2D);


 gl.glEnableClientState(GL.GL_VERTEX_ARRAY);
 gl.glVertexPointer(2, GL.GL_FLOAT, 0, paintBuffer);
 // gl.glHint (gl.GL_POINT_SMOOTH_HINT, gl.GL_NICEST);    
 // gl.glEnable(gl.GL_POINT_SMOOTH);
 gl.glEnable(gl.GL_VERTEX_PROGRAM_POINT_SIZE);

 gl.glEnable(gl.GL_BLEND);      
 gl.glEnable(gl.GL_DEPTH_TEST);
 gl.glDepthFunc(gl.GL_NICEST);
 gl.glDisable(gl.GL_ALPHA_TEST);
 gl.glAlphaFunc(gl.GL_LESS, 0.01);

 gl.glPointSize(35.0);  

  float kBrushOpacity = 0.05/3.0; 

  println(kBrushOpacity);

  float  colorchange = 1.0;



 if (timer>200) {
   colorchange = 0.5; //////COLOR GETS DARKER
  }

 if (timer>400) {
   //colorchange = 0.2; //////COLOR GETS DARKER AGAIN
 }

  timer++;
 gl.glDisableClientState( gl.GL_COLOR_ARRAY );
  gl.glColor4f(colorchange, 0, 0.0, kBrushOpacity);  
  gl.glBlendFuncSeparate(gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_SRC_ALPHA,gl.GL_SRC_ALPHA, gl.GL_ONE_MINUS_DST_ALPHA);////////THIS IS THE OPENGL BLEND EQUATION FOR PREMULTIPLIED COLORS



  gl.glDrawArrays(GL.GL_POINTS, 0, count); //Count tells us how many point exist to be drawn.
 gl.glDisable(gl.GL_BLEND);     //Dont use blend when drawing the texture to screen. Just draw it.

 gl.glDisableClientState(GL.GL_VERTEX_ARRAY);
  gl.glMatrixMode(GL.GL_PROJECTION);
  gl.glPopMatrix(); 
 gl.glMatrixMode(GL.GL_MODELVIEW);
 gl.glPopMatrix();    
 // Unbinding drawFBO. Now drawing to screen again.
  gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, 0);   '

ここで、テクスチャを画面に描画します。

' gl.glDrawArrays(GL.GL_POINTS, 0, count); //Count tells us how many point exist to be drawn.
gl.glDisable(gl.GL_BLEND);      //Dont use blend when drawing the texture to screen. Just draw it.

gl.glDisableClientState(GL.GL_VERTEX_ARRAY);
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glPopMatrix(); 
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glPopMatrix();     
// Unbinding drawFBO. Now drawing to screen again.
gl.glBindFramebufferEXT(GL.GL_FRAMEBUFFER_EXT, 0);   

// Setting orthographic projection. 
gl.glMatrixMode(GL.GL_PROJECTION);
gl.glPushMatrix();    
gl.glLoadIdentity();
gl.glOrtho(0.0, width, 0.0, height, -100.0, +100.0);
gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glPushMatrix();    
gl.glLoadIdentity();

 gl.glViewport(0, 0, width, height);

 // Drawing texture to screen.
 gl.glEnable(GL.GL_TEXTURE_2D);
 gl.glActiveTexture(GL.GL_TEXTURE0);
  gl.glBindTexture(GL.GL_TEXTURE_2D, drawTex[0]);
 gl.glTexEnvf(GL.GL_TEXTURE_ENV, GL.GL_TEXTURE_ENV_MODE, GL.GL_REPLACE);
 gl.glBegin(GL.GL_QUADS);
gl.glTexCoord2f(0.0, 1.0);
gl.glVertex2f(0.0, 0.0);

 gl.glTexCoord2f(1.0, 1.0);
 gl.glVertex2f(width, 0.0);

 gl.glTexCoord2f(1.0, 0.0);
 gl.glVertex2f(width, height);

 gl.glTexCoord2f(0.0, 0.0);
 gl.glVertex2f(0.0, height);
  gl.glEnd();
  gl.glBindTexture(GL.GL_TEXTURE_2D, 0);

  gl.glMatrixMode(GL.GL_PROJECTION);
  gl.glPopMatrix(); 
 gl.glMatrixMode(GL.GL_MODELVIEW);
gl.glPopMatrix();   '
4

2 に答える 2

2

ソースファクタとして GL_ONE を選択した理由をお伺いしてもよろしいですか? ブレンド式の合計乗算値が 1 より大きいという事実は、同じ色をそれ自体とブレンドするだけで明るくすることを意味します。これは、暗くしようとしているときに平衡に達しているときに見られます。

より一般的なソース ファクタ GL_SRC_ALPHA を使用した場合は、期待どおりに動作するはずです。採用しなかった理由はありますか?

GL_SRC_ALPHA と GL_ONE_MINUS_SRC_ALPHA をソース/デスト ブレンド係数として使用する場合、乗算係数の合計が 1 になるため、ブレンドを実行して画像を明るくする方向に偏ることはありません。

編集: GL_SRC_ALPHA を使用しても同じ問題が発生することに同意しません。以下に示すように、数式の簡単なモックアップを Excel で作成しました。ブレンドの値は、最終的にソース カラー (0.1f) に収束します。より速く収束させたい場合は、より大きな src alpha 値を使用してください。

パラメーター:

Source Red = 0.1
Source Alpha = 0.2
Dest Red = 1.0 (iteration==0), Result[iteration-1] (iteration != 0)
1-Src Alpha = 0.8
Result = Src Red * Src Alpha + Dest Red * One_Minus_Src_Alpha

結果:

列:

0: Iteration
1: Source Red    
2: Source Alpha
3: Dest Red
4: 1-Src Alpha
5: Result

0   1   2   3       4   5
------------------------------------------------
0   0.1 0.2 1.00    0.8 0.82   (0.1 * 0.2 + 1.0  * 0.8 = 0.82)
1   0.1 0.2 0.82    0.8 0.68   (0.1 * 0.2 + 0.82 * 0.8 = 0.68) 
2   0.1 0.2 0.68    0.8 0.56   (etc...)
3   0.1 0.2 0.56    0.8 0.47
4   0.1 0.2 0.47    0.8 0.39
5   0.1 0.2 0.39    0.8 0.34
6   0.1 0.2 0.34    0.8 0.29
7   0.1 0.2 0.29    0.8 0.25
8   0.1 0.2 0.25    0.8 0.22
9   0.1 0.2 0.22    0.8 0.20
10  0.1 0.2 0.20    0.8 0.18
11  0.1 0.2 0.18    0.8 0.16
12  0.1 0.2 0.16    0.8 0.15
13  0.1 0.2 0.15    0.8 0.14
14  0.1 0.2 0.14    0.8 0.13
15  0.1 0.2 0.13    0.8 0.13
16  0.1 0.2 0.13    0.8 0.12
17  0.1 0.2 0.12    0.8 0.12
18  0.1 0.2 0.12    0.8 0.11
19  0.1 0.2 0.11    0.8 0.11
20  0.1 0.2 0.11    0.8 0.11
21  0.1 0.2 0.11    0.8 0.11
22  0.1 0.2 0.11    0.8 0.11
23  0.1 0.2 0.11    0.8 0.10
24  0.1 0.2 0.10    0.8 0.10
25  0.1 0.2 0.10    0.8 0.10
于 2012-05-25T05:59:43.773 に答える
1

答えは、GIMP や Photoshop、SKetchbook などの描画プログラムと同じ方法を使用することです。キャンバスに新しく描画されたものをブレンドすることはなく、各呼び出しの最後にテクスチャ クワッドとして描画されるだけです。あなたはそれを見たことがないほど速い......とにかく、これは私にとってはうまくいき、他の人に役立つことを願っています。

于 2012-05-28T02:56:51.900 に答える