From 8771a238d350e93f4e705285c4b2402e8b19c355 Mon Sep 17 00:00:00 2001 From: Emil Axelsson Date: Wed, 8 Jun 2016 15:00:03 +0200 Subject: [PATCH] improve galaxy rendering --- data/scene/enlilnh/enlilnh.mod | 2 +- data/scene/milkyway/milkyway.mod | 2 +- ext/ghoul | 2 +- include/openspace/rendering/abufferrenderer.h | 1 + .../openspace/rendering/framebufferrenderer.h | 2 + include/openspace/rendering/renderengine.h | 3 + include/openspace/rendering/renderer.h | 2 +- modules/base/rendering/renderablemodel.cpp | 1 + modules/base/rendering/renderablestars.cpp | 2 + modules/base/shaders/star_fs.glsl | 4 +- modules/galaxy/rendering/renderablegalaxy.cpp | 16 ++-- modules/galaxy/rendering/renderablegalaxy.h | 1 + modules/galaxy/shaders/galaxyraycast.glsl | 6 +- modules/galaxy/shaders/points.fs | 4 +- modules/galaxy/shaders/points.vs | 11 ++- modules/galaxy/shaders/raycasterbounds.vs | 5 +- .../rendering/renderablemultiresvolume.cpp | 2 +- shaders/abuffer/postrenderabuffer.frag | 9 +-- shaders/abuffer/resolveabuffer.frag | 23 ++++-- shaders/abuffer/resolveconstants.glsl | 4 +- shaders/abuffer/resolvehelpers.glsl | 42 +++++++---- shaders/framebuffer/raycastframebuffer.frag | 21 +++++- src/rendering/abufferrenderer.cpp | 32 ++++---- src/rendering/framebufferrenderer.cpp | 74 ++++++++++++++++--- src/rendering/renderengine.cpp | 16 ++++ src/rendering/renderengine_lua.inl | 17 +++++ 26 files changed, 220 insertions(+), 84 deletions(-) diff --git a/data/scene/enlilnh/enlilnh.mod b/data/scene/enlilnh/enlilnh.mod index d6e31699be..0cfb1abbb5 100644 --- a/data/scene/enlilnh/enlilnh.mod +++ b/data/scene/enlilnh/enlilnh.mod @@ -12,7 +12,7 @@ return { Translation = {0, 0, 0}, Rotation = {2.1, 0, 0}, Scaling = {1.1, 1.1, 1.1}, - ScalingExponent = 12, + ScalingExponent = 13, Source = "tsp/enlil_nh_128_128_16.tsp", ErrorHistogramsSource = "tsp/enlil_nh_128_128_16.errorHistograms", TransferFunction = "transferfunctions/fire.txt", diff --git a/data/scene/milkyway/milkyway.mod b/data/scene/milkyway/milkyway.mod index 824529977c..148ac2b331 100644 --- a/data/scene/milkyway/milkyway.mod +++ b/data/scene/milkyway/milkyway.mod @@ -7,7 +7,7 @@ return { }, Renderable = { Type = "RenderableSphere", - Size = {10, 25}, + Size = {10, 22}, Segments = 40, Texture = "textures/DarkUniverse_mellinger_8k.jpg", Orientation = "Inside/Outside" diff --git a/ext/ghoul b/ext/ghoul index 735ed53cd2..5cde645215 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 735ed53cd236a7a7cca36d6289ce95909e6a0c92 +Subproject commit 5cde64521525f9094b95a73bca6ca1ccac1a5541 diff --git a/include/openspace/rendering/abufferrenderer.h b/include/openspace/rendering/abufferrenderer.h index d6af2088d1..4a9689fa9f 100644 --- a/include/openspace/rendering/abufferrenderer.h +++ b/include/openspace/rendering/abufferrenderer.h @@ -69,6 +69,7 @@ public: void setCamera(Camera* camera) override; void setScene(Scene* scene) override; void setResolution(glm::ivec2 res) override; + void setNAaSamples(int nAaSamples) override; void preRaycast(ghoul::opengl::ProgramObject& programObject); void postRaycast(ghoul::opengl::ProgramObject& programObject); diff --git a/include/openspace/rendering/framebufferrenderer.h b/include/openspace/rendering/framebufferrenderer.h index fb65728005..df996e695f 100644 --- a/include/openspace/rendering/framebufferrenderer.h +++ b/include/openspace/rendering/framebufferrenderer.h @@ -68,6 +68,7 @@ public: void setCamera(Camera* camera) override; void setScene(Scene* scene) override; void setResolution(glm::ivec2 res) override; + void setNAaSamples(int nAaSamples) override; void update() override; void render(float blackoutFactor, bool doPerformanceMeasurements) override; @@ -84,6 +85,7 @@ private: std::map _raycastData; std::map> _exitPrograms; std::map> _raycastPrograms; + std::map> _insideRaycastPrograms; std::unique_ptr _resolveProgram; diff --git a/include/openspace/rendering/renderengine.h b/include/openspace/rendering/renderengine.h index 913ccd9c82..60ff02bc0b 100644 --- a/include/openspace/rendering/renderengine.h +++ b/include/openspace/rendering/renderengine.h @@ -105,6 +105,8 @@ public: float globalBlackOutFactor(); void setGlobalBlackOutFactor(float factor); + void setNAaSamples(int nAaSamples); + void setDisableRenderingOnMaster(bool enabled); @@ -203,6 +205,7 @@ private: float _fadeDuration; float _currentFadeTime; int _fadeDirection; + int _nAaSamples; std::vector _programs; std::vector> _screenSpaceRenderables; diff --git a/include/openspace/rendering/renderer.h b/include/openspace/rendering/renderer.h index 5835b4f8b8..3258be73c0 100644 --- a/include/openspace/rendering/renderer.h +++ b/include/openspace/rendering/renderer.h @@ -58,7 +58,7 @@ public: virtual void setCamera(Camera* camera) = 0; virtual void setScene(Scene* scene) = 0; virtual void setResolution(glm::ivec2 res) = 0; - + virtual void setNAaSamples(int nAaSamples) = 0; /** * Set raycasting uniforms on the program object, and setup raycasting. diff --git a/modules/base/rendering/renderablemodel.cpp b/modules/base/rendering/renderablemodel.cpp index 76d16ff58e..bd1137554b 100644 --- a/modules/base/rendering/renderablemodel.cpp +++ b/modules/base/rendering/renderablemodel.cpp @@ -267,6 +267,7 @@ void RenderableModel::loadTexture() { if (_texture) { LDEBUG("Loaded texture from '" << absPath(_colorTexturePath) << "'"); _texture->uploadTexture(); + _texture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); } } } diff --git a/modules/base/rendering/renderablestars.cpp b/modules/base/rendering/renderablestars.cpp index 9cc959270f..cf4c2bc3cd 100644 --- a/modules/base/rendering/renderablestars.cpp +++ b/modules/base/rendering/renderablestars.cpp @@ -316,10 +316,12 @@ void RenderableStars::update(const UpdateData& data) { _pointSpreadFunctionTexture = nullptr; if (_pointSpreadFunctionTexturePath.value() != "") { _pointSpreadFunctionTexture = std::move(ghoul::io::TextureReader::ref().loadTexture(absPath(_pointSpreadFunctionTexturePath))); + if (_pointSpreadFunctionTexture) { LDEBUG("Loaded texture from '" << absPath(_pointSpreadFunctionTexturePath) << "'"); _pointSpreadFunctionTexture->uploadTexture(); } + _pointSpreadFunctionTexture->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); delete _psfTextureFile; _psfTextureFile = new ghoul::filesystem::File(_pointSpreadFunctionTexturePath); diff --git a/modules/base/shaders/star_fs.glsl b/modules/base/shaders/star_fs.glsl index 43f77a26b7..39cdcd0bc9 100644 --- a/modules/base/shaders/star_fs.glsl +++ b/modules/base/shaders/star_fs.glsl @@ -58,7 +58,7 @@ vec4 bv2rgb(float bv) { Fragment getFragment() { // Something in the color calculations need to be changed because before it was dependent // on the gl blend functions since the abuffer was not involved - + vec4 color = vec4(0.0); switch (colorOption) { case COLOROPTION_COLOR: @@ -79,7 +79,7 @@ Fragment getFragment() { vec4 position = vs_position; // This has to be fixed when the scale graph is in place ---emiax - position.w = 19; + position.w = 15; Fragment frag; frag.color = fullColor; diff --git a/modules/galaxy/rendering/renderablegalaxy.cpp b/modules/galaxy/rendering/renderablegalaxy.cpp index e1d1bbbd58..6ecfd1a46d 100644 --- a/modules/galaxy/rendering/renderablegalaxy.cpp +++ b/modules/galaxy/rendering/renderablegalaxy.cpp @@ -55,10 +55,11 @@ namespace openspace { RenderableGalaxy::RenderableGalaxy(const ghoul::Dictionary& dictionary) : Renderable(dictionary) - , _stepSize("stepSize", "Step Size", 0.001, 0.0005, 0.05) + , _stepSize("stepSize", "Step Size", 0.012, 0.0005, 0.05) , _pointStepSize("pointStepSize", "Point Step Size", 0.01, 0.01, 0.1) , _translation("translation", "Translation", glm::vec3(0.0, 0.0, 0.0), glm::vec3(0.0), glm::vec3(10.0)) - , _rotation("rotation", "Euler rotation", glm::vec3(0.0, 0.0, 0.0), glm::vec3(0), glm::vec3(6.28)) { + , _rotation("rotation", "Euler rotation", glm::vec3(0.0, 0.0, 0.0), glm::vec3(0), glm::vec3(6.28)) + , _enabledPointsRatio("nEnabledPointsRatio", "Enabled points", 0.2, 0, 1) { float stepSize; glm::vec3 scaling, translation, rotation; @@ -160,6 +161,7 @@ bool RenderableGalaxy::initialize() { addProperty(_pointStepSize); addProperty(_translation); addProperty(_rotation); + addProperty(_enabledPointsRatio); // initialize points. std::ifstream pointFile(_pointsFilename, std::ios::in | std::ios::binary); @@ -271,9 +273,13 @@ void RenderableGalaxy::update(const UpdateData& data) { glm::mat4 volumeTransform = glm::scale(transform, static_cast(_volumeSize)); _pointTransform = glm::scale(transform, static_cast(_pointScaling)); + glm::vec4 translation = glm::vec4(static_cast(_translation), 0.0); + // Todo: handle floating point overflow, to actually support translation. - volumeTransform = glm::translate(volumeTransform, static_cast(_translation)); - _pointTransform = glm::translate(_pointTransform, static_cast(_translation)); + + volumeTransform[3] += translation; + _pointTransform[3] += translation; + _raycaster->setStepSize(_stepSize); _raycaster->setAspect(_aspect); @@ -349,7 +355,7 @@ void RenderableGalaxy::postRender(const RenderData& data) { glDisable(GL_DEPTH_TEST); glDepthMask(false); glBlendFunc(GL_SRC_ALPHA, GL_ONE); - glDrawArrays(GL_POINTS, 0, _nPoints); + glDrawArrays(GL_POINTS, 0, _nPoints * _enabledPointsRatio); glBindVertexArray(0); glDepthMask(true); glEnable(GL_DEPTH_TEST); diff --git a/modules/galaxy/rendering/renderablegalaxy.h b/modules/galaxy/rendering/renderablegalaxy.h index c60ab5fa3d..69b395a2dd 100644 --- a/modules/galaxy/rendering/renderablegalaxy.h +++ b/modules/galaxy/rendering/renderablegalaxy.h @@ -56,6 +56,7 @@ private: properties::FloatProperty _pointStepSize; properties::Vec3Property _translation; properties::Vec3Property _rotation; + properties::FloatProperty _enabledPointsRatio; std::string _volumeFilename; glm::ivec3 _volumeDimensions; diff --git a/modules/galaxy/shaders/galaxyraycast.glsl b/modules/galaxy/shaders/galaxyraycast.glsl index 1d4db0dbcb..7bdf9d9dd3 100644 --- a/modules/galaxy/shaders/galaxyraycast.glsl +++ b/modules/galaxy/shaders/galaxyraycast.glsl @@ -35,11 +35,11 @@ void sample#{id}(vec3 samplePos, inout float maxStepSize) { vec3 aspect = aspect#{id}; - maxStepSize = maxStepSize#{id} * length(dir * 1/aspect); + maxStepSize = maxStepSize#{id} / length(dir/aspect); vec4 sampledColor = texture(galaxyTexture#{id}, samplePos.xyz); - float STEP_SIZE = maxStepSize; + float STEP_SIZE = maxStepSize#{id}; vec3 alphaTint = vec3(0.3, 0.54, 0.85); //alphaTint = vec3(0.0, 0.5, 1.0); @@ -55,7 +55,7 @@ void sample#{id}(vec3 samplePos, //sampledColor.rgb = pow(sampledColor.rgb, vec3(10.0)); //sampledColor.a = pow(sampledColor.a, 10.0); //sampledColor.a = pow(sampledColor.a, 100000000.0); - sampledColor.rgb *= 4000.0; + sampledColor.rgb *= 500.0; sampledColor.a = sampledColor.a * 0.3; //1.0; diff --git a/modules/galaxy/shaders/points.fs b/modules/galaxy/shaders/points.fs index db7daa29e8..74548099fe 100644 --- a/modules/galaxy/shaders/points.fs +++ b/modules/galaxy/shaders/points.fs @@ -36,10 +36,10 @@ Fragment getFragment() { Fragment frag; float depth = pscDepth(vec4(vsPosition, 0.0)); - float coefficient = exp(1.27 * log(emittanceFactor) - 2*log(depth)); + float coefficient = exp(1.38 * log(emittanceFactor) - 2*log(depth)); frag.color = vec4(vsColor.rgb * coefficient, 1.0); - + frag.depth = depth; diff --git a/modules/galaxy/shaders/points.vs b/modules/galaxy/shaders/points.vs index d14f031033..2e1170fdcd 100644 --- a/modules/galaxy/shaders/points.vs +++ b/modules/galaxy/shaders/points.vs @@ -38,13 +38,16 @@ out vec3 vsColor; #include "PowerScaling/powerScaling_vs.hglsl" void main() { - vec4 p = vec4(inPosition, 0.0); + vec4 p = vec4(inPosition, 1.0); - vec4 tmp = p; - vec4 position = pscTransform(tmp, model); + vec4 worldPosition = model * p; + worldPosition.w = 0.0; + vec4 position = worldPosition; //pscTransform(worldPosition, model); + + + position = pscTransform(position, mat4(1.0)); vsPosition = position.xyz; position = projection * view * position; gl_Position = z_normalization(position); - vsColor = inColor; } diff --git a/modules/galaxy/shaders/raycasterbounds.vs b/modules/galaxy/shaders/raycasterbounds.vs index 37ae94349a..a304a22d03 100644 --- a/modules/galaxy/shaders/raycasterbounds.vs +++ b/modules/galaxy/shaders/raycasterbounds.vs @@ -37,8 +37,9 @@ out vec4 worldPosition; void main() { vPosition = vertPosition.xyz; - worldPosition = vec4(vertPosition.xyz, 0.0); - vec4 position = pscTransform(worldPosition, modelTransform); + worldPosition = modelTransform * vec4(vertPosition.xyz, 1.0); + worldPosition.w = 0.0; + vec4 position = pscTransform(worldPosition, mat4(1.0)); diff --git a/modules/multiresvolume/rendering/renderablemultiresvolume.cpp b/modules/multiresvolume/rendering/renderablemultiresvolume.cpp index b37f0fa83c..0db6385d55 100644 --- a/modules/multiresvolume/rendering/renderablemultiresvolume.cpp +++ b/modules/multiresvolume/rendering/renderablemultiresvolume.cpp @@ -363,7 +363,7 @@ bool RenderableMultiresVolume::initialize() { } }; - + onEnabledChange(onChange); return success; } diff --git a/shaders/abuffer/postrenderabuffer.frag b/shaders/abuffer/postrenderabuffer.frag index 602a98ed67..53136ea591 100644 --- a/shaders/abuffer/postrenderabuffer.frag +++ b/shaders/abuffer/postrenderabuffer.frag @@ -43,10 +43,6 @@ void main() { Fragment newFrag = getFragment(); int sampleMask = gl_SampleMaskIn[0]; - - if (newFrag.depth < 0) { - discard; - } float fboDepth = denormalizeFloat(texelFetch(mainDepthTexture, ivec2(gl_FragCoord), 0).x); vec4 fboRgba = texelFetch(mainColorTexture, ivec2(gl_FragCoord), 0); @@ -122,11 +118,10 @@ void main() { #endif } */ + + vec4 newColor = newFrag.color; vec3 contribution = newColor.rgb * blackoutFactor; - //vec3 contribution = newColor.rgb * blackoutFactor; - - _out_color_ = vec4(contribution, 1.0); // _out_color_ = vec4(1.0); diff --git a/shaders/abuffer/resolveabuffer.frag b/shaders/abuffer/resolveabuffer.frag index 59526cf138..38cb3269a5 100644 --- a/shaders/abuffer/resolveabuffer.frag +++ b/shaders/abuffer/resolveabuffer.frag @@ -91,7 +91,7 @@ void main() { //raycast to the first fragment // discard; float startDepth = 0; - float endDepth = _depth_(fragments[0]); + float endDepth = min(_depth_(fragments[0]), fboDepth); raycast(endDepth - startDepth, raycasterMask, accumulatedColor, accumulatedAlpha); //accumulatedColor = vec3(1.0); } @@ -134,7 +134,10 @@ void main() { // Ray cast to next fragment if (i + 1 < nFrags && raycasterMask != 0) { float startDepth = _depth_(fragments[i]); - float endDepth = _depth_(fragments[i + 1]); + float endDepth = min(_depth_(fragments[i + 1]), fboDepth); + if (endDepth < startDepth) { + break; + } raycast(endDepth - startDepth, raycasterMask, accumulatedColor, accumulatedAlpha); @@ -145,9 +148,8 @@ void main() { accumulatedAlpha = clamp(accumulatedAlpha, 0.0, 1.0); //maccumulatedAlpha = vec3(0.0); - accumulatedColor += (1 - accumulatedAlpha) * fboRgba.rgb; + accumulatedColor += (1 - accumulatedAlpha) * pow(fboRgba.rgb, vec3(gamma)); - finalColor = vec4(accumulatedColor.rgb, 1.0); // Gamma correction. @@ -156,17 +158,24 @@ void main() { finalColor = vec4(finalColor.rgb * blackoutFactor, 1.0); + + //finalColor = vec4(vec3(fboRgba.a), 1.0); + //finalColor = fboRgba; //finalColor = vec4(0.0); - //finalColor = vec4(vec3(acc/1000.0), 1.0); + + //finalColor = vec4(0.0, acc/1000.0, acc/1000.0, 1.0); + //finalColor = vec4(acc/1000.0, 0.0, 0.0, 01.0); //finalColor = vec4(vec3(float(nFrags) / 10), 1.0); //finalColor = vec4(vec3(float(_depth_(fragments[0])) / 10), 1.0); + //finalColor = vec4(vec3(nFilteredFrags - nFrags) * 0.2, 1.0); - //finalColor = vec4(vec3(nFrags) * 0.2, 1.0); + //finalColor = vec4(vec3(nFilteredFrags) * 0.2, 1.0); + //finalColor = vec4(vec3(nFrags) * 0.05, 1.0); //finalColor = vec4(raycasterData[0].position, 1.0); //finalColor = debugColor; //finalColor = vec4(gamma * 0.5); - + //finalColor = vec4(fboRgba); } diff --git a/shaders/abuffer/resolveconstants.glsl b/shaders/abuffer/resolveconstants.glsl index 65677a7cb4..78e9fcd8f0 100644 --- a/shaders/abuffer/resolveconstants.glsl +++ b/shaders/abuffer/resolveconstants.glsl @@ -1,7 +1,7 @@ #define RAYCASTING_ENABLED #{resolveData.raycastingEnabled} -#define STORE_SORTED false//#{resolveData.storeSorted} +#define STORE_SORTED false //#{resolveData.storeSorted} #define N_RAYCASTERS #{resolveData.nRaycasters} #define ALPHA_LIMIT 0.9 -#define RAYCAST_MAX_STEPS 10000 +#define RAYCAST_MAX_STEPS 1000 #define INT_MAX 2147483647 #define GAMMA 2.2 \ No newline at end of file diff --git a/shaders/abuffer/resolvehelpers.glsl b/shaders/abuffer/resolvehelpers.glsl index 713efcc109..b464550d7c 100644 --- a/shaders/abuffer/resolvehelpers.glsl +++ b/shaders/abuffer/resolvehelpers.glsl @@ -25,10 +25,13 @@ #ifndef _RESOLVEHELPERS_GLSL_ #define _RESOLVEHELPERS_GLSL_ + +float acc = 0; + #if RAYCASTING_ENABLED #include "raycasterdata.glsl" -float acc = 0; + // Include all ray caster helpers @@ -40,10 +43,14 @@ float acc = 0; // Include all ray casters #for id, raycaster in resolveData.raycasters #include <#{raycaster.raycastPath}> -uniform bool insideRaycaster#{id}; -uniform vec3 cameraPosInRaycaster#{id} #endfor +#for index in 1..#{resolveData.nRaycasters} +uniform bool insideRaycaster#{index}; +uniform vec3 cameraPosInRaycaster#{index} +#endfor + + #endif @@ -79,7 +86,7 @@ uint countSamples(uint mask) { uint depthFilterFragments(uint nFrags, float depthThreshold) { uint j = 0; for (uint i = 0; i < nFrags; i++) { - if (_depth_(fragments[i]) < depthThreshold) { + if (_type_(fragments[i]) != 0 || _depth_(fragments[i]) < depthThreshold) { fragments[j] = fragments[i]; j++; } @@ -129,16 +136,16 @@ j < nFrags && ((newMask = _msaa_(fragments[j])) & accumulatedMask) == 0 && _type */ void retrieveRaycasterData(uint nFrags) { float entryDepths[N_RAYCASTERS]; -#for i in 0..#{resolveData.nRaycasters} +#for i in 1..#{resolveData.nRaycasters} { - int i = #{i}; - entryDepths[i] = -1; - raycasterData[i].scale = -1; + int j = #{i} - 1; + entryDepths[j] = -1; + raycasterData[j].scale = -1; bool inside = insideRaycaster#{i}; if (inside) { - entryDepths[i] = 0; - raycasterData[i].position = cameraPosInRaycaster#{i}; - raycasterData[i].previousJitterDistance = 0; + entryDepths[j] = 0; + raycasterData[j].position = cameraPosInRaycaster#{i}; + raycasterData[j].previousJitterDistance = 0; } } #endfor @@ -167,6 +174,7 @@ void retrieveRaycasterData(uint nFrags) { } } + /** * Perform raycasting */ @@ -185,7 +193,6 @@ void raycast(float raycastDepth, uint raycasterMask, inout vec3 accumulatedColor #endfor float currentDepth = 0.0; - for (int steps = 0; (accumulatedAlpha.x < ALPHA_LIMIT || accumulatedAlpha.y < ALPHA_LIMIT || @@ -220,7 +227,7 @@ void raycast(float raycastDepth, uint raycasterMask, inout vec3 accumulatedColor accumulatedColor, accumulatedAlpha, maxStepSizeLocal); - + float sampleDistance = jitteredStepSizeLocal + data.previousJitterDistance; uint blend = raycasterData[#{raycaster.id}].blend; @@ -244,11 +251,14 @@ void raycast(float raycastDepth, uint raycasterMask, inout vec3 accumulatedColor bool initRaycasterMask(inout uint raycasterMask) { bool insideAnyRaycaster = false; raycasterMask = 0; -#for i in 0..#{resolveData.nRaycasters} { - if (insideRaycaster#{i} && raycasterData[#{i}].scale > 0) { - raycasterMask |= (1 << #{i}); +#for i in 1..#{resolveData.nRaycasters} + { + int j = #{i} - 1; + if (insideRaycaster#{i} && raycasterData[j].scale > 0) { + raycasterMask |= (1 << j); insideAnyRaycaster = true; } + } #endfor return insideAnyRaycaster; } diff --git a/shaders/framebuffer/raycastframebuffer.frag b/shaders/framebuffer/raycastframebuffer.frag index 2ef798954d..0eab935531 100644 --- a/shaders/framebuffer/raycastframebuffer.frag +++ b/shaders/framebuffer/raycastframebuffer.frag @@ -28,11 +28,16 @@ uniform sampler2D exitColorTexture; uniform sampler2D exitDepthTexture; uniform sampler2DMS mainDepthTexture; +uniform bool insideRaycaster; +uniform vec3 cameraPosInRaycaster; + + #include "blending.glsl" #include "rand.glsl" #include "PowerScaling/powerScalingMath.hglsl" #include <#{fragmentPath}> + #for id, helperPath in helperPaths #include <#{helperPath}> #endfor @@ -68,10 +73,18 @@ void main() { float jitterFactor = 0.5 + 0.5 * rand(gl_FragCoord.xy); // should be between 0.5 and 1.0 - // fetch entry point from rendered fragment - Fragment f = getFragment(); - vec3 entryPos = f.color.xyz; - float entryDepth = f.depth; + vec3 entryPos; + float entryDepth; + + if (insideRaycaster) { + entryPos = cameraPosInRaycaster; + entryDepth = 0; + } else { + // fetch entry point from rendered fragment + Fragment f = getFragment(); + entryPos = f.color.xyz; + entryDepth = f.depth; + } vec3 position = entryPos; vec3 diff = exitPos - entryPos; diff --git a/src/rendering/abufferrenderer.cpp b/src/rendering/abufferrenderer.cpp index 402b2cc37e..2620cb2a86 100644 --- a/src/rendering/abufferrenderer.cpp +++ b/src/rendering/abufferrenderer.cpp @@ -109,15 +109,7 @@ void ABufferRenderer::initialize() { GLint defaultFbo; glGetIntegerv(GL_FRAMEBUFFER_BINDING, &defaultFbo); - - _nAaSamples = OsEng.windowWrapper().currentNumberOfAaSamples(); - if (_nAaSamples == 0) { - _nAaSamples = 1; - } - if (_nAaSamples > 8) { - LERROR("ABuffer renderer does not support more than 8 MSAA samples."); - _nAaSamples = 8; - } + updateResolution(); updateRendererData(); @@ -335,9 +327,10 @@ void ABufferRenderer::preRaycast(ghoul::opengl::ProgramObject& program) { glm::vec3 localCameraPosition; bool cameraIsInside = raycastData.first->cameraIsInside(*_renderData, localCameraPosition); - program.setUniform("insideRaycaster" + std::to_string(raycastData.second.id), cameraIsInside); + int uniformIndex = raycastData.second.id + 1; // uniforms are indexed from 1 (not from 0) + program.setUniform("insideRaycaster" + std::to_string(uniformIndex), cameraIsInside); if (cameraIsInside) { - program.setUniform("cameraPosInRaycaster" + std::to_string(raycastData.second.id), localCameraPosition); + program.setUniform("cameraPosInRaycaster" + std::to_string(uniformIndex), localCameraPosition); } } @@ -367,6 +360,18 @@ void ABufferRenderer::setResolution(glm::ivec2 res) { } } +void ABufferRenderer::setNAaSamples(int nAaSamples) { + _nAaSamples = nAaSamples; + if (_nAaSamples == 0) { + _nAaSamples = 1; + } + if (_nAaSamples > 8) { + LERROR("Framebuffer renderer does not support more than 8 MSAA samples."); + _nAaSamples = 8; + } + _dirtyResolution = true; +} + void ABufferRenderer::clear() { glBindBuffer(GL_PIXEL_UNPACK_BUFFER, _anchorPointerTextureInitializer); glBindTexture(GL_TEXTURE_2D, _anchorPointerTexture); @@ -406,12 +411,11 @@ 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, + _nAaSamples, GL_RGBA, GLsizei(_resolution.x), GLsizei(_resolution.y), @@ -420,7 +424,7 @@ void ABufferRenderer::updateResolution() { glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainDepthTexture); glTexImage2DMultisample( GL_TEXTURE_2D_MULTISAMPLE, - nSamples, + _nAaSamples, GL_DEPTH_COMPONENT32F, GLsizei(_resolution.x), GLsizei(_resolution.y), diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index 6d407d1646..6798f6f6ed 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -123,14 +123,7 @@ void FramebufferRenderer::initialize() { OsEng.renderEngine().raycasterManager().addListener(*this); - _nAaSamples = OsEng.windowWrapper().currentNumberOfAaSamples(); - if (_nAaSamples == 0) { - _nAaSamples = 1; - } - if (_nAaSamples > 8) { - LERROR("Framebuffer renderer does not support more than 8 MSAA samples."); - _nAaSamples = 8; - } + } void FramebufferRenderer::deinitialize() { @@ -194,10 +187,21 @@ void FramebufferRenderer::update() { } } } + + for (auto &program : _insideRaycastPrograms) { + if (program.second->isDirty()) { + try { + program.second->rebuildFromFile(); + } + catch (ghoul::RuntimeError e) { + LERROR(e.message); + } + } + } } void FramebufferRenderer::updateResolution() { - int nSamples = OsEng.windowWrapper().currentNumberOfAaSamples(); + int nSamples = _nAaSamples; glBindTexture(GL_TEXTURE_2D_MULTISAMPLE, _mainColorTexture); glTexImage2DMultisample( @@ -255,6 +259,7 @@ void FramebufferRenderer::updateRaycastData() { _raycastData.clear(); _exitPrograms.clear(); _raycastPrograms.clear(); + _insideRaycastPrograms.clear(); const std::vector& raycasters = OsEng.renderEngine().raycasterManager().raycasters(); int nextId = 0; @@ -291,6 +296,15 @@ void FramebufferRenderer::updateRaycastData() { } catch (ghoul::RuntimeError e) { LERROR(e.message); } + try { + _insideRaycastPrograms[raycaster] = ghoul::opengl::ProgramObject::Build( + "Volume " + std::to_string(data.id) + " inside raycast", + "${SHADERS}/framebuffer/resolveframebuffer.vert", + RaycastFragmentShaderPath, dict); + } + catch (ghoul::RuntimeError e) { + LERROR(e.message); + } } _dirtyRaycastData = false; } @@ -333,9 +347,25 @@ void FramebufferRenderer::render(float blackoutFactor, bool doPerformanceMeasure glBindFramebuffer(GL_FRAMEBUFFER, _mainFramebuffer); - ghoul::opengl::ProgramObject* raycastProgram = _raycastPrograms[raycaster].get(); + + ghoul::opengl::ProgramObject* insideRaycastProgram = _raycastPrograms[raycaster].get(); + + glm::vec3 cameraPosition; + bool cameraIsInside = raycaster->cameraIsInside(raycasterTask.renderData, cameraPosition); + ghoul::opengl::ProgramObject* raycastProgram = nullptr; + + if (cameraIsInside) { + raycastProgram = _insideRaycastPrograms[raycaster].get(); + } else { + raycastProgram = _raycastPrograms[raycaster].get(); + } + if (raycastProgram) { raycastProgram->activate(); + + raycastProgram->setUniform("insideRaycaster", cameraIsInside); + raycastProgram->setUniform("cameraPosInRaycaster", cameraPosition); + raycaster->preRaycast(_raycastData[raycaster], *raycastProgram); ghoul::opengl::TextureUnit exitColorTextureUnit; @@ -355,12 +385,21 @@ void FramebufferRenderer::render(float blackoutFactor, bool doPerformanceMeasure raycastProgram->setUniform("nAaSamples", _nAaSamples); + glDisable(GL_DEPTH_TEST); glDepthMask(false); - raycaster->renderEntryPoints(raycasterTask.renderData, *raycastProgram); + if (cameraIsInside) { + glBindVertexArray(_screenQuad); + glDrawArrays(GL_TRIANGLES, 0, 6); + glBindVertexArray(0); + } else { + raycaster->renderEntryPoints(raycasterTask.renderData, *raycastProgram); + } glDepthMask(true); glEnable(GL_DEPTH_TEST); + + raycaster->postRaycast(_raycastData[raycaster], *raycastProgram); raycastProgram->deactivate(); } else { @@ -380,6 +419,7 @@ void FramebufferRenderer::render(float blackoutFactor, bool doPerformanceMeasure _resolveProgram->setUniform("nAaSamples", _nAaSamples); glBindVertexArray(_screenQuad); glDrawArrays(GL_TRIANGLES, 0, 6); + glBindVertexArray(0); _resolveProgram->deactivate(); } @@ -397,6 +437,18 @@ void FramebufferRenderer::setResolution(glm::ivec2 res) { _dirtyResolution = true; } +void FramebufferRenderer::setNAaSamples(int nAaSamples) { + _nAaSamples = nAaSamples; + if (_nAaSamples == 0) { + _nAaSamples = 1; + } + if (_nAaSamples > 8) { + LERROR("Framebuffer renderer does not support more than 8 MSAA samples."); + _nAaSamples = 8; + } + _dirtyResolution = true; +} + void FramebufferRenderer::updateRendererData() { ghoul::Dictionary dict; dict.setValue("fragmentRendererPath", std::string(RenderFragmentShaderPath)); diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index 5dc84a7710..f781c16bae 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -191,6 +191,7 @@ bool RenderEngine::initialize() { } _raycasterManager = new RaycasterManager(); + _nAaSamples = OsEng.windowWrapper().currentNumberOfAaSamples(); LINFO("Seting renderer from string: " << renderingMethod); setRendererFromString(renderingMethod); @@ -649,11 +650,20 @@ void RenderEngine::setRenderer(std::unique_ptr renderer) { _renderer = std::move(renderer); _renderer->setResolution(res); + _renderer->setNAaSamples(_nAaSamples); _renderer->initialize(); _renderer->setCamera(_mainCamera); _renderer->setScene(_sceneGraph); } + +void RenderEngine::setNAaSamples(int nAaSamples) { + _nAaSamples = nAaSamples; + if (_renderer) { + _renderer->setNAaSamples(_nAaSamples); + } +} + scripting::ScriptEngine::LuaLibrary RenderEngine::luaLibrary() { return { "", @@ -670,6 +680,12 @@ scripting::ScriptEngine::LuaLibrary RenderEngine::luaLibrary() { "string", "Sets the renderer (ABuffer or FrameBuffer)" }, + { + "setNAaSamples", + &luascriptfunctions::setNAaSamples, + "int", + "Sets the number of anti-aliasing (msaa) samples" + }, { "showRenderInformation", &luascriptfunctions::showRenderInformation, diff --git a/src/rendering/renderengine_lua.inl b/src/rendering/renderengine_lua.inl index 18fc6235d0..5e3937aeb6 100644 --- a/src/rendering/renderengine_lua.inl +++ b/src/rendering/renderengine_lua.inl @@ -57,6 +57,23 @@ int setRenderer(lua_State* L) { return 0; } +/** +* \ingroup LuaScripts +* setNAaSamples(int): +* set the number of anti-aliasing samples (msaa) +*/ +int setNAaSamples(lua_State* L) { + int nArguments = lua_gettop(L); + if (nArguments != 1) + return luaL_error(L, "Expected %i arguments, got %i", 1, nArguments); + + double t = luaL_checknumber(L, -1); + + OsEng.renderEngine().setNAaSamples(static_cast(t)); + return 0; +} + + /** * \ingroup LuaScripts * visualizeABuffer(bool):