Zum Inhalt springen

3D Grafik im Browser (Geschwindigkeitstest)

3.3/5 - (3 votes)

Das ist ein Testprogramm für Grafikgeschwindigkeit. Für eine in Entwcklung befindliche WATOR-Simulation.
Hier kann man mal ausprobieren, wieviele “Wesen” hier so gleichzeitig rumwuseln dürfen, ohne das der Rechner stehenbleibt. 🙂
Die Wesen kennen den Rand der Welt (noch) nicht – sie bewegen sich zufallsgeneriert einfach auf und davon.
Jedenfalls bin ich zufrieden mit der Geschwindigkeit, auch bei einigen 1000 “Wesen”.


* * * Player * * *









Wer sich für das "WIE" interessiert:

Den Code kann man hier ausklappen.

<div class="wrapper_div">
    <div class="output_div" id="output">
    </div>
    <div class="input_div">
        <br><label for="world-dimension"> Welt Dimension: </label>
        <input type="number" id="world-dimension" value="50"> <br>
        <br>

        <label for="fish-amount"> Fische Anzahl: </label>
        <input type="number" id="fish-amount" value="1000"> <br>
        <label for="shark-amount"> Hai Anzahl: </label>
        <input type="number" id="shark-amount" value="1000"> <br>

        <br>


        <button onclick="initScene();"> reSTART </button><br>
        <br>
        <button onclick="simulationRunning=true;"> Play </button>
        <button onclick="simulationRunning=false;"> Pause </button>
        <button onclick="simulationRunning=false; Zeitschritt();"> Schritt </button>

    </div>
</div>

<script src="https://cdn.jsdelivr.net/npm/three@0.128.0/build/three.js">
</script>
<script src="https://cdn.jsdelivr.net/npm/three@0.128.0/examples/js/controls/OrbitControls.js">
</script>

<script>
    let scene, camera, renderer, controls;
    let fishMesh, sharkMesh;
    let worldDimension;
    let fishAmount;
    let fishBirth;
    let sharkAmount;
    let sharkBirth;
    let sharkEnergy;
    let worldBoundary;
    let neighborSides;
    let neighborEdges;
    let neighborCorners;
    let simulationRunning;


    function isMobileDevice() {
            return (typeof window.orientation !== "undefined") || (navigator.userAgent.indexOf('IEMobile') !== -1);
        }


    function initScene() {
        worldDimension = parseInt(document.getElementById('world-dimension').value);
        fishAmount = parseInt(document.getElementById('fish-amount').value);
        sharkAmount = parseInt(document.getElementById('shark-amount').value);

        scene = new THREE.Scene();
        camera = new THREE.PerspectiveCamera(75, 1, 0.1, 10000);
        renderer = new THREE.WebGLRenderer({ antialias: true });



        if (isMobileDevice()) {
            // Code für Mobilgeräte hier ausführen
            renderer.setSize(300, 300);
        } else {
            // Code für Desktop-Geräte hier ausführen
            renderer.setSize(600, 600);
        }

        const output = document.getElementById('output');
        output.innerHTML = '';
        output.appendChild(renderer.domElement);

        controls = new THREE.OrbitControls(camera, renderer.domElement);

        const ambientLight = new THREE.AmbientLight(0xffffff, 0.5);
        scene.add(ambientLight);

        const directionalLight = new THREE.DirectionalLight(0xffffff, 0.5);
        directionalLight.position.set(0, 0, 100000);
        scene.add(directionalLight);

        const fishGeometry = new THREE.BoxGeometry(1, 1, 1);
        const fishMaterial = new THREE.MeshPhongMaterial({ color: 0x00ff00 });
        fishMesh = new THREE.InstancedMesh(fishGeometry, fishMaterial, fishAmount);
        scene.add(fishMesh);

        const sharkGeometry = new THREE.BoxGeometry(1, 1, 1);
        const sharkMaterial = new THREE.MeshPhongMaterial({ color: 0xff0000 });
        sharkMesh = new THREE.InstancedMesh(sharkGeometry, sharkMaterial, sharkAmount);
        scene.add(sharkMesh);

        for (let i = 0; i < fishAmount; i++) {
            const position = new THREE.Vector3(
                Math.floor(Math.random() * worldDimension) - Math.floor(worldDimension / 2),
                Math.floor(Math.random() * worldDimension) - Math.floor(worldDimension / 2),
                Math.floor(Math.random() * worldDimension) - Math.floor(worldDimension / 2)
            );
            fishMesh.setMatrixAt(i, new THREE.Matrix4().makeTranslation(position.x, position.y, position.z));
        }
        fishMesh.instanceMatrix.needsUpdate = true;

        for (let i = 0; i < sharkAmount; i++) {
            const position = new THREE.Vector3(
                Math.floor(Math.random() * worldDimension) - Math.floor(worldDimension / 2),
                Math.floor(Math.random() * worldDimension) - Math.floor(worldDimension / 2),
                Math.floor(Math.random() * worldDimension) - Math.floor(worldDimension / 2)
            );
            sharkMesh.setMatrixAt(i, new THREE.Matrix4().makeTranslation(position.x, position.y, position.z));
        }
        sharkMesh.instanceMatrix.needsUpdate = true;

        camera.position.x = worldDimension;
        camera.position.y = worldDimension;
        camera.position.z = worldDimension;
    }

    function rnd_int(von, bis) {
        const x = Math.floor(Math.random() * (bis - von + 1)) + von;
        return x;
    }

    function rnd_vector_int(von, bis) {
        const x = rnd_int(von, bis);
        const y = rnd_int(von, bis);
        const z = rnd_int(von, bis);
        return new THREE.Vector3(x, y, z);
    }

    function Zeitschritt() {
        for (let i = 0; i < fishAmount; i++) {
            const fishMatrix = new THREE.Matrix4().fromArray(fishMesh.instanceMatrix.array, i * 16);
            const fishPosition = new THREE.Vector3();
            fishPosition.setFromMatrixPosition(fishMatrix);

            // Manipulate fish position here using "fishPosition"

            fishPosition.x = fishPosition.x + rnd_int(-1, 1);
            fishPosition.y = fishPosition.y + rnd_int(-1, 1);
            fishPosition.z = fishPosition.z + rnd_int(-1, 1);


            fishMesh.setMatrixAt(i, fishMatrix.makeTranslation(fishPosition.x, fishPosition.y, fishPosition.z));
        }
        fishMesh.instanceMatrix.needsUpdate = true;
    }

    function animate() {
        if (simulationRunning) { Zeitschritt() }
        controls.update();
        renderer.render(scene, camera);
    }
    simulationRunning = true;
    initScene();

    setInterval(animate, 30);

</script>

Für Interessierte: Der aktuelle Stand: www.irrbert.de/wator

Schreibe einen Kommentar