I have this weird bug on my website when I try to draw on a canvas. I’m using cameras to “take a picture” of walls and draw them on canvases. I have 4 of these, but for some reason only this canvas is acting weird and I have no idea why. I’ve also included a screenshot of how it would look normally. I recently started learning three.js, pls help guys…
Here is the code of how I draw them:
const wallDirections = [
{ position: { x: 0, y: 495, z: 500 }, lookAt: { x: 0, y: 495, z: -1 } },
{ position: { x: -500, y: 495, z: 0 }, lookAt: { x: 1, y: 495, z: 0 } },
{ position: { x: 0, y: 495, z: -500 }, lookAt: { x: 0, y: 495, z: 1 } },
{ position: { x: 500, y: 495, z: 0 }, lookAt: { x: -1, y: 495, z: 0 } }
];
wallDirections.forEach(direction => {
const distanceFromWall = roomSize;
const verticalFOV = 2 * Math.atan((roomSize / 2) / distanceFromWall) * (180 / Math.PI);
const wallCamera = new THREE.PerspectiveCamera(verticalFOV, 1, 0.1, 1800);
wallCamera.position.set(direction.position.x, direction.position.y, direction.position.z);
wallCamera.lookAt(direction.lookAt.x, direction.lookAt.y, direction.lookAt.z);
const renderTarget = new THREE.WebGLRenderTarget(1000, 1000);
wallCameras.push(wallCamera);
wallTextures.push(renderTarget.texture);
wallRenderTargets.push(renderTarget);
});
function renderWallPreviews() {
wallCameras.forEach((camera, index) => {
renderer.setRenderTarget(wallRenderTargets[index]);
renderer.render(scene, camera);
renderer.setRenderTarget(null);
});
}
function updateWallPreviews() {
const previewCanvases = getPreviewCanvases();
const letters = ['A','B','C','D'];
previewCanvases.forEach((canvas, index) => {
if (canvas) {
const context = canvas.getContext("2d");
const canvasWidth = canvas.width;
const canvasHeight = canvas.height;
const width = wallRenderTargets[index].width;
const height = wallRenderTargets[index].height;
const pixels = new Uint8Array(width * height * 4); // RGBA format
// Read the pixels from the render target
renderer.readRenderTargetPixels(wallRenderTargets[index], 0, 0, width, height, pixels);
// Manually flip the image data
const flippedPixels = new Uint8Array(width * height * 4);
for (let y = 0; y < height; y++) {
for (let x = 0; x < width; x++) {
const srcIndex = (y * width + x) * 4;
const destIndex = ((height - y - 1) * width + x) * 4;
flippedPixels[destIndex] = pixels[srcIndex];
flippedPixels[destIndex + 1] = pixels[srcIndex + 1];
flippedPixels[destIndex + 2] = pixels[srcIndex + 2];
flippedPixels[destIndex + 3] = pixels[srcIndex + 3];
}
}
// Create ImageData from the flipped pixel buffer
const imageData = new ImageData(new Uint8ClampedArray(flippedPixels), width, height);
// Create an off-screen canvas to resize the image data
const offScreenCanvas = document.createElement('canvas');
offScreenCanvas.width = width;
offScreenCanvas.height = height;
const offScreenContext = offScreenCanvas.getContext('2d');
// Draw ImageData onto the off-screen canvas
offScreenContext.putImageData(imageData, 0, 0);
// Calculate aspect ratios for resizing
const imgAspectRatio = width / height;
const canvasAspectRatio = canvasWidth / canvasHeight;
let renderWidth, renderHeight;
if (imgAspectRatio > canvasAspectRatio) {
renderWidth = canvasWidth;
renderHeight = canvasWidth / imgAspectRatio;
} else {
renderHeight = canvasHeight;
renderWidth = canvasHeight * imgAspectRatio;
}
// Clear the canvas before drawing
context.clearRect(0, 0, canvasWidth, canvasHeight);
// Center the resized image on the canvas
const offsetX = (canvasWidth - renderWidth) / 2;
const offsetY = (canvasHeight - renderHeight) / 2;
// Draw the resized image from the off-screen canvas onto the main canvas
context.drawImage(offScreenCanvas, 0, 0, width, height, offsetX, offsetY, renderWidth, renderHeight);
context.font = "bold 30px Arial";
context.fillStyle = "white";
context.fillText(letters[index], 10, 40);
}
});
}