Jump to content

Draw big map pixel by pixel.


ZeRo000s
 Share

Recommended Posts

My game have map auto  generator that make an unlimited map pixel by pixel, i tried to draw it pixel by pixel using graphics that was so slow! so i tried 2d canvas and drawing chunks asynchronously that was good kinda good but ah still slow sometimes i can see unloaded chunks and can be a huge problem for players with bad computer, so i tried webgl fragementshader instead that worked good but it draw it again and again when i need it to draw it only once is there anyway to draw it using webgl in pixi other than fragementshader?

Edited by ZeRo000s
Link to comment
Share on other sites

Its all possible, but requires soooo much explanation. Please provide more information about your current implementation.

Also I know a number of projects like that and all of them are struggling, spending lots of time on perfecting the technique. I dont know if i actually can explain you all the tricks of production-ready apps for that kind of thing in several sentences :(

Usually ist collection of RenderTexture tiles (256x256 or 512x512) , and you take mouse input, interpolate to curve, spawn a number of "brush sprites" and then render their container in tiles that are affected. Something like this: https://github.com/wonderunit/alchemancy

Edited by ivan.popelyshev
Link to comment
Share on other sites

here is a quick exemple. im using 2d canvas and async now (i thought game did draw chunks asynchronously but i forgot to add it) and added option to change map resolution its good enough i guess but using webgl drawing will be alot better. like pixi does with fragementshader 😄

// drawing a pixel in a "block"

mapInfos; // 3d array sent from server to client that conatain infos of the top left pixel of everyblock.
//client use the mapInfos and bilinear interpolation to calculate infos of other pixels than use that to choose a color.
pos; // pixel position in the chunk normilized to 0-1.
cpos; //block

Height = bilinearInterpolation(pos,[mapInfos[cpos.x][cpos.y][0],mapInfos[cpos.x+1][cpos.y][0],mapInfos[cpos.x][cpos.y+1][0],mapInfos[cpos.x+1][cpos.y+1][0]]);
Temperature = bilinearInterpolation(pos,[mapInfos[cpos.x][cpos.y][1],mapInfos[cpos.x+1][cpos.y][1],mapInfos[cpos.x][cpos.y+1][1],mapInfos[cpos.x+1][cpos.y+1][1]]);

// check what color it should be using Height and Temperature value :]

and the result is something like this (ignore ugly trees/stones they are just for test)
image.thumb.png.b9775e2cb9ec647f63ac5402a59714fb.png

and map will be something like this
image.thumb.png.19960dc4d7ec109d757a76c475ba90ae.png

Edited by ZeRo000s
Link to comment
Share on other sites

oh, you dont want to draw on that map.. I just thought you want a drawing app :)

It looks like dynamic meshing with chunks, like in minecraft. What is the problem? Problem is that its a big topic.

I call it "problem of 100k bunnies"

In that kind of cases there are high-level algos that are made by you and low-level structures/algos that you take from pixi, plugins or write yourself.

Resulting performance depends on both, its all about balance and it took me 4 years to learn that. People usually solve their first problem randomly using algos that they think are "effective", but true mastery comes only in 2 or so years.

Without many details, its just not possible to say "yes, that algorithm will work for your case for sure".

Usually when we discuss this, I reference pixi-tilemap, so please use this search if you want more info on subject (even if its not related to tilemaps): https://www.html5gamedevs.com/search/?q=pixi-tilemap&quick=1&type=forums_topic&nodes=15

 

Edited by ivan.popelyshev
Link to comment
Share on other sites

Bear in mind - you are asking about very difficult thing that is not supplied by any html5 library and i dont know of frameworks that can do that. Usually people discuss it only in context of agar-io and its heavy already. You have not only circles but many other objects on the map, and you shouldn't wait when someone gives you solution, you should research it and ask more concrete questions. Without your own high-level algorithms its just not possible

Link to comment
Share on other sites

Okay, thank you :]
it draws only visible chunks so its not that hard i guess! i made it kinda faster by using faster bilinear interpolation (calculate edge values and use this values to calculate other pixels values faster).

im making rn a  simple search algo that find rectangles with the same color and draw them instead of drawing it pixel by pixel :]

im not sure you understand what i want exactly i want accelerate drawing the map by using webgl if possible bc drawing using fragementshader is pretty fast but it keep drawing it again and again every frame , i will maybe use fragementshader to draw chunks incase i add some animations like water level changing!

Edited by ZeRo000s
Link to comment
Share on other sites

The drawing is fast enough now after changing some bad code

why not just put those things in a texture? You cant directly access texture pixels but you can ask it to update from your buffer

colorz = new Uint32Array(4*width*height);
colorz[0] = 255;//first R;
colorz[1] = 255;//first R;
colorz[2] = 255;//first R;
colorz[3] = 255;//first G;

const myTex = Texture.from(colorz, { width: width, height:height });

colorz[index] = ...

myTex.update();

and use that texture in sprite

the downside is of course the texImage2D that uploads array to videomem, but if you have only a several chunks updating per tick, it should be fine. Otherwise you might create a queue which chunks have to be updated and update several of them in one frame

to understand limitations of pixi you can go through https://webglfundamentals.org/ . we dont have pixi version of it, but pixi uses all those things in its low-level. If you think in webgl terms, its easy to convert them to pixi and estimate what exactly is going on.

Also one of basic debug tricks - use SpectorJS to capture one single frame and you'll see what is happening inside it

Edited by ivan.popelyshev
Link to comment
Share on other sites

In case textures take too much memory, you can try use texture with only one channel (LUMINANCE format) and make a shader for your chunk that will produce color based on the value (basically, storing palette somewhere, maybe in texture)

how to make basic mesh shader: https://pixijs.io/examples/#/mesh-and-shaders/triangle-textured.js

Color-Map filter, might be good for taking some code for shader, it has palette: https://github.com/pixijs/pixi-filters/blob/master/filters/color-map/src/color-map.frag , see the example in the plugin

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...