first attempt. doesn't build :P

This commit is contained in:
benpm
2025-06-24 19:33:51 -06:00
parent 49f4b47532
commit fd5c126e15
4 changed files with 178 additions and 34 deletions

View File

@@ -60,12 +60,16 @@ uniform float ambientIntensity;
#if SHADOW_MAPPING_ENABLED
#define NSSamplesMinusOne #{nShadowSamples}
#define NSSamples (NSSamplesMinusOne + 1)
// Ring texture projection uniforms
uniform sampler1D ringTextureFwrd;
uniform sampler1D ringTextureBckwrd;
uniform sampler1D ringTextureUnlit;
uniform sampler1D ringTextureColor;
uniform sampler1D ringTextureTransparency;
uniform vec2 textureOffset;
uniform vec3 sunPositionObj;
uniform vec3 camPositionObj;
in vec4 shadowCoords;
uniform sampler2DShadow shadowMapTexture;
uniform float zFightingPercentage;
#endif // SHADOW_MAPPING_ENABLED
#if USE_ECLIPSE_SHADOWS
@@ -269,27 +273,45 @@ Fragment getFragment() {
#if SHADOW_MAPPING_ENABLED
float shadow = 1.0;
if (shadowCoords.w > 1) {
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 = sum / (8.0 * NSSamples + 1.f);
// Calculate ring shadow by projecting ring texture directly onto surface
// Assume ring lies in the XZ plane (Y=0) in object space
vec3 surfaceToSun = normalize(sunPositionObj - positionCameraSpace);
// Find intersection of light ray with ring plane (Y=0)
// Ray equation: P = positionCameraSpace + t * surfaceToSun
// For ring plane: P.y = 0, so t = -positionCameraSpace.y / surfaceToSun.y
if (abs(surfaceToSun.y) > 0.001) { // Avoid division by zero
float t = -positionCameraSpace.y / surfaceToSun.y;
if (t > 0.0) { // Ray intersects ring plane in front of surface
vec3 ringIntersection = positionCameraSpace + t * surfaceToSun;
// Calculate distance from ring center
float ringRadius = length(ringIntersection.xz);
// Convert radius to texture coordinate based on ring texture mapping
// Radius \in [textureOffset.x, textureOffset.y] maps to texCoord \in [0,1]
float texCoord = (ringRadius - textureOffset.x) / (textureOffset.y - textureOffset.x);
if (texCoord >= 0.0 && texCoord <= 1.0) {
// Sample ring transparency texture
vec4 transparency = texture(ringTextureTransparency, texCoord);
// Determine which side of ring we're viewing from (matches ring shader logic)
float lerpFactor = dot(camPositionObj, sunPositionObj);
// Sample appropriate ring texture based on viewing direction
vec4 ringColor = mix(texture(ringTextureFwrd, texCoord), texture(ringTextureBckwrd, texCoord), lerpFactor);
// Calculate shadow factor based on ring opacity
float ringOpacity = transparency.a;
shadow = 1.0 - ringOpacity;
shadow = clamp(shadow + 0.3, 0.0, 1.0); // Add ambient light similar to original
}
}
}
frag.color.xyz *= shadow < 0.99 ? clamp(shadow + 0.3, 0.0, 1.0) : shadow;
frag.color.xyz *= shadow;
#endif
frag.color.a *= opacity;

View File

@@ -1441,9 +1441,7 @@ void RenderableGlobe::renderChunkGlobally(const Chunk& chunk, const RenderData&
if (_eclipseShadowsEnabled && !_ellipsoid.shadowConfigurationArray().empty()) {
calculateEclipseShadows(program, data, ShadowCompType::GLOBAL_SHADOW);
}
// Shadow Mapping
} // Shadow Mapping
ghoul::opengl::TextureUnit shadowMapUnit;
if (_shadowMappingProperties.shadowMapping && shadowData.shadowDepthTexture != 0) {
// Adding the model transformation to the final shadow matrix so we have a
@@ -1462,6 +1460,49 @@ void RenderableGlobe::renderChunkGlobally(const Chunk& chunk, const RenderData&
"zFightingPercentage",
_shadowMappingProperties.zFightingPercentage
);
// Bind ring textures for direct projection when rings component is available
if (_ringsComponent && _ringsComponent->isEnabled() && _ringsComponent->isReady()) {
ghoul::opengl::TextureUnit ringTextureFwrdUnit;
ghoul::opengl::TextureUnit ringTextureBckwrdUnit;
ghoul::opengl::TextureUnit ringTextureUnlitUnit;
ghoul::opengl::TextureUnit ringTextureColorUnit;
ghoul::opengl::TextureUnit ringTextureTransparencyUnit;
if (_ringsComponent->ringTextureFwrd()) {
ringTextureFwrdUnit.activate();
_ringsComponent->ringTextureFwrd()->bind();
program.setUniform("ringTextureFwrd", ringTextureFwrdUnit);
}
if (_ringsComponent->ringTextureBckwrd()) {
ringTextureBckwrdUnit.activate();
_ringsComponent->ringTextureBckwrd()->bind();
program.setUniform("ringTextureBckwrd", ringTextureBckwrdUnit);
}
if (_ringsComponent->ringTextureUnlit()) {
ringTextureUnlitUnit.activate();
_ringsComponent->ringTextureUnlit()->bind();
program.setUniform("ringTextureUnlit", ringTextureUnlitUnit);
}
if (_ringsComponent->ringTextureColor()) {
ringTextureColorUnit.activate();
_ringsComponent->ringTextureColor()->bind();
program.setUniform("ringTextureColor", ringTextureColorUnit);
}
if (_ringsComponent->ringTextureTransparency()) {
ringTextureTransparencyUnit.activate();
_ringsComponent->ringTextureTransparency()->bind();
program.setUniform("ringTextureTransparency", ringTextureTransparencyUnit);
}
program.setUniform("textureOffset", _ringsComponent->textureOffset());
program.setUniform("sunPositionObj", _ringsComponent->sunPositionObj());
program.setUniform("camPositionObj", _ringsComponent->camPositionObj());
}
}
else if (_shadowMappingProperties.shadowMapping && _shadowComponent) {
shadowMapUnit.activate();
@@ -1581,9 +1622,7 @@ void RenderableGlobe::renderChunkLocally(const Chunk& chunk, const RenderData& d
if (_eclipseShadowsEnabled && !_ellipsoid.shadowConfigurationArray().empty()) {
calculateEclipseShadows(program, data, ShadowCompType::LOCAL_SHADOW);
}
// Shadow Mapping
} // Shadow Mapping
ghoul::opengl::TextureUnit shadowMapUnit;
if (_shadowMappingProperties.shadowMapping && shadowData.shadowDepthTexture != 0) {
// Adding the model transformation to the final shadow matrix so we have a
@@ -1602,6 +1641,49 @@ void RenderableGlobe::renderChunkLocally(const Chunk& chunk, const RenderData& d
"zFightingPercentage",
_shadowMappingProperties.zFightingPercentage
);
// Bind ring textures for direct projection when rings component is available
if (_ringsComponent && _ringsComponent->isEnabled() && _ringsComponent->isReady()) {
ghoul::opengl::TextureUnit ringTextureFwrdUnit;
ghoul::opengl::TextureUnit ringTextureBckwrdUnit;
ghoul::opengl::TextureUnit ringTextureUnlitUnit;
ghoul::opengl::TextureUnit ringTextureColorUnit;
ghoul::opengl::TextureUnit ringTextureTransparencyUnit;
if (_ringsComponent->ringTextureFwrd()) {
ringTextureFwrdUnit.activate();
_ringsComponent->ringTextureFwrd()->bind();
program.setUniform("ringTextureFwrd", ringTextureFwrdUnit);
}
if (_ringsComponent->ringTextureBckwrd()) {
ringTextureBckwrdUnit.activate();
_ringsComponent->ringTextureBckwrd()->bind();
program.setUniform("ringTextureBckwrd", ringTextureBckwrdUnit);
}
if (_ringsComponent->ringTextureUnlit()) {
ringTextureUnlitUnit.activate();
_ringsComponent->ringTextureUnlit()->bind();
program.setUniform("ringTextureUnlit", ringTextureUnlitUnit);
}
if (_ringsComponent->ringTextureColor()) {
ringTextureColorUnit.activate();
_ringsComponent->ringTextureColor()->bind();
program.setUniform("ringTextureColor", ringTextureColorUnit);
}
if (_ringsComponent->ringTextureTransparency()) {
ringTextureTransparencyUnit.activate();
_ringsComponent->ringTextureTransparency()->bind();
program.setUniform("ringTextureTransparency", ringTextureTransparencyUnit);
}
program.setUniform("textureOffset", _ringsComponent->textureOffset());
program.setUniform("sunPositionObj", _ringsComponent->sunPositionObj());
program.setUniform("camPositionObj", _ringsComponent->camPositionObj());
}
}
else if (_shadowMappingProperties.shadowMapping) {
shadowMapUnit.activate();

View File

@@ -867,4 +867,36 @@ double RingsComponent::size() const {
return _size;
}
ghoul::opengl::Texture* RingsComponent::ringTextureFwrd() const {
return _textureForwards.get();
}
ghoul::opengl::Texture* RingsComponent::ringTextureBckwrd() const {
return _textureBackwards.get();
}
ghoul::opengl::Texture* RingsComponent::ringTextureUnlit() const {
return _textureUnlit.get();
}
ghoul::opengl::Texture* RingsComponent::ringTextureColor() const {
return _textureColor.get();
}
ghoul::opengl::Texture* RingsComponent::ringTextureTransparency() const {
return _textureTransparency.get();
}
glm::vec2 RingsComponent::textureOffset() const {
return _offset;
}
glm::vec3 RingsComponent::sunPositionObj() const {
return _sunPosition;
}
glm::vec3 RingsComponent::camPositionObj() const {
return _camPositionObjectSpace;
}
} // namespace openspace

View File

@@ -69,11 +69,19 @@ public:
);
void update(const UpdateData& data);
static documentation::Documentation Documentation();
bool isEnabled() const;
static documentation::Documentation Documentation(); bool isEnabled() const;
double size() const;
// Texture access methods for globe rendering
ghoul::opengl::Texture* ringTextureFwrd() const;
ghoul::opengl::Texture* ringTextureBckwrd() const;
ghoul::opengl::Texture* ringTextureUnlit() const;
ghoul::opengl::Texture* ringTextureColor() const;
ghoul::opengl::Texture* ringTextureTransparency() const;
glm::vec2 textureOffset() const;
glm::vec3 sunPositionObj() const;
glm::vec3 camPositionObj() const;
private:
void loadTexture();
void createPlane();