Closed vorg closed 2 years ago
There are many names people use Scene + Renderer, Engine, World.
The most logical name would be defaultRenderer
but wink wink it would actually consist of both systems and renderers so it is not accurate.
const ecs = defaultSetup()
ctx.frame(() => {
ecs.update(entities)
})
const app = defaultSetup()
ctx.frame(() => {
app.update(entities)
})
const engine = defaultSetup()
ctx.frame(() => {
engine.update(entities)
})
Maybe it's just defaultSystems
const systems = defaultSystems()
ctx.frame(() => {
systems.update(entities)
})
To clarify this is what the "default setup" looks like
module.exports = (node, graph) => {
const {
systems,
renderGraph: createRenderGraph,
resourceCache: createResourceCache,
} = require("pex-renderer");
const triggerIn = node.triggerIn("in");
const triggerOut = node.triggerOut("out");
const ctx = graph.ctx;
const renderGraph = createRenderGraph(ctx);
const resourceCache = createResourceCache(ctx);
const renderPipelineSystem = systems.renderPipeline({
ctx: graph.ctx,
outputEncoding: graph.ctx.Encoding.Gamma,
resourceCache,
renderGraph,
});
const standardRendererSystem = systems.renderer.standard({
ctx,
resourceCache,
renderGraph,
});
const basicRendererSystem = systems.renderer.basic({
ctx,
resourceCache,
renderGraph,
});
const lineRendererSystem = systems.renderer.line({
ctx,
resourceCache,
renderGraph,
});
const helperRendererSys = systems.renderer.helper({ ctx });
const skyboxRendererSys = systems.renderer.skybox({ ctx });
triggerIn.onTrigger = (props) => {
const { entities, renderWidth, renderHeight } = props;
resourceCache.beginFrame();
renderGraph.beginFrame();
const cameraEntity = entities.find((e) => e.camera);
const renderView = {
camera: cameraEntity.camera,
cameraEntity: cameraEntity,
viewport: [0, 0, renderWidth, renderHeight],
};
node.comment = cameraEntity.camera.fov + "\n" + renderView.viewport;
renderPipelineSystem.update(props.entities, {
renderView,
renderers: [
standardRendererSystem,
// basicRendererSystem,
lineRendererSystem,
skyboxRendererSys,
// helperRendererSys,
],
});
renderGraph.endFrame();
resourceCache.endFrame();
// node.comment = props.entities.length;
triggerOut.trigger(props);
};
};
So systems
is already taken by internal pex-render namespace.
Is it engine
then?
const engine = defaultEngine()
ctx.frame(() => {
engine.update(entities)
})
Or SystemGroup
. Which can be a system by itself, running a list of systems.
SystemGroup would still need to contain logic about system order and renderers to provide each system. In this case we could return compositeSystem so system made out of systems aka object implementing update() method
OR
we just push renderers to one long systems array and do
const defaultSystems = defaultSetup()
defaultSystems.forEach((system) => {
system.update(entities, defaultSystems)
})
assuming that renderer systems have empty update method and that renderPipeline can find renderer systems on it's own (by checking renderStage prop)
@dmnsgn and would nodes have Scene
and DefaultEngine
in this case?
@dmnsgn and would nodes have
Scene
andDefaultEngine
in this case?
Scene
and Engine
Am I missing a piece of the puzzle or would this work?
pex-renderer/systems/engine.js
export default function engine(ctx) {
const renderGraph = createRenderGraph(ctx);
const resourceCache = createResourceCache(ctx);
const renderPipelineSystem = systems.renderPipeline({
ctx,
outputEncoding: ctx.Encoding.Gamma,
resourceCache,
renderGraph,
});
const standardRendererSystem = systems.renderer.standard({
ctx,
resourceCache,
renderGraph,
});
const lineRendererSystem = systems.renderer.line({
ctx,
resourceCache,
renderGraph,
});
const helperRendererSys = systems.renderer.helper({ ctx });
const skyboxRendererSys = systems.renderer.skybox({ ctx });
const renderers = [
standardRendererSystem,
lineRendererSystem,
skyboxRendererSys,
helperRendererSys,
];
return {
renderers,
update(entities, { viewport }) {
resourceCache.beginFrame();
renderGraph.beginFrame();
const cameraEntity = entities.find((e) => e.camera);
const renderView = {
camera: cameraEntity.camera,
cameraEntity: cameraEntity,
viewport,
};
renderPipelineSystem.update(entities, { renderView, renderers });
renderGraph.endFrame();
resourceCache.endFrame();
},
};
}
app.js
import { engineSystem } from "pex-renderer";
const engine = engineSystem({ ctx });
const entities = []
// entities.push(entity);
ctx.frame(() => {
engine.update(entities);
})
Or are you saying it is not clean to update a system (renderPipelineSystem) inside another system (engineSystem)?
@dmnsgn you are not. It's exactly what i've implemented today https://github.com/pex-gl/pex-renderer/blob/304-port-to-ecs/default-engine.js https://github.com/pex-gl/pex-renderer/blob/304-port-to-ecs/examples/basic-engine.js
const engine = createDefaultEngine({ ctx });
ctx.frame(() => {
const now = Date.now();
const deltaTime = (now - prevTime) / 1000;
prevTime = now;
const cameraEntity = world.entities.find((e) => e.camera);
engine.update(world.entities, deltaTime);
engine.render(world.entities, cameraEntity);
gui.draw();
});
It's just "engine" is not a word i've used in 10 years. And the package is not pex-engine but pex-renderer despite actually doing engine's work. So it feels like we are using concept that is bigger than the library itself.
I also quite like the look of helpers example (currently no longer running) but it implies that systems can setup themselves and find their dependencies (other systems and renderers)
world.addSystem(systems.geometry({ ctx }));
world.addSystem(systems.animation());
world.addSystem(systems.transform());
world.addSystem(systems.camera());
world.addSystem(systems.skybox({ ctx }));
world.addSystem(systems.reflectionProbe({ ctx }));
world.addSystem(systems.renderer({ ctx, outputEncoding: ctx.Encoding.Gamma }));
world.addSystem(systems.helper({ ctx }));
...
ctx.frame(() => {
world.update();
gui.draw();
});
There is also a question of how much of a kitchen sink that "engine" thing should be and should it handle:
To document thinking process especially in the context of Nodes
DefaultEngine
- pretends it to be a bit more than it is?
DefaultSystems
undersells it as it is also a renderer
DefaultRenderer
is not accurate as it has systems inside and multiple renderers (standard/pbr, lines, particles etc)
So maybe it should be GraphicsEngine
- not a game engine and not just a renderer either as geometrySystem, animationSystem etc are part of defining "graphics". Or even better RenderEngine
.
It would be good to have a shortcut for creating all the render graph, resource cache, systems and renderers in one call so the user can focus on entities and scene building. The question is how do we call this soup of systems and renderers?
defaultSetup
?