Skip to content

Star Wars (Data East)

Star Wars DE showcased a pre-rendered 3D art pipeline using Cinema 4D and Octane, with extensive GI on/off rendering, custom insert techniques, and a parallel multi-developer workflow. The project produced over 200 renders across 8 depth-bias layers and demonstrated advanced techniques for transparent ramps, normal maps, and displacement mapping.

Build Notes

Multi-Developer Workflow

Star Wars DE demonstrated parallel development:

  • Kingdids: C4D/Octane rendering (all GI on/off/flash textures, inserts, 200+ renders)
  • Sixtoe: VPX table setup, scripting, VR room, flashers, GI hookup
  • iaakki: Lampz/NFozzy code integration, GI fading materials
  • apophis79: Physics, Fleep sounds, flipper tuning, drop target fixes
  • Wylte: R2D2 primitive code, ramp shadows

Sequential file passing with version numbers (v0.001 through v0.022+). Detailed changelog comments in the script header for each version.

GI On/Off Rendering Pipeline

Pre-rendered GI workflow requires 3 renders per depth bias layer: GI On, GI Off (doubles as Flash Off), and Flash On. Objects are grouped by depth bias into layers. Moving objects (R2D2 head, Death Star) get their own textures.

Duplicate primitive sets in VPX: one with GI-on textures, the other gets animation/fading. When combining VPX lights with pre-rendered textures, render slightly darker than intended (VPX adds ~2-3 stops of brightness). Export renders as EXR/HDR for exposure adjustment latitude.

3D & Art

Pre-Rendered Plastic Ramps with Refraction

Technique using two separate objects:

  • Plastic body: rendered with refraction showing playfield elements beneath
  • Decal: separate object sitting slightly below (0.001) the surface, rendered double-sided for light refraction scattering

In Octane, enable "Fake Shadows/Caustics" on the plastic material. Disable dispersion to avoid color contamination. Set roughness to 0.001 for clear plastic. In VPX, set BlendDisableLighting to 0.5-1.0.

Octane Baking Camera vs Camera Projection

Two rendering approaches:

  • Camera projection: renders from a fixed POV, looks great from that angle but breaks in VR
  • Baking camera: renders onto unwrapped UVs, works from all viewing angles (essential for VR). Requires enabling "Use Camera Position" checkbox and entering camera coordinates manually

Camera projection works for desktop/cabinet but breaks in VR where the viewing angle changes.

Octane General Visibility for Transparent Ramps

The Sky object's "General Visibility" slider controls how much scene shows through transparent objects. Turning it down makes ramps more transparent with only edge reflections. Render overlapping ramps separately using C4D Take Manager for batch rendering. Combine in compositing and use After Effects curves to fine-tune the alpha channel.

Insert Rendering with LuxCore

The "on" state insert textures use LuxCore renderer in Blender for bi-directional path tracing that creates the characteristic glow pattern. C4D Arnold, Octane, and Corona could not replicate the same look.

Insert setup uses two trays (depth bias +100 and -100): bottom tray = "on" image, top tray = "off" image with 0.99 opacity. VPX light at depth bias 0, halo height -0.01. Insert textures rendered clear/untinted; color applied via VPX materials.

C4D/Octane Insert Rig

Alternative insert pipeline entirely in C4D/Octane:

  • Create insert pattern in Photoshop as displacement map
  • Plug into Octane insert rig
  • Renders both on and off states in ~15 minutes (excluding render time)
  • Includes 1:1 trays compatible with Flupper's VPX method

Object Space Normal Maps

For VPX normal maps rendered in Octane, use object space (the rainbow-colored map), not tangent space. Tangent maps produce no visible detail from overhead camera. Check the "Object Space" box in VPX. A texture is always required alongside the normal map.

Death Star Displacement Mapping

The Death Star uses displacement mapping on a smooth dome -- none of the grooves exist as geometry. The dome cutout uses VPX environment reflections for a metallic look with no baked lighting.

Depth Bias for Stacked Transparent Ramps

Stacked transparent ramps cause cloudiness from overlapping semi-transparent textures. Set different depth bias values per ramp. VR is "super mega ultra sensitive" to depth bias. Each ramp must be rendered individually with other ramps hidden. All transparent ramp prims must be set as "active."

POV and Table Dimensions

POV settings are affected by the physical extent of walls and ramps. Ramps used as VR room floor/roof dramatically affect POV. Primitives do NOT affect POV, only walls and ramps. Sixtoe's VR room design uses minimal geometry (single flat plane) to avoid POV impact.

VR Room Rotation

The VR room/cabinet needs a 6-degree rotation around the X-axis to match the natural slope of the pinball table.

Poly Count Guidelines

  • 20,000 polygons max per non-collidable object
  • Render texture and normal map from high-poly, decimate to low-poly, apply in VPX
  • C4D can reduce poly count without affecting original UVs

Rubber Band Physics

Rubber bands should be split into separate sections:

  • Post/curve section: tighter, stiffer elasticity
  • Straight section: loose, more elastic
  • Middle section (for larger bands): its own physics material

High-poly rendered meshes should NOT be used as collidables; export low-poly versions as invisible collidable primitives.

Scripting

DisableLighting Callback for Lampz

Code pattern for insert illumination through Lampz:

Sub DisableLighting(pri, DLintensity, ByVal aLvl)
    if Lampz.UseFunction then aLvl = Lampz.FilterOut(aLvl)
    pri.blenddisablelighting = aLvl * DLintensity * 0.4
End Sub

Callback registration: Lampz.Callback(41) = "DisableLighting InsertTrayON015, 150,"

GI Primitive Fading with Material Swaps

For pre-rendered GI textures on duplicate primitive layers:

  • Created 4 materials: OpaqueON, OpaqueOFF, PlasticTransON, PlasticTransOFF
  • GI fading controlled in GIUpdates sub by adjusting material opacity
  • ON primitives should not fade to zero (clamp between 0.5 and 1.0)
  • Different primitive groups may need different fading speeds

Troubleshooting

R2D2 Movement Sound Bug

R2D2's movement code triggered a bumper sound every frame during rotation, creating continuous buzzing. Fix: changed to the quieter "DropUp" sound effect.

Non-Collidable Primitives and Performance

Non-collidable primitives should be set as "toys" in VPX. Without this, VPX still processes them in collision detection even if set to non-collidable.

Death Star Depth Bias in VR

Depth bias set to -600 caused rendering issues in VR. Changing to +600 fixed it. Negative depth bias values can cause unpredictable behavior in VR mode.

Flasher Position Bug

A flasher in the wrong VPX collection rendered at an incorrect position in VR. Stacking VPX lights/flashers at the same position causes brightness clipping (turning black) rather than additive blending.

Drop Target RotZ vs ObjRotZ

Drop target primitives must use RotZ (not ObjRotZ) when setting angle in Roth drop target code. Using ObjRotZ caused targets to appear unresponsive on some systems.

Duplicate Subroutine Detection

Thalamus created a Perl script to detect duplicate subs/functions in VBScript. VPX silently uses the last listed instance when a sub is defined twice, making manual detection very difficult.

Game Knowledge

ROM Versions

  • 1.04: Original. STAR WARS letters collectible from ramp shots (very exploitable)
  • 1.06: Removed letter collection from ramps (rebalancing)
  • 1.07 (20th Anniversary mod): Community ROM with many improvements. Default for the VPW table. Details at pinballcode.com/sw107

Resources

Projection Rendering Resolution

Camera projection rendering that frames the playfield at a specific POV may use only 2/3 of the texture area. A 4K texture effectively yields ~1080p on a cabinet screen. Fix: render at 6K or 8K so the playfield portion remains sharp at 4K display resolution.

Duplicate Detection Tool

Thalamus's Perl script scans VBS exports for duplicated sub/function names that VPX silently overrides.