@volter/blender-engine 0.1.135 → 0.1.136

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.
@@ -58,6 +58,16 @@ const SAVED_SHADING = {
58
58
  MATERIAL: 'preview',
59
59
  RENDERED: 'rendered',
60
60
  } as const;
61
+ /** SKY-LIGHT OCCLUSION (`blender-world-visibility.ts`) IS OFF IN EVERY VIEW. Its
62
+ * sixteen 512-square tiles each span the whole scene, so a 360 m level gets
63
+ * about a metre per texel, and each lookup is one nearest texel answering
64
+ * yes or no. Faceted surfaces then occlude their own sky at random pixels --
65
+ * static on every polygon in Rendered and Play -- and narrow specular lobes,
66
+ * dominated by a few of the sixteen directions, plausibly flash as the camera
67
+ * moves. It measured right in a closed room a few metres across. Turn it back
68
+ * on once its lookups are filtered and its resolution follows the scene's size
69
+ * (docs/BLENDER-RENDERING-PARITY.md lists the rest). */
70
+ const WORLD_VISIBILITY = false;
61
71
  const scalar = z.number().finite();
62
72
  const point = z.tuple([scalar, scalar, scalar]);
63
73
  const edge = z.tuple([z.number().int().nonnegative(), z.number().int().nonnegative()]);
@@ -799,7 +809,7 @@ export class BlenderRuntimeView {
799
809
  * (`blender-workbench-material.ts`) over their viewport display. */
800
810
  private workbench = false;
801
811
  private readonly workbenchMaterials = new Map<string, THREE.Material>();
802
- private readonly fallback = new THREE.MeshPhysicalMaterial({ color: 0xb9bec6, roughness: 0.72, side: THREE.DoubleSide });
812
+ private readonly fallback = new THREE.MeshPhysicalMaterial({ color: 0xb9bec6, roughness: 0.72, side: THREE.DoubleSide, shadowSide: THREE.BackSide });
803
813
  /** Base Color images, by image name -- ONE texture per image however many
804
814
  * materials read it, and the cache OWNS it: a material points at one and
805
815
  * never disposes it. Held with the size and revision the resident bytes
@@ -1429,13 +1439,15 @@ export class BlenderRuntimeView {
1429
1439
  // objects. Fit shadows for that draw, rather than the camera's pose
1430
1440
  // when Rendered shading was first entered. Captures use this path too.
1431
1441
  if (this.rendered) this.applyShadows(true, camera);
1432
- this.worldVisibility.sync(this.objects.values(),this.world.lightingTexture(),this.root,this.rendered);
1433
- for(const material of [...this.materials.values(),this.fallback])bindWorldVisibility(material,this.worldVisibility);
1434
- for(const object of this.objects.values()) {
1435
- const mesh=object as THREE.Mesh;if(!mesh.isMesh)continue;
1436
- for(const material of Array.isArray(mesh.material)?mesh.material:[mesh.material])bindWorldVisibility(material,this.worldVisibility);
1442
+ if (WORLD_VISIBILITY) {
1443
+ this.worldVisibility.sync(this.objects.values(),this.world.lightingTexture(),this.root,this.rendered);
1444
+ for(const material of [...this.materials.values(),this.fallback])bindWorldVisibility(material,this.worldVisibility);
1445
+ for(const object of this.objects.values()) {
1446
+ const mesh=object as THREE.Mesh;if(!mesh.isMesh)continue;
1447
+ for(const material of Array.isArray(mesh.material)?mesh.material:[mesh.material])bindWorldVisibility(material,this.worldVisibility);
1448
+ }
1449
+ if(options?.renderer)this.worldVisibility.prepare(options.renderer);
1437
1450
  }
1438
- if(options?.renderer)this.worldVisibility.prepare(options.renderer);
1439
1451
  const opaqueDone = performance.now();
1440
1452
  const motion = this.motionGeometry.prepare(camera, !this.rendered && (this.mode ?? this.frame?.mode) === 'OBJECT' &&
1441
1453
  options?.interactive === true, options?.height ?? 0);
@@ -1995,7 +2007,11 @@ export class BlenderRuntimeView {
1995
2007
  for (const [id, data] of Object.entries(next.materials)) {
1996
2008
  // Cycles intersects and shades both faces, including an arcade viewed
1997
2009
  // from underneath. Three's front-face default drops those surfaces.
1998
- const material = this.materials.get(id) ?? new THREE.MeshPhysicalMaterial({ side: THREE.DoubleSide });
2010
+ // The shadow map keeps the back faces a front-faced material draws
2011
+ // there: a two-sided depth pass puts every lit face into its own map, and
2012
+ // the normal offset cannot hold that off at grazing light.
2013
+ const material = this.materials.get(id) ??
2014
+ new THREE.MeshPhysicalMaterial({ side: THREE.DoubleSide, shadowSide: THREE.BackSide });
1999
2015
  material.name = data.name;
2000
2016
  // A LINKED BASE COLOUR REPLACES THE SOCKET'S VALUE, it does not multiply
2001
2017
  // it. Python's `_reduce` fills `color` from the Base Color socket's
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "@volter/blender-engine",
3
3
  "author": "Volter AI, Inc.",
4
4
  "license": "GPL-3.0-or-later",
5
- "version": "0.1.135",
5
+ "version": "0.1.136",
6
6
  "publishConfig": {
7
7
  "access": "public"
8
8
  },