diff options
Diffstat (limited to 'source/blender/nodes')
-rw-r--r-- | source/blender/nodes/shader/nodes/node_shader_tex_environment.c | 14 | ||||
-rw-r--r-- | source/blender/nodes/shader/nodes/node_shader_tex_image.c | 147 |
2 files changed, 95 insertions, 66 deletions
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 6c380efe0b2..72ad5581050 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_environment.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_environment.c @@ -88,7 +88,7 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat, "node_tex_environment_equirectangular", in[0].link, GPU_constant(&clamp_size), - GPU_image(ima, iuser), + GPU_image(ima, iuser, 0), &in[0].link); } else { @@ -103,7 +103,7 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat, GPU_link(mat, "node_tex_image_linear_no_mip", in[0].link, - GPU_image(ima, iuser), + GPU_image(ima, iuser, 0), &out[0].link, &outalpha); break; @@ -111,13 +111,17 @@ static int node_shader_gpu_tex_environment(GPUMaterial *mat, GPU_link(mat, "node_tex_image_nearest", in[0].link, - GPU_image(ima, iuser), + GPU_image(ima, iuser, 0), &out[0].link, &outalpha); break; default: - GPU_link( - mat, "node_tex_image_cubic", in[0].link, GPU_image(ima, iuser), &out[0].link, &outalpha); + GPU_link(mat, + "node_tex_image_cubic", + in[0].link, + GPU_image(ima, iuser, 0), + &out[0].link, + &outalpha); break; } 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 c81f4f9853f..34a5e323490 100644 --- a/source/blender/nodes/shader/nodes/node_shader_tex_image.c +++ b/source/blender/nodes/shader/nodes/node_shader_tex_image.c @@ -74,6 +74,12 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat, "node_tex_image_cubic", "node_tex_image_smart", }; + static const char *names_tiled[] = { + "node_tex_tile_linear", + "node_tex_tile_nearest", + "node_tex_tile_cubic", + "node_tex_tile_smart", + }; static const char *names_box[] = { "tex_box_sample_linear", "tex_box_sample_nearest", @@ -123,70 +129,89 @@ static int node_shader_gpu_tex_image(GPUMaterial *mat, node_shader_gpu_tex_mapping(mat, node, in, out); - switch (tex->projection) { - case SHD_PROJ_FLAT: - if (do_texco_clip) { - /* This seems redundant, but is required to ensure the texco link - * is not freed by GPU_link, as it is still needed for GPU_stack_link. - * Intermediate links like this can only be used once and are then - * freed immediately, but if we make it the output link of a set_rgb - * node it will be kept and can be used multiple times. */ - GPU_link(mat, "set_rgb", *texco, texco); - GPU_link(mat, "set_rgb", *texco, &input_coords); - } - if (do_texco_extend) { - GPU_link(mat, "point_texco_clamp", *texco, GPU_image(ima, iuser), texco); - } - GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser)); - break; - - case SHD_PROJ_BOX: - vnor = GPU_builtin(GPU_WORLD_NORMAL); - ob_mat = GPU_builtin(GPU_OBJECT_MATRIX); - blend = GPU_uniform(&tex->projection_blend); - gpu_image = GPU_image(ima, iuser); - - /* equivalent to normal_world_to_object */ - GPU_link(mat, "normal_transform_transposed_m4v3", vnor, ob_mat, &norm); - GPU_link(mat, gpu_node_name, *texco, norm, GPU_image(ima, iuser), &col1, &col2, &col3); - GPU_stack_link( - mat, node, "node_tex_image_box", in, out, norm, col1, col2, col3, gpu_image, blend); - break; - - case SHD_PROJ_SPHERE: - GPU_link(mat, "point_texco_remap_square", *texco, texco); - GPU_link(mat, "point_map_to_sphere", *texco, texco); - if (do_texco_clip) { - /* See SHD_PROJ_FLAT for explanation. */ - GPU_link(mat, "set_rgb", *texco, texco); - GPU_link(mat, "set_rgb", *texco, &input_coords); - } - if (do_texco_extend) { - GPU_link(mat, "point_texco_clamp", *texco, GPU_image(ima, iuser), texco); - } - GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser)); - break; + if (ima->source == IMA_SRC_TILED) { + GPUNodeLink *map; + GPU_link(mat, "node_tex_tile_map", in[0].link, &out[0].link, &map); + /* This is not exactly great, but if we want to support different sizes per + * tile and older hardware, which rules out better methods like texture arrays. */ + LISTBASE_FOREACH (ImageTile *, tile, &ima->tiles) { + float tile_number = tile->tile_number; + GPU_link(mat, + names_tiled[tex->interpolation], + map, + GPU_uniform(&tile_number), + GPU_image(ima, iuser, tile->tile_number), + out[0].link, + &out[0].link, + &out[1].link); + } + } + else { + switch (tex->projection) { + case SHD_PROJ_FLAT: + if (do_texco_clip) { + /* This seems redundant, but is required to ensure the texco link + * is not freed by GPU_link, as it is still needed for GPU_stack_link. + * Intermediate links like this can only be used once and are then + * freed immediately, but if we make it the output link of a set_rgb + * node it will be kept and can be used multiple times. */ + GPU_link(mat, "set_rgb", *texco, texco); + GPU_link(mat, "set_rgb", *texco, &input_coords); + } + if (do_texco_extend) { + GPU_link(mat, "point_texco_clamp", *texco, GPU_image(ima, iuser, 0), texco); + } + GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser, 0)); + break; + + case SHD_PROJ_BOX: + vnor = GPU_builtin(GPU_WORLD_NORMAL); + ob_mat = GPU_builtin(GPU_OBJECT_MATRIX); + blend = GPU_uniform(&tex->projection_blend); + gpu_image = GPU_image(ima, iuser, 0); - case SHD_PROJ_TUBE: - GPU_link(mat, "point_texco_remap_square", *texco, texco); - GPU_link(mat, "point_map_to_tube", *texco, texco); + /* equivalent to normal_world_to_object */ + GPU_link(mat, "normal_transform_transposed_m4v3", vnor, ob_mat, &norm); + GPU_link(mat, gpu_node_name, *texco, norm, GPU_image(ima, iuser, 0), &col1, &col2, &col3); + GPU_stack_link( + mat, node, "node_tex_image_box", in, out, norm, col1, col2, col3, gpu_image, blend); + break; + + case SHD_PROJ_SPHERE: + GPU_link(mat, "point_texco_remap_square", *texco, texco); + GPU_link(mat, "point_map_to_sphere", *texco, texco); + if (do_texco_clip) { + /* See SHD_PROJ_FLAT for explanation. */ + GPU_link(mat, "set_rgb", *texco, texco); + GPU_link(mat, "set_rgb", *texco, &input_coords); + } + if (do_texco_extend) { + GPU_link(mat, "point_texco_clamp", *texco, GPU_image(ima, iuser, 0), texco); + } + GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser, 0)); + break; + + case SHD_PROJ_TUBE: + GPU_link(mat, "point_texco_remap_square", *texco, texco); + GPU_link(mat, "point_map_to_tube", *texco, texco); + if (do_texco_clip) { + /* See SHD_PROJ_FLAT for explanation. */ + GPU_link(mat, "set_rgb", *texco, texco); + GPU_link(mat, "set_rgb", *texco, &input_coords); + } + if (do_texco_extend) { + GPU_link(mat, "point_texco_clamp", *texco, GPU_image(ima, iuser, 0), texco); + } + GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser, 0)); + break; + } + + if (tex->projection != SHD_PROJ_BOX) { if (do_texco_clip) { - /* See SHD_PROJ_FLAT for explanation. */ - GPU_link(mat, "set_rgb", *texco, texco); - GPU_link(mat, "set_rgb", *texco, &input_coords); - } - if (do_texco_extend) { - GPU_link(mat, "point_texco_clamp", *texco, GPU_image(ima, iuser), texco); + gpu_node_name = names_clip[tex->interpolation]; + in[0].link = input_coords; + GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser, 0), out[0].link); } - GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser)); - break; - } - - if (tex->projection != SHD_PROJ_BOX) { - if (do_texco_clip) { - gpu_node_name = names_clip[tex->interpolation]; - in[0].link = input_coords; - GPU_stack_link(mat, node, gpu_node_name, in, out, GPU_image(ima, iuser), out[0].link); } } |