DylanD Posted August 16, 2018 Share Posted August 16, 2018 Hello everyone, I am trying to build what seems to me as a very complex shaderMaterial. Here is what I have so far (actually its mostly @Nabroski 's code, hopefully he know, he's smart!) https://www.babylonjs-playground.com/#2IFRKC#31 I have a list of things I'm trying to do and can't figure out how to do them so I have come to you guys. Here is what I am trying to do, have the shader fade between the two colours, had the height where the two shaders start fading into each other be base off of where the camera is compared to the mesh the shader is on, but I also want it to work on many meshes at the same time so that the fade happens around the same point on screen, but at different points per mesh so that they all look in sync. So: -Fade between the two colours -Height of the colours is based off camera height - specific mesh height -in sync with other meshes In the playground above I set it so that the blocks were at different heights, and the shader is at the same level of each box but different "global' height levels. I want the global height level to be the same, but the meshes height position to be different. Could anybody help with this? This is my first time making a shaderMaterial so I don't really understand it very well, yet. This also might be able to be accomplished with gradient materials but those seemed far less dynamic. So since I need them to be dynamic per mesh I don't think they will work. But I am open to suggestions. Quote Link to comment Share on other sites More sharing options...
brianzinn Posted August 16, 2018 Share Posted August 16, 2018 You can get the gradient materials shader code here to blend the colours - I think that's what you meant - it's a smooth gradient: https://github.com/BabylonJS/Babylon.js/blob/master/materialsLibrary/src/gradient/gradient.fragment.fx I've written some of my own gradient shaders from scratch as well, they ended up something like this, but for a skybox, which you can do multiple steps - ie: an intermediate gradient. I think global height is the same, but it doesn't take camera height into account. global height Vertex shader followed by gradient shader: precision mediump float; // Attributes attribute vec3 position; attribute vec3 normal; attribute vec2 uv; // Uniforms uniform mat4 worldViewProjection; // Varying varying vec4 vPosition; varying vec3 vNormal; void main() { vec4 p = vec4( position, 1. ); vPosition = p; vNormal = normal; gl_Position = worldViewProjection * p; } precision mediump float; uniform mat4 worldView; varying vec4 vPosition; varying vec3 vNormal; // Offset position // uniform float step1; // uniform float step2; uniform float offset; // Colors uniform vec3 topColor; uniform vec3 middleColor; uniform vec3 bottomColor; void main(void) { float h = normalize(vPosition + offset).y; //gl_FragColor = vec4( mix(bottomColor, topColor, max(pow(max(h, 0.0), 1.2), 0.0)), 1.0 ); gl_FragColor = vec4( mix(bottomColor, topColor, h), 1.0 ); // float h = normalize(vPosition).y; // vec4 color = vec4(mix(bottomColor, middleColor, smoothstep(0.0, step1, h)), 1.0); // color = vec4(mix(middleColor, topColor, smoothstep(step2, 1.0, h)), 1.0); // gl_FragColor = color; } Hopefully that helps a bit. It's not your solution. Quote Link to comment Share on other sites More sharing options...
Pryme8 Posted August 16, 2018 Share Posted August 16, 2018 https://www.babylonjs-playground.com/#2IFRKC#33 ? https://www.babylonjs-playground.com/#2IFRKC#35 I had just a few minutes to look, sorry hope this gets you in the right direction. you will need to bind the cameras position if you want to start using that though. *EDIT* Just reread your question, give me a little bit I got to get back to work but if no one else helps Ill get at it when I can. https://www.babylonjs-playground.com/#2IFRKC#37| https://www.babylonjs-playground.com/#2IFRKC#38 Quote Link to comment Share on other sites More sharing options...
DylanD Posted August 17, 2018 Author Share Posted August 17, 2018 19 hours ago, Pryme8 said: https://www.babylonjs-playground.com/#2IFRKC#33 ? https://www.babylonjs-playground.com/#2IFRKC#35 I had just a few minutes to look, sorry hope this gets you in the right direction. you will need to bind the cameras position if you want to start using that though. *EDIT* Just reread your question, give me a little bit I got to get back to work but if no one else helps Ill get at it when I can. https://www.babylonjs-playground.com/#2IFRKC#37| https://www.babylonjs-playground.com/#2IFRKC#38 WOW! These are all really great! This ones pretty much exactly what I need (I think so far) https://www.babylonjs-playground.com/#2IFRKC%2338 I just need it to fade a bit more like this one https://www.babylonjs-playground.com/#2IFRKC%2335 But I can get that much on my own Thanks though @Pryme8 ! You have helped me a lot!! Quote Link to comment Share on other sites More sharing options...
DylanD Posted August 17, 2018 Author Share Posted August 17, 2018 I was also wondering how expensive performance wise are shaders? If I had 4 of them would that reduce performance for mobile devices? Quote Link to comment Share on other sites More sharing options...
Pryme8 Posted August 17, 2018 Share Posted August 17, 2018 They are not, almost everything you see is ran by a shader. effectively BJS is just displaying shaders to you even when just using standard methods. when you hear someone say ran on the GPU, they are talking about some glsl usually. They are as intensive as the number of passes and pxls they have to calculate. Quote Link to comment Share on other sites More sharing options...
DylanD Posted August 17, 2018 Author Share Posted August 17, 2018 I was also thinking, would there be a way to change the shaders top or bottom colours? I have a nice gradient through all of the colours that I would like to apply to it, not sure if thats possible. Im assuming I would have to do something like: https://www.babylonjs-playground.com/#2IFRKC#39 But that doesn't work... Any ideas on how I could do that? Quote Link to comment Share on other sites More sharing options...
Pryme8 Posted August 17, 2018 Share Posted August 17, 2018 Everything is possible. take a look at: https://www.shadertoy.com/view/lscGDr Quote Link to comment Share on other sites More sharing options...
DylanD Posted August 17, 2018 Author Share Posted August 17, 2018 33 minutes ago, Pryme8 said: Everything is possible. take a look at: https://www.shadertoy.com/view/lscGDr uh this seems to be blank.. ? edit: I think it might just not be loading edit 2: it wouldn't open in safari it opened in chrome though. Sorry I was not very clear, I already have a color that goes through a gradient, I just want to apply the colours that my gradient is at the beginning of every frame or so. So for example, the top colour starts of red and the bottom is black then the red slowly switch to blue and I make the top colour blue. Basically I want to be able to change the colour through my render loop. But I am not sure how to pass a colour through the arguments, I tried here: https://www.babylonjs-playground.com/#2IFRKC#39 but it doesn't seem to work as the bottom colour is black and not green. I thought that passing a Vector3 through to a vec3 would work, but I don't think it is. When I try to do it with Color3 it makes everything red, again even when I set the passed colour to blue or green. Quote Link to comment Share on other sites More sharing options...
Pryme8 Posted August 17, 2018 Share Posted August 17, 2018 you are not binding the uniform. https://www.babylonjs-playground.com/#2IFRKC#40 Quote Link to comment Share on other sites More sharing options...
Pryme8 Posted August 17, 2018 Share Posted August 17, 2018 http://pryme8.com/procedural-investigations-in-webgl-introduction/ This might be a good read for you, especially the section 1 "Sampling Space and Manipulations" DylanD 1 Quote Link to comment Share on other sites More sharing options...
DylanD Posted August 17, 2018 Author Share Posted August 17, 2018 17 minutes ago, Pryme8 said: http://pryme8.com/procedural-investigations-in-webgl-introduction/ This might be a good read for you, especially the section 1 "Sampling Space and Manipulations" This whole website looks like a good read Thanks il have to read it once I get home! Quote Link to comment Share on other sites More sharing options...
Pryme8 Posted August 17, 2018 Share Posted August 17, 2018 why thank you ^_^, there is a wordpress bug I'm trying to work out cause like half of my articles are missing, but yeah there is some stuff that might help give you some ideas. DylanD 1 Quote Link to comment Share on other sites More sharing options...
brianzinn Posted August 17, 2018 Share Posted August 17, 2018 i've been enjoying the articles as well. thanks for sharing. Pryme8 1 Quote Link to comment Share on other sites More sharing options...
DylanD Posted August 17, 2018 Author Share Posted August 17, 2018 47 minutes ago, Pryme8 said: why thank you ^_^, there is a wordpress bug I'm trying to work out cause like half of my articles are missing, but yeah there is some stuff that might help give you some ideas. Hi there again, although I have the shader I want, I can't seem to get it into my scene, there are no errors, and it will run. However the mesh just does not show up at all. So I must be doing something wrong with copy pasting. I am in typescript. I define the shader under my class. Then in my constructor I initialize the shader with this code var shaderMaterial1 = new BABYLON.ShaderMaterial('', this.scene, { vertex: 'custom', fragment: 'custom', },{ attributes: ["position", "uv"], uniforms: ["worldViewProjection", "time", 'cameraOffset','topColour'] }); shaderMaterial1.setVector3('topColour', new BABYLON.Vector3(0,0.2,1)); then I put it on my mesh with cube.material = shaderMaterial1; None of this shows any errors that I could think of. I don't think this is a problem with the shader, I think it is a problem with my setup somehow. There doesn't seem to need a shaderStore package. I read this doc: http://doc.babylonjs.com/how_to/how_to_use_procedural_textures#using-a-shaderstore-for-shader-storage It seems the only thing I didn't do like the doc was that it is using proceduralTexture, where as I don't I use BABYLON.ShaderMaterial so im not really sure whats going wrong. Any ideas at what my problem could be? I am clueless... Quote Link to comment Share on other sites More sharing options...
Sebavan Posted August 17, 2018 Share Posted August 17, 2018 Could you create a playground with your code ? this will help a lot in troubleshooting. Quote Link to comment Share on other sites More sharing options...
DylanD Posted August 17, 2018 Author Share Posted August 17, 2018 1 minute ago, Sebavan said: Could you create a playground with your code ? this will help a lot in troubleshooting. I know it will, unfortunately its a lot of different scripts and all in typescript, which would be very difficult to put into a playground but, basically I'm using this playground:https://www.babylonjs-playground.com/#2IFRKC#41 Except I have the original mesh boxes making new instances with cube.createInstance(""); Could that be stopping the shader? I also don't have the camera in that specific script... Which might cause that. Im just going to keep updating with things that might be causing it to go blank Quote Link to comment Share on other sites More sharing options...
Pryme8 Posted August 17, 2018 Share Posted August 17, 2018 https://www.babylonjs-playground.com/#2IFRKC#44 its working. Quote Link to comment Share on other sites More sharing options...
Pryme8 Posted August 17, 2018 Share Posted August 17, 2018 4 minutes ago, DylanD said: cube.createInstance(""); Could that be stopping the shader? Yes, if you do not have instance support on your shader. 1 second. Quote Link to comment Share on other sites More sharing options...
DylanD Posted August 17, 2018 Author Share Posted August 17, 2018 Just now, Pryme8 said: https://www.babylonjs-playground.com/#2IFRKC#44 its working. well yea the playground you created works great! But I mean when I add it to my games code it does not work. Quote Link to comment Share on other sites More sharing options...
DylanD Posted August 17, 2018 Author Share Posted August 17, 2018 Just now, Pryme8 said: Yes, if you do not have instance support on your shader. 1 second. oh, I actually didn't think it would make a difference, strange because my standard materials were working with instances, I guess not. xD Quote Link to comment Share on other sites More sharing options...
Pryme8 Posted August 17, 2018 Share Posted August 17, 2018 If the shader does not have stuff like: #if NUM_BONE_INFLUENCERS > 0 uniform mat4 mBones[BonesPerMesh]; attribute vec4 matricesIndices; attribute vec4 matricesWeights; #if NUM_BONE_INFLUENCERS > 4 attribute vec4 matricesIndicesExtra; attribute vec4 matricesWeightsExtra; #endif #endif #ifdef INSTANCES attribute vec4 world0; attribute vec4 world1; attribute vec4 world2; attribute vec4 world3; #else uniform mat4 world; #endif vec4 p = vec4( position, 1. ); #ifdef INSTANCES mat4 finalWorld = mat4(world0, world1, world2, world3); #else mat4 finalWorld = world; #endif #if NUM_BONE_INFLUENCERS > 0 mat4 influence; influence = mBones[int(matricesIndices[0])] * matricesWeights[0]; #if NUM_BONE_INFLUENCERS > 1 influence += mBones[int(matricesIndices[1])] * matricesWeights[1]; #endif #if NUM_BONE_INFLUENCERS > 2 influence += mBones[int(matricesIndices[2])] * matricesWeights[2]; #endif #if NUM_BONE_INFLUENCERS > 3 influence += mBones[int(matricesIndices[3])] * matricesWeights[3]; #endif #if NUM_BONE_INFLUENCERS > 4 influence += mBones[int(matricesIndicesExtra[0])] * matricesWeightsExtra[0]; #endif #if NUM_BONE_INFLUENCERS > 5 influence += mBones[int(matricesIndicesExtra[1])] * matricesWeightsExtra[1]; #endif #if NUM_BONE_INFLUENCERS > 6 influence += mBones[int(matricesIndicesExtra[2])] * matricesWeightsExtra[2]; #endif #if NUM_BONE_INFLUENCERS > 7 influence += mBones[int(matricesIndicesExtra[3])] * matricesWeightsExtra[3]; #endif finalWorld = finalWorld * influence; #endif gl_Position = viewProjection * finalWorld * p; then it wont support instances, I am uber busy right this second maybe someone else can help you deploy instancing on the shader. Otherwise use clones for now. You could try to use include<instancesstuff> (they are different then that) in your shader string. take a look at the default material in the shaderstore and duplicate all things dealing with instances. Quote Link to comment Share on other sites More sharing options...
DylanD Posted August 17, 2018 Author Share Posted August 17, 2018 Just now, Pryme8 said: If the shader does not have stuff like: #if NUM_BONE_INFLUENCERS > 0 uniform mat4 mBones[BonesPerMesh]; attribute vec4 matricesIndices; attribute vec4 matricesWeights; #if NUM_BONE_INFLUENCERS > 4 attribute vec4 matricesIndicesExtra; attribute vec4 matricesWeightsExtra; #endif #endif #ifdef INSTANCES attribute vec4 world0; attribute vec4 world1; attribute vec4 world2; attribute vec4 world3; #else uniform mat4 world; #endif vec4 p = vec4( position, 1. ); #ifdef INSTANCES mat4 finalWorld = mat4(world0, world1, world2, world3); #else mat4 finalWorld = world; #endif #if NUM_BONE_INFLUENCERS > 0 mat4 influence; influence = mBones[int(matricesIndices[0])] * matricesWeights[0]; #if NUM_BONE_INFLUENCERS > 1 influence += mBones[int(matricesIndices[1])] * matricesWeights[1]; #endif #if NUM_BONE_INFLUENCERS > 2 influence += mBones[int(matricesIndices[2])] * matricesWeights[2]; #endif #if NUM_BONE_INFLUENCERS > 3 influence += mBones[int(matricesIndices[3])] * matricesWeights[3]; #endif #if NUM_BONE_INFLUENCERS > 4 influence += mBones[int(matricesIndicesExtra[0])] * matricesWeightsExtra[0]; #endif #if NUM_BONE_INFLUENCERS > 5 influence += mBones[int(matricesIndicesExtra[1])] * matricesWeightsExtra[1]; #endif #if NUM_BONE_INFLUENCERS > 6 influence += mBones[int(matricesIndicesExtra[2])] * matricesWeightsExtra[2]; #endif #if NUM_BONE_INFLUENCERS > 7 influence += mBones[int(matricesIndicesExtra[3])] * matricesWeightsExtra[3]; #endif finalWorld = finalWorld * influence; #endif gl_Position = viewProjection * finalWorld * p; then it wont support instances, I am uber busy right this second maybe someone else can help you deploy instancing on the shader. Otherwise use clones for now. clones sound good to me(I should test before I post this but no time!), Thanks again @Pryme8 ! Quote Link to comment Share on other sites More sharing options...
DylanD Posted August 21, 2018 Author Share Posted August 21, 2018 Is it better performance wise, that if I don't need super detailed lights, on majority of my objects, I just make pseudo lights in the shader? Because that is what I did and if so thats awesome! Also how do shaders and lights work together? From my testing it seems that once applied to the object the shader takes priority over the lights and the lights do not impact the object. Oh, @Pryme8 I was wondering what is the best way to debug a shader? console.log("test") doesn't seem to work. Any pro tips? Quote Link to comment Share on other sites More sharing options...
DylanD Posted August 21, 2018 Author Share Posted August 21, 2018 Here are some resources that have helped me, for anyone trying to learn. https://thebookofshaders.com http://pryme8.com/procedural-investigations-in-webgl-introduction/ 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.