collada_scene: improve ssao implementation
This commit is contained in:
parent
e4ba80ae80
commit
6a57516349
@ -23,6 +23,12 @@ local shader_ssao = love.graphics.newShader(pixel_ssao, vertex_screen)
|
|||||||
local pixel_clear = love.filesystem.newFileData("pixel_clear.glsl")
|
local pixel_clear = love.filesystem.newFileData("pixel_clear.glsl")
|
||||||
local shader_clear = love.graphics.newShader(pixel_clear, vertex_screen)
|
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 noise_texture = random_data.generate_noise_texture(4, 4)
|
||||||
local ssao_kernel_shaderstorage_buffer = random_data.generate_ssao_kernel(64)
|
local ssao_kernel_shaderstorage_buffer = random_data.generate_ssao_kernel(64)
|
||||||
|
|
||||||
@ -323,10 +329,10 @@ collada_scene = {
|
|||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
if true then
|
if true then
|
||||||
love.graphics.setCanvas()
|
love.graphics.setCanvas({g_occlusion_canvas_a, depth=false})
|
||||||
love.graphics.setShader(shader_ssao)
|
love.graphics.setShader(shader_ssao)
|
||||||
shader_ssao:send("projection", "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_color_sampler", g_color_canvas)
|
||||||
shader_ssao:send("g_position_sampler", g_position_canvas)
|
shader_ssao:send("g_position_sampler", g_position_canvas)
|
||||||
shader_ssao:send("g_normal_sampler", g_normal_canvas)
|
shader_ssao:send("g_normal_sampler", g_normal_canvas)
|
||||||
shader_ssao:send("noise_sampler", noise_texture)
|
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_exponent", global_parameters.ssao.occlusion_exponent)
|
||||||
shader_ssao:send("occlusion_offset", global_parameters.ssao.occlusion_offset)
|
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.setDepthMode("always", false)
|
||||||
love.graphics.drawFromShader(screen_index_buffer, 3 * 2, 1, 1)
|
love.graphics.drawFromShader(screen_index_buffer, 3 * 2, 1, 1)
|
||||||
end
|
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,
|
end,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -1,9 +1,19 @@
|
|||||||
local params = {
|
local params = {
|
||||||
ssao = {
|
ssao = {
|
||||||
bias = 0.05,
|
-- bias = 7.05,
|
||||||
radius = 0.5,
|
-- radius = 20.5,
|
||||||
occlusion_exponent = 1,
|
-- occlusion_exponent = 12,
|
||||||
occlusion_offset = 0,
|
-- 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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
2
main.lua
2
main.lua
@ -81,6 +81,8 @@ function init()
|
|||||||
g_position_canvas = love.graphics.newCanvas(1024, 1024, {format = "rgba32f"})
|
g_position_canvas = love.graphics.newCanvas(1024, 1024, {format = "rgba32f"})
|
||||||
g_normal_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_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"})
|
g_shadow_canvas = love.graphics.newCanvas(2048, 2048, {format = "r32f"})
|
||||||
|
|
||||||
|
|||||||
37
pixel_blur.glsl
Normal file
37
pixel_blur.glsl
Normal file
@ -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);
|
||||||
|
}
|
||||||
@ -71,8 +71,8 @@ void pixelmain()
|
|||||||
specular = specular_color;
|
specular = specular_color;
|
||||||
}
|
}
|
||||||
|
|
||||||
//float diffuse_intensity = max(dot(normal, light_direction), 0.0);
|
float diffuse_intensity = max(dot(normal, light_direction), 0.0);
|
||||||
float diffuse_intensity = 0.7;
|
//float diffuse_intensity = 0.7;
|
||||||
float specular_intensity = pow(max(dot(view_direction, reflect_light_direction), 0.0), shininess);
|
float specular_intensity = pow(max(dot(view_direction, reflect_light_direction), 0.0), shininess);
|
||||||
|
|
||||||
vec3 color = emission.xyz * 0;
|
vec3 color = emission.xyz * 0;
|
||||||
|
|||||||
21
pixel_shade.glsl
Normal file
21
pixel_shade.glsl
Normal file
@ -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);
|
||||||
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
#pragma language glsl4
|
#pragma language glsl4
|
||||||
|
|
||||||
uniform sampler2D g_color_sampler;
|
//uniform sampler2D g_color_sampler;
|
||||||
uniform sampler2D g_position_sampler;
|
uniform sampler2D g_position_sampler;
|
||||||
uniform sampler2D g_normal_sampler;
|
uniform sampler2D g_normal_sampler;
|
||||||
uniform sampler2D noise_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);
|
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 bias;
|
||||||
uniform float radius;
|
uniform float radius;
|
||||||
uniform float occlusion_exponent;
|
uniform float occlusion_exponent;
|
||||||
@ -19,16 +24,27 @@ const int samples = 64;
|
|||||||
|
|
||||||
varying vec4 PixelTexture;
|
varying vec4 PixelTexture;
|
||||||
|
|
||||||
out vec4 out_color;
|
out vec2 out_occlusion;
|
||||||
|
|
||||||
layout (std430) readonly buffer SSAOKernelLayout
|
layout (std430) readonly buffer SSAOKernelLayout
|
||||||
{
|
{
|
||||||
vec4 SSAOKernel[];
|
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()
|
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 position = texture(g_position_sampler, PixelTexture.xy).xyz;
|
||||||
vec3 normal = normalize(texture(g_normal_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));
|
vec3 noise = normalize(vec3(texture(noise_sampler, PixelTexture.xy * noise_scale).xy, 0));
|
||||||
@ -37,24 +53,27 @@ void pixelmain()
|
|||||||
vec3 bitangent = cross(normal, tangent);
|
vec3 bitangent = cross(normal, tangent);
|
||||||
mat3 TBN = mat3(tangent, bitangent, normal);
|
mat3 TBN = mat3(tangent, bitangent, normal);
|
||||||
|
|
||||||
|
float occlusion1 = 0.0;
|
||||||
float occlusion = 0.0;
|
float occlusion = 0.0;
|
||||||
for (int i = 0; i < samples; i++) {
|
for (int i = 0; i < samples; i++) {
|
||||||
vec3 sample_position = TBN * SSAOKernel[i].xyz;
|
vec3 sample_position = (TBN * SSAOKernel[i].xyz) * radius + position;
|
||||||
//vec3 sample_position = SSAOKernel[i].xyz;
|
vec3 sample_position1 = (SSAOKernel[i].xyz) * radius1 + position;
|
||||||
sample_position = sample_position * radius + position;
|
|
||||||
|
|
||||||
vec4 offset = vec4(sample_position, 1.0);
|
float sample_depth = kernel_depth(position, sample_position);
|
||||||
offset = projection * offset;
|
float sample_depth1 = kernel_depth(position, sample_position1);
|
||||||
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 range_check = smoothstep(0.0, 1.0, radius / abs(position.z - sample_depth));
|
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 += (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 = 1.0 - (occlusion / samples);
|
||||||
occlusion = pow(occlusion, occlusion_exponent) + occlusion_offset;
|
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);
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,37 +2,36 @@ local _font = require 'font'
|
|||||||
|
|
||||||
local global_parameters = require "global_parameters"
|
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 current_param_ix = 0
|
||||||
|
|
||||||
local get_max_param_ix = function()
|
local get_max_param_ix = function()
|
||||||
local param_ix = 0
|
return #parameter_order
|
||||||
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
|
end
|
||||||
|
|
||||||
local max_param_ix = get_max_param_ix()
|
local max_param_ix = get_max_param_ix()
|
||||||
|
|
||||||
local get_current_param_keys = function()
|
local get_current_param_keys = function()
|
||||||
local param_ix = 0
|
local params = parameter_order[current_param_ix + 1]
|
||||||
for key, values in pairs(global_parameters) do
|
return params[1], params[2]
|
||||||
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
|
end
|
||||||
|
|
||||||
local update_parameter = function(f)
|
local update_parameter = function(f)
|
||||||
key, subkey = get_current_param_keys()
|
key, subkey = get_current_param_keys()
|
||||||
local value = global_parameters[key][subkey]
|
local value = global_parameters[key][subkey]
|
||||||
local new_value = f(value)
|
local new_value = f(value)
|
||||||
|
print(value, new_value)
|
||||||
global_parameters[key][subkey] = new_value
|
global_parameters[key][subkey] = new_value
|
||||||
end
|
end
|
||||||
|
|
||||||
@ -52,18 +51,17 @@ local draw = function(font)
|
|||||||
local x = init_x
|
local x = init_x
|
||||||
local y = 10
|
local y = 10
|
||||||
|
|
||||||
local param_ix = 0
|
for param_ix, params in ipairs(parameter_order) do
|
||||||
for key, values in pairs(global_parameters) do
|
local prefix = " "
|
||||||
for subkey, value in pairs(values) do
|
if (param_ix - 1) == current_param_ix then
|
||||||
local prefix = " "
|
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
|
||||||
|
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
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user