collada_scene: shadow mapping
This commit is contained in:
parent
8f22a0faf2
commit
ba777fbf3c
@ -6,12 +6,28 @@ local scalar = _math.scalar
|
||||
|
||||
local collada_types = require 'collada_types'
|
||||
|
||||
local pixel_data = love.filesystem.newFileData("pixel.glsl")
|
||||
local pixel_color_data = love.filesystem.newFileData("pixel_color.glsl")
|
||||
local pixel_shadow_data = love.filesystem.newFileData("pixel_shadow.glsl")
|
||||
local vertex_static_data = love.filesystem.newFileData("vertex_static.glsl")
|
||||
local vertex_skinned_data = love.filesystem.newFileData("vertex_skinned.glsl")
|
||||
local shader_static = love.graphics.newShader(pixel_data, vertex_static_data)
|
||||
local shader_skinned = love.graphics.newShader(pixel_data, vertex_skinned_data)
|
||||
local shader_color_static = love.graphics.newShader(pixel_color_data, vertex_static_data)
|
||||
local shader_color_skinned = love.graphics.newShader(pixel_color_data, vertex_skinned_data)
|
||||
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 shader_set = {
|
||||
shadow = {
|
||||
static = shader_shadow_static,
|
||||
skinned = shader_shadow_skinned,
|
||||
},
|
||||
color = {
|
||||
static = shader_color_static,
|
||||
skinned = shader_color_skinned,
|
||||
},
|
||||
}
|
||||
|
||||
local send_material
|
||||
local current_shader_set
|
||||
local current_shader
|
||||
|
||||
local images_textures = {}
|
||||
@ -46,13 +62,16 @@ collada_scene = {
|
||||
{ name = 'Joint', format = 'int32vec4' },
|
||||
{ name = 'Weight', format = 'floatvec4' },
|
||||
}
|
||||
shader_static:send("VertexPNTLayout", vtx_shaderstorage_buffer)
|
||||
shader_skinned:send("VertexPNTLayout", vtx_shaderstorage_buffer)
|
||||
shader_color_static:send("VertexPNTLayout", vtx_shaderstorage_buffer)
|
||||
shader_color_skinned:send("VertexPNTLayout", vtx_shaderstorage_buffer)
|
||||
shader_shadow_static:send("VertexPNTLayout", vtx_shaderstorage_buffer)
|
||||
shader_shadow_skinned:send("VertexPNTLayout", vtx_shaderstorage_buffer)
|
||||
|
||||
local vjw_data = love.filesystem.newFileData(vjw_path)
|
||||
if vjw_data:getSize() ~= 0 then
|
||||
local vjw_shaderstorage_buffer = love.graphics.newBuffer(vjw_format, vjw_data, { shaderstorage = true, usage = "static" })
|
||||
shader_skinned:send("VertexJWLayout", vjw_shaderstorage_buffer)
|
||||
shader_color_skinned:send("VertexJWLayout", vjw_shaderstorage_buffer)
|
||||
shader_shadow_skinned:send("VertexJWLayout", vjw_shaderstorage_buffer)
|
||||
end
|
||||
end,
|
||||
|
||||
@ -118,7 +137,9 @@ collada_scene = {
|
||||
local base_index_buffer_offset = mesh.index_buffer_offset / 4
|
||||
|
||||
for _, instance_material in ipairs(instance_materials) do
|
||||
if send_material then
|
||||
collada_scene.set_instance_material(instance_material)
|
||||
end
|
||||
local triangles = mesh.triangles[instance_material.element_index + 1]
|
||||
|
||||
local index_offset = base_index_buffer_offset + triangles.index_offset
|
||||
@ -184,7 +205,7 @@ collada_scene = {
|
||||
end
|
||||
end,
|
||||
|
||||
draw_node = function(view_position, light_position, node_state, node, node_instance, transform)
|
||||
draw_node = function(node_state, transform, light_transform, node, node_instance)
|
||||
if node.type ~= collada_types.node_type.NODE then
|
||||
return
|
||||
end
|
||||
@ -195,31 +216,37 @@ collada_scene = {
|
||||
|
||||
local world = node_instance.world
|
||||
transform = world * transform
|
||||
light_transform = world * light_transform
|
||||
|
||||
if node.instance_geometries_count > 0 then
|
||||
current_shader = shader_static
|
||||
current_shader = current_shader_set.static
|
||||
love.graphics.setShader(current_shader)
|
||||
current_shader:send("view_position", view_position.data)
|
||||
current_shader:send("light_position", light_position.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 = shader_skinned
|
||||
current_shader = current_shader_set.skinned
|
||||
love.graphics.setShader(current_shader)
|
||||
current_shader:send("view_position", view_position)
|
||||
current_shader:send("light_position", light_position)
|
||||
|
||||
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, projection)
|
||||
draw_nodes = function(node_state, transform, 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)
|
||||
node_index = node_index + 1
|
||||
end
|
||||
end,
|
||||
|
||||
draw_scene = function(node_state, perspective_projection, orthographic_projection)
|
||||
local camera_world = node_state.node_instances[node_state.camera].world
|
||||
local view_position = vec3.transform(vec3._zero, camera_world)
|
||||
|
||||
@ -229,23 +256,47 @@ collada_scene = {
|
||||
local light_world = node_state.node_instances[node_state.light].world
|
||||
local light_position = vec3.transform(vec3._zero, light_world)
|
||||
|
||||
local view = mat4.look_at_rh(view_position,
|
||||
view_target_position,
|
||||
vec3(0, 0, 1))
|
||||
local up = vec3(0, 0, 1)
|
||||
|
||||
local transform = view * projection
|
||||
local view = mat4.look_at_rh(view_position, view_target_position, up)
|
||||
local transform = view * perspective_projection
|
||||
|
||||
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(view_position, light_position, node_state, node, node_instance, transform)
|
||||
node_index = node_index + 1
|
||||
end
|
||||
local light_view = mat4.look_at_rh(light_position, vec3._zero, up)
|
||||
local light_transform = light_view * orthographic_projection
|
||||
|
||||
----------------------------------------------------------------------
|
||||
-- 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)
|
||||
|
||||
----------------------------------------------------------------------
|
||||
-- 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_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()
|
||||
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)
|
||||
end,
|
||||
}
|
||||
|
||||
return {
|
||||
draw_nodes = collada_scene.draw_nodes,
|
||||
draw_scene = collada_scene.draw_scene,
|
||||
load_buffers = collada_scene.load_buffers,
|
||||
load_node_instances = collada_scene.load_node_instances,
|
||||
load_images = collada_scene.load_images,
|
||||
|
||||
28
main.lua
28
main.lua
@ -35,9 +35,6 @@ local scenes = {
|
||||
|
||||
local node_state
|
||||
|
||||
local g_position_canvas
|
||||
local g_normal_canvas
|
||||
|
||||
local screen_index_buffer
|
||||
local screen_shader
|
||||
|
||||
@ -57,8 +54,8 @@ end
|
||||
local load_screen_shader = function()
|
||||
load_screen_index_buffer()
|
||||
|
||||
local pixel_data = love.filesystem.newFileData("pixel_sobel.glsl")
|
||||
local vertex_data = love.filesystem.newFileData("vertex_sobel.glsl")
|
||||
local pixel_data = love.filesystem.newFileData("pixel_screen.glsl")
|
||||
local vertex_data = love.filesystem.newFileData("vertex_screen.glsl")
|
||||
screen_shader = love.graphics.newShader(pixel_data, vertex_data)
|
||||
end
|
||||
|
||||
@ -80,6 +77,8 @@ function love.load(args)
|
||||
g_normal_canvas = love.graphics.newCanvas(1024, 1024, {format = "rgba32f"})
|
||||
g_color_canvas = love.graphics.newCanvas(1024, 1024, {format = "rgba32f"})
|
||||
|
||||
g_shadow_canvas = love.graphics.newCanvas(2048, 2048, {format = "r32f"})
|
||||
|
||||
load_screen_shader()
|
||||
end
|
||||
|
||||
@ -93,26 +92,24 @@ function love.draw()
|
||||
width, height = love.graphics.getDimensions()
|
||||
|
||||
local aspect_ratio = width / height
|
||||
local projection = mat4.perspective_fov_rh(scalar.convert_to_radians(45 * 0.5),
|
||||
local perspective_projection = mat4.perspective_fov_rh(scalar.convert_to_radians(45 * 0.5),
|
||||
aspect_ratio,
|
||||
0.1,
|
||||
10000.0)
|
||||
|
||||
--projection = mat4.orthographic_rh(500, 500, 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 transform = projection
|
||||
|
||||
collada_scene_animate.update(t, node_state)
|
||||
t = t + 0.016
|
||||
t = t + 0.016 * 0.1
|
||||
|
||||
love.graphics.setBlendMode("replace", "premultiplied")
|
||||
love.graphics.setDepthMode("less", true)
|
||||
collada_scene.draw_nodes(node_state, transform)
|
||||
collada_scene.draw_scene(node_state, perspective_projection, orthographic_projection)
|
||||
|
||||
-- love.graphics.setCanvas({
|
||||
-- g_color_canvas,
|
||||
@ -126,9 +123,8 @@ function love.draw()
|
||||
-- {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_normal_sampler", g_normal_canvas)
|
||||
--screen_shader:send("g_color_sampler", g_color_canvas)
|
||||
--love.graphics.drawFromShader(screen_index_buffer, 3 * 2, 1, 1)
|
||||
-- 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)
|
||||
end
|
||||
|
||||
@ -3,6 +3,7 @@
|
||||
varying vec4 PixelNormal;
|
||||
varying vec4 PixelTexture;
|
||||
varying vec4 PixelWorldPosition;
|
||||
varying vec4 PixelLightPosition;
|
||||
|
||||
uniform vec4 emission_color;
|
||||
uniform vec4 ambient_color;
|
||||
@ -15,6 +16,8 @@ uniform sampler2D ambient_sampler;
|
||||
uniform sampler2D diffuse_sampler;
|
||||
uniform sampler2D specular_sampler;
|
||||
|
||||
uniform sampler2D shadow_sampler;
|
||||
|
||||
uniform vec4 view_position;
|
||||
uniform vec4 light_position;
|
||||
uniform ivec4 texture_channel;
|
||||
@ -23,6 +26,18 @@ layout (location = 0) out vec4 g_color;
|
||||
layout (location = 1) out vec4 g_position;
|
||||
layout (location = 2) out vec4 g_normal;
|
||||
|
||||
float Shadow(vec3 normal, vec3 light_direction)
|
||||
{
|
||||
vec3 projected = PixelLightPosition.xyz / PixelLightPosition.w;
|
||||
projected = projected * vec3(0.5, -0.5, 0.5) + 0.5;
|
||||
float shadow_depth = texture(shadow_sampler, projected.xy).x;
|
||||
float fragment_depth = projected.z;
|
||||
|
||||
float bias = max(0.05 * (1.0 - dot(normal, light_direction)), 0.005);
|
||||
return fragment_depth - bias > shadow_depth ? 0.3 : 1.0;
|
||||
//return shadow_depth;
|
||||
}
|
||||
|
||||
void pixelmain()
|
||||
{
|
||||
vec3 normal = normalize(PixelNormal.xyz);
|
||||
@ -63,7 +78,11 @@ void pixelmain()
|
||||
color += diffuse.xyz * diffuse_intensity;
|
||||
color += specular.xyz * specular_intensity * 0.3;
|
||||
|
||||
g_position = vec4(PixelWorldPosition.xyz * 0.0005 + 0.5, 0.0);
|
||||
g_normal = vec4(normal * 0.5 + 0.5, PixelWorldPosition.z * 0.001 + 0.5);
|
||||
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_normal = vec4(normal, 0.0);
|
||||
}
|
||||
12
pixel_screen.glsl
Normal file
12
pixel_screen.glsl
Normal file
@ -0,0 +1,12 @@
|
||||
#pragma language glsl3
|
||||
|
||||
uniform sampler2D g_sampler;
|
||||
|
||||
out vec4 out_color;
|
||||
|
||||
void pixelmain()
|
||||
{
|
||||
vec4 color = texelFetch(g_sampler, ivec2(gl_FragCoord), 0);
|
||||
|
||||
out_color = vec4(color.xyz, 1.0);
|
||||
}
|
||||
8
pixel_shadow.glsl
Normal file
8
pixel_shadow.glsl
Normal file
@ -0,0 +1,8 @@
|
||||
#pragma language glsl3
|
||||
|
||||
layout (location = 0) out float g_out;
|
||||
|
||||
void pixelmain()
|
||||
{
|
||||
g_out = gl_FragCoord.z;
|
||||
}
|
||||
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
17
vertex_screen.glsl
Normal file
17
vertex_screen.glsl
Normal file
@ -0,0 +1,17 @@
|
||||
#pragma language glsl3
|
||||
|
||||
const vec4 vtx[4] = vec4[](vec4(-1.0, 1.0, 0.0, 1.0), // tl
|
||||
vec4( 1.0, 1.0, 0.0, 1.0), // tr
|
||||
vec4( 1.0, -1.0, 0.0, 1.0), // br
|
||||
vec4(-1.0, -1.0, 0.0, 1.0)); // bl
|
||||
|
||||
varying vec4 PixelTexture;
|
||||
|
||||
void vertexmain()
|
||||
{
|
||||
vec4 vertex = vtx[gl_VertexID];
|
||||
|
||||
PixelTexture = vec4(vertex.xy * vec2(0.5, -0.5) + 0.5, 0, 0);
|
||||
|
||||
love_Position = vertex;
|
||||
}
|
||||
@ -26,12 +26,14 @@ uniform int VertexJWOffset;
|
||||
|
||||
uniform mat4 Joints[3];
|
||||
|
||||
uniform mat4 light_transform;
|
||||
uniform mat4 world_transform;
|
||||
uniform mat4 transform;
|
||||
|
||||
varying vec4 PixelNormal;
|
||||
varying vec4 PixelTexture;
|
||||
varying vec4 PixelWorldPosition;
|
||||
varying vec4 PixelLightPosition;
|
||||
|
||||
void vertexmain()
|
||||
{
|
||||
@ -49,7 +51,8 @@ void vertexmain()
|
||||
PixelTexture = VertexPNT.Texture;
|
||||
|
||||
vec4 Position = mSkin * vec4(VertexPNT.Position.xyz, 1);
|
||||
//vec4 Position = Joints * vec4(VertexPNT.Position.xyz, 1);
|
||||
|
||||
PixelWorldPosition = world_transform * Position;
|
||||
PixelLightPosition = light_transform * Position;
|
||||
love_Position = transform * Position;
|
||||
}
|
||||
|
||||
@ -14,11 +14,13 @@ layout (std430) readonly buffer VertexPNTLayout
|
||||
uniform int VertexPNTOffset;
|
||||
|
||||
uniform mat4 world_transform;
|
||||
uniform mat4 light_transform;
|
||||
uniform mat4 transform;
|
||||
|
||||
varying vec4 PixelNormal;
|
||||
varying vec4 PixelTexture;
|
||||
varying vec4 PixelWorldPosition;
|
||||
varying vec4 PixelLightPosition;
|
||||
|
||||
void vertexmain()
|
||||
{
|
||||
@ -27,7 +29,9 @@ void vertexmain()
|
||||
PixelNormal = world_transform * vec4(VertexPNT.Normal.xyz, 0);
|
||||
PixelTexture = VertexPNT.Texture;
|
||||
|
||||
PixelWorldPosition = world_transform * vec4(VertexPNT.Position.xyz, 1);
|
||||
vec4 Position = vec4(VertexPNT.Position.xyz, 1);
|
||||
|
||||
love_Position = transform * vec4(VertexPNT.Position.xyz, 1);
|
||||
PixelWorldPosition = world_transform * Position;
|
||||
PixelLightPosition = light_transform * Position;
|
||||
love_Position = transform * Position;
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user