Hi friends,
I have a simple shader code to add 2 arrays. It works well in Playground and I can see the resultArray being logged out to console. However, when I embed this code into my front-end web app, it does not print resultArray to console, even though the code is the same.
When I do browser debugging, I can see that the execution reach to the block bufferResultArray.read().then((res) at the end of my code; however, the code inside the brackets to log the buffer content to console never got executed.
May anyone help tell me the reason why ? Thank you
cv['onRuntimeInitialized'] = () => {
// Get the input and canvas elements
const imageInput = document.getElementById('imageInput');
const canvasOutput = document.getElementById('canvasOutput');
// Event listener for file input
imageInput.addEventListener('change', (e) => {
// Check if WebGPU is supported
BABYLON.WebGPUEngine.IsSupportedAsync.then((isSupported) => {
if (isSupported) {
console.log("WebGPU is supported in current browser!");
// Initialize the WebGPUEngine
const canvas = document.getElementById('renderCanvas');
engine = new BABYLON.WebGPUEngine(canvas);
} else {
console.log("WebGPU is not supported, fallback to standard engine.");
// Fallback to the standard Engine
const canvas = document.getElementById('renderCanvas');
engine = new BABYLON.Engine(canvas, true);
}
});
const file = e.target.files[0];
if (file) {
const reader = new FileReader();
// When the file is read, create an image and process it
reader.onload = (event) => {
const img = new Image();
img.onload = () => {
engine.initAsync().then(() => {
const supportCS = engine.getCaps().supportComputeShaders;
if (supportCS) {
console.log("Compute shaders are supported!");
}
else {
console.log("Compute shaders are not supported!");
}
console.log('Engine started: ' + engine.getInfo().renderer);
console.log('Engine vendor:' + engine.getInfo().vendor);
scene = new BABYLON.Scene(engine);
fishviewer = new FishViewer(engine, scene);
fishviewer.setMap(xmap, ymap);
fishviewer.setHomography(M);
const shaderCode = `
@group(0) @binding(0) var<storage,read> firstArray: array<f32>;
@group(0) @binding(1) var<storage,read> secondArray: array<f32>;
@group(0) @binding(2) var<storage,read_write> resultArray: array<f32>;
@compute @workgroup_size(1, 1, 1)
fn main(@builtin(global_invocation_id) global_id: vec3<u32>) {
let index: u32 = global_id.x;
resultArray[index] = firstArray[index] + secondArray[index];
}
`;
const computeShader = new BABYLON.ComputeShader(
"MyAwesomeComputeShader", // give it a name
engine, // give it the WebGPU engine
{ computeSource: shaderCode }, // give it our shader code
// Then declare the same bindings as what was in our code
{
bindingsMapping: {
firstArray: { group: 0, binding: 0 },
secondArray: { group: 0, binding: 1 },
resultArray: { group: 0, binding: 2 }
}
}
);
const firstArray = new Float32Array([1, 2, 3, 4, 5, 6, 7, 8, 9]);
const secondArray = new Float32Array([9, 8, 7, 6, 5, 4, 3, 2, 1]);
const bufferFirstArray = new BABYLON.StorageBuffer(engine, firstArray.byteLength);
bufferFirstArray.update(firstArray);
const bufferSecondArray = new BABYLON.StorageBuffer(engine, secondArray.byteLength);
bufferSecondArray.update(secondArray);
const bufferResultArray = new BABYLON.StorageBuffer(engine, Float32Array.BYTES_PER_ELEMENT * firstArray.length);
computeShader.setStorageBuffer("firstArray", bufferFirstArray);
computeShader.setStorageBuffer("secondArray", bufferSecondArray);
computeShader.setStorageBuffer("resultArray", bufferResultArray);
computeShader.dispatchWhenReady(firstArray.length, 1, 1).then(() => {
bufferResultArray.read().then((res) => {
const result = new Float32Array(res.buffer);
console.log(result);
});
});
})
.catch((error) => {
console.error("Failed to initialize Babylon.js WebGPU engine", error);
});
};
};
}
});
};