Skip to content
Kiln1.3Get Kiln

Original fitted PSX cabin furnishing with procedural pixel textures.

Cabin in the Woods: PSX Horror pack
Original fitted PSX cabin furnishing with procedural pixel textures.

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.

Triangles
684
Meshes
30
Materials
5
Dimensions (m)
0.22 × 0.31 × 0.70

Runtime assets

Models, textures and animations prepared for use in a scene or application.

10,959 bytes (0.01 MB)

Download runtime assets

Full Kiln assets (remixable)

Models plus Kiln source, editing metadata, materials and included revisions, so you can reopen and continue editing.

63,344 bytes (0.06 MB)

Download full kiln assets (remixable)

Runtime includes the GLB and metadata sidecar. The editable ZIP contains this selected revision and its complete material closure. Parent revision identifiers are retained; earlier authoring history is deliberately not distributed in this initial pack.

Import this ZIP into Kiln’s Library, or run node kiln.mjs import asset.zip in an authoring workspace. The full model, exact source, editing metadata, preview and material resources are included so you can reopen and remix it.

Use an importing Kiln build that supports the included material schemas. Use Kiln 1.2.3 or later.

Collection / asset / revision
project / a_b73b3fb4f25948509b941aa871157256 / r_2f39fecba5634b46805f472e7615d7fd
Source SHA-256
8181181ec76c68b644a013d270bcd072ac2a7e5f06a2a3ecc9d5e059b85a44e2
Cabin radio and reading table dressing: exact saved source
const meta={name:"Cabin radio and reading table dressing",description:'Original PSX cabin-v2 wall or tabletop furnishing; fitted functional geometry and original cabin immutable material maps.'};const ITEM="tabletopDressing",SPECS={"tx02":{"schemaVersion":3,"model":"pbrMetallicRoughness","name":"Warm interior boards","baseColor":16777215,"roughness":1,"metalness":0,"emissiveIntensity":1,"alphaMode":"opaque","alphaCutoff":0.5,"doubleSided":false,"textures":{"baseColor":{"kind":"resource","resourceId":"kiln.library.d86eb2087a7bd4edbe734e603bc6b8180220e751bc0e5244d80c696b566dfc26.base-color","sampler":{"minFilter":"nearest-mipmap-linear","magFilter":"nearest","wrapS":"repeat","wrapT":"repeat"}}}},"tx08":{"schemaVersion":3,"model":"pbrMetallicRoughness","name":"Worn iron","baseColor":16777215,"roughness":0.85,"metalness":0.25,"emissiveIntensity":1,"alphaMode":"opaque","alphaCutoff":0.5,"doubleSided":false,"textures":{"baseColor":{"kind":"resource","resourceId":"kiln.library.1870a95ffec8e00bc9daac56a32bc537547e002305e373c4ff7a97f098119fbe.base-color","sampler":{"minFilter":"nearest-mipmap-linear","magFilter":"nearest","wrapS":"repeat","wrapT":"repeat"}}}},"tx09":{"schemaVersion":3,"model":"pbrMetallicRoughness","name":"CRT olive enamel","baseColor":16777215,"roughness":0.85,"metalness":0,"emissiveIntensity":1,"alphaMode":"opaque","alphaCutoff":0.5,"doubleSided":false,"textures":{"baseColor":{"kind":"resource","resourceId":"kiln.library.c93242eb798477b337836583041d305076ffe53b051abc78ba592be6803105c5.base-color","sampler":{"minFilter":"nearest-mipmap-linear","magFilter":"nearest","wrapS":"repeat","wrapT":"repeat"}}}}};
async function build(){const root=createRoot('CabinV2_'+ITEM),m={};for(const[k,s]of Object.entries(SPECS))m[k]=await compilePortableMaterialSpecV3(s);const wood=m.tx02,iron=m.tx08,enamel=m.tx09??iron;const black=new THREE.MeshStandardMaterial({color:0x222923,roughness:1}),cover=new THREE.MeshStandardMaterial({color:0x465544,roughness:.95});
function anchor(n,p){const a=new THREE.Object3D();a.name=n;a.position.fromArray(p);root.add(a);return a;}
function grain(g,axis='Z',phase=0){const p=g.getAttribute('position'),n=g.getAttribute('normal'),uv=g.getAttribute('uv'),get=(a,i)=>a==='X'?p.getX(i):a==='Y'?p.getY(i):p.getZ(i);for(let i=0;i<p.count;i++){const N=[Math.abs(n.getX(i)),Math.abs(n.getY(i)),Math.abs(n.getZ(i))],d=['X','Y','Z'][N.indexOf(Math.max(...N))],v=['X','Y','Z'].find(a=>a!==axis&&a!==d)??(axis==='Y'?'Z':'Y'),u=d===axis?['X','Y','Z'].find(a=>a!==d&&a!==v):axis;uv.setXY(i,get(u,i)*.5+.4+phase,get(v,i)*.5+.13+phase*1.73);}return g;}
function box(n,size,pos,mat=wood,axis='Z',phase=0){return createPart(n,grain(boxGeo(...size).clone(),axis,phase),mat,{parent:root,position:pos});}
function cyl(n,r,h,pos,mat=iron,rotation=[0,0,0],rTop=r){return createPart(n,cylinderGeo(rTop,r,h,12),mat,{parent:root,position:pos,rotation});}
function beam(n,a,b,width=.012,mat=iron){const A=new THREE.Vector3(...a),B=new THREE.Vector3(...b),v=B.clone().sub(A),part=createPart(n,grain(boxGeo(width,v.length(),width).clone(),'Y'),mat,{parent:root,position:A.clone().add(B).multiplyScalar(.5).toArray()});part.quaternion.setFromUnitVectors(new THREE.Vector3(0,1,0),v.normalize());return part;}
function ring(n,r,t,pos,mat=iron,rotation=[0,0,0],arc=Math.PI*2){return createPart(n,new THREE.TorusGeometry(r,t,4,12,arc),mat,{parent:root,position:pos,rotation});}
async function pixel(name,w,h,bg,ops=[]){return compilePortableMaterialSpecV3({schemaVersion:3,model:'pbrMetallicRoughness',name,roughness:1,textures:{baseColor:{kind:'procedural',spec:{schemaVersion:3,width:w,height:h,usage:'albedo',background:bg,operations:ops},sampler:{minFilter:'nearest',magFilter:'nearest',wrapS:'clamp-to-edge',wrapT:'clamp-to-edge'}}}});}
const paper=await pixel('Original worn paper',16,16,[185,181,153,255],[4,8,12].map(y=>({op:'paint',shape:{kind:'rectangle',x:0,y,width:16,height:1},rgba:[150,149,130,255]})));
function book(n,pos){createPart(n+'Pages',boxGeo(.15,.035,.10),paper,{parent:root,position:[pos[0],pos[1]+.0215,pos[2]]});box(n+'LowerCover',[.165,.004,.112],[pos[0],pos[1]+.002,pos[2]],cover);box(n+'UpperCover',[.165,.004,.112],[pos[0],pos[1]+.041,pos[2]],cover);box(n+'Spine',[.008,.043,.112],[pos[0]-.08,pos[1]+.0215,pos[2]],cover);}
function mug(n,x,z,r=.034){createPart(n+'HollowWall',new THREE.CylinderGeometry(r,r*.87,.078,12,1,true),enamel,{parent:root,position:[x,.039,z]});cyl(n+'Bottom',r*.89,.004,[x,.002,z],enamel);ring(n+'Lip',r,.003,[x,.078,z],iron,[90,0,0]);ring(n+'Handle',.024,.004,[x+.043,.047,z],enamel,[0,0,0]);cyl(n+'Coffee',r*.85,.001,[x,.065,z],black);}
if(ITEM==='wallShelf'){box('ShelfPlank',[.25,.026,.8],[0,.237,0],wood,'Z',.17);for(const z of[-.29,.29]){beam('BracketUpright_'+z,[-.114,0,z],[-.114,.226,z],.025);beam('BracketArm_'+z,[-.114,.216,z],[.105,.216,z],.025);beam('BracketDiagonal_'+z,[-.114,.030,z],[.10,.209,z],.018);cyl('MountBolt_'+z,.009,.012,[-.099,.08,z],iron,[0,0,-90]);}anchor('wall_mount',[-.126,.125,0]);anchor('shelf_support',[0,.25,0]);}
else if(ITEM==='toolRack'){box('MountRail',[.028,.13,.90],[-.075,.325,0],wood,'Z',.2);for(const z of[-.33,.33]){cyl('RailBolt_'+z,.008,.01,[-.057,.325,z],iron,[0,0,-90]);beam('CradleArm_'+z,[-.061,.285,z],[.108,.285,z],.018);beam('CradleLip_'+z,[.108,.285,z],[.108,.342,z],.018);box('LeatherPad_'+z,[.07,.014,.026],[.079,.3,z],cover);}for(const z of[-.12,.12]){beam('UtilityHook_'+z,[-.06,.315,z],[.055,.315,z]);beam('UtilityHookTip_'+z,[.055,.315,z],[.055,.35,z]);}box('LowerRail',[.028,.07,.68],[-.075,.035,0]);anchor('wall_mount',[-.089,.21,0]);anchor('axe_support',[.05,.304,-.33]);anchor('shotgun_support',[.05,.304,.33]);root.userData.supportPolicy='Mount supports only; scene aligns actual tool grip/model to cradle. No tools duplicated in asset.';}
else if(ITEM==='mapCoatHooks'){const ops=[];for(let i=0;i<7;i++)ops.push({op:'paint',shape:{kind:'line',from:[5,7+i*7],to:[58,12+i*6],width:1},rgba:[141,146,113,255]});for(let i=0;i<5;i++)ops.push({op:'paint',shape:{kind:'line',from:[8+i*7,5],to:[13+i*8,60],width:1},rgba:[152,156,124,255]});ops.push({op:'paint',shape:{kind:'line',from:[10,49],to:[49,18],width:2},rgba:[81,99,115,255]},{op:'paint',shape:{kind:'rectangle',x:31,y:28,width:5,height:4},rgba:[98,70,53,255]},{op:'paint',shape:{kind:'rectangle',x:48,y:10,width:2,height:8},rgba:[54,65,51,255]},{op:'paint',shape:{kind:'line',from:[44,14],to:[53,14],width:1},rgba:[54,65,51,255]});const map=await pixel('Original fictional cabin route map',64,64,[186,181,144,255],ops);box('MapBack',[.022,.48,.72],[-.029,.51,0]);createPart('PrintedMap',boxGeo(.005,.404,.636),map,{parent:root,position:[-.014,.51,0]});for(const z of[-.34,.34])box('MapFrameSide_'+z,[.022,.48,.04],[-.005,.51,z],wood,'Y',.2);for(const y of[.29,.73])box('MapFrameRail_'+y,[.022,.04,.68],[-.005,y,0],wood,'Z',.1);box('CoatPegRail',[.035,.075,.65],[-.015,.14,0]);for(const z of[-.22,0,.22]){beam('HookStem_'+z,[.005,.14,z],[.055,.08,z],.016);beam('HookTip_'+z,[.055,.08,z],[.067,.123,z],.016);cyl('HookPlate_'+z,.014,.008,[.008,.14,z],iron,[0,0,-90]);}anchor('wall_mount',[-.04,.375,0]);root.userData.map='Original fictional contour/river/cabin marks, no external map or gameplay navigation claim';}
else if(ITEM==='clock'){const ops=[];for(let i=0;i<12;i++){const a=i*Math.PI/6;ops.push({op:'paint',shape:{kind:'line',from:[Math.round(31+23*Math.sin(a)),Math.round(31-23*Math.cos(a))],to:[Math.round(31+27*Math.sin(a)),Math.round(31-27*Math.cos(a))],width:i%3===0?2:1},rgba:[61,66,52,255]});}const dial=await pixel('Original twelve tick clock dial',64,64,[186,180,148,255],ops);cyl('FacetedClockCase',.18,.065,[0,.18,0],wood,[0,0,-90]);const face=createPart('Dial',new THREE.CircleGeometry(.151,12),dial,{parent:root,position:[.034,.18,0],rotation:[0,90,0]});ring('IronBezel',.155,.007,[.037,.18,0],iron,[0,90,0]);beam('HourHand',[.047,.18,0],[.047,.247,-.037],.009,black);beam('MinuteHand',[.048,.18,0],[.048,.107,.076],.006,black);cyl('CentrePin',.011,.008,[.053,.18,0],iron,[0,0,-90]);anchor('wall_mount',[-.0325,.18,0]);root.userData.clock='Static authored dial 10:22; not runtime timer';}
else if(ITEM==='torchBracket'){box('MountPlate',[.016,.36,.10],[-.088,.18,0],iron,'Y');for(const y of[.038,.322])cyl('MountBolt_'+y,.009,.010,[-.073,y,0],iron,[0,0,-90]);beam('LowerArm',[-.075,.055,0],[.060,.055,0],.022);beam('DiagonalBrace',[-.075,.24,0],[.060,.060,0],.016);ring('RetainingCollar',.053,.008,[.060,.28,0],iron,[90,0,0]);for(const z of[-.036,.036])beam('CollarSupport_'+z,[-.075,.27,z],[.04,.27,z],.013);cyl('BaseCup',.036,.028,[.06,.082,0],iron);anchor('wall_mount',[-.096,.18,0]);anchor('torch_support',[.06,.096,0]);root.userData.supportPolicy='Bracket only; separate carried torch geometry/gameplay deferred';}
else if(ITEM==='tabletopDressing'){box('RadioEnclosure',[.13,.19,.28],[-.06,.109,-.26],enamel);box('RadioFeetLeft',[.11,.014,.022],[-.06,.007,-.36],iron);box('RadioFeetRight',[.11,.014,.022],[-.06,.007,-.16],iron);box('SpeakerInset',[.007,.126,.13],[.008,.104,-.308],black);for(let i=0;i<6;i++)box('SpeakerSlat_'+i,[.010,.004,.122],[.013,.053+i*.020,-.308],iron);box('TunerScale',[.009,.038,.083],[.014,.158,-.188],paper);for(const y of[.057,.101])cyl('TunerKnob_'+y,.014,.015,[.022,y,-.182],iron,[0,0,-90]);beam('RadioHandleLeft',[-.06,.206,-.37],[-.06,.242,-.37],.014);beam('RadioHandleTop',[-.06,.242,-.37],[-.06,.242,-.15],.014);beam('RadioHandleRight',[-.06,.242,-.15],[-.06,.206,-.15],.014);beam('Aerial',[-.095,.204,-.165],[-.075,.305,-.145],.004);mug('ReadingMug',.015,.045);book('Diary',[-.015,0,.21]);book('FieldBook',[.015,.043,.245]);anchor('tabletop_support',[0,0,0]);root.userData.supportPolicy='Entire group bottom Y0; place on table_support .78, not floor';}
else if(ITEM==='kitchenDressing'){cyl('KettleBody',.074,.134,[-.045,.069,-.27],enamel,[0,0,0],.064);cyl('KettleLid',.068,.007,[-.045,.139,-.27],iron);cyl('LidKnob',.012,.016,[-.045,.15,-.27],cover);ring('KettleBail',.090,.006,[-.045,.162,-.27],iron,[0,0,0],Math.PI);beam('SpoutLower',[-.015,.07,-.27],[.067,.111,-.27],.036,enamel);beam('SpoutTip',[.067,.111,-.27],[.105,.143,-.27],.026,enamel);cyl('SpoutOpening',.009,.002,[.109,.148,-.27],black,[0,0,-55]);mug('WorkMug',-.025,.02);mug('GuestMug',.065,.11);for(const[z,h]of[[.32,.12],[.42,.095]]){cyl('FoodTin_'+z,.039,h,[-.052,h/2,z],iron);ring('TinRim_'+z,.039,.003,[-.052,h,z],iron,[90,0,0]);box('PaperTinLabel_'+z,[.001,.055,.054],[-.012,h*.5,z],paper);}book('KitchenNotes',[.032,0,.32]);anchor('tabletop_support',[0,0,0]);root.userData.supportPolicy='Bottom Y0; support on worktop .88; hollow mugs and shut kettle. No plumbing or stove claim';}
else throw Error('Unknown');const bounds=new THREE.Box3().setFromObject(root),centre=bounds.getCenter(new THREE.Vector3()),shift=new THREE.Vector3(centre.x,bounds.min.y,centre.z);for(const child of root.children)child.position.sub(shift);root.userData.originNormalization=shift.toArray();root.userData.furnishing={version:1,kind:ITEM,frame:{forward:'+X',up:'+Y',right:'+Z'},origin:ITEM.endsWith('Dressing')?'support-centred':'bottom-centred',wallMount:!ITEM.endsWith('Dressing'),textureDensity:'Original timber64texels/m, purposefully varied deterministic sampling; labels16 or64pixel islands'};return root;}

Asset content follows the supplied CC0-1.0 licence record. Kiln and scene software retain their own licences.