I've made a "biome gridmap playground" app which help to design biomes for a 2D grid map using simplex noise. The algorithm is roughly this: for each grid map tile, we look at the noises values (moisture and height) at this coordinate, determine the color of the tile and then render it on the canvas. It is very slow when there are hundreds of tiles. Also, rendering the canvas blocks the main thread and therefore the UI, which is very annoying. I think this could be solved by using Web Workers. However, it would not fix my main issue: canvas rendering seems to be slow. I'm wondering if using threejs could improve performances? Or maybe there is a smarter algorithm I could implement?
How can I improve the performance of my HTML5 2D canvas?
84 Views Asked by Ershetz At
1
There are 1 best solutions below
Related Questions in JAVASCRIPT
- Using Puppeteer to scrape a public API only when the data changes
- inline SVG text (js)
- An array of images and a for loop display the buttons. How to assign each button to open its own block by name?
- Storing the preferred font-size in localStorage
- Simple movie API request not showing up in the console log
- Authenticate Flask rest API
- Deploying sveltekit app with gunjs on vercel throws cannot find module './lib/text-encoding'
- How to request administrator rights?
- mp4 embedded videos within github pages website not loading
- Scrimba tutorial was working, suddenly stopped even trying the default
- In Datatables, start value resets to 0, when column sorting
- How do I link two models in mongoose?
- parameter values only being sent to certain columns in google sheet?
- Run main several times of wasm in browser
- Variable inside a Variable, not updating
Related Questions in HTML5-CANVAS
- Can I pre-scale and cache Images?
- SigmaJS: Create a snapshot of "sigma-containter"
- MediaPipe segmentation mask for Pose Detection Web
- Canvas element having padding + scrollbar
- openfl canvas toDataUrl() return blank image
- CSS animation is not reaching to last element
- Using HTML Canvas, how can I maintain the border-image width of the left and right border to be the same as the top and bottom?
- Resize nodes bug
- How to make layer of different color mask on a image or a div element
- How to relate canvas drawing objects with canvas controller objects in flutter (in SOLID correspondence)?
- Making canvas background transparent
- Where is the bug in this Canvas implementation of Conway's Game of Life?
- How to fix Document is not defined when creating a canvas in Angular
- Tried to create a class for a button creating, but didn't get it with Canvas Context
- finding a point and its angle on a cubic Bezier curve in JavaScript
Related Questions in NOISE
- How can I calculate the SNR of a curve that has impulse noise added?
- stm32 cubeIDE DMA DAC noise on DAC output
- Remove central noise from image
- Visible Grid-Lines in Perlin Noise Generation Algorithm
- How to generate covariance matrix of coloured noise?
- Equation for 3D Noise Power Spectrum (NPS)
- OpenSimplexNoise vs Perlin Noise: why so much difference?
- How to calculate Signal to noise ratio in a completely dark image
- Can i create a scss gradient from black to transparent with a noise texture?
- NAudio Only picking up Microphone input sound when another app is using the same microphone
- Need help understanding this C function for Perlin noise vector generation
- how to estimate the SNR with limited knowledge of the signal
- gcplyr::smooth_data() errors - do you have to use this function in tandem with mutate() or subset_by()?
- Datasets for various types of noisy images
- value noise is not correlated
Related Questions in SIMPLEX-NOISE
- OpenSimplexNoise vs Perlin Noise: why so much difference?
- WebGL: INVALID_OPERATION: texImage2D: ArrayBufferView not big enough for request
- Noise function outputs subtly different result when converted from hlsl to c#
- How can I improve the performance of my HTML5 2D canvas?
- Why is no data getting written to image?
- Symbol.tsx: undefined is not a constructor (evaluating 'new _simplexNoise.default(i + "-" + j)')
- Infinte map generation in isometric game - Java LibGDX
- I can't get this demo to work on my computer in three.js and cannon.js from sandbox
- Physics.Raycast not working with a Marching Cubes -generated mesh
- How does Roblox's math.noise() deal with negative inputs?
- Issue with seamless 1-D SImplex noise
- How can I generate a circle/square gradient and store it in a 2d array?
- Transforming simplex noise value to color
- Speed up Simplex Noise
- Godot - How can I make my chunks generate around the player in a 3 by 3 grid
Trending Questions
- UIImageView Frame Doesn't Reflect Constraints
- Is it possible to use adb commands to click on a view by finding its ID?
- How to create a new web character symbol recognizable by html/javascript?
- Why isn't my CSS3 animation smooth in Google Chrome (but very smooth on other browsers)?
- Heap Gives Page Fault
- Connect ffmpeg to Visual Studio 2008
- Both Object- and ValueAnimator jumps when Duration is set above API LvL 24
- How to avoid default initialization of objects in std::vector?
- second argument of the command line arguments in a format other than char** argv or char* argv[]
- How to improve efficiency of algorithm which generates next lexicographic permutation?
- Navigating to the another actvity app getting crash in android
- How to read the particular message format in android and store in sqlite database?
- Resetting inventory status after order is cancelled
- Efficiently compute powers of X in SSE/AVX
- Insert into an external database using ajax and php : POST 500 (Internal Server Error)
Popular Questions
- How do I undo the most recent local commits in Git?
- How can I remove a specific item from an array in JavaScript?
- How do I delete a Git branch locally and remotely?
- Find all files containing a specific text (string) on Linux?
- How do I revert a Git repository to a previous commit?
- How do I create an HTML button that acts like a link?
- How do I check out a remote Git branch?
- How do I force "git pull" to overwrite local files?
- How do I list all files of a directory?
- How to check whether a string contains a substring in JavaScript?
- How do I redirect to another webpage?
- How can I iterate over rows in a Pandas DataFrame?
- How do I convert a String to an int in Java?
- Does Python have a string 'contains' substring method?
- How do I check if a string contains a specific word?
GPU State changes
Nice APP "biome gridmap playground" :)
You are wasting a lot of time changing GPU state by setting
ctx.fillStylefor each tile.GPU State changes are a major source of slowdown for all apps that use the GPU (even native apps) Always go out of your way to avoid GPU state changes as they are evil.
Use CPU
Rather than use the 2D API to fill tiles (
gridMap) change the image pixels directly using the CPU.Create the 2D API with option
canvas.getContext("2d", {willReadFrequently: true})this will disable the GPU for the 2D API (as we will not be using it)Get the pixels using ctx.getImageData. The data contains the raw pixel data.
You can then write directly to the image data buffer and avoid all state changes in the process.
Example
Using drawRawMap as an example.
Details of
drawRawMapdrawRawMapandget2DCanvas.wCanvaswith tile size 1 to fill with B/W pixelsimageDataand uses view ofUint32Arrayd32to have single write per pixel.pxLuto convert raw 0 - 255 values to gray scale pixelsThis will be an order of magnitude faster (at least) than the existing code.
You can do the same with other rendering calls. Draw to a working canvas pixels', use lookup table to get pixels colors. Use tile size 1 to avoid needing to set more than one pixel per tile, and scale by
tilesizewhen drawing the result to display canvas.Avoid blocking code
Use Workers
You can get improvement via workers but it will be complicated as moving data between offscreen canvases has many caveats.
Use Generators
Using a generator function you can split the task into sections (eg per row). Using
yieldto stop the generator functions' execution (without dumping its context) and let UI have a go.You can display the result using a timer (eg
requestAnimationFrame) as the data is created. The timer just callsnext()on the generator to process the next section (row).If the generator is less than 16ms per section (yield token) the user will experience zero lag.
An example of a generator to show progress to a solution.
This will prevent the task from blocking the UI and let the user see the progress to the solution (or wait till done to show result).
Noise
I did not look at the source of your simplex noise, the following is a fork of open simplex noise that has a good performance increase on the original.