Merge pull request #1505 from OpenSpace/issue/1099

Issue/1099
This commit is contained in:
Jonathas Costa
2021-02-22 12:09:05 -05:00
committed by GitHub
8 changed files with 699 additions and 47 deletions
@@ -21,7 +21,19 @@ local Saturn = {
SegmentsPerPatch = 64,
Layers = {},
Rings = {
Texture = texturesPath .. "/saturn_rings.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
},
@@ -2,6 +2,6 @@ local TexturesPath = asset.syncedResource({
Type = "HttpSynchronization",
Name = "Saturn textures",
Identifier = "saturn_textures",
Version = 3
Version = 4
})
asset.export("TexturesPath", TexturesPath)
+2
View File
@@ -92,6 +92,8 @@ set(SOURCE_FILES
source_group("Source Files" FILES ${SOURCE_FILES})
set(SHADER_FILES
shaders/advanced_rings_vs.glsl
shaders/advanced_rings_fs.glsl
shaders/blending.hglsl
shaders/globalrenderer_vs.glsl
shaders/localrenderer_vs.glsl
@@ -0,0 +1,143 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* *
* 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. *
****************************************************************************************/
#include "PowerScaling/powerScaling_fs.hglsl"
#include "fragment.glsl"
#define NSSamplesMinusOne #{nShadowSamples}
#define NSSamples (NSSamplesMinusOne + 1)
in vec2 vs_st;
in float vs_screenSpaceDepth;
in vec4 shadowCoords;
uniform sampler2DShadow shadowMapTexture;
uniform sampler1D ringTextureFwrd;
uniform sampler1D ringTextureBckwrd;
uniform sampler1D ringTextureUnlit;
uniform sampler1D ringTextureColor;
uniform sampler1D ringTextureTransparency;
uniform vec2 textureOffset;
uniform float colorFilterValue;
uniform vec3 sunPosition;
uniform vec3 sunPositionObj;
uniform vec3 camPositionObj;
uniform float _nightFactor;
uniform float zFightingPercentage;
// temp
in vec4 fragPosInLightSpace;
Fragment getFragment() {
// Moving the origin to the center
vec2 st = (vs_st - vec2(0.5)) * 2.0;
// The length of the texture coordinates vector is our distance from the center
float radius = length(st);
// We only want to consider ring-like objects so we need to discard everything else
if (radius > 1.0) {
discard;
}
// Remapping the texture coordinates
// Radius \in [0,1], texCoord \in [textureOffset.x, textureOffset.y]
// textureOffset.x -> 0
// textureOffset.y -> 1
float texCoord = (radius - textureOffset.x) / (textureOffset.y - textureOffset.x);
if (texCoord < 0.f || texCoord > 1.f) {
discard;
}
vec4 colorBckwrd = texture(ringTextureBckwrd, texCoord);
vec4 colorFwrd = texture(ringTextureFwrd, texCoord);
vec4 colorMult = texture(ringTextureColor, texCoord);
vec4 transparency = texture(ringTextureTransparency, texCoord);
float lerpFactor = dot(camPositionObj, sunPositionObj);
// 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 * colorMult, colorBckwrd * colorMult, lerpFactor);
diffuse.a = colorFilterValue * transparency.a;
float colorValue = length(diffuse.rgb) / 0.57735026919;
if (colorValue < 0.1) {
discard;
}
// shadow == 1.0 means it is not in shadow
float shadow = 1.0;
if (shadowCoords.z >= 0) {
vec4 normalizedShadowCoords = shadowCoords;
normalizedShadowCoords.z = normalizeFloat(zFightingPercentage * normalizedShadowCoords.w);
normalizedShadowCoords.xy = normalizedShadowCoords.xy / normalizedShadowCoords.w;
normalizedShadowCoords.w = 1.0;
float sum = 0;
#for i in 0..#{nShadowSamples}
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + #{i}, -NSSamples + #{i}));
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + #{i}, 0));
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(-NSSamples + #{i}, NSSamples - #{i}));
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , -NSSamples + #{i}));
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( 0 , NSSamples - #{i}));
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - #{i}, -NSSamples + #{i}));
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - #{i}, 0));
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2( NSSamples - #{i}, NSSamples - #{i}));
#endfor
sum += textureProjOffset(shadowMapTexture, normalizedShadowCoords, ivec2(0, 0));
shadow = clamp(sum / (8.0 * NSSamples + 1.f), 0.35, 1.0);
}
// The normal for the one plane depends on whether we are dealing
// with a front facing or back facing fragment
vec3 normal;
// The plane is oriented on the xz plane
// WARNING: This might not be the case for Uranus
if (gl_FrontFacing) {
normal = vec3(-1.0, 0.0, 0.0);
}
else {
normal = vec3(1.0, 0.0, 0.0);
}
// 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(1.0, 0.97075, 0.952) *
texture(ringTextureUnlit, texCoord).xyz *
_nightFactor;
}
Fragment frag;
frag.color = diffuse * shadow;
frag.depth = vs_screenSpaceDepth;
frag.gPosition = vec4(1e30, 1e30, 1e30, 1.0);
frag.gNormal = vec4(normal, 1.0);
return frag;
}
@@ -0,0 +1,53 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2021 *
* *
* 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__
#include "PowerScaling/powerScaling_vs.hglsl"
layout(location = 0) in vec2 in_position;
layout(location = 1) in vec2 in_st;
out vec2 vs_st;
out float vs_screenSpaceDepth;
out vec4 vs_positionViewSpace;
out vec4 shadowCoords;
uniform dmat4 modelViewProjectionMatrix;
// ShadowMatrix is the matrix defined by:
// textureCoordsMatrix * projectionMatrix * combinedViewMatrix * modelMatrix
// where textureCoordsMatrix is just a scale and bias computation: [-1,1] to [0,1]
uniform dmat4 shadowMatrix;
void main() {
vs_st = in_st;
dvec4 positionClipSpace = modelViewProjectionMatrix * dvec4(in_position, 0.0, 1.0);
vec4 positionClipSpaceZNorm = z_normalization(vec4(positionClipSpace));
shadowCoords = vec4(shadowMatrix * dvec4(in_position, 0.0, 1.0));
vs_screenSpaceDepth = positionClipSpaceZNorm.w;
gl_Position = positionClipSpaceZNorm;
}
@@ -949,7 +949,7 @@ TileMetaData RawTileDataReader::tileMetaData(RawTile& rawTile,
bool allIsMissing = true;
for (int y = 0; y < region.numPixels.y; ++y) {
const size_t yi = (region.numPixels.y - 1 - y) * bytesPerLine;
const size_t yi = (static_cast<unsigned long long>(region.numPixels.y) - 1 - y) * bytesPerLine;
size_t i = 0;
for (int x = 0; x < region.numPixels.x; ++x) {
for (size_t raster = 0; raster < _initData.nRasters; ++raster) {
+464 -44
View File
@@ -41,6 +41,7 @@
#include <ghoul/logging/logmanager.h>
#include <ghoul/misc/dictionary.h>
#include <ghoul/misc/profiling.h>
#include <ghoul/opengl/openglstatecache.h>
#include <ghoul/opengl/programobject.h>
#include <ghoul/opengl/texture.h>
#include <ghoul/opengl/textureunit.h>
@@ -54,10 +55,17 @@ namespace {
constexpr const std::array<const char*, 9> UniformNames = {
"modelViewProjectionMatrix", "textureOffset", "colorFilterValue", "_nightFactor",
"sunPosition", "ringTexture", "shadowMatrix", "shadowMapTexture",
"sunPosition", "ringTexture", "shadowMatrix", "shadowMapTexture",
"zFightingPercentage"
};
constexpr const std::array<const char*, 15> UniformNamesAdvancedRings = {
"modelViewProjectionMatrix", "textureOffset", "colorFilterValue", "_nightFactor",
"sunPosition", "sunPositionObj", "camPositionObj", "ringTextureFwrd",
"ringTextureBckwrd", "ringTextureUnlit", "ringTextureColor",
"ringTextureTransparency", "shadowMatrix", "shadowMapTexture", "zFightingPercentage"
};
constexpr const std::array<const char*, 3> GeomUniformNames = {
"modelViewProjectionMatrix", "textureOffset", "ringTexture"
};
@@ -69,6 +77,41 @@ namespace {
"texture which is used for these rings."
};
constexpr openspace::properties::Property::PropertyInfo TextureFwrdInfo = {
"TextureFwrd",
"TextureFwrd",
"This value is the path to a texture on disk that contains a one-dimensional "
"texture which is used for forward scattering light in these rings."
};
constexpr openspace::properties::Property::PropertyInfo TextureBckwrdInfo = {
"TextureBckwrd",
"TextureBckwrd",
"This value is the path to a texture on disk that contains a one-dimensional "
"texture which is used for backward scattering light in these rings."
};
constexpr openspace::properties::Property::PropertyInfo TextureUnlitInfo = {
"TextureUnlit",
"TextureUnlit",
"This value is the path to a texture on disk that contains a one-dimensional "
"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",
@@ -128,6 +171,36 @@ documentation::Documentation RingsComponent::Documentation() {
Optional::Yes,
TextureInfo.description
},
{
TextureFwrdInfo.identifier,
new StringVerifier,
Optional::Yes,
TextureFwrdInfo.description
},
{
TextureBckwrdInfo.identifier,
new StringVerifier,
Optional::Yes,
TextureBckwrdInfo.description
},
{
TextureUnlitInfo.identifier,
new StringVerifier,
Optional::Yes,
TextureUnlitInfo.description
},
{
TextureColorInfo.identifier,
new StringVerifier,
Optional::Yes,
TextureColorInfo.description
},
{
TextureTransparencyInfo.identifier,
new StringVerifier,
Optional::Yes,
TextureTransparencyInfo.description
},
{
SizeInfo.identifier,
new DoubleVerifier,
@@ -171,6 +244,11 @@ documentation::Documentation RingsComponent::Documentation() {
RingsComponent::RingsComponent(const ghoul::Dictionary& dictionary)
: properties::PropertyOwner({ "Rings" })
, _texturePath(TextureInfo)
, _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)
@@ -209,21 +287,71 @@ void RingsComponent::initialize() {
_size.onChange([&]() { _planeIsDirty = true; });
addProperty(_size);
_texturePath = absPath(
_ringsDictionary.value<std::string>(TextureInfo.identifier)
);
_textureFile = std::make_unique<File>(_texturePath);
if (_ringsDictionary.hasKey(TextureInfo.identifier)) {
_texturePath = absPath(
_ringsDictionary.value<std::string>(TextureInfo.identifier)
);
_textureFile = std::make_unique<File>(_texturePath);
_texturePath.onChange([&]() { loadTexture(); });
addProperty(_texturePath);
_textureFile->setCallback([&](const File&) { _textureIsDirty = true; });
}
if (_ringsDictionary.hasKey(TextureFwrdInfo.identifier)) {
_textureFwrdPath = absPath(
_ringsDictionary.value<std::string>(TextureFwrdInfo.identifier)
);
_textureFileForwards = std::make_unique<File>(_textureFwrdPath);
_textureFwrdPath.onChange([&]() { loadTexture(); });
addProperty(_textureFwrdPath);
_textureFileForwards->setCallback([&](const File&) { _textureIsDirty = true; });
}
if (_ringsDictionary.hasKey(TextureBckwrdInfo.identifier)) {
_textureBckwrdPath = absPath(
_ringsDictionary.value<std::string>(TextureBckwrdInfo.identifier)
);
_textureFileBackwards = std::make_unique<File>(_textureBckwrdPath);
_textureBckwrdPath.onChange([&]() { loadTexture(); });
addProperty(_textureBckwrdPath);
_textureFileBackwards->setCallback([&](const File&) { _textureIsDirty = true; });
}
if (_ringsDictionary.hasKey(TextureUnlitInfo.identifier)) {
_textureUnlitPath = absPath(
_ringsDictionary.value<std::string>(TextureUnlitInfo.identifier)
);
_textureFileUnlit = std::make_unique<File>(_textureUnlitPath);
_textureUnlitPath.onChange([&]() { loadTexture(); });
addProperty(_textureUnlitPath);
_textureFileUnlit->setCallback([&](const File&) { _textureIsDirty = true; });
}
if (_ringsDictionary.hasKey(TextureColorInfo.identifier)) {
_textureColorPath = absPath(
_ringsDictionary.value<std::string>(TextureColorInfo.identifier)
);
_textureFileColor = std::make_unique<File>(_textureColorPath);
_textureColorPath.onChange([&]() { loadTexture(); });
addProperty(_textureColorPath);
_textureFileColor->setCallback([&](const File&) { _textureIsDirty = true; });
}
if (_ringsDictionary.hasKey(TextureTransparencyInfo.identifier)) {
_textureTransparencyPath = absPath(
_ringsDictionary.value<std::string>(TextureTransparencyInfo.identifier)
);
_textureFileTransparency = std::make_unique<File>(_textureTransparencyPath);
_textureTransparencyPath.onChange([&]() { loadTexture(); });
addProperty(_textureTransparencyPath);
_textureFileTransparency->setCallback([&](const File&) { _textureIsDirty = true; });
}
if (_ringsDictionary.hasValue<glm::dvec2>(OffsetInfo.identifier)) {
_offset = _ringsDictionary.value<glm::dvec2>(OffsetInfo.identifier);
}
addProperty(_offset);
_texturePath.onChange([&]() { loadTexture(); });
addProperty(_texturePath);
_textureFile->setCallback([&](const File&) { _textureIsDirty = true; });
if (_ringsDictionary.hasValue<double>(NightFactorInfo.identifier)) {
_nightFactor = static_cast<float>(
_ringsDictionary.value<double>(NightFactorInfo.identifier)
@@ -261,6 +389,7 @@ bool RingsComponent::isReady() const {
void RingsComponent::initializeGL() {
ZoneScoped
loadTexture();
compileShadowShader();
try {
@@ -285,7 +414,6 @@ void RingsComponent::initializeGL() {
glGenBuffers(1, &_vertexPositionBuffer);
createPlane();
loadTexture();
}
void RingsComponent::deinitializeGL() {
@@ -297,6 +425,13 @@ void RingsComponent::deinitializeGL() {
_textureFile = nullptr;
_texture = nullptr;
_textureFileForwards = nullptr;
_textureForwards = nullptr;
_textureFileBackwards = nullptr;
_textureBackwards = nullptr;
_textureFileUnlit = nullptr;
_textureUnlit = nullptr;
global::renderEngine->removeRenderProgram(_shader.get());
_shader = nullptr;
@@ -326,34 +461,144 @@ void RingsComponent::draw(const RenderData& data,
* modelTransform;
ghoul::opengl::TextureUnit ringTextureUnit;
ghoul::opengl::TextureUnit ringTextureFwrdUnit;
ghoul::opengl::TextureUnit ringTextureBckwrdUnit;
ghoul::opengl::TextureUnit ringTextureUnlitUnit;
ghoul::opengl::TextureUnit ringTextureColorUnit;
ghoul::opengl::TextureUnit ringTextureTransparencyUnit;
if (renderPass == GeometryAndShading) {
_shader->setUniform(
_uniformCache.modelViewProjectionMatrix,
modelViewProjectionTransform
);
_shader->setUniform(_uniformCache.textureOffset, _offset);
_shader->setUniform(_uniformCache.colorFilterValue, _colorFilter);
_shader->setUniform(_uniformCache.nightFactor, _nightFactor);
_shader->setUniform(_uniformCache.sunPosition, _sunPosition);
_shader->setUniform(_uniformCache.zFightingPercentage, _zFightingPercentage);
if (_isAdvancedTextureEnabled) {
_shader->setUniform(
_uniformCacheAdvancedRings.modelViewProjectionMatrix,
modelViewProjectionTransform
);
_shader->setUniform(_uniformCacheAdvancedRings.textureOffset, _offset);
_shader->setUniform(_uniformCacheAdvancedRings.colorFilterValue, _colorFilter);
_shader->setUniform(_uniformCacheAdvancedRings.nightFactor, _nightFactor);
_shader->setUniform(_uniformCacheAdvancedRings.sunPosition, _sunPosition);
const glm::dmat4 inverseModelTransform = glm::inverse(modelTransform);
ringTextureUnit.activate();
_texture->bind();
_shader->setUniform(_uniformCache.ringTexture, ringTextureUnit);
glm::vec3 sunPositionObjectSpace = glm::normalize(
glm::vec3(inverseModelTransform * glm::vec4(_sunPosition, 0.0))
);
// 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.
_shader->setUniform(
_uniformCache.shadowMatrix,
shadowData.shadowMatrix * modelTransform
);
_shader->setUniform(
_uniformCacheAdvancedRings.sunPositionObj,
sunPositionObjectSpace
);
_shader->setUniform(
_uniformCacheAdvancedRings.zFightingPercentage,
_zFightingPercentage
);
_shader->setUniform(
_uniformCacheAdvancedRings.modelViewProjectionMatrix,
modelViewProjectionTransform
);
ghoul::opengl::TextureUnit shadowMapUnit;
shadowMapUnit.activate();
glBindTexture(GL_TEXTURE_2D, shadowData.shadowDepthTexture);
ringTextureFwrdUnit.activate();
_textureForwards->bind();
_shader->setUniform(
_uniformCacheAdvancedRings.ringTextureFwrd,
ringTextureFwrdUnit
);
_shader->setUniform(_uniformCache.shadowMapTexture, shadowMapUnit);
ringTextureBckwrdUnit.activate();
_textureBackwards->bind();
_shader->setUniform(
_uniformCacheAdvancedRings.ringTextureBckwrd,
ringTextureBckwrdUnit
);
ringTextureUnlitUnit.activate();
_textureUnlit->bind();
_shader->setUniform(
_uniformCacheAdvancedRings.ringTextureUnlit,
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.
_shader->setUniform(
_uniformCacheAdvancedRings.shadowMatrix,
shadowData.shadowMatrix * modelTransform
);
const glm::dmat4 camToObjectTransform = glm::inverse(
data.camera.combinedViewMatrix()
* modelTransform
);
_camPositionObjectSpace = glm::normalize(
glm::vec3(camToObjectTransform * glm::dvec4(0.0, 0.0, 0.0, 1.0))
);
_shader->setUniform(
_uniformCacheAdvancedRings.camPositionObj,
_camPositionObjectSpace
);
ghoul::opengl::TextureUnit shadowMapUnit;
shadowMapUnit.activate();
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,
modelViewProjectionTransform
);
_shader->setUniform(_uniformCache.textureOffset, _offset);
_shader->setUniform(_uniformCache.colorFilterValue, _colorFilter);
_shader->setUniform(_uniformCache.nightFactor, _nightFactor);
_shader->setUniform(_uniformCache.sunPosition, _sunPosition);
_shader->setUniform(_uniformCache.zFightingPercentage, _zFightingPercentage);
_shader->setUniform(
_uniformCache.modelViewProjectionMatrix,
modelViewProjectionTransform
);
ringTextureUnit.activate();
_texture->bind();
_shader->setUniform(_uniformCache.ringTexture, ringTextureUnit);
// 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.
_shader->setUniform(
_uniformCache.shadowMatrix,
shadowData.shadowMatrix * modelTransform
);
ghoul::opengl::TextureUnit shadowMapUnit;
shadowMapUnit.activate();
glBindTexture(GL_TEXTURE_2D, shadowData.shadowDepthTexture);
_shader->setUniform(_uniformCache.shadowMapTexture, shadowMapUnit);
}
glEnable(GL_DEPTH_TEST);
glEnablei(GL_BLEND, 0);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
}
else if (renderPass == GeometryOnly) {
_geometryOnlyShader->setUniform(
@@ -363,7 +608,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);
}
@@ -377,6 +628,8 @@ void RingsComponent::draw(const RenderData& data,
if (renderPass == GeometryAndShading) {
_shader->deactivate();
global::renderEngine->openglStateCache().resetBlendState();
//global::renderEngine->openglStateCache().resetDepthState();
}
else if (renderPass == GeometryOnly) {
_geometryOnlyShader->deactivate();
@@ -416,9 +669,11 @@ void RingsComponent::update(const UpdateData& data) {
}
void RingsComponent::loadTexture() {
using namespace ghoul::io;
using namespace ghoul::opengl;
if (!_texturePath.value().empty()) {
using namespace ghoul::io;
using namespace ghoul::opengl;
std::unique_ptr<Texture> texture = TextureReader::ref().loadTexture(
absPath(_texturePath)
);
@@ -439,6 +694,143 @@ void RingsComponent::loadTexture() {
);
}
}
if (!_textureFwrdPath.value().empty()) {
std::unique_ptr<Texture> textureForwards = TextureReader::ref().loadTexture(
absPath(_textureFwrdPath)
);
if (textureForwards) {
LDEBUGC(
"RingsComponent",
fmt::format(
"Loaded forwards scattering texture from '{}'",
absPath(_textureFwrdPath)
)
);
_textureForwards = std::move(textureForwards);
_textureForwards->uploadTexture();
_textureForwards->setFilter(
ghoul::opengl::Texture::FilterMode::AnisotropicMipMap);
_textureFileForwards = std::make_unique<ghoul::filesystem::File>(
_textureFwrdPath
);
_textureFileForwards->setCallback(
[&](const ghoul::filesystem::File&) { _textureIsDirty = true; }
);
}
}
if (!_textureBckwrdPath.value().empty()) {
std::unique_ptr<Texture> textureBackwards = TextureReader::ref().loadTexture(
absPath(_textureBckwrdPath)
);
if (textureBackwards) {
LDEBUGC(
"RingsComponent",
fmt::format(
"Loaded backwards scattering texture from '{}'",
absPath(_textureBckwrdPath)
)
);
_textureBackwards = std::move(textureBackwards);
_textureBackwards->uploadTexture();
_textureBackwards->setFilter(
ghoul::opengl::Texture::FilterMode::AnisotropicMipMap);
_textureFileBackwards = std::make_unique<ghoul::filesystem::File>(
_textureBckwrdPath
);
_textureFileBackwards->setCallback(
[&](const ghoul::filesystem::File&) { _textureIsDirty = true; }
);
}
}
if (!_textureUnlitPath.value().empty()) {
std::unique_ptr<Texture> textureUnlit = TextureReader::ref().loadTexture(
absPath(_textureUnlitPath)
);
if (textureUnlit) {
LDEBUGC(
"RingsComponent",
fmt::format(
"Loaded unlit texture from '{}'",
absPath(_textureUnlitPath)
)
);
_textureUnlit = std::move(textureUnlit);
_textureUnlit->uploadTexture();
_textureUnlit->setFilter(ghoul::opengl::Texture::FilterMode::AnisotropicMipMap);
_textureFileUnlit = std::make_unique<ghoul::filesystem::File>(_textureUnlitPath);
_textureFileUnlit->setCallback(
[&](const ghoul::filesystem::File&) { _textureIsDirty = true; }
);
}
}
if (!_textureColorPath.value().empty()) {
std::unique_ptr<Texture> 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<ghoul::filesystem::File>(_textureColorPath);
_textureFileColor->setCallback(
[&](const ghoul::filesystem::File&) { _textureIsDirty = true; }
);
}
}
if (!_textureTransparencyPath.value().empty()) {
std::unique_ptr<Texture> 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<ghoul::filesystem::File>(
_textureTransparencyPath
);
_textureFileTransparency->setCallback(
[&](const ghoul::filesystem::File&) { _textureIsDirty = true; }
);
}
}
_isAdvancedTextureEnabled = _textureForwards && _textureBackwards && _textureUnlit;
}
void RingsComponent::createPlane() {
@@ -489,14 +881,42 @@ void RingsComponent::compileShadowShader() {
try {
global::renderEngine->removeRenderProgram(_shader.get());
_shader = global::renderEngine->buildRenderProgram(
"RingsProgram",
absPath("${MODULE_GLOBEBROWSING}/shaders/rings_vs.glsl"),
absPath("${MODULE_GLOBEBROWSING}/shaders/rings_fs.glsl"),
dict
);
// _shader = global::renderEngine->buildRenderProgram(
// "RingsProgram",
// absPath("${MODULE_GLOBEBROWSING}/shaders/rings_vs.glsl"),
// absPath("${MODULE_GLOBEBROWSING}/shaders/rings_fs.glsl"),
// dict
// );
ghoul::opengl::updateUniformLocations(*_shader, _uniformCache, UniformNames);
// ghoul::opengl::updateUniformLocations(*_shader, _uniformCache, UniformNames);
// Uses multiple textures for the Rings
// See https://bjj.mmedia.is/data/s_rings/index.html for theory behind it
if (_isAdvancedTextureEnabled) {
_shader = global::renderEngine->buildRenderProgram(
"AdvancedRingsProgram",
absPath("${MODULE_GLOBEBROWSING}/shaders/advanced_rings_vs.glsl"),
absPath("${MODULE_GLOBEBROWSING}/shaders/advanced_rings_fs.glsl"),
dict
);
ghoul::opengl::updateUniformLocations(
*_shader,
_uniformCacheAdvancedRings,
UniformNamesAdvancedRings
);
}
else {
// Uses simple texture for the Rings
_shader = global::renderEngine->buildRenderProgram(
"RingsProgram",
absPath("${MODULE_GLOBEBROWSING}/shaders/rings_vs.glsl"),
absPath("${MODULE_GLOBEBROWSING}/shaders/rings_fs.glsl"),
dict
);
ghoul::opengl::updateUniformLocations(*_shader, _uniformCache, UniformNames);
}
}
catch (const ghoul::RuntimeError& e) {
LERROR(e.message);
@@ -78,6 +78,11 @@ private:
void compileShadowShader();
properties::StringProperty _texturePath;
properties::StringProperty _textureFwrdPath;
properties::StringProperty _textureBckwrdPath;
properties::StringProperty _textureUnlitPath;
properties::StringProperty _textureColorPath;
properties::StringProperty _textureTransparencyPath;
properties::FloatProperty _size;
properties::Vec2Property _offset;
properties::FloatProperty _nightFactor;
@@ -91,18 +96,35 @@ private:
UniformCache(modelViewProjectionMatrix, textureOffset, colorFilterValue, nightFactor,
sunPosition, ringTexture, shadowMatrix, shadowMapTexture, zFightingPercentage
) _uniformCache;
UniformCache(modelViewProjectionMatrix, textureOffset, colorFilterValue, nightFactor,
sunPosition, sunPositionObj, camPositionObj, ringTextureFwrd, ringTextureBckwrd,
ringTextureUnlit, ringTextureColor, ringTextureTransparency, shadowMatrix,
shadowMapTexture, zFightingPercentage
) _uniformCacheAdvancedRings;
UniformCache(modelViewProjectionMatrix, textureOffset, ringTexture
) _geomUniformCache;
std::unique_ptr<ghoul::opengl::Texture> _texture;
std::unique_ptr<ghoul::opengl::Texture> _textureForwards;
std::unique_ptr<ghoul::opengl::Texture> _textureBackwards;
std::unique_ptr<ghoul::opengl::Texture> _textureUnlit;
std::unique_ptr<ghoul::opengl::Texture> _textureTransparency;
std::unique_ptr<ghoul::opengl::Texture> _textureColor;
std::unique_ptr<ghoul::filesystem::File> _textureFile;
std::unique_ptr<ghoul::filesystem::File> _textureFileForwards;
std::unique_ptr<ghoul::filesystem::File> _textureFileBackwards;
std::unique_ptr<ghoul::filesystem::File> _textureFileUnlit;
std::unique_ptr<ghoul::filesystem::File> _textureFileColor;
std::unique_ptr<ghoul::filesystem::File> _textureFileTransparency;
ghoul::Dictionary _ringsDictionary;
bool _textureIsDirty = false;
bool _isAdvancedTextureEnabled = false;
GLuint _quad = 0;
GLuint _vertexPositionBuffer = 0;
bool _planeIsDirty = false;
glm::vec3 _sunPosition = glm::vec3(0.f);
glm::vec3 _camPositionObjectSpace = glm::vec3(0.f);
};
} // namespace openspace