Class: Doom::Render::ZBufferRenderer
- Defined in:
- lib/doom/render/zbuffer_renderer.rb
Overview
Experimental renderer path. It deliberately reuses the proven BSP visibility and texture sampling code while replacing the visibility target with a full, per-pixel depth buffer. This makes it possible to add mesh rasterisation and ray traced passes without changing game logic.
Defined Under Namespace
Classes: Light
Constant Summary collapse
- MAX_DYNAMIC_LIGHTS =
8- LIGHT_LEVELS =
16
Constants inherited from Renderer
Renderer::SKY_TEXTUREMID, Renderer::SKY_XSCALE, Renderer::SKY_YSCALE
Instance Attribute Summary collapse
-
#depth_buffer ⇒ Object
readonly
Returns the value of attribute depth_buffer.
Attributes inherited from Renderer
#animations, #colormap, #combat, #cos_angle, #flats, #framebuffer, #hidden_things, #leveltime, #map, #monster_ai, #palette, #player_angle, #player_x, #player_y, #player_z, #players, #sin_angle, #skip_background_fill, #sprites, #textures, #view_player, #wad
Instance Method Summary collapse
-
#draw_wall_column_ex(x, y1, y2, texture_name, dist, light_level, tex_col, tex_y_start, scale, world_top) ⇒ Object
Opaque walls are the first geometry producer for the new depth target.
-
#initialize ⇒ ZBufferRenderer
constructor
A new instance of ZBufferRenderer.
- #render_frame ⇒ Object
Methods inherited from Renderer
#apply_view, #build_native_renderer, #check_plane, #draw_all_visplanes, #draw_floor_ceiling_background, #draw_sky_plane, #draw_span, #fill_uncovered_with_sector, #find_or_create_visplane, #native_wall_pass, #precompute_column_data, #render_visplane_spans, #set_player, #sprite_diagnostics
Constructor Details
#initialize ⇒ ZBufferRenderer
Returns a new instance of ZBufferRenderer.
16 17 18 19 20 |
# File 'lib/doom/render/zbuffer_renderer.rb', line 16 def initialize(...) super @depth_buffer = Array.new(SCREEN_WIDTH * SCREEN_HEIGHT, Float::INFINITY) @light_lut = build_light_lut end |
Instance Attribute Details
#depth_buffer ⇒ Object (readonly)
Returns the value of attribute depth_buffer.
10 11 12 |
# File 'lib/doom/render/zbuffer_renderer.rb', line 10 def depth_buffer @depth_buffer end |
Instance Method Details
#draw_wall_column_ex(x, y1, y2, texture_name, dist, light_level, tex_col, tex_y_start, scale, world_top) ⇒ Object
Opaque walls are the first geometry producer for the new depth target. BSP clipping remains the visibility algorithm for this initial stage; later raster passes can consume the per-pixel depth values written here.
31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 |
# File 'lib/doom/render/zbuffer_renderer.rb', line 31 def draw_wall_column_ex(x, y1, y2, texture_name, dist, light_level, tex_col, tex_y_start, scale, world_top) clip_top = @ceiling_clip[x] + 1 clip_bottom = @floor_clip[x] - 1 first = [[y1, clip_top, 0].max, SCREEN_HEIGHT].min last = [[y2, clip_bottom, SCREEN_HEIGHT - 1].min, -1].max super return if first > last || texture_name.nil? || texture_name.empty? || texture_name == '-' return unless @textures[anim_texture(texture_name)] # Reconstruct the world-space wall hit. Each dynamic source casts a # visibility ray to it; one-sided linedefs produce hard shadows. ray_distance = dist * @column_distscale[x] hit_x = @player_x + (ray_distance * @column_cos[x]) hit_y = @player_y - (ray_distance * @column_sin[x]) visible_lights = @dynamic_lights.select do |light| dx = light.x - hit_x dy = light.y - hit_y (dx * dx) + (dy * dy) < light.radius * light.radius && light_visible?(hit_x, hit_y, light) end y = first while y <= last offset = (y * SCREEN_WIDTH) + x @depth_buffer[offset] = dist if dist < @depth_buffer[offset] unless visible_lights.empty? world_z = world_top - ((y - (HALF_HEIGHT - ((world_top - @player_z) * scale))) / scale) intensity = visible_lights.sum do |light| distance = Math.sqrt(((light.x - hit_x)**2) + ((light.y - hit_y)**2) + ((light.z - world_z)**2)) distance < light.radius ? light.energy * ((1.0 - (distance / light.radius))**2) : 0.0 end level = (intensity * (LIGHT_LEVELS - 1)).to_i.clamp(0, LIGHT_LEVELS - 1) @framebuffer[offset] = @light_lut[level][@framebuffer[offset]] if level.positive? end y += 1 end end |
#render_frame ⇒ Object
22 23 24 25 26 |
# File 'lib/doom/render/zbuffer_renderer.rb', line 22 def render_frame @depth_buffer.fill(Float::INFINITY) @dynamic_lights = collect_dynamic_lights super end |