diff --git a/collada_scene.lua b/collada_scene.lua index 2e5ef24..cb9bb12 100644 --- a/collada_scene.lua +++ b/collada_scene.lua @@ -23,6 +23,12 @@ local shader_ssao = love.graphics.newShader(pixel_ssao, vertex_screen) local pixel_clear = love.filesystem.newFileData("pixel_clear.glsl") local shader_clear = love.graphics.newShader(pixel_clear, vertex_screen) +local pixel_blur = love.filesystem.newFileData("pixel_blur.glsl") +local shader_blur = love.graphics.newShader(pixel_blur, vertex_screen) + +local pixel_shade = love.filesystem.newFileData("pixel_shade.glsl") +local shader_shade = love.graphics.newShader(pixel_shade, vertex_screen) + local noise_texture = random_data.generate_noise_texture(4, 4) local ssao_kernel_shaderstorage_buffer = random_data.generate_ssao_kernel(64) @@ -323,10 +329,10 @@ collada_scene = { ---------------------------------------------------------------------- if true then - love.graphics.setCanvas() + love.graphics.setCanvas({g_occlusion_canvas_a, depth=false}) love.graphics.setShader(shader_ssao) shader_ssao:send("projection", "column", perspective_projection.data) - shader_ssao:send("g_color_sampler", g_color_canvas) + --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) @@ -337,9 +343,38 @@ collada_scene = { shader_ssao:send("occlusion_exponent", global_parameters.ssao.occlusion_exponent) shader_ssao:send("occlusion_offset", global_parameters.ssao.occlusion_offset) + shader_ssao:send("bias1", global_parameters.ssao.bias1) + shader_ssao:send("radius1", global_parameters.ssao.radius1) + shader_ssao:send("occlusion_exponent1", global_parameters.ssao.occlusion_exponent1) + shader_ssao:send("occlusion_offset1", global_parameters.ssao.occlusion_offset1) + love.graphics.setDepthMode("always", false) love.graphics.drawFromShader(screen_index_buffer, 3 * 2, 1, 1) end + + if true then + love.graphics.setShader(shader_blur) + for i = 1, 2 do + shader_blur:send("g_occlusion_sampler", g_occlusion_canvas_a) + shader_blur:send("inverse_screen_size", {1.0 / 1024.0, 1.0 / 1024.0}) + shader_blur:send("dir", {1, 0}) + love.graphics.setDepthMode("always", false) + love.graphics.setCanvas({g_occlusion_canvas_b, depth=false}) + love.graphics.drawFromShader(screen_index_buffer, 3 * 2, 1, 1) + + shader_blur:send("g_occlusion_sampler", g_occlusion_canvas_b) + shader_blur:send("dir", {0, 1}) + love.graphics.setCanvas({g_occlusion_canvas_a, depth=false}) + love.graphics.drawFromShader(screen_index_buffer, 3 * 2, 1, 1) + end + end + + shader_shade:send("g_occlusion_sampler", g_occlusion_canvas_a) + shader_shade:send("g_color_sampler", g_color_canvas) + love.graphics.setDepthMode("always", false) + love.graphics.setCanvas() + love.graphics.setShader(shader_shade) + love.graphics.drawFromShader(screen_index_buffer, 3 * 2, 1, 1) end, } diff --git a/global_parameters.lua b/global_parameters.lua index f0ac173..75783de 100644 --- a/global_parameters.lua +++ b/global_parameters.lua @@ -1,9 +1,19 @@ local params = { ssao = { - bias = 0.05, - radius = 0.5, - occlusion_exponent = 1, - occlusion_offset = 0, + -- bias = 7.05, + -- radius = 20.5, + -- occlusion_exponent = 12, + -- occlusion_offset = 0.1, + + bias = 4.85, + radius = 12.7, + occlusion_exponent = 18.3, + occlusion_offset = 0.10, + + bias1 = -1.12, + radius1 = 2.7, + occlusion_exponent1 = 0.56, + occlusion_offset1 = 0.01, } } diff --git a/main.lua b/main.lua index 50b3e79..6c1be5d 100644 --- a/main.lua +++ b/main.lua @@ -81,6 +81,8 @@ function init() g_position_canvas = love.graphics.newCanvas(1024, 1024, {format = "rgba32f"}) g_normal_canvas = love.graphics.newCanvas(1024, 1024, {format = "rgba32f"}) g_color_canvas = love.graphics.newCanvas(1024, 1024, {format = "rgba32f"}) + g_occlusion_canvas_a = love.graphics.newCanvas(1024, 1024, {format = "rg32f"}) + g_occlusion_canvas_b = love.graphics.newCanvas(1024, 1024, {format = "rg32f"}) g_shadow_canvas = love.graphics.newCanvas(2048, 2048, {format = "r32f"}) diff --git a/pixel_blur.glsl b/pixel_blur.glsl new file mode 100644 index 0000000..72794a8 --- /dev/null +++ b/pixel_blur.glsl @@ -0,0 +1,37 @@ +#pragma language glsl3 + +uniform sampler2D g_occlusion_sampler; + +in vec4 PixelTexture; + +out vec2 out_blur; + +//const float offset[3] = float[](0.0, 1.3846153846, 3.2307692308); +//const float weight[3] = float[](0.2270270270, 0.3162162162, 0.0702702703); +const float offset[3] = float[](-1.200436, 0, 1.200436); +const float weight[3] = float[](0.30613, 0.38774, 0.30613); + +uniform vec2 inverse_screen_size; +uniform vec2 dir; + +void pixelmain() +{ + vec2 sample = texture(g_occlusion_sampler, gl_FragCoord.xy * inverse_screen_size).xy; + + float blur = sample.x * weight[1]; + + vec2 a = (gl_FragCoord.xy + (dir * offset[0])) * inverse_screen_size; + vec2 b = (gl_FragCoord.xy - (dir * offset[0])) * inverse_screen_size; + blur += texture(g_occlusion_sampler, a).x * weight[0]; + blur += texture(g_occlusion_sampler, b).x * weight[0]; + /* + for (int i=1; i<1; i++) { + vec2 a = (gl_FragCoord.xy + (dir * offset[i])) * inverse_screen_size; + vec2 b = (gl_FragCoord.xy - (dir * offset[i])) * inverse_screen_size; + blur += texture(g_occlusion_sampler, a).x * weight[i]; + blur += texture(g_occlusion_sampler, b).x * weight[i]; + } + */ + + out_blur = vec2(blur, sample.y); +} diff --git a/pixel_color.glsl b/pixel_color.glsl index 010ddbd..2b891df 100644 --- a/pixel_color.glsl +++ b/pixel_color.glsl @@ -71,8 +71,8 @@ void pixelmain() specular = specular_color; } - //float diffuse_intensity = max(dot(normal, light_direction), 0.0); - float diffuse_intensity = 0.7; + float diffuse_intensity = max(dot(normal, light_direction), 0.0); + //float diffuse_intensity = 0.7; float specular_intensity = pow(max(dot(view_direction, reflect_light_direction), 0.0), shininess); vec3 color = emission.xyz * 0; diff --git a/pixel_shade.glsl b/pixel_shade.glsl new file mode 100644 index 0000000..cf8e677 --- /dev/null +++ b/pixel_shade.glsl @@ -0,0 +1,21 @@ +#pragma language glsl3 + +uniform sampler2D g_occlusion_sampler; +uniform sampler2D g_color_sampler; + +out vec4 out_color; + +void pixelmain() +{ + vec2 occlusion = texelFetch(g_occlusion_sampler, ivec2(gl_FragCoord.xy), 0).xy; + vec3 color = texelFetch(g_color_sampler, ivec2(gl_FragCoord.xy), 0).xyz; + + float f = (1.0 - min(1.0, occlusion.y)); + float f2 = smoothstep(0.0, 0.2, f); + //out_color = vec4(color * f2 * occlusion.x, 1.0); + if (color == vec3(0, 0, 0)) + out_color = vec4(0, 0, 0, 1); + else + out_color = vec4(color * occlusion.x + occlusion.y * occlusion.y, 1.0); + //out_color = vec4(occlusion.y); +} diff --git a/pixel_ssao.glsl b/pixel_ssao.glsl index f25d88b..f475177 100644 --- a/pixel_ssao.glsl +++ b/pixel_ssao.glsl @@ -1,6 +1,6 @@ #pragma language glsl4 -uniform sampler2D g_color_sampler; +//uniform sampler2D g_color_sampler; uniform sampler2D g_position_sampler; uniform sampler2D g_normal_sampler; uniform sampler2D noise_sampler; @@ -10,6 +10,11 @@ uniform vec3 sample_kernel[64]; const vec2 noise_scale = vec2(1024.0 / 4.0, 1024 / 4.0); +uniform float bias1; +uniform float radius1; +uniform float occlusion_exponent1; +uniform float occlusion_offset1; + uniform float bias; uniform float radius; uniform float occlusion_exponent; @@ -19,16 +24,27 @@ const int samples = 64; varying vec4 PixelTexture; -out vec4 out_color; +out vec2 out_occlusion; layout (std430) readonly buffer SSAOKernelLayout { vec4 SSAOKernel[]; }; +float kernel_depth(vec3 position, vec3 sample_position) +{ + vec4 offset = vec4(sample_position, 1.0); + offset = projection * offset; + offset.xyz = offset.xyz / offset.w; + + vec2 sample_depth_coord = offset.xy * vec2(0.5, -0.5) + 0.5; + float sample_depth = texture(g_position_sampler, sample_depth_coord).z; + return sample_depth; +} + void pixelmain() { - vec3 color = texture(g_color_sampler, PixelTexture.xy).xyz; + //vec3 color = texture(g_color_sampler, PixelTexture.xy).xyz; vec3 position = texture(g_position_sampler, PixelTexture.xy).xyz; vec3 normal = normalize(texture(g_normal_sampler, PixelTexture.xy).xyz); vec3 noise = normalize(vec3(texture(noise_sampler, PixelTexture.xy * noise_scale).xy, 0)); @@ -37,24 +53,27 @@ void pixelmain() vec3 bitangent = cross(normal, tangent); mat3 TBN = mat3(tangent, bitangent, normal); + float occlusion1 = 0.0; 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; + vec3 sample_position = (TBN * SSAOKernel[i].xyz) * radius + position; + vec3 sample_position1 = (SSAOKernel[i].xyz) * radius1 + position; - vec4 offset = vec4(sample_position, 1.0); - offset = projection * offset; - offset.xyz = offset.xyz / offset.w; - - 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 sample_depth = kernel_depth(position, sample_position); + float sample_depth1 = kernel_depth(position, sample_position1); 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; + + float range_check1 = smoothstep(0.0, 1.0, radius1 / abs(position.z - sample_depth1)); + occlusion1 += (sample_depth1 >= sample_position1.z + bias1 ? 1.0 : 0.0) * range_check1; } occlusion = 1.0 - (occlusion / samples); occlusion = pow(occlusion, occlusion_exponent) + occlusion_offset; - out_color = vec4(color * occlusion, 1.0); + occlusion1 = 1.0 - (occlusion1 / samples); + occlusion1 = pow(occlusion1, occlusion_exponent1) + occlusion_offset1; + + //out_color = vec4(color * occlusion * occlusion1, 1.0); + out_occlusion = vec2(occlusion, occlusion1); } diff --git a/update_global_parameters.lua b/update_global_parameters.lua index f4ff491..05eebb1 100644 --- a/update_global_parameters.lua +++ b/update_global_parameters.lua @@ -2,37 +2,36 @@ local _font = require 'font' local global_parameters = require "global_parameters" +local parameter_order = { + {"ssao", "bias"}, + {"ssao", "radius"}, + {"ssao", "occlusion_exponent"}, + {"ssao", "occlusion_offset"}, + + {"ssao", "bias1"}, + {"ssao", "radius1"}, + {"ssao", "occlusion_exponent1"}, + {"ssao", "occlusion_offset1"}, +} + 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 + return #parameter_order 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) + local params = parameter_order[current_param_ix + 1] + return params[1], params[2] end local update_parameter = function(f) key, subkey = get_current_param_keys() local value = global_parameters[key][subkey] local new_value = f(value) + print(value, new_value) global_parameters[key][subkey] = new_value end @@ -52,18 +51,17 @@ local draw = function(font) 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 + for param_ix, params in ipairs(parameter_order) do + local prefix = " " + if (param_ix - 1) == current_param_ix then + prefix = "> " end + local key = params[1] + local subkey = params[2] + local value = global_parameters[key][subkey] + local line = prefix .. key .. "." .. subkey .. ": " .. tostring(value) + _font.draw_string(font, line, x, y) + y = y + font.glyph_height end end