diff options
author | Clément Foucault <foucault.clem@gmail.com> | 2018-07-20 16:45:59 +0300 |
---|---|---|
committer | Clément Foucault <foucault.clem@gmail.com> | 2018-07-20 20:16:48 +0300 |
commit | 26b6b5871ea83dea372495b56ac2768bb63e88b6 (patch) | |
tree | 26588d611df04213f9569637bc62381eccfa24c7 | |
parent | e7d8908f1405bbe54df2b5b51b4c1078200e5020 (diff) |
GPUMaterial: Texture Node: support for nearest (closest) filtering method
Add placeholder for cubic and smart filtering for now.
-rw-r--r-- | source/blender/gpu/shaders/gpu_shader_material.glsl | 72 | ||||
-rw-r--r-- | source/blender/nodes/shader/nodes/node_shader_tex_image.c | 34 |
2 files changed, 95 insertions, 11 deletions
diff --git a/source/blender/gpu/shaders/gpu_shader_material.glsl b/source/blender/gpu/shaders/gpu_shader_material.glsl index 4b376160105..7f2475f0aab 100644 --- a/source/blender/gpu/shaders/gpu_shader_material.glsl +++ b/source/blender/gpu/shaders/gpu_shader_material.glsl @@ -1798,13 +1798,31 @@ void node_tex_environment_empty(vec3 co, out vec4 color) color = vec4(1.0, 0.0, 1.0, 1.0); } -void node_tex_image(vec3 co, sampler2D ima, out vec4 color, out float alpha) +void node_tex_image_linear(vec3 co, sampler2D ima, out vec4 color, out float alpha) { color = texture(ima, co.xy); alpha = color.a; } -void tex_box_sample(vec3 texco, +void node_tex_image_nearest(vec3 co, sampler2D ima, out vec4 color, out float alpha) +{ + ivec2 pix = ivec2(co.xy * textureSize(ima, 0).xy); + color = texelFetch(ima, pix, 0); + alpha = color.a; +} + +void node_tex_image_cubic(vec3 co, sampler2D ima, out vec4 color, out float alpha) +{ + node_tex_image_linear(co, ima, color, alpha); +} + +void node_tex_image_smart(vec3 co, sampler2D ima, out vec4 color, out float alpha) +{ + /* use cubic for now */ + node_tex_image_cubic(co, ima, color, alpha); +} + +void tex_box_sample_linear(vec3 texco, vec3 N, sampler2D ima, out vec4 color1, @@ -1831,6 +1849,56 @@ void tex_box_sample(vec3 texco, color3 = texture(ima, uv); } +void tex_box_sample_nearest(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; + } + ivec2 pix = ivec2(uv.xy * textureSize(ima, 0).xy); + color1 = texelFetch(ima, pix, 0); + /* Y projection */ + uv = texco.xz; + if (N.y > 0.0) { + uv.x = 1.0 - uv.x; + } + pix = ivec2(uv.xy * textureSize(ima, 0).xy); + color2 = texelFetch(ima, pix, 0); + /* Z projection */ + uv = texco.yx; + if (N.z > 0.0) { + uv.x = 1.0 - uv.x; + } + pix = ivec2(uv.xy * textureSize(ima, 0).xy); + color3 = texelFetch(ima, pix, 0); +} + +void tex_box_sample_cubic(vec3 texco, + vec3 N, + sampler2D ima, + out vec4 color1, + out vec4 color2, + out vec4 color3) +{ + tex_box_sample_linear(texco, N, ima, color1, color2, color3); +} + +void tex_box_sample_smart(vec3 texco, + vec3 N, + sampler2D ima, + out vec4 color1, + out vec4 color2, + out vec4 color3) +{ + tex_box_sample_cubic(texco, N, ima, color1, color2, color3); +} + void node_tex_image_box(vec3 texco, vec3 N, vec4 color1, 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 20753445aa6..9782df2638f 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_image.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.c @@ -55,9 +55,25 @@ static void node_shader_init_tex_image(bNodeTree *UNUSED(ntree), bNode *node) static int node_shader_gpu_tex_image(GPUMaterial *mat, bNode *node, bNodeExecData *UNUSED(execdata), GPUNodeStack *in, GPUNodeStack *out) { + static const char *names[] = { + "node_tex_image_linear", + "node_tex_image_nearest", + "node_tex_image_cubic", + "node_tex_image_smart" + }; + static const char *names_box[] = { + "tex_box_sample_linear", + "tex_box_sample_nearest", + "tex_box_sample_cubic", + "tex_box_sample_smart" + }; + Image *ima = (Image *)node->id; ImageUser *iuser = NULL; NodeTexImage *tex = node->storage; + const char *gpu_node_name = (tex->projection == SHD_PROJ_BOX) + ? names_box[tex->interpolation] + : names[tex->interpolation]; bool do_color_correction = false; GPUNodeLink *norm, *col1, *col2, *col3; @@ -84,7 +100,7 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat, bNode *node, bNodeExecDat switch (tex->projection) { case SHD_PROJ_FLAT: - GPU_stack_link(mat, node, "node_tex_image", in, out, GPU_image(ima, iuser, isdata)); + GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser, isdata)); break; case SHD_PROJ_BOX: GPU_link(mat, "direction_transform_m4v3", GPU_builtin(GPU_VIEW_NORMAL), @@ -93,12 +109,12 @@ 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); + GPU_link(mat, gpu_node_name, 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); @@ -115,12 +131,12 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat, bNode *node, bNodeExecDat case SHD_PROJ_SPHERE: GPU_link(mat, "point_texco_remap_square", in[0].link, &in[0].link); GPU_link(mat, "point_map_to_sphere", in[0].link, &in[0].link); - GPU_stack_link(mat, node, "node_tex_image", in, out, GPU_image(ima, iuser, isdata)); + GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser, isdata)); break; case SHD_PROJ_TUBE: GPU_link(mat, "point_texco_remap_square", in[0].link, &in[0].link); GPU_link(mat, "point_map_to_tube", in[0].link, &in[0].link); - GPU_stack_link(mat, node, "node_tex_image", in, out, GPU_image(ima, iuser, isdata)); + GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser, isdata)); break; } |