[GitHub PR - v1.1.4]
[NPM - v1.1.4]
[GitHub Repo - Seed Engine]
[Github Repo - Boilerplate]
[Demo]
Seed Game Engine - Multiple Program Support and Text & MapTile Rendering
Hello Steemit! It's been a while since I've had an update on Seed Engine. As the project continues, my focus changes more towards my game rather than the Engine. Updates only make it into the Engine as I need them to continue the game as well as generic enough for use in other games. For that reason, I haven't been moving very fast with the engine lately!
Today I bring updates on the Rendering engine for building more efficient games that better utilize the GPU. The TextureManager and ProgramManager are now completely isolated from the Renderer, allowing for complete customization over WebGL rendering without limitations from the engine. Finally, I focussed on new renderer components and a new shader program that offers advanced features for drawing maps, text, and others efficiently. This post will go over these updates in detail, and demo a few examples using the new features.
There hasn't been any updates to the boilerplate or game, but I hope to have a significant update for Kingdom of Eloria out in a few weeks.
Continued WebGL Renderer Abstraction
This update is mainly orientated around Program and Texture management abstraction. The Program Manager, up until now, did not have uniform support, and all renderables used the same uniforms. Additionally, all renderable were only able to contain one texture.
The ProgramManager now contains its own uniform data required for its corresponding shaders. The RendererManager is now able to read and bind multiple textures if a Renderable needs it. Call setUniformData
on any renderable to update the uniform data for that Renderable. It may not always be required for you to call this explicitly, depending on the Renderable.
These changes allow for fully customizable WebGL programs without having to touch the RendererManager. This leads us to the next section.
TileMap Fragment Shader
I designed a fragment shader that uses a Matrix4 and another texture to cache drawing data in a data texture, and the Matrix4 to interpret how to read the data. With this shader, advanced drawing components for drawing text, tile maps, mini-maps, and a lot more are all possible.
One of JavaScript's biggest bottleneck with WebGL is communicating with the GPU. In early examples of the game, I had each of the 660 tiles viewable as a separate renderable, where they each bound their own uniform data. With JavaScript, this is very slow!
In this screenshot, uniform4fv and uniformMatrix3fv are two main uniforms used for subimage data and position. Just setting the data (doing no calculations on the data) is using 20% of the engine's processing time.
Defining, updating, and binding textures to pass data appears to be the most efficient, especially if there's a lot of data, and fewer updates to the data. The TileMap Fragment Shader bypasses excessive uniform setting by offloading a lot of sprite management to the GPU, where it will handle where each tile goes. With the TileMap Shader, the 660 tiles can now be drawn with one renderable.
New Renderable Components
Many of the new renderable components all use the same new TileMap fragment shader. This is an additional benefit as there are fewer program switches, an expensive WebGL operation. I may not need to switch programs at all by using this shader to handle all future game rendering.
Renderable2DMultitex
This Renderable is a base for anything that needs to use more than one texture in its shaders. This renderer uses the Default program, which doesn't do anything with the second texture. To get results, another shader will have to be used to handle both textures. Renderable2DGrid & FontRenderer both inherit this Renderer, and handle these issues for the developer.
Renderable2DGrid
The Renderable2DGrid can be seen as a wrapper for a use case of the Renderable2DMultitex and TileMap Fragment Shader Program. Renderable2DGrid uses this program and base renderer to create easy to manage tilemaps for very large, seamless maps. A 4,096x4,096 map is possible for any player without affecting performance. Users with higher end graphics cards which support larger gl.MAX_TEXTURE_SIZE
values can support more map data at once. Maps can be made larger, they just need to update their texture data as it all can't fit in one.
The Renderable2DGrid loads map data into a texture, where texture coordinates of that tile correspond to a map coordinate. A matrix4 is passed to the shader to handle the viewport; relative positioning, width and height. The Fragment Shader draws a sprite at each location in the viewport, depending on the id of the tile passed in through the data texture. Below is an example of setting up a Renderable2DGrid for a map:
//Create a new Renderer component.
//Pass the texture name of the tiles, tile data, width and height of map, and viewport width and height.
let renderableGrid = new Renderable2DGrid('groundTilesTextureName',[0, 0, 1, 2], 2, 2, 1, 1);
//Add component to game object.
this.addComponent(renderableGrid);
//Add to the correct viewport.
renderableGrid.addToViewport(0);
//update viewport position
renderableGrid.buildShaderTileData(viewportX1, viewportY1, viewportWidth, viewportHeight);
//get updates for new viewport position
this.renderableGrid.updateGridData(tilesViewport, minX, minY, maxX, maxY);
RenderableText
RenderableText is another wrapper for the Renderable2DMultitex and TileMap Fragment Shader Program. The renderer uses the same program as the Renderable2DGrid, but by column instead of map tile id. RenderableText components store their text data in the data texture by each column of the letter at that position, avoiding the need to handle letter spacing on different sized characters. New lines can be handled incredibly easily, by increasing the viewport on the shader to read multiple lines of text from the texture. It also allows the reuse of the same program as the Renderable2DGrid. Of course, this is all handled for you already:
//sets the text of the text renderable, and a font scale size. (1 is same size as the font glyphs).
textRenderable.setText('Here we have some text!', 1);
Here's what a font glyph texture looks like. You cant see it because it's white, open it in a new tab. In order to apply colors to the font and avoid transparency issues, the font glyphs must be solid white.
(Click here to open it in a new tab.)
Other Updates / Fixes
- The Updateable base class has had some optimizations under the hood. The update function is no longer redefined after being started. It should change nothing for a developer using the engine.
- Updated documentation.
Engine Features:
ECS System
Core Game LoopBaseclassesScenes and Scene ManagementGame ObjectsScene vs Persistent ObjectsViewportsBaseComponentMessaging
Components
Renderable, Renderable2D, RenderableSprite, RenderableShape, Renderable2DGrid, RenderableText- Audio
- Collider, Collider2D, CircleCollider, BoxCollider
- Transform
- Input
- Controllers
- Physics
Rendering (2D for now):
Multiple Views per SceneMatrix transformations- Camera per view
- Multiple Lights per view
Multiple ShapesTextures (Sprites)Animations (SpriteSheet Textures)- Particles & Particle Systems
- Effect shaders (Shadow, fire, water)
Documentation
You can view the documentation here. Documentation was updated to accompany the new features, and some outdated documentation. Members are still lacking documentation in some files.
Contributing
The GitHub readme links to the contributor section, where feature requests can be viewed. The Seed Engine is open source under the MIT license, anyone may contribute. At this time, features or updates must follow the guidelines of the request. Feature proposals are welcome!
End
I hope to make a lot of improvements to Kingdom of Eloria in the next few weeks. It will likely be renamed one final time... I hope to have basic multiplayer support, chat, accounts, and a 1000x1000 map to explore by then. Thanks for reading! Then next movements for the engine will be towards UI and audio. I'll need to focus on UI as KoE requires a substantial amount of UI components, enough to implement it as part of the engine.
looks nice
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
WARNING - The message you received from @fatimaah is a CONFIRMED SCAM!
DO NOT FOLLOW any instruction and DO NOT CLICK on any link in the comment!
For more information about this scam, read this post:
https://steemit.com/steemit/@arcange/phishing-site-reported-steem-link-premium
https://steemit.com/steemit/@arcange/anti-phishing-war-the-crooks-continue-their-bashing-campaign
If you find my work to protect you and the community valuable, please consider to upvote this warning or to vote for my witness.
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Congratulations @jaegar! You have completed the following achievement on Steemit and have been rewarded with new badge(s) :
Award for the number of upvotes received
Click on the badge to view your Board of Honor.
If you no longer want to receive notifications, reply to this comment with the word
STOP
To support your work, I also upvoted your post!
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Hey @jaegar
Thanks for contributing on Utopian.
We’re already looking forward to your next contribution!
Want to chat? Join us on Discord https://discord.gg/h52nFrV.
Vote for Utopian Witness!
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Congratulations @jaegar! You received a personal award!
Click here to view your Board
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit
Congratulations @jaegar! You received a personal award!
You can view your badges on your Steem Board and compare to others on the Steem Ranking
Vote for @Steemitboard as a witness to get one more award and increased upvotes!
Downvoting a post can decrease pending rewards and make it less visible. Common reasons:
Submit