Browse Source

Integrated depth alpha rendering.

jcsyshc 1 year ago
parent
commit
ac6ab0e85e

+ 8 - 0
src/codec/scene_decoder.cpp

@@ -101,6 +101,14 @@ struct scene_decoder::impl {
         ret.material.diffuse =
                 to_glm<glm::vec3>(j["material.diffuse"]);
         ret.mesh = mesh_dec->decode(extra);
+
+        if (auto iter = j.find("alpha_factor"); iter != j.end()) {
+            ret.enable_depth_alpha = true;
+            ret.alpha_factor = iter->get<float>();
+        } else {
+            ret.enable_depth_alpha = false;
+        }
+
         return ret;
     }
 

+ 3 - 0
src/codec/scene_encoder.cpp

@@ -46,6 +46,9 @@ namespace scene_encoder_impl {
         auto ret = json();
         ret["material.ambient"] = glm_to_json(info.material.ambient);
         ret["material.diffuse"] = glm_to_json(info.material.diffuse);
+        if (info.enable_depth_alpha) {
+            ret["alpha_factor"] = info.alpha_factor;
+        }
         return ret;
     }
 

+ 6 - 0
src/module/impl/augment_manager_v2.cpp

@@ -84,6 +84,8 @@ void augment_manager_v2::impl::update(const camera_info &info, bool no_commit) {
             case ITEM_MESH: {
                 auto mesh_info = scene_render_info::mesh_info{
                         .mesh = OBJ_QUERY(mesh_ptr, item.name),
+                        .enable_depth_alpha = item.enable_depth_alpha,
+                        .alpha_factor = item.alpha_factor,
                 };
                 mesh_info.material = {
                         .ambient = item.color * item.ambient_factor,
@@ -145,6 +147,10 @@ void augment_manager_v2::impl::show() {
             }
 
             if (item.type == ITEM_MESH) {
+                ImGui::Checkbox("Depth Alpha", &item.enable_depth_alpha);
+                if (item.enable_depth_alpha) {
+                    ImGui::DragFloat("Alpha Factor", &item.alpha_factor, 0.005f, 0.0f, 1.0f);
+                }
                 ImGui::DragFloat("Ambient Factor", &item.ambient_factor, 0.005f, 0.0f, 1.0f);
             }
 

+ 3 - 0
src/module/impl/augment_manager_v2_impl.h

@@ -21,6 +21,9 @@ struct augment_manager_v2::impl {
         // for mesh
         float ambient_factor = 0.5f;
 
+        bool enable_depth_alpha = false;
+        float alpha_factor = 0.1;
+
         // for pc
         float point_size = 1.0f;
 

+ 1 - 0
src/module/impl/camera_augment_helper_v2.cpp

@@ -299,6 +299,7 @@ void camera_augment_helper_v2::impl::cursor_guide_slot(const scene_ptr &info) {
         auto item_info = scene_render_info::mesh_info{
                 .mesh = cursor_symbol,
                 .material = {.ambient = color * amb_factor, .diffuse = color,},
+                .enable_depth_alpha = true, .alpha_factor = 0.f,
         };
         info->items.push_back(
                 {.info = item_info, .transform = glm::translate(*cursor_pos),});

+ 31 - 0
src/render/impl/render_mesh.cpp

@@ -1,4 +1,5 @@
 #include "render_mesh_impl.h"
+#include "render/render_texture.h"
 
 #include <assimp/postprocess.h>
 
@@ -17,6 +18,11 @@ namespace render_mesh_impl {
 
     mesh_cache_type mesh_cache;
 
+    using fbo_conf_type =
+            smart_frame_buffer::create_config;
+    fbo_conf_type fbo_conf = {};
+    smart_frame_buffer mesh_fbo;
+
 }
 
 mesh_type::gl_info_type::~gl_info_type() {
@@ -240,6 +246,27 @@ namespace render_mesh_impl {
         draw_mesh(info.model.mesh);
     }
 
+    void ren_mesh_depth_alpha(const mesh_render_info &info) {
+        auto &extra = info.extra.depth_alpha;
+        assert(extra.bg.mesh == nullptr);
+
+        fbo_conf.size = query_viewport_size();
+        mesh_fbo.create(fbo_conf);
+        mesh_fbo.bind();
+        ren_mesh_normal(info);
+        mesh_fbo.unbind();
+
+        auto tex_info = tex_render_info();
+        tex_info.mode = TEX_COLOR_DEPTH;
+        tex_info.color.id = mesh_fbo.color_tex[0].id;
+        tex_info.depth.id = mesh_fbo.depth_tex.id;
+        tex_info.depth.enable_alpha_effect = true;
+        auto &tex_extra = tex_info.extra.color_depth;
+        tex_extra.proj_mat = info.camera.project;
+        tex_extra.alpha_factor = extra.alpha_factor;
+        render_texture(tex_info);
+    }
+
 }
 
 void render_mesh(const mesh_render_info &info) {
@@ -248,6 +275,10 @@ void render_mesh(const mesh_render_info &info) {
             ren_mesh_normal(info);
             break;
         }
+        case MESH_DEPTH_ALPHA: {
+            ren_mesh_depth_alpha(info);
+            break;
+        }
         default: {
             RET_ERROR;
         }

+ 2 - 0
src/render/impl/render_mesh_impl.h

@@ -18,6 +18,8 @@ namespace render_mesh_impl {
             std::unordered_map<std::string, std::shared_ptr<mesh_type>>;
     extern mesh_cache_type mesh_cache;
 
+    // used for depth alpha rendering
+    extern smart_frame_buffer mesh_fbo;
 }
 
 using namespace render_mesh_impl;

+ 8 - 0
src/render/impl/render_scene.cpp

@@ -37,6 +37,14 @@ namespace render_scene_impl {
                 .camera = req.camera,
                 .light= req.light,
         };
+
+        // depth alpha
+        if (info.enable_depth_alpha) {
+            ren_conf.mode = MESH_DEPTH_ALPHA;
+            auto &extra = ren_conf.extra.depth_alpha;
+            extra.alpha_factor = info.alpha_factor;
+        }
+
         render_mesh(ren_conf);
     }
 

+ 64 - 8
src/render/impl/render_texture.cpp

@@ -13,14 +13,13 @@ namespace render_texture_impl {
     bool init_ok = false;
 
     using pg_type = std::unique_ptr<smart_program>;
-    pg_type pg_bw; // render black/white texture
-    pg_type pg_rgb; // render rgb texture
-    pg_type pg_rgba; // render rgba texture
+    pg_type pg_bw;    // render black/white texture
+    pg_type pg_rgb;   // render rgb texture
+    pg_type pg_rgba;  // render rgba texture
     pg_type pg_rgb_d; // render rgb and depth texture
-    pg_type pg_nv12; // render nv12 textures
-//    pg_type pg_depth_only;
-//    pg_type pg_color_depth;
-//    pg_type pg_depth_alpha;
+    pg_type pg_rgbd2; // render rgb and depth texture (use depth alpha)
+    pg_type pg_nv12;  // render nv12 textures
+    pg_type pg_d;     // render depth only
 
     void init_buffers() {
         assert(!init_ok);
@@ -75,6 +74,26 @@ namespace render_texture_impl {
         glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_INT, nullptr);
     }
 
+    void ren_d_only(const tex_render_info &info) {
+        auto &pg = pg_d;
+        if (pg == nullptr) {
+            pg = std::unique_ptr<smart_program>(
+                    smart_program::create("tex_d",
+                                          {{GL_VERTEX_SHADER,   "tex.vert"},
+                                           {GL_FRAGMENT_SHADER, "tex_d.frag"}}));
+        }
+        assert(pg != nullptr);
+        pg->use();
+
+        glActiveTexture(GL_TEXTURE0 + 0);
+        glBindTexture(GL_TEXTURE_2D, info.depth.id);
+        pg->set_uniform_i("d_tex", 0);
+
+        glEnable(GL_DEPTH_TEST);
+        config_buffers(info);
+        draw();
+    }
+
     // render bw texture
     void ren_bw_only(const tex_render_info &info) {
         auto &pg = pg_bw;
@@ -168,6 +187,35 @@ namespace render_texture_impl {
         draw();
     }
 
+    void ren_rgb_d_v2(const tex_render_info &info) {
+        auto &pg = pg_rgbd2;
+        if (pg == nullptr) {
+            pg = std::unique_ptr<smart_program>(
+                    smart_program::create("tex_rgb_d_v2",
+                                          {{GL_VERTEX_SHADER,   "tex.vert"},
+                                           {GL_FRAGMENT_SHADER, "tex_rgb_d_v2.frag"}}));
+        }
+        assert(pg != nullptr);
+        pg->use();
+
+        auto &extra = info.extra.color_depth;
+        pg->set_uniform_f("opacity", info.color.alpha);
+        pg->set_uniform_f("alpha_factor", extra.alpha_factor);
+        pg->set_uniform_mat4("proj_inv",
+                             glm::inverse(extra.proj_mat));
+
+        glActiveTexture(GL_TEXTURE0 + 0);
+        glBindTexture(GL_TEXTURE_2D, info.color.id);
+        pg->set_uniform_i("c_tex", 0);
+        glActiveTexture(GL_TEXTURE0 + 1);
+        glBindTexture(GL_TEXTURE_2D, info.depth.id);
+        pg->set_uniform_i("d_tex", 1);
+
+        glDisable(GL_DEPTH_TEST);
+        config_buffers(info);
+        draw();
+    }
+
     void ren_nv12_only(const tex_render_info &info) {
         auto &pg = pg_nv12;
         if (pg == nullptr) {
@@ -221,7 +269,11 @@ namespace render_texture_impl {
     void ren_c_d(const tex_render_info &info) {
         switch (info.color.fmt) {
             case COLOR_RGB: {
-                ren_rgb_d(info);
+                if (info.depth.enable_alpha_effect) {
+                    ren_rgb_d_v2(info);
+                } else {
+                    ren_rgb_d(info);
+                }
                 break;
             }
             default: {
@@ -240,6 +292,10 @@ void render_texture(const tex_render_info &info) {
             ren_c_only(info);
             break;
         }
+        case TEX_DEPTH_ONLY: {
+            ren_d_only(info);
+            break;
+        }
         case TEX_COLOR_DEPTH: {
             ren_c_d(info);
             break;

+ 4 - 0
src/render/impl/render_texturer_impl.h

@@ -5,6 +5,8 @@
 
 namespace render_texture_impl {
 
+    void ren_d_only(const tex_render_info &info);
+
     void ren_bw_only(const tex_render_info &info);
 
     void ren_rgb_only(const tex_render_info &info);
@@ -13,6 +15,8 @@ namespace render_texture_impl {
 
     void ren_rgb_d(const tex_render_info &info);
 
+    void ren_rgb_d_v2(const tex_render_info &info);
+
     void ren_nv12_only(const tex_render_info &info);
 
     void ren_c_only(const tex_render_info &info);

+ 11 - 0
src/render/impl/shader/tex_d.frag

@@ -0,0 +1,11 @@
+#version 460
+
+uniform sampler2D d_tex; // depth texture
+
+in vec2 frag_uv;
+
+layout (depth_less) out float gl_FragDepth;
+
+void main() {
+    gl_FragDepth = texture(d_tex, frag_uv).x;
+}

+ 47 - 0
src/render/impl/shader/tex_rgb_d_v2.frag

@@ -0,0 +1,47 @@
+#version 460
+
+uniform float opacity;
+uniform float alpha_factor;
+
+uniform mat4 proj_inv;
+
+uniform sampler2D c_tex;// color texture
+uniform sampler2D d_tex;// depth texture
+
+in vec2 frag_uv;
+
+layout (location = 0) out vec4 frag_color;
+layout (depth_less) out float gl_FragDepth;
+
+vec3 ndc_to_camera(in vec3 ndc) {
+    vec4 position = proj_inv * vec4(ndc, 1.0);// NDC -> camera
+    return position.xyz / position.w;// homogeneous -> cartesian
+}
+
+vec3 tex_to_ndc(in vec3 coord) {
+    return 2 * coord - 1;
+}
+
+vec3 tex_to_camera(in vec3 coord) {
+    return ndc_to_camera(tex_to_ndc(coord));
+}
+
+void main() {
+    float cur_depth = texture(d_tex, frag_uv).x;
+    if (cur_depth == 1.0) return;
+
+    float alpha = opacity;
+    if (cur_depth > gl_FragDepth) {
+        vec3 cur_pos = tex_to_camera(vec3(frag_uv, cur_depth));
+        vec3 bg_pos  = tex_to_camera(vec3(frag_uv, gl_FragDepth));
+        float dis = distance(cur_pos, bg_pos);
+        alpha *= exp(-alpha_factor * dis);
+    } else {
+        gl_FragDepth = cur_depth;
+    }
+
+    frag_color.rgb = texture(c_tex, frag_uv).rgb;
+    frag_color.a = alpha;
+}
+
+// GL_DEPTH_TEST should be disabled.

+ 1 - 1
src/render/render_mesh.h

@@ -92,7 +92,7 @@ struct mesh_render_info {
         struct {
         } normal;
         struct {
-            mesh_info_type bg;
+            mesh_info_type bg; // if nullptr, depth buffer will be used.
             float alpha_factor;
             bool show_bg;
         } depth_alpha;

+ 2 - 0
src/render/render_scene.h

@@ -26,6 +26,8 @@ struct scene_render_info {
     struct mesh_info {
         mesh_ptr mesh = nullptr;
         material_type material = {};
+        bool enable_depth_alpha = false;
+        float alpha_factor = 0.1;
     };
 
     struct pc_info {

+ 2 - 3
src/render/render_texture.h

@@ -9,7 +9,6 @@ enum tex_render_mode {
     TEX_COLOR_ONLY = 0x1,
     TEX_DEPTH_ONLY = 0x2,
     TEX_COLOR_DEPTH = TEX_COLOR_ONLY | TEX_DEPTH_ONLY,
-    TEX_DEPTH_ALPHA
 };
 
 struct tex_render_info {
@@ -31,14 +30,14 @@ struct tex_render_info {
     // depth texture info
     struct {
         GLuint id = 0;
+        bool enable_alpha_effect = false;
     } depth;
 
     union {
         struct {
-            GLuint bg_id; // id of the background texture
             glm::mat4 proj_mat;
             GLfloat alpha_factor;
-        } depth_alpha;
+        } color_depth;
     } extra = {};
 };