Context
PR #837 improved EffectsManager significantly — OutlinePass for
selection silhouettes, Fresnel shader for jets, setSelectionColor()
for experiment customization. Strong foundation.
Four gaps remain that block further extensibility, all verified
against current main after #837 merged.
Gap 1 — GLSL embedded as TypeScript strings, no CI validation
VERTEX_SHADER and HOVER_FRAGMENT_SHADER
are private static readonly TypeScript string constants containing
raw GLSL. A syntax error only surfaces at WebGL runtime — never in
yarn test:ci. Search of .github/workflows/ for glslang,
glsl-loader, glsl-validate returns zero results.
The Fresnel shader added in PR #837 (phoenix-objects.ts) follows
the same pattern — no shader in the codebase has a validation path.
Gap 2 — No formal state model
The render path branches on implicit checks:
- Line 148:
if (this.selectedObjectsSet.size > 0)
- Line 157:
else if (this.hoverOutline)
- Line 219:
if (this.selectionOutlinePass && this.selectedObjectsSet.size > 0)
- Line 268:
this.selectionOutlinePass.enabled = this.selectedObjectsSet.size > 0
Search for EffectsState returns zero results — no enum, no typed
state machine exists. Adding a new visual state — DIMMED for pileup
animation (PR #862) or HIGHLIGHTED for masterclass mode — requires
finding and updating every implicit branch with no compiler guidance.
Gap 3 — Hover color hardcoded, selection color configurable
setSelectionColor(color: number) exists at line 328 — experiments
can override the amber selection outline. Hover color is hardcoded
at line 71:
vec3 color = vec3(0.2, 0.6, 1.0);
No setHoverColor() exists. An experiment with blue-colored objects
(e.g. LHCb calorimeter deposits) cannot change hover color without
modifying core code — inconsistent with the configurable selection
color pattern established by #837.
Gap 4 — No experiment effect override API
Search for registerEffect, effectOverride, override in
effects-manager.ts returns zero results. Search of all experiment
pages in packages/phoenix-ng/projects/phoenix-app/src/app/sections/
for effectsManager. calls returns zero results.
The only experiment-configurable API is setSelectionColor().
Experiments wanting custom hover behavior for a specific object type
must fork effects-manager.ts — no extension point exists.
Proposed Fix — Three Phases
Phase 1 — Low risk, independently mergeable:
- Add
EffectsState enum: DEFAULT | HOVERED | SELECTED | HIGHLIGHTED | DIMMED
- Add
setHoverColor(color: number) to match setSelectionColor()
- Update
HOVER_FRAGMENT_SHADER to use uniform vec3 color
- Full unit tests — no render path changes, no shader extraction yet
Phase 2 — Shader organisation:
- Extract
VERTEX_SHADER and HOVER_FRAGMENT_SHADER to shaders/
ShaderRegistry class via glsl-loader
- Add
glslangValidator CI validation step
Phase 3 — Extensibility:
registerEffectOverride(objectType, config) API
- Experiments configure visual behavior per object type without
forking core code — demonstrated with one working example
Happy to implement all three phases.
Context
PR #837 improved
EffectsManagersignificantly — OutlinePass forselection silhouettes, Fresnel shader for jets,
setSelectionColor()for experiment customization. Strong foundation.
Four gaps remain that block further extensibility, all verified
against current
mainafter #837 merged.Gap 1 — GLSL embedded as TypeScript strings, no CI validation
VERTEX_SHADERandHOVER_FRAGMENT_SHADERare
private static readonlyTypeScript string constants containingraw GLSL. A syntax error only surfaces at WebGL runtime — never in
yarn test:ci. Search of.github/workflows/forglslang,glsl-loader,glsl-validatereturns zero results.The Fresnel shader added in PR #837 (
phoenix-objects.ts) followsthe same pattern — no shader in the codebase has a validation path.
Gap 2 — No formal state model
The render path branches on implicit checks:
if (this.selectedObjectsSet.size > 0)else if (this.hoverOutline)if (this.selectionOutlinePass && this.selectedObjectsSet.size > 0)this.selectionOutlinePass.enabled = this.selectedObjectsSet.size > 0Search for
EffectsStatereturns zero results — no enum, no typedstate machine exists. Adding a new visual state —
DIMMEDfor pileupanimation (PR #862) or
HIGHLIGHTEDfor masterclass mode — requiresfinding and updating every implicit branch with no compiler guidance.
Gap 3 — Hover color hardcoded, selection color configurable
setSelectionColor(color: number)exists at line 328 — experimentscan override the amber selection outline. Hover color is hardcoded
at line 71:
No
setHoverColor()exists. An experiment with blue-colored objects(e.g. LHCb calorimeter deposits) cannot change hover color without
modifying core code — inconsistent with the configurable selection
color pattern established by #837.
Gap 4 — No experiment effect override API
Search for
registerEffect,effectOverride,overrideineffects-manager.tsreturns zero results. Search of all experimentpages in
packages/phoenix-ng/projects/phoenix-app/src/app/sections/for
effectsManager.calls returns zero results.The only experiment-configurable API is
setSelectionColor().Experiments wanting custom hover behavior for a specific object type
must fork
effects-manager.ts— no extension point exists.Proposed Fix — Three Phases
Phase 1 — Low risk, independently mergeable:
EffectsStateenum:DEFAULT | HOVERED | SELECTED | HIGHLIGHTED | DIMMEDsetHoverColor(color: number)to matchsetSelectionColor()HOVER_FRAGMENT_SHADERto useuniform vec3 colorPhase 2 — Shader organisation:
VERTEX_SHADERandHOVER_FRAGMENT_SHADERtoshaders/ShaderRegistryclass viaglsl-loaderglslangValidatorCI validation stepPhase 3 — Extensibility:
registerEffectOverride(objectType, config)APIforking core code — demonstrated with one working example
Happy to implement all three phases.