UNPKG

gpu-curtains

Version:

gpu-curtains is a 3D WebGPU rendering engine. It can be used as a standalone 3D engine, but also includes extra classes focused on mapping 3d objects to DOM elements; It allows users to synchronize values such as position, sizing, or scale between them.

79 lines (65 loc) 2.48 kB
import { constants } from "../../chunks/utils/constants.mjs"; //#region src/core/shaders/full/compute/compute-cubemap-from-HDR.ts /** * Compute a cube map texture from HDR image data. */ const computeCubemapFromHDR = ` ${constants} // Cube face lookup vectors // positive and negative Y need to be inverted const faceVectors = array<array<vec3f, 2>, 6>( array<vec3f, 2>(vec3f(1.0, 0.0, 0.0), vec3f(0.0, 1.0, 0.0)), // +X array<vec3f, 2>(vec3f(-1.0, 0.0, 0.0), vec3f(0.0, 1.0, 0.0)), // -X array<vec3f, 2>(vec3f(0.0, -1.0, 0.0), vec3f(0.0, 0.0, 1.0)), // -Y array<vec3f, 2>(vec3f(0.0, 1.0, 0.0), vec3f(0.0, 0.0, -1.0)), // +Y array<vec3f, 2>(vec3f(0.0, 0.0, 1.0), vec3f(0.0, 1.0, 0.0)), // +Z array<vec3f, 2>(vec3f(0.0, 0.0, -1.0), vec3f(0.0, 1.0, 0.0)) // -Z ); // Utility to calculate 3D direction for a given cube face pixel fn texelDirection(faceIndex : u32, u : f32, v : f32) -> vec3f { let forward = faceVectors[faceIndex][0]; let up = faceVectors[faceIndex][1]; let right = normalize(cross(up, forward)); return normalize(forward + (2.0 * u - 1.0) * right + (2.0 * v - 1.0) * up); } // Map 3D direction to equirectangular coordinates fn dirToEquirect(dir : vec3f) -> vec2f { let phi = atan2(dir.z, dir.x); let theta = asin(dir.y); let u = 0.5 + 0.5 * phi / PI; let v = 0.5 - theta / PI; return vec2f(u, v); } @compute @workgroup_size(8, 8, 1) fn main(@builtin(global_invocation_id) global_id : vec3u) { let faceSize = params.faceSize; let cubeFaceIndex = global_id.z; let x = global_id.x; let y = global_id.y; if (x >= faceSize || y >= faceSize || cubeFaceIndex >= 6u) { return; } let u = f32(x) / f32(faceSize - 1); let v = f32(y) / f32(faceSize - 1); // Get the 3D direction for this cube face texel let dir = texelDirection(cubeFaceIndex, u, v); // Map to equirectangular coordinates let uv = dirToEquirect(dir); let hdrWidth = params.imageSize.x; let hdrHeight = params.imageSize.y; let texX = u32(clamp(uv.x * hdrWidth, 0.0, hdrWidth - 1.0)); let texY = u32(clamp(uv.y * hdrHeight, 0.0, hdrHeight - 1.0)); let hdrTexelIndex = texY * u32(hdrWidth) + texX; // Sample the equirectangular texture let sampledColor = params.hdrImageData[hdrTexelIndex]; // Correct cube face order in texture store (fix for reversed face indices) textureStore( storageCubemap, vec2u(x, y), cubeFaceIndex, sampledColor ); } `; //#endregion export { computeCubemapFromHDR };