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

threejs-minecraft-bedrock-rtx-loader

v0.1.0

Published

Three.js loader for Minecraft Bedrock RTX material texture sets (MER/MERS, DirectX normals)

Readme

threejs-minecraft-bedrock-rtx-loader

A Three.js loader for Minecraft Bedrock RTX material texture sets. It reads the color map plus the Bedrock-specific MER/MERS and DirectX normal/heightmap channels and produces a ready-to-render material built on MeshPhysicalMaterial via three-custom-shader-material (CSM). Because it extends a standard physical material, it integrates automatically with your scene's lights, shadows, and environment maps.

Install

bun add three three-custom-shader-material threejs-minecraft-bedrock-rtx-loader

three (>=0.160) and three-custom-shader-material (>=6) are peer dependencies — install them alongside the loader.

Quick start

import * as THREE from "three"
import { BedrockRtxLoader } from "threejs-minecraft-bedrock-rtx-loader"

const loader = new BedrockRtxLoader()

const material = await loader.loadAsync({
  color: "./textures/stone.png",
  mer: "./textures/stone_mer.png",
  normal: "./textures/stone_normal.png",
})

const mesh = new THREE.Mesh(new THREE.BoxGeometry(1, 1, 1), material)
scene.add(mesh)

That's it. The material reacts to your scene's lights, shadows, and environment maps like any MeshPhysicalMaterial. You do NOT need to call geometry.computeTangents() — the shader reconstructs a per-pixel cotangent frame from screen-space derivatives, so plain UV'd geometry works out of the box.

Callback API

The callback form follows the THREE.Loader convention:

loader.load(
  { color: "./textures/stone.png", mer: "./textures/stone_mer.png" },
  (material) => scene.add(new THREE.Mesh(geometry, material)),
  undefined, // onProgress
  (error) => console.error(error),
)

From pre-loaded textures

If you already have THREE.Texture objects, build the material directly:

import { createBedrockMaterial } from "threejs-minecraft-bedrock-rtx-loader"

const material = createBedrockMaterial(
  { color: colorTex, mers: mersTex, normal: normalTex },
  { emissionStrength: 2.0 },
)

API

new BedrockRtxLoader(manager?)

Extends THREE.Loader.

  • loadAsync(set, onProgress?, options?): Promise<material>
  • load(set, onLoad, onProgress?, onError?, options?): void

The set is an object of texture URLs:

| Key | Required | Description | | ----------- | -------- | ---------------------------------------------------------- | | color | yes | Base color / albedo map. | | mer | no | Metalness / Emissive / Roughness map. | | mers | no | MER plus a Subsurface alpha channel. | | normal | no | DirectX-convention normal map (green channel flipped). | | heightmap | no | Grayscale heightmap (alternative to normal). |

createBedrockMaterial(textures, options?)

Build a material from already-loaded THREE.Texture objects (same keys as the URL set above, but holding textures). Returns a CSM material.

This factory accepts one extra key the URL set does not: pomHeight, the heightfield for the experimental parallax occlusion march — see Parallax occlusion mapping.

Options

Both loadAsync/load and createBedrockMaterial accept an options object:

| Option | Type | Default | Description | | ------------------ | --------- | ------- | ------------------------------------------------------------ | | sss.enabled | boolean | true | Enable subsurface scattering approximation (uses MERS alpha).| | emissionStrength | number | 1.0 | Multiplier for the MER/MERS emissive channel. Clamped to ≥0. | | normalStrength | number | 1.0 | Strength of the normal/height perturbation. Clamped to ≥0. | | pom.enabled | boolean | false | Experimental. Enable parallax occlusion mapping. Requires a pomHeight texture. | | pom.depth | number | 0.25 | March depth as a fraction of one tile (one tile = one block). Clamped to 0–1. | | pom.channel | "r"|"g"|"b"|"a" | "b" | Channel of pomHeight carrying the heightfield. |

Parallax occlusion mapping (experimental)

An opt-in GLSL port of BetterRTX's hybrid texel-DDA parallax occlusion march. It is off by default and needs two things: a pomHeight texture and pom.enabled.

import { createBedrockMaterial } from "threejs-minecraft-bedrock-rtx-loader"

const material = createBedrockMaterial(
  { color: colorTex, mer: merTex, normal: normalTex, pomHeight: heightTex },
  { pom: { enabled: true, depth: 0.25, channel: "b" } },
)

pomHeight is typically the Bedrock normal + POM pack, whose blue channel carries the heightfield — hence the "b" default. That default also reads a plain greyscale heightmap correctly, since there b === r.

pom.depth is expressed as a fraction of one tile, where one tile spans one block. The 0.25 default matches BetterRTX's POM_DEPTH and the absolute scale that bedrock.graphics' Normal + POM export encodes against — keep your pack, your export, and this value in sync or the surface renders at the wrong depth.

The march can also be toggled at runtime without rebuilding the material:

material.uniforms.uUsePom.value = 0 // or 1 to re-enable

Note: POM is currently reachable only via createBedrockMaterial. BedrockRtxLoader's URL set does not accept a pomHeight URL yet — load that texture yourself and use the factory.

Texture channel mapping

MER / MERS pack three (or four) PBR scalars into one image:

| Channel | MER | MERS | | ------- | ---------- | ----------- | | R | Metalness | Metalness | | G | Emissive | Emissive | | B | Roughness | Roughness | | A | — | Subsurface |

Normal maps use the DirectX convention: the green (Y) channel is flipped relative to the OpenGL convention. The loader flips it back for you, so supply your Bedrock normal maps as-is.

Mutual exclusion rules

  • mer and mers are mutually exclusive — supply at most one.
  • normal and heightmap are mutually exclusive — supply at most one.

Passing both members of a pair throws an error.

Visual harness

A small Bun-powered harness renders a textured cube so you can eyeball a texture set. It is published from examples/ to GitHub Pages on every push to the default branch:

https://jasonjgardner.github.io/threejs-minecraft-bedrock-rtx-loader/

Locally

bun run example

Then open http://127.0.0.1:3001. The dev server bundles src/index.ts on the fly, so a plain static file server will not work in its place — serving the raw .ts fails with a MIME-type error in the browser. Make sure nothing else is holding port 3001 (the sibling labPBR harness uses port 3000).

Edit the texture URLs in examples/index.html to point at your own set. Local files dropped into examples/ are served alongside the page.

Building the static site

bun run build:examples

This writes examples/dist/index.html, a minified bedrock.js, and a .nojekyll marker — which is exactly what the Pages workflow uploads. The build rewrites the import map's /bedrock.js to a relative ./bedrock.js so the page works from the /<repo>/ sub-path Pages serves a project site from.

Known limitations

  • SSS is approximated via the physical material's transmission/thickness, not a true subsurface-scattering model.
  • Uniform MER/MERS value arrays are not supported. Bedrock's texture_set.json lets you specify constant scalar values in place of a texture; this loader supports textures only.
  • No texture_set.json parsing. Supply the individual texture URLs directly.
  • heightmap contributes normals only. It perturbs the surface normal but does not displace vertices. Parallax occlusion mapping is a separate, opt-in path driven by the pomHeight texture — see Parallax occlusion mapping.
  • POM is experimental and reachable only through createBedrockMaterial; BedrockRtxLoader's URL set does not yet accept a pomHeight URL.

License

MIT © Jason Gardner