From b591af3c2a1697b919c73e5ecc7dceddb24ea044 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Fri, 11 Oct 2019 18:11:22 -0400 Subject: [PATCH 01/10] Initial tests for performance improvements. --- modules/galaxy/shaders/galaxyraycast.glsl | 19 ++++++++------- shaders/framebuffer/raycastframebuffer.frag | 26 ++++++++++----------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/modules/galaxy/shaders/galaxyraycast.glsl b/modules/galaxy/shaders/galaxyraycast.glsl index a16188aa5d..dab687e3ca 100644 --- a/modules/galaxy/shaders/galaxyraycast.glsl +++ b/modules/galaxy/shaders/galaxyraycast.glsl @@ -29,17 +29,18 @@ uniform float absorptionMultiply#{id} = 50.0; uniform float emissionMultiply#{id} = 1500.0; uniform sampler3D galaxyTexture#{id}; -void sample#{id}(vec3 samplePos, +void sample#{id}( + vec3 samplePos, vec3 dir, inout vec3 accumulatedColor, inout vec3 accumulatedAlpha, - inout float stepSize) - { + inout float stepSize + ) { vec3 aspect = aspect#{id}; stepSize = maxStepSize#{id} / length(dir / aspect); //Early ray termination on black parts of the data - vec3 normalizedPos = samplePos*2.0 - 1.0; + vec3 normalizedPos = samplePos * 2.f - 1.f; if (normalizedPos.x * normalizedPos.x + normalizedPos.y * normalizedPos.y > 0.7) { return; } @@ -51,12 +52,12 @@ void sample#{id}(vec3 samplePos, sampledColor = sampledColor*sampledColor; // Fudge for the dust "spreading" - sampledColor.a = clamp(sampledColor.a, 0.0, 1.0); - sampledColor.a = pow(sampledColor.a, 0.7); + sampledColor.a = clamp(sampledColor.a, 0.f, 1.f); + sampledColor.a = pow(sampledColor.a, 0.7f); // Absorption probability float scaledDensity = sampledColor.a * stepSize * absorptionMultiply#{id}; - vec3 alphaTint = vec3(0.3, 0.54, 0.85); + vec3 alphaTint = vec3(0.3f, 0.54f, 0.85f); vec3 absorption = alphaTint * scaledDensity; // Extinction @@ -67,10 +68,10 @@ void sample#{id}(vec3 samplePos, accumulatedColor.rgb += sampledColor.rgb * stepSize * emissionMultiply#{id} * opacityCoefficient#{id}; - vec3 oneMinusFrontAlpha = vec3(1.0) - accumulatedAlpha; + vec3 oneMinusFrontAlpha = vec3(1.f) - accumulatedAlpha; accumulatedAlpha += oneMinusFrontAlpha * sampledColor.rgb * opacityCoefficient#{id}; } float stepSize#{id}(vec3 samplePos, vec3 dir) { - return maxStepSize#{id} * length(dir * 1.0 / aspect#{id}); + return maxStepSize#{id} * length(dir * 1.f / aspect#{id}); } diff --git a/shaders/framebuffer/raycastframebuffer.frag b/shaders/framebuffer/raycastframebuffer.frag index 6a949b4cc9..b5a972cff8 100644 --- a/shaders/framebuffer/raycastframebuffer.frag +++ b/shaders/framebuffer/raycastframebuffer.frag @@ -45,7 +45,7 @@ uniform vec2 windowSize; out vec4 finalColor; #define ALPHA_LIMIT 0.99 -#define RAYCAST_MAX_STEPS 1000 +#define RAYCAST_MAX_STEPS 480 #include <#{getEntryPath}> @@ -55,7 +55,7 @@ void main() { vec4 exitColorTexture = texture(exitColorTexture, texCoord); // If we don't have an exit, discard the ray - if (exitColorTexture.a < 1.0 || exitColorTexture.rgb == vec3(0.0)) { + if (exitColorTexture.a < 1.f || exitColorTexture.rgb == vec3(0.f)) { discard; } @@ -63,13 +63,13 @@ void main() { vec3 exitPos = exitColorTexture.rgb; float exitDepth = denormalizeFloat(texture(exitDepthTexture, texCoord).x); - float jitterFactor = 0.5 + 0.5 * rand(gl_FragCoord.xy); // should be between 0.5 and 1.0 + float jitterFactor = 0.5f + 0.5f * rand(gl_FragCoord.xy); // should be between 0.5 and 1.0 vec3 entryPos; float entryDepth; getEntry(entryPos, entryDepth); // If we don't have an entry, discard the ray - if (entryPos == vec3(0.0)) { + if (entryPos == vec3(0.f)) { discard; } @@ -80,21 +80,21 @@ void main() { float raycastDepth = length(diff); float geoDepth = denormalizeFloat(texelFetch(mainDepthTexture, ivec2(gl_FragCoord), 0).x); - float geoRatio = clamp((geoDepth - entryDepth) / (exitDepth - entryDepth), 0.0, 1.0); + float geoRatio = clamp((geoDepth - entryDepth) / (exitDepth - entryDepth), 0.f, 1.f); raycastDepth = geoRatio * raycastDepth; - float currentDepth = 0.0; + float currentDepth = 0.f; float nextStepSize = stepSize#{id}(position, direction); float currentStepSize; - float previousJitterDistance = 0.0; + float previousJitterDistance = 0.f; int nSteps = 0; int sampleIndex = 0; - float opacityDecay = 1.0; + float opacityDecay = 1.f; - vec3 accumulatedColor = vec3(0.0); - vec3 accumulatedAlpha = vec3(0.0); + vec3 accumulatedColor = vec3(0.f); + vec3 accumulatedAlpha = vec3(0.f); for (nSteps = 0; @@ -102,7 +102,7 @@ void main() { accumulatedAlpha.b < ALPHA_LIMIT) && nSteps < RAYCAST_MAX_STEPS; ++nSteps) { - if (nextStepSize < raycastDepth / 10000000000.0) { + if (nextStepSize < raycastDepth / 10000000000.f) { break; } @@ -110,7 +110,7 @@ void main() { currentDepth += currentStepSize; float jitteredStepSize = currentStepSize * jitterFactor; - vec3 jitteredPosition = position + direction*jitteredStepSize; + vec3 jitteredPosition = position + direction * jitteredStepSize; position += direction * currentStepSize; sample#{id}(jitteredPosition, direction, accumulatedColor, accumulatedAlpha, nextStepSize); @@ -122,7 +122,7 @@ void main() { nextStepSize = min(nextStepSize, maxStepSize); } - finalColor = vec4(accumulatedColor, (accumulatedAlpha.r + accumulatedAlpha.g + accumulatedAlpha.b) / 3); + finalColor = vec4(accumulatedColor, (accumulatedAlpha.r + accumulatedAlpha.g + accumulatedAlpha.b) / 3.f); finalColor.rgb /= finalColor.a ; gl_FragDepth = normalizeFloat(entryDepth); From 0fce6a8d268949b6855d5e67391b52e70d29ae52 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Sun, 10 Nov 2019 14:17:23 -0500 Subject: [PATCH 02/10] Super-fast volume (aka Downscaled Volume Rendering). --- .../scene/milkyway/milkyway/volume.asset | 4 +- .../openspace/rendering/framebufferrenderer.h | 11 + include/openspace/rendering/volumeraycaster.h | 19 ++ modules/galaxy/rendering/renderablegalaxy.cpp | 14 ++ modules/galaxy/rendering/renderablegalaxy.h | 2 + shaders/framebuffer/hdrAndFiltering.frag | 1 - .../framebuffer/mergeDownscaledVolume.frag | 35 ++++ .../framebuffer/mergeDownscaledVolume.vert | 33 +++ shaders/framebuffer/raycastframebuffer.frag | 5 +- src/rendering/framebufferrenderer.cpp | 193 +++++++++++++++++- 10 files changed, 310 insertions(+), 7 deletions(-) create mode 100644 shaders/framebuffer/mergeDownscaledVolume.frag create mode 100644 shaders/framebuffer/mergeDownscaledVolume.vert diff --git a/data/assets/scene/milkyway/milkyway/volume.asset b/data/assets/scene/milkyway/milkyway/volume.asset index 0d1537d45e..78195a1b5c 100644 --- a/data/assets/scene/milkyway/milkyway/volume.asset +++ b/data/assets/scene/milkyway/milkyway/volume.asset @@ -24,7 +24,9 @@ local MilkyWayVolumeGalaxy = { Type = "Volume", Filename = data .. "/MilkyWayRGBAVolume1024x1024x128.raw", Dimensions = {1024, 1024, 128}, - Size = {1.2E21, 1.2E21, 0.15E21} + Size = {1.2E21, 1.2E21, 0.15E21}, + Steps = 480, + Downscale = 0.5, }, Points = { Type = "Points", diff --git a/include/openspace/rendering/framebufferrenderer.h b/include/openspace/rendering/framebufferrenderer.h index a49568fe17..4529fd60a4 100644 --- a/include/openspace/rendering/framebufferrenderer.h +++ b/include/openspace/rendering/framebufferrenderer.h @@ -70,6 +70,7 @@ public: void updateDeferredcastData(); void updateHDRAndFiltering(); void updateFXAA(); + void updateDownscaledVolume(); void setResolution(glm::ivec2 res) override; void setHDRExposure(float hdrExposure) override; @@ -110,6 +111,8 @@ private: void resolveMSAA(float blackoutFactor); void applyTMO(float blackoutFactor); void applyFXAA(); + void updateDownscaleColorTexture(); + void writeDownscaledVolume(); std::map _raycastData; RaycasterProgObjMap _exitPrograms; @@ -122,10 +125,12 @@ private: std::unique_ptr _hdrFilteringProgram; std::unique_ptr _tmoProgram; std::unique_ptr _fxaaProgram; + std::unique_ptr _downscaledVolumeProgram; UniformCache(hdrFeedingTexture, blackoutFactor, hdrExposure, gamma, Hue, Saturation, Value) _hdrUniformCache; UniformCache(renderedTexture, inverseScreenSize) _fxaaUniformCache; + UniformCache(downscaledRenderedVolume) _writeDownscaledVolumeUniformCache; GLint _defaultFBO; GLuint _screenQuad; @@ -157,6 +162,12 @@ private: GLuint fxaaTexture; } _fxaaBuffers; + struct { + GLuint framebuffer; + GLuint colorTexture; + float currentDownscaleFactor = 1.f; + } _downscaleVolumeRendering; + unsigned int _pingPongIndex = 0u; bool _dirtyDeferredcastData; diff --git a/include/openspace/rendering/volumeraycaster.h b/include/openspace/rendering/volumeraycaster.h index f8ed000553..687a5f335a 100644 --- a/include/openspace/rendering/volumeraycaster.h +++ b/include/openspace/rendering/volumeraycaster.h @@ -128,6 +128,25 @@ public: * helper file) which should be a prefix to all symbols defined by the helper */ virtual std::string helperPath() const = 0; + + virtual void setMaxSteps(int nsteps) { _rayCastMaxSteps = nsteps; }; + + virtual const int maxSteps() const { return _rayCastMaxSteps; }; + + virtual void setDownscaleRender(float value) { _downscaleRenderConst = value; }; + + virtual const float downscaleRender() const { return _downscaleRenderConst; }; + +private: + /** + * Maximum number of integration steps to be executed by the volume integrator. + */ + int _rayCastMaxSteps = 1000; + + /** + * Enable and set the downscale rendering of the volume. Used to improve performance. + */ + float _downscaleRenderConst = 1.0f; }; } // namespace openspace diff --git a/modules/galaxy/rendering/renderablegalaxy.cpp b/modules/galaxy/rendering/renderablegalaxy.cpp index 1d88c2da23..758ab082a1 100644 --- a/modules/galaxy/rendering/renderablegalaxy.cpp +++ b/modules/galaxy/rendering/renderablegalaxy.cpp @@ -224,6 +224,18 @@ namespace openspace { LERROR("No volume dimensions specified."); } + if (volumeDictionary.hasKey("Steps")) { + _rayCastSteps = static_cast(volumeDictionary.value("Steps")); + } + else { + LINFO("Number of raycasting steps not specified for Milkway Galaxy." + " Using default value."); + } + + if (volumeDictionary.hasKey("Downscale")) { + _downScaleVolumeRendering = volumeDictionary.value("Downscale"); + } + if (!dictionary.hasKeyAndValue("Points")) { LERROR("No points dictionary specified."); } @@ -470,6 +482,8 @@ void RenderableGalaxy::update(const UpdateData& data) { volumeTransform[3] += translation; _pointTransform[3] += translation; + _raycaster->setDownscaleRender(_downScaleVolumeRendering); + _raycaster->setMaxSteps(_rayCastSteps); _raycaster->setStepSize(_stepSize); _raycaster->setAspect(_aspect); _raycaster->setModelTransform(volumeTransform); diff --git a/modules/galaxy/rendering/renderablegalaxy.h b/modules/galaxy/rendering/renderablegalaxy.h index 0b49d848c4..8346820b99 100644 --- a/modules/galaxy/rendering/renderablegalaxy.h +++ b/modules/galaxy/rendering/renderablegalaxy.h @@ -79,6 +79,8 @@ private: glm::ivec3 _volumeDimensions; std::string _pointsFilename; std::string _pointSpreadFunctionTexturePath; + int _rayCastSteps = 1000; + float _downScaleVolumeRendering = 1.f; std::unique_ptr _raycaster; std::unique_ptr>> _volume; diff --git a/shaders/framebuffer/hdrAndFiltering.frag b/shaders/framebuffer/hdrAndFiltering.frag index b22ebd9bc4..0e2b3b2090 100644 --- a/shaders/framebuffer/hdrAndFiltering.frag +++ b/shaders/framebuffer/hdrAndFiltering.frag @@ -38,7 +38,6 @@ uniform float Hue; uniform float Saturation; uniform float Value; uniform float Lightness; -uniform int nAaSamples; uniform sampler2D hdrFeedingTexture; diff --git a/shaders/framebuffer/mergeDownscaledVolume.frag b/shaders/framebuffer/mergeDownscaledVolume.frag new file mode 100644 index 0000000000..f34a300742 --- /dev/null +++ b/shaders/framebuffer/mergeDownscaledVolume.frag @@ -0,0 +1,35 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2019 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#version __CONTEXT__ + +layout (location = 0) out vec4 finalColor; + +uniform sampler2D downscaledRenderedVolume; + +in vec2 texCoord; + +void main() { + finalColor = texture(downscaledRenderedVolume, texCoord); +} diff --git a/shaders/framebuffer/mergeDownscaledVolume.vert b/shaders/framebuffer/mergeDownscaledVolume.vert new file mode 100644 index 0000000000..f737e51882 --- /dev/null +++ b/shaders/framebuffer/mergeDownscaledVolume.vert @@ -0,0 +1,33 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2019 * + * * + * Permission is hereby granted, free of charge, to any person obtaining a copy of this * + * software and associated documentation files (the "Software"), to deal in the Software * + * without restriction, including without limitation the rights to use, copy, modify, * + * merge, publish, distribute, sublicense, and/or sell copies of the Software, and to * + * permit persons to whom the Software is furnished to do so, subject to the following * + * conditions: * + * * + * The above copyright notice and this permission notice shall be included in all copies * + * or substantial portions of the Software. * + * * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, * + * INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A * + * PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT * + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF * + * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE * + * OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. * + ****************************************************************************************/ + +#version __CONTEXT__ + +layout(location = 0) in vec4 position; +out vec2 texCoord; + +void main() { + texCoord = 0.5 + position.xy * 0.5; + gl_Position = position; +} diff --git a/shaders/framebuffer/raycastframebuffer.frag b/shaders/framebuffer/raycastframebuffer.frag index b5a972cff8..120bcdd2b8 100644 --- a/shaders/framebuffer/raycastframebuffer.frag +++ b/shaders/framebuffer/raycastframebuffer.frag @@ -32,6 +32,8 @@ uniform bool insideRaycaster; uniform vec3 cameraPosInRaycaster; uniform vec2 windowSize; +uniform int rayCastSteps; + #include "blending.glsl" #include "rand.glsl" #include "floatoperations.glsl" @@ -45,7 +47,6 @@ uniform vec2 windowSize; out vec4 finalColor; #define ALPHA_LIMIT 0.99 -#define RAYCAST_MAX_STEPS 480 #include <#{getEntryPath}> @@ -99,7 +100,7 @@ void main() { for (nSteps = 0; (accumulatedAlpha.r < ALPHA_LIMIT || accumulatedAlpha.g < ALPHA_LIMIT || - accumulatedAlpha.b < ALPHA_LIMIT) && nSteps < RAYCAST_MAX_STEPS; + accumulatedAlpha.b < ALPHA_LIMIT) && nSteps < rayCastSteps; ++nSteps) { if (nextStepSize < raycastDepth / 10000000000.f) { diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index 2007f13a53..b6ce5df96e 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -59,6 +59,10 @@ namespace { "renderedTexture", "inverseScreenSize" }; + constexpr const std::array DownscaledVolumeUniformNames = { + "downscaledRenderedVolume" + }; + constexpr const char* ExitFragmentShaderPath = "${SHADERS}/framebuffer/exitframebuffer.frag"; constexpr const char* RaycastFragmentShaderPath = @@ -184,6 +188,10 @@ void FramebufferRenderer::initialize() { glGenFramebuffers(1, &_fxaaBuffers.fxaaFramebuffer); glGenTextures(1, &_fxaaBuffers.fxaaTexture); + // DownscaleVolumeRendering + glGenFramebuffers(1, &_downscaleVolumeRendering.framebuffer); + glGenTextures(1, &_downscaleVolumeRendering.colorTexture); + // Allocate Textures/Buffers Memory updateResolution(); @@ -307,11 +315,29 @@ void FramebufferRenderer::initialize() { LERROR("FXAA framebuffer is not complete"); } + //================================================// + //===== Downscale Volume Rendering Buffers =====// + //================================================// + glBindFramebuffer(GL_FRAMEBUFFER, _downscaleVolumeRendering.framebuffer); + glFramebufferTexture( + GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + _downscaleVolumeRendering.colorTexture, + 0 + ); + + status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) { + LERROR("Downscale Volume Rendering framebuffer is not complete"); + } + + // JCC: Moved to here to avoid NVidia: "Program/shader state performance warning" // Building programs updateHDRAndFiltering(); updateFXAA(); updateDeferredcastData(); + updateDownscaledVolume(); // Sets back to default FBO glBindFramebuffer(GL_FRAMEBUFFER, _defaultFBO); @@ -326,6 +352,11 @@ void FramebufferRenderer::initialize() { _fxaaUniformCache, FXAAUniformNames ); + ghoul::opengl::updateUniformLocations( + *_downscaledVolumeProgram, + _writeDownscaledVolumeUniformCache, + DownscaledVolumeUniformNames + ); global::raycasterManager.addListener(*this); global::deferredcasterManager.addListener(*this); @@ -342,6 +373,7 @@ void FramebufferRenderer::deinitialize() { glDeleteFramebuffers(1, &_hdrBuffers.hdrFilteringFramebuffer); glDeleteFramebuffers(1, &_fxaaBuffers.fxaaFramebuffer); glDeleteFramebuffers(1, &_pingPongBuffers.framebuffer); + glDeleteFramebuffers(1, &_downscaleVolumeRendering.framebuffer); glDeleteTextures(1, &_gBuffers.colorTexture); glDeleteTextures(1, &_gBuffers.depthTexture); @@ -350,7 +382,8 @@ void FramebufferRenderer::deinitialize() { glDeleteTextures(1, &_fxaaBuffers.fxaaTexture); glDeleteTextures(1, &_gBuffers.positionTexture); glDeleteTextures(1, &_gBuffers.normalTexture); - + glDeleteTextures(1, &_downscaleVolumeRendering.colorTexture); + glDeleteTextures(1, &_pingPongBuffers.colorTexture[1]); glDeleteTextures(1, &_exitColorTexture); @@ -447,6 +480,90 @@ void FramebufferRenderer::applyFXAA() { _fxaaProgram->deactivate(); } +void FramebufferRenderer::updateDownscaleColorTexture() { + glBindTexture(GL_TEXTURE_2D, _downscaleVolumeRendering.colorTexture); + glTexImage2D( + GL_TEXTURE_2D, + 0, + GL_RGBA32F, + _resolution.x * _downscaleVolumeRendering.currentDownscaleFactor, + _resolution.y * _downscaleVolumeRendering.currentDownscaleFactor, + 0, + GL_RGBA, + GL_FLOAT, + nullptr + ); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); +} + +void FramebufferRenderer::writeDownscaledVolume() { + const bool doPerformanceMeasurements = global::performanceManager.isEnabled(); + std::unique_ptr perfInternal; + + if (doPerformanceMeasurements) { + perfInternal = std::make_unique( + "FramebufferRenderer::render::writeDownscaledVolume" + ); + } + + // Saving current OpenGL state + GLboolean blendEnabled = glIsEnabledi(GL_BLEND, 0); + + GLenum blendEquationRGB; + glGetIntegerv(GL_BLEND_EQUATION_RGB, &blendEquationRGB); + + GLenum blendEquationAlpha; + glGetIntegerv(GL_BLEND_EQUATION_ALPHA, &blendEquationAlpha); + + GLenum blendDestAlpha; + glGetIntegerv(GL_BLEND_DST_ALPHA, &blendDestAlpha); + + GLenum blendDestRGB; + glGetIntegerv(GL_BLEND_DST_RGB, &blendDestRGB); + + GLenum blendSrcAlpha; + glGetIntegerv(GL_BLEND_SRC_ALPHA, &blendSrcAlpha); + + GLenum blendSrcRGB; + glGetIntegerv(GL_BLEND_SRC_RGB, &blendSrcRGB); + + glEnablei(GL_BLEND, 0); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + + _downscaledVolumeProgram->activate(); + + ghoul::opengl::TextureUnit downscaledTextureUnit; + downscaledTextureUnit.activate(); + glBindTexture( + GL_TEXTURE_2D, + _downscaleVolumeRendering.colorTexture + ); + + _downscaledVolumeProgram->setUniform( + _writeDownscaledVolumeUniformCache.downscaledRenderedVolume, + downscaledTextureUnit + ); + + glEnablei(GL_BLEND, 0); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + + glBindVertexArray(_screenQuad); + glDrawArrays(GL_TRIANGLES, 0, 6); + glBindVertexArray(0); + + _downscaledVolumeProgram->deactivate(); + + // Restores blending state + glBlendEquationSeparate(blendEquationRGB, blendEquationAlpha); + glBlendFuncSeparate(blendSrcRGB, blendDestRGB, blendSrcAlpha, blendDestAlpha); + + if (!blendEnabled) { + glDisablei(GL_BLEND, 0); + } + +} + void FramebufferRenderer::update() { if (_dirtyResolution) { updateResolution(); @@ -480,6 +597,16 @@ void FramebufferRenderer::update() { ); } + if (_downscaledVolumeProgram->isDirty()) { + _downscaledVolumeProgram->rebuildFromFile(); + + ghoul::opengl::updateUniformLocations( + *_downscaledVolumeProgram, + _writeDownscaledVolumeUniformCache, + DownscaledVolumeUniformNames + ); + } + using K = VolumeRaycaster*; using V = std::unique_ptr; for (const std::pair& program : _exitPrograms) { @@ -639,6 +766,23 @@ void FramebufferRenderer::updateResolution() { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + // Downscale Volume Rendering + glBindTexture(GL_TEXTURE_2D, _downscaleVolumeRendering.colorTexture); + glTexImage2D( + GL_TEXTURE_2D, + 0, + GL_RGBA32F, + _resolution.x * _downscaleVolumeRendering.currentDownscaleFactor, + _resolution.y * _downscaleVolumeRendering.currentDownscaleFactor, + 0, + GL_RGBA, + GL_FLOAT, + nullptr + ); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + + // Volume Rendering Textures glBindTexture(GL_TEXTURE_2D, _exitColorTexture); glTexImage2D( @@ -822,6 +966,17 @@ void FramebufferRenderer::updateFXAA() { //_fxaaProgram->setIgnoreUniformLocationError(IgnoreError::Yes); } +void FramebufferRenderer::updateDownscaledVolume() { + _downscaledVolumeProgram = ghoul::opengl::ProgramObject::Build( + "Write Downscaled Volume Program", + absPath("${SHADERS}/framebuffer/mergeDownscaledVolume.vert"), + absPath("${SHADERS}/framebuffer/mergeDownscaledVolume.frag") + ); + using IgnoreError = ghoul::opengl::ProgramObject::IgnoreError; + //_downscaledVolumeProgram->setIgnoreSubroutineUniformLocationError(IgnoreError::Yes); + //_downscaledVolumeProgram->setIgnoreUniformLocationError(IgnoreError::Yes); +} + void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFactor) { // Set OpenGL default rendering state glGetIntegerv(GL_FRAMEBUFFER_BINDING, &_defaultFBO); @@ -945,7 +1100,20 @@ void FramebufferRenderer::performRaycasterTasks(const std::vector exitProgram->deactivate(); } - glBindFramebuffer(GL_FRAMEBUFFER, _gBuffers.framebuffer); + if (raycaster->downscaleRender() != 1.f) { + float scaleDown = raycaster->downscaleRender(); + glBindFramebuffer(GL_FRAMEBUFFER, _downscaleVolumeRendering.framebuffer); + glViewport(0, 0, _resolution.x * scaleDown, _resolution.y * scaleDown); + if (_downscaleVolumeRendering.currentDownscaleFactor != scaleDown) { + _downscaleVolumeRendering.currentDownscaleFactor = scaleDown; + updateDownscaleColorTexture(); + } + glClear(GL_COLOR_BUFFER_BIT); + } + else { + glBindFramebuffer(GL_FRAMEBUFFER, _gBuffers.framebuffer); + } + glm::vec3 cameraPosition; bool isCameraInside = raycaster->isCameraInside( raycasterTask.renderData, @@ -977,6 +1145,8 @@ void FramebufferRenderer::performRaycasterTasks(const std::vector } if (raycastProgram) { + raycastProgram->setUniform("rayCastSteps", raycaster->maxSteps()); + raycaster->preRaycast(_raycastData[raycaster], *raycastProgram); ghoul::opengl::TextureUnit exitColorTextureUnit; @@ -994,7 +1164,16 @@ void FramebufferRenderer::performRaycasterTasks(const std::vector glBindTexture(GL_TEXTURE_2D, _gBuffers.depthTexture); raycastProgram->setUniform("mainDepthTexture", mainDepthTextureUnit); - raycastProgram->setUniform("windowSize", static_cast(_resolution)); + if (raycaster->downscaleRender() != 1.f) { + float scaleDown = raycaster->downscaleRender(); + raycastProgram->setUniform( + "windowSize", + glm::vec2(_resolution.x * scaleDown, _resolution.y * scaleDown) + ); + } + else { + raycastProgram->setUniform("windowSize", static_cast(_resolution)); + } glDisable(GL_DEPTH_TEST); glDepthMask(false); @@ -1015,6 +1194,14 @@ void FramebufferRenderer::performRaycasterTasks(const std::vector else { LWARNING("Raycaster is not attached when trying to perform raycaster task"); } + + if (raycaster->downscaleRender() != 1.f) { + float scaleDown = raycaster->downscaleRender(); + glViewport(0, 0, _resolution.x, _resolution.y); + glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _gBuffers.framebuffer); + writeDownscaledVolume(); + + } } } From 86bd05276ff78a78340efacb3809820750880fa4 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Mon, 11 Nov 2019 13:29:32 -0500 Subject: [PATCH 03/10] Added slide control for downscaling factor. --- modules/galaxy/rendering/renderablegalaxy.cpp | 12 ++++++++++++ modules/galaxy/rendering/renderablegalaxy.h | 2 +- 2 files changed, 13 insertions(+), 1 deletion(-) diff --git a/modules/galaxy/rendering/renderablegalaxy.cpp b/modules/galaxy/rendering/renderablegalaxy.cpp index 758ab082a1..8597c7a5e0 100644 --- a/modules/galaxy/rendering/renderablegalaxy.cpp +++ b/modules/galaxy/rendering/renderablegalaxy.cpp @@ -117,6 +117,13 @@ namespace { "Enabled points", "" // @TODO Missing documentation }; + + constexpr openspace::properties::Property::PropertyInfo DownscaleVolumeRenderingInfo = { + "Downscale", + "Downscale Factor Volume Rendering", + "This value set the downscaling factor" + " when rendering the current volume." + }; } // namespace namespace openspace { @@ -135,6 +142,7 @@ namespace openspace { , _enabledPointsRatio(EnabledPointsRatioInfo, 0.5f, 0.01f, 1.0f) , _translation(TranslationInfo, glm::vec3(0.f), glm::vec3(0.f), glm::vec3(1.f)) , _rotation(RotationInfo, glm::vec3(0.f), glm::vec3(0.f), glm::vec3(6.28f)) + , _downScaleVolumeRendering(DownscaleVolumeRenderingInfo, 1.f, 0.1f, 1.f) { dictionary.getValue("VolumeRenderingEnabled", _volumeRenderingEnabled); dictionary.getValue("StarRenderingEnabled", _starRenderingEnabled); @@ -232,6 +240,9 @@ namespace openspace { " Using default value."); } + _downScaleVolumeRendering.setVisibility( + openspace::properties::Property::Visibility::Developer + ); if (volumeDictionary.hasKey("Downscale")) { _downScaleVolumeRendering = volumeDictionary.value("Downscale"); } @@ -319,6 +330,7 @@ void RenderableGalaxy::initializeGL() { addProperty(_enabledPointsRatio); addProperty(_translation); addProperty(_rotation); + addProperty(_downScaleVolumeRendering); // initialize points. if (!_pointsFilename.empty()) { diff --git a/modules/galaxy/rendering/renderablegalaxy.h b/modules/galaxy/rendering/renderablegalaxy.h index 8346820b99..ea7ddcb824 100644 --- a/modules/galaxy/rendering/renderablegalaxy.h +++ b/modules/galaxy/rendering/renderablegalaxy.h @@ -71,6 +71,7 @@ private: properties::FloatProperty _enabledPointsRatio; properties::Vec3Property _translation; properties::Vec3Property _rotation; + properties::FloatProperty _downScaleVolumeRendering; std::unique_ptr _pointSpreadFunctionTexture; std::unique_ptr _pointSpreadFunctionFile; @@ -80,7 +81,6 @@ private: std::string _pointsFilename; std::string _pointSpreadFunctionTexturePath; int _rayCastSteps = 1000; - float _downScaleVolumeRendering = 1.f; std::unique_ptr _raycaster; std::unique_ptr>> _volume; From 6ca304724759d8d9e3f267d7571f68a29f98e922 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Mon, 11 Nov 2019 14:39:28 -0500 Subject: [PATCH 04/10] Updated ToyVolume. Add downscaling controls. --- .../rendering/renderabletoyvolume.cpp | 29 +++++++++++++++++++ .../toyvolume/rendering/renderabletoyvolume.h | 3 ++ openspace.cfg | 2 +- 3 files changed, 33 insertions(+), 1 deletion(-) diff --git a/modules/toyvolume/rendering/renderabletoyvolume.cpp b/modules/toyvolume/rendering/renderabletoyvolume.cpp index ccb5018780..a5c37bf4e2 100644 --- a/modules/toyvolume/rendering/renderabletoyvolume.cpp +++ b/modules/toyvolume/rendering/renderabletoyvolume.cpp @@ -29,8 +29,10 @@ #include #include #include +#include namespace { + constexpr const char* _loggerCat = "Renderable ToyVolume"; constexpr openspace::properties::Property::PropertyInfo SizeInfo = { "Size", "Size", @@ -66,6 +68,13 @@ namespace { "Color", "" // @TODO Missing documentation }; + + constexpr openspace::properties::Property::PropertyInfo DownscaleVolumeRenderingInfo = { + "Downscale", + "Downscale Factor Volume Rendering", + "This value set the downscaling factor" + " when rendering the current volume." + }; } // namespace namespace openspace { @@ -78,6 +87,7 @@ RenderableToyVolume::RenderableToyVolume(const ghoul::Dictionary& dictionary) , _translation(TranslationInfo, glm::vec3(0.f), glm::vec3(0.f), glm::vec3(10.f)) , _rotation(RotationInfo, glm::vec3(0.f, 0.f, 0.f), glm::vec3(0), glm::vec3(6.28f)) , _color(ColorInfo, glm::vec4(1.f, 0.f, 0.f, 0.1f), glm::vec4(0.f), glm::vec4(1.f)) + , _downScaleVolumeRendering(DownscaleVolumeRenderingInfo, 1.f, 0.1f, 1.f) { if (dictionary.hasKeyAndValue(ScalingExponentInfo.identifier)) { _scalingExponent = static_cast( @@ -104,6 +114,22 @@ RenderableToyVolume::RenderableToyVolume(const ghoul::Dictionary& dictionary) if (dictionary.hasKeyAndValue(StepSizeInfo.identifier)) { _stepSize = static_cast(dictionary.value(StepSizeInfo.identifier)); } + + _downScaleVolumeRendering.setVisibility( + openspace::properties::Property::Visibility::Developer + ); + if (dictionary.hasKey("Downscale")) { + _downScaleVolumeRendering = dictionary.value("Downscale"); + } + + if (dictionary.hasKey("Steps")) { + _rayCastSteps = static_cast(dictionary.value("Steps")); + } + else { + LINFO("Number of raycasting steps not specified for ToyVolume." + " Using default value."); + } + } RenderableToyVolume::~RenderableToyVolume() {} @@ -131,6 +157,7 @@ void RenderableToyVolume::initializeGL() { addProperty(_translation); addProperty(_rotation); addProperty(_color); + addProperty(_downScaleVolumeRendering); } void RenderableToyVolume::deinitializeGL() { @@ -167,6 +194,8 @@ void RenderableToyVolume::update(const UpdateData& data) { _raycaster->setStepSize(_stepSize); _raycaster->setModelTransform(transform); _raycaster->setTime(data.time.j2000Seconds()); + _raycaster->setDownscaleRender(_downScaleVolumeRendering); + _raycaster->setMaxSteps(_rayCastSteps); } } diff --git a/modules/toyvolume/rendering/renderabletoyvolume.h b/modules/toyvolume/rendering/renderabletoyvolume.h index 8c1b0a36e0..d946bd21f9 100644 --- a/modules/toyvolume/rendering/renderabletoyvolume.h +++ b/modules/toyvolume/rendering/renderabletoyvolume.h @@ -55,8 +55,11 @@ private: properties::Vec3Property _translation; properties::Vec3Property _rotation; properties::Vec4Property _color; + properties::FloatProperty _downScaleVolumeRendering; std::unique_ptr _raycaster; + + int _rayCastSteps = 1000; }; } // namespace openspace diff --git a/openspace.cfg b/openspace.cfg index b47a47aa89..996fa99556 100644 --- a/openspace.cfg +++ b/openspace.cfg @@ -27,7 +27,7 @@ SGCTConfig = sgct.config.single{} -- SGCTConfig = sgct.config.fisheye{1024, 1024} -- A 4k fisheye rendering in a 1024x1024 window --- SGCTConfig = sgct.config.fisheye{1024, 1024, res={4096, 4096}, quality="2k", tilt=27} +SGCTConfig = sgct.config.fisheye{1024, 1024, res={4096, 4096}, quality="2k", tilt=27} -- Streaming OpenSpace via Spout to OBS -- SGCTConfig = sgct.config.single{2560, 1440, shared=true, name="WV_OBS_SPOUT1"} From 7e8cae4a515e1c524632611f25e794ce9e8b0895 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Mon, 11 Nov 2019 14:48:35 -0500 Subject: [PATCH 05/10] Improved volume border color. --- src/rendering/framebufferrenderer.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index 39a85fe1fd..f45c618b76 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -793,6 +793,8 @@ void FramebufferRenderer::updateResolution() { ); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + float volumeBorderColor[] = { 0.0f, 0.0f, 0.0f, 1.0f }; + glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, volumeBorderColor); // Volume Rendering Textures From caa02ca20ac68c5564a21ecb7e985d602807b78c Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Tue, 12 Nov 2019 17:19:23 -0500 Subject: [PATCH 06/10] Clean up. Added the raycasting number of steps as a slider for user's control. --- modules/galaxy/rendering/renderablegalaxy.cpp | 21 ++++++++++++++----- modules/galaxy/rendering/renderablegalaxy.h | 2 +- openspace.cfg | 2 +- shaders/framebuffer/raycastframebuffer.frag | 4 ++-- src/rendering/framebufferrenderer.cpp | 6 +++--- 5 files changed, 23 insertions(+), 12 deletions(-) diff --git a/modules/galaxy/rendering/renderablegalaxy.cpp b/modules/galaxy/rendering/renderablegalaxy.cpp index 8597c7a5e0..9dfe003559 100644 --- a/modules/galaxy/rendering/renderablegalaxy.cpp +++ b/modules/galaxy/rendering/renderablegalaxy.cpp @@ -124,6 +124,12 @@ namespace { "This value set the downscaling factor" " when rendering the current volume." }; + + constexpr openspace::properties::Property::PropertyInfo NumberOfRayCastingStepsInfo = { + "Steps", + "Number of RayCasting Steps", + "This value set the number of integration steps during the raycasting procedure." + }; } // namespace namespace openspace { @@ -143,6 +149,7 @@ namespace openspace { , _translation(TranslationInfo, glm::vec3(0.f), glm::vec3(0.f), glm::vec3(1.f)) , _rotation(RotationInfo, glm::vec3(0.f), glm::vec3(0.f), glm::vec3(6.28f)) , _downScaleVolumeRendering(DownscaleVolumeRenderingInfo, 1.f, 0.1f, 1.f) + , _numberOfRayCastingSteps(NumberOfRayCastingStepsInfo, 1000.f, 1.f, 1000.f) { dictionary.getValue("VolumeRenderingEnabled", _volumeRenderingEnabled); dictionary.getValue("StarRenderingEnabled", _starRenderingEnabled); @@ -232,8 +239,10 @@ namespace openspace { LERROR("No volume dimensions specified."); } - if (volumeDictionary.hasKey("Steps")) { - _rayCastSteps = static_cast(volumeDictionary.value("Steps")); + if (volumeDictionary.hasKey(NumberOfRayCastingStepsInfo.identifier)) { + _numberOfRayCastingSteps = static_cast( + volumeDictionary.value(NumberOfRayCastingStepsInfo.identifier) + ); } else { LINFO("Number of raycasting steps not specified for Milkway Galaxy." @@ -243,8 +252,9 @@ namespace openspace { _downScaleVolumeRendering.setVisibility( openspace::properties::Property::Visibility::Developer ); - if (volumeDictionary.hasKey("Downscale")) { - _downScaleVolumeRendering = volumeDictionary.value("Downscale"); + if (volumeDictionary.hasKey(DownscaleVolumeRenderingInfo.identifier)) { + _downScaleVolumeRendering = + volumeDictionary.value(DownscaleVolumeRenderingInfo.identifier); } if (!dictionary.hasKeyAndValue("Points")) { @@ -331,6 +341,7 @@ void RenderableGalaxy::initializeGL() { addProperty(_translation); addProperty(_rotation); addProperty(_downScaleVolumeRendering); + addProperty(_numberOfRayCastingSteps); // initialize points. if (!_pointsFilename.empty()) { @@ -495,7 +506,7 @@ void RenderableGalaxy::update(const UpdateData& data) { _pointTransform[3] += translation; _raycaster->setDownscaleRender(_downScaleVolumeRendering); - _raycaster->setMaxSteps(_rayCastSteps); + _raycaster->setMaxSteps(_numberOfRayCastingSteps); _raycaster->setStepSize(_stepSize); _raycaster->setAspect(_aspect); _raycaster->setModelTransform(volumeTransform); diff --git a/modules/galaxy/rendering/renderablegalaxy.h b/modules/galaxy/rendering/renderablegalaxy.h index ea7ddcb824..d074bd848b 100644 --- a/modules/galaxy/rendering/renderablegalaxy.h +++ b/modules/galaxy/rendering/renderablegalaxy.h @@ -72,6 +72,7 @@ private: properties::Vec3Property _translation; properties::Vec3Property _rotation; properties::FloatProperty _downScaleVolumeRendering; + properties::FloatProperty _numberOfRayCastingSteps; std::unique_ptr _pointSpreadFunctionTexture; std::unique_ptr _pointSpreadFunctionFile; @@ -80,7 +81,6 @@ private: glm::ivec3 _volumeDimensions; std::string _pointsFilename; std::string _pointSpreadFunctionTexturePath; - int _rayCastSteps = 1000; std::unique_ptr _raycaster; std::unique_ptr>> _volume; diff --git a/openspace.cfg b/openspace.cfg index 996fa99556..b47a47aa89 100644 --- a/openspace.cfg +++ b/openspace.cfg @@ -27,7 +27,7 @@ SGCTConfig = sgct.config.single{} -- SGCTConfig = sgct.config.fisheye{1024, 1024} -- A 4k fisheye rendering in a 1024x1024 window -SGCTConfig = sgct.config.fisheye{1024, 1024, res={4096, 4096}, quality="2k", tilt=27} +-- SGCTConfig = sgct.config.fisheye{1024, 1024, res={4096, 4096}, quality="2k", tilt=27} -- Streaming OpenSpace via Spout to OBS -- SGCTConfig = sgct.config.single{2560, 1440, shared=true, name="WV_OBS_SPOUT1"} diff --git a/shaders/framebuffer/raycastframebuffer.frag b/shaders/framebuffer/raycastframebuffer.frag index 120bcdd2b8..4cb79d25a0 100644 --- a/shaders/framebuffer/raycastframebuffer.frag +++ b/shaders/framebuffer/raycastframebuffer.frag @@ -28,7 +28,6 @@ uniform sampler2D exitColorTexture; uniform sampler2D exitDepthTexture; uniform sampler2D mainDepthTexture; -uniform bool insideRaycaster; uniform vec3 cameraPosInRaycaster; uniform vec2 windowSize; @@ -53,6 +52,7 @@ out vec4 finalColor; void main() { vec2 texCoord = vec2(gl_FragCoord.xy / windowSize); + // Boundary position in view space vec4 exitColorTexture = texture(exitColorTexture, texCoord); // If we don't have an exit, discard the ray @@ -80,7 +80,7 @@ void main() { vec3 direction = normalize(diff); float raycastDepth = length(diff); - float geoDepth = denormalizeFloat(texelFetch(mainDepthTexture, ivec2(gl_FragCoord), 0).x); + float geoDepth = denormalizeFloat((texture(mainDepthTexture, texCoord).x)); float geoRatio = clamp((geoDepth - entryDepth) / (exitDepth - entryDepth), 0.f, 1.f); raycastDepth = geoRatio * raycastDepth; diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index f45c618b76..76f571cf01 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -1116,7 +1116,7 @@ void FramebufferRenderer::performRaycasterTasks(const std::vector exitProgram->deactivate(); } - if (raycaster->downscaleRender() != 1.f) { + if (raycaster->downscaleRender() < 1.f) { float scaleDown = raycaster->downscaleRender(); glBindFramebuffer(GL_FRAMEBUFFER, _downscaleVolumeRendering.framebuffer); glViewport(0, 0, _resolution.x * scaleDown, _resolution.y * scaleDown); @@ -1180,7 +1180,7 @@ void FramebufferRenderer::performRaycasterTasks(const std::vector glBindTexture(GL_TEXTURE_2D, _gBuffers.depthTexture); raycastProgram->setUniform("mainDepthTexture", mainDepthTextureUnit); - if (raycaster->downscaleRender() != 1.f) { + if (raycaster->downscaleRender() < 1.f) { float scaleDown = raycaster->downscaleRender(); raycastProgram->setUniform( "windowSize", @@ -1211,7 +1211,7 @@ void FramebufferRenderer::performRaycasterTasks(const std::vector LWARNING("Raycaster is not attached when trying to perform raycaster task"); } - if (raycaster->downscaleRender() != 1.f) { + if (raycaster->downscaleRender() < 1.f) { float scaleDown = raycaster->downscaleRender(); glViewport(0, 0, _resolution.x, _resolution.y); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _gBuffers.framebuffer); From aaa73415e9a62b1dc169c090cf4882ea19285d83 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Wed, 13 Nov 2019 15:36:13 -0500 Subject: [PATCH 07/10] Final touches in MW volume. --- data/assets/scene/milkyway/milkyway/volume.asset | 3 +-- include/openspace/rendering/framebufferrenderer.h | 1 + src/rendering/framebufferrenderer.cpp | 5 ++++- 3 files changed, 6 insertions(+), 3 deletions(-) diff --git a/data/assets/scene/milkyway/milkyway/volume.asset b/data/assets/scene/milkyway/milkyway/volume.asset index 78195a1b5c..5e88cb9052 100644 --- a/data/assets/scene/milkyway/milkyway/volume.asset +++ b/data/assets/scene/milkyway/milkyway/volume.asset @@ -25,8 +25,7 @@ local MilkyWayVolumeGalaxy = { Filename = data .. "/MilkyWayRGBAVolume1024x1024x128.raw", Dimensions = {1024, 1024, 128}, Size = {1.2E21, 1.2E21, 0.15E21}, - Steps = 480, - Downscale = 0.5, + Downscale = 0.4, }, Points = { Type = "Points", diff --git a/include/openspace/rendering/framebufferrenderer.h b/include/openspace/rendering/framebufferrenderer.h index 4529fd60a4..952bf13d68 100644 --- a/include/openspace/rendering/framebufferrenderer.h +++ b/include/openspace/rendering/framebufferrenderer.h @@ -112,6 +112,7 @@ private: void applyTMO(float blackoutFactor); void applyFXAA(); void updateDownscaleColorTexture(); + void updateExitVolumeTextures(); void writeDownscaledVolume(); std::map _raycastData; diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index 76f571cf01..7d43b4d981 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -560,10 +560,14 @@ void FramebufferRenderer::writeDownscaledVolume() { glEnablei(GL_BLEND, 0); glBlendFunc(GL_SRC_ALPHA, GL_ONE); + glDisable(GL_DEPTH_TEST); + glBindVertexArray(_screenQuad); glDrawArrays(GL_TRIANGLES, 0, 6); glBindVertexArray(0); + glEnable(GL_DEPTH_TEST); + _downscaledVolumeProgram->deactivate(); // Restores blending state @@ -1212,7 +1216,6 @@ void FramebufferRenderer::performRaycasterTasks(const std::vector } if (raycaster->downscaleRender() < 1.f) { - float scaleDown = raycaster->downscaleRender(); glViewport(0, 0, _resolution.x, _resolution.y); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _gBuffers.framebuffer); writeDownscaledVolume(); From 60813e3209d20674f7902ff3d0964ec6fc3b5aa9 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Tue, 26 Nov 2019 11:06:39 -0500 Subject: [PATCH 08/10] Final version with volume depth interpolation. --- .../openspace/rendering/framebufferrenderer.h | 6 +- .../framebuffer/mergeDownscaledVolume.frag | 4 +- shaders/framebuffer/raycastframebuffer.frag | 1 + src/rendering/framebufferrenderer.cpp | 60 +++++++++++++++++-- 4 files changed, 64 insertions(+), 7 deletions(-) diff --git a/include/openspace/rendering/framebufferrenderer.h b/include/openspace/rendering/framebufferrenderer.h index 952bf13d68..7dd048052f 100644 --- a/include/openspace/rendering/framebufferrenderer.h +++ b/include/openspace/rendering/framebufferrenderer.h @@ -111,7 +111,7 @@ private: void resolveMSAA(float blackoutFactor); void applyTMO(float blackoutFactor); void applyFXAA(); - void updateDownscaleColorTexture(); + void updateDownscaleTextures(); void updateExitVolumeTextures(); void writeDownscaledVolume(); @@ -131,7 +131,8 @@ private: UniformCache(hdrFeedingTexture, blackoutFactor, hdrExposure, gamma, Hue, Saturation, Value) _hdrUniformCache; UniformCache(renderedTexture, inverseScreenSize) _fxaaUniformCache; - UniformCache(downscaledRenderedVolume) _writeDownscaledVolumeUniformCache; + UniformCache(downscaledRenderedVolume, downscaledRenderedVolumeDepth) + _writeDownscaledVolumeUniformCache; GLint _defaultFBO; GLuint _screenQuad; @@ -166,6 +167,7 @@ private: struct { GLuint framebuffer; GLuint colorTexture; + GLuint depthbuffer; float currentDownscaleFactor = 1.f; } _downscaleVolumeRendering; diff --git a/shaders/framebuffer/mergeDownscaledVolume.frag b/shaders/framebuffer/mergeDownscaledVolume.frag index f34a300742..14a6405735 100644 --- a/shaders/framebuffer/mergeDownscaledVolume.frag +++ b/shaders/framebuffer/mergeDownscaledVolume.frag @@ -27,9 +27,11 @@ layout (location = 0) out vec4 finalColor; uniform sampler2D downscaledRenderedVolume; +uniform sampler2D downscaledRenderedVolumeDepth; in vec2 texCoord; void main() { - finalColor = texture(downscaledRenderedVolume, texCoord); + finalColor = texture(downscaledRenderedVolume, texCoord); + gl_FragDepth = texture(downscaledRenderedVolumeDepth, texCoord).r; } diff --git a/shaders/framebuffer/raycastframebuffer.frag b/shaders/framebuffer/raycastframebuffer.frag index 4cb79d25a0..bff04b1dbe 100644 --- a/shaders/framebuffer/raycastframebuffer.frag +++ b/shaders/framebuffer/raycastframebuffer.frag @@ -126,5 +126,6 @@ void main() { finalColor = vec4(accumulatedColor, (accumulatedAlpha.r + accumulatedAlpha.g + accumulatedAlpha.b) / 3.f); finalColor.rgb /= finalColor.a ; + gl_FragDepth = normalizeFloat(entryDepth); } diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index 7d43b4d981..6f9d372218 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -59,8 +59,8 @@ namespace { "renderedTexture", "inverseScreenSize" }; - constexpr const std::array DownscaledVolumeUniformNames = { - "downscaledRenderedVolume" + constexpr const std::array DownscaledVolumeUniformNames = { + "downscaledRenderedVolume", "downscaledRenderedVolumeDepth" }; constexpr const char* ExitFragmentShaderPath = @@ -191,6 +191,7 @@ void FramebufferRenderer::initialize() { // DownscaleVolumeRendering glGenFramebuffers(1, &_downscaleVolumeRendering.framebuffer); glGenTextures(1, &_downscaleVolumeRendering.colorTexture); + glGenTextures(1, &_downscaleVolumeRendering.depthbuffer); // Allocate Textures/Buffers Memory updateResolution(); @@ -325,6 +326,12 @@ void FramebufferRenderer::initialize() { _downscaleVolumeRendering.colorTexture, 0 ); + glFramebufferTexture( + GL_FRAMEBUFFER, + GL_DEPTH_ATTACHMENT, + _downscaleVolumeRendering.depthbuffer, + 0 + ); status = glCheckFramebufferStatus(GL_FRAMEBUFFER); if (status != GL_FRAMEBUFFER_COMPLETE) { @@ -383,6 +390,7 @@ void FramebufferRenderer::deinitialize() { glDeleteTextures(1, &_gBuffers.positionTexture); glDeleteTextures(1, &_gBuffers.normalTexture); glDeleteTextures(1, &_downscaleVolumeRendering.colorTexture); + glDeleteTextures(1, &_downscaleVolumeRendering.depthbuffer); glDeleteTextures(1, &_pingPongBuffers.colorTexture[1]); @@ -492,7 +500,7 @@ void FramebufferRenderer::applyFXAA() { _fxaaProgram->deactivate(); } -void FramebufferRenderer::updateDownscaleColorTexture() { +void FramebufferRenderer::updateDownscaleTextures() { glBindTexture(GL_TEXTURE_2D, _downscaleVolumeRendering.colorTexture); glTexImage2D( GL_TEXTURE_2D, @@ -507,6 +515,23 @@ void FramebufferRenderer::updateDownscaleColorTexture() { ); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + float volumeBorderColor[] = { 0.0f, 0.0f, 0.0f, 1.0f }; + glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, volumeBorderColor); + + glBindTexture(GL_TEXTURE_2D, _downscaleVolumeRendering.depthbuffer); + glTexImage2D( + GL_TEXTURE_2D, + 0, + GL_DEPTH_COMPONENT32F, + _resolution.x * _downscaleVolumeRendering.currentDownscaleFactor, + _resolution.y * _downscaleVolumeRendering.currentDownscaleFactor, + 0, + GL_DEPTH_COMPONENT, + GL_FLOAT, + nullptr + ); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } void FramebufferRenderer::writeDownscaledVolume() { @@ -557,6 +582,19 @@ void FramebufferRenderer::writeDownscaledVolume() { downscaledTextureUnit ); + ghoul::opengl::TextureUnit downscaledDepthUnit; + downscaledDepthUnit.activate(); + glBindTexture( + GL_TEXTURE_2D, + _downscaleVolumeRendering.depthbuffer + ); + + _downscaledVolumeProgram->setUniform( + _writeDownscaledVolumeUniformCache.downscaledRenderedVolumeDepth, + downscaledDepthUnit + ); + + glEnablei(GL_BLEND, 0); glBlendFunc(GL_SRC_ALPHA, GL_ONE); @@ -800,6 +838,20 @@ void FramebufferRenderer::updateResolution() { float volumeBorderColor[] = { 0.0f, 0.0f, 0.0f, 1.0f }; glTexParameterfv(GL_TEXTURE_2D, GL_TEXTURE_BORDER_COLOR, volumeBorderColor); + glBindTexture(GL_TEXTURE_2D, _downscaleVolumeRendering.depthbuffer); + glTexImage2D( + GL_TEXTURE_2D, + 0, + GL_DEPTH_COMPONENT32F, + _resolution.x * _downscaleVolumeRendering.currentDownscaleFactor, + _resolution.y * _downscaleVolumeRendering.currentDownscaleFactor, + 0, + GL_DEPTH_COMPONENT, + GL_FLOAT, + nullptr + ); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); // Volume Rendering Textures glBindTexture(GL_TEXTURE_2D, _exitColorTexture); @@ -1126,7 +1178,7 @@ void FramebufferRenderer::performRaycasterTasks(const std::vector glViewport(0, 0, _resolution.x * scaleDown, _resolution.y * scaleDown); if (_downscaleVolumeRendering.currentDownscaleFactor != scaleDown) { _downscaleVolumeRendering.currentDownscaleFactor = scaleDown; - updateDownscaleColorTexture(); + updateDownscaleTextures(); } glClear(GL_COLOR_BUFFER_BIT); } From e2e86c12abe09ff27eafc326a8aeb9077ac80e34 Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Tue, 26 Nov 2019 17:07:27 -0500 Subject: [PATCH 09/10] Ops. Cleaning depth buffer now. --- src/rendering/framebufferrenderer.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index 6f9d372218..3e145ecf5a 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -1180,7 +1180,7 @@ void FramebufferRenderer::performRaycasterTasks(const std::vector _downscaleVolumeRendering.currentDownscaleFactor = scaleDown; updateDownscaleTextures(); } - glClear(GL_COLOR_BUFFER_BIT); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); } else { glBindFramebuffer(GL_FRAMEBUFFER, _gBuffers.framebuffer); From cf3a64110399caa37b3289d716a8b2c852b27cfa Mon Sep 17 00:00:00 2001 From: Alexander Bock Date: Mon, 16 Dec 2019 09:50:34 +0100 Subject: [PATCH 10/10] Some small cleanup Remove virtual attribute from some of the raycaster functions --- data/assets/scene/milkyway/milkyway/volume.asset | 8 ++++---- include/openspace/rendering/volumeraycaster.h | 8 ++++---- modules/galaxy/rendering/renderablegalaxy.cpp | 5 ++--- src/rendering/framebufferrenderer.cpp | 4 +--- src/rendering/volumeraycaster.cpp | 16 ++++++++++++++++ 5 files changed, 27 insertions(+), 14 deletions(-) diff --git a/data/assets/scene/milkyway/milkyway/volume.asset b/data/assets/scene/milkyway/milkyway/volume.asset index adbd05e08a..2ae420e931 100644 --- a/data/assets/scene/milkyway/milkyway/volume.asset +++ b/data/assets/scene/milkyway/milkyway/volume.asset @@ -21,7 +21,7 @@ local MilkyWayVolumeGalaxy = { -- The center of the Milky Way is approximately 8 kiloparsec from the Sun. -- The x-axis of galactic coordinates points from the sun towards the center -- of the galaxy. - Position = {8 * kiloparsec, 0, 0} + Position = { 8 * kiloparsec, 0, 0 } } }, Renderable = { @@ -29,12 +29,12 @@ local MilkyWayVolumeGalaxy = { StepSize = 0.01, AbsorptionMultiply = 200, EmissionMultiply = 250, - Rotation = {3.1415926, 3.1248, 4.45741}, + Rotation = { 3.1415926, 3.1248, 4.45741 }, Volume = { Type = "Volume", Filename = data .. "/MilkyWayRGBAVolume1024x1024x128.raw", - Dimensions = {1024, 1024, 128}, - Size = {1.2E21, 1.2E21, 0.15E21}, + Dimensions = { 1024, 1024, 128 }, + Size = { 1.2E21, 1.2E21, 0.15E21 }, Downscale = 0.4, }, Points = { diff --git a/include/openspace/rendering/volumeraycaster.h b/include/openspace/rendering/volumeraycaster.h index 687a5f335a..aa1133606e 100644 --- a/include/openspace/rendering/volumeraycaster.h +++ b/include/openspace/rendering/volumeraycaster.h @@ -129,13 +129,13 @@ public: */ virtual std::string helperPath() const = 0; - virtual void setMaxSteps(int nsteps) { _rayCastMaxSteps = nsteps; }; + void setMaxSteps(int nsteps); - virtual const int maxSteps() const { return _rayCastMaxSteps; }; + int maxSteps() const; - virtual void setDownscaleRender(float value) { _downscaleRenderConst = value; }; + void setDownscaleRender(float value); - virtual const float downscaleRender() const { return _downscaleRenderConst; }; + float downscaleRender() const; private: /** diff --git a/modules/galaxy/rendering/renderablegalaxy.cpp b/modules/galaxy/rendering/renderablegalaxy.cpp index 9dfe003559..71edb8d372 100644 --- a/modules/galaxy/rendering/renderablegalaxy.cpp +++ b/modules/galaxy/rendering/renderablegalaxy.cpp @@ -245,8 +245,7 @@ namespace openspace { ); } else { - LINFO("Number of raycasting steps not specified for Milkway Galaxy." - " Using default value."); + LINFO("Number of raycasting steps not specified. Using default value."); } _downScaleVolumeRendering.setVisibility( @@ -254,7 +253,7 @@ namespace openspace { ); if (volumeDictionary.hasKey(DownscaleVolumeRenderingInfo.identifier)) { _downScaleVolumeRendering = - volumeDictionary.value(DownscaleVolumeRenderingInfo.identifier); + volumeDictionary.value(DownscaleVolumeRenderingInfo.identifier); } if (!dictionary.hasKeyAndValue("Points")) { diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index 3e145ecf5a..a6b327149b 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -1271,14 +1271,12 @@ void FramebufferRenderer::performRaycasterTasks(const std::vector glViewport(0, 0, _resolution.x, _resolution.y); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _gBuffers.framebuffer); writeDownscaledVolume(); - } } } void FramebufferRenderer::performDeferredTasks( - const std::vector& tasks - ) + const std::vector& tasks) { for (const DeferredcasterTask& deferredcasterTask : tasks) { Deferredcaster* deferredcaster = deferredcasterTask.deferredcaster; diff --git a/src/rendering/volumeraycaster.cpp b/src/rendering/volumeraycaster.cpp index 17d13627c0..954bda7ac7 100644 --- a/src/rendering/volumeraycaster.cpp +++ b/src/rendering/volumeraycaster.cpp @@ -33,4 +33,20 @@ bool VolumeRaycaster::isCameraInside(const RenderData&, glm::vec3&) { return false; } +void VolumeRaycaster::setMaxSteps(int nsteps) { + _rayCastMaxSteps = nsteps; +} + +int VolumeRaycaster::maxSteps() const { + return _rayCastMaxSteps; +} + +void VolumeRaycaster::setDownscaleRender(float value) { + _downscaleRenderConst = value; +} + +float VolumeRaycaster::downscaleRender() const { + return _downscaleRenderConst; +} + } // namespace openspace