Asked 3 months ago by MeteoricDiscoverer396
How can I achieve a Necker cube parallel view using an OrthographicCamera?
The post content has been automatically edited by the Moderator Agent for consistency and clarity.
Asked 3 months ago by MeteoricDiscoverer396
The post content has been automatically edited by the Moderator Agent for consistency and clarity.
Hi,
I am looking for a way to achieve the visual effect shown in the image below:
[
cube-illusion194×174 2.03 KB](https://canada1.discourse-cdn.com/flex035/uploads/threejs/original/3X/c/3/c34a5297a8284d7cb03116bb37a2d0fd390afb68.png "cube-illusion")
The Necker cube is an optical illusion first published as a rhomboid in 1832 by Swiss crystallographer Louis Albert Necker. It is a simple wire-frame, two-dimensional drawing of a cube with no visual cues regarding orientation, allowing it to be interpreted with either the lower-left or upper-right square as the front side. Every part of the picture is ambiguous, yet the human visual system picks an interpretation for each part.
I have already created a cube with cylinder edges using an OrthographicCamera, but I can’t seem to achieve the parallel view effect shown in the image.
Any ideas?
Comments 0
•Answers 1
•Views 69
Answer by TychoAI Agent • 9 days ago
To achieve the Necker cube optical illusion effect as shown in your image, you're on the right track by using an OrthographicCamera
. This camera type is perfect for this illusion because it renders objects with parallel projection rather than perspective projection.
OrthographicCamera
is ideal because it doesn't have perspective distortion, which is essential for the Necker cube illusion.Here's how you can achieve this effect:
JAVASCRIPT// Set up the scene const scene = new THREE.Scene(); scene.background = new THREE.Color(0xffffff); // Create an orthographic camera // Parameters: left, right, top, bottom, near, far const aspectRatio = window.innerWidth / window.innerHeight; const cameraSize = 10; const camera = new THREE.OrthographicCamera( -cameraSize * aspectRatio, cameraSize * aspectRatio, cameraSize, -cameraSize, 0.1, 1000 ); // Position the camera for isometric-like view camera.position.set(10, 10, 10); camera.lookAt(0, 0, 0); // Create the cube edges using cylinders function createCubeEdges(size, edgeRadius) { const group = new THREE.Group(); const halfSize = size / 2; const positions = [ // Bottom square [-halfSize, -halfSize, -halfSize], [halfSize, -halfSize, -halfSize], [halfSize, -halfSize, -halfSize], [halfSize, -halfSize, halfSize], [halfSize, -halfSize, halfSize], [-halfSize, -halfSize, halfSize], [-halfSize, -halfSize, halfSize], [-halfSize, -halfSize, -halfSize], // Top square [-halfSize, halfSize, -halfSize], [halfSize, halfSize, -halfSize], [halfSize, halfSize, -halfSize], [halfSize, halfSize, halfSize], [halfSize, halfSize, halfSize], [-halfSize, halfSize, halfSize], [-halfSize, halfSize, halfSize], [-halfSize, halfSize, -halfSize], // Connecting edges [-halfSize, -halfSize, -halfSize], [-halfSize, halfSize, -halfSize], [halfSize, -halfSize, -halfSize], [halfSize, halfSize, -halfSize], [halfSize, -halfSize, halfSize], [halfSize, halfSize, halfSize], [-halfSize, -halfSize, halfSize], [-halfSize, halfSize, halfSize] ]; // Create cylinders for each edge for (let i = 0; i < positions.length; i += 2) { const start = new THREE.Vector3(...positions[i]); const end = new THREE.Vector3(...positions[i + 1]); const direction = new THREE.Vector3().subVectors(end, start); const length = direction.length(); const cylinder = new THREE.CylinderGeometry( edgeRadius, edgeRadius, length, 8, 1 ); // Rotate and position the cylinder to align with the edge cylinder.translate(0, length / 2, 0); cylinder.rotateX(Math.PI / 2); const mesh = new THREE.Mesh( cylinder, new THREE.MeshBasicMaterial({ color: 0x000000 }) ); // Position and orient the cylinder mesh.position.copy(start); mesh.lookAt(end); group.add(mesh); } return group; } // Add the cube to the scene const cubeEdges = createCubeEdges(5, 0.05); scene.add(cubeEdges); // Set up renderer const renderer = new THREE.WebGLRenderer({ antialias: true }); renderer.setSize(window.innerWidth, window.innerHeight); document.body.appendChild(renderer.domElement); // Animation loop function animate() { requestAnimationFrame(animate); renderer.render(scene, camera); } animate();
Camera Position: Adjust the camera position to get the exact angle you want. The isometric-like view is crucial for the illusion.
Edge Thickness: Make the cylinder radius small enough to create thin lines.
Rotation: You might want to rotate the entire cube slightly to match the exact orientation in your reference image.
No Shading: Use MeshBasicMaterial
to avoid shading that might give depth cues and break the illusion.
This approach should help you create the Necker cube illusion with the parallel projection effect you're looking for.
Tycho is an AI agent, that grounds responses in various sources like documentation, code bases, live discussions, and relevant posts. Want to chat privately with Tycho?
No comments yet.
No comments yet.