Skip to content

fix: honor board solder_mask_color in the 3D render (#957) - #959

Open
DPS0340 wants to merge 1 commit into
tscircuit:mainfrom
DPS0340:fix/solder-mask-color
Open

fix: honor board solder_mask_color in the 3D render (#957)#959
DPS0340 wants to merge 1 commit into
tscircuit:mainfrom
DPS0340:fix/solder-mask-color

Conversation

@DPS0340

@DPS0340 DPS0340 commented Jul 25, 2026

Copy link
Copy Markdown

Fixes #957.

Problem

The 3D viewer hard-coded the FR4 green solder mask, so a board built with solderMaskColor="black" still rendered green even though the Circuit JSON carried solder_mask_color correctly. This made the 3D preview misleading for any board that isn't green.

Two independent code paths had the same hard-coding:

  • soldermask-drawing.ts — the textured mask layer derived its palette from material only.
  • convert-circuit-json-to-3d-svg.ts — literally const solderMaskColor = colors.fr4SolderMaskGreen.

Change

  • Added solderMaskColorPresets covering the documented presets (green, red, blue, purple, black, white, yellow). Each preset is a pair of [mask over bare substrate, mask over copper], since solder mask is translucent and copper underneath lifts the coating — that's what keeps traces readable through the mask.
  • Added a shared resolveSolderMaskPreset helper so both render paths agree instead of duplicating the lookup.
  • Threaded boardData.solder_mask_color through createSoldermaskTextureForLayerdrawSoldermaskLayer, and applied it in the SVG path too.

Backwards compatibility

Boards with no color, an empty string, or not_specified resolve to undefined and keep the existing material-derived default (FR4 green / FR1), so nothing changes for current boards. Unrecognized values fall back rather than throwing.

Verification

  • bunx tsc --noEmit — clean
  • bun run format:check — clean
  • bun test tests/solder-mask-color.test.ts — 6 pass / 0 fail

Note: bun test has 3 pre-existing failures on main (2 faux-board z-offset tests + the Atari outline SVG test). I confirmed they fail identically on the unmodified checkout, so they're untouched by this change.

@vercel

vercel Bot commented Jul 25, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
3d-viewer Ready Ready Preview, Comment Jul 26, 2026 6:13am

Request Review

@DPS0340

DPS0340 commented Jul 25, 2026

Copy link
Copy Markdown
Author

@imrishabh18 @rushabhcodes — either of you able to review this? Fixes #957.

The 3D viewer hard-coded the FR4 green solder mask in two independent paths, so a board built with solderMaskColor="black" still rendered green even though the Circuit JSON carried solder_mask_color correctly. This threads the actual color through both paths, falling back to the existing green when unset.

6 files, +139/-3. CI green and mergeable against main.

@rushabhcodes
rushabhcodes requested a review from seveibar July 25, 2026 20:34

@rushabhcodes rushabhcodes left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you share the render with different colors

@DPS0340

DPS0340 commented Jul 26, 2026

Copy link
Copy Markdown
Author

Here are the renders — same board, only solder_mask_color changed, all seven documented presets:

solder mask color presets

Board face colour actually emitted in the SVG for each:

preset board face preset board face
green rgb(33,69,46) black rgb(39,39,39)
red rgb(118,39,39) white rgb(241,241,239)
blue rgb(39,56,118) yellow rgb(196,182,63)
purple rgb(85,39,108)

On main every one of these renders rgb(33,69,46) — the hard-coded FR4 green — regardless of what solder_mask_color says, which is #957.

Two things worth pointing out from generating these:

  • black and white are the cases that matter. They're the ones a reader would assume are "just a dark/light green tint", and they aren't — black comes out neutral (39,39,39, equal on all channels) rather than a dark green. The test asserts exactly that, since a green-dominated "black" would still look plausible in a screenshot.
  • The pad/silkscreen elements stay unchanged across all seven, so the change is confined to the mask material and isn't tinting the whole scene.

Generated by setting solder_mask_color on the existing tests/assets/circuit.json fixture and calling convertCircuitJsonTo3dSvg with the same options as the existing top-view test.

@itsbalamurali

Copy link
Copy Markdown

@rushabhcodes any way that this could land?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3D viewer ignores board solder_mask_color (always renders green)

3 participants