Skip to content

Commit

Permalink
Kind of working ray bundle marching
Browse files Browse the repository at this point in the history
  • Loading branch information
MichaelMoroz committed Aug 6, 2019
1 parent 3a588bc commit 55b9d99
Show file tree
Hide file tree
Showing 5 changed files with 161 additions and 71 deletions.
37 changes: 22 additions & 15 deletions game_folder/shaders/compute/main.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -3,19 +3,17 @@
#define bundle_size 4
#define bundle_length 16
#define bundle_center 8
#define group_size 4
#define block_size 16
#define group_size 8
#define block_size 64
#define MAX_MARCHES 128
#include<camera.glsl>

//4*4 bundle of ray bundles(oh lol)
layout(local_size_x = group_size, local_size_y = group_size) in;
layout(rgba8, binding = 0) uniform image2D img_output;

//make all the local ray bundle centers shared
shared vec3 ray_dir[block_size];
//positions and DE(.w)
shared vec4 ray_pos[block_size];
//make all the local distance estimator spheres shared
shared vec4 de_sph[block_size];

#include<ray_marching.glsl>

Expand All @@ -31,7 +29,8 @@ void main() {

//ray bundle array
vec4 pos[bundle_length];
vec3 dir[bundle_length];
vec4 dir[bundle_length];
vec4 var[bundle_length];

//initialize the ray bundle
for(int i = 0; i < bundle_length; i++)
Expand All @@ -40,20 +39,19 @@ void main() {
ivec2 pix = bundle_size*global_pos + getLPos(i);
ray rr = get_ray(vec2(pix)/vec2(imageSize(img_output)));
pos[i] = vec4(rr.pos,0);
dir[i] = rr.dir;
dir[i] = vec4(rr.dir,0);
var[i] = vec4(0);
}

//central ray
ray_pos[local_indx] = pos[bundle_center];
ray_dir[local_indx] = dir[bundle_center];
de_sph[local_indx] = pos[bundle_center];

memoryBarrierShared();

ray_bundle_marching(pos, dir, local_indx);
ray_bundle_marching1(pos, dir, var, local_indx);

/*for(int i = 0; i < bundle_length; i++)
{
ray_march(pos[i], dir[i]);
ray_march(pos[i], dir[i], var[i]);
}*/

// output to the specified image block
Expand All @@ -62,8 +60,17 @@ void main() {
ivec2 pix = bundle_size*global_pos + getLPos(i);
ray rr = get_ray(vec2(pix)/vec2(imageSize(img_output)));

float td = length(rr.pos - pos[i].xyz);
vec3 depth = 1.f - vec3(td,td,td)/10.f;
/* pos[i] = vec4(rr.pos,0);
dir[i] = vec4(rr.dir,0);
ray_march(pos[i], dir[i]);*/

float ao = (1 - var[i].x/MAX_MARCHES);
float td = (1 - dir[i].w*0.06f);
vec3 depth = vec3(td,td,td);
if(isinf(td))
{
depth = vec3(td,td,ao);
}

imageStore(img_output, pix, vec4(depth, 1));
}
Expand Down
4 changes: 2 additions & 2 deletions game_folder/shaders/compute/pipeline.cfg
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#shader name
main.glsl
#global size
width/16
height/16
width/32
height/32
#texture resolution
width
height
Expand Down
181 changes: 132 additions & 49 deletions game_folder/shaders/compute/ray_marching.glsl
Original file line number Diff line number Diff line change
@@ -1,46 +1,57 @@
#include<distance_estimators.glsl>

#define MAX_DIST 50
#define MIN_DIST 0.01
float FOVperPixel = 0.01;
#define MIN_DIST 0.001

void ray_march(inout vec4 pos, inout vec3 dir)

void ray_march(inout vec4 pos, inout vec4 dir, inout vec4 var, float fov = fovray)
{
//March the ray
pos.w = DE(pos.xyz);
float td = 0;
for (float s = 0; s < MAX_MARCHES; s += 1.0) {
float s = 0;
for (; s < 5; s += 1.0) {
//if the distance from the surface is less than the distance per pixel we stop
float min_dist = max(FOVperPixel*td, MIN_DIST);
if(td > MAX_DIST || pos.w < min_dist)
float min_dist = max(fov*dir.w, MIN_DIST);
if(dir.w > MAX_DIST || pos.w < min_dist)
{
break;
}
td += pos.w;
pos.xyz += pos.w*dir;
dir.w += pos.w;
pos.xyz += pos.w*dir.xyz;
pos.w = DE(pos.xyz);
}
var.x = s;
}


float sphere_intersection(vec3 r, vec3 p, vec4 sphere)
{
vec3 dp = sphere.xyz - p;
float b = dot(dp, r);
float c = sphere.w*sphere.w - dot(dp,dp);
float D = b*b + c;
if((D < 0) || (c < 0)) //if no intersection
{
return 0;
}
else
if(sphere.w > MIN_DIST && sphere.w < MAX_DIST)
{
return sqrt(D) + b; //use furthest solution in the direction of the ray
vec3 dp = sphere.xyz - p;
/*if(dp == vec3(0))
{
return sphere.w;
}*/

float b = dot(dp, r);
float c = sphere.w*sphere.w - dot(dp,dp);
float D = b*b + c;

if((D <= 0) || (c <= 0)) //if no intersection
{
return 0;
}
else
{
return sqrt(D) + b; //use furthest solution in the direction of the ray
}
}
return 0;
}
/*


/*
bool march_ray_bundle(ivec2 p)
{
int i = p.x, j = p.y;
Expand Down Expand Up @@ -70,7 +81,7 @@ bool march_ray_bundle(ivec2 p)
}
return false;
}*/

/*
vec4 find_furthest_DE_sphere(vec3 r, vec3 p)
{
float d = 0;
Expand All @@ -88,87 +99,159 @@ vec4 find_furthest_DE_sphere(vec3 r, vec3 p)
return desphere;
}
float find_furthest_DE_local(vec3 r, vec3 p, int id)
float find_furthest_DE_local(vec3 r, vec3 p, int id, float tr)
{
float d = 0;
ivec2 id2 = getGpos(id);
/*ivec2 id2 = getGpos(id);
ivec2 id11 = max(id2 - 1,0);
ivec2 id22 = min(id2 + 1,group_size);
//check through all of the local bundles
for(int i = id11.x; i < id22.x; i++)
{
for(int j = id11.y; j < id22.y; j++)
{
float this_d = sphere_intersection(r, p, ray_pos[i + group_size*j]);
d = max(this_d, d);
int index = i + group_size*j;
if(ray_pos[index].w < 2*tr)
d = max(sphere_intersection(r, p, ray_pos[index]), d);
}
}
d = max(sphere_intersection(r, p, ray_pos[id]), d);
return d;
}
float find_furthest_DE(vec3 r, vec3 p, int id)
{
float d = 0;
float tr = ray_pos[id].w;
//check through all of the local bundles
/*
for(int i = 0; i < block_size; i++)
{
memoryBarrierShared();
float this_d = sphere_intersection(r, p, ray_pos[i]);
d = max(this_d, d);
if(ray_pos[i].w < 2*tr)
d = max(sphere_intersection(r, p, ray_pos[i]), d);
}
*/
d = max(sphere_intersection(r, p, ray_pos[max(id-1, 0)]), d);
d = max(sphere_intersection(r, p, ray_pos[id]), d);
// d = max(sphere_intersection(r, p, ray_pos[id]), d);
return d;
}
void ray_bundle_marching(inout vec4 pos[bundle_length], inout vec3 dir[bundle_length], int id)
void ray_bundle_marching(inout vec4 pos[bundle_length], inout vec4 dir[bundle_length], int id)
{
float bundle_fov = bundle_size*fovray;
float td = 0;
float bundle_fov = 4*bundle_size*fovray;
float d = 0;
bool marching = true;

int l = 0;
for(int m = 0; (m < MAX_MARCHES) && marching; m++)
{
memoryBarrierShared();
ray_pos[id].w = DE(ray_pos[id].xyz);
memoryBarrierShared();
if(ray_pos[id].w < bundle_fov*td)
if(ray_pos[id].w < bundle_fov*ray_dir[id].w)
{
break;
marching = false;
//march the ray bundle
for(int i = 0; i < bundle_length; i++)
{
if(pos[i].w > fovray)
if(l == 0)
{
pos[i].xyz += dir[i].xyz*ray_dir[id].w;
pos[i].w = d;
dir[i].w = ray_dir[id].w;
}
if(pos[i].w > fovray*dir[i].w)
{
marching = true;
pos[i].w = find_furthest_DE_local(dir[i], pos[i].xyz, id);
d = find_furthest_DE_local(dir[i].xyz, pos[i].xyz, id, pos[i].w);
//if found a usable DE
if(pos[i].w > 0)
if(true || d == 0)
{
pos[i].xyz += dir[i]*pos[i].w;
pos[i].w = DE(pos[i].xyz);
pos[i].xyz += dir[i].xyz*pos[i].w;
dir[i].w += pos[i].w;
}
else //calculate a new DE
else
{
pos[i].w = DE(pos[i].xyz);
pos[i].xyz += dir[i]*pos[i].w;
pos[i].xyz += dir[i].xyz*d;
dir[i].w += d;
}
}
}
l++;
}
else if(ray_dir[id].w > MAX_DIST)
{
for(int i = 0; i < bundle_length; i++)
{
pos[i] = ray_pos[id];
dir[i] = ray_dir[id];
}
break;
}
else
{
d = find_furthest_DE(ray_dir[id], ray_pos[id].xyz, id);
d = find_furthest_DE_local(ray_dir[id].xyz, ray_pos[id].xyz, id, ray_pos[id].w);
memoryBarrierShared();
ray_pos[id].xyz += ray_dir[id]*d;
ray_dir[id].w += d;
ray_pos[id].xyz += ray_dir[id].xyz*d;
}
}
}
*/
void ray_bundle_marching1(inout vec4 pos[bundle_length], inout vec4 dir[bundle_length], inout vec4 var[bundle_length], int id)
{
bool marching = true;
float d = 0.f;

for(int i = 0; i < bundle_length; i++)
//march central ray while safe to do so(ray bundle within ray cone)
ray_march(pos[bundle_center], dir[bundle_center], var[bundle_center], fovray*bundle_size*4);

pos[bundle_center].w = 0;
for(int i = bundle_center+1; i < bundle_length+bundle_center; i++)
{
int ii = i%bundle_length;
pos[ii].xyz += dir[ii].xyz*dir[bundle_center].w;
dir[ii].w = dir[bundle_center].w;
var[ii] = var[bundle_center];
}

vec4 sphere = vec4(0);
for(int m = 0; (m < MAX_MARCHES) && marching; m++)
{
pos[i] = ray_pos[id];
marching = false;
sphere.w = 0;
for(int i = 0; i < bundle_length; i++)
{
if((dir[i].w > MAX_DIST || (pos[i].w < fovray*dir[i].w && pos[i].w > 0)) && dir[i].w > 0)
{
continue;
}
else
{
marching = true;
}


pos[i].xyz += dir[i].xyz*abs(pos[i].w);
dir[i].w += abs(pos[i].w);
var[i].x += 1.f;

memoryBarrierShared();
d = sphere_intersection(dir[i].xyz, pos[i].xyz, sphere);

if(d == 0)
{
pos[i].w = DE(pos[i].xyz);
if(sphere.w < pos[i].w)
{
sphere = pos[i];
}
}
else //if found a usable DE
{
pos[i].w = -d;
}
}
}
}
8 changes: 4 additions & 4 deletions src/Renderer.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -53,16 +53,16 @@ void Renderer::Initialize(int w, int h, std::string compute_folder)
LoadShader(shader_file);
break;
case 1:
global.x = parser.Evaluate(variables);
global.x = ceil(parser.Evaluate(variables));
break;
case 2:
global.y = parser.Evaluate(variables);
global.y = ceil(parser.Evaluate(variables));
break;
case 3:
tex_resolution.x = parser.Evaluate(variables);
tex_resolution.x = ceil(parser.Evaluate(variables));
break;
case 4:
tex_resolution.y = parser.Evaluate(variables);
tex_resolution.y = ceil(parser.Evaluate(variables));
break;
case 5:
int tnum = parser.Evaluate(variables);
Expand Down
2 changes: 1 addition & 1 deletion src/Shaders.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ void ComputeShader::LoadShader(const std::string file_path)
void ComputeShader::Run(vec2 global)
{
glUseProgram(ProgramID);
glDispatchCompute(global.x, global.y, 1);
glDispatchCompute(ceil(global.x), ceil(global.y), 1);
glMemoryBarrier(GL_SHADER_STORAGE_BARRIER_BIT);
}

Expand Down

0 comments on commit 55b9d99

Please sign in to comment.