Jump to content

Exca

Members
  • Content Count

    360
  • Joined

  • Last visited

  • Days Won

    11

Reputation Activity

  1. Like
    Exca got a reaction from vornay in Can pixijs frames be processed individually?   
    You could extract the frames from canvas with toDataUrl or use the extract plugin to get the actual pixel data of a single frame. Then gather all of the frames and encode them into a video with some encoder, dunno if those exist in the browser, most likely someone has made one.
    You can do stacked rendering with multiple different ways.
    - Have 2 containers that move with different speeds.
    - Use overlapping canvases with each having their own renderer and move them.
    - Have each of your object in the scene have a depth value and move everything based on that.
    - Use rendertextures to create the stage and use those with tilingsprite and offset them at different speeds.
    Different methods have different limitations & benefits.
  2. Thanks
    Exca got a reaction from Zealot in Raycasting and inverse masking   
    You could make a filter that takes the world texture as input and the light mask as input and then just draw the world if light has value at that same position. And otherwise keep value hidden.
    Something like this:

    vec4 world = texture(worldTex,uv);
    float light = texture(lightTex,uv).a; //Using only one channel for light, this could also be light color + alpha for intensity
    gl_FragColor = mix( vec4(0,0,0,1), world, light);
  3. Like
    Exca got a reaction from flatliner in Rotate with mouse wheel   
    Just listen for wheel event on the window/document/element https://developer.mozilla.org/en-US/docs/Web/API/Element/wheel_event
  4. Thanks
    Exca got a reaction from ShoemakerSteve in Performance advice and basic concepts   
    Very simple optimization. Instead of graphics use sprites with single white rectangle as their basetexture. Then apply tint to them to color the sprite. That way the squares can be rendered as a batch. That should be good enough for 150*200 squares (30k sprites). But for 1000 x 1000  (1M squares) you need to go deep into webgl rendering or have some other optimization strategy. Or would those squares be all visible at the same time? If not, then that would be doable by separating logic from rendering and only rendering a subsection of the whole area.
    And here's a little rundown about different graphic objects:
    - Graphics: Dynamically drawn content. Use when you need to draw lines, shapes etc. Be aware that updating graphics every frame might be costly depending on the complexity.
    - Sprites: Sprites are basically just to tell what texture to draw and where, with this rotation, tint and scale. Sprites are among the cheapest objects in pixi.
    - Textures: Textures are a region of baseTexture. They tell you what part of a baseTexture should be drawn. When using spritesheets the difference between texture and baseTexture is very noticable. When using just regular images then usually textures point just to a baseTexture and say that I want to render that whole thing.
    - Basetexture: Basetextures represent a single image in memory.
    - Mesh: Meshes are renderables that have customizable vertices. You could think that sprite is also a mesh that has 4 vertex points (topleft, topright, bottomright and bottomleft). With Meshes you can control how your polygons get formed. There are some premade mesh classes that provide premade useful meshes: SimpleRope, SimpleMesh and SimplePlane. Those abstract some of the complexity away.

    And when to use them:
    Graphics: Dynamic drawn content.
    Sprites: Images with basic affine transformations (scale, rotation, position) and basic color transformation (tint, alpha).
    Textures & BaseTexture: Pretty much always if you have some images to use. Very often these get handled automatically.
    Mesh: When you need deformations.
    Also here's a short instruction on shaders:
    Modern computer graphics cards have a pipeline where you tell what program (vertex + fragment shader) you want to use, what vertices it gets as input and what uniforms (+ other stuff that I wont go into at this point). Then for each vertex it runs the vertex shader program. This basically calculates where on the screen should the point be. Then for the polygons formed by these vertices it runs the fragment shader for each pixel that is inside the polygon. The fragment shader returns the color value for that pixel. The uniforms mentioned beforehand are values that stay the same for both vertex and fragment shader on all vertex & pixel values. They are used to give values that are needed to calculate the output values. In sprite fragment shader "tint" is an uniform that is multiplied with the texture value.
    So basically your gpu renders wegbl like this (simplified): list of points to draw -> vertex shader -> find out what pixels are affected -> fragment shader -> pixel to screen.
  5. Haha
    Exca reacted to ivan.popelyshev in image texture dynamic transition   
    > is out of my scope in reasonable time.
     
    Im gonna steal that phrase
  6. Like
    Exca got a reaction from ivan.popelyshev in image texture dynamic transition   
    You could do that by creating a shader with two texture inputs which blend between those two. The actual code & math inside the shader is out of my scope in reasonable time.

    As a starting point I would propably try doing somekind of convolution with previous frame as feedback and then moving towards target image.
    This is the closest example for blending. In the example a perlin noise image is used to determine the blending. In your case that would be the shader somehow morphing the images.
    https://pixijs.io/examples/#/mesh-and-shaders/multipass-shader-generated-mesh.js
  7. Like
    Exca got a reaction from Minimog in Do not trigger interaction listener if something “covering” interactive element was clicked   
    The covering element has to have interaction enabled as well as the other item. Only those that are marked as interactive and whose parents dont have interactivechildren are taken into account when checking interactions.
  8. Thanks
    Exca got a reaction from leeda in How to create a rounded rectangle loading animation with Pixi.js v4.0+?   
    Added spinners pull request to examples. You can check that from pr or wait until it gets accepted to see it at examples.
  9. Thanks
    Exca got a reaction from Jammy in Sprite compression   
    There's plenty you can do with compression.
    For png/jpg images the amount of original image doesnt change how much memory gpu takes for that image. As those images get unpacked. But you could use compressed textures to remove decompressing and lower gpu memory usage. https://developer.mozilla.org/en-US/docs/Web/API/WebGL_API/Compressed_texture_formats
    One thing I'm not really sure is that if you have 8 bit png does that become 8bit or 32bit image after decoding.
    When it comes to loading related compression (targeting minimal dl time and no compressed textures needed) my basic workflow is to do the following:

    - Use spritesheets to group similar colored assets together (without breaking batching).
    - Group assets that dont need transparency together.
    - Export all as nonpacked png.
    - For images without transparency, update the json to use jpg and pack the png with Google Guetzli (https://github.com/google/guetzli)
    - Pack the png images to 8 bit version and do a visual check if quality drops too much. I use PNGoo for this. (https://pngquant.org/)
    - Run all png assets trough PNGauntlet ( https://pnggauntlet.com/) It's a tool that combines PNGOut, OptiPNG and DeflOpt and picks the smallest png.
    And doing lots of profiling between steps to see what actually has a positive impact.
  10. Like
    Exca got a reaction from Freckles in mouseup doesn't fire (PIXI)   
    Are those standard html input fields with canvas below them?
    You could make a container that has a hitarea with the size of whole screen and set interactive = true. Then on the handler call blur for the inputfields (or focus for another element, canvas for example).
  11. Thanks
    Exca got a reaction from Freckles in Accessing variables in PIXI*   
    setInterval(() => { this.cursor.alpha = 1; //alpha is undefined setTimeout( ()=> { this.cursor.alpha = 0; }, 500); }, 1000); You could use arrow functions instead. The scope to which this refers in javascript changes in your first example to functions scope.
    For more info on how this gets scoped check out this https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/this
  12. Like
    Exca got a reaction from b10b in PIXI Sound mp3 loop 'pause'   
    The mp3 looping problem is caused by the format. It can be mitigated by fiddling around the original sound source and compression: https://www.compuphase.com/mp3/mp3loops.htm
    I'd suggest using multiple formats and drop them based on browser support. Most of the audio libraries have alternateExtension -configuration (or something similar) to handle this. I usually go with ogg as first choice and then mp3 for those that dont support ogg.
  13. Like
    Exca got a reaction from charlie_says in PIXI Sound mp3 loop 'pause'   
    The mp3 looping problem is caused by the format. It can be mitigated by fiddling around the original sound source and compression: https://www.compuphase.com/mp3/mp3loops.htm
    I'd suggest using multiple formats and drop them based on browser support. Most of the audio libraries have alternateExtension -configuration (or something similar) to handle this. I usually go with ogg as first choice and then mp3 for those that dont support ogg.
  14. Like
    Exca got a reaction from mircha in Replacing sprite with one solid color?   
    Here you go:

     
    var sprite = new PIXI.Sprite(PIXI.Texture.WHITE); sprite.tint = 0xff0000; //Change with the color wanted sprite.width = 100; sprite.height = 100; maincontainer.addChild(sprite); Or if it's something that currently exists you could change the sprites .texture to PIXI.Texture.WHITE and tint it.

    [Edit]. If you need to have sprite change between normal display and completely tinted then just keep the normal texture stored somewhere and set it back to texture after tinting part is done.
  15. Like
    Exca got a reaction from bbyford in Sprite sheet maximum size   
    Anything below or equal to MAX * MAX is quaranteed to work (almost always, unless something is wrong with the gpu/driver). Going over either of those (even if decreasing another) might work or might not work.
    From the khronos specifciation: "The value gives a rough estimate of the largest texture that the GL can handle. The value must be at least 64. "
  16. Like
    Exca got a reaction from Iacus in Way to build image pixel by pixel?   
    const canvas = document.createElement("canvas"); //draw what you want to canvas.. //Build the basetexture, texture and sprite using the canvas const canvasTexture = new PIXI.Texture( new PIXI.BaseTexture(canvas)); const sprite = new PIXI.Sprite(canvasTexture); //Add the sprite where you want. If the canvas changes, you need to call update to basetexture. (Or it might detect it automatically, cant remember right now).
    And if you want to make it a bit faster you could use offScreenCanvas -element instead of canvas. Though that is not yet widely supported. https://developer.mozilla.org/en-US/docs/Web/API/OffscreenCanvas
  17. Like
    Exca got a reaction from ivan.popelyshev in Way to build image pixel by pixel?   
    You can also use an external 2d canvas for a bit more of drawing api. You could even use p5js to draw that, then use that canvas as a source for basetexture.
  18. Thanks
    Exca got a reaction from Iacus in Way to build image pixel by pixel?   
    You can also use an external 2d canvas for a bit more of drawing api. You could even use p5js to draw that, then use that canvas as a source for basetexture.
  19. Like
    Exca got a reaction from ivan.popelyshev in PIXI.js + TweenJS: Await finish of tween animation?   
    If I understood correctly you want to animate habbo to coord1 in a loop and then continue the loop after animation is done?
    That is not possible with await as tween does not return a promise. You would have to have your tween in a separate function and have it return a promise and then have it resolve the promise in completion.
    That would make your code pretty complex for no good reason. I assume that you want to animate the habbo-character from coord1 to coordN right?
    You could do that with tweenjs chaining:
    const moveChar = (char,points) =>{ const tween = Tween.get(char); let coord = null; for( let i = 0; i < points.length; i++) { coord = points[i]; tween.to( {x:coord.x, y: coord.y}, 500) tween.wait( 50 ); //Wait 50 milliseconds before moving to next to make the movement nicer? } //Add callback to chain ending. tween.call( () => { console.log("FINISH: " + coord); }); } moveChar( this.habbo, [ {x:0, y:0}, {x:100, y:0}, {x:100, y:100}, {x:200, y:100} ]); If I misunderstood the problem please describe it a bit more. As usually having synchronous code requirement inside a for loop is an issue that should not happen when doing rendering related stuff.
  20. Thanks
    Exca got a reaction from soop in How to create a circular cooldown effect?   
    You could draw it by having the masked graphic be round and then build the mask by drawing line to start angle. Then moving it to edge off bounding box and then to end angle position and from that on back to origo. That way you would need only 4 basic lins instead of arcs. Not sure which one is faster though.

    Here's an example:
     
    var angle = -Math.PI*0.3 - Math.PI/2; var angleStart= 0 - Math.PI/2; var radius= 40; test.beginFill(0xFF0000, 1); test.moveTo(0, 0); var x1= Math.cos(angleStart) * radius; var y1= Math.sin(angleStart) * radius; var x2= Math.cos(angle) * radius; var y2= Math.sin(angle) * radius; //Move to start point. test.lineTo( x1 , y1); //Move to left or right edge depending on which side the target is at. test.lineTo( x2 < 0 ? -radius : radius, y1); //Move to y-coordinate where end angle starts test.lineTo( x2 < 0 ? -radius : radius, y2); //Move to position where end angle starts test.lineTo( x2, y2); //Move back to center. test.lineTo( 0, 0); test.endFill(); [Edit]: You could also calculate the distance to edge and use that as a radius multiplier for each angle and then just draw line to corner of bounding box. That way it would work also with rectangle graphics.
  21. Like
    Exca got a reaction from jonforum in PIXI.js: How to build a soft sprite animation (not loop)   
    Easiest way for this would be to use some tweening library. For example tween.js (https://createjs.com/tweenjs), gsap (https://greensock.com/3) or some other from multiple possibilites.
    The examples below are done with tween.js.
    You could have in your click-handler code like:
    function moveTo(character, newX,newY) { var time = 500; createjs.Tween.get(character.position).to({x:newX, y:newY}, time); } and it would move the character with given amount of time to given position.
    If you do not wish to use tweening libraries, then you can also calculate the animation yourself and update the position in the mainloop. Below is one way how to do that (pseudocode, might have errors)
    const app = new PIXI.Application(...); const container = new PIXI.Container(); const characterSprite = PIXI.Sprite.from(...); const bg = PIXI.Sprite.from(...); container.addChild(bg); container.addChild(characterSprite); let targetPoint = characterSprite.position; let moveStart = characterSprite.position; let moveTime = 0; let timeCount = 0; bg.interactive = true; bg.addListener("click", function(e){ var to = /*Determine the coordinates where to move*/ targetPoint = to; moveStart = characterSprite.position; //Calculate the distance between points to determine how long should move last const dx = to.x - moveStart.x; const dy = to.y - moveStart.y; moveTime = Math.sqrt(dx*dx + dy*dy); }); app.ticker.add( function(delta){ if(moveTime > 0) { timeCount+=delta; if(timeCount >= moveTime) { //End has been reached. moveTime = 0; characterSprite.position = targetPoint; } else { const dx = targetPoint.x - moveStart.x; const dy = targetPoint.y - moveStart.y; characterSprite.x = moveStart.x + dx * timeCount/moveTime; characterSprite.y = moveStart.y + dy * timeCount/moveTime; } } }); Basically what happens there is you move the character between it's current point and target  point by linearly interpolating the position based on time.
  22. Like
    Exca got a reaction from ivan.popelyshev in PIXI.js: How to build a soft sprite animation (not loop)   
    Easiest way for this would be to use some tweening library. For example tween.js (https://createjs.com/tweenjs), gsap (https://greensock.com/3) or some other from multiple possibilites.
    The examples below are done with tween.js.
    You could have in your click-handler code like:
    function moveTo(character, newX,newY) { var time = 500; createjs.Tween.get(character.position).to({x:newX, y:newY}, time); } and it would move the character with given amount of time to given position.
    If you do not wish to use tweening libraries, then you can also calculate the animation yourself and update the position in the mainloop. Below is one way how to do that (pseudocode, might have errors)
    const app = new PIXI.Application(...); const container = new PIXI.Container(); const characterSprite = PIXI.Sprite.from(...); const bg = PIXI.Sprite.from(...); container.addChild(bg); container.addChild(characterSprite); let targetPoint = characterSprite.position; let moveStart = characterSprite.position; let moveTime = 0; let timeCount = 0; bg.interactive = true; bg.addListener("click", function(e){ var to = /*Determine the coordinates where to move*/ targetPoint = to; moveStart = characterSprite.position; //Calculate the distance between points to determine how long should move last const dx = to.x - moveStart.x; const dy = to.y - moveStart.y; moveTime = Math.sqrt(dx*dx + dy*dy); }); app.ticker.add( function(delta){ if(moveTime > 0) { timeCount+=delta; if(timeCount >= moveTime) { //End has been reached. moveTime = 0; characterSprite.position = targetPoint; } else { const dx = targetPoint.x - moveStart.x; const dy = targetPoint.y - moveStart.y; characterSprite.x = moveStart.x + dx * timeCount/moveTime; characterSprite.y = moveStart.y + dy * timeCount/moveTime; } } }); Basically what happens there is you move the character between it's current point and target  point by linearly interpolating the position based on time.
  23. Thanks
    Exca reacted to ivan.popelyshev in How to make sprites look crisp in non-source resolution   
    I see that @Exca helped, now i can 

    "mipmap" is not a boolean anymore, you have to use "1" or "PIXI.MIPMAP_MODES.POW2" for it , make sure your atlas has size of power-of-two. Alternatively set it to "2" or "PIXI.MIPMAP_MODES.ON" - that'll enable it in webgl2 for textures of any size.
    "sprite.roundPixels=true" helps to prevent blur when you have "anchor=0.5" and odd width/height   Mostly helps with text
    Text scaling can be a problem but you can ignore scale of parents with this trick: https://github.com/pixijs/pixi.js/wiki/v5-Hacks#ignore-parent-scale--rotation , and instead change the font size every time everything is scaled.
    Welcome tho the forums!
  24. Like
    Exca got a reaction from ivan.popelyshev in How to make sprites look crisp in non-source resolution   
    There's a few things that could help:

    - Changing the scaling mode to nearest from linear (good for pixel styled games). In this method you should scale in multipliers of 2 to keep pixels aligned. Looks really bad in nonpixel graphics style.
    - Using mipmap. Texture needs to be power of two and baseTexture.mipmap set to true. This might look better or worse.
    - Make sure sprite is on exact pixel coordinates.
    - Render the game in 1:1 pixel ratio and scale the canvas down instead of objects in renderer.
    - Create multiple sets of assets and select the one closest to wanted resolution (many spritesheet tools have automation for this).
    Propably some other things that could help that I cant remember just now.
  25. Thanks
    Exca reacted to Junkybyte in Pixi.js Showcase   
    Ivan, I want to share with you how much I appreciate your work, Pixi is an incredible library, I never wrote anything on the forum but I used it extensively these last months and your suggestions / answers have been a huge help.
    Thank you for the kind words, I really appreciate, if you ever actually refer it do it with a bit of salt, I'm pretty sure my usage of Pixi can be improved, when I started writing the library I had no prior experience with it and I learned on the road.
    Nevertheless I'm quite honoured  have a lovely day
×
×
  • Create New...