Godot Version
v4.2.2.stable.official [15073afe3]
Question
Hi!
I’m dipping my feet into Godot shaders now, but there’s one piece I’m having a bit of trouble wrapping my head around.
I’m working on a simple use case. An item is dropped from an enemy. It has a shine effect.
The item’s image is from a large Atlas texture array with many different items.
How would I adapt the following shader for such a case? I notice many of the shaders on this site seem to only work for simple, single-sprite textures:
My attempt (which is fairly close to getting what I need) is below. (Side note: This is actually quite a cool effect on its own)
shader_type canvas_item;
// --- Includes --- //
//#include "res://shaders/includes/generic_functions.gdshaderinc"
// --- Uniforms --- //
uniform vec4 shine_color: source_color = vec4(1.0, 1.0, 1.0, 0.25);
uniform float line_width: hint_range(0.0, 2.0, 0.01) = 0.1;
uniform float angle: hint_range(0.0, 6.28318530718, 0.1308996939) = 0.785398163397;
uniform float speed: hint_range(0.0, 10.0, 0.1) = 1.0;
uniform float wait_cycles: hint_range(0.0, 10.0, 0.1) = 1.0;
uniform vec2 sprite_size;
uniform vec2 atlas_size;
vec2 getPixelPosInTile(vec2 uv) {
float exactPosX = floor(uv.x * atlas_size.x * sprite_size.x);
float exactPosY = floor(uv.y * atlas_size.y * sprite_size.y);
float relativePosX = mod(exactPosX, sprite_size.x);
float relativePosY = mod(exactPosY, sprite_size.y);
return vec2(relativePosX, relativePosY);
}
// --- Functions --- //
vec2 rotate_precalculated(vec2 _pos, float _sine, float _cosine) {
return vec2(_pos.x * _cosine + _pos.y * -_sine, _pos.x * _sine + _pos.y * _cosine);
}
void fragment() {
vec2 pixel_pos = getPixelPosInTile(UV);
float sine = sin(angle);
float cosine = cos(angle);
float len = 1.5 - max(abs(sine), abs(cosine)) + line_width;
float line = smoothstep(-line_width, line_width,
rotate_precalculated((pixel_pos - vec2(0.5)), sine, cosine).y - mod(TIME * speed, (len * 2.0) * wait_cycles) + len);
COLOR.rgb += shine_color.rgb * shine_color.a * vec3(line * (1.0 - line) * 4.0);
}