Mikal's Forum Posts

  • Working on some effects and I have noticed that the uniform pixelSize changes when opacity is set below 100%. I imagine this has something to do with rendering required on sprite before opacity/blend is applied. Any suggestions on how to handle the case of pixelSize changing as opacity is switched between 100% and < 100%?

    pixelSize is being used to get the full render screen resolution in the effect which uses it for relative positioning. An alternative is to pass this value in directly via another uniform.

    Tagged:

  • Thanks, appreciate the work!

  • I posted a possible solution on the Construct Community Discord. Using fract() and normalize of uv/Vtex with srcOrigin*.

  • Looking good! Nice work.

  • Good post, I had forgotten I also did a PWA for C3, it's nice to have its own clean window running and with cut & paste, I'm pretty much ok vs desktop. The local files are nice because of the potential use of git/version control in a better way for a team, but in reality, fine-grained collab on C3 is hard anyway.

    The other interesting thing for local files for me would be to link animation frames to local image files and have a refresh button per sprite or frame (didn't C2 have this?)

  • First, I know this is bleeding edge, but perhaps interesting for future Electron / nw.js exports.

    I am using a plugin with DOM side scripts (Greengrinds an extended version of the official Greenworks plugin.)

    With the plugin, my game exported and I built an Electron version with efc. It works well from Electron 3.x to 6.x (chromium 76, node 12.4.) However, for Electron 7.0.0-beta.3 (chromium 78, node 12.8), it looks like the domSide.js script is no longer loading in the DOM, it _appears_ to be running in the renderer. The evidence is the require stack has changed and I have had to change

    	require('../../app.asar.unpacked/greenworks/greenworks');
    

    to

    	require('electron').remote.require('../app.asar.unpacked/greenworks/greenworks');
    

    Once done that works, but it still seems like my DOM side script is not running on the DOM side anymore in this later version of Electron/Chrome/Node. I know this is all bleeding edge, so I don't expect everything to work, but I thought it was interesting enough to mention in the forum in case someone else has an insight into it.

    electronforconstruct.armaldio.xyz

  • Try Construct 3

    Develop games in your browser. Powerful, performant & highly capable.

    Try Now Construct 3 users don't see these ads
  • Comment from the C3 Community Discord (it looks like the issue is still persisting though at least on my side with regards to accessing forum, etc.) It does feel like there should be some kind of back up for at least sign in though (even with offline mode, sometimes I move to a different machine or new VM and I need to login in again.)

    Website issues should be resolved, think was a combination of a) Azure network issue (causing connectivity problems to Redis) and b) degradation of performance from rollout of arcade caused by increased visitor traffic (significant).

    The Azure network problem seems to of resolved, and we're adding extra capacity and have made a few changes on the VM's to improve performance significantly.

    Everything should be OK now.

    We've planned for these sorts of events with regards to access to C3, if you had it available in offline mode it should of been able to run with all features without issue.

  • Updated the ElementQuad helper with the help of Ashley to use newly documented SDKs and released.

    The Spine example is doing one Spine animation rendered to one separate canvas and the canvas is used for multiple ElementQuad instances (a light port of the Spine meshes demo.) For more Spine animations, this example may need another canvas per Spine animation and either a clone of ElementQuad or a new instance. Control of the animation will need to be done through JS calls to the Spine-TS API, movement, angle, size, effects, etc. on the resulting ElementQuad can be through C3 events.

    Link to addon and example in the original post.

  • Thanks Ashley this worked well, it seems to perform reasonably well (100 instances at 320x240 still ran at 60 fps, I think I will be more in the 1-10 range.) I am also glad to be using only the C3 SDK and no 'raw' webgl which could get out of sync with the engine gl batching and optimizations. Thanks for the help and the docs. I will post the addon (and Spine example which uses it) after some more testing.

    Here's my updated Draw() function.

     Draw(renderer)
     {
     if (this._elementId == "") return; // elementID not set, can't draw the element
    
     var myCanvas = document.getElementById(this._elementId)
     // Create texture if it does not exist (could this be done in constructor or setElementId action)
     if (this._elementTexture === null)
     {
     this._elementTexture = renderer.CreateDynamicTexture(myCanvas.width,myCanvas.height,{mipMap:false})
     // console.log(this._elementTexture)
     }
    
     const wi = this.GetWorldInfo();
     const quad = wi.GetBoundingQuad();
     const rcTex = new C3.Rect(0,0,1,1) // Possible to get from this._texture instead? Not needed, not spritesheeted?
    
     renderer.UpdateTexture(myCanvas, this._elementTexture, {})
    
     renderer.SetTexture(this._elementTexture)
    
     if (this._runtime.IsPixelRoundingEnabled())
     {
     const ox = Math.round(wi.GetX()) - wi.GetX();
     const oy = Math.round(wi.GetY()) - wi.GetY();
     tempQuad.copy(quad);
     tempQuad.offset(ox, oy);
     renderer.Quad3(tempQuad, rcTex);
     }
     else
     {
     renderer.Quad3(quad, rcTex);
     }
     }
    
  • Ashley Thanks for the great response, details of the engine and suggested method for implementation. I will take a look at implementing something similar to the text method and thanks for the additional documentation that you just provided. I appreciate the comment on the resize and creating a new texture based on that - very helpful in making this all more robust.

  • I think I found at least one improvement to use more of the C3 SDK, I can use the below to get the rcTex coordinates:

    getLeft()
    getTop()
    getRight()
    getBottom()
    
  • Ashley Thanks for the reply (and thanks for the comments in the bug report, I understand, that makes sense.)

    I do agree that rendering directly to the C3 canvas would be better and that will be something to explore, however, the render is done through the Spine-TS runtime script and it looks like a lot to dive into to figure out (10K lines). It's already set up to render to a canvas, however, also integrating in the render with other sprite objects could be a challenge? Though I think it would be possible if created a Drawing plugin and did the work to integrate the Spine render into the Drawing Plugin Draw function? Something to explore in the future.

    I was looking for a short cut to use the existing Spine-TS. I have found a way that works and _seems_ to perform pretty well. I definitely tried to use only C3 SDK, but I think I used a little more. In this method, I created a drawing plugin which replaces a sub texture of the drawing plugin Sprite Sheet with the canvas texture on each Draw() call. There are limitations: it only replaces the top MIP level, so if the Sprite is scaled down, the old image starts to blend in. So, for the game, I will force screen resolution and keep Sprite size relatively the same so the other MIP levels do not kick in (this will likely be a desktop nw.js / Electron game, so I will have some control over which chromium engine the game is shipped with and control over full screen vs windowed.) I know this is not bullet proof, but I think I can work around the issues. If you have suggestions on how to make the below use more C3 SDK functions, that would be very appreciated!

    In general for Spine animations, I will just use 1-3 characters animated this way, so 'only' 1-3 texture updates per frame. The rest will be simpler and use traditional sprite frame animation.

     Draw(renderer)
     {
     var gl = renderer._gl
     const imageInfo = this._objectClass.GetImageInfo();
     const texture = imageInfo.GetTexture();
     if (!texture) return; // dynamic texture load which hasn't completed yet; can't draw anything
    
     const wi = this.GetWorldInfo();
     const quad = wi.GetBoundingQuad();
     const rcTex = imageInfo.GetTexRect();
     var myCanvas = document.getElementById(this._elementId)
    
     gl.bindTexture(gl.TEXTURE_2D, texture._texture);
     // webgl2: gl.texSubImage2D(gl.TEXTURE_2D, 0, (rcTex._left * texture.GetWidth() - 0.5).toFixed(0), (rcTex._top * texture.GetHeight() - 0.5).toFixed(0), myCanvas.width, myCanvas.height, gl.RGBA, gl.UNSIGNED_BYTE, myCanvas);
     gl.texSubImage2D(gl.TEXTURE_2D, 0, (rcTex._left * texture.GetWidth()).toFixed(0), (rcTex._top * texture.GetHeight()).toFixed(0), gl.RGBA, gl.UNSIGNED_BYTE, myCanvas);
    
     renderer.SetTexture(texture)
    
     if (this._runtime.IsPixelRoundingEnabled())
     {
     const ox = Math.round(wi.GetX()) - wi.GetX();
     const oy = Math.round(wi.GetY()) - wi.GetY();
     tempQuad.copy(quad);
     tempQuad.offset(ox, oy);
     renderer.Quad3(tempQuad, rcTex);
     }
     else
     {
     renderer.Quad3(quad, rcTex);
     }
     }
    
  • I've posted a project template with the plugin bundled.

    The new drawing plugin ElementQuad, takes an element as ID as an argument and each frame (Draw is called), it sets the image texture to the element (I am using the SpineCanvas which is the canvas I am using to render a Spine animation to.) It is just replacing the top MIP level, so you cannot scale the ElementQuad too much (or other MIP levels which do not contain the Sprite render will start blending in.) The ElementQuad image size works best if it's the same size as the Element (canvas.)

    So, the original issue in the thread is no longer blocking, this alternative approach also seems much more performant (with the caveat for the sizing limitations.)

    Here's a link to the template and plugin, please feel free to suggest improvements. It is still only a template and only one Spine object is currently supported.

    construct.net/en/forum/construct-3/general-discussion-7/spine-animation-js-template-145940

  • Update 08/11/2019:

    Created a plugin helper ElementQuad, which can use a canvas directly as a texture, which lowers memory usage and improves performance. There is now no stutter, one caveat is that it works best if the ElementQuad image size is the same as the Spine render canvas.

    An updated project with the new ElementQuad plugin bundled is in the original post.

  • I am taking a new approach.

    I've created an ElementQuad helper plugin which is a Drawing plugin that replaces its initial texture with an Element from the document which can be set via an action. Right now I'm using the Spine render canvas as the Element to be used as a replacement texture. With this method, it looks there is not a large amount of new data/objects created to be GC'd later and the animations now run smoothly without a stutter. I will post the new template and plugin.