0 votes

Hi everyone,

I have a half-transparent TextureRect (some paper-texture) placed all over the screen. The only thing happening in the background is an animated sprite moving across from one point to another (the scene will be instanced occasionally in my project). So this looks like some "Okami" paper-effect...

However, instead of showing the whole full-screen paper, I'd like it to only appear in front of my sprite while the rest of the texture shouldn't be visible at all. Is there any usual approach how to achieve this?

Godot version 3.3
in Engine by (433 points)

I think you're describing a sprite mask here, and for that there's an example project that demonstrates using Light2D to mask sprites. The ordering of your textures may differ but I think this is the desired result.

https://github.com/godotengine/godot-demo-projects/tree/master/2d/light2d_as_mask

Another approach may be to blend the textures, perhaps using a shader.

Thanks for your help, spaceyjase and Hugo4IT!

I read the entry in the docs before, but for a beginner like me getting an explanation is obviously much better...

So it works, just as you described it to me! Only one following question came up:
regulating Paper Influence shifts the transparency of the paper texture, making the sprite behind more or less "pale"... is it possible to change the paper texture's transparancy mode to "add" or "multiply" within the shader-code? That might show the texture while keeping the sprite's contrast.
There's "blendadd" and "blendmul" mentioned as render modes in the docs, but I'm not able to apply them. I know it's possible to select such a blend mode on a new CanvasItemMaterial, but could it also be added to our running shader?

1 Answer

+2 votes
Best answer

What you're looking for is a technique called masking (wikipedia doesn't have a page for digital masking :/). You can easily achieve this using shaders, I'll guide you through adding the shader I created for you, but I highly recommend you read Godot's documentation on shaders:

First, create a ShaderMaterial:

a screenshot of that

Then, create a Shader:

another screenshot

Clicking the newly created Shader will open it in the bottom window (press Shift+F12 to maximize it). Then you can paste my shader code (again, make sure to read the documentation, so you understand what's going on):

shadertype canvasitem;

uniform sampler2D paper_texture;
uniform sampler2D paper_normal;
uniform float paper_influence: hint_range(0.0, 1.0) = 0.5;

void fragment() {
    vec4 original_color = texture(TEXTURE, UV);
    COLOR = mix(original_color, vec4(texture(paper_texture, SCREEN_UV).rgb, original_color.a), paper_influence);
    NORMALMAP = mix(NORMAL, texture(paper_normal, SCREEN_UV).xyz, paper_influence);
}

You can now adjust the settings:

A screenshot of the settings

A description of the settings:

  • paper_texture: The overlay texture.
  • paper_normal: Behaves like a sprite's normal map, you can leave it empty.
  • paper_influence: How much of the overlay is visible, 0 is only the sprite's texture, 1 is only the overlay texture, anything in between is a mix of both.

Demo

I used a brick texture as it is much easier to see, also, please excuse the terrible gif quality, the noise is from ffmpeg throwing a fit.

A gif preview

by (104 points)
selected by
Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.