【问题标题】:Multiple shaders, objects and materials with OOP具有 OOP 的多个着色器、对象和材质
【发布时间】:2014-12-08 21:05:54
【问题描述】:

我在我正在制作的一个小型 Java OpenGL 项目中使用 GLSL 着色器,并且我正在尝试提出一种编写良好的面向对象的方式来组织我的代码。到目前为止,我有一个名为Model 的类,它可以包含多个网格,每个网格都有自己的纹理和材质(材质是一组用于描述环境、漫反射、镜面反射、混合等的参数)。为了实现这一点,我知道每次需要更改材质时都可以将统一变量传递给着色器。但是,绘图发生在模型的draw() 方法中。这是否意味着Model 类的每个实例都需要关联一个特定的着色器?

另外,我有一个Camera 类,它会生成一个矩阵,该矩阵将转换顶点以模拟相机的俯仰、偏航和位置。然后这个矩阵需要作为视图矩阵上传到着色器。这是否意味着我需要将此矩阵上传到我使用的每个着色器?因此,如果每个Model 都可以有自己的着色器,我怎样才能将相机的视图矩阵上传到所有它们?即便如此,每个模型都拥有自己的着色器不是效率低下吗?如果您想多次绘制某个模型,那么您将use()着色器并在每次绘制时将矩阵上传到着色器。

我真的很难想出一个面向对象的解决方案来链接多个着色器、多个对象和多个材质。任何帮助表示赞赏。

【问题讨论】:

    标签: java oop opengl glsl shader


    【解决方案1】:

    现代 OpenGL 要求您编写 vert/frag 着色器来渲染任何东西,因此将 MaterialModel 对象一起存储是一个安全的选择。如果没有与模型对象相关联,您可能会拥有 Default Material - 有点像缺少纹理或模型。

    渲染引擎架构通常是一个很大的概念,我自己并不完全理解一些东西,但到目前为止,我非常喜欢THREE.js 如何构建它。当然它是用 javascript 制作的,但是这些想法可以很好地翻译成其他语言。你应该调查一下。

    scene = new THREE.Scene();
    
    camera = new THREE.PerspectiveCamera( 75, window.innerWidth / window.innerHeight, 1, 10000 );
    camera.position.z = 1000;
    
    geometry = new THREE.BoxGeometry( 200, 200, 200 );
    material = new THREE.MeshBasicMaterial( { color: 0xff0000, wireframe: true } );
    
    mesh = new THREE.Mesh( geometry, material );
    scene.add( mesh );
    
    renderer = new THREE.CanvasRenderer();
    renderer.setSize( window.innerWidth, window.innerHeight );
    

    【讨论】:

      【解决方案2】:

      要回答您的第二个问题,是的,您需要能够为您使用的每个着色器访问Camera 的视图矩阵。您可能需要让渲染的任何对象都可以访问它。

      每个Model 可以有自己的着色器,但由于着色器更改是最昂贵的状态切换操作之一,许多引擎通过着色器批量渲染。所以(希望)你没有使用太多不同的着色器。

      【讨论】:

      • 但是模型类的每个实例都会自己渲染,所以理论上我可以让任意数量的对象进行渲染。写一个可以接受和渲染Model 类的Renderer 类会更好吗?
      • 是的,我想是的。一旦你的场景变得足够复杂,你会想要通过状态变化(类似的着色器、纹理等)对Models 进行排序,并且进行排序的对象也可能是Renderer。此外,考虑多通道场景可能会有所帮助,例如反射或花哨的灯光效果(或者可能会令人困惑,在这种情况下,请在遇到这种情况时处理它:)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-03-08
      • 2019-03-01
      • 2015-02-16
      • 1970-01-01
      • 2020-07-24
      相关资源
      最近更新 更多