Skip to content

Commit

Permalink
More WIP on vulkan traversal kernels
Browse files Browse the repository at this point in the history
  • Loading branch information
gboisse committed Jan 22, 2018
1 parent 75141bd commit 6b0c026
Show file tree
Hide file tree
Showing 5 changed files with 231 additions and 7 deletions.
2 changes: 1 addition & 1 deletion RadeonRays/src/kernels/CL/intersect_bvh2_bittrail.cl
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,7 @@ KERNEL void intersect_main(
float3 const v3 = vertices[node.i2];
// Calculate hit position
float3 const p = r.o.xyz + r.d.xyz * t_max;
// Calculte barycentric coordinates
// Calculate barycentric coordinates
float2 const uv = triangle_calculate_barycentrics(p, v1, v2, v3);
// Update hit information
hits[global_id].shape_id = node.shape_id;
Expand Down
2 changes: 1 addition & 1 deletion RadeonRays/src/kernels/CL/intersect_bvh2_lds.cl
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ KERNEL void intersect_main(
const bvh_node node = nodes[closest_addr];
const float3 p = myRay.o.xyz + closest_t * myRay.d.xyz;

// Calculte barycentric coordinates
// Calculate barycentric coordinates
const float2 uv = triangle_calculate_barycentrics(
p,
node.aabb_left_min_or_v0_and_addr_left.xyz,
Expand Down
2 changes: 1 addition & 1 deletion RadeonRays/src/kernels/CL/intersect_bvh2_lds_fp16.cl
Original file line number Diff line number Diff line change
Expand Up @@ -284,7 +284,7 @@ KERNEL void intersect_main(
const bvh_node node = nodes[closest_addr];
const float3 p = myRay.o.xyz + closest_t * myRay.d.xyz;

// Calculte barycentric coordinates
// Calculate barycentric coordinates
const float2 uv = triangle_calculate_barycentrics(
p,
as_float3(node.aabb01_min_or_v0_and_addr0.xyz),
Expand Down
2 changes: 1 addition & 1 deletion RadeonRays/src/kernels/CL/intersect_bvh2_short_stack.cl
Original file line number Diff line number Diff line change
Expand Up @@ -433,7 +433,7 @@ KERNEL void intersect_main(
float3 const v3 = vertices[node.i2];
// Calculate hit position
float3 const p = r.o.xyz + r.d.xyz * t_max;
// Calculte barycentric coordinates
// Calculate barycentric coordinates
float2 const uv = triangle_calculate_barycentrics(p, v1, v2, v3);
// Update hit information
hits[global_id].shape_id = node.shape_id;
Expand Down
230 changes: 227 additions & 3 deletions RadeonRays/src/kernels/GLSL/bvh2.comp
Original file line number Diff line number Diff line change
Expand Up @@ -71,12 +71,12 @@ layout(std140, binding = 1) buffer restrict readonly RaysBlock

layout(std140, binding = 2) buffer restrict readonly NumraysBlock
{
int Numrays;
uint Numrays;
};

layout(std430, binding = 3) buffer StackBlock
{
int Stack[];
uint Stack[];
};

layout(std430, binding = 4) buffer restrict writeonly HitsBlock
Expand All @@ -86,15 +86,239 @@ layout(std430, binding = 4) buffer restrict writeonly HitsBlock

layout(std430, binding = 4) buffer restrict writeonly HitsResults
{
int Hitresults[];
uint Hitresults[];
};

layout(local_size_x = GROUP_SIZE, local_size_y = 1, local_size_z = 1) in;

shared uint lds_stack[GROUP_SIZE * LDS_STACK_SIZE];

float copysign(float a, float b)
{
return sign(b) >= 0.f ? a : -a;
}

float mymin3(float a, float b, float c)
{
return min(c, min(a, b));
}

float mymax3(float a, float b, float c)
{
return max(c, max(a, b));
}

vec2 calculate_barycentrics(vec3 p, vec3 v1, vec3 v2, vec3 v3)
{
vec3 e1 = v2 - v1;
vec3 e2 = v3 - v1;
vec3 e = p - v1;
float d00 = dot(e1, e1);
float d01 = dot(e1, e2);
float d11 = dot(e2, e2);
float d20 = dot(e, e1);
float d21 = dot(e, e2);
float invdenom = 1.0 / (d00 * d11 - d01 * d01);
float b1 = (d11 * d20 - d01 * d21) * invdenom;
float b2 = (d00 * d21 - d01 * d20) * invdenom;
return vec2(b1, b2);
}

vec2 fast_intersect_aabb(
vec3 pmin, vec3 pmax,
vec3 invdir, vec3 oxinvdir,
float t_max)
{
vec3 f = fma(pmax, invdir, oxinvdir);
vec3 n = fma(pmin, invdir, oxinvdir);
vec3 tmax = max(f, n);
vec3 tmin = min(f, n);
float t1 = min(mymin3(tmax.x, tmax.y, tmax.z), t_max);
float t0 = max(mymax3(tmin.x, tmin.y, tmin.z), 0.0);
return vec2(t0, t1);
}

float fast_intersect_triangle(ray r, vec3 v1, vec3 v2, vec3 v3, float t_max)
{
vec3 e1 = v2 - v1;
vec3 e2 = v3 - v1;
vec3 s1 = cross(r.d.xyz, e2);
float invd = 1.0 / dot(s1, e1);
vec3 d = r.o.xyz - v1;
float b1 = dot(d, s1) * invd;
vec3 s2 = cross(d, e1);
float b2 = dot(r.d.xyz, s2) * invd;
float temp = dot(e2, s2) * invd;

if (b1 < 0.0 || b1 > 1.0 ||
b2 < 0.0 || b1 + b2 > 1.0 ||
temp < 0.0 || temp > t_max)
{
return t_max;
}
else
{
return temp;
}
}

vec3 safe_invdir(vec3 d)
{
float dirx = d.x;
float diry = d.y;
float dirz = d.z;
float ooeps = 1e-5;
vec3 invdir;
invdir.x = 1.0 / (abs(dirx) > ooeps ? dirx : copysign(ooeps, dirx));
invdir.y = 1.0 / (abs(diry) > ooeps ? diry : copysign(ooeps, diry));
invdir.z = 1.0 / (abs(dirz) > ooeps ? dirz : copysign(ooeps, dirz));
return invdir;
}

void intersect_main()
{
uint index = gl_GlobalInvocationID.x;
uint local_index = gl_LocalInvocationID.x;

// Handle only working subset
if (index >= Numrays) return;

ray myRay = Rays[index]; // TODO: VK:- SC SPIR-V module not valid: OpStore Pointer <id> '136's type does not match Object <id> '137's type. (gboisse)
vec3 invDir = safe_invdir(myRay.d.xyz);
vec3 oxInvDir = -myRay.o.xyz * invDir;

// Intersection parametric distance
float closest_t = myRay.o.w;

// Current node address
uint addr = 0;
// Current closest address
uint closest_addr = INVALID_ADDR;

uint stack_bottom = STACK_SIZE * index;
uint sptr = stack_bottom;
uint lds_stack_bottom = local_index * LDS_STACK_SIZE;
uint lds_sptr = lds_stack_bottom;

lds_stack[lds_sptr++] = INVALID_ADDR;

#if 0

while (addr != INVALID_ADDR)
{
BvhNode node = bvh[addr];

if (INTERNAL_NODE(node))
{
vec2 s0 = fast_intersect_aabb(
node.aabb_left_min_or_v0,
node.aabb_left_max_or_v1,
invDir, oxInvDir, closest_t);
vec2 s1 = fast_intersect_aabb(
node.aabb_right_min_or_v2,
node.aabb_right_max,
invDir, oxInvDir, closest_t);

bool traverse_c0 = (s0.x <= s0.y);
bool traverse_c1 = (s1.x <= s1.y);
bool c1first = traverse_c1 && (s0.x > s1.x);

if (traverse_c0 || traverse_c1) {
uint deferred = INVALID_ADDR;

if (c1first || !traverse_c0) {
addr = node.addr_right;
deferred = node.addr_left;
}
else {
addr = node.addr_left;
deferred = node.addr_right;
}

if (traverse_c0 && traverse_c1) {
if (lds_sptr - lds_stack_bottom >= LDS_STACK_SIZE) {
for (int i = 1; i < LDS_STACK_SIZE; ++i) {
stack[sptr + i] = lds_stack[lds_stack_bottom + i];
}

sptr += LDS_STACK_SIZE;
lds_sptr = lds_stack_bottom + 1;
}

lds_stack[lds_sptr++] = deferred;
}

continue;
}
}
else {
float t = fast_intersect_triangle(
myRay,
node.aabb_left_min_or_v0,
node.aabb_left_max_or_v1,
node.aabb_right_min_or_v2,
closest_t);

if (t < closest_t) {
closest_t = t;
closest_addr = addr;
}
}

addr = lds_stack[--lds_sptr];

if (addr == INVALID_ADDR && sptr > stack_bottom) {
sptr -= LDS_STACK_SIZE;
for (int i = 1; i < LDS_STACK_SIZE; ++i) {
lds_stack[lds_stack_bottom + i] = stack[sptr + i];
}

lds_sptr = lds_stack_bottom + LDS_STACK_SIZE - 1;
addr = lds_stack[lds_sptr];
}
}

#endif

#if 0
// TODO: what, why?!? (gboisse)
Intersection isect;
isect.padding.x = 667;
isect.padding.y = r.padding.x;
isect.uvwt = vec4(0.0f, 0.0f, 0.0f, closest_t);

#if 0

// Check if we have found an intersection
if (closest_addr != INVALID_ADDR)
{
// Calculate hit position
BvhNode node = Nodes[closest_addr];
vec3 p = myRay.o.xyz + closest_t * myRay.d.xyz;

// Calculate barycentric coordinates
isect.uvwt.xy = calculate_barycentrics(
p,
node.aabb_left_min_or_v0,
node.aabb_left_max_or_v1,
node.aabb_right_min_or_v2
);

// Update hit information
hit.prim_id = node.prim_id;
hit.shape_id = node.mesh_id;
}
else
#endif
{
// Miss here
isect.prim_id = -1;
isect.shape_id = -1;
}

// Write result to memory
Hits[index] = isect;
#endif
}

void occluded_main()
Expand Down

0 comments on commit 6b0c026

Please sign in to comment.