Deco radio
Stepped walnut cabinet with a brass grille and tuning controls
Earlier examples from earlier Kiln versions.

Drag to orbit after opening. The model starts stationary.
For your engine. The download is a standard glTF 2.0 binary (GLB) with PBR metallic-roughness materials. glTF stores materials, not lighting or tone mapping, so your engine decides how they read. This 3D view tone-maps with Review Neutral, the Khronos PBR Neutral construction with a smaller glare offset (0.015 instead of 0.04), at exposure 0.9. Its Tone mapping control also shows ACES and Linear, for comparison.
Build measurements
- Triangles
- 13,216
- Estimated draws
- 158
- Materials
- 11
- Textures
- 0
- Animation clips
- 1
- Bounds X × Y × Z
- 0.21 × 0.39 × 0.34 m
- Build warnings
- 0
Measurements come from this build.
Download this build
Runtime: 206,416 bytes. Original: 206,192 bytes.
These GLBs are build outputs of the MIT-licensed example source; no separate terms are stated for the builds.
Runtime provenance metadataSHA-256 download hashes
- Runtime GLB
- 9bc36f8616f1485e1099ebf80697ebdc08f3157a78f6175975a3e2ccba62a191
- Original GLB
- 5ef16001317b96858e46b5c17a29128d7edb3b12346c55be7663758ab42e8cb7
- Source
- f0c0ec0dee84e5b8714744a16f8e66399ad66f35a415ad974c409efed4b7bf73
The example source is part of the Kiln repository. Repository licence: MIT.
These GLBs are build outputs of the MIT-licensed example source; no separate terms are stated for the builds.
Recorded authorship
Gemini 3.8 Flash through Antigravity CLI (agy) ·
Recorded Antigravity / gemini-3.8-flash-high run; configured model, no provider-internal attestation. Subsequent rear-panel repair by a Codex maintainer agent is recorded in source history.
- Source access
- Fresh project-local authoring workspace with a brief, installed skills and Kiln tools.
- Inherited context
- Fresh independent authoring conversation.
- Starting example
- None supplied.
- Human input
- Maintainer supplied the brief and reviewed exports. Codex maintainer agent subsequently resized the rear panels to fit within the cabinet faces, matched the walnut finish, and repositioned rear details. Original model source is retained in revision history.
- Authoring review
- Actual GPU images inspected independently. The author repaired grille and dial orientation after image review. Dial markings remain pale; this is a decorative asset, not a functioning radio. Subsequent maintainer repair inspected in actual front and rear GPU images; rear panels no longer protrude beyond the stepped cabinet.
Gallery GPU render of this exact source. The separate poster receipt records image, camera, renderer, and the artifact hash of the GLB bytes the image was rendered from.
Poster camera and render recordThe source behind this build
// Art Deco Radio - Collectible 1930s Cathedral/Waterfall Tabletop Model
const meta = {
name: 'Art Deco Radio',
category: 'prop',
role: 'prop'
};
async function build() {
const root = createRoot('ArtDecoRadio');
// Materials
const walnutMat = gameMaterial(0x4a2a18, { roughness: 0.42, metalness: 0.06 });
const darkWoodMat = gameMaterial(0x23140c, { roughness: 0.48, metalness: 0.04 });
const brassMat = gameMaterial(0xd4af37, { roughness: 0.22, metalness: 0.88 });
const antiqueBrassMat = gameMaterial(0x9e7b2c, { roughness: 0.35, metalness: 0.82 });
const grilleClothMat = gameMaterial(0xc29b38, { roughness: 0.92, metalness: 0.02 });
const dialFaceMat = gameMaterial(0xfcf5e5, { roughness: 0.55, emissive: 0xffd27d, emissiveIntensity: 0.32 });
const dialGlassMat = glassMaterial(0xd8f0ff, { opacity: 0.32, roughness: 0.08 });
const pointerMat = gameMaterial(0xd32f2f, { roughness: 0.30, metalness: 0.10 });
const bakeliteMat = gameMaterial(0x1a120e, { roughness: 0.32, metalness: 0.08 });
const pilotJewelMat = gameMaterial(0xdd1818, { roughness: 0.15, emissive: 0xff2200, emissiveIntensity: 0.75 });
const backPanelMat = walnutMat;
const dialTickMat = gameMaterial(0x2b1c11, { roughness: 0.6 });
// 1. Stepped Plinth Base & Corner Feet
const lowerPlinthGeo = await roundedBoxGeo(0.200, 0.015, 0.340, 0.004, { segments: 32 });
createPart('LowerPlinth', lowerPlinthGeo, darkWoodMat, { position: [0, 0.0075, 0], parent: root });
const plinthBrassGeo = boxGeo(0.194, 0.004, 0.330);
createPart('PlinthBrassTrim', plinthBrassGeo, brassMat, { position: [0, 0.017, 0], parent: root });
const upperPlinthGeo = await roundedBoxGeo(0.186, 0.014, 0.316, 0.0035, { segments: 32 });
createPart('UpperPlinth', upperPlinthGeo, darkWoodMat, { position: [0, 0.026, 0], parent: root });
const footPositions = [
[0.075, 0.003, 0.140],
[0.075, 0.003, -0.140],
[-0.075, 0.003, 0.140],
[-0.075, 0.003, -0.140]
];
footPositions.forEach((pos, idx) => {
const footGeo = cylinderYGeo(0.014, 0.011, 0.006, 32);
createPart(`Foot_${idx + 1}`, footGeo, antiqueBrassMat, { position: pos, parent: root });
const footRingGeo = cylinderYGeo(0.016, 0.016, 0.002, 32);
createPart(`FootRing_${idx + 1}`, footRingGeo, brassMat, { position: [pos[0], 0.005, pos[2]], parent: root });
});
// 2. Stepped Silhouette Cabinet Body
const wingGeo = await roundedBoxGeo(0.165, 0.200, 0.050, 0.014, { segments: 36 });
createPart('LeftWing', wingGeo, walnutMat, { position: [0, 0.133, -0.125], parent: root });
createPart('RightWing', wingGeo, walnutMat, { position: [0, 0.133, 0.125], parent: root });
[-0.151, 0.151].forEach((zSide, sideIdx) => {
[-0.03, 0, 0.03].forEach((yOffset, ribIdx) => {
const ribGeo = cylinderXGeo(0.002, 0.002, 0.12, 16);
createPart(`WingRib_${sideIdx}_${ribIdx}`, ribGeo, brassMat, {
position: [0, 0.133 + yOffset, zSide],
parent: root
});
});
});
const shoulderGeo = await roundedBoxGeo(0.172, 0.280, 0.026, 0.010, { segments: 36 });
createPart('LeftShoulder', shoulderGeo, walnutMat, { position: [0, 0.173, -0.088], parent: root });
createPart('RightShoulder', shoulderGeo, walnutMat, { position: [0, 0.173, 0.088], parent: root });
// Reeded decorative wood pilasters on shoulders
[-0.096, -0.088, -0.080, 0.080, 0.088, 0.096].forEach((zPos, pIdx) => {
const reedGeo = cylinderYGeo(0.002, 0.002, 0.264, 16);
createPart(`ShoulderReed_${pIdx}`, reedGeo, darkWoodMat, {
position: [0.0865, 0.173, zPos],
parent: root
});
});
const centerTowerGeo = await roundedBoxGeo(0.178, 0.347, 0.150, 0.018, { segments: 42 });
createPart('CenterTower', centerTowerGeo, walnutMat, { position: [0, 0.206, 0], parent: root });
// Waterfall Top Brass Speed Ribbons
[-0.038, 0, 0.038].forEach((zPos, rIdx) => {
const topRibbonGeo = boxGeo(0.140, 0.003, 0.003);
createPart(`WaterfallRibbon_${rIdx}`, topRibbonGeo, brassMat, {
position: [0, 0.380, zPos],
parent: root
});
});
[-0.076, 0.076].forEach((zPos, idx) => {
const pillarGeo = cylinderYGeo(0.0035, 0.0035, 0.276, 20);
createPart(`DecoPillar_${idx + 1}`, pillarGeo, brassMat, { position: [0.088, 0.174, zPos], parent: root });
const capGeo = boxGeo(0.010, 0.006, 0.010);
createPart(`PillarCap_${idx + 1}`, capGeo, brassMat, { position: [0.088, 0.314, zPos], parent: root });
const baseGeo = boxGeo(0.010, 0.006, 0.010);
createPart(`PillarBase_${idx + 1}`, baseGeo, brassMat, { position: [0.088, 0.035, zPos], parent: root });
});
const crestTiers = [
{ size: [0.110, 0.005, 0.070], y: 0.382 },
{ size: [0.085, 0.005, 0.048], y: 0.387 },
{ size: [0.055, 0.005, 0.026], y: 0.392 }
];
crestTiers.forEach((tier, idx) => {
const tierGeo = boxGeo(tier.size[0], tier.size[1], tier.size[2]);
createPart(`ApexCrest_${idx + 1}`, tierGeo, brassMat, { position: [0, tier.y, 0], parent: root });
});
// 3. Speaker Grille & Woven Geometric Fretwork
// Open 4-piece stepped brass bezel frame around acoustic aperture (projects from X=0.088 to 0.096)
const grilleFrameT = 0.008;
const grilleTopBar = boxGeo(grilleFrameT, 0.010, 0.124);
createPart('GrilleFrameTop', grilleTopBar, brassMat, { position: [0.092, 0.275 + 0.063, 0], parent: root });
const grilleBotBar = boxGeo(grilleFrameT, 0.010, 0.124);
createPart('GrilleFrameBot', grilleBotBar, brassMat, { position: [0.092, 0.275 - 0.063, 0], parent: root });
const grilleLeftBar = boxGeo(grilleFrameT, 0.116, 0.010);
createPart('GrilleFrameLeft', grilleLeftBar, brassMat, { position: [0.092, 0.275, -0.057], parent: root });
const grilleRightBar = boxGeo(grilleFrameT, 0.116, 0.010);
createPart('GrilleFrameRight', grilleRightBar, brassMat, { position: [0.092, 0.275, 0.057], parent: root });
// Acoustic Fabric Backing (Woven golden cloth sitting cleanly in aperture at X = 0.0898)
const clothGeo = boxGeo(0.002, 0.116, 0.104);
createPart('GrilleCloth', clothGeo, grilleClothMat, { position: [0.0898, 0.275, 0], parent: root });
// Woven cloth weave texture: interwoven vertical warp & horizontal weft bars
[-0.045, -0.038, -0.031, -0.024, -0.017, -0.010, -0.003, 0.004, 0.011, 0.018, 0.025, 0.032, 0.039, 0.046].forEach((zPos, idx) => {
const warpGeo = cylinderYGeo(0.0006, 0.0006, 0.114, 16);
createPart(`GrilleWarp_${idx}`, warpGeo, darkWoodMat, { position: [0.0910, 0.275, zPos], parent: root });
});
[-0.050, -0.040, -0.030, -0.020, -0.010, 0, 0.010, 0.020, 0.030, 0.040, 0.050].forEach((yOff, idx) => {
const weftGeo = cylinderZGeo(0.0006, 0.0006, 0.098, 16);
createPart(`GrilleWeft_${idx}`, weftGeo, grilleClothMat, { position: [0.0916, 0.275 + yOff, 0], parent: root });
});
// Woven-look Chevron Fretwork in front of fabric
const chevronTiers = [0.038, 0.014, -0.010, -0.034];
chevronTiers.forEach((yOff, cIdx) => {
const armGeoL = boxGeo(0.002, 0.0035, 0.048);
createPart(`Chevron_L_${cIdx}`, armGeoL, darkWoodMat, {
position: [0.0926, 0.275 + yOff, -0.024],
rotation: [22, 0, 0],
parent: root
});
const armGeoR = boxGeo(0.002, 0.0035, 0.048);
createPart(`Chevron_R_${cIdx}`, armGeoR, darkWoodMat, {
position: [0.0926, 0.275 + yOff, 0.024],
rotation: [-22, 0, 0],
parent: root
});
});
// Vertical brass speedbars over the chevron fretwork
[-0.022, 0, 0.022].forEach((zPos, idx) => {
const barGeo = cylinderYGeo(0.0018, 0.0018, 0.114, 16);
createPart(`GrilleCenterBar_${idx}`, barGeo, brassMat, { position: [0.0938, 0.275, zPos], parent: root });
});
// Brass Diamond Medallion in center of grille
const medallionGeo = boxGeo(0.0035, 0.018, 0.018);
createPart('GrilleMedallion', medallionGeo, brassMat, { position: [0.0948, 0.275, 0], rotation: [45, 0, 0], parent: root });
// 4. Inset Glass Tuning Dial & Animated Pointer
// Stepped brass bezel frame projecting from X = 0.089 to 0.098
const dialFrameT = 0.009;
const dialTopBar = boxGeo(dialFrameT, 0.010, 0.114);
createPart('DialFrameTop', dialTopBar, brassMat, { position: [0.0935, 0.165 + 0.028, 0], parent: root });
const dialBotBar = boxGeo(dialFrameT, 0.010, 0.114);
createPart('DialFrameBot', dialBotBar, brassMat, { position: [0.0935, 0.165 - 0.028, 0], parent: root });
const dialLeftBar = boxGeo(dialFrameT, 0.046, 0.011);
createPart('DialFrameLeft', dialLeftBar, brassMat, { position: [0.0935, 0.165, -0.051], parent: root });
const dialRightBar = boxGeo(dialFrameT, 0.046, 0.011);
createPart('DialFrameRight', dialRightBar, brassMat, { position: [0.0935, 0.165, 0.051], parent: root });
// Recessed Illuminated Dial Face Backplate (sitting cleanly at X = 0.0902)
const dialFaceGeo = boxGeo(0.002, 0.046, 0.090);
createPart('DialFace', dialFaceGeo, dialFaceMat, { position: [0.0902, 0.165, 0], parent: root });
// Dial Frequency Scale Markings (crisp station bands)
const scaleLineAM = boxGeo(0.001, 0.0018, 0.076);
createPart('ScaleLineAM', scaleLineAM, dialTickMat, { position: [0.0912, 0.176, 0], parent: root });
const scaleLineSW = boxGeo(0.001, 0.0018, 0.076);
createPart('ScaleLineSW', scaleLineSW, dialTickMat, { position: [0.0912, 0.154, 0], parent: root });
for (let t = -8; t <= 8; t++) {
const isMajor = t % 2 === 0;
const tickH = isMajor ? 0.006 : 0.0035;
const tickGeo = boxGeo(0.001, tickH, 0.0012);
createPart(`DialTick_${t + 8}`, tickGeo, dialTickMat, {
position: [0.0912, 0.176 - (isMajor ? 0.0025 : 0.001), t * 0.0044],
parent: root
});
}
// Animated Tuning Pointer (mounted on Joint_TuningPointer, swinging at X = 0.0924)
const pointerPivot = createPivot('TuningPointer', [0.0924, 0.144, 0], root);
const needleArmGeo = boxGeo(0.0014, 0.034, 0.0018);
createPart('NeedleArm', needleArmGeo, pointerMat, { position: [0, 0.017, 0], parent: pointerPivot });
const needleTipGeo = cylinderYGeo(0.0006, 0.0018, 0.006, 12);
createPart('NeedleTip', needleTipGeo, pointerMat, { position: [0, 0.034, 0], parent: pointerPivot });
const pointerHubGeo = cylinderXGeo(0.004, 0.004, 0.0025, 24);
createPart('NeedleHub', pointerHubGeo, brassMat, { position: [0, 0, 0], parent: pointerPivot });
// Protective Inset Dial Glass (recessed inside bezel at X = 0.0945)
const glassGeo = boxGeo(0.0015, 0.046, 0.090);
createPart('DialGlass', glassGeo, dialGlassMat, { position: [0.0945, 0.165, 0], parent: root });
// 5. Tactile Differentiated Knobs
// Center Tuning Knob (with 18 flutes and brass cap, animated on Joint_TuningKnob)
const tuningKnobPivot = createPivot('TuningKnob', [0.092, 0.076, 0], root);
const centerBezelGeo = cylinderXGeo(0.017, 0.017, 0.003, 28);
createPart('TuningKnobBezel', centerBezelGeo, brassMat, { position: [0.0015, 0, 0], parent: tuningKnobPivot });
const centerBodyGeo = cylinderXGeo(0.0145, 0.0155, 0.014, 28);
createPart('TuningKnobBody', centerBodyGeo, bakeliteMat, { position: [0.008, 0, 0], parent: tuningKnobPivot });
const fluteCount = 24;
for (let f = 0; f < fluteCount; f++) {
const angle = (f * (360 / fluteCount)) * (Math.PI / 180);
const fluteGeo = cylinderXGeo(0.0013, 0.0013, 0.012, 14);
createPart(`TuningFlute_${f}`, fluteGeo, bakeliteMat, {
position: [0.008, 0.0152 * Math.cos(angle), 0.0152 * Math.sin(angle)],
parent: tuningKnobPivot
});
}
const centerCapGeo = cylinderXGeo(0.009, 0.009, 0.002, 28);
createPart('TuningCap', centerCapGeo, brassMat, { position: [0.015, 0, 0], parent: tuningKnobPivot });
const tuningPipGeo = boxGeo(0.002, 0.003, 0.0015);
createPart('TuningPip', tuningPipGeo, pointerMat, { position: [0.0158, 0.006, 0], parent: tuningKnobPivot });
// Left Knob: Dual-Concentric Volume / Tone Knob
const leftKnobBaseGeo = cylinderXGeo(0.013, 0.014, 0.008, 24);
createPart('VolumeKnobBase', leftKnobBaseGeo, darkWoodMat, { position: [0.094, 0.076, -0.054], parent: root });
const leftKnobBrassRim = cylinderXGeo(0.0142, 0.0142, 0.0025, 24);
createPart('VolumeKnobRim', leftKnobBrassRim, brassMat, { position: [0.0985, 0.076, -0.054], parent: root });
const leftKnobInnerGeo = cylinderXGeo(0.0075, 0.008, 0.015, 20);
createPart('VolumeKnobInner', leftKnobInnerGeo, bakeliteMat, { position: [0.103, 0.076, -0.054], parent: root });
const leftKnobCapGeo = cylinderXGeo(0.005, 0.005, 0.002, 20);
createPart('VolumeKnobCap', leftKnobCapGeo, brassMat, { position: [0.111, 0.076, -0.054], parent: root });
// Right Knob: Art Deco Teardrop Band Selector Knob
const rightKnobHubGeo = cylinderXGeo(0.012, 0.0125, 0.009, 24);
createPart('SelectorKnobHub', rightKnobHubGeo, bakeliteMat, { position: [0.094, 0.076, 0.054], parent: root });
const rightPointerArm = boxGeo(0.007, 0.016, 0.005);
createPart('SelectorPointerArm', rightPointerArm, bakeliteMat, {
position: [0.097, 0.082, 0.058],
rotation: [30, 0, 0],
parent: root
});
const rightKnobCap = cylinderXGeo(0.006, 0.006, 0.002, 20);
createPart('SelectorKnobCap', rightKnobCap, brassMat, { position: [0.101, 0.076, 0.054], parent: root });
// 6. Fine Details
const lampBezelGeo = cylinderXGeo(0.0055, 0.0055, 0.003, 16);
createPart('PilotLampBezel', lampBezelGeo, brassMat, { position: [0.090, 0.114, 0], parent: root });
const jewelGeo = cylinderXGeo(0.0035, 0.002, 0.003, 14);
createPart('PilotJewel', jewelGeo, pilotJewelMat, { position: [0.092, 0.114, 0], parent: root });
const plaqueGeo = boxGeo(0.002, 0.009, 0.042);
createPart('BrandPlaque', plaqueGeo, brassMat, { position: [0.090, 0.048, 0], parent: root });
const plaqueInlayGeo = boxGeo(0.001, 0.006, 0.036);
createPart('BrandPlaqueInlay', plaqueInlayGeo, darkWoodMat, { position: [0.0912, 0.048, 0], parent: root });
// Center rear panel fitting stepped cabinet silhouette
const backBoardGeo = boxGeo(0.004, 0.298, 0.112);
createPart('BackPanel', backBoardGeo, backPanelMat, { position: [-0.089, 0.1995, 0], parent: root });
// Wing rear panels matching stepped flanks
[-0.125, 0.125].forEach((zPos, idx) => {
const wingBackGeo = boxGeo(0.004, 0.162, 0.020);
createPart(`WingBack_${idx}`, wingBackGeo, backPanelMat, { position: [-0.0825, 0.133, zPos], parent: root });
});
for (let v = 0; v < 5; v++) {
const louverGeo = boxGeo(0.002, 0.005, 0.100);
createPart(`BackLouver_${v}`, louverGeo, darkWoodMat, { position: [-0.092, 0.230 - v * 0.018, 0], parent: root });
}
const grommetGeo = cylinderXGeo(0.006, 0.006, 0.004, 16);
createPart('PowerGrommet', grommetGeo, bakeliteMat, { position: [-0.092, 0.062, 0.040], parent: root });
return root;
}
function animate(root) {
const pointerTrack = rotationTrack('Joint_TuningPointer', [
{ time: 0.0, rotation: [-24, 0, 0] },
{ time: 1.2, rotation: [10, 0, 0] },
{ time: 2.2, rotation: [26, 0, 0] },
{ time: 3.0, rotation: [-8, 0, 0] },
{ time: 4.0, rotation: [-24, 0, 0] }
]);
const knobTrack = rotationTrack('Joint_TuningKnob', [
{ time: 0.0, rotation: [0, 0, 0] },
{ time: 1.2, rotation: [240, 0, 0] },
{ time: 2.2, rotation: [480, 0, 0] },
{ time: 3.0, rotation: [160, 0, 0] },
{ time: 4.0, rotation: [0, 0, 0] }
]);
return [createClip('Tune', 4.0, [pointerTrack, knobTrack])];
}Scroll code horizontally
Brief and retained revisions
Brief summary
Create a collectible Art Deco radio with a rounded walnut cabinet, brass trim, a geometric speaker grille, an inset tuning dial and animated controls.
Initial design
First retained radio. Solid bezel faces obscured the dial and grille, and several decorative bars extended beyond the cabinet.
Download initial design sourceSHA-256: f2989a63a016b89ed7dc0704537b33c3dda9969f59ee0b759ddff3e620c8b96b
Frame and cabinet repair
Opened the bezel frames, contained the grille bars and fitted the rear panels to the stepped cabinet.
Download frame and cabinet repair sourceSHA-256: 98e5e0acc662589323030271bc1cf44987890c33c4228ad1bd3f1d0a7cea1d49
Dial and grille revision
Moved the dial and grille layers in front of the cabinet surface and added fluting to the controls and shoulders.
Download dial and grille revision sourceSHA-256: ce748f8b92d155134d6f06938e17d189663418f16d2c0a09afa05ab5cdf80c52
Final Gemini authoring revision
Added woven grille bars, detailed feet and finer tuning-knob flutes. The tuning scale uses marks rather than numeric labels.
Download final gemini authoring revision sourceSHA-256: d79eec971bd3199993b8af63673f17feb0b968d91745873ad032927ea48a9241
Maintainer rear-panel fit and finish · Shown here
Codex maintainer agent resized the three rear panels to stay inside the flat cabinet faces, matched their walnut material, and repositioned the louvers and power grommet. Actual front and rear GPU views inspected. Original dial and control animation retained.
Download maintainer rear-panel fit and finish sourceSHA-256: f0c0ec0dee84e5b8714744a16f8e66399ad66f35a415ad974c409efed4b7bf73