Merge branch 'feature/hybrid-renderer' into feature/galaxy

This commit is contained in:
Emil Axelsson
2016-05-19 15:25:10 +02:00
6 changed files with 137 additions and 20 deletions

View File

@@ -110,6 +110,9 @@ private:
ghoul::Dictionary _resolveDictionary;
GLuint _mainColorTexture;
GLuint _mainDepthTexture;
GLuint _mainFramebuffer;
GLuint _screenQuad;
GLuint _anchorPointerTexture;
GLuint _anchorPointerTextureInitializer;

View File

@@ -31,24 +31,31 @@ out vec4 _out_color_;
void main() {
Fragment frag = getFragment();
int sampleMask = gl_SampleMaskIn[0];
uint newHead = atomicCounterIncrement(atomicCounterBuffer);
if (newHead >= #{rendererData.maxTotalFragments}) {
discard; // ABuffer is full!
}
uint prevHead = imageAtomicExchange(anchorPointerTexture, ivec2(gl_FragCoord.xy), newHead);
// todo: calculate full sample mask from nAaSamples instead of hardcoded 255.
if (frag.color.a < 1.0 || sampleMask != 255) {
uint newHead = atomicCounterIncrement(atomicCounterBuffer);
if (newHead >= #{rendererData.maxTotalFragments}) {
discard; // ABuffer is full!
}
uint prevHead = imageAtomicExchange(anchorPointerTexture, ivec2(gl_FragCoord.xy), newHead);
ABufferFragment aBufferFrag;
_color_(aBufferFrag, frag.color);
_depth_(aBufferFrag, frag.depth);
_blend_(aBufferFrag, frag.blend);
ABufferFragment aBufferFrag;
_color_(aBufferFrag, frag.color);
_depth_(aBufferFrag, frag.depth);
_blend_(aBufferFrag, frag.blend);
_type_(aBufferFrag, 0); // 0 = geometry type
_msaa_(aBufferFrag, gl_SampleMaskIn[0]);
_next_(aBufferFrag, prevHead);
storeFragment(newHead, aBufferFrag);
discard;
} else {
_out_color_ = frag.color;
gl_FragDepth = normalizeFloat(frag.depth);
}
_type_(aBufferFrag, 0); // 0 = geometry type
_msaa_(aBufferFrag, gl_SampleMaskIn[0]);
_next_(aBufferFrag, prevHead);
storeFragment(newHead, aBufferFrag);
discard;
}

View File

@@ -35,6 +35,8 @@ layout (location = 0) out vec4 finalColor;
uniform float blackoutFactor;
uniform int nAaSamples;
uniform sampler2DMS mainColorTexture;
uniform sampler2DMS mainDepthTexture;
#define RAYCASTING_ENABLED #{raycastingEnabled}
#define N_RAYCASTERS #{nRaycasters}
@@ -86,6 +88,18 @@ uint countSamples(uint mask) {
+ ((mask >> 7) & 1);
}
uint depthFilterFragments(uint nFrags, float depthThreshold) {
uint j = 0;
for (uint i = 0; i < nFrags; i++) {
if (_depth_(fragments[i]) < depthThreshold) {
fragments[j] = fragments[i];
j++;
}
}
return j;
}
uint reduceFragments(uint nFrags) {
uint outputIndex = 0;
for (uint inputIndex = 0; inputIndex < nFrags; inputIndex++, outputIndex++) {
@@ -216,14 +230,33 @@ void raycast(float raycastDepth, uint raycasterMask, inout vec4 finalColor) {
#endif // RAYCASTING_ENABLED
void main() {
//vec4 opaqueColor = vec4(0.0);
finalColor = vec4(0.0);
float maxOpaqueDepth = 0;
vec4 opaqueColor = vec4(0.0);
for (int i = 0; i < nAaSamples; i++) {
float depth = denormalizeFloat(texelFetch(mainDepthTexture, ivec2(gl_FragCoord), i).x);
// finalColor += color;
if (depth > maxOpaqueDepth) {
maxOpaqueDepth = depth;
}
opaqueColor += texelFetch(mainColorTexture, ivec2(gl_FragCoord), i);
//finalColor.r += depth;
//finalColor += vec4(0.120);
}
opaqueColor /= nAaSamples;
uint nOriginalFrags = loadFragments();
uint raycasterMask = 0;
sortFragments(nOriginalFrags);
uint nFilteredFrags = depthFilterFragments(nOriginalFrags, maxOpaqueDepth);
sortFragments(nFilteredFrags);
uint nFrags = reduceFragments(nOriginalFrags);
uint nFrags = reduceFragments(nFilteredFrags);
#if RAYCASTING_ENABLED
retrieveRaycasterData(nFrags);
#endif
@@ -261,10 +294,18 @@ void main() {
}
#endif
}
normalBlend(finalColor, opaqueColor);
// finalColor is expressed with premultiplied alpha
finalColor.rgb *= blackoutFactor;
// Render everything on a black background
finalColor.a = 1.0;
//finalColor.rgb = vec3(float(nFrags) * 0.25);
}

View File

@@ -22,6 +22,7 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#include "PowerScaling/powerScalingMath.hglsl"
#include <#{fragmentPath}>
out vec4 _out_color_;

View File

@@ -35,6 +35,7 @@
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/textureunit.h>
#include <ghoul/misc/dictionary.h>
#include <ghoul/misc/exception.h>
@@ -97,7 +98,15 @@ void ABufferRenderer::initialize() {
glBufferData(GL_ATOMIC_COUNTER_BUFFER, sizeof(GLuint), NULL, GL_DYNAMIC_COPY);
glGenBuffers(1, &_fragmentBuffer);
glGenTextures(1, &_fragmentTexture);
glGenTextures(1, &_mainColorTexture);
glGenTextures(1, &_mainDepthTexture);
glGenFramebuffers(1, &_mainFramebuffer);
GLint defaultFbo;
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFbo);
_nAaSamples = OsEng.windowWrapper().currentNumberOfAaSamples();
if (_nAaSamples == 0) {
_nAaSamples = 1;
@@ -112,6 +121,18 @@ void ABufferRenderer::initialize() {
updateRaycastData();
updateResolveDictionary();
glBindFramebuffer(GL_FRAMEBUFFER, _mainFramebuffer);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D_MULTISAMPLE, _mainColorTexture, 0);
glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D_MULTISAMPLE, _mainDepthTexture, 0);
GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER);
if (status != GL_FRAMEBUFFER_COMPLETE) {
LERROR("Main framebuffer is not complete");
}
glBindFramebuffer(GL_FRAMEBUFFER, defaultFbo);
try {
_resolveProgram = ghoul::opengl::ProgramObject::Build("ABuffer Resolve",
"${SHADERS}/abuffer/resolveabuffer.vert",
@@ -201,6 +222,13 @@ void ABufferRenderer::render(float blackoutFactor, bool doPerformanceMeasurement
if (_scene == nullptr) return;
if (_camera == nullptr) return;
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
GLint defaultFbo;
glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFbo);
glBindFramebuffer(GL_FRAMEBUFFER, _mainFramebuffer);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Reset
clear();
glEnable(GL_DEPTH_TEST);
@@ -219,6 +247,9 @@ void ABufferRenderer::render(float blackoutFactor, bool doPerformanceMeasurement
_scene->render(data, tasks);
glBindFramebuffer(GL_FRAMEBUFFER, defaultFbo);
// Step 2: Perform raycasting tasks requested by the scene
for (const RaycasterTask& raycasterTask : tasks.raycasterTasks) {
VolumeRaycaster* raycaster = raycasterTask.raycaster;
@@ -238,6 +269,16 @@ void ABufferRenderer::render(float blackoutFactor, bool doPerformanceMeasurement
// Step 3: Resolve the buffer
_resolveProgram->activate();
ghoul::opengl::TextureUnit mainColorTextureUnit;
mainColorTextureUnit.activate();
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainColorTexture);
ghoul::opengl::TextureUnit mainDepthTextureUnit;
mainDepthTextureUnit.activate();
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainDepthTexture);
_resolveProgram->setUniform("mainColorTexture", mainColorTextureUnit);
_resolveProgram->setUniform("mainDepthTexture", mainDepthTextureUnit);
// 3a: Perform the pre-raycast step for all raycaster tasks.
for (const RaycasterTask& raycasterTask : tasks.raycasterTasks) {
@@ -293,6 +334,7 @@ void ABufferRenderer::clear() {
glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, _atomicCounterBuffer);
glBufferSubData(GL_ATOMIC_COUNTER_BUFFER, 0, sizeof(zero), &zero);
glBindBufferBase(GL_ATOMIC_COUNTER_BUFFER, 0, 0);
}
void ABufferRenderer::updateResolution() {
@@ -320,6 +362,26 @@ void ABufferRenderer::updateResolution() {
glBindImageTexture(1, _fragmentTexture, 0, GL_FALSE, 0, GL_WRITE_ONLY, GL_RGBA32UI);
int nSamples = OsEng.windowWrapper().currentNumberOfAaSamples();
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainColorTexture);
glTexImage2DMultisample(
GL_TEXTURE_2D_MULTISAMPLE,
nSamples,
GL_RGBA,
GLsizei(_resolution.x),
GLsizei(_resolution.y),
true);
glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainDepthTexture);
glTexImage2DMultisample(
GL_TEXTURE_2D_MULTISAMPLE,
nSamples,
GL_DEPTH_COMPONENT32F,
GLsizei(_resolution.x),
GLsizei(_resolution.y),
true);
_dirtyResolution = false;
}

View File

@@ -246,6 +246,8 @@ void FramebufferRenderer::updateResolution() {
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
_dirtyResolution = false;
}
void FramebufferRenderer::updateRaycastData() {
@@ -393,6 +395,7 @@ void FramebufferRenderer::setCamera(Camera* camera) {
void FramebufferRenderer::setResolution(glm::ivec2 res) {
_resolution = res;
_dirtyResolution = true;
}
void FramebufferRenderer::updateRendererData() {