Designing a Unique Shader with Three.js

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>Float32Arrays are being populated with half the data from the quadVertBuffer 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.

Answer №1

After some experimentation, I was able to make this functionality "work", although I hesitate to call it a complete "fix".

The approach I took involved flipping the tilemap (tilemap.flipY = true), unflipping the tileset (tileset.flipY = false), and tweaking the mapmaker.html file (originally created by Toji for generating tilemaps) to render each tile upside down on the sprite sheet (tileset).

I would much rather find a proper solution that addresses the root problem instead of resorting to these workarounds. However, until then, this workaround serves as my temporary fix.

Below is the relevant code snippet:

Shader:

(Code snippet depicting shader implementation)

Shader Material Section (where tilemap and tileset are THREE.Textures):

(Code snippet illustrating material setup and uniform declaration)

Modified Mapmaker Segment:

(Segment showing modifications in the MapMaker function for processing tiles)

If there are alternative solutions out there, feel free to share them. Your input is greatly appreciated!

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

A guide on traversing through nested HTML divs using jQuery

I am facing an issue with nested HTML div elements on my website. The data is being fetched from a JSON file and stored in a variable. For example, the 'obj' variable contains an array of objects with properties such as Name, Progress, Descripti ...

Navigating in Angular with parameters without modifying the URL address

In a nutshell, my goal is to navigate to a page with parameters without showing them in the URL. I have two components: Component A and B. What I want to do is route to B while still needing some parameters from A. I know I can achieve this by setting a ...

Using Try...catch compared to .catch

Within my service.ts file, I have various user service functions that handle database operations. export const service = { async getAll(): Promise<User[]> { try { const result = await query return result } catch (e) { rep ...

How to efficiently transfer dynamically generated table row data to JavaScript for database submission using the POST method

Currently, I am working with Laravel and facing an issue related to dynamic rows in my form. Each row has its own form with unique values. My goal is to pass the form data along with values to JavaScript when the submit button is clicked without refreshin ...

JavaScript: protecting data, revealing functionality

Looking to enhance my understanding of Javascript basics in order to delve into client-side frameworks like Knockout and Angular, as well as make headway in learning Node.js. I've selected a simple problem used in teaching C# and am now attempting to ...

Is there a way I can set a variable as global in a jade template?

I am trying to pass a global object to a jade template so that I can use it for various purposes later on. For instance: app.get("/", function(req, res){ var options = { myGlobal : {// This is the object I want to be global "prop ...

Importing three.js using ES6 syntax

When it comes to working with ES6, my workflow involves using Babel and babel-plugin-transform-es2015-modules-system.js specifically to transform module import/export for compatibility with system.js. I rely on a "green" browser for most ES6 features excep ...

Displaying a popover upon page load using JavaScript

Currently, I am attempting to implement a JavaScript function that displays a popup on my webpage whenever a user visits the site. The script that I have found uses jQuery, but I am wondering if it is possible to achieve the same result using pure JavaScri ...

Implement Vue.js functionality to dynamically add the 'active' class upon clicking an element, while also removing

Is it possible to create an active link on a div element? Check out this example to see how you can achieve that in your code: http://jsfiddle.net/fiddleyetu/9ff79/ $(function() { $( 'ul.nav li' ).on( 'click', function() { $ ...

The distinction between plural and singular array identifiers in JavaScript

The functionality of this code in Chrome 59.0.3071.115 is causing confusion for me: var names = ["Cat 1", "Cat 2"]; console.log(names); When executed, it displays an array object; however, var name = ["Cat 1", "Cat 2"]; console.log(name); Instead print ...

Is it feasible to dynamically insert and delete elements in React?

I'm currently in the process of rebuilding a project, specifically a drag and drop website builder, using React after it was originally built with a heavy reliance on jQuery. My main challenge lies in being able to dynamically add and remove elements ...

Encountering a Meteor issue during the installation of npm packages

When attempting to install cheerio through npm, I encountered a specific error message. Error: Can't set DOCTYPE here. (Meteor sets <!DOCTYPE html> for you) - line 1, file Similarly, when trying to use jsdom, I faced a parse error. Currently ...

Display Material Popup in Angular before user leaves the page

My goal is to display an Angular Material Dialog Box (Popup window) when the user clicks the Chrome Window Close button. The Dialog modal should prompt the user if they want to save changes or cancel. However, the modal only appears for a brief moment and ...

Search for a DIV element within iMacro on a consistent basis

I recently started using iMacro and encountered an issue while recording a script that involved clicking on a pop-up when it appeared on the screen. The problem arose because the pop-up only appears when a new event is posted. Therefore, when I initially c ...

React component will automatically rerender if the cache is disabled in the Chrome browser

In my React application, I am utilizing 'react-image-pan-zoom-rotate' to display images. Visit the GitHub repository here The image I am displaying is sourced from an external service and passed to both libraries for rendering. Lately, I have ...

The styles for Material-UI Popover are not taking effect

I have integrated the Popover component from Material-UI into my application: <Popover anchorEl={AnchorElement} anchorOrigin={{ vertical: 'bottom', horizontal: 'right' }} open={props.isVisible} className='popove ...

Determining the Existence of Undefined Values in Jquery Ajax Requests with Json

I have the following jQuery code: $.ajax({ url: "?module=gestionApplication&action=getTests&scenario="+encodeURI(scenario)+"&application="+$application, dataType:'json', success: function( data ) { $.each(data, f ...

Has the JSON information been stored in the correct variable?

I'm trying to store the JSON data from the file named a5.json in a variable called rects. However, I am not sure if I did it correctly. My goal is to display rectangles using the rects variable. Can someone guide me on how to achieve that? <script ...

Adjusting the opacity of the background image in the section - focus solely on the background

This section is what I'm working on. <section ID="Cover"> <div id="searchEngine">hello</div> </section> I am trying to achieve a fade in/out effect specifically for the background image of the Cover section. T ...

Using AngularJS Material's mdDialog to show locally stored data in a template

In the controller, the section responsible for spawning mdDialog appears as follows: $scope.removeAttendee = function(item) { console.log(item); $mdDialog.show({ controller: DialogController, templateUrl: 'views/removeMsg.tm ...