diff --git a/collada_scene.lua b/collada_scene.lua index 3fac2f6..2e5ef24 100644 --- a/collada_scene.lua +++ b/collada_scene.lua @@ -26,6 +26,8 @@ local shader_clear = love.graphics.newShader(pixel_clear, vertex_screen) local noise_texture = random_data.generate_noise_texture(4, 4) local ssao_kernel_shaderstorage_buffer = random_data.generate_ssao_kernel(64) +local global_parameters = require "global_parameters" + local shader_set = { shadow = { static = shader_shadow_static, @@ -323,12 +325,18 @@ collada_scene = { if true then love.graphics.setCanvas() love.graphics.setShader(shader_ssao) - shader_ssao:send("projection2", "column", perspective_projection.data) + shader_ssao:send("projection", "column", perspective_projection.data) shader_ssao:send("g_color_sampler", g_color_canvas) shader_ssao:send("g_position_sampler", g_position_canvas) shader_ssao:send("g_normal_sampler", g_normal_canvas) shader_ssao:send("noise_sampler", noise_texture) shader_ssao:send("SSAOKernelLayout", ssao_kernel_shaderstorage_buffer) + + shader_ssao:send("bias", global_parameters.ssao.bias) + shader_ssao:send("radius", global_parameters.ssao.radius) + shader_ssao:send("occlusion_exponent", global_parameters.ssao.occlusion_exponent) + shader_ssao:send("occlusion_offset", global_parameters.ssao.occlusion_offset) + love.graphics.setDepthMode("always", false) love.graphics.drawFromShader(screen_index_buffer, 3 * 2, 1, 1) end diff --git a/global_parameters.lua b/global_parameters.lua new file mode 100644 index 0000000..f0ac173 --- /dev/null +++ b/global_parameters.lua @@ -0,0 +1,10 @@ +local params = { + ssao = { + bias = 0.05, + radius = 0.5, + occlusion_exponent = 1, + occlusion_offset = 0, + } +} + +return params diff --git a/main.lua b/main.lua index ee6f79d..50b3e79 100644 --- a/main.lua +++ b/main.lua @@ -19,6 +19,8 @@ local scene_shadow_test = require 'scene.shadow_test.shadow_test' local font = require 'font' local terminus_font +local update_global_parameters = require "update_global_parameters" + local scenes = { sci_fi_ship = { descriptor = scene_sci_fi_ship.descriptor, @@ -62,7 +64,7 @@ local load_screen_shader = function() screen_shader = love.graphics.newShader(pixel_data, vertex_data) end -function love.load(args) +function init() love.window.setMode(1024, 1024, {depth=true, resizable=false}) local scene = scenes.sci_fi_ship @@ -90,12 +92,16 @@ end local rotation = 0.0 local t = 0.0 -function love.draw() - local radius = 100 - local mx, my = love.mouse.getPosition() +local update = function(dt) + collada_scene_animate.update(t, node_state) + t = t + 0.016 * 0.1 + + rotation = rotation + 0.01 +end + +local draw = function() width, height = love.graphics.getDimensions() - local aspect_ratio = width / height local perspective_projection = mat4.perspective_fov_rh(scalar.convert_to_radians(45 * 0.5), aspect_ratio, @@ -106,33 +112,59 @@ function love.draw() local orthographic_projection = mat4.orthographic_rh(300, 300, 200, 400.0) - local world1 = mat4.rotation_z(rotation) - local world2 = mat4.rotation_z(rotation * 0.5) - --local world3 = mat4.translation(0, 0, -0.5) - rotation = rotation + 0.01 - - collada_scene_animate.update(t, node_state) - t = t + 0.016 * 0.1 - love.graphics.setBlendMode("replace", "premultiplied") collada_scene.draw_scene(node_state, perspective_projection, orthographic_projection) - -- love.graphics.setCanvas({ - -- g_color_canvas, - -- g_position_canvas, - -- g_normal_canvas, - -- depth = true - -- }) - -- love.graphics.clear( - -- {0.0, 0.0, 0.0, 1.0}, - -- {0.0, 0.0, 0.0, 1.0}, - -- {0.0, 0.0, 0.0, 1.0}) - -- collada_scene.draw_nodes(node_state, transform) - - -- love.graphics.setCanvas() - -- love.graphics.setShader(screen_shader) - -- screen_shader:send("g_sampler", g_shadow_canvas) - -- love.graphics.drawFromShader(screen_index_buffer, 3 * 2, 1, 1) - - font.draw_string(terminus_font, "asdf test 1234", 10, 10) + update_global_parameters.draw(terminus_font) +end + +local keypressed = function(key, scancode, isrepeat) + --print(key, scancode, isrepeat) + if key == "q" then + update_global_parameters.update_parameter(function(v) return v - 0.01 end) + elseif key == "w" then + update_global_parameters.update_parameter(function(v) return v + 0.01 end) + elseif key == "a" then + update_global_parameters.update_parameter(function(v) return v - 0.1 end) + elseif key == "s" then + update_global_parameters.update_parameter(function(v) return v + 0.1 end) + elseif key == "z" then + update_global_parameters.update_parameter(function(v) return v - 1.0 end) + elseif key == "x" then + update_global_parameters.update_parameter(function(v) return v + 1.0 end) + elseif key == "up" then + update_global_parameters.update_current_ix(function(v) return v - 1 end) + elseif key == "down" then + update_global_parameters.update_current_ix(function(v) return v + 1 end) + else + print(key) + end +end + +function love.run() + init() + + love.timer.step() + + return function() + love.event.pump() + for name, a,b,c,d,e,f,g,h in love.event.poll() do + --print(name) + if name == "quit" then + if c or not love.quit or not love.quit() then + return a or 0, b + end + end + if name == "keypressed" then + keypressed(a, b, c) + end + --love.handlers[name](a,b,c,d,e,f,g,h) + end + + local dt = love.timer.step() + update(dt) + draw() + love.graphics.present() + love.timer.sleep(0.001) + end end diff --git a/pixel_font.glsl b/pixel_font.glsl index 27acd84..f4f2df1 100644 --- a/pixel_font.glsl +++ b/pixel_font.glsl @@ -15,5 +15,4 @@ void pixelmain() float px = sample.x == 0.0 ? 0.0 : 1.0; g_color = vec4(vec3(px), 1.0); - //g_color = vec4(1, 0, 0, 1.0); } diff --git a/pixel_ssao.glsl b/pixel_ssao.glsl index a1e9fb2..f25d88b 100644 --- a/pixel_ssao.glsl +++ b/pixel_ssao.glsl @@ -5,13 +5,16 @@ uniform sampler2D g_position_sampler; uniform sampler2D g_normal_sampler; uniform sampler2D noise_sampler; -uniform mat4 projection2; +uniform mat4 projection; uniform vec3 sample_kernel[64]; const vec2 noise_scale = vec2(1024.0 / 4.0, 1024 / 4.0); -const float bias = 0.05; -const float radius = 0.5; +uniform float bias; +uniform float radius; +uniform float occlusion_exponent; +uniform float occlusion_offset; + const int samples = 64; varying vec4 PixelTexture; @@ -37,28 +40,21 @@ void pixelmain() float occlusion = 0.0; for (int i = 0; i < samples; i++) { vec3 sample_position = TBN * SSAOKernel[i].xyz; + //vec3 sample_position = SSAOKernel[i].xyz; sample_position = sample_position * radius + position; vec4 offset = vec4(sample_position, 1.0); - offset = projection2 * offset; + offset = projection * offset; offset.xyz = offset.xyz / offset.w; - offset.xyz = offset.xyz * vec3(0.5, -0.5, 0.5) + 0.5; - float sample_depth = texture(g_position_sampler, offset.xy).z; + vec2 sample_depth_coord = offset.xy * vec2(0.5, -0.5) + 0.5; + float sample_depth = texture(g_position_sampler, sample_depth_coord).z; float range_check = smoothstep(0.0, 1.0, radius / abs(position.z - sample_depth)); occlusion += (sample_depth >= sample_position.z + bias ? 1.0 : 0.0) * range_check; } occlusion = 1.0 - (occlusion / samples); + occlusion = pow(occlusion, occlusion_exponent) + occlusion_offset; - out_color = vec4(color * vec3(pow(occlusion, 20) + 0.75), 1.0); - - //out_color = vec4(vec3(-position.z * 0.0001), 1.0); - - //out_color = vec4(vec3(-position.z * 0.0001), 1.0); - //vec4 foo = projection2 * vec4(position, 1.0); - //foo.xyz = foo.xyz / foo.w; - //out_color = vec4(foo.xy * 0.5 + 0.5, 0.0, 1.0); - //out_color = vec4(normal, 1); - //out_color = vec4(SSAOKernel[].xyz * 8, 1.0); + out_color = vec4(color * occlusion, 1.0); } diff --git a/update_global_parameters.lua b/update_global_parameters.lua new file mode 100644 index 0000000..f4ff491 --- /dev/null +++ b/update_global_parameters.lua @@ -0,0 +1,74 @@ +local _font = require 'font' + +local global_parameters = require "global_parameters" + +local current_param_ix = 0 + +local get_max_param_ix = function() + local param_ix = 0 + for key, values in pairs(global_parameters) do + for subkey, _ in pairs(values) do + param_ix = param_ix + 1 + end + end + return param_ix +end + +local max_param_ix = get_max_param_ix() + +local get_current_param_keys = function() + local param_ix = 0 + for key, values in pairs(global_parameters) do + for subkey, _ in pairs(values) do + if param_ix == current_param_ix then + return key, subkey + end + param_ix = param_ix + 1 + end + end + assert(false) +end + +local update_parameter = function(f) + key, subkey = get_current_param_keys() + local value = global_parameters[key][subkey] + local new_value = f(value) + global_parameters[key][subkey] = new_value +end + +local update_current_ix = function(f) + local ix = f(current_param_ix) + if ix < 0 then + ix = max_param_ix - 1 + end + if ix >= max_param_ix then + ix = 0 + end + current_param_ix = ix +end + +local draw = function(font) + local init_x = 10 + local x = init_x + local y = 10 + + local param_ix = 0 + for key, values in pairs(global_parameters) do + for subkey, value in pairs(values) do + local prefix = " " + if param_ix == current_param_ix then + prefix = "> " + end + local line = prefix .. key .. "." .. subkey .. ": " .. tostring(value) + _font.draw_string(font, line, x, y) + y = y + font.glyph_height + param_ix = param_ix + 1 + end + end +end + +return { + update_parameter = update_parameter, + update_current_ix = update_current_ix, + draw = draw, +}