Pass animation easing curve value to shaders in uniform

This commit is contained in:
Kovid Goyal 2026-08-06 20:18:31 +05:30
parent 2c8767b4e3
commit 89dbb25b5f
No known key found for this signature in database
GPG key ID: 06BC317B515ACE7C
7 changed files with 27 additions and 9 deletions

View file

@ -2334,6 +2334,7 @@ run_custom_end_shader(OSWindow *os_window, float sx, float sy, monotonic_t now)
GLint group_loc = program_uniform_location(CUSTOM_END_PROGRAM, "group");
GLint viewport_loc = program_uniform_location(CUSTOM_END_PROGRAM, "viewport");
GLint anim_progress_loc = program_uniform_location(CUSTOM_END_PROGRAM, "animation_progress");
const unsigned num_groups = (unsigned)custom_shaders.end.num_groups;
const unsigned textures_mask = custom_shaders.end.textures;
const int vw = os_window->viewport_width, vh = os_window->viewport_height;
@ -2433,8 +2434,17 @@ run_custom_end_shader(OSWindow *os_window, float sx, float sy, monotonic_t now)
vp_h = sh;
}
float anim_progress = 0.0f;
if (cg->animation_start_events != 0 && cg->animation_end_duration > 0 && os_window->shader_group_anim[g].active) {
double elapsed = (double)(now - os_window->shader_group_anim[g].started_at);
double t = elapsed / (double)cg->animation_end_duration;
if (t < 0.0) t = 0.0;
if (t > 1.0) t = 1.0;
anim_progress = (float)(cg->animation_curve ? apply_easing_curve(cg->animation_curve, t, cg->animation_end_duration) : t);
}
glUniform1i(group_loc, (GLint)g);
glUniform4f(viewport_loc, vp_x, vp_y, vp_w, vp_h);
glUniform1f(anim_progress_loc, anim_progress);
draw_quad(false, 0);
if (is_last) last_group_rendered = true;
}

View file

@ -49,7 +49,8 @@ public float4 fragment_main(
float4 color,
KittyTextures t,
KittyCustomShaderData d,
float4 viewport
float4 viewport,
float animation_progress
) {
float2 uv = t.pos;

View file

@ -17,7 +17,8 @@ public float4 fragment_main(
float4 color,
KittyTextures t,
KittyCustomShaderData d,
float4 viewport
float4 viewport,
float animation_progress
) {
// UV within the current viewport (0..1)
float2 uv = t.pos;

View file

@ -59,7 +59,7 @@ float3 linear2srgb(float3 x) { // vector
uniform Sampler2D backbuffer, a, b, persist;
public float4 pipeline_fragment_main(float2 backbuffer_pos, int group, float4 viewport) {
public float4 pipeline_fragment_main(float2 backbuffer_pos, int group, float4 viewport, float animation_progress) {
float4 color = backbuffer.Sample(backbuffer_pos); // pre multiplied linear RGB
color = float4(color.rgb / color.a, color.a); // un pre multiplied color passed through pipeline
KittyTextures t = {backbuffer, a, b, persist, backbuffer_pos};

View file

@ -17,7 +17,10 @@ public float4 fragment_main(
// the bottom-left of the screen and y increasing upwards (standard UV
// coordinates). All numbers are unit floats. If no viewport is defined for
// the group defaults to (0, 0, 1, 1) that is, the full backbuffer.
float4 viewport
float4 viewport,
// The value after applying the animation easing curve to time since
// animation start.
float animation_progress
) {
return float4(color.r, min(max(0.1, color.g) * 2, 1), color.b, color.a);
}

View file

@ -22,7 +22,8 @@ public float4 fragment_main(
float4 color,
KittyTextures t,
KittyCustomShaderData d,
float4 viewport
float4 viewport,
float animation_progress
) {
float2 pixel_pos = t.pos * float2(d.viewport_size_pixels);
float3 c = color.rgb;

View file

@ -1411,7 +1411,9 @@ def build_custom_shader_pipeline_ir(pipeline: Pipeline, cache_dir: str, invocati
implementing {slot_module_name};
import kitty_custom_shader_types;
import {module_name};
public float4 {entry_point}(float4 inp, KittyTextures t, KittyCustomShaderData d, float4 viewport) {{ return fragment_main(inp, t, d, viewport); }}
public float4 {entry_point}(
float4 inp, KittyTextures t, KittyCustomShaderData d, float4 viewport, float animation_progress
) {{ return fragment_main(inp, t, d, viewport, animation_progress); }}
"""
wrappers[f'wrapper{i}.slang'] = wrapper_src
entry_points.append(entry_point)
@ -1424,7 +1426,7 @@ public float4 {entry_point}(float4 inp, KittyTextures t, KittyCustomShaderData d
num_groups = len(pipeline['groups'])
for g_idx, group in enumerate(pipeline['groups']):
n = len(group['shaders'])
calls = '\n'.join(f' color = fragment_main{ep_idx + j}(color, t, csd, viewport);' for j in range(n))
calls = '\n'.join(f' color = fragment_main{ep_idx + j}(color, t, csd, viewport, animation_progress);' for j in range(n))
is_last = g_idx == num_groups - 1
if is_last:
calls += '\n color = float4(linear2srgb(color.rgb), color.a);'
@ -1482,8 +1484,8 @@ VertexOutput vmain_wrap(uint vertex_id : SV_VertexID) {
}
[shader("fragment")]
float4 fmain_wrap(float2 texcoord : TEXCOORD, uniform int group, uniform float4 viewport) : SV_Target {
return pipeline_fragment_main(texcoord, group, viewport);
float4 fmain_wrap(float2 texcoord : TEXCOORD, uniform int group, uniform float4 viewport, uniform float animation_progress) : SV_Target {
return pipeline_fragment_main(texcoord, group, viewport, animation_progress);
}
""".replace('MODULE', slot.replace('-', '_')).encode()