Files
batrix/shaders/projectile.gdshader
2025-09-17 14:03:09 +10:00

74 lines
1.9 KiB
Plaintext

// using noise displacement code from
// https://godotshaders.com/shader/3d-bubble-spatial-shield-shader/ and local
// screen space UV from https://godotshaders.com/shader/local-screen-space-uv/
shader_type spatial;
render_mode cull_back, unshaded;
group_uniforms Colors;
uniform vec4 inside_color : source_color;
uniform vec4 middle_color : source_color;
uniform vec4 rim_color : source_color;
uniform sampler2D rim_texture : source_color;
uniform vec2 tiling = vec2(1.0);
uniform vec2 offset = vec2(0.0);
uniform vec2 offset_speed = vec2(0.1);
group_uniforms VertexDisplacement;
uniform float speed = 1.0;
uniform float scale = 1.0;
uniform float distortion = 5.0;
varying vec4 NODE_POSITION_CLIP;
float noise(vec3 p) {
return fract(sin(dot(p, vec3(12.9898, 78.233, 45.5432))) * 43758.5453);
}
float fbm(vec3 p) {
float value = 0.0;
float amplitude = 0.5;
float frequency = 1.0;
for (int i = 0; i < 5; i++) {
value += amplitude * noise(p * frequency);
amplitude *= 0.5;
frequency *= 2.0;
}
return value;
}
void vertex() {
float displacement =
(fbm(VERTEX * scale + vec3(0.0, 0.0, TIME * speed * 0.000001)) - 0.5) *
distortion;
VERTEX += NORMAL * displacement * 0.1;
NODE_POSITION_CLIP = (PROJECTION_MATRIX * vec4(NODE_POSITION_VIEW, 1.0));
}
void fragment() {
if (COLOR.r >= 0.5) {
ALBEDO = inside_color.rgb;
} else if (COLOR.g >= 0.5) {
ALBEDO = middle_color.rgb;
} else if (COLOR.b >= 0.5) {
vec2 local_uv =
(SCREEN_UV * 2.0 - 1.0) * NODE_POSITION_CLIP.w - NODE_POSITION_CLIP.xy;
local_uv.x *= VIEWPORT_SIZE.x / VIEWPORT_SIZE.y;
local_uv *= -1.0 / PROJECTION_MATRIX[1][1];
vec3 color = texture(rim_texture,
local_uv * tiling + 0.5 + offset + TIME * offset_speed)
.rgb;
if (color.r < 0.5) {
ALBEDO = rim_color.rgb;
} else {
ALBEDO = middle_color.rgb;
}
}
}