[Bf-blender-cvs] [4f709152f4f] blender2.8: Eevee: Add support for interpolation options for Environment Texture nodes

Clément Foucault noreply at git.blender.org
Wed Nov 7 22:16:20 CET 2018


Commit: 4f709152f4f0140a03edd69c1a501dbd5cec4b55
Author: Clément Foucault
Date:   Wed Nov 7 22:14:18 2018 +0100
Branches: blender2.8
https://developer.blender.org/rB4f709152f4f0140a03edd69c1a501dbd5cec4b55

Eevee: Add support for interpolation options for Environment Texture nodes

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

M	source/blender/gpu/shaders/gpu_shader_material.glsl
M	source/blender/nodes/shader/nodes/node_shader_tex_environment.c

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

diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl
index 3983a8c3f32..1cc431fd89e 100644
--- a/source/blender/gpu/shaders/gpu_shader_material.glsl
+++ b/source/blender/gpu/shaders/gpu_shader_material.glsl
@@ -1975,37 +1975,27 @@ void node_tex_clouds(vec3 co, float size, out vec4 color, out float fac)
 	fac = 1.0;
 }
 
-void node_tex_environment_equirectangular(vec3 co, sampler2D ima, out vec4 color)
+void node_tex_environment_equirectangular(vec3 co, float clamp_size, sampler2D ima, out vec3 uv)
 {
 	vec3 nco = normalize(co);
-	float u = -atan(nco.y, nco.x) / (2.0 * M_PI) + 0.5;
-	float v = atan(nco.z, hypot(nco.x, nco.y)) / M_PI + 0.5;
+	uv.x = -atan(nco.y, nco.x) / (2.0 * M_PI) + 0.5;
+	uv.y = atan(nco.z, hypot(nco.x, nco.y)) / M_PI + 0.5;
 
 	/* Fix pole bleeding */
-	float half_width = 0.5 / float(textureSize(ima, 0).x);
-	v = clamp(v, half_width, 1.0 - half_width);
-
-	/* Fix u = 0 seam */
-	/* This is caused by texture filtering, since uv don't have smooth derivatives
-	 * at u = 0 or 2PI, hardware filtering is using the smallest mipmap for certain
-	 * texels. So we force the highest mipmap and don't do anisotropic filtering. */
-	color = textureLod(ima, vec2(u, v), 0.0);
+	float half_height = clamp_size / float(textureSize(ima, 0).y);
+	uv.y = clamp(uv.y, half_height, 1.0 - half_height);
+	uv.z = 0.0;
 }
 
-void node_tex_environment_mirror_ball(vec3 co, sampler2D ima, out vec4 color)
+void node_tex_environment_mirror_ball(vec3 co, out vec3 uv)
 {
 	vec3 nco = normalize(co);
-
 	nco.y -= 1.0;
 
 	float div = 2.0 * sqrt(max(-0.5 * nco.y, 0.0));
-	if (div > 0.0)
-		nco /= div;
+	nco /= max(1e-8, div);
 
-	float u = 0.5 * (nco.x + 1.0);
-	float v = 0.5 * (nco.z + 1.0);
-
-	color = texture(ima, vec2(u, v));
+	uv = 0.5 * nco.xzz + 0.5;
 }
 
 void node_tex_environment_empty(vec3 co, out vec4 color)
@@ -2019,6 +2009,12 @@ void node_tex_image_linear(vec3 co, sampler2D ima, out vec4 color, out float alp
 	alpha = color.a;
 }
 
+void node_tex_image_linear_no_mip(vec3 co, sampler2D ima, out vec4 color, out float alpha)
+{
+	color = textureLod(ima, co.xy, 0.0);
+	alpha = color.a;
+}
+
 void node_tex_image_nearest(vec3 co, sampler2D ima, out vec4 color, out float alpha)
 {
 	ivec2 pix = ivec2(fract(co.xy) * textureSize(ima, 0).xy);
diff --git a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
index 41860df5670..ab8ce456b05 100644
--- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
+++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c
@@ -57,27 +57,44 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat, bNode *node, bNodeE
 {
 	Image *ima = (Image *)node->id;
 	ImageUser *iuser = NULL;
-	NodeTexImage *tex = node->storage;
+	NodeTexEnvironment *tex = node->storage;
 	int isdata = tex->color_space == SHD_COLORSPACE_NONE;
+	GPUNodeLink *outalpha;
 
 	if (!ima)
 		return GPU_stack_link(mat, node, "node_tex_environment_empty", in, out);
 
 	if (!in[0].link) {
-		GPUMatType type = GPU_Material_get_type(mat);
-
-		if (type == GPU_MATERIAL_TYPE_MESH)
-			in[0].link = GPU_builtin(GPU_VIEW_POSITION);
-		else
-			GPU_link(mat, "background_transform_to_world", GPU_builtin(GPU_VIEW_POSITION), &in[0].link);
+		GPU_link(mat, "node_tex_environment_texco", GPU_builtin(GPU_VIEW_POSITION), &in[0].link);
 	}
 
 	node_shader_gpu_tex_mapping(mat, node, in, out);
 
-	if (tex->projection == SHD_PROJ_EQUIRECTANGULAR)
-		GPU_stack_link(mat, node, "node_tex_environment_equirectangular", in, out, GPU_image(ima, iuser, isdata));
-	else
-		GPU_stack_link(mat, node, "node_tex_environment_mirror_ball", in, out, GPU_image(ima, iuser, isdata));
+	/* Compute texture coordinate. */
+	if (tex->projection == SHD_PROJ_EQUIRECTANGULAR) {
+		/* To fix pole issue we clamp the v coordinate. The clamp value depends on the filter size. */
+		float clamp_size = (ELEM(tex->interpolation, SHD_INTERP_CUBIC, SHD_INTERP_SMART)) ? 1.5 : 0.5;
+		GPU_link(mat, "node_tex_environment_equirectangular", in[0].link, GPU_constant(&clamp_size),
+		                                                      GPU_image(ima, iuser, isdata), &in[0].link);
+	}
+	else {
+		GPU_link(mat, "node_tex_environment_mirror_ball", in[0].link, &in[0].link);
+	}
+
+	/* Sample texture with correct interpolation. */
+	switch (tex->interpolation) {
+		case SHD_INTERP_LINEAR:
+			/* Force the highest mipmap and don't do anisotropic filtering.
+			 * This is to fix the artifact caused by derivatives discontinuity. */
+			GPU_link(mat, "node_tex_image_linear_no_mip", in[0].link, GPU_image(ima, iuser, isdata), &out[0].link, &outalpha);
+			break;
+		case SHD_INTERP_CLOSEST:
+			GPU_link(mat, "node_tex_image_nearest", in[0].link, GPU_image(ima, iuser, isdata), &out[0].link, &outalpha);
+			break;
+		default:
+			GPU_link(mat, "node_tex_image_cubic", in[0].link, GPU_image(ima, iuser, isdata), &out[0].link, &outalpha);
+			break;
+	}
 
 	ImBuf *ibuf = BKE_image_acquire_ibuf(ima, iuser, NULL);
 	if (ibuf && (ibuf->colormanage_flag & IMB_COLORMANAGE_IS_DATA) == 0 &&



More information about the Bf-blender-cvs mailing list