2016-06-20 2 views
1

this exampleと同様のウィンドウレベルを適用しようとしていますが、画像上にマウスをドラッグすると明るさ+コントラスト効果が表示されます。WebGLで輝度+コントラストを実現する方法は?

しかし、WebGLを使用して同じことを達成したいのですが、GPUはCPUよりも高速に処理するためです。

ここに私がやっていることだ。

バーテックスシェーダ:

attribute vec3 attrVertexPos; 
attribute vec2 attrTextureCoord; 

varying highp vec2 vTextureCoord; 

void main(void) { 
    gl_Position = vec4(attrVertexPos, 0.81); 
    vTextureCoord = attrTextureCoord; 
} 

フラグメントシェーダ:

#ifdef GL_ES 
    precision highp float; 
#endif 

varying highp vec2 vTextureCoord; 

uniform sampler2D uImage; 
uniform float brightnessFactor; 
uniform float contrastFactor; 

void main(void) { 
    gl_FragColor = texture2D(uImage, vTextureCoord) *(brightnessFactor/contrastFactor); 
} 

しかし、予想通り、それは上記のリンクに従って動作しません。

var isMouseDown = false; 

document.getElementById('canvas').onmousedown = function() { isMouseDown = true }; 
document.getElementById('canvas').onmouseup = function() { isMouseDown = false }; 
document.getElementById('canvas').onmousemove = function(e) { 
    if (isMouseDown) { 
     var intWidth = $('canvas').innerWidth(); 
     var intHeight = $('canvas').innerHeight(); 
     var x = (e.clientX/intWidth)*100; 
     var y = (e.clientY/intHeight)*100; 

     console.log(x/10 + ' :: ' + y/10); 

     brightnessVal = x/10; 
     gl.uniform1f(gl.getUniformLocation(program, "contrastFactor"), brightnessVal); 
     contrastVal = y/10; 
     gl.uniform1f(gl.getUniformLocation(program, "brightnessFactor"), contrastVal); 
    } 
}; 

答えて

3

差はピクセル操作である:

はここでJavascriptのコードです。係数を乗算するだけです(また、使用する係数の名前が間違っています)。リンクされた例証のように、もう少し複雑なことが起こっています。ソースイメージから(その中心と幅で説明)いくつかの色の範囲がフル[0,1]の範囲に拡大します:

newColor = (oldColor - rangeCenter)/rangeWidth + 0.5 

なぜそれが、これは私の知識を超えてやっているが(ページは医療のための一例ですイメージングライブラリと私はそれについて何も知らない)。それにもかかわらず、私はあなたのコードに数式を移植することができました。まず、フラグメントシェーダの変更:JavaScriptのためとして

#ifdef GL_FRAGMENT_PRECISION_HIGH 
    precision highp float; 
#else 
    precision mediump float; 
#endif 

varying highp vec2 vTextureCoord; 
uniform sampler2D uImage; 

// New uniforms 
uniform float rangeCenter; 
uniform float rangeWidth; 

void main(void) { 
    vec3 c = texture2D(uImage, vTextureCoord).rgb; 
    gl_FragColor = vec4(
     // The above formula, clamped to [0, 1] 
     clamp((c - windowCenter)/windowWidth + 0.5, 0.0, 1.0), 
     // Also, let's not screw alpha 
     1 
    ); 
} 

を、私がリンクされている例に、それは少し近づけるために自由を撮影した:

var isMouseDown = false, 
    // Initially we set "equality" colour mapping 
    rangeCenter = 0.5, 
    ragneWidth = 1, 
    lastX, lastY; 

document.getElementById('canvas').onmousedown = function(e) { 
    lastX = e.clientX; 
    lastY = e.clientY; 
    isMouseDown = true 
}; 
document.getElementById('canvas').onmouseup = function() { 
    isMouseDown = false 
}; 
document.getElementById('canvas').onmousemove = function(e) { 
    if (isMouseDown) { 
     var intWidth = $('canvas').innerWidth(); 
     var intHeight = $('canvas').innerHeight(); 

     // Change params according to cursor coords delta 
     rangeWidth += (e.clientX - lastX)/intWidth; 
     rangeCenter += (e.clientY - lastY)/intHeight; 

     gl.uniform1f(
      gl.getUniformLocation(program, "rangeWidth"), 
      rangeWidth 
     ); 

     gl.uniform1f(
      gl.getUniformLocation(program, "rangeCenter"), 
      rangeCenter 
     ); 

     lastX = e.clientX; 
     lastY = e.clientY; 
    } 
}; 

旧答え:

問題は、コードに従って、mousemoveイベント後に 画像を再描画しないことです。ユニフォームを設定した後、適切なパラメータで描画呼び出し(またはいくつかの 描画呼び出し)を挿入するだけです。 例えば、それは次のようになります。

document.getElementById('canvas').onmousemove = function(e) { 
    if (isMouseDown) { 
     // your code 

     gl.drawArrays(/* params, e.g gl.TRIANGLES, 0 and vertex count */); 
    } 
}; 

良い方法は 再描画する​​コールバックを使用しています。

function draw() { 
    /* your draw calls here */ 
} 

document.getElementById('canvas').onmousemove = function(e) { 
    if (isMouseDown) { 
     // your code 

     requestAnimationFrame(draw); 
    } 
}; 

P.S.:、あなたのための コールを描き作り、​​コールバックにそれを使用しますdraw機能を定義することを行うために、また、私はお互いに、#ifdef GL_ESものはどこから来たのですか? highpの精度を基準にしてGL_ESマクロに設定されています。ハードウェアは、標準に従ってそれをサポートする必要はありません。正しい方法は次のようになります。実は、私はrequestAnimationFrameのは、すでに実施している

#ifdef GL_FRAGMENT_PRECISION_HIGH 
    precision highp float; 
#else 
    precision mediump float; 
#endif 
+0

、それは私に間違った結果得られます。varレンダリング=機能(){ \t gl.clear(gl.COLOR_BUFFER_BIT | GLを。DEPTH_BUFFER_BIT); \t gl.drawElements(gl.TRIANGLES、indices.length、gl.UNSIGNED_SHORT、0); \t requestAnimationFrame(render); } –

+0

OK、少し詳しく説明できますか:あなたが見ている画像に何が問題なのですか?あなたはページやjsfiddleをリンクすることができますので、私はより詳しく見ることができますか? –

+0

確かに、私はあなたのためにフィドルを作成させてください –

関連する問題