diff --git a/data/assets/customization/volumes.asset b/data/assets/customization/volumes.asset index 4beb79b4a1..da77323480 100644 --- a/data/assets/customization/volumes.asset +++ b/data/assets/customization/volumes.asset @@ -21,7 +21,8 @@ local MilkyWayVolumeGalaxy = { Points = { Type = "Points", Filename = "${BASE}/../OpenSpaceData/Milkyway/MilkyWayPoints.off", - Scaling = {1.0, 1.0, 1.0} + Scaling = {1.0, 1.0, 1.0}, + Texture = "${BASE}/../OpenSpaceData/Milkyway/halo.png" } }, GUI = { diff --git a/modules/galaxy/rendering/renderablegalaxy.cpp b/modules/galaxy/rendering/renderablegalaxy.cpp index c0fde80d62..be8bb1df03 100644 --- a/modules/galaxy/rendering/renderablegalaxy.cpp +++ b/modules/galaxy/rendering/renderablegalaxy.cpp @@ -54,9 +54,9 @@ namespace { "${MODULES}/galaxy/shaders/raycasterbounds_fs.glsl"; constexpr const char* _loggerCat = "Renderable Galaxy"; - constexpr const std::array UniformNames = { + constexpr const std::array UniformNames = { "modelMatrix", "cameraUp", "eyePosition", "cameraViewProjectionMatrix", - "emittanceFactor" + "emittanceFactor", "psfTexture" }; constexpr openspace::properties::Property::PropertyInfo StepSizeInfo = { @@ -77,18 +77,6 @@ namespace { "" // @TODO Missing documentation }; - constexpr openspace::properties::Property::PropertyInfo PointStepSizeInfo = { - "PointStepSize", - "Point Step Size", - "" // @TODO Missing documentation - }; - - constexpr openspace::properties::Property::PropertyInfo PointScaleFactorInfo = { - "PointScaleFactor", - "Point Scale Factor", - "" // @TODO Missing documentation - }; - constexpr openspace::properties::Property::PropertyInfo TranslationInfo = { "Translation", "Translation", @@ -115,8 +103,6 @@ namespace openspace { , _stepSize(StepSizeInfo, 0.01f, 0.0005f, 0.05f, 0.001f) , _absorptionMultiply(AbsorptionMultiplyInfo, 40.f, 0.0f, 100.0f) , _emissionMultiply(EmissionMultiplyInfo, 400.f, 0.0f, 1000.0f) - , _pointStepSize(PointStepSizeInfo, 0.01f, 0.01f, 0.1f) - , _pointScaleFactor(PointScaleFactorInfo, 1.f, 1.f, 64.f) , _enabledPointsRatio(EnabledPointsRatioInfo, 0.02f, 0.001f, 0.1f) , _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)) @@ -124,8 +110,6 @@ namespace openspace { dictionary.getValue("StepSize", _stepSize); dictionary.getValue("AbsorptionMultiply", _absorptionMultiply); dictionary.getValue("EmissionMultiply", _emissionMultiply); - dictionary.getValue("PointStepSize", _pointStepSize); - dictionary.getValue("PointScaleFactor", _pointScaleFactor); dictionary.getValue("EnabledPointsRatio", _enabledPointsRatio); dictionary.getValue("Translation", _translation); dictionary.getValue("Rotation", _rotation); @@ -142,14 +126,6 @@ namespace openspace { _emissionMultiply = static_cast(dictionary.value(EmissionMultiplyInfo.identifier)); } - if (dictionary.hasKeyAndValue(PointStepSizeInfo.identifier)) { - _pointStepSize = static_cast(dictionary.value(PointStepSizeInfo.identifier)); - } - - if (dictionary.hasKeyAndValue(PointScaleFactorInfo.identifier)) { - _pointScaleFactor = static_cast(dictionary.value(PointScaleFactorInfo.identifier)); - } - if (dictionary.hasKeyAndValue(EnabledPointsRatioInfo.identifier)) { _enabledPointsRatio = static_cast(dictionary.value(EnabledPointsRatioInfo.identifier)); } @@ -199,6 +175,15 @@ namespace openspace { } else { LERROR("No points filename specified."); } + + std::string pointSpreadFunctionTexturePath; + if (pointsDictionary.getValue("Texture", pointSpreadFunctionTexturePath)) { + _pointSpreadFunctionTexturePath = absPath(pointSpreadFunctionTexturePath); + _pointSpreadFunctionFile = std::make_unique(_pointSpreadFunctionTexturePath); + } + else { + LERROR("No points filename specified."); + } } void RenderableGalaxy::initializeGL() { @@ -247,8 +232,6 @@ void RenderableGalaxy::initializeGL() { addProperty(_stepSize); addProperty(_absorptionMultiply); addProperty(_emissionMultiply); - addProperty(_pointStepSize); - addProperty(_pointScaleFactor); addProperty(_enabledPointsRatio); addProperty(_translation); addProperty(_rotation); @@ -262,6 +245,27 @@ void RenderableGalaxy::initializeGL() { absPath("${MODULE_GALAXY}/shaders/points_ge.glsl") ); + if (!_pointSpreadFunctionTexturePath.empty()) { + _pointSpreadFunctionTexture = ghoul::io::TextureReader::ref().loadTexture( + absPath(_pointSpreadFunctionTexturePath) + ); + + if (_pointSpreadFunctionTexture) { + LDEBUG(fmt::format( + "Loaded texture from '{}'", + absPath(_pointSpreadFunctionTexturePath) + )); + _pointSpreadFunctionTexture->uploadTexture(); + } + _pointSpreadFunctionTexture->setFilter( + ghoul::opengl::Texture::FilterMode::AnisotropicMipMap + ); + + _pointSpreadFunctionFile = std::make_unique( + _pointSpreadFunctionTexturePath + ); + } + ghoul::opengl::updateUniformLocations(*_pointsProgram, _uniformCache, UniformNames); _pointsProgram->setIgnoreUniformLocationError( @@ -292,7 +296,7 @@ void RenderableGalaxy::initializeGL() { // Read points float x, y, z, r, g, b, a; - for (size_t i = 0; i < static_cast(_nPoints * 0.1) + 1; ++i) { + for (size_t i = 0; i < static_cast(_nPoints * _enabledPointsRatio.maxValue()) + 1; ++i) { std::getline(pointFile, line); std::istringstream issp(line); issp >> x >> y >> z >> r >> g >> b >> a; @@ -472,37 +476,18 @@ void RenderableGalaxy::render(const RenderData& data, RendererTasks& tasks) { glm::dmat4 cameraViewProjectionMatrix = projectionMatrix * data.camera.combinedViewMatrix(); - - /*glm::mat4 modelMatrix = _pointTransform; - glm::mat4 viewMatrix = data.camera.combinedViewMatrix(); - glm::mat4 projectionMatrix = data.camera.projectionMatrix(); - - _pointsProgram->setUniform("model", modelMatrix); - _pointsProgram->setUniform("view", viewMatrix); - _pointsProgram->setUniform("projection", projectionMatrix);*/ - - /*glm::dmat4 modelTransform = - glm::translate(glm::dmat4(1.0), data.modelTransform.translation) * - glm::dmat4(data.modelTransform.rotation) * - glm::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale)) * - glm::dmat4(_pointTransform); - - glm::mat4 modelViewTransform = viewMatrix * modelMatrix; - - _pointsProgram->setUniform("modelViewTransform", modelViewTransform); - _pointsProgram->setUniform("viewProjection", data.camera.viewProjectionMatrix());*/ - _pointsProgram->setUniform(_uniformCache.modelMatrix, modelMatrix); _pointsProgram->setUniform( _uniformCache.cameraViewProjectionMatrix, cameraViewProjectionMatrix ); float emittanceFactor = _opacityCoefficient * static_cast(_volumeSize).x; + ghoul::opengl::TextureUnit psfUnit; + psfUnit.activate(); + _pointSpreadFunctionTexture->bind(); + _pointsProgram->setUniform(_uniformCache.psfTexture, psfUnit); _pointsProgram->setUniform(_uniformCache.emittanceFactor, emittanceFactor); - /*_pointsProgram->setUniform("scaleFactor", _pointScaleFactor); - _pointsProgram->setUniform("emittanceFactor", emittanceFactor);*/ - glBindVertexArray(_pointsVao); glDrawArrays(GL_POINTS, 0, static_cast(_nPoints * _enabledPointsRatio)); @@ -527,37 +512,4 @@ float RenderableGalaxy::safeLength(const glm::vec3& vector) const { return glm::length(vector / maxComponent) * maxComponent; } -/*void RenderableGalaxy::postRender(const RenderData& data) { - - _raycaster->setStepSize(_pointStepSize); - - _pointsProgram->activate(); - setPscUniforms(*_pointsProgram.get(), data.camera, data.position); - - OsEng.ref().renderEngine().preRaycast(*_pointsProgram); - - glm::mat4 modelMatrix = _pointTransform; - glm::mat4 viewMatrix = data.camera.viewMatrix(); - glm::mat4 projectionMatrix = data.camera.projectionMatrix(); - - _pointsProgram->setUniform("model", modelMatrix); - _pointsProgram->setUniform("view", viewMatrix); - _pointsProgram->setUniform("projection", projectionMatrix); - - float emittanceFactor = _opacityCoefficient * static_cast(_volumeSize).x; - _pointsProgram->setUniform("emittanceFactor", emittanceFactor); - - glBindVertexArray(_pointsVao); - glDisable(GL_DEPTH_TEST); - glDepthMask(false); - glBlendFunc(GL_SRC_ALPHA, GL_ONE); - glDrawArrays(GL_POINTS, 0, _nPoints * _enabledPointsRatio); - glBindVertexArray(0); - glDepthMask(true); - glEnable(GL_DEPTH_TEST); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - OsEng.ref().renderEngine().postRaycast(*_pointsProgram); -}*/ - } // namespace openspace diff --git a/modules/galaxy/rendering/renderablegalaxy.h b/modules/galaxy/rendering/renderablegalaxy.h index b4ae9c57f4..3bb36b8fad 100644 --- a/modules/galaxy/rendering/renderablegalaxy.h +++ b/modules/galaxy/rendering/renderablegalaxy.h @@ -62,15 +62,17 @@ private: properties::FloatProperty _stepSize; properties::FloatProperty _absorptionMultiply; properties::FloatProperty _emissionMultiply; - properties::FloatProperty _pointStepSize; - properties::FloatProperty _pointScaleFactor; properties::FloatProperty _enabledPointsRatio; properties::Vec3Property _translation; properties::Vec3Property _rotation; + std::unique_ptr _pointSpreadFunctionTexture; + std::unique_ptr _pointSpreadFunctionFile; + std::string _volumeFilename; glm::ivec3 _volumeDimensions; std::string _pointsFilename; + std::string _pointSpreadFunctionTexturePath; std::unique_ptr _raycaster; std::unique_ptr>> _volume; @@ -82,7 +84,7 @@ private: std::unique_ptr _pointsProgram; UniformCache( modelMatrix, cameraUp, eyePosition, cameraViewProjectionMatrix, - emittanceFactor + emittanceFactor, psfTexture ) _uniformCache; std::vector _pointsData; size_t _nPoints; diff --git a/modules/galaxy/shaders/galaxyraycast.glsl b/modules/galaxy/shaders/galaxyraycast.glsl index 7135a08c13..d3da09d2b4 100644 --- a/modules/galaxy/shaders/galaxyraycast.glsl +++ b/modules/galaxy/shaders/galaxyraycast.glsl @@ -1,26 +1,26 @@ /***************************************************************************************** - * * - * 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. * - ****************************************************************************************/ +* * +* 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. * +****************************************************************************************/ uniform float maxStepSize#{id} = 0.1; uniform vec3 aspect#{id} = vec3(1.0); @@ -30,52 +30,52 @@ uniform float emissionMultiply#{id} = 1500.0; uniform sampler3D galaxyTexture#{id}; void sample#{id}(vec3 samplePos, - vec3 dir, - inout vec3 accumulatedColor, - inout vec3 accumulatedAlpha, - inout float maxStepSize) -{ - //Speed up and border edge artifact fix - vec3 normalizedPos = (samplePos*2.0)-1.0; - if(abs(normalizedPos.x) > 0.8 || abs(normalizedPos.y) > 0.8){ - //accumulatedAlpha = vec3(0.0); - return; - } + vec3 dir, + inout vec3 accumulatedColor, + inout vec3 accumulatedAlpha, + inout float maxStepSize) + { + //Speed up and border edge artifact fix + vec3 normalizedPos = (samplePos*2.0)-1.0; + if(abs(normalizedPos.x) > 0.8 || abs(normalizedPos.y) > 0.8){ + //accumulatedAlpha = vec3(0.0); + return; + } vec3 aspect = aspect#{id}; maxStepSize = maxStepSize#{id} / length(dir / aspect); vec4 sampledColor = texture(galaxyTexture#{id}, samplePos.xyz); - //float STEP_SIZE = maxStepSize#{id}*0.5; - float STEP_SIZE = 1 / 256.0; + float STEP_SIZE = maxStepSize#{id}*0.5; + //float STEP_SIZE = 1 / 256.0; vec3 alphaTint = vec3(0.3, 0.54, 0.85); - // Source textures currently are square-rooted to avoid dithering in the shadows. - // So square them back + // Source textures currently are square-rooted to avoid dithering in the shadows. + // So square them back sampledColor = sampledColor*sampledColor; - // fudge for the dust "spreading" - sampledColor.a = clamp(sampledColor.a, 0.0, 1.0) * opacityCoefficient#{id}; + // fudge for the dust "spreading" + sampledColor.a = clamp(sampledColor.a, 0.0, 1.0) * opacityCoefficient#{id}; sampledColor.a = pow(sampledColor.a, 0.7); - // absorption probability - float scaled_density = sampledColor.a * STEP_SIZE * absorptionMultiply#{id}; - vec3 absorption = alphaTint * scaled_density; + // absorption probability + float scaled_density = sampledColor.a * STEP_SIZE * absorptionMultiply#{id}; + vec3 absorption = alphaTint * scaled_density; - // extinction - vec3 extinction = exp(-absorption); - accumulatedColor.rgb *= extinction; + // extinction + vec3 extinction = exp(-absorption); + accumulatedColor.rgb *= extinction; - // emission - accumulatedColor.rgb += sampledColor.rgb * STEP_SIZE * emissionMultiply#{id}; + // emission + accumulatedColor.rgb += sampledColor.rgb * STEP_SIZE * emissionMultiply#{id}; - vec3 oneMinusFrontAlpha = vec3(1.0) - accumulatedAlpha; + vec3 oneMinusFrontAlpha = vec3(1.0) - accumulatedAlpha; //accumulatedColor += oneMinusFrontAlpha * sampledColor.rgb; - accumulatedAlpha += oneMinusFrontAlpha * sampledColor.rgb; -} + accumulatedAlpha += oneMinusFrontAlpha * sampledColor.rgb; + } -float stepSize#{id}(vec3 samplePos, vec3 dir) { + float stepSize#{id}(vec3 samplePos, vec3 dir) { return maxStepSize#{id} * length(dir * 1.0 / aspect#{id}); -} + } diff --git a/modules/galaxy/shaders/points_fs.glsl b/modules/galaxy/shaders/points_fs.glsl index b9f49f7c0d..beb563f8e1 100644 --- a/modules/galaxy/shaders/points_fs.glsl +++ b/modules/galaxy/shaders/points_fs.glsl @@ -25,29 +25,26 @@ #include "fragment.glsl" #include "floatoperations.glsl" +uniform sampler2D psfTexture; +uniform float emittanceFactor; + in vec4 vs_position; +in vec2 psfCoords; in vec3 ge_color; in float ge_screenSpaceDepth; -uniform float emittanceFactor; - Fragment getFragment() { Fragment frag; - //frag.depth = vs_screenSpaceDepth; - //float coefficient = exp(1.38 * log(emittanceFactor) - 2*log(ge_screenSpaceDepth)); - float coefficient = exp(1.38 * log(0.2) - 2*log(ge_screenSpaceDepth)); - frag.color = vec4(ge_color, 1.0)*emittanceFactor; - //frag.gPosition = vec4(vs_position, 1.0); - //frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0); + vec4 textureColor = texture(psfTexture, 0.5*psfCoords + 0.5); + vec4 fullColor = vec4(ge_color*textureColor.a, textureColor.a); + fullColor.a *= emittanceFactor; + if (fullColor.a == 0) { + discard; + } + frag.color = fullColor; - //frag.color = vec4(1.0, 0.0, 0.0, 1.0); - //frag.depth = depth; - //frag.blend = BLEND_MODE_ADDITIVE; - - //float coefficient = exp(1.38 * log(emittanceFactor) - 2*log(ge_screenSpaceDepth)); - //frag.color = vec4(ge_color.rgb * coefficient, 1.0); frag.depth = ge_screenSpaceDepth; frag.gPosition = vs_position; frag.gNormal = vec4(0.0, 0.0, 0.0, 1.0);