Unsurprisingly, shaders are hard.
I'm trying to make a warp shader (specifically, to adapt this specific shader by AmazingThew on Shadertoy into Ren'Py: https://www.shadertoy.com/view/XlS3Wm; you can see the preview of what I'm going for there, too). And currently, I'm failing. Anyways, here's my code. I have no idea what I'm doing, but I'm trying my best.
Code: Select all
renpy.register_shader("mygame.warp", variables=
"""
uniform sampler2D tex0;
uniform sampler2D tex1;
uniform vec2 res0;
uniform float u_time;
uniform vec2 u_model_size;
uniform vec2 uv;
uniform float power;
uniform float warpSpeed;
uniform float warpDistance;
attribute vec4 a_position;
varying vec2 v_position;
""", vertex_200="""
v_position = a_position.xy / u_model_size.xy;
""", fragment_200=
"""
float warpSpeed = 0.3;
float warpDistance = 0.02;
vec2 uv = v_position.xy / res0.xy;
uv.y *= -1.0;
vec3 offTexX = texture2D(tex1, uv).rgb;
vec3 luma = vec3(0.299, 0.587, 0.114);
float power = dot(offTexX, luma);
power = sin(3.1415927*2.0 * mod(power + u_time * warpSpeed, 1.0));
gl_FragColor=texture2D(tex0, uv+vec2(0, power)*warpDistance);
""")
Code: Select all
init python:
class ShaderDisplayable(renpy.Displayable):
def __init__(self, *args, **kwargs):
self.shader_kws, kwargs = renpy.split_properties(kwargs, "u_", "")
self.shader = kwargs.pop("shader")
self.mipmap = kwargs.pop("mipmap", None)
# Pass additional properties on to the constructor.
super(ShaderDisplayable, self).__init__(**kwargs)
self.shader_textures = [renpy.easy.displayable(k) for k in args]
def render(self, width, height, st, at):
mr = renpy.display.render.render(
self.shader_textures[0], width, height, st, at)
w, h = mr.get_size()
rv = renpy.display.render.Render(w, h, opaque=False)
rv.blit(mr, (0,0))
for k in self.shader_textures[1:]:
cr = renpy.display.render.render(k, w, h, st, at)
rv.blit(cr, (0,0), focus=False, main=False)
rv.mesh = True
rv.add_shader(self.shader)
for k,v in self.shader_kws.items():
rv.add_uniform("u_{}".format(k), v)
rv.add_property("mipmap",
renpy.config.mipmap_dissolves if (self.mipmap is None)
else self.mipmap)
return rv
def event(self, ev, x, y, st):
return None
def visit(self):
return self.shader_textures
Code: Select all
show expression ShaderDisplayable("images/panorama.jpg","images/bayer.png", shader="mygame.warp")