webGL2 片段着色器收到错误值
webGL2 fragment shader receives bad values
我正在尝试渲染 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
你的例子没有意义。您可能在绘制时遇到错误 INVALID_OPERATION
,甚至可能没有注意到它
这行来自你的着色器
uniform sampler3D in_texture;
与 R16I
纹理不兼容。
来自 WebGL2 规范
5.23 A sampler type must match the internal texture format
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, i.e., 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). In WebGL, generates an INVALID_OPERATION error in the corresponding draw call, including drawArrays, drawElements, drawArraysInstanced, drawElementsInstanced , and drawRangeElements.
如果您想使用 R16I
纹理,则必须将上面那行更改为使用 isampler3D
// uniform sampler3D in_texture; BAD!!!
uniform isampler3D in_texture; GOOD!!
之后这条线将失败
vec4 textureColor = texture(in_texture, v_texcoord);
因为 in_texture
现在只有 returns 个整数,或者在这种情况下 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个浮点数那就更复杂了
我正在尝试渲染 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
你的例子没有意义。您可能在绘制时遇到错误 INVALID_OPERATION
,甚至可能没有注意到它
这行来自你的着色器
uniform sampler3D in_texture;
与 R16I
纹理不兼容。
来自 WebGL2 规范
5.23 A sampler type must match the internal texture format
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, i.e., 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). In WebGL, generates an INVALID_OPERATION error in the corresponding draw call, including drawArrays, drawElements, drawArraysInstanced, drawElementsInstanced , and drawRangeElements.
如果您想使用 R16I
纹理,则必须将上面那行更改为使用 isampler3D
// uniform sampler3D in_texture; BAD!!!
uniform isampler3D in_texture; GOOD!!
之后这条线将失败
vec4 textureColor = texture(in_texture, v_texcoord);
因为 in_texture
现在只有 returns 个整数,或者在这种情况下 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个浮点数那就更复杂了