diff --git a/data/assets/examples/animation.asset b/data/assets/examples/animation.asset index 69a3b14451..7dc15495c2 100644 --- a/data/assets/examples/animation.asset +++ b/data/assets/examples/animation.asset @@ -28,9 +28,7 @@ local animationLoop = { ModelScale = 3E7, LightSources = { sun.LightSource - }, - PerformShading = true, - DisableFaceCulling = true + } }, GUI = { Name = "Animated Model example (LoopFromStart)", @@ -57,9 +55,7 @@ local animationLoopInf = { ModelScale = 3E7, LightSources = { sun.LightSource - }, - PerformShading = true, - DisableFaceCulling = true + } }, GUI = { Name = "Animated Model example (LoopInfinitely)", @@ -86,9 +82,7 @@ local animationOnce = { ModelScale = 3E7, LightSources = { sun.LightSource - }, - PerformShading = true, - DisableFaceCulling = true + } }, GUI = { Name = "Animated Model example (Once)", @@ -115,9 +109,7 @@ local animationBounceInf = { ModelScale = 3E7, LightSources = { sun.LightSource - }, - PerformShading = true, - DisableFaceCulling = true + } }, GUI = { Name = "Animated Model example (BounceInfinitely)", @@ -144,9 +136,7 @@ local animationBounce = { ModelScale = 3E7, LightSources = { sun.LightSource - }, - PerformShading = true, - DisableFaceCulling = true + } }, GUI = { Name = "Animated Model example (BounceFromStart)", diff --git a/data/assets/examples/approachevents.asset b/data/assets/examples/approachevents.asset index 54291995a2..26b77d9cc7 100644 --- a/data/assets/examples/approachevents.asset +++ b/data/assets/examples/approachevents.asset @@ -32,14 +32,14 @@ local obj = { Renderable = { Type = "RenderableModel", GeometryFile = model .. "BoxAnimated.glb", - ModelScale = 1.0, + ModelScale = 1000, LightSources = { sun.LightSource - }, - PerformShading = true, - DisableFaceCulling = true + } }, - InteractionSphere = 1000.0, + InteractionSphere = 900, + ApproachFactor = 50.0, + ReachFactor = 5.0, OnApproach = { "os.example.generic" }, OnReach = { "os.example.generic" }, OnRecede = { "os.example.generic" }, diff --git a/data/assets/examples/globerotation.asset b/data/assets/examples/globerotation.asset index 4ada35e386..b1aaec3951 100644 --- a/data/assets/examples/globerotation.asset +++ b/data/assets/examples/globerotation.asset @@ -1,3 +1,4 @@ +local sun = asset.require("scene/solarsystem/sun/sun") local earth = asset.require("scene/solarsystem/planets/earth/earth") local sunTransforms = asset.require("scene/solarsystem/sun/transforms") @@ -35,8 +36,10 @@ local Example_GlobeRotation = { }, Renderable = { Type = "RenderableModel", - Body = "NEW HORIZONS", - GeometryFile = models .. "NewHorizonsCleanModel.obj" + GeometryFile = models .. "NewHorizonsCleanModel.obj", + LightSources = { + sun.LightSource + } }, GUI = { Path = "/Example" diff --git a/data/assets/examples/globetranslation.asset b/data/assets/examples/globetranslation.asset index 2150c723d6..9421c0e9c5 100644 --- a/data/assets/examples/globetranslation.asset +++ b/data/assets/examples/globetranslation.asset @@ -1,3 +1,4 @@ +local sun = asset.require("scene/solarsystem/sun/sun") local earth = asset.require("scene/solarsystem/planets/earth/earth") local sunTransforms = asset.require("scene/solarsystem/sun/transforms") @@ -22,8 +23,10 @@ local Example_Fixed_Height = { }, Renderable = { Type = "RenderableModel", - Body = "NEW HORIZONS", - GeometryFile = models .. "NewHorizonsCleanModel.obj" + GeometryFile = models .. "NewHorizonsCleanModel.obj", + LightSources = { + sun.LightSource + } }, GUI = { Path = "/Example" @@ -44,8 +47,10 @@ local Example_Adaptive_Height = { }, Renderable = { Type = "RenderableModel", - Body = "NEW HORIZONS", - GeometryFile = models .. "NewHorizonsCleanModel.obj" + GeometryFile = models .. "NewHorizonsCleanModel.obj", + LightSources = { + sun.LightSource + } }, GUI = { Path = "/Example" diff --git a/data/assets/examples/modelshader/model_fs.glsl b/data/assets/examples/modelshader/model_fs.glsl index be9f2558fc..09d448619a 100644 --- a/data/assets/examples/modelshader/model_fs.glsl +++ b/data/assets/examples/modelshader/model_fs.glsl @@ -28,48 +28,69 @@ in vec2 vs_st; in vec3 vs_normalViewSpace; in vec4 vs_positionCameraSpace; in float vs_screenSpaceDepth; -in mat3 TBN; +in mat3 vs_TBN; uniform float ambientIntensity = 0.2; uniform float diffuseIntensity = 1.0; uniform float specularIntensity = 1.0; - uniform bool performShading = true; + uniform bool use_forced_color = false; uniform bool has_texture_diffuse; uniform bool has_texture_normal; uniform bool has_texture_specular; uniform bool has_color_specular; -uniform bool opacityBlending = false; - uniform sampler2D texture_diffuse; uniform sampler2D texture_normal; uniform sampler2D texture_specular; uniform vec3 color_diffuse; uniform vec3 color_specular; +uniform float opacity = 1.0; uniform int nLightSources; uniform vec3 lightDirectionsViewSpace[8]; uniform float lightIntensities[8]; -uniform float opacity = 1.0; +uniform bool performManualDepthTest = false; +uniform sampler2D gBufferDepthTexture; + +uniform vec2 resolution; Fragment getFragment() { Fragment frag; + frag.depth = vs_screenSpaceDepth; + frag.gPosition = vs_positionCameraSpace; + frag.gNormal = vec4(vs_normalViewSpace, 0.0); + frag.disableLDR2HDR = true; + frag.color.a = opacity; + if (performManualDepthTest) { + // gl_FragCoord.x goes from 0 to resolution.x and gl_FragCoord.y goes from 0 to + // resolution.y, need to normalize it + vec2 texCoord = gl_FragCoord.xy; + texCoord.x = texCoord.x / resolution.x; + texCoord.y = texCoord.y / resolution.y; + + // Manual depth test + float gBufferDepth = denormalizeFloat(texture(gBufferDepthTexture, texCoord).x); + if (vs_screenSpaceDepth > gBufferDepth) { + frag.color = vec4(0.0); + frag.depth = gBufferDepth; + return frag; + } + } + + // Frag color is the values of the normal vector if (has_texture_normal) { vec3 normalAlbedo = texture(texture_normal, vs_st).rgb; normalAlbedo = normalize(normalAlbedo * 2.0 - 1.0); - frag.color.rgb = normalize(TBN * normalAlbedo); + frag.color.rgb = normalize(vs_TBN * normalAlbedo); } else { frag.color.rgb = normalize(vs_normalViewSpace); } - frag.color.a = 1.0; - frag.gPosition = vs_positionCameraSpace; - frag.gNormal = vec4(vs_normalViewSpace, 0.0); - frag.disableLDR2HDR = true; + return frag; } diff --git a/data/assets/examples/modelshader/model_vs.glsl b/data/assets/examples/modelshader/model_vs.glsl index 8413d4f4c1..ddd94fe996 100644 --- a/data/assets/examples/modelshader/model_vs.glsl +++ b/data/assets/examples/modelshader/model_vs.glsl @@ -35,7 +35,7 @@ out vec2 vs_st; out vec3 vs_normalViewSpace; out float vs_screenSpaceDepth; out vec4 vs_positionCameraSpace; -out mat3 TBN; +out mat3 vs_TBN; uniform mat4 modelViewTransform; uniform mat4 projectionTransform; @@ -52,17 +52,18 @@ void main() { vs_st = in_st; vs_screenSpaceDepth = positionScreenSpace.w; - vs_normalViewSpace = normalize(mat3(normalTransform) * (mat3(meshNormalTransform) * in_normal)); + vs_normalViewSpace = + normalize(mat3(normalTransform) * (mat3(meshNormalTransform) * in_normal)); - // TBN matrix for normal mapping - vec3 T = normalize(mat3(normalTransform) * (mat3(meshNormalTransform) * in_tangent)); - vec3 N = normalize(mat3(normalTransform) * (mat3(meshNormalTransform) * in_normal)); + // TBN matrix for normal mapping + vec3 T = normalize(mat3(normalTransform) * (mat3(meshNormalTransform) * in_tangent)); + vec3 N = normalize(mat3(normalTransform) * (mat3(meshNormalTransform) * in_normal)); - // Re-orthogonalize T with respect to N - T = normalize(T - dot(T, N) * N); + // Re-orthogonalize T with respect to N + T = normalize(T - dot(T, N) * N); - // Retrieve perpendicular vector B with cross product of T and N - vec3 B = normalize(cross(N, T)); + // Retrieve perpendicular vector B with cross product of T and N + vec3 B = normalize(cross(N, T)); - TBN = mat3(T, B, N); + vs_TBN = mat3(T, B, N); } diff --git a/data/assets/examples/modelshader/modelshader.asset b/data/assets/examples/modelshader/modelshader.asset index 9cab18baf0..405e9bb3f6 100644 --- a/data/assets/examples/modelshader/modelshader.asset +++ b/data/assets/examples/modelshader/modelshader.asset @@ -25,7 +25,6 @@ local model = { sun.LightSource }, PerformShading = true, - DisableFaceCulling = true, VertexShader = asset.localResource("model_vs.glsl"), FragmentShader = asset.localResource("model_fs.glsl"), }, diff --git a/data/assets/scene/milkyway/objects/orionnebula/nebula.asset b/data/assets/scene/milkyway/objects/orionnebula/nebula.asset index e2dc3d5551..9516ce8354 100644 --- a/data/assets/scene/milkyway/objects/orionnebula/nebula.asset +++ b/data/assets/scene/milkyway/objects/orionnebula/nebula.asset @@ -58,7 +58,7 @@ local OrionNebulaModel = { Type = "RenderableModel", GeometryFile = sync .. "orion_nebula.obj", Opacity = 1.0, - DisableFaceCulling = false, + EnableFaceCulling = false, SpecularIntensity = 0.0, AmbientIntensity = 0.0, DiffuseIntensity = 1.0, @@ -93,7 +93,6 @@ local OrionNebulaShocksModel = { Type = "RenderableModel", GeometryFile = sync .. "orishocks.obj", Opacity = 1.0, - DisableFaceCulling = false, SpecularIntensity = 0.0, AmbientIntensity = 0.0, DiffuseIntensity = 1.0, @@ -128,8 +127,7 @@ local OrionNebulaProplydsModel = { Renderable = { Type = "RenderableModel", GeometryFile = sync .. "proplyds.obj", - Opacity = 1.0, - DisableFaceCulling = false, + Opacity = 1.0, SpecularIntensity = 0.0, AmbientIntensity = 0.0, DiffuseIntensity = 1.0, diff --git a/data/assets/scene/solarsystem/missions/apollo/15/apollo15.asset b/data/assets/scene/solarsystem/missions/apollo/15/apollo15.asset index 3566107c78..c47c88f0a1 100644 --- a/data/assets/scene/solarsystem/missions/apollo/15/apollo15.asset +++ b/data/assets/scene/solarsystem/missions/apollo/15/apollo15.asset @@ -44,8 +44,7 @@ local Apollo15 = { LightSources = { sun.LightSource }, - PerformShading = true, - DisableFaceCulling = true + PerformShading = true }, TimeFrame = { Type = "TimeFrameInterval", diff --git a/data/assets/scene/solarsystem/missions/apollo/17/bouldersstation2.asset b/data/assets/scene/solarsystem/missions/apollo/17/bouldersstation2.asset index 30f2ed29ec..585565ce27 100644 --- a/data/assets/scene/solarsystem/missions/apollo/17/bouldersstation2.asset +++ b/data/assets/scene/solarsystem/missions/apollo/17/bouldersstation2.asset @@ -49,7 +49,7 @@ local Station2Boulder1Model = { } }, PerformShading = false, - DisableFaceCulling = true + EnableFaceCulling = false }, GUI = { Name = "Station 2 Boulder 1 Model", @@ -98,7 +98,7 @@ local Station2Boulder2Model = { } }, PerformShading = false, - DisableFaceCulling = true + EnableFaceCulling = false }, GUI = { Name = "Station 2 Boulder 2 Model", @@ -147,7 +147,7 @@ local Station2Boulder3Model = { } }, PerformShading = false, - DisableFaceCulling = true + EnableFaceCulling = false }, GUI = { Name = "Station 2 Boulder 3 Model", diff --git a/data/assets/scene/solarsystem/missions/apollo/17/bouldersstation6.asset b/data/assets/scene/solarsystem/missions/apollo/17/bouldersstation6.asset index af9d40e5e8..86ad7a235d 100644 --- a/data/assets/scene/solarsystem/missions/apollo/17/bouldersstation6.asset +++ b/data/assets/scene/solarsystem/missions/apollo/17/bouldersstation6.asset @@ -58,7 +58,7 @@ local Station6Frag1Model = { } }, PerformShading = false, - DisableFaceCulling = true + EnableFaceCulling = false }, GUI = { Name = "Station 6 Fragment 1 Model", @@ -108,7 +108,7 @@ local Station6Frag2Model = { } }, PerformShading = false, - DisableFaceCulling = true, + EnableFaceCulling = false, }, GUI = { Name = "Station 6 Fragment 2 Model", @@ -146,7 +146,7 @@ local Station6Frag3Model = { } }, PerformShading = false, - DisableFaceCulling = true + EnableFaceCulling = false }, GUI = { Name = "Station 6 Fragment 3 Model", diff --git a/data/assets/scene/solarsystem/missions/apollo/17/bouldersstation7.asset b/data/assets/scene/solarsystem/missions/apollo/17/bouldersstation7.asset index 5ad8cd27dc..843f431930 100644 --- a/data/assets/scene/solarsystem/missions/apollo/17/bouldersstation7.asset +++ b/data/assets/scene/solarsystem/missions/apollo/17/bouldersstation7.asset @@ -49,7 +49,7 @@ local Station7BoulderModel = { } }, PerformShading = false, - DisableFaceCulling = true + EnableFaceCulling = false }, GUI = { Name = "Station 7 Boulder Model", diff --git a/data/assets/scene/solarsystem/missions/apollo/8/launch_model.asset b/data/assets/scene/solarsystem/missions/apollo/8/launch_model.asset index fee121656d..1b2a7b7ab5 100644 --- a/data/assets/scene/solarsystem/missions/apollo/8/launch_model.asset +++ b/data/assets/scene/solarsystem/missions/apollo/8/launch_model.asset @@ -30,7 +30,7 @@ local Apollo8Launch = { }, GUI = { Name = "Apollo 8 Launch Capsule", - Path = "/Solar System/Missions/Apollo" + Path = "/Solar System/Missions/Apollo/8" } } @@ -55,8 +55,7 @@ local Apollo8LaunchModel = { LightSources = { sun.LightSource }, - PerformShading = true, - DisableFaceCulling = true + PerformShading = true }, GUI = { Hidden = true, diff --git a/data/assets/scene/solarsystem/missions/apollo/8/model.asset b/data/assets/scene/solarsystem/missions/apollo/8/model.asset index c7d134b7bf..493bc2b05f 100644 --- a/data/assets/scene/solarsystem/missions/apollo/8/model.asset +++ b/data/assets/scene/solarsystem/missions/apollo/8/model.asset @@ -42,7 +42,7 @@ local Apollo8 = { }, GUI = { Name = "Apollo 8", - Path = "/Solar System/Missions/Apollo" + Path = "/Solar System/Missions/Apollo/8" } } @@ -67,13 +67,12 @@ local Apollo8Model = { LightSources = { sun.LightSource }, - PerformShading = true, - DisableFaceCulling = true + PerformShading = true }, GUI = { Hidden = true, Name = "Apollo 8 Model", - Path = "/Solar System/Missions/Apollo" + Path = "/Solar System/Missions/Apollo/8" } } @@ -89,7 +88,7 @@ local Apollo8Pivot = { }, GUI = { Name = "Apollo 8 Pivot", - Path = "/Solar System/Missions/Apollo" + Path = "/Solar System/Missions/Apollo/8" } } diff --git a/data/assets/scene/solarsystem/missions/apollo/8/trails.asset b/data/assets/scene/solarsystem/missions/apollo/8/trails.asset index 6bc4398bef..d8d24ce58b 100644 --- a/data/assets/scene/solarsystem/missions/apollo/8/trails.asset +++ b/data/assets/scene/solarsystem/missions/apollo/8/trails.asset @@ -25,7 +25,7 @@ local LaunchTrail = { }, GUI = { Name = "Apollo 8 Launch Trail", - Path = "/Solar System/Missions/Apollo" + Path = "/Solar System/Missions/Apollo/8" } } @@ -49,7 +49,7 @@ local MoonTrail = { }, GUI = { Name = "Apollo 8 Moon Trail", - Path = "/Solar System/Missions/Apollo" + Path = "/Solar System/Missions/Apollo/8" } } @@ -73,7 +73,7 @@ local EarthBarycenterTrail = { }, GUI = { Name = "Apollo 8 Earth Barycenter Trail", - Path = "/Solar System/Missions/Apollo" + Path = "/Solar System/Missions/Apollo/8" } } diff --git a/data/assets/scene/solarsystem/missions/dawn/dawn.asset b/data/assets/scene/solarsystem/missions/dawn/dawn.asset index c805757412..42285429f4 100644 --- a/data/assets/scene/solarsystem/missions/dawn/dawn.asset +++ b/data/assets/scene/solarsystem/missions/dawn/dawn.asset @@ -1,7 +1,6 @@ local transforms = asset.require("scene/solarsystem/sun/transforms") local sun = asset.require("scene/solarsystem/sun/sun") - local kernels = asset.syncedResource({ Name = "Dawn Kernels", Type = "HttpSynchronization", @@ -20,7 +19,7 @@ local models = asset.syncedResource({ Name = "Dawn Models", Type = "HttpSynchronization", Identifier = "dawn_model", - Version = 1 + Version = 2 }) local KernelFiles = { @@ -75,8 +74,8 @@ local LightSources = { } } -local Dawn = { - Identifier = "Dawn", +local DawnPosition = { + Identifier = "DawnPosition", Parent = transforms.SolarSystemBarycenter.Identifier, Transform = { Translation = { @@ -85,6 +84,23 @@ local Dawn = { Observer = "SSB", Kernels = KernelFiles }, + -- Rotation for model version 2 + Rotation = { + Type = "StaticRotation", + Rotation = { math.pi/2.0, 0.0, math.pi/2.0 } + } + }, + GUI = { + Name = "Dawn Position", + Path = "/Solar System/Missions/Dawn", + Hidden = true + } +} + +local Dawn = { + Identifier = "Dawn", + Parent = DawnPosition.Identifier, + Transform = { Rotation = { Type = "SpiceRotation", SourceFrame = "DAWN_SPACECRAFT", @@ -94,67 +110,11 @@ local Dawn = { }, Renderable = { Type = "RenderableModel", - Body = "DAWN", - GeometryFile = models .. "mainbodydawn.obj", + GeometryFile = models .. "Dawn_19.glb", LightSources = LightSources }, GUI = { - Path = "/Solar System/Missions/Dawn" - } -} - --- Dawn Solar Array module 1 -local DawnSolarArray1 = { - Identifier = "DawnSolar1", - Parent = Dawn.Identifier, - Transform = { - -- JCC: Spice rotations are commented because spice ck files - -- are not present. - -- Rotation = { - -- Type = "SpiceRotation", - -- SourceFrame = "DAWN_SA-Y", - -- DestinationFrame = "DAWN_SPACECRAFT" - -- } - Rotation = { - Type = "StaticRotation", - Rotation = { 0.0, 4.71225, 0.0 } - } - }, - Renderable = { - Type = "RenderableModel", - Body = "DAWN", - GeometryFile = models .. "solarpanelleft.obj", - LightSources = LightSources - }, - GUI = { - Name = "Dawn Solar 1", - Path = "/Solar System/Missions/Dawn" - } -} - --- Dawn Solar Array module 2 -local DawnSolarArray2 = { - Identifier = "DawnSolar2", - Parent = Dawn.Identifier, - Transform = { - -- Rotation = { - -- Type = "SpiceRotation", - -- SourceFrame = "DAWN_SA+Y", - -- DestinationFrame = "DAWN_SPACECRAFT" - -- } - Rotation = { - Type = "StaticRotation", - Rotation = { math.pi, math.pi/2, 0.0 } - } - }, - Renderable = { - Type = "RenderableModel", - Body = "DAWN", - GeometryFile = models .. "solarpanelright.obj", - LightSources = LightSources - }, - GUI = { - Name = "Dawn Solar 2", + Name = "Dawn", Path = "/Solar System/Missions/Dawn" } } @@ -229,9 +189,8 @@ local DawnFramingCamera2 = { } local nodes = { + DawnPosition, Dawn, - DawnSolarArray1, - DawnSolarArray2, DawnTrail, DawnFramingCamera1, DawnFramingCamera2 @@ -256,7 +215,7 @@ end asset.meta = { Name = "Dawn", - Version = "1.0", + Version = "2.0", Description = "Dawn spacecraft and trail", Author = "OpenSpace Team", URL = "http://openspaceproject.com", diff --git a/data/assets/scene/solarsystem/missions/dawn/vesta.asset b/data/assets/scene/solarsystem/missions/dawn/vesta.asset index 57a1d68144..b70a62a4fa 100644 --- a/data/assets/scene/solarsystem/missions/dawn/vesta.asset +++ b/data/assets/scene/solarsystem/missions/dawn/vesta.asset @@ -48,10 +48,11 @@ local Vesta = { DestinationFrame = "GALACTIC" } }, + BoundingSphere = 262000, + InteractionSphere = 262000, Renderable = { Type = "RenderableModelProjection", GeometryFile = models .. "VestaComet_5000.obj", - BoundingSphereRadius = 262000, Projection = { Sequence = images, SequenceType = "image-sequence", @@ -152,7 +153,7 @@ asset.export(VestaTrail) asset.meta = { Name = "Vesta", - Version = "1.0", + Version = "1.1", Description = "Vesta model projection and trail", Author = "OpenSpace Team", URL = "http://openspaceproject.com", diff --git a/data/assets/scene/solarsystem/missions/jwst/jwst.asset b/data/assets/scene/solarsystem/missions/jwst/jwst.asset index 821929ee73..5cdff947e1 100644 --- a/data/assets/scene/solarsystem/missions/jwst/jwst.asset +++ b/data/assets/scene/solarsystem/missions/jwst/jwst.asset @@ -79,8 +79,7 @@ local JWSTModel = { LightSources = { sun.LightSource }, - PerformShading = true, - DisableFaceCulling = true + PerformShading = true }, GUI = { Name = "James Webb Space Telescope Model", diff --git a/data/assets/scene/solarsystem/missions/rosetta/67p.asset b/data/assets/scene/solarsystem/missions/rosetta/67p.asset index 93e86cae24..3ddae9990d 100644 --- a/data/assets/scene/solarsystem/missions/rosetta/67p.asset +++ b/data/assets/scene/solarsystem/missions/rosetta/67p.asset @@ -47,63 +47,62 @@ local Comet67P = { Identifier = "67P", Parent = Barycenter.Identifier, Transform = { - Rotation = { - Type = "SpiceRotation", - SourceFrame = "67P/C-G_CK", - DestinationFrame = "GALACTIC" - } + Rotation = { + Type = "SpiceRotation", + SourceFrame = "67P/C-G_CK", + DestinationFrame = "GALACTIC" + } }, + BoundingSphere = 5000.0, Renderable = { - Type = "RenderableModelProjection", - GeometryFile = models .. "67P_rotated_5_130.obj", - Projection = { - Sequence = { imagesDestination }, - SequenceType = "image-sequence", - Observer = "ROSETTA", - Target = "CHURYUMOV-GERASIMENKO", - Aberration = "NONE", - TextureMap = true, - ShadowMap = true, + Type = "RenderableModelProjection", + GeometryFile = models .. "67P_rotated_5_130.obj", + Projection = { + Sequence = { imagesDestination }, + SequenceType = "image-sequence", + Observer = "ROSETTA", + Target = "CHURYUMOV-GERASIMENKO", + Aberration = "NONE", + TextureMap = true, + ShadowMap = true, - DataInputTranslation = { - Instrument = { - NAVCAM = { - DetectorType = "Camera", - Spice = { "ROS_NAVCAM-A" } - } - }, - Target = { - Read = { - "TARGET_NAME", - "INSTRUMENT_HOST_NAME", - "INSTRUMENT_ID", - "START_TIME", - "STOP_TIME" - }, - Convert = { - CHURYUMOV = { "CHURYUMOV-GERASIMENKO" }, - ROSETTA = { "ROSETTA" }, - ["ROSETTA-ORBITER"] = { "ROSETTA" }, - CHURYUMOVGERASIMENKO11969R1 = { "CHURYUMOV-GERASIMENKO" }, - CHURYUMOVGERASIMENKO = { "CHURYUMOV-GERASIMENKO" }, - ["CHURYUMOV-GERASIMENKO1(1969R1)"] = { "CHURYUMOV-GERASIMENKO" }, - CALIBRATION = { "CALIBRATION" }, - ALPHALYR = { "ALPHALYR" }, - ZETACAS = { "ZETACAS" } - } + DataInputTranslation = { + Instrument = { + NAVCAM = { + DetectorType = "Camera", + Spice = { "ROS_NAVCAM-A" } } }, - - Instrument = { - Name = "ROS_NAVCAM-A", - Method = "ELLIPSOID", - Aberration = "NONE", - Fovy = 5.00, - Aspect = 1 + Target = { + Read = { + "TARGET_NAME", + "INSTRUMENT_HOST_NAME", + "INSTRUMENT_ID", + "START_TIME", + "STOP_TIME" + }, + Convert = { + CHURYUMOV = { "CHURYUMOV-GERASIMENKO" }, + ROSETTA = { "ROSETTA" }, + ["ROSETTA-ORBITER"] = { "ROSETTA" }, + CHURYUMOVGERASIMENKO11969R1 = { "CHURYUMOV-GERASIMENKO" }, + CHURYUMOVGERASIMENKO = { "CHURYUMOV-GERASIMENKO" }, + ["CHURYUMOV-GERASIMENKO1(1969R1)"] = { "CHURYUMOV-GERASIMENKO" }, + CALIBRATION = { "CALIBRATION" }, + ALPHALYR = { "ALPHALYR" }, + ZETACAS = { "ZETACAS" } + } } - }, + }, - BoundingSphereRadius = 5000.0 + Instrument = { + Name = "ROS_NAVCAM-A", + Method = "ELLIPSOID", + Aberration = "NONE", + Fovy = 5.00, + Aspect = 1 + } + }, }, GUI = { Name = "67P Churymov-Gerasimenko", @@ -191,6 +190,6 @@ end) asset.export("Barycenter", Barycenter) -- @TODO: This double export should disappear asset.export(Barycenter) -asset.export("Comet67P", Comet67P) -- @TODO: This double export should disappear +asset.export("Comet67P", Comet67P) -- @TODO: This double export should disappear asset.export(Comet67P) asset.export(Trail67P) diff --git a/data/assets/scene/solarsystem/missions/rosetta/rosetta.asset b/data/assets/scene/solarsystem/missions/rosetta/rosetta.asset index 69c258e62b..53e2acaa4e 100644 --- a/data/assets/scene/solarsystem/missions/rosetta/rosetta.asset +++ b/data/assets/scene/solarsystem/missions/rosetta/rosetta.asset @@ -6,7 +6,7 @@ local models = asset.syncedResource({ Name = "Rosetta Models", Type = "HttpSynchronization", Identifier = "rosetta_model", - Version = 4 + Version = 5 }) local kernels = asset.syncedResource({ @@ -71,8 +71,8 @@ local RotationMatrix = { 1, 0, 0 } -local Rosetta = { - Identifier = "Rosetta", +local RosettaPosition = { + Identifier = "RosettaPosition", Parent = sunTransforms.SolarSystemBarycenter.Identifier, Transform = { Translation = { @@ -88,33 +88,24 @@ local Rosetta = { } }, GUI = { - Path = "/Solar System/Missions/Rosetta" + Name = "Rosetta Position", + Path = "/Solar System/Missions/Rosetta", + Hidden = true } } -local RosettaModel = { - Identifier = "RosettaModel", - Parent = Rosetta.Identifier, +local Rosetta = { + Identifier = "Rosetta", + Parent = RosettaPosition.Identifier, Transform = { - Scale = { - Type = "StaticScale", - -- The scale of the model is in cm; OpenSpace is in m - Scale = 0.01 + Rotation = { + Type = "StaticRotation", + Rotation = { 0.0, math.pi/2.0, 0.0 } } }, - GUI = { - Name = "Rosetta Model", - Path = "/Solar System/Missions/Rosetta" - } -} - -local RosettaBlackFoil = { - Identifier = "Rosetta_black_foil", - Parent = RosettaModel.Identifier, Renderable = { Type = "RenderableModel", - Body = "ROSETTA", - GeometryFile = models .. "black_foil.obj", + GeometryFile = models .. "rosetta.glb", ModelTransform = RotationMatrix, LightSources = { sun.LightSource, @@ -126,200 +117,15 @@ local RosettaBlackFoil = { } }, GUI = { - Name = "Rosetta Model Part Black Foil", + Name = "Rosetta", Path = "/Solar System/Missions/Rosetta" } } -local RosettaBlackParts = { - Identifier = "Rosetta_black_parts", - Parent = RosettaModel.Identifier, - Renderable = { - Type = "RenderableModel", - Body = "ROSETTA", - GeometryFile = models .. "black_parts.obj", - ModelTransform = RotationMatrix, - LightSources = { - sun.LightSource, - { - Identifier = "Camera", - Type = "CameraLightSource", - Intensity = 0.5 - } - } - }, - GUI = { - Name = "Rosetta Model Part Black Parts", - Path = "/Solar System/Missions/Rosetta" - } -} - -local RosettaDish = { - Identifier = "Rosetta_dish", - Parent = RosettaModel.Identifier, - Renderable = { - Type = "RenderableModel", - Body = "ROSETTA", - GeometryFile = models .. "dish.obj", - ModelTransform = RotationMatrix, - LightSources = { - sun.LightSource, - { - Identifier = "Camera", - Type = "CameraLightSource", - Intensity = 0.5 - } - } - }, - GUI = { - Name = "Rosetta Model Part Dish", - Path = "/Solar System/Missions/Rosetta" - } -} - -local RosettaParts = { - Identifier = "Rosetta_parts", - Parent = RosettaModel.Identifier, - Renderable = { - Type = "RenderableModel", - Body = "ROSETTA", - GeometryFile = models .. "parts.obj", - ModelTransform = RotationMatrix, - LightSources = { - sun.LightSource, - { - Identifier = "Camera", - Type = "CameraLightSource", - Intensity = 0.5 - } - } - }, - GUI = { - Name = "Rosetta Model Part Parts", - Path = "/Solar System/Missions/Rosetta" - } -} - -local RosettaSilverFoil = { - Identifier = "Rosetta_silver_foil", - Parent = RosettaModel.Identifier, - Renderable = { - Type = "RenderableModel", - Body = "ROSETTA", - GeometryFile = models .. "silver_foil.obj", - ModelTransform = RotationMatrix, - LightSources = { - sun.LightSource, - { - Identifier = "Camera", - Type = "CameraLightSource", - Intensity = 0.5 - } - } - }, - GUI = { - Name = "Rosetta Model Part Silver Foil", - Path = "/Solar System/Missions/Rosetta" - } -} - -local RosettaVents = { - Identifier = "Rosetta_vents", - Parent = RosettaModel.Identifier, - Renderable = { - Type = "RenderableModel", - Body = "ROSETTA", - GeometryFile = models .. "vents.obj", - ModelTransform = RotationMatrix, - LightSources = { - sun.LightSource, - { - Identifier = "Camera", - Type = "CameraLightSource", - Intensity = 0.5 - } - } - }, - GUI = { - Name = "Rosetta Model Part Vents", - Path = "/Solar System/Missions/Rosetta" - } -} - -local RosettaWingA = { - Identifier = "Rosetta_wing_a", - Parent = RosettaModel.Identifier, - Renderable = { - Type = "RenderableModel", - Body = "ROSETTA", - GeometryFile = models .."wingA.obj", - ModelTransform = RotationMatrix, - LightSources = { - sun.LightSource, - { - Identifier = "Camera", - Type = "CameraLightSource", - Intensity = 0.5 - } - } - }, - GUI = { - Name = "Rosetta Model Part Wing A", - Path = "/Solar System/Missions/Rosetta" - } -} - -local RosettaWingB = { - Identifier = "Rosetta_wing_b", - Parent = RosettaModel.Identifier, - Renderable = { - Type = "RenderableModel", - Body = "ROSETTA", - GeometryFile = models .. "wingB.obj", - ModelTransform = RotationMatrix, - LightSources = { - sun.LightSource, - { - Identifier = "Camera", - Type = "CameraLightSource", - Intensity = 0.5 - } - } - }, - GUI = { - Name = "Rosetta Model Part Wing B", - Path = "/Solar System/Missions/Rosetta" - } -} - -local RosettaYellowFoil = { - Identifier = "Rosetta_yellow_foil", - Parent = RosettaModel.Identifier, - Renderable = { - Type = "RenderableModel", - Body = "ROSETTA", - GeometryFile = models .. "yellow_foil.obj", - ModelTransform = RotationMatrix, - LightSources = { - sun.LightSource, - { - Identifier = "Camera", - Type = "CameraLightSource", - Intensity = 0.5 - } - } - }, - GUI = { - Name = "Rosetta Model Part Yellow Foil", - Path = "/Solar System/Missions/Rosetta" - } -} - -local Philae = { - Identifier = "Philae", +local PhilaePosition = { + Identifier = "PhilaePosition", Parent = transforms.Barycenter.Identifier, - -- This should need a transform, but currently the model is intrinsically - -- translated + -- This should need a transform, but currently the model containes it instead Transform = { Translation = { Type = "SpiceTranslation", @@ -331,26 +137,27 @@ local Philae = { Type = "SpiceRotation", SourceFrame = "ROS_SPACECRAFT", DestinationFrame = "GALACTIC", - }, - Scale = { - Type = "StaticScale", - -- The scale of the model is in cm; OpenSpace is in m - Scale = 0.01 } }, GUI = { - Name = "Philae Model", - Path = "/Solar System/Missions/Rosetta" + Name = "Philae Position", + Path = "/Solar System/Missions/Rosetta", + Hidden = true } } -local PhilaeFoil = { - Identifier = "Philae_foil", - Parent = Philae.Identifier, +local Philae = { + Identifier = "Philae", + Parent = PhilaePosition.Identifier, + Transform = { + Rotation = { + Type = "StaticRotation", + Rotation = { 0.0, math.pi/2.0, 0.0 } + } + }, Renderable = { Type = "RenderableModel", - Body = "ROSETTA", - GeometryFile = models .. "lander_foil.obj", + GeometryFile = models .. "lander.glb", ModelTransform = RotationMatrix, LightSources = { sun.LightSource, @@ -362,83 +169,14 @@ local PhilaeFoil = { } }, GUI = { - Name = "Philae Model Part Foil", - Path = "/Solar System/Missions/Rosetta" - } -} - -local PhilaeLids = { - Identifier = "Philae_lids", - Parent = Philae.Identifier, - Renderable = { - Type = "RenderableModel", - Body = "ROSETTA", - GeometryFile = models .. "lander_lids.obj", - ModelTransform = RotationMatrix, - LightSources = { - sun.LightSource, - { - Identifier = "Camera", - Type = "CameraLightSource", - Intensity = 0.5 - } - } - }, - GUI = { - Name = "Philae Model Part Lids", - Path = "/Solar System/Missions/Rosetta" - } -} - -local PhilaeParts = { - Identifier = "Philae_parts", - Parent = Philae.Identifier, - Renderable = { - Type = "RenderableModel", - Body = "ROSETTA", - GeometryFile = models .. "lander_parts.obj", - ModelTransform = RotationMatrix, - LightSources = { - sun.LightSource, - { - Identifier = "Camera", - Type = "CameraLightSource", - Intensity = 0.5 - } - } - }, - GUI = { - Name = "Philae Model Part Parts", - Path = "/Solar System/Missions/Rosetta" - } -} - -local PhilaeSolarPanels = { - Identifier = "Philae_solarp", - Parent = Philae.Identifier, - Renderable = { - Type = "RenderableModel", - Body = "ROSETTA", - GeometryFile = models .. "lander_solarp.obj", - ModelTransform = RotationMatrix, - LightSources = { - sun.LightSource, - { - Identifier = "Camera", - Type = "CameraLightSource", - Intensity = 0.5 - } - } - }, - GUI = { - Name = "Philae Model Parts Solar Panels", + Name = "Philae", Path = "/Solar System/Missions/Rosetta" } } local NavCam = { Identifier = "NAVCAM", - Parent = Rosetta.Identifier, + Parent = RosettaPosition.Identifier, GUI = { Path = "/Solar System/Missions/Rosetta/Instruments" } @@ -529,28 +267,16 @@ local PhilaeTrail = { } local nodes = { + RosettaPosition, Rosetta, - RosettaModel, - RosettaBlackFoil, - RosettaBlackParts, - RosettaDish, - RosettaParts, - RosettaSilverFoil, - RosettaVents, - RosettaWingA, - RosettaWingB, - RosettaYellowFoil, + + PhilaePosition, + Philae, NavCam, NavCamFov, ImagePlane, - Philae, - PhilaeFoil, - PhilaeLids, - PhilaeParts, - PhilaeSolarPanels, - RosettaCometTrail, PhilaeTrail } diff --git a/data/assets/scene/solarsystem/planets/earth/satellites/misc/iss.asset b/data/assets/scene/solarsystem/planets/earth/satellites/misc/iss.asset index ac51bb3388..b257dc2599 100644 --- a/data/assets/scene/solarsystem/planets/earth/satellites/misc/iss.asset +++ b/data/assets/scene/solarsystem/planets/earth/satellites/misc/iss.asset @@ -17,8 +17,8 @@ local omm = asset.syncedResource({ Override = true }) -local iss = { - Identifier = "ISS", +local issPosition = { + Identifier = "ISSPosition", Parent = transforms.EarthInertial.Identifier, BoundingSphere = 54.5, -- half the width Transform = { @@ -36,18 +36,19 @@ local iss = { }, Tag = { "earth_satellite", "ISS" }, GUI = { - Name = "ISS", - Path = "/Solar System/Planets/Earth/Satellites/ISS" + Name = "ISS Position", + Path = "/Solar System/Planets/Earth/Satellites/ISS", + Hidden = true } } -local parentNode = { - Identifier = "ISSModel", - Parent = iss.Identifier, +local issModel = { + Identifier = "ISS", + Parent = issPosition.Identifier, Transform = { Rotation = { Type = "FixedRotation", - Attached = "ISSModel", + Attached = "ISS", XAxis = { 0.01, -1.0, 0.56 }, XAxisOrthogonal = true, YAxis = transforms.EarthInertial.Identifier @@ -60,11 +61,11 @@ local parentNode = { LightSources = { sun.LightSource }, - PerformShading = true, - DisableFaceCulling = true + PerformShading = true }, + Tag = { "earth_satellite", "ISS" }, GUI = { - Name = "ISS Model", + Name = "ISS", Path = "/Solar System/Planets/Earth/Satellites/ISS" } } @@ -95,7 +96,7 @@ local issTrail = { -- @TODO (emmbr, 2021-05-27) add to scene when label rendering issues have been fixed local IssLabel = { Identifier = "IssLabel", - Parent = iss.Identifier, + Parent = issPosition.Identifier, Renderable = { Enabled = false, Type = "RenderableLabel", @@ -133,11 +134,11 @@ asset.onInitialize(function () local i = openspace.space.readKeplerFile(omm .. "ISS.txt", "OMM") issTrail.Renderable.Period = i[1].Period / (60 * 60 * 24) - openspace.addSceneGraphNode(iss) - openspace.addSceneGraphNode(parentNode) - openspace.setPropertyValueSingle("Scene.ISSModel.Rotation.yAxisInvertObject", true) + openspace.addSceneGraphNode(issPosition) + openspace.addSceneGraphNode(issModel) openspace.addSceneGraphNode(issTrail) + openspace.setPropertyValueSingle("Scene.ISS.Rotation.yAxisInvertObject", true) openspace.action.registerAction(focus_iss) end) @@ -145,20 +146,19 @@ asset.onDeinitialize(function () openspace.action.removeAction(focus_iss) openspace.removeSceneGraphNode(issTrail) - openspace.removeSceneGraphNode(parentNode) - openspace.removeSceneGraphNode(iss) + openspace.removeSceneGraphNode(issModel) + openspace.removeSceneGraphNode(issPosition) end) asset.export(issTrail) -asset.export(parentNode) -asset.export(iss) - +asset.export(issModel) +asset.export(issPosition) asset.meta = { Name = "ISS", - Version = "1.1", + Version = "2.0", Description = [[Model and Trail for ISS. Model from NASA 3D models, trail from - Celestrak]], + Celestrak.]], Author = "OpenSpace Team", URL = "https://celestrak.com/", License = "NASA" diff --git a/data/assets/scene/solarsystem/planets/mars/moons/deimos.asset b/data/assets/scene/solarsystem/planets/mars/moons/deimos.asset index 7ef7f8f2ac..f47cf5f5cc 100644 --- a/data/assets/scene/solarsystem/planets/mars/moons/deimos.asset +++ b/data/assets/scene/solarsystem/planets/mars/moons/deimos.asset @@ -44,8 +44,7 @@ local Deimos = { LightSources = { sun.LightSource }, - PerformShading = true, - DisableFaceCulling = true + PerformShading = true }, Tag = { "moon_solarSystem", "moon_terrestrial", "moon_mars" }, GUI = { diff --git a/data/assets/scene/solarsystem/planets/mars/moons/phobos.asset b/data/assets/scene/solarsystem/planets/mars/moons/phobos.asset index 4189cc20ee..bf318c1dd2 100644 --- a/data/assets/scene/solarsystem/planets/mars/moons/phobos.asset +++ b/data/assets/scene/solarsystem/planets/mars/moons/phobos.asset @@ -45,8 +45,7 @@ local Phobos = { LightSources = { sun.LightSource }, - PerformShading = true, - DisableFaceCulling = true + PerformShading = true }, Tag = { "moon_solarSystem", "moon_terrestrial", "moon_mars" }, GUI = { diff --git a/data/assets/scene/solarsystem/sssb/itokawa.asset b/data/assets/scene/solarsystem/sssb/itokawa.asset index e53c6466b1..3a652206d5 100644 --- a/data/assets/scene/solarsystem/sssb/itokawa.asset +++ b/data/assets/scene/solarsystem/sssb/itokawa.asset @@ -68,7 +68,6 @@ local ItokawaModel = { sun.LightSource }, PerformShading = true, - DisableFaceCulling = true, SpecularIntensity = 0.0 }, GUI = { diff --git a/data/assets/util/asset_helper.asset b/data/assets/util/asset_helper.asset index 07b229d7e1..70b0b882a4 100644 --- a/data/assets/util/asset_helper.asset +++ b/data/assets/util/asset_helper.asset @@ -170,7 +170,7 @@ local createModelPart = function (parent, sunLightSourceNode, models, geometry, GeometryFile = models .. "/" .. geometry .. ".obj", LightSources = lightSources, PerformShading = performShading, - DisableFaceCulling = true + EnableFaceCulling = true }, GUI = { Hidden = true diff --git a/ext/ghoul b/ext/ghoul index 14fc8c5487..eb435c3bb9 160000 --- a/ext/ghoul +++ b/ext/ghoul @@ -1 +1 @@ -Subproject commit 14fc8c5487891a1c2bf4e95698f8c306492cb7a1 +Subproject commit eb435c3bb9847320cd59d3ee978132ee171b7fb9 diff --git a/include/openspace/rendering/framebufferrenderer.h b/include/openspace/rendering/framebufferrenderer.h index 3bc3dea272..a9701e8a8e 100644 --- a/include/openspace/rendering/framebufferrenderer.h +++ b/include/openspace/rendering/framebufferrenderer.h @@ -59,6 +59,89 @@ class FramebufferRenderer final : public RaycasterListener, public Deferredcaste public: virtual ~FramebufferRenderer() override = default; + //============================// + //===== Reuse textures =====// + //============================// + /** + * Gives access to the currently NOT used pingPongTexture. This texture is available + * for all RenderBins. However, it cannot be used at the same time as the Deferred + * Caster Tasks. The size of the texture is the resolution of the viewport. + * + * NOTE (malej 2023-FEB-21): The currently NOT used pingPongTexture might change + * depending on where in the render cycle you are. Especially after the Deferred + * Caster Tasks. + * + * \return identifier of the currently NOT used pingPongTexture + */ + GLuint additionalColorTexture1() const; + + /** + * Gives access to the exitColorTexture. This texture is available for all RenderBins. + * However, it cannot be used at the same time as the Raycaster Tasks. The size of the + * texture is the resolution of the viewport. + * + * \return identifier of the exitColorTexture + */ + GLuint additionalColorTexture2() const; + + /** + * Gives access to the fxaaTexture. This texture is available for all RenderBins. + * However, it cannot be used at the same time as the FXAA Task. The size of the + * texture is the resolution of the viewport. + * + * \return identifier of the fxaaTexture + */ + GLuint additionalColorTexture3() const; + + /** + * Gives access to the exitDepthTexture. This texture is available for all RenderBins. + * However, it cannot be used at the same time as the Raycaster Tasks. The size of the + * texture is the resolution of the viewport. + * + * \return identifier of the exitDepthTexture + */ + GLuint additionalDepthTexture() const; + + //=============================// + //===== Access G-buffer =====// + //=============================// + // Functions to access the G-buffer textures + /** + * Gives access to the color texture of the G-buffer. NOTE: This texture is used for + * the majority of rendering the scene and might be already in use. Use CAUTION when + * using this function. The size of the texture is the resolution of the viewport. + * + * \return identifier of the color texture of the G-buffer + */ + GLuint gBufferColorTexture() const; + + /** + * Gives access to the position texture of the G-buffer. NOTE: This texture is used for + * the majority of rendering the scene and might be already in use. Use CAUTION when + * using this function. The size of the texture is the resolution of the viewport. + * + * \return identifier of the position texture of the G-buffer + */ + GLuint gBufferPositionTexture() const; + + /** + * Gives access to the normal texture of the G-buffer. NOTE: This texture is used for + * the majority of rendering the scene and might be already in use. Use CAUTION when + * using this function. The size of the texture is the resolution of the viewport. + * + * \return identifier of the normal texture of the G-buffer + */ + GLuint gBufferNormalTexture() const; + + /** + * Gives access to the depth texture of the G-buffer. NOTE: This texture is used for + * the majority of rendering the scene and might be already in use. Use CAUTION when + * using this function. The size of the texture is the resolution of the viewport. + * + * \return identifier of the depth texture of the G-buffer + */ + GLuint gBufferDepthTexture() const; + void initialize(); void deinitialize(); @@ -154,11 +237,6 @@ private: GLuint colorTexture[2]; } _pingPongBuffers; - struct { - GLuint hdrFilteringFramebuffer; - GLuint hdrFilteringTexture; - } _hdrBuffers; - struct { GLuint fxaaFramebuffer; GLuint fxaaTexture; diff --git a/include/openspace/rendering/renderable.h b/include/openspace/rendering/renderable.h index 4c1d61fa1c..fd1e45db08 100644 --- a/include/openspace/rendering/renderable.h +++ b/include/openspace/rendering/renderable.h @@ -66,8 +66,9 @@ public: Background = 1, Opaque = 2, PreDeferredTransparent = 4, - PostDeferredTransparent = 8, - Overlay = 16 + Overlay = 8, + PostDeferredTransparent = 16, + Sticker = 32 }; static ghoul::mm_unique_ptr createFromDictionary( @@ -133,6 +134,7 @@ protected: SceneGraphNode* parent() const noexcept; bool automaticallyUpdatesRenderBin() const noexcept; + bool hasOverrideRenderBin() const noexcept; RenderBin _renderBin = RenderBin::Opaque; @@ -148,6 +150,7 @@ private: SceneGraphNode* _parent = nullptr; const bool _shouldUpdateIfDisabled = false; bool _automaticallyUpdateRenderBin = true; + bool _hasOverrideRenderBin = false; // We only want the SceneGraphNode to be able manipulate the parent, so we don't want // to provide a set method for this. Otherwise, anyone might mess around with our diff --git a/include/openspace/rendering/renderengine.h b/include/openspace/rendering/renderengine.h index 068403a34b..4a298becb6 100644 --- a/include/openspace/rendering/renderengine.h +++ b/include/openspace/rendering/renderengine.h @@ -68,6 +68,8 @@ public: RenderEngine(); virtual ~RenderEngine() override; + const FramebufferRenderer& renderer() const; + void initialize(); void initializeGL(); void deinitializeGL(); diff --git a/modules/base/rendering/renderablemodel.cpp b/modules/base/rendering/renderablemodel.cpp index d44a3bbdb5..c90f7ffbaf 100644 --- a/modules/base/rendering/renderablemodel.cpp +++ b/modules/base/rendering/renderablemodel.cpp @@ -28,7 +28,10 @@ #include #include #include +#include +#include #include +#include #include #include #include @@ -39,8 +42,10 @@ #include #include #include +#include #include #include +#include #include #include @@ -62,11 +67,22 @@ namespace { { "Color Adding", ColorAddingBlending } }; - constexpr std::array UniformNames = { - "opacity", "nLightSources", "lightDirectionsViewSpace", "lightIntensities", + const GLenum ColorAttachmentArray[3] = { + GL_COLOR_ATTACHMENT0, + GL_COLOR_ATTACHMENT1, + GL_COLOR_ATTACHMENT2, + }; + + constexpr std::array UniformNames = { + "nLightSources", "lightDirectionsViewSpace", "lightIntensities", "modelViewTransform", "normalTransform", "projectionTransform", "performShading", "ambientIntensity", "diffuseIntensity", - "specularIntensity", "opacityBlending" + "specularIntensity", "performManualDepthTest", "gBufferDepthTexture", + "resolution", "opacity" + }; + + constexpr std::array UniformOpacityNames = { + "opacity", "colorTexture", "depthTexture", "viewport", "resolution" }; constexpr openspace::properties::Property::PropertyInfo EnableAnimationInfo = { @@ -100,10 +116,10 @@ namespace { "of the Sun" }; - constexpr openspace::properties::Property::PropertyInfo DisableFaceCullingInfo = { - "DisableFaceCulling", - "Disable Face Culling", - "Disable OpenGL automatic face culling optimization" + constexpr openspace::properties::Property::PropertyInfo EnableFaceCullingInfo = { + "EnableFaceCulling", + "Enable Face Culling", + "Enable OpenGL automatic face culling optimization" }; constexpr openspace::properties::Property::PropertyInfo ModelTransformInfo = { @@ -125,10 +141,10 @@ namespace { "A list of light sources that this model should accept light from" }; - constexpr openspace::properties::Property::PropertyInfo DisableDepthTestInfo = { - "DisableDepthTest", - "Disable Depth Test", - "Disable Depth Testing for the Model" + constexpr openspace::properties::Property::PropertyInfo EnableDepthTestInfo = { + "EnableDepthTest", + "Enable Depth Test", + "Enable Depth Testing for the Model" }; constexpr openspace::properties::Property::PropertyInfo BlendingOptionInfo = { @@ -138,12 +154,6 @@ namespace { "respect to the opacity" }; - constexpr openspace::properties::Property::PropertyInfo EnableOpacityBlendingInfo = { - "EnableOpacityBlending", - "Enable Opacity Blending", - "Enable Opacity Blending" - }; - struct [[codegen::Dictionary(RenderableModel)]] Parameters { // The file or files that should be loaded in this RenderableModel. The file can // contain filesystem tokens. This specifies the model that is rendered by @@ -158,8 +168,6 @@ namespace { Decimeter, Meter, Kilometer, - - // Weird units Thou, Inch, Foot, @@ -228,8 +236,8 @@ namespace { // [[codegen::verbatim(ShadingInfo.description)]] std::optional performShading; - // [[codegen::verbatim(DisableFaceCullingInfo.description)]] - std::optional disableFaceCulling; + // [[codegen::verbatim(EnableFaceCullingInfo.description)]] + std::optional enableFaceCulling; // [[codegen::verbatim(ModelTransformInfo.description)]] std::optional modelTransform; @@ -241,15 +249,12 @@ namespace { std::optional> lightSources [[codegen::reference("core_light_source")]]; - // [[codegen::verbatim(DisableDepthTestInfo.description)]] - std::optional disableDepthTest; + // [[codegen::verbatim(EnableDepthTestInfo.description)]] + std::optional enableDepthTest; // [[codegen::verbatim(BlendingOptionInfo.description)]] std::optional blendingOption; - // [[codegen::verbatim(EnableOpacityBlendingInfo.description)]] - std::optional enableOpacityBlending; - // The path to the vertex shader program that is used instead of the default // shader. std::optional vertexShader; @@ -268,13 +273,13 @@ documentation::Documentation RenderableModel::Documentation() { } RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary) - : Renderable(dictionary) + : Renderable(dictionary, { .automaticallyUpdateRenderBin = false }) , _enableAnimation(EnableAnimationInfo, false) , _ambientIntensity(AmbientIntensityInfo, 0.2f, 0.f, 1.f) , _diffuseIntensity(DiffuseIntensityInfo, 1.f, 0.f, 1.f) , _specularIntensity(SpecularIntensityInfo, 1.f, 0.f, 1.f) , _performShading(ShadingInfo, true) - , _disableFaceCulling(DisableFaceCullingInfo, false) + , _enableFaceCulling(EnableFaceCullingInfo, true) , _modelTransform( ModelTransformInfo, glm::dmat3(1.0), @@ -282,8 +287,7 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary) glm::dmat3(1.0) ) , _rotationVec(RotationVecInfo, glm::dvec3(0.0), glm::dvec3(0.0), glm::dvec3(360.0)) - , _disableDepthTest(DisableDepthTestInfo, false) - , _enableOpacityBlending(EnableOpacityBlendingInfo, false) + , _enableDepthTest(EnableDepthTestInfo, true) , _blendingFuncOption( BlendingOptionInfo, properties::OptionProperty::DisplayType::Dropdown @@ -410,8 +414,8 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary) _diffuseIntensity = p.diffuseIntensity.value_or(_diffuseIntensity); _specularIntensity = p.specularIntensity.value_or(_specularIntensity); _performShading = p.performShading.value_or(_performShading); - _disableDepthTest = p.disableDepthTest.value_or(_disableDepthTest); - _disableFaceCulling = p.disableFaceCulling.value_or(_disableFaceCulling); + _enableDepthTest = p.enableDepthTest.value_or(_enableDepthTest); + _enableFaceCulling = p.enableFaceCulling.value_or(_enableFaceCulling); if (p.vertexShader.has_value()) { _vertexShaderPath = p.vertexShader->string(); @@ -440,8 +444,8 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary) addProperty(_diffuseIntensity); addProperty(_specularIntensity); addProperty(_performShading); - addProperty(_disableFaceCulling); - addProperty(_disableDepthTest); + addProperty(_enableFaceCulling); + addProperty(_enableDepthTest); addProperty(_modelTransform); addProperty(_rotationVec); @@ -468,7 +472,6 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary) _blendingFuncOption.addOption(DefaultBlending, "Default"); _blendingFuncOption.addOption(AdditiveBlending, "Additive"); - _blendingFuncOption.addOption(PointsAndLinesBlending, "Points and Lines"); _blendingFuncOption.addOption(PolygonBlending, "Polygon"); _blendingFuncOption.addOption(ColorAddingBlending, "Color Adding"); @@ -479,13 +482,11 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary) _blendingFuncOption.set(BlendingMapping[blendingOpt]); } - _enableOpacityBlending = p.enableOpacityBlending.value_or(_enableOpacityBlending); - - addProperty(_enableOpacityBlending); + _originalRenderBin = renderBin(); } bool RenderableModel::isReady() const { - return _program; + return _program && _quadProgram; } void RenderableModel::initialize() { @@ -538,14 +539,112 @@ void RenderableModel::initializeGL() { ghoul::opengl::updateUniformLocations(*_program, _uniformCache, UniformNames); + _quadProgram = BaseModule::ProgramObjectManager.request( + "ModelOpacityProgram", + [&]() -> std::unique_ptr { + std::filesystem::path vs = + absPath("${MODULE_BASE}/shaders/modelOpacity_vs.glsl"); + std::filesystem::path fs = + absPath("${MODULE_BASE}/shaders/modelOpacity_fs.glsl"); + + return global::renderEngine->buildRenderProgram("ModelOpacityProgram", vs, fs); + } + ); + ghoul::opengl::updateUniformLocations( + *_quadProgram, + _uniformOpacityCache, + UniformOpacityNames + ); + + // Screen quad VAO + const GLfloat quadVertices[] = { + // x y s t + -1.f, -1.f, 0.f, 0.f, + 1.f, 1.f, 1.f, 1.f, + -1.f, 1.f, 0.f, 1.f, + -1.f, -1.f, 0.f, 0.f, + 1.f, -1.f, 1.f, 0.f, + 1.f, 1.f, 1.f, 1.f + }; + + glGenVertexArrays(1, &_quadVao); + glBindVertexArray(_quadVao); + + glGenBuffers(1, &_quadVbo); + glBindBuffer(GL_ARRAY_BUFFER, _quadVbo); + + glBufferData(GL_ARRAY_BUFFER, sizeof(quadVertices), &quadVertices, GL_STATIC_DRAW); + glEnableVertexAttribArray(0); + glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 4 * sizeof(GLfloat), nullptr); + glEnableVertexAttribArray(1); + glVertexAttribPointer( + 1, + 2, + GL_FLOAT, + GL_FALSE, + 4 * sizeof(GLfloat), + reinterpret_cast(2 * sizeof(GLfloat)) + ); + + // Generate textures and the frame buffer + glGenFramebuffers(1, &_framebuffer); + + // Bind textures to the framebuffer + glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer); + glFramebufferTexture( + GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + global::renderEngine->renderer().additionalColorTexture1(), + 0 + ); + glFramebufferTexture( + GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT1, + global::renderEngine->renderer().additionalColorTexture2(), + 0 + ); + glFramebufferTexture( + GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT2, + global::renderEngine->renderer().additionalColorTexture3(), + 0 + ); + glFramebufferTexture( + GL_FRAMEBUFFER, + GL_DEPTH_ATTACHMENT, + global::renderEngine->renderer().additionalDepthTexture(), + 0 + ); + + if (glbinding::Binding::ObjectLabel.isResolved()) { + glObjectLabel(GL_FRAMEBUFFER, _framebuffer, -1, "RenderableModel Framebuffer"); + } + + // Check status + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) { + LERROR("Framebuffer is not complete"); + } + glBindFramebuffer(GL_FRAMEBUFFER, 0); + + // Initialize geometry _geometry->initialize(); _geometry->calculateBoundingRadius(); + setBoundingSphere(_geometry->boundingRadius() * _modelScale); + + // Set Interaction sphere size to be 10% of the bounding sphere + setInteractionSphere(boundingSphere() * 0.1); } void RenderableModel::deinitializeGL() { _geometry->deinitialize(); _geometry.reset(); + glDeleteFramebuffers(1, &_framebuffer); + + glDeleteBuffers(1, &_quadVbo); + glDeleteVertexArrays(1, &_quadVao); + std::string program = std::string(ProgramName); if (!_vertexShaderPath.empty()) { program += "|vs=" + _vertexShaderPath; @@ -559,7 +658,17 @@ void RenderableModel::deinitializeGL() { global::renderEngine->removeRenderProgram(p); } ); + + BaseModule::ProgramObjectManager.release( + "ModelOpacityProgram", + [](ghoul::opengl::ProgramObject* p) { + global::renderEngine->removeRenderProgram(p); + } + ); + _program = nullptr; + _quadProgram = nullptr; + ghoul::opengl::FramebufferObject::deactivate(); } void RenderableModel::render(const RenderData& data, RendererTasks&) { @@ -573,110 +682,241 @@ void RenderableModel::render(const RenderData& data, RendererTasks&) { // Formula from RenderableGlobe constexpr double tfov = 0.5773502691896257; constexpr int res = 2880; - const double maxDistance = res * boundingSphere() / tfov; - if (distanceToCamera < maxDistance) { - _program->activate(); + // @TODO (malej 13-APR-23): This should only use the boundingSphere function once + // that takes the gui scale into account too for all renderables + const double maxDistance = + res * boundingSphere() * glm::compMax(data.modelTransform.scale) / tfov; - _program->setUniform(_uniformCache.opacity, opacity()); + // Don't render if model is too far away + if (distanceToCamera >= maxDistance) { + return; + } - // Model transform and view transform needs to be in double precision - const 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::scale(_modelTransform.value(), glm::dvec3(_modelScale)); - const glm::dmat4 modelViewTransform = data.camera.combinedViewMatrix() * - modelTransform; + _program->activate(); - int nLightSources = 0; - _lightIntensitiesBuffer.resize(_lightSources.size()); - _lightDirectionsViewSpaceBuffer.resize(_lightSources.size()); - for (const std::unique_ptr& lightSource : _lightSources) { - if (!lightSource->isEnabled()) { - continue; - } - _lightIntensitiesBuffer[nLightSources] = lightSource->intensity(); - _lightDirectionsViewSpaceBuffer[nLightSources] = - lightSource->directionViewSpace(data); + // Model transform and view transform needs to be in double precision + const 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::scale(_modelTransform.value(), glm::dvec3(_modelScale)); + const glm::dmat4 modelViewTransform = data.camera.combinedViewMatrix() * + modelTransform; - ++nLightSources; + int nLightSources = 0; + _lightIntensitiesBuffer.resize(_lightSources.size()); + _lightDirectionsViewSpaceBuffer.resize(_lightSources.size()); + for (const std::unique_ptr& lightSource : _lightSources) { + if (!lightSource->isEnabled()) { + continue; } + _lightIntensitiesBuffer[nLightSources] = lightSource->intensity(); + _lightDirectionsViewSpaceBuffer[nLightSources] = + lightSource->directionViewSpace(data); + ++nLightSources; + } + + _program->setUniform( + _uniformCache.nLightSources, + nLightSources + ); + _program->setUniform( + _uniformCache.lightIntensities, + _lightIntensitiesBuffer + ); + _program->setUniform( + _uniformCache.lightDirectionsViewSpace, + _lightDirectionsViewSpaceBuffer + ); + _program->setUniform( + _uniformCache.modelViewTransform, + glm::mat4(modelViewTransform) + ); + + glm::dmat4 normalTransform = glm::transpose(glm::inverse(modelViewTransform)); + + _program->setUniform( + _uniformCache.normalTransform, + glm::mat4(normalTransform) + ); + + _program->setUniform( + _uniformCache.projectionTransform, + data.camera.projectionMatrix() + ); + _program->setUniform(_uniformCache.ambientIntensity, _ambientIntensity); + _program->setUniform(_uniformCache.diffuseIntensity, _diffuseIntensity); + _program->setUniform(_uniformCache.specularIntensity, _specularIntensity); + _program->setUniform(_uniformCache.performShading, _performShading); + + if (!_enableFaceCulling) { + glDisable(GL_CULL_FACE); + } + + // Configure blending + glEnablei(GL_BLEND, 0); + switch (_blendingFuncOption) { + case DefaultBlending: + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + break; + case AdditiveBlending: + glBlendFunc(GL_ONE, GL_ONE); + break; + case PolygonBlending: + glBlendFunc(GL_SRC_ALPHA_SATURATE, GL_ONE); + break; + case ColorAddingBlending: + glBlendFunc(GL_SRC_COLOR, GL_DST_COLOR); + break; + }; + + if (!_enableDepthTest) { + glDisable(GL_DEPTH_TEST); + } + + + if (!_shouldRenderTwice) { + // Reset manual depth test _program->setUniform( - _uniformCache.nLightSources, - nLightSources - ); - _program->setUniform( - _uniformCache.lightIntensities, - _lightIntensitiesBuffer - ); - _program->setUniform( - _uniformCache.lightDirectionsViewSpace, - _lightDirectionsViewSpaceBuffer - ); - _program->setUniform( - _uniformCache.modelViewTransform, - glm::mat4(modelViewTransform) + _uniformCache.performManualDepthTest, + false ); - glm::dmat4 normalTransform = glm::transpose(glm::inverse(modelViewTransform)); - - _program->setUniform( - _uniformCache.normalTransform, - glm::mat4(normalTransform) - ); - - _program->setUniform( - _uniformCache.projectionTransform, - data.camera.projectionMatrix() - ); - _program->setUniform(_uniformCache.ambientIntensity, _ambientIntensity); - _program->setUniform(_uniformCache.diffuseIntensity, _diffuseIntensity); - _program->setUniform(_uniformCache.specularIntensity, _specularIntensity); - _program->setUniform(_uniformCache.performShading, _performShading); - _program->setUniform(_uniformCache.opacityBlending, _enableOpacityBlending); - - if (_disableFaceCulling) { - glDisable(GL_CULL_FACE); + if (hasOverrideRenderBin()) { + // If override render bin is set then use the opacity values as normal + _program->setUniform(_uniformCache.opacity, opacity()); } - - glEnablei(GL_BLEND, 0); - switch (_blendingFuncOption) { - case DefaultBlending: - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - break; - case AdditiveBlending: - glBlendFunc(GL_ONE, GL_ONE); - break; - case PointsAndLinesBlending: - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - break; - case PolygonBlending: - glBlendFunc(GL_SRC_ALPHA_SATURATE, GL_ONE); - break; - case ColorAddingBlending: - glBlendFunc(GL_SRC_COLOR, GL_DST_COLOR); - break; - }; - - if (_disableDepthTest) { - glDisable(GL_DEPTH_TEST); + else { + // Otherwise reset to 1 + _program->setUniform(_uniformCache.opacity, 1.f); } _geometry->render(*_program); - if (_disableFaceCulling) { - glEnable(GL_CULL_FACE); - } - - global::renderEngine->openglStateCache().resetBlendState(); - - if (_disableDepthTest) { - glEnable(GL_DEPTH_TEST); - } - - _program->deactivate(); } + else { + // Prepare framebuffer + GLint defaultFBO = ghoul::opengl::FramebufferObject::getActiveObject(); + glBindFramebuffer(GL_FRAMEBUFFER, _framebuffer); + + // Re-bind first texture to use the currently not used Ping-Pong texture in the + // FramebufferRenderer + glFramebufferTexture( + GL_FRAMEBUFFER, + GL_COLOR_ATTACHMENT0, + global::renderEngine->renderer().additionalColorTexture1(), + 0 + ); + // Check status + GLenum status = glCheckFramebufferStatus(GL_FRAMEBUFFER); + if (status != GL_FRAMEBUFFER_COMPLETE) { + LERROR("Framebuffer is not complete"); + } + + glDrawBuffers(3, ColorAttachmentArray); + glClearBufferfv(GL_COLOR, 1, glm::value_ptr(glm::vec4(0.f, 0.f, 0.f, 0.f))); + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + // Use a manuel depth test to make the models aware of the rest of the scene + _program->setUniform( + _uniformCache.performManualDepthTest, + _enableDepthTest + ); + + // Bind the G-buffer depth texture for a manual depth test towards the rest + // of the scene + ghoul::opengl::TextureUnit gBufferDepthTextureUnit; + gBufferDepthTextureUnit.activate(); + glBindTexture( + GL_TEXTURE_2D, + global::renderEngine->renderer().gBufferDepthTexture() + ); + _program->setUniform( + _uniformCache.gBufferDepthTexture, + gBufferDepthTextureUnit + ); + + // Will also need the resolution to get a texture coordinate for the G-buffer + // depth texture + _program->setUniform( + _uniformCache.resolution, + glm::vec2(global::windowDelegate->currentDrawBufferResolution()) + ); + + // Make sure opacity in first pass is always 1 + _program->setUniform(_uniformCache.opacity, 1.f); + + // Render Pass 1 + // Render all parts of the model into the new framebuffer without opacity + _geometry->render(*_program); + _program->deactivate(); + + // Render pass 2 + // Render the whole model into the G-buffer with the correct opacity + glBindFramebuffer(GL_FRAMEBUFFER, defaultFBO); + + // Screen-space quad should not be discarded due to depth test, + // but we still want to be able to write to the depth buffer -> GL_ALWAYS + glEnable(GL_DEPTH_TEST); + glDepthFunc(GL_ALWAYS); + + _quadProgram->activate(); + + _quadProgram->setUniform(_uniformOpacityCache.opacity, opacity()); + + // Bind textures + ghoul::opengl::TextureUnit colorTextureUnit; + colorTextureUnit.activate(); + glBindTexture( + GL_TEXTURE_2D, + global::renderEngine->renderer().additionalColorTexture1() + ); + _quadProgram->setUniform(_uniformOpacityCache.colorTexture, colorTextureUnit); + + ghoul::opengl::TextureUnit depthTextureUnit; + depthTextureUnit.activate(); + glBindTexture( + GL_TEXTURE_2D, + global::renderEngine->renderer().additionalDepthTexture() + ); + _quadProgram->setUniform(_uniformOpacityCache.depthTexture, depthTextureUnit); + + // Will also need the resolution and viewport to get a texture coordinate + _quadProgram->setUniform( + _uniformOpacityCache.resolution, + glm::vec2(global::windowDelegate->currentDrawBufferResolution()) + ); + + GLint vp[4] = { 0 }; + global::renderEngine->openglStateCache().viewport(vp); + glm::ivec4 viewport = glm::ivec4(vp[0], vp[1], vp[2], vp[3]); + _quadProgram->setUniform( + _uniformOpacityCache.viewport, + viewport[0], + viewport[1], + viewport[2], + viewport[3] + ); + + // Draw + glBindVertexArray(_quadVao); + glDrawArrays(GL_TRIANGLES, 0, 6); + _quadProgram->deactivate(); + } + + // Reset + if (!_enableFaceCulling) { + glEnable(GL_CULL_FACE); + } + + if (!_enableDepthTest) { + glEnable(GL_DEPTH_TEST); + } + + global::renderEngine->openglStateCache().resetBlendState(); + global::renderEngine->openglStateCache().resetDepthState(); + glActiveTexture(GL_TEXTURE0); } void RenderableModel::update(const UpdateData& data) { @@ -685,11 +925,19 @@ void RenderableModel::update(const UpdateData& data) { ghoul::opengl::updateUniformLocations(*_program, _uniformCache, UniformNames); } - setBoundingSphere(_geometry->boundingRadius() * _modelScale * - glm::compMax(data.modelTransform.scale) - ); - // Set Interaction sphere size to be 10% of the bounding sphere - setInteractionSphere(boundingSphere() * 0.1); + if (!hasOverrideRenderBin()) { + // Only render two pass if the model is in any way transparent + const float o = opacity(); + if ((o >= 0.f && o < 1.f) || _geometry->isTransparent()) { + setRenderBin(Renderable::RenderBin::PostDeferredTransparent); + _shouldRenderTwice = true; + } + else { + setRenderBin(_originalRenderBin); + _shouldRenderTwice = false; + } + } + if (_geometry->hasAnimation() && !_animationStart.empty()) { double relativeTime; diff --git a/modules/base/rendering/renderablemodel.h b/modules/base/rendering/renderablemodel.h index a4d1bee6b8..11b11e0155 100644 --- a/modules/base/rendering/renderablemodel.h +++ b/modules/base/rendering/renderablemodel.h @@ -33,7 +33,6 @@ #include #include #include -#include #include #include #include @@ -93,21 +92,21 @@ private: properties::FloatProperty _specularIntensity; properties::BoolProperty _performShading; - properties::BoolProperty _disableFaceCulling; + properties::BoolProperty _enableFaceCulling; properties::DMat4Property _modelTransform; properties::Vec3Property _rotationVec; - properties::BoolProperty _disableDepthTest; - properties::BoolProperty _enableOpacityBlending; + properties::BoolProperty _enableDepthTest; properties::OptionProperty _blendingFuncOption; std::string _vertexShaderPath; std::string _fragmentShaderPath; ghoul::opengl::ProgramObject* _program = nullptr; - UniformCache(opacity, nLightSources, lightDirectionsViewSpace, lightIntensities, + UniformCache(nLightSources, lightDirectionsViewSpace, lightIntensities, modelViewTransform, normalTransform, projectionTransform, performShading, ambientIntensity, diffuseIntensity, - specularIntensity, opacityBlending) _uniformCache; + specularIntensity, performManualDepthTest, gBufferDepthTexture, + resolution, opacity) _uniformCache; std::vector> _lightSources; @@ -116,6 +115,20 @@ private: std::vector _lightDirectionsViewSpaceBuffer; properties::PropertyOwner _lightSourcePropertyOwner; + + // Framebuffer and screen space quad + GLuint _framebuffer = 0; + GLuint _quadVao = 0; + GLuint _quadVbo = 0; + bool _shouldRenderTwice = false; + + // Opacity program + ghoul::opengl::ProgramObject* _quadProgram = nullptr; + UniformCache(opacity, colorTexture, depthTexture, viewport, + resolution) _uniformOpacityCache; + + // Store the original RenderBin + Renderable::RenderBin _originalRenderBin; }; } // namespace openspace diff --git a/modules/base/rendering/renderabletrail.cpp b/modules/base/rendering/renderabletrail.cpp index 490a0f73ae..66c391b146 100644 --- a/modules/base/rendering/renderabletrail.cpp +++ b/modules/base/rendering/renderabletrail.cpp @@ -434,6 +434,9 @@ void RenderableTrail::render(const RenderData& data, RendererTasks&) { const double distance = glm::distance(trailPosWorld, data.camera.eyePositionVec3()); if (distance > boundingSphere() * DISTANCE_CULLING_RADII) { + // Reset + global::renderEngine->openglStateCache().resetBlendState(); + global::renderEngine->openglStateCache().resetDepthState(); return; } @@ -468,8 +471,9 @@ void RenderableTrail::render(const RenderData& data, RendererTasks&) { glBindVertexArray(0); - glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - glDepthMask(true); + // Reset + global::renderEngine->openglStateCache().resetBlendState(); + global::renderEngine->openglStateCache().resetDepthState(); _programObject->deactivate(); } diff --git a/modules/base/rendering/screenspaceframebuffer.cpp b/modules/base/rendering/screenspaceframebuffer.cpp index 27c1514886..42da3e2383 100644 --- a/modules/base/rendering/screenspaceframebuffer.cpp +++ b/modules/base/rendering/screenspaceframebuffer.cpp @@ -108,7 +108,7 @@ void ScreenSpaceFramebuffer::render() { const glm::vec4& size = _size.value(); const float xratio = resolution.x / (size.z - size.x); - const float yratio = resolution.y / (size.w - size.y);; + const float yratio = resolution.y / (size.w - size.y); if (!_renderFunctions.empty()) { GLint viewport[4]; diff --git a/modules/base/shaders/modelOpacity_fs.glsl b/modules/base/shaders/modelOpacity_fs.glsl new file mode 100644 index 0000000000..cbe4f94f8b --- /dev/null +++ b/modules/base/shaders/modelOpacity_fs.glsl @@ -0,0 +1,64 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2022 * + * * + * 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 "fragment.glsl" +#include "floatoperations.glsl" + +in vec2 vs_st; + +uniform float opacity = 1.0; + +uniform sampler2D colorTexture; +uniform sampler2D depthTexture; + +uniform ivec4 viewport; +uniform vec2 resolution; + +Fragment getFragment() { + Fragment frag; + + // Modify the texCoord based on the Viewport and Resolution. This modification is + // necessary in case of side-by-side stereo as we only want to access the part of the + // feeding texture that we are currently responsible for. Otherwise we would map the + // entire feeding texture into our half of the result texture, leading to a doubling of + // the "missing" half. If you don't believe me, load a configuration file with the + // side_by_side stereo mode enabled, disable FXAA, and remove this modification. + // The same calculation is done in the HDR resolving shader + vec2 st = vs_st; + st.x = st.x / (resolution.x / viewport[2]) + (viewport[0] / resolution.x); + st.y = st.y / (resolution.y / viewport[3]) + (viewport[1] / resolution.y); + + vec4 textureColor = texture(colorTexture, st); + if (textureColor.a == 0.0 || opacity == 0.0) { + discard; + } + + frag.color.rgb = textureColor.rgb; + frag.color.a = opacity * textureColor.a; + + frag.depth = denormalizeFloat(texture(depthTexture, vs_st).x); + frag.disableLDR2HDR = true; + + return frag; +} diff --git a/modules/base/shaders/modelOpacity_vs.glsl b/modules/base/shaders/modelOpacity_vs.glsl new file mode 100644 index 0000000000..8ac1fac67e --- /dev/null +++ b/modules/base/shaders/modelOpacity_vs.glsl @@ -0,0 +1,35 @@ +/***************************************************************************************** + * * + * OpenSpace * + * * + * Copyright (c) 2014-2022 * + * * + * 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__ + +layout(location = 0) in vec2 in_position; +layout(location = 1) in vec2 in_st; + +out vec2 vs_st; + +void main() { + vs_st = in_st; + gl_Position = vec4(in_position.x, in_position.y, 0.0, 1.0); +} diff --git a/modules/base/shaders/model_fs.glsl b/modules/base/shaders/model_fs.glsl index 5ee2771f32..0c3108274a 100644 --- a/modules/base/shaders/model_fs.glsl +++ b/modules/base/shaders/model_fs.glsl @@ -28,135 +28,139 @@ in vec2 vs_st; in vec3 vs_normalViewSpace; in vec4 vs_positionCameraSpace; in float vs_screenSpaceDepth; -in mat3 TBN; +in mat3 vs_TBN; uniform float ambientIntensity = 0.2; uniform float diffuseIntensity = 1.0; uniform float specularIntensity = 1.0; uniform bool performShading = true; + uniform bool use_forced_color = false; uniform bool has_texture_diffuse; uniform bool has_texture_normal; uniform bool has_texture_specular; uniform bool has_color_specular; -uniform bool opacityBlending = false; + uniform sampler2D texture_diffuse; uniform sampler2D texture_normal; uniform sampler2D texture_specular; -uniform vec3 color_diffuse; -uniform vec3 color_specular; + +uniform vec4 color_diffuse; +uniform vec4 color_specular; +uniform float opacity = 1.0; + uniform int nLightSources; uniform vec3 lightDirectionsViewSpace[8]; uniform float lightIntensities[8]; -uniform float opacity = 1.0; +uniform bool performManualDepthTest = false; +uniform sampler2D gBufferDepthTexture; + +uniform vec2 resolution; Fragment getFragment() { + Fragment frag; + frag.depth = vs_screenSpaceDepth; + frag.gPosition = vs_positionCameraSpace; + frag.gNormal = vec4(vs_normalViewSpace, 0.0); + frag.disableLDR2HDR = true; + frag.color.a = opacity; + + if (performManualDepthTest) { + // gl_FragCoord.x goes from 0 to resolution.x and gl_FragCoord.y goes from 0 to + // resolution.y, need to normalize it + vec2 texCoord = gl_FragCoord.xy; + texCoord.x = texCoord.x / resolution.x; + texCoord.y = texCoord.y / resolution.y; + + // Manual depth test + float gBufferDepth = denormalizeFloat(texture(gBufferDepthTexture, texCoord).x); + if (vs_screenSpaceDepth > gBufferDepth) { + frag.color = vec4(0.0); + frag.depth = gBufferDepth; + return frag; + } + } + // Render invisible mesh with flashy procedural material if (use_forced_color) { - Fragment frag; - - vec3 adjustedPos = floor(vs_positionCameraSpace.xyz * 3.0); + vec3 adjustedPos = floor(vs_positionCameraSpace.xyz / 500.0); float chessboard = adjustedPos.x + adjustedPos.y + adjustedPos.z; chessboard = fract(chessboard * 0.5); chessboard *= 2; + // Pink and complementary green in a chessboard pattern frag.color.rgb = mix(vec3(1.0, 0.0, 0.8), vec3(0.0, 1.0, 0.2), chessboard); - - frag.color.a = opacity; - frag.depth = vs_screenSpaceDepth; - frag.gPosition = vs_positionCameraSpace; - frag.gNormal = vec4(vs_normalViewSpace, 0.0); - frag.disableLDR2HDR = true; - return frag; } - vec3 diffuseAlbedo; + // Base color + vec4 diffuseAlbedo; if (has_texture_diffuse) { - diffuseAlbedo = texture(texture_diffuse, vs_st).rgb; + diffuseAlbedo = texture(texture_diffuse, vs_st); } else { diffuseAlbedo = color_diffuse; } - if (opacity == 0.0) { - discard; - } - - Fragment frag; - if (performShading) { + // Specular color vec3 specularAlbedo; if (has_texture_specular) { specularAlbedo = texture(texture_specular, vs_st).rgb; } else { if (has_color_specular) { - specularAlbedo = color_specular; + specularAlbedo = color_specular.rgb; } else { - specularAlbedo = vec3(1.0); + specularAlbedo = diffuseAlbedo.rgb; } } - // Some of these values could be passed in as uniforms - const vec3 lightColorAmbient = vec3(1.0); - const vec3 lightColor = vec3(1.0); - - vec3 n; + // Bumb mapping + vec3 normal; if (has_texture_normal) { vec3 normalAlbedo = texture(texture_normal, vs_st).rgb; normalAlbedo = normalize(normalAlbedo * 2.0 - 1.0); - n = normalize(TBN * normalAlbedo); + normal = normalize(vs_TBN * normalAlbedo); } else { - n = normalize(vs_normalViewSpace); + normal = normalize(vs_normalViewSpace); } + frag.gNormal = vec4(normal, 0.0); - vec3 c = normalize(vs_positionCameraSpace.xyz); + // Could be seperated into ambinet, diffuse and specular and passed in as uniforms + const vec3 lightColor = vec3(1.0); + const float specularPower = 100.0; - vec3 color = ambientIntensity * lightColorAmbient * diffuseAlbedo; + // Ambient light + vec3 totalLightColor = ambientIntensity * lightColor * diffuseAlbedo.rgb; + + vec3 viewDirection = normalize(vs_positionCameraSpace.xyz); for (int i = 0; i < nLightSources; ++i) { - vec3 l = lightDirectionsViewSpace[i]; - vec3 r = reflect(l, n); - - float diffuseCosineFactor = dot(n,l); - float specularCosineFactor = dot(c,r); - const float specularPower = 100.0; - + // Diffuse light + vec3 lightDirection = lightDirectionsViewSpace[i]; + float diffuseFactor = max(dot(normal, lightDirection), 0.0); vec3 diffuseColor = - diffuseIntensity * lightColor * diffuseAlbedo * max(diffuseCosineFactor, 0); + diffuseIntensity * lightColor * diffuseFactor * diffuseAlbedo.rgb; + // Specular light + vec3 reflectDirection = reflect(lightDirection, normal); + float specularFactor = + pow(max(dot(viewDirection, reflectDirection), 0.0), specularPower); vec3 specularColor = - specularIntensity * lightColor * specularAlbedo * - pow(max(specularCosineFactor, 0), specularPower); + specularIntensity * lightColor * specularFactor * specularAlbedo; - color += lightIntensities[i] * (diffuseColor + specularColor); + totalLightColor += lightIntensities[i] * (diffuseColor + specularColor); } - frag.color.rgb = color; + frag.color.rgb = totalLightColor; } else { - frag.color.rgb = diffuseAlbedo; + frag.color.rgb = diffuseAlbedo.rgb; } - if (opacityBlending) { - // frag.color.a = opacity * (frag.color.r + frag.color.g + frag.color.b)/3.0; - frag.color.a = opacity * max(max(frag.color.r, frag.color.g), frag.color.b); - } - else { - frag.color.a = opacity; - } - - if (frag.color.a < 0.1) { - discard; - } - - frag.depth = vs_screenSpaceDepth; - frag.gPosition = vs_positionCameraSpace; - frag.gNormal = vec4(vs_normalViewSpace, 0.0); - frag.disableLDR2HDR = true; - + frag.color.a = diffuseAlbedo.a * opacity; return frag; } diff --git a/modules/base/shaders/model_vs.glsl b/modules/base/shaders/model_vs.glsl index 6e863b322c..76cead149f 100644 --- a/modules/base/shaders/model_vs.glsl +++ b/modules/base/shaders/model_vs.glsl @@ -35,7 +35,7 @@ out vec2 vs_st; out vec3 vs_normalViewSpace; out float vs_screenSpaceDepth; out vec4 vs_positionCameraSpace; -out mat3 TBN; +out mat3 vs_TBN; uniform mat4 modelViewTransform; uniform mat4 projectionTransform; @@ -53,17 +53,18 @@ void main() { vs_st = in_st; vs_screenSpaceDepth = positionScreenSpace.w; - vs_normalViewSpace = normalize(mat3(normalTransform) * (mat3(meshNormalTransform) * in_normal)); + vs_normalViewSpace = + normalize(mat3(normalTransform) * (mat3(meshNormalTransform) * in_normal)); - // TBN matrix for normal mapping - vec3 T = normalize(mat3(normalTransform) * (mat3(meshNormalTransform) * in_tangent)); - vec3 N = normalize(mat3(normalTransform) * (mat3(meshNormalTransform) * in_normal)); + // TBN matrix for normal mapping + vec3 T = normalize(mat3(normalTransform) * (mat3(meshNormalTransform) * in_tangent)); + vec3 N = normalize(mat3(normalTransform) * (mat3(meshNormalTransform) * in_normal)); - // Re-orthogonalize T with respect to N - T = normalize(T - dot(T, N) * N); + // Re-orthogonalize T with respect to N + T = normalize(T - dot(T, N) * N); - // Retrieve perpendicular vector B with cross product of T and N - vec3 B = normalize(cross(N, T)); + // Retrieve perpendicular vector B with cross product of T and N + vec3 B = normalize(cross(N, T)); - TBN = mat3(T, B, N); + vs_TBN = mat3(T, B, N); } diff --git a/modules/spacecraftinstruments/rendering/renderablemodelprojection.cpp b/modules/spacecraftinstruments/rendering/renderablemodelprojection.cpp index 7c71dbf15e..b80cfc36c0 100644 --- a/modules/spacecraftinstruments/rendering/renderablemodelprojection.cpp +++ b/modules/spacecraftinstruments/rendering/renderablemodelprojection.cpp @@ -30,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -67,18 +68,38 @@ namespace { // This specifies the model that is rendered by the Renderable. std::filesystem::path geometryFile; + enum class [[codegen::map(openspace::DistanceUnit)]] ScaleUnit { + Nanometer, + Micrometer, + Millimeter, + Centimeter, + Decimeter, + Meter, + Kilometer, + Thou, + Inch, + Foot, + Yard, + Chain, + Furlong, + Mile + }; + + // The scale of the model. For example if the model is in centimeters + // then ModelScale = Centimeter or ModelScale = 0.01 + std::optional> modelScale; + + // By default the given ModelScale is used to scale the model down, + // by setting this setting to true the model is instead scaled up with the + // given ModelScale + std::optional invertModelScale; + // Contains information about projecting onto this planet. ghoul::Dictionary projection [[codegen::reference("spacecraftinstruments_projectioncomponent")]]; // [[codegen::verbatim(PerformShadingInfo.description)]] std::optional performShading; - - // The radius of the bounding sphere of this object. This has to be a - // radius that is larger than anything that is rendered by it. It has to - // be at least as big as the convex hull of the object. The default value - // is 10e9 meters. - std::optional boundingSphereRadius; }; #include "renderablemodelprojection_codegen.cpp" } // namespace @@ -102,12 +123,30 @@ RenderableModelProjection::RenderableModelProjection(const ghoul::Dictionary& di ghoul::io::ModelReader::NotifyInvisibleDropped::Yes ); + _invertModelScale = p.invertModelScale.value_or(_invertModelScale); + + if (p.modelScale.has_value()) { + if (std::holds_alternative(*p.modelScale)) { + Parameters::ScaleUnit scaleUnit = + std::get(*p.modelScale); + DistanceUnit distanceUnit = codegen::map(scaleUnit); + _modelScale = toMeter(distanceUnit); + } + else if (std::holds_alternative(*p.modelScale)) { + _modelScale = std::get(*p.modelScale); + } + else { + throw ghoul::MissingCaseException(); + } + + if (_invertModelScale) { + _modelScale = 1.0 / _modelScale; + } + } + addPropertySubOwner(_projectionComponent); _projectionComponent.initialize(identifier(), p.projection); - double boundingSphereRadius = p.boundingSphereRadius.value_or(1.0e9); - setBoundingSphere(boundingSphereRadius); - _performShading = p.performShading.value_or(_performShading); addProperty(_performShading); } @@ -161,9 +200,11 @@ void RenderableModelProjection::initializeGL() { _projectionComponent.initializeGL(); - double bs = boundingSphere(); _geometry->initialize(); - setBoundingSphere(bs); // ignore bounding sphere set by geometry. + setBoundingSphere(_geometry->boundingRadius() * _modelScale); + + // Set Interaction sphere size to be 10% of the bounding sphere + setInteractionSphere(boundingSphere() * 0.1); } void RenderableModelProjection::deinitializeGL() { @@ -222,8 +263,11 @@ void RenderableModelProjection::render(const RenderData& data, RendererTasks&) { const glm::dmat4 transform = 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::scale(glm::dmat4(1.0), glm::dvec3(data.modelTransform.scale)) * + glm::scale(glm::dmat4(1.0), glm::dvec3(_modelScale)); const glm::dmat4 modelViewTransform = data.camera.combinedViewMatrix() * transform; + + // malej 2023-FEB-23: The light sources should probably not be hard coded const glm::vec3 directionToSun = glm::normalize(_sunPosition - bodyPos); const glm::vec3 directionToSunViewSpace = glm::normalize( glm::mat3(data.camera.combinedViewMatrix()) * directionToSun diff --git a/modules/spacecraftinstruments/rendering/renderablemodelprojection.h b/modules/spacecraftinstruments/rendering/renderablemodelprojection.h index 9b6cca43d8..c2b70bbc86 100644 --- a/modules/spacecraftinstruments/rendering/renderablemodelprojection.h +++ b/modules/spacecraftinstruments/rendering/renderablemodelprojection.h @@ -84,6 +84,8 @@ private: UniformCache(ProjectorMatrix, ModelTransform) _depthFboUniformCache; std::unique_ptr _geometry; + double _modelScale = 1.0; + bool _invertModelScale = false; glm::dmat3 _instrumentMatrix = glm::dmat3(1.0); diff --git a/modules/spacecraftinstruments/shaders/renderableModel_fs.glsl b/modules/spacecraftinstruments/shaders/renderableModel_fs.glsl index 6ed9b41adc..cf155e390d 100644 --- a/modules/spacecraftinstruments/shaders/renderableModel_fs.glsl +++ b/modules/spacecraftinstruments/shaders/renderableModel_fs.glsl @@ -32,7 +32,7 @@ in vec4 vs_positionCameraSpace; uniform bool has_texture_diffuse; uniform sampler2D baseTexture; -uniform vec3 baseColor; +uniform vec4 baseColor; uniform sampler2D projectionTexture; uniform bool performShading; uniform float projectionFading; @@ -47,13 +47,23 @@ const float specularPower = 100.0; Fragment getFragment() { + Fragment frag; + frag.depth = vs_depth; + frag.gPosition = vs_positionCameraSpace; + frag.gNormal = vec4(vs_normalViewSpace, 0.0); + frag.disableLDR2HDR = true; + frag.color.a = 1.0; + + // Base color vec4 textureColor; if (has_texture_diffuse) { - textureColor = texture(baseTexture, vs_st); + textureColor = texture(baseTexture, vs_st); } else { - textureColor = vec4(baseColor, 1.0); + textureColor = vec4(baseColor.rgb, 1.0); } + + // Mix base color with the projection images vec4 projectionColor = texture(projectionTexture, vs_st); if (projectionColor.a > 0.0) { textureColor.rgb = mix( @@ -65,34 +75,35 @@ Fragment getFragment() { vec3 diffuseAlbedo = textureColor.rgb; - Fragment frag; if (performShading) { - // Some of these values could be passed in as uniforms - const vec3 lightColorAmbient = vec3(1.0); + // Could be seperated into ambinet, diffuse and specular and passed in as uniforms const vec3 lightColor = vec3(1.0); + const float specularPower = 100.0; - vec3 n = normalize(vs_normalViewSpace); - vec3 l = directionToSunViewSpace; - vec3 c = normalize(vs_positionCameraSpace.xyz); - vec3 r = reflect(l, n); + // Ambient light + vec3 ambientColor = ambientIntensity * lightColor * diffuseAlbedo; - float diffuseCosineFactor = dot(n,l); - float specularCosineFactor = dot(c,r); - - vec3 ambientColor = ambientIntensity * lightColorAmbient * diffuseAlbedo; + // Diffuse light + vec3 normal = normalize(vs_normalViewSpace); + vec3 lightDirection = directionToSunViewSpace; + float diffuseFactor = max(dot(normal, lightDirection), 0.0); vec3 diffuseColor = - diffuseIntensity * lightColor * diffuseAlbedo * max(diffuseCosineFactor, 0.0); - vec3 specularColor = specularIntensity * lightColor * specularAlbedo * - pow(max(specularCosineFactor, 0.0), specularPower); + diffuseIntensity * lightColor * diffuseFactor * diffuseAlbedo; + // Specular light + vec3 viewDirection = normalize(vs_positionCameraSpace.xyz); + vec3 reflectDirection = reflect(lightDirection, normal); + float specularFactor = + pow(max(dot(viewDirection, reflectDirection), 0.0), specularPower); + vec3 specularColor = + specularIntensity * lightColor * specularFactor * specularAlbedo; + + // Total light frag.color.rgb = ambientColor + diffuseColor + specularColor; } else { frag.color.rgb = diffuseAlbedo; } - frag.color.a = 1.0; - frag.depth = vs_depth; - // frag.depth = 0.0; return frag; } diff --git a/modules/spacecraftinstruments/shaders/renderableModel_vs.glsl b/modules/spacecraftinstruments/shaders/renderableModel_vs.glsl index b2a2e26c30..c77edb6d6d 100644 --- a/modules/spacecraftinstruments/shaders/renderableModel_vs.glsl +++ b/modules/spacecraftinstruments/shaders/renderableModel_vs.glsl @@ -37,7 +37,6 @@ out vec4 vs_positionCameraSpace; uniform mat4 modelViewTransform; uniform mat4 projectionTransform; -uniform vec3 cameraDirectionWorldSpace; uniform mat4 meshTransform; uniform mat4 meshNormalTransform; diff --git a/src/rendering/framebufferrenderer.cpp b/src/rendering/framebufferrenderer.cpp index e126b424de..6c85a386ac 100644 --- a/src/rendering/framebufferrenderer.cpp +++ b/src/rendering/framebufferrenderer.cpp @@ -87,6 +87,53 @@ namespace { namespace openspace { +//============================// +//===== Reuse textures =====// +//============================// +GLuint FramebufferRenderer::additionalColorTexture1() const { + // Gives access to the currently NOT used pingPongTexture + int unusedPingPongIndex = _pingPongIndex == 0 ? 1 : 0; + return _pingPongBuffers.colorTexture[unusedPingPongIndex]; +} + +GLuint FramebufferRenderer::additionalColorTexture2() const { + // Gives access to the exitColorTexture + return _exitColorTexture; +} + +GLuint FramebufferRenderer::additionalColorTexture3() const { + // Gives access to the fxaaTexture + return _fxaaBuffers.fxaaTexture; +} + +GLuint FramebufferRenderer::additionalDepthTexture() const { + // Gives access to the exitDepthTexture + return _exitDepthTexture; +} + +//=============================// +//===== Access G-buffer =====// +//=============================// +GLuint FramebufferRenderer::gBufferColorTexture() const { + // Gives access to the color texture of the G-buffer + return _gBuffers.colorTexture; +} + +GLuint FramebufferRenderer::gBufferPositionTexture() const { + // Gives access to the position texture of the G-buffer + return _gBuffers.positionTexture; +} + +GLuint FramebufferRenderer::gBufferNormalTexture() const { + // Gives access to the normal texture of the G-buffer + return _gBuffers.normalTexture; +} + +GLuint FramebufferRenderer::gBufferDepthTexture() const { + // Gives access to the depth texture of the G-buffer + return _gBuffers.depthTexture; +} + void FramebufferRenderer::initialize() { ZoneScoped; TracyGpuZone("Rendering initialize"); @@ -134,10 +181,6 @@ void FramebufferRenderer::initialize() { glGenTextures(1, &_exitDepthTexture); glGenFramebuffers(1, &_exitFramebuffer); - // HDR / Filtering Buffers - glGenFramebuffers(1, &_hdrBuffers.hdrFilteringFramebuffer); - glGenTextures(1, &_hdrBuffers.hdrFilteringTexture); - // FXAA Buffers glGenFramebuffers(1, &_fxaaBuffers.fxaaFramebuffer); glGenTextures(1, &_fxaaBuffers.fxaaTexture); @@ -252,30 +295,6 @@ void FramebufferRenderer::initialize() { LERROR("Exit framebuffer is not complete"); } - //===================================// - //===== HDR/Filtering Buffers =====// - //===================================// - glBindFramebuffer(GL_FRAMEBUFFER, _hdrBuffers.hdrFilteringFramebuffer); - glFramebufferTexture( - GL_FRAMEBUFFER, - GL_COLOR_ATTACHMENT0, - _hdrBuffers.hdrFilteringTexture, - 0 - ); - if (glbinding::Binding::ObjectLabel.isResolved()) { - glObjectLabel( - GL_FRAMEBUFFER, - _hdrBuffers.hdrFilteringFramebuffer, - -1, - "HDR filtering" - ); - } - - status = glCheckFramebufferStatus(GL_FRAMEBUFFER); - if (status != GL_FRAMEBUFFER_COMPLETE) { - LERROR("HDR/Filtering framebuffer is not complete"); - } - //===================================// //========== FXAA Buffers =========// //===================================// @@ -384,7 +403,6 @@ void FramebufferRenderer::deinitialize() { glDeleteFramebuffers(1, &_gBuffers.framebuffer); glDeleteFramebuffers(1, &_exitFramebuffer); - glDeleteFramebuffers(1, &_hdrBuffers.hdrFilteringFramebuffer); glDeleteFramebuffers(1, &_fxaaBuffers.fxaaFramebuffer); glDeleteFramebuffers(1, &_pingPongBuffers.framebuffer); glDeleteFramebuffers(1, &_downscaleVolumeRendering.framebuffer); @@ -392,7 +410,6 @@ void FramebufferRenderer::deinitialize() { glDeleteTextures(1, &_gBuffers.colorTexture); glDeleteTextures(1, &_gBuffers.depthTexture); - glDeleteTextures(1, &_hdrBuffers.hdrFilteringTexture); glDeleteTextures(1, &_fxaaBuffers.fxaaTexture); glDeleteTextures(1, &_gBuffers.positionTexture); glDeleteTextures(1, &_gBuffers.normalTexture); @@ -801,27 +818,6 @@ void FramebufferRenderer::updateResolution() { ); } - // HDR / Filtering - glBindTexture(GL_TEXTURE_2D, _hdrBuffers.hdrFilteringTexture); - glTexImage2D( - GL_TEXTURE_2D, - 0, - GL_RGBA32F, - _resolution.x, - _resolution.y, - 0, - GL_RGBA, - GL_FLOAT, - nullptr - ); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - if (glbinding::Binding::ObjectLabel.isResolved()) { - glObjectLabel(GL_TEXTURE, _hdrBuffers.hdrFilteringTexture, -1, "HDR filtering"); - } - // FXAA glBindTexture(GL_TEXTURE_2D, _fxaaBuffers.fxaaTexture); glTexImage2D( @@ -943,7 +939,7 @@ void FramebufferRenderer::updateResolution() { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); if (glbinding::Binding::ObjectLabel.isResolved()) { - glObjectLabel(GL_TEXTURE, _exitColorTexture, -1, "Exit depth"); + glObjectLabel(GL_TEXTURE, _exitDepthTexture, -1, "Exit depth"); } _dirtyResolution = false; @@ -1186,7 +1182,14 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac glEnablei(GL_BLEND, 0); { - TracyGpuZone("PostDeferredTransparent"); + TracyGpuZone("Overlay") + ghoul::GLDebugGroup group("Overlay"); + data.renderBinMask = static_cast(Renderable::RenderBin::Overlay); + scene->render(data, tasks); + } + + { + TracyGpuZone("PostDeferredTransparent") ghoul::GLDebugGroup group("PostDeferredTransparent"); data.renderBinMask = static_cast( Renderable::RenderBin::PostDeferredTransparent @@ -1195,9 +1198,11 @@ void FramebufferRenderer::render(Scene* scene, Camera* camera, float blackoutFac } { - TracyGpuZone("Overlay"); - ghoul::GLDebugGroup group("Overlay"); - data.renderBinMask = static_cast(Renderable::RenderBin::Overlay); + TracyGpuZone("Sticker") + ghoul::GLDebugGroup group("Sticker"); + data.renderBinMask = static_cast( + Renderable::RenderBin::Sticker + ); scene->render(data, tasks); } diff --git a/src/rendering/renderable.cpp b/src/rendering/renderable.cpp index 22a3e8603f..fedc25848d 100644 --- a/src/rendering/renderable.cpp +++ b/src/rendering/renderable.cpp @@ -150,6 +150,7 @@ Renderable::Renderable(const ghoul::Dictionary& dictionary, RenderableSettings s if (p.renderBinMode.has_value()) { _automaticallyUpdateRenderBin = false; + _hasOverrideRenderBin = true; setRenderBin(codegen::map(*p.renderBinMode)); } @@ -326,4 +327,8 @@ bool Renderable::automaticallyUpdatesRenderBin() const noexcept { return _automaticallyUpdateRenderBin; } +bool Renderable::hasOverrideRenderBin() const noexcept { + return _hasOverrideRenderBin; +} + } // namespace openspace diff --git a/src/rendering/renderengine.cpp b/src/rendering/renderengine.cpp index c093f9505f..85da66d100 100644 --- a/src/rendering/renderengine.cpp +++ b/src/rendering/renderengine.cpp @@ -413,6 +413,10 @@ RenderEngine::RenderEngine() RenderEngine::~RenderEngine() {} +const FramebufferRenderer& RenderEngine::renderer() const { + return _renderer; +} + void RenderEngine::initialize() { ZoneScoped; diff --git a/src/scene/scene.cpp b/src/scene/scene.cpp index 83d790b0e5..0184c648cc 100644 --- a/src/scene/scene.cpp +++ b/src/scene/scene.cpp @@ -75,10 +75,13 @@ namespace { return "PreDeferredTransparent"; } else if (renderBin == 8) { - return "PostDeferredTransparent"; + return "Overlay"; } else if (renderBin == 16) { - return "Overlay"; + return "PostDeferredTransparent"; + } + else if (renderBin == 32) { + return "Sticker"; } else { throw ghoul::MissingCaseException();