Add water surface subdivision and UV interpolation in box brush mesh
This commit is contained in:
@@ -23,6 +23,7 @@ const EDGE_VERTEX_IDS = {
|
|||||||
edgeZ_negX_posY: ["negX_posY_negZ", "negX_posY_posZ"],
|
edgeZ_negX_posY: ["negX_posY_negZ", "negX_posY_posZ"],
|
||||||
edgeZ_posX_posY: ["posX_posY_negZ", "posX_posY_posZ"]
|
edgeZ_posX_posY: ["posX_posY_negZ", "posX_posY_posZ"]
|
||||||
};
|
};
|
||||||
|
const WATER_TOP_FACE_RENDER_SEGMENTS = 12;
|
||||||
function cloneVec3(vector) {
|
function cloneVec3(vector) {
|
||||||
return { x: vector.x, y: vector.y, z: vector.z };
|
return { x: vector.x, y: vector.y, z: vector.z };
|
||||||
}
|
}
|
||||||
@@ -222,6 +223,29 @@ function computeFaceBounds(vertices) {
|
|||||||
}
|
}
|
||||||
return { min, max };
|
return { min, max };
|
||||||
}
|
}
|
||||||
|
function lerpNumber(start, end, amount) {
|
||||||
|
return start + (end - start) * amount;
|
||||||
|
}
|
||||||
|
function lerpVec3(start, end, amount) {
|
||||||
|
return {
|
||||||
|
x: lerpNumber(start.x, end.x, amount),
|
||||||
|
y: lerpNumber(start.y, end.y, amount),
|
||||||
|
z: lerpNumber(start.z, end.z, amount)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
function interpolateQuadSurfaceVertex(corners, u, v) {
|
||||||
|
const topEdge = lerpVec3(corners[0], corners[1], u);
|
||||||
|
const bottomEdge = lerpVec3(corners[3], corners[2], u);
|
||||||
|
return lerpVec3(topEdge, bottomEdge, v);
|
||||||
|
}
|
||||||
|
function pushRenderedFaceVertex(positions, normals, uvs, indices, vertex, normal, faceId, faceBounds, uvSize, uvState) {
|
||||||
|
const projectedUv = projectLocalVertexToFaceUv(vertex, faceId, faceBounds);
|
||||||
|
const transformedUv = transformProjectedFaceUv(projectedUv, uvSize, uvState);
|
||||||
|
positions.push(vertex.x, vertex.y, vertex.z);
|
||||||
|
normals.push(normal.x, normal.y, normal.z);
|
||||||
|
uvs.push(transformedUv.x, transformedUv.y);
|
||||||
|
indices.push(indices.length);
|
||||||
|
}
|
||||||
export function getBoxBrushFaceVertexIds(faceId) {
|
export function getBoxBrushFaceVertexIds(faceId) {
|
||||||
return FACE_VERTEX_IDS[faceId];
|
return FACE_VERTEX_IDS[faceId];
|
||||||
}
|
}
|
||||||
@@ -257,6 +281,7 @@ export function buildBoxBrushDerivedMeshData(brush) {
|
|||||||
const normal = computeNewellNormal(faceVertices);
|
const normal = computeNewellNormal(faceVertices);
|
||||||
const faceBounds = computeFaceBounds(faceVertices);
|
const faceBounds = computeFaceBounds(faceVertices);
|
||||||
const uvSize = getFaceUvSize(faceId, faceBounds);
|
const uvSize = getFaceUvSize(faceId, faceBounds);
|
||||||
|
const uvState = brush.faces[faceId].uv;
|
||||||
const indexStart = indices.length;
|
const indexStart = indices.length;
|
||||||
faceSurfaces.push({
|
faceSurfaces.push({
|
||||||
faceId,
|
faceId,
|
||||||
@@ -264,15 +289,32 @@ export function buildBoxBrushDerivedMeshData(brush) {
|
|||||||
triangles,
|
triangles,
|
||||||
normal
|
normal
|
||||||
});
|
});
|
||||||
for (const triangle of triangles) {
|
const useSubdividedWaterTopFace = brush.volume.mode === "water" && faceId === "posY" && brush.volume.water.surfaceDisplacementEnabled;
|
||||||
for (const vertexOffset of triangle) {
|
if (useSubdividedWaterTopFace) {
|
||||||
const vertex = faceVertices[vertexOffset];
|
const faceCorners = faceVertices;
|
||||||
const projectedUv = projectLocalVertexToFaceUv(vertex, faceId, faceBounds);
|
for (let row = 0; row < WATER_TOP_FACE_RENDER_SEGMENTS; row += 1) {
|
||||||
const transformedUv = transformProjectedFaceUv(projectedUv, uvSize, brush.faces[faceId].uv);
|
const v0 = row / WATER_TOP_FACE_RENDER_SEGMENTS;
|
||||||
positions.push(vertex.x, vertex.y, vertex.z);
|
const v1 = (row + 1) / WATER_TOP_FACE_RENDER_SEGMENTS;
|
||||||
normals.push(normal.x, normal.y, normal.z);
|
for (let column = 0; column < WATER_TOP_FACE_RENDER_SEGMENTS; column += 1) {
|
||||||
uvs.push(transformedUv.x, transformedUv.y);
|
const u0 = column / WATER_TOP_FACE_RENDER_SEGMENTS;
|
||||||
indices.push(indices.length);
|
const u1 = (column + 1) / WATER_TOP_FACE_RENDER_SEGMENTS;
|
||||||
|
const quadVertices = [
|
||||||
|
interpolateQuadSurfaceVertex(faceCorners, u0, v0),
|
||||||
|
interpolateQuadSurfaceVertex(faceCorners, u1, v0),
|
||||||
|
interpolateQuadSurfaceVertex(faceCorners, u1, v1),
|
||||||
|
interpolateQuadSurfaceVertex(faceCorners, u0, v1)
|
||||||
|
];
|
||||||
|
for (const vertex of [quadVertices[0], quadVertices[1], quadVertices[2], quadVertices[0], quadVertices[2], quadVertices[3]]) {
|
||||||
|
pushRenderedFaceVertex(positions, normals, uvs, indices, vertex, normal, faceId, faceBounds, uvSize, uvState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
for (const triangle of triangles) {
|
||||||
|
for (const vertexOffset of triangle) {
|
||||||
|
pushRenderedFaceVertex(positions, normals, uvs, indices, faceVertices[vertexOffset], normal, faceId, faceBounds, uvSize, uvState);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
groups.push({
|
groups.push({
|
||||||
|
|||||||
@@ -36,6 +36,8 @@ const EDGE_VERTEX_IDS: Record<BoxEdgeId, readonly [BoxVertexId, BoxVertexId]> =
|
|||||||
edgeZ_posX_posY: ["posX_posY_negZ", "posX_posY_posZ"]
|
edgeZ_posX_posY: ["posX_posY_negZ", "posX_posY_posZ"]
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const WATER_TOP_FACE_RENDER_SEGMENTS = 12;
|
||||||
|
|
||||||
export interface BoxBrushGeometryDiagnostic {
|
export interface BoxBrushGeometryDiagnostic {
|
||||||
code: string;
|
code: string;
|
||||||
message: string;
|
message: string;
|
||||||
@@ -280,6 +282,50 @@ function computeFaceBounds(vertices: Vec3[]): { min: Vec3; max: Vec3 } {
|
|||||||
return { min, max };
|
return { min, max };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function lerpNumber(start: number, end: number, amount: number) {
|
||||||
|
return start + (end - start) * amount;
|
||||||
|
}
|
||||||
|
|
||||||
|
function lerpVec3(start: Vec3, end: Vec3, amount: number): Vec3 {
|
||||||
|
return {
|
||||||
|
x: lerpNumber(start.x, end.x, amount),
|
||||||
|
y: lerpNumber(start.y, end.y, amount),
|
||||||
|
z: lerpNumber(start.z, end.z, amount)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
function interpolateQuadSurfaceVertex(
|
||||||
|
corners: readonly [Vec3, Vec3, Vec3, Vec3],
|
||||||
|
u: number,
|
||||||
|
v: number
|
||||||
|
): Vec3 {
|
||||||
|
const topEdge = lerpVec3(corners[0], corners[1], u);
|
||||||
|
const bottomEdge = lerpVec3(corners[3], corners[2], u);
|
||||||
|
|
||||||
|
return lerpVec3(topEdge, bottomEdge, v);
|
||||||
|
}
|
||||||
|
|
||||||
|
function pushRenderedFaceVertex(
|
||||||
|
positions: number[],
|
||||||
|
normals: number[],
|
||||||
|
uvs: number[],
|
||||||
|
indices: number[],
|
||||||
|
vertex: Vec3,
|
||||||
|
normal: Vec3,
|
||||||
|
faceId: BoxFaceId,
|
||||||
|
faceBounds: { min: Vec3; max: Vec3 },
|
||||||
|
uvSize: Vec2,
|
||||||
|
uvState: FaceUvState
|
||||||
|
) {
|
||||||
|
const projectedUv = projectLocalVertexToFaceUv(vertex, faceId, faceBounds);
|
||||||
|
const transformedUv = transformProjectedFaceUv(projectedUv, uvSize, uvState);
|
||||||
|
|
||||||
|
positions.push(vertex.x, vertex.y, vertex.z);
|
||||||
|
normals.push(normal.x, normal.y, normal.z);
|
||||||
|
uvs.push(transformedUv.x, transformedUv.y);
|
||||||
|
indices.push(indices.length);
|
||||||
|
}
|
||||||
|
|
||||||
export function getBoxBrushFaceVertexIds(faceId: BoxFaceId): readonly [BoxVertexId, BoxVertexId, BoxVertexId, BoxVertexId] {
|
export function getBoxBrushFaceVertexIds(faceId: BoxFaceId): readonly [BoxVertexId, BoxVertexId, BoxVertexId, BoxVertexId] {
|
||||||
return FACE_VERTEX_IDS[faceId];
|
return FACE_VERTEX_IDS[faceId];
|
||||||
}
|
}
|
||||||
@@ -322,6 +368,7 @@ export function buildBoxBrushDerivedMeshData(brush: BoxBrush): DerivedBoxBrushMe
|
|||||||
const normal = computeNewellNormal(faceVertices);
|
const normal = computeNewellNormal(faceVertices);
|
||||||
const faceBounds = computeFaceBounds(faceVertices);
|
const faceBounds = computeFaceBounds(faceVertices);
|
||||||
const uvSize = getFaceUvSize(faceId, faceBounds);
|
const uvSize = getFaceUvSize(faceId, faceBounds);
|
||||||
|
const uvState = brush.faces[faceId].uv as FaceUvState;
|
||||||
const indexStart = indices.length;
|
const indexStart = indices.length;
|
||||||
|
|
||||||
faceSurfaces.push({
|
faceSurfaces.push({
|
||||||
@@ -331,15 +378,49 @@ export function buildBoxBrushDerivedMeshData(brush: BoxBrush): DerivedBoxBrushMe
|
|||||||
normal
|
normal
|
||||||
});
|
});
|
||||||
|
|
||||||
for (const triangle of triangles) {
|
const useSubdividedWaterTopFace =
|
||||||
for (const vertexOffset of triangle) {
|
brush.volume.mode === "water" &&
|
||||||
const vertex = faceVertices[vertexOffset];
|
faceId === "posY" &&
|
||||||
const projectedUv = projectLocalVertexToFaceUv(vertex, faceId, faceBounds);
|
brush.volume.water.surfaceDisplacementEnabled;
|
||||||
const transformedUv = transformProjectedFaceUv(projectedUv, uvSize, brush.faces[faceId].uv as FaceUvState);
|
|
||||||
positions.push(vertex.x, vertex.y, vertex.z);
|
if (useSubdividedWaterTopFace) {
|
||||||
normals.push(normal.x, normal.y, normal.z);
|
const faceCorners = faceVertices as [Vec3, Vec3, Vec3, Vec3];
|
||||||
uvs.push(transformedUv.x, transformedUv.y);
|
|
||||||
indices.push(indices.length);
|
for (let row = 0; row < WATER_TOP_FACE_RENDER_SEGMENTS; row += 1) {
|
||||||
|
const v0 = row / WATER_TOP_FACE_RENDER_SEGMENTS;
|
||||||
|
const v1 = (row + 1) / WATER_TOP_FACE_RENDER_SEGMENTS;
|
||||||
|
|
||||||
|
for (let column = 0; column < WATER_TOP_FACE_RENDER_SEGMENTS; column += 1) {
|
||||||
|
const u0 = column / WATER_TOP_FACE_RENDER_SEGMENTS;
|
||||||
|
const u1 = (column + 1) / WATER_TOP_FACE_RENDER_SEGMENTS;
|
||||||
|
const quadVertices: [Vec3, Vec3, Vec3, Vec3] = [
|
||||||
|
interpolateQuadSurfaceVertex(faceCorners, u0, v0),
|
||||||
|
interpolateQuadSurfaceVertex(faceCorners, u1, v0),
|
||||||
|
interpolateQuadSurfaceVertex(faceCorners, u1, v1),
|
||||||
|
interpolateQuadSurfaceVertex(faceCorners, u0, v1)
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const vertex of [quadVertices[0], quadVertices[1], quadVertices[2], quadVertices[0], quadVertices[2], quadVertices[3]]) {
|
||||||
|
pushRenderedFaceVertex(positions, normals, uvs, indices, vertex, normal, faceId, faceBounds, uvSize, uvState);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
for (const triangle of triangles) {
|
||||||
|
for (const vertexOffset of triangle) {
|
||||||
|
pushRenderedFaceVertex(
|
||||||
|
positions,
|
||||||
|
normals,
|
||||||
|
uvs,
|
||||||
|
indices,
|
||||||
|
faceVertices[vertexOffset],
|
||||||
|
normal,
|
||||||
|
faceId,
|
||||||
|
faceBounds,
|
||||||
|
uvSize,
|
||||||
|
uvState
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -718,7 +718,6 @@ export function createWaterMaterial(options) {
|
|||||||
|
|
||||||
varying vec2 vLocalSurfaceUv;
|
varying vec2 vLocalSurfaceUv;
|
||||||
varying vec3 vWaveNormal;
|
varying vec3 vWaveNormal;
|
||||||
varying vec3 vWorldPos;
|
|
||||||
varying vec3 vViewDir;
|
varying vec3 vViewDir;
|
||||||
varying vec4 vReflectionCoord;
|
varying vec4 vReflectionCoord;
|
||||||
#include <fog_pars_vertex>
|
#include <fog_pars_vertex>
|
||||||
@@ -754,7 +753,6 @@ export function createWaterMaterial(options) {
|
|||||||
|
|
||||||
vec4 worldPos = modelMatrix * vec4(transformedPosition, 1.0);
|
vec4 worldPos = modelMatrix * vec4(transformedPosition, 1.0);
|
||||||
vec4 mvPosition = viewMatrix * worldPos;
|
vec4 mvPosition = viewMatrix * worldPos;
|
||||||
vWorldPos = worldPos.xyz;
|
|
||||||
vViewDir = normalize(cameraPosition - worldPos.xyz);
|
vViewDir = normalize(cameraPosition - worldPos.xyz);
|
||||||
vReflectionCoord = reflectionMatrix * worldPos;
|
vReflectionCoord = reflectionMatrix * worldPos;
|
||||||
gl_Position = projectionMatrix * mvPosition;
|
gl_Position = projectionMatrix * mvPosition;
|
||||||
@@ -779,7 +777,6 @@ export function createWaterMaterial(options) {
|
|||||||
|
|
||||||
varying vec2 vLocalSurfaceUv;
|
varying vec2 vLocalSurfaceUv;
|
||||||
varying vec3 vWaveNormal;
|
varying vec3 vWaveNormal;
|
||||||
varying vec3 vWorldPos;
|
|
||||||
varying vec3 vViewDir;
|
varying vec3 vViewDir;
|
||||||
varying vec4 vReflectionCoord;
|
varying vec4 vReflectionCoord;
|
||||||
#include <fog_pars_fragment>
|
#include <fog_pars_fragment>
|
||||||
|
|||||||
@@ -975,7 +975,6 @@ export function createWaterMaterial(options: WaterMaterialOptions): WaterMateria
|
|||||||
|
|
||||||
varying vec2 vLocalSurfaceUv;
|
varying vec2 vLocalSurfaceUv;
|
||||||
varying vec3 vWaveNormal;
|
varying vec3 vWaveNormal;
|
||||||
varying vec3 vWorldPos;
|
|
||||||
varying vec3 vViewDir;
|
varying vec3 vViewDir;
|
||||||
varying vec4 vReflectionCoord;
|
varying vec4 vReflectionCoord;
|
||||||
#include <fog_pars_vertex>
|
#include <fog_pars_vertex>
|
||||||
@@ -1011,7 +1010,6 @@ export function createWaterMaterial(options: WaterMaterialOptions): WaterMateria
|
|||||||
|
|
||||||
vec4 worldPos = modelMatrix * vec4(transformedPosition, 1.0);
|
vec4 worldPos = modelMatrix * vec4(transformedPosition, 1.0);
|
||||||
vec4 mvPosition = viewMatrix * worldPos;
|
vec4 mvPosition = viewMatrix * worldPos;
|
||||||
vWorldPos = worldPos.xyz;
|
|
||||||
vViewDir = normalize(cameraPosition - worldPos.xyz);
|
vViewDir = normalize(cameraPosition - worldPos.xyz);
|
||||||
vReflectionCoord = reflectionMatrix * worldPos;
|
vReflectionCoord = reflectionMatrix * worldPos;
|
||||||
gl_Position = projectionMatrix * mvPosition;
|
gl_Position = projectionMatrix * mvPosition;
|
||||||
@@ -1036,7 +1034,6 @@ export function createWaterMaterial(options: WaterMaterialOptions): WaterMateria
|
|||||||
|
|
||||||
varying vec2 vLocalSurfaceUv;
|
varying vec2 vLocalSurfaceUv;
|
||||||
varying vec3 vWaveNormal;
|
varying vec3 vWaveNormal;
|
||||||
varying vec3 vWorldPos;
|
|
||||||
varying vec3 vViewDir;
|
varying vec3 vViewDir;
|
||||||
varying vec4 vReflectionCoord;
|
varying vec4 vReflectionCoord;
|
||||||
#include <fog_pars_fragment>
|
#include <fog_pars_fragment>
|
||||||
|
|||||||
@@ -628,8 +628,19 @@ export class RuntimeHost {
|
|||||||
const previousAutoClear = this.renderer.autoClear;
|
const previousAutoClear = this.renderer.autoClear;
|
||||||
const previousRenderTarget = this.renderer.getRenderTarget();
|
const previousRenderTarget = this.renderer.getRenderTarget();
|
||||||
const previousFogDensity = this.underwaterSceneFog.density;
|
const previousFogDensity = this.underwaterSceneFog.density;
|
||||||
|
const previousReflectionStates = this.runtimeWaterContactUniforms.map((waterBinding) => ({
|
||||||
|
binding: waterBinding,
|
||||||
|
enabled: waterBinding.reflectionEnabledUniform?.value ?? 0,
|
||||||
|
texture: waterBinding.reflectionTextureUniform?.value ?? null
|
||||||
|
}));
|
||||||
try {
|
try {
|
||||||
this.underwaterSceneFog.density = 0;
|
this.underwaterSceneFog.density = 0;
|
||||||
|
for (const state of previousReflectionStates) {
|
||||||
|
if (state.binding.reflectionEnabledUniform !== null) {
|
||||||
|
state.binding.reflectionEnabledUniform.value = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
binding.reflectionTextureUniform.value = null;
|
||||||
this.renderer.autoClear = true;
|
this.renderer.autoClear = true;
|
||||||
this.renderer.setRenderTarget(binding.reflectionRenderTarget);
|
this.renderer.setRenderTarget(binding.reflectionRenderTarget);
|
||||||
this.renderer.clear();
|
this.renderer.clear();
|
||||||
@@ -640,6 +651,14 @@ export class RuntimeHost {
|
|||||||
this.renderer.autoClear = previousAutoClear;
|
this.renderer.autoClear = previousAutoClear;
|
||||||
this.modelGroup.visible = previousModelGroupVisibility;
|
this.modelGroup.visible = previousModelGroupVisibility;
|
||||||
this.underwaterSceneFog.density = previousFogDensity;
|
this.underwaterSceneFog.density = previousFogDensity;
|
||||||
|
for (const state of previousReflectionStates) {
|
||||||
|
if (state.binding.reflectionEnabledUniform !== null) {
|
||||||
|
state.binding.reflectionEnabledUniform.value = state.enabled;
|
||||||
|
}
|
||||||
|
if (state.binding.reflectionTextureUniform !== null) {
|
||||||
|
state.binding.reflectionTextureUniform.value = state.texture;
|
||||||
|
}
|
||||||
|
}
|
||||||
for (const hiddenWaterMesh of hiddenWaterMeshes) {
|
for (const hiddenWaterMesh of hiddenWaterMeshes) {
|
||||||
hiddenWaterMesh.mesh.visible = hiddenWaterMesh.visible;
|
hiddenWaterMesh.mesh.visible = hiddenWaterMesh.visible;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -884,9 +884,20 @@ export class RuntimeHost {
|
|||||||
const previousAutoClear = this.renderer.autoClear;
|
const previousAutoClear = this.renderer.autoClear;
|
||||||
const previousRenderTarget = this.renderer.getRenderTarget();
|
const previousRenderTarget = this.renderer.getRenderTarget();
|
||||||
const previousFogDensity = this.underwaterSceneFog.density;
|
const previousFogDensity = this.underwaterSceneFog.density;
|
||||||
|
const previousReflectionStates = this.runtimeWaterContactUniforms.map((waterBinding) => ({
|
||||||
|
binding: waterBinding,
|
||||||
|
enabled: waterBinding.reflectionEnabledUniform?.value ?? 0,
|
||||||
|
texture: waterBinding.reflectionTextureUniform?.value ?? null
|
||||||
|
}));
|
||||||
|
|
||||||
try {
|
try {
|
||||||
this.underwaterSceneFog.density = 0;
|
this.underwaterSceneFog.density = 0;
|
||||||
|
for (const state of previousReflectionStates) {
|
||||||
|
if (state.binding.reflectionEnabledUniform !== null) {
|
||||||
|
state.binding.reflectionEnabledUniform.value = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
binding.reflectionTextureUniform.value = null;
|
||||||
this.renderer.autoClear = true;
|
this.renderer.autoClear = true;
|
||||||
this.renderer.setRenderTarget(binding.reflectionRenderTarget);
|
this.renderer.setRenderTarget(binding.reflectionRenderTarget);
|
||||||
this.renderer.clear();
|
this.renderer.clear();
|
||||||
@@ -896,6 +907,14 @@ export class RuntimeHost {
|
|||||||
this.renderer.autoClear = previousAutoClear;
|
this.renderer.autoClear = previousAutoClear;
|
||||||
this.modelGroup.visible = previousModelGroupVisibility;
|
this.modelGroup.visible = previousModelGroupVisibility;
|
||||||
this.underwaterSceneFog.density = previousFogDensity;
|
this.underwaterSceneFog.density = previousFogDensity;
|
||||||
|
for (const state of previousReflectionStates) {
|
||||||
|
if (state.binding.reflectionEnabledUniform !== null) {
|
||||||
|
state.binding.reflectionEnabledUniform.value = state.enabled;
|
||||||
|
}
|
||||||
|
if (state.binding.reflectionTextureUniform !== null) {
|
||||||
|
state.binding.reflectionTextureUniform.value = state.texture;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (const hiddenWaterMesh of hiddenWaterMeshes) {
|
for (const hiddenWaterMesh of hiddenWaterMeshes) {
|
||||||
hiddenWaterMesh.mesh.visible = hiddenWaterMesh.visible;
|
hiddenWaterMesh.mesh.visible = hiddenWaterMesh.visible;
|
||||||
|
|||||||
@@ -3137,7 +3137,18 @@ export class ViewportHost {
|
|||||||
|
|
||||||
const previousAutoClear = this.renderer.autoClear;
|
const previousAutoClear = this.renderer.autoClear;
|
||||||
const previousRenderTarget = this.renderer.getRenderTarget();
|
const previousRenderTarget = this.renderer.getRenderTarget();
|
||||||
|
const previousReflectionStates = this.viewportWaterSurfaceBindings.map((waterBinding) => ({
|
||||||
|
binding: waterBinding,
|
||||||
|
enabled: waterBinding.reflectionEnabledUniform?.value ?? 0,
|
||||||
|
texture: waterBinding.reflectionTextureUniform?.value ?? null
|
||||||
|
}));
|
||||||
try {
|
try {
|
||||||
|
for (const state of previousReflectionStates) {
|
||||||
|
if (state.binding.reflectionEnabledUniform !== null) {
|
||||||
|
state.binding.reflectionEnabledUniform.value = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
binding.reflectionTextureUniform.value = null;
|
||||||
this.renderer.autoClear = true;
|
this.renderer.autoClear = true;
|
||||||
this.renderer.setRenderTarget(binding.reflectionRenderTarget);
|
this.renderer.setRenderTarget(binding.reflectionRenderTarget);
|
||||||
this.renderer.clear();
|
this.renderer.clear();
|
||||||
@@ -3145,6 +3156,14 @@ export class ViewportHost {
|
|||||||
} finally {
|
} finally {
|
||||||
this.renderer.setRenderTarget(previousRenderTarget);
|
this.renderer.setRenderTarget(previousRenderTarget);
|
||||||
this.renderer.autoClear = previousAutoClear;
|
this.renderer.autoClear = previousAutoClear;
|
||||||
|
for (const state of previousReflectionStates) {
|
||||||
|
if (state.binding.reflectionEnabledUniform !== null) {
|
||||||
|
state.binding.reflectionEnabledUniform.value = state.enabled;
|
||||||
|
}
|
||||||
|
if (state.binding.reflectionTextureUniform !== null) {
|
||||||
|
state.binding.reflectionTextureUniform.value = state.texture;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
for (const hiddenObject of hiddenObjects) {
|
for (const hiddenObject of hiddenObjects) {
|
||||||
hiddenObject.object.visible = hiddenObject.visible;
|
hiddenObject.object.visible = hiddenObject.visible;
|
||||||
|
|||||||
Reference in New Issue
Block a user