Skip to content
Kiln1.3Get Kiln

Original worn handheld flashlight with authored grip, lens and beam sockets. Runtime light belongs to the scene.

Cabin in the Woods: PSX Horror pack
Original worn handheld flashlight with authored grip, lens and beam sockets. Runtime light belongs to the scene.

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
250
Meshes
2
Materials
2
Dimensions (m)
0.21 × 0.05 × 0.05

Full Kiln assets (remixable)

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

82,462 bytes (0.08 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_b006392179ec455e94b3fab12d017815 / r_0f129d3f232b40f8b9b12e92b7eab31e
Source SHA-256
9b96929bdf1bfdaf65cde20dda015820547226c1364466a8be74ba37ea427366
Handheld flashlight: exact saved source
const BODY={"schemaVersion": 3, "model": "pbrMetallicRoughness", "name": "Worn handheld flashlight olive metal and rubber", "roughness": 0.78, "metalness": 0.16, "emissiveIntensity": 1, "alphaMode": "opaque", "alphaCutoff": 0.5, "doubleSided": false, "textures": {"baseColor": {"kind": "resource", "resourceId": "kiln.library.9a45e6f3ebb2e469e919aca3df78e60c6ea6ddbe9809907b0889c63eae05a167.base-color", "sampler": {"minFilter": "nearest", "magFilter": "nearest", "wrapS": "clamp-to-edge", "wrapT": "clamp-to-edge"}}}};
const GLASS={"schemaVersion": 3, "model": "pbrMetallicRoughness", "name": "Recessed flashlight glass", "roughness": 0.22, "metalness": 0, "emissiveIntensity": 1, "alphaMode": "opaque", "alphaCutoff": 0.5, "doubleSided": false, "textures": {"baseColor": {"kind": "resource", "resourceId": "kiln.library.9a45e6f3ebb2e469e919aca3df78e60c6ea6ddbe9809907b0889c63eae05a167.base-color", "sampler": {"minFilter": "nearest", "magFilter": "nearest", "wrapS": "clamp-to-edge", "wrapT": "clamp-to-edge"}}}};
const meta={name:'Handheld flashlight',role:'prop'};
// Compact faceted rural torch. +X is the physical lens normal/beam direction.
const PROFILE=[[-.078,.017],[-.074,.020],[-.060,.020],[-.056,.019],[-.052,.020],[.027,.020],[.031,.019],[.066,.019],[.084,.024],[.112,.025],[.127,.025]];
function buffer(){return {p:[],uv:[]};}
function tri(o,p,uv){for(let k=0;k<3;k++){o.p.push(...p[k]);o.uv.push(...uv[k]);}}
function quad(o,p,uv){tri(o,[p[0],p[1],p[2]],[uv[0],uv[1],uv[2]]);tri(o,[p[0],p[2],p[3]],[uv[0],uv[2],uv[3]]);}
function ring(x,r){return Array.from({length:8},(_,k)=>{const a=k*2*Math.PI/8;return[x,Math.cos(a)*r,Math.sin(a)*r];});}
function cap(o,x,r,reverse=false,region=[.52,.98]){const q=ring(x,r);for(let k=1;k<7;k++){const ids=reverse?[0,k+1,k]:[0,k,k+1];tri(o,ids.map(i=>q[i]),ids.map(i=>[.5+.45*Math.cos(i*2*Math.PI/8),region[0]+(region[1]-region[0])*(.5+.45*Math.sin(i*2*Math.PI/8))]));}}
function casing(o){const rings=PROFILE.map(([x,r])=>ring(x,r));for(let k=0;k<rings.length-1;k++)for(let i=0;i<8;i++){const q=(i+1)%8,grip=PROFILE[k][0]>=-.052&&PROFILE[k+1][0]<=.027,lo=grip?.26:.52,hi=grip?.49:.98;quad(o,[rings[k][i],rings[k][q],rings[k+1][q],rings[k+1][i]],[[i/8,lo],[(i+1)/8,lo],[(i+1)/8,hi],[i/8,hi]]);}cap(o,-.078,.017,true);
 const outer=ring(.127,.025),inner=ring(.127,.0193),back=ring(.117,.0193);for(let k=0;k<8;k++){const q=(k+1)%8;quad(o,[outer[k],outer[q],inner[q],inner[k]],[[k/8,.87],[q/8,.87],[q/8,.73],[k/8,.73]]);quad(o,[inner[k],inner[q],back[q],back[k]],[[k/8,.55],[q/8,.55],[q/8,.60],[k/8,.60]]);}
}
function box(o,min,max,region){const v=[];for(let x of [min[0],max[0]])for(let y of [min[1],max[1]])for(let z of [min[2],max[2]])v.push([x,y,z]);for(const f of [[0,1,3,2],[4,6,7,5],[0,4,5,1],[2,3,7,6],[0,2,6,4],[1,5,7,3]])quad(o,f.map(k=>v[k]),[[.1,region[0]],[.9,region[0]],[.9,region[1]],[.1,region[1]]]);}
function mesh(o,name,material,root){const g=new THREE.BufferGeometry();g.setAttribute('position',new THREE.Float32BufferAttribute(o.p,3));g.setAttribute('uv',new THREE.Float32BufferAttribute(o.uv.map((v,i)=>i%2?1-v:v),2));g.computeVertexNormals();const m=new THREE.Mesh(g,material);m.name=name;root.add(m);return m;}
function socket(root,name,pos){const s=new THREE.Object3D();s.name=name;s.position.set(...pos);root.add(s);return s;}
async function build(){const root=createRoot('HandheldFlashlight'),metal=await compilePortableMaterialSpecV3(BODY),glass=await compilePortableMaterialSpecV3(GLASS),body=buffer(),lens=buffer();casing(body);box(body,[.031,.0188,-.006],[.053,.023,.006],[.52,.98]);box(body,[.035,.023,-.0045],[.048,.0253,.0045],[.26,.49]);cap(lens,.119,.0194,false,[.02,.23]);cap(lens,.117,.0194,true,[.02,.23]);const a=ring(.117,.0194),b=ring(.119,.0194);for(let i=0;i<8;i++){const q=(i+1)%8;quad(lens,[a[i],a[q],b[q],b[i]],[[.05,.02],[.95,.02],[.95,.23],[.05,.23]]);}const shell=mesh(body,'Flashlight_CasingGripToggle',metal,root);markOpenShell(shell,'Intentional lens-seat opening closed visually by the separate recessed lens; hollow bezel is not a single closed manufacturing solid.');mesh(lens,'Flashlight_RecessedLens',glass,root);socket(root,'grip_left',[0,0,0]);socket(root,'lens',[.119,0,0]);socket(root,'beam_origin',[.129,0,0]);root.userData.flashlight={version:1,axes:'+X lens/beam, +Y up, +Z right',grip:'grip_left',frontLens:'lens',beamOrigin:'beam_origin',gripBandRangeX:[-.052,.027],lensSurfaceX:.119,bezelFrontX:.127,pivot:'hand attachment; not grounded',runtimeOnly:'Light visibility and illumination are controlled by scene code; no baked light.'};return root;}

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