Compare commits

..

5 Commits

26 changed files with 3113 additions and 2609 deletions

881
_math.lua

File diff suppressed because it is too large Load Diff

View File

@ -5,6 +5,7 @@ local vec4 = _math.vec4
local scalar = _math.scalar
local collada_types = require 'collada_types'
local random_data = require 'random_data'
local pixel_color_data = love.filesystem.newFileData("pixel_color.glsl")
local pixel_shadow_data = love.filesystem.newFileData("pixel_shadow.glsl")
@ -15,6 +16,24 @@ local shader_color_skinned = love.graphics.newShader(pixel_color_data, vertex_sk
local shader_shadow_static = love.graphics.newShader(pixel_shadow_data, vertex_static_data)
local shader_shadow_skinned = love.graphics.newShader(pixel_shadow_data, vertex_skinned_data)
local vertex_screen = love.filesystem.newFileData("vertex_screen.glsl")
local pixel_ssao = love.filesystem.newFileData("pixel_ssao.glsl")
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)
local global_parameters = require "global_parameters"
local shader_set = {
shadow = {
static = shader_shadow_static,
@ -192,9 +211,9 @@ collada_scene = {
end
--shader:send("Joints", "column",
--joints[1].data,
--joints[2].data,
--joints[3].data)
--joints[1]:data(),
--joints[2]:data(),
--joints[3]:data())
current_shader:send("Joints", "column",
mat4.store_table(joints[1]),
mat4.store_table(joints[2]),
@ -205,7 +224,7 @@ collada_scene = {
end
end,
draw_node = function(node_state, transform, light_transform, node, node_instance)
draw_node = function(node_state, projection, view, light_transform, node, node_instance)
if node.type ~= collada_types.node_type.NODE then
return
end
@ -215,33 +234,36 @@ collada_scene = {
end
local world = node_instance.world
transform = world * transform
view_transform = world * view
transform = view_transform * projection
light_transform = world * light_transform
if node.instance_geometries_count > 0 then
current_shader = current_shader_set.static
love.graphics.setShader(current_shader)
current_shader:send("world_transform", "column", world.data)
current_shader:send("light_transform", "column", light_transform.data)
current_shader:send("transform", "column", transform.data)
--current_shader:send("projection", "column", projection:data())
current_shader:send("view_transform", "column", view_transform:data())
current_shader:send("world_transform", "column", world:data())
current_shader:send("light_transform", "column", light_transform:data())
current_shader:send("transform", "column", transform:data())
collada_scene.draw_instance_geometries(node.instance_geometries)
end
if node.instance_controllers_count > 0 then
current_shader = current_shader_set.skinned
love.graphics.setShader(current_shader)
current_shader:send("world_transform", "column", world.data)
current_shader:send("light_transform", "column", light_transform.data)
current_shader:send("transform", "column", transform.data)
current_shader:send("world_transform", "column", world:data())
current_shader:send("light_transform", "column", light_transform:data())
current_shader:send("transform", "column", transform:data())
collada_scene.draw_instance_controllers(node_state, node.instance_controllers)
end
end,
draw_nodes = function(node_state, transform, light_transform)
draw_nodes = function(node_state, projection, view, light_transform)
local node_index = 0
for _, node in ipairs(node_state.nodes) do
local node_instance = node_state.node_instances[node_index]
collada_scene.draw_node(node_state, transform, light_transform, node, node_instance)
collada_scene.draw_node(node_state, projection, view, light_transform, node, node_instance)
node_index = node_index + 1
end
end,
@ -268,29 +290,91 @@ collada_scene = {
-- shadow
----------------------------------------------------------------------
love.graphics.setCanvas({g_shadow_canvas, depth=true})
love.graphics.clear({0.0, 0.0, 0.0, 1.0})
current_shader_set = shader_set.shadow
send_material = false
collada_scene.draw_nodes(node_state, light_transform, light_transform)
if false then
love.graphics.setCanvas({g_shadow_canvas, depth=true})
love.graphics.clear({0.0, 0.0, 0.0, 1.0})
current_shader_set = shader_set.shadow
send_material = false
love.graphics.setDepthMode("less", true)
collada_scene.draw_nodes(node_state, light_transform, light_transform)
end
----------------------------------------------------------------------
-- color
----------------------------------------------------------------------
shader_color_static:send("view_position", view_position.data)
shader_color_static:send("light_position", light_position.data)
shader_color_static:send("shadow_sampler", g_shadow_canvas)
shader_color_static:send("view_position", view_position:data())
shader_color_static:send("light_position", light_position:data())
--shader_color_static:send("shadow_sampler", g_shadow_canvas)
shader_color_skinned:send("view_position", view_position.data)
shader_color_skinned:send("light_position", light_position.data)
shader_color_skinned:send("shadow_sampler", g_shadow_canvas)
shader_color_skinned:send("view_position", view_position:data())
shader_color_skinned:send("light_position", light_position:data())
--shader_color_skinned:send("shadow_sampler", g_shadow_canvas)
love.graphics.setCanvas({g_color_canvas, g_position_canvas, g_normal_canvas, depth=true})
--love.graphics.setCanvas()
--love.graphics.clear({0.0, 0.0, 0.0, 1.0})
--love.graphics.clear({0, 0, 0, 1.0}, {0, 0, 0, 1.0}, {0, 0, 0, 1.0}, 255, 0)
love.graphics.setDepthMode("always", true)
love.graphics.setShader(shader_clear)
love.graphics.drawFromShader(screen_index_buffer, 3 * 2, 1, 1)
love.graphics.setCanvas()
love.graphics.clear({0.0, 0.0, 0.0, 1.0})
current_shader_set = shader_set.color
send_material = true
collada_scene.draw_nodes(node_state, transform, light_transform)
love.graphics.setDepthMode("greater", true)
collada_scene.draw_nodes(node_state, perspective_projection, view, light_transform)
----------------------------------------------------------------------
-- ssao
----------------------------------------------------------------------
if true then
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_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)
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,
}

View File

@ -30,11 +30,11 @@ local transform_matrix = function (loaded_transform)
elseif type == collada_types.transform_type.MATRIX then
return value
elseif type == collada_types.transform_type.ROTATE then
if value.f[0] == 0 and value.f[1] == 0 and value.f[2] == 0 then
if value.x == 0 and value.y == 0 and value.z == 0 then
-- WUT?
return mat4.identity()
end
return mat4.rotation_axis(value, scalar.convert_to_radians(value.f[3]))
return mat4.rotation_axis(value, scalar.convert_to_radians(value.w))
elseif type == collada_types.transform_type.SCALE then
return mat4.scaling_from_vector(value)
elseif type == collada_types.transform_type.TRANSLATE then

95
font.lua Normal file
View File

@ -0,0 +1,95 @@
local _math = require "_math"
local mat4 = _math.mat4
local pixel_font_data = love.filesystem.newFileData("pixel_font.glsl")
local vertex_font_data = love.filesystem.newFileData("vertex_font.glsl")
local shader_font = love.graphics.newShader(pixel_font_data, vertex_font_data)
local fonts = {
ter_6x12 = {
path = "font/terminus_128x64_6x12.data",
texture_width = 128,
texture_height = 64,
glyph_width = 6,
glyph_height = 12,
},
ter_8x16 = {
path = "font/terminus_128x128_8x16.data",
texture_width = 128,
texture_height = 128,
glyph_width = 8,
glyph_height = 16,
},
ter_10x18 = {
path = "font/terminus_256x128_10x18.data",
texture_width = 256,
texture_height = 128,
glyph_width = 10,
glyph_height = 18,
},
ter_12x24 = {
path = "font/terminus_256x128_12x24.data",
texture_width = 256,
texture_height = 128,
glyph_width = 12,
glyph_height = 24,
}
}
local load_font = function(desc)
local file_data = love.filesystem.newFileData(desc.path)
local image_data = love.image.newImageData(desc.texture_width, desc.texture_height, "r8", file_data)
local texture = love.graphics.newTexture(image_data)
texture:setFilter("nearest", "nearest")
local font = {
texture = texture,
texture_width = desc.texture_width,
texture_height = desc.texture_height,
glyph_width = desc.glyph_width,
glyph_height = desc.glyph_height,
stride = math.floor(desc.texture_width / desc.glyph_width),
}
return font
end
local glyph_coordinate = function(font, ord)
local c = ord - 32
local x = c % font.stride
local y = math.floor(c / font.stride)
return {x, y}
end
local glyph_transform = function(font, x, y)
local transform = (
mat4.scaling(font.glyph_width, font.glyph_height, 0)
* mat4.translation(x, -y, 0)
* mat4.scaling(2 / 1024, 2 / 1024, 0)
* mat4.translation(-1, 1, 0)
)
return transform
end
local draw_string = function(font, s, x, y)
love.graphics.setCanvas()
love.graphics.setShader(shader_font)
shader_font:send("texture_sampler", font.texture)
love.graphics.setDepthMode("always", false)
shader_font:send("cell", {font.glyph_width / font.texture_width, font.glyph_height / font.texture_height})
for i = 1, #s do
local c = s:byte(i)
if c ~= 32 then
shader_font:send("transform", "column", glyph_transform(font, x, y):data())
shader_font:send("glyph", glyph_coordinate(font, c))
love.graphics.drawFromShader(screen_index_buffer, 3 * 2, 1, 1)
end
x = x + font.glyph_width
end
end
return {
fonts = fonts,
load_font = load_font,
draw_string = draw_string,
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

20
global_parameters.lua Normal file
View File

@ -0,0 +1,20 @@
local params = {
ssao = {
-- 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,
}
}
return params

119
main.lua
View File

@ -16,6 +16,11 @@ local scene_noodle = require 'scene.noodle.noodle'
local scene_sci_fi_ship = require 'scene.sci_fi_ship.sci_fi_ship'
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,
@ -35,7 +40,7 @@ local scenes = {
local node_state
local screen_index_buffer
--local screen_index_buffer
local screen_shader
local load_screen_index_buffer = function()
@ -59,10 +64,10 @@ 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.shadow_test
local scene = scenes.sci_fi_ship
collada_scene.load_buffers(scene.idx_path, scene.vtx_path, scene.vjw_path)
collada_scene.load_images(scene.image_path, scene.descriptor.images)
node_state = collada_scene_node_state(scene.descriptor.nodes)
@ -76,55 +81,93 @@ function love.load(args)
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"})
load_screen_shader()
terminus_font = font.load_font(font.fonts.ter_10x18)
end
local rotation = 0.0
local t = 0.0
function love.draw()
local radius = 100
local mx, my = love.mouse.getPosition()
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,
0.1,
10000.0)
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
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,
1,
0.1)
--0.1,
--10000.0)
local orthographic_projection = mat4.orthographic_rh(300, 300, 200, 400.0)
love.graphics.setBlendMode("replace", "premultiplied")
love.graphics.setDepthMode("less", true)
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)
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

37
pixel_blur.glsl Normal file
View 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);
}

10
pixel_clear.glsl Normal file
View File

@ -0,0 +1,10 @@
layout (location = 0) out vec4 g_color;
layout (location = 1) out vec4 g_position;
layout (location = 2) out vec4 g_normal;
void pixelmain()
{
g_color = vec4(0.0, 0.0, 0.0, 1.0);
g_position = vec4(0.0, 0.0, 0.0, 1.0);
g_normal = vec4(0.0, 0.0, 0.0, 1.0);
}

View File

@ -2,6 +2,7 @@
varying vec4 PixelNormal;
varying vec4 PixelTexture;
varying vec4 PixelViewPosition;
varying vec4 PixelWorldPosition;
varying vec4 PixelLightPosition;
@ -71,6 +72,7 @@ void pixelmain()
}
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;
@ -78,11 +80,9 @@ void pixelmain()
color += diffuse.xyz * diffuse_intensity;
color += specular.xyz * specular_intensity * 0.3;
color *= Shadow(normal, light_direction);
//color *= Shadow(normal, light_direction);
g_color = vec4(color, 1.0);
//float s = Shadow();
//g_color = vec4(s, s, s, 1.0);
g_position = vec4(PixelWorldPosition.xyz, 1.0);
g_position = PixelViewPosition;
g_normal = vec4(normal, 0.0);
}

18
pixel_font.glsl Normal file
View File

@ -0,0 +1,18 @@
#pragma language glsl3
layout (location = 0) out vec4 g_color;
uniform sampler2D texture_sampler;
in vec4 PixelTexture;
uniform vec2 cell;
uniform vec2 glyph;
void pixelmain()
{
vec4 sample = texture(texture_sampler, PixelTexture.xy * cell + cell * glyph);
float px = sample.x == 0.0 ? 0.0 : 1.0;
g_color = vec4(vec3(px), 1.0);
}

21
pixel_shade.glsl Normal file
View 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);
}

79
pixel_ssao.glsl Normal file
View File

@ -0,0 +1,79 @@
#pragma language glsl4
//uniform sampler2D g_color_sampler;
uniform sampler2D g_position_sampler;
uniform sampler2D g_normal_sampler;
uniform sampler2D noise_sampler;
uniform mat4 projection;
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;
uniform float occlusion_offset;
const int samples = 64;
varying vec4 PixelTexture;
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 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));
vec3 tangent = normalize(noise - normal * dot(noise, normal));
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) * radius + position;
vec3 sample_position1 = (SSAOKernel[i].xyz) * radius1 + position;
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;
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);
}

52
random_data.lua Normal file
View File

@ -0,0 +1,52 @@
local ffi = require 'ffi'
local _math = require '_math'
local vec3 = _math.vec3
local generate_noise_texture = function(width, height)
local noise_data = love.data.newByteData(width * height * 2 * 4)
local noise_data_ptr = ffi.cast('float*', noise_data:getFFIPointer())
for i = 0, (width * height - 1) do
noise_data_ptr[i * 2 + 0] = love.math.random() * 2 - 1
noise_data_ptr[i * 2 + 1] = love.math.random() * 2 - 1
end
local noise_image_data = love.image.newImageData(width, height, "rg32f", noise_data)
local noise_texture = love.graphics.newTexture(noise_image_data)
noise_texture:setWrap("repeat", "repeat")
return noise_texture
end
local lerp = function(a, b, t)
return a + t * (b - a)
end
local generate_ssao_kernel = function(kernel_samples)
local ssao_kernel_data = love.data.newByteData(kernel_samples * 4 * 4)
local ssao_kernel_data_ptr = ffi.cast('float*', ssao_kernel_data:getFFIPointer())
for i = 0, (kernel_samples - 1) do
local v = vec3(love.math.random() * 2.0 - 1.0,
love.math.random() * 2.0 - 1.0,
love.math.random())
v = vec3.normalize(v)
local scale = i / kernel_samples
scale = lerp(0.1, 1.0, scale * scale)
v = vec3.multiply_scalar(v, love.math.random() * scale)
ssao_kernel_data_ptr[i * 4 + 0] = v.x
ssao_kernel_data_ptr[i * 4 + 1] = v.y
ssao_kernel_data_ptr[i * 4 + 2] = v.z
--ssao_kernel_data_ptr[i * 4 + 3] = 0
end
local ssao_kernel_format = {
{ format = 'floatvec4' },
}
local ssao_kernel_shaderstorage_buffer = love.graphics.newBuffer(ssao_kernel_format, ssao_kernel_data, { shaderstorage = true, usage = "static" })
return ssao_kernel_shaderstorage_buffer
end
return {
generate_noise_texture = generate_noise_texture,
generate_ssao_kernel = generate_ssao_kernel,
}

File diff suppressed because one or more lines are too long

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

View File

@ -0,0 +1,72 @@
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()
return #parameter_order
end
local max_param_ix = get_max_param_ix()
local get_current_param_keys = function()
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
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
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
return {
update_parameter = update_parameter,
update_current_ix = update_current_ix,
draw = draw,
}

21
vertex_font.glsl Normal file
View File

@ -0,0 +1,21 @@
#pragma language glsl3
const vec2 vtx[4] = vec2[](vec2(-1.0, 1.0), // tl
vec2( 1.0, 1.0), // tr
vec2( 1.0, -1.0), // br
vec2(-1.0, -1.0)); // bl
uniform mat4 transform;
out vec4 PixelTexture;
void vertexmain()
{
vec2 vertex = vtx[gl_VertexID];
PixelTexture = vec4(vertex * vec2(0.5, -0.5) + 0.5, 0, 0);
vertex = vertex * vec2(0.5, 0.5) + vec2(0.5, -0.5);
love_Position = transform * vec4(vertex, 0.0, 1.0);
}

View File

@ -13,5 +13,5 @@ void vertexmain()
PixelTexture = vec4(vertex.xy * vec2(0.5, -0.5) + 0.5, 0, 0);
love_Position = vertex;
love_Position = vec4(vertex.xy, -1.0, 1.0);
}

View File

@ -34,6 +34,7 @@ varying vec4 PixelNormal;
varying vec4 PixelTexture;
varying vec4 PixelWorldPosition;
varying vec4 PixelLightPosition;
varying vec4 PixelViewPosition;
void vertexmain()
{

View File

@ -13,6 +13,7 @@ layout (std430) readonly buffer VertexPNTLayout
uniform int VertexPNTOffset;
uniform mat4 view_transform;
uniform mat4 world_transform;
uniform mat4 light_transform;
uniform mat4 transform;
@ -21,6 +22,7 @@ varying vec4 PixelNormal;
varying vec4 PixelTexture;
varying vec4 PixelWorldPosition;
varying vec4 PixelLightPosition;
varying vec4 PixelViewPosition;
void vertexmain()
{
@ -31,6 +33,7 @@ void vertexmain()
vec4 Position = vec4(VertexPNT.Position.xyz, 1);
PixelViewPosition = view_transform * Position;
PixelWorldPosition = world_transform * Position;
PixelLightPosition = light_transform * Position;
love_Position = transform * Position;