Cycles: add Equiangular Cubemap Face camera projection

This can be used for example for VR video formats that use this projection
instead of perspective projection for cubemap faces.

Differential Revision: https://developer.blender.org/D13525
This commit is contained in:
Damian Trebilco 2022-10-28 14:30:18 +02:00 committed by Brecht Van Lommel
parent 105c8d59cd
commit f9113b7eb6
4 changed files with 34 additions and 5 deletions

View File

@ -60,13 +60,14 @@ enum_filter_types = (
)
enum_panorama_types = (
('EQUIRECTANGULAR', "Equirectangular", "Render the scene with a spherical camera, also known as Lat Long panorama"),
('FISHEYE_EQUIDISTANT', "Fisheye Equidistant", "Ideal for fulldomes, ignore the sensor dimensions"),
('EQUIRECTANGULAR', "Equirectangular", "Spherical camera for environment maps, also known as Lat Long panorama", 0),
('EQUIANGULAR_CUBEMAP_FACE', "Equiangular Cubemap Face", "Single face of an equiangular cubemap", 5),
('MIRRORBALL', "Mirror Ball", "Mirror ball mapping for environment maps", 3),
('FISHEYE_EQUIDISTANT', "Fisheye Equidistant", "Ideal for fulldomes, ignore the sensor dimensions", 1),
('FISHEYE_EQUISOLID', "Fisheye Equisolid",
"Similar to most fisheye modern lens, takes sensor dimensions into consideration"),
('MIRRORBALL', "Mirror Ball", "Uses the mirror ball mapping"),
"Similar to most fisheye modern lens, takes sensor dimensions into consideration", 2),
('FISHEYE_LENS_POLYNOMIAL', "Fisheye Lens Polynomial",
"Defines the lens projection as polynomial to allow real world camera lenses to be mimicked"),
"Defines the lens projection as polynomial to allow real world camera lenses to be mimicked", 4),
)
enum_curve_shape = (

View File

@ -201,11 +201,35 @@ ccl_device float2 direction_to_mirrorball(float3 dir)
return make_float2(u, v);
}
/* Single face of a equiangular cube map projection as described in
https://blog.google/products/google-ar-vr/bringing-pixels-front-and-center-vr-video/ */
ccl_device float3 equiangular_cubemap_face_to_direction(float u, float v)
{
u = (1.0f - u);
u = tanf(u * M_PI_2_F - M_PI_4_F);
v = tanf(v * M_PI_2_F - M_PI_4_F);
return make_float3(1.0f, u, v);
}
ccl_device float2 direction_to_equiangular_cubemap_face(float3 dir)
{
float u = atan2f(dir.y, dir.x) * 2.0f / M_PI_F + 0.5f;
float v = atan2f(dir.z, dir.x) * 2.0f / M_PI_F + 0.5f;
u = 1.0f - u;
return make_float2(u, v);
}
ccl_device_inline float3 panorama_to_direction(ccl_constant KernelCamera *cam, float u, float v)
{
switch (cam->panorama_type) {
case PANORAMA_EQUIRECTANGULAR:
return equirectangular_range_to_direction(u, v, cam->equirectangular_range);
case PANORAMA_EQUIANGULAR_CUBEMAP_FACE:
return equiangular_cubemap_face_to_direction(u, v);
case PANORAMA_MIRRORBALL:
return mirrorball_to_direction(u, v);
case PANORAMA_FISHEYE_EQUIDISTANT:
@ -230,6 +254,8 @@ ccl_device_inline float2 direction_to_panorama(ccl_constant KernelCamera *cam, f
switch (cam->panorama_type) {
case PANORAMA_EQUIRECTANGULAR:
return direction_to_equirectangular_range(dir, cam->equirectangular_range);
case PANORAMA_EQUIANGULAR_CUBEMAP_FACE:
return direction_to_equiangular_cubemap_face(dir);
case PANORAMA_MIRRORBALL:
return direction_to_mirrorball(dir);
case PANORAMA_FISHEYE_EQUIDISTANT:

View File

@ -490,6 +490,7 @@ enum PanoramaType {
PANORAMA_FISHEYE_EQUISOLID = 2,
PANORAMA_MIRRORBALL = 3,
PANORAMA_FISHEYE_LENS_POLYNOMIAL = 4,
PANORAMA_EQUIANGULAR_CUBEMAP_FACE = 5,
PANORAMA_NUM_TYPES,
};

View File

@ -84,6 +84,7 @@ NODE_DEFINE(Camera)
static NodeEnum panorama_type_enum;
panorama_type_enum.insert("equirectangular", PANORAMA_EQUIRECTANGULAR);
panorama_type_enum.insert("equiangular_cubemap_face", PANORAMA_EQUIANGULAR_CUBEMAP_FACE);
panorama_type_enum.insert("mirrorball", PANORAMA_MIRRORBALL);
panorama_type_enum.insert("fisheye_equidistant", PANORAMA_FISHEYE_EQUIDISTANT);
panorama_type_enum.insert("fisheye_equisolid", PANORAMA_FISHEYE_EQUISOLID);