-
Notifications
You must be signed in to change notification settings - Fork 124
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
210 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
COMPUTEFUNCTIONS | ||
INCLUDE helper_functions.glsl | ||
|
||
SHADER pathtracer | ||
COMPUTE | ||
LAYOUT 8 8 1 | ||
// texture unit 0: UAV albedo | ||
UNIFORMS texuavw0 | ||
UNIFORM uint frame_count | ||
UNIFORM uint frame_accum | ||
UNIFORM mat2x3 m_ray | ||
UNIFORM mat2x3 lens | ||
UNIFORM ivec2 window_size | ||
|
||
ivec2 iuv = ivec2(gl_GlobalInvocationID.xy); | ||
uvec2 uv = gl_GlobalInvocationID.xy; | ||
Ray cam = Ray(m_ray[0], m_ray[1]); | ||
uint seed = init_random_seed(uv, uint(frame_count)); | ||
|
||
vec3 cx = lens[0]; | ||
vec3 cy = lens[1]; | ||
|
||
float r1 = clamp(2.0 * random_float(seed), 0.0, 2.0); | ||
float dx = r1<1.0 ? sqrt(r1)-1.0 : 1.0-sqrt(2.0-r1); | ||
float r2 = clamp(2.0 * random_float(seed), 0.0, 2.0); | ||
float dy = r2<1.0 ? sqrt(r2)-1.0 : 1.0-sqrt(2.0-r2); | ||
vec3 d = cx*( ( (1.0 + dx)/2.0 + uv.x)/window_size.x - .5) + | ||
cy*( ( (1.0 + dy)/2.0 + uv.y)/window_size.y - .5) + cam.d; | ||
d = normalize(d); | ||
|
||
vec3 r = radiance(Ray(cam.o+d*140.0, d), 0); | ||
iuv.y = window_size.y - iuv.y - 1; | ||
imageStore(texuavw0, iuv, vec4(r, 1.0)); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,82 @@ | ||
/* translated from http://www.kevinbeason.com/smallpt/ | ||
and ported to glsl from smallpt.lobster | ||
Path tracer + accumulator | ||
*/ | ||
|
||
import vec | ||
import color | ||
import gl | ||
import texture | ||
|
||
//TODO: unified structs | ||
struct Ray: | ||
o:float3 | ||
d:float3 | ||
|
||
|
||
let rgba32f = texture_format_float | texture_format_clamp | texture_format_nomipmap | ||
|
||
let albedo_tex_format = rgba32f | ||
var last_window_size = int2{800, 600} | ||
fatal(gl.window("compute path tracer", last_window_size.x, last_window_size.y)) | ||
gl.require_version(4, 3) | ||
|
||
let pathtracer = read_file("custom_shader_pt.glsl") | ||
if pathtracer: | ||
fatal(gl.load_materials(pathtracer, true)) | ||
else: | ||
fatal("Could not find custom_shader_pt.glsl") | ||
|
||
let mats = | ||
""" | ||
SHADER screen | ||
VERTEX | ||
INPUTS apos:4 atc:2 | ||
UNIFORMS mvp | ||
gl_Position = mvp * apos; | ||
itc = atc; | ||
PIXEL | ||
INPUTS itc:2 | ||
UNIFORMS tex0 | ||
frag_color = texture(tex0, itc); | ||
""" | ||
|
||
fatal(gl.load_materials(mats, true)) | ||
var albedo_tex = gl.create_blank_texture(int3(last_window_size, 0), albedo_tex_format) | ||
var window_size_changed_last_frame = false | ||
var frame_count = 0 | ||
var frame_accum = 0 // for averaging | ||
|
||
let cam = Ray { float3 { 50.0,50.0,290.0 }, normalize(float3 { 0.0,-0.042612,-1.0 }) } // cam pos, dir | ||
// pack cam into 2x3 matrix | ||
let cam_vector = [cam.o.x, cam.o.y, cam.o.z, cam.d.x, cam.d.y, cam.d.z] | ||
|
||
var cx = float3_x * (last_window_size.x * .5135 / last_window_size.y) | ||
var cy = normalize(cx.cross(cam.d)) * .5135 | ||
var lens_matrix = [cx.x, cx.y, cx.z, cy.x, cy.y, cy.z] | ||
|
||
while(gl.frame()): | ||
if gl.button("escape") == 1: return | ||
window_size_changed_last_frame = last_window_size != gl.window_size() | ||
last_window_size = gl.window_size() | ||
++frame_count | ||
++frame_accum | ||
if window_size_changed_last_frame: | ||
albedo_tex = gl.create_blank_texture(int3(last_window_size, 0), albedo_tex_format) | ||
frame_accum = 0 | ||
cx = float3_x * (last_window_size.x * .5135 / last_window_size.y) | ||
cy = normalize(cx.cross(cam.d)) * .5135 | ||
lens_matrix = [cx.x, cx.y, cx.z, cy.x, cy.y, cy.z] | ||
gl.set_shader("pathtracer") | ||
gl.set_uniform("frame_count", frame_count) | ||
gl.set_uniform("frame_accum", frame_accum) | ||
gl.set_uniform_matrix("m_ray", cam_vector, true) | ||
gl.set_uniform_matrix("lens", lens_matrix, true) | ||
gl.set_uniform("window_size", last_window_size) | ||
gl.set_image_texture(0, albedo_tex, 0, texture_format_writeonly) | ||
let groups = (last_window_size + 7) / 8 | ||
gl.dispatch_compute(int3(groups, 1)) | ||
gl.blend(blend_none) | ||
gl.set_shader("screen") | ||
gl.set_primitive_texture(0, albedo_tex) | ||
gl.rect(float(gl.window_size())) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
|
||
const uint DIFF = 0; | ||
const uint SPEC = 1; | ||
const uint REFR = 2; | ||
|
||
struct Ray { | ||
vec3 o; | ||
vec3 d; | ||
}; | ||
|
||
struct Sphere { | ||
float rad; // radius | ||
vec3 p; // position | ||
vec3 e; // emission | ||
vec3 c; // color | ||
uint refl; // Material | ||
}; | ||
|
||
// Wang Hash Function | ||
uint wang_hash(uint seed) | ||
{ | ||
seed = (seed ^ 61u) ^ (seed >> 16u); | ||
seed *= 9u; | ||
seed = seed ^ (seed >> 4u); | ||
seed *= 0x27d4eb2du; | ||
seed = seed ^ (seed >> 15u); | ||
return seed; | ||
} | ||
|
||
// Function to initialize the random seed | ||
uint init_random_seed(uvec2 pixel_coords, uint frame_number) | ||
{ | ||
uint seed = pixel_coords.x + pixel_coords.y * 12345u + frame_number * 6789u; | ||
return wang_hash(seed); | ||
} | ||
|
||
// XorShift RNG | ||
uint xorshift32(inout uint state) | ||
{ | ||
if (state == 0) state = 1; | ||
state ^= state << 13u; | ||
state ^= state >> 17u; | ||
state ^= state << 5u; | ||
return state; | ||
} | ||
|
||
// Function to generate a random float between 0 and 1 | ||
float random_float(inout uint state) | ||
{ | ||
uint rnd = xorshift32(state); | ||
return rnd * 2.3283064365386963e-10f; // 1/2^32 | ||
} | ||
|
||
float intersect(Sphere s, Ray r) { | ||
vec3 op = s.p - r.o; // Solve t^2*d.d + 2*t*(o-p).d + (o-p).(o-p)-R^2 = 0 | ||
float eps = 0.0001; | ||
float b = dot(op, r.d); | ||
float det = b * b - dot(op, op) + s.rad * s.rad; | ||
if (det < 0.0) return 0.0; | ||
det = sqrt(det); | ||
float t = b - det; | ||
return t > eps ? t : (t = b + det) > eps ? t : 0.0; | ||
} | ||
|
||
const float bigrad = 1000.0; | ||
const float lrad = 100.0; | ||
|
||
const uint num_spheres = 9; | ||
const Sphere spheres[num_spheres] = Sphere[]( | ||
Sphere(50.0, vec3(50.0, lrad + 81.6 - 1.0, 81.6), vec3(12.0), vec3(0), DIFF), // Lite | ||
Sphere(16.5, vec3(73.0, 16.5, 78.0), vec3(0.0), vec3(0.999), REFR), // Glas | ||
Sphere(16.5, vec3(27.0, 16.5, 47.0), vec3(0.0), vec3(0.999), SPEC), // Mirr | ||
Sphere(bigrad, vec3(50.0, -bigrad + 81.6, 81.6), vec3(0.0), vec3(0.75), DIFF), // Top | ||
Sphere(bigrad, vec3(50.0, bigrad, 81.6), vec3(0.0), vec3(0.75), DIFF), // Botm | ||
Sphere(bigrad, vec3(50.0, 40.8, -bigrad + 170.0), vec3(0.0), vec3(0), DIFF), // Frnt | ||
Sphere(bigrad, vec3(50.0, 40.8, bigrad), vec3(0.0), vec3(0.75), DIFF), // Back | ||
Sphere(bigrad, vec3(-bigrad + 99.0, 40.8, 81.6), vec3(0.0), vec3(0.25, 0.25, 0.75), DIFF), // Rght | ||
Sphere(bigrad, vec3(bigrad + 1.0, 40.8, 81.6), vec3(0.0), vec3(0.75, 0.25, 0.25), DIFF) // Left | ||
); | ||
|
||
|
||
vec3 radiance(Ray r, uint depth) { | ||
float t = 1000000000000.0; // distance to intersection | ||
int id = -1; // id of intersected object | ||
for (int i = 0; i < num_spheres; ++i) { | ||
float d = intersect(spheres[i], r); | ||
if (d > 0.0 && d < t) { | ||
t = d; | ||
id = i; | ||
} | ||
} | ||
if (id == -1) return vec3(0.0); // if miss, return black | ||
return spheres[id].c; // the hit object | ||
// return vec3(1.0); // the hit object | ||
} |