Update visual defaults

Somewhat more conventional visual presentation:

+ Use a neutral gray background a-la most other CAD/modelling software
  for better contrast with the geometry (which defaults to a bright
  yellow).  This is done with the "skybox-environment" image in
  model-viewer, so add a new setting value in settings.ts for this (it
  can be overriden in the URL just like other settings)

+ But using a skybox will cause that image to be used for lighting
  too, which is clearly not desired.  So fetch a nice professional
  HDRI image from Polyhaven for lighting.  This is much better (more
  directional, higher contrast) than the default light environment
  anyway.

+ The checkerboard texture isn't really a good default.  Use a 1x1
  white pixel instead, essentially presenting the model materials
  unchanged.

Also collect the default color in gltf.py out of the code and put it
next to the texture for clarity.  This should probably be wired
through to a setting at some point.

Signed-off-by: Andy Ross <andy@plausible.org>
This commit is contained in:
Andy Ross
2025-07-15 15:16:54 -07:00
parent 3845720d53
commit c14a823dc1
3 changed files with 13 additions and 8 deletions

View File

@@ -29,7 +29,11 @@ export async function settings() {
panSensitivity: 1,
exposure: 1,
shadowIntensity: 0,
background: '',
// Nice low-res outdoor/high-contrast HDRI image (CC0 licensed) for lighting
background: "https://dl.polyhaven.org/file/ph-assets/HDRIs/hdr/1k/qwantani_afternoon_1k.hdr",
// Uniform (1x1 pixel) medium gray background for visibility
skybox: "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNsaFjwHwAFyQKh26fFAAAAAABJRU5ErkJggg==",
};
// Auto-override any settings from the URL

View File

@@ -215,7 +215,7 @@ watch(disableTap, (newDisableTap) => {
<model-viewer ref="elem" v-if="sett != null" :ar="sett.arModes.length > 0" :ar-modes="sett.arModes"
:environment-image="sett.background" :exposure="sett.exposure" :autoplay="sett.autoplay"
:orbit-sensitivity="sett.orbitSensitivity" :pan-sensitivity="sett.panSensitivity"
:poster="poster" :shadow-intensity="sett.shadowIntensity" :skybox-image="sett.background"
:poster="poster" :shadow-intensity="sett.shadowIntensity" :skybox-image="sett.skybox"
:src="props.src" :zoom-sensitivity="sett.zoomSensitivity" alt="The 3D model(s)" camera-controls
camera-orbit="30deg 75deg auto" interaction-prompt="none" max-camera-orbit="Infinity 180deg auto"
min-camera-orbit="-Infinity 0deg 5%" style="width: 100%; height: 100%">
@@ -302,4 +302,4 @@ watch(disableTap, (newDisableTap) => {
float: left;
transition: width 0.3s;
}
</style>
</style>

View File

@@ -4,9 +4,10 @@ import numpy as np
from build123d import Location, Plane, Vector
from pygltflib import *
_checkerboard_image_bytes = base64.decodebytes(
b'iVBORw0KGgoAAAANSUhEUgAAAAIAAAACCAIAAAD91JpzAAAAF0lEQVQI12N49OjR////Gf'
b'/////48WMATwULS8tcyj8AAAAASUVORK5CYII=')
# PNG file containing 1x1 while pixel
_default_tex = (b'iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mP8/x8AAwMCAO+ip1sAAAAASUVORK5CYII=')
_default_color = (1.0, 0.75, 0.0, 1.0)
def get_version() -> str:
try:
@@ -36,7 +37,7 @@ class GLTFMgr:
vertex_positions: List[float] # x, y, z
vertex_colors: List[float] # r, g, b, a
def __init__(self, image: Optional[Tuple[bytes, str]] = (_checkerboard_image_bytes, 'image/png')):
def __init__(self, image: Optional[Tuple[bytes, str]] = (_default_tex, 'image/png')):
self.gltf = GLTF2(
asset=Asset(generator=f"yacv_server@{get_version()}"),
scene=0,
@@ -79,7 +80,7 @@ class GLTFMgr:
def add_face(self, vertices_raw: List[Vector], indices_raw: List[Tuple[int, int, int]],
tex_coord_raw: List[Tuple[float, float]], color: Optional[Tuple[float, float, float, float]] = None):
"""Add a face to the GLTF mesh"""
if color is None: color = (1.0, 0.75, 0.0, 1.0)
if color is None: color = _default_color
# assert len(vertices_raw) == len(tex_coord_raw), f"Vertices and texture coordinates have different lengths"
# assert min([i for t in indices_raw for i in t]) == 0, f"Face indices start at {min(indices_raw)}"
# assert max([e for t in indices_raw for e in t]) < len(vertices_raw), f"Indices have non-existing vertices"