minecraft-renderer 0.1.79 → 0.1.81
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/README.md +66 -26
- package/dist/mesher.js +36 -36
- package/dist/mesher.js.map +4 -4
- package/dist/mesherWasm.js +217 -217
- package/dist/minecraft-renderer.js +66 -66
- package/dist/minecraft-renderer.js.meta.json +1 -1
- package/dist/threeWorker.js +450 -450
- package/package.json +5 -2
- package/src/bundler/bundlePrepare.ts +3 -8
- package/src/graphicsBackend/appViewer.ts +10 -7
- package/src/graphicsBackend/config.ts +1 -5
- package/src/graphicsBackend/playerState.ts +35 -34
- package/src/graphicsBackend/preloadWorkers.ts +43 -41
- package/src/graphicsBackend/rendererDefaultOptions.ts +68 -70
- package/src/graphicsBackend/rendererOptionsSync.ts +24 -50
- package/src/graphicsBackend/types.ts +2 -2
- package/src/index.ts +6 -27
- package/src/lib/DebugGui.ts +34 -31
- package/src/lib/animationController.ts +9 -9
- package/src/lib/bakeLegacyLight.ts +1 -6
- package/src/lib/bindAbortableListener.test.ts +32 -12
- package/src/lib/bindAbortableListener.ts +14 -6
- package/src/lib/blockEntityLightRegistry.ts +11 -20
- package/src/lib/blockEntityLighting.test.ts +1 -6
- package/src/lib/blockEntityLighting.ts +5 -5
- package/src/lib/buildSharedConfig.mjs +4 -4
- package/src/lib/buildWorkerMcDataIndexes.test.ts +4 -4
- package/src/lib/buildWorkerMcDataIndexes.ts +11 -19
- package/src/lib/cameraBobbing.ts +1 -1
- package/src/lib/canvas2DOverlay.example.ts +13 -33
- package/src/lib/canvas2DOverlay.quickstart.ts +24 -54
- package/src/lib/canvas2DOverlay.ts +28 -47
- package/src/lib/cleanupDecorator.ts +2 -2
- package/src/lib/createPlayerObject.test.ts +2 -7
- package/src/lib/createPlayerObject.ts +18 -25
- package/src/lib/frameTimingCollector.ts +2 -5
- package/src/lib/guiRenderer.ts +57 -42
- package/src/lib/items.ts +15 -9
- package/src/lib/mesherlogReader.ts +5 -6
- package/src/lib/simpleUtils.ts +5 -5
- package/src/lib/skyLight.ts +3 -3
- package/src/lib/smoothSwitcher.ts +11 -18
- package/src/lib/ui/newStats.ts +10 -12
- package/src/lib/utils/proxy.ts +7 -1
- package/src/lib/utils/skins.ts +4 -4
- package/src/lib/utils.ts +1 -1
- package/src/lib/workerMessageSanitize.ts +5 -12
- package/src/lib/workerProxy.ts +52 -42
- package/src/lib/workerSyncOps.test.ts +58 -41
- package/src/lib/worldrendererCommon.reconfigure.test.ts +24 -21
- package/src/lib/worldrendererCommon.removeColumn.test.ts +11 -13
- package/src/lib/worldrendererCommon.ts +349 -211
- package/src/mesher-legacy/mesher.ts +9 -4
- package/src/mesher-legacy/test/a.ts +1 -1
- package/src/mesher-legacy/test/mesherTester.ts +2 -2
- package/src/mesher-legacy/test/playground.ts +1 -1
- package/src/mesher-legacy/test/run/test-js.ts +1 -1
- package/src/mesher-legacy/test/snapshotUtils.ts +3 -8
- package/src/mesher-legacy/test/test-perf.ts +1 -1
- package/src/mesher-legacy/test/tests.test.ts +2 -2
- package/src/mesher-shared/blockEntityMetadata.test.ts +7 -5
- package/src/mesher-shared/blockEntityMetadata.ts +28 -19
- package/src/mesher-shared/blockPropertiesForMeshing.ts +2 -2
- package/src/mesher-shared/computeHeightmap.ts +2 -4
- package/src/mesher-shared/exportedGeometryTypes.ts +3 -3
- package/src/mesher-shared/faceOcclusion.ts +324 -0
- package/src/mesher-shared/models.ts +80 -131
- package/src/mesher-shared/modelsGeometryCommon.ts +30 -15
- package/src/mesher-shared/shared.ts +46 -46
- package/src/mesher-shared/standaloneRenderer.ts +40 -44
- package/src/mesher-shared/tests/faceOcclusion.test.ts +179 -0
- package/src/mesher-shared/tests/liquidQuadInvariant.test.ts +12 -8
- package/src/mesher-shared/vertexShading.ts +2 -11
- package/src/mesher-shared/world.ts +19 -19
- package/src/mesher-shared/worldLighting.test.ts +2 -2
- package/src/performanceMonitor/PerformanceMonitor.ts +4 -13
- package/src/performanceMonitor/formatPerformanceFactorsDebug.ts +2 -2
- package/src/performanceMonitor/index.ts +1 -5
- package/src/performanceMonitor/types.ts +1 -1
- package/src/playerState/playerState.ts +55 -50
- package/src/playerState/types.ts +2 -8
- package/src/playground/allEntitiesDebug.ts +19 -16
- package/src/playground/baseScene.ts +29 -32
- package/src/playground/mobileControls.tsx +133 -129
- package/src/playground/playground.html +76 -73
- package/src/playground/playground.ts +14 -1
- package/src/playground/playgroundUi.tsx +100 -74
- package/src/playground/reactUtils.ts +3 -7
- package/src/playground/scenes/entities.ts +10 -7
- package/src/playground/scenes/frequentUpdates.ts +5 -5
- package/src/playground/scenes/geometryExport.ts +6 -20
- package/src/playground/scenes/highPosEntityUpdates.ts +2 -10
- package/src/playground/scenes/index.ts +1 -1
- package/src/playground/scenes/lightingStarfield.ts +18 -12
- package/src/playground/scenes/main.ts +15 -11
- package/src/playground/scenes/partialBlockCulling.ts +31 -0
- package/src/playground/scenes/railsCobweb.ts +1 -1
- package/src/playground/scenes/rotationIssue.ts +1 -1
- package/src/playground/scenes/slabsOptimization.ts +1 -2
- package/src/playground/scenes/transparencyIssue.ts +1 -1
- package/src/playground/shared.ts +2 -2
- package/src/resourcesManager/resourcesManager.ts +29 -54
- package/src/resourcesManager/resourcesManager.worker.test.ts +6 -10
- package/src/shims/minecraftData.ts +70 -24
- package/src/sign-renderer/index.html +10 -12
- package/src/sign-renderer/index.ts +29 -29
- package/src/sign-renderer/playground.ts +22 -15
- package/src/sign-renderer/tests.test.ts +16 -13
- package/src/sign-renderer/vite.config.ts +2 -2
- package/src/three/appShared.ts +46 -25
- package/src/three/bannerRenderer.ts +33 -61
- package/src/three/cameraCollisionBlockCache.ts +156 -0
- package/src/three/cameraCollisionSolidity.ts +50 -0
- package/src/three/cameraShake.ts +15 -6
- package/src/three/chunkMeshManager.ts +223 -390
- package/src/three/cinimaticScript.ts +26 -15
- package/src/three/cubeDrawSpans.ts +27 -37
- package/src/three/cubeMultiDraw.ts +9 -22
- package/src/three/documentRenderer.ts +15 -18
- package/src/three/entities.ts +175 -150
- package/src/three/entity/EntityMesh.ts +114 -108
- package/src/three/entity/animations.js +3 -3
- package/src/three/entity/armorModels.ts +15 -15
- package/src/three/entity/gltfAnimationUtils.ts +2 -5
- package/src/three/fireworks.ts +34 -32
- package/src/three/fireworksRenderer.ts +32 -29
- package/src/three/globalBlockBuffer.ts +167 -100
- package/src/three/globalLegacyBuffer.ts +248 -264
- package/src/three/graphicsBackendBase.ts +19 -25
- package/src/three/graphicsBackendOffThread.ts +12 -15
- package/src/three/hand.ts +21 -21
- package/src/three/handLegacy.ts +3 -13
- package/src/three/holdingBlock.ts +116 -79
- package/src/three/holdingBlockFactory.ts +1 -4
- package/src/three/holdingBlockItemIdentity.test.ts +25 -17
- package/src/three/holdingBlockItemIdentity.ts +9 -6
- package/src/three/holdingBlockLegacy.ts +113 -132
- package/src/three/itemMesh.ts +20 -29
- package/src/three/legacyMultiDraw.ts +10 -16
- package/src/three/legacySectionCull.ts +8 -14
- package/src/three/menuBackground/activeView.ts +1 -4
- package/src/three/menuBackground/assetUrl.ts +1 -1
- package/src/three/menuBackground/classic.ts +4 -12
- package/src/three/menuBackground/gpuPreference.ts +1 -3
- package/src/three/menuBackground/index.ts +2 -11
- package/src/three/menuBackground/renderer.ts +1 -5
- package/src/three/menuBackground/types.ts +1 -4
- package/src/three/menuBackground/v2.ts +196 -96
- package/src/three/menuBackground/v2Meta.ts +3 -3
- package/src/three/menuBackground/worldBlocks.ts +37 -35
- package/src/three/modules/blockBreakParticles.ts +59 -28
- package/src/three/modules/cameraBobbing.ts +3 -6
- package/src/three/modules/index.ts +1 -1
- package/src/three/modules/rain.ts +10 -23
- package/src/three/modules/sciFiWorldReveal.ts +11 -25
- package/src/three/modules/starfield.ts +7 -13
- package/src/three/renderSlot.ts +28 -16
- package/src/three/rendererModuleSystem.ts +1 -3
- package/src/three/sceneOrigin.ts +96 -33
- package/src/three/sectionRaycastAabb.ts +24 -110
- package/src/three/shaderCubeMesh.ts +6 -17
- package/src/three/shaders/cubeBlockShader.ts +85 -96
- package/src/three/shaders/legacyBlockShader.ts +21 -43
- package/src/three/shaders/textureIndexMapping.ts +89 -95
- package/src/three/shaders/tintPalette.ts +156 -170
- package/src/three/signTextureCache.ts +9 -12
- package/src/three/skyboxRenderer.ts +62 -70
- package/src/three/tests/chunkMeshManagerLegacy.test.ts +34 -64
- package/src/three/tests/cubeDrawSpans.test.ts +55 -25
- package/src/three/tests/globalBlockBuffer.test.ts +217 -0
- package/src/three/tests/globalLegacyBuffer.test.ts +300 -41
- package/src/three/tests/legacyMultiDraw.test.ts +8 -29
- package/src/three/tests/pr3PerFrameCpuCuts.test.ts +106 -29
- package/src/three/tests/signTextureCache.test.ts +4 -4
- package/src/three/thirdPersonVoxelRaycast.ts +120 -0
- package/src/three/threeJsMedia.ts +55 -72
- package/src/three/threeJsParticles.ts +32 -41
- package/src/three/threeJsSound.ts +3 -3
- package/src/three/threeJsUtils.ts +3 -3
- package/src/three/threeWorker.ts +2 -2
- package/src/three/waypointSprite.ts +55 -82
- package/src/three/waypoints.ts +20 -23
- package/src/three/world/cursorBlock.ts +25 -12
- package/src/three/world/vr.ts +11 -17
- package/src/three/worldGeometryExport.ts +15 -34
- package/src/three/worldRendererThree.ts +144 -166
- package/src/wasm-mesher/bridge/convertChunk.ts +3 -9
- package/src/wasm-mesher/bridge/render-from-wasm.ts +204 -229
- package/src/wasm-mesher/bridge/shaderCubeBridge.ts +26 -67
- package/src/wasm-mesher/tests/cameraCollisionBlockCache.test.ts +82 -0
- package/src/wasm-mesher/tests/cullingRegression.test.ts +307 -0
- package/src/wasm-mesher/tests/heightmapParity.test.ts +8 -18
- package/src/wasm-mesher/tests/mesherWasmConversionCache.test.ts +2 -2
- package/src/wasm-mesher/tests/sectionRaycastAabb.test.ts +1 -93
- package/src/wasm-mesher/tests/shaderCubeInstances.test.ts +103 -141
- package/src/wasm-mesher/tests/splitColumnWasmOutput.test.ts +14 -22
- package/src/wasm-mesher/tests/thirdPersonVoxelRaycast.test.ts +63 -0
- package/src/wasm-mesher/worker/mesherWasm.ts +150 -141
- package/src/wasm-mesher/worker/mesherWasmConversionCache.ts +2 -8
- package/src/wasm-mesher/worker/mesherWasmLightDirty.test.ts +1 -3
- package/src/wasm-mesher/worker/mesherWasmLightDirty.ts +1 -5
- package/src/wasm-mesher/worker/mesherWasmRequestTracker.ts +42 -42
- package/src/worldView/worldView.spiral.test.ts +1 -1
- package/src/worldView/worldView.ts +34 -39
- package/src/worldView/worldViewWorkerBridge.test.ts +4 -4
|
@@ -25,22 +25,23 @@ export class SkyboxRenderer {
|
|
|
25
25
|
private readonly brightnessAtPosition = 1
|
|
26
26
|
debugGui: DebugGui
|
|
27
27
|
|
|
28
|
-
constructor
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
'
|
|
35
|
-
|
|
36
|
-
'distanceFactor'
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
28
|
+
constructor(
|
|
29
|
+
private readonly scene: THREE.Scene,
|
|
30
|
+
public defaultSkybox: boolean,
|
|
31
|
+
public initialImage: string | null
|
|
32
|
+
) {
|
|
33
|
+
this.debugGui = new DebugGui(
|
|
34
|
+
'skybox_renderer',
|
|
35
|
+
this,
|
|
36
|
+
['temperature', 'worldTime', 'inWater', 'waterBreathing', 'fogOrangeness', 'brightnessAtPosition', 'distanceFactor'],
|
|
37
|
+
{
|
|
38
|
+
brightnessAtPosition: { min: 0, max: 1, step: 0.01 },
|
|
39
|
+
temperature: { min: 0, max: 1, step: 0.01 },
|
|
40
|
+
worldTime: { min: 0, max: 24_000, step: 1 },
|
|
41
|
+
fogOrangeness: { min: -1, max: 1, step: 0.01 },
|
|
42
|
+
distanceFactor: { min: 0, max: 5, step: 0.01 }
|
|
43
|
+
}
|
|
44
|
+
)
|
|
44
45
|
|
|
45
46
|
if (!initialImage) {
|
|
46
47
|
this.createGradientSky()
|
|
@@ -48,13 +49,13 @@ export class SkyboxRenderer {
|
|
|
48
49
|
// this.debugGui.activate()
|
|
49
50
|
}
|
|
50
51
|
|
|
51
|
-
async init
|
|
52
|
+
async init() {
|
|
52
53
|
if (this.initialImage) {
|
|
53
54
|
await this.setSkyboxImage(this.initialImage)
|
|
54
55
|
}
|
|
55
56
|
}
|
|
56
57
|
|
|
57
|
-
async setSkyboxImage
|
|
58
|
+
async setSkyboxImage(imageUrl: string) {
|
|
58
59
|
// Dispose old textures if they exist
|
|
59
60
|
if (this.texture) {
|
|
60
61
|
this.texture.dispose()
|
|
@@ -62,19 +63,16 @@ export class SkyboxRenderer {
|
|
|
62
63
|
|
|
63
64
|
// Load the equirectangular texture
|
|
64
65
|
const textureLoader = new THREE.TextureLoader()
|
|
65
|
-
this.texture = await new Promise(
|
|
66
|
-
textureLoader.load(
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
resolve(texture)
|
|
76
|
-
}
|
|
77
|
-
)
|
|
66
|
+
this.texture = await new Promise(resolve => {
|
|
67
|
+
textureLoader.load(imageUrl, texture => {
|
|
68
|
+
texture.mapping = THREE.EquirectangularReflectionMapping
|
|
69
|
+
texture.colorSpace = THREE.SRGBColorSpace
|
|
70
|
+
// Keep pixelated look
|
|
71
|
+
texture.minFilter = THREE.NearestFilter
|
|
72
|
+
texture.magFilter = THREE.NearestFilter
|
|
73
|
+
texture.needsUpdate = true
|
|
74
|
+
resolve(texture)
|
|
75
|
+
})
|
|
78
76
|
})
|
|
79
77
|
|
|
80
78
|
// Create or update the skybox
|
|
@@ -100,7 +98,7 @@ export class SkyboxRenderer {
|
|
|
100
98
|
}
|
|
101
99
|
}
|
|
102
100
|
|
|
103
|
-
update
|
|
101
|
+
update(cameraPosition: THREE.Vector3, newViewDistance: number) {
|
|
104
102
|
if (newViewDistance !== this.viewDistance) {
|
|
105
103
|
this.viewDistance = newViewDistance
|
|
106
104
|
this.updateSkyColors()
|
|
@@ -118,7 +116,7 @@ export class SkyboxRenderer {
|
|
|
118
116
|
}
|
|
119
117
|
|
|
120
118
|
// Update world time
|
|
121
|
-
updateTime
|
|
119
|
+
updateTime(timeOfDay: number, partialTicks = 0) {
|
|
122
120
|
if (this.debugGui.visible) return
|
|
123
121
|
this.worldTime = timeOfDay
|
|
124
122
|
this.partialTicks = partialTicks
|
|
@@ -126,20 +124,20 @@ export class SkyboxRenderer {
|
|
|
126
124
|
}
|
|
127
125
|
|
|
128
126
|
// Update view distance
|
|
129
|
-
updateViewDistance
|
|
127
|
+
updateViewDistance(viewDistance: number) {
|
|
130
128
|
this.viewDistance = viewDistance
|
|
131
129
|
this.updateSkyColors()
|
|
132
130
|
}
|
|
133
131
|
|
|
134
132
|
// Update temperature (for biome support)
|
|
135
|
-
updateTemperature
|
|
133
|
+
updateTemperature(temperature: number) {
|
|
136
134
|
if (this.debugGui.visible) return
|
|
137
135
|
this.temperature = temperature
|
|
138
136
|
this.updateSkyColors()
|
|
139
137
|
}
|
|
140
138
|
|
|
141
139
|
// Update water state
|
|
142
|
-
updateWaterState
|
|
140
|
+
updateWaterState(inWater: boolean, waterBreathing: boolean) {
|
|
143
141
|
if (this.debugGui.visible) return
|
|
144
142
|
this.inWater = inWater
|
|
145
143
|
this.waterBreathing = waterBreathing
|
|
@@ -147,13 +145,13 @@ export class SkyboxRenderer {
|
|
|
147
145
|
}
|
|
148
146
|
|
|
149
147
|
// Update default skybox setting
|
|
150
|
-
updateDefaultSkybox
|
|
148
|
+
updateDefaultSkybox(defaultSkybox: boolean) {
|
|
151
149
|
if (this.debugGui.visible) return
|
|
152
150
|
this.defaultSkybox = defaultSkybox
|
|
153
151
|
this.updateSkyColors()
|
|
154
152
|
}
|
|
155
153
|
|
|
156
|
-
private createGradientSky
|
|
154
|
+
private createGradientSky() {
|
|
157
155
|
const size = 64
|
|
158
156
|
const scale = 256 / size + 2
|
|
159
157
|
|
|
@@ -190,7 +188,7 @@ export class SkyboxRenderer {
|
|
|
190
188
|
this.updateSkyColors()
|
|
191
189
|
}
|
|
192
190
|
|
|
193
|
-
private getFogColor
|
|
191
|
+
private getFogColor(partialTicks = 0): THREE.Vector3 {
|
|
194
192
|
const angle = this.getCelestialAngle(partialTicks)
|
|
195
193
|
let rotation = Math.cos(angle * Math.PI * 2) * 2 + 0.5
|
|
196
194
|
rotation = Math.max(0, Math.min(1, rotation))
|
|
@@ -199,14 +197,14 @@ export class SkyboxRenderer {
|
|
|
199
197
|
let y = 0.847_058_83
|
|
200
198
|
let z = 1
|
|
201
199
|
|
|
202
|
-
x *=
|
|
203
|
-
y *=
|
|
204
|
-
z *=
|
|
200
|
+
x *= rotation * 0.94 + 0.06
|
|
201
|
+
y *= rotation * 0.94 + 0.06
|
|
202
|
+
z *= rotation * 0.91 + 0.09
|
|
205
203
|
|
|
206
204
|
return new THREE.Vector3(x, y, z)
|
|
207
205
|
}
|
|
208
206
|
|
|
209
|
-
private getSkyColor
|
|
207
|
+
private getSkyColor(x = 0, z = 0, partialTicks = 0): THREE.Vector3 {
|
|
210
208
|
const angle = this.getCelestialAngle(partialTicks)
|
|
211
209
|
let brightness = Math.cos(angle * 3.141_593 * 2) * 2 + 0.5
|
|
212
210
|
|
|
@@ -220,15 +218,11 @@ export class SkyboxRenderer {
|
|
|
220
218
|
const green = ((rgb >> 8) & 0xff) / 255
|
|
221
219
|
const blue = (rgb & 0xff) / 255
|
|
222
220
|
|
|
223
|
-
return new THREE.Vector3(
|
|
224
|
-
red * brightness,
|
|
225
|
-
green * brightness,
|
|
226
|
-
blue * brightness
|
|
227
|
-
)
|
|
221
|
+
return new THREE.Vector3(red * brightness, green * brightness, blue * brightness)
|
|
228
222
|
}
|
|
229
223
|
|
|
230
|
-
private calculateCelestialAngle
|
|
231
|
-
const modTime =
|
|
224
|
+
private calculateCelestialAngle(time: number, partialTicks: number): number {
|
|
225
|
+
const modTime = time % 24_000
|
|
232
226
|
let angle = (modTime + partialTicks) / 24_000 - 0.25
|
|
233
227
|
|
|
234
228
|
if (angle < 0) {
|
|
@@ -238,21 +232,21 @@ export class SkyboxRenderer {
|
|
|
238
232
|
angle--
|
|
239
233
|
}
|
|
240
234
|
|
|
241
|
-
angle = 1 - (
|
|
235
|
+
angle = 1 - (Math.cos(angle * Math.PI) + 1) / 2
|
|
242
236
|
angle += (angle - angle) / 3
|
|
243
237
|
|
|
244
238
|
return angle
|
|
245
239
|
}
|
|
246
240
|
|
|
247
|
-
private getCelestialAngle
|
|
241
|
+
private getCelestialAngle(partialTicks: number): number {
|
|
248
242
|
return this.calculateCelestialAngle(this.worldTime, partialTicks)
|
|
249
243
|
}
|
|
250
244
|
|
|
251
|
-
private getTemperature
|
|
245
|
+
private getTemperature(x: number, z: number): number {
|
|
252
246
|
return this.temperature
|
|
253
247
|
}
|
|
254
248
|
|
|
255
|
-
private getSkyColorByTemp
|
|
249
|
+
private getSkyColorByTemp(temperature: number): number {
|
|
256
250
|
temperature /= 3
|
|
257
251
|
if (temperature < -1) temperature = -1
|
|
258
252
|
if (temperature > 1) temperature = 1
|
|
@@ -262,17 +256,20 @@ export class SkyboxRenderer {
|
|
|
262
256
|
// Orange is around hue 0.08-0.15, so we need to shift from blue-purple (0.62) toward orange
|
|
263
257
|
// Use a more dramatic shift and also increase saturation for more noticeable effect
|
|
264
258
|
const orangeHue = 0.12 // Orange hue value
|
|
265
|
-
const hue =
|
|
266
|
-
|
|
267
|
-
|
|
259
|
+
const hue =
|
|
260
|
+
this.fogOrangeness > 0
|
|
261
|
+
? baseHue + (orangeHue - baseHue) * this.fogOrangeness * 0.8 // Blend toward orange
|
|
262
|
+
: baseHue + this.fogOrangeness * 0.1 // Subtle shift for negative values
|
|
268
263
|
const saturation = 0.5 + temperature * 0.1 + Math.abs(this.fogOrangeness) * 0.3 // Increase saturation with orangeness
|
|
269
264
|
const brightness = 1
|
|
270
265
|
|
|
271
266
|
return this.hsbToRgb(hue, saturation, brightness)
|
|
272
267
|
}
|
|
273
268
|
|
|
274
|
-
private hsbToRgb
|
|
275
|
-
let r = 0
|
|
269
|
+
private hsbToRgb(hue: number, saturation: number, brightness: number): number {
|
|
270
|
+
let r = 0
|
|
271
|
+
let g = 0
|
|
272
|
+
let b = 0
|
|
276
273
|
if (saturation === 0) {
|
|
277
274
|
r = g = b = Math.floor(brightness * 255 + 0.5)
|
|
278
275
|
} else {
|
|
@@ -280,7 +277,7 @@ export class SkyboxRenderer {
|
|
|
280
277
|
const f = h - Math.floor(h)
|
|
281
278
|
const p = brightness * (1 - saturation)
|
|
282
279
|
const q = brightness * (1 - saturation * f)
|
|
283
|
-
const t = brightness * (1 -
|
|
280
|
+
const t = brightness * (1 - saturation * (1 - f))
|
|
284
281
|
switch (Math.floor(h)) {
|
|
285
282
|
case 0:
|
|
286
283
|
r = Math.floor(brightness * 255 + 0.5)
|
|
@@ -314,10 +311,10 @@ export class SkyboxRenderer {
|
|
|
314
311
|
break
|
|
315
312
|
}
|
|
316
313
|
}
|
|
317
|
-
return 0xff_00_00_00 | (r << 16) | (g << 8) |
|
|
314
|
+
return 0xff_00_00_00 | (r << 16) | (g << 8) | Math.trunc(b)
|
|
318
315
|
}
|
|
319
316
|
|
|
320
|
-
private updateSkyColors
|
|
317
|
+
private updateSkyColors() {
|
|
321
318
|
if (!this.skyMesh || !this.voidMesh) return
|
|
322
319
|
|
|
323
320
|
// If default skybox is disabled, hide the skybox meshes
|
|
@@ -357,7 +354,7 @@ export class SkyboxRenderer {
|
|
|
357
354
|
|
|
358
355
|
// Normal sky colors
|
|
359
356
|
const viewDistance = this.viewDistance * 16
|
|
360
|
-
const viewFactor = 1 - (0.25 + 0.75 * this.viewDistance / 32) ** 0.25
|
|
357
|
+
const viewFactor = 1 - (0.25 + (0.75 * this.viewDistance) / 32) ** 0.25
|
|
361
358
|
|
|
362
359
|
const angle = this.getCelestialAngle(this.partialTicks)
|
|
363
360
|
const skyColor = this.getSkyColor(0, 0, this.partialTicks)
|
|
@@ -375,16 +372,11 @@ export class SkyboxRenderer {
|
|
|
375
372
|
|
|
376
373
|
this.scene.background = new THREE.Color(red, green, blue)
|
|
377
374
|
this.scene.fog = new THREE.Fog(new THREE.Color(red, green, blue), 0.0025, viewDistance * this.distanceFactor)
|
|
378
|
-
|
|
379
375
|
;(this.skyMesh.material as THREE.MeshBasicMaterial).color.set(new THREE.Color(skyColor.x, skyColor.y, skyColor.z))
|
|
380
|
-
;(this.voidMesh.material as THREE.MeshBasicMaterial).color.set(new THREE.Color(
|
|
381
|
-
skyColor.x * 0.2 + 0.04,
|
|
382
|
-
skyColor.y * 0.2 + 0.04,
|
|
383
|
-
skyColor.z * 0.6 + 0.1
|
|
384
|
-
))
|
|
376
|
+
;(this.voidMesh.material as THREE.MeshBasicMaterial).color.set(new THREE.Color(skyColor.x * 0.2 + 0.04, skyColor.y * 0.2 + 0.04, skyColor.z * 0.6 + 0.1))
|
|
385
377
|
}
|
|
386
378
|
|
|
387
|
-
dispose
|
|
379
|
+
dispose() {
|
|
388
380
|
if (this.texture) {
|
|
389
381
|
this.texture.dispose()
|
|
390
382
|
}
|
|
@@ -3,7 +3,7 @@ import { test, expect, vi } from 'vitest'
|
|
|
3
3
|
import * as THREE from 'three'
|
|
4
4
|
|
|
5
5
|
vi.mock('../entity/EntityMesh', () => ({
|
|
6
|
-
getMesh: vi.fn()
|
|
6
|
+
getMesh: vi.fn()
|
|
7
7
|
}))
|
|
8
8
|
|
|
9
9
|
import { ChunkMeshManager } from '../chunkMeshManager'
|
|
@@ -11,13 +11,8 @@ import type { WorldRendererThree } from '../worldRendererThree'
|
|
|
11
11
|
import type { MesherGeometryOutput } from '../../mesher-shared/shared'
|
|
12
12
|
import { renderWasmOutputToGeometry } from '../../wasm-mesher/bridge/render-from-wasm'
|
|
13
13
|
|
|
14
|
-
function makeQuadArrays
|
|
15
|
-
const positions = new Float32Array([
|
|
16
|
-
-1, -1, -1,
|
|
17
|
-
-1, 1, -1,
|
|
18
|
-
-1, 1, 1,
|
|
19
|
-
-1, -1, 1,
|
|
20
|
-
])
|
|
14
|
+
function makeQuadArrays() {
|
|
15
|
+
const positions = new Float32Array([-1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1])
|
|
21
16
|
const colors = new Float32Array(12).fill(1)
|
|
22
17
|
const skyLights = new Float32Array(4).fill(1)
|
|
23
18
|
const blockLights = new Float32Array(4).fill(0)
|
|
@@ -26,7 +21,7 @@ function makeQuadArrays () {
|
|
|
26
21
|
return { positions, colors, skyLights, blockLights, uvs, indices }
|
|
27
22
|
}
|
|
28
23
|
|
|
29
|
-
function makeBlendOnlyGeometry
|
|
24
|
+
function makeBlendOnlyGeometry(): MesherGeometryOutput {
|
|
30
25
|
const blend = makeQuadArrays()
|
|
31
26
|
return {
|
|
32
27
|
sectionYNumber: 0,
|
|
@@ -62,12 +57,12 @@ function makeBlendOnlyGeometry (): MesherGeometryOutput {
|
|
|
62
57
|
skyLights: blend.skyLights,
|
|
63
58
|
blockLights: blend.blockLights,
|
|
64
59
|
uvs: blend.uvs,
|
|
65
|
-
indices: blend.indices
|
|
66
|
-
}
|
|
60
|
+
indices: blend.indices
|
|
61
|
+
}
|
|
67
62
|
}
|
|
68
63
|
}
|
|
69
64
|
|
|
70
|
-
function makeMixedGeometry
|
|
65
|
+
function makeMixedGeometry(): MesherGeometryOutput {
|
|
71
66
|
const opaque = makeQuadArrays()
|
|
72
67
|
const blend = makeQuadArrays()
|
|
73
68
|
return {
|
|
@@ -104,12 +99,12 @@ function makeMixedGeometry (): MesherGeometryOutput {
|
|
|
104
99
|
skyLights: blend.skyLights,
|
|
105
100
|
blockLights: blend.blockLights,
|
|
106
101
|
uvs: blend.uvs,
|
|
107
|
-
indices: blend.indices
|
|
108
|
-
}
|
|
102
|
+
indices: blend.indices
|
|
103
|
+
}
|
|
109
104
|
}
|
|
110
105
|
}
|
|
111
106
|
|
|
112
|
-
function makeInvalidBlendGeometry
|
|
107
|
+
function makeInvalidBlendGeometry(): MesherGeometryOutput {
|
|
113
108
|
const geo = makeBlendOnlyGeometry()
|
|
114
109
|
const blend = geo.blend!
|
|
115
110
|
return {
|
|
@@ -117,8 +112,8 @@ function makeInvalidBlendGeometry (): MesherGeometryOutput {
|
|
|
117
112
|
blend: {
|
|
118
113
|
...blend,
|
|
119
114
|
positions: new Float32Array([0, 0, 0, 1, 0, 0, 2, 0, 0]),
|
|
120
|
-
indices: new Uint32Array([0, 1, 2, 0, 2, 1, 3])
|
|
121
|
-
}
|
|
115
|
+
indices: new Uint32Array([0, 1, 2, 0, 2, 1, 3])
|
|
116
|
+
}
|
|
122
117
|
}
|
|
123
118
|
}
|
|
124
119
|
|
|
@@ -128,23 +123,18 @@ type ManagerOptions = {
|
|
|
128
123
|
finishedChunks?: Record<string, boolean>
|
|
129
124
|
}
|
|
130
125
|
|
|
131
|
-
function makeShaderCubeOnlyGeometry
|
|
126
|
+
function makeShaderCubeOnlyGeometry(): MesherGeometryOutput {
|
|
132
127
|
const block = {
|
|
133
128
|
position: [0, 0, 0] as [number, number, number],
|
|
134
129
|
block_state_id: 1,
|
|
135
130
|
visible_faces: (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5),
|
|
136
131
|
ao_data: Array.from({ length: 6 }, () => [3, 3, 3, 3]),
|
|
137
132
|
light_data: Array.from({ length: 6 }, () => [1, 1, 1, 1]),
|
|
138
|
-
light_combined: Array.from({ length: 6 }, () => [255, 255, 255, 255])
|
|
133
|
+
light_combined: Array.from({ length: 6 }, () => [255, 255, 255, 255])
|
|
139
134
|
}
|
|
140
|
-
const out = renderWasmOutputToGeometry(
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
'0,0,0',
|
|
144
|
-
{ x: 8, y: 8, z: 8 },
|
|
145
|
-
undefined,
|
|
146
|
-
{ shaderCubes: true },
|
|
147
|
-
)
|
|
135
|
+
const out = renderWasmOutputToGeometry({ blocks: [block], block_count: 1, block_iterations: 0 }, '1.16.5', '0,0,0', { x: 8, y: 8, z: 8 }, undefined, {
|
|
136
|
+
shaderCubes: true
|
|
137
|
+
})
|
|
148
138
|
return {
|
|
149
139
|
sectionYNumber: 0,
|
|
150
140
|
chunkKey: '0,0',
|
|
@@ -172,11 +162,11 @@ function makeShaderCubeOnlyGeometry (): MesherGeometryOutput {
|
|
|
172
162
|
banners: {},
|
|
173
163
|
hadErrors: false,
|
|
174
164
|
blocksCount: 1,
|
|
175
|
-
shaderCubes: out.shaderCubes
|
|
165
|
+
shaderCubes: out.shaderCubes
|
|
176
166
|
}
|
|
177
167
|
}
|
|
178
168
|
|
|
179
|
-
function makeCullCamera
|
|
169
|
+
function makeCullCamera(): THREE.PerspectiveCamera {
|
|
180
170
|
const camera = new THREE.PerspectiveCamera(60, 1, 0.1, 1000)
|
|
181
171
|
camera.position.set(8, 8, 20)
|
|
182
172
|
camera.lookAt(8, 8, 8)
|
|
@@ -184,13 +174,19 @@ function makeCullCamera (): THREE.PerspectiveCamera {
|
|
|
184
174
|
return camera
|
|
185
175
|
}
|
|
186
176
|
|
|
187
|
-
function
|
|
177
|
+
function drainCubeUploads(manager: ChunkMeshManager): void {
|
|
178
|
+
const gb = manager.globalBlockBuffer
|
|
179
|
+
if (!gb) return
|
|
180
|
+
while (gb.hasPendingUploads()) gb.uploadDirtyRange()
|
|
181
|
+
}
|
|
182
|
+
|
|
183
|
+
function createManager(opts: ManagerOptions = {}): ChunkMeshManager {
|
|
188
184
|
const scene = new THREE.Scene()
|
|
189
185
|
const material = new THREE.MeshBasicMaterial()
|
|
190
186
|
const revealModule = opts.revealDefer
|
|
191
187
|
? {
|
|
192
|
-
|
|
193
|
-
|
|
188
|
+
shouldDeferSectionGeometry: () => true
|
|
189
|
+
}
|
|
194
190
|
: undefined
|
|
195
191
|
const worldRenderer = {
|
|
196
192
|
shaderCubeBlocksEnabled: () => opts.shaderCubes ?? false,
|
|
@@ -198,12 +194,12 @@ function createManager (opts: ManagerOptions = {}): ChunkMeshManager {
|
|
|
198
194
|
sceneOrigin: {
|
|
199
195
|
track: () => {},
|
|
200
196
|
removeAndUntrack: () => {},
|
|
201
|
-
removeAndUntrackAll: () => {}
|
|
197
|
+
removeAndUntrackAll: () => {}
|
|
202
198
|
},
|
|
203
199
|
blockEntities: {},
|
|
204
200
|
worldRendererConfig: opts.shaderCubes ? { wasmMesher: true } : {},
|
|
205
201
|
displayOptions: { inWorldRenderingConfig: {} },
|
|
206
|
-
finishedChunks: opts.finishedChunks ?? (opts.shaderCubes ? { '0,0': true } : {})
|
|
202
|
+
finishedChunks: opts.finishedChunks ?? (opts.shaderCubes ? { '0,0': true } : {})
|
|
207
203
|
} as unknown as WorldRendererThree
|
|
208
204
|
return new ChunkMeshManager(worldRenderer, scene, material, 256, 1)
|
|
209
205
|
}
|
|
@@ -251,6 +247,8 @@ test('ChunkMeshManager: hidden section excluded from draw spans', () => {
|
|
|
251
247
|
expect(manager.globalLegacyBlendBuffer?.getVisibleIndexSpans().length).toBe(0)
|
|
252
248
|
|
|
253
249
|
section.visible = true
|
|
250
|
+
const blendBuf = manager.globalLegacyBlendBuffer!
|
|
251
|
+
while (blendBuf.hasPendingUploads()) blendBuf.uploadDirtyRange()
|
|
254
252
|
manager.updateSectionCullAndSort(camera, 8, 8, 20)
|
|
255
253
|
expect(manager.globalLegacyBlendBuffer?.getVisibleIndexSpans().length).toBeGreaterThan(0)
|
|
256
254
|
|
|
@@ -298,36 +296,6 @@ test('ChunkMeshManager: invalid blend geometry falls back to pooled mesh', () =>
|
|
|
298
296
|
manager.dispose()
|
|
299
297
|
})
|
|
300
298
|
|
|
301
|
-
test('ChunkMeshManager: raycastGlobalLegacySections rejects off-ray sections within center distance', () => {
|
|
302
|
-
const manager = createManager()
|
|
303
|
-
const onRayKey = '0,0,0'
|
|
304
|
-
const offRayKey = '0,2,0'
|
|
305
|
-
|
|
306
|
-
manager.updateSection(onRayKey, makeBlendOnlyGeometry())
|
|
307
|
-
|
|
308
|
-
const offRayGeo = makeBlendOnlyGeometry()
|
|
309
|
-
offRayGeo.sz = 40
|
|
310
|
-
manager.updateSection(offRayKey, offRayGeo)
|
|
311
|
-
|
|
312
|
-
expect(manager.globalLegacyBlendBuffer?.hasSection(onRayKey)).toBe(true)
|
|
313
|
-
expect(manager.globalLegacyBlendBuffer?.hasSection(offRayKey)).toBe(true)
|
|
314
|
-
expect(manager.sectionObjects[offRayKey]?.worldZ).toBe(40)
|
|
315
|
-
|
|
316
|
-
const origin = new THREE.Vector3(4, 8, 8)
|
|
317
|
-
const direction = new THREE.Vector3(1, 0, 0).normalize()
|
|
318
|
-
const raycaster = new THREE.Raycaster(origin, direction)
|
|
319
|
-
raycaster.far = 4
|
|
320
|
-
|
|
321
|
-
const hit = manager.raycastGlobalLegacySections(raycaster, origin, 80)
|
|
322
|
-
expect(hit).toBeDefined()
|
|
323
|
-
expect(hit!).toBeGreaterThan(2)
|
|
324
|
-
expect(hit!).toBeLessThan(4)
|
|
325
|
-
|
|
326
|
-
manager.cleanupSection(onRayKey)
|
|
327
|
-
manager.cleanupSection(offRayKey)
|
|
328
|
-
manager.dispose()
|
|
329
|
-
})
|
|
330
|
-
|
|
331
299
|
test('ChunkMeshManager: mixed opaque and blend route to separate global buffers', () => {
|
|
332
300
|
const manager = createManager()
|
|
333
301
|
const key = '0,0,0'
|
|
@@ -352,6 +320,7 @@ test('ChunkMeshManager: hidden cube section excluded from draw spans', () => {
|
|
|
352
320
|
manager.updateSection(key, makeShaderCubeOnlyGeometry())
|
|
353
321
|
const section = manager.sectionObjects[key]!
|
|
354
322
|
expect(manager.globalBlockBuffer?.hasSection(key)).toBe(true)
|
|
323
|
+
drainCubeUploads(manager)
|
|
355
324
|
|
|
356
325
|
const camera = makeCullCamera()
|
|
357
326
|
manager.updateSectionCullAndSort(camera, 8, 8, 20)
|
|
@@ -385,6 +354,7 @@ test('ChunkMeshManager: finishChunkDisplay reveals cube spans and marks cull dir
|
|
|
385
354
|
expect(manager.sectionObjects[key]?.visible).toBe(true)
|
|
386
355
|
expect(markCullDirtySpy).toHaveBeenCalled()
|
|
387
356
|
|
|
357
|
+
drainCubeUploads(manager)
|
|
388
358
|
manager.updateSectionCullAndSort(camera, 8, 8, 20)
|
|
389
359
|
expect(manager.globalBlockBuffer?.getVisibleSpans().length).toBeGreaterThan(0)
|
|
390
360
|
|
|
@@ -1,46 +1,76 @@
|
|
|
1
1
|
//@ts-nocheck
|
|
2
2
|
import { describe, expect, test } from 'vitest'
|
|
3
|
-
import {
|
|
4
|
-
buildVisibleCubeSpans,
|
|
5
|
-
MAX_CUBE_SPANS,
|
|
6
|
-
SPAN_GAP_TOLERANCE_FACES,
|
|
7
|
-
} from '../cubeDrawSpans'
|
|
3
|
+
import { buildVisibleCubeSpans } from '../cubeDrawSpans'
|
|
8
4
|
|
|
9
5
|
describe('buildVisibleCubeSpans', () => {
|
|
10
6
|
test('contiguous slots merge into one span', () => {
|
|
11
|
-
const spans = buildVisibleCubeSpans(
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
7
|
+
const spans = buildVisibleCubeSpans(
|
|
8
|
+
[
|
|
9
|
+
{ start: 0, count: 4 },
|
|
10
|
+
{ start: 4, count: 2 }
|
|
11
|
+
],
|
|
12
|
+
6
|
|
13
|
+
)
|
|
15
14
|
expect(spans.length).toBe(1)
|
|
16
15
|
expect(spans[0]).toEqual({ start: 0, count: 6 })
|
|
17
16
|
})
|
|
18
17
|
|
|
19
18
|
test('scattered slots stay as multiple spans', () => {
|
|
20
|
-
const
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
19
|
+
const spans = buildVisibleCubeSpans(
|
|
20
|
+
[
|
|
21
|
+
{ start: 0, count: 1 },
|
|
22
|
+
{ start: 10, count: 1 }
|
|
23
|
+
],
|
|
24
|
+
11
|
|
25
|
+
)
|
|
25
26
|
expect(spans.length).toBe(2)
|
|
26
27
|
expect(spans[0]).toEqual({ start: 0, count: 1 })
|
|
27
|
-
expect(spans[1]).toEqual({ start:
|
|
28
|
+
expect(spans[1]).toEqual({ start: 10, count: 1 })
|
|
28
29
|
})
|
|
29
30
|
|
|
30
31
|
test('full draw when most faces visible', () => {
|
|
31
|
-
const spans = buildVisibleCubeSpans(
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
32
|
+
const spans = buildVisibleCubeSpans(
|
|
33
|
+
[
|
|
34
|
+
{ start: 0, count: 3 },
|
|
35
|
+
{ start: 3, count: 3 },
|
|
36
|
+
{ start: 6, count: 2 }
|
|
37
|
+
],
|
|
38
|
+
8
|
|
39
|
+
)
|
|
36
40
|
expect(spans.length).toBe(1)
|
|
37
41
|
expect(spans[0]).toEqual({ start: 0, count: 8 })
|
|
38
42
|
})
|
|
39
43
|
|
|
40
|
-
test('
|
|
41
|
-
const
|
|
42
|
-
|
|
43
|
-
|
|
44
|
+
test('full draw blocked when canFullDraw is false', () => {
|
|
45
|
+
const spans = buildVisibleCubeSpans([{ start: 0, count: 6 }], 8, false)
|
|
46
|
+
expect(spans).toEqual([{ start: 0, count: 6 }])
|
|
47
|
+
})
|
|
48
|
+
|
|
49
|
+
test('carves pending interior range from full-draw span', () => {
|
|
50
|
+
const spans = buildVisibleCubeSpans([{ start: 0, count: 6 }], 8, true, undefined, [{ start: 2, end: 3 }])
|
|
51
|
+
expect(spans).toEqual([
|
|
52
|
+
{ start: 0, count: 2 },
|
|
53
|
+
{ start: 4, count: 4 }
|
|
54
|
+
])
|
|
55
|
+
})
|
|
56
|
+
|
|
57
|
+
test('does not merge across interior gap', () => {
|
|
58
|
+
const spans = buildVisibleCubeSpans(
|
|
59
|
+
[
|
|
60
|
+
{ start: 0, count: 1 },
|
|
61
|
+
{ start: 2, count: 1 }
|
|
62
|
+
],
|
|
63
|
+
3
|
|
64
|
+
)
|
|
65
|
+
expect(spans.length).toBe(2)
|
|
66
|
+
expect(spans[0]).toEqual({ start: 0, count: 1 })
|
|
67
|
+
expect(spans[1]).toEqual({ start: 2, count: 1 })
|
|
68
|
+
})
|
|
69
|
+
|
|
70
|
+
test('does not cap span count when many scattered sections', () => {
|
|
71
|
+
const visibleSectionCount = 69
|
|
72
|
+
const padFaces = 10
|
|
73
|
+
const visibleSlots: Array<{ start: number; count: number }> = []
|
|
44
74
|
let cursor = 0
|
|
45
75
|
|
|
46
76
|
for (let i = 0; i < visibleSectionCount; i++) {
|
|
@@ -53,7 +83,7 @@ describe('buildVisibleCubeSpans', () => {
|
|
|
53
83
|
|
|
54
84
|
const highWatermark = cursor
|
|
55
85
|
const spans = buildVisibleCubeSpans(visibleSlots, highWatermark)
|
|
56
|
-
expect(spans.length).toBe(
|
|
86
|
+
expect(spans.length).toBe(visibleSectionCount)
|
|
57
87
|
|
|
58
88
|
const covered = new Set<number>()
|
|
59
89
|
for (const span of spans) {
|