renpy
renpy copied to clipboard
Shader transform does not appear to get animation timebase updates when there is no ATL-animated object on screen
Sorry for the long title, but I think that's the most correct description of what is happening. Or at least what I think is happening.
This is a script.rpy meant to be dropped into a fresh new project which illustrates the problem, and is the most concise expression of it I could work out:
init python:
renpy.register_shader("testanim",
variables="""
uniform vec2 u_model_size;
uniform float u_lod_bias;
uniform sampler2D tex0;
uniform float u_time;
varying vec2 v_uv;
uniform vec2 u_speed;
uniform float u_scale;
uniform sampler2D tex1;
uniform vec2 res1;
attribute vec2 a_tex_coord;
""",
vertex_300="""
v_uv = a_tex_coord;
""",
fragment_300="""
vec2 warp = texture2D(tex1, fract(v_uv + u_time * u_speed), u_lod_bias).rg;
vec2 st = v_uv + warp * u_scale;
gl_FragColor = texture2D(tex0, st, u_lod_bias);
"""
)
init:
image bg test = Tile("blindstile.png")
transform anishader(child):
shader "testanim"
Model().child(child, fit=True).texture("squarestile.png")
u_speed (0.05,0.05)
u_scale 0.5
# This is the workaround.
# Uncomment this to see the shader animation stop stuttering.
# zoom 1.0
# block:
# linear 60 zoom 1.000001
# linear 60 zoom 1.0
# repeat
transform imageanim:
align (0.5,0.5)
alpha 0
ease 0.2 alpha 1.0
block:
ease 1.0 alpha 0.0
pause 1
ease 1.0 alpha 1.0
pause 1
repeat
image testimage = At(Text("FOO, I say.", size=80, color="#000"), imageanim)
label start:
scene bg test at anishader
"Watch the stuttering shader on the background. It's not supposed to stutter."
"Now we're going to put up an animated image."
show testimage at truecenter
"Notice how the shader animation stutters when there
is {i}no{/i} object constantly animated by ATL on screen,
but runs smoothly when there is -- and starts stuttering again
when the animation pauses."
return
Initially I thought it was the reverse -- that pauses in ATL (I had a CTC blinking in the corner) cause the shader to stop, which turned out not to be the case. The obvious workaround is to have the shader ATL constantly animate a parameter that does not actually affect the display, which will keep the timebase spinning. However, this strikes me as a very crude solution.
I suspect this is intended behavior, but if so, it would be lovely if there was a legitimate way to override it, and it definitely needs to be documented as a caveat.
P.S. Eventually I found this issue, which describes the same situation. As well as the fact that pause 0
repeat
is the legit way to handle it and the behavior is intended.
If everyone is too busy to do so, I could send a PR?...
What PR are you considering? It might make sense to have better documentation for pause 0 / repeat, but I'm not sure we need additional syntax for it.
Better documentation for the potential pitfall of an animated shader not animating as expected, and the way of specifying it must be animated anyway by pause 0
/ repeat
is exactly what I'm considering.