Add contact patch collection and update material creation for water brushes

This commit is contained in:
2026-04-06 17:32:49 +02:00
parent ab4eb22662
commit 94c423878e

View File

@@ -1676,7 +1676,10 @@ export class ViewportHost {
const volumeRenderPaths = resolveBoxVolumeRenderPaths(document.world.advancedRendering);
for (const brush of Object.values(document.brushes)) {
const geometry = buildBoxBrushDerivedMeshData(brush).geometry;
const materials = BOX_FACE_IDS.map((faceId) => this.createFaceMaterial(brush, faceId, document.materials[brush.faces[faceId].materialId ?? ""], this.getFaceHighlightState(brush.id, faceId), volumeRenderPaths));
const contactPatches = brush.volume.mode === "water"
? this.collectViewportWaterContactPatches(document, brush.id, brush.center, brush.rotationDegrees, brush.size)
: [];
const materials = BOX_FACE_IDS.map((faceId) => this.createFaceMaterial(brush, faceId, document.materials[brush.faces[faceId].materialId ?? ""], this.getFaceHighlightState(brush.id, faceId), volumeRenderPaths, contactPatches));
const mesh = new Mesh(geometry, materials);
const brushSelected = isBrushSelected(selection, brush.id);
mesh.userData.brushId = brush.id;
@@ -2067,7 +2070,7 @@ export class ViewportHost {
}
return "none";
}
createFaceMaterial(brush, faceId, material, highlightState, volumeRenderPaths) {
createFaceMaterial(brush, faceId, material, highlightState, volumeRenderPaths, contactPatches) {
const face = brush.faces[faceId];
const selectedFace = highlightState === "selected";
const hoveredFace = highlightState === "hovered";
@@ -2077,32 +2080,25 @@ export class ViewportHost {
const baseOpacity = Math.max(0.08, Math.min(1, brush.volume.water.surfaceOpacity));
const opacityBoost = faceId === "posY" ? 0.16 : 0;
const opacity = Math.min(1, baseOpacity + opacityBoost + (selectedFace ? 0.08 : hoveredFace ? 0.04 : 0));
if (this.displayMode === "wireframe") {
return new MeshBasicMaterial({
color: brush.volume.water.colorHex,
wireframe: true,
transparent: true,
opacity: Math.min(1, opacity + 0.2),
depthWrite: false
});
}
if (this.displayMode === "authoring") {
return new MeshBasicMaterial({
color: brush.volume.water.colorHex,
transparent: true,
opacity
});
}
return new MeshStandardMaterial({
color: brush.volume.water.colorHex,
emissive: brush.volume.water.colorHex,
emissiveIntensity: quality ? 0.09 + brush.volume.water.waveStrength * 0.1 : 0.03,
roughness: quality ? 0.1 : 0.2,
metalness: quality ? 0.04 : 0.01,
transparent: true,
const waterMaterial = createWaterMaterial({
colorHex: brush.volume.water.colorHex,
surfaceOpacity: brush.volume.water.surfaceOpacity,
waveStrength: brush.volume.water.waveStrength,
opacity,
envMapIntensity: quality ? 1.15 : 1
quality,
wireframe: this.displayMode === "wireframe",
isTopFace: faceId === "posY",
time: this.volumeTime,
halfSize: {
x: brush.size.x * 0.5,
z: brush.size.z * 0.5
},
contactPatches
});
if (waterMaterial.animationUniform !== null) {
this.volumeAnimatedUniforms.push(waterMaterial.animationUniform);
}
return waterMaterial.material;
}
if (brush.volume.mode === "fog") {
const quality = volumeRenderPaths.fog === "quality";