Loading skill
Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Create a real 3D WebGL object with geometric mesh depth, physically based material, directional and ambient lighting, perspective camera, subtle rotation, and floating motion. Use when a page needs a faceted 3D hero object or product-like visual with real lighting instead of CSS transform tricks.
| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-08 | ✗→✓ | ▲ Improved | 11% | 0% |
| case-02 | ✗→✓ | ▲ Improved | -9% | 0% |
| case-09 | ✗→✓ | ▲ Improved | 142% | 0% |
| case-10 | ✗→✓ | ▲ Improved | 57% | 0% |
| case-15 | ✗→✓ | ▲ Improved | 18% | 0% |
IcosahedronGeometry, DodecahedronGeometry, BoxGeometry, custom BufferGeometry, or a glTF mesh.MeshStandardMaterial or MeshPhysicalMaterial.metalness, roughness, and emissive to match the brand mood.html<div class="webgl-object-shell"> <canvas class="webgl-object-canvas" data-webgl-3d-object></canvas> </div>
css.webgl-object-shell { position: relative; width: min(100%, 720px); aspect-ratio: 1 / 1; } .webgl-object-canvas { position: absolute; inset: 0; width: 100%; height: 100%; display: block; }
jsimport * as THREE from "three"; function initWebGL3DObject(canvas, options = {}) { if (!canvas) return () => {}; const renderer = new THREE.WebGLRenderer({ canvas, antialias: true, alpha: true, }); renderer.setClearColor(0x000000, 0); renderer.setPixelRatio(Math.min(window.devicePixelRatio || 1, options.maxDpr || 1.75)); renderer.outputColorSpace = THREE.SRGBColorSpace; renderer.toneMapping = THREE.ACESFilmicToneMapping; renderer.toneMappingExposure = options.exposure || 1.05; renderer.shadowMap.enabled = true; renderer.shadowMap.type = THREE.PCFSoftShadowMap; const scene = new THREE.Scene(); const camera = new THREE.PerspectiveCamera(38, 1, 0.1, 100); camera.position.set(0, 0.15, 5.2); const geometry = new THREE.IcosahedronGeometry(options.radius || 1.35, options.detail || 1); const material = new THREE.MeshStandardMaterial({ color: options.color || 0x8aa4ff, metalness: options.metalness ?? 0.48, roughness: options.roughness ?? 0.34, emissive: options.emissive || 0x101833, emissiveIntensity: options.emissiveIntensity ?? 0.22, flatShading: true, }); const object = new THREE.Mesh(geometry, material); object.castShadow = true; object.receiveShadow = true; scene.add(object); const ambient = new THREE.AmbientLight(0xffffff, 0.38); scene.add(ambient); const key = new THREE.DirectionalLight(0xffffff, 2.15); key.position.set(3.4, 4.2, 4.8); key.castShadow = true; key.shadow.mapSize.set(1024, 1024); scene.add(key); const rim = new THREE.DirectionalLight(options.rimColor || 0x7dd3fc, 0.82); rim.position.set(-4.2, 1.2, -2.8); scene.add(rim); const shadowPlane = new THREE.Mesh( new THREE.PlaneGeometry(5.2, 5.2), new THREE.ShadowMaterial({ opacity: 0.18 }) ); shadowPlane.position.set(0, -1.65, 0); shadowPlane.rotation.x = -Math.PI / 2; shadowPlane.receiveShadow = true; scene.add(shadowPlane); const reduceMotion = window.matchMedia("(prefers-reduced-motion: reduce)").matches; let rafId = 0; function resize() { const width = Math.max(1, canvas.clientWidth); const height = Math.max(1, canvas.clientHeight); renderer.setPixelRatio(Math.min(window.devicePixelRatio || 1, options.maxDpr || 1.75)); renderer.setSize(width, height, false); camera.aspect = width / height; camera.updateProjectionMatrix(); } function render(time = 0) { const t = time * 0.001; object.rotation.x = -0.16 + Math.sin(t * 0.45) * 0.06; object.rotation.y = t * 0.28; object.rotation.z = Math.sin(t * 0.32) * 0.08; object.position.y = reduceMotion ? 0 : Math.sin(t * 0.8) * 0.08; renderer.render(scene, camera); if (!reduceMotion) rafId = requestAnimationFrame(render); } function handleResize() { cancelAnimationFrame(rafId); resize(); render(); } resize(); render(); window.addEventListener("resize", handleResize); return () => { cancelAnimationFrame(rafId); window.removeEventListener("resize", handleResize); geometry.dispose(); material.dispose(); shadowPlane.geometry.dispose(); shadowPlane.material.dispose(); renderer.dispose(); }; } const cleanupObject = initWebGL3DObject( document.querySelector("[data-webgl-3d-object]"), { color: 0x8aa4ff, rimColor: 0x7dd3fc, metalness: 0.48, roughness: 0.34, emissive: 0x101833, } );
metalness: 0.45-0.7, roughness: 0.25-0.45.metalness: 0.0-0.15, roughness: 0.38-0.62.emissive with emissiveIntensity: 0.12-0.35.flatShading: true; smooth product object: set it to false.0.04 to 0.12 units on Y.metalness, roughness, and optional emissive.Other measured skills in the registry, with their headline benchmark lift.