From dfd60dfeec1b72033980ec1c60e127c1bd84901a Mon Sep 17 00:00:00 2001 From: Jonathas Costa Date: Wed, 17 Feb 2021 20:53:51 -0500 Subject: [PATCH] Changed to full texture control as Carter wanted. --- .../solarsystem/planets/saturn/saturn.asset | 16 ++- .../shaders/advanced_rings_fs.glsl | 31 ++-- modules/globebrowsing/src/ringscomponent.cpp | 135 +++++++++++++++++- modules/globebrowsing/src/ringscomponent.h | 9 +- 4 files changed, 166 insertions(+), 25 deletions(-) diff --git a/data/assets/scene/solarsystem/planets/saturn/saturn.asset b/data/assets/scene/solarsystem/planets/saturn/saturn.asset index 7ab7bedbb9..09b3a33e2d 100644 --- a/data/assets/scene/solarsystem/planets/saturn/saturn.asset +++ b/data/assets/scene/solarsystem/planets/saturn/saturn.asset @@ -21,10 +21,18 @@ local Saturn = { SegmentsPerPatch = 64, Layers = {}, Rings = { - Texture = texturesPath .. "/saturn_rings.png", - --TextureFwrd = texturesPath .. "/final_color_forward_os.png", - --TextureBckwrd = texturesPath .. "/final_color_backwards_os.png", - --TextureUnlit = texturesPath .. "/unlit_final_color_os.png", + -- Single Texture Values: + --Texture = texturesPath .. "/saturn_rings.png", + --ColorFilter = 0.15, + + -- MultiTexture Valeus: + TextureFwrd = texturesPath .. "/forward_original_single.png", + TextureBckwrd = texturesPath .. "/back_original_single.png", + TextureUnlit = texturesPath .. "/unlit_original_single.png", + TextureColor = texturesPath .. "/color_original_single.png", + TextureTransparency = texturesPath .. "/trans_original_single.png", + ColorFilter = 0.8, + NightFactor = 1.0, Size = 140445000, Offset = { 74500 / 140445.100671159, 1.0 }, -- min / max extend diff --git a/modules/globebrowsing/shaders/advanced_rings_fs.glsl b/modules/globebrowsing/shaders/advanced_rings_fs.glsl index 5c74b16e95..9219fa66b1 100644 --- a/modules/globebrowsing/shaders/advanced_rings_fs.glsl +++ b/modules/globebrowsing/shaders/advanced_rings_fs.glsl @@ -36,6 +36,8 @@ uniform sampler2DShadow shadowMapTexture; uniform sampler1D ringTextureFwrd; uniform sampler1D ringTextureBckwrd; uniform sampler1D ringTextureUnlit; +uniform sampler1D ringTextureColor; +uniform sampler1D ringTextureTransparency; uniform vec2 textureOffset; uniform float colorFilterValue; @@ -70,27 +72,20 @@ Fragment getFragment() { discard; } - vec4 colorBckwrd = vec4(0.95) * texture(ringTextureBckwrd, texCoord); - vec4 colorFwrd = vec4(0.5) * texture(ringTextureFwrd, texCoord); + vec4 colorBckwrd = texture(ringTextureBckwrd, texCoord); + vec4 colorFwrd = texture(ringTextureFwrd, texCoord); + vec4 colorMult = texture(ringTextureColor, texCoord); + vec4 transparency = texture(ringTextureTransparency, texCoord); + float lerpFactor = (1.f + dot(camPositionObj.xyz, sunPosition.xyz)) * 0.5f; // Jon Colors: //vec4 diffuse = mix(colorFwrd * vec4(1, 0.88, 0.82, 1.0), colorBckwrd * vec4(1, 0.88, 0.82, 1.0), lerpFactor); - vec4 diffuse = mix(colorFwrd, colorBckwrd, lerpFactor); - diffuse.a = 1.f; - - // divided by 3 as length of vec3(1.0, 1.0, 1.0) will return 3 and we want - // to normalize the alpha value to [0,1] + vec4 diffuse = mix(colorFwrd * colorMult, colorBckwrd * colorMult, lerpFactor); + diffuse.a = colorFilterValue * transparency.a; float colorValue = length(diffuse.rgb) / 0.57735026919; - if (colorValue < colorFilterValue) { - diffuse.a = colorValue * colorFilterValue; - if (diffuse.a < 0.99) - discard; - } else { - diffuse.a = colorValue; - if (diffuse.a + 1 < 1.2) - discard; - } + if (colorValue < 0.1) + discard; // shadow == 1.0 means it is not in shadow float shadow = 1.0; @@ -130,7 +125,9 @@ Fragment getFragment() { // Reduce the color of the fragment by the user factor // if we are facing away from the Sun if (dot(sunPosition, normal) < 0) { - diffuse.xyz = vec3(0.9) * texture(ringTextureUnlit, texCoord).xyz * _nightFactor; + diffuse.xyz = vec3(1.0, 0.97075, 0.952) * + texture(ringTextureUnlit, texCoord).xyz * + _nightFactor; } Fragment frag; diff --git a/modules/globebrowsing/src/ringscomponent.cpp b/modules/globebrowsing/src/ringscomponent.cpp index 8acf9bde45..9a047868fe 100644 --- a/modules/globebrowsing/src/ringscomponent.cpp +++ b/modules/globebrowsing/src/ringscomponent.cpp @@ -59,10 +59,11 @@ namespace { "zFightingPercentage" }; - constexpr const std::array UniformNamesAdvancedRings = { + constexpr const std::array UniformNamesAdvancedRings = { "modelViewProjectionMatrix", "textureOffset", "colorFilterValue", "_nightFactor", "sunPosition", "camPositionObj", "ringTextureFwrd", "ringTextureBckwrd", - "ringTextureUnlit", "shadowMatrix", "shadowMapTexture", "zFightingPercentage" + "ringTextureUnlit", "ringTextureColor", "ringTextureTransparency", "shadowMatrix", + "shadowMapTexture", "zFightingPercentage" }; constexpr const std::array GeomUniformNames = { @@ -97,6 +98,20 @@ namespace { "texture which is used for unlit part in these rings." }; + constexpr openspace::properties::Property::PropertyInfo TextureColorInfo = { + "TextureColor", + "TextureColor", + "This value is the path to a texture on disk that contains a one-dimensional " + "texture color which is used for unlit part in these rings." + }; + + constexpr openspace::properties::Property::PropertyInfo TextureTransparencyInfo = { + "TextureTransparency", + "TextureTransparency", + "This value is the path to a texture on disk that contains a one-dimensional " + "texture transparency which is used for unlit part in these rings." + }; + constexpr openspace::properties::Property::PropertyInfo SizeInfo = { "Size", "Size", @@ -174,6 +189,18 @@ documentation::Documentation RingsComponent::Documentation() { Optional::Yes, TextureUnlitInfo.description }, + { + TextureColorInfo.identifier, + new StringVerifier, + Optional::Yes, + TextureColorInfo.description + }, + { + TextureTransparencyInfo.identifier, + new StringVerifier, + Optional::Yes, + TextureTransparencyInfo.description + }, { SizeInfo.identifier, new DoubleVerifier, @@ -220,6 +247,8 @@ RingsComponent::RingsComponent(const ghoul::Dictionary& dictionary) , _textureFwrdPath(TextureFwrdInfo) , _textureBckwrdPath(TextureBckwrdInfo) , _textureUnlitPath(TextureUnlitInfo) + , _textureColorPath(TextureColorInfo) + , _textureTransparencyPath(TextureTransparencyInfo) , _size(SizeInfo, 1.f, 0.f, 1e25f) , _offset(OffsetInfo, glm::vec2(0.f, 1.f), glm::vec2(0.f), glm::vec2(1.f)) , _nightFactor(NightFactorInfo, 0.33f, 0.f, 1.f) @@ -298,6 +327,26 @@ void RingsComponent::initialize() { _textureFileUnlit->setCallback([&](const File&) { _textureIsDirty = true; }); } + if (_ringsDictionary.hasKey(TextureColorInfo.identifier)) { + _textureColorPath = absPath( + _ringsDictionary.value(TextureColorInfo.identifier) + ); + _textureFileColor = std::make_unique(_textureColorPath); + _textureColorPath.onChange([&]() { loadTexture(); }); + addProperty(_textureColorPath); + _textureFileColor->setCallback([&](const File&) { _textureIsDirty = true; }); + } + + if (_ringsDictionary.hasKey(TextureTransparencyInfo.identifier)) { + _textureTransparencyPath = absPath( + _ringsDictionary.value(TextureTransparencyInfo.identifier) + ); + _textureFileTransparency = std::make_unique(_textureTransparencyPath); + _textureTransparencyPath.onChange([&]() { loadTexture(); }); + addProperty(_textureTransparencyPath); + _textureFileTransparency->setCallback([&](const File&) { _textureIsDirty = true; }); + } + if (_ringsDictionary.hasValue(OffsetInfo.identifier)) { _offset = _ringsDictionary.value(OffsetInfo.identifier); } @@ -415,6 +464,8 @@ void RingsComponent::draw(const RenderData& data, ghoul::opengl::TextureUnit ringTextureFwrdUnit; ghoul::opengl::TextureUnit ringTextureBckwrdUnit; ghoul::opengl::TextureUnit ringTextureUnlitUnit; + ghoul::opengl::TextureUnit ringTextureColorUnit; + ghoul::opengl::TextureUnit ringTextureTransparencyUnit; if (renderPass == GeometryAndShading) { if (_isAdvancedTextureEnabled) { _shader->setUniform( @@ -455,6 +506,20 @@ void RingsComponent::draw(const RenderData& data, ringTextureUnlitUnit ); + ringTextureColorUnit.activate(); + _textureColor->bind(); + _shader->setUniform( + _uniformCacheAdvancedRings.ringTextureColor, + ringTextureColorUnit + ); + + ringTextureTransparencyUnit.activate(); + _textureTransparency->bind(); + _shader->setUniform( + _uniformCacheAdvancedRings.ringTextureTransparency, + ringTextureTransparencyUnit + ); + // Adding the model transformation to the final shadow matrix so we have a // complete transformation from the model coordinates to the clip space of // the light position. @@ -482,6 +547,10 @@ void RingsComponent::draw(const RenderData& data, glBindTexture(GL_TEXTURE_2D, shadowData.shadowDepthTexture); _shader->setUniform(_uniformCacheAdvancedRings.shadowMapTexture, shadowMapUnit); + glEnable(GL_DEPTH_TEST); + glEnablei(GL_BLEND, 0); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } else { _shader->setUniform( _uniformCache.modelViewProjectionMatrix, @@ -527,7 +596,13 @@ void RingsComponent::draw(const RenderData& data, _geometryOnlyShader->setUniform(_geomUniformCache.textureOffset, _offset); ringTextureUnit.activate(); - _texture->bind(); + if (_isAdvancedTextureEnabled) { + _textureForwards->bind(); + } + else { + _texture->bind(); + } + _geometryOnlyShader->setUniform(_geomUniformCache.ringTexture, ringTextureUnit); } @@ -689,6 +764,60 @@ void RingsComponent::loadTexture() { } } + if (!_textureColorPath.value().empty()) { + std::unique_ptr textureColor = TextureReader::ref().loadTexture( + absPath(_textureColorPath) + ); + + if (textureColor) { + LDEBUGC( + "RingsComponent", + fmt::format( + "Loaded color texture from '{}'", + absPath(_textureColorPath) + ) + ); + _textureColor = std::move(textureColor); + + _textureColor->uploadTexture(); + _textureColor->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap); + + _textureFileColor = std::make_unique(_textureColorPath); + _textureFileColor->setCallback( + [&](const ghoul::filesystem::File&) { _textureIsDirty = true; } + ); + } + } + + if (!_textureTransparencyPath.value().empty()) { + std::unique_ptr textureTransparency = TextureReader::ref().loadTexture( + absPath(_textureTransparencyPath) + ); + + if (textureTransparency) { + LDEBUGC( + "RingsComponent", + fmt::format( + "Loaded unlit texture from '{}'", + absPath(_textureUnlitPath) + ) + ); + _textureTransparency = std::move(textureTransparency); + + _textureTransparency->uploadTexture(); + _textureTransparency->setFilter( + ghoul::opengl::Texture::FilterMode::AnisotropicMipMap + ); + + _textureFileTransparency = std::make_unique( + _textureTransparencyPath + ); + _textureFileTransparency->setCallback( + [&](const ghoul::filesystem::File&) { _textureIsDirty = true; } + ); + } + } + _isAdvancedTextureEnabled = _textureForwards && _textureBackwards && _textureUnlit; } diff --git a/modules/globebrowsing/src/ringscomponent.h b/modules/globebrowsing/src/ringscomponent.h index d956df08f5..b4e3a9cda3 100644 --- a/modules/globebrowsing/src/ringscomponent.h +++ b/modules/globebrowsing/src/ringscomponent.h @@ -81,6 +81,8 @@ private: properties::StringProperty _textureFwrdPath; properties::StringProperty _textureBckwrdPath; properties::StringProperty _textureUnlitPath; + properties::StringProperty _textureColorPath; + properties::StringProperty _textureTransparencyPath; properties::FloatProperty _size; properties::Vec2Property _offset; properties::FloatProperty _nightFactor; @@ -96,7 +98,8 @@ private: ) _uniformCache; UniformCache(modelViewProjectionMatrix, textureOffset, colorFilterValue, nightFactor, sunPosition, camPositionObj, ringTextureFwrd, ringTextureBckwrd, - ringTextureUnlit, shadowMatrix, shadowMapTexture, zFightingPercentage + ringTextureUnlit, ringTextureColor, ringTextureTransparency, shadowMatrix, + shadowMapTexture, zFightingPercentage ) _uniformCacheAdvancedRings; UniformCache(modelViewProjectionMatrix, textureOffset, ringTexture ) _geomUniformCache; @@ -104,10 +107,14 @@ private: std::unique_ptr _textureForwards; std::unique_ptr _textureBackwards; std::unique_ptr _textureUnlit; + std::unique_ptr _textureTransparency; + std::unique_ptr _textureColor; std::unique_ptr _textureFile; std::unique_ptr _textureFileForwards; std::unique_ptr _textureFileBackwards; std::unique_ptr _textureFileUnlit; + std::unique_ptr _textureFileColor; + std::unique_ptr _textureFileTransparency; ghoul::Dictionary _ringsDictionary; bool _textureIsDirty = false;