141

GitHub - VKoskiv/c-ray: C-Ray is a small, simple raytracer written in C

 6 years ago
source link: https://github.com/VKoskiv/c-ray
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

README.md

68747470733a2f2f692e696d6775722e636f6d2f665042754354472e706e67

Rendering with SDL installed

68747470733a2f2f6d656469612e67697068792e636f6d2f6d656469612f3863543644626f376b43693372526a3546722f67697068792e676966

Status

Build Status

Synopsis

C-Ray is a simple raytracer built for studying computer graphics. It's also a great platform for developing your own raytracing algorithms. Just write your own rayTrace() function! Multithreading, 3D model loading and render previews are handled by c-ray, so you can concentrate on the core principles.

C-Ray currently supports:

  • Real-time render preview using SDL
  • Easy scene compositing using JSON
  • Multithreading
  • OBJ loading with matrix transforms for compositing a scene
  • PNG and BMP file output
  • k-d tree acceleration structure for fast intersection checks even with millions of primitives
  • Antialiasing
  • Multi-sampling

The default recursive raytracing algorithm supports:

  • reflections
  • lights with radius (soft shadows)
  • triangles and spheres
  • blinn-phong lighting model
  • Depth of field
  • Refraction

Things I'm looking to implement:

  • Implement more robust material handling to support textures, and multiple materials for a single OBJ
  • Some procedural textures
  • Expand the default raytracer into a full path tracer
  • Expand the default raytracer to use PBR

Dependencies

  • SDL2 (Disabled by default. uncomment #define UI_ENABLED in includes.h:12 to enable it)
  • Standard C99/GNU99 with some standard libraries

All other libraries are included as source

Installation

macOS:

  1. Install SDL2 (See installing SDL below)
  2. Open the .xcodeproj file in Xcode
  3. Edit scheme by clicking C-Ray in top left, make sure 'Use custom working directory' is ticked and set it to the root directory of this project.
  4. Go into the Arguments tab, and add by clicking +. Type in ./input/scene.json, then click close
  5. Build&Run with CMD+R

Linux:

  1. (Optional) Install SDL2 (See installing SDL below)
  2. (Optional) Edit src/includes.h to uncomment #define UI_ENABLED
  3. Run make
  4. Suggest a fix to my makefile because it didn't link SDL2 on your platform.
  5. Run binary: ./bin/c-ray ./input/scene.json (Making sure the working dir is the root directory)

Windows:

  1. Open the VS project in CRayWindows
  2. (Optional) Edit src\includes.h to uncomment #define UI_ENABLED
  3. Build the project (You only need to do this once)
  4. VS places a binary under CRayWindows\bin\
  5. Open cmd and navigate to C:\path\to\c-ray
  6. Run >CRayWindows\x64\Release\CRayWindows.exe input\scene.json

Installing SDL

On macOS, download the SDL2 runtime framework from https://www.libsdl.org/download-2.0.php and place in /Library/Frameworks/

If you don't have root access, place under ~/Library/Frameworks

On Windows, Visual Studio should include SDL automatically

On Linux using APT, run sudo apt install libsdl2-dev

Writing your own raytracing algorithm

C-Ray is built such that a new raytracing algorithm can be a drop-in replacement. Here's some pointers on getting started.

Your custom raytracing function takes two parameters. A light ray, and a scene:

struct color rayTrace(struct lightRay *incidentRay, struct world *scene) It then returns a color corresponding to that pixel.

The renderThread in renderer.c runs on multiple threads, and sets up the light ray, and passes it to the function you write. This call happens at renderer.c:386

Note: Currently there are two default renderers. rayTrace() is the original algorithm I wrote starting in 2015, and newTrace() is a new recursive, more modular algorithm that I hope to expand into a full PBR path tracer eventually.

When writing your own algorithm, either replace one of the existing ones, or write your own into raytrace.c and edit the function call on renderer.c:386

Use the built-in intersection checks in your algorithm:

rayIntersectsWithNode() takes the kd-tree root of an OBJ, a lightRay, and an intersection struct. It returns true if intersected, and sets useful shading information into the given intersection struct. This function uses the kd-tree acceleration structure to minimize the amount of intersection checks.

If you do want to check for an intersection on a primitive (Without acceleration structure), use rayIntersectsWithPolygon(). It takes a lightRay, a poly, current t value, a surface normal and a UV coordinate. Returns true if intersected, and sets the surface normal and UV to the given pointers.

For spheres, we have similar functions: rayIntersectsWithSphere() takes a lightRay, a sphere and the current t value, and returns true if intersected.

rayIntersectsWithSphereTemp() is a newer function that sets shading information into a given intersection struct, just like intersectsWithNode. It uses rayIntersectsWithSphere internally.

Tests

You really thought I wrote tests...?

Credits

3rd party libraries included in this project

OBJ Loader library: http://www.kixor.net/dev/objloader/

lodePNG PNG compression library: http://lodev.org/lodepng/

SDL2: https://www.libsdl.org/index.php

JSON parsing library: https://github.com/DaveGamble/cJSON

Contributors

If you know more than me, please do get in touch at vkoskiv [at] gmail (dot) com!


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK