Commit 336213da authored by unknown's avatar unknown
Browse files

Cleanup, method-like glsl calls and benchmark presets

parent 219dcceb
assets/screenshots/render.png

972 KB | W: | H:

assets/screenshots/render.png

1.1 MB | W: | H:

assets/screenshots/render.png
assets/screenshots/render.png
assets/screenshots/render.png
assets/screenshots/render.png
  • 2-up
  • Swipe
  • Onion skin
#ifdef __GL_BVH
#define __GL_BVH
#include <raytracer/basic_structs.glh>
#include <raytracer/buffers.glh>
#include <raytracer/intersections.glh>
#include <raytracer/std.glh>
struct BVHNode
{
Bounds bounds;
uint type;
uint left_idx;
uint right_idx;
uint parent;
};
STD_BUFFER_R bvh_node_buffer
{
BVHNode b_bvh_nodes[];
};
//"Stackless" BVH-Traversal.
// See https://pdfs.semanticscholar.org/7e81/6b82fb92df08d7bc0d9805f8988754e0d8c1.pdf
bool traverse(const in Ray ray, inout Hit hit, const in bool nearest_only, const in float max_distance)
{
float t = 0;
float t_min = FLT_MAX;
// Check once the AABB for the whole scene
bool hit_scene = intersectsRayBounds(ray, b_bvh_nodes[0].bounds);
bool hit_triangle = false;
int current_node = 0;
int bitstack = 0;
//if (hit_scene){
while (hit_scene)
{
if (b_bvh_nodes[current_node].type == 0) //Inner node.
{
int id_left = int(b_bvh_nodes[current_node].left_idx);
bool hit_left = intersectsRayBounds(ray, b_bvh_nodes[id_left].bounds);
int id_right = int(b_bvh_nodes[current_node].right_idx);
bool hit_right = intersectsRayBounds(ray, b_bvh_nodes[id_right].bounds);
//both hit
if (hit_left && hit_right)
{
// shift bitstack and mark as branched, so we can use the marker
// when backtracking to stop here and use the right child.
bitstack = bitstack << 1;
current_node = id_left;
bitstack = bitstack | 1;
continue;
}
// only left hit
else if (hit_left && !hit_right)
{
// Not branching here, the other sibling-check won't be needed here.
bitstack = bitstack << 1;
current_node = id_left;
continue;
}
// only right hit
else if (!hit_left && hit_right)
{
// Not branching here, the other sibling-check won't be needed here.
bitstack = bitstack << 1;
current_node = id_right;
continue;
}
}
else
{
//Is leaf
// intersect ray with primitives.
//shorten ray if closer intersection found.
//intersect triangles
Triangle tri;
int start = int(b_bvh_nodes[current_node].left_idx);
int end = int(b_bvh_nodes[current_node].right_idx);
float u, v;
for (int i = start; i <= end; i++)
{
if (intersectsRayTriangle(ray, b_triangles[i], t, u, v))
{
if (t < t_min && t < max_distance) //test for ray_length
{
t_min = t;
hit_triangle = true;
//TODO: Hitparameter must be filled with information according to the ray-flag information
if (nearest_only)
{
return true;
}
hit.barycentric = vec3(u, v, 1 - u - v);
hit.triangle = i;
}
}
}
}
//Backtrace on bitstack until we find a branching point (where bit value is 1)
while ((bitstack & 1) == 0)
{
//Empty bitstack
if (bitstack == 0)
{
return hit_triangle;
}
current_node = int(b_bvh_nodes[current_node].parent);
bitstack = bitstack >> 1;
}
//Use other (right) sibling from the left child of the branched tree node.
current_node = int(b_bvh_nodes[b_bvh_nodes[current_node].parent].right_idx);
bitstack = bitstack ^ 1;
}
return hit_triangle;
}
bool bvh__nearestIntersection(const in Ray ray, inout Hit hit)
{
return traverse(ray, hit, false, FLT_MAX);
}
bool bvh__intersectsAny(const in Ray ray, const in float max_distance)
{
Hit unused_hit;
return traverse(ray, unused_hit, true, max_distance);
}
#endif //__GL_BVH
\ No newline at end of file
......@@ -12,11 +12,11 @@ Bounds getNodeBounds(int index, const in Mesh mesh)
return mesh.nodes[index].bounds;
}
bool bvh__traverse(const in Mesh mesh, const in Ray local_ray, const in bool use_first, const in float max_distance, inout Hit hit, inout float t_min)
bool traverseBVH(const in Mesh mesh, const in Ray local_ray, const in bool use_first, const in float max_distance, inout Hit hit, inout float t_min)
{
float t = 0;
// Check once the AABB for the whole scene
bool hit_scene = intersectsRayBounds(local_ray, getNodeBounds(0, mesh), max_distance);
bool hit_scene = local_ray.intersectsBounds(getNodeBounds(0, mesh), max_distance);
bool hit_triangle = false;
int current_node = 0;
......@@ -27,10 +27,10 @@ bool bvh__traverse(const in Mesh mesh, const in Ray local_ray, const in bool use
if (mesh.nodes[current_node].type == 0) //Inner node.
{
int id_left = int(mesh.nodes[current_node].left_idx);
bool hit_left = intersectsRayBounds(local_ray, getNodeBounds(id_left, mesh), max_distance);
bool hit_left = local_ray.intersectsBounds(getNodeBounds(id_left, mesh), max_distance);
int id_right = int(mesh.nodes[current_node].right_idx);
bool hit_right = intersectsRayBounds(local_ray, getNodeBounds(id_right, mesh), max_distance);
bool hit_right = local_ray.intersectsBounds(getNodeBounds(id_right, mesh), max_distance);
//both hit
if (hit_left && hit_right)
......@@ -71,7 +71,7 @@ bool bvh__traverse(const in Mesh mesh, const in Ray local_ray, const in bool use
float u, v;
for (int i = start; i <= end; i++)
{
if (intersectsRayTriangleMeshLocal(local_ray, i, mesh, t, u, v))
if (local_ray.intersectsTriangleLocal(i, mesh, t, u, v))
{
if (t < t_min && t < max_distance) //test for ray_length
{
......
......@@ -9,76 +9,19 @@ uniform bool u_use_ls;
#define USE_OBJECT_BVH true ||
//#define USE_OBJECT_BVH false &&
bool objectsTraverse(const in Ray ray, const in bool use_first, const in float max_distance, inout Hit hit, inout float t_min, bool force_bvh = false);
bool traverseObjects(const in Ray ray, const in bool use_first, const in float max_distance, inout Hit hit, inout float t_min, bool force_bvh = false);
bool nearestIntersection(const in Ray ray, inout Hit hit, bool force_bvh = false)
{
//if(USE_OBJECT_BVH b_meshes.length() < 20){
// #ifdef USE_OBJECT_BVH
/*float t_min = FLT_MAX;
return objectsTraverse(ray, false, FLT_MAX, hit, t_min, force_bvh);*/
// }
if(!force_bvh){
float current_t = FLT_MAX;
float min_t = FLT_MAX;
bool hits = false;
for (int i = 0; i < b_meshes.length(); ++i)
{
Mesh mesh = b_meshes[i];
hits = bool(int(hits) | int(ls__traverse(mesh, ray__makeMeshLocal(ray, mesh), false, current_t, hit, min_t)));
}
return hits;
}
else
{
float current_t = FLT_MAX;
float min_t = FLT_MAX;
bool hits = false;
for (int i = 0; i < b_meshes.length(); ++i)
{
Mesh mesh = b_meshes[i];
hits = bool(int(hits) | int(bvh__traverse(mesh, ray__makeMeshLocal(ray, mesh), false, current_t, hit, min_t)));
}
return hits;
}
// #endif
float t_min = FLT_MAX;
return traverseObjects(ray, false, FLT_MAX, hit, t_min, force_bvh);
}
bool intersectsAny(const in Ray ray, const in float max_distance, bool force_bvh = false)
{
// #ifdef USE_OBJECT_BVH
//if(USE_OBJECT_BVH b_meshes.length() < 20){
/*float t_min = max_distance;
Hit unused_hit;
return objectsTraverse(ray, true, max_distance, unused_hit, t_min, force_bvh);*/
// #else
//}
if(!force_bvh){
float t_min = max_distance;
Hit unused_hit;
float current_t = max_distance;
for (int i = 0; i < b_meshes.length(); ++i)
{
Mesh mesh = b_meshes[i];
if (ls__traverse(mesh, ray__makeMeshLocal(ray, mesh), true, max_distance, unused_hit, current_t))
return true;
}
return false;
}
else
{
Hit unused_hit;
float current_t = max_distance;
for (int i = 0; i < b_meshes.length(); ++i)
{
Mesh mesh = b_meshes[i];
if (bvh__traverse(mesh, ray__makeMeshLocal(ray, mesh), true, max_distance, unused_hit, current_t))
return true;
}
return false;
}
// #endif
return traverseObjects(ray, true, max_distance, unused_hit, t_min, force_bvh);
}
Bounds getObjectNodeBounds(int index)
......@@ -86,12 +29,12 @@ Bounds getObjectNodeBounds(int index)
return b_object_nodes[index].bounds;
}
bool objectsTraverse(const in Ray ray, const in bool use_first, const in float max_distance, inout Hit hit, inout float t_min, bool force_bvh = false)
bool traverseObjects(const in Ray ray, const in bool use_first, const in float max_distance, inout Hit hit, inout float t_min, bool force_bvh = false)
{
float t = t_min;
float max_dist = max_distance;
// Check once the AABB for the whole scene
bool hit_scene = intersectsRayBounds(ray, getObjectNodeBounds(0), max_distance);
bool hit_scene = ray.intersectsBounds(getObjectNodeBounds(0), max_distance);
bool hit_triangle = false;
int current_node = 0;
......@@ -102,10 +45,10 @@ bool objectsTraverse(const in Ray ray, const in bool use_first, const in float m
if (b_object_nodes[current_node].type == 0) //Inner node.
{
int id_left = int(b_object_nodes[current_node].left_idx);
bool hit_left = intersectsRayBounds(ray, getObjectNodeBounds(id_left), max_distance);
bool hit_left = ray.intersectsBounds(getObjectNodeBounds(id_left), max_distance);
int id_right = int(b_object_nodes[current_node].right_idx);
bool hit_right = intersectsRayBounds(ray, getObjectNodeBounds(id_right), max_distance);
bool hit_right = ray.intersectsBounds(getObjectNodeBounds(id_right), max_distance);
//both hit
if (hit_left && hit_right)
......@@ -149,7 +92,7 @@ bool objectsTraverse(const in Ray ray, const in bool use_first, const in float m
const Mesh mesh = b_meshes[b_object_ids[i]];
if(force_bvh)
{
if(bvh__traverse(mesh, ray__makeMeshLocal(ray, mesh), use_first, max_dist, hit, t_min)){
if(mesh.traverseBVH(ray.makeMeshLocal(mesh), use_first, t_min, hit, t_min)){
hit_triangle = true;
if (use_first)
{
......@@ -159,7 +102,7 @@ bool objectsTraverse(const in Ray ray, const in bool use_first, const in float m
}
else
{
if(ls__traverse(mesh, ray__makeMeshLocal(ray, mesh), use_first, max_dist, hit, t_min)){
if(mesh.traverseLineSpace(ray.makeMeshLocal(mesh), use_first, t_min, hit, t_min)){
hit_triangle = true;
if (use_first)
{
......
......@@ -114,7 +114,7 @@ uint ls__lineIndex(const in Ray ray, const in Mesh mesh, float tmin, float tmax,
return offset + start + end;
}
bool ls__traverse(const in Mesh mesh, const in Ray local_ray, const in bool use_first, const in float max_distance, inout Hit hit, inout float t_min)
bool traverseLineSpace(const in Mesh mesh, const in Ray local_ray, const in bool use_first, const in float max_distance, inout Hit hit, inout float t_min)
{
float tmin;
......@@ -125,7 +125,7 @@ bool ls__traverse(const in Mesh mesh, const in Ray local_ray, const in bool use_
Ray offset_ray = local_ray;
offset_ray.origin += local_ray.direction * 2*mesh.linespace.patch_size;
if(!intersectsRayBounds(offset_ray, mesh.linespace.bounds, tmin, tmax, face_tmin, face_tmax) || t_min <= tmin || tmin > max_distance)
if(!offset_ray.intersectsBounds(mesh.linespace.bounds, tmin, tmax, face_tmin, face_tmax) || t_min <= tmin || tmin > max_distance)
{
return false;
}
......
#ifndef __GL_ENVIRONMENT
#define __GL_ENVIRONMENT
uniform struct
{
samplerCube cubemap;
bool has;
vec4 color;
} u_environment;
vec4 environment__sample(const in vec3 direction)
{
return (u_environment.has ? texture(u_environment.cubemap, direction) : u_environment.color);
}
#endif //__GL_ENVIRONMENT
\ No newline at end of file
......@@ -8,7 +8,7 @@
#include <raytracer/buffers.glh>
#include <raytracer/utilities.glh>
#include <raytracer/random.glh>
#include <raytracer/camera.glh>
#include <raytracer/properties/camera.glh>
layout(local_size_variable) in;
......@@ -23,8 +23,8 @@ void resetImportance(int id);
void main()
{
int id = camera__invocation2D();
ivec2 target_size = camera__renderTargetSize();
int id = invocation2D();
ivec2 target_size = u_render_target.imageSize();
if (int(gl_GlobalInvocationID.x) >= target_size.x || int(gl_GlobalInvocationID.y) >= target_size.y)
return;
......@@ -36,13 +36,13 @@ void main()
void generate(int id)
{
b_traces[id].ray = camera__getRayFromPixel(vec2(gl_GlobalInvocationID.xy), settings.u_random_subpixel ? vec2(0, 0) : rand2D(random_seed + id));
b_traces[id].ray = u_camera.getRayFromPixel(vec2(gl_GlobalInvocationID.xy), settings.u_random_subpixel ? vec2(0, 0) : rand2D(random_seed + id));
}
void trace(int id)
{
b_traces[id].hit.invalidate();
bool intersects = nearestIntersection(b_traces[id].ray, b_traces[id].hit, true);
b_traces[id].hit.barycentric.x = mix(-1, b_traces[id].hit.barycentric.x, int(intersects));
}
void resetImportance(int id)
......
......@@ -7,7 +7,7 @@
#include <raytracer/buffers.glh>
#include <raytracer/random.glh>
#include <raytracer/utilities.glh>
#include <raytracer/camera.glh>
#include <raytracer/properties/camera.glh>
layout(rgba32f) uniform readonly image2D u_gbuffer_texture_01;
......@@ -25,12 +25,12 @@ void main()
if (id < b_traces.length())
{
ivec2 target_size = camera__renderTargetSize();
ivec2 target_size = u_render_target.imageSize();
vec2 pixel = vec2(id%target_size.x, id/target_size.x);
vec4 texel_01 = imageLoad(u_gbuffer_texture_01, ivec2(pixel));
vec4 texel_01 = u_gbuffer_texture_01.imageLoad(ivec2(pixel));
b_traces[id].ray = camera__getRayFromPixel(pixel, rand2D(random_seed + int(id)));
hit__invalidate(b_traces[id].hit);
b_traces[id].ray = u_camera.getRayFromPixel(pixel, rand2D(random_seed + int(id)));
b_traces[id].hit.invalidate();
if (length(texel_01) != 0) {
......
......@@ -5,7 +5,7 @@
#include <raytracer/buffers.glh>
#include <raytracer/utilities.glh>
bool intersectsRayBounds(const in Ray ray, const in Bounds bounds)
bool intersectsBounds(const in Ray ray, const in Bounds bounds)
{
vec3 dirfrac = 1.0f / ray.direction.xyz;
......@@ -32,7 +32,7 @@ int faceID(float t, float t1, float t2, float t3, float t4, float t5, float t6)
: 2)))); //pos_z
}
bool intersectsRayBounds(const in Ray ray, const in Bounds bounds, inout float tmin, inout float tmax, inout int face_tmin, inout int face_tmax)
bool intersectsBounds(const in Ray ray, const in Bounds bounds, inout float tmin, inout float tmax, inout int face_tmin, inout int face_tmax)
{
vec3 dirfrac = 1.0f / ray.direction.xyz;
......@@ -55,7 +55,7 @@ bool intersectsRayBounds(const in Ray ray, const in Bounds bounds, inout float t
return tmax >= 0 && tmin <= tmax;
}
bool intersectsRayBounds(const in Ray ray, const in Bounds bounds, const in float max_t)
bool intersectsBounds(const in Ray ray, const in Bounds bounds, const in float max_t)
{
vec3 dirfrac = 1.0f / ray.direction.xyz;
......@@ -73,7 +73,7 @@ bool intersectsRayBounds(const in Ray ray, const in Bounds bounds, const in floa
return tmax >= 0 && tmin <= tmax && tmin <= max_t;
}
bool intersectsRayTriangleMesh(const in Ray ray, int triangle_index, const in Mesh mesh, inout float t, inout float u, inout float v)
bool intersectsTriangle(const in Ray ray, int triangle_index, const in Mesh mesh, inout float t, inout float u, inout float v)
{
float EPSILON = FLT_EPSILON;
......@@ -127,7 +127,7 @@ bool intersectsRayTriangleMesh(const in Ray ray, int triangle_index, const in Me
return false;
}
bool intersectsRayTriangleMeshLocal(const in Ray ray, int triangle_index, const in Mesh mesh, inout float t, inout float u, inout float v)
bool intersectsTriangleLocal(const in Ray ray, int triangle_index, const in Mesh mesh, inout float t, inout float u, inout float v)
{
float EPSILON = FLT_EPSILON;
......@@ -181,255 +181,5 @@ bool intersectsRayTriangleMeshLocal(const in Ray ray, int triangle_index, const
return false;
}
bool deprecated_______intersectsTriangleBounds(const in Triangle tri, const in Bounds bounds)
{
// SAT: Separating Axis Theorem
// Two convex polyhedra A and B are disjoint, if they can be separated along either an axis parallel to a normal of a face of either A or B,
// or along an Axis formed from the cross product of an edge from A widh an edge from B.
// ------------------------------------------------------------------------------------------------------------------------------------------
// 1) Project triangle points on x, y and z min and max plane normals. Quit if disjoint.
// 2) Project AABB points on triangle normal. Quit if disjoint.
// ------------------------------------------------------------------------------------------------------------------------------------------
// Projection procedure: Calculate vector cp from plane center (eg x max = bounds.max-vec3(0, half[y], half[z])) to triangle point.
// Then check dot(cp, plane_normal) < 0.
vec3 triangle_corners[3] = { vec3(0), vec3(1), vec3(2) };
vec3 bounds_halfsize = bounds__size(bounds).xyz * 0.5f;
vec3 mid = bounds.min.xyz + bounds_halfsize;
vec3 mid_distances[3] = { (triangle_corners[0].xyz - mid), (triangle_corners[1].xyz - mid), (triangle_corners[2].xyz - mid) };
Bounds triangle_bounds;
bounds__expand(triangle_bounds, triangle_corners[0]);
bounds__expand(triangle_bounds, triangle_corners[1]);
bounds__expand(triangle_bounds, triangle_corners[2]);
vec3 bounds_size = bounds__size(triangle_bounds).xyz;
float max = compMax(bounds_size);
int largest_component = 0;
for (int i = 0; i < 3; i++)
{
if (max == bounds_size[i])
{
largest_component = i;
break;
}
}
if (triangle_corners[0][largest_component] < triangle_corners[1][largest_component])
swap(triangle_corners[0], triangle_corners[1]);
if (triangle_corners[1][largest_component] < triangle_corners[2][largest_component])
swap(triangle_corners[1], triangle_corners[2]);
if (triangle_corners[0][largest_component] < triangle_corners[1][largest_component])
swap(triangle_corners[0], triangle_corners[1]);
// --------------------------------------- NEEDED ----------------------------------------------------
float sidedness_max;
float sidedness_min;
int i;
// ---------------------------------------------------------------------------------------------------
// --------------------------------------- X AXIS ----------------------------------------------------
// Check separating min and max planes on x-plane
vec3 plane_max = bounds.max.xyz - vec3(0, bounds_halfsize[1], bounds_halfsize[2]);
vec3 plane_min = bounds.min.xyz + vec3(0, bounds_halfsize[1], bounds_halfsize[2]);
bool separate_min = true;
bool separate_max = true;
for (i = 0; i < 3; i++) {
sidedness_max = dot(triangle_corners[i].xyz - plane_max, vec3(1, 0, 0));
sidedness_min = dot(triangle_corners[i].xyz - plane_min, vec3(-1, 0, 0));
//separate is true, if all sidedness values are >1.
separate_max = separate_max && (sidedness_max > 0);
separate_min = separate_min && (sidedness_min > 0);
}
if (separate_min || separate_max)
return false;
// ---------------------------------------------------------------------------------------------------
// --------------------------------------- Y AXIS ----------------------------------------------------
// Check separating min and max planes on y-plane
plane_max = bounds.max.xyz - vec3(bounds_halfsize[0], 0, bounds_halfsize[2]);
plane_min = bounds.min.xyz + vec3(bounds_halfsize[0], 0, bounds_halfsize[2]);
separate_min = true;
separate_max = true;
for (i = 0; i < 3; i++) {
sidedness_max = dot(triangle_corners[i].xyz - plane_max, vec3(0, 1, 0));
sidedness_min = dot(triangle_corners[i].xyz - plane_min, vec3(0, -1, 0));
//separate is true, if all sidedness values are >1.
separate_max = separate_max && (sidedness_max > 0);
separate_min = separate_min && (sidedness_min > 0);
}
if (separate_min || separate_max)
return false;
// ---------------------------------------------------------------------------------------------------
// --------------------------------------- Z AXIS ----------------------------------------------------
// Check separating min and max planes on z-plane
plane_max = bounds.max.xyz - vec3(bounds_halfsize[0], bounds_halfsize[1], 0);
plane_min = bounds.min.xyz + vec3(bounds_halfsize[0], bounds_halfsize[1], 0);
separate_min = true;
separate_max = true;
for (i = 0; i < 3; i++) {
sidedness_max = dot(triangle_corners[i].xyz - plane_max, vec3(0, 0, 1));
sidedness_min = dot(triangle_corners[i].xyz - plane_min, vec3(0, 0, -1));
//separate is true, if all sidedness values are >1.
separate_max = separate_max && (sidedness_max > 0);
separate_min = separate_min && (sidedness_min > 0);
}
if (separate_min || separate_max)
return false;
// ---------------------------------------------------------------------------------------------------
// -------------------------------------- TRIANGLE ---------------------------------------------------
// Check separating from triangle
vec3 normal = cross(triangle_corners[1] - triangle_corners[0], triangle_corners[2] - triangle_corners[0]);
separate_min = true;
separate_max = true;
for (i = -1; i < 3; i++)
{
vec3 corner = bounds.min.xyz;
if (i >= 0)
{
corner[abs(i)] += -2 * bounds_halfsize[abs(i)];
}
sidedness_min = dot(corner - triangle_corners[0].xyz, normal);
separate_min = separate_min && (sidedness_min < 0);
separate_max = separate_max && (sidedness_min > 0);
}
for (i = -1; i < 3; i++)
{
vec3 corner = bounds.max.xyz;
if (i >= 0)
{
corner[abs(i)] += 2 * bounds_halfsize[abs(i)];
}
sidedness_min = dot(corner - triangle_corners[0].xyz, normal);
separate_min = separate_min && (sidedness_min < 0);
separate_max = separate_max && (sidedness_min > 0);
}
if (separate_min || separate_max)
return false;
// ---------------------------------------------------------------------------------------------------
return true;
}
int intersectsTriangleBounds(const in Triangle tri, const in Bounds bounds)
{
vec3 vertex0, vertex1, vertex2;
vec3 d = bounds__size(triangle__deconstruct(tri, vertex0, vertex1, vertex2)).xyz;
vec3 voxCenter = bounds.min.xyz + bounds__size(bounds).xyz*0.5f;
vec3 v0, v1, v2, e0, e1, e2, e0_abs, e1_abs, e2_abs;
float minValue, maxValue, p0, p1, p2, r;
v0 = vertex0 - voxCenter;
v1 = vertex1 - voxCenter;
v2 = vertex2 - voxCenter;
e0 = v1 - v0;
e1 = v2 - v1;
e2 = v0 - v2;
e0_abs = abs(e0);
// AXISTEST_x_e0
p0 = e0.z * v0.y - e0.y * v0.z;
p2 = e0.z * v2.y - e0.y * v2.z;
if (p0 < p2)
{
minValue = p0;
maxValue = p2;
}
else
{
minValue = p2;
maxValue = p0;
}
r = e0_abs.z * d.y + e0_abs.y * d.z;
if (minValue > r || maxValue < -r) return 1;
// AXISTEST_y_e0
p0 = -e0.z * v0.x + e0.x * v0.z;
p2 = -e0.z * v2.x + e0.x * v2.z;
if (p0 < p2)
{
minValue = p0;
maxValue = p2;
}
else
{
minValue = p2;
maxValue = p0;
}
r = e0_abs.z * d.x + e0_abs.x * d.z;
if (minValue > r || maxValue < -r) return 1;
e1_abs = abs(e1);