2

我正在尝试渲染 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
    );

任何建议将不胜感激!

编辑

正如您在图像中看到的那样,我没有收到任何错误。

图片

4

1 回答 1

3

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

着色器中的这条线

uniform sampler3D in_texture;

纹理不兼容R16I

来自 WebGL2 规范

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

纹理查找函数以浮点、无符号整数或有符号整数的形式返回值,具体取决于传递给查找函数的采样器类型。如果纹理访问使用了错误的采样器类型,即采样器类型与纹理内部格式不匹配,则返回值在 OpenGL ES Shading Language 3.00.6(OpenGL ES Shading Language 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 浮点数,那就更复杂了

于 2018-01-24T16:28:40.157 回答