mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-04-24 04:58:59 -05:00
@@ -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)
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user