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
GIUpdatessub 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.