diff options
| -rw-r--r-- | local_sunrise.py | 20 | ||||
| -rw-r--r-- | raymarch.cl | 62 | 
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); +}  | 
