[Bf-blender-cvs] SVN commit: /data/svn/bf-blender [44521] trunk/blender: Cycles: support for camera rendering an environment map with equirectangular

Brecht Van Lommel brechtvanlommel at pandora.be
Tue Feb 28 17:44:55 CET 2012


Revision: 44521
          http://projects.blender.org/scm/viewvc.php?view=rev&root=bf-blender&revision=44521
Author:   blendix
Date:     2012-02-28 16:44:54 +0000 (Tue, 28 Feb 2012)
Log Message:
-----------
Cycles: support for camera rendering an environment map with equirectangular
environment map, by enabling the Panorama option in the camera.

http://wiki.blender.org/index.php/Doc:2.6/Manual/Render/Cycles/Camera#Panorama

The focal length or sensor settings are not used, the UI can be tweaked still to
communicate this, also panorama should probably become a proper camera type like
perspective or ortho.

Modified Paths:
--------------
    trunk/blender/intern/cycles/app/cycles_xml.cpp
    trunk/blender/intern/cycles/blender/blender_camera.cpp
    trunk/blender/intern/cycles/kernel/kernel_camera.h
    trunk/blender/intern/cycles/kernel/kernel_displace.h
    trunk/blender/intern/cycles/kernel/kernel_light.h
    trunk/blender/intern/cycles/kernel/kernel_montecarlo.h
    trunk/blender/intern/cycles/kernel/kernel_types.h
    trunk/blender/intern/cycles/render/camera.cpp
    trunk/blender/intern/cycles/render/camera.h
    trunk/blender/intern/cycles/render/light.cpp
    trunk/blender/release/scripts/startup/bl_ui/properties_data_camera.py

Modified: trunk/blender/intern/cycles/app/cycles_xml.cpp
===================================================================
--- trunk/blender/intern/cycles/app/cycles_xml.cpp	2012-02-28 16:44:45 UTC (rev 44520)
+++ trunk/blender/intern/cycles/app/cycles_xml.cpp	2012-02-28 16:44:54 UTC (rev 44521)
@@ -288,9 +288,11 @@
 	xml_read_float(&cam->shutterclose, node, "shutterclose");
 
 	if(xml_equal_string(node, "type", "orthographic"))
-		cam->ortho = true;
+		cam->type = CAMERA_ORTHOGRAPHIC;
 	else if(xml_equal_string(node, "type", "perspective"))
-		cam->ortho = false;
+		cam->type = CAMERA_PERSPECTIVE;
+	else if(xml_equal_string(node, "type", "environment"))
+		cam->type = CAMERA_ENVIRONMENT;
 
 	cam->matrix = state.tfm;
 

Modified: trunk/blender/intern/cycles/blender/blender_camera.cpp
===================================================================
--- trunk/blender/intern/cycles/blender/blender_camera.cpp	2012-02-28 16:44:45 UTC (rev 44520)
+++ trunk/blender/intern/cycles/blender/blender_camera.cpp	2012-02-28 16:44:54 UTC (rev 44521)
@@ -31,7 +31,7 @@
 	float nearclip;
 	float farclip;
 
-	bool ortho;
+	CameraType type;
 	float ortho_scale;
 
 	float lens;
@@ -58,6 +58,7 @@
 {
 	memset(bcam, 0, sizeof(BlenderCamera));
 
+	bcam->type = CAMERA_PERSPECTIVE;
 	bcam->zoom = 1.0f;
 	bcam->pixelaspect = make_float2(1.0f, 1.0f);
 	bcam->sensor_width = 32.0f;
@@ -91,7 +92,9 @@
 		bcam->nearclip = b_camera.clip_start();
 		bcam->farclip = b_camera.clip_end();
 
-		bcam->ortho = (b_camera.type() == BL::Camera::type_ORTHO);
+		bcam->type = (b_camera.type() == BL::Camera::type_ORTHO)? CAMERA_ORTHOGRAPHIC: CAMERA_PERSPECTIVE;
+		if(bcam->type == CAMERA_PERSPECTIVE && b_camera.use_panorama())
+			bcam->type = CAMERA_ENVIRONMENT;
 		bcam->ortho_scale = b_camera.ortho_scale();
 
 		bcam->lens = b_camera.lens();
@@ -159,39 +162,48 @@
 	}
 
 	/* modify aspect for orthographic scale */
-	if(bcam->ortho) {
+	if(bcam->type == CAMERA_ORTHOGRAPHIC) {
 		xaspect = xaspect*bcam->ortho_scale/(aspectratio*2.0f);
 		yaspect = yaspect*bcam->ortho_scale/(aspectratio*2.0f);
 		aspectratio = bcam->ortho_scale/2.0f;
 	}
 
-	/* set viewplane */
-	cam->left = -xaspect;
-	cam->right = xaspect;
-	cam->bottom = -yaspect;
-	cam->top = yaspect;
+	if(bcam->type == CAMERA_ENVIRONMENT) {
+		/* set viewplane */
+		cam->left = 0.0f;
+		cam->right = 1.0f;
+		cam->bottom = 0.0f;
+		cam->top = 1.0f;
+	}
+	else {
+		/* set viewplane */
+		cam->left = -xaspect;
+		cam->right = xaspect;
+		cam->bottom = -yaspect;
+		cam->top = yaspect;
 
-	/* zoom for 3d camera view */
-	cam->left *= bcam->zoom;
-	cam->right *= bcam->zoom;
-	cam->bottom *= bcam->zoom;
-	cam->top *= bcam->zoom;
+		/* zoom for 3d camera view */
+		cam->left *= bcam->zoom;
+		cam->right *= bcam->zoom;
+		cam->bottom *= bcam->zoom;
+		cam->top *= bcam->zoom;
 
-	/* modify viewplane with camera shift and 3d camera view offset */
-	float dx = 2.0f*(aspectratio*bcam->shift.x + bcam->offset.x*xaspect*2.0f);
-	float dy = 2.0f*(aspectratio*bcam->shift.y + bcam->offset.y*yaspect*2.0f);
+		/* modify viewplane with camera shift and 3d camera view offset */
+		float dx = 2.0f*(aspectratio*bcam->shift.x + bcam->offset.x*xaspect*2.0f);
+		float dy = 2.0f*(aspectratio*bcam->shift.y + bcam->offset.y*yaspect*2.0f);
 
-	cam->left += dx;
-	cam->right += dx;
-	cam->bottom += dy;
-	cam->top += dy;
+		cam->left += dx;
+		cam->right += dx;
+		cam->bottom += dy;
+		cam->top += dy;
+	}
 
 	/* clipping distances */
 	cam->nearclip = bcam->nearclip;
 	cam->farclip = bcam->farclip;
 
-	/* orthographic */
-	cam->ortho = bcam->ortho;
+	/* type */
+	cam->type = bcam->type;
 
 	/* perspective */
 	cam->fov = 2.0f*atan((0.5f*sensor_size)/bcam->lens/aspectratio);
@@ -200,8 +212,24 @@
 	cam->blades = bcam->apertureblades;
 	cam->bladesrotation = bcam->aperturerotation;
 
-	/* transform, note the blender camera points along the negative z-axis */
-	cam->matrix = bcam->matrix * transform_scale(1.0f, 1.0f, -1.0f);
+	/* transform */
+	cam->matrix = bcam->matrix;
+
+	if(bcam->type == CAMERA_ENVIRONMENT) {
+		/* make it so environment camera needs to be pointed in the direction
+		   of the positive x-axis to match an environment texture, this way
+		   it is looking at the center of the texture */
+		cam->matrix = cam->matrix *
+			make_transform( 0.0f, -1.0f, 0.0f, 0.0f,
+			                0.0f,  0.0f, 1.0f, 0.0f,
+			               -1.0f,  0.0f, 0.0f, 0.0f,
+			                0.0f,  0.0f, 0.0f, 1.0f);
+	}
+	else {
+		/* note the blender camera points along the negative z-axis */
+		cam->matrix = cam->matrix * transform_scale(1.0f, 1.0f, -1.0f);
+	}
+
 	cam->matrix = transform_clear_scale(cam->matrix);
 
 	/* set update flag */
@@ -269,7 +297,7 @@
 		bcam.farclip *= 0.5;
 		bcam.nearclip = -bcam.farclip;
 
-		bcam.ortho = true;
+		bcam.type = CAMERA_ORTHOGRAPHIC;
 		bcam.ortho_scale = b_rv3d.view_distance();
 	}
 

Modified: trunk/blender/intern/cycles/kernel/kernel_camera.h
===================================================================
--- trunk/blender/intern/cycles/kernel/kernel_camera.h	2012-02-28 16:44:45 UTC (rev 44520)
+++ trunk/blender/intern/cycles/kernel/kernel_camera.h	2012-02-28 16:44:54 UTC (rev 44521)
@@ -122,6 +122,44 @@
 #endif
 }
 
+/* Environment Camera */
+
+__device void camera_sample_environment(KernelGlobals *kg, float raster_x, float raster_y, Ray *ray)
+{
+	Transform rastertocamera = kernel_data.cam.rastertocamera;
+	float3 Pcamera = transform(&rastertocamera, make_float3(raster_x, raster_y, 0.0f));
+
+	/* create ray form raster position */
+	ray->P = make_float3(0.0, 0.0f, 0.0f);
+	ray->D = equirectangular_to_direction(Pcamera.x, Pcamera.y);
+
+	/* transform ray from camera to world */
+	Transform cameratoworld = kernel_data.cam.cameratoworld;
+
+	ray->P = transform(&cameratoworld, ray->P);
+	ray->D = transform_direction(&cameratoworld, ray->D);
+	ray->D = normalize(ray->D);
+
+#ifdef __RAY_DIFFERENTIALS__
+	/* ray differential */
+	ray->dP.dx = make_float3(0.0f, 0.0f, 0.0f);
+	ray->dP.dy = make_float3(0.0f, 0.0f, 0.0f);
+
+	Pcamera = transform(&rastertocamera, make_float3(raster_x + 1.0f, raster_y, 0.0f));
+	ray->dD.dx = equirectangular_to_direction(Pcamera.x, Pcamera.y) - ray->D;
+
+	Pcamera = transform(&rastertocamera, make_float3(raster_x, raster_y + 1.0f, 0.0f));
+	ray->dD.dy = equirectangular_to_direction(Pcamera.x, Pcamera.y) - ray->D;
+#endif
+
+#ifdef __CAMERA_CLIPPING__
+	/* clipping */
+	ray->t = kernel_data.cam.cliplength;
+#else
+	ray->t = FLT_MAX;
+#endif
+}
+
 /* Common */
 
 __device void camera_sample(KernelGlobals *kg, int x, int y, float filter_u, float filter_v, float lens_u, float lens_v, Ray *ray)
@@ -134,10 +172,12 @@
 	//ray->time = lerp(time_t, kernel_data.cam.shutter_open, kernel_data.cam.shutter_close);
 
 	/* sample */
-	if(kernel_data.cam.ortho)
+	if(kernel_data.cam.type == CAMERA_PERSPECTIVE)
+		camera_sample_perspective(kg, raster_x, raster_y, lens_u, lens_v, ray);
+	else if(kernel_data.cam.type == CAMERA_ORTHOGRAPHIC)
 		camera_sample_orthographic(kg, raster_x, raster_y, ray);
 	else
-		camera_sample_perspective(kg, raster_x, raster_y, lens_u, lens_v, ray);
+		camera_sample_environment(kg, raster_x, raster_y, ray);
 }
 
 CCL_NAMESPACE_END

Modified: trunk/blender/intern/cycles/kernel/kernel_displace.h
===================================================================
--- trunk/blender/intern/cycles/kernel/kernel_displace.h	2012-02-28 16:44:45 UTC (rev 44520)
+++ trunk/blender/intern/cycles/kernel/kernel_displace.h	2012-02-28 16:44:54 UTC (rev 44521)
@@ -41,9 +41,11 @@
 	else { // SHADER_EVAL_BACKGROUND
 		/* setup ray */
 		Ray ray;
+		float u = __int_as_float(in.x);
+		float v = __int_as_float(in.y);
 
 		ray.P = make_float3(0.0f, 0.0f, 0.0f);
-		ray.D = make_float3(__int_as_float(in.x), __int_as_float(in.y), __int_as_float(in.z));
+		ray.D = equirectangular_to_direction(u, v);
 		ray.t = 0.0f;
 
 #ifdef __RAY_DIFFERENTIALS__

Modified: trunk/blender/intern/cycles/kernel/kernel_light.h
===================================================================
--- trunk/blender/intern/cycles/kernel/kernel_light.h	2012-02-28 16:44:45 UTC (rev 44520)
+++ trunk/blender/intern/cycles/kernel/kernel_light.h	2012-02-28 16:44:54 UTC (rev 44521)
@@ -120,13 +120,9 @@
 	float du = (randu - cdf_u.y) / (cdf_next_u.y - cdf_u.y);
 	float u = (index_u + du) / res;
 
-	/* spherical coordinates */
-	float theta = v * M_PI_F;
-	float phi = u * M_PI_F * 2.0f;
-
 	/* compute pdf */
 	float denom = cdf_last_u.x * cdf_last_v.x;
-	float sin_theta = sinf(theta);
+	float sin_theta = sinf(M_PI_F * v);
 
 	if(sin_theta == 0.0f || denom == 0.0f)
 		*pdf = 0.0f;
@@ -136,7 +132,7 @@
 	*pdf *= kernel_data.integrator.pdf_lights;
 
 	/* compute direction */
-	return spherical_to_direction(theta, phi);
+	return -equirectangular_to_direction(u, v);
 }
 
 __device float background_light_pdf(KernelGlobals *kg, float3 direction)

Modified: trunk/blender/intern/cycles/kernel/kernel_montecarlo.h
===================================================================
--- trunk/blender/intern/cycles/kernel/kernel_montecarlo.h	2012-02-28 16:44:45 UTC (rev 44520)
+++ trunk/blender/intern/cycles/kernel/kernel_montecarlo.h	2012-02-28 16:44:54 UTC (rev 44521)
@@ -185,7 +185,7 @@
 	return make_float2(cr*p.x - sr*p.y, sr*p.x + cr*p.y);
 }
 
-/* Spherical coordinates <-> Cartesion direction  */
+/* Spherical coordinates <-> Cartesian direction  */
 
 __device float2 direction_to_spherical(float3 dir)
 {
@@ -203,11 +203,11 @@
 		cosf(theta));
 }
 
-/* Equirectangular */
+/* Equirectangular coordinates <-> Cartesian direction */
 
 __device float2 direction_to_equirectangular(float3 dir)
 {
-	float u = (atan2f(dir.y, dir.x) + M_PI_F)/(2.0f*M_PI_F);
+	float u = -atan2f(dir.y, dir.x)/(2.0f*M_PI_F) + 0.5f;
 	float v = atan2f(dir.z, hypotf(dir.x, dir.y))/M_PI_F + 0.5f;
 
 	return make_float2(u, v);
@@ -215,9 +215,8 @@
 
 __device float3 equirectangular_to_direction(float u, float v)
 {
-	/* XXX check correctness? */
-	float theta = M_PI_F*v;
-	float phi = 2.0f*M_PI_F*u;
+	float phi = M_PI_F*(1.0f - 2.0f*u);
+	float theta = M_PI_F*(1.0f - v);
 
 	return make_float3(
 		sin(theta)*cos(phi),

Modified: trunk/blender/intern/cycles/kernel/kernel_types.h
===================================================================
--- trunk/blender/intern/cycles/kernel/kernel_types.h	2012-02-28 16:44:45 UTC (rev 44520)
+++ trunk/blender/intern/cycles/kernel/kernel_types.h	2012-02-28 16:44:54 UTC (rev 44521)
@@ -240,6 +240,14 @@
 	LIGHT_AREA
 } LightType;
 
+/* Camera Type */
+

@@ Diff output truncated at 10240 characters. @@



More information about the Bf-blender-cvs mailing list