minecraft-renderer 0.1.78 → 0.1.80
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 +29 -25
- package/dist/mesher.js +36 -36
- package/dist/mesher.js.map +4 -4
- package/dist/mesherWasm.js +217 -217
- package/dist/minecraft-renderer.js +32 -32
- package/dist/minecraft-renderer.js.meta.json +1 -1
- package/dist/threeWorker.js +415 -415
- 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 +338 -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/cameraShake.ts +15 -6
- package/src/three/chunkMeshManager.ts +329 -301
- 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 +174 -99
- package/src/three/globalLegacyBuffer.ts +465 -136
- 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 +93 -0
- 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 +30 -18
- 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 +133 -25
- 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 +460 -58
- package/src/three/tests/legacyMultiDraw.test.ts +88 -0
- package/src/three/tests/pr3PerFrameCpuCuts.test.ts +370 -0
- package/src/three/tests/signTextureCache.test.ts +4 -4
- 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 +131 -133
- 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/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 +17 -4
- package/src/wasm-mesher/tests/shaderCubeInstances.test.ts +103 -141
- package/src/wasm-mesher/tests/splitColumnWasmOutput.test.ts +14 -22
- 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,20 +3,16 @@ 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'
|
|
10
10
|
import type { WorldRendererThree } from '../worldRendererThree'
|
|
11
11
|
import type { MesherGeometryOutput } from '../../mesher-shared/shared'
|
|
12
|
+
import { renderWasmOutputToGeometry } from '../../wasm-mesher/bridge/render-from-wasm'
|
|
12
13
|
|
|
13
|
-
function makeQuadArrays
|
|
14
|
-
const positions = new Float32Array([
|
|
15
|
-
-1, -1, -1,
|
|
16
|
-
-1, 1, -1,
|
|
17
|
-
-1, 1, 1,
|
|
18
|
-
-1, -1, 1,
|
|
19
|
-
])
|
|
14
|
+
function makeQuadArrays() {
|
|
15
|
+
const positions = new Float32Array([-1, -1, -1, -1, 1, -1, -1, 1, 1, -1, -1, 1])
|
|
20
16
|
const colors = new Float32Array(12).fill(1)
|
|
21
17
|
const skyLights = new Float32Array(4).fill(1)
|
|
22
18
|
const blockLights = new Float32Array(4).fill(0)
|
|
@@ -25,7 +21,7 @@ function makeQuadArrays () {
|
|
|
25
21
|
return { positions, colors, skyLights, blockLights, uvs, indices }
|
|
26
22
|
}
|
|
27
23
|
|
|
28
|
-
function makeBlendOnlyGeometry
|
|
24
|
+
function makeBlendOnlyGeometry(): MesherGeometryOutput {
|
|
29
25
|
const blend = makeQuadArrays()
|
|
30
26
|
return {
|
|
31
27
|
sectionYNumber: 0,
|
|
@@ -61,12 +57,12 @@ function makeBlendOnlyGeometry (): MesherGeometryOutput {
|
|
|
61
57
|
skyLights: blend.skyLights,
|
|
62
58
|
blockLights: blend.blockLights,
|
|
63
59
|
uvs: blend.uvs,
|
|
64
|
-
indices: blend.indices
|
|
65
|
-
}
|
|
60
|
+
indices: blend.indices
|
|
61
|
+
}
|
|
66
62
|
}
|
|
67
63
|
}
|
|
68
64
|
|
|
69
|
-
function makeMixedGeometry
|
|
65
|
+
function makeMixedGeometry(): MesherGeometryOutput {
|
|
70
66
|
const opaque = makeQuadArrays()
|
|
71
67
|
const blend = makeQuadArrays()
|
|
72
68
|
return {
|
|
@@ -103,12 +99,12 @@ function makeMixedGeometry (): MesherGeometryOutput {
|
|
|
103
99
|
skyLights: blend.skyLights,
|
|
104
100
|
blockLights: blend.blockLights,
|
|
105
101
|
uvs: blend.uvs,
|
|
106
|
-
indices: blend.indices
|
|
107
|
-
}
|
|
102
|
+
indices: blend.indices
|
|
103
|
+
}
|
|
108
104
|
}
|
|
109
105
|
}
|
|
110
106
|
|
|
111
|
-
function makeInvalidBlendGeometry
|
|
107
|
+
function makeInvalidBlendGeometry(): MesherGeometryOutput {
|
|
112
108
|
const geo = makeBlendOnlyGeometry()
|
|
113
109
|
const blend = geo.blend!
|
|
114
110
|
return {
|
|
@@ -116,33 +112,94 @@ function makeInvalidBlendGeometry (): MesherGeometryOutput {
|
|
|
116
112
|
blend: {
|
|
117
113
|
...blend,
|
|
118
114
|
positions: new Float32Array([0, 0, 0, 1, 0, 0, 2, 0, 0]),
|
|
119
|
-
indices: new Uint32Array([0, 1, 2, 0, 2, 1, 3])
|
|
120
|
-
}
|
|
115
|
+
indices: new Uint32Array([0, 1, 2, 0, 2, 1, 3])
|
|
116
|
+
}
|
|
121
117
|
}
|
|
122
118
|
}
|
|
123
119
|
|
|
124
120
|
type ManagerOptions = {
|
|
125
121
|
revealDefer?: boolean
|
|
122
|
+
shaderCubes?: boolean
|
|
123
|
+
finishedChunks?: Record<string, boolean>
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
function makeShaderCubeOnlyGeometry(): MesherGeometryOutput {
|
|
127
|
+
const block = {
|
|
128
|
+
position: [0, 0, 0] as [number, number, number],
|
|
129
|
+
block_state_id: 1,
|
|
130
|
+
visible_faces: (1 << 0) | (1 << 1) | (1 << 2) | (1 << 3) | (1 << 4) | (1 << 5),
|
|
131
|
+
ao_data: Array.from({ length: 6 }, () => [3, 3, 3, 3]),
|
|
132
|
+
light_data: Array.from({ length: 6 }, () => [1, 1, 1, 1]),
|
|
133
|
+
light_combined: Array.from({ length: 6 }, () => [255, 255, 255, 255])
|
|
134
|
+
}
|
|
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
|
+
})
|
|
138
|
+
return {
|
|
139
|
+
sectionYNumber: 0,
|
|
140
|
+
chunkKey: '0,0',
|
|
141
|
+
sectionStartY: 0,
|
|
142
|
+
sectionEndY: 16,
|
|
143
|
+
sectionStartX: 0,
|
|
144
|
+
sectionEndX: 16,
|
|
145
|
+
sectionStartZ: 0,
|
|
146
|
+
sectionEndZ: 16,
|
|
147
|
+
sx: 8,
|
|
148
|
+
sy: 8,
|
|
149
|
+
sz: 8,
|
|
150
|
+
positions: new Float32Array(0),
|
|
151
|
+
normals: new Float32Array(0),
|
|
152
|
+
colors: new Float32Array(0),
|
|
153
|
+
skyLights: new Float32Array(0),
|
|
154
|
+
blockLights: new Float32Array(0),
|
|
155
|
+
uvs: new Float32Array(0),
|
|
156
|
+
indices: new Uint32Array(0),
|
|
157
|
+
indicesCount: 0,
|
|
158
|
+
using32Array: true,
|
|
159
|
+
tiles: {},
|
|
160
|
+
heads: {},
|
|
161
|
+
signs: {},
|
|
162
|
+
banners: {},
|
|
163
|
+
hadErrors: false,
|
|
164
|
+
blocksCount: 1,
|
|
165
|
+
shaderCubes: out.shaderCubes
|
|
166
|
+
}
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
function makeCullCamera(): THREE.PerspectiveCamera {
|
|
170
|
+
const camera = new THREE.PerspectiveCamera(60, 1, 0.1, 1000)
|
|
171
|
+
camera.position.set(8, 8, 20)
|
|
172
|
+
camera.lookAt(8, 8, 8)
|
|
173
|
+
camera.updateMatrixWorld()
|
|
174
|
+
return camera
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
function drainCubeUploads(manager: ChunkMeshManager): void {
|
|
178
|
+
const gb = manager.globalBlockBuffer
|
|
179
|
+
if (!gb) return
|
|
180
|
+
while (gb.hasPendingUploads()) gb.uploadDirtyRange()
|
|
126
181
|
}
|
|
127
182
|
|
|
128
|
-
function createManager
|
|
183
|
+
function createManager(opts: ManagerOptions = {}): ChunkMeshManager {
|
|
129
184
|
const scene = new THREE.Scene()
|
|
130
185
|
const material = new THREE.MeshBasicMaterial()
|
|
131
186
|
const revealModule = opts.revealDefer
|
|
132
187
|
? {
|
|
133
|
-
|
|
134
|
-
|
|
188
|
+
shouldDeferSectionGeometry: () => true
|
|
189
|
+
}
|
|
135
190
|
: undefined
|
|
136
191
|
const worldRenderer = {
|
|
137
|
-
shaderCubeBlocksEnabled: () => false,
|
|
192
|
+
shaderCubeBlocksEnabled: () => opts.shaderCubes ?? false,
|
|
138
193
|
getModule: (name: string) => (name === 'futuristicReveal' ? revealModule : undefined),
|
|
139
194
|
sceneOrigin: {
|
|
140
195
|
track: () => {},
|
|
141
196
|
removeAndUntrack: () => {},
|
|
142
|
-
removeAndUntrackAll: () => {}
|
|
197
|
+
removeAndUntrackAll: () => {}
|
|
143
198
|
},
|
|
144
199
|
blockEntities: {},
|
|
145
|
-
worldRendererConfig: {},
|
|
200
|
+
worldRendererConfig: opts.shaderCubes ? { wasmMesher: true } : {},
|
|
201
|
+
displayOptions: { inWorldRenderingConfig: {} },
|
|
202
|
+
finishedChunks: opts.finishedChunks ?? (opts.shaderCubes ? { '0,0': true } : {})
|
|
146
203
|
} as unknown as WorldRendererThree
|
|
147
204
|
return new ChunkMeshManager(worldRenderer, scene, material, 256, 1)
|
|
148
205
|
}
|
|
@@ -187,11 +244,13 @@ test('ChunkMeshManager: hidden section excluded from draw spans', () => {
|
|
|
187
244
|
camera.updateMatrixWorld()
|
|
188
245
|
|
|
189
246
|
manager.updateSectionCullAndSort(camera, 8, 8, 20)
|
|
190
|
-
expect(manager.globalLegacyBlendBuffer?.
|
|
247
|
+
expect(manager.globalLegacyBlendBuffer?.getVisibleIndexSpans().length).toBe(0)
|
|
191
248
|
|
|
192
249
|
section.visible = true
|
|
250
|
+
const blendBuf = manager.globalLegacyBlendBuffer!
|
|
251
|
+
while (blendBuf.hasPendingUploads()) blendBuf.uploadDirtyRange()
|
|
193
252
|
manager.updateSectionCullAndSort(camera, 8, 8, 20)
|
|
194
|
-
expect(manager.globalLegacyBlendBuffer?.
|
|
253
|
+
expect(manager.globalLegacyBlendBuffer?.getVisibleIndexSpans().length).toBeGreaterThan(0)
|
|
195
254
|
|
|
196
255
|
manager.cleanupSection(key)
|
|
197
256
|
manager.dispose()
|
|
@@ -284,3 +343,52 @@ test('ChunkMeshManager: mixed opaque and blend route to separate global buffers'
|
|
|
284
343
|
|
|
285
344
|
manager.dispose()
|
|
286
345
|
})
|
|
346
|
+
|
|
347
|
+
test('ChunkMeshManager: hidden cube section excluded from draw spans', () => {
|
|
348
|
+
const manager = createManager({ shaderCubes: true })
|
|
349
|
+
const key = '0,0,0'
|
|
350
|
+
manager.updateSection(key, makeShaderCubeOnlyGeometry())
|
|
351
|
+
const section = manager.sectionObjects[key]!
|
|
352
|
+
expect(manager.globalBlockBuffer?.hasSection(key)).toBe(true)
|
|
353
|
+
drainCubeUploads(manager)
|
|
354
|
+
|
|
355
|
+
const camera = makeCullCamera()
|
|
356
|
+
manager.updateSectionCullAndSort(camera, 8, 8, 20)
|
|
357
|
+
expect(manager.globalBlockBuffer?.getVisibleSpans().length).toBeGreaterThan(0)
|
|
358
|
+
|
|
359
|
+
section.visible = false
|
|
360
|
+
manager.updateSectionCullAndSort(camera, 8, 8, 20)
|
|
361
|
+
expect(manager.globalBlockBuffer?.getVisibleSpans().length).toBe(0)
|
|
362
|
+
|
|
363
|
+
section.visible = true
|
|
364
|
+
manager.updateSectionCullAndSort(camera, 8, 8, 20)
|
|
365
|
+
expect(manager.globalBlockBuffer?.getVisibleSpans().length).toBeGreaterThan(0)
|
|
366
|
+
|
|
367
|
+
manager.cleanupSection(key)
|
|
368
|
+
manager.dispose()
|
|
369
|
+
})
|
|
370
|
+
|
|
371
|
+
test('ChunkMeshManager: finishChunkDisplay reveals cube spans and marks cull dirty', () => {
|
|
372
|
+
const manager = createManager({ shaderCubes: true, finishedChunks: {} })
|
|
373
|
+
const key = '0,0,0'
|
|
374
|
+
manager.updateSection(key, makeShaderCubeOnlyGeometry())
|
|
375
|
+
expect(manager.sectionObjects[key]?.visible).toBe(false)
|
|
376
|
+
expect(manager.globalBlockBuffer?.hasSection(key)).toBe(true)
|
|
377
|
+
|
|
378
|
+
const camera = makeCullCamera()
|
|
379
|
+
manager.updateSectionCullAndSort(camera, 8, 8, 20)
|
|
380
|
+
expect(manager.globalBlockBuffer?.getVisibleSpans().length).toBe(0)
|
|
381
|
+
|
|
382
|
+
const markCullDirtySpy = vi.spyOn(manager, 'markCullDirty')
|
|
383
|
+
manager.finishChunkDisplay('0,0')
|
|
384
|
+
expect(manager.sectionObjects[key]?.visible).toBe(true)
|
|
385
|
+
expect(markCullDirtySpy).toHaveBeenCalled()
|
|
386
|
+
|
|
387
|
+
drainCubeUploads(manager)
|
|
388
|
+
manager.updateSectionCullAndSort(camera, 8, 8, 20)
|
|
389
|
+
expect(manager.globalBlockBuffer?.getVisibleSpans().length).toBeGreaterThan(0)
|
|
390
|
+
|
|
391
|
+
markCullDirtySpy.mockRestore()
|
|
392
|
+
manager.cleanupSection(key)
|
|
393
|
+
manager.dispose()
|
|
394
|
+
})
|
|
@@ -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) {
|