Logo Pastebin.fr
Pastebin

Retrouvez, créez et partagez vos snippets en temps réel.

raytracing bugged

<!DOCTYPE html>
<html lang="fr">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Ray Tracing Sphere</title>
    <style>
        body {
            margin: 0;
            overflow: hidden;
            background-color: #000; /* Fond noir pour un meilleur rendu */
        }
        canvas {
            display: block;
        }
        #fpsCounter {
            position: absolute;
            top: 10px;
            left: 10px;
            color: white;
            font-size: 16px;
        }
        #zoomCounter {
            position: absolute;
            top: 30px;
            left: 10px;
            color: white;
            font-size: 16px;
        }
    </style>
</head>
<body onmousemove="moveLightSource(event)" onwheel="handleZoom(event)">
    <canvas id="myCanvas"></canvas>
    <div id="fpsCounter"></div>
    <div id="zoomCounter"></div>

    <script>
        const canvas = document.getElementById('myCanvas');
        const ctx = canvas.getContext('2d');
        const fpsCounter = document.getElementById('fpsCounter');
        const zoomCounter = document.getElementById('zoomCounter');

        // Configuration
        const width = canvas.width = window.innerWidth*0.5;
        const height = canvas.height = window.innerHeight*0.5;
        const sphereRadius = 1; // Sphere radius

        // Camera settings
        let cameraZ = 3; // Distance de la caméra
        const minZoom = 1.5; // Distance minimale
        const maxZoom = 10; // Distance maximale

        // Light Source
        let lightSource = [0, 0, 3]; // Initial light source position

        // Function to create sphere intersection
        function createSphere(radius, center) {
            return {
                radius: radius,
                center: center
            }
        }
        
        let sphere = createSphere(sphereRadius, [0,0,0]);

        // Render Variables
        let lastTime = 0;
        let fps = 0;

        // Function to calculate the distance from the ray origin to the sphere center
        function distance(rayOrigin, sphereCenter) {
          return Math.sqrt(Math.pow(rayOrigin[0] - sphereCenter[0], 2) + 
                Math.pow(rayOrigin[1] - sphereCenter[1], 2) + 
                Math.pow(rayOrigin[2] - sphereCenter[2], 2));
        }


        // Function to move the light source based on mouse position
        function moveLightSource(event) {
            const mouseX = event.clientX;
            const mouseY = event.clientY;

            // Convert mouse coordinates to 3D coordinates. Adjust factors as needed.
            lightSource[0] = (mouseX / width) * 2 - 1;
            lightSource[1] = 1 - (mouseY / height) * 2;
            lightSource[2] = 3; // Fixed depth for the light source

            render(); // Redraw the scene with the new light position
        }
      
        // Function to calculate the color of a point on the sphere
        function calculateColor(point) {
            const normal = normalize([
                point[0] - sphere.center[0],
                point[1] - sphere.center[1],
                point[2] - sphere.center[2]
            ]);

            const lightDirection = normalize([
                lightSource[0] - point[0],
                lightSource[1] - point[1],
                lightSource[2] - point[2]
            ]);

            let intensity = Math.max(dot(normal, lightDirection), 0); // removed .1
        return [intensity, intensity, intensity]; // Basic grayscale color
    }


        // Function to calculate the dot product
        function dot(v1, v2) {
            return v1[0] * v2[0] + v1[1] * v2[1] + v1[2] * v2[2];
        }

        // Function to normalize a vector
        function normalize(vector) {
            let length = Math.sqrt(dot(vector, vector));
            if (length === 0) {
                return [0, 0, 0];
            }
            return [vector[0] / length, vector[1] / length, vector[2] / length];
        }

        // Function to handle zoom with mouse wheel
        function handleZoom(event) {
            event.preventDefault();
            
            // Adjust camera distance based on wheel direction
            const zoomSpeed = 0.1;
            if (event.deltaY < 0) {
                // Zoom in
                cameraZ = Math.max(minZoom, cameraZ - zoomSpeed);
            } else {
                // Zoom out
                cameraZ = Math.min(maxZoom, cameraZ + zoomSpeed);
            }
            
            zoomCounter.textContent = `Zoom: ${cameraZ.toFixed(2)}`;
            render(performance.now());
        }

        // Render function
        function render(timestamp) {
            ctx.clearRect(0, 0, width, height);

            let now = timestamp;
            let deltaTime = now - lastTime;
            lastTime = now;

            fps = Math.round(1000 / deltaTime);
            fpsCounter.textContent = `FPS: ${fps}`;
            zoomCounter.textContent = `Zoom: ${cameraZ.toFixed(2)}`;

            // Raytracing loop
            for (let y = 0; y < height; y++) {
                for (let x = 0; x < width; x++) {
                    // Ray origin and direction
                    let rayOrigin = [0, 0, -cameraZ]; // Camera position with zoom
                    let rayDirection = [
                        (x / width) * 2 - 1,  // Normalize x to -1 to 1
                        1 - (y / height) * 2,  // Normalize y to -1 to 1
                        1  // Point into the screen
                    ];
                    rayDirection = normalize(rayDirection);

                    // Calculate intersection with sphere
                    let oc = [
                        rayOrigin[0] - sphere.center[0],
                        rayOrigin[1] - sphere.center[1],
                        rayOrigin[2] - sphere.center[2]
                    ];
                    let a = dot(rayDirection, rayDirection);
                    let b = 2 * dot(oc, rayDirection);
                    let c = dot(oc, oc) - sphere.radius * sphere.radius;
                    let discriminant = b * b - 4 * a * c;

                    if (discriminant >= 0) {
        let t1 = (-b - Math.sqrt(discriminant)) / (2 * a);
        let t2 = (-b + Math.sqrt(discriminant)) / (2 * a);

        //let t = Math.max(t1, t2);  // Use the closer intersection
        let t = t1; //choose the first value
        let intersectionPoint = [
            rayOrigin[0] + t * rayDirection[0],
            rayOrigin[1] + t * rayDirection[1],
            rayOrigin[2] + t * rayDirection[2]
        ];

        let color = calculateColor(intersectionPoint);
        ctx.fillStyle = `rgb(${color[0] * 255}, ${color[1] * 255}, ${color[2] * 255})`;
        ctx.fillRect(x, y, 1, 1);
                    } else {
                        // No intersection - draw background color
                        ctx.fillStyle = 'rgb(0, 0, 0)'; // Black background
                        ctx.fillRect(x, y, 1, 1);
                    }
                }
            }
        }

        // Initial render
        let timestamp;
        function init() {
            timestamp = performance.now();
            render(timestamp);
        }
        init();
    </script>
</body>
</html>

Créé il y a 3 semaines.

Rechercher un Pastebin

Aucun paste trouvé.