Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Formula Not Working as Expected when inside GPU.js kernel #828

Open
@sojs-coder

Description

No meme sorry

What is wrong?

I have made a lighting shader using GPU.js. After taking the exact same code and modifying it to work with variables passed to a GPU.js kernel, it stops working.

This is a photo of it working...
image

The exact same formula put into GPU.js kernel (I am away that the kernel's height is inverted from normal canvas.js... this is not the problem

image

Where does it happen?

Firefox, chrome browsers.

How do we replicate the issue?

Copied and pasted no worky code

<!DOCTYPE html>
<html lang="en">
<head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <title>Directional Lighting Scene</title>
 <style>
 canvas { border: 1px solid #000; }
 </style>
</head>
<body> 
 <script src = "matter.js"></script>
 <script src = "gpu.js"></script>
 <script src = "anvil.js"></script>
 <canvas id="canvas" width="400" height="400"></canvas>
 <script>
 const canvas = document.getElementById('canvas');
 const ctx = canvas.getContext('2d');
 // Define colored triangles in the scene
 const triangles = [
 { vertices: [[50, 50], [150, 50], [100, 150]], color: [255, 0, 0, 255] }, // Red triangle
 { vertices: [[200, 50], [300, 50], [250, 150]], color: [0, 255, 0, 255] }, // Green triangle
 { vertices: [[100, 200], [200, 200], [150, 300]], color: [0, 0, 255, 255] } // Blue triangle
 ];
 function drawScene() {
 ctx.fillStyle = "white";
 ctx.fillRect(0,0,canvas.width,canvas.height);
 for (const triangle of triangles) {
 const path = new Path2D();
 const [startX, startY] = triangle.vertices[0];
 path.moveTo(startX, startY);
 for (let i = 1; i < triangle.vertices.length; i++) {
 const [x, y] = triangle.vertices[i];
 path.lineTo(x, y);
 }
 path.closePath();
 const [r, g, b, a] = triangle.color;
 ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a / 255})`;
 ctx.fill(path);
 }
 }
 const directionalLights = [
 [Math.PI / 4, 100, 100, 1, 400, Math.PI / 3],
 [Math.PI, 300, 300, 0.8, 500, Math.PI / 4]
 ];
 var gpu = new GPU()
 var diffuseKernel = gpu.createKernel(function(pix, width, height, dlights, numdlights, ambient){
 var pixNum = ((width * height-this.thread.y) +this.thread.x) * 4;
 var red = pix[pixNum];
 var green = pix[pixNum+1];
 var blue = pix[pixNum+2];
 var brightness = ambient;
 var dlight = dlights[0];
 var lightDir = dlights[0][0];
 var lightX = dlights[0][1];
 var lightY = dlights[0][2];
 var intensity = dlights[0][3];
 var diffuse = dlights[0][4];
 var spread = dlights[0][5];
 const dirX = this.thread.x - lightX;
 const dirY = this.thread.y - lightY;
 const distance = Math.sqrt(dirX * dirX + dirY * dirY);
 const angleToLight = Math.atan2(dirY, dirX);
 const angleDiff = Math.abs(angleToLight - lightDir);
 if (angleDiff <= spread / 2) {
 // Calculate diffuse lighting
 const diffuseFactor = Math.max(0, Math.cos(angleDiff) * (1 - (distance / diffuse)));
 brightness += intensity * diffuseFactor;
 }
 this.color((red/255)*brightness, (green/255)*brightness, (blue/255)*brightness,pix[pixNum+2]/255)
 },{
 output: [canvas.width,canvas.height],
 graphical: true
 })
 function applyDirectionalLights(x, y, currentColor) {
 let ambient = 0.05;
 let finalColor = [0,0,0,255]; // Initialize with ambient color
 let pixelLit = false;
 brightness = ambient;
 for (const light of directionalLights) {
 const [lightDir, lightX, lightY, intensity, diffuse, spread] = light;
 // Calculate direction from light to pixel
 const dirX = x - lightX;
 const dirY = y - lightY;
 const distance = Math.sqrt(dirX * dirX + dirY * dirY);
 // Check if pixel is within the light spread angle
 const angleToLight = Math.atan2(dirY, dirX);
 const angleDiff = Math.abs(angleToLight - lightDir);
 if (angleDiff <= spread / 2) {
 // Calculate diffuse lighting
 const diffuseFactor = Math.max(0, Math.cos(angleDiff) * (1 - (distance / diffuse)));
 brightness += intensity * diffuseFactor;
 }
 }
 finalColor = currentColor.map((channel, index) => Math.min(255, channel * brightness));
 return finalColor
 }
 // Draw the initial scene
 drawScene();
 function diffuse(){
 const width = canvas.width;
 const height = canvas.height;
 const pix = ctx.getImageData(0, 0, width, height).data;
 diffuseKernel(pix, width, height, directionalLights, directionalLights.length, 0.05);
 const pixels = this.diffuseKernel.getPixels();
 ctx.putImageData(new ImageData(pixels, width, height), 0, 0);
 }
 var mouseX, mouseY = [-1,-1]
 document.addEventListener("mousemove",(e)=>{
 mouseX = event.clientX - canvas.getBoundingClientRect().left;
 mouseY = event.clientY - canvas.getBoundingClientRect().top;
 })
 // Call the diffuse function to apply directional lighting
 diffuse();
 setInterval(()=>{
 ctx.clearRect(0,0,canvas.width,canvas.height);
 directionalLights[0][0] = Math.atan2(mouseY - directionalLights[0][1], mouseX - directionalLights[0][2]);
 drawScene();
 diffuse();
 },1000/0.5);
 </script>
</body>
</html>

Copied and pasted worky code

 <!DOCTYPE html>
 <html lang="en">
 <head>
 <meta charset="UTF-8">
 <meta name="viewport" content="width=device-width, initial-scale=1.0">
 <title>Directional Lighting Scene</title>
 <style>
 canvas { border: 1px solid #000; }
 </style>
 </head>
 <body> 
 <script src = "matter.js"></script>
 <script src = "gpu.js"></script>
 <script src = "anvil.js"></script>
 <canvas id="canvas" width="400" height="400"></canvas>
 <script>
 const canvas = document.getElementById('canvas');
 const ctx = canvas.getContext('2d');
 // Define colored triangles in the scene
 const triangles = [
 { vertices: [[50, 50], [150, 50], [100, 150]], color: [255, 0, 0, 255] }, // Red triangle
 { vertices: [[200, 50], [300, 50], [250, 150]], color: [0, 255, 0, 255] }, // Green triangle
 { vertices: [[100, 200], [200, 200], [150, 300]], color: [0, 0, 255, 255] } // Blue triangle
 ];
 function drawScene() {
 ctx.fillStyle = "white";
 ctx.fillRect(0,0,canvas.width,canvas.height);
 for (const triangle of triangles) {
 const path = new Path2D();
 const [startX, startY] = triangle.vertices[0];
 path.moveTo(startX, startY);
 for (let i = 1; i < triangle.vertices.length; i++) {
 const [x, y] = triangle.vertices[i];
 path.lineTo(x, y);
 }
 path.closePath();
 const [r, g, b, a] = triangle.color;
 ctx.fillStyle = `rgba(${r}, ${g}, ${b}, ${a / 255})`;
 ctx.fill(path);
 }
 }
 const directionalLights = [
 [Math.PI / 4, 100, 100, 1, 400, Math.PI / 3],
 [Math.PI, 300, 300, 0.8, 500, Math.PI / 4]
 ];
 function applyDirectionalLights(x, y, currentColor) {
 let ambient = 0.05;
 let finalColor = [0,0,0,255]; // Initialize with ambient color
 let pixelLit = false;
 brightness = ambient;
 for (const light of directionalLights) {
 const [lightDir, lightX, lightY, intensity, diffuse, spread] = light;
 // Calculate direction from light to pixel
 const dirX = x - lightX;
 const dirY = y - lightY;
 const distance = Math.sqrt(dirX * dirX + dirY * dirY);
 // Check if pixel is within the light spread angle
 const angleToLight = Math.atan2(dirY, dirX);
 const angleDiff = Math.abs(angleToLight - lightDir);
 if (angleDiff <= spread / 2) {
 // Calculate diffuse lighting
 const diffuseFactor = Math.max(0, Math.cos(angleDiff) * (1 - (distance / diffuse)));
 brightness += intensity * diffuseFactor;
 
 }
 }
 finalColor = currentColor.map((channel, index) => Math.min(255, channel * brightness));
 return finalColor
 }
 // Draw the initial scene
 drawScene();
 function diffuse(){
 const width = canvas.width;
 const height = canvas.height;
 
 const pix = ctx.getImageData(0, 0, width, height).data;
 // Loop through each pixel
 for(var x = 0; x < width; x++){
 for(var y = 0; y < height; y++){
 // Calculate the color of the pixel
 const pixelColor = [pix[(x + y * width) * 4 + 0], pix[(x + y * width) * 4 + 1], pix[(x + y * width) * 4 + 2], pix[(x + y * width) * 4 + 3]];
 var [r,g,b,a] = applyDirectionalLights(x,y,pixelColor);
 ctx.fillStyle = `rgba(${r},${g},${b},${a})`
 ctx.fillRect(x,y,1,1);
 }
 }
 }
 var mouseX, mouseY = [-1,-1]
 document.addEventListener("mousemove",(e)=>{
 mouseX = event.clientX - canvas.getBoundingClientRect().left;
 mouseY = event.clientY - canvas.getBoundingClientRect().top;
 
 })
 // Call the diffuse function to apply directional lighting
 diffuse();
 setInterval(()=>{
 ctx.clearRect(0,0,canvas.width,canvas.height);
 directionalLights[0][0] = Math.atan2(mouseY - directionalLights[0][1], mouseX - directionalLights[0][2]);
 drawScene();
 diffuse();
 },1000/10);
 </script>
 </body>
 </html>

How important is this (1-5)?

I have to delay the directional lighting system in my game as long as this is not resolved
4 ( I can work on other things in the meantime, but still important)

Expected behavior (i.e. solution)

Provided image

Other Comments

If it is a bug in my own code.... I'm sorry but I can't find it, ChatGPT can't find it, Bard can't find it, and my math teacher can't find it.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions

        AltStyle によって変換されたページ (->オリジナル) /