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:
Diffstat (limited to 'source/blender/draw/engines/workbench/shaders/workbench_image_lib.glsl')
-rw-r--r--source/blender/draw/engines/workbench/shaders/workbench_image_lib.glsl83
1 files changed, 83 insertions, 0 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
new file mode 100644
index 00000000000..6f99739f259
--- /dev/null
+++ b/source/blender/draw/engines/workbench/shaders/workbench_image_lib.glsl
@@ -0,0 +1,83 @@
+
+/* TODO(fclem) deduplicate code. */
+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)
+ return false;
+
+ float tile = 10.0 * tile_pos.y + tile_pos.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)
+ return false;
+
+ vec4 tile_info = texelFetch(map, ivec2(tile, 1), 0);
+
+ co = vec3(((co.xy - tile_pos) * tile_info.zw) + tile_info.xy, tile_layer);
+ return true;
+}
+
+vec4 workbench_sample_texture(sampler2D image, vec2 coord, bool nearest_sampling)
+{
+ vec2 tex_size = vec2(textureSize(image, 0).xy);
+ /* TODO(fclem) We could do the same with sampler objects.
+ * But this is a quick workaround instead of messing with the GPUTexture itself. */
+ vec2 uv = nearest_sampling ? (floor(coord * tex_size) + 0.5) / tex_size : coord;
+ return texture(image, uv);
+}
+
+vec4 workbench_sample_texture_array(sampler2DArray tile_array,
+ sampler1DArray tile_data,
+ vec2 coord,
+ bool nearest_sampling)
+{
+ vec2 tex_size = vec2(textureSize(tile_array, 0).xy);
+
+ 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. */
+ uv.xy = nearest_sampling ? (floor(uv.xy * tex_size) + 0.5) / tex_size : uv.xy;
+ 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
+# ifdef TEXTURE_IMAGE_ARRAY
+ vec4 color = workbench_sample_texture_array(imageTileArray, imageTileData, uvs, imageNearest);
+# else
+ vec4 color = workbench_sample_texture(imageTexture, uvs, imageNearest);
+# endif
+
+ /* Unpremultiply if stored multiplied, since straight alpha is expected by shaders. */
+ if (imagePremult && !(color.a == 0.0 || color.a == 1.0)) {
+ color.rgb /= color.a;
+ }
+
+# ifdef GPU_FRAGMENT_SHADER
+ if (color.a < imageTransparencyCutoff) {
+ discard;
+ }
+# endif
+
+ return color.rgb;
+#else
+ return vec3(1.0);
+#endif
+}