[Bf-blender-cvs] [90298c24a2c] master: EEVEE & Viewport: Add a built-in shader called 3D_IMAGE, and expose to the python API

Shashank Shekhar noreply at git.blender.org
Mon May 9 08:07:41 CEST 2022


Commit: 90298c24a2cab088093006ef92a685d41c5a6ac2
Author: Shashank Shekhar
Date:   Mon May 9 08:07:28 2022 +0200
Branches: master
https://developer.blender.org/rB90298c24a2cab088093006ef92a685d41c5a6ac2

EEVEE & Viewport: Add a built-in shader called 3D_IMAGE, and expose to the python API

Adds an example python script to the documentation for the 3D_IMAGE shader.

The **use-case** is to draw textures with 3D vertex positions, in XR views as well as non-XR views (in a simpler manner).

**Testing**: I've tested that this compiles and works on my Macbook (with the example python script included in this change). I don't have access to a Windows or Linux machine right now, but this change doesn't look platform-specific and no new glsl shaders have been added or edited by this change. I'll try to get access to a Windows machine, but if someone does have one, I'd be really grateful if they could try this change. Thanks!

**Problem addressed**: The existing 2D_IMAGE shader (exposed in the python API) gets near-clipped when drawn in the
XR view, regardless of the near-clip settings. Additionally, the 2D_IMAGE shader only accepts 2D
positions for the image vertices, which means drawing textures in 3D requires providing
2D coordinates and then pushing a transform-rotate-scale matrix to the GPU, even for
non-XR (i.e. WINDOW) views. The 3D_IMAGE shader is simpler: it accepts 3D vertex positions, and doesn't require
any additional work by the scripter.

**Workaround**: The current workaround is to use custom shaders in the python script.

**Non-intrusive change**: No new glsl shaders were added. This change just bundles two existing shaders: the vertex shader used
by the 3D_IMAGE_MODULATE_ALPHA shader, and the fragment shader used by the 2D_IMAGE shader.

Reviewed By: #eevee_viewport, jbakker

Differential Revision: https://developer.blender.org/D14832

===================================================================

M	doc/python_api/examples/gpu.6.py
M	source/blender/gpu/CMakeLists.txt
M	source/blender/gpu/GPU_shader.h
M	source/blender/gpu/intern/gpu_shader_builtin.c
A	source/blender/gpu/shaders/infos/gpu_shader_3D_image_info.hh
M	source/blender/gpu/tests/gpu_shader_builtin_test.cc
M	source/blender/python/gpu/gpu_py_shader.c

===================================================================

diff --git a/doc/python_api/examples/gpu.6.py b/doc/python_api/examples/gpu.6.py
index be164a03028..5576b2d0bfe 100644
--- a/doc/python_api/examples/gpu.6.py
+++ b/doc/python_api/examples/gpu.6.py
@@ -29,3 +29,36 @@ def draw():
 
 
 bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_PIXEL')
+
+"""
+3D Image
+--------
+
+Similar to the 2D Image shader, but works with 3D positions for the image vertices.
+To use this example you have to provide an image that should be displayed.
+"""
+import bpy
+import gpu
+from gpu_extras.batch import batch_for_shader
+
+IMAGE_NAME = "Untitled"
+image = bpy.data.images[IMAGE_NAME]
+texture = gpu.texture.from_image(image)
+
+shader = gpu.shader.from_builtin('3D_IMAGE')
+batch = batch_for_shader(
+    shader, 'TRIS',
+    {
+        "pos": ((0, 0, 0), (0, 1, 1), (1, 1, 1), (1, 1, 1), (1, 0, 0), (0, 0, 0)),
+        "texCoord": ((0, 0), (0, 1), (1, 1), (1, 1), (1, 0), (0, 0)),
+    },
+)
+
+
+def draw():
+    shader.bind()
+    shader.uniform_sampler("image", texture)
+    batch.draw(shader)
+
+
+bpy.types.SpaceView3D.draw_handler_add(draw, (), 'WINDOW', 'POST_VIEW')
diff --git a/source/blender/gpu/CMakeLists.txt b/source/blender/gpu/CMakeLists.txt
index 5fee9167362..eac33f6c705 100644
--- a/source/blender/gpu/CMakeLists.txt
+++ b/source/blender/gpu/CMakeLists.txt
@@ -498,6 +498,7 @@ set(SRC_SHADER_CREATE_INFOS
   shaders/infos/gpu_shader_2D_widget_info.hh
   shaders/infos/gpu_shader_3D_depth_only_info.hh
   shaders/infos/gpu_shader_3D_flat_color_info.hh
+  shaders/infos/gpu_shader_3D_image_info.hh
   shaders/infos/gpu_shader_3D_image_modulate_alpha_info.hh
   shaders/infos/gpu_shader_3D_point_info.hh
   shaders/infos/gpu_shader_3D_polyline_info.hh
diff --git a/source/blender/gpu/GPU_shader.h b/source/blender/gpu/GPU_shader.h
index b620fe9cc9d..72a36ebfac4 100644
--- a/source/blender/gpu/GPU_shader.h
+++ b/source/blender/gpu/GPU_shader.h
@@ -279,6 +279,16 @@ typedef enum eGPUBuiltinShader {
   GPU_SHADER_2D_IMAGE_OVERLAYS_MERGE,
   GPU_SHADER_2D_IMAGE_OVERLAYS_STEREO_MERGE,
   GPU_SHADER_2D_IMAGE_SHUFFLE_COLOR,
+  /**
+   * Draw a texture in 3D. Take a 3D position and a 2D texture coordinate for each vertex.
+   *
+   * Exposed via pyapi for add-ons.
+   *
+   * \param image: uniform sampler2D
+   * \param texCoord: in vec2
+   * \param pos: in vec3
+   */
+  GPU_SHADER_3D_IMAGE,
   /**
    * Draw texture with alpha. Take a 3D position and a 2D texture coordinate for each vertex.
    *
diff --git a/source/blender/gpu/intern/gpu_shader_builtin.c b/source/blender/gpu/intern/gpu_shader_builtin.c
index 1100272b712..b92fae4a89b 100644
--- a/source/blender/gpu/intern/gpu_shader_builtin.c
+++ b/source/blender/gpu/intern/gpu_shader_builtin.c
@@ -150,6 +150,11 @@ static const GPUShaderStages builtin_shader_stages[GPU_SHADER_BUILTIN_LEN] = {
             .name = "GPU_SHADER_SIMPLE_LIGHTING",
             .create_info = "gpu_shader_simple_lighting",
         },
+    [GPU_SHADER_3D_IMAGE] =
+        {
+            .name = "GPU_SHADER_3D_IMAGE",
+            .create_info = "gpu_shader_3D_image",
+        },
     [GPU_SHADER_3D_IMAGE_MODULATE_ALPHA] =
         {
             .name = "GPU_SHADER_3D_IMAGE_MODULATE_ALPHA",
diff --git a/source/blender/gpu/shaders/infos/gpu_shader_3D_image_info.hh b/source/blender/gpu/shaders/infos/gpu_shader_3D_image_info.hh
new file mode 100644
index 00000000000..94cf58933af
--- /dev/null
+++ b/source/blender/gpu/shaders/infos/gpu_shader_3D_image_info.hh
@@ -0,0 +1,20 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later
+ * Copyright 2022 Blender Foundation. All rights reserved. */
+
+/** \file
+ * \ingroup gpu
+ */
+
+#include "gpu_interface_info.hh"
+#include "gpu_shader_create_info.hh"
+
+GPU_SHADER_CREATE_INFO(gpu_shader_3D_image)
+    .vertex_in(0, Type::VEC3, "pos")
+    .vertex_in(1, Type::VEC2, "texCoord")
+    .vertex_out(smooth_tex_coord_interp_iface)
+    .fragment_out(0, Type::VEC4, "fragColor")
+    .push_constant(Type::MAT4, "ModelViewProjectionMatrix")
+    .sampler(0, ImageType::FLOAT_2D, "image")
+    .vertex_source("gpu_shader_3D_image_vert.glsl")
+    .fragment_source("gpu_shader_image_frag.glsl")
+    .do_static_compilation(true);
diff --git a/source/blender/gpu/tests/gpu_shader_builtin_test.cc b/source/blender/gpu/tests/gpu_shader_builtin_test.cc
index 6ef8a032a73..5dc70a8bf0f 100644
--- a/source/blender/gpu/tests/gpu_shader_builtin_test.cc
+++ b/source/blender/gpu/tests/gpu_shader_builtin_test.cc
@@ -35,6 +35,7 @@ static void test_shader_builtin()
   test_compile_builtin_shader(GPU_SHADER_2D_UNIFORM_COLOR, GPU_SHADER_CFG_DEFAULT);
   test_compile_builtin_shader(GPU_SHADER_2D_FLAT_COLOR, GPU_SHADER_CFG_DEFAULT);
   test_compile_builtin_shader(GPU_SHADER_2D_SMOOTH_COLOR, GPU_SHADER_CFG_DEFAULT);
+  test_compile_builtin_shader(GPU_SHADER_3D_IMAGE, GPU_SHADER_CFG_DEFAULT);
   test_compile_builtin_shader(GPU_SHADER_2D_IMAGE, GPU_SHADER_CFG_DEFAULT);
   test_compile_builtin_shader(GPU_SHADER_2D_IMAGE_COLOR, GPU_SHADER_CFG_DEFAULT);
   test_compile_builtin_shader(GPU_SHADER_2D_IMAGE_DESATURATE_COLOR, GPU_SHADER_CFG_DEFAULT);
diff --git a/source/blender/python/gpu/gpu_py_shader.c b/source/blender/python/gpu/gpu_py_shader.c
index 77333c6dfea..80c48e31510 100644
--- a/source/blender/python/gpu/gpu_py_shader.c
+++ b/source/blender/python/gpu/gpu_py_shader.c
@@ -46,6 +46,9 @@
   "``3D_FLAT_COLOR``\n" \
   "   :Attributes: vec3 pos, vec4 color\n" \
   "   :Uniforms: none\n" \
+  "``3D_IMAGE``\n" \
+  "   :Attributes: vec3 pos, vec2 texCoord\n" \
+  "   :Uniforms: sampler2D image\n" \
   "``3D_SMOOTH_COLOR``\n" \
   "   :Attributes: vec3 pos, vec4 color\n" \
   "   :Uniforms: none\n" \
@@ -68,6 +71,7 @@ static const struct PyC_StringEnumItems pygpu_shader_builtin_items[] = {
     {GPU_SHADER_2D_SMOOTH_COLOR, "2D_SMOOTH_COLOR"},
     {GPU_SHADER_2D_UNIFORM_COLOR, "2D_UNIFORM_COLOR"},
     {GPU_SHADER_3D_FLAT_COLOR, "3D_FLAT_COLOR"},
+    {GPU_SHADER_3D_IMAGE, "3D_IMAGE"},
     {GPU_SHADER_3D_SMOOTH_COLOR, "3D_SMOOTH_COLOR"},
     {GPU_SHADER_3D_UNIFORM_COLOR, "3D_UNIFORM_COLOR"},
     {GPU_SHADER_3D_POLYLINE_FLAT_COLOR, "3D_POLYLINE_FLAT_COLOR"},



More information about the Bf-blender-cvs mailing list