Please be aware that a lot of the code has changed as per edit 3 below.
I came across a blog post by Brandon Jones (link here) that I really liked. I wanted to convert his code to Three.js, but I'm encountering some difficulties. You can access his complete code here. Here's my current attempt, along with a few comments regarding some questions I have:
// Shader
var tilemapVS = [
"attribute vec2 pos;",
"attribute vec2 texture;",
"varying vec2 pixelCoord;",
"varying vec2 texCoord;",
"uniform vec2 viewOffset;",
"uniform vec2 viewportSize;",
"uniform vec2 inverseTileTextureSize;",
"uniform float inverseTileSize;",
"void main(void) {",
" pixelCoord = (texture * viewportSize) + viewOffset;",
/* remaining shader code */
this.mesh = new THREE.Mesh(this.plane, this.material);
When the page loads, I am confronted with the following error message:
TypeError: v1 is undefined
customAttribute.array[ offset_custom ] = v1.x;
It seems like this error is related to how I've set the attributes, but I'm unsure about the correct settings. Any assistance would be greatly appreciated since there's limited information available on Custom Shaders in Three.js.
EDIT: The blog post contains the code snippet below for populating the 2 attributes of the vertex shader (pos
, and texture
):
//in ctor var quadVerts = [ //x y u v /* coordinates data */ ]; //shader execution gl.enableVertexAttribArray(shader.attribute.position); /* additional WebGL buffer operations */ <p>I do not entirely grasp the specifics of what's happening here, but it seems like two <code>Float32Array
s are being populated with half the data from thequadVertBuffer
each. Not only am I uncertain about the rationale behind this, but I'm also unsure if my interpretation is accurate, or how to translate it into the Three.js approach.
EDIT3:
Upon realizing that Three.js automatically handles position and uv vectors for me (which appear similar, if not identical, to the position/texture in the earlier example), and rectifying potential type errors (many declared types 'v2' were actually loaded via 'uniform2fv'), updating to 'v2v' resolved the issue. Though no longer encountering errors, the output does not yet depict the tilemap accurately.
A revised Vertex Shader excerpt:
var tilemapVS = /* updated vertex shader code */;
Updated Shader Material:
this._material = /* updated material code */;
The current result displayed is empty. Any suggestions are welcome!
EDIT 4:
Adjusting the Vertex shader according to the "Three.js method" demonstrated progress, albeit with an incorrect sprite sheet offset. Modifying the varying 'pixelCoord' should resolve this discrepancy (considering 'uv' displays slightly different values than 'texture').
Altered Vertex Shader main function:
void main(void) { pixelCoord = (uv * viewportSize) + viewOffset; texCoord = pixelCoord * inverseTileTextureSize * inverseTileSize; gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); }
The tiles now reflect correctly from the texture sheet, notwithstanding the wrong tile selection:
Another step closer, any guidance remains invaluable.
EDIT 5:
This update may well conclude my contributions, nearing a resolution. After setting 'tileset.flipY = false', where 'tileset' denotes the actual texture tiles (not the map), all tiles transitioned to their rightful locations—albeit upside down!
Result post alteration:
To counteract this inversion without modifying the tileset image directly, introducing vector math within the shader might achieve individual texture flipping over the Y axis effectively. While applying such adjustments considering 'tilemap.flipY = false' alongside 'tileset.flipY = false' appropriately positions the textures, juxtaposing them suitably—the entire layout appears inverted!
Continued support and insights are eagerly awaited.