webGL2片段着色器接收错误值

时间:2018-01-24 13:51:07

标签: javascript webgl2

我正在尝试渲染3D纹理,但我对片段着色器有问题。我应该接收映射在0和1之间的纹理值,但我只收到0和其他东西。换句话说,我的意思是下一个代码(片段着色器)只在我的形状中打印红色和灰色:

修改

#version 300 es

precision highp float;
precision highp int;
precision highp sampler3D;

uniform sampler3D in_texture;

in vec3 v_texcoord;

out vec4 color;

void main()
{


    vec4 textureColor = texture(in_texture, v_texcoord);

    //color = vec4(textureColor.r, 0.0, 0.0, 0.5);

    if(textureColor.r == 0.0){
        color = vec4(1.0,0.0,0.0,1.0);
    }
    if(textureColor.r != 0.0){
        color = vec4(0.5,0.5,0.5,1.0);
    }
    if( textureColor.r > 0.0){
        color = vec4(0.0,1.0,0.0,1.0);
    }
    if(textureColor.r < 0.0){
        color = vec4(0.0,0.0,1.0,1.0);
    }
}

在创建纹理之前检查纹理的值(应该有更多颜色,因为数字从-32k到32k)并且我使用以下参数创建纹理:

    var textureData = new Int16Array();

    //fill textureData

    var texture = gl.createTexture();
    gl.activeTexture(gl.TEXTURE0);
    gl.bindTexture(gl.TEXTURE_3D, texture);
    gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_WRAP_R, gl.CLAMP_TO_EDGE);
    gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MAG_FILTER, gl.NEAREST);
    gl.texParameteri(gl.TEXTURE_3D, gl.TEXTURE_MIN_FILTER, gl.NEAREST);

    gl.texImage3D(
        gl.TEXTURE_3D,  // target
        0,              // level
        gl.R16I,        // internalformat
        texW,           // width
        texH,           // height
        texD,           // depth
        0,              // border
        gl.RED_INTEGER, // format
        gl.SHORT,       // type
        textureData     // pixeldata
    );

任何建议都将不胜感激!

修改

我没有收到任何错误,你可以在图片中看到。

image

1 个答案:

答案 0 :(得分:3)

你的例子毫无意义。您绘制时可能会收到错误INVALID_OPERATION,甚至可能没有注意到它

着色器中的这一行

uniform sampler3D in_texture;

INCOMPATIBLE ,带有R16I纹理。

来自WebGL2规范

  

5.23采样器类型必须与内部纹理格式匹配

     

纹理查找函数将值返回为浮点,无符号整数或有符号整数,具体取决于传递给查找函数的采样器类型。如果错误的采样器类型用于纹理访问,即采样器类型与纹理内部格式不匹配,则返回值在OpenGL ES着色语言3.00.6(OpenGL ES着色语言3.00.6§8.8)中未定义。在WebGL中,在相应的绘制调用中生成INVALID_OPERATION错误,包括drawArrays,drawElements,drawArraysInstanced,drawElementsInstanced和drawRangeElements。

如果您想使用R16I纹理,则必须更改上面的该行以使用isampler3D

// uniform sampler3D in_texture;   BAD!!!
uniform isampler3D in_texture;     GOOD!!

之后这一行将失败

vec4 textureColor = texture(in_texture, v_texcoord);

因为in_texture现在只返回整数,或者在这种情况下只返回ivec4

目前还不清楚你想要发生什么。如果您想要标准化值,您希望您的整数值从-32768到+32787(这是R16I),那么您将必须决定如何进行转换。简单的转换就像是

const int INT16_MIN = -32768;
const int INT16_MAX =  32767; 
const int INT16_RANGE = INT16_MAX - INT16_MIN;

ivec4 intValues = texture(in_texture, v_texcoord);
vec4 textureColors = (float(intValues - INT16_MIN) / float(INT16_RANGE)) * 2. - 1.;

如果你想要0整数等于0浮点数那么它就更复杂了