Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorClément Foucault <foucault.clem@gmail.com>2020-06-08 11:58:45 +0300
committerClément Foucault <foucault.clem@gmail.com>2020-06-08 11:58:45 +0300
commit1f6d1213d27cbe3e50460aa6da54e0c7606f2216 (patch)
treee2c42891c2e76fc3f36ce62d9e81a2d4751c6f59 /source/blender/draw/engines/workbench
parent11ba9eec70175b39e34943c8ffacb54c35cbb897 (diff)
Workbench: Use eGPUSamplerState to change texture sampling behavior
This removes some fragment shader hacks and improve the support of different repeat & filtering modes. This fix T77453 Image texture not repeating in viewport
Diffstat (limited to 'source/blender/draw/engines/workbench')
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_image_lib.glsl62
-rw-r--r--source/blender/draw/engines/workbench/workbench_engine.c12
-rw-r--r--source/blender/draw/engines/workbench/workbench_materials.c32
-rw-r--r--source/blender/draw/engines/workbench/workbench_private.h2
4 files changed, 42 insertions, 66 deletions
diff --git a/source/blender/draw/engines/workbench/shaders/workbench_image_lib.glsl b/source/blender/draw/engines/workbench/shaders/workbench_image_lib.glsl
index e45f7a7b9e3..c5ad48191d1 100644
--- a/source/blender/draw/engines/workbench/shaders/workbench_image_lib.glsl
+++ b/source/blender/draw/engines/workbench/shaders/workbench_image_lib.glsl
@@ -4,17 +4,20 @@ bool node_tex_tile_lookup(inout vec3 co, sampler2DArray ima, sampler1DArray map)
{
vec2 tile_pos = floor(co.xy);
- if (tile_pos.x < 0 || tile_pos.y < 0 || tile_pos.x >= 10)
+ if (tile_pos.x < 0 || tile_pos.y < 0 || tile_pos.x >= 10) {
return false;
+ }
float tile = 10.0 * tile_pos.y + tile_pos.x;
- if (tile >= textureSize(map, 0).x)
+ if (tile >= textureSize(map, 0).x) {
return false;
+ }
/* Fetch tile information. */
float tile_layer = texelFetch(map, ivec2(tile, 0), 0).x;
- if (tile_layer < 0.0)
+ if (tile_layer < 0.0) {
return false;
+ }
vec4 tile_info = texelFetch(map, ivec2(tile, 1), 0);
@@ -22,59 +25,29 @@ bool node_tex_tile_lookup(inout vec3 co, sampler2DArray ima, sampler1DArray map)
return true;
}
-vec4 workbench_sample_texture(sampler2D image, vec2 coord, bool nearest_sampling)
-{
- /* TODO(fclem) We could do the same with sampler objects.
- * But this is a quick workaround instead of messing with the GPUTexture itself. */
- if (nearest_sampling) {
- /* Use texelFetch for nearest_sampling to reduce glitches. See: T73726 */
- vec2 tex_size = vec2(textureSize(image, 0).xy);
- ivec2 uv = ivec2(floor(coord * tex_size) + 0.5);
- return texelFetch(image, uv, 0);
- }
- else {
- return texture(image, coord);
- }
-}
-
-vec4 workbench_sample_texture_array(sampler2DArray tile_array,
- sampler1DArray tile_data,
- vec2 coord,
- bool nearest_sampling)
-{
-
- vec3 uv = vec3(coord, 0);
- if (!node_tex_tile_lookup(uv, tile_array, tile_data))
- return vec4(1.0, 0.0, 1.0, 1.0);
-
- /* TODO(fclem) We could do the same with sampler objects.
- * But this is a quick workaround instead of messing with the GPUTexture itself. */
- if (nearest_sampling) {
- /* Use texelFetch for nearest_sampling to reduce glitches. See: T73726 */
- vec3 tex_size = vec3(textureSize(tile_array, 0));
- uv.xy = floor(uv.xy * tex_size.xy) + 0.5;
- return texelFetch(tile_array, ivec3(uv), 0);
- }
- else {
- return texture(tile_array, uv);
- }
-}
-
uniform sampler2DArray imageTileArray;
uniform sampler1DArray imageTileData;
uniform sampler2D imageTexture;
uniform float imageTransparencyCutoff = 0.1;
-uniform bool imageNearest;
uniform bool imagePremult;
vec3 workbench_image_color(vec2 uvs)
{
#ifdef V3D_SHADING_TEXTURE_COLOR
+ vec4 color;
+
# ifdef TEXTURE_IMAGE_ARRAY
- vec4 color = workbench_sample_texture_array(imageTileArray, imageTileData, uvs, imageNearest);
+ vec3 co = vec3(uvs, 0.0);
+ if (node_tex_tile_lookup(co, imageTileArray, imageTileData)) {
+ color = texture(imageTileArray, co);
+ }
+ else {
+ color = vec4(1.0, 0.0, 1.0, 1.0);
+ }
# else
- vec4 color = workbench_sample_texture(imageTexture, uvs, imageNearest);
+
+ color = texture(imageTexture, uvs);
# endif
/* Unpremultiply if stored multiplied, since straight alpha is expected by shaders. */
@@ -90,6 +63,7 @@ vec3 workbench_image_color(vec2 uvs)
return color.rgb;
#else
+
return vec3(1.0);
#endif
}
diff --git a/source/blender/draw/engines/workbench/workbench_engine.c b/source/blender/draw/engines/workbench/workbench_engine.c
index 511dd563b46..bc5a2c14538 100644
--- a/source/blender/draw/engines/workbench/workbench_engine.c
+++ b/source/blender/draw/engines/workbench/workbench_engine.c
@@ -141,10 +141,10 @@ static void workbench_cache_texpaint_populate(WORKBENCH_PrivateData *wpd, Object
struct GPUBatch *geom = DRW_cache_mesh_surface_texpaint_single_get(ob);
if (geom) {
Image *ima = imapaint->canvas;
- int interp = (imapaint->interp == IMAGEPAINT_INTERP_LINEAR) ? SHD_INTERP_LINEAR :
- SHD_INTERP_CLOSEST;
+ eGPUSamplerState state = GPU_SAMPLER_REPEAT;
+ SET_FLAG_FROM_TEST(state, imapaint->interp == IMAGEPAINT_INTERP_LINEAR, GPU_SAMPLER_FILTER);
- DRWShadingGroup *grp = workbench_image_setup(wpd, ob, 0, ima, NULL, interp);
+ DRWShadingGroup *grp = workbench_image_setup(wpd, ob, 0, ima, NULL, state);
DRW_shgroup_call(grp, geom, ob);
}
}
@@ -210,10 +210,10 @@ static void workbench_cache_hair_populate(WORKBENCH_PrivateData *wpd,
const ImagePaintSettings *imapaint = use_texpaint_mode ? &scene->toolsettings->imapaint : NULL;
Image *ima = (imapaint && imapaint->mode == IMAGEPAINT_MODE_IMAGE) ? imapaint->canvas : NULL;
- int interp = (imapaint && imapaint->interp == IMAGEPAINT_INTERP_LINEAR) ? SHD_INTERP_LINEAR :
- SHD_INTERP_CLOSEST;
+ eGPUSamplerState state = 0;
+ SET_FLAG_FROM_TEST(state, imapaint->interp == IMAGEPAINT_INTERP_LINEAR, GPU_SAMPLER_FILTER);
DRWShadingGroup *grp = (use_texpaint_mode) ?
- workbench_image_hair_setup(wpd, ob, matnr, ima, NULL, interp) :
+ workbench_image_hair_setup(wpd, ob, matnr, ima, NULL, state) :
workbench_material_hair_setup(wpd, ob, matnr, color_type);
DRW_shgroup_hair_create_sub(ob, psys, md, grp);
diff --git a/source/blender/draw/engines/workbench/workbench_materials.c b/source/blender/draw/engines/workbench/workbench_materials.c
index b36a4a3a494..0b2d508fee5 100644
--- a/source/blender/draw/engines/workbench/workbench_materials.c
+++ b/source/blender/draw/engines/workbench/workbench_materials.c
@@ -101,31 +101,34 @@ BLI_INLINE Material *workbench_object_material_get(Object *ob, int mat_nr)
}
BLI_INLINE void workbench_material_get_image(
- Object *ob, int mat_nr, Image **r_image, ImageUser **r_iuser, int *r_interp)
+ Object *ob, int mat_nr, Image **r_image, ImageUser **r_iuser, eGPUSamplerState *r_sampler)
{
bNode *node;
+ *r_sampler = 0;
ED_object_get_active_image(ob, mat_nr, r_image, r_iuser, &node, NULL);
if (node && *r_image) {
switch (node->type) {
case SH_NODE_TEX_IMAGE: {
NodeTexImage *storage = node->storage;
- *r_interp = storage->interpolation;
+ const bool use_filter = (storage->interpolation != SHD_INTERP_CLOSEST);
+ const bool use_repeat = (storage->extension == SHD_IMAGE_EXTENSION_REPEAT);
+ const bool use_clip = (storage->extension == SHD_IMAGE_EXTENSION_CLIP);
+ SET_FLAG_FROM_TEST(*r_sampler, use_filter, GPU_SAMPLER_FILTER);
+ SET_FLAG_FROM_TEST(*r_sampler, use_repeat, GPU_SAMPLER_REPEAT);
+ SET_FLAG_FROM_TEST(*r_sampler, use_clip, GPU_SAMPLER_CLAMP_BORDER);
break;
}
case SH_NODE_TEX_ENVIRONMENT: {
NodeTexEnvironment *storage = node->storage;
- *r_interp = storage->interpolation;
+ const bool use_filter = (storage->interpolation != SHD_INTERP_CLOSEST);
+ SET_FLAG_FROM_TEST(*r_sampler, use_filter, GPU_SAMPLER_FILTER);
break;
}
default:
BLI_assert(!"Node type not supported by workbench");
- *r_interp = 0;
}
}
- else {
- *r_interp = 0;
- }
}
/* Return true if the current material ubo has changed and needs to be rebind. */
@@ -164,11 +167,11 @@ DRWShadingGroup *workbench_material_setup_ex(WORKBENCH_PrivateData *wpd,
{
Image *ima = NULL;
ImageUser *iuser = NULL;
- int interp;
+ eGPUSamplerState sampler;
const bool infront = (ob->dtx & OB_DRAWXRAY) != 0;
if (color_type == V3D_SHADING_TEXTURE_COLOR) {
- workbench_material_get_image(ob, mat_nr, &ima, &iuser, &interp);
+ workbench_material_get_image(ob, mat_nr, &ima, &iuser, &sampler);
if (ima == NULL) {
/* Fallback to material color. */
color_type = V3D_SHADING_MATERIAL_COLOR;
@@ -177,7 +180,7 @@ DRWShadingGroup *workbench_material_setup_ex(WORKBENCH_PrivateData *wpd,
switch (color_type) {
case V3D_SHADING_TEXTURE_COLOR: {
- return workbench_image_setup_ex(wpd, ob, mat_nr, ima, iuser, interp, hair);
+ return workbench_image_setup_ex(wpd, ob, mat_nr, ima, iuser, sampler, hair);
}
case V3D_SHADING_MATERIAL_COLOR: {
/* For now, we use the same ubo for material and object coloring but with different indices.
@@ -247,13 +250,13 @@ DRWShadingGroup *workbench_image_setup_ex(WORKBENCH_PrivateData *wpd,
int mat_nr,
Image *ima,
ImageUser *iuser,
- int interp,
+ eGPUSamplerState sampler,
bool hair)
{
GPUTexture *tex = NULL, *tex_tile_data = NULL;
if (ima == NULL) {
- workbench_material_get_image(ob, mat_nr, &ima, &iuser, &interp);
+ workbench_material_get_image(ob, mat_nr, &ima, &iuser, &sampler);
}
if (ima) {
@@ -284,13 +287,12 @@ DRWShadingGroup *workbench_image_setup_ex(WORKBENCH_PrivateData *wpd,
*grp_tex = grp = DRW_shgroup_create_sub(grp);
if (tex_tile_data) {
- DRW_shgroup_uniform_texture(grp, "imageTileArray", tex);
+ DRW_shgroup_uniform_texture_ex(grp, "imageTileArray", tex, sampler);
DRW_shgroup_uniform_texture(grp, "imageTileData", tex_tile_data);
}
else {
- DRW_shgroup_uniform_texture(grp, "imageTexture", tex);
+ DRW_shgroup_uniform_texture_ex(grp, "imageTexture", tex, sampler);
}
DRW_shgroup_uniform_bool_copy(grp, "imagePremult", (ima && ima->alpha_mode == IMA_ALPHA_PREMUL));
- DRW_shgroup_uniform_bool_copy(grp, "imageNearest", (interp == SHD_INTERP_CLOSEST));
return grp;
}
diff --git a/source/blender/draw/engines/workbench/workbench_private.h b/source/blender/draw/engines/workbench/workbench_private.h
index 967bdf9bae0..20b6d368ac0 100644
--- a/source/blender/draw/engines/workbench/workbench_private.h
+++ b/source/blender/draw/engines/workbench/workbench_private.h
@@ -462,7 +462,7 @@ DRWShadingGroup *workbench_image_setup_ex(WORKBENCH_PrivateData *wpd,
int mat_nr,
Image *ima,
ImageUser *iuser,
- int interp,
+ eGPUSamplerState sampler,
bool hair);
#define workbench_material_setup(wpd, ob, mat_nr, color_type, r_transp) \