diff options
author | Aiden Gall <aiden@aidengall.xyz> | 2024-02-04 23:16:23 +0000 |
---|---|---|
committer | Aiden Gall <aiden@aidengall.xyz> | 2024-02-04 23:16:23 +0000 |
commit | 27279a4e8db5f7d0e8d1f260cbe6190af92b2e67 (patch) | |
tree | 322631488b3232dd9010682d7d80d8ce2987a3c9 | |
parent | c0fb8bf2d8e25308eadff659564ad9600e5cb369 (diff) |
draw normal shaded sphere
-rw-r--r-- | src/cl/spirt.cl | 75 | ||||
-rw-r--r-- | src/spirt.c | 2 |
2 files changed, 61 insertions, 16 deletions
diff --git a/src/cl/spirt.cl b/src/cl/spirt.cl index 26bdf00..e037a38 100644 --- a/src/cl/spirt.cl +++ b/src/cl/spirt.cl @@ -13,12 +13,27 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#define RAY_ORIG(RAYS, INDEX) (RAYS[INDEX]) -#define RAY_DIR(RAYS, INDEX) (RAYS[INDEX + 1]) +struct ray { + float3 orig; + float3 dir; +}; + +static float3 +at(const struct ray ray, const float t) +{ + return ray.orig + ray.dir * t; +} + +static float +length_squared(const float3 v) +{ + return v.x * v.x + v.y * v.y + v.z * v.z; +} __kernel void -gen_rays(__global float3 *const rays, float3 camera_centre, - float3 pixel_delta_u, float3 pixel_delta_v, float3 corner00) +gen_rays(__global float3 *const rays, const float3 camera_centre, + const float3 pixel_delta_u, const float3 pixel_delta_v, + const float3 corner00) { size_t idx, w, i, j; @@ -29,18 +44,37 @@ gen_rays(__global float3 *const rays, float3 camera_centre, idx = (w * j + i) * 2; - RAY_ORIG(rays, idx) = camera_centre; - RAY_DIR(rays, idx) = corner00 + - ((i * pixel_delta_u) + (j * pixel_delta_v)) - - camera_centre; + rays[idx] = camera_centre; + rays[idx + 1] = corner00 + ((i * pixel_delta_u) + (j * pixel_delta_v)) - + camera_centre; +} + +static float +hit_sphere(const float3 center, const float radius, const struct ray ray) +{ + float3 oc; + float a, half_b, c, disc; + + oc = ray.orig - center; + a = length_squared(ray.dir); + half_b = dot(oc, ray.dir); + c = length_squared(oc) - radius * radius; + disc = half_b * half_b - a * c; + + if (disc < 0.0f) + return -1.0f; + + return (-half_b - sqrt(disc)) / a; } __kernel void -ray_colour(__global uchar *const canvas, __global float3 *const rays) +ray_colour(__global uchar *const canvas, __global const float3 *const rays) { + struct ray ray; + size_t canvas_idx, ray_idx, w, i, j; - float3 unit_direction, colour; - float a; + float3 colour; + float t; w = get_global_size(0); @@ -50,10 +84,23 @@ ray_colour(__global uchar *const canvas, __global float3 *const rays) canvas_idx = (w * j + i) * 4; ray_idx = (w * j + i) * 2; - unit_direction = normalize(RAY_DIR(rays, ray_idx)); - a = 0.5f * (unit_direction.y + 1.0f); + ray.orig = rays[ray_idx]; + ray.dir = rays[ray_idx + 1]; + + t = hit_sphere((float3)(0.0f, 0.0f, -1.0f), 0.5f, ray); + + if (t > 0.0) { + colour = 0.5f * + (normalize(at(ray, t) - (float3)(0.0f, 0.0f, -1.0f)) + + 1.0f); + } else { + float3 unit_direction; + float a; - colour = (1.0f - a) * (float3)(1.0f) + a * (float3)(0.5f, 0.7f, 1.0f); + unit_direction = normalize(ray.dir); + a = 0.5f * (unit_direction.y + 1.0f); + colour = (1.0f - a) * 1.0f + a * (float3)(0.5f, 0.7f, 1.0f); + } colour = 256.0f * clamp(sqrt(colour), 0.0f, 0.999f); canvas[canvas_idx] = colour.x; diff --git a/src/spirt.c b/src/spirt.c index 527981f..f9c6420 100644 --- a/src/spirt.c +++ b/src/spirt.c @@ -302,8 +302,6 @@ main(int argc, char *argv[]) img.format = PIXELFORMAT_UNCOMPRESSED_R8G8B8A8; img.mipmaps = 1; - clFlush(runtime.command_queue); - InitWindow(opts.width, opts.height, "spirt"); SetTargetFPS(60); |