diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2020-06-03 15:59:49 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2020-06-03 17:18:50 +0300 |
commit | 054923c8607c804a717cb5bb8ef15c0d4b151df3 (patch) | |
tree | 543cda2dc165bc032aba0c4bb754085414bd2594 /source | |
parent | 47bdb288412db819672b3b8345b18f36c4f96373 (diff) |
GPUMaterial: Rework/simplify environment texture filtering
This use the latest GPUTexture change to use the sampler state to avoid
the pole issues instead of using GLSL hacks.
Diffstat (limited to 'source')
3 files changed, 28 insertions, 49 deletions
diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_tex_environment.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_tex_environment.glsl index 9bd36f8a757..20a65f23c05 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_tex_environment.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_tex_environment.glsl @@ -15,16 +15,11 @@ void node_tex_environment_texco(vec3 viewvec, out vec3 worldvec) #endif } -void node_tex_environment_equirectangular(vec3 co, float clamp_size, sampler2D ima, out vec3 uv) +void node_tex_environment_equirectangular(vec3 co, out vec3 uv) { vec3 nco = normalize(co); 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_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, out vec3 uv) diff --git a/source/blender/gpu/shaders/material/gpu_shader_material_tex_image.glsl b/source/blender/gpu/shaders/material/gpu_shader_material_tex_image.glsl index c39bec8ac64..3a9fc49e8b8 100644 --- a/source/blender/gpu/shaders/material/gpu_shader_material_tex_image.glsl +++ b/source/blender/gpu/shaders/material/gpu_shader_material_tex_image.glsl @@ -54,19 +54,6 @@ 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 = safe_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); - color = safe_color(texelFetch(ima, pix, 0)); - alpha = color.a; -} - /** \param f: Signed distance to texel center. */ void cubic_bspline_coefs(vec2 f, out vec2 w0, out vec2 w1, out vec2 w2, out vec2 w3) { 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 a62c2ee22b2..0cf4b51f307 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c @@ -19,6 +19,8 @@ #include "../node_shader_util.h" +#include "GPU_draw.h" + /* **************** OUTPUT ******************** */ static bNodeSocketTemplate sh_node_tex_environment_in[] = { @@ -56,7 +58,10 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat, bNode *node_original = node->original ? node->original : node; NodeTexImage *tex_original = node_original->storage; ImageUser *iuser = &tex_original->iuser; - eGPUSamplerState sampler_state = GPU_SAMPLER_MAX; + eGPUSamplerState sampler = GPU_SAMPLER_REPEAT | GPU_SAMPLER_ANISO | GPU_SAMPLER_FILTER; + if (GPU_get_mipmap()) { + sampler |= GPU_SAMPLER_MIPMAP; + } GPUNodeLink *outalpha; @@ -73,49 +78,41 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat, /* 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(mat, ima, iuser, sampler_state), - &in[0].link); + GPU_link(mat, "node_tex_environment_equirectangular", in[0].link, &in[0].link); + /* To fix pole issue we clamp the v coordinate. */ + sampler &= ~GPU_SAMPLER_REPEAT_T; + /* Force the highest mipmap and don't do anisotropic filtering. + * This is to fix the artifact caused by derivatives discontinuity. */ + sampler &= ~(GPU_SAMPLER_MIPMAP | GPU_SAMPLER_ANISO); } else { GPU_link(mat, "node_tex_environment_mirror_ball", in[0].link, &in[0].link); + /* Fix pole issue. */ + sampler &= ~GPU_SAMPLER_REPEAT; } - /* Sample texture with correct interpolation. */ + const char *gpufunc; + static const char *names[] = { + "node_tex_image_linear", + "node_tex_image_cubic", + }; + 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(mat, ima, iuser, sampler_state), - &out[0].link, - &outalpha); + gpufunc = names[0]; break; case SHD_INTERP_CLOSEST: - GPU_link(mat, - "node_tex_image_nearest", - in[0].link, - GPU_image(mat, ima, iuser, sampler_state), - &out[0].link, - &outalpha); + sampler &= ~(GPU_SAMPLER_FILTER | GPU_SAMPLER_MIPMAP); + gpufunc = names[0]; break; default: - GPU_link(mat, - "node_tex_image_cubic", - in[0].link, - GPU_image(mat, ima, iuser, sampler_state), - &out[0].link, - &outalpha); + gpufunc = names[1]; break; } + /* Sample texture with correct interpolation. */ + GPU_link(mat, gpufunc, in[0].link, GPU_image(mat, ima, iuser, sampler), &out[0].link, &outalpha); + if (out[0].hasoutput) { if (ELEM(ima->alpha_mode, IMA_ALPHA_IGNORE, IMA_ALPHA_CHANNEL_PACKED) || IMB_colormanagement_space_name_is_data(ima->colorspace_settings.name)) { |