[SOLVED] Value to Shader Uniform

  • #1, by caligarimarteMonday, 08. August 2016, 15:36 4 years ago
    I am using a Shader and want it to be affected by a Value outisde of the Script, a Value which my Protagonist has. How can I translate such a Value into an Int or Float inside a Shader Script? I would suppose it has to do with the "uniform" command, but I am not sure on the exact Implementation.

    Forum Fan

    145 Posts


  • #2, by SimonSMonday, 08. August 2016, 17:35 4 years ago
    If you're using the shadertoolkit, you can do something like this:
    shader_effects.ripple1.num.frequency = Values.value.Int
    1
    2

    Lua doesn't care if it's float or int, it will be a float in the end. But if you explicitly want an int in the shader, you need to add _i_ to uniform when writing to it.

    Thread Captain

    1368 Posts

  • #3, by caligarimarteMonday, 08. August 2016, 19:03 4 years ago
    Thanks so far. I have a few Questions about that:

    1. Although I have the Shader Toolkit in my Project, but this particular Shader is in its own little Script, so I don't exactly know whether this as "using the shadertoolkit" or not.
    2. Where exactly would I insert the suggested Line? In the Shader-Part, or in the LUA-Part? And should it be called once or rather repeatedly?
    3. So, in the suggested Line, "ripple1" is the name of the Shader, which in my Case would be "daynight". What exactly would be ".num.frequency"? "num" I have seen defined in the Shader Toolkit, but I have no Idea whether that has anything to do with my Script -- I guess not? And "frequency" I suppose would be a Flat/Int defined somewhere in the Shader Script? (As a Uniform?)
    4. And if my Protagonist has the Value "Daylight", I suppose in my Case "Values.value.Int" would be "Values.Daylight.Int"?


    For Completion's Sake and to maybe make helping me a little easier, here is my little Script:
    shader_effects["daynight"] = {shader=basic_fsh..[[

    float x = iGlobalTime * 0.5;
    // This should be changed to go along with the Value "Daylight"

    float pi = 3.1415926535897932384626433832795;

    float R = (0.75+sin((x-3)*0.5*pi + cos((x-3)*0.5*pi))*0.25);
    float G = (0.75+0.125+cos(x*0.5*pi)*0.125);
    float B = (0.75+0.125+cos(x*1.0*pi)*0.125);

    void main()
    {
    vec3 base = texture2D(iChannel0, texcoord.xy).rgb;
    gl_FragColor = vec4(base.r*R,base.g*G,base.b*B, 1.0);
    }
    ]]}

    if getObject("Conditions[DaylightShader]"):getBool(VConditionValue) then
    shaderAddEffect("daynight");
    end
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22

    Forum Fan

    145 Posts

  • #4, by SimonSMonday, 08. August 2016, 22:54 4 years ago
    Since you're using the functions of the shader toolkit, it counts.

    How do you want to change the values ? Depending on that you need to call it every frame or only once, after the shader is compiled (happens in shaderAddEffect). If it's done repeatedly you can also use bind().

    bind("daynight", "uniform", field("Values.Daylight.Int"))

    Once the shader is compiled information about that is saved in the num object of the shader_effects. So with shader_effects["daynight" ].num you can set uniforms without using the shaderUniform function (happens internally). It must be an uniform, that are the only variables that are exposed.

    Yes, it's Values.Daylight.Int .

    Also note that the shader is written a bit inconvinient. You should always put every calculation in a function and only constants outside the main function, so it's better to be understood and with the new version of the engine cross-compiled for DX.

    Thread Captain

    1368 Posts

  • #5, by caligarimarteTuesday, 09. August 2016, 02:08 4 years ago
    Where do I put the "bind(...)" Function? Right after "shaderAddEffect("daynight")"? Or in the repeating Action which updates the "Daytime"-Value every now and then? I tried it in both Places, and saw no Effect. In the repeating "updateDaytime" Action I also tried Variations of the num-Line:

    shader_effects["daynight"].num.uniform.Daylight = Values.Daytime.Int * 3.33

    ... but I did not notice any Effect, and probably got the Line wrong anyway. I don't know what exactly should come after the "num".

    So, to make my Script more efficient, I basically should put the R, G, and B Floats in the Main Function? (Okay, I did that.) Also the "x" Float? Also the Uniform?? (Which I would not assume, but at this Point I am just confused anyway.)

    Sorry for being such a n00b with handling those Shaders in Visionaire -- the currently massive Lack of Documentation and Examples to learn from (except from the Contents of the Shader Toolkit itself) make it a little hard for me to get into it. :/

    Forum Fan

    145 Posts

  • #6, by afrlmeTuesday, 09. August 2016, 04:04 4 years ago
    I think Simon is about the only one that has a clue about the shader stuff. It's way beyond me as I'm not very savvy in any of the C languages.

    Bind is a function though, so you can put it anywhere you like. There's probably some examples of bind function floating about on the forum, but as to whether you can find them (search engine is pap) is another question entirely.

    Imperator

    6842 Posts

  • #7, by SimonSTuesday, 09. August 2016, 10:22 4 years ago
    I worked it out for you:
    shader_effects["daynight"] = {shader=basic_fsh..[[
    const float pi = 3.1415926535897932384626433832795;
    uniform float daytime;
    void main()
    {
    float x = daytime;
    float R = (0.75+sin((x-3.0)*0.5*pi + cos((x-3.0)*0.5*pi))*0.25);
    float G = (0.75+0.125+cos(x*0.5*pi)*0.125);
    float B = (0.75+0.125+cos(x*1.0*pi)*0.125);
    vec3 col = vec3(R,G,B);
    gl_FragColor = vec4(texture2D(iChannel0, texcoord.xy).rgb*col, 1.0);
    }
    ]]}

    shaderAddEffect("daynight")

    bind("daynight", "daytime", field("Values.daytime.Int"))
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18

    Last line will check every frame for the value, if you write that only once you can do:
    shader_effects["daynight"].num.daytime = Values.daytime.Int
    1
    2

    Thread Captain

    1368 Posts

  • #8, by caligarimarteTuesday, 09. August 2016, 14:01 4 years ago
    Thank you very, very much, it has finally worked, after some Adjustments. \o/

    Forum Fan

    145 Posts

Write post