minecraft-renderer 0.1.52 → 0.1.54

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "minecraft-renderer",
3
- "version": "0.1.52",
3
+ "version": "0.1.54",
4
4
  "description": "The most Modular Minecraft world renderer with Three.js WebGL backend",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -19,6 +19,7 @@ export type RendererOptionMeta = {
19
19
  text?: string
20
20
  tooltip?: string
21
21
  requiresRestart?: boolean
22
+ requiresChunksReload?: boolean
22
23
  }
23
24
 
24
25
  export type RendererMesherPipeline = 'wasm' | 'legacy-js'
@@ -62,6 +63,7 @@ export const RENDERER_DEFAULT_OPTIONS = {
62
63
  rendererPerfDebugOverlay: false as boolean,
63
64
  disableBlockEntityTextures: false as boolean,
64
65
  rendererMesher: 'wasm' as RendererMesherPipeline,
66
+ rendererShaderCubeBlocks: false as boolean,
65
67
  rendererShaderCubeDebugMode: 'off' as RendererShaderCubeDebugMode,
66
68
  showChunkBorders: false as boolean,
67
69
  renderEntities: true as boolean,
@@ -177,6 +179,11 @@ export const RENDERER_OPTIONS_META: Partial<Record<RendererDefaultOptionKey, Ren
177
179
  tooltip: 'WASM is faster. Use JS if WASM is not working. Requires reload.',
178
180
  requiresRestart: true
179
181
  },
182
+ rendererShaderCubeBlocks: {
183
+ text: 'Instanced shader cubes',
184
+ tooltip: 'Render full blocks through the global GPU instanced path. Requires WASM mesher and WebGL2.',
185
+ requiresChunksReload: true,
186
+ },
180
187
  rendererShaderCubeDebugMode: {
181
188
  text: 'Shader cube debug',
182
189
  tooltip: 'Instanced cube path visualization (requires shader cubes enabled).',
@@ -253,7 +260,7 @@ export const RENDERER_OPTIONS_META: Partial<Record<RendererDefaultOptionKey, Ren
253
260
  min: 30,
254
261
  max: 110,
255
262
  unit: '°',
256
- text: 'Field of view'
263
+ text: 'FOV (Field of View)'
257
264
  },
258
265
  gpuPreference: {
259
266
  text: 'GPU preference',
@@ -317,7 +324,7 @@ export const RENDERER_RENDER_GUI_SECTIONS: ReadonlyArray<{
317
324
  },
318
325
  {
319
326
  title: 'Mesher',
320
- keys: ['rendererMesher']
327
+ keys: ['rendererMesher', 'rendererShaderCubeBlocks']
321
328
  },
322
329
  {
323
330
  title: 'Renderer debug',
@@ -163,6 +163,7 @@ export function applyRendererOptions(
163
163
  cfg.fetchPlayerSkins = o.loadPlayerSkins
164
164
  cfg.highlightBlockColor = o.highlightBlockColor
165
165
  cfg.wasmMesher = wasmActive
166
+ cfg.shaderCubeBlocks = o.rendererShaderCubeBlocks && wasmActive
166
167
  cfg.disableMesherConversionCache = !!ctx.isSafari
167
168
 
168
169
  setSkinsConfig({ apiEnabled: o.loadPlayerSkins })
@@ -1,5 +1,6 @@
1
1
  export const dynamicMcDataFiles = {
2
2
  'blocks': 'blocksArray',
3
3
  'blockCollisionShapes': 'blockCollisionShapes',
4
- 'biomes': 'biomesArray'
4
+ 'biomes': 'biomesArray',
5
+ 'tints': 'tints',
5
6
  }
@@ -1277,6 +1277,8 @@ export const initMesherWorker = (onGotMessage: (data: any) => void, workerName =
1277
1277
  return worker
1278
1278
  }
1279
1279
 
1280
+ let mesherMcDataTintsMissingWarned = false
1281
+
1280
1282
  export const meshersSendMcData = (workers: Worker[], version: string, mcDataKeys = dynamicMcDataFiles, mcDataFull: IndexedData) => {
1281
1283
  const mcData = {
1282
1284
  version: JSON.parse(JSON.stringify(mcDataFull.version))
@@ -1284,6 +1286,10 @@ export const meshersSendMcData = (workers: Worker[], version: string, mcDataKeys
1284
1286
  for (const [finalKey, sourceKey] of Object.entries(mcDataKeys)) {
1285
1287
  mcData[finalKey] = mcDataFull[sourceKey]
1286
1288
  }
1289
+ if ('tints' in mcDataKeys && !mcData.tints && !mesherMcDataTintsMissingWarned) {
1290
+ mesherMcDataTintsMissingWarned = true
1291
+ console.warn(`[meshersSendMcData] mcData.tints missing for version ${version}; shader cubes will use legacy path in worker`)
1292
+ }
1287
1293
 
1288
1294
  for (const worker of workers) {
1289
1295
  worker.postMessage({ type: 'mcData', mcData })
@@ -174,7 +174,9 @@ export class ChunkMeshManager {
174
174
  if (!mat) return
175
175
  const atlas = (this.material as THREE.MeshBasicMaterial).map ?? null
176
176
  mat.uniforms.u_atlas.value = atlas
177
- const { tintPalette } = getShaderCubeResources()
177
+ const resources = getShaderCubeResources()
178
+ if (!resources) return
179
+ const { tintPalette } = resources
178
180
  if (!tintPalette.isReady()) {
179
181
  tintPalette.createTexture()
180
182
  }
@@ -155,7 +155,8 @@ export class RainModule implements RendererModuleController {
155
155
  color: 0xcc_dd_ee,
156
156
  transparent: true,
157
157
  opacity: 0.35,
158
- depthWrite: false,
158
+ // Must write depth so log-depth blocks occlude rain correctly (see cubeBlockShader).
159
+ depthWrite: true,
159
160
  fog: true,
160
161
  })
161
162
 
@@ -123,7 +123,9 @@ function shaderMaterialForExport(legacyMaterial: THREE.Material): THREE.ShaderMa
123
123
  if (!atlas) return null
124
124
  const shaderMat = createCubeBlockMaterial()
125
125
  shaderMat.uniforms.u_atlas.value = atlas
126
- const { tintPalette } = getShaderCubeResources()
126
+ const resources = getShaderCubeResources()
127
+ if (!resources) return null
128
+ const { tintPalette } = resources
127
129
  if (!tintPalette.isReady()) tintPalette.createTexture()
128
130
  shaderMat.uniforms.u_tintPalette.value = tintPalette.getTexture()
129
131
  return shaderMat
@@ -81,6 +81,7 @@ export interface ShaderCubeModelInput {
81
81
 
82
82
  let tintPalette: TintPalette | null = null
83
83
  let textureIndexMapping: TextureIndexMapping | null = null
84
+ let tintsMissingWarned = false
84
85
 
85
86
  /** Convert mc-assets texture scales (normalized or negative) to pixel tile size for index lookup. */
86
87
  function normalizeTextureEntryForTileIndex(
@@ -122,10 +123,14 @@ export function resolveFaceTileIndex(
122
123
  }
123
124
 
124
125
  /** Main thread + worker: use `loadedData` set by the app / mesher (see mesherWasm). */
125
- function getTintsJson(): Record<string, any> {
126
+ function getTintsJson(): Record<string, any> | null {
126
127
  const tints = (globalThis as any).loadedData?.tints
127
128
  if (!tints) {
128
- throw new Error('shaderCubeBridge: globalThis.loadedData.tints is not available yet')
129
+ if (!tintsMissingWarned) {
130
+ tintsMissingWarned = true
131
+ console.warn('[shaderCubeBridge] loadedData.tints missing; shader cubes use legacy path')
132
+ }
133
+ return null
129
134
  }
130
135
  return tints
131
136
  }
@@ -133,9 +138,13 @@ function getTintsJson(): Record<string, any> {
133
138
  export function getShaderCubeResources(): {
134
139
  tintPalette: TintPalette
135
140
  textureIndexMapping: TextureIndexMapping
136
- } {
141
+ } | null {
142
+ const tintsData = getTintsJson()
143
+ if (!tintsData) {
144
+ return null
145
+ }
137
146
  if (!tintPalette) {
138
- tintPalette = TintPalette.fromTintsData(getTintsJson())
147
+ tintPalette = TintPalette.fromTintsData(tintsData)
139
148
  tintPalette.createTexture()
140
149
  }
141
150
  if (!textureIndexMapping) {
@@ -155,6 +164,7 @@ export function getShaderCubeResources(): {
155
164
  export function resetShaderCubeResources(): void {
156
165
  tintPalette = null
157
166
  textureIndexMapping = null
167
+ tintsMissingWarned = false
158
168
  }
159
169
 
160
170
  /**
@@ -358,3 +358,12 @@ test('GlobalBlockBuffer: free-list reuses slot with EMPTY sentinel', () => {
358
358
  buffer.dispose()
359
359
  mat.dispose()
360
360
  })
361
+
362
+ test('getShaderCubeResources: returns null without loadedData.tints (no throw)', () => {
363
+ const prev = (globalThis as any).loadedData
364
+ ;(globalThis as any).loadedData = {}
365
+ resetShaderCubeResources()
366
+ expect(getShaderCubeResources()).toBeNull()
367
+ ;(globalThis as any).loadedData = prev
368
+ resetShaderCubeResources()
369
+ })