minecraft-renderer 0.1.35 → 0.1.36

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "minecraft-renderer",
3
- "version": "0.1.35",
3
+ "version": "0.1.36",
4
4
  "description": "The most Modular Minecraft world renderer with Three.js WebGL backend",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -32,6 +32,10 @@ export const defaultWorldRendererConfig = {
32
32
  autoLowerRenderDistance: false,
33
33
 
34
34
  // Rendering engine settings
35
+ /** Face shading: vanilla Minecraft vs higher-contrast client look */
36
+ shadingTheme: 'high-contrast' as 'vanilla' | 'high-contrast',
37
+ /** Synced from player reactive state (dimension / nether) — consumed by mesher */
38
+ cardinalLight: 'default' as string,
35
39
  dayCycle: true,
36
40
  smoothLighting: true,
37
41
  enableLighting: true,
@@ -32,6 +32,7 @@ export const getInitialPlayerState = (): PlayerStateReactive => proxy({
32
32
  itemUsageTicks: 0,
33
33
  username: '',
34
34
  onlineMode: false,
35
+ cardinalLight: 'default',
35
36
  lightingDisabled: false,
36
37
  shouldHideHand: false,
37
38
  heldItemMain: undefined,
@@ -124,6 +124,7 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
124
124
  soundSystem: SoundSystem | undefined
125
125
 
126
126
  abstract changeBackgroundColor(color: [number, number, number]): void
127
+ abstract changeCardinalLight(cardinalLight: string): void
127
128
 
128
129
  /** Override in subclass to check if any enabled module requires heightmap data */
129
130
  protected anyModuleRequiresHeightmap(): boolean {
@@ -310,6 +311,9 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
310
311
  this.onReactivePlayerStateUpdated('backgroundColor', (value) => {
311
312
  this.changeBackgroundColor(value)
312
313
  })
314
+ this.onReactivePlayerStateUpdated('cardinalLight', (value) => {
315
+ this.changeCardinalLight(value)
316
+ })
313
317
  }
314
318
 
315
319
  watchReactiveConfig() {
@@ -549,6 +553,8 @@ export abstract class WorldRendererCommon<WorkerSend = any, WorkerReceive = any>
549
553
  enableLighting: this.worldRendererConfig.enableLighting,
550
554
  skyLight,
551
555
  smoothLighting: this.worldRendererConfig.smoothLighting,
556
+ shadingTheme: this.worldRendererConfig.shadingTheme,
557
+ cardinalLight: this.worldRendererConfig.cardinalLight,
552
558
  outputFormat: this.outputFormat,
553
559
  // textureSize: this.resourcesManager.currentResources!.blocksAtlasParser.atlas.latest.width,
554
560
  debugModelVariant: this.worldRendererConfig.debugModelVariant,
@@ -395,7 +395,16 @@ function renderElement(world: World, cursor: Vec3, element: BlockElement, doAO:
395
395
  const aos: number[] = []
396
396
  const neighborPos = position.plus(new Vec3(...dir))
397
397
  // 10%
398
- const baseLight = world.getLight(neighborPos, undefined, undefined, block.name) / 15
398
+ const { smoothLighting, shadingTheme, cardinalLight } = world.config
399
+ const faceLight = world.getLight(neighborPos, undefined, undefined, block.name)
400
+ const sideShading = (shadingTheme === 'high-contrast')
401
+ ? (0.8 + 0.5 * Math.max(0, 0.66 * dir[0] + 0.66 * dir[1] + 0.33 * dir[2])) // old directional light behavior
402
+ : (
403
+ cardinalLight === 'nether'
404
+ ? (0.5 + Math.abs(0.1 * dir[0] + 0.4 * dir[1] + 0.3 * dir[2]))
405
+ : (0.75 + 0.25 * dir[1] + 0.05 * (Math.abs(dir[2]) - 3 * Math.abs(dir[0])))
406
+ )
407
+ const baseLight = sideShading * faceLight / 15
399
408
  for (const pos of corners) {
400
409
  let vertex = [
401
410
  (pos[0] ? maxx : minx),
@@ -429,8 +438,6 @@ function renderElement(world: World, cursor: Vec3, element: BlockElement, doAO:
429
438
  }
430
439
 
431
440
  let light = 1
432
- const { smoothLighting } = world.config
433
- // const smoothLighting = true
434
441
  if (doAO) {
435
442
  const dx = pos[0] * 2 - 1
436
443
  const dy = pos[1] * 2 - 1
@@ -442,7 +449,7 @@ function renderElement(world: World, cursor: Vec3, element: BlockElement, doAO:
442
449
  const side2 = world.getBlock(cursor.offset(...side2Dir))
443
450
  const corner = world.getBlock(cursor.offset(...cornerDir))
444
451
 
445
- let cornerLightResult = baseLight * 15
452
+ let cornerLightResult = faceLight
446
453
 
447
454
  if (smoothLighting) {
448
455
  const dirVec = new Vec3(...dir)
@@ -459,7 +466,7 @@ function renderElement(world: World, cursor: Vec3, element: BlockElement, doAO:
459
466
  const cornerLightDir = getVec(new Vec3(...cornerDir))
460
467
  const cornerLight = world.getLight(cursor.plus(cornerLightDir))
461
468
  // interpolate
462
- const lights = [side1Light, side2Light, cornerLight, baseLight * 15]
469
+ const lights = [side1Light, side2Light, cornerLight, faceLight]
463
470
  cornerLightResult = lights.reduce((acc, cur) => acc + cur, 0) / lights.length
464
471
  }
465
472
 
@@ -470,8 +477,10 @@ function renderElement(world: World, cursor: Vec3, element: BlockElement, doAO:
470
477
  // TODO: correctly interpolate ao light based on pos (evaluate once for each corner of the block)
471
478
 
472
479
  const ao = (side1Block && side2Block) ? 0 : (3 - (side1Block + side2Block + cornerBlock))
480
+ const ao_bias = (shadingTheme === 'high-contrast') ? 0.25 : 0.4
481
+ const ao_scale = (shadingTheme === 'high-contrast') ? 0.25 : 0.2
473
482
  // todo light should go upper on lower blocks
474
- light = (ao + 1) / 4 * (cornerLightResult / 15)
483
+ light = sideShading * (ao * ao_scale + ao_bias) * (cornerLightResult / 15)
475
484
  aos.push(ao)
476
485
 
477
486
  // Log AO and light for this corner (corner index is aos.length - 1)
@@ -11,7 +11,9 @@ export const defaultMesherConfig = {
11
11
  worldMinY: 0,
12
12
  enableLighting: true,
13
13
  skyLight: 15,
14
- smoothLighting: false,
14
+ smoothLighting: true,
15
+ shadingTheme: 'high-contrast' as 'vanilla' | 'high-contrast',
16
+ cardinalLight: 'default' as string,
15
17
  outputFormat: 'threeJs' as 'threeJs' | 'webgpu',
16
18
  // textureSize: 1024, // for testing
17
19
  debugModelVariant: undefined as undefined | number[],
@@ -39,6 +39,8 @@ export const getInitialPlayerState = () => proxy({
39
39
  itemUsageTicks: 0,
40
40
  username: '',
41
41
  onlineMode: false,
42
+ /** Dimension ambient lighting preset (e.g. nether) — from login/respawn dimension data when available */
43
+ cardinalLight: 'default' as string,
42
44
  lightingDisabled: false,
43
45
  shouldHideHand: false,
44
46
  heldItemMain: undefined as HandItemBlock | undefined,
@@ -56,7 +56,7 @@ export class WorldRendererThree extends WorldRendererCommon {
56
56
  directionalLight = new THREE.DirectionalLight(0xff_ff_ff, 0.5)
57
57
  entities = new Entities(this, (globalThis as any).mcData)
58
58
  cameraGroupVr?: THREE.Object3D
59
- material = new THREE.MeshLambertMaterial({ vertexColors: true, transparent: true, alphaTest: 0.1 })
59
+ material = new THREE.MeshBasicMaterial({ vertexColors: true, transparent: true, alphaTest: 0.1 })
60
60
  itemsTexture!: THREE.Texture
61
61
  cursorBlock: CursorBlock
62
62
  onRender: Array<(deltaTime: number) => void> = []
@@ -632,6 +632,10 @@ export class WorldRendererThree extends WorldRendererCommon {
632
632
  this.realScene.background = new THREE.Color(color[0], color[1], color[2])
633
633
  }
634
634
 
635
+ changeCardinalLight(cardinalLight: string): void {
636
+ this.worldRendererConfig.cardinalLight = cardinalLight
637
+ }
638
+
635
639
  timeUpdated(newTime: number): void {
636
640
  // Update starfield module with time
637
641
  const starfieldModule = this.getModule<any>('starfield')