Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
Diffstat (limited to 'source/blender')
-rw-r--r--source/blender/gpu/shaders/gpu_shader_material.glsl116
-rw-r--r--source/blender/nodes/shader/nodes/node_shader_tex_image.c31
2 files changed, 78 insertions, 69 deletions
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index d1183c792f5..4b376160105 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -1804,18 +1804,46 @@ void node_tex_image(vec3 co, sampler2D ima, out vec4 color, out float alpha)
alpha = color.a;
}
+void tex_box_sample(vec3 texco,
+ vec3 N,
+ sampler2D ima,
+ out vec4 color1,
+ out vec4 color2,
+ out vec4 color3)
+{
+ /* X projection */
+ vec2 uv = texco.yz;
+ if (N.x < 0.0) {
+ uv.x = 1.0 - uv.x;
+ }
+ color1 = texture(ima, uv);
+ /* Y projection */
+ uv = texco.xz;
+ if (N.y > 0.0) {
+ uv.x = 1.0 - uv.x;
+ }
+ color2 = texture(ima, uv);
+ /* Z projection */
+ uv = texco.yx;
+ if (N.z > 0.0) {
+ uv.x = 1.0 - uv.x;
+ }
+ color3 = texture(ima, uv);
+}
+
void node_tex_image_box(vec3 texco,
vec3 N,
+ vec4 color1,
+ vec4 color2,
+ vec4 color3,
sampler2D ima,
float blend,
out vec4 color,
out float alpha)
{
- vec3 signed_N = N;
-
/* project from direction vector to barycentric coordinates in triangles */
- N = vec3(abs(N.x), abs(N.y), abs(N.z));
- N /= (N.x + N.y + N.z);
+ N = abs(N);
+ N /= dot(N, vec3(1.0));
/* 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,
@@ -1825,72 +1853,36 @@ void node_tex_image_box(vec3 texco,
* 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 */
+ * 7 zones, with an if () test for each zone
+ * EDIT: Now there is only 4 if's. */
- vec3 weight = vec3(0.0, 0.0, 0.0);
- float limit = 0.5 * (1.0 + blend);
+ float limit = 0.5 + 0.5 * blend;
- /* first test for corners with single texture */
- if (N.x > limit * (N.x + N.y) && N.x > limit * (N.x + N.z)) {
- weight.x = 1.0;
- }
- else if (N.y > limit * (N.x + N.y) && N.y > limit * (N.y + N.z)) {
- weight.y = 1.0;
+ vec3 weight;
+ weight.x = N.x / (N.x + N.y);
+ weight.y = N.y / (N.y + N.z);
+ weight.z = N.z / (N.x + N.z);
+ weight = clamp((weight - 0.5 * (1.0 - blend)) / max(1e-8, blend), 0.0, 1.0);
+
+ /* test for mixes between two textures */
+ if (N.z < (1.0 - limit) * (N.y + N.x)) {
+ weight.z = 0.0;
+ weight.y = 1.0 - weight.x;
}
- else if (N.z > limit * (N.x + N.z) && N.z > limit * (N.y + N.z)) {
- weight.z = 1.0;
+ else if (N.x < (1.0 - limit) * (N.y + N.z)) {
+ weight.x = 0.0;
+ weight.z = 1.0 - weight.y;
}
- else if (blend > 0.0) {
- /* in case of blending, test for mixes between two textures */
- if (N.z < (1.0 - limit) * (N.y + N.x)) {
- weight.x = N.x / (N.x + N.y);
- weight.x = clamp((weight.x - 0.5 * (1.0 - blend)) / blend, 0.0, 1.0);
- weight.y = 1.0 - weight.x;
- }
- else if (N.x < (1.0 - limit) * (N.y + N.z)) {
- weight.y = N.y / (N.y + N.z);
- weight.y = clamp((weight.y - 0.5 * (1.0 - blend)) / blend, 0.0, 1.0);
- weight.z = 1.0 - weight.y;
- }
- else if (N.y < (1.0 - limit) * (N.x + N.z)) {
- weight.x = N.x / (N.x + N.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) * N.x + (limit - 1.0)) / (2.0 * limit - 1.0);
- weight.y = ((2.0 - limit) * N.y + (limit - 1.0)) / (2.0 * limit - 1.0);
- weight.z = ((2.0 - limit) * N.z + (limit - 1.0)) / (2.0 * limit - 1.0);
- }
+ else if (N.y < (1.0 - limit) * (N.x + N.z)) {
+ weight.y = 0.0;
+ weight.x = 1.0 - weight.z;
}
else {
- /* Desperate mode, no valid choice anyway, fallback to one side.*/
- weight.x = 1.0;
- }
- color = vec4(0);
- if (weight.x > 0.0) {
- vec2 uv = texco.yz;
- if(signed_N.x < 0.0) {
- uv.x = 1.0 - uv.x;
- }
- color += weight.x * texture(ima, uv);
- }
- if (weight.y > 0.0) {
- vec2 uv = texco.xz;
- if(signed_N.y > 0.0) {
- uv.x = 1.0 - uv.x;
- }
- color += weight.y * texture(ima, uv);
- }
- if (weight.z > 0.0) {
- vec2 uv = texco.yx;
- if(signed_N.z > 0.0) {
- uv.x = 1.0 - uv.x;
- }
- color += weight.z * texture(ima, uv);
+ /* last case, we have a mix between three */
+ weight = ((2.0 - limit) * N + (limit - 1.0)) / max(1e-8, 2.0 * limit - 1.0);
}
+ color = weight.x * color1 + weight.y * color2 + weight.z * color3;
alpha = color.a;
}
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_image.c b/source/blender/nodes/shader/nodes/node_shader_tex_image.c
index 2bbe3617bee..20753445aa6 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_image.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.c
@@ -58,8 +58,9 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat, bNode *node, bNodeExecDat
Image *ima = (Image *)node->id;
ImageUser *iuser = NULL;
NodeTexImage *tex = node->storage;
+ bool do_color_correction = false;
- GPUNodeLink *norm;
+ GPUNodeLink *norm, *col1, *col2, *col3;
int isdata = tex->color_space == SHD_COLORSPACE_NONE;
float blend = tex->projection_blend;
@@ -67,6 +68,15 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat, bNode *node, bNodeExecDat
if (!ima)
return GPU_stack_link(mat, node, "node_tex_image_empty", in, out);
+ ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
+ if ((tex->color_space == SHD_COLORSPACE_COLOR) &&
+ ibuf && (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) == 0 &&
+ GPU_material_do_color_management(mat))
+ {
+ do_color_correction = true;
+ }
+ BKE_image_release_ibuf(ima, ibuf, NULL);
+
if (!in[0].link)
in[0].link = GPU_attribute(CD_MTFACE, "");
@@ -83,8 +93,20 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat, bNode *node, bNodeExecDat
GPU_link(mat, "direction_transform_m4v3", norm,
GPU_builtin(GPU_INVERSE_OBJECT_MATRIX),
&norm);
+ GPU_link(mat, "tex_box_sample", in[0].link,
+ norm,
+ GPU_image(ima, iuser, isdata),
+ &col1,
+ &col2,
+ &col3);
+ if (do_color_correction) {
+ GPU_link(mat, "srgb_to_linearrgb", col1, &col1);
+ GPU_link(mat, "srgb_to_linearrgb", col2, &col2);
+ GPU_link(mat, "srgb_to_linearrgb", col3, &col3);
+ }
GPU_link(mat, "node_tex_image_box", in[0].link,
norm,
+ col1, col2, col3,
GPU_image(ima, iuser, isdata),
GPU_uniform(&blend),
&out[0].link,
@@ -102,14 +124,9 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat, bNode *node, bNodeExecDat
break;
}
- ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
- if ((tex->color_space == SHD_COLORSPACE_COLOR) &&
- ibuf && (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) == 0 &&
- GPU_material_do_color_management(mat))
- {
+ if (do_color_correction && (tex->projection != SHD_PROJ_BOX)) {
GPU_link(mat, "srgb_to_linearrgb", out[0].link, &out[0].link);
}
- BKE_image_release_ibuf(ima, ibuf, NULL);
return true;
}