[Bf-blender-cvs] [dd8016f7081] master: Fix T52652: Cycles image box mapping has flipped textures.

Brecht Van Lommel noreply at git.blender.org
Wed Sep 6 13:54:20 CEST 2017


Commit: dd8016f7081fb502b969b3c1f7512e00466879eb
Author: Brecht Van Lommel
Date:   Tue Sep 5 18:11:13 2017 +0200
Branches: master
https://developer.blender.org/rBdd8016f7081fb502b969b3c1f7512e00466879eb

Fix T52652: Cycles image box mapping has flipped textures.

This breaks backwards compatibility some in that 3 sides will be mapped
differently now, but difficult to avoid and can be considered a bugfix.

===================================================================

M	intern/cycles/kernel/svm/svm_image.h
M	source/blender/gpu/shaders/gpu_shader_material.glsl

===================================================================

diff --git a/intern/cycles/kernel/svm/svm_image.h b/intern/cycles/kernel/svm/svm_image.h
index 7be03dcd65a..6d6e92e73f6 100644
--- a/intern/cycles/kernel/svm/svm_image.h
+++ b/intern/cycles/kernel/svm/svm_image.h
@@ -211,6 +211,8 @@ ccl_device void svm_node_tex_image_box(KernelGlobals *kg, ShaderData *sd, float
 	object_inverse_normal_transform(kg, sd, &N);
 
 	/* project from direction vector to barycentric coordinates in triangles */
+	float3 signed_N = N;
+
 	N.x = fabsf(N.x);
 	N.y = fabsf(N.y);
 	N.z = fabsf(N.z);
@@ -280,12 +282,19 @@ ccl_device void svm_node_tex_image_box(KernelGlobals *kg, ShaderData *sd, float
 	float4 f = make_float4(0.0f, 0.0f, 0.0f, 0.0f);
 	uint use_alpha = stack_valid(alpha_offset);
 
-	if(weight.x > 0.0f)
-		f += weight.x*svm_image_texture(kg, id, co.y, co.z, srgb, use_alpha);
-	if(weight.y > 0.0f)
-		f += weight.y*svm_image_texture(kg, id, co.x, co.z, srgb, use_alpha);
-	if(weight.z > 0.0f)
-		f += weight.z*svm_image_texture(kg, id, co.y, co.x, srgb, use_alpha);
+	/* Map so that no textures are flipped, rotation is somewhat arbitrary. */
+	if(weight.x > 0.0f) {
+		float2 uv = make_float2((signed_N.x < 0.0f)? 1.0f - co.y: co.y, co.z);
+		f += weight.x*svm_image_texture(kg, id, uv.x, uv.y, srgb, use_alpha);
+	}
+	if(weight.y > 0.0f) {
+		float2 uv = make_float2((signed_N.y > 0.0f)? 1.0f - co.x: co.x, co.z);
+		f += weight.y*svm_image_texture(kg, id, uv.x, uv.y, srgb, use_alpha);
+	}
+	if(weight.z > 0.0f) {
+		float2 uv = make_float2((signed_N.z > 0.0f)? 1.0f - co.y: co.y, co.x);
+		f += weight.z*svm_image_texture(kg, id, uv.x, uv.y, srgb, use_alpha);
+	}
 
 	if(stack_valid(out_offset))
 		stack_store_float3(stack, out_offset, make_float3(f.x, f.y, f.z));
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index f14db57a26a..3dbecc58a7e 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -3116,15 +3116,17 @@ void node_tex_image(vec3 co, sampler2D ima, out vec4 color, out float alpha)
 }
 
 void node_tex_image_box(vec3 texco,
-                        vec3 nob,
+                        vec3 N,
                         sampler2D ima,
                         float blend,
                         out vec4 color,
                         out float alpha)
 {
+	vec3 signed_N = N;
+
 	/* 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);
+	N = vec3(abs(N.x), abs(N.y), abs(N.z));
+	N /= (N.x + N.y + N.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,
@@ -3140,37 +3142,37 @@ void node_tex_image_box(vec3 texco,
 	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)) {
+	if (N.x > limit * (N.x + N.y) && N.x > limit * (N.x + N.z)) {
 		weight.x = 1.0;
 	}
-	else if (nob.y > limit * (nob.x + nob.y) && nob.y > limit * (nob.y + nob.z)) {
+	else if (N.y > limit * (N.x + N.y) && N.y > limit * (N.y + N.z)) {
 		weight.y = 1.0;
 	}
-	else if (nob.z > limit * (nob.x + nob.z) && nob.z > limit * (nob.y + nob.z)) {
+	else if (N.z > limit * (N.x + N.z) && N.z > limit * (N.y + N.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);
+		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 (nob.x < (1.0 - limit) * (nob.y + nob.z)) {
-			weight.y = nob.y / (nob.y + nob.z);
+		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 (nob.y < (1.0 - limit) * (nob.x + nob.z)) {
-			weight.x = nob.x / (nob.x + nob.z);
+		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) * 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);
+			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 {
@@ -3179,13 +3181,25 @@ void node_tex_image_box(vec3 texco,
 	}
 	color = vec4(0);
 	if (weight.x > 0.0) {
-		color += weight.x * texture2D(ima, texco.yz);
+		vec2 uv = texco.yz;
+		if(signed_N.x < 0.0) {
+			uv.x = 1.0 - uv.x;
+		}
+		color += weight.x * texture2D(ima, uv);
 	}
 	if (weight.y > 0.0) {
-		color += weight.y * texture2D(ima, texco.xz);
+		vec2 uv = texco.xz;
+		if(signed_N.y > 0.0) {
+			uv.x = 1.0 - uv.x;
+		}
+		color += weight.y * texture2D(ima, uv);
 	}
 	if (weight.z > 0.0) {
-		color += weight.z * texture2D(ima, texco.yx);
+		vec2 uv = texco.yx;
+		if(signed_N.z > 0.0) {
+			uv.x = 1.0 - uv.x;
+		}
+		color += weight.z * texture2D(ima, uv);
 	}
 
 	alpha = color.a;



More information about the Bf-blender-cvs mailing list