forked from bartvdbraak/blender
Cycles: Make sphere and tube image mapping friendly with OpenCL
OpenCL doesn't let you to get address of vector components, which is kinda annoying. On the other hand, maybe now compiler will have more chances to optimize something out.
This commit is contained in:
parent
5004b58262
commit
3e534833e3
@ -106,7 +106,9 @@ static void mikk_get_texture_coordinate(const SMikkTSpaceContext *context, float
|
||||
int vert_idx = userdata->mesh.tessfaces[face_num].vertices()[vert_num];
|
||||
float3 orco =
|
||||
get_float3(userdata->mesh.vertices[vert_idx].undeformed_co());
|
||||
map_to_sphere(&uv[0], &uv[1], orco[0], orco[1], orco[2]);
|
||||
float2 tmp = map_to_sphere(make_float3(orco[0], orco[1], orco[2]));
|
||||
uv[0] = tmp.x;
|
||||
uv[1] = tmp.y;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -368,16 +368,20 @@ ccl_device void svm_node_tex_image(KernelGlobals *kg, ShaderData *sd, float *sta
|
||||
decode_node_uchar4(node.z, &co_offset, &out_offset, &alpha_offset, &srgb);
|
||||
|
||||
float3 co = stack_load_float3(stack, co_offset);
|
||||
float2 tex_co;
|
||||
uint use_alpha = stack_valid(alpha_offset);
|
||||
if(node.w == NODE_IMAGE_PROJ_SPHERE) {
|
||||
co = texco_remap_square(co);
|
||||
map_to_sphere(&co.x, &co.y, co.x, co.y, co.z);
|
||||
tex_co = map_to_sphere(co);
|
||||
}
|
||||
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);
|
||||
tex_co = map_to_tube(co);
|
||||
}
|
||||
float4 f = svm_image_texture(kg, id, co.x, co.y, srgb, use_alpha);
|
||||
else {
|
||||
tex_co = make_float2(co.x, co.y);
|
||||
}
|
||||
float4 f = svm_image_texture(kg, id, tex_co.x, tex_co.y, srgb, use_alpha);
|
||||
|
||||
if(stack_valid(out_offset))
|
||||
stack_store_float3(stack, out_offset, make_float3(f.x, f.y, f.z));
|
||||
|
@ -1457,38 +1457,37 @@ ccl_device bool ray_quad_intersect(
|
||||
}
|
||||
|
||||
/* projections */
|
||||
ccl_device void map_to_tube(float *r_u, float *r_v,
|
||||
const float x, const float y, const float z)
|
||||
ccl_device_inline float2 map_to_tube(const float3 co)
|
||||
{
|
||||
float len;
|
||||
*r_v = (z + 1.0f) * 0.5f;
|
||||
len = sqrtf(x * x + y * y);
|
||||
float len, u, v;
|
||||
len = sqrtf(co.x * co.x + co.y * co.y);
|
||||
if (len > 0.0f) {
|
||||
*r_u = (1.0f - (atan2f(x / len, y / len) / M_PI_F)) * 0.5f;
|
||||
u = (1.0f - (atan2f(co.x / len, co.y / len) / M_PI_F)) * 0.5f;
|
||||
v = (co.x + 1.0f) * 0.5f;
|
||||
}
|
||||
else {
|
||||
*r_v = *r_u = 0.0f; /* To avoid un-initialized variables. */
|
||||
u = v = 0.0f;
|
||||
}
|
||||
return make_float2(u, v);
|
||||
}
|
||||
|
||||
ccl_device bool map_to_sphere(float *r_u, float *r_v,
|
||||
const float x, const float y, const float z)
|
||||
ccl_device_inline float2 map_to_sphere(const float3 co)
|
||||
{
|
||||
float len = sqrtf(x * x + y * y + z * z);
|
||||
if(len > 0.0f) {
|
||||
if(UNLIKELY(x == 0.0f && y == 0.0f)) {
|
||||
*r_u = 0.0f; /* othwise domain error */
|
||||
float l = len(co);
|
||||
float u, v;
|
||||
if(l > 0.0f) {
|
||||
if(UNLIKELY(co.x == 0.0f && co.y == 0.0f)) {
|
||||
u = 0.0f; /* othwise domain error */
|
||||
}
|
||||
else {
|
||||
*r_u = (1.0f - atan2f(x, y) / M_PI_F) / 2.0f;
|
||||
u = (1.0f - atan2f(co.x, co.y) / M_PI_F) / 2.0f;
|
||||
}
|
||||
*r_v = 1.0f - safe_acosf(z / len) / M_PI_F;
|
||||
return true;
|
||||
v = 1.0f - safe_acosf(co.z / l) / M_PI_F;
|
||||
}
|
||||
else {
|
||||
*r_v = *r_u = 0.0f; /* to avoid un-initialized variables */
|
||||
return false;
|
||||
u = v = 0.0f;
|
||||
}
|
||||
return make_float2(u, v);
|
||||
}
|
||||
|
||||
ccl_device_inline int util_max_axis(float3 vec)
|
||||
|
Loading…
Reference in New Issue
Block a user