使用OOP的多个着色器,对象和材质

时间:2014-12-08 21:05:55

标签: java oop opengl glsl shader

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

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

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

2 个答案:

答案 0 :(得分:2)

现代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 );

答案 1 :(得分:1)

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

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