AlexB Posted June 11, 2018 Share Posted June 11, 2018 I think I'll be posting a lot as we port from ThreeJS over to Babylon, so apologies. Our application allows user input to affect the appears of a 3D object. A user can change out a material on an object. Sometimes, this means that the uniforms should change. For instance, we may want to use a structure like: struct Graphic { vec2 flip; vec2 offset; float rotation; vec2 scale; sampler2D texture; sampler2D normal; }; However, if the graphic does not have a normal texture, we don't need that texture slot so I'll write the structure on the fly like this: struct Graphic { vec2 flip; vec2 offset; float rotation; vec2 scale; sampler2D texture; vec3 normal; }; So when I create a ShaderMaterial, it allows me to send in a frag shader and a vertex shader as string, like so: const material: any = new BABYLON.ShaderMaterial( name, scene, { vertex: 'some vertex', fragment: 'some fragment', }, { // options } ); But how can I later update that frag shader with new text? Something like: material.fragmentShader = newFrag; Thanks! EDIT: It also looks like I can't just set the frag and vertex code as a string. Does it have to be wrapped somehow? Quote Link to comment Share on other sites More sharing options...
Guest Posted June 11, 2018 Share Posted June 11, 2018 Hello, welcome and no need for apologies Regarding your question: as the shaders (both) are linked into a program, you have to rebuild it entirely so this means you will have to dispose the current material and creates a new one (Also I encourage you using defines as babylon.js will be able to optimize and cache effects for you) Quote Link to comment Share on other sites More sharing options...
AlexB Posted June 11, 2018 Author Share Posted June 11, 2018 Update: I have a shader loading using the ShadersStore array. BABYLON.Effect.ShadersStore[`${part.url}FragmentShader`] = ` precision highp float; varying vec2 vUV; struct Color { vec3 color } Color myColor; void main(void) { gl_FragColor = vec4(1., 0., 0., 1.); } `; This works, and I can update the fragment shader. But it appears that Babylon doesn't support GLSL structures? Is there a way to access the shader uniforms directly? Quote Link to comment Share on other sites More sharing options...
AlexB Posted June 11, 2018 Author Share Posted June 11, 2018 So by defines, you mean having conditional code in the same shader, but omitting one by setting a flag? #ifdef HAS_METALROUGHNESSMAP uniform sampler2D u_MetallicRoughnessSampler; #endif Quote Link to comment Share on other sites More sharing options...
AlexB Posted June 12, 2018 Author Share Posted June 12, 2018 @Deltakosh am I right that Babylon does not support GLSL struct objects? Quote Link to comment Share on other sites More sharing options...
Guest Posted June 12, 2018 Share Posted June 12, 2018 we support all glsl data structure and we are even using struct internally. So it should work If you can repro in the Playground I will be able to probably help Quote Link to comment Share on other sites More sharing options...
AlexB Posted June 12, 2018 Author Share Posted June 12, 2018 12 minutes ago, Deltakosh said: we support all glsl data structure and we are even using struct internally. So it should work If you can repro in the Playground I will be able to probably help I was referring to this bit of code in ShaderMaterial where it lists all the uniform types: private _textureArrays: { [name: string]: Texture[] } = {}; private _floats: { [name: string]: number } = {}; private _ints: { [name: string]: number } = {}; private _floatsArrays: { [name: string]: number[] } = {}; private _colors3: { [name: string]: Color3 } = {}; private _colors3Arrays: { [name: string]: number[] } = {}; private _colors4: { [name: string]: Color4 } = {}; private _vectors2: { [name: string]: Vector2 } = {}; private _vectors3: { [name: string]: Vector3 } = {}; private _vectors4: { [name: string]: Vector4 } = {}; private _matrices: { [name: string]: Matrix } = {}; private _matrices3x3: { [name: string]: Float32Array } = {}; private _matrices2x2: { [name: string]: Float32Array } = {}; private _vectors2Arrays: { [name: string]: number[] } = {}; private _vectors3Arrays: { [name: string]: number[] } = {}; It doesn't appear that I can set a Struct type, like so: https://www.babylonjs-playground.com/#ATDL99#1 * Note that I'm trying to use a myColor.color vec3 instead of fogColor Quote Link to comment Share on other sites More sharing options...
Guest Posted June 12, 2018 Share Posted June 12, 2018 oh ok understood.. we were not on the same page It is not supported you are right as this is not a basic type..But happy to merge a PR if you want to add it Quote Link to comment Share on other sites More sharing options...
AlexB Posted June 12, 2018 Author Share Posted June 12, 2018 13 minutes ago, Deltakosh said: oh ok understood.. we were not on the same page It is not supported you are right as this is not a basic type..But happy to merge a PR if you want to add it Gotcha. I'll look into adding support for that. Would it just affect ShaderMaterial and the _checkUniform method? I don't quite understand all your code yet. It's changed a lot since I last used it ? Quote Link to comment Share on other sites More sharing options...
Guest Posted June 12, 2018 Share Posted June 12, 2018 I hope it is better now ;D It will affect shaderMaterial and probably the effect class (which is used internally to communicate with shaders) Quote Link to comment Share on other sites More sharing options...
AlexB Posted June 12, 2018 Author Share Posted June 12, 2018 4 hours ago, Deltakosh said: I hope it is better now ;D It will affect shaderMaterial and probably the effect class (which is used internally to communicate with shaders) It turns out this is a harder problem than I thought. There is no low level method on the GL object to set structures, so what the ThreeJS implementation is doing is looping through a structure and discovering each type in a recursive loop. Then it applies each struct property one by one. I'm not sure I have time to figure it out. I got a good start on it if anyone wants to give it a try. I can push up a branch. Quote Link to comment Share on other sites More sharing options...
Guest Posted June 13, 2018 Share Posted June 13, 2018 Are you sure you want to stick with a struct then? Quote Link to comment Share on other sites More sharing options...
AlexB Posted June 13, 2018 Author Share Posted June 13, 2018 28 minutes ago, Deltakosh said: Are you sure you want to stick with a struct then? I was hoping that adding support for structures would be faster than re-wiring my shader, but I think it'll be faster to just use arrays. But I'd still love to have support for structs at some point. They make the shaders way more readable, IMO. Thanks for your help! Quote Link to comment Share on other sites More sharing options...
Guest Posted June 13, 2018 Share Posted June 13, 2018 Agree! Please create an issue on our repo to track this need AlexB 1 Quote Link to comment Share on other sites More sharing options...
AlexB Posted June 13, 2018 Author Share Posted June 13, 2018 11 minutes ago, Deltakosh said: Agree! Please create an issue on our repo to track this need https://github.com/BabylonJS/Babylon.js/issues/4520 GameMonetize 1 Quote Link to comment Share on other sites More sharing options...
Nabroski Posted June 19, 2018 Share Posted June 19, 2018 just in case someone find this post lurking for how to use struckts, i leave it here. https://www.babylonjs-playground.com/#ATDL99#3 UniformBufferObjects would be nice anyway. Quote Link to comment Share on other sites More sharing options...
AlexB Posted June 19, 2018 Author Share Posted June 19, 2018 9 hours ago, Nabroski said: just in case someone find this post lurking for how to use struckts, i leave it here. https://www.babylonjs-playground.com/#ATDL99#3 UniformBufferObjects would be nice anyway. Can you give an example of how to use a uniform buffer object with Babylon? Our user base will all be on WebGL2 browsers. Quote Link to comment Share on other sites More sharing options...
Sebavan Posted June 19, 2018 Share Posted June 19, 2018 You can have a look in the BackgroundMaterial everywhere _uniformBuffer is used. This is the smaller material we have relying on UBO: https://github.com/BabylonJS/Babylon.js/blob/master/src/Materials/Background/babylon.backgroundMaterial.ts Quote Link to comment Share on other sites More sharing options...
Nabroski Posted June 20, 2018 Share Posted June 20, 2018 @AlexB sorry, i have to pass on this one. my sketch https://www.babylonjs-playground.com/#CNE3P8 Babylonjs have a new shader system (or something like wise) you have to bind the uniform to createEffect not createShader somehow. Ask a questions in this forum, i have no idea how to use it. http://doc.babylonjs.com/api/classes/babylon.engine#createshaderprogram http://doc.babylonjs.com/api/classes/babylon.engine#createEffect Good Luck @Sebavan Yeah Quote Link to comment Share on other sites More sharing options...
Pryme8 Posted June 20, 2018 Share Posted June 20, 2018 On 6/19/2018 at 7:47 AM, AlexB said: Can you give an example of how to use a uniform buffer object with Babylon? Our user base will all be on WebGL2 browsers. I think this might help, if a uniform buffer object is the same as a VBO. If I can find my grass simulation, it covers a lot of this... let me see if I can find that this morning when things slow down at the office. Quote Link to comment Share on other sites More sharing options...
Nabroski Posted June 20, 2018 Share Posted June 20, 2018 @Pryme8 thanks for catching up. No their are not the same https://learnopengl.com/Advanced-OpenGL/Advanced-GLSL https://github.com/WebGLSamples/WebGL2Samples/blob/master/samples/buffer_uniform.html Quote Link to comment Share on other sites More sharing options...
Pryme8 Posted June 20, 2018 Share Posted June 20, 2018 Whoa, I need to learn this! Thank you. --- there are so many things to learn still with webGL, this never gets old. *UPDATE* Oh my... I needed to of know this days ago, wow... smh. Quote Link to comment Share on other sites More sharing options...
Nabroski Posted June 24, 2018 Share Posted June 24, 2018 just to be complite WebGL1: https://www.babylonjs-playground.com/#CNE3P8#2 And the babylonjs createEffect is listening to PostProcess var postProcess = new BABYLON.PostProcess("My custom post process", "custom", ["Block"], null, 0.25, camera); postProcess.onApply = function (effect) { effect.bindUniformBlock(effect.getProgram(),"Block") }; 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.