Default Shader Parts
Shader parts are used by Model-Based Rendering and Text Shaders. This file contains an index of parts by priority, and the source of each shader part.
Vertex Part Priorities
How Ren'Py uses vertex part priorities:
Priority 0 sets up gl_Position.
Priority 10 is used to capture gl_Position in virtual or drawable coordinates before adjustment.
Priorities 20-80 adjust gl_Position in virtual or drawable coordinates.
Priority 90 is used to capture gl_Position in virtual or drawable coordinates after adjustment.
Priority 100 transforms gl_Position to viewport coordinates.
Priority 200 stores more information in varying variables, without touching gl_Position.
In order:
Fragment Part Priorities
How Ren'Py uses fragment part priorities:
Priority 200 determines an original color and stores it in gl_FragColor.
Priority 300 multiplies that color with a second texture.
Priority 325 stores alpha before the text shaders adjust it.
Priority 350 applies text shaders that adjust alpha.
Priority 375 can undo part of the effect of these text shaders.
Priority 400 adjusts the color, applying Transform and displayable-based changes.
Priority 500 adjusts the alpha channel, applying Transform and displayable-based changes.
In order:
renpy.alpha
Variables:
uniform float u_renpy_alpha;
uniform float u_renpy_over;
Fragment shader (priority 500):
gl_FragColor = gl_FragColor * vec4(u_renpy_alpha, u_renpy_alpha, u_renpy_alpha, u_renpy_alpha * u_renpy_over);
renpy.alpha_mask
Variables:
uniform sampler2D tex0;
uniform sampler2D tex1;
attribute vec2 a_tex_coord;
varying vec2 v_tex_coord;
Vertex shader (priority 200):
v_tex_coord = a_tex_coord;
Fragment shader (priority 500):
vec4 src = texture2D(tex0, v_tex_coord.xy);
vec4 mask = texture2D(tex1, v_tex_coord.xy);
gl_FragColor = vec4(src.r * mask.r, src.g * mask.r, src.b * mask.r, mask.r);
renpy.blur
Variables:
uniform sampler2D tex0;
attribute vec2 a_tex_coord;
varying vec2 v_tex_coord;
uniform float u_renpy_blur_log2;
Vertex shader (priority 200):
v_tex_coord = a_tex_coord;
Fragment shader (priority 200):
gl_FragColor = vec4(0.);
float renpy_blur_norm = 0.;
for (float i = -5.; i < 1.; i += 1.) {
float renpy_blur_weight = exp(-0.5 * pow(u_renpy_blur_log2 - i, 2.));
renpy_blur_norm += renpy_blur_weight;
}
gl_FragColor += renpy_blur_norm * texture2D(tex0, v_tex_coord.xy, 0.);
for (float i = 1.; i < 14.; i += 1.) {
if (i >= u_renpy_blur_log2 + 5.) {
break;
}
float renpy_blur_weight = exp(-0.5 * pow(u_renpy_blur_log2 - i, 2.));
gl_FragColor += renpy_blur_weight * texture2D(tex0, v_tex_coord.xy, i);
renpy_blur_norm += renpy_blur_weight;
}
if (renpy_blur_norm > 0.0) {
gl_FragColor /= renpy_blur_norm;
} else {
gl_FragColor = texture2D(tex0, v_tex_coord.xy, 0.0);
}
renpy.dissolve
Variables:
uniform float u_lod_bias;
uniform sampler2D tex0;
uniform sampler2D tex1;
uniform float u_renpy_dissolve;
attribute vec2 a_tex_coord;
varying vec2 v_tex_coord;
Vertex shader (priority 200):
v_tex_coord = a_tex_coord;
Fragment shader (priority 200):
vec4 color0 = texture2D(tex0, v_tex_coord.st, u_lod_bias);
vec4 color1 = texture2D(tex1, v_tex_coord.st, u_lod_bias);
gl_FragColor = mix(color0, color1, u_renpy_dissolve);
renpy.geometry
Variables:
uniform mat4 u_transform;
attribute vec4 a_position;
Vertex shader (priority 0):
gl_Position = a_position;
Vertex shader (priority 100):
gl_Position = u_transform * gl_Position;
renpy.imagedissolve
Variables:
uniform float u_lod_bias;
uniform sampler2D tex0;
uniform sampler2D tex1;
uniform sampler2D tex2;
uniform float u_renpy_dissolve_offset;
uniform float u_renpy_dissolve_multiplier;
attribute vec2 a_tex_coord;
varying vec2 v_tex_coord;
Vertex shader (priority 200):
v_tex_coord = a_tex_coord;
Fragment shader (priority 200):
vec4 color0 = texture2D(tex0, v_tex_coord.st, u_lod_bias);
vec4 color1 = texture2D(tex1, v_tex_coord.st, u_lod_bias);
vec4 color2 = texture2D(tex2, v_tex_coord.st, u_lod_bias);
float a = clamp((color0.a + u_renpy_dissolve_offset) * u_renpy_dissolve_multiplier, 0.0, 1.0);
gl_FragColor = mix(color1, color2, a);
renpy.mask
Variables:
uniform float u_lod_bias;
uniform sampler2D tex0;
uniform sampler2D tex1;
uniform float u_renpy_mask_multiplier;
uniform float u_renpy_mask_offset;
attribute vec2 a_tex_coord;
varying vec2 v_tex_coord;
Vertex shader (priority 200):
v_tex_coord = a_tex_coord;
Fragment shader (priority 200):
vec4 src = texture2D(tex0, v_tex_coord.st, u_lod_bias);
vec4 mask = texture2D(tex1, v_tex_coord.st, u_lod_bias);
gl_FragColor = src * (mask.a * u_renpy_mask_multiplier + u_renpy_mask_offset);
renpy.matrixcolor
Variables:
uniform mat4 u_renpy_matrixcolor;
Fragment shader (priority 400):
gl_FragColor = u_renpy_matrixcolor * gl_FragColor;
renpy.solid
Variables:
uniform vec4 u_renpy_solid_color;
Fragment shader (priority 200):
gl_FragColor = u_renpy_solid_color;
renpy.texture
Variables:
uniform float u_lod_bias;
uniform sampler2D tex0;
attribute vec2 a_tex_coord;
varying vec2 v_tex_coord;
Vertex shader (priority 200):
v_tex_coord = a_tex_coord;
Fragment shader (priority 200):
gl_FragColor = texture2D(tex0, v_tex_coord.xy, u_lod_bias);
textshader.dissolve
Variables:
uniform float u_textshader_dissolve_duration;
uniform float u_text_slow_duration;
uniform float u_text_slow_time;
attribute float a_text_time;
varying float v_text_time;
Vertex shader (priority 200):
v_text_time = a_text_time;
Fragment shader (priority 350):
float l_textshader_dissolve_duration = u_textshader_dissolve_duration * u_text_slow_duration;
float l_textshader_dissolve_done;
if (l_textshader_dissolve_duration > 0.0) {
l_textshader_dissolve_done = clamp((u_text_slow_time - v_text_time) / l_textshader_dissolve_duration, 0.0, 1.0);
} else {
l_textshader_dissolve_done = v_text_time <= u_text_slow_time ? 1.0 : 0.0;
}
gl_FragColor = gl_FragColor * l_textshader_dissolve_done;
textshader.flip
Variables:
uniform float u_textshader_flip_duration;
uniform float u_text_slow_duration;
uniform float u_text_slow_time;
attribute vec2 a_text_center;
attribute float a_text_min_time;
Vertex shader (priority 20):
float l_textshader_flip_duration = u_textshader_flip_duration * u_text_slow_duration;
float l_textshader_flip_done;
if (l_textshader_flip_duration > 0.0) {
l_textshader_flip_done = clamp((u_text_slow_time - a_text_min_time) / l_textshader_flip_duration, 0.0, 1.0);
} else {
l_textshader_flip_done = a_text_min_time <= u_text_slow_time ? 1.0 : 0.0;
}
gl_Position.x = mix(a_text_center.x - (gl_Position.x - a_text_center.x), gl_Position.x, l_textshader_flip_done);
textshader.jitter
Variables:
uniform vec2 u_textshader_jitter_jitter;
uniform vec4 u_random;
uniform float u_text_to_drawable;
Vertex shader (priority 30):
vec2 l_textshader_jitter_jitter = u_textshader_jitter_jitter * u_text_to_drawable;
gl_Position.xy += l_textshader_jitter_jitter * u_random.xy - l_textshader_jitter_jitter / 2.0;
textshader.linetexture
Variables:
uniform sampler2D u_textshader_linetexture_texture;
uniform vec2 u_textshader_linetexture_scale;
uniform vec2 u_textshader_linetexture_texture_res;
uniform float u_text_to_virtual;
uniform float u_text_main;
attribute vec2 a_text_center;
varying vec2 v_textshader_linetexture_coord;
Vertex shader (priority 10):
v_textshader_linetexture_coord = vec2( gl_Position.x, (gl_Position.y - a_text_center.y)) / u_textshader_linetexture_scale * u_text_to_virtual / u_textshader_linetexture_texture_res;
v_textshader_linetexture_coord.y += 0.5;
Fragment shader (priority 300):
if (u_text_main == 1.0) {
gl_FragColor = texture2D(u_textshader_linetexture_texture, v_textshader_linetexture_coord) * gl_FragColor;
}
textshader.offset
Variables:
uniform vec2 u_textshader_offset_offset;
uniform float u_text_to_drawable;
Vertex shader (priority 35):
gl_Position.xy += u_textshader_offset_offset * u_text_to_drawable;
textshader.slowalpha
Variables:
uniform float u_textshader_slowalpha_alpha
Fragment shader (priority 325):
vec4 l_textshader_slowalpha_color = gl_FragColor;
Fragment shader (priority 375):
gl_FragColor = mix(gl_FragColor, l_textshader_slowalpha_color, u_textshader_slowalpha_alpha);
textshader.texture
Variables:
uniform sampler2D u_textshader_texture_texture;
uniform vec2 u_textshader_texture_texture_res;
uniform float u_text_to_virtual;
uniform float u_text_main;
varying vec2 v_textshader_texture_coord;
Vertex shader (priority 10):
v_textshader_texture_coord = u_text_to_virtual * gl_Position.xy / u_textshader_texture_texture_res;
Fragment shader (priority 300):
if (u_text_main == 1.0) {
gl_FragColor = texture2D(u_textshader_texture_texture, v_textshader_texture_coord) * gl_FragColor;
}
textshader.typewriter
Variables:
uniform float u_text_slow_time;
attribute float a_text_min_time;
varying float v_text_min_time;
Vertex shader (priority 200):
v_text_min_time = a_text_min_time;
Fragment shader (priority 350):
float l_textshader_typewriter_done = v_text_min_time <= u_text_slow_time ? 1.0 : 0.0;
gl_FragColor = gl_FragColor * l_textshader_typewriter_done;
textshader.wave
Variables:
uniform float u_textshader_wave_amplitude;
uniform float u_textshader_wave_frequency
uniform float u_textshader_wave_wavelength;
uniform float u_time;
uniform float u_text_to_drawable;
attribute float a_text_index;
Vertex shader (priority 40):
gl_Position.y += cos(2.0 * 3.14159265359 * (a_text_index / u_textshader_wave_wavelength + u_time * u_textshader_wave_frequency)) * u_textshader_wave_amplitude * u_text_to_drawable;
textshader.zoom
Variables:
uniform float u_textshader_zoom_zoom;
uniform float u_textshader_zoom_duration;
uniform float u_text_slow_duration;
uniform float u_text_slow_time;
attribute vec2 a_text_center;
attribute float a_text_min_time;
Vertex shader (priority 25):
float l_textshader_zoom_duration = u_textshader_zoom_duration * u_text_slow_duration;
if (l_textshader_zoom_duration > 0.0) {
float l_textshader_zoom_done = clamp((u_text_slow_time - a_text_min_time) / l_textshader_zoom_duration, 0.0, 1.0);
gl_Position.xy = mix(a_text_center + (gl_Position.xy - a_text_center) * u_textshader_zoom_zoom, gl_Position.xy, l_textshader_zoom_done);
}