2014-12-08 2 views
0

Я использую шейдеры GLSL в небольшом проекте Java OpenGL, который я делаю, и я пытаюсь создать хорошо написанный объектно-ориентированный способ организации моего кода. До сих пор у меня есть класс под названием Model, который может содержать несколько сеток, каждый из которых имеет свою собственную текстуру и материал (материал представляет собой набор параметров для описания окружающего, диффузного, зеркального, смешивания и т. Д.). Для этого я понимаю, что каждый раз, когда мне нужно менять материал, я могу передавать однородные переменные в шейдер. Однако рисунок имеет место в методе модели draw(). Означает ли это, что каждый экземпляр класса Model должен иметь определенный шейдер, связанный с ним?Несколько шейдеров, объектов и материалов с OOP

Кроме того, у меня есть класс Camera, который создает матрицу, которая преобразует вершины, имитирует шаг, рыскание и положение камеры. Затем эта матрица должна быть загружена в шейдер в качестве матрицы представлений. Разве это не означает, что мне нужно загрузить эту матрицу в каждый шейдер, который я использую? Так что, если у каждого Model может быть свой собственный шейдер, как я могу загрузить матрицу просмотра камеры для всех? И даже несмотря на это, разве неэффективно для каждой модели иметь свой собственный шейдер? Если бы вы хотели нарисовать определенную модель много раз, тогда вы должны были бы занять шейдер и загружать матрицу в шейдер каждый раз, когда вы ее нарисовали.

Я действительно изо всех сил пытаюсь найти объектно-ориентированное решение, которое связывает несколько шейдеров, несколько объектов и множество материалов. Любая помощь приветствуется.

ответ

2

Современный OpenGL требует написания верт/Frag шейдеры для того, чтобы сделать что-нибудь, так что это будет безопасная ставка, чтобы иметь Material хранимую с Model объекта. Возможно, у вас может быть 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

Чтобы ответить на ваш второй вопрос, да вы должны быть в состоянии получить доступ к матричному Camera «s для каждого шейдера вы используете. Вероятно, вам нужно сделать его доступным для любого объекта, который выполняет рендеринг.

Каждый Model может иметь свой собственный шейдер, но так как изменения шейдеров являются одними из самых дорогостоящих операций переключения состояний, многие моделируют пакетный рендеринг с помощью шейдеров. Так что (надеюсь) у вас не слишком много разных шейдеров.

+0

Но каждый экземпляр класса модели проявляет себя, поэтому теоретически я мог бы иметь любое количество объектов, выполняющих рендеринг. Было бы лучше написать класс «Renderer», который может принимать и отображать классы «Model»? – Tristram

+0

Да, я так думаю. После того, как ваши сцены будут достаточно сложными, вы захотите отсортировать «Модели с помощью изменений состояния (похожие шейдеры, текстуры и т. Д.), А также объект, который выполняет сортировку, также может быть« Renderer ». Кроме того, это может помочь подумать о многопроходных сценариях, таких как отражения или причудливые световые эффекты (или это может сбивать с толку, и в этом случае просто иметь дело с ним, когда вы приходите к нему :). – chronospoon

Смежные вопросы