Author: eilemann@gmail.com
State:
- Implemented in 1.0-alpha
Overview
This documents specifies how to switch between stereo and mono rendering in a running config. The application has to be able to switch between mono and stereo rendering selectively for each view. The configurations file shall be able to specify different segments for each eye pass to mix passive stereo and mono, as well as contain different (scalability) compounds for stereo and mono.
Specification
Each segment is stereo-aware, that is, its destination compounds are only activated for the eye passes activated by the active views. For example, a segment rendering the left and cyclop eye with a view in mono mode will only activate the cyclop rendering on the compounds using its destination channels.
Each view has a stereo mode (mono / stereo). Switching the stereo mode activates different compound eye traversals and potentially different compounds and dependent entities.
The semantics of the compound eye attribute changes from describing the eye
passes to be rendered to the eye passes this compound can render. The actual
selection of the eye passes will be done by the view of the destination
channel(s). That is, a compound using eye [ LEFT RIGHT CYCPLOP ]
will render all three eye passes in Equalizer 0.9.1, but only the cyclop (view
is in mono mode) or left and right (view is in stereo) passes in the new
implementation. Consequently, the default setting shall change from eye
[ CYCLOP ]
to eye [ LEFT RIGHT CYCPLOP ]
.
For convenience, the compound attribute stereo_mode
will also
support the new value AUTO
, which will become the new default
value. Auto selects quad-buffered stereo if the destination channel has a
quad-buffered visual, otherwise anaglyphic stereo.
Implementation
- Implement file format, including converter
- Implement compound auto stereo mode
- Implement View::changeMode
- Make compound activation eye-aware
- Make compound update and task generation eye-aware
- Move compound activation from canvas to view:
ChannelUpdateVisitor: - skip compound if not activated for current eye -> need per-eye activation count for each compound Compounds are activated globally right now server::View: new member _currentMode; // NONE, MONO or STEREO server::View::activateMode: Activate destination compounds for new eye(s) for each destination channel of view: if channel's canvas uses our layout and segment supports new eye find and activate destination compound for eye(s) Deactivate destination compounds for old eye(s) for each destination channel of view: if channel's canvas uses our layout and segment supports old eye find and deactivate destination compound for eye(s) _currentMode = mode; Refactor server::Canvas::activateLayout to use server::View::activateMode: activateMode( MODE_NONE ) on old layout views set new layout activateMode( getMode( )) on new layout views
API
View::changeMode( EQ_MONO | EQ_STEREO ); Also setter/getter for file format additions.
File Format
#Equalizer 1.1 ascii view { mode MONO | STEREO } segment { ... eye [ CYCLOP LEFT RIGHT ] # eye passes rendered by segment, default all } compound { attributes { stereo_mode QUAD | ANAGLYPH | AUTO # new AUTO, also new default } }
Examples
Passive stereo powerwall: layout { view { }} canvas { layout 1 wall {} segment { eye [ LEFT CYCLOP ] channel "left-projector" } segment { eye [ RIGHT ] channel "right-projector" } } compound { channel ( view 0 segment 0 ) eye [ CYCLOP ] load_equalizer{} compound {} compound { channel "right-PBuffer" outputframe{} } inputframe{ name "frame.right-PBuffer" } } compound { compound { channel ( view 0 segment 0 ) eye [ LEFT ] swapbarrier{} } compound { channel ( view 0 segment 1 ) eye [ RIGHT ] swapbarrier{} } } Active stereo powerwall: layout { view { }} canvas { layout 1 wall {} segment { eye [ LEFT RIGHT CYCLOP ] channel "projector" } } compound { channel ( view 0 segment 0 ) } Active stereo powerwall with second source GPU: layout { view { }} canvas { layout 1 wall {} segment { eye [ LEFT RIGHT CYCLOP ] channel "projector" } } compound { channel ( view 0 segment 0 ) eye [ CYCLOP ] load_equalizer{} compound {} compound { channel "source" outputframe{} } inputframe{ name "frame.source" } } compound { channel ( view 0 segment 0 ) eye [ LEFT RIGHT ] compound { eye [ LEFT ] } compound { eye [ RIGHT ] compound { channel "source" outputframe{} } inputframe{ name "frame.source" } } }
Issues
Q1: Is the stereo switch per view or per observer?
Resolved: per view, implementing a convenience method Observer::setEyePasses is possible.
The eye separation and head matrix, affecting stereo rendering, are on the observer. It should however be possible to observe one view in stereo and one in mono with one observer.
Q2: Shall one view be able to render mono and stereo concurrently?
Resolved: No.
The benefit of rendering mono and stereo concurrently, presumably to different segments, is marginal but makes writing different compounds for stereo and mono difficult. Typically the mono config assumes that the resources used for stereo rendering can be used for scalability, since stereo and mono are rarely active at the same time.