311. 在精灵渲染流水线中传递背景不透明掩码

在精灵渲染流水线中传递背景不透明度掩码。

311 / 356 · tests/chapter_09_sprite_rendering/test_311_thread_background_opaque_mask_through_sprite_pipeline.py

需要更新的文件

emulator/rendering/frame_compositor.py
emulator/rendering/sprite_renderer.py

为什么需要这一步

步骤 310 创建了 BackgroundOpaqueMask。在应用精灵优先级行为之前,我们先让相关函数接受并传递该掩码。

这样可以让教程保持渐进式推进

Step 310 -> build the mask
Step 311 -> thread the mask through function signatures
Step 312 -> use the mask to enforce sprite priority bit 5

所需的 API 形式

def composite_background_and_sprites(
    background: Framebuffer,
    oam: bytes | bytearray,
    pattern_table: bytes,
    sprite_palettes: SpritePalettes,
    # --- ADD THIS NEW LINE ---
    background_opaque_mask: BackgroundOpaqueMask | None = None,
) -> Framebuffer:
    ...
    render_oam_sprites_to_framebuffer(
        framebuffer,
        oam,
        pattern_table,
        sprite_palettes,
        # --- ADD THIS NEW LINE ---
        background_opaque_mask,
    )
    ...


def render_oam_sprites_to_framebuffer(
    framebuffer: Framebuffer,
    oam: bytes | bytearray,
    pattern_table: bytes,
    sprite_palettes: SpritePalettes,
    # --- ADD THIS NEW LINE ---
    background_opaque_mask: BackgroundOpaqueMask | None = None,
) -> None:
    ...
    render_sprite_8x8_to_framebuffer(
        framebuffer,
        sprite,
        pattern_table,
        sprite_palettes,
        # --- ADD THIS NEW LINE ---
        background_opaque_mask,
    )


def render_sprite_8x8_to_framebuffer(
    framebuffer: Framebuffer,
    sprite: SpriteEntry,
    pattern_table: bytes,
    sprite_palettes: SpritePalettes,
    # --- ADD THIS NEW LINE ---
    background_opaque_mask: BackgroundOpaqueMask | None = None,
) -> None:
    ...

还需要在必要的地方添加该类型的导入

# --- ADD THIS NEW LINE ---
from emulator.rendering.nametable_renderer import BackgroundOpaqueMask

重要提示

这一步还不需要真正使用该掩码。下一步将添加这一规则:

if sprite is behind background and background_opaque_mask[pixel] is True:
    skip drawing this sprite pixel

为什么参数是可选的 None?较早的测试和较早的教程步骤已经在不传入背景掩码的情况下调用这些渲染辅助函数。将该参数保持为可选,可以在演进流水线的同时保持向后兼容。

本步骤范围之外

  • 应用精灵优先级第 5 位
  • 更改 Console.render_framebuffer()
  • 从 PPU 状态构建掩码
  • 精灵 0 命中
  • 精灵溢出
  • pygame

运行本课

uv run pytest tests/chapter_09_sprite_rendering/test_311_thread_background_opaque_mask_through_sprite_pipeline.py -v