intersecting triangles on cpu
This commit is contained in:
parent
9c4c59e073
commit
6603f27c90
@ -56,8 +56,10 @@ rl_window_loop :: proc() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
main :: proc() {
|
main :: proc() {
|
||||||
|
rl.SetTraceLogLevel(rl.TraceLogLevel.ERROR)
|
||||||
|
|
||||||
// Fill pixelbuffer with raytraced image.
|
// Fill pixelbuffer with raytraced image.
|
||||||
|
|
||||||
rayt_cpu_main()
|
rayt_cpu_main()
|
||||||
|
|
||||||
fmt.println("Finished raytracing, launching Raylib window")
|
fmt.println("Finished raytracing, launching Raylib window")
|
||||||
|
|||||||
@ -2,6 +2,8 @@ package main
|
|||||||
|
|
||||||
import "core:fmt"
|
import "core:fmt"
|
||||||
import "core:math/rand"
|
import "core:math/rand"
|
||||||
|
import "core:math/linalg"
|
||||||
|
import "core:math"
|
||||||
|
|
||||||
RAND_SEED :: 1984
|
RAND_SEED :: 1984
|
||||||
|
|
||||||
@ -13,6 +15,11 @@ MAX_NUM_ENTITIES :: 64
|
|||||||
|
|
||||||
Vec3 :: distinct [3]f32
|
Vec3 :: distinct [3]f32
|
||||||
|
|
||||||
|
// Global colors
|
||||||
|
COLOR_LIGHT_BLUE :: Vec3{0.5, 0.7, 1.0}
|
||||||
|
COLOR_WHITE :: Vec3{1.0, 1.0, 1.0}
|
||||||
|
|
||||||
|
|
||||||
Image :: struct {
|
Image :: struct {
|
||||||
width : u32,
|
width : u32,
|
||||||
height : u32,
|
height : u32,
|
||||||
@ -41,6 +48,11 @@ Viewport :: struct {
|
|||||||
}
|
}
|
||||||
viewport: Viewport
|
viewport: Viewport
|
||||||
|
|
||||||
|
Ray :: struct {
|
||||||
|
origin : Vec3,
|
||||||
|
direction : Vec3
|
||||||
|
}
|
||||||
|
|
||||||
HitRecord :: struct {
|
HitRecord :: struct {
|
||||||
point : Vec3,
|
point : Vec3,
|
||||||
normal : Vec3,
|
normal : Vec3,
|
||||||
@ -69,6 +81,21 @@ vec3_rand_uniform :: proc() -> Vec3 {
|
|||||||
return Vec3{rand.float32(), rand.float32(), rand.float32()}
|
return Vec3{rand.float32(), rand.float32(), rand.float32()}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ray_get :: proc(x : f32, y : f32) -> Ray {
|
||||||
|
out : Ray
|
||||||
|
|
||||||
|
px_u := x*viewport.pixel_delta_u
|
||||||
|
px_v := y*viewport.pixel_delta_v
|
||||||
|
pixel_center := viewport.pixel_origin + px_u + px_v
|
||||||
|
|
||||||
|
ray_direction := pixel_center - camera.center
|
||||||
|
|
||||||
|
out.direction = ray_direction
|
||||||
|
out.origin = camera.center
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
rayt_cpu_main :: proc() {
|
rayt_cpu_main :: proc() {
|
||||||
rand.reset(RAND_SEED)
|
rand.reset(RAND_SEED)
|
||||||
|
|
||||||
@ -129,21 +156,8 @@ rayt_cpu_main :: proc() {
|
|||||||
pixelbuffer = make([]Vec3, num_pixels);
|
pixelbuffer = make([]Vec3, num_pixels);
|
||||||
pixelbuffer_rgb = make([]u8, num_pixels * 3) // rgb values for each pixel
|
pixelbuffer_rgb = make([]u8, num_pixels * 3) // rgb values for each pixel
|
||||||
|
|
||||||
// Temp fill pixels
|
fmt.println("Starting CPU raytracing")
|
||||||
{
|
cpu_raytracing()
|
||||||
for x in 0..<image.width {
|
|
||||||
for y in 0..<image.height {
|
|
||||||
pixel_idx := y * image.width + x
|
|
||||||
|
|
||||||
x_val := cast(f32)x/cast(f32)image.width
|
|
||||||
y_val := cast(f32)y/cast(f32)image.height
|
|
||||||
pixelbuffer[pixel_idx] = Vec3{x_val, y_val, 0.0}
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// Translate pixelbuffer with colors from 0 to 1, to rgb 0..255
|
// Translate pixelbuffer with colors from 0 to 1, to rgb 0..255
|
||||||
{
|
{
|
||||||
@ -159,8 +173,123 @@ rayt_cpu_main :: proc() {
|
|||||||
pixelbuffer_rgb[rgb_idx + 1] = u8(255.999 * g)
|
pixelbuffer_rgb[rgb_idx + 1] = u8(255.999 * g)
|
||||||
pixelbuffer_rgb[rgb_idx + 2] = u8(255.999 * b)
|
pixelbuffer_rgb[rgb_idx + 2] = u8(255.999 * b)
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
vec3_lerp :: proc(s : f32, a : Vec3, b : Vec3) -> Vec3 {
|
||||||
|
return (1.0-s)*a + s*b
|
||||||
|
}
|
||||||
|
|
||||||
|
ray_point :: proc(t : f32, ray : ^Ray) -> Vec3 {
|
||||||
|
out : Vec3
|
||||||
|
out = ray.origin + t * ray.direction
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
triangle_intersection :: proc(ray : ^Ray, rec : ^HitRecord, triangle : ^Entity) {
|
||||||
|
edge1 := triangle.v1-triangle.v0
|
||||||
|
edge2 := triangle.v2-triangle.v0
|
||||||
|
rec.hit = false
|
||||||
|
|
||||||
|
// Moller-Trumbore intersection algorithm
|
||||||
|
{
|
||||||
|
h := linalg.cross(ray.direction, edge2)
|
||||||
|
closest_so_far : f32 = rec.t
|
||||||
|
a := linalg.dot(edge1, h)
|
||||||
|
|
||||||
|
if a <= -0.001 || a >= 0.001 {
|
||||||
|
f := 1.0/a
|
||||||
|
s := ray.origin-triangle.v0
|
||||||
|
u := f * linalg.dot(s, h)
|
||||||
|
if u >= 0.0 && u <= 1.0 {
|
||||||
|
q := linalg.cross(s, edge1)
|
||||||
|
v := f * linalg.dot(ray.direction, q)
|
||||||
|
if v >= 0.0 && (u + v) <= 1.0 {
|
||||||
|
t := f * linalg.dot(edge2, q)
|
||||||
|
if t > 0.0001 && t <= closest_so_far {
|
||||||
|
rec.hit = true
|
||||||
|
rec.t = t
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if rec.hit {
|
||||||
|
intersection_point := ray_point(rec.t, ray)
|
||||||
|
v0_normal := linalg.cross(edge1, edge2)
|
||||||
|
v0_normal = linalg.normalize(v0_normal)
|
||||||
|
|
||||||
|
front_face := linalg.dot(ray.direction, v0_normal) < 0.0
|
||||||
|
if front_face {
|
||||||
|
rec.normal = v0_normal
|
||||||
|
} else {
|
||||||
|
rec.normal = -1.0*v0_normal
|
||||||
|
}
|
||||||
|
rec.point = intersection_point
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
cpu_raytracing :: proc() {
|
||||||
|
|
||||||
|
num_hits : u32 = 0
|
||||||
|
last_ray : Ray
|
||||||
|
// Temp fill pixels
|
||||||
|
{
|
||||||
|
|
||||||
|
hit_rec : HitRecord
|
||||||
|
for x in 0..<image.width {
|
||||||
|
for y in 0..<image.height {
|
||||||
|
pixel_idx := y * image.width + x
|
||||||
|
|
||||||
|
sample_pixel_color : Vec3
|
||||||
|
ray := ray_get(cast(f32)x, cast(f32)y)
|
||||||
|
|
||||||
|
|
||||||
|
hit_rec.hit = false
|
||||||
|
hit_rec.t = math.F32_MAX
|
||||||
|
temp_hit_rec : HitRecord
|
||||||
|
temp_hit_rec.hit = false
|
||||||
|
temp_hit_rec.t = hit_rec.t
|
||||||
|
for i in 0..<MAX_NUM_ENTITIES {
|
||||||
|
tri_ref := &entities[i]
|
||||||
|
triangle_intersection(&ray, &temp_hit_rec, tri_ref)
|
||||||
|
if temp_hit_rec.hit {
|
||||||
|
hit_rec.hit = true
|
||||||
|
hit_rec.t = temp_hit_rec.t
|
||||||
|
hit_rec.normal = temp_hit_rec.normal
|
||||||
|
num_hits += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if hit_rec.hit {
|
||||||
|
// Color triangle
|
||||||
|
sample_pixel_color = 0.5*(hit_rec.normal + COLOR_WHITE)
|
||||||
|
} else {
|
||||||
|
// Background gradient
|
||||||
|
unit_dir := linalg.normalize(ray.direction)
|
||||||
|
|
||||||
|
blend : f32 = 0.5*(unit_dir.y + 1.0)
|
||||||
|
|
||||||
|
sample_pixel_color = vec3_lerp(blend, COLOR_WHITE, COLOR_LIGHT_BLUE)
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pixelbuffer[pixel_idx] = sample_pixel_color
|
||||||
|
last_ray = ray
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//fmt.printf("Num hits on triangles: %i \n", num_hits)
|
||||||
|
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue
Block a user