Support all Cycles image texture projections in the GLSL viewport
This patch enables Tube, Sphere and Box projections in GLSL for the image texture node. Reviewers: sergey Projects: #nodes, #opengl_gfx Differential Revision: https://developer.blender.org/D2036
This commit is contained in:
@@ -218,6 +218,42 @@ void point_transform_m4v3(vec3 vin, mat4 mat, out vec3 vout)
|
||||
vout = (mat * vec4(vin, 1.0)).xyz;
|
||||
}
|
||||
|
||||
void point_texco_remap_square(vec3 vin, out vec3 vout)
|
||||
{
|
||||
vout = vec3(vin - vec3(0.5, 0.5, 0.5)) * 2.0;
|
||||
}
|
||||
|
||||
void point_map_to_sphere(vec3 vin, out vec3 vout)
|
||||
{
|
||||
float len = length(vin);
|
||||
float v, u;
|
||||
if (len > 0.0) {
|
||||
if (vin.x == 0.0 && vin.y == 0.0)
|
||||
u = 0.0;
|
||||
else
|
||||
u = (1.0 - atan(vin.x, vin.y) / M_PI) / 2.0;
|
||||
|
||||
v = 1.0 - acos(vin.z / len) / M_PI;
|
||||
}
|
||||
else
|
||||
v = u = 0.0;
|
||||
|
||||
vout = vec3(u, v, 0.0);
|
||||
}
|
||||
|
||||
void point_map_to_tube(vec3 vin, out vec3 vout)
|
||||
{
|
||||
float u, v;
|
||||
v = (vin.z + 1.0) * 0.5;
|
||||
float len = sqrt(vin.x * vin.x + vin.y * vin[1]);
|
||||
if (len > 0.0)
|
||||
u = (1.0 - (atan(vin.x / len, vin.y / len) / M_PI)) * 0.5;
|
||||
else
|
||||
v = u = 0.0;
|
||||
|
||||
vout = vec3(u, v, 0.0);
|
||||
}
|
||||
|
||||
void mapping(vec3 vec, mat4 mat, vec3 minvec, vec3 maxvec, float domin, float domax, out vec3 outvec)
|
||||
{
|
||||
outvec = (mat * vec4(vec, 1.0)).xyz;
|
||||
@@ -2872,6 +2908,82 @@ void node_tex_image(vec3 co, sampler2D ima, out vec4 color, out float alpha)
|
||||
alpha = color.a;
|
||||
}
|
||||
|
||||
void node_tex_image_box(vec3 texco,
|
||||
vec3 nob,
|
||||
sampler2D ima,
|
||||
float blend,
|
||||
out vec4 color,
|
||||
out float alpha)
|
||||
{
|
||||
/* project from direction vector to barycentric coordinates in triangles */
|
||||
nob = vec3(abs(nob.x), abs(nob.y), abs(nob.z));
|
||||
nob /= (nob.x + nob.y + nob.z);
|
||||
|
||||
/* 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 */
|
||||
|
||||
vec3 weight = vec3(0.0, 0.0, 0.0);
|
||||
float limit = 0.5 * (1.0 + blend);
|
||||
|
||||
/* first test for corners with single texture */
|
||||
if (nob.x > limit * (nob.x + nob.y) && nob.x > limit * (nob.x + nob.z)) {
|
||||
weight.x = 1.0;
|
||||
}
|
||||
else if (nob.y > limit * (nob.x + nob.y) && nob.y > limit * (nob.y + nob.z)) {
|
||||
weight.y = 1.0;
|
||||
}
|
||||
else if (nob.z > limit * (nob.x + nob.z) && nob.z > limit * (nob.y + nob.z)) {
|
||||
weight.z = 1.0;
|
||||
}
|
||||
else if (blend > 0.0) {
|
||||
/* in case of blending, test for mixes between two textures */
|
||||
if (nob.z < (1.0 - limit) * (nob.y + nob.x)) {
|
||||
weight.x = nob.x / (nob.x + nob.y);
|
||||
weight.x = clamp((weight.x - 0.5 * (1.0 - blend)) / blend, 0.0, 1.0);
|
||||
weight.y = 1.0 - weight.x;
|
||||
}
|
||||
else if (nob.x < (1.0 - limit) * (nob.y + nob.z)) {
|
||||
weight.y = nob.y / (nob.y + nob.z);
|
||||
weight.y = clamp((weight.y - 0.5 * (1.0 - blend)) / blend, 0.0, 1.0);
|
||||
weight.z = 1.0 - weight.y;
|
||||
}
|
||||
else if (nob.y < (1.0 - limit) * (nob.x + nob.z)) {
|
||||
weight.x = nob.x / (nob.x + nob.z);
|
||||
weight.x = clamp((weight.x - 0.5 * (1.0 - blend)) / blend, 0.0, 1.0);
|
||||
weight.z = 1.0 - weight.x;
|
||||
}
|
||||
else {
|
||||
/* last case, we have a mix between three */
|
||||
weight.x = ((2.0 - limit) * nob.x + (limit - 1.0)) / (2.0 * limit - 1.0);
|
||||
weight.y = ((2.0 - limit) * nob.y + (limit - 1.0)) / (2.0 * limit - 1.0);
|
||||
weight.z = ((2.0 - limit) * nob.z + (limit - 1.0)) / (2.0 * limit - 1.0);
|
||||
}
|
||||
}
|
||||
else {
|
||||
/* Desperate mode, no valid choice anyway, fallback to one side.*/
|
||||
weight.x = 1.0;
|
||||
}
|
||||
|
||||
if (weight.x > 0.0) {
|
||||
color += weight.x * texture2D(ima, texco.yz);
|
||||
}
|
||||
if (weight.y > 0.0) {
|
||||
color += weight.y * texture2D(ima, texco.xz);
|
||||
}
|
||||
if (weight.z > 0.0) {
|
||||
color += weight.z * texture2D(ima, texco.yx);
|
||||
}
|
||||
|
||||
alpha = color.a;
|
||||
}
|
||||
|
||||
void node_tex_image_empty(vec3 co, out vec4 color, out float alpha)
|
||||
{
|
||||
color = vec4(0.0);
|
||||
|
||||
Reference in New Issue
Block a user