npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

realistic-diamond-shader

v0.1.2

Published

A WebGL2 BVH ray-traced diamond material for Three.js with HDR and EXR environment support.

Readme

realistic-diamond-shader

A WebGL2 diamond material for Three.js. It performs per-pixel BVH ray tracing for internal reflections and refractions, models chromatic dispersion, and samples equirectangular HDR or EXR environment maps.

The package is framework-agnostic: use it with plain Three.js, React Three Fiber, Vue, or any renderer that gives you a Three.js WebGLRenderer.

Features

  • Internal BVH ray tracing through real diamond geometry.
  • Chromatic fire, Fresnel reflection, transmission, absorption, and gamma control.
  • Runtime controls that update uniforms without recompiling the shader.
  • HDR and EXR equirectangular environment-map loading.
  • TypeScript declarations and an ESM-only bundle.
  • No model files, HDRIs, analytics, network calls, or framework dependency.

Requirements

  • Three.js 0.160.x through 0.189.x.
  • three-mesh-bvh 0.9.x.
  • WebGL2. The shader uses GLSL 3 and integer BVH textures.

Install

npm install realistic-diamond-shader three three-mesh-bvh

three and three-mesh-bvh are peer dependencies. Your application must use one compatible copy of each rather than bundling a second copy through this package.

Quick start

import * as THREE from 'three';
import {
  createDiamondBVH,
  createDiamondMaterial,
  loadDiamondEnvironment,
  setDiamondEnvironmentRotation,
  updateDiamondCamera
} from 'realistic-diamond-shader';

const renderer = new THREE.WebGLRenderer();
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(45, innerWidth / innerHeight, 0.1, 100);

const environmentMap = await loadDiamondEnvironment('/assets/diamond.exr');
const diamondMaterials = [];

gltf.scene.traverse((mesh) => {
  if (!mesh.isMesh || !mesh.name.toLowerCase().includes('diamond')) return;

  const { bvh } = createDiamondBVH(mesh.geometry);
  const material = createDiamondMaterial({
    environmentMap,
    bvh,
    ior: 2.42,
    dispersion: 0.004,
    environmentIntensity: 1.5,
    rayBounces: 3,
    facetSharpness: 1
  });

  mesh.material = material;
  diamondMaterials.push(material);
});

setDiamondEnvironmentRotation(diamondMaterials[0], { x: 0, y: 30, z: 0 });

function render() {
  requestAnimationFrame(render);
  for (const material of diamondMaterials) updateDiamondCamera(material, camera);
  renderer.render(scene, camera);
}
render();

API

createDiamondBVH(geometry, options?)

Builds an acceleration structure for one THREE.BufferGeometry and returns { boundsTree, bvh }. Pass the returned bvh to createDiamondMaterial. Keep that object and source geometry alive while the material is rendered. A second call for the same geometry reuses the prepared GPU BVH data. The default leaf size is ten triangles, which reduces BVH node and texture fetches for typical faceted gem meshes.

createDiamondMaterial(options)

Creates a THREE.ShaderMaterial.

createDiamondMaterial({ environmentMap, bvh, ...diamondOptions })

environmentMap must be a loaded equirectangular THREE.Texture; bvh must come from createDiamondBVH.

setDiamondOptions(material, options)

Updates material uniforms in place. This is suitable for UI sliders.

| Option | Default | Accepted values | Meaning | | --- | ---: | --- | --- | | ior | 2.42 | >= 1 | Refractive index. | | dispersion | 0.004 | >= 0 | Chromatic fire strength. | | rayBounces | 3 | integer, 1–12 | Internal ray bounces. Higher values cost more GPU time. | | facetSharpness | 1 | 0–1 | Blend between smooth and geometric facet normals. | | environmentIntensity | 1.5 | >= 0 | Reflection/refraction brightness. | | gamma | 1.09 | > 0 | Internal-light contrast. | | color | white | Three.js colour input | Diamond tint. | | rgbBoost | [2,2,2] | Vector3 or three numbers | Per-channel brilliance gain. | | reflectivity | 0.46 | 0–1 | Exterior Fresnel contribution. | | transmission | 0 | 0–1 | Direct refracted environment contribution. | | absorption | 1 | >= 0 | Beer–Lambert attenuation multiplier. | | environmentMap | — | THREE.Texture | Replaces the active environment texture. |

setDiamondRendererResolution(renderer, options)

Controls the renderer's drawing-buffer resolution, independently of the diamond material. It is useful when a viewer needs to let its users trade sharpness for GPU cost on lower-end devices.

import { setDiamondRendererResolution } from 'realistic-diamond-shader';

// Fill the browser viewport at a chosen pixel ratio.
setDiamondRendererResolution(renderer, {
  mode: 'display',
  width: window.innerWidth,
  height: window.innerHeight,
  scale: 1.25
});

// Or use a fixed drawing buffer, regardless of the display size.
setDiamondRendererResolution(renderer, {
  mode: 'custom',
  width: 1080,
  height: 1080
});

display uses width and height as CSS pixels and applies scale as the renderer pixel ratio. custom renders at the exact supplied pixel dimensions with a pixel ratio of 1. Values below 1 reduce work further; 1 or 1.25 is a sensible starting point for mobile. Apply a new setting only after a user changes the control, not every frame.

updateDiamondCamera(material, camera)

Copies the current camera position into the shader. Call it once per material before each render. This is required for correct refraction while the camera or diamond moves.

setDiamondEnvironmentRotation(material, rotation?)

Sets the equirectangular environment orientation in degrees. The default order is YXZ, matching standard Three.js viewer controls.

setDiamondEnvironmentRotation(material, { x: 0, y: 45, z: 0 });

loadDiamondEnvironment(url, options?)

Loads an .exr with EXRLoader or an .hdr with RGBELoader, sets EquirectangularReflectionMapping, and returns the texture. Set { type: 'exr' } or { type: 'hdr' } to override automatic detection.

Environment maps

The material samples the unfiltered equirectangular texture directly. Use a high-dynamic-range map designed for jewellery lighting, and keep ownership or distribution rights for every HDRI/EXR you use. Environment files are not included in this package.

Performance

The optimized ray-tracing mode traces one internal BVH path per diamond fragment. It retains the direct exit, the strongest internal exit, and the terminal reflected path, so the diamond keeps its internal reflections without sampling the HDRI at every bounce. It supports up to 12 bounces; start at 3 and increase only while the target device remains smooth. Limit device pixel ratio on phones, reuse geometries for repeated diamonds, and avoid rebuilding BVHs during animation.

For interactive viewers, render on demand rather than continuously. Choose a fixed device pixel ratio for the viewer session. Changing the WebGL drawing buffer size while the user is dragging can visibly clear the canvas on Safari, so apply resolution changes after interaction instead.

Compatibility and limitations

  • The material is ESM-only and does not provide a CommonJS entry point.
  • WebGL1 is not supported.
  • WebGPU is not supported.
  • Non-uniformly scaling a diamond mesh can produce incorrect normal and ray directions; use uniform scale or bake the scale into its geometry.
  • This package contains no automatic gem classification. Select diamond meshes in your own model-loading code.

Development

npm ci
npm run check
npm test
npm run build
npm run test:package

See CONTRIBUTING.md for contribution requirements and SECURITY.md for vulnerability reporting.

Licence

Licensed under Apache-2.0. See NOTICE for attribution.

Apache-2.0 permits commercial use, modification, and redistribution while requiring licence and attribution notices to remain with redistributed copies. It does not grant trademark rights.