User Tools

Site Tools


docs:rendering_notes

Rendering Notes

This document describes the current Stargate rendering implementation. The renderer is functional and visually close to the intended direction, but it is still a procedural prototype rather than a final model/rendering architecture.

Renderer Registration

LanteaCraftClient.registerRenderers registers:

ModBlockEntities.STARGATE_BASE -> StargateBaseRenderer

Only the base block has a block entity. The full rendered Stargate ring is therefore anchored to the base block entity, not to each individual frame block.

StargateBaseRenderer Responsibilities

StargateBaseRenderer currently owns all assembled-gate visual rendering:

  • procedural ring shell geometry
  • glyph ring overlay
  • chevron geometry
  • chevron lock lighting
  • ring rotation during dialing
  • active chevron state while connected
  • bottom-row camouflage blocks
  • event horizon disc
  • kawoosh burst
  • expanded render bounds/culling behavior

The normal stargate_base, stargate_ring, and stargate_chevron block models still exist, but the assembled gate's main visual identity is the BER.

Coordinate System

The renderer exits early unless the base block has assembled=true.

For assembled gates it:

  1. translates to the base block center and raises the origin to the ring center:
    • translate(0.5, 3.5, 0.5)
  2. rotates around Y by the negative base facing yaw
  3. draws the procedural ring in local XY with depth on local Z

Important dimensions:

  • ring segments: 38
  • chevrons: 9
  • inner radius: 2.75
  • moving/glyph inner radius: 2.90
  • outer radius: 3.5
  • ring depth: 0.15
  • horizon radius: just inside the moving inner radius

Textures And RenderTypes

Frame/ring/chevrons:

textures/tileentity/stargate.png
RenderType.entitySolid

Glyph ring:

textures/tileentity/stargate_glyphs.png
RenderType.entityCutout

Event horizon/kawoosh:

textures/fx/eventhorizon.png
RenderType.entityTranslucent

The frame texture is treated as a 16×16 tile atlas inside a 1024×1024 image. Tile constants select areas for outer ring, face, inner ring, unlit chevrons, and lit chevrons.

Shell Geometry

renderShell builds the ring from 38 radial segments.

For each segment it emits quads for:

  • outer cylindrical wall
  • inner cylindrical wall
  • center face band
  • moving/glyph ring band
  • front bevels
  • rear bevels

Lighting is forced to LightTexture.FULL_BRIGHT for the Stargate mesh, so the ring remains readable independent of world lighting.

Prototype Quality

  • Normals are currently simplified as (0,0,1) for all vertices.
  • Geometry is hand-authored in code and not backed by baked models.
  • Ring dimensions are tuned visually, not derived from the legacy model source as a formal port.

Glyph Ring And Dialing Rotation

renderGlyphRing draws a textured annular band over the moving ring area.

During dialing:

  • dialingState reads StargateBaseBlockEntity.dialingAddress
  • each address symbol maps to an angle using the legacy 38-glyph alphabet
  • ring rotation lerps to the target symbol angle
  • easing is cosine-based

When connected and not dialing:

  • the ring rests on the final connected symbol angle
  • chevrons corresponding to the connected address remain lit

Prototype Quality

  • The renderer has its own copy of the legacy glyph string instead of sharing StargateAddress.LEGACY_GLYPHS.
  • The glyph ring is texture-coordinate based, not individual symbol meshes.
  • Current behavior supports up to 9 chevron lock slots visually, but the gameplay address is currently 7 symbols.

Chevron Rendering

renderChevrons places nine chevrons around the ring.

Chevron constants:

  • count: 9
  • angular spacing: 360 / 9
  • lock order: { 8, 7, 6, 3, 2, 1, 0, 5, 4 }

Each chevron:

  • is rendered as two wedge-like front quads
  • moves slightly when locked
  • overlays lit quads when lock > 0
  • uses the lit chevron tile from stargate.png

Implemented

  • Chevrons light progressively during dialing.
  • Lit chevrons remain active while the gate is connected.
  • The destination/incoming gate is also put into a connected visual state by the dialing payload.

Prototype Quality

  • Chevron order is hand-tuned and should be checked against legacy/show expectations.
  • The final chevron placement/order was recently adjusted and needs another in-game pass.
  • Chevron geometry is stylized and procedural, not a model import.

Event Horizon

The event horizon is drawn only when:

  • the base BE is connected
  • the BE has a level
  • the gate is no longer in the dialing phase

renderEventHorizon draws:

  • a short kawoosh burst if the gate has just opened
  • the steady event horizon disc

The steady puddle:

  • is a procedural circular mesh
  • uses 10 radial bands and 38 angular segments
  • uses translucent event horizon texture
  • applies small Z displacement from horizonRipple
  • animates UVs through animatedU and animatedV

The puddle does not spin as a whole. It ripples by changing per-vertex Z offset and UV sampling over time.

Prototype Quality

  • It is a flat-ish translucent mesh with ripple displacement, not a fluid simulation.
  • It has no collision/portal surface block.
  • It renders from the base BER, so the base BE is the render anchor.
  • Alpha/depth sorting may need testing with terrain, water, and other translucent objects.

Kawoosh

The kawoosh is also procedural.

Current behavior:

  • lasts 18 ticks
  • starts immediately after dialing duration completes
  • expands from the center
  • protrudes forward along local Z
  • fades out as progress approaches 1
  • uses the same event horizon texture/render type

Core methods:

  • renderKawoosh
  • kawooshDisplacement
  • kawooshProfile

The shape is a center-heavy protrusion plus a smaller rim bulge and animated wave.

Prototype Quality

  • The kawoosh is visually tuned, not physically or canonically accurate.
  • It has no gameplay damage/destruction effect.
  • It does not currently mask, clip, or interact with world blocks/entities.
  • Timing is tied to BE dialing state, not an explicit server event packet.

Needs Testing

  • Whether the kawoosh appears exactly once on fresh connection.
  • Whether it incorrectly replays after chunk reload, dimension travel, or client reconnect.
  • Visual quality at low FPS and high latency.

Bottom Camouflage Rendering

Bottom-row camouflage is stored on StargateBaseBlockEntity as a single BlockState.

renderBottomCamouflage renders seven copies of that block across local x=-3..3, at the bottom row of the gate.

The renderer uses Minecraft's block renderer:

Minecraft.getInstance().getBlockRenderer().renderSingleBlock(...)

Each rendered camouflage block is slightly scaled up (1.004) to reduce fighting with existing blocks/models.

Prototype Quality

  • Only one camouflage state is stored for the whole bottom row.
  • The state is reduced to the target block's default state, so orientation/properties are not preserved.
  • There is no clearing interaction yet besides code support on the BE.

Culling And Bounds

The renderer overrides:

  • shouldRenderOffScreentrue
  • getViewDistance128
  • shouldRender → distance check against expanded gate bounds
  • getRenderBoundingBox → expanded AABB around the base

The bounds are:

new AABB(basePos).inflate(5, 5, 5).expandTowards(0, 6, 0)

This was added because the gate mesh is much larger than the base block and otherwise disappears when the base block leaves the camera frustum.

Prototype Quality

  • The bounds are intentionally generous.
  • shouldRenderOffScreen=true helps avoid base-frustum clipping but can increase render cost.
  • More precise bounds could be computed per facing.

Sound-Driven Visual State

Visual state is primarily derived from StargateBaseBlockEntity:

  • dialingAddress
  • dialingStartGameTime
  • dialingDurationTicks
  • connectedAddress

Server-side BE tick plays sounds:

  • roll on dialing start
  • chevron lock as each symbol progresses
  • open after dialing completes
  • ambient while connected
  • close when connection clears

The renderer does not play sounds. It only visualizes the same BE state.

Known Risks And TODOs

Current Risks

  • The renderer uses a copied legacy glyph string instead of the central address constant.
  • The full ring depends on one block entity. If the base BE is missing or desynced, the whole visual disappears.
  • Full-bright rendering may not match desired lighting once final art direction settles.
  • Translucent event horizon sorting needs more testing.
  • Geometry normals are placeholder-quality.
  • Render cost should be profiled with many gates visible.

TODO Candidates

  • Share the glyph alphabet constant with StargateAddress.
  • Split rendering helpers into smaller classes once behavior stabilizes.
  • Add a proper model/baked-geometry path if procedural maintenance gets painful.
  • Add explicit client event/state for kawoosh instead of deriving it from persisted dialing time.
  • Add configurable render distance/detail for active gates.
  • Add a clear camouflage interaction and preserve more blockstate properties if needed.
  • Revisit chevron lock order against legacy implementation.
docs/rendering_notes.txt · Last modified: by 127.0.0.1