### Initialize Scene and Render Loop Source: https://github.com/gpujs/gpu.js/blob/develop/examples/parallel-raytracer.html Sets up the scene, generates kernels, and starts the rendering loop when the window loads. ```javascript var scene = Scene.generateScene(); var _a = generateKernels(kernelDimension, scene), gpuKernels = _a[0], cpuKernels = _a[1]; var renderLoop = renderer(gpuKernels, cpuKernels, scene); window.onload = renderLoop; ``` -------------------------------- ### Main Execution Flow Source: https://github.com/gpujs/gpu.js/blob/develop/examples/mandelbulb.html Initializes raytracer parameters, sets up the GUI, and starts the animation frame loop for rendering. ```javascript let raytracerParams = new RaytracerParams(); let tmpMouseWhellY = -3000; let locked = false; let start; refreshScreenSize(); //let raytracer = initFractalGPU(raytracerParams); initGui(raytracerParams); window.requestAnimationFrame(refreshWindow); ``` -------------------------------- ### Camera and Viewport Setup Source: https://github.com/gpujs/gpu.js/blob/develop/examples/raytracer.html Calculates camera vectors, viewport dimensions, and pixel sizes based on camera parameters and canvas dimensions. This setup is crucial for ray casting. ```javascript const cameraPoint = new Vector(camera[0], camera[1], camera[2]); const cameraVector = new Vector(camera[3], camera[4], camera[5]); const eyeVector = Vector.norm(Vector.minus(cameraVector, cameraPoint)); const vpRight = Vector.norm(Vector.cross(eyeVector, new Vector(0, 1, 0))); const vpUp = Vector.norm(Vector.cross(vpRight, eyeVector)); const fovRadians = Math.PI * (camera[6] / 2) / 180; const heightWidthRatio = canvasHeight / canvasWidth; const halfWidth = Math.tan(fovRadians); const halfHeight = heightWidthRatio * halfWidth; const cameraWidth = halfWidth * 2; const cameraHeight = halfHeight * 2; const pixelWidth = cameraWidth / (canvasWidth - 1); const pixelHeight = cameraHeight / (canvasHeight - 1); ``` -------------------------------- ### GPU.js Initialization and Rendering Setup Source: https://github.com/gpujs/gpu.js/blob/develop/examples/raster-globe/index.html Initializes the GPU, loads the image, and sets up the kernel for rendering. It configures constants, output size, and rendering tactics. ```javascript const gpu = new GPU(); const logFps = document.querySelector('#log-fps'); const image = new Image(); image.src = './earth-map.jpg'; image.onload = () => { const w = 975; const h = 975; const render = gpu .createKernel(kernel, { functions: [applyRotation, frac] }) .setConstants({ w, h, srcw: image.width, srch: image.height }) .setOutput([w, h]) .setTactic('precision') .setGraphical(true); const canvas = render.canvas; document.body.appendChild(canvas); let lastCalledTime; let fps; function callRender() { let r0 = (-Date.now() / 30) % 360, r1 = 35 * Math.sin((-Date.now() / 1030) % 360), r2 = 0, scale = 0.49; render(image, r0, r1, r2, scale); const delta = (Date.now() - lastCalledTime) / 1000; lastCalledTime = Date.now(); fps = 1 / delta; logFps.innerHTML = fps.toFixed(0) + ' FPS'; window.requestAnimationFrame(() => { callRender(); }); } callRender(); }; ``` -------------------------------- ### Install gpu.js with npm Source: https://github.com/gpujs/gpu.js/blob/develop/README.md Use this command to add gpu.js to your project's dependencies via npm. ```bash npm install gpu.js --save ``` -------------------------------- ### Kernel Creation and Canvas Setup Source: https://github.com/gpujs/gpu.js/blob/develop/examples/raytracer.html Creates both GPU and CPU kernels using `createKernel` and appends the respective canvases to the DOM. This prepares the rendering environment. ```javascript const gpuKernel = createKernel(0); const cpuKernel = createKernel(1); const gpuCanvas = gpuKernel.canvas; const cpuCanvas = cpuKernel.canvas; document.getElementById(stringOfMode(initialMode)).checked = true; const canvasContainer = document.getElementById('canvas-holder'); canvasContainer.appendChild(gpuCanvas); canvasContainer.appendChild(cpuCanvas); ``` -------------------------------- ### Install gpu.js with yarn Source: https://github.com/gpujs/gpu.js/blob/develop/README.md Use this command to add gpu.js to your project's dependencies via yarn. ```bash yarn add gpu.js ``` -------------------------------- ### Raytracer Renderer Setup Source: https://github.com/gpujs/gpu.js/blob/develop/examples/parallel-raytracer.html Sets up the main rendering loop for the raytracer. It includes camera controls via keyboard input and handles rendering for both CPU and GPU modes. ```javascript var renderer = function(gpuKernels, cpuKernel, scene) { var camera = scene.camera, lights = scene.lights, entities = scene.entities, eyeVector = scene.eyeVector, vpRight = scene.vpRight, vpUp = scene.vpUp, canvasHeight = scene.canvasHeight, canvasWidth = scene.canvasWidth, fovRadians = scene.fovRadians, heightWidthRatio = scene.heightWidthRatio, halfWidth = scene.halfWidth, halfHeight = scene.halfHeight, cameraWidth = scene.cameraWidth, cameraHeight = scene.cameraHeight, pixelWidth = scene.pixelWidth, pixelHeight = scene.pixelHeight; var Movement; (function(Movement) { Movement[Movement["Forward"] = 0] = "Forward"; Movement[Movement["Backward"] = 1] = "Backward"; Movement[Movement["LeftStrafe"] = 2] = "LeftStrafe"; Movement[Movement["RightStrafe"] = 3] = "RightStrafe"; })(Movement || (Movement = {})); document.onkeydown = function(e) { var keyMap = { 87: Movement.Forward, 83: Movement.Backward, 65: Movement.LeftStrafe, 68: Movement.RightStrafe, }; var forwardSpeed = 0.2; var backwardSpeed = 0.2; var strafeSpeed = 0.2; switch (keyMap[e.keyCode]) { case Movement.Forward: camera[2] -= forwardSpeed; break; case Movement.Backward: camera[2] += backwardSpeed; break; case Movement.LeftStrafe: camera[0] -= strafeSpeed; break; case Movement.RightStrafe: camera[0] += strafeSpeed; break; default: break; } }; var fps = { startTime: 0, frameNumber: 0, totalFrameCount: 0, getFPS: function() { this.totalFrameCount++; this.frameNumber++; var d = new Date().getTime(); var currentTime = (d - this.startTime) / 1000; var result = Math.floor(this.frameNumber / currentTime); if (currentTime > 1) { this.startTime = new Date().getTime(); this.frameNumber = 0; } return result; } }; var nextTick = function() { if (!isRunning) { return; } if (!bm.isBenchmarking) { updateFPS(fps.getFPS().toString()); } if (bm.isBenchmarking) { startTime = performance.now(); } var startTime, endTime; if (mode == Mode.CPU) { for (var i = 0; i < cpuKernels.length; i++) { var cpuKernel_1 = cpuKernels[i]; cpuKernel_1(camera, lights, entities, eyeVector, vpRight, vpUp, canvasHeight, canvasWidth, fovRadians, heightWidthRatio, halfWidth, halfHeight, cameraWidth, cameraHeight, pixelWidth, pixelHeight, i % kernelDimension, Math.floor(i / kernelDimension)); if (canvasNeedsUpdate) { var cv = document.getElementById("canvas" + i).childNodes[0]; var bdy = cv.parentNode; var newCanvas = cpuKernel_1.canvas; bdy.replaceChild(newCanvas, cv); } } if (canvasNeedsUpdate) { canvasNeedsUpdate = false; } } else { for (var i = 0; i < gpuKernels.length; i++) { var gpuKernel = gpuKernels[i]; gpuKernel(camera, lights, entities, eyeVector, vpRight, vpUp, canvasHeight, canvasWidth, fovRadians, heightWidthRatio, halfWidth, halfHeight, cameraWidth, cameraHeight, pixelWidth, pixelHeight, i % kernelDimension, Math.floor(i / kernelDimension)); if (canvasNeedsUpdate) { var cv = document.getElementById("canvas" + i).childNodes[0]; var bdy = cv.parentNode; var newCanvas = gpuKernel.canvas; bdy.replaceChild(newCanvas, cv); } } if (canvasNeedsUpdate) { canvasNeedsUpdate = ``` -------------------------------- ### Strongly Typed Kernel with GPU.js Source: https://github.com/gpujs/gpu.js/blob/develop/README.md Demonstrates how to create a strongly typed kernel function using TypeScript and GPU.js. This example shows basic kernel creation and output. ```typescript import { GPU, IKernelFunctionThis } from 'gpu.js'; const gpu = new GPU(); function kernelFunction(this: IKernelFunctionThis): number { return 1 + this.thread.x; } const kernelMap = gpu.createKernel(kernelFunction) .setOutput([3,3,3]); const result = kernelMap(); console.log(result as number[][][]); ``` -------------------------------- ### Initialize Mandelbulb GPU Kernel Source: https://github.com/gpujs/gpu.js/blob/develop/examples/mandelbulb.html Sets up the canvas, initializes the GPU.js instance, and creates the rendering kernel for the Mandelbulb fractal. This function is essential for starting the raytracing process on the GPU. ```javascript function initFractalGPU(raytracerParams) { params = raytracerParams.getParams(); let pxWidth = params.screen.pxWidth; let pxHeight = params.screen.pxHeight; let canvas = document.getElementById("myCanvas"); if(canvas) { canvas.remove(); } canvas = document.createElement('canvas'); canvas.id = 'myCanvas'; document.body.querySelector('.panel').appendChild(canvas); //canvas.width = pxWidth; //canvas.height = pxHeight; canvas.addEventListener('click', canvasOnClick_enablePointerLocking); document.addEventListener('pointerlockchange', lockChange, false); const gl = canvas.getContext('webgl2', { premultipliedAlpha: false }); const gpu = new GPU({ canvas, webGl: gl }) .addFunction(sdPlane) .addFunction(mandelbulb) .addFunction(distScene) .addFunction(hsv2rgb); return gpu.createKernel(kernelMarchingRays) .setDebug(true) .setConstants({ pxWidth, pxHeight, iterations: 100 }) .setOutput([pxWidth, pxHeight]) .setGraphical(true) .setLoopMaxIterations(10000); } ``` -------------------------------- ### GPU Kernel for Raytracing Source: https://github.com/gpujs/gpu.js/blob/develop/examples/parallel-raytracer.html Creates a GPU kernel for raytracing, configuring output dimensions and constants. Requires GPU.js setup. ```javascript var createKernel = function(modeNumber, scene) { var mode = stringOfMode(modeNumber); var opt = { mode: mode, output: [Math.floor(scene.canvasWidth / kernelDimension), Math.floor(scene.canvasHeight / kernelDimension)], graphical: true, safeTextureReadHack: false, constants: { ENTITY_COUNT: scene.entities.length, LIGHT_COUNT: scene.lights.length, SPHERE: Entity.Type.SPHERE, PLANE: Entity.Type.PLANE, LIGHTSPHERE: Entity.Type.LIGHTSPHERE } }; var gpu = new GPU({ mode }); addFunctions(gpu, vectorFunctions); addFunctions(gpu, utilityFunctions); return gpu.createKernel(function(camera, lights, entities, eyeVector, vpRight, vpUp, canvasHeight, canvasWidth, fovRadians, heightWidthRatio, halfWidth, halfHeight, cameraWidth, cameraHeight, pixelWidth, pixelHeight, xOffset, yOffset) { var x = this.thread.x + (this.output.x * xOffset); var y = this.thread.y + (this.output.y * yOffset); var xCompX = vpRight[0] * (x * pixelWidth - halfWidth); var xCompY = vpRight[1] * (x * pixelWidth - halfWidth); var xCompZ = vpRight[2] * (x * pixelWidth - halfWidth); var yCompX = vpUp[0] * (y * pixelHeight - halfHeight); var yCompY = vpUp[1] * (y * pixelHeight - halfHeight); var yCompZ = vpUp[2] * (y * pixelHeight - halfHeight); var rayPtX = camera[0]; var rayPtY = camera[1]; var rayPtZ = camera[2]; var rayVecX = eyeVector[0] + xCompX + yCompX; var rayVecY = eyeVector[1] + xCompY + yCompY; var rayVecZ = ``` -------------------------------- ### Scene Generation and Camera Setup Source: https://github.com/gpujs/gpu.js/blob/develop/examples/parallel-raytracer.html Generates the scene entities and camera vectors. Provides functions to update the sphere count and generate the scene object. ```javascript var opts = generateRandomSpheres(4) .concat(light_opts); var entities = opts.map(function(opt) { return new Entity.Entity(opt); }).map(function(ent) { return ent.toVector(); }); var eyeVector = vecNormalize(vecSubtract([camera[3], camera[4], camera[5]], [camera[0], camera[1], camera[2]])); var vpRight = vecNormalize(vecCrossProduct(eyeVector, upVector)); var vpUp = vecNormalize(vecCrossProduct(vpRight, eyeVector)); var canvasHeight = 640; var canvasWidth = 640; var fieldOfViewRadians = Math.PI * (camera[6] / 2) / 180; var heightWidthRatio = canvasHeight / canvasWidth; var halfWidth = Math.tan(fieldOfViewRadians); var halfHeight = heightWidthRatio * halfWidth; var cameraWidth = halfWidth * 2; var cameraHeight = halfHeight * 2; var pixelWidth = cameraWidth / (canvasWidth - 1); var pixelHeight = cameraHeight / (canvasHeight - 1); Scene.generateScene = function() { return { camera: camera, lights: lights, entities: entities, eyeVector: eyeVector, vpRight: vpRight, vpUp: vpUp, canvasHeight: canvasHeight, canvasWidth: canvasWidth, fovRadians: fieldOfViewRadians, heightWidthRatio: heightWidthRatio, halfWidth: halfWidth, halfHeight: halfHeight, cameraWidth: cameraWidth, cameraHeight: cameraHeight, pixelWidth: pixelWidth, pixelHeight: pixelHeight }; }; Scene.updateSphereCount = function(count) { opts = generateRandomSpheres(count).concat(light_opts); entities = opts.map(function(opt) { return new Entity.Entity(opt); }).map(function(ent) { return ent.toVector(); }); return entities; }; })(Scene || (Scene = {})); ``` -------------------------------- ### Strongly Typed Mapped Kernel with GPU.js Source: https://github.com/gpujs/gpu.js/blob/develop/README.md Illustrates creating a strongly typed mapped kernel with GPU.js, including a sub-kernel and pipeline functionality. This example uses Texture and toArray for output. ```typescript import { GPU, Texture, IKernelFunctionThis } from 'gpu.js'; const gpu = new GPU(); function kernelFunction(this: IKernelFunctionThis): [number, number] { return [1, 1]; } function subKernel(): [number, number] { return [1, 1]; } const kernelMap = gpu.createKernelMap({ test: subKernel, }, kernelFunction) .setOutput([1]) .setPipeline(true); const result = kernelMap(); console.log((result.test as Texture).toArray() as [number, number][]); ``` -------------------------------- ### SSPS Constructor and Control Building Source: https://github.com/gpujs/gpu.js/blob/develop/examples/fluid.html Initializes the SSPS simulation and builds the user interface controls for interaction. Provides a basic structure for simulation setup. ```javascript function SSPS(psim) { this.dt = 0; this.psim = psim; this.keys = {}; this.controls = {}; this.buildControls(); } SSPS.prototype.buildControls = function() { let html =
SSPS by Chadams - fps - particles @
[W] - Forward, [S] - Reverse, [ARROWS] - Look
[E] - Grab, [SPACE] - Shoot Particle
[R] - Cycle Render Mode:
[1] - Cycle Particle Density:
[2] - Cycle Particle Viscosity:
[3] - Cycle Particle Mass:
[4] - Cycle Particle Incompressiveness: { return '../..'; } }; window.require = (module) => { if (module.match(/[/.]/[.]\\/src$/)) return browserGPU; if (module === 'sinon') return sinon; if (module === 'qunit') return QUnit; if (module === 'acorn') return acorn; if (module.match(/[/.]/[.]\\/browser-test-utils$/)) return browserTestUtils; throw new Error('cannot find ' + module); }; ``` -------------------------------- ### Browser Environment Setup for GPU.JS Testing Source: https://github.com/gpujs/gpu.js/blob/develop/test/all-template.html This snippet configures a browser environment for testing GPU.JS. It mocks the 'process' and 'require' objects to simulate a Node.js-like environment within the browser, allowing the library to be tested as if it were running in Node.js. ```javascript const isBrowser = true; const browserGPU = { GPU }; for (const p in GPU) { if (p === 'GPU') continue; browserGPU[p] = GPU[p]; } window.process = { cwd: () => { return '../..'; } }; window.require = (module) => { if (module.match(/[/\\]src$/)) return browserGPU; if (module === 'sinon') return sinon; if (module === 'qunit') return QUnit; if (module === 'acorn') return acorn; if (module.match(/browser-test-utils$/)) return browserTestUtils; throw new Error('cannot find ' + module); }; {{test-files}} ``` -------------------------------- ### Initialize GPU Instances and Define Random Draw Function Source: https://github.com/gpujs/gpu.js/blob/develop/examples/random.html Initializes GPU instances for CPU, WebGL, and WebGL2 modes. Defines a kernel function that sets a random color. This setup is required before creating and running graphical kernels. ```javascript let cpu, webGL, webGL2; cpu = new GPU({ mode: 'cpu', canvas: document.getElementById('cpu-random-output') }); try { webGL = new GPU({ mode: 'webgl', canvas: document.getElementById('web-gl-random-output') }); } catch (e) {} try { webGL2 = new GPU({ mode: 'webgl2', canvas: document.getElementById('web-gl2-random-output') }); } catch (e) {} function drawRandomFunction() { this.color(Math.random(), Math.random(), Math.random()); } ``` -------------------------------- ### Inspect GPU Kernel Values by Returning Early Source: https://github.com/gpujs/gpu.js/blob/develop/README.md To debug an actual GPU kernel, return intermediate values early in the kernel function. This allows you to inspect specific calculated values before the full kernel execution completes. For example, returning `x` helps debug its calculation. ```javascript const gpu = new GPU({ mode: 'cpu' }); const kernel = gpu.createKernel(function(arg1, time) { const x = this.thread.x * time; return x; // <--NOTICE THIS, IMPORTANT! const v = arg1[this.thread.y][x]; return v; }, { output: [100, 100] }); ``` -------------------------------- ### Initialize GUI and Event Listeners Source: https://github.com/gpujs/gpu.js/blob/develop/examples/mandelbulb.html Sets up the graphical user interface and binds event listeners for mouse wheel, mouse movement, and keyboard input to control the camera and rendering parameters. ```javascript function initGui() { raytracer.canvas.addEventListener('wheel',(event) => { mouseWheel(event); return false; }, false); raytracer.canvas.addEventListener('mousemove',(event) => { mouseMove(event); return false; }, false); document.onkeypress = (e) => { if(e.key === "w") moveCamera(1,0,0); if(e.key === "s") moveCamera(-1,0,0); if(e.key === "a") moveCamera(0,-1,0); if(e.key === "d") moveCamera(0,1,0); if(e.key === "e") moveCamera(0,0,1); if(e.key === "c") moveCamera(0,0,-1); if(e.key === "+") mouseWheel({deltaY: -10}); if(e.key === "-") mouseWheel({deltaY: 10}); }; chceckScreenResize(); refresh(); } ``` -------------------------------- ### Get Average Frame Render Duration Source: https://github.com/gpujs/gpu.js/blob/develop/examples/parallel-raytracer.html Calculates and returns the average duration from the recorded frame render times. ```javascript Benchmark.prototype.getAvgFrameRenderDuration = function() { var sum = this.getResults().frameRenderDurations.reduce(function(a, b) { return a + b; }); var avg = sum / this.getResults().frameRenderDurations.length; return avg; }; ``` -------------------------------- ### Get Maximum Frame Render Duration Source: https://github.com/gpujs/gpu.js/blob/develop/examples/parallel-raytracer.html Finds and returns the maximum duration from the recorded frame render times. ```javascript Benchmark.prototype.getMaxFrameRenderDuration = function() { return Math.max.apply(Math, this.getResults().frameRenderDurations); }; ``` -------------------------------- ### Initialize GPU in Browser Source: https://github.com/gpujs/gpu.js/blob/develop/README.md Include the GPU.js browser script and create a new GPU instance in an HTML page. ```html ``` -------------------------------- ### Get Minimum Frame Render Duration Source: https://github.com/gpujs/gpu.js/blob/develop/examples/parallel-raytracer.html Finds and returns the minimum duration from the recorded frame render times. ```javascript Benchmark.prototype.getMinFrameRenderDuration = function() { return Math.min.apply(Math, this.getResults().frameRenderDurations); }; ``` -------------------------------- ### Initialize GPU in Node.js (JavaScript) Source: https://github.com/gpujs/gpu.js/blob/develop/README.md Import and create a new GPU instance in a Node.js JavaScript environment. ```javascript const { GPU } = require('gpu.js'); const gpu = new GPU(); ``` -------------------------------- ### Create GPU Kernel with Chained Output Setting Source: https://github.com/gpujs/gpu.js/blob/develop/README.md Create a GPU kernel and set its output size using a chainable method. This is a more concise way to specify settings. ```javascript const kernel = gpu.createKernel(function() { return this.thread.x; }).setOutput([100]); kernel(); // Result: Float32Array[0, 1, 2, 3, ... 99] ``` -------------------------------- ### Get Median Frame Render Duration Source: https://github.com/gpujs/gpu.js/blob/develop/examples/parallel-raytracer.html Calculates and returns the median duration from the recorded frame render times after sorting them. ```javascript Benchmark.prototype.getMedianFrameRenderDuration = function() { var count = this.getResults().frameRenderDurations.length; if (count % 2 == 0) { count -= 1; } var median = this.getResults().frameRenderDurations.sort()["\"" + Math.floor(count / 2) + "\""]; return median; }; ``` -------------------------------- ### Initialize and Render Image with Wobble Effect Source: https://github.com/gpujs/gpu.js/blob/develop/examples/cat-image/index.html Loads an image, converts it to an array, creates a GPU.js kernel for rendering with a wobble effect, and sets up a continuous animation loop with FPS monitoring. ```javascript const logFps = document.querySelector('#log-fps'); const image = new Image(); image.src = './cat.jpg'; image.onload = () => { const array = imageToArray(image); const render = (new GPU({mode: "gpu"})) .createKernel(kernel) .setConstants({ w: image.width, h: image.height }) .setOutput([image.width, image.height]) .setGraphical(true); const canvas = render.canvas; document.body.appendChild(canvas); let lastCalledTime; let fps; function callRender() { const wobble = 14 * Math.sin(Date.now() / 400); render(array, wobble); const delta = (Date.now() - lastCalledTime)/1000; lastCalledTime = Date.now(); fps = 1 / delta; logFps.innerHTML = fps.toFixed(0) + ' FPS'; window.requestAnimationFrame(() => { callRender(); }); } callRender(); }; ``` -------------------------------- ### Execute a GPU Kernel Source: https://github.com/gpujs/gpu.js/blob/develop/README.md Call the created GPU kernel function like a regular JavaScript function to get the computed result. ```javascript kernel(); // Result: Float32Array[0, 1, 2, 3, ... 99] ``` -------------------------------- ### Get Average FPS Source: https://github.com/gpujs/gpu.js/blob/develop/examples/parallel-raytracer.html Calculates the average frames per second based on the total frames rendered and the actual benchmark duration. ```javascript Benchmark.prototype.getAverageFPS = function() { var durationSeconds = this.getResults().actualBenchmarkDuration / 1000; var frameCount = this.getResults().totalFrameCount; return frameCount / durationSeconds; }; ``` -------------------------------- ### Initialize GPU and Kernel with Unsigned Precision Source: https://github.com/gpujs/gpu.js/blob/develop/examples/internal-variable-precision.html Initializes a GPU instance and creates a kernel configured for graphical output with 'unsigned' precision. This is useful for rendering operations where color values are expected to be within the 0-1 range. ```javascript const ivp = document.getElementById('ivp'); const gpu = new GPU(); const startSize = 10; const fullSize = window.innerWidth; const kernel = gpu.createKernel(function() { const x = this.thread.x / this.output.x; const y = this.thread.y / this.output.y; this.color(x, y, y, 1); }, { graphical: true, dynamicOutput: true, precision: 'unsigned' }); document.body.appendChild(kernel.canvas); let currentSize = startSize; ``` -------------------------------- ### Benchmark Class Initialization Source: https://github.com/gpujs/gpu.js/blob/develop/examples/parallel-raytracer.html Initializes the Benchmark class with default settings for mode, duration, and frame count. It also sets up result history storage. ```javascript var Benchmark; (function(Benchmark_1) { var Benchmark = (function() { function Benchmark() { this.mode = ""; this.benchmarkDuration = 8000; this.resetBenchmark(); this.resultHistory = []; this.framesToRender = 60; } Benchmark.prototype.resetBenchmark = function() { this.isBenchmarking = false; this.latestResults = { mode: this.mode, actualBenchmarkDuration: 0, totalFrameCount: 0, frameRenderDurations: [] }; this.startTime = null; }; Benchmark.prototype.startBenchmark = function(mode, callback) { this.resetBenchmark(); this.setMode(mode); this.setCallback(callback); this.startTime = performance.now(); this.isBenchmarking = true; }; Benchmark.prototype.stopBenchmark = function() { this.isBenchmarking = false; this.latestResults.actualBenchmarkDuration = performance.now() - this.startTime; this.computeMinMaxAvg(); this.saveResults(); this.callback(); }; Benchmark.prototype.setCallback = function(callback) { this.callback = callback; }; Benchmark.prototype.getResults = function() { return this.latestResults; }; Benchmark.prototype.saveResults = function() { this.resultHistory.push(this.latestResults); localStorage.setItem(this.mode, JSON.stringify(this.latestResults)); localStorage.setItem("history", JSON.stringify(this.resultHistory)); }; Benchmark.prototype.displaySpeedup = function(elem) { var cpuResults = ``` -------------------------------- ### Initialize GPU in Node.js (TypeScript) Source: https://github.com/gpujs/gpu.js/blob/develop/README.md Import and create a new GPU instance in a Node.js TypeScript environment. This is a new feature in V2. ```typescript import { GPU } from 'gpu.js'; const gpu = new GPU(); ``` -------------------------------- ### GPU and CPU Initialization Source: https://github.com/gpujs/gpu.js/blob/develop/examples/raytracer.html Initializes GPU.js instances for both GPU and CPU rendering. The 'opt' function is used to configure the rendering options. ```javascript const gpu = new GPU(); const cpu = new GPU({ mode: 'cpu'}); ``` -------------------------------- ### Check and Handle Window Resize Source: https://github.com/gpujs/gpu.js/blob/develop/examples/mandelbulb.html Sets up an event listener for the window resize event, although the actual refresh logic is commented out. ```javascript function chceckScreenResize() { window.addEventListener("resize",() => { //refreshScreenSize(); }); } ``` -------------------------------- ### Setting Kernel Precision in GPU.js Source: https://github.com/gpujs/gpu.js/wiki/Quick-Concepts Demonstrates how to create a GPU.js kernel with a specific precision setting, such as 'single' precision. This is useful for controlling the accuracy of calculations performed on the GPU. ```javascript const gpu = new GPU(); const kernel = gpu.createKernel(function() { // ... some maths... return value; }, { output: [10], precision: 'single', }); ``` -------------------------------- ### Extending Constants in GPU.js Kernels Source: https://github.com/gpujs/gpu.js/blob/develop/README.md Shows how to extend constants for GPU.js kernels using TypeScript interfaces. This example defines custom constants and uses them within the kernel function. ```typescript import { GPU, IKernelFunctionThis } from 'gpu.js'; const gpu = new GPU(); interface IConstants { screen: [number, number]; } type This = { constants: IConstants } & IKernelFunctionThis; function kernelFunction(this: This): number { const { screen } = this.constants; return 1 + screen[0]; } const kernelMap = gpu.createKernel(kernelFunction) .setOutput([3,3,3]) .setConstants({ screen: [1, 1] }); const result = kernelMap(); console.log(result as number[][][]); ``` -------------------------------- ### Configuration Constants and Options Source: https://github.com/gpujs/gpu.js/blob/develop/examples/raytracer.html Defines canvas dimensions, initial rendering mode, camera parameters, light sources, and scene objects. Also sets up constants for the GPU kernel. ```javascript const canvasHeight = (window.innerWidth < 600) ? (window.innerWidth - 20) : 600; const canvasWidth = canvasHeight; const initialMode = 1; const camera = [ 0, 0, 16, 0, 0, 1, 45 ]; const lights = [ [-16, 16, 8], [16, 16, 8], ]; const things = [ [0, 13, 1.0, 0.0, 0.0, 0.3, 0.7, 0.2, 1.0, -2, 2, -2, 1], [0, 13, 0.0, 1.0, 0.0, 0.3, 0.7, 0.2, 1.0, 0, 2, 0, 1], [0, 13, 0.0, 0.0, 1.0, 0.3, 0.7, 0.2, 1.0, 2, 2, 2, 1], [0, 13, 0.0, 1.0, 1.0, 0.3, 0.7, 0.2, 1.0, -2, -2, 2, 1], [0, 13, 1.0, 0.0, 1.0, 0.3, 0.7, 0.2, 1.0, 0, -2, 0, 1], [0, 13, 1.0, 1.0, 0.0, 0.3, 0.7, 0.2, 1.0, 2, -2, -2, 1], ]; const constants = { LIGHTSCOUNT: lights.length, THINGSCOUNT: things.length }; const opt = function (mode) { return { constants: constants, graphical: true, mode: stringOfMode(mode), output: [canvasWidth, canvasHeight], tactic: 'precision', }; }; ``` -------------------------------- ### Render Loop with Dynamic Output and Precision Check Source: https://github.com/gpujs/gpu.js/blob/develop/examples/internal-variable-precision.html Sets up a render loop that dynamically adjusts the kernel's output size and checks for canvas tearing. It also displays the current variable precision string. Use this to observe how the kernel behaves as its size increases. ```javascript function render() { if (currentSize < fullSize) { kernel.setOutput([++currentSize, currentSize]); kernel(); ivp.textContent = kernel.getVariablePrecisionString(); requestAnimationFrame(render); } else { alert('reached the width of the window without tearing'); } } requestAnimationFrame(render); ``` -------------------------------- ### Cloning Textures in Pipelined Kernels Source: https://github.com/gpujs/gpu.js/blob/develop/README.md Demonstrates how to clone textures when using pipeline mode. This allows outputs from one kernel to be reused or passed to another kernel, preserving data. ```javascript const kernel1 = gpu.createKernel(function(v) { return v[this.thread.x]; }) .setPipeline(true) .setOutput([100]); const kernel2 = gpu.createKernel(function(v) { return v[this.thread.x]; }) .setOutput([100]); const result1 = kernel1(array); // Result: Texture console.log(result1.toArray()); // Result: Float32Array[0, 1, 2, 3, ... 99] const result2 = kernel2(result1); // Result: Float32Array[0, 1, 2, 3, ... 99] ``` -------------------------------- ### Initialize Kernel Dimension and Mode Source: https://github.com/gpujs/gpu.js/blob/develop/examples/parallel-raytracer.html Initializes the kernel dimension from session storage or defaults to 2, and sets the initial mode to GPU. ```javascript var kernelDimension = kernelDimension || 2; if (sessionStorage.getItem("kernelDimension")) { kernelDimension = parseInt(sessionStorage.getItem("kernelDimension")); var slider = document.getElementById("dimension-slider"); slider.value = kernelDimension; var label = document.getElementById("grid-dimension"); label.innerHTML = kernelDimension; } var mode = Mode.GPU; var canvasNeedsUpdate = true; var isRunning = true; ``` -------------------------------- ### Get Pixel Data from Graphical Kernel Source: https://github.com/gpujs/gpu.js/blob/develop/README.md Retrieve pixel data from a graphical kernel using the getPixels() method. This returns a flat array of RGBA values, similar to WebGL's readPixels, for unified pixel data access. ```javascript const render = gpu.createKernel(function() { this.color(0, 0, 0, 1); }) .setOutput([20, 20]) .setGraphical(true); render(); const pixels = render.getPixels(); // [r,g,b,a, r,g,b,a... ``` -------------------------------- ### Debug Graphical Output by Setting Conditional Colors Source: https://github.com/gpujs/gpu.js/blob/develop/README.md For graphical kernels, debug by conditionally setting pixel colors based on calculated values. This example sets pixels to red or green depending on the value of `x`, allowing visual inspection of the kernel's logic. ```javascript const gpu = new GPU({ mode: 'cpu' }); const kernel = gpu.createKernel(function(arg1, time) { const x = this.thread.x * time; if (x < 4 || x > 2) { // RED this.color(1, 0, 0); // <--NOTICE THIS, IMPORTANT! return; } if (x > 6 && x < 12) { // GREEN this.color(0, 1, 0); // <--NOTICE THIS, IMPORTANT! return; } const v = arg1[this.thread.y][x]; return v; }, { output: [100, 100], graphical: true }); ``` -------------------------------- ### Create and Configure Graphical Kernels Source: https://github.com/gpujs/gpu.js/blob/develop/examples/random.html Creates graphical kernels for each GPU instance using the defined drawRandomFunction. Sets the output size to 100x100 pixels. Handles cases where WebGL or WebGL2 might not be available. ```javascript const cpuDrawRandom = cpu.createKernel(drawRandomFunction) .setGraphical(true) .setOutput([100, 100]); const webGLDrawRandom = webGL ? webGL.createKernel(drawRandomFunction) .setGraphical(true) .setOutput([100, 100]) : () => {}; const webGL2DrawRandom = webGL2 ? webGL2.createKernel(drawRandomFunction) .setGraphical(true) .setOutput([100, 100]) : () => {}; ``` -------------------------------- ### Animation Frame and Render Loop Source: https://github.com/gpujs/gpu.js/blob/develop/examples/raytracer.html Sets up the main render loop using `requestAnimationFrame`. It updates FPS, processes rendering via CPU or GPU kernel, and animates scene elements. ```javascript let requestId = null; function togglePause() { if (requestId) { if (document.getElementById('pause').value === 'Pause') { cancelAnimationFrame(requestId); document.getElementById('pause').value = 'Play'; } else { requestId = requestAnimationFrame(renderLoop); document.getElementById('pause').value = 'Pause'; } } }; const f = document.getElementById('fps'); const lambert = document.getElementById('lambert'); const specular = document.getElementById('specular'); const cpuProcessor = document.getElementById('cpu'); function renderLoop() { f.innerHTML = fps.getFPS().toString(); const lambertianReflectance = lambert.checked ? 1 : 0; const specularReflection = specular.checked ? 1 : 0; if (cpuProcessor.checked) { cpuKernel(camera, lights, things, eyeVector.toArray(), vpRight.toArray(), vpUp.toArray(), halfHeight, halfWidth, pixelHeight, pixelWidth, lambertianReflectance, specularReflection); if (canvas !== cpuKernel.canvas) { showCPUCanvas(); } } else { gpuKernel(camera, lights, things, eyeVector.toArray(), vpRight.toArray(), vpUp.toArray(), halfHeight, halfWidth, pixelHeight, pixelWidth, lambertianReflectance, specularReflection); if (canvas !== gpuKernel.canvas) { showGPUCanvas(); } } for (let i = 0; i < things.length; i++) { const thing = things[i]; const height = canvasHeight / (halfHeight * 2 * 100); if (thing[10] < height) { thing[10] = (thing[10] + 0.02) % (height + 1); } else { thing[10] = -1 * height; } } requestId = requestAnimationFrame(renderLoop); } window.onload = renderLoop; ``` -------------------------------- ### Hash Table Initialization Source: https://github.com/gpujs/gpu.js/blob/develop/examples/fluid.html Initializes a hash table used for spatial partitioning in the simulation. This helps in efficiently querying neighboring particles. ```javascript this.hash = []; for (let i=0; i\n
  • Min frame render speedup: " + minSpeedup + "
  • \n
  • Median frame render speedup: " + medianSpeedup + "
  • \n "; }; ``` -------------------------------- ### Create Kernel Map with Array Outputs Source: https://github.com/gpujs/gpu.js/blob/develop/README.md Use `createKernelMap` with an array to define multiple indexed kernels within a single GPU operation. This provides flexibility for saving intermediate results when named outputs are not required. ```javascript const megaKernel = gpu.createKernelMap([ function add(a, b) { return a + b; }, function multiply(a, b) { return a * b; } ], function(a, b, c) { return multiply(add(a[this.thread.x], b[this.thread.x]), c[this.thread.x]); }, { output: [10] }); megaKernel(a, b, c); // Result: { 0: Float32Array, 1: Float32Array, result: Float32Array } ```