2017-04-11 8 views
0

パラメータgl.R8、gl.RED、gl.UNSIGNED_BYTEからgl.texImage2Dで1x1テクスチャを作成しました。WebGL2 texelテクスチャの予期しない結果を取得する

これは基本的に1バイトのバッファを作成すると想像します。

今私はtexelFetchを使用して、フラグメントシェーダのこの1バイトバッファにアクセスしたいが、アップロードした1バイトは得られない。

私は私の問題を説明するための最低限の例を作成しました:本質的にはhttps://jsfiddle.net/w5hp18e0/7/

//Absolutely no error checking for clarity 

var canvas=document.getElementById('canvas'); 
var gl=canvas.getContext('webgl2'); 
gl.clearColor(0,0,0,1); 
gl.clear(gl.COLOR_BUFFER_BIT); 

//Vertex shader 
var vtx_so=gl.createShader(gl.VERTEX_SHADER); 
gl.shaderSource(vtx_so,`#version 300 es 
in vec4 a_pos; 
void main(){ 
    gl_Position=a_pos; 
}`); 
gl.compileShader(vtx_so); 

//Fragment shader 
var frg_so=gl.createShader(gl.FRAGMENT_SHADER); 
gl.shaderSource(frg_so,`#version 300 es 
precision mediump float; 
precision mediump usampler2D; 
uniform usampler2D u_samp; 
out vec4 o_color; 
void main(){ 
    // README 
    uint val=texelFetch(u_samp,ivec2(0,0),0).x; 
    // replace false with true in desired location 
    if(false){ 
    // set to red IF val != 0 
    if(val!=0u) 
     {o_color=vec4(1.,0.,0.,1.);} 
    }else if(false){ 
    // set to red IF val == 1 
    if(val==1u) 
     {o_color=vec4(1.,0.,0.,1.);} 
    }else if(false){ 
    // set to red IF val & 0x01000000 
    if((val&0x01000000u)!=0u) 
     {o_color=vec4(1.,0.,0.,1.);} 
    }else if(false){ 
    // set to red IF val == 0x01000000 
    if(val==0x01000000u) 
     {o_color=vec4(1.,0.,0.,1.);} 
    } 
}`); 
gl.compileShader(frg_so); 
console.log(gl.getShaderInfoLog(frg_so)); 

//Program 
var prog=gl.createProgram(); 
gl.attachShader(prog,vtx_so); 
gl.attachShader(prog,frg_so); 
gl.linkProgram(prog); 
gl.useProgram(prog); 

//Verticies 
var vao=gl.createVertexArray(); 
gl.bindVertexArray(vao); 
var vbo=gl.createBuffer(); 
gl.bindBuffer(gl.ARRAY_BUFFER,vbo); 
gl.bufferData(gl.ARRAY_BUFFER,new Float32Array([ 
    0,0,0,1,1,1,1,1,1,0,0,0, 
]),gl.STATIC_DRAW); 
var loc=gl.getAttribLocation(prog,'a_pos'); 
gl.vertexAttribPointer(loc,2,gl.FLOAT,false,0,0); 
gl.enableVertexAttribArray(loc); 

//Texture 
var tex=gl.createTexture(); 
gl.bindTexture(gl.TEXTURE_2D,tex); 
gl.texParameteri(gl.TEXTURE_2D,gl.TEXTURE_MAX_LEVEL,0); 
var tex_buf=new Uint8Array(1); 
// README 
tex_buf[0]=1; // set me to some 8-bit value 
gl.texImage2D(gl.TEXTURE_2D,0,gl.R8,1,1,0,gl.RED,gl.UNSIGNED_BYTE,tex_buf); 

//Sampler 
loc=gl.getUniformLocation(prog,'u_samp'); 
gl.uniform1i(loc,0); 

gl.activeTexture(gl.TEXTURE0); 
gl.bindTexture(gl.TEXTURE_2D,tex); 
gl.drawArrays(gl.TRIANGLES,0,6); 

、私は、値「1」をアップロードし、私の質感をtexelFetchとき、それはいくつかの非ゼロの数を返します。 1ではありません。私がこの返された値を推定できる唯一のプロパティは、val & 0x01000000がtrueを返すということです。しかし、val == 0x01000000でさえもtrueを返します。これは少し混乱します。

私は間違っていますか?

答えて

1

不適切な内部形式を使用しています。 GL_R8floatを表し、GL_R8UIunsigned intを表す。同様に間違ったフォーマットを使用しています。ここでも同様にGL_RED_INTEGERを使用する必要があります(前述と同じ理由)。

gl.texImage2D(gl.TEXTURE_2D, 0, gl.R8UI, 1, 1, 0, gl.RED_INTEGER, gl.UNSIGNED_BYTE, tex_buf); 

また、フィルタリングをGL_NEARESTに設定する必要があります。

gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.NEAREST); 
gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.NEAREST); 
+0

ありがとう、あなたは素晴らしいです。 –