Cycles: Support tube projection for images
This way Cycles finally becomes feature-full on image projections compared to Blender Internal and Gooseberry Project Team could finally finish the movie.
This commit is contained in:
@@ -17,13 +17,32 @@
|
|||||||
#include "stdosl.h"
|
#include "stdosl.h"
|
||||||
#include "node_color.h"
|
#include "node_color.h"
|
||||||
|
|
||||||
|
point texco_remap_square(point co)
|
||||||
|
{
|
||||||
|
return (co - point(0.5, 0.5, 0.5)) * 2.0;
|
||||||
|
}
|
||||||
|
|
||||||
|
point map_to_tube(vector dir)
|
||||||
|
{
|
||||||
|
float u, v;
|
||||||
|
v = (dir[2] + 1.0) * 0.5;
|
||||||
|
float len = sqrt(dir[0]*dir[0] + dir[1]*dir[1]);
|
||||||
|
if (len > 0.0) {
|
||||||
|
u = (1.0 - (atan2(dir[0] / len, dir[1] / len) / M_PI)) * 0.5;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
v = u = 0.0; /* To avoid un-initialized variables. */
|
||||||
|
}
|
||||||
|
return point(u, v, 0.0);
|
||||||
|
}
|
||||||
|
|
||||||
point map_to_sphere(vector dir)
|
point map_to_sphere(vector dir)
|
||||||
{
|
{
|
||||||
float len = length(dir);
|
float len = length(dir);
|
||||||
float v, u;
|
float v, u;
|
||||||
if(len > 0.0) {
|
if(len > 0.0) {
|
||||||
if(dir[0] == 0.0 && dir[1] == 0.0) {
|
if(dir[0] == 0.0 && dir[1] == 0.0) {
|
||||||
u = 0.0; /* othwise domain error */
|
u = 0.0; /* Othwise domain error. */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
u = (1.0 - atan2(dir[0], dir[1]) / M_PI) / 2.0;
|
u = (1.0 - atan2(dir[0], dir[1]) / M_PI) / 2.0;
|
||||||
@@ -31,7 +50,7 @@ point map_to_sphere(vector dir)
|
|||||||
v = 1.0 - acos(dir[2] / len) / M_PI;
|
v = 1.0 - acos(dir[2] / len) / M_PI;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
v = u = 0.0; /* to avoid un-initialized variables */
|
v = u = 0.0; /* To avoid un-initialized variables. */
|
||||||
}
|
}
|
||||||
return point(u, v, 0.0);
|
return point(u, v, 0.0);
|
||||||
}
|
}
|
||||||
@@ -156,7 +175,13 @@ shader node_image_texture(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (projection == "Sphere") {
|
else if (projection == "Sphere") {
|
||||||
point projected = map_to_sphere((p - vector(0.5, 0.5, 0.5)) * 2.0);
|
point projected = map_to_sphere(texco_remap_square(p));
|
||||||
|
Color = image_texture_lookup(filename, color_space,
|
||||||
|
projected[0], projected[1],
|
||||||
|
Alpha, use_alpha, is_float, interpolation);
|
||||||
|
}
|
||||||
|
else if (projection == "Tube") {
|
||||||
|
point projected = map_to_tube(texco_remap_square(p));
|
||||||
Color = image_texture_lookup(filename, color_space,
|
Color = image_texture_lookup(filename, color_space,
|
||||||
projected[0], projected[1],
|
projected[0], projected[1],
|
||||||
Alpha, use_alpha, is_float, interpolation);
|
Alpha, use_alpha, is_float, interpolation);
|
||||||
|
@@ -354,6 +354,12 @@ ccl_device float4 svm_image_texture(KernelGlobals *kg, int id, float x, float y,
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* Remap coordnate from 0..1 box to -1..-1 */
|
||||||
|
ccl_device_inline float3 texco_remap_square(float3 co)
|
||||||
|
{
|
||||||
|
return (co - make_float3(0.5f, 0.5f, 0.5f)) * 2.0f;
|
||||||
|
}
|
||||||
|
|
||||||
ccl_device void svm_node_tex_image(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
|
ccl_device void svm_node_tex_image(KernelGlobals *kg, ShaderData *sd, float *stack, uint4 node)
|
||||||
{
|
{
|
||||||
uint id = node.y;
|
uint id = node.y;
|
||||||
@@ -364,9 +370,13 @@ ccl_device void svm_node_tex_image(KernelGlobals *kg, ShaderData *sd, float *sta
|
|||||||
float3 co = stack_load_float3(stack, co_offset);
|
float3 co = stack_load_float3(stack, co_offset);
|
||||||
uint use_alpha = stack_valid(alpha_offset);
|
uint use_alpha = stack_valid(alpha_offset);
|
||||||
if(node.w == NODE_IMAGE_PROJ_SPHERE) {
|
if(node.w == NODE_IMAGE_PROJ_SPHERE) {
|
||||||
co = (co - make_float3(0.5f, 0.5f, 0.5f)) * 2.0f;
|
co = texco_remap_square(co);
|
||||||
map_to_sphere(&co.x, &co.y, co.x, co.y, co.z);
|
map_to_sphere(&co.x, &co.y, co.x, co.y, co.z);
|
||||||
}
|
}
|
||||||
|
else if(node.w == NODE_IMAGE_PROJ_TUBE) {
|
||||||
|
co = texco_remap_square(co);
|
||||||
|
map_to_tube(&co.x, &co.y, co.x, co.y, co.z);
|
||||||
|
}
|
||||||
float4 f = svm_image_texture(kg, id, co.x, co.y, srgb, use_alpha);
|
float4 f = svm_image_texture(kg, id, co.x, co.y, srgb, use_alpha);
|
||||||
|
|
||||||
if(stack_valid(out_offset))
|
if(stack_valid(out_offset))
|
||||||
|
@@ -338,6 +338,7 @@ typedef enum NodeImageProjection {
|
|||||||
NODE_IMAGE_PROJ_FLAT = 0,
|
NODE_IMAGE_PROJ_FLAT = 0,
|
||||||
NODE_IMAGE_PROJ_BOX = 1,
|
NODE_IMAGE_PROJ_BOX = 1,
|
||||||
NODE_IMAGE_PROJ_SPHERE = 2,
|
NODE_IMAGE_PROJ_SPHERE = 2,
|
||||||
|
NODE_IMAGE_PROJ_TUBE = 3,
|
||||||
} NodeImageProjection;
|
} NodeImageProjection;
|
||||||
|
|
||||||
typedef enum ShaderType {
|
typedef enum ShaderType {
|
||||||
|
@@ -177,6 +177,7 @@ static ShaderEnum image_projection_init()
|
|||||||
enm.insert("Flat", NODE_IMAGE_PROJ_FLAT);
|
enm.insert("Flat", NODE_IMAGE_PROJ_FLAT);
|
||||||
enm.insert("Box", NODE_IMAGE_PROJ_BOX);
|
enm.insert("Box", NODE_IMAGE_PROJ_BOX);
|
||||||
enm.insert("Sphere", NODE_IMAGE_PROJ_SPHERE);
|
enm.insert("Sphere", NODE_IMAGE_PROJ_SPHERE);
|
||||||
|
enm.insert("Tube", NODE_IMAGE_PROJ_TUBE);
|
||||||
|
|
||||||
return enm;
|
return enm;
|
||||||
}
|
}
|
||||||
|
@@ -1450,6 +1450,20 @@ ccl_device bool ray_quad_intersect(
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* projections */
|
/* projections */
|
||||||
|
ccl_device void map_to_tube(float *r_u, float *r_v,
|
||||||
|
const float x, const float y, const float z)
|
||||||
|
{
|
||||||
|
float len;
|
||||||
|
*r_v = (z + 1.0f) * 0.5f;
|
||||||
|
len = sqrtf(x * x + y * y);
|
||||||
|
if (len > 0.0f) {
|
||||||
|
*r_u = (1.0f - (atan2f(x / len, y / len) / (float)M_PI)) * 0.5f;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
*r_v = *r_u = 0.0f; /* To avoid un-initialized variables. */
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ccl_device bool map_to_sphere(float *r_u, float *r_v,
|
ccl_device bool map_to_sphere(float *r_u, float *r_v,
|
||||||
const float x, const float y, const float z)
|
const float x, const float y, const float z)
|
||||||
{
|
{
|
||||||
|
@@ -963,6 +963,7 @@ typedef struct NodeSunBeams {
|
|||||||
#define SHD_PROJ_FLAT 0
|
#define SHD_PROJ_FLAT 0
|
||||||
#define SHD_PROJ_BOX 1
|
#define SHD_PROJ_BOX 1
|
||||||
#define SHD_PROJ_SPHERE 2
|
#define SHD_PROJ_SPHERE 2
|
||||||
|
#define SHD_PROJ_TUBE 3
|
||||||
|
|
||||||
/* image texture interpolation */
|
/* image texture interpolation */
|
||||||
#define SHD_INTERP_LINEAR 0
|
#define SHD_INTERP_LINEAR 0
|
||||||
|
@@ -3437,6 +3437,8 @@ static void def_sh_tex_image(StructRNA *srna)
|
|||||||
"Image is projected using different components for each side of the object space bounding box"},
|
"Image is projected using different components for each side of the object space bounding box"},
|
||||||
{SHD_PROJ_SPHERE, "SPHERE", 0, "Sphere",
|
{SHD_PROJ_SPHERE, "SPHERE", 0, "Sphere",
|
||||||
"Image is projected spherically using the Z axis as central"},
|
"Image is projected spherically using the Z axis as central"},
|
||||||
|
{SHD_PROJ_TUBE, "TUBE", 0, "Tube",
|
||||||
|
"Image is projected from the tube using the Z axis as central"},
|
||||||
{0, NULL, 0, NULL, NULL}
|
{0, NULL, 0, NULL, NULL}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user