Fix many issues related to shadows.

This commit is contained in:
Alberto Torres 2024-09-21 02:09:22 +02:00
parent 1640040f93
commit dca0123f13
4 changed files with 41 additions and 4 deletions

View file

@ -208,7 +208,7 @@ proc initShader*(self: Shader, engine: MyouEngine, material: Material,
@[
&"precision {precision} float;",
&"precision {precision} int;",
&"precision {precision} sampler2DShadow;",
&"precision {precision} sampler2DArrayShadow;",
]
else:
@[]
@ -438,6 +438,7 @@ proc initShader*(self: Shader, engine: MyouEngine, material: Material,
if success == 0:
let gl_log = get_shader_info_log(fragment_shader)
let error_msg = &"Error compiling fragment shader of material {material.name}\n{gl_log}"
echo error_msg
# console_error fragment
let lines = fragment.split("\n")
if "ERROR: 0:" in gl_log:
@ -452,8 +453,8 @@ proc initShader*(self: Shader, engine: MyouEngine, material: Material,
for i in max(1, line - 1000) ..< min(line + 4, lines.len):
console_error(&"{i} {lines[i - 1]}")
else:
for i in 1 ..< lines.len:
console_error(&"{i} {lines[i - 1]}")
for i,line in lines:
console_error(&"{i+1} {line}")
console_error(error_msg)
return
glGetProgramiv(prog, GL_LINK_STATUS, addr success)

View file

@ -33,6 +33,7 @@
import ../types
import vmath except Quat
import ../util
import ../graphics/material
when defined(nimdoc):
type TYPES* = LightType | Light
@ -100,6 +101,9 @@ proc newLight*(engine: MyouEngine, name: string="",
scene.add_object(this, name=name)
return this
when defined(myouDebugShadows):
var debug_mesh: Mesh
proc configure_shadow*(self: Light,
camera: Camera = nil,
max_distance: float32 = 0.0,
@ -131,13 +135,16 @@ proc configure_shadow*(self: Light,
# TODO: instead of a ground plane, we can just exclude the largest
# convex object, as long as we can clamp the polygons outside the
# frustum. Can we avoid clipping by setting W?
self.scene.update_all_matrices()
var casters: seq[Vec3]
for ob in self.scene.children:
for ob in objects:
if not (ob.is_mesh and ob.visible):
continue
let me = ob.get_mesh
let bb = me.bound_box
if bb[0] == bb[1]:
continue
let world_dim = (ob.world_matrix * vec4(bb[1] - bb[0], 0.0)).xyz
var casts = true
if world_dim.z < 0.00001:
@ -155,9 +162,29 @@ proc configure_shadow*(self: Light,
break
casts = not all_above
if casts:
echo "adding casting ", ob.name
for v in box_corners(bb):
casters.add ob.world_matrix * v
if casters.len == 0:
return
when defined(myouDebugShadows):
if debug_mesh.nonNil:
debug_mesh.destroy()
debug_mesh = self.engine.newMesh(vertex_count = 100, draw_method = Lines)
debug_mesh.materials.add self.engine.newSolidMaterial("green", vec4(0,1,0,1))
debug_mesh.visible = true
self.scene.add_object debug_mesh
let hull = quickhull(casters)
for f in hull:
debug_mesh.add_vertex f.points[0], vec4(1)
for v in f.points[1..^1]:
debug_mesh.add_vertex v, vec4(1)
debug_mesh.add_vertex v, vec4(1)
debug_mesh.add_vertex f.points[0], vec4(1)
debug_mesh.data.update_varray()
casters = quickhull_points(casters)
let shadow = newSimpleShadowManager(self, use_camera = false)
shadow.caster_bounding_points = casters

View file

@ -38,6 +38,12 @@ proc updateShadowStorage*(scene: Scene) =
let fb_size = scene.shadow_map_resolution
assert color_channels <= 4
if scene.shadow_maps != nil:
# TODO: we're assuming that if it exists it has all the same parameters
# and that only resolution and number of layers will change
if scene.shadow_maps.width == fb_size and
scene.shadow_maps.layer_count == count:
scene.calculate_max_lights_and_cubemaps()
return
scene.shadow_maps.destroy()
scene.shadow_maps = scene.engine.newFramebuffer(fb_size, fb_size,
if color_channels != 0:

View file

@ -97,6 +97,8 @@ proc newSimpleShadowManager*(light: Light;
self.uses_depth = false
when defined(myouDebugShadows):
if debug_mesh != nil:
debug_mesh.destroy()
debug_mesh = self.engine.newMesh(vertex_count = 100, draw_method = Lines)
debug_mesh.materials.add self.engine.newSolidMaterial("green", vec4(0,1,0,1))
debug_mesh.visible = false
@ -105,6 +107,7 @@ proc newSimpleShadowManager*(light: Light;
method destroy*(self: SimpleShadowManager) {.locks:"unknown".} =
if self.material != nil:
self.material.destroy()
debug_mesh.destroy()
when defined(myouDebugShadows):
proc show_mat(mat: Mat4) =