Fixed issue with incorrect raycasts by changing ray-box algorithm and applying normal offset
This commit is contained in:
parent
404c7875bf
commit
0f668084d3
|
@ -39,6 +39,7 @@ struct HitInfo {
|
||||||
struct AabbHitInfo {
|
struct AabbHitInfo {
|
||||||
hit: bool,
|
hit: bool,
|
||||||
distance: f32,
|
distance: f32,
|
||||||
|
normal: vec3<f32>,
|
||||||
};
|
};
|
||||||
|
|
||||||
struct Feedback {
|
struct Feedback {
|
||||||
|
@ -67,20 +68,54 @@ fn get_shading_offset(hit: HitInfo) -> u32 {
|
||||||
return (*brickmap).shading_table_offset + map_voxel_idx;
|
return (*brickmap).shading_table_offset + map_voxel_idx;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn max_component(v: vec3<f32>) -> f32 {
|
||||||
|
return max(max(v.x, v.y), v.z);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn less_than(a: vec2<f32>, b: vec2<f32>) -> vec2<bool> {
|
||||||
|
return vec2<bool>(a.x < b.x, a.y < b.y);
|
||||||
|
}
|
||||||
|
|
||||||
fn ray_intersect_aabb(
|
fn ray_intersect_aabb(
|
||||||
ray_pos: vec3<f32>,
|
orig_ray_pos: vec3<f32>,
|
||||||
ray_dir: vec3<f32>,
|
ray_dir: vec3<f32>,
|
||||||
min: vec3<f32>,
|
min: vec3<f32>,
|
||||||
max: vec3<f32>
|
max: vec3<f32>
|
||||||
) -> AabbHitInfo {
|
) -> AabbHitInfo {
|
||||||
let ray_dir_inv = 1.0 / ray_dir;
|
let radius = (max - min) * 0.5;
|
||||||
let t1 = (min - ray_pos) * ray_dir_inv;
|
let center = min + radius;
|
||||||
let t2 = (max - ray_pos) * ray_dir_inv;
|
let ray_pos = orig_ray_pos - center;
|
||||||
let t_min = min(t1, t2);
|
var winding = 1.0;
|
||||||
let t_max = max(t1, t2);
|
if (max_component(abs(ray_pos) * (1.0 / radius)) < 1.0) {
|
||||||
let tmin = max(max(t_min.x, 0.0), max(t_min.y, t_min.z));
|
winding = -1.0;
|
||||||
let tmax = min(t_max.x, min(t_max.y, t_max.z));
|
}
|
||||||
return AabbHitInfo(tmax > tmin, tmin);
|
var sgn = -sign(ray_dir);
|
||||||
|
let d = (radius * winding * sgn - ray_pos) * (1.0 / ray_dir);
|
||||||
|
let test = vec3<bool>(
|
||||||
|
(d.x >= 0.0) && all(less_than(abs(ray_pos.yz + ray_dir.yz * d.x), radius.yz)),
|
||||||
|
(d.y >= 0.0) && all(less_than(abs(ray_pos.zx + ray_dir.zx * d.y), radius.zx)),
|
||||||
|
(d.z >= 0.0) && all(less_than(abs(ray_pos.xy + ray_dir.xy * d.z), radius.xy))
|
||||||
|
);
|
||||||
|
|
||||||
|
if (test.x) {
|
||||||
|
sgn = vec3<f32>(sgn.x, 0.0, 0.0);
|
||||||
|
} else if (test.y) {
|
||||||
|
sgn = vec3<f32>(0.0, sgn.y, 0.0);
|
||||||
|
} else if (test.z) {
|
||||||
|
sgn = vec3<f32>(0.0, 0.0, sgn.z);
|
||||||
|
} else {
|
||||||
|
sgn = vec3<f32>(0.0, 0.0, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
|
var distance = 0.0;
|
||||||
|
if (sgn.x != 0.0) {
|
||||||
|
distance = d.x;
|
||||||
|
} else if (sgn.y != 0.0) {
|
||||||
|
distance = d.y;
|
||||||
|
} else if (sgn.z != 0.0) {
|
||||||
|
distance = d.z;
|
||||||
|
}
|
||||||
|
return AabbHitInfo((sgn.x != 0.0) || (sgn.y != 0.0) || (sgn.z != 0.0), distance * winding, sgn);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn point_inside_aabb(p: vec3<i32>, min: vec3<i32>, max: vec3<i32>) -> bool {
|
fn point_inside_aabb(p: vec3<i32>, min: vec3<i32>, max: vec3<i32>) -> bool {
|
||||||
|
@ -116,7 +151,7 @@ fn brick_ray_cast(
|
||||||
// tmin is greater than 0 if the ray is outside of the AABB, so we need to
|
// tmin is greater than 0 if the ray is outside of the AABB, so we need to
|
||||||
// accelerate the ray to be on the edge of the AABB.
|
// accelerate the ray to be on the edge of the AABB.
|
||||||
if (tmin > 0.0) {
|
if (tmin > 0.0) {
|
||||||
ray_pos += ray_dir * (tmin + 0.0001);
|
ray_pos += ray_dir * tmin - aabbHit.normal * 0.0001;
|
||||||
}
|
}
|
||||||
|
|
||||||
// DDA setup
|
// DDA setup
|
||||||
|
@ -174,7 +209,7 @@ fn grid_cast_ray(orig_ray_pos: vec3<f32>, ray_dir: vec3<f32>) -> HitInfo {
|
||||||
// tmin is greater than 0 if the ray is outside of the AABB, so we need to
|
// tmin is greater than 0 if the ray is outside of the AABB, so we need to
|
||||||
// accelerate the ray to be on the edge of the AABB.
|
// accelerate the ray to be on the edge of the AABB.
|
||||||
if (tmin > 0.0) {
|
if (tmin > 0.0) {
|
||||||
ray_pos += ray_dir * (tmin + 0.0001);
|
ray_pos += ray_dir * tmin - aabbHit.normal * 0.0001;
|
||||||
}
|
}
|
||||||
|
|
||||||
// DDA setup
|
// DDA setup
|
||||||
|
|
Loading…
Reference in New Issue