Skip to content

Commit

Permalink
Initial smallpt commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Jaisiero committed Dec 28, 2024
1 parent 549c951 commit 513ef76
Show file tree
Hide file tree
Showing 3 changed files with 210 additions and 0 deletions.
33 changes: 33 additions & 0 deletions samples/demos/custom_shader_pt/custom_shader_pt.glsl
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));
82 changes: 82 additions & 0 deletions samples/demos/custom_shader_pt/custom_shader_pt.lobster
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()))
95 changes: 95 additions & 0 deletions samples/demos/custom_shader_pt/helper_functions.glsl
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
}

0 comments on commit 513ef76

Please sign in to comment.