Evalum Posted November 8, 2018 Share Posted November 8, 2018 Hello! Can someone point me in direction on how can I render 2d plane with custom shader as GUI? I am thinking of doing health bar but splitting just simple image won't do. I want to have pixel level control over it through shader final look of the health bar image will be composed of multiple pictures and some shader logic to tie them together. I am looking for answer like var effect = ...; effect.onBind(function () { // ... set uniforms }); var healthbar = new BABYLON.Gui(effect, scene); healthbar.position = new BABYLON.Vector2(0,0); // position on screen This is just pseudo-code. It should be relatively simple answer. Just rendering plane on top of everything that is rendered on the scene. Quote Link to comment Share on other sites More sharing options...
NasimiAsl Posted November 9, 2018 Share Posted November 9, 2018 hi @Evalum welcome to the forum https://www.babylonjs-playground.com/#40Y6CY#56 Quote Link to comment Share on other sites More sharing options...
Evalum Posted November 9, 2018 Author Share Posted November 9, 2018 7 hours ago, NasimiAsl said: hi @Evalum welcome to the forum https://www.babylonjs-playground.com/#40Y6CY#56 Thank you! I looked through code and it can indeed be used for what I intend. It looks like a lot of overhead to simply render image(s) on top of everything. I can do that in pure WebGL with even less lines of code without much problems, but since I am using BabylonJS, I was wondering whether there is a way to do it in Babylon style? Quote Link to comment Share on other sites More sharing options...
MarianG Posted November 9, 2018 Share Posted November 9, 2018 Hi. A simple and fast solution is to parent your plane to camera. line 22-26, and on plane you can add any material effect you want. But this is with 3d planes Quote Link to comment Share on other sites More sharing options...
Evalum Posted November 10, 2018 Author Share Posted November 10, 2018 21 hours ago, MarianG said: Hi. A simple and fast solution is to parent your plane to camera. line 22-26, and on plane you can add any material effect you want. But this is with 3d planes This is fast and simple indeed, but behind the scenes it is too complex and unnecessary complicated to do just such a simple thing. What I was wondering is whether Babylon has a solution that does something like the code I'll provide: (Setup once) var vao, program, gl = engine._gl; var vSource = ` precision highp float; attribute vec2 a_position; void main() { gl_Position = vec4( a_position * vec2(0.1, 0.22) + vec2(0.0, -0.5), 0.0, 1.0); } `; var fSource = ` precision highp float; void main() { gl_FragColor = vec4( 1.0, 0.0, 1.0, 1.0 ); } `; { vao = gl.createVertexArray(); gl.bindVertexArray( vao ); const vbo = gl.createBuffer(); gl.bindBuffer( gl.ARRAY_BUFFER, vbo ); gl.bufferData( gl.ARRAY_BUFFER, new Float32Array([-1.0, 1.0, 1.0,-1.0, 1.0, 1.0, 1.0,-1.0, -1.0,-1.0, -1.0, 1.0]), gl.STATIC_DRAW ); gl.vertexAttribPointer( 0 , 2, gl.FLOAT, false, 0, 0 ); gl.enableVertexAttribArray( 0 ); program = gl.createProgram(); function _initShader( s, type ) { var shader = gl.createShader( type ); gl.shaderSource( shader, s ); gl.compileShader( shader ); if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { var err = gl.getShaderInfoLog(shader); gl.deleteShader(shader); throw Error('An error occurred compiling the shaders: ' + err); } return shader; } gl.attachShader( program, _initShader( vSource, gl.VERTEX_SHADER ) ); gl.attachShader( program, _initShader( fSource, gl.FRAGMENT_SHADER ) ); gl.linkProgram( program ); if (!gl.getProgramParameter( program, gl.LINK_STATUS)) { throw Error('Unable to initialize the shader program: ' + gl.getProgramInfoLog(program)); } gl.bindAttribLocation( program, 0, "a_position"); } scene.render(); gl.useProgram( program ); gl.bindVertexArray( vao ); gl.drawArrays( gl.TRIANGLE_STRIP, 0, 6 ); (Final code is used after every time the scene is rendered) From there I can use uniforms for multiple textures I want to use and to position and scale the plane. Isn't there anything in Babylon that does that already built in? If not, I'll roll my own and mark this issue as closed. Quote Link to comment Share on other sites More sharing options...
Evalum Posted November 10, 2018 Author Share Posted November 10, 2018 This is the motivation behind this question and the final result gui.mp4 Quote Link to comment Share on other sites More sharing options...
Guest Posted November 11, 2018 Share Posted November 11, 2018 Lovely Quote Link to comment Share on other sites More sharing options...
Guest Posted November 11, 2018 Share Posted November 11, 2018 So regarding your question, GUI is not rendered with shaders but with DynamicTexture. Your code will work, but you will face potential issues by updating gl context as Babylon.js is keeping a cache of all changes and this cache will not know about your changes. I would recommend using a ShaderMaterial on a plane as mentioned by @MarianG Evalum 1 Quote Link to comment Share on other sites More sharing options...
Evalum Posted November 11, 2018 Author Share Posted November 11, 2018 @Deltakosh Well, I'll then let the cache know about the changes :=) I am thinking of writing this as feature (GUI with shaders). gui3.mp4 Quote Link to comment Share on other sites More sharing options...
Guest Posted November 12, 2018 Share Posted November 12, 2018 I will gladly merge such a PR Quote Link to comment Share on other sites More sharing options...
Evalum Posted November 12, 2018 Author Share Posted November 12, 2018 @Deltakosh I guess it's only natural to re-write/extend some of the features tool (like Babylon) offers during game development. I'll push features that are more general and can be taken advantage of in general game programming when I end up writing some. Quote Link to comment Share on other sites More sharing options...
Guest Posted November 12, 2018 Share Posted November 12, 2018 Sure no worry Quote Link to comment Share on other sites More sharing options...
Recommended Posts
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.