简体   繁体   English

webGL2片段着色器收到错误的值

[英]webGL2 fragment shader receives bad values

I'm trying to render a 3D texture but I have a problem with the fragment shader. 我正在尝试渲染3D纹理,但是片段着色器存在问题。 I should receive texture values mapped between 0 and 1 but I just receive 0 and other things. 我应该收到0到1之间映射的纹理值,但是我只收到0和其他东西。 By other things I mean that the next code (fragment shader) only prints red and grey colors in my shape: 换句话说,我的意思是下一个代码(片段着色器)仅以我的形状打印红色和灰色:

EDIT 编辑

#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);
    }
}

I check the values of the texture before create the texture (there should be more colors because numbers go from -32k to 32k) and I create the texture with the following parameters: 我在创建纹理之前检查纹理的值(应该有更多颜色,因为数字从-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
    );

Any suggestions will be greatly appreciated! 任何建议将不胜感激!

EDIT 编辑

I'm not getting any error as you can see in the image. 正如您在图片中看到的那样,我没有收到任何错误。

image 图片

your example makes no sense. 你的例子没有道理。 You're probably getting an error INVALID_OPERATION when you draw and probably not even noticing it 绘制时可能会收到错误INVALID_OPERATION ,甚至可能没有注意到

This line from your shader 着色器中的这一行

uniform sampler3D in_texture;

Is INCOMPATIBLE with an R16I texture. 不兼容R16I质感。

From the WebGL2 spec 从WebGL2规范

5.23 A sampler type must match the internal texture format 5.23采样器类型必须与内部纹理格式匹配

Texture lookup functions return values as floating point, unsigned integer or signed integer, depending on the sampler type passed to the lookup function. 纹理查找函数根据传递给查找函数的采样器类型,将值返回为浮点数,无符号整数或有符号整数。 If the wrong sampler type is used for texture access, ie, the sampler type does not match the texture internal format, the returned values are undefined in OpenGL ES Shading Language 3.00.6 (OpenGL ES Shading Language 3.00.6 §8.8). 如果错误的采样器类型用于纹理访问,即采样器类型与纹理内部格式不匹配,则返回值在OpenGL ES阴影语言3.00.6(OpenGL ES阴影语言3.00.6§8.8)中未定义。 In WebGL, generates an INVALID_OPERATION error in the corresponding draw call, including drawArrays, drawElements, drawArraysInstanced, drawElementsInstanced , and drawRangeElements. 在WebGL中,在相应的绘图调用(包括drawArrays,drawElements,drawArraysInstanced,drawElementsInstanced和drawRangeElements)中生成INVALID_OPERATION错误。

If you want to use an R16I texture then that line above must be changed to use an isampler3D 如果要使用R16I纹理,则必须将上面的那行更改为使用isampler3D

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

After that this line will fail 之后,此行将失败

vec4 textureColor = texture(in_texture, v_texcoord);

Because in_texture now only returns integers or in this case an ivec4 . 因为in_texture现在仅返回整数或本例中的ivec4

At this point it's not clear what you want to happen. 目前尚不清楚您要发生什么。 If you want normalized values as in you want your integer values that go from -32768 to +32787 (which is what R16I is) then you'll have to decide how you want to do the conversion. 如果要像归一化的值一样,要使整数值从-32768到+32787( R16I是),则必须决定如何进行转换。 A simple conversion would be something like 一个简单的转换就是

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.;

If you want 0 integer to equal 0 float then it's more complicated 如果您想让0整数等于0 float,那就更复杂了

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM