我正在尝试渲染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
);
任何建议都将不胜感激!
修改
我没有收到任何错误,你可以在图片中看到。
答案 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浮点数那么它就更复杂了