Drop shadow shader makes texture get offset

Godot Version

4.3 stable Windows 11

Question

I have a TextureRect node that I wanted to add an offset shadow to, and since I don’t know C# myself, I’ve been experimenting with free shaders made by other people, particularly this one: GitHub - TABmk/godot-2d-shadow-shader: 2D shadow shader for Godot 4+

Problem is, when I apply this shader to my TextureRect, it makes the texture itself offset by a lot. The shadow works, but I would prefer my main texture didn’t shift down and to the side.

I’ve also tried other drop shadow shaders, and one of them just turned my texturerect into a white rectangle, and another made it disappear completely. I tinkered a bit with the shader, but to no avail, since I don’t understand C#. Would anyone happen to know how to fix this?

First of all, shaders have nothing to do with C#. They are written in a special shading language similar to GLSL:

It is a very limited language, that, syntax wise, is quite easy to get if you are comfortable with programming (or at least know one other programming language). So I suggest you take a look and try to write a simple shader (e.g., a simple drop shadow shader without scaling) :slight_smile:

Now to the offset. The shader you are using does some scaling so that you don’t have to prepare the texture (i.e., have a big enough transparent border around it). It is implemented for Sprite2D which has it’s origin in the middle (by default - it can be changed). Texture2D on the other hand has the origin on the top left. Therefore, you probably have to change the ‘center’ scaling to a ‘top-left’ scaling. I had a quick look at the shader and this might do the trick (haven’t tested it myself, use with care ;)):

void fragment() {
    float final_scale = max(border_scale, border_scale * shadow_scale);
    vec2 scaled_uv = UV * final_scale;
    // instead of 
    // vec2 scaled_uv = UV * final_scale - (0.5 * (final_scale - 1.0));

Note, that the shader will now offset the texture if applied to a Sprite2D with centered set to true (default).

As mentioned before, you could try to implement it yourself: If you already have a transparent border around you sprite you could make a simple shader that just samples in the relevant direction and checks if it’s ‘non-transparent’.

This topic was automatically closed 30 days after the last reply. New replies are no longer allowed.