diff options
Diffstat (limited to 'intern/cycles/kernel/shaders/node_image_texture.osl')
-rw-r--r-- | intern/cycles/kernel/shaders/node_image_texture.osl | 378 |
1 files changed, 189 insertions, 189 deletions
diff --git a/intern/cycles/kernel/shaders/node_image_texture.osl b/intern/cycles/kernel/shaders/node_image_texture.osl index 7cd2922dd4f..df5eda39985 100644 --- a/intern/cycles/kernel/shaders/node_image_texture.osl +++ b/intern/cycles/kernel/shaders/node_image_texture.osl @@ -19,217 +19,217 @@ point texco_remap_square(point co) { - return (co - point(0.5, 0.5, 0.5)) * 2.0; + 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); + 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) { - float len = length(dir); - float v, u; - if (len > 0.0) { - if (dir[0] == 0.0 && dir[1] == 0.0) { - u = 0.0; /* Othwise domain error. */ - } - else { - u = (1.0 - atan2(dir[0], dir[1]) / M_PI) / 2.0; - } - v = 1.0 - acos(dir[2] / len) / M_PI; - } - else { - v = u = 0.0; /* To avoid un-initialized variables. */ - } - return point(u, v, 0.0); + float len = length(dir); + float v, u; + if (len > 0.0) { + if (dir[0] == 0.0 && dir[1] == 0.0) { + u = 0.0; /* Othwise domain error. */ + } + else { + u = (1.0 - atan2(dir[0], dir[1]) / M_PI) / 2.0; + } + v = 1.0 - acos(dir[2] / len) / M_PI; + } + else { + v = u = 0.0; /* To avoid un-initialized variables. */ + } + return point(u, v, 0.0); } color image_texture_lookup(string filename, string color_space, - float u, float v, + float u, + float v, output float Alpha, int use_alpha, int is_float, string interpolation, string extension) { - color rgb = (color)texture(filename, u, 1.0 - v, "wrap", extension, "interp", interpolation, "alpha", Alpha); + color rgb = (color)texture( + filename, u, 1.0 - v, "wrap", extension, "interp", interpolation, "alpha", Alpha); - if (use_alpha) { - rgb = color_unpremultiply(rgb, Alpha); - - if (!is_float) - rgb = min(rgb, 1.0); - } + if (use_alpha) { + rgb = color_unpremultiply(rgb, Alpha); - if (color_space == "sRGB") { - rgb = color_srgb_to_scene_linear(rgb); - } + if (!is_float) + rgb = min(rgb, 1.0); + } - return rgb; + if (color_space == "sRGB") { + rgb = color_srgb_to_scene_linear(rgb); + } + + return rgb; } -shader node_image_texture( - int use_mapping = 0, - matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), - point Vector = P, - string filename = "", - string color_space = "sRGB", - string projection = "flat", - string interpolation = "smartcubic", - string extension = "periodic", - float projection_blend = 0.0, - int is_float = 1, - int use_alpha = 1, - output color Color = 0.0, - output float Alpha = 1.0) +shader node_image_texture(int use_mapping = 0, + matrix mapping = matrix(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0), + point Vector = P, + string filename = "", + string color_space = "sRGB", + string projection = "flat", + string interpolation = "smartcubic", + string extension = "periodic", + float projection_blend = 0.0, + int is_float = 1, + int use_alpha = 1, + output color Color = 0.0, + output float Alpha = 1.0) { - point p = Vector; - - if (use_mapping) - p = transform(mapping, p); - - if (projection == "flat") { - Color = image_texture_lookup(filename, - color_space, - p[0], p[1], - Alpha, - use_alpha, - is_float, - interpolation, - extension); - } - else if (projection == "box") { - /* object space normal */ - vector Nob = transform("world", "object", N); - - /* project from direction vector to barycentric coordinates in triangles */ - Nob = vector(fabs(Nob[0]), fabs(Nob[1]), fabs(Nob[2])); - Nob /= (Nob[0] + Nob[1] + Nob[2]); - - /* basic idea is to think of this as a triangle, each corner representing - * one of the 3 faces of the cube. in the corners we have single textures, - * in between we blend between two textures, and in the middle we a blend - * between three textures. - * - * the Nxyz values are the barycentric coordinates in an equilateral - * triangle, which in case of blending, in the middle has a smaller - * equilateral triangle where 3 textures blend. this divides things into - * 7 zones, with an if () test for each zone */ - - vector weight = vector(0.0, 0.0, 0.0); - float blend = projection_blend; - float limit = 0.5 * (1.0 + blend); - - /* first test for corners with single texture */ - if (Nob[0] > limit * (Nob[0] + Nob[1]) && Nob[0] > limit * (Nob[0] + Nob[2])) { - weight[0] = 1.0; - } - else if (Nob[1] > limit * (Nob[0] + Nob[1]) && Nob[1] > limit * (Nob[1] + Nob[2])) { - weight[1] = 1.0; - } - else if (Nob[2] > limit * (Nob[0] + Nob[2]) && Nob[2] > limit * (Nob[1] + Nob[2])) { - weight[2] = 1.0; - } - else if (blend > 0.0) { - /* in case of blending, test for mixes between two textures */ - if (Nob[2] < (1.0 - limit) * (Nob[1] + Nob[0])) { - weight[0] = Nob[0] / (Nob[0] + Nob[1]); - weight[0] = clamp((weight[0] - 0.5 * (1.0 - blend)) / blend, 0.0, 1.0); - weight[1] = 1.0 - weight[0]; - } - else if (Nob[0] < (1.0 - limit) * (Nob[1] + Nob[2])) { - weight[1] = Nob[1] / (Nob[1] + Nob[2]); - weight[1] = clamp((weight[1] - 0.5 * (1.0 - blend)) / blend, 0.0, 1.0); - weight[2] = 1.0 - weight[1]; - } - else if (Nob[1] < (1.0 - limit) * (Nob[0] + Nob[2])) { - weight[0] = Nob[0] / (Nob[0] + Nob[2]); - weight[0] = clamp((weight[0] - 0.5 * (1.0 - blend)) / blend, 0.0, 1.0); - weight[2] = 1.0 - weight[0]; - } - else { - /* last case, we have a mix between three */ - weight[0] = ((2.0 - limit) * Nob[0] + (limit - 1.0)) / (2.0 * limit - 1.0); - weight[1] = ((2.0 - limit) * Nob[1] + (limit - 1.0)) / (2.0 * limit - 1.0); - weight[2] = ((2.0 - limit) * Nob[2] + (limit - 1.0)) / (2.0 * limit - 1.0); - } - } - else { - /* Desperate mode, no valid choice anyway, fallback to one side.*/ - weight[0] = 1.0; - } - - Color = color(0.0, 0.0, 0.0); - Alpha = 0.0; - - float tmp_alpha; - - if (weight[0] > 0.0) { - Color += weight[0] * image_texture_lookup(filename, - color_space, - p[1], p[2], - tmp_alpha, - use_alpha, - is_float, - interpolation, - extension); - Alpha += weight[0] * tmp_alpha; - } - if (weight[1] > 0.0) { - Color += weight[1] * image_texture_lookup(filename, - color_space, - p[0], p[2], - tmp_alpha, - use_alpha, - is_float, - interpolation, - extension); - Alpha += weight[1] * tmp_alpha; - } - if (weight[2] > 0.0) { - Color += weight[2] * image_texture_lookup(filename, - color_space, - p[1], p[0], - tmp_alpha, - use_alpha, - is_float, - interpolation, - extension); - Alpha += weight[2] * tmp_alpha; - } - } - else if (projection == "sphere") { - 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, - extension); - } - else if (projection == "tube") { - point projected = map_to_tube(texco_remap_square(p)); - Color = image_texture_lookup(filename, - color_space, - projected[0], projected[1], - Alpha, - use_alpha, - is_float, - interpolation, - extension); - } + point p = Vector; + + if (use_mapping) + p = transform(mapping, p); + + if (projection == "flat") { + Color = image_texture_lookup( + filename, color_space, p[0], p[1], Alpha, use_alpha, is_float, interpolation, extension); + } + else if (projection == "box") { + /* object space normal */ + vector Nob = transform("world", "object", N); + + /* project from direction vector to barycentric coordinates in triangles */ + Nob = vector(fabs(Nob[0]), fabs(Nob[1]), fabs(Nob[2])); + Nob /= (Nob[0] + Nob[1] + Nob[2]); + + /* basic idea is to think of this as a triangle, each corner representing + * one of the 3 faces of the cube. in the corners we have single textures, + * in between we blend between two textures, and in the middle we a blend + * between three textures. + * + * the Nxyz values are the barycentric coordinates in an equilateral + * triangle, which in case of blending, in the middle has a smaller + * equilateral triangle where 3 textures blend. this divides things into + * 7 zones, with an if () test for each zone */ + + vector weight = vector(0.0, 0.0, 0.0); + float blend = projection_blend; + float limit = 0.5 * (1.0 + blend); + + /* first test for corners with single texture */ + if (Nob[0] > limit * (Nob[0] + Nob[1]) && Nob[0] > limit * (Nob[0] + Nob[2])) { + weight[0] = 1.0; + } + else if (Nob[1] > limit * (Nob[0] + Nob[1]) && Nob[1] > limit * (Nob[1] + Nob[2])) { + weight[1] = 1.0; + } + else if (Nob[2] > limit * (Nob[0] + Nob[2]) && Nob[2] > limit * (Nob[1] + Nob[2])) { + weight[2] = 1.0; + } + else if (blend > 0.0) { + /* in case of blending, test for mixes between two textures */ + if (Nob[2] < (1.0 - limit) * (Nob[1] + Nob[0])) { + weight[0] = Nob[0] / (Nob[0] + Nob[1]); + weight[0] = clamp((weight[0] - 0.5 * (1.0 - blend)) / blend, 0.0, 1.0); + weight[1] = 1.0 - weight[0]; + } + else if (Nob[0] < (1.0 - limit) * (Nob[1] + Nob[2])) { + weight[1] = Nob[1] / (Nob[1] + Nob[2]); + weight[1] = clamp((weight[1] - 0.5 * (1.0 - blend)) / blend, 0.0, 1.0); + weight[2] = 1.0 - weight[1]; + } + else if (Nob[1] < (1.0 - limit) * (Nob[0] + Nob[2])) { + weight[0] = Nob[0] / (Nob[0] + Nob[2]); + weight[0] = clamp((weight[0] - 0.5 * (1.0 - blend)) / blend, 0.0, 1.0); + weight[2] = 1.0 - weight[0]; + } + else { + /* last case, we have a mix between three */ + weight[0] = ((2.0 - limit) * Nob[0] + (limit - 1.0)) / (2.0 * limit - 1.0); + weight[1] = ((2.0 - limit) * Nob[1] + (limit - 1.0)) / (2.0 * limit - 1.0); + weight[2] = ((2.0 - limit) * Nob[2] + (limit - 1.0)) / (2.0 * limit - 1.0); + } + } + else { + /* Desperate mode, no valid choice anyway, fallback to one side.*/ + weight[0] = 1.0; + } + + Color = color(0.0, 0.0, 0.0); + Alpha = 0.0; + + float tmp_alpha; + + if (weight[0] > 0.0) { + Color += weight[0] * image_texture_lookup(filename, + color_space, + p[1], + p[2], + tmp_alpha, + use_alpha, + is_float, + interpolation, + extension); + Alpha += weight[0] * tmp_alpha; + } + if (weight[1] > 0.0) { + Color += weight[1] * image_texture_lookup(filename, + color_space, + p[0], + p[2], + tmp_alpha, + use_alpha, + is_float, + interpolation, + extension); + Alpha += weight[1] * tmp_alpha; + } + if (weight[2] > 0.0) { + Color += weight[2] * image_texture_lookup(filename, + color_space, + p[1], + p[0], + tmp_alpha, + use_alpha, + is_float, + interpolation, + extension); + Alpha += weight[2] * tmp_alpha; + } + } + else if (projection == "sphere") { + 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, + extension); + } + else if (projection == "tube") { + point projected = map_to_tube(texco_remap_square(p)); + Color = image_texture_lookup(filename, + color_space, + projected[0], + projected[1], + Alpha, + use_alpha, + is_float, + interpolation, + extension); + } } |