Logo

Braindead.bzh

Game Dev Hobbyist

A blog about my game dev hobby and various stuff.

Menu
Logo

Braindead.bzh

Game Dev Hobbyist

A blog about my game dev hobby and various stuff.

Godot Quick Tip #3 - Black&White visual field

Want to create a visual field effect in 2D but want the rest of the scene to be visible in black&white? Let me show you how.

Note: this quick tip is based on the Using Lights As Mask demo and assume basic fragment shader knowledge.

Source: https://bitbucket.org/braindeadbzh/visual-field-effect-1

Introduction

Creating a visual field effect in Godot is quite simple. The idea is to use a Light2D node as a child of a character node, and use a texture depending on how you want the field to look like. Then for each element we want to be hidden to set a CanvasItemMaterial with Shading Mode set to Light Only.

But this very basic and can be easily change to something much more compelling visually.

The Fragment shader

At the root item of the scene, instead of setting Shading Mode, we create a CanvasItemShader with the following code for the fragment shader:

// Get the vertex color or the color from the texture if set
color FINAL_COLOR = min(tex(TEXTURE, UV), SRC_COLOR);

if(AT_LIGHT_PASS) {
    // For all fragments in the light we just use the input color
    COLOR = FINAL_COLOR;
} else {
    // For all other fragments we make them B&W
    float value = dot(FINAL_COLOR.rgb, vec3(0.2125, 0.7154, 0.0721));
    COLOR = color(value, value, value, FINAL_COLOR.a);
}

For all nodes you want to be affected by the effect, just select Use Parent in Material. What is also interesting in case:

  • You want a node to remain visible just don't check Use Parent
  • You want a node to be completely invisible outside the visual field, don't check Use Parent and set Light Only in Shading Mode.

The Fragment shader for Godot 3.x

shader_type canvas_item;

void fragment() {
    // Get the vertex color or the color from the texture if set
    vec4 finalColor = min(texture(TEXTURE, UV), COLOR);

    if(AT_LIGHT_PASS) {
        // For all fragments in the light we just use the input color
        COLOR = finalColor;
    } else {
        // For all other fragments we make them B&W
        float value = dot(finalColor.rgb, vec3(0.2125, 0.7154, 0.0721));
        COLOR = vec4(value, value, value, 1.0);
    }
}

Written by Olivier on Monday November 27, 2017

« Godot Quick Tip #2 - Getting the mouse cursor position in your 2D fragment shader Godot Plugin #1 - VoxelOctree »

comments powered by Disqus