minecraft-renderer 0.1.73 → 0.1.75
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/dist/minecraft-renderer.js +62 -60
- package/dist/minecraft-renderer.js.meta.json +1 -1
- package/dist/threeWorker.js +428 -426
- package/package.json +1 -1
- package/src/graphicsBackend/config.ts +4 -0
- package/src/graphicsBackend/types.ts +1 -0
- package/src/lib/bindAbortableListener.ts +1 -1
- package/src/lib/createPlayerObject.ts +1 -1
- package/src/lib/worldrendererCommon.reconfigure.test.ts +4 -1
- package/src/lib/worldrendererCommon.removeColumn.test.ts +8 -4
- package/src/lib/worldrendererCommon.ts +1 -1
- package/src/three/bannerRenderer.ts +4 -1
- package/src/three/chunkMeshManager.ts +10 -77
- package/src/three/entities.ts +2 -1
- package/src/three/graphicsBackendBase.ts +9 -5
- package/src/three/itemMesh.ts +1 -1
- package/src/three/modules/rain.ts +22 -21
- package/src/three/modules/starfield.ts +17 -5
- package/src/three/signTextureCache.ts +64 -0
- package/src/three/tests/signTextureCache.test.ts +60 -39
- package/src/three/worldRendererThree.ts +8 -90
- package/src/wasm-mesher/tests/shaderCubeInstances.test.ts +14 -8
|
@@ -1,11 +1,6 @@
|
|
|
1
1
|
//@ts-nocheck
|
|
2
2
|
import { test, expect, vi, beforeEach } from 'vitest'
|
|
3
3
|
import * as THREE from 'three'
|
|
4
|
-
import { Vec3 } from 'vec3'
|
|
5
|
-
|
|
6
|
-
vi.mock('../entity/EntityMesh', () => ({
|
|
7
|
-
getMesh: vi.fn(),
|
|
8
|
-
}))
|
|
9
4
|
|
|
10
5
|
const renderSignMock = vi.fn()
|
|
11
6
|
vi.mock('../../sign-renderer', () => ({
|
|
@@ -16,25 +11,11 @@ vi.mock('prismarine-chat', () => ({
|
|
|
16
11
|
default: () => () => ({}),
|
|
17
12
|
}))
|
|
18
13
|
|
|
19
|
-
import {
|
|
14
|
+
import { getSignTexture, releaseSignTexture, disposeAllSignTextures } from '../signTextureCache'
|
|
20
15
|
import type { WorldRendererThree } from '../worldRendererThree'
|
|
21
16
|
|
|
22
|
-
function
|
|
23
|
-
|
|
24
|
-
const material = new THREE.MeshBasicMaterial()
|
|
25
|
-
const worldRenderer = {
|
|
26
|
-
version: '1.20',
|
|
27
|
-
shaderCubeBlocksEnabled: () => false,
|
|
28
|
-
getModule: () => undefined,
|
|
29
|
-
sceneOrigin: {
|
|
30
|
-
track: () => {},
|
|
31
|
-
removeAndUntrack: () => {},
|
|
32
|
-
removeAndUntrackAll: () => {},
|
|
33
|
-
},
|
|
34
|
-
blockEntities: {},
|
|
35
|
-
worldRendererConfig: {},
|
|
36
|
-
} as unknown as WorldRendererThree
|
|
37
|
-
return new ChunkMeshManager(worldRenderer, scene, material, 256, 1)
|
|
17
|
+
function createWorldRenderer (): WorldRendererThree {
|
|
18
|
+
return { version: '1.20' } as WorldRendererThree
|
|
38
19
|
}
|
|
39
20
|
|
|
40
21
|
function stubCanvas () {
|
|
@@ -44,40 +25,80 @@ function stubCanvas () {
|
|
|
44
25
|
beforeEach(() => {
|
|
45
26
|
renderSignMock.mockReset()
|
|
46
27
|
renderSignMock.mockImplementation(() => stubCanvas())
|
|
28
|
+
disposeAllSignTextures()
|
|
47
29
|
})
|
|
48
30
|
|
|
49
|
-
test('getSignTexture: same
|
|
50
|
-
const
|
|
51
|
-
const signHeadsRenderer = (manager as unknown as { signHeadsRenderer: { getSignTexture: Function } }).signHeadsRenderer
|
|
52
|
-
const pos = new Vec3(10, 64, 10)
|
|
31
|
+
test('getSignTexture: same content at different positions shares one texture', () => {
|
|
32
|
+
const wr = createWorldRenderer()
|
|
53
33
|
const blockEntity = { Text1: '{"text":"Hello"}' }
|
|
54
34
|
|
|
55
|
-
const tex1 =
|
|
56
|
-
const tex2 =
|
|
35
|
+
const tex1 = getSignTexture(wr, blockEntity, false)
|
|
36
|
+
const tex2 = getSignTexture(wr, { ...blockEntity }, false)
|
|
57
37
|
|
|
58
38
|
expect(tex1).toBeDefined()
|
|
59
39
|
expect(tex2).toBe(tex1)
|
|
60
40
|
expect(renderSignMock).toHaveBeenCalledTimes(1)
|
|
41
|
+
})
|
|
42
|
+
|
|
43
|
+
test('getSignTexture: different text yields different textures', () => {
|
|
44
|
+
const wr = createWorldRenderer()
|
|
61
45
|
|
|
62
|
-
|
|
46
|
+
const tex1 = getSignTexture(wr, { Text1: '{"text":"Hello"}' }, false)!
|
|
47
|
+
const tex2 = getSignTexture(wr, { Text1: '{"text":"World"}' }, false)!
|
|
48
|
+
|
|
49
|
+
expect(tex2).not.toBe(tex1)
|
|
50
|
+
expect(renderSignMock).toHaveBeenCalledTimes(2)
|
|
63
51
|
})
|
|
64
52
|
|
|
65
|
-
test('
|
|
66
|
-
const
|
|
67
|
-
const signHeadsRenderer = (manager as unknown as { signHeadsRenderer: { getSignTexture: Function } }).signHeadsRenderer
|
|
68
|
-
const pos = new Vec3(10, 64, 10)
|
|
53
|
+
test('releaseSignTexture: partial release keeps texture in cache', () => {
|
|
54
|
+
const wr = createWorldRenderer()
|
|
69
55
|
const blockEntity = { Text1: '{"text":"Hello"}' }
|
|
70
56
|
|
|
71
|
-
const tex1 =
|
|
57
|
+
const tex1 = getSignTexture(wr, blockEntity, false)!
|
|
58
|
+
const tex2 = getSignTexture(wr, blockEntity, false)!
|
|
59
|
+
expect(tex1).toBe(tex2)
|
|
60
|
+
|
|
72
61
|
const disposeSpy = vi.spyOn(tex1, 'dispose')
|
|
62
|
+
releaseSignTexture(tex1)
|
|
63
|
+
|
|
64
|
+
expect(disposeSpy).not.toHaveBeenCalled()
|
|
65
|
+
expect(getSignTexture(wr, blockEntity, false)).toBe(tex1)
|
|
66
|
+
expect(renderSignMock).toHaveBeenCalledTimes(1)
|
|
67
|
+
})
|
|
73
68
|
|
|
74
|
-
|
|
75
|
-
const
|
|
69
|
+
test('releaseSignTexture: dispose at zero refcount removes cache entry', () => {
|
|
70
|
+
const wr = createWorldRenderer()
|
|
71
|
+
const blockEntity = { Text1: '{"text":"Hello"}' }
|
|
76
72
|
|
|
77
|
-
|
|
78
|
-
|
|
73
|
+
const tex = getSignTexture(wr, blockEntity, false)!
|
|
74
|
+
const disposeSpy = vi.spyOn(tex, 'dispose')
|
|
75
|
+
|
|
76
|
+
releaseSignTexture(tex)
|
|
79
77
|
expect(disposeSpy).toHaveBeenCalledTimes(1)
|
|
78
|
+
|
|
79
|
+
const tex2 = getSignTexture(wr, blockEntity, false)!
|
|
80
|
+
expect(tex2).not.toBe(tex)
|
|
80
81
|
expect(renderSignMock).toHaveBeenCalledTimes(2)
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
test('getSignTexture: key ignores irrelevant NBT fields', () => {
|
|
85
|
+
const wr = createWorldRenderer()
|
|
86
|
+
const base = { Text1: '{"text":"Hello"}', Color: 'black' }
|
|
81
87
|
|
|
82
|
-
|
|
88
|
+
const tex1 = getSignTexture(wr, base, false)!
|
|
89
|
+
const tex2 = getSignTexture(wr, { ...base, GlowingText: 1, is_waxed: 1 }, false)!
|
|
90
|
+
|
|
91
|
+
expect(tex2).toBe(tex1)
|
|
92
|
+
expect(renderSignMock).toHaveBeenCalledTimes(1)
|
|
93
|
+
})
|
|
94
|
+
|
|
95
|
+
test('getSignTexture: isHanging is part of cache key', () => {
|
|
96
|
+
const wr = createWorldRenderer()
|
|
97
|
+
const blockEntity = { Text1: '{"text":"Hello"}' }
|
|
98
|
+
|
|
99
|
+
const standing = getSignTexture(wr, blockEntity, false)!
|
|
100
|
+
const hanging = getSignTexture(wr, blockEntity, true)!
|
|
101
|
+
|
|
102
|
+
expect(hanging).not.toBe(standing)
|
|
103
|
+
expect(renderSignMock).toHaveBeenCalledTimes(2)
|
|
83
104
|
})
|
|
@@ -2,12 +2,10 @@
|
|
|
2
2
|
import * as THREE from 'three'
|
|
3
3
|
import { Vec3 } from 'vec3'
|
|
4
4
|
import nbt from 'prismarine-nbt'
|
|
5
|
-
import PrismarineChatLoader from 'prismarine-chat'
|
|
6
5
|
import * as tweenJs from '@tweenjs/tween.js'
|
|
7
6
|
import { Biome } from 'minecraft-data'
|
|
8
|
-
import { renderSign } from '../sign-renderer'
|
|
9
7
|
import { DisplayWorldOptions, GraphicsInitOptions } from '../graphicsBackend/types'
|
|
10
|
-
import {
|
|
8
|
+
import { sectionPos } from '../lib/simpleUtils'
|
|
11
9
|
import { WorldRendererCommon } from '../lib/worldrendererCommon'
|
|
12
10
|
import { calculateSkyLightSimple } from '../lib/skyLight'
|
|
13
11
|
import { addNewStat, MC_RENDERER_DEBUG_OVERLAY_CLASS } from '../lib/ui/newStats'
|
|
@@ -55,8 +53,6 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|
|
55
53
|
get sectionObjects() {
|
|
56
54
|
return this.chunkMeshManager.sectionObjects
|
|
57
55
|
}
|
|
58
|
-
chunkTextures = new Map<string, { [pos: string]: THREE.Texture }>()
|
|
59
|
-
signsCache = new Map<string, any>()
|
|
60
56
|
cameraSectionPos: Vec3 = new Vec3(0, 0, 0)
|
|
61
57
|
holdingBlock: IHoldingBlock
|
|
62
58
|
holdingBlockLeft: IHoldingBlock
|
|
@@ -355,6 +351,11 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|
|
355
351
|
return targetState
|
|
356
352
|
}
|
|
357
353
|
|
|
354
|
+
setRain(enabled: boolean): void {
|
|
355
|
+
this.worldRendererConfig.isRaining = enabled
|
|
356
|
+
this.toggleModule('rain', enabled)
|
|
357
|
+
}
|
|
358
|
+
|
|
358
359
|
/**
|
|
359
360
|
* Dispose all modules
|
|
360
361
|
*/
|
|
@@ -696,7 +697,7 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|
|
696
697
|
this.syncSkyLevelFromTime(newTime)
|
|
697
698
|
}
|
|
698
699
|
|
|
699
|
-
private syncSkyLevelFromTime
|
|
700
|
+
private syncSkyLevelFromTime(timeOfDay: number): void {
|
|
700
701
|
const skyLevel = calculateSkyLightSimple(timeOfDay) / 15
|
|
701
702
|
this.chunkMeshManager.setSkyLevel(skyLevel)
|
|
702
703
|
}
|
|
@@ -792,10 +793,6 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|
|
792
793
|
}
|
|
793
794
|
}
|
|
794
795
|
|
|
795
|
-
override updateViewerPosition(pos: Vec3): void {
|
|
796
|
-
this.viewerChunkPosition = pos
|
|
797
|
-
}
|
|
798
|
-
|
|
799
796
|
cameraSectionPositionUpdate() {
|
|
800
797
|
// eslint-disable-next-line guard-for-in
|
|
801
798
|
for (const key in this.sectionObjects) {
|
|
@@ -928,28 +925,6 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|
|
928
925
|
}
|
|
929
926
|
|
|
930
927
|
|
|
931
|
-
getSignTexture(position: Vec3, blockEntity, isHanging, backSide = false) {
|
|
932
|
-
const chunk = chunkPos(position)
|
|
933
|
-
let textures = this.chunkTextures.get(`${chunk[0]},${chunk[1]}`)
|
|
934
|
-
if (!textures) {
|
|
935
|
-
textures = {}
|
|
936
|
-
this.chunkTextures.set(`${chunk[0]},${chunk[1]}`, textures)
|
|
937
|
-
}
|
|
938
|
-
const texturekey = `${position.x},${position.y},${position.z}`
|
|
939
|
-
// todo investigate bug and remove this so don't need to clean in section dirty
|
|
940
|
-
if (textures[texturekey]) return textures[texturekey]
|
|
941
|
-
|
|
942
|
-
const PrismarineChat = PrismarineChatLoader(this.version)
|
|
943
|
-
const canvas = renderSign(blockEntity, isHanging, PrismarineChat)
|
|
944
|
-
if (!canvas) return
|
|
945
|
-
const tex = new THREE.Texture(canvas)
|
|
946
|
-
tex.magFilter = THREE.NearestFilter
|
|
947
|
-
tex.minFilter = THREE.NearestFilter
|
|
948
|
-
tex.needsUpdate = true
|
|
949
|
-
textures[texturekey] = tex
|
|
950
|
-
return tex
|
|
951
|
-
}
|
|
952
|
-
|
|
953
928
|
getCameraPosition(target?: THREE.Vector3): THREE.Vector3 {
|
|
954
929
|
return (target ?? this._tmpCameraPos).set(this.cameraWorldPos.x, this.cameraWorldPos.y, this.cameraWorldPos.z)
|
|
955
930
|
}
|
|
@@ -1442,49 +1417,6 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|
|
1442
1417
|
}
|
|
1443
1418
|
}
|
|
1444
1419
|
|
|
1445
|
-
renderSign(position: Vec3, rotation: number, isWall: boolean, isHanging: boolean, blockEntity) {
|
|
1446
|
-
const tex = this.getSignTexture(position, blockEntity, isHanging)
|
|
1447
|
-
|
|
1448
|
-
if (!tex) return
|
|
1449
|
-
|
|
1450
|
-
// todo implement
|
|
1451
|
-
// const key = JSON.stringify({ position, rotation, isWall })
|
|
1452
|
-
// if (this.signsCache.has(key)) {
|
|
1453
|
-
// console.log('cached', key)
|
|
1454
|
-
// } else {
|
|
1455
|
-
// this.signsCache.set(key, tex)
|
|
1456
|
-
// }
|
|
1457
|
-
|
|
1458
|
-
const mesh = new THREE.Mesh(new THREE.PlaneGeometry(1, 1), new THREE.MeshBasicMaterial({ map: tex, transparent: true }))
|
|
1459
|
-
mesh.renderOrder = 999
|
|
1460
|
-
|
|
1461
|
-
const lineHeight = 7 / 16
|
|
1462
|
-
const scaleFactor = isHanging ? 1.3 : 1
|
|
1463
|
-
mesh.scale.set(1 * scaleFactor, lineHeight * scaleFactor, 1 * scaleFactor)
|
|
1464
|
-
|
|
1465
|
-
const thickness = (isHanging ? 2 : 1.5) / 16
|
|
1466
|
-
const wallSpacing = 0.25 / 16
|
|
1467
|
-
if (isWall && !isHanging) {
|
|
1468
|
-
mesh.position.set(0, 0, -0.5 + thickness + wallSpacing + 0.0001)
|
|
1469
|
-
} else {
|
|
1470
|
-
mesh.position.set(0, 0, thickness / 2 + 0.0001)
|
|
1471
|
-
}
|
|
1472
|
-
|
|
1473
|
-
const group = new THREE.Group()
|
|
1474
|
-
group.rotation.set(
|
|
1475
|
-
0,
|
|
1476
|
-
-THREE.MathUtils.degToRad(rotation * (isWall ? 90 : 45 / 2)),
|
|
1477
|
-
0
|
|
1478
|
-
)
|
|
1479
|
-
group.add(mesh)
|
|
1480
|
-
const height = (isHanging ? 10 : 8) / 16
|
|
1481
|
-
const heightOffset = (isHanging ? 0 : isWall ? 4.333 : 9.333) / 16
|
|
1482
|
-
const textPosition = height / 2 + heightOffset
|
|
1483
|
-
this.sceneOrigin.track(group)
|
|
1484
|
-
group.position.set(position.x + 0.5, position.y + textPosition, position.z + 0.5)
|
|
1485
|
-
return group
|
|
1486
|
-
}
|
|
1487
|
-
|
|
1488
1420
|
lightUpdate(chunkX: number, chunkZ: number) {
|
|
1489
1421
|
// set all sections in the chunk dirty
|
|
1490
1422
|
for (let y = this.worldSizeParams.minY; y < this.worldSizeParams.worldHeight; y += 16) {
|
|
@@ -1534,19 +1466,6 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|
|
1534
1466
|
}))
|
|
1535
1467
|
}
|
|
1536
1468
|
|
|
1537
|
-
cleanChunkTextures(x, z) {
|
|
1538
|
-
const textures = this.chunkTextures.get(`${Math.floor(x / 16)},${Math.floor(z / 16)}`) ?? {}
|
|
1539
|
-
for (const key of Object.keys(textures)) {
|
|
1540
|
-
textures[key].dispose()
|
|
1541
|
-
delete textures[key]
|
|
1542
|
-
}
|
|
1543
|
-
// Sign / head textures moved to ChunkMeshManager.signHeadsRenderer in PR
|
|
1544
|
-
// #16; without invalidating that cache here, sign edits (and any other
|
|
1545
|
-
// block-entity NBT change picked up via setSectionDirty) would re-render
|
|
1546
|
-
// with the stale cached canvas until a full world reset.
|
|
1547
|
-
this.chunkMeshManager.cleanSignChunkTextures(x, z)
|
|
1548
|
-
}
|
|
1549
|
-
|
|
1550
1469
|
readdChunks() {
|
|
1551
1470
|
for (const key of Object.keys(this.sectionObjects)) {
|
|
1552
1471
|
this.scene.remove(this.sectionObjects[key])
|
|
@@ -1568,7 +1487,6 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|
|
1568
1487
|
removeColumn(x, z) {
|
|
1569
1488
|
super.removeColumn(x, z)
|
|
1570
1489
|
|
|
1571
|
-
this.cleanChunkTextures(x, z)
|
|
1572
1490
|
this.clearPendingSectionUpdatesForChunk(x, z)
|
|
1573
1491
|
const sectionHeight = this.getSectionHeight()
|
|
1574
1492
|
const worldMinY = this.worldMinYRender
|
|
@@ -1583,7 +1501,7 @@ export class WorldRendererThree extends WorldRendererCommon {
|
|
|
1583
1501
|
this.chunkMeshManager.onChunkRemovedFromGate(`${x},${z}`)
|
|
1584
1502
|
}
|
|
1585
1503
|
|
|
1586
|
-
updateViewerPosition(pos: Vec3) {
|
|
1504
|
+
override updateViewerPosition(pos: Vec3) {
|
|
1587
1505
|
super.updateViewerPosition(pos)
|
|
1588
1506
|
if (this.chunkMeshManager.pendingNearReveal.size > 0) {
|
|
1589
1507
|
this.chunkMeshManager.tryRevealPending()
|
|
@@ -23,6 +23,12 @@ import { renderWasmOutputToGeometry } from '../bridge/render-from-wasm'
|
|
|
23
23
|
|
|
24
24
|
const VERSION = '1.16.5'
|
|
25
25
|
const STONE = 1
|
|
26
|
+
|
|
27
|
+
function requireShaderCubeResources() {
|
|
28
|
+
const resources = getShaderCubeResources()
|
|
29
|
+
if (!resources) throw new Error('shader cube resources unavailable in test')
|
|
30
|
+
return resources
|
|
31
|
+
}
|
|
26
32
|
/** mc-assets blocksAtlases.json → stone */
|
|
27
33
|
const STONE_ATLAS_TILE_INDEX = 552
|
|
28
34
|
|
|
@@ -39,7 +45,7 @@ test('packWord2: AO diagonal flip sets bit 12', () => {
|
|
|
39
45
|
light_data: [[1, 1, 1, 1]],
|
|
40
46
|
light_combined: [[255, 255, 255, 255]],
|
|
41
47
|
}
|
|
42
|
-
const { textureIndexMapping, tintPalette } =
|
|
48
|
+
const { textureIndexMapping, tintPalette } = requireShaderCubeResources()
|
|
43
49
|
const model = {
|
|
44
50
|
elements: [{
|
|
45
51
|
faces: {
|
|
@@ -78,7 +84,7 @@ test('packWord0: section-local lx/ly/lz and face id', () => {
|
|
|
78
84
|
light_data: [[0.5, 0.5, 0.5, 0.5]],
|
|
79
85
|
light_combined: [[128, 128, 128, 128]],
|
|
80
86
|
}
|
|
81
|
-
const { textureIndexMapping, tintPalette } =
|
|
87
|
+
const { textureIndexMapping, tintPalette } = requireShaderCubeResources()
|
|
82
88
|
const model = {
|
|
83
89
|
elements: [{
|
|
84
90
|
faces: {
|
|
@@ -111,7 +117,7 @@ test('packWord0: section-local lx/ly/lz and face id', () => {
|
|
|
111
117
|
})
|
|
112
118
|
|
|
113
119
|
test('isShaderCubeBlock: rejects model rotation and sectionHeight !== 16', () => {
|
|
114
|
-
const { textureIndexMapping } =
|
|
120
|
+
const { textureIndexMapping } = requireShaderCubeResources()
|
|
115
121
|
const baseModel = {
|
|
116
122
|
elements: [{
|
|
117
123
|
faces: {
|
|
@@ -222,7 +228,7 @@ test('south face: AO corners remapped to shader order (elemFaces [0,3,1,2] → s
|
|
|
222
228
|
light_data: [[1, 1, 1, 1]],
|
|
223
229
|
light_combined: [[10, 20, 30, 40]],
|
|
224
230
|
}
|
|
225
|
-
const { textureIndexMapping, tintPalette } =
|
|
231
|
+
const { textureIndexMapping, tintPalette } = requireShaderCubeResources()
|
|
226
232
|
const model = { elements: [{ faces: SIX_FACE_TEXTURES }] }
|
|
227
233
|
tryBuildShaderCubeInstances(
|
|
228
234
|
block,
|
|
@@ -248,7 +254,7 @@ test('south face: diagonal flip uses remapped AO (differs from raw elemFaces for
|
|
|
248
254
|
light_data: [[1, 1, 1, 1]],
|
|
249
255
|
light_combined: [[255, 255, 255, 255]],
|
|
250
256
|
}
|
|
251
|
-
const { textureIndexMapping, tintPalette } =
|
|
257
|
+
const { textureIndexMapping, tintPalette } = requireShaderCubeResources()
|
|
252
258
|
const model = { elements: [{ faces: SIX_FACE_TEXTURES }] }
|
|
253
259
|
const opts = {
|
|
254
260
|
sectionOrigin: { x: 0, y: 0, z: 0 },
|
|
@@ -285,7 +291,7 @@ test('doAO false: full bright AO/light and no diagonal flip', () => {
|
|
|
285
291
|
light_data: [[0, 0, 0, 0]],
|
|
286
292
|
light_combined: [[0, 0, 0, 0]],
|
|
287
293
|
}
|
|
288
|
-
const { textureIndexMapping, tintPalette } =
|
|
294
|
+
const { textureIndexMapping, tintPalette } = requireShaderCubeResources()
|
|
289
295
|
const model = { elements: [{ faces: SIX_FACE_TEXTURES }] }
|
|
290
296
|
tryBuildShaderCubeInstances(
|
|
291
297
|
block,
|
|
@@ -329,7 +335,7 @@ test.each(SECTION_ORIGIN_ROUND_TRIP_CASES)(
|
|
|
329
335
|
light_data: [[1, 1, 1, 1]],
|
|
330
336
|
light_combined: [[255, 255, 255, 255]],
|
|
331
337
|
}
|
|
332
|
-
const { textureIndexMapping, tintPalette } =
|
|
338
|
+
const { textureIndexMapping, tintPalette } = requireShaderCubeResources()
|
|
333
339
|
const model = { elements: [{ faces: SIX_FACE_TEXTURES }] }
|
|
334
340
|
tryBuildShaderCubeInstances(
|
|
335
341
|
block,
|
|
@@ -361,7 +367,7 @@ test('section index relative decode past 2^20: exact integer subtract', () => {
|
|
|
361
367
|
light_data: [[1, 1, 1, 1]],
|
|
362
368
|
light_combined: [[255, 255, 255, 255]],
|
|
363
369
|
}
|
|
364
|
-
const { textureIndexMapping, tintPalette } =
|
|
370
|
+
const { textureIndexMapping, tintPalette } = requireShaderCubeResources()
|
|
365
371
|
const model = { elements: [{ faces: SIX_FACE_TEXTURES }] }
|
|
366
372
|
tryBuildShaderCubeInstances(
|
|
367
373
|
block,
|