Blender如何优雅的使用OpenGL之UniformBuffer

本文详细解释了如何在Blender中使用OpenGL时,通过GPU_SHADER_CREATE_INFO宏创建ShaderCreateInfo结构体来管理uniform变量,包括Uniform_buf的使用和VertexInterfaceDeclare方法的编码。重点涉及Uniform的绑定信息和ShaderCreateInfo的配置过程。
部署运行你感兴趣的模型镜像

先说明一下Blender在使用OpenGL 的uniform时,需要通过在程序中生成相关的布局限定语句字符串,然后传递给对应的着色器程序,而存储对应uniform的名称和绑定点的信息的对象是一个ShaderCreateInfo结构体。

1.创建Uniform变量:

通过填充这个结构体来实现创建Uniform:

GPU_SHADER_CREATE_INFO(draw_view)
    .uniform_buf(DRW_VIEW_UBO_SLOT, "ViewMatrices", "drw_view_[DRW_VIEW_LEN]", Frequency::PASS)
    .define("drw_view", "drw_view_[drw_view_id]")
    .typedef_source("draw_shader_shared.h");

这段代码是使用GPU_SHADER_CREATE_INFO宏来创建着色器信息,并在其中指定变量的创建和数据来源。让我们逐步解释这个过程:

  1. GPU_SHADER_CREATE_INFO(draw_view):这是一个宏,用于创建一个ShaderCreateInfo结构体的实例,命名为draw_view。这个结构体用于存储着色器的相关信息。

  2. .uniform_buf(DRW_VIEW_UBO_SLOT, "ViewMatrices", "drw_view_[DRW_VIEW_LEN]", Frequency::PASS):这是在ShaderCreateInfo结构体中使用uniform_buf方法来设置uniform缓冲区的信息,具体含义和用法在之前的回答中已经解释过了。

  3. .define("drw_view", "drw_view_[drw_view_id]"):这是在ShaderCreateInfo结构体中使用define方法来定义一个宏。这个宏的作用是将"drw_view"替换为"drw_view_[drw_view_id]"。这样可以在着色器代码中使用宏来实现更灵活的变量命名。

  4. .typedef_source("draw_shader_shared.h"):这是在ShaderCreateInfo结构体中使用typedef_source方法来指定一个头文件。这个头文件中可能包含了一些类型定义或者其他的预处理指令,可以在着色器代码中使用。

GPU_SHADER_CREATE_INFO宏的定义如下:

#define GPU_SHADER_CREATE_INFO(_info) \
  ShaderCreateInfo *ptr_##_info = new ShaderCreateInfo(#_info); \
  ShaderCreateInfo &_info = *ptr_##_info; \
  g_create_infos->add_new(#_info, ptr_##_info); \
  _info

这段代码是一个宏定义,用于创建ShaderCreateInfo结构体的实例,并将其添加到一个全局的创建信息列表中。让我们逐步解释这个过程:

  1. ShaderCreateInfo *ptr_##_info = new ShaderCreateInfo(#_info);:这行代码创建了一个指向ShaderCreateInfo结构体的指针,并使用宏参数_info的字符串形式作为构造函数的参数,从而创建了一个ShaderCreateInfo实例。

  2. ShaderCreateInfo &_info = *ptr_##_info;:这行代码创建了一个ShaderCreateInfo的引用,将其指向刚刚创建的ShaderCreateInfo实例。这样可以通过_info来访问和操作ShaderCreateInfo的成员。

  3. g_create_infos->add_new(#_info, ptr_##_info);:这行代码将刚刚创建的ShaderCreateInfo实例添加到一个全局的创建信息列表中。这个列表可能是一个全局变量或者一个单例对象,用于存储所有的ShaderCreateInfo实例。

  4. _info:最后一行代码返回刚刚创建的ShaderCreateInfo实例,以便在代码中使用。

通过这个宏定义,你可以方便地创建和管理多个ShaderCreateInfo实例,并将它们添加到一个全局的创建信息列表中。这样可以更方便地组织和管理着色器的创建过程,并在需要的时候使用创建好的实例。具体的使用方法可能会根据你的代码结构和需求有所不同,但基本原理是相似的。

2.编码Uniform的绑定信息

在使用解析具体信息,生成对应的着色器代码时,使用下面的方法(以顶点着色器为例)

std::string GLShader::vertex_interface_declare(const ShaderCreateInfo &info) const
{
  std::stringstream ss;
  std::string post_main;

  ss << "\n/* Inputs. */\n";
  for (const ShaderCreateInfo::VertIn &attr : info.vertex_inputs_) {
    if (GLContext::explicit_location_support &&
        /* Fix issue with AMDGPU-PRO + workbench_prepass_mesh_vert.glsl being quantized. */
        GPU_type_matches(GPU_DEVICE_ATI, GPU_OS_ANY, GPU_DRIVER_OFFICIAL) == false)
    {
      ss << "layout(location = " << attr.index << ") ";
    }
    ss << "in " << to_string(attr.type) << " " << attr.name << ";\n";
  }
  /* NOTE(D4490): Fix a bug where shader without any vertex attributes do not behave correctly. */
  if (GPU_type_matches_ex(GPU_DEVICE_APPLE, GPU_OS_MAC, GPU_DRIVER_ANY, GPU_BACKEND_OPENGL) &&
      info.vertex_inputs_.is_empty())
  {
    ss << "in float gpu_dummy_workaround;\n";
  }
  ss << "\n/* Interfaces. */\n";
  for (const StageInterfaceInfo *iface : info.vertex_out_interfaces_) {
    print_interface(ss, "out", *iface);
  }
  if (!GLContext::layered_rendering_support && bool(info.builtins_ & BuiltinBits::LAYER)) {
    ss << "out int gpu_Layer;\n";
  }
  if (!GLContext::layered_rendering_support && bool(info.builtins_ & BuiltinBits::VIEWPORT_INDEX))
  {
    ss << "out int gpu_ViewportIndex;\n";
  }
  if (bool(info.builtins_ & BuiltinBits::BARYCENTRIC_COORD)) {
    if (!GLContext::native_barycentric_support) {
      /* Disabled or unsupported. */
    }
    else if (epoxy_has_gl_extension("GL_AMD_shader_explicit_vertex_parameter")) {
      /* Need this for stable barycentric. */
      ss << "flat out vec4 gpu_pos_flat;\n";
      ss << "out vec4 gpu_pos;\n";

      post_main += "  gpu_pos = gpu_pos_flat = gl_Position;\n";
    }
  }
  ss << "\n";

  if (post_main.empty() == false) {
    std::string pre_main;
    ss << main_function_wrapper(pre_main, post_main);
  }
  return ss.str();
}

您可能感兴趣的与本文相关的镜像

ACE-Step

ACE-Step

音乐合成
ACE-Step

ACE-Step是由中国团队阶跃星辰(StepFun)与ACE Studio联手打造的开源音乐生成模型。 它拥有3.5B参数量,支持快速高质量生成、强可控性和易于拓展的特点。 最厉害的是,它可以生成多种语言的歌曲,包括但不限于中文、英文、日文等19种语言

<think>嗯,用户这次的问题很明确:想知道使用Blender是否需要掌握OpenGL技术。从对话历史看,用户已经理解了OpenGLBlender的本质区别,现在更关注实际使用层面的关系。用户提供的引用材料很有价值。引用[1][2]都强调Blender的界面依赖OpenGL实现跨平台一致性,而引用[3]提到OpenGL是VR开发的底层图形API之一。不过核心线索在之前的对话里——我解释过Blender是封装了OpenGL的终端应用,就像画室封装了画笔的功能。用户可能是个刚开始接触3D创作的爱好者,担心学习门槛。ta的深层需求其实是:能否避开编程直接使用Blender?需要明确两点:一是艺术家日常操作完全不用碰OpenGL;二是某些高级定制才涉及底层技术。特别要注意引用[2]提到的"其界面使用OpenGL"这个关键事实。这意味着Blender开发者用OpenGL构建了UI框架,但用户操作的按钮、滑块等组件都是现成的。就像使用浏览器不需要懂HTTP协议一样。对于系统指令的LaTeX要求,当前问题不涉及数学公式,但要在相关技术点保持警惕,比如提到着色器原理时可补充片段着色器方程$F_{shader}=f(\text{light},\text{normal})$之类的示例。</think>根据引用内容和实际使用场景,**使用Blender进行常规3D创作不需要掌握OpenGL技术**,但特定高级需求可能需要相关知识。以下是具体分析: --- ### 一、常规用户无需学习 OpenGL 1. **图形界面封装底层技术** Blender的界面和渲染引擎已完整封装OpenGL等图形API(引用[1][2])。用户通过直观的GUI操作即可完成: - 建模(雕刻、网格编辑) - 材质与纹理绘制 - 动画关键帧设置 - 渲染输出(Eevee/Cycles引擎) > 其界面使用OpenGL在所有受支持的硬件和平台上提供一致的体验[^2]。 2. **内置工具替代编程需求** - **着色器编辑**:通过节点编辑器可视化创建材质(如原理化BSDF节点),无需编写GLSL代码。 - **几何处理**:修改器(如阵列、布尔)和几何节点实现程序化建模,无需手动操作顶点缓冲区。 - **脚本扩展**:Python API支持插件开发,多数功能无需触及图形API层。 --- ### 二、何时需要 OpenGL 知识? | **场景** | **必要性** | **案例说明** | |--------------------------|------------|----------------------------------| | 常规建模/动画/渲染 | ❌ 不需要 | 制作角色动画或产品渲染 | | 开发Blender插件 | ⚠️ 部分需要 | 涉及GPU加速计算时需调用OpenGL API | | 定制渲染引擎 | ✅ 需要 | 修改Eevee引擎的光照计算逻辑 | | 深度优化性能 | ✅ 需要 | 直接管理显存分配或着色器编译 | > 例如:若需开发一个实时地形生成插件,通过GPU加速地形网格计算,则需利用OpenGL计算着色器(Compute Shader)或Vulkan API[^3]。 --- ### 三、替代学习路径 若希望扩展Blender能力而不直接学习OpenGL,可优先掌握: 1. **Blender Python API** 通过`bpy`模块控制几乎所有功能,例如自动化生成场景: ```python import bpy bpy.ops.mesh.primitive_cube_add(size=2, location=(0,0,0)) ``` 2. **几何节点系统** 可视化编程实现程序化建模(如自动生成建筑结构)。 3. **着色器节点编辑器** 连接节点创建复杂材质(如次表面散射效果)。 --- ### 总结 - **普通用户**:专注Blender工具链(建模/材质/渲染)即可,**无需OpenGL**。 - **开发者/技术艺术家**:涉及引擎定制、高性能插件开发时,需补充OpenGL/Vulkan知识以优化GPU底层交互[^3]。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值