Jump to content

ShaderMaterial Questions


DylanD
 Share

Recommended Posts

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. :D 

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.

Link to comment
Share on other sites

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.
 

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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!! :D   :D   :D 

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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.

Link to comment
Share on other sites

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...

Link to comment
Share on other sites

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

Link to comment
Share on other sites

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.
 

Link to comment
Share on other sites

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 !

Link to comment
Share on other sites

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?

Link to comment
Share on other sites

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.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...