MandelbrotThreeJS is a simple ThreeJS application that visualizes a Mandelbrot set in 3D space using custom shaders. This project demonstrates the use of ThreeJS, GLSL shaders, and interactive web technologies to create a visually appealing and dynamic 3D fractal experience.
Uploading colors-c.mov
To run this application locally, follow these steps:
Clone the repository:
git clone https://github.com/yourusername/MandelbrotThree.git
cd MandelbrotThree
Install dependencies:
Ensure you have Node.js installed, then run:
npm install
Run the application:
npm start
Open your browser and navigate to http://localhost:8080
to see the application in action.
The vertex shader calculates the position of each point in the 3D space:
varying vec3 vPosition;
void main() {
vPosition = position;
gl_PointSize = 2.0;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
The fragment shader colors the points based on their distance from the center, using a dynamic hue that changes over time:
precision mediump float;
varying vec3 vPosition;
uniform float uTime;
vec3 hsv2rgb(vec3 c) {
vec4 K = vec4(1.0, 2.0/3.0, 1.0/3.0, 3.0);
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);
}
void main() {
vec2 coord = gl_PointCoord * 2.0 - 1.0;
float distance = length(coord);
if (distance > 1.0) {
discard;
}
float distanceFromCenter = length(vPosition - vec3(0.0));
float scale = 0.5 + 0.5 * sin(uTime * 0.5);
float hue = mod(distanceFromCenter * 0.1 * scale + sin(uTime) * 0.5, 1.0);
vec3 color = hsv2rgb(vec3(hue, 1.0, 1.0));
gl_FragColor = vec4(color, 1.0);
}
The main application initializes the ThreeJS scene, camera, renderer, and controls. It also creates the MandelbrotCube
object and handles the animation loop.
import './style.css';
import * as THREE from 'three';
import { XRButton, OrbitControls } from 'three/examples/jsm/Addons.js';
import Stats from 'three/examples/jsm/libs/stats.module.js';
import { MandelbrotCube } from './Mandelbrot';
const stats = new Stats();
stats.showPanel(0);
document.body.appendChild(stats.dom);
const scene = new THREE.Scene();
scene.background = new THREE.Color(0x808080);
const camera = new THREE.PerspectiveCamera(50, window.innerWidth / window.innerHeight, 0.0001, 100);
camera.position.set(0, 1, 2);
scene.add(new THREE.HemisphereLight(0xbcbcbc, 0xa5a5a5, 3));
scene.add(new THREE.AxesHelper(1));
const renderer = new THREE.WebGLRenderer({ antialias: true });
renderer.setPixelRatio(window.devicePixelRatio);
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setAnimationLoop(animate);
renderer.xr.enabled = true;
renderer.xr.setFoveation(0.0);
document.body.appendChild(renderer.domElement);
document.body.appendChild(XRButton.createButton(renderer));
const controls = new OrbitControls(camera, renderer.domElement);
controls.target = new THREE.Vector3(0, 1.5, -1);
window.addEventListener('resize', () => {
camera.aspect = window.innerWidth / window.innerHeight;
camera.updateProjectionMatrix();
renderer.setSize(window.innerWidth, window.innerHeight);
});
const mandelbrot = new MandelbrotCube();
mandelbrot.scale.multiplyScalar(1 / 400);
mandelbrot.position.set(0, 1.25, -0.2);
scene.add(mandelbrot);
const clock = new THREE.Clock();
function animate() {
stats.begin();
const elapsedTime = clock.getElapsedTime();
mandelbrot.update(elapsedTime);
controls.update();
renderer.render(scene, camera);
stats.end();
}
animate();
Feel free to submit issues and pull requests. For major changes, please open an issue first to discuss what you would like to change.
git checkout -b feature/AmazingFeature
)git commit -m 'Add some AmazingFeature'
)git push origin feature/AmazingFeature
)Distributed under the MIT License. See LICENSE
for more information.
This README provides a comprehensive overview of the MandelbrotThreeJS project, detailing how to set it up, its features, and how to contribute to it. Adjust the demo link and GitHub repository URL placeholders with actual links once available.