Updating material shader Float parameter does not work

Hello,

the dissolve shader wich use a vec2 unifor parameter to apply realtime effect modification is working great

i try to do the same with a shader of mine, but using a float uniform

initialisation of shader material :
[java]
Float stripesValue=0;
mat.setFloat(“StripesValue”, stripesValue);
[/java]

update during game loop :

this does not work
[java]
stripesValue=(float)Math.random();
[/java]

this does work
[java]
stripesValue=(float)Math.random();
Node n=(Node) ((Node)spatial).getChild(0);
Geometry geo=(Geometry) n.getChild(0);
geo.getMaterial().setFloat(“StripesValue”, stripesValue);
[/java]

why do i nead to update “manualy” the parameter for a Float, when for a Vector2 (or vec2) it does the trick automaticaly ?

for the dissolve shader
[java]
dissolveVector.x+=0.1;
[/java]

this code works without having to update the parameter to the material

i guess it has to do with the fact that a vector contains instances of x and y
but the float i pass as parameter is an instance too

is this a bug ?

thx

Two things.

First of all Material.setFloat( “Name”, value ), takes a data primitive as an input, it does not pass a reference to your value, so it should be very clear that changing the value itself, does not change the value in the material.

Second of all, even if the value was passed as a reference, you are working on a CPU and a GPU, they do not simply share ANY value that exists in your application, you need send values from the CPU side to the GPU side - anything else would require a massive and constant flow of data between your two processing units.

Actually passing by reference and changing the contents of where it points to is highly recommended, because if the value is used as a Define then the shader must be recompiled each time you set a new value to it

<cite>@nihal said:</cite> Two things.

First of all Material.setFloat( “Name”, value ), takes a data primitive as an input, it does not pass a reference to your value, so it should be very clear that changing the value itself, does not change the value in the material.

Second of all, even if the value was passed as a reference, you are working on a CPU and a GPU, they do not simply share ANY value that exists in your application, you need send values from the CPU side to the GPU side - anything else would require a massive and constant flow of data between your two processing units.

well, yes , obviously
tell me something that i don’t know

but it works with the dissolve shader
that’s my point

<cite>@wezrule said:</cite> Actually passing by reference and changing the contents of where it points to is highly recommended, because if the value is used as a Define then the shader must be recompiled each time you set a new value to it

not at all

i wrote an engine years ago, and i was just sending values back to shaders without recompiling every time
(glSetAttribute or something)

the point here is that…

it works with dissolve shader (using a vec2 uniform)
it does not with my shader (using a float uniform)

@curtisnewton said: not at all

i wrote an engine years ago, and i was just sending values back to shaders without recompiling every time
(glSetAttribute or something)

the point here is that…

it works with dissolve shader (using a vec2 uniform)
it does not with my shader (using a float uniform)

Because a vec2 is a real object. You aren’t changing the vec2 pointer just the values in it.

A float is a primitive. So you are just passing the value. There is no way to pass the address of a primitive variable in Java. You’d have to have it as the field of an object… like in… tada: Vector2f.

And wezrule’s point is that in a shader that has been defined as linking a particular uniform to a define will get recompiled every time you change that uniform. It’s a JME feature.

BTW, you’re “I know everything and you guys are all stupid” attitude won’t get very far… especially when you miss basic Java coding stuff.

1 Like
<cite>@pspeed said:</cite> Because a vec2 is a real object. You aren't changing the vec2 pointer just the values in it.

A float is a primitive. So you are just passing the value. There is no way to pass the address of a primitive variable in Java. You’d have to have it as the field of an object… like in… tada: Vector2f.

And wezrule’s point is that in a shader that has been defined as linking a particular uniform to a define will get recompiled every time you change that uniform. It’s a JME feature.

BTW, you’re “I know everything and you guys are all stupid” attitude won’t get very far… especially when you miss basic Java coding stuff.

no

i use an instance

[java]
Float stripesValue=0;
mat.setFloat(“StripesValue”, stripesValue);
[/java]

and you’re wrong !

one dont need to recompile a shader to update uniforms, it is an OpenGL feature

if you dont believe me check the dissolve shader, you’ll see that it works and i really doubt that JME is recompiling the shader everytime

if you replace the vec2 in dissolve shader by a float, and apply the change in the matdefs and in the java code
i does not work anymore

so i don’t think people are stupid
they just think they know everything
but wont even bother to read what i write entirely

to me it is either a jme bug
or there is a good reason why Float values are not propagated, while Vector2f values, are

anybody who really wants to adress this issue withoug going wack about what i write ?

i don’t mean no offense to anyone, but PLEASE READ WHAT I WRITE

<cite>@pspeed said:</cite> Because a vec2 is a real object. You aren't changing the vec2 pointer just the values in it.

A float is a primitive. So you are just passing the value. There is no way to pass the address of a primitive variable in Java. You’d have to have it as the field of an object… like in… tada: Vector2f.

And wezrule’s point is that in a shader that has been defined as linking a particular uniform to a define will get recompiled every time you change that uniform. It’s a JME feature.

BTW, you’re “I know everything and you guys are all stupid” attitude won’t get very far… especially when you miss basic Java coding stuff.

so here is the dissolve shader (shaderblow) example

[java]
@Override
public void simpleUpdate(float tpf) {

   count+=tpf*speed*dir;
   
   // animation ossolation
   if (count &gt; 1f) {
       dir = -1;
   } else if (count &lt; 0) {
       dir = 1;
   }
   
   // update the dissolve amounts
   DSParams.setX(count);
   DSParamsInv.setX(count);
   DSParamsBurn.setX(count-.05f);
 }

[/java]

may i suggest that as i get >400 fps, it seems highly improbable that JME is recompiling the shader @ each frame
or am i too mush of an asshole to point that out ?

BTW, you're "I know everything and you guys are all stupid" attitude won't get very far... especially when you miss basic Java coding stuff.

how would you feel if you suspected a strange behaviour with a mouse driver and the support guy would just
reply to you :

“to use a mouse, unpack it, put it on the table (IT HAS TO BE ON THE TABLE OR IT WONT WORK)
then, put it on the table move it and click on the buttons”

i know jme represents a lot of work, but if this is the way you treat someone, just becos he’s suspecting something wrong

@curtisnewton said: no

i use an instance

[java]
Float stripesValue=0;
mat.setFloat(“StripesValue”, stripesValue);
[/java]

This is the most hilarious thing I’ve read in a long time. You do not know the difference between an instance and a value.

Here is an experiment (though you have already proved 5 times over that you are not worth the time since you don’t read our posts clearly but then accuse us of the same thing despite your increasing ignorance with each new post):

[java]
public class BasicJava {
private float notAnInstance;

public void setNotAnInstance( float byValue ) {
    notAnInstance = byValue;
}

public static void main( String... args ) {
    BasicJava test = new BasicJava();

    float f = 123;
    test.setNotAnInstance( f  );
    f = 456;

    // Now... what do you expect test.notAnInstance to be at this point?
    // Hint... it's still 123
}

}
[/java]

@curtisnewton said: so here is the dissolve shader (shaderblow) example

[java]
@Override
public void simpleUpdate(float tpf) {

   count+=tpf*speed*dir;
   
   // animation ossolation
   if (count &gt; 1f) {
       dir = -1;
   } else if (count &lt; 0) {
       dir = 1;
   }
   
   // update the dissolve amounts
   DSParams.setX(count);
   DSParamsInv.setX(count);
   DSParamsBurn.setX(count-.05f);
 }

[/java]

may i suggest that as i get >400 fps, it seems highly improbable that JME is recompiling the shader @ each frame
or am i too mush of an asshole to point that out ?

Nope. Just too stupid to read what I already wrote.

I’ll try to spell it out as clearly as possible:
THIS IS ONLY AN ISSUE IF THE UNIFORM IS LINKED TO A DEFINE.

In other words:
IF THE UNIFORM IS NOT LINKED TO A DEFINE THEN THIS IS NOT AN ISSUE.

And this is never an issue if you are just modifying the fields of a vector since the material never specifically knows about that… the values just get updated behind the scenes because the uniform is resent each time the material is encountered.

1 Like

Bottom line, Material.setFloat( … ) takes a data primitive and your Float instance is going to be treated as such.

Also, Float is immutable so you can’t change it’s value without sending another complete instance anyway… and we are right back to the pass-by-value issue in the first post.

ok obviously you read in diagonal…

1 - I NEVER CLAIMED TO BE MORE CLEVER THAN ANYONE, and you’ree the one insulting others

2 - i did not use float , but Float , so go on, tell me again what is and is not an instance … come on
you’re mocking me and the using a “float” as an counter exemple … ???

let me be more stupid, at least, you’ll have a good laugh, right
j just want to have my answer, it is the only way to understand fully something, …->asking stupid questions
dont mind if i do, i won’t mind you mocking bird :wink:

1 here is the matdef for dissolve exemple

        // Dissolve Map
        Texture2D DissolveMap
        Vector2 DissolveParams;

            DISSOLVE_MAP : DissolveMap
            DISSOLVE_PARAMS : DissolveParams

2 here is the frag shader part

#ifdef DISSOLVE_MAP
    uniform sampler2D m_DissolveMap;
    #ifdef DISSOLVE_PARAMS
        uniform vec2 m_DissolveParams;
    #endif
#endif

ok, so do you agree that it uses a define, right ?

BUT MODIFYING THE VALUE IN JAVA DOES HAVE AN EFFECT IN THE SCENE
i don’t say this is right or wrong, I JUST SAY IT DOES WORK

ok ?

now… please be honest
here is the modifs i have done

1 matdef

        // Stripes Map
        Texture2D StripesMap
        Float StripesValue;

            STRIPES_MAP : StripesMap
            STRIPES_PARAMS : StripesValue

2 shader

#ifdef STRIPES_MAP
    uniform sampler2D m_StripesMap;
    #ifdef STRIPES_PARAMS
        uniform float m_StripesValue;
    #endif
#endif

so i understand what you said above, but still how do you explain that using float instead of a vec2 makes it not working anymore

make me go like the dumb one does not make you answer the BLOODY QUESTION (no offense)

the values just get updated behind the scenes because the uniform is resent each time the material is encountered.

i can’t believe you wrote that

well if it does resent the bloody value, how do you explain, that without changin anything, but the type of value, it does not wrk

and dont come with your “not an instance” thing, I DO USE ONE

unless lately, java has been so deeply changed that “Float a” does not mean "an integer instance named ‘a’ " anymore

jesus… pffff

<cite>@nihal said:</cite> Bottom line, Material.setFloat( .. ) takes a data primitive and your Float instance is going to be treated as such.

so you agree that it will keep the instance as it would do with a Vector2F ?
i mean no reason why it should not work anymore

that’s the whole point of my question

btw thank you for the time you spend answering me

Typo fixed to still prove that you don’t know what you are talking about:

[java]
public class BasicJava {
private float notAnInstance;

public void setNotAnInstance( float byValue ) {
    notAnInstance = byValue;
}

public static void main( String… args ) {
    BasicJava test = new BasicJava();

    Float f = 123;
    test.setNotAnInstance( f  );
    f = 456;

    // Now… what do you expect test.notAnInstance to be at this point?
    // Hint… it’s still 123
}

}
[/java]

You were insulting with your very first response to someone who a) genuinely tried to help you, and b) gave you the exact right answer which you chose to ignore.

I don’t think you will get much more help here.

@curtisnewton said: ok obviously you read in diagonal...

1 - I NEVER CLAIMED TO BE MORE CLEVER THAN ANYONE, and you’ree the one insulting others

2 - i did not use float , but Float , so go on, tell me again what is and is not an instance … come on
you’re mocking me and the using a “float” as an counter exemple … ???

let me be more stupid, at least, you’ll have a good laugh, right
j just want to have my answer, it is the only way to understand fully something, …->asking stupid questions
dont mind if i do, i won’t mind you mocking bird :wink:

1 here is the matdef for dissolve exemple

        // Dissolve Map
        Texture2D DissolveMap
        Vector2 DissolveParams;

            DISSOLVE_MAP : DissolveMap
            DISSOLVE_PARAMS : DissolveParams

2 here is the frag shader part

#ifdef DISSOLVE_MAP
    uniform sampler2D m_DissolveMap;
    #ifdef DISSOLVE_PARAMS
        uniform vec2 m_DissolveParams;
    #endif
#endif

ok, so do you agree that it uses a define, right ?

BUT MODIFYING THE VALUE IN JAVA DOES HAVE AN EFFECT IN THE SCENE

Because you are modifying the fields of an instance and Material does not know that you have done that. You are not changing the reference to a new Vector2f instance.

This is fundamental by-value and by-reference stuff.

<cite>@pspeed said:</cite> Also, Float is immutable so you can't change it's value without sending another complete instance anyway... and we are right back to the pass-by-value issue in the first post.

yes precisely

but my question was not about does it use a define, or is it linked, or is it ans instance

but

why Float, not ok
Vector2f ok

i mean the engine will send the value as
a vec2 for Vector2f
and a float for Float

i did not change anything else, that’s my point

i use a float, becos for my shader i dond need x,y tuple, but only a float value

this is such a simple case, i dont understand why am i so misunderstood :slight_smile:

just please give it a try , you’ll see that float values are not propagated

sorry to bee soooooo stupid, but honestly, what is the explanation

i repeat I DID NOT ADD/REMODE DEFINES or anaything AND I AM USING A Float INSTANCE

<cite>@pspeed said:</cite> Typo fixed to still prove that you don't know what you are talking about:

[java]
public class BasicJava {
private float notAnInstance;

public void setNotAnInstance( float byValue ) {
    notAnInstance = byValue;
}

public static void main( String… args ) {
    BasicJava test = new BasicJava();

    Float f = 123;
    test.setNotAnInstance( f  );
    f = 456;

    // Now… what do you expect test.notAnInstance to be at this point?
    // Hint… it’s still 123
}

}
[/java]

You were insulting with your very first response to someone who a) genuinely tried to help you, and b) gave you the exact right answer which you chose to ignore.

I don’t think you will get much more help here.

i did not insult anyone , where did you came up with that idea for god sake ?

@curtisnewton said: i did not insult anyone , where did you came up with that idea for god sake ?

This is pretty antagonistic:

@curtisnewton said: well, yes , obviously tell me something that i don't know

Despite the fact that the answer was exactly right.