mirror of https://github.com/sotrh/learn-wgpu
You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
87 lines
2.3 KiB
Plaintext
87 lines
2.3 KiB
Plaintext
const PI: f32 = 3.1415926535897932384626433832795;
|
|
|
|
struct Face {
|
|
forward: vec3<f32>,
|
|
up: vec3<f32>,
|
|
right: vec3<f32>,
|
|
}
|
|
|
|
@group(0)
|
|
@binding(0)
|
|
var src: texture_2d<f32>;
|
|
|
|
@group(0)
|
|
@binding(1)
|
|
var dst: texture_storage_2d_array<rgba32float, write>;
|
|
|
|
|
|
@compute
|
|
@workgroup_size(16, 16, 1)
|
|
fn compute_equirect_to_cubemap(
|
|
@builtin(global_invocation_id)
|
|
gid: vec3<u32>,
|
|
) {
|
|
// If texture size is not divisible by 32 we
|
|
// need to make sure we don't try to write to
|
|
// pixels that don't exist.
|
|
if gid.x >= u32(textureDimensions(dst).x) {
|
|
return;
|
|
}
|
|
|
|
var FACES: array<Face, 6> = array(
|
|
// FACES +X
|
|
Face(
|
|
vec3(1.0, 0.0, 0.0), // forward
|
|
vec3(0.0, 1.0, 0.0), // up
|
|
vec3(0.0, 0.0, -1.0), // right
|
|
),
|
|
// FACES -X
|
|
Face (
|
|
vec3(-1.0, 0.0, 0.0),
|
|
vec3(0.0, 1.0, 0.0),
|
|
vec3(0.0, 0.0, 1.0),
|
|
),
|
|
// FACES +Y
|
|
Face (
|
|
vec3(0.0, -1.0, 0.0),
|
|
vec3(0.0, 0.0, 1.0),
|
|
vec3(1.0, 0.0, 0.0),
|
|
),
|
|
// FACES -Y
|
|
Face (
|
|
vec3(0.0, 1.0, 0.0),
|
|
vec3(0.0, 0.0, -1.0),
|
|
vec3(1.0, 0.0, 0.0),
|
|
),
|
|
// FACES +Z
|
|
Face (
|
|
vec3(0.0, 0.0, 1.0),
|
|
vec3(0.0, 1.0, 0.0),
|
|
vec3(1.0, 0.0, 0.0),
|
|
),
|
|
// FACES -Z
|
|
Face (
|
|
vec3(0.0, 0.0, -1.0),
|
|
vec3(0.0, 1.0, 0.0),
|
|
vec3(-1.0, 0.0, 0.0),
|
|
),
|
|
);
|
|
|
|
// Get texture coords relative to cubemap face
|
|
let dst_dimensions = vec2<f32>(textureDimensions(dst));
|
|
let cube_uv = vec2<f32>(gid.xy) / dst_dimensions * 2.0 - 1.0;
|
|
|
|
// Get spherical coordinate from cube_uv
|
|
let face = FACES[gid.z];
|
|
let spherical = normalize(face.forward + face.right * cube_uv.x + face.up * cube_uv.y);
|
|
|
|
// Get coordinate on the equirectangular texture
|
|
let inv_atan = vec2(0.1591, 0.3183);
|
|
let eq_uv = vec2(atan2(spherical.z, spherical.x), asin(spherical.y)) * inv_atan + 0.5;
|
|
let eq_pixel = vec2<i32>(eq_uv * vec2<f32>(textureDimensions(src)));
|
|
|
|
// We use textureLoad() as textureSample() is not allowed in compute shaders
|
|
var sample = textureLoad(src, eq_pixel, 0);
|
|
|
|
textureStore(dst, gid.xy, gid.z, sample);
|
|
} |