I am having some trouble finding mistake in the code. I hope you will indicate me the direction where to look for a solution.
I try to use 2+ textures in one draw call. For testing I use 2 textures.
When I try to render the scene, the first texture (name: "dataTexture") is empty, the second texture (name: "u_image0") is available and works fine.
Here is a uniform that contains both textures
myUniform = [
...
{
name: "dataTexture",
type: "TEXTURE_2D",
variableLocation: WebGLUniformLocation,
valueToPass: WebGLTexture
},
{
name: "u_image0",
type: "TEXTURE_2D",
variableLocation: WebGLUniformLocation,
valueToPass: WebGLTexture
}
];
Then I use a separate function to render these textures It looks like this
// For textures
// Using 2 or more textures
textureID = 0; // textureID = 0, 1, 2, ... (int)
let len = myUniforms.length;
for (i = 0; i < len; i++) {
...
if (type == "TEXTURE_2D") {
// Set which texture units to render with
if (variableLocation != null){
console.log("Location exist");
gl.uniform1i(variableLocation, textureID); // textureID = 0, 1, 2, ...
textureID++;
}
else {console.log("No location");}
// Set each texture unit to use a particular texture
gl.activeTexture(gl.TEXTURE0 + textureID);
// Bind texture image
gl.bindTexture(gl.TEXTURE_2D, valueToPass);
}
}
...
// Render
gl.drawArrays(primitiveType, offsetArray, count);
Here are the shaders
vertexShaderSource = [
"#version 300 es",
// Attributes
// An attribute is an input (in) to a vertex shader.
// It will receive data from a buffer
"in vec2 a_position;",
// Texture coordinates
"in vec2 a_texCoord;",
// Data indices in texture
"in float a_matrixIndices;",
// Uniforms
// Data texture
"uniform sampler2D dataTexture;",
// Clip space matrix
"uniform mat3 clipSpaceMatrix;",
// Vareable to pass to fragment shader
// Color
"out vec3 color;",
// Texture coordinates
"out vec2 v_texCoord;",
// Texture for use in the current instance
"out float textureID;",
// Read data from texture
"vec4 getValueByIndexFromTexture(sampler2D tex, int index) {",
"int texWidth = textureSize(tex, 0).x;",
"int col = index % texWidth;",
"int row = index / texWidth;",
"return texelFetch(tex, ivec2(col, row), 0);",
"}",
"void main() {",
// Index to read data from texture
"int index = int(a_matrixIndices);",
"vec3 data = getValueByIndexFromTexture(dataTexture, index).xyz;",
// Object type
"int objectType = int(data.x);",
// Matrix to convert from object space to world space
"mat3 matrixWorld = mat3(.0);",
"if (objectType == 0) {",
// Obect type = RasterImage
"matrixWorld[0][0] = data.y;",
"matrixWorld[0][1] = data.z;",
"data = getValueByIndexFromTexture(dataTexture, index + 1).xyz,",
"matrixWorld[0][2] = data.x;",
"matrixWorld[1][0] = data.y;",
"matrixWorld[1][1] = data.z;",
"data = getValueByIndexFromTexture(dataTexture, index + 2).xyz,",
"matrixWorld[1][2] = data.x;",
"matrixWorld[2][0] = data.y;",
"matrixWorld[2][1] = data.z;",
"data = getValueByIndexFromTexture(dataTexture, index + 3).xyz,",
"matrixWorld[2][2] = data.x;",
// Texture ID
// Texture for use in the current instance
"textureID = data.y;",
"}",
// Multiply the position by the matrix
"vec3 position = clipSpaceMatrix * matrixWorld * vec3(a_position.xy, 1);",
"gl_Position = vec4(position, 1);",
// Send color to fragment shader
"color = vec3(.1, 0.7, 0.3);",
// Pass the texCoord to the fragment shader
"v_texCoord = a_texCoord;",
"}"
].join("\n");
fragmentShaderSource = [
// WebGL2 version
"#version 300 es",
// Fragment shaders don't have a default precision so we need
// to pick one. highp is a good default. It means "high precision"
"precision highp float;",
// Uniforms
// Textures
"uniform sampler2D u_image0;",
//"uniform sampler2D u_image1;",
// Passed in from the vertex shader.
//"uniform vec3 foo;",
"in vec3 color;",
// Texture coordinates
// The GPU will interpolate this value between points
"in vec2 v_texCoord;",
// Texture for use in the current instance
"in float textureID;",
// We need to declare an output for the fragment shader
"out vec4 outColor;",
"void main() {",
"vec4 fragmentColor = vec4(1.0, 0.0, 1.0, 1.0);",
"if (textureID == 0.0) {",
"fragmentColor = texture(u_image0, v_texCoord);",
"}",
//"else if (textureID == 1.0) {",
// "fragmentColor = texture(u_image1, v_texCoord);",
//"}",
// Set color
"outColor = fragmentColor;",
"}"
].join("\n");
Thanks to everyone. This code is correct. You can use it however you want. As usual, a SMALL error that spoils everything: invalid data was sent to create a dataTexture. Confused push()
with concat()
.
For push() method:
dataTexture = dataTexture.push(data0, data1, ...); // This is wrong (returns array length)
dataTexture.push(data0, data1, ...); // Correct (returns changed array)
For conact() method
dataTexture = dataTexture.concat(Array[data0, data1, ...], ...); // Correct way (returns changed array)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.