minecraft-renderer 0.1.72 → 0.1.74

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.
Files changed (70) hide show
  1. package/README.md +1 -1
  2. package/dist/mesher.js +81 -81
  3. package/dist/mesher.js.map +3 -3
  4. package/dist/mesherWasm.js +1183 -943
  5. package/dist/minecraft-renderer.js +253 -80
  6. package/dist/minecraft-renderer.js.meta.json +1 -1
  7. package/dist/threeWorker.js +1735 -1002
  8. package/package.json +3 -3
  9. package/src/graphicsBackend/config.ts +4 -0
  10. package/src/graphicsBackend/rendererDefaultOptions.ts +2 -7
  11. package/src/graphicsBackend/rendererOptionsSync.ts +1 -1
  12. package/src/graphicsBackend/types.ts +1 -0
  13. package/src/lib/bakeLegacyLight.ts +17 -0
  14. package/src/lib/bindAbortableListener.ts +1 -1
  15. package/src/lib/blockEntityLightRegistry.test.ts +18 -0
  16. package/src/lib/blockEntityLightRegistry.ts +75 -0
  17. package/src/lib/blockEntityLighting.test.ts +30 -0
  18. package/src/lib/blockEntityLighting.ts +53 -0
  19. package/src/lib/createPlayerObject.ts +1 -1
  20. package/src/lib/worldrendererCommon.reconfigure.test.ts +4 -1
  21. package/src/lib/worldrendererCommon.removeColumn.test.ts +8 -4
  22. package/src/lib/worldrendererCommon.ts +15 -7
  23. package/src/mesher-shared/blockEntityMetadata.test.ts +33 -0
  24. package/src/mesher-shared/blockEntityMetadata.ts +19 -3
  25. package/src/mesher-shared/exportedGeometryTypes.ts +11 -0
  26. package/src/mesher-shared/models.ts +161 -92
  27. package/src/mesher-shared/shared.ts +15 -4
  28. package/src/mesher-shared/tests/liquidQuadInvariant.test.ts +40 -0
  29. package/src/mesher-shared/world.ts +12 -0
  30. package/src/mesher-shared/worldLighting.test.ts +54 -0
  31. package/src/playground/baseScene.ts +1 -1
  32. package/src/three/bannerRenderer.ts +14 -4
  33. package/src/three/chunkMeshManager.ts +663 -69
  34. package/src/three/cubeDrawSpans.ts +74 -0
  35. package/src/three/cubeMultiDraw.ts +119 -0
  36. package/src/three/documentRenderer.ts +0 -2
  37. package/src/three/entities.ts +7 -7
  38. package/src/three/entity/EntityMesh.ts +7 -5
  39. package/src/three/entity/gltfAnimationUtils.ts +5 -3
  40. package/src/three/globalBlockBuffer.ts +208 -12
  41. package/src/three/globalLegacyBuffer.ts +701 -0
  42. package/src/three/graphicsBackendBase.ts +9 -5
  43. package/src/three/itemMesh.ts +6 -3
  44. package/src/three/legacySectionCull.ts +85 -0
  45. package/src/three/modules/rain.ts +22 -21
  46. package/src/three/modules/sciFiWorldReveal.ts +347 -703
  47. package/src/three/modules/starfield.ts +19 -6
  48. package/src/three/sectionRaycastAabb.ts +25 -0
  49. package/src/three/shaders/cubeBlockShader.ts +80 -17
  50. package/src/three/shaders/legacyBlockShader.ts +292 -0
  51. package/src/three/skyboxRenderer.ts +1 -1
  52. package/src/three/tests/chunkMeshManagerLegacy.test.ts +286 -0
  53. package/src/three/tests/cubeDrawSpans.test.ts +73 -0
  54. package/src/three/tests/globalLegacyBuffer.test.ts +360 -0
  55. package/src/three/tests/legacySectionCull.test.ts +80 -0
  56. package/src/three/tests/signTextureCache.test.ts +83 -0
  57. package/src/three/threeJsMedia.ts +2 -2
  58. package/src/three/waypointSprite.ts +2 -2
  59. package/src/three/world/cursorBlock.ts +1 -0
  60. package/src/three/world/vr.ts +2 -2
  61. package/src/three/worldGeometryExport.ts +83 -26
  62. package/src/three/worldRendererThree.ts +100 -30
  63. package/src/wasm-mesher/bridge/render-from-wasm.ts +214 -72
  64. package/src/wasm-mesher/bridge/shaderCubeBridge.ts +18 -6
  65. package/src/wasm-mesher/runtime-build/wasm_mesher_bg.wasm +0 -0
  66. package/src/wasm-mesher/tests/sectionRaycastAabb.test.ts +20 -0
  67. package/src/wasm-mesher/tests/shaderCubeInstances.test.ts +80 -12
  68. package/src/wasm-mesher/worker/mesherWasm.ts +70 -14
  69. package/src/wasm-mesher/worker/mesherWasmLightDirty.test.ts +11 -0
  70. package/src/wasm-mesher/worker/mesherWasmLightDirty.ts +15 -0
@@ -69,7 +69,7 @@ export const getBackendMethods = (worldRenderer: WorldRendererThree): any => {
69
69
  // New method for updating skybox
70
70
  setSkyboxImage: worldRenderer.skyboxRenderer.setSkyboxImage.bind(worldRenderer.skyboxRenderer),
71
71
  // Rain methods
72
- setRain: (newState: boolean) => worldRenderer.toggleModule('rain', newState),
72
+ setRain: worldRenderer.setRain.bind(worldRenderer),
73
73
  spawnBlockBreakParticles(x: number, y: number, z: number, blockName: string, floorMap: number[], biomeName?: string) {
74
74
  const module = worldRenderer.getModule<import('./modules/blockBreakParticles').BlockBreakParticlesModule>('blockBreakParticles')
75
75
  module?.spawnBlockBreakParticles(x, y, z, blockName, floorMap, biomeName)
@@ -145,6 +145,10 @@ export const createGraphicsBackendBase = () => {
145
145
  let frameTimingCollector: FrameTimingCollector | null = null
146
146
 
147
147
  const init = (initOptionsArg: GraphicsInitOptions, mainData?: ThreeRendererMainData) => {
148
+ if (initOptionsArg.hello) {
149
+ console.log('Thanks for using minecraft-renderer project: one of the most performant Minecraft world renderers for the web!')
150
+ }
151
+
148
152
  if (isWebWorker) {
149
153
  initOptions = restoreTransferred(initOptionsArg, initOptionsRestorers, globalThis as unknown as Worker)
150
154
  } else {
@@ -166,8 +170,8 @@ export const createGraphicsBackendBase = () => {
166
170
  worldRenderer.destroy()
167
171
  worldRenderer = null
168
172
  frameTimingCollector = null
169
- ;(globalThis as any).world = undefined
170
- ;(globalThis as any).frameTimingCollector = undefined
173
+ ; (globalThis as any).world = undefined
174
+ ; (globalThis as any).frameTimingCollector = undefined
171
175
  }
172
176
 
173
177
  if (menuBackgroundRenderer) {
@@ -202,8 +206,8 @@ export const createGraphicsBackendBase = () => {
202
206
  worldRenderer.destroy()
203
207
  worldRenderer = null
204
208
  frameTimingCollector = null
205
- ;(globalThis as any).world = undefined
206
- ;(globalThis as any).frameTimingCollector = undefined
209
+ ; (globalThis as any).world = undefined
210
+ ; (globalThis as any).frameTimingCollector = undefined
207
211
  }
208
212
 
209
213
  const displayOptionsRestorers = [ResourcesManager, WorldViewWorker]
@@ -40,7 +40,7 @@ export function create3DItemMesh (
40
40
  throw new Error(`Invalid canvas dimensions: ${canvas.width}x${canvas.height}`)
41
41
  }
42
42
 
43
- const ctx = canvas.getContext('2d')!
43
+ const ctx = canvas.getContext('2d') as CanvasRenderingContext2D | OffscreenCanvasRenderingContext2D
44
44
  const imageData = ctx.getImageData(0, 0, canvas.width, canvas.height)
45
45
  const { data } = imageData
46
46
 
@@ -257,7 +257,7 @@ export interface ItemMeshResult {
257
257
  * Extracts item texture region to a canvas
258
258
  */
259
259
  export function extractItemTextureToCanvas (
260
- sourceTexture: THREE.Texture,
260
+ sourceTexture: THREE.Texture<HTMLImageElement | ImageBitmap>,
261
261
  textureInfo: ItemTextureInfo
262
262
  ): ItemTextureCanvas {
263
263
  const { u, v, sizeX, sizeY } = textureInfo
@@ -333,7 +333,10 @@ export function createItemMesh (
333
333
  if (use3D) {
334
334
  // Try to create 3D mesh
335
335
  try {
336
- const canvas = extractItemTextureToCanvas(sourceTexture, textureInfo)
336
+ const canvas = extractItemTextureToCanvas(
337
+ sourceTexture as THREE.Texture<HTMLImageElement | ImageBitmap>,
338
+ textureInfo
339
+ )
337
340
  const { geometry } = create3DItemMesh(canvas, { depth })
338
341
 
339
342
  // Create texture from canvas for the 3D mesh
@@ -0,0 +1,85 @@
1
+ //@ts-nocheck
2
+ import * as THREE from 'three'
3
+ import type { RenderOrigin } from './shaders/legacyBlockShader'
4
+
5
+ /** Half-extent of a section mesh AABB in section-local space. */
6
+ export const LEGACY_SECTION_HALF_EXTENT = 8
7
+
8
+ /** Small pad on camera-relative section AABBs for frustum tests. */
9
+ const CULL_BOX_EPSILON = 0.01
10
+
11
+ /**
12
+ * Set a legacy section mesh world translation once at build time.
13
+ * Position proxy is not used — camera-relative math lives in the shader.
14
+ */
15
+ export function setupLegacySectionMatrix (
16
+ mesh: THREE.Mesh,
17
+ sx: number,
18
+ sy: number,
19
+ sz: number,
20
+ renderOrigin: RenderOrigin,
21
+ ): void {
22
+ mesh.matrix.makeTranslation(sx - renderOrigin.x, sy - renderOrigin.y, sz - renderOrigin.z)
23
+ mesh.matrixWorldNeedsUpdate = true
24
+ mesh.frustumCulled = false
25
+ }
26
+
27
+ export function sectionIntersectsFrustum (
28
+ sectionWorldX: number,
29
+ sectionWorldY: number,
30
+ sectionWorldZ: number,
31
+ cameraWorldX: number,
32
+ cameraWorldY: number,
33
+ cameraWorldZ: number,
34
+ frustum: THREE.Frustum,
35
+ box: THREE.Box3,
36
+ boxMin: THREE.Vector3,
37
+ boxMax: THREE.Vector3,
38
+ ): { visible: boolean, distSq: number } {
39
+ const dx = sectionWorldX - cameraWorldX
40
+ const dy = sectionWorldY - cameraWorldY
41
+ const dz = sectionWorldZ - cameraWorldZ
42
+
43
+ const half = LEGACY_SECTION_HALF_EXTENT + CULL_BOX_EPSILON
44
+ boxMin.set(dx - half, dy - half, dz - half)
45
+ boxMax.set(dx + half, dy + half, dz + half)
46
+ box.set(boxMin, boxMax)
47
+
48
+ return {
49
+ visible: frustum.intersectsBox(box),
50
+ distSq: dx * dx + dy * dy + dz * dz,
51
+ }
52
+ }
53
+
54
+ /**
55
+ * Per-frame frustum cull + back-to-front renderOrder for one legacy section.
56
+ * Used for pooled per-section meshes (reveal defer + invariant fallback).
57
+ */
58
+ export function updateLegacySectionCullState (
59
+ mesh: THREE.Mesh,
60
+ sectionWorldX: number,
61
+ sectionWorldY: number,
62
+ sectionWorldZ: number,
63
+ cameraWorldX: number,
64
+ cameraWorldY: number,
65
+ cameraWorldZ: number,
66
+ frustum: THREE.Frustum,
67
+ box: THREE.Box3,
68
+ boxMin: THREE.Vector3,
69
+ boxMax: THREE.Vector3,
70
+ ): void {
71
+ const { visible, distSq } = sectionIntersectsFrustum(
72
+ sectionWorldX,
73
+ sectionWorldY,
74
+ sectionWorldZ,
75
+ cameraWorldX,
76
+ cameraWorldY,
77
+ cameraWorldZ,
78
+ frustum,
79
+ box,
80
+ boxMin,
81
+ boxMax,
82
+ )
83
+ mesh.visible = visible
84
+ mesh.renderOrder = -distSq
85
+ }
@@ -17,11 +17,6 @@ const FALL_SPEED_MAX = 24
17
17
  const HORIZONTAL_DRIFT = 1.2
18
18
  const RESPAWN_BELOW = -5
19
19
 
20
- const moduleOptions = {
21
- particleCount: 2000,
22
- speedFactor: 1,
23
- }
24
-
25
20
  export class RainModule implements RendererModuleController {
26
21
  private instancedMesh?: THREE.InstancedMesh
27
22
  private geometry?: THREE.BoxGeometry
@@ -32,8 +27,14 @@ export class RainModule implements RendererModuleController {
32
27
  private readonly tempPosition = new THREE.Vector3()
33
28
  private readonly tempQuaternion = new THREE.Quaternion()
34
29
  private readonly tempScale = new THREE.Vector3()
30
+ private readonly configUnsubs: Array<() => void> = []
35
31
 
36
- constructor(private readonly worldRenderer: WorldRendererThree) { }
32
+ constructor(private readonly worldRenderer: WorldRendererThree) {
33
+ this.configUnsubs.push(
34
+ this.worldRenderer.onReactiveConfigUpdated('rainColor', () => this.syncRainAppearance()),
35
+ this.worldRenderer.onReactiveConfigUpdated('rainOpacity', () => this.syncRainAppearance()),
36
+ )
37
+ }
37
38
 
38
39
  enable(): void {
39
40
  if (this.enabled) return
@@ -42,6 +43,7 @@ export class RainModule implements RendererModuleController {
42
43
  this.createRain()
43
44
  } else {
44
45
  this.instancedMesh.visible = true
46
+ this.syncRainAppearance()
45
47
  }
46
48
  }
47
49
 
@@ -60,8 +62,6 @@ export class RainModule implements RendererModuleController {
60
62
  render?: (deltaTime: number) => void = (deltaTime) => {
61
63
  if (!this.enabled || !this.instancedMesh || !this.material) return
62
64
 
63
- this.syncMaterialToSceneFog()
64
-
65
65
  const cameraPos = this.worldRenderer.getCameraPosition()
66
66
  this.instancedMesh.position.set(0, 0, 0)
67
67
 
@@ -126,6 +126,9 @@ export class RainModule implements RendererModuleController {
126
126
  }
127
127
 
128
128
  dispose(): void {
129
+ for (const unsub of this.configUnsubs) unsub()
130
+ this.configUnsubs.length = 0
131
+
129
132
  if (this.instancedMesh) {
130
133
  this.worldRenderer.scene.remove(this.instancedMesh)
131
134
  }
@@ -137,33 +140,31 @@ export class RainModule implements RendererModuleController {
137
140
  this.particles = []
138
141
  }
139
142
 
140
- /** Match scene fog so rain fades with distance instead of a flat blue sheet. */
141
- private syncMaterialToSceneFog(): void {
143
+ private syncRainAppearance(): void {
142
144
  if (!this.material) return
143
- const fog = this.worldRenderer.scene.fog
144
- if (fog instanceof THREE.Fog || fog instanceof THREE.FogExp2) {
145
- this.material.color.copy(fog.color)
146
- } else {
147
- this.material.color.set(0xcc_dd_ee)
148
- }
149
- this.material.fog = true
145
+
146
+ const { rainColor, rainOpacity } = this.worldRenderer.worldRendererConfig
147
+ this.material.color.set(rainColor)
148
+ this.material.opacity = Math.max(0, Math.min(1, rainOpacity))
149
+ this.material.needsUpdate = true
150
150
  }
151
151
 
152
152
  private createRain(): void {
153
+ const { rainColor, rainOpacity } = this.worldRenderer.worldRendererConfig
154
+
153
155
  this.geometry = new THREE.BoxGeometry(0.03, 0.3, 0.03)
154
156
  this.material = new THREE.MeshBasicMaterial({
155
- color: 0xcc_dd_ee,
157
+ color: rainColor,
156
158
  transparent: true,
157
- opacity: 0.35,
159
+ opacity: Math.max(0, Math.min(1, rainOpacity)),
158
160
  // Must write depth so log-depth blocks occlude rain correctly (see cubeBlockShader).
159
161
  depthWrite: true,
160
- fog: true,
162
+ fog: false,
161
163
  })
162
164
 
163
165
  this.instancedMesh = new THREE.InstancedMesh(this.geometry, this.material, PARTICLE_COUNT)
164
166
  this.instancedMesh.name = 'rain-particles'
165
167
  this.instancedMesh.frustumCulled = false
166
- this.syncMaterialToSceneFog()
167
168
 
168
169
  const dummy = new THREE.Matrix4()
169
170
  const position = new THREE.Vector3()