nw::render

nw::render is the renderer-facing data and submission layer above nw::gfx.

It is not a scene graph, gameplay system, editor framework, or source-format owner. It turns explicit runtime data into GPU work through nw::gfx command lists and backend resources.

The Short Version

The current renderer path is:

source assets
  -> common CPU records
     ModelAsset, ParticleEffectDef, sockets, deformers, animation clips
  -> runtime/upload records
     RenderModel, CompiledParticleEffect, ModelInstance, material overrides
  -> frame records
     PreparedModelDraw, PreparedModelSurfaceDraw, particle packets, light lists
  -> renderer passes
     model, particle, shadow, Forward+, fog
  -> nw::gfx
     buffers, textures, pipelines, command lists, swapchain

The common case is source-neutral runtime data. glTF and NWN are inputs to that data, not renderer policy. NWN compatibility still exists where the common runtime does not yet own equivalent data.

Relationship To nw::gfx

nw::gfx owns the low-level graphics API boundary:

  • devices, swapchains, buffers, textures, render targets
  • shader and pipeline handles
  • command recording and submission
  • bindless texture indices and backend escape hatches

nw::render owns renderer meaning:

  • model, material, animation, particle, light, shadow, and fog records
  • GPU backend resources needed by renderer passes
  • source-neutral frame protocols such as prepared model surface draws
  • compatibility adapters for NWN sidecar data while bridge work is in progress

If a change needs to know about models, particles, PLT, shadows, Forward+, or viewer scene data, it belongs in nw::render or above. If it only manages GPU resources and command submission, it belongs in nw::gfx.

Main Runtime Pieces

RenderService

RenderService owns renderer singletons for the current graphics context:

  • ModelGpuBackend
  • ForwardPlusRenderer
  • ShadowRenderer
  • LocalShadowRenderer
  • ParticleRenderer
  • FogRenderer
  • NWN compatibility GPU resources and render asset cache

It returns two model contexts:

  • ModelRenderContext: common RenderModel / PBR submission context.
  • nwn::ModelRenderContext: NWN sidecar compatibility context.

New common renderer code should use ModelRenderContext unless it actually needs NWN sidecar payloads.

Model Data

The modern model path centers on these records:

  • ModelAsset: CPU-side source-neutral model data before GPU upload.
  • RenderModel: uploaded model data and GPU handles.
  • ModelInstance: scene/runtime placement, visibility, animation state, bounds, material overrides, and shadow summary.
  • ModelInstanceHandle: stable scene-owned handle with generation checking.
  • PreparedModelDraw: flat validated draw record collected from handles.
  • PreparedModelSurfaceDraw: smallest renderer-facing model surface command.

PreparedModelSurfaceDraw is the shared frame protocol. It carries source kind, source indices, pass/material data, transforms, skin index, bounds, and shadow-caster state. The array is sorted in place by pass/material needs.

The renderer should not infer behavior from model, texture, or node names. Source-specific quirks should be lowered into explicit common records or kept in a compatibility sidecar with counters.

Particles

The particle system is source-neutral:

  • authoring data: ParticleEffectDef
  • compiled data: CompiledParticleEffect
  • runtime data: ParticleSystemInstance
  • render data: ParticleRenderPacketList

NWN emitters are imported into this protocol. The emitter field map lives in docs/nwn_emitter_map.md, and the particle architecture overview lives in docs/particle_system.md.

Lighting, Shadows, And Fog

RenderContext carries per-frame camera, viewport, lighting, shadow, and Forward+ data. Area/viewer code prepares visible light lists and shadow caster sets before renderer passes consume them.

Forward+ local light clustering, shadow rendering, local shadow maps, and fog are renderer services. nw::gfx only sees their buffers, textures, pipelines, and commands.

Viewer Layer

lib/nw/render/viewer is the preview/tooling bridge used by mudl and renderer tests. It owns preview-scene assembly, area visibility records, particle-owner binding, debug drawing, screenshots, and parity toggles.

The viewer is not the production scene graph. It is where source adapters and common renderer contracts are exercised against real NWN/glTF data until a compiled runtime asset path exists.

Source Conversion Notes

Existing Detailed Docs

Open Issues