class PostRenderer
def self.initialize
@@copy = Native::Effect.new()
@@copy.load_from_file("resources/shaders/copy.shader")
end
def self.initialize_for(buffer)
layout = Native::VertexLayout.new()
layout << {:size => 2, :type => Float, :stride => 16, :offset => 0}
layout << {:size => 2, :type => Float, :stride => 16, :offset => 8}
display_quad = Native::VertexBufferObject.new(layout)
display_quad.primitive = Native::TriangleStrip
display_quad << [ -1.0, -1.0, 0.0, 0.0 ]
display_quad << [ 1.0, -1.0, 1.0, 0.0 ]
display_quad << [ -1.0, 1.0, 0.0, 1.0 ]
display_quad << [ 1.0, 1.0, 1.0, 1.0 ]
@@display_quads = {} if !defined?(@@display_quads)
@@display_quads[buffer] = display_quad
return display_quad
end
def self.initialize_shaders(window_size, supersample, downsample, tonemap, luminance, ambient_blur)
@@supersample = supersample
@@downsample = downsample
@@tonemap = tonemap
@@luminance = luminance
@@ambient_blur = ambient_blur
@@tonemap.set_parameter("exposure", 0.45)
@@tonemap.set_parameter("exposureBias", 2.0)
@@tonemap.set_parameter("luminanceBias", 1.0)
@@ambient_blur.set_parameter("blurStrength", 5.0)
@@tonemapping_buffer = SFML::RenderTexture.new(window_size.x, window_size.y, false)
setup_texture(@@tonemapping_buffer)
@@luminance_buffer = SFML::RenderTexture.new(window_size.x, window_size.y, false)
setup_texture(@@luminance_buffer)
@@blur_buffer = SFML::RenderTexture.new(window_size.x, window_size.y, false)
setup_texture(@@blur_buffer)
@@downsample_buffers = [
SFML::RenderTexture.new(1, 1, false),
SFML::RenderTexture.new(4, 4, false),
SFML::RenderTexture.new(16, 16, false),
SFML::RenderTexture.new(64, 64, false),
SFML::RenderTexture.new(256, 256, false),
SFML::RenderTexture.new(1024, 1024, false)
]
setup_texture(@@downsample_buffers[0])
setup_texture(@@downsample_buffers[1])
setup_texture(@@downsample_buffers[2])
setup_texture(@@downsample_buffers[3])
setup_texture(@@downsample_buffers[4])
setup_texture(@@downsample_buffers[5])
end
def self.setup_texture(texture)
texture.active = true
Native.make_hdr_texture(texture.texture)
test = SFML::RectangleShape.new()
texture.draw(test)
initialize_for(texture)
end
def self.get_quad_for(buffer)
if defined?(@@display_quads) && @@display_quads.has_key?(buffer)
return @@display_quads[buffer]
else
return self.initialize_for(buffer)
end
end
def self.exposure=(val)
@@tonemap.set_parameter("exposure", val.to_f)
end
def self.exposure_bias=(val)
@@tonemap.set_parameter("exposureBias", val.to_f)
end
def self.luminance=(val)
@@tonemap.set_parameter("luminanceBias", val.to_f)
end
def self.copy(target, source)
@@copy.set_parameter("sourceSampler", source)
self.render(@@copy, target)
target.display()
end
def self.supersample(target, source)
@@supersample.set_parameter("sourceSampler", source)
@@supersample.set_parameter("sourceTextureSize", source.size)
self.render(@@supersample, target)
end
def self.tonemap(target)
@@tonemapping_buffer.active = true
self.copy(@@tonemapping_buffer, target.texture)
@@luminance_buffer.active = true
self.calc_luminance(@@luminance_buffer, target.texture)
luminance_texture = self.downsample_to(1, @@luminance_buffer.texture)
target.active = true
@@tonemap.set_parameter("luminanceSampler", luminance_texture)
@@tonemap.set_parameter("sourceSampler", @@tonemapping_buffer.texture)
self.render(@@tonemap, target)
target.display()
end
def self.calc_luminance(target, source)
@@luminance.set_parameter("sourceSampler", source)
self.render(@@luminance, target)
target.display
end
def self.downsample_to(target_size, source)
start_index = @@downsample_buffers.size - 1
while start_index > 0 && @@downsample_buffers[start_index].size.x > source.size.x
start_index -= 1
end
downsample(@@downsample_buffers[start_index], source)
end_index = start_index
(start_index-1).downto(0).each do |index|
source = @@downsample_buffers[index+1]
target = @@downsample_buffers[index]
break if target.size.x < target_size
downsample(target, source.texture)
end_index = index
end
@@downsample_buffers[end_index].texture
end
def self.downsample(target, source)
target.active = true
@@downsample.set_parameter("sourceSampler", source)
@@downsample.set_parameter("sourceTextureSize", source.size)
self.render(@@downsample, target)
target.display()
end
def self.blur_ambient(target)
@@blur_buffer.active = true
@@ambient_blur.set_parameter("sourceSampler", target.texture)
@@ambient_blur.set_parameter("sourceTextureSize", target.size)
@@ambient_blur.set_parameter("blurDirection", SFML::Vector2.new(1.0, 0.0))
self.render(@@ambient_blur, @@blur_buffer)
@@blur_buffer.display
target.active = true
@@ambient_blur.set_parameter("sourceSampler", @@blur_buffer.texture)
@@ambient_blur.set_parameter("blurDirection", SFML::Vector2.new(0.0, 1.0))
self.render(@@ambient_blur, target)
end
def self.render(effect, target)
quad = get_quad_for(target)
quad.effect = effect
target.draw(quad)
end
end