diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2018-07-20 20:16:33 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2018-07-20 20:17:15 +0300 |
commit | 28fa79219df8d103ccc4af9433c581be50ae2bc7 (patch) | |
tree | 85a304304b887664adda2b7317a2b94424dabdac /source/blender/gpu/shaders | |
parent | 26b6b5871ea83dea372495b56ac2768bb63e88b6 (diff) |
GPUMaterial: Texture Node: Add support for Cubic filtering
Like in cycles it's a bit more slower than linear but it's smoother.
Works for all projection type.
Diffstat (limited to 'source/blender/gpu/shaders')
-rw-r--r-- | source/blender/gpu/shaders/gpu_shader_material.glsl | 76 |
1 files changed, 74 insertions, 2 deletions
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 7f2475f0aab..961837f6b16 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -1813,7 +1813,61 @@ void node_tex_image_nearest(vec3 co, sampler2D ima, out vec4 color, out float al void node_tex_image_cubic(vec3 co, sampler2D ima, out vec4 color, out float alpha) { - node_tex_image_linear(co, ima, color, alpha); + vec2 tex_size = vec2(textureSize(ima, 0).xy); + + co.xy *= tex_size; + /* texel center */ + vec2 tc = floor(co.xy - 0.5) + 0.5; + vec2 f = co.xy - tc; + vec2 f2 = f * f; + vec2 f3 = f2 * f; + /* Bspline coefs (optimized) */ + vec2 w3 = f3 / 6.0; + vec2 w0 = -w3 + f2 * 0.5 - f * 0.5 + 1.0 / 6.0; + vec2 w1 = f3 * 0.5 - f2 * 1.0 + 2.0 / 3.0; + vec2 w2 = 1.0 - w0 - w1 - w3; + +#if 1 /* Optimized version using 4 filtered tap. */ + vec2 s0 = w0 + w1; + vec2 s1 = w2 + w3; + + vec2 f0 = w1 / (w0 + w1); + vec2 f1 = w3 / (w2 + w3); + + vec4 final_co; + final_co.xy = tc - 1.0 + f0; + final_co.zw = tc + 1.0 + f1; + + final_co /= tex_size.xyxy; + + color = texture(ima, final_co.xy) * s0.x * s0.y; + color += texture(ima, final_co.zy) * s1.x * s0.y; + color += texture(ima, final_co.xw) * s0.x * s1.y; + color += texture(ima, final_co.zw) * s1.x * s1.y; + +#else /* Reference bruteforce 16 tap. */ + color = texelFetch(ima, ivec2(tc + vec2(-1.0, -1.0)), 0) * w0.x * w0.y; + color += texelFetch(ima, ivec2(tc + vec2( 0.0, -1.0)), 0) * w1.x * w0.y; + color += texelFetch(ima, ivec2(tc + vec2( 1.0, -1.0)), 0) * w2.x * w0.y; + color += texelFetch(ima, ivec2(tc + vec2( 2.0, -1.0)), 0) * w3.x * w0.y; + + color += texelFetch(ima, ivec2(tc + vec2(-1.0, 0.0)), 0) * w0.x * w1.y; + color += texelFetch(ima, ivec2(tc + vec2( 0.0, 0.0)), 0) * w1.x * w1.y; + color += texelFetch(ima, ivec2(tc + vec2( 1.0, 0.0)), 0) * w2.x * w1.y; + color += texelFetch(ima, ivec2(tc + vec2( 2.0, 0.0)), 0) * w3.x * w1.y; + + color += texelFetch(ima, ivec2(tc + vec2(-1.0, 1.0)), 0) * w0.x * w2.y; + color += texelFetch(ima, ivec2(tc + vec2( 0.0, 1.0)), 0) * w1.x * w2.y; + color += texelFetch(ima, ivec2(tc + vec2( 1.0, 1.0)), 0) * w2.x * w2.y; + color += texelFetch(ima, ivec2(tc + vec2( 2.0, 1.0)), 0) * w3.x * w2.y; + + color += texelFetch(ima, ivec2(tc + vec2(-1.0, 2.0)), 0) * w0.x * w3.y; + color += texelFetch(ima, ivec2(tc + vec2( 0.0, 2.0)), 0) * w1.x * w3.y; + color += texelFetch(ima, ivec2(tc + vec2( 1.0, 2.0)), 0) * w2.x * w3.y; + color += texelFetch(ima, ivec2(tc + vec2( 2.0, 2.0)), 0) * w3.x * w3.y; +#endif + + alpha = color.a; } void node_tex_image_smart(vec3 co, sampler2D ima, out vec4 color, out float alpha) @@ -1886,7 +1940,25 @@ void tex_box_sample_cubic(vec3 texco, out vec4 color2, out vec4 color3) { - tex_box_sample_linear(texco, N, ima, color1, color2, color3); + float alpha; + /* X projection */ + vec2 uv = texco.yz; + if (N.x < 0.0) { + uv.x = 1.0 - uv.x; + } + node_tex_image_cubic(uv.xyy, ima, color1, alpha); + /* Y projection */ + uv = texco.xz; + if (N.y > 0.0) { + uv.x = 1.0 - uv.x; + } + node_tex_image_cubic(uv.xyy, ima, color2, alpha); + /* Z projection */ + uv = texco.yx; + if (N.z > 0.0) { + uv.x = 1.0 - uv.x; + } + node_tex_image_cubic(uv.xyy, ima, color3, alpha); } void tex_box_sample_smart(vec3 texco, |