Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/image-processing/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Image processing 在WebGL中采样整数纹理会返回奇怪的值_Image Processing_Webgl_Fragment Shader_Webgl2_Glteximage2d - Fatal编程技术网

Image processing 在WebGL中采样整数纹理会返回奇怪的值

Image processing 在WebGL中采样整数纹理会返回奇怪的值,image-processing,webgl,fragment-shader,webgl2,glteximage2d,Image Processing,Webgl,Fragment Shader,Webgl2,Glteximage2d,我试图通过应用片段着色器从WebGL2中的16位数组缓冲区渲染灰度图像。I'v生成的纹理如下所示: let typedArray = new Int16Array(data); gl.texImage2D( gl.TEXTURE_2D, 0, gl.R16I, w, h, 0, gl.RED_INTEGER, gl.SHORT, typedArray); 并尝试使用下

我试图通过应用片段着色器从WebGL2中的16位数组缓冲区渲染灰度图像。I'v生成的纹理如下所示:

let typedArray = new Int16Array(data);
gl.texImage2D(
        gl.TEXTURE_2D,
        0,
        gl.R16I,
        w, h,
        0,
        gl.RED_INTEGER,
        gl.SHORT,
        typedArray);
并尝试使用下面片段着色器中的数据:

let fragmentShaderSource = `#version 300 es
    precision highp float;
    precision highp int;
    precision highp isampler2D;

    // our texture
    uniform isampler2D u_image;

    uniform highp float u_windowWidth;
    uniform highp float u_windowCenter;

    in vec2 v_texCoord;
    out vec4 outColor;

    void main() {
        highp float f = float(texture(u_image, v_texCoord).r);
        f = (f - (u_windowCenter - 0.5)) / max(u_windowWidth - 1.0, 1.0) + 0.5;
        f = min(max(f, 0.0), 1.0);
        outColor = vec4(vec3(f), 1.0);
    }
    `;
但这只会呈现一个黑屏。实际上,经过一些调试,我发现
纹理(u_image,v_texCoord)
在所有像素的
rgb
中都有零值,
a
(alpha)字段有非常大的(2^29~2^30)值。我尝试过在着色器中更改精度,但结果是一样的

为了缩小问题范围,我尝试了一种不同的方法,将16位整数拆分为
gl.RGBA4
,每个RGBA通道中包含4位:

let typedArray = new Uint16Array(data);
gl.texImage2D(
        gl.TEXTURE_2D,
        0,
        gl.RGBA4,
        w, h,
        0,
        gl.RGBA,
        gl.UNSIGNED_SHORT_4_4_4_4,
        typedArray);
并在片段着色器中将RGBA值合并回16位整数

let fragmentShaderSource = `#version 300 es
    precision highp float;
    precision highp int;
    precision highp sampler2D;

    // our texture
    uniform sampler2D u_image;

    uniform highp float u_windowWidth;
    uniform highp float u_windowCenter;

    in vec2 v_texCoord;
    out vec4 outColor;

    void main() {
        highp vec4 rgba_map = texture(u_image, v_texCoord);
        // Combining rgba4 back into int16
        highp f = rgba_map.r * 65536.0 + rgba_map.g * 4096.0 + rgba_map.b * 256.0 + rgba_map.a * 16.0;
        // signed value
        if (f > 32768.0) {
            f = 65536.0 - f;
        }
        f = (f - (u_windowCenter - 0.5)) / max(u_windowWidth - 1.0, 1.0) + 0.5;
        f = min(max(f, 0.0), 1.0);
        outColor = vec4(vec3(f), 1.0);
    }
    `;

这个版本很好地渲染了预期的图像,尽管由于转换,结果有点嘈杂。我还尝试了一些其他格式,那些浮点型的格式很好,而整数型格式都不起作用。所以我觉得节目的其他部分都很好。我想知道我的程序出了什么问题。

你还没有发布足够的代码来调试,所以让我们做一些有用的东西

函数main(){
const gl=document.querySelector('canvas').getContext('webgl2');
如果(!gl){
返回警报(“需要WebGL2”);
}
const vs=`#版本300 es
void main(){
gl_PointSize=300.0;
gl_位置=vec4(0,0,0,1);
}
`;
常数fs=`#版本300 es
高精度浮点;
精度高;
精度高,精度高;
//我们的质地
均匀的二维u_图像;
输出vec4颜色;
void main(){
ivec4 intColor=纹理(u_图像,gl_PointCoord.xy);
color=vec4(vec3(intColor.rrr)/10000.0,1);
}
`;
const program=twgl.createProgram(gl[vs,fs]);
常量tex=gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D,tex);
gl.texImage2D(
gl.U 2D,
0,//mip级别
gl.R16I,//内部格式
10,//宽度
1,//高度
0,//边框
gl.RED\u整数,//源格式
gl.SHORT,//源类型
新的Int16Array([
1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000
]));
//无法过滤整数纹理
gl.texParameteri(gl.TEXTURE\u 2D,gl.TEXTURE\u MAG\u过滤器,gl.NEAREST);
gl.texParameteri(gl.TEXTURE\u 2D,gl.TEXTURE\u MIN\u过滤器,gl.NEAREST);
gl.useProgram(程序);
//无需设置任何属性或参数
//制服,因为我们不使用属性
//制服默认为零,因此将使用
//纹理单位零
总图绘制阵列(总图点,0,1);
console.log('max point size:',gl.getParameter(gl.ALIASED_point_size_RANGE)[1]);
}
main()
画布{
边框:1px纯黑;
背景:红色;
}

您还没有发布足够的代码进行调试,所以让我们做一些有用的东西

函数main(){
const gl=document.querySelector('canvas').getContext('webgl2');
如果(!gl){
返回警报(“需要WebGL2”);
}
const vs=`#版本300 es
void main(){
gl_PointSize=300.0;
gl_位置=vec4(0,0,0,1);
}
`;
常数fs=`#版本300 es
高精度浮点;
精度高;
精度高,精度高;
//我们的质地
均匀的二维u_图像;
输出vec4颜色;
void main(){
ivec4 intColor=纹理(u_图像,gl_PointCoord.xy);
color=vec4(vec3(intColor.rrr)/10000.0,1);
}
`;
const program=twgl.createProgram(gl[vs,fs]);
常量tex=gl.createTexture();
gl.bindTexture(gl.TEXTURE_2D,tex);
gl.texImage2D(
gl.U 2D,
0,//mip级别
gl.R16I,//内部格式
10,//宽度
1,//高度
0,//边框
gl.RED\u整数,//源格式
gl.SHORT,//源类型
新的Int16Array([
1000, 2000, 3000, 4000, 5000, 6000, 7000, 8000, 9000, 10000
]));
//无法过滤整数纹理
gl.texParameteri(gl.TEXTURE\u 2D,gl.TEXTURE\u MAG\u过滤器,gl.NEAREST);
gl.texParameteri(gl.TEXTURE\u 2D,gl.TEXTURE\u MIN\u过滤器,gl.NEAREST);
gl.useProgram(程序);
//无需设置任何属性或参数
//制服,因为我们不使用属性
//制服默认为零,因此将使用
//纹理单位零
总图绘制阵列(总图点,0,1);
console.log('max point size:',gl.getParameter(gl.ALIASED_point_size_RANGE)[1]);
}
main()
画布{
边框:1px纯黑;
背景:红色;
}


我没有关闭纹理,通过添加这两行,我获得了完美的效果!感谢您的深刻见解,并对没有添加足够的信息表示歉意。我很惊讶您在JavaScript控制台中没有出现错误。如果我没有设置过滤chrome打印错误,纹理没有渲染Lei没有关闭纹理,通过添加这两条线,我得到了完美的结果!感谢您的深刻见解,并对没有添加足够的信息表示歉意。我很惊讶您在JavaScript控制台中没有出现错误。如果我没有设置过滤铬打印错误,纹理是不可渲染的