Pixalise Shader Help with GDScript Control

JayBananaJayBanana Posts: 13Member

Hi,

I'm very new to Godot and I'm hoping to make a pixalise / pixalize Shader for a transition.
As you can see below I have the Shader code sorted and the scene nodes are ready - a white TextureRect is overlayed on the background image sprite. I've got this far, but I have no idea how to control it in GDScript, how are variables passed between the Script and the Shader language?

The Shader is meant to create a pixalated effect that either starts pixalated at a high value such as 0.0008 then loops down to it's original state, or the opposite direction in a similar manner. Great for old-school platform games etc.

I did see mentioned online that it can be accomplished by:
CanvasItemMaterial's set_shader_param method

But I have no idea how to script this in GDScript.

Any help for a beginner would be appreciated!

Answers

  • TwistedTwiglegTwistedTwigleg Posts: 1,049Admin

    This Godot QA answer shows how to set variables in a shader using GDScript. You just need to use the set_shader_param and get_shader_param functions exposed by the ShaderMaterial class.

    I never remember this myself, so every time I need to do this for my shaders I have to do a Google search to remind myself how this all works :lol:

    Hopefully this helps! :smile:

  • JayBananaJayBanana Posts: 13Member

    Thanks TwistedTwigleg, I saw this post you provided in your link, I attempted to tackle it earlier, but I got quite stuck. I just couldn't apply it to my example - I'm still very much a beginner with Godot.

    Any chance of a snippet of code to help please?

  • TwistedTwiglegTwistedTwigleg Posts: 1,049Admin

    Sure. You are needing to change size_x and size_y so it goes from 1 to 0.008 smoothly, correct? If so, then in theory something like this should let you transition the shader:

    # NOTE: I'm assuming the script is on the Node2DLevel node!
    extends Node2D
    
    var shader_material;
    var shader_strength = 1;
    const LOWEST_SHADER_STRENGTH = 0.008;
    const HIGHEST_SHADER_STRENGTH = 1;
    var shader_speed = 0.5;
    var shader_do_transition = false;
    var shader_become_stronger = false;
    
    func _ready():
        shader_material = get_node("TextureRect").material;
        shader_material.set_shader_param("size_x", shader_strength);
        shader_material.set_shader_param("size_y", shader_strength);
    
    func _process(delta):
        if (shader_do_transition == true):
            if (shader_become_stronger == true):
                shader_strength += delta * shader_speed;
                if (shader_strength >= HIGHEST_SHADER_STRENGTH):
                    # Do whatever you need to do when the shader value is its highest here!
                    shader_strength = HIGHEST_SHADER_STRENGTH;
                    shader_do_transition = false;
                    shader_become_stronger = false;
            else:
                shader_strength -= delta * shader_speed;
                if (shader_strength <= LOWEST_SHADER_STRENGTH):
                    # Do whatever you need to do when the shader value is its highest here!
                    shader_strength = LOWEST_SHADER_STRENGTH;
                    shader_do_transition = false;
                    shader_become_stronger = true;
            shader_material.set_shader_param("size_x", shader_strength);
            shader_material.set_shader_param("size_y", shader_strength);
        if (Input.is_action_just_pressed("ui_submit")):
            if (shader_do_transition == false):
                shader_do_transition = true;
    

    I just wrote this from memory, so hopefully it works. If not, then I'll actually go into Godot and make a script there, and then I'll post it here when it is working.

    Hopefully this helps :smile:

  • JayBananaJayBanana Posts: 13Member

    Hi TwistedTwigleg,

    Thanks for the help and the script. Took me a few attempts as I kept getting strange errors with the Shader when I opened the project file - but that's fine now after re-typing in the shader code.

    Sadly though I'm not getting anything happening with the transition, all I get is a purple rectangle suggesting it's zoomed in a long way and stuck there.

    If you get chance to look over your code when you're in front of Godot that would be cool.

    I attached it to the Node2DLevel ;)

    I also spelt Pixelise incorrectly today, silly me.

  • TwistedTwiglegTwistedTwigleg Posts: 1,049Admin
    Answer ✓

    Okay, I went into Godot, copied the shader code from the screenshot, copied the script and made a few changes to the script to get it working with my scene.

    However, it appears the issue was not the code and how it was changing the shader, though the range in the script was too large for good results, but rather the shader in the screenshot does not transition nicely between values. It seems to only work with really, really small values, which limits the range you can use.

    However, I found a Reddit post where a user called fleurInestimable posted a shader that turns a high resolution sprite into a lower, more pixel filled version. I made a few small changes to the shader so it works with the screen texture, and then changed the range in the script and it all works now. Now when you press space/enter, it transitions from a non-pixel version to a pixel version.

    I have attached the project I used. Hopefully it helps :smile:

  • JayBananaJayBanana Posts: 13Member

    Thanks TwistedTwigleg, the example does exactly what I needed and can be adjusted, great!

    It's one of those effects I created in Construct 2 and wished to port over to Godot, but I became completely stuck. This will be a great addition to my pixel art games in Godot, cheers :)

  • TwistedTwiglegTwistedTwigleg Posts: 1,049Admin

    @JayBanana said:
    Thanks TwistedTwigleg, the example does exactly what I needed and can be adjusted, great!

    It's one of those effects I created in Construct 2 and wished to port over to Godot, but I became completely stuck. This will be a great addition to my pixel art games in Godot, cheers :)

    Cool, I’m glad it works!

    While I have not used Construct 2 myself, I totally get the desire to use the effect. It is a cool looking effect and I can see how it adds some neat visual flare :smile:

Sign In or Register to comment.