aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdrian Kummerlaender2020-01-11 14:00:46 +0100
committerAdrian Kummerlaender2020-01-11 14:00:46 +0100
commitb189cb5ed36764bbb8ac9614ba14a2d330e654e0 (patch)
tree075f002989e40775ed8ea23668454d56d81cdb8c
parent1d4b7059aa969875dbd4904c8a6980afdb39f647 (diff)
downloadfirmament-b189cb5ed36764bbb8ac9614ba14a2d330e654e0.tar
firmament-b189cb5ed36764bbb8ac9614ba14a2d330e654e0.tar.gz
firmament-b189cb5ed36764bbb8ac9614ba14a2d330e654e0.tar.bz2
firmament-b189cb5ed36764bbb8ac9614ba14a2d330e654e0.tar.lz
firmament-b189cb5ed36764bbb8ac9614ba14a2d330e654e0.tar.xz
firmament-b189cb5ed36764bbb8ac9614ba14a2d330e654e0.tar.zst
firmament-b189cb5ed36764bbb8ac9614ba14a2d330e654e0.zip
Implement basic fish eye view
-rw-r--r--local_sunrise.py20
-rw-r--r--raymarch.cl62
2 files changed, 57 insertions, 25 deletions
diff --git a/local_sunrise.py b/local_sunrise.py
index 58ec73d..37cf17d 100644
--- a/local_sunrise.py
+++ b/local_sunrise.py
@@ -12,20 +12,22 @@ from planets import earth
from sun import sun_direction
from datetime import datetime
+fish_eye = True
+
config = {
- 'size_x': 1920//4,
- 'size_y': 1080//4,
+ 'size_x': 1000 if fish_eye else 1920//4,
+ 'size_y': 1000 if fish_eye else 1080//4,
'ray_samples' : 16,
'light_samples': 8,
- 'exposure': 2.0,
- 'zoom': 1.0,
+ 'exposure': 4.0,
+ 'zoom': 1.0, # only for pinhole view
'eye_pos': np.array([0, 0, 1.0001]),
- 'eye_dir': np.array([0, 1, 0]),
+ 'eye_dir': np.array([0, 1, 0]), # only for pinhole view
- 'date': (2020, 1, 10),
+ 'date': (2020, 1, 20),
'latitude': 49.01,
'longitude': 8.4
}
@@ -49,13 +51,13 @@ for time in np.arange(*time_range):
sun_dir = sun_direction(config['latitude'], config['longitude'], pit, 1.0)
sun = make_double3(
- np.sin(sun_dir[1])*np.cos(sun_dir[0]),
- np.cos(sun_dir[1])*np.cos(sun_dir[0]),
+ np.cos(sun_dir[0])*np.sin(sun_dir[1]),
+ np.cos(sun_dir[0])*np.cos(sun_dir[1]),
np.sin(sun_dir[0])
)
print(sun_dir)
- program.render(
+ (program.render_fisheye if fish_eye else program.render_pinhole)(
cl_queue, (config['size_x'], config['size_y']), None, cl_picture,
make_double3(*(config['eye_pos'] * earth['earth_radius'])),
make_double3(*(config['eye_dir'] * earth['earth_radius'])),
diff --git a/raymarch.cl b/raymarch.cl
index 6cde456..34ef8ed 100644
--- a/raymarch.cl
+++ b/raymarch.cl
@@ -52,20 +52,31 @@ bool solveRaySphereIntersection(double3 origin, double3 dir, double r, double* d
/// Map {0,...,screenX}x{0,...,screenY} to [-1,1]^2
double2 getNormalizedScreenPos(double x, double y) {
return (double2)(
- 2.0 * (x / $size_x - 0.5) * $size_x.0 / $size_y.0,
- 2.0 * (y / $size_y - 0.5)
+ 2.0 * (0.5 - x / $size_x) * $size_x.0 / $size_y.0,
+ 2.0 * (0.5 - y / $size_y)
);
}
/// Pinhole camera
double3 getEyeRayDir(double2 screen_pos, double3 eye_pos, double3 eye_target) {
const double3 forward = normalize(eye_target - eye_pos);
- const double3 right = normalize(cross((double3)(0.0, 0.0, 1.0), forward));
+ const double3 right = normalize(cross((double3)(0.0, 0.0, -1.0), forward));
const double3 up = normalize(cross(forward, right));
return normalize(screen_pos.x*right + screen_pos.y*up + $zoom*forward);
}
+/// Fisheye camera
+bool inFishEyeView(double2 screen_pos) {
+ return length(screen_pos) <= 1.0;
+}
+
+double3 getFishEyeRayDir(double2 screen_pos) {
+ const double phi = atan2(screen_pos.y, screen_pos.x);
+ const double theta = acos(1.0 - (screen_pos.x*screen_pos.x + screen_pos.y*screen_pos.y));
+ return (double3)(sin(theta)*cos(phi), sin(theta)*sin(phi), cos(theta));
+}
+
/// Return true iff earth is hit by rays along dir
bool isVisible(double3 origin, double3 dir) {
double e0, e1;
@@ -140,16 +151,9 @@ void setColor(__global double* result, unsigned x, unsigned y, double3 color) {
result[3*$size_x*y + 3*x + 2] = color.z;
}
-__kernel void render(__global double* result, double3 eye_pos, double3 eye_dir, double3 sun) {
- const unsigned x = get_global_id(0);
- const unsigned y = get_global_id(1);
-
- double2 screen_pos = getNormalizedScreenPos(x, y);
- double3 ray_dir = getEyeRayDir(screen_pos, eye_pos, eye_pos + eye_dir);
-
+void render(__global double* result, unsigned x, unsigned y, double3 origin, double3 ray_dir, double3 sun) {
double d0, d1;
-
- if (!solveRaySphereIntersection(eye_pos, ray_dir, earth_radius + atmos_height, &d0, &d1)) {
+ if (!solveRaySphereIntersection(origin, ray_dir, earth_radius + atmos_height, &d0, &d1)) {
setColor(result, x, y, 0.0);
return;
}
@@ -157,19 +161,19 @@ __kernel void render(__global double* result, double3 eye_pos, double3 eye_dir,
double min_dist = d0;
double max_dist = d1;
- if (insideAtmosphere(eye_pos)) {
+ if (insideAtmosphere(origin)) {
min_dist = 0.0;
- if (solveRaySphereIntersection(eye_pos, ray_dir, earth_radius, &d0, &d1) && d1 > 0) {
+ if (solveRaySphereIntersection(origin, ray_dir, earth_radius, &d0, &d1) && d1 > 0) {
max_dist = max(0.0, d0);
}
} else {
- if (solveRaySphereIntersection(eye_pos, ray_dir, earth_radius, &d0, &d1)) {
+ if (solveRaySphereIntersection(origin, ray_dir, earth_radius, &d0, &d1)) {
max_dist = d0;
}
}
- const double3 ray_origin = eye_pos + min_dist*ray_dir;
+ const double3 ray_origin = origin + min_dist*ray_dir;
const double ray_length = max_dist - min_dist;
double3 color = scatter(ray_origin, ray_dir, ray_length, normalize(sun));
@@ -177,3 +181,29 @@ __kernel void render(__global double* result, double3 eye_pos, double3 eye_dir,
setColor(result, x, y, color);
}
+
+__kernel void render_fisheye(__global double* result, double3 eye_pos, double3 eye_dir, double3 sun) {
+ const unsigned x = get_global_id(0);
+ const unsigned y = get_global_id(1);
+
+ const double2 screen_pos = getNormalizedScreenPos(x, y);
+
+ if (!inFishEyeView(screen_pos)) {
+ setColor(result, x, y, 0.0);
+ return;
+ }
+
+ const double3 ray_dir = getFishEyeRayDir(screen_pos);
+
+ render(result, x, y, eye_pos, ray_dir, sun);
+}
+
+__kernel void render_pinhole(__global double* result, double3 eye_pos, double3 eye_dir, double3 sun) {
+ const unsigned x = get_global_id(0);
+ const unsigned y = get_global_id(1);
+
+ const double2 screen_pos = getNormalizedScreenPos(x, y);
+ const double3 ray_dir = getEyeRayDir(screen_pos, eye_pos, eye_pos + eye_dir);
+
+ render(result, x, y, eye_pos, ray_dir, sun);
+}