Skip to content

Instantly share code, notes, and snippets.

@bil-bas
Created July 15, 2011 11:35
Show Gist options
  • Save bil-bas/1084532 to your computer and use it in GitHub Desktop.
Save bil-bas/1084532 to your computer and use it in GitHub Desktop.
Pixelation shader in Ray
# Pixelation post-processing effect
# based on http://www.geeks3d.com/20101029/shader-library-pixelation-post-processing-effect-glsl/
# Shaders -------------------
PIXEL_SHADER =<<END
uniform sampler2D in_Texture; // Automatically set by Ray.
uniform float rt_w; // Width of window.
uniform float rt_h; // Height of window.
uniform vec4 clip_rect;
uniform float pixel_w; // Width of pixel shown, in regular pixels.
uniform float pixel_h; // Height of pixel shown, in regular pixels.
varying vec2 var_TexCoord; // Pixel to process.
uniform bool pixelation_enabled; // Turn the pixelation effect on or off.
// Returns the pixelated result for this pixel.
vec4 pixelate()
{
float dx = pixel_w * (1.0 / rt_w);
float dy = pixel_h * (1.0 / rt_h);
vec2 coord = vec2(dx * floor(var_TexCoord.x / dx),
dy * floor(var_TexCoord.y / dy));
return texture2D(in_Texture, coord).rgba;
}
void main()
{
// Clip and, optionally, pixelate.
if (gl_FragCoord.x >= clip_rect[0] &&
gl_FragCoord.x <= clip_rect[2] &&
gl_FragCoord.y >= clip_rect[1] &&
gl_FragCoord.y <= clip_rect[3])
{
if (pixelation_enabled)
{
gl_FragColor = pixelate();
}
else
{
gl_FragColor = texture2D(in_Texture, var_TexCoord).rgba;
}
}
}
END
# Code ----------------------------
$:.unshift File.expand_path(File.dirname(__FILE__) + "/../ray/lib")
$:.unshift File.expand_path(File.dirname(__FILE__) + "/../ray/ext")
require 'ray'
def path_of(res)
File.expand_path File.join(File.dirname(__FILE__), '../ray/test/res', res)
end
Ray.game "Pixelization shader (space to enable/disable pixelation effect)" do
register { add_hook :quit, method(:exit!) }
scene :pixelization do
@sprites = []
img = image path_of("sprite.png")
5.times do |x|
3.times do |y|
@sprites << sprite(img, at: [20 + x * img.width, y * img.height])
end
end
window.shader.compile(:frag => StringIO.new(PIXEL_SHADER))
window.shader[:rt_w], window.shader[:rt_h] = *window.size
window.shader[:pixel_w] = 1.0 # Width of meta-pixel in pixels.
window.shader[:pixel_h] = 1.0 # Height of meta-pixel in pixels.
window.shader[:clip_rect] = [100, 100, 540, 480] # Remember, GL y is inverted.
@pixelized = true
window.shader[:pixelation_enabled] = @pixelized
# Animate so that processed pixels grow from 1 to 100 normal pixels and back again.
@animation = block_animation :duration => 5, :block => proc { |target, progression|
target[:pixel_w] = progression
target[:pixel_h] = progression
}
@reverse_animation = -@animation
on :animation_end, @animation do
@reverse_animation.start window.shader
end
on :animation_end, @reverse_animation do
@animation.start window.shader
end
@animation.start window.shader
on :key_press, key(:space) do
@pixelized = (not @pixelized)
window.shader[:pixelation_enabled] = @pixelized
end
always do
if @pixelized
@animation.update
@reverse_animation.update
end
end
render do |win|
@sprites.each {|s| win.draw s }
end
end
scenes << :pixelization
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment