Randomise scene
This commit is contained in:
67
demo.c
67
demo.c
@@ -7,40 +7,71 @@
|
|||||||
|
|
||||||
#define W 800
|
#define W 800
|
||||||
#define H 600
|
#define H 600
|
||||||
|
|
||||||
|
#define OBJ_COUNT 32
|
||||||
|
|
||||||
|
#define MAX_DIST 100.0
|
||||||
|
#define MAX_RAD 10.0
|
||||||
|
#define MIN_RAD 1.0
|
||||||
|
|
||||||
#define FOV 90
|
#define FOV 90
|
||||||
#define SAMPLES_PER_PIXEL 100
|
#define SAMPLES_PER_PIXEL 100
|
||||||
|
|
||||||
#define NELEMS(arr) (sizeof(arr) / sizeof(arr[0]))
|
static const vec3_t camera_pos = { -100.0, 25.0, -100.0 };
|
||||||
|
static const vec3_t target = { 0.0, 0.0, 0.0 };
|
||||||
static const vec3_t camera_pos = { 0.0, 1.5, -2.0 };
|
|
||||||
static const vec3_t camera_target = { 0.0, 1.0, 1.0 };
|
|
||||||
|
|
||||||
static const vec3_t sky = { 0.6, 0.7, 1.0 };
|
static const vec3_t sky = { 0.6, 0.7, 1.0 };
|
||||||
|
|
||||||
static const obj_t objs[] = {
|
static const material_t floor = LAMBERTIAN(1.0, 0.94, 0.80);
|
||||||
SPHERE(1.0, 1.0, 3.0, 1.0, LAMBERTIAN(0.6, 0.2, 0.8)),
|
static const material_t gold = REFLECTIVE(1.0, 0.9, 0.5, 0.0);
|
||||||
SPHERE(-0.8, 1.0, 3.8, 1.0, LAMBERTIAN(1.0, 1.0, 1.0)),
|
static const material_t silver = REFLECTIVE(0.9, 0.9, 0.9, 0.0);
|
||||||
SPHERE(-1.0, 0.2, 2.6, 0.2, LAMBERTIAN(0.2, 0.9, 0.3)),
|
static const material_t bronze = REFLECTIVE(0.9, 0.7, 0.5, 0.0);
|
||||||
SPHERE(0.3, 0.3, 1.8, 0.3, LAMBERTIAN(0.9, 0.6, 0.2)),
|
static const material_t glass = DIELECTRIC(1.5);
|
||||||
SPHERE(-1.6, 0.2, 2.0, 0.2, REFLECTIVE(1.0, 0.9, 0.4, 0.0)),
|
|
||||||
SPHERE(-6.0, 6.0, 5.0, 6.0, REFLECTIVE(0.9, 0.9, 0.9, 0.05)),
|
static const material_t metals[] = { gold, silver, bronze };
|
||||||
SPHERE(-0.7, 0.25, 1.5, 0.25, DIELECTRIC(1.5)),
|
|
||||||
SPHERE(0.0, -1000.0, 0.0, 1000.0, LAMBERTIAN(0.3, 0.3, 0.3)),
|
static obj_t objs[OBJ_COUNT] = {
|
||||||
|
[0] = SPHERE(0.0, -100000.0, 0.0, 100000.0, floor),
|
||||||
};
|
};
|
||||||
|
|
||||||
static pix_t pixbuf[W * H];
|
static pix_t pixbuf[W * H];
|
||||||
|
|
||||||
|
static void rand_obj(obj_t *out, rng_t *rng)
|
||||||
|
{
|
||||||
|
material_t material;
|
||||||
|
const uint32_t rand = rng_uint32(rng);
|
||||||
|
if (rand % 2 == 0) {
|
||||||
|
const double r = rng_canon(rng);
|
||||||
|
const double g = rng_canon(rng);
|
||||||
|
const double b = rng_canon(rng);
|
||||||
|
material = (material_t)LAMBERTIAN(r, g, b);
|
||||||
|
} else if (rand % 3 == 0) {
|
||||||
|
material = glass;
|
||||||
|
} else {
|
||||||
|
material = metals[rng_uint32(rng) % 3];
|
||||||
|
}
|
||||||
|
|
||||||
|
const double r = MIN_RAD + (MAX_RAD - MIN_RAD) * rng_canon(rng);
|
||||||
|
const double x = MAX_DIST * rng_disc(rng);
|
||||||
|
const double z = MAX_DIST * rng_disc(rng);
|
||||||
|
*out = (obj_t)SPHERE(x, r, z, r, material);
|
||||||
|
}
|
||||||
|
|
||||||
int main()
|
int main()
|
||||||
{
|
{
|
||||||
|
rng_t rng = rng_init(0);
|
||||||
|
for (int i = 1; i < OBJ_COUNT; ++i)
|
||||||
|
rand_obj(objs + i, &rng);
|
||||||
|
|
||||||
|
img_t img = { .pix = pixbuf };
|
||||||
|
camera_t camera
|
||||||
|
= camera_init(camera_pos, target, FOV, W, H, SAMPLES_PER_PIXEL);
|
||||||
|
|
||||||
const scene_t scene = {
|
const scene_t scene = {
|
||||||
.sky_colour = sky,
|
.sky_colour = sky,
|
||||||
.objs = objs,
|
.objs = objs,
|
||||||
.obj_count = NELEMS(objs),
|
.obj_count = OBJ_COUNT,
|
||||||
};
|
};
|
||||||
|
|
||||||
img_t img = { .pix = pixbuf };
|
|
||||||
camera_t camera = camera_init(
|
|
||||||
camera_pos, camera_target, FOV, W, H, SAMPLES_PER_PIXEL);
|
|
||||||
camera_render(&camera, &scene, &img);
|
camera_render(&camera, &scene, &img);
|
||||||
|
|
||||||
ff_write(STDOUT_FILENO, img);
|
ff_write(STDOUT_FILENO, img);
|
||||||
|
|||||||
@@ -10,7 +10,9 @@ typedef struct {
|
|||||||
} rng_t;
|
} rng_t;
|
||||||
|
|
||||||
rng_t rng_init(unsigned seed);
|
rng_t rng_init(unsigned seed);
|
||||||
|
uint32_t rng_uint32(rng_t *rng);
|
||||||
double rng_canon(rng_t *rng);
|
double rng_canon(rng_t *rng);
|
||||||
|
double rng_disc(rng_t *rng);
|
||||||
vec3_t rng_vec3(rng_t *rng);
|
vec3_t rng_vec3(rng_t *rng);
|
||||||
vec3_t rng_gaussian_xy(rng_t *rng, double stddev);
|
vec3_t rng_gaussian_xy(rng_t *rng, double stddev);
|
||||||
|
|
||||||
|
|||||||
30
src/rng.c
30
src/rng.c
@@ -9,7 +9,14 @@
|
|||||||
#define M_PI 3.14159265258979323846264
|
#define M_PI 3.14159265258979323846264
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static uint32_t next(rng_t *rng)
|
rng_t rng_init(unsigned seed)
|
||||||
|
{
|
||||||
|
struct timeval tv;
|
||||||
|
gettimeofday(&tv, nullptr);
|
||||||
|
return (rng_t) { .state = tv.tv_usec + seed };
|
||||||
|
}
|
||||||
|
|
||||||
|
uint32_t rng_uint32(rng_t *rng)
|
||||||
{
|
{
|
||||||
uint32_t x = rng->state;
|
uint32_t x = rng->state;
|
||||||
x ^= x << 13;
|
x ^= x << 13;
|
||||||
@@ -18,26 +25,19 @@ static uint32_t next(rng_t *rng)
|
|||||||
return rng->state = x;
|
return rng->state = x;
|
||||||
}
|
}
|
||||||
|
|
||||||
static double disc(rng_t *rng)
|
double rng_canon(rng_t *rng)
|
||||||
|
{
|
||||||
|
return (double)rng_uint32(rng) / (double)UINT32_MAX;
|
||||||
|
}
|
||||||
|
|
||||||
|
double rng_disc(rng_t *rng)
|
||||||
{
|
{
|
||||||
return 2.0 * rng_canon(rng) - 1.0;
|
return 2.0 * rng_canon(rng) - 1.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
rng_t rng_init(unsigned seed)
|
|
||||||
{
|
|
||||||
struct timeval tv;
|
|
||||||
gettimeofday(&tv, nullptr);
|
|
||||||
return (rng_t) { .state = tv.tv_usec + seed };
|
|
||||||
}
|
|
||||||
|
|
||||||
double rng_canon(rng_t *rng)
|
|
||||||
{
|
|
||||||
return (double)next(rng) / (double)UINT32_MAX;
|
|
||||||
}
|
|
||||||
|
|
||||||
vec3_t rng_vec3(rng_t *rng)
|
vec3_t rng_vec3(rng_t *rng)
|
||||||
{
|
{
|
||||||
const vec3_t v = { disc(rng), disc(rng), disc(rng) };
|
const vec3_t v = { rng_disc(rng), rng_disc(rng), rng_disc(rng) };
|
||||||
return vec3_unit(v);
|
return vec3_unit(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user