mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-02-18 02:49:03 -06:00
merge + codegen doc return
This commit is contained in:
@@ -63,7 +63,7 @@ namespace {
|
||||
int startIndex = 0;
|
||||
std::string token = "${USER_ASSETS}/";
|
||||
if (path.find(token) == 0) {
|
||||
startIndex = token.length();
|
||||
startIndex = static_cast<int>(token.length());
|
||||
}
|
||||
const size_t slash = path.find_first_of('/', startIndex);
|
||||
const bool endOfPath = (slash == std::string::npos);
|
||||
|
||||
@@ -1078,7 +1078,7 @@ int main(int argc, char* argv[]) {
|
||||
|
||||
bool showHelp = parser.execute();
|
||||
if (showHelp) {
|
||||
parser.displayHelp(std::cout);
|
||||
std::cout << parser.helpText();
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
// Take an actual copy of the arguments
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
local assetHelper = asset.require('util/asset_helper')
|
||||
|
||||
local colorLUT = asset.require('./stars_colormap').BvColorLUT
|
||||
local colormaps = asset.require('./stars_colormap').ColorMaps
|
||||
|
||||
local textures = asset.syncedResource({
|
||||
Name = "Stars Textures",
|
||||
@@ -30,10 +30,21 @@ local stars = {
|
||||
File = speck .. "/stars.speck",
|
||||
Texture = textures .. "/halo.png",
|
||||
--ShapeTexture = textures .. "/disc.png",
|
||||
ColorMap = colorLUT .. "/colorbv.cmap",
|
||||
ColorMap = colormaps .. "/colorbv.cmap",
|
||||
OtherDataColorMap = colormaps .. "/viridis.cmap",
|
||||
MagnitudeExponent = 6.2,
|
||||
SizeComposition = "Distance Modulus",
|
||||
RenderMethod = "Texture Based" -- or PSF
|
||||
RenderMethod = "Texture Based", -- or PSF
|
||||
DataMapping = {
|
||||
Bv = "colorb_v",
|
||||
Luminance = "lum",
|
||||
AbsoluteMagnitude = "absmag",
|
||||
ApparentMagnitude = "appmag",
|
||||
Vx = "vx",
|
||||
Vy = "vy",
|
||||
Vz = "vz",
|
||||
Speed = "speed"
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "Stars",
|
||||
@@ -55,12 +66,22 @@ local sunstar = {
|
||||
File = sunspeck .. "/sunstar.speck",
|
||||
Texture = textures .. "/halo.png",
|
||||
--ShapeTexture = textures .. "/disc.png",
|
||||
ColorMap = colorLUT .. "/colorbv.cmap",
|
||||
ColorMap = colormaps .. "/colorbv.cmap",
|
||||
MagnitudeExponent = 6.2,
|
||||
SizeComposition = "Distance Modulus",
|
||||
RenderMethod = "Texture Based", -- or PSF
|
||||
FadeInDistances = { 0.0001, 0.1 },
|
||||
RenderableType = "PostDeferredTransparent"
|
||||
RenderableType = "PostDeferredTransparent",
|
||||
DataMapping = {
|
||||
Bv = "colorb_v",
|
||||
Luminance = "lum",
|
||||
AbsoluteMagnitude = "absmag",
|
||||
ApparentMagnitude = "appmag",
|
||||
Vx = "vx",
|
||||
Vy = "vy",
|
||||
Vz = "vz",
|
||||
Speed = "speed",
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "Sun",
|
||||
|
||||
@@ -1,20 +1,20 @@
|
||||
local assetHelper = asset.require('util/asset_helper')
|
||||
|
||||
local BvColorLUT = asset.syncedResource({
|
||||
local colormaps = asset.syncedResource({
|
||||
Name = "Stars Color Table",
|
||||
Type = "HttpSynchronization",
|
||||
Identifier = "stars_colormap",
|
||||
Version = 2
|
||||
})
|
||||
|
||||
asset.export("BvColorLUT", BvColorLUT)
|
||||
asset.export("ColorMaps", colormaps)
|
||||
|
||||
asset.meta = {
|
||||
Name = "Stars B-V Colormap",
|
||||
Name = "Star Colormaps",
|
||||
Version = "2.0",
|
||||
Description = [[A lookup table that maps a B-V color index to an RGB color.
|
||||
The B-V values are in the range (-0.4, 2.0) and each line maps a value
|
||||
in that range to a color]],
|
||||
Description = [[Lookup tables used for star datasets, one of the tables map a B-V color
|
||||
index to an RGB color. The B-V values are in the range (-0.4, 2.0) and each line maps
|
||||
a value in that range to a color. The other table is the commonly used viridis map]],
|
||||
Author = "OpenSpace Team",
|
||||
URL = "https://www.amnh.org/research/hayden-planetarium/digital-universe",
|
||||
License = "AMNH Digital Universe"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
local bvColorLUT = asset.require('scene/digitaluniverse/stars_colormap').BvColorLUT
|
||||
local colormaps = asset.require('scene/digitaluniverse/stars_colormap').ColorMaps
|
||||
|
||||
local DataPath = asset.syncedResource({
|
||||
Name = "Exoplanet Data Files",
|
||||
@@ -15,7 +15,7 @@ asset.onInitialize(function ()
|
||||
|
||||
p = "Modules.Exoplanets.BvColormap";
|
||||
if (openspace.getPropertyValue(p) == "") then
|
||||
openspace.setPropertyValueSingle(p, bvColorLUT .. "/colorbv.cmap")
|
||||
openspace.setPropertyValueSingle(p, colormaps .. "/colorbv.cmap")
|
||||
end
|
||||
end)
|
||||
|
||||
|
||||
@@ -39,7 +39,17 @@ local gaia_abundance_apogee = {
|
||||
ColorMap = colorLUT .. "/colorbv.cmap",
|
||||
OtherDataColorMap = colorLUT .. "/viridis.cmap",
|
||||
StaticFilter = -9999,
|
||||
StaticFilterReplacement = 0.0
|
||||
StaticFilterReplacement = 0.0,
|
||||
DataMapping = {
|
||||
Bv = "colorb_v",
|
||||
Luminance = "lum",
|
||||
AbsoluteMagnitude = "absmag",
|
||||
ApparentMagnitude = "appmag",
|
||||
Vx = "vx",
|
||||
Vy = "vy",
|
||||
Vz = "vz",
|
||||
Speed = "speed"
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Path = "/Milky Way/Gaia"
|
||||
|
||||
@@ -39,7 +39,17 @@ local gaia_abundance_galah = {
|
||||
ColorMap = colorLUT .. "/colorbv.cmap",
|
||||
OtherDataColorMap = colorLUT .. "/viridis.cmap",
|
||||
StaticFilter = -9999,
|
||||
StaticFilterReplacement = 0.0
|
||||
StaticFilterReplacement = 0.0,
|
||||
DataMapping = {
|
||||
Bv = "colorb_v",
|
||||
Luminance = "lum",
|
||||
AbsoluteMagnitude = "absmag",
|
||||
ApparentMagnitude = "appmag",
|
||||
Vx = "vx",
|
||||
Vy = "vy",
|
||||
Vz = "vz",
|
||||
Speed = "speed"
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Path = "/Milky Way/Gaia"
|
||||
|
||||
@@ -19,7 +19,17 @@ local OrionClusterStars = {
|
||||
ColorMap = sync .. "/colorbv.cmap",
|
||||
MagnitudeExponent = 5.02,
|
||||
SizeComposition = "Distance Modulus",
|
||||
RenderMethod = "Texture Based"
|
||||
RenderMethod = "Texture Based",
|
||||
DataMapping = {
|
||||
Bv = "colorb_v",
|
||||
Luminance = "lum",
|
||||
AbsoluteMagnitude = "absmag",
|
||||
ApparentMagnitude = "appmag",
|
||||
Vx = "vx",
|
||||
Vy = "vy",
|
||||
Vz = "vz",
|
||||
Speed = "speed"
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "Orion Nebula Star Cluster",
|
||||
|
||||
@@ -32,7 +32,17 @@ local object = {
|
||||
ColorMap = colorLUT .. "/denver_colorbv.cmap",
|
||||
MagnitudeExponent = 6.2,
|
||||
SizeComposition = "Distance Modulus",
|
||||
RenderMethod = "Texture Based" -- or PSF
|
||||
RenderMethod = "Texture Based", -- or PSF
|
||||
DataMapping = {
|
||||
Bv = "colorb_v",
|
||||
Luminance = "lum",
|
||||
AbsoluteMagnitude = "absmag",
|
||||
ApparentMagnitude = "appmag",
|
||||
Vx = "vx",
|
||||
Vy = "vy",
|
||||
Vz = "vz",
|
||||
Speed = "speed"
|
||||
}
|
||||
},
|
||||
GUI = {
|
||||
Name = "Stars (Denver)",
|
||||
|
||||
@@ -46,12 +46,12 @@ local initializeAndAddNodes = function()
|
||||
}
|
||||
|
||||
local parentNode = {
|
||||
Identifier = "ISSparentNode",
|
||||
Identifier = "ISSModel",
|
||||
Parent = iss.Identifier,
|
||||
Transform = {
|
||||
Rotation = {
|
||||
Type = "FixedRotation",
|
||||
Attached = "ISSparentNode",
|
||||
Attached = "ISSModel",
|
||||
XAxis = { 0.01, -1.0, 0.56 },
|
||||
XAxisOrthogonal = true,
|
||||
YAxis = transforms.EarthInertial.Identifier
|
||||
@@ -73,9 +73,8 @@ local initializeAndAddNodes = function()
|
||||
DisableFaceCulling = true
|
||||
},
|
||||
GUI = {
|
||||
Name = "ISSparentNode",
|
||||
Path = "/Solar System/Planets/Earth/Satellites/ISS",
|
||||
Hidden = true,
|
||||
Name = "ISS Model",
|
||||
Path = "/Solar System/Planets/Earth/Satellites/ISS"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -141,7 +140,7 @@ asset.onInitialize(function ()
|
||||
for _, node in ipairs(nodes) do
|
||||
openspace.addSceneGraphNode(node)
|
||||
end
|
||||
openspace.setPropertyValueSingle("Scene.ISSparentNode.Rotation.yAxisInvertObject", true)
|
||||
openspace.setPropertyValueSingle("Scene.ISSModel.Rotation.yAxisInvertObject", true)
|
||||
|
||||
end)
|
||||
|
||||
|
||||
@@ -4,6 +4,7 @@ local propertyHelper = asset.require('./property_helper')
|
||||
-- "None"
|
||||
-- "Orbit X"
|
||||
-- "Orbit Y"
|
||||
-- "Zoom" -- both in and out
|
||||
-- "Zoom In"
|
||||
-- "Zoom Out"
|
||||
-- "LocalRoll X"
|
||||
@@ -44,10 +45,10 @@ local PS4Controller = {
|
||||
RightThumbStick = { 2, 5 },
|
||||
LeftTrigger = 3,
|
||||
RightTrigger = 4,
|
||||
A = 3, -- Triangle
|
||||
B = 0, -- Square
|
||||
X = 2, -- Circle
|
||||
Y = 1, -- Cross
|
||||
A = 1, -- Cross
|
||||
B = 2, -- Circle
|
||||
X = 0, -- Square
|
||||
Y = 3, -- Triangle
|
||||
LB = 4,
|
||||
RB = 5,
|
||||
Select = 9, -- options
|
||||
@@ -62,6 +63,14 @@ local PS4Controller = {
|
||||
}
|
||||
}
|
||||
|
||||
local SpaceMouse = {
|
||||
Push = {0, 1, 2}, -- left/right, back/forth, up/down
|
||||
Twist = {5}, -- left/right
|
||||
Tilt = {4, 3}, -- left/right, back/forth
|
||||
LeftButton = 0,
|
||||
RightButton = 1
|
||||
}
|
||||
|
||||
-- Variables to store the state of the joystick between frames
|
||||
Joystick = {}
|
||||
Joystick.State = {}
|
||||
@@ -73,11 +82,11 @@ local bindLocalRoll = function(axis)
|
||||
-- We only want to store the current state in the first mode that is enabled, otherwise we will overwrite the backup
|
||||
if not Joystick.State.IsInRollMode then
|
||||
-- Save current axis state
|
||||
Joystick.State.Axis.Type, Joystick.State.Axis.Inverted, Joystick.State.Axis.Normalized = openspace.navigation.joystickAxis(]] .. axis .. [[)
|
||||
Joystick.State.Axis.Type, Joystick.State.Axis.Inverted, Joystick.State.Axis.Normalized, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity = openspace.navigation.joystickAxis(]] .. axis .. [[)
|
||||
end
|
||||
|
||||
-- Set new axis state
|
||||
openspace.navigation.bindJoystickAxis(]] .. axis .. [[, "LocalRoll X", true);
|
||||
openspace.navigation.bindJoystickAxis(]] .. axis .. [[, "LocalRoll X", Joystick.State.Axis.Inverted, Joystick.State.Axis.Normalized, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity);
|
||||
Joystick.State.IsInRollMode = true
|
||||
]]
|
||||
end
|
||||
@@ -87,88 +96,133 @@ local bindGlobalRoll = function(axis)
|
||||
-- We only want to store the current state in the first mode that is enabled, otherwise we will overwrite the backup
|
||||
if not Joystick.State.IsInRollMode then
|
||||
-- Save current axis state
|
||||
Joystick.State.Axis.Type, Joystick.State.Axis.Inverted, Joystick.State.Axis.Normalized = openspace.navigation.joystickAxis(]] .. axis .. [[)
|
||||
Joystick.State.Axis.Type, Joystick.State.Axis.Inverted, Joystick.State.Axis.Normalized, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity = openspace.navigation.joystickAxis(]] .. axis .. [[)
|
||||
end
|
||||
|
||||
-- Set new axis state
|
||||
openspace.navigation.bindJoystickAxis(]] .. axis .. [[, "GlobalRoll X", true);
|
||||
openspace.navigation.bindJoystickAxis(]] .. axis .. [[, "GlobalRoll X", Joystick.State.Axis.Inverted, Joystick.State.Axis.Normalized, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity);
|
||||
Joystick.State.IsInRollMode = true
|
||||
]]
|
||||
end
|
||||
|
||||
local permaBindLocalRoll = function(axis)
|
||||
return [[
|
||||
-- Save current axis state
|
||||
Joystick.State.Axis.Type, Joystick.State.Axis.Inverted, Joystick.State.Axis.Normalized, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity = openspace.navigation.joystickAxis(]] .. axis .. [[)
|
||||
|
||||
-- Set new axis state
|
||||
openspace.navigation.bindJoystickAxis(]] .. axis .. [[, "LocalRoll X", Joystick.State.Axis.Inverted, Joystick.State.Axis.Normalized, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity);
|
||||
]]
|
||||
end
|
||||
|
||||
local permaBindGlobalRoll = function(axis)
|
||||
return [[
|
||||
-- Save current axis state
|
||||
Joystick.State.Axis.Type, Joystick.State.Axis.Inverted, Joystick.State.Axis.Normalized, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity = openspace.navigation.joystickAxis(]] .. axis .. [[)
|
||||
|
||||
-- Set new axis state
|
||||
openspace.navigation.bindJoystickAxis(]] .. axis .. [[, "GlobalRoll X", Joystick.State.Axis.Inverted, Joystick.State.Axis.Normalized, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity);
|
||||
]]
|
||||
end
|
||||
|
||||
local unbindRoll = function(axis)
|
||||
return [[
|
||||
-- Reset previous state
|
||||
openspace.navigation.bindJoystickAxis(]] .. axis .. [[, Joystick.State.Axis.Type, Joystick.State.Axis.Inverted, Joystick.State.Axis.Normalized);
|
||||
openspace.navigation.bindJoystickAxis(]] .. axis .. [[, Joystick.State.Axis.Type, Joystick.State.Axis.Inverted, Joystick.State.Axis.Normalized, Joystick.State.Axis.Sticky, Joystick.State.Axis.Sensitivity);
|
||||
]]
|
||||
end
|
||||
|
||||
asset.onInitialize(function()
|
||||
-- Set the controller to the connected controller
|
||||
-- Currently: XBoxController or PS4Controller
|
||||
-- Currently: XBoxController, PS4Controller or SpaceMouse
|
||||
local controller = XBoxController;
|
||||
|
||||
openspace.navigation.setAxisDeadZone(controller.LeftThumbStick[1], 0.15)
|
||||
openspace.navigation.setAxisDeadZone(controller.LeftThumbStick[2], 0.15)
|
||||
openspace.navigation.setAxisDeadZone(controller.RightThumbStick[1], 0.15)
|
||||
openspace.navigation.setAxisDeadZone(controller.RightThumbStick[2], 0.15)
|
||||
openspace.navigation.setAxisDeadZone(controller.LeftTrigger, 0.15)
|
||||
openspace.navigation.setAxisDeadZone(controller.RightTrigger, 0.15)
|
||||
-- Case of XBoxController or PS4Controller
|
||||
if(controller.A ~= nil) then
|
||||
openspace.navigation.setAxisDeadZone(controller.LeftThumbStick[1], 0.15)
|
||||
openspace.navigation.setAxisDeadZone(controller.LeftThumbStick[2], 0.15)
|
||||
openspace.navigation.setAxisDeadZone(controller.RightThumbStick[1], 0.15)
|
||||
openspace.navigation.setAxisDeadZone(controller.RightThumbStick[2], 0.15)
|
||||
|
||||
openspace.navigation.bindJoystickAxis(controller.LeftThumbStick[1], "Orbit X");
|
||||
openspace.navigation.bindJoystickAxis(controller.LeftThumbStick[2], "Orbit Y", true);
|
||||
openspace.navigation.bindJoystickAxis(controller.RightThumbStick[1], "Pan X", true);
|
||||
openspace.navigation.bindJoystickAxis(controller.RightThumbStick[2], "Pan Y", true);
|
||||
openspace.navigation.bindJoystickAxis(controller.LeftTrigger, "Zoom Out", false, true);
|
||||
openspace.navigation.bindJoystickAxis(controller.RightTrigger, "Zoom In", false, true);
|
||||
openspace.navigation.bindJoystickAxis(controller.LeftThumbStick[1], "Orbit X");
|
||||
openspace.navigation.bindJoystickAxis(controller.LeftThumbStick[2], "Orbit Y", true);
|
||||
openspace.navigation.bindJoystickAxis(controller.RightThumbStick[1], "Pan X", true);
|
||||
openspace.navigation.bindJoystickAxis(controller.RightThumbStick[2], "Pan Y", true);
|
||||
openspace.navigation.bindJoystickAxis(controller.LeftTrigger, "Zoom Out", false, true);
|
||||
openspace.navigation.bindJoystickAxis(controller.RightTrigger, "Zoom In", false, true);
|
||||
|
||||
openspace.navigation.bindJoystickButton(
|
||||
controller.LB,
|
||||
bindLocalRoll(controller.RightThumbStick[1]),
|
||||
"Switch to local roll mode"
|
||||
)
|
||||
openspace.navigation.bindJoystickButton(
|
||||
controller.LB,
|
||||
unbindRoll(controller.RightThumbStick[1]),
|
||||
"Switch back to normal mode",
|
||||
"Release"
|
||||
)
|
||||
openspace.navigation.bindJoystickButton(
|
||||
controller.RB,
|
||||
bindGlobalRoll(controller.RightThumbStick[1]),
|
||||
"Switch to global roll mode"
|
||||
)
|
||||
openspace.navigation.bindJoystickButton(
|
||||
controller.RB,
|
||||
unbindRoll(controller.RightThumbStick[1]),
|
||||
"Switch back to normal mode",
|
||||
"Release"
|
||||
)
|
||||
openspace.navigation.bindJoystickButton(
|
||||
controller.LB,
|
||||
bindLocalRoll(controller.RightThumbStick[1]),
|
||||
"Switch to local roll mode"
|
||||
)
|
||||
openspace.navigation.bindJoystickButton(
|
||||
controller.LB,
|
||||
unbindRoll(controller.RightThumbStick[1]),
|
||||
"Switch back to normal mode",
|
||||
"Release"
|
||||
)
|
||||
openspace.navigation.bindJoystickButton(
|
||||
controller.RB,
|
||||
bindGlobalRoll(controller.RightThumbStick[1]),
|
||||
"Switch to global roll mode"
|
||||
)
|
||||
openspace.navigation.bindJoystickButton(
|
||||
controller.RB,
|
||||
unbindRoll(controller.RightThumbStick[1]),
|
||||
"Switch back to normal mode",
|
||||
"Release"
|
||||
)
|
||||
|
||||
openspace.navigation.bindJoystickButton(
|
||||
controller.A,
|
||||
propertyHelper.invert('NavigationHandler.OrbitalNavigator.Friction.ZoomFriction'),
|
||||
"Toggle zoom friction"
|
||||
)
|
||||
openspace.navigation.bindJoystickButton(
|
||||
controller.B,
|
||||
propertyHelper.invert('NavigationHandler.OrbitalNavigator.Friction.RotationalFriction'),
|
||||
"Toggle rotational friction"
|
||||
)
|
||||
openspace.navigation.bindJoystickButton(
|
||||
controller.DPad.Left,
|
||||
propertyHelper.invert('NavigationHandler.OrbitalNavigator.Friction.RollFriction'),
|
||||
"Toggle roll friction"
|
||||
)
|
||||
openspace.navigation.bindJoystickButton(
|
||||
controller.A,
|
||||
propertyHelper.invert('NavigationHandler.OrbitalNavigator.Friction.ZoomFriction'),
|
||||
"Toggle zoom friction"
|
||||
)
|
||||
openspace.navigation.bindJoystickButton(
|
||||
controller.B,
|
||||
propertyHelper.invert('NavigationHandler.OrbitalNavigator.Friction.RotationalFriction'),
|
||||
"Toggle rotational friction"
|
||||
)
|
||||
openspace.navigation.bindJoystickButton(
|
||||
controller.DPad.Left,
|
||||
propertyHelper.invert('NavigationHandler.OrbitalNavigator.Friction.RollFriction'),
|
||||
"Toggle roll friction"
|
||||
)
|
||||
|
||||
openspace.navigation.bindJoystickButton(
|
||||
controller.X,
|
||||
"openspace.setPropertyValue('NavigationHandler.Origin', 'Earth')",
|
||||
"Switch target to Earth"
|
||||
)
|
||||
openspace.navigation.bindJoystickButton(
|
||||
controller.Y,
|
||||
"openspace.setPropertyValue('NavigationHandler.Origin', 'Mars')",
|
||||
"Switch target to Mars"
|
||||
)
|
||||
openspace.navigation.bindJoystickButton(
|
||||
controller.X,
|
||||
"openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.Aim', '');" ..
|
||||
"openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.Anchor', 'Earth');" ..
|
||||
"openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil);",
|
||||
"Switch target to Earth"
|
||||
)
|
||||
openspace.navigation.bindJoystickButton(
|
||||
controller.Y,
|
||||
"openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.Aim', '');" ..
|
||||
"openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.Anchor', 'Mars');" ..
|
||||
"openspace.setPropertyValueSingle('NavigationHandler.OrbitalNavigator.RetargetAnchor', nil);",
|
||||
"Switch target to Mars"
|
||||
)
|
||||
-- Case of SpaceMouse
|
||||
elseif (controller.LeftButton ~= nil) then
|
||||
openspace.navigation.bindJoystickAxis(controller.Push[1], "Orbit X", false, false, true, 40.0);
|
||||
openspace.navigation.bindJoystickAxis(controller.Push[2], "Orbit Y", false, false, true, 40.0);
|
||||
openspace.navigation.bindJoystickAxis(controller.Twist[1], "Pan X", true, false, true, 40.0);
|
||||
openspace.navigation.bindJoystickAxis(controller.Tilt[2], "Pan Y", false, false, true, 35.0);
|
||||
openspace.navigation.bindJoystickAxis(controller.Push[3], "Zoom", false, false, true, 40.0);
|
||||
openspace.navigation.bindJoystickAxis(controller.Tilt[1], "LocalRoll X", false, false, true, 35.0);
|
||||
|
||||
openspace.navigation.bindJoystickButton(
|
||||
controller.LeftButton,
|
||||
permaBindLocalRoll(controller.Tilt[1]),
|
||||
"Switch to local roll mode"
|
||||
)
|
||||
|
||||
openspace.navigation.bindJoystickButton(
|
||||
controller.RightButton,
|
||||
permaBindGlobalRoll(controller.Tilt[1]),
|
||||
"Switch to global roll mode"
|
||||
)
|
||||
end
|
||||
end)
|
||||
|
||||
@@ -36,7 +36,7 @@ local Keybindings = {
|
||||
{
|
||||
Key = "SPACE",
|
||||
Name = "Toggle Pause (Interpolated)",
|
||||
Command = "openspace.time.interpolateTogglePause()",
|
||||
Command = "openspace.time.pauseToggleViaKeyboard()",
|
||||
Documentation = "Smoothly starts and stops the simulation time.",
|
||||
GuiPath = "/Simulation Speed",
|
||||
Local = true
|
||||
|
||||
@@ -93,7 +93,7 @@ struct TestResult {
|
||||
|
||||
|
||||
/// Is \c true if the TestResult is positive, \c false otherwise
|
||||
bool success;
|
||||
bool success = false;
|
||||
/// Contains a list of offenses that were found in the test. Is empty if
|
||||
/// TestResult::Success is \c true
|
||||
std::vector<Offense> offenses;
|
||||
|
||||
@@ -43,6 +43,7 @@ public:
|
||||
OrbitY,
|
||||
ZoomIn,
|
||||
ZoomOut,
|
||||
Zoom,
|
||||
LocalRollX,
|
||||
LocalRollY,
|
||||
GlobalRollX,
|
||||
@@ -60,7 +61,15 @@ public:
|
||||
AxisInvert invert = AxisInvert::No;
|
||||
AxisNormalize normalize = AxisNormalize::No;
|
||||
|
||||
// The axis values can either go back to 0 when the joystick is released or it can
|
||||
// stay at the value it was before the joystick was released.
|
||||
// The latter is called a sticky axis, when the values don't go back to 0.
|
||||
bool isSticky = false;
|
||||
|
||||
float deadzone = 0.f;
|
||||
|
||||
// Every axis can have their own sensitivity
|
||||
double sensitivity = 0.0;
|
||||
};
|
||||
|
||||
JoystickCameraStates(double sensitivity, double velocityScaleFactor);
|
||||
@@ -69,7 +78,8 @@ public:
|
||||
|
||||
void setAxisMapping(int axis, AxisType mapping,
|
||||
AxisInvert shouldInvert = AxisInvert::No,
|
||||
AxisNormalize shouldNormalize = AxisNormalize::No
|
||||
AxisNormalize shouldNormalize = AxisNormalize::No,
|
||||
bool isSticky = false, double sensitivity = 0.0
|
||||
);
|
||||
|
||||
AxisInformation axisMapping(int axis) const;
|
||||
@@ -91,6 +101,10 @@ private:
|
||||
|
||||
std::array<AxisInformation, JoystickInputState::MaxAxes> _axisMapping;
|
||||
|
||||
// This array is used to store the old axis values from the previous frame,
|
||||
// it is used to calculate the difference in the values in the case of a sticky axis
|
||||
std::array<float, JoystickInputState::MaxAxes> _prevAxisValues;
|
||||
|
||||
struct ButtonInformation {
|
||||
std::string command;
|
||||
JoystickAction action;
|
||||
@@ -135,6 +149,7 @@ from_string(std::string_view string)
|
||||
if (string == "None") { return T::None; }
|
||||
if (string == "Orbit X") { return T::OrbitX; }
|
||||
if (string == "Orbit Y") { return T::OrbitY; }
|
||||
if (string == "Zoom") { return T::Zoom; }
|
||||
if (string == "Zoom In") { return T::ZoomIn; }
|
||||
if (string == "Zoom Out") { return T::ZoomOut; }
|
||||
if (string == "LocalRoll X") { return T::LocalRollX; }
|
||||
|
||||
@@ -71,6 +71,11 @@ struct JoystickInputState {
|
||||
/// \c nAxes values are defined values, the rest are undefined
|
||||
std::array<float, MaxAxes> axes;
|
||||
|
||||
/// The axis values can either go back to 0 when the joystick is released or it can
|
||||
/// stay at the value it was before the joystick was released.
|
||||
/// The latter is called a sticky axis, when the values don't go back to 0.
|
||||
bool isSticky = false;
|
||||
|
||||
/// The number of buttons that this joystick possesses
|
||||
int nButtons = 0;
|
||||
/// The status of each button. Only the first \c nButtons values are defined, the rest
|
||||
|
||||
@@ -115,7 +115,8 @@ public:
|
||||
JoystickCameraStates::AxisInvert shouldInvert =
|
||||
JoystickCameraStates::AxisInvert::No,
|
||||
JoystickCameraStates::AxisNormalize shouldNormalize =
|
||||
JoystickCameraStates::AxisNormalize::No
|
||||
JoystickCameraStates::AxisNormalize::No,
|
||||
bool isSticky = false, double sensitivity = 0.0
|
||||
);
|
||||
|
||||
JoystickCameraStates::AxisInformation joystickAxisMapping(int axis) const;
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
#include <openspace/properties/scalar/boolproperty.h>
|
||||
#include <openspace/scripting/lualibrary.h>
|
||||
#include <vector>
|
||||
#include <chrono>
|
||||
|
||||
namespace openspace::interaction {
|
||||
|
||||
@@ -60,7 +61,8 @@ public:
|
||||
enum class SessionState {
|
||||
Idle = 0,
|
||||
Recording,
|
||||
Playback
|
||||
Playback,
|
||||
PlaybackPaused
|
||||
};
|
||||
|
||||
struct Timestamps {
|
||||
@@ -69,6 +71,18 @@ public:
|
||||
double timeSim;
|
||||
};
|
||||
|
||||
/*
|
||||
* Struct for storing a script substring that, if found in a saved script,
|
||||
* will be replaced by its substringReplacement counterpart.
|
||||
*/
|
||||
struct ScriptSubstringReplace {
|
||||
std::string substringFound;
|
||||
std::string substringReplacement;
|
||||
ScriptSubstringReplace(std::string found, std::string replace)
|
||||
: substringFound(found)
|
||||
, substringReplacement(replace) {};
|
||||
};
|
||||
|
||||
static const size_t FileHeaderVersionLength = 5;
|
||||
char FileHeaderVersion[FileHeaderVersionLength+1] = "01.00";
|
||||
char TargetConvertVersion[FileHeaderVersionLength+1] = "01.00";
|
||||
@@ -117,6 +131,20 @@ public:
|
||||
*/
|
||||
double fixedDeltaTimeDuringFrameOutput() const;
|
||||
|
||||
/**
|
||||
* Returns the number of microseconds that have elapsed since playback started, if
|
||||
* playback is set to be in the mode where a screenshot is captured with every
|
||||
* rendered frame (enableTakeScreenShotDuringPlayback() is used to enable this mode).
|
||||
* At the start of playback, this timer is set to the current steady_clock value.
|
||||
* However, during playback it is incremented by the fixed framerate of the playback
|
||||
* rather than the actual clock value (as in normal operation).
|
||||
*
|
||||
* \returns number of microseconds elapsed since playback started in terms of the
|
||||
* number of rendered frames multiplied by the fixed time increment per
|
||||
* frame
|
||||
*/
|
||||
std::chrono::steady_clock::time_point currentPlaybackInterpolationTime() const;
|
||||
|
||||
/**
|
||||
* Starts a recording session, which will save data to the provided filename
|
||||
* according to the data format specified, and will continue until recording is
|
||||
@@ -154,16 +182,20 @@ public:
|
||||
/**
|
||||
* Starts a playback session, which can run in one of three different time modes.
|
||||
*
|
||||
* \param filename file containing recorded keyframes to play back
|
||||
* \param filename file containing recorded keyframes to play back. The file path
|
||||
* is relative to the base recordings directory specified in the
|
||||
* config file by the RECORDINGS variable
|
||||
* \param timeMode which of the 3 time modes to use for time reference during
|
||||
* \param forceSimTimeAtStart if true simulation time is forced to that of playback
|
||||
* playback: recorded time, application time, or simulation time. See the
|
||||
* LuaLibrary entry for SessionRecording for details on these time modes
|
||||
* \param loop if true then the file will playback in loop mode, continuously
|
||||
* looping back to the beginning until it is manually stopped
|
||||
*
|
||||
* \return \c true if recording to file starts without errors
|
||||
*/
|
||||
bool startPlayback(std::string& filename, KeyframeTimeRef timeMode,
|
||||
bool forceSimTimeAtStart);
|
||||
bool forceSimTimeAtStart, bool loop);
|
||||
|
||||
/**
|
||||
* Used to stop a playback in progress. If open, the playback file will be closed,
|
||||
@@ -171,6 +203,22 @@ public:
|
||||
*/
|
||||
void stopPlayback();
|
||||
|
||||
/**
|
||||
* Returns playback pause status.
|
||||
*
|
||||
* \return \c true if playback is paused
|
||||
*/
|
||||
bool isPlaybackPaused();
|
||||
|
||||
/**
|
||||
* Pauses a playback session. This does both the normal pause functionality of
|
||||
* setting simulation delta time to zero, and pausing the progression through the
|
||||
* timeline.
|
||||
*
|
||||
* \param pause if true, then will set playback timeline progression to zero
|
||||
*/
|
||||
void setPlaybackPause(bool pause);
|
||||
|
||||
/**
|
||||
* Enables that rendered frames should be saved during playback
|
||||
* \param fps Number of frames per second.
|
||||
@@ -205,13 +253,13 @@ public:
|
||||
* whether it is following the rotation of a node, and timestamp). The data will be
|
||||
* saved to the recording file only if a recording is currently in progress.
|
||||
*/
|
||||
void saveCameraKeyframe();
|
||||
void saveCameraKeyframeToTimeline();
|
||||
|
||||
/**
|
||||
* Used to trigger a save of the current timing states. The data will be saved to the
|
||||
* recording file only if a recording is currently in progress.
|
||||
*/
|
||||
void saveTimeKeyframe();
|
||||
void saveTimeKeyframeToTimeline();
|
||||
|
||||
/**
|
||||
* Used to trigger a save of a script to the recording file, but only if a recording
|
||||
@@ -219,7 +267,7 @@ public:
|
||||
*
|
||||
* \param scriptToSave String of the Lua command to be saved
|
||||
*/
|
||||
void saveScriptKeyframe(std::string scriptToSave);
|
||||
void saveScriptKeyframeToTimeline(std::string scriptToSave);
|
||||
|
||||
/**
|
||||
* \return The Lua library that contains all Lua functions available to affect the
|
||||
@@ -405,6 +453,19 @@ public:
|
||||
void saveScriptKeyframeAscii(Timestamps& times,
|
||||
datamessagestructures::ScriptMessage& sm, std::ofstream& file);
|
||||
|
||||
/**
|
||||
* Since session recordings only record changes, the initial conditions aren't
|
||||
* preserved when a playback starts. This function is called whenever a property
|
||||
* value is set and a recording is in progress. Before the set happens, this
|
||||
* function will read the current value of the property and store it so that when
|
||||
* the recording is finished, the initial state will be added as a set property
|
||||
* command at the beginning of the recording file, to be applied when playback
|
||||
* starts.
|
||||
*
|
||||
* \param prop The property being set
|
||||
*/
|
||||
void savePropertyBaseline(properties::Property& prop);
|
||||
|
||||
/**
|
||||
* Reads header information from a session recording file
|
||||
*
|
||||
@@ -524,17 +585,20 @@ protected:
|
||||
struct timelineEntry {
|
||||
RecordedType keyframeType;
|
||||
unsigned int idxIntoKeyframeTypeArray;
|
||||
double timestamp;
|
||||
Timestamps t3stamps;
|
||||
};
|
||||
ExternInteraction _externInteract;
|
||||
double _timestampRecordStarted = 0.0;
|
||||
Timestamps _timestamps3RecordStarted;
|
||||
double _timestampPlaybackStarted_application = 0.0;
|
||||
double _timestampPlaybackStarted_simulation = 0.0;
|
||||
double _timestampApplicationStarted_simulation = 0.0;
|
||||
bool hasCameraChangedFromPrev(datamessagestructures::CameraKeyframe kfNew);
|
||||
double appropriateTimestamp(double timeOs, double timeRec, double timeSim);
|
||||
double appropriateTimestamp(Timestamps t3stamps);
|
||||
double equivalentSimulationTime(double timeOs, double timeRec, double timeSim);
|
||||
double equivalentApplicationTime(double timeOs, double timeRec, double timeSim);
|
||||
void recordCurrentTimePauseState();
|
||||
void recordCurrentTimeRate();
|
||||
bool handleRecordingFile(std::string filenameIn);
|
||||
static bool isPath(std::string& filename);
|
||||
void removeTrailingPathSlashes(std::string& filename);
|
||||
@@ -544,19 +608,26 @@ protected:
|
||||
bool playbackScript();
|
||||
bool playbackAddEntriesToTimeline();
|
||||
void signalPlaybackFinishedForComponent(RecordedType type);
|
||||
void findFirstCameraKeyframeInTimeline();
|
||||
bool findFirstCameraKeyframeInTimeline();
|
||||
Timestamps generateCurrentTimestamp3(double keyframeTime);
|
||||
static void saveStringToFile(const std::string& s, unsigned char* kfBuffer,
|
||||
size_t& idx, std::ofstream& file);
|
||||
static void saveKeyframeToFileBinary(unsigned char* bufferSource, size_t size,
|
||||
std::ofstream& file);
|
||||
|
||||
bool addKeyframe(double timestamp,
|
||||
bool addKeyframe(Timestamps t3stamps,
|
||||
interaction::KeyframeNavigator::CameraPose keyframe, int lineNum);
|
||||
bool addKeyframe(double timestamp, datamessagestructures::TimeKeyframe keyframe,
|
||||
int lineNum);
|
||||
bool addKeyframe(double timestamp, std::string scriptToQueue, int lineNum);
|
||||
bool addKeyframeToTimeline(RecordedType type, size_t indexIntoTypeKeyframes,
|
||||
double timestamp, int lineNum);
|
||||
bool addKeyframe(Timestamps t3stamps,
|
||||
datamessagestructures::TimeKeyframe keyframe, int lineNum);
|
||||
bool addKeyframe(Timestamps t3stamps,
|
||||
std::string scriptToQueue, int lineNum);
|
||||
bool addKeyframeToTimeline(std::vector<timelineEntry>& timeline, RecordedType type,
|
||||
size_t indexIntoTypeKeyframes, Timestamps t3stamps, int lineNum);
|
||||
|
||||
void initializePlayback_time(double now);
|
||||
void initializePlayback_modeFlags();
|
||||
bool initializePlayback_timeline();
|
||||
void initializePlayback_triggerStart();
|
||||
void moveAheadInTime();
|
||||
void lookForNonCameraKeyframesThatHaveComeDue(double currTime);
|
||||
void updateCameraWithOrWithoutNewKeyframes(double currTime);
|
||||
@@ -580,9 +651,14 @@ protected:
|
||||
const int lineNum);
|
||||
void saveSingleKeyframeScript(datamessagestructures::ScriptMessage& kf,
|
||||
Timestamps& times, DataMode mode, std::ofstream& file, unsigned char* buffer);
|
||||
void saveScriptKeyframeToPropertiesBaseline(std::string script);
|
||||
bool isPropertyAllowedForBaseline(const std::string& propString);
|
||||
unsigned int findIndexOfLastCameraKeyframeInTimeline();
|
||||
bool doesTimelineEntryContainCamera(unsigned int index) const;
|
||||
std::vector<std::pair<CallbackHandle, StateChangeCallback>> _stateChangeCallbacks;
|
||||
bool doesStartWithSubstring(const std::string& s, const std::string& matchSubstr);
|
||||
void trimCommandsFromScriptIfFound(std::string& script);
|
||||
void replaceCommandsFromScriptIfFound(std::string& script);
|
||||
|
||||
RecordedType getNextKeyframeType();
|
||||
RecordedType getPrevKeyframeType();
|
||||
@@ -600,6 +676,14 @@ protected:
|
||||
DataMode readModeFromHeader(std::string filename);
|
||||
void readPlaybackHeader_stream(std::stringstream& conversionInStream,
|
||||
std::string& version, DataMode& mode);
|
||||
void populateListofLoadedSceneGraphNodes();
|
||||
|
||||
bool checkIfScriptUsesScenegraphNode(std::string s);
|
||||
void checkForScenegraphNodeAccess_Scene(std::string& s, std::string& result);
|
||||
void checkForScenegraphNodeAccess_Nav(std::string& s, std::string& result);
|
||||
bool checkIfInitialFocusNodeIsLoaded(unsigned int firstCamIndex);
|
||||
void eraseSpacesFromString(std::string& s);
|
||||
std::string getNameFromSurroundingQuotes(std::string& s);
|
||||
|
||||
static void writeToFileBuffer(unsigned char* buf, size_t& idx, double src);
|
||||
static void writeToFileBuffer(unsigned char* buf, size_t& idx, std::vector<char>& cv);
|
||||
@@ -616,27 +700,78 @@ protected:
|
||||
std::string _playbackLineParsing;
|
||||
std::ofstream _recordFile;
|
||||
int _playbackLineNum = 1;
|
||||
int _recordingEntryNum = 1;
|
||||
KeyframeTimeRef _playbackTimeReferenceMode;
|
||||
datamessagestructures::CameraKeyframe _prevRecordedCameraKeyframe;
|
||||
bool _playbackActive_camera = false;
|
||||
bool _playbackActive_time = false;
|
||||
bool _playbackActive_script = false;
|
||||
bool _hasHitEndOfCameraKeyframes = false;
|
||||
bool _setSimulationTimeWithNextCameraKeyframe = false;
|
||||
bool _playbackPausedWithinDeltaTimePause = false;
|
||||
bool _playbackLoopMode = false;
|
||||
bool _playbackForceSimTimeAtStart = false;
|
||||
double _playbackPauseOffset = 0.0;
|
||||
double _previousTime = 0.0;
|
||||
|
||||
bool _saveRenderingDuringPlayback = false;
|
||||
double _saveRenderingDeltaTime = 1.0 / 30.0;
|
||||
double _saveRenderingCurrentRecordedTime;
|
||||
std::chrono::steady_clock::duration _saveRenderingDeltaTime_interpolation_usec;
|
||||
std::chrono::steady_clock::time_point _saveRenderingCurrentRecordedTime_interpolation;
|
||||
long long _saveRenderingClockInterpolation_countsPerSec;
|
||||
bool _saveRendering_isFirstFrame = true;
|
||||
|
||||
unsigned char _keyframeBuffer[_saveBufferMaxSize_bytes];
|
||||
|
||||
bool _cleanupNeeded = false;
|
||||
const std::string scriptReturnPrefix = "return ";
|
||||
|
||||
std::vector<interaction::KeyframeNavigator::CameraPose> _keyframesCamera;
|
||||
std::vector<datamessagestructures::TimeKeyframe> _keyframesTime;
|
||||
std::vector<std::string> _keyframesScript;
|
||||
std::vector<timelineEntry> _timeline;
|
||||
|
||||
std::vector<std::string> _keyframesSavePropertiesBaseline_scripts;
|
||||
std::vector<timelineEntry> _keyframesSavePropertiesBaseline_timeline;
|
||||
std::vector<std::string> _propertyBaselinesSaved;
|
||||
const std::vector<std::string> _propertyBaselineRejects = {
|
||||
"NavigationHandler.OrbitalNavigator.Anchor",
|
||||
"NavigationHandler.OrbitalNavigator.Aim",
|
||||
"NavigationHandler.OrbitalNavigator.RetargetAnchor",
|
||||
"NavigationHandler.OrbitalNavigator.RetargetAim"
|
||||
};
|
||||
//A script that begins with an exact match of any of the strings contained in
|
||||
// _scriptRejects will not be recorded
|
||||
const std::vector<std::string> _scriptRejects = {
|
||||
"openspace.sessionRecording.enableTakeScreenShotDuringPlayback",
|
||||
"openspace.sessionRecording.startPlayback",
|
||||
"openspace.sessionRecording.stopPlayback",
|
||||
"openspace.sessionRecording.startRecording",
|
||||
"openspace.sessionRecording.stopRecording",
|
||||
"openspace.scriptScheduler.clear"
|
||||
};
|
||||
const std::vector<std::string> _navScriptsUsingNodes = {
|
||||
"RetargetAnchor",
|
||||
"Anchor",
|
||||
"Aim"
|
||||
};
|
||||
//Any script snippet included in this vector will be trimmed from any script
|
||||
// from the script manager, before it is recorded in the session recording file.
|
||||
// The remainder of the script will be retained.
|
||||
const std::vector<std::string> _scriptsToBeTrimmed = {
|
||||
"openspace.sessionRecording.togglePlaybackPause"
|
||||
};
|
||||
//Any script snippet included in this vector will be trimmed from any script
|
||||
// from the script manager, before it is recorded in the session recording file.
|
||||
// The remainder of the script will be retained.
|
||||
const std::vector<ScriptSubstringReplace> _scriptsToBeReplaced = {
|
||||
{
|
||||
"openspace.time.pauseToggleViaKeyboard",
|
||||
"openspace.time.interpolateTogglePause"
|
||||
}
|
||||
};
|
||||
std::vector<std::string> _loadedNodes;
|
||||
|
||||
unsigned int _idxTimeline_nonCamera = 0;
|
||||
unsigned int _idxTime = 0;
|
||||
unsigned int _idxScript = 0;
|
||||
|
||||
@@ -49,6 +49,14 @@ struct CameraKeyframe {
|
||||
CameraKeyframe(const std::vector<char>& buffer) {
|
||||
deserialize(buffer);
|
||||
}
|
||||
CameraKeyframe(glm::dvec3&& pos, glm::dquat&& rot, std::string&& focusNode,
|
||||
bool&& followNodeRot, float&& scale)
|
||||
: _position(pos)
|
||||
, _rotation(rot)
|
||||
, _followNodeRotation(followNodeRot)
|
||||
, _focusNode(focusNode)
|
||||
, _scale(scale)
|
||||
{}
|
||||
|
||||
glm::dvec3 _position = glm::dvec3(0.0);
|
||||
glm::dquat _rotation = glm::dquat(1.0, 0.0, 0.0, 0.0);
|
||||
|
||||
@@ -25,6 +25,7 @@
|
||||
#ifndef __OPENSPACE_CORE___DEFERREDCASTER___H
|
||||
#define __OPENSPACE_CORE___DEFERREDCASTER___H
|
||||
|
||||
#include <filesystem>
|
||||
#include <string>
|
||||
|
||||
namespace ghoul::opengl {
|
||||
@@ -46,31 +47,30 @@ public:
|
||||
const DeferredcastData& /*deferredData*/,
|
||||
ghoul::opengl::ProgramObject& /*program*/) {};
|
||||
|
||||
virtual void postRaycast(const RenderData & /*renderData*/,
|
||||
virtual void postRaycast(const RenderData& /*renderData*/,
|
||||
const DeferredcastData& /*deferredData*/,
|
||||
ghoul::opengl::ProgramObject& /*program*/) {};
|
||||
|
||||
virtual std::string deferredcastPath() const = 0;
|
||||
virtual std::filesystem::path deferredcastPath() const = 0;
|
||||
|
||||
virtual std::string deferredcastVSPath() const = 0;
|
||||
virtual std::filesystem::path deferredcastVSPath() const = 0;
|
||||
|
||||
virtual std::string deferredcastFSPath() const = 0;
|
||||
virtual std::filesystem::path deferredcastFSPath() const = 0;
|
||||
|
||||
virtual void initializeCachedVariables(ghoul::opengl::ProgramObject&) = 0;
|
||||
|
||||
virtual void update(const UpdateData&) = 0;
|
||||
|
||||
/**
|
||||
* Return a path to a glsl file with helper functions required for the
|
||||
* transformation and raycast steps.
|
||||
* This file will be included once per shader program generated,
|
||||
* regardless of how many volumes say they require the file.
|
||||
* Ideal to avoid redefinitions of helper functions.
|
||||
* Return a path to a GLSL file with helper functions required for the transformation
|
||||
* and raycast steps. This file will be included once per shader program generated,
|
||||
* regardless of how many volumes say they require the file. Ideal to avoid
|
||||
* redefinitions of helper functions.
|
||||
*
|
||||
* The shader preprocessor will have access to the #{namespace} variable (unique per
|
||||
* helper file) which should be a prefix to all symbols defined by the helper
|
||||
*/
|
||||
virtual std::string helperPath() const = 0;
|
||||
virtual std::filesystem::path helperPath() const = 0;
|
||||
};
|
||||
|
||||
} // namespace openspace
|
||||
|
||||
@@ -109,7 +109,7 @@ protected:
|
||||
properties::TriggerProperty _delete;
|
||||
|
||||
glm::ivec2 _objectSize = glm::ivec2(0);
|
||||
UniformCache(color, alpha, modelTransform, viewProj, texture) _uniformCache;
|
||||
UniformCache(color, opacity, mvp, texture) _uniformCache;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _shader;
|
||||
};
|
||||
|
||||
|
||||
@@ -92,7 +92,7 @@ public:
|
||||
Relative
|
||||
};
|
||||
|
||||
Type type;
|
||||
Type type = Type::Absolute;
|
||||
std::string value;
|
||||
};
|
||||
struct CameraNavState {
|
||||
|
||||
@@ -47,8 +47,8 @@ struct Keyframe : public KeyframeBase {
|
||||
Keyframe(size_t i, double t, T d);
|
||||
|
||||
Keyframe(Keyframe const&) = default;
|
||||
Keyframe(Keyframe&&) = default;
|
||||
Keyframe& operator=(Keyframe&&) = default;
|
||||
Keyframe(Keyframe&&) noexcept = default;
|
||||
Keyframe& operator=(Keyframe&&) noexcept = default;
|
||||
Keyframe& operator=(Keyframe const&) = default;
|
||||
T data;
|
||||
};
|
||||
|
||||
@@ -40,7 +40,7 @@ namespace openspace {
|
||||
|
||||
struct TimeKeyframeData {
|
||||
Time time;
|
||||
double delta;
|
||||
double delta = 0.0;
|
||||
bool pause = false;
|
||||
bool jump = false;
|
||||
};
|
||||
|
||||
@@ -40,30 +40,17 @@ set(SHADER_FILES
|
||||
shaders/atmosphere_common.glsl
|
||||
shaders/atmosphere_deferred_vs.glsl
|
||||
shaders/atmosphere_deferred_fs.glsl
|
||||
shaders/deltaE_calc_vs.glsl
|
||||
shaders/calculation_gs.glsl
|
||||
shaders/calculation_vs.glsl
|
||||
shaders/deltaE_calc_fs.glsl
|
||||
shaders/deltaJ_calc_vs.glsl
|
||||
shaders/deltaJ_calc_fs.glsl
|
||||
shaders/deltaJ_calc_gs.glsl
|
||||
shaders/deltaS_calc_vs.glsl
|
||||
shaders/deltaS_calc_gs.glsl
|
||||
shaders/deltaS_calc_fs.glsl
|
||||
shaders/deltaS_sup_calc_vs.glsl
|
||||
shaders/deltaS_sup_calc_gs.glsl
|
||||
shaders/deltaS_sup_calc_fs.glsl
|
||||
shaders/inScattering_calc_vs.glsl
|
||||
shaders/inScattering_calc_gs.glsl
|
||||
shaders/inScattering_calc_fs.glsl
|
||||
shaders/inScattering_sup_calc_vs.glsl
|
||||
shaders/inScattering_sup_calc_gs.glsl
|
||||
shaders/inScattering_sup_calc_fs.glsl
|
||||
shaders/irradiance_calc_vs.glsl
|
||||
shaders/irradiance_calc_fs.glsl
|
||||
shaders/irradiance_final_vs.glsl
|
||||
shaders/irradiance_final_fs.glsl
|
||||
shaders/irradiance_sup_calc_vs.glsl
|
||||
shaders/irradiance_sup_calc_fs.glsl
|
||||
shaders/transmittance_calc_vs.glsl
|
||||
shaders/transmittance_calc_fs.glsl
|
||||
)
|
||||
source_group("Shader Files" FILES ${SHADER_FILES})
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -31,7 +31,6 @@
|
||||
#include <ghoul/glm.h>
|
||||
#include <ghoul/opengl/textureunit.h>
|
||||
#include <ghoul/opengl/uniformcache.h>
|
||||
|
||||
#include <string>
|
||||
#include <vector>
|
||||
|
||||
@@ -46,6 +45,16 @@ struct RenderData;
|
||||
struct DeferredcastData;
|
||||
struct ShadowConfiguration;
|
||||
|
||||
struct ShadowRenderingStruct {
|
||||
double xu = 0.0;
|
||||
double xp = 0.0;
|
||||
double rs = 0.0;
|
||||
double rc = 0.0;
|
||||
glm::dvec3 sourceCasterVec = glm::dvec3(0.0);
|
||||
glm::dvec3 casterPositionVec = glm::dvec3(0.0);
|
||||
bool isShadowing = false;
|
||||
};
|
||||
|
||||
class AtmosphereDeferredcaster : public Deferredcaster {
|
||||
public:
|
||||
virtual ~AtmosphereDeferredcaster() = default;
|
||||
@@ -53,27 +62,27 @@ public:
|
||||
void initialize();
|
||||
void deinitialize();
|
||||
void preRaycast(const RenderData& renderData, const DeferredcastData& deferredData,
|
||||
ghoul::opengl::ProgramObject& program) override;
|
||||
ghoul::opengl::ProgramObject& program) override;
|
||||
void postRaycast(const RenderData& renderData, const DeferredcastData& deferredData,
|
||||
ghoul::opengl::ProgramObject& program) override;
|
||||
ghoul::opengl::ProgramObject& program) override;
|
||||
|
||||
std::string deferredcastPath() const override;
|
||||
std::string deferredcastVSPath() const override;
|
||||
std::string deferredcastFSPath() const override;
|
||||
std::string helperPath() const override;
|
||||
std::filesystem::path deferredcastPath() const override;
|
||||
std::filesystem::path deferredcastVSPath() const override;
|
||||
std::filesystem::path deferredcastFSPath() const override;
|
||||
std::filesystem::path helperPath() const override;
|
||||
|
||||
void initializeCachedVariables(ghoul::opengl::ProgramObject&) override;
|
||||
void initializeCachedVariables(ghoul::opengl::ProgramObject& program) override;
|
||||
|
||||
void update(const UpdateData&) override;
|
||||
|
||||
void preCalculateAtmosphereParam();
|
||||
|
||||
void setModelTransform(const glm::dmat4 &transform);
|
||||
void setModelTransform(glm::dmat4 transform);
|
||||
void setTime(double time);
|
||||
void setAtmosphereRadius(float atmRadius);
|
||||
void setPlanetRadius(float planetRadius);
|
||||
void setPlanetAverageGroundReflectance(float averageGReflectance);
|
||||
void setPlanetGroundRadianceEmittion(float groundRadianceEmittion);
|
||||
void setPlanetGroundRadianceEmission(float groundRadianceEmission);
|
||||
void setRayleighHeightScale(float rayleighHeightScale);
|
||||
void enableOzone(bool enable);
|
||||
void setOzoneHeightScale(float ozoneHeightScale);
|
||||
@@ -100,20 +109,9 @@ private:
|
||||
void deleteUnusedComputationTextures();
|
||||
void executeCalculations(GLuint quadCalcVAO, GLenum drawBuffers[1],
|
||||
GLsizei vertexSize);
|
||||
void step3DTexture(std::unique_ptr<ghoul::opengl::ProgramObject>& shaderProg,
|
||||
int layer, bool doCalculation = true);
|
||||
void checkFrameBufferState(const std::string& codePosition) const;
|
||||
void loadAtmosphereDataIntoShaderProgram(
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> & shaderProg
|
||||
);
|
||||
void renderQuadForCalc(GLuint vao, GLsizei numberOfVertices);
|
||||
void saveTextureToPPMFile(GLenum color_buffer_attachment, const std::string& fileName,
|
||||
int width, int height) const;
|
||||
bool isAtmosphereInFrustum(const glm::dmat4& MVMatrix, const glm::dvec3& position,
|
||||
double radius) const;
|
||||
|
||||
// Number of planet radii to use as distance threshold for culling
|
||||
const double DISTANCE_CULLING_RADII = 5000;
|
||||
void step3DTexture(ghoul::opengl::ProgramObject& shaderProg, int layer,
|
||||
bool doCalculation);
|
||||
void loadAtmosphereDataIntoShaderProgram(ghoul::opengl::ProgramObject& shaderProg);
|
||||
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _transmittanceProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _irradianceProgramObject;
|
||||
@@ -125,19 +123,13 @@ private:
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _deltaSProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _deltaSSupTermsProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _deltaJProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _atmosphereProgramObject;
|
||||
std::unique_ptr<ghoul::opengl::ProgramObject> _deferredAtmosphereProgramObject;
|
||||
|
||||
UniformCache(cullAtmosphere, Rg, Rt,
|
||||
groundRadianceEmittion, HR, betaRayleigh, HM,
|
||||
betaMieExtinction, mieG, sunRadiance, ozoneLayerEnabled,
|
||||
HO, betaOzoneExtinction, SAMPLES_R,
|
||||
SAMPLES_MU, SAMPLES_MU_S, SAMPLES_NU) _uniformCache;
|
||||
UniformCache(dInverseModelTransformMatrix, dModelTransformMatrix,
|
||||
dSgctProjectionToModelTransformMatrix,
|
||||
dSGCTViewToWorldMatrix, dCamPosObj, sunDirectionObj,
|
||||
hardShadows, transmittanceTexture, irradianceTexture,
|
||||
inscatterTexture) _uniformCache2;
|
||||
UniformCache(cullAtmosphere, Rg, Rt, groundRadianceEmission, HR, betaRayleigh, HM,
|
||||
betaMieExtinction, mieG, sunRadiance, ozoneLayerEnabled, HO, betaOzoneExtinction,
|
||||
SAMPLES_R, SAMPLES_MU, SAMPLES_MU_S, SAMPLES_NU, dInverseModelTransformMatrix,
|
||||
dModelTransformMatrix, dSgctProjectionToModelTransformMatrix,
|
||||
dSGCTViewToWorldMatrix, dCamPosObj, sunDirectionObj, hardShadows,
|
||||
transmittanceTexture, irradianceTexture, inscatterTexture) _uniformCache;
|
||||
|
||||
GLuint _transmittanceTableTexture = 0;
|
||||
GLuint _irradianceTableTexture = 0;
|
||||
@@ -146,7 +138,6 @@ private:
|
||||
GLuint _deltaSRayleighTableTexture = 0;
|
||||
GLuint _deltaSMieTableTexture = 0;
|
||||
GLuint _deltaJTableTexture = 0;
|
||||
GLuint _atmosphereTexture = 0;
|
||||
|
||||
ghoul::opengl::TextureUnit _transmittanceTableTextureUnit;
|
||||
ghoul::opengl::TextureUnit _irradianceTableTextureUnit;
|
||||
@@ -159,7 +150,7 @@ private:
|
||||
float _atmosphereRadius = 0.f;
|
||||
float _atmospherePlanetRadius = 0.f;
|
||||
float _planetAverageGroundReflectance = 0.f;
|
||||
float _planetGroundRadianceEmittion = 0.f;
|
||||
float _planetGroundRadianceEmission = 0.f;
|
||||
float _rayleighHeightScale = 0.f;
|
||||
float _ozoneHeightScale = 0.f;
|
||||
float _mieHeightScale = 0.f;
|
||||
@@ -173,12 +164,9 @@ private:
|
||||
glm::dvec3 _ellipsoidRadii = glm::vec3(0.f);
|
||||
|
||||
// Atmosphere Textures Dimmensions
|
||||
int _transmittance_table_width = 256;
|
||||
int _transmittance_table_height = 64;
|
||||
int _irradiance_table_width = 64;
|
||||
int _irradiance_table_height = 16;
|
||||
int _delta_e_table_width = 64;
|
||||
int _delta_e_table_height = 16;
|
||||
glm::ivec2 _transmittanceTableSize = glm::ivec2(256, 64);
|
||||
glm::ivec2 _irradianceTableSize = glm::ivec2(64, 16);
|
||||
glm::ivec2 _deltaETableSize = glm::ivec2(64, 16);
|
||||
int _r_samples = 32;
|
||||
int _mu_samples = 128;
|
||||
int _mu_s_samples = 32;
|
||||
@@ -192,7 +180,6 @@ private:
|
||||
bool _hardShadowsEnabled = false;
|
||||
|
||||
// Atmosphere Debugging
|
||||
float _calculationTextureScale = 1.f;
|
||||
bool _saveCalculationTextures = false;
|
||||
|
||||
std::vector<ShadowRenderingStruct> _shadowDataArrayCache;
|
||||
|
||||
@@ -25,33 +25,10 @@
|
||||
#include <modules/atmosphere/rendering/renderableatmosphere.h>
|
||||
|
||||
#include <modules/atmosphere/rendering/atmospheredeferredcaster.h>
|
||||
#include <modules/space/rendering/planetgeometry.h>
|
||||
#include <openspace/documentation/documentation.h>
|
||||
#include <openspace/documentation/verifier.h>
|
||||
#include <openspace/engine/globals.h>
|
||||
#include <openspace/rendering/deferredcastermanager.h>
|
||||
#include <openspace/rendering/renderengine.h>
|
||||
#include <openspace/rendering/renderer.h>
|
||||
#include <openspace/scene/scenegraphnode.h>
|
||||
#include <openspace/util/time.h>
|
||||
#include <openspace/util/spicemanager.h>
|
||||
#include <ghoul/filesystem/filesystem.h>
|
||||
#include <ghoul/io/texture/texturereader.h>
|
||||
#include <ghoul/logging/logmanager.h>
|
||||
#include <ghoul/misc/assert.h>
|
||||
#include <ghoul/misc/invariants.h>
|
||||
#include <ghoul/misc/profiling.h>
|
||||
#include <ghoul/opengl/programobject.h>
|
||||
#include <ghoul/opengl/texture.h>
|
||||
#include <ghoul/opengl/textureunit.h>
|
||||
#include <glm/gtx/string_cast.hpp>
|
||||
#include <fstream>
|
||||
#include <memory>
|
||||
#include <optional>
|
||||
|
||||
#ifdef WIN32
|
||||
#define _USE_MATH_DEFINES
|
||||
#endif // WIN32
|
||||
#include <math.h>
|
||||
|
||||
namespace {
|
||||
@@ -69,7 +46,7 @@ namespace {
|
||||
"phase"
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo GroundRadianceEmittioninfo = {
|
||||
constexpr openspace::properties::Property::PropertyInfo GroundRadianceEmissionInfo = {
|
||||
"GroundRadianceEmission",
|
||||
"Percentage of initial radiance emitted from ground",
|
||||
"Multiplier of the ground radiance color during the rendering phase"
|
||||
@@ -197,7 +174,7 @@ namespace {
|
||||
// [[codegen::verbatim(MieScatteringExtinctionPropCoeffInfo.description)]]
|
||||
std::optional<float> mieScatteringExtinctionPropCoefficient;
|
||||
|
||||
// [[codegen::verbatim(GroundRadianceEmittioninfo.description)]]
|
||||
// [[codegen::verbatim(GroundRadianceEmissionInfo.description)]]
|
||||
float groundRadianceEmission;
|
||||
|
||||
struct Rayleigh {
|
||||
@@ -243,16 +220,14 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation RenderableAtmosphere::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "atmosphere_renderable_atmosphere";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("atmosphere_renderable_atmosphere");
|
||||
}
|
||||
|
||||
RenderableAtmosphere::RenderableAtmosphere(const ghoul::Dictionary& dictionary)
|
||||
: Renderable(dictionary)
|
||||
, _atmosphereHeight(AtmosphereHeightInfo, 60.f, 0.1f, 99.0f)
|
||||
, _groundAverageReflectance(AverageGroundReflectanceInfo, 0.f, 0.f, 1.f)
|
||||
, _groundRadianceEmission(GroundRadianceEmittioninfo, 0.f, 0.f, 1.f)
|
||||
, _groundRadianceEmission(GroundRadianceEmissionInfo, 0.f, 0.f, 1.f)
|
||||
, _rayleighHeightScale(RayleighHeightScaleInfo, 0.f, 0.1f, 50.f)
|
||||
, _rayleighScatteringCoeff(
|
||||
RayleighScatteringCoeffInfo,
|
||||
@@ -282,9 +257,7 @@ RenderableAtmosphere::RenderableAtmosphere(const ghoul::Dictionary& dictionary)
|
||||
_deferredCasterNeedsUpdate = true;
|
||||
_deferredCasterNeedsCalculation = true;
|
||||
};
|
||||
auto updateWithoutCalculation = [this]() {
|
||||
_deferredCasterNeedsUpdate = true;
|
||||
};
|
||||
auto updateWithoutCalculation = [this]() { _deferredCasterNeedsUpdate = true; };
|
||||
|
||||
const Parameters p = codegen::bake<Parameters>(dictionary);
|
||||
|
||||
@@ -413,8 +386,8 @@ glm::dmat4 RenderableAtmosphere::computeModelTransformMatrix(
|
||||
const TransformData& transformData)
|
||||
{
|
||||
// scale the planet to appropriate size since the planet is a unit sphere
|
||||
return glm::translate(glm::dmat4(1.0), transformData.translation) * // Translation
|
||||
glm::dmat4(transformData.rotation) * // Spice rotation
|
||||
return glm::translate(glm::dmat4(1.0), transformData.translation) *
|
||||
glm::dmat4(transformData.rotation) *
|
||||
glm::scale(glm::dmat4(1.0), glm::dvec3(transformData.scale));
|
||||
}
|
||||
|
||||
@@ -448,7 +421,7 @@ void RenderableAtmosphere::updateAtmosphereParameters() {
|
||||
_deferredcaster->setAtmosphereRadius(_planetRadius + _atmosphereHeight);
|
||||
_deferredcaster->setPlanetRadius(_planetRadius);
|
||||
_deferredcaster->setPlanetAverageGroundReflectance(_groundAverageReflectance);
|
||||
_deferredcaster->setPlanetGroundRadianceEmittion(_groundRadianceEmission);
|
||||
_deferredcaster->setPlanetGroundRadianceEmission(_groundRadianceEmission);
|
||||
_deferredcaster->setRayleighHeightScale(_rayleighHeightScale);
|
||||
_deferredcaster->enableOzone(_ozoneEnabled);
|
||||
_deferredcaster->setOzoneHeightScale(_ozoneHeightScale);
|
||||
|
||||
@@ -33,9 +33,7 @@
|
||||
#include <openspace/properties/scalar/floatproperty.h>
|
||||
#include <openspace/properties/vector/vec3property.h>
|
||||
#include <openspace/util/updatestructures.h>
|
||||
|
||||
#include <ghoul/opengl/textureunit.h>
|
||||
|
||||
#include <memory>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
@@ -57,16 +55,6 @@ struct ShadowConfiguration {
|
||||
std::pair<std::string, double> caster;
|
||||
};
|
||||
|
||||
struct ShadowRenderingStruct {
|
||||
double xu = 0.0;
|
||||
double xp = 0.0;
|
||||
double rs = 0.0;
|
||||
double rc = 0.0;
|
||||
glm::dvec3 sourceCasterVec = glm::dvec3(0.0);
|
||||
glm::dvec3 casterPositionVec = glm::dvec3(0.0);
|
||||
bool isShadowing = false;
|
||||
};
|
||||
|
||||
namespace documentation { struct Documentation; }
|
||||
namespace planetgeometry { class PlanetGeometry; }
|
||||
|
||||
|
||||
@@ -27,42 +27,38 @@
|
||||
* from Eric Bruneton is used in the following code. *
|
||||
****************************************************************************************/
|
||||
|
||||
/**
|
||||
/**
|
||||
* Precomputed Atmospheric Scattering
|
||||
* Copyright (c) 2008 INRIA
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holders nor the names of its
|
||||
* contributors may be used to endorse or promote products derived from
|
||||
* this software without specific prior written permission.
|
||||
* Redistribution and use in source and binary forms, with or without modification, are
|
||||
* permitted provided that the following conditions are met:
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other
|
||||
* materials provided with the distribution.
|
||||
* 3. Neither the name of the copyright holders nor the names of its contributors may be
|
||||
* used to endorse or promote products derived from this software without specific
|
||||
* prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
|
||||
* THE POSSIBILITY OF SUCH DAMAGE.
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
|
||||
* EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
|
||||
* THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
|
||||
* STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
|
||||
* THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
|
||||
// Atmosphere Rendering Parameters
|
||||
uniform float Rg;
|
||||
uniform float Rt;
|
||||
uniform float AverageGroundReflectance;
|
||||
uniform float groundRadianceEmittion;
|
||||
uniform float groundRadianceEmission;
|
||||
uniform float HR;
|
||||
uniform vec3 betaRayleigh;
|
||||
uniform float HO;
|
||||
@@ -75,12 +71,9 @@ uniform float sunRadiance;
|
||||
|
||||
uniform bool ozoneLayerEnabled;
|
||||
|
||||
uniform int TRANSMITTANCE_W;
|
||||
uniform int TRANSMITTANCE_H;
|
||||
uniform int SKY_W;
|
||||
uniform int SKY_H;
|
||||
uniform int OTHER_TEXTURES_W;
|
||||
uniform int OTHER_TEXTURES_H;
|
||||
uniform ivec2 TRANSMITTANCE;
|
||||
uniform ivec2 SKY;
|
||||
uniform ivec2 OTHER_TEXTURES;
|
||||
uniform int SAMPLES_R;
|
||||
uniform int SAMPLES_MU;
|
||||
uniform int SAMPLES_MU_S;
|
||||
@@ -95,46 +88,44 @@ const int IRRADIANCE_INTEGRAL_SAMPLES = 32;
|
||||
const int INSCATTER_SPHERICAL_INTEGRAL_SAMPLES = 16;
|
||||
|
||||
const float M_PI = 3.141592657;
|
||||
const float M_2PI = 2.0 * M_PI;
|
||||
|
||||
uniform sampler2D transmittanceTexture;
|
||||
|
||||
float Rg2 = Rg * Rg;
|
||||
float Rt2 = Rt * Rt;
|
||||
float H = sqrt(Rt2 - Rg2);
|
||||
float H2 = Rt2 - Rg2;
|
||||
float invSamplesMu = 1.0f / float(SAMPLES_MU);
|
||||
float invSamplesR = 1.0f / float(SAMPLES_R);
|
||||
float invSamplesMuS = 1.0f / float(SAMPLES_MU_S);
|
||||
float invSamplesNu = 1.0f / float(SAMPLES_NU);
|
||||
float Rg2 = Rg * Rg;
|
||||
float Rt2 = Rt * Rt;
|
||||
float H = sqrt(Rt2 - Rg2);
|
||||
float H2 = Rt2 - Rg2;
|
||||
float invSamplesMu = 1.0 / float(SAMPLES_MU);
|
||||
float invSamplesR = 1.0 / float(SAMPLES_R);
|
||||
float invSamplesMuS = 1.0 / float(SAMPLES_MU_S);
|
||||
float invSamplesNu = 1.0 / float(SAMPLES_NU);
|
||||
float RtMinusRg = float(Rt - Rg);
|
||||
float invRtMinusRg = 1.0f / RtMinusRg;
|
||||
float invRtMinusRg = 1.0 / RtMinusRg;
|
||||
|
||||
float opticalDepth(float localH, float r, float mu, float d) {
|
||||
float invH = 1.0/localH;
|
||||
float a = sqrt((0.5 * invH)*r);
|
||||
vec2 a01 = a*vec2(mu, mu + d / r);
|
||||
vec2 a01s = sign(a01);
|
||||
vec2 a01sq = a01*a01;
|
||||
float x = a01s.y > a01s.x ? exp(a01sq.x) : 0.0;
|
||||
vec2 y = a01s / (2.3193*abs(a01) + sqrt(1.52*a01sq + 4.0)) * vec2(1.0, exp(-d*invH*(d/(2.0*r)+mu)));
|
||||
return sqrt((6.2831*H)*r) * exp((Rg-r)*invH) * (x + dot(y, vec2(1.0, -1.0)));
|
||||
float invH = 1.0 / localH;
|
||||
float a = sqrt(0.5 * invH * r);
|
||||
vec2 a01 = a * vec2(mu, mu + d / r);
|
||||
vec2 a01s = sign(a01);
|
||||
vec2 a01sq = a01 * a01;
|
||||
float x = a01s.y > a01s.x ? exp(a01sq.x) : 0.0;
|
||||
vec2 y = a01s / (2.3193 * abs(a01) + sqrt(1.52 * a01sq + 4.0)) * vec2(1.0, exp(-d * invH * (d / (2.0 * r) + mu)));
|
||||
return sqrt(M_2PI * H * r) * exp((Rg-r)*invH) * (x + dot(y, vec2(1.0, -1.0)));
|
||||
}
|
||||
|
||||
vec3 analyticTransmittance(float r, float mu, float d) {
|
||||
vec3 ozone = vec3(0.0);
|
||||
if (ozoneLayerEnabled) {
|
||||
return exp(-betaRayleigh * opticalDepth(HR, r, mu, d) -
|
||||
betaOzoneExtinction * (0.0000006) * opticalDepth(HO, r, mu, d) -
|
||||
betaMieExtinction * opticalDepth(HM, r, mu, d));
|
||||
}
|
||||
else {
|
||||
return exp(-betaRayleigh * opticalDepth(HR, r, mu, d) -
|
||||
betaMieExtinction * opticalDepth(HM, r, mu, d));
|
||||
ozone = betaOzoneExtinction * (0.0000006) * opticalDepth(HO, r, mu, d);
|
||||
}
|
||||
return exp(-betaRayleigh * opticalDepth(HR, r, mu, d) - ozone -
|
||||
betaMieExtinction * opticalDepth(HM, r, mu, d));
|
||||
}
|
||||
|
||||
vec3 irradiance(sampler2D sampler, float r, float muSun) {
|
||||
float u_r = (r - Rg) * invRtMinusRg;
|
||||
float u_muSun = (muSun + 0.2) / (1.0 + 0.2);
|
||||
float u_r = (r - Rg) * invRtMinusRg;
|
||||
float u_muSun = (muSun + 0.2) / 1.2;
|
||||
return texture(sampler, vec2(u_muSun, u_r)).rgb;
|
||||
}
|
||||
|
||||
@@ -143,160 +134,104 @@ vec3 irradiance(sampler2D sampler, float r, float muSun) {
|
||||
//=============== General Functions ==============//
|
||||
//================================================//
|
||||
// In the following shaders r (altitude) is the length of vector/position x in the
|
||||
// atmosphere (or on the top of it when considering an observer in space),
|
||||
// where the light is comming from the opposite direction of the view direction,
|
||||
// here the vector v or viewDirection.
|
||||
// Rg is the planet radius and Rt the atmosphere radius.
|
||||
// atmosphere (or on the top of it when considering an observer in space), where the light
|
||||
// is coming from the opposite direction of the view direction, here the vector v or
|
||||
// viewDirection. Rg is the planet radius and Rt the atmosphere radius.
|
||||
|
||||
//--- Calculate the distance of the ray starting at x (height r)
|
||||
// until the planet's ground or top of atmosphere. ---
|
||||
// Calculate the distance of the ray starting at x (height r) until the planet's ground
|
||||
// or top of atmosphere
|
||||
// r := || vec(x) || e [0, Rt]
|
||||
// mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v))/r
|
||||
float rayDistance(float r, float mu) {
|
||||
// The light ray starting at the observer in/on the atmosphere can
|
||||
// have to possible end points: the top of the atmosphere or the
|
||||
// planet ground. So the shortest path is the one we are looking for,
|
||||
// otherwise we may be passing through the ground.
|
||||
// The light ray starting at the observer in/on the atmosphere can have to possible end
|
||||
// points: the top of the atmosphere or the planet ground. So the shortest path is the
|
||||
// one we are looking for, otherwise we may be passing through the ground
|
||||
|
||||
// cosine law
|
||||
float atmRadiusEps = Rt + ATM_EPSILON;
|
||||
float rayDistanceAtmosphere = -r * mu +
|
||||
sqrt(r * r * (mu * mu - 1.0f) + atmRadiusEps * atmRadiusEps);
|
||||
float delta = r * r * (mu * mu - 1.0f) + Rg * Rg;
|
||||
float atmRadiusEps2 = (Rt + ATM_EPSILON) * (Rt + ATM_EPSILON);
|
||||
float mu2 = mu * mu;
|
||||
float r2 = r * r;
|
||||
float rg2 = Rg * Rg;
|
||||
float rayDistanceAtmosphere = -r * mu + sqrt(r2 * (mu2 - 1.0) + atmRadiusEps2);
|
||||
float delta = r2 * (mu2 - 1.0) + rg2;
|
||||
|
||||
// Ray may be hitting ground
|
||||
if (delta >= 0.0f) {
|
||||
if (delta >= 0.0) {
|
||||
float rayDistanceGround = -r * mu - sqrt(delta);
|
||||
if (rayDistanceGround >= 0.0f) {
|
||||
if (rayDistanceGround >= 0.0) {
|
||||
return min(rayDistanceAtmosphere, rayDistanceGround);
|
||||
}
|
||||
}
|
||||
return rayDistanceAtmosphere;
|
||||
}
|
||||
|
||||
//-- Given the window's fragment coordinates, for a defined
|
||||
// viewport, gives back the interpolated r e [Rg, Rt] and
|
||||
// mu e [-1, 1] --
|
||||
// r := height of starting point vect(x)
|
||||
// mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v))/r
|
||||
void unmappingRAndMu(out float r, out float mu) {
|
||||
float u_mu = gl_FragCoord.x / float(TRANSMITTANCE_W);
|
||||
float u_r = gl_FragCoord.y / float(TRANSMITTANCE_H);
|
||||
|
||||
// In the paper u_r^2 = (r^2-Rg^2)/(Rt^2-Rg^2)
|
||||
// So, extracting r from u_r in the above equation:
|
||||
//r = sqrt( Rg * Rg + (u_r * u_r) * (Rt * Rt - Rg * Rg) );
|
||||
r = Rg + (u_r * u_r) * RtMinusRg;
|
||||
|
||||
// In the paper the Bruneton suggest mu = dot(v,x)/||x|| with ||v|| = 1.0
|
||||
// Later he proposes u_mu = (1-exp(-3mu-0.6))/(1-exp(-3.6))
|
||||
// But the below one is better. See Colliene.
|
||||
// One must remember that mu is defined from 0 to PI/2 + epsillon.
|
||||
mu = -0.15f + tan(1.5f * u_mu) / tan(1.5f) * (1.0f + 0.15f);
|
||||
}
|
||||
|
||||
//-- Given the windows's fragment coordinates, for a defined view port,
|
||||
// gives back the interpolated r e [Rg, Rt] and muSun e [-1, 1] --
|
||||
// r := height of starting point vect(x)
|
||||
// muSun := cosine of the zeith angle of vec(s). Or muSun = (vec(s) * vec(v))
|
||||
void unmappingRAndMuSun(out float r, out float muSun) {
|
||||
// See Bruneton and Colliene to understand the mapping.
|
||||
muSun = -0.2f + (gl_FragCoord.x - 0.5f) / (float(OTHER_TEXTURES_W) - 1.0f) * (1.0f + 0.2f);
|
||||
//r = Rg + (gl_FragCoord.y - 0.5f) / (float(OTHER_TEXTURES_H) - 1.0f) * (Rt - Rg);
|
||||
r = Rg + (gl_FragCoord.y - 0.5f) / (float(OTHER_TEXTURES_H) ) * RtMinusRg;
|
||||
}
|
||||
|
||||
//-- Given the windows's fragment coordinates, for a defined view port,
|
||||
// gives back the interpolated r e [Rg, Rt] and muSun e [-1, 1] for the
|
||||
// Irradiance deltaE texture table --
|
||||
// r := height of starting point vect(x)
|
||||
// muSun := cosine of the zeith angle of vec(s). Or muSun = (vec(s) * vec(v))
|
||||
void unmappingRAndMuSunIrradiance(out float r, out float muSun) {
|
||||
// See Bruneton and Colliene to understand the mapping.
|
||||
muSun = -0.2f + (gl_FragCoord.x - 0.5f) / (float(SKY_W) - 1.0f) * (1.0f + 0.2f);
|
||||
r = Rg + (gl_FragCoord.y - 0.5f) / (float(SKY_H) - 1.0f) * RtMinusRg;
|
||||
}
|
||||
|
||||
//-- Given the windows's fragment coordinates, for a defined view port,
|
||||
// gives back the interpolated r e [Rg, Rt] and mu, muSun amd nu e [-1, 1] --
|
||||
// Given the windows's fragment coordinates, for a defined view port, gives back the
|
||||
// interpolated r e [Rg, Rt] and mu, muSun amd nu e [-1, 1]
|
||||
// r := height of starting point vect(x)
|
||||
// mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v))/r
|
||||
// muSun := cosine of the zeith angle of vec(s). Or muSun = (vec(s) * vec(v))
|
||||
// nu := cosone of the angle between vec(s) and vec(v)
|
||||
// dhdH := it is a vec4. dhdH.x stores the dminT := Rt - r, dhdH.y stores the dH value (see paper),
|
||||
// dhdH.z stores dminG := r - Rg and dhdH.w stores dh (see paper).
|
||||
// dhdH := it is a vec4. dhdH.x stores the dminT := Rt - r, dhdH.y stores the dH value
|
||||
// (see paper), dhdH.z stores dminG := r - Rg and dhdH.w stores dh (see paper)
|
||||
void unmappingMuMuSunNu(float r, vec4 dhdH, out float mu, out float muSun, out float nu) {
|
||||
// Window coordinates of pixel (uncentering also)
|
||||
float fragmentX = gl_FragCoord.x - 0.5f;
|
||||
float fragmentY = gl_FragCoord.y - 0.5f;
|
||||
vec2 fragment = gl_FragCoord.xy - vec2(0.5);
|
||||
|
||||
// Pre-calculations
|
||||
//float Rg2 = Rg * Rg;
|
||||
//float Rt2 = Rt * Rt;
|
||||
float r2 = r * r;
|
||||
|
||||
float halfSAMPLE_MU = float(SAMPLES_MU) / 2.0f;
|
||||
// If the (vec(x) dot vec(v))/r is negative, i.e.,
|
||||
// the light ray has great probability to touch
|
||||
// the ground, we obtain mu considering the geometry
|
||||
// of the ground
|
||||
if (fragmentY < halfSAMPLE_MU) {
|
||||
float ud = 1.0f - (fragmentY / (halfSAMPLE_MU - 1.0f));
|
||||
float halfSAMPLE_MU = float(SAMPLES_MU) / 2.0;
|
||||
// If the (vec(x) dot vec(v))/r is negative, i.e., the light ray has great probability
|
||||
// to touch the ground, we obtain mu considering the geometry of the ground
|
||||
if (fragment.y < halfSAMPLE_MU) {
|
||||
float ud = 1.0 - (fragment.y / (halfSAMPLE_MU - 1.0));
|
||||
float d = min(max(dhdH.z, ud * dhdH.w), dhdH.w * 0.999);
|
||||
// cosine law: Rg^2 = r^2 + d^2 - 2rdcos(pi-theta)
|
||||
// where cosine(theta) = mu
|
||||
// cosine law: Rg^2 = r^2 + d^2 - 2rdcos(pi-theta) where cosine(theta) = mu
|
||||
mu = (Rg2 - r2 - d * d) / (2.0 * r * d);
|
||||
// We can't handle a ray inside the planet, i.e.,
|
||||
// when r ~ Rg, so we check against it.
|
||||
// If that is the case, we approximate to
|
||||
// a ray touching the ground.
|
||||
// We can't handle a ray inside the planet, i.e., when r ~ Rg, so we check against it.
|
||||
// If that is the case, we approximate to a ray touching the ground.
|
||||
// cosine(pi-theta) = dh/r = sqrt(r^2-Rg^2)
|
||||
// cosine(theta) = - sqrt(1 - Rg^2/r^2)
|
||||
mu = min(mu, -sqrt(1.0 - (Rg2 / r2)) - 0.001);
|
||||
}
|
||||
// The light ray is touching the atmosphere and
|
||||
// not the ground
|
||||
// The light ray is touching the atmosphere and not the ground
|
||||
else {
|
||||
float d = (fragmentY - halfSAMPLE_MU) / (halfSAMPLE_MU - 1.0f);
|
||||
float d = (fragment.y - halfSAMPLE_MU) / (halfSAMPLE_MU - 1.0);
|
||||
d = min(max(dhdH.x, d * dhdH.y), dhdH.y * 0.999);
|
||||
// cosine law: Rt^2 = r^2 + d^2 - 2rdcos(pi-theta)
|
||||
// whre cosine(theta) = mu
|
||||
mu = (Rt2 - r2 - d * d) / (2.0f * r * d);
|
||||
// cosine law: Rt^2 = r^2 + d^2 - 2rdcos(pi-theta) where cosine(theta) = mu
|
||||
mu = (Rt2 - r2 - d * d) / (2.0 * r * d);
|
||||
}
|
||||
|
||||
float modValueMuSun = mod(fragmentX, float(SAMPLES_MU_S)) / (float(SAMPLES_MU_S) - 1.0f);
|
||||
float modValueMuSun = mod(fragment.x, float(SAMPLES_MU_S)) / (float(SAMPLES_MU_S) - 1.0);
|
||||
// The following mapping is different from the paper. See Colliene for an details.
|
||||
muSun = tan((2.0f * modValueMuSun - 1.0f + 0.26f) * 1.1f) / tan(1.26f * 1.1f);
|
||||
nu = -1.0f + floor(fragmentX / float(SAMPLES_MU_S)) / (float(SAMPLES_NU) - 1.0f) * 2.0f;
|
||||
muSun = tan((2.0 * modValueMuSun - 1.0 + 0.26) * 1.1f) / tan(1.26 * 1.1);
|
||||
nu = -1.0 + floor(fragment.x / float(SAMPLES_MU_S)) / (float(SAMPLES_NU) - 1.0) * 2.0;
|
||||
}
|
||||
|
||||
|
||||
//-- Function to access the transmittance texture. Given r
|
||||
// and mu, returns the transmittance of a ray starting at vec(x),
|
||||
// height r, and direction vec(v), mu, and length until it hits
|
||||
// the ground or the top of atmosphere. --
|
||||
// Function to access the transmittance texture. Given r and mu, returns the transmittance
|
||||
// of a ray starting at vec(x), height r, and direction vec(v), mu, and length until it
|
||||
// hits the ground or the top of atmosphere.
|
||||
// r := height of starting point vect(x)
|
||||
// mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v))/r
|
||||
vec3 transmittanceLUT(float r, float mu) {
|
||||
// Given the position x (here the altitude r) and the view
|
||||
// angle v (here the cosine(v)= mu), we map this
|
||||
float u_r = sqrt((r - Rg) * invRtMinusRg);
|
||||
//float u_r = sqrt((r*r - Rg*Rg) / (Rt*Rt - Rg*Rg));
|
||||
// See Colliene to understand the different mapping.
|
||||
float u_mu = atan((mu + 0.15f) / (1.0f + 0.15f) * tan(1.5f)) / 1.5f;
|
||||
vec3 transmittance(float r, float mu) {
|
||||
// Given the position x (here the altitude r) and the view angle v
|
||||
// (here the cosine(v)= mu), we map this
|
||||
float u_r = sqrt((r - Rg) * invRtMinusRg);
|
||||
// See Colliene to understand the mapping
|
||||
float u_mu = atan((mu + 0.15) / 1.15 * tan(1.5)) / 1.5;
|
||||
|
||||
return texture(transmittanceTexture, vec2(u_mu, u_r)).rgb;
|
||||
}
|
||||
|
||||
// -- Given a position r and direction mu, calculates de transmittance
|
||||
// along the ray with length d. This function uses the propriety
|
||||
// of Transmittance: T(a,b) = TableT(a,v)/TableT(b, v) --
|
||||
// Given a position r and direction mu, calculates de transmittance along the ray with
|
||||
// length d. This function uses the propriety of Transmittance:
|
||||
// T(a,b) = TableT(a,v)/TableT(b, v)
|
||||
// r := height of starting point vect(x)
|
||||
// mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v))/r
|
||||
vec3 transmittance(float r, float mu, float d) {
|
||||
// Here we use the transmittance property: T(x,v) = T(x,d)*T(d,v)
|
||||
// to, given a distance d, calculates that transmittance along
|
||||
// that distance starting in x (hight r): T(x,d) = T(x,v)/T(d,v).
|
||||
// Here we use the transmittance property: T(x,v) = T(x,d)*T(d,v) to, given a distance
|
||||
// d, calculates that transmittance along that distance starting in x (height r):
|
||||
// T(x,d) = T(x,v)/T(d,v).
|
||||
//
|
||||
// From cosine law: c^2 = a^2 + b^2 - 2*a*b*cos(ab)
|
||||
float ri = sqrt(d * d + r * r + 2.0 * r * d * mu);
|
||||
@@ -305,105 +240,75 @@ vec3 transmittance(float r, float mu, float d) {
|
||||
// = (r*mu + d) / r_i
|
||||
float mui = (d + r * mu) / ri;
|
||||
|
||||
// It's important to remember that we calculate the Transmittance
|
||||
// table only for zenith angles between 0 and pi/2+episilon.
|
||||
// Then, if mu < 0.0, we just need to invert the view direction
|
||||
// and the start and end points between them, i.e., if
|
||||
// It's important to remember that we calculate the Transmittance table only for zenith
|
||||
// angles between 0 and pi/2+episilon. Then, if mu < 0.0, we just need to invert the
|
||||
// view direction and the start and end points between them, i.e., if
|
||||
// x --> x0, then x0-->x.
|
||||
// Also, let's use the property: T(a,c) = T(a,b)*T(b,c)
|
||||
// Because T(a,c) and T(b,c) are already in the table T,
|
||||
// T(a,b) = T(a,c)/T(b,c).
|
||||
if (mu > 0.0f) {
|
||||
return min(transmittanceLUT(r, mu) /
|
||||
transmittanceLUT(ri, mui), 1.0f);
|
||||
// Because T(a,c) and T(b,c) are already in the table T, T(a,b) = T(a,c)/T(b,c).
|
||||
if (mu > 0.0) {
|
||||
return min(transmittance(r, mu) / transmittance(ri, mui), 1.0);
|
||||
}
|
||||
else {
|
||||
return min(transmittanceLUT(ri, -mui) /
|
||||
transmittanceLUT(r, -mu), 1.0f);
|
||||
return min(transmittance(ri, -mui) / transmittance(r, -mu), 1.0);
|
||||
}
|
||||
}
|
||||
|
||||
// -- Calculates Rayleigh phase function given the
|
||||
// scattering cosine angle mu --
|
||||
// Calculates Rayleigh phase function given the scattering cosine angle mu
|
||||
// mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v))/r
|
||||
float rayleighPhaseFunction(float mu) {
|
||||
//return (3.0f / (16.0f * M_PI)) * (1.0f + mu * mu);
|
||||
return 0.0596831036 * (1.0f + mu * mu);
|
||||
return 0.0596831036 * (1.0 + mu * mu);
|
||||
}
|
||||
|
||||
// -- Calculates Mie phase function given the
|
||||
// scattering cosine angle mu --
|
||||
// mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v))/r
|
||||
float miePhaseFunction(float mu) {
|
||||
//return (3.0f / (8.0f * M_PI)) *
|
||||
// ( ( (1.0f - (mieG * mieG) ) * (1.0f + mu * mu) ) /
|
||||
// ( (2.0f + mieG * mieG) *
|
||||
// pow(1.0f + mieG * mieG - 2.0f * mieG * mu, 3.0f/2.0f) ) );
|
||||
// return 1.5f * 1.0f / (4.0f * M_PI) * (1.0f - mieG * mieG) *
|
||||
// pow(1.0f + (mieG * mieG) - 2.0f * mieG * mu, -3.0f/2.0f) * (1.0f + mu * mu) / (2.0f + mieG*mieG);
|
||||
|
||||
// Calculates Mie phase function given the scattering cosine angle mu
|
||||
// mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v)) / r
|
||||
// mieG := mie phase function value
|
||||
float miePhaseFunction(float mu, float mieG) {
|
||||
float mieG2 = mieG * mieG;
|
||||
return 0.1193662072 * (1.0f - mieG2) *
|
||||
pow(1.0f + mieG2 - 2.0f * mieG * mu, -1.5f) * (1.0f + mu * mu) / (2.0f + mieG2);
|
||||
return 0.1193662072 * (1.0 - mieG2) *
|
||||
pow(1.0 + mieG2 - 2.0 * mieG * mu, -1.5) * (1.0 + mu * mu) / (2.0 + mieG2);
|
||||
}
|
||||
|
||||
// -- Given the height rm view-zenith angle (cosine) mu,
|
||||
// sun-zenith angle (cosine) muSun and the angle (cosine)
|
||||
// between the vec(s) and vec(v), nu, we access the 3D textures
|
||||
// and interpolate between them (r) to find the value for the
|
||||
// 4D texture. --
|
||||
// Given the height rm view-zenith angle (cosine) mu, sun-zenith angle (cosine) muSun and
|
||||
// the angle (cosine) between the vec(s) and vec(v), nu, we access the 3D textures and
|
||||
// interpolate between them (r) to find the value for the 4D texture.
|
||||
// r := height of starting point vect(x)
|
||||
// mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v))/r
|
||||
// muSun := cosine of the zeith angle of vec(s). Or muSun = (vec(s) * vec(v))
|
||||
// nu := cosine of the angle between vec(s) and vec(v)
|
||||
vec4 texture4D(sampler3D table, float r, float mu, float muSun, float nu) {
|
||||
//float Rg2 = Rg * Rg;
|
||||
//float Rt2 = Rt * Rt;
|
||||
float r2 = r * r;
|
||||
//float H = sqrt(Rt2 - Rg2);
|
||||
float rho = sqrt(r2 - Rg2);
|
||||
float rmu = r * mu;
|
||||
float delta = rmu * rmu - r2 + Rg2;
|
||||
//float invSamplesMu = 1.0f / float(SAMPLES_MU);
|
||||
//float invSamplesR = 1.0f / float(SAMPLES_R);
|
||||
//float invSamplesMuS = 1.0f / float(SAMPLES_MU_S);
|
||||
//float invSamplesNu = 1.0f / float(SAMPLES_NU);
|
||||
// vec4 cst = rmu < 0.0f && delta > 0.0f ?
|
||||
// vec4(1.0f, 0.0f, 0.0f, 0.5f - 0.5f / float(SAMPLES_MU)) :
|
||||
// vec4(-1.0f, H * H, H, 0.5f + 0.5f / float(SAMPLES_MU));
|
||||
float r2 = r * r;
|
||||
float rho = sqrt(r2 - Rg2);
|
||||
float rmu = r * mu;
|
||||
float delta = rmu * rmu - r2 + Rg2;
|
||||
|
||||
vec4 cst = rmu < 0.0f && delta > 0.0f ?
|
||||
vec4(1.0f, 0.0f, 0.0f, 0.5f - 0.5f * invSamplesMu) :
|
||||
vec4(-1.0f, H2, H, 0.5f + 0.5f * invSamplesMu);
|
||||
vec4 cst = rmu < 0.0 && delta > 0.0 ?
|
||||
vec4(1.0, 0.0, 0.0, 0.5 - 0.5 * invSamplesMu) :
|
||||
vec4(-1.0, H2, H, 0.5 + 0.5 * invSamplesMu);
|
||||
|
||||
//float u_r = 0.5f / float(SAMPLES_R) + rho / H * (1.0f - 1.0f / float(SAMPLES_R));
|
||||
float u_r = 0.5f * invSamplesR + rho / H * (1.0f - invSamplesR);
|
||||
//float u_mu = cst.w + (rmu * cst.x + sqrt(delta + cst.y)) / (rho + cst.z) * (0.5f - 1.0f / float(SAMPLES_MU));
|
||||
float u_mu = cst.w + (rmu * cst.x + sqrt(delta + cst.y)) / (rho + cst.z) * (0.5f - invSamplesMu);
|
||||
// float u_mu_s = 0.5f / float(SAMPLES_MU_S) +
|
||||
// (atan(max(muSun, -0.1975) * tan(1.26f * 1.1f)) / 1.1f + (1.0f - 0.26f)) * 0.5f * (1.0f - 1.0f / float(SAMPLES_MU_S));
|
||||
float u_mu_s = 0.5f * invSamplesMuS +
|
||||
(atan(max(muSun, -0.1975) * tan(1.386f)) * 0.9090909090909090 + (0.74f)) * 0.5f * (1.0f - invSamplesMuS);
|
||||
float lerp = (nu + 1.0f) / 2.0f * (float(SAMPLES_NU) - 1.0f);
|
||||
float u_r = 0.5 * invSamplesR + rho / H * (1.0 - invSamplesR);
|
||||
float u_mu = cst.w + (rmu * cst.x + sqrt(delta + cst.y)) / (rho + cst.z) * (0.5 - invSamplesMu);
|
||||
float u_mu_s = 0.5 * invSamplesMuS +
|
||||
(atan(max(muSun, -0.1975) * tan(1.386)) * 0.9090909090909090 + 0.74) * 0.5 * (1.0 - invSamplesMuS);
|
||||
float lerp = (nu + 1.0) / 2.0 * (float(SAMPLES_NU) - 1.0);
|
||||
float u_nu = floor(lerp);
|
||||
lerp = lerp - u_nu;
|
||||
|
||||
// return texture(table, vec3((u_nu + u_mu_s) / float(SAMPLES_NU), u_mu, u_r)) * (1.0f - lerp) +
|
||||
// texture(table, vec3((u_nu + u_mu_s + 1.0f) / float(SAMPLES_NU), u_mu, u_r)) * lerp;
|
||||
|
||||
return texture(table, vec3((u_nu + u_mu_s) * invSamplesNu, u_mu, u_r)) * (1.0f - lerp) +
|
||||
texture(table, vec3((u_nu + u_mu_s + 1.0f) * invSamplesNu, u_mu, u_r)) * lerp;
|
||||
return texture(
|
||||
table, vec3((u_nu + u_mu_s) * invSamplesNu, u_mu, u_r)) * (1.0 - lerp) +
|
||||
texture(table, vec3((u_nu + u_mu_s + 1.0) * invSamplesNu, u_mu, u_r)) * lerp;
|
||||
}
|
||||
|
||||
// -- Given the irradiance texture table, the cosine of zenith sun vector
|
||||
// and the height of the observer (ray's stating point x), calculates the
|
||||
// mapping for u_r and u_muSun and returns the value in the LUT. --
|
||||
// Given the irradiance texture table, the cosine of zenith sun vector and the height of
|
||||
// the observer (ray's stating point x), calculates the mapping for u_r and u_muSun and
|
||||
// returns the value in the LUT
|
||||
// lut := OpenGL texture2D sampler (the irradiance texture deltaE)
|
||||
// muSun := cosine of the zeith angle of vec(s). Or muSun = (vec(s) * vec(v))
|
||||
// r := height of starting point vect(x)
|
||||
vec3 irradianceLUT(sampler2D lut, float muSun, float r) {
|
||||
// See Bruneton paper and Coliene to understand the mapping
|
||||
float u_muSun = (muSun + 0.2f) / (1.0f + 0.2f);
|
||||
float u_r = (r - Rg) * invRtMinusRg;
|
||||
float u_muSun = (muSun + 0.2) / 1.2;
|
||||
float u_r = (r - Rg) * invRtMinusRg;
|
||||
return texture(lut, vec2(u_muSun, u_r)).rgb;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -26,11 +26,9 @@
|
||||
|
||||
layout(location = 0) in vec4 in_position;
|
||||
|
||||
out vec3 interpolatedNDCPos;
|
||||
out vec2 texCoord;
|
||||
|
||||
void main() {
|
||||
texCoord = 0.5 + in_position.xy * 0.5;
|
||||
interpolatedNDCPos = in_position.xyz;
|
||||
gl_Position = in_position;
|
||||
texCoord = in_position.xy / 2.0 + 0.5;
|
||||
gl_Position = in_position;
|
||||
}
|
||||
|
||||
@@ -30,10 +30,10 @@ layout (triangles) in;
|
||||
layout (triangle_strip, max_vertices = 3) out;
|
||||
|
||||
void main() {
|
||||
for (int n = 0; n < gl_in.length(); ++n) {
|
||||
gl_Position = gl_in[n].gl_Position;
|
||||
gl_Layer = layer;
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
for (int n = 0; n < gl_in.length(); ++n) {
|
||||
gl_Position = gl_in[n].gl_Position;
|
||||
gl_Layer = layer;
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
||||
@@ -27,5 +27,5 @@
|
||||
layout(location = 0) in vec3 in_position;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(in_position, 1.0);
|
||||
gl_Position = vec4(in_position, 1.0);
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout(location = 0) in vec3 in_position;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(in_position, 1.0);
|
||||
}
|
||||
@@ -26,7 +26,7 @@
|
||||
|
||||
#include "atmosphere_common.glsl"
|
||||
|
||||
out vec4 renderTarget1;
|
||||
out vec4 renderTarget;
|
||||
|
||||
uniform float r;
|
||||
uniform vec4 dhdH;
|
||||
@@ -38,14 +38,14 @@ uniform sampler3D deltaSMTexture;
|
||||
uniform int firstIteraction;
|
||||
|
||||
// -- Spherical Coordinates Steps. phi e [0,2PI] and theta e [0, PI]
|
||||
const float stepPhi = (2.0f * M_PI) / float(INSCATTER_SPHERICAL_INTEGRAL_SAMPLES);
|
||||
const float stepPhi = (2.0 * M_PI) / float(INSCATTER_SPHERICAL_INTEGRAL_SAMPLES);
|
||||
const float stepTheta = M_PI / float(INSCATTER_SPHERICAL_INTEGRAL_SAMPLES);
|
||||
|
||||
void inscatter(float r, float mu, float muSun, float nu, inout vec3 radianceJ) {
|
||||
vec3 inscatter(float r, float mu, float muSun, float nu) {
|
||||
// Be sure to not get a cosine or height out of bounds
|
||||
r = clamp(r, Rg, Rt);
|
||||
mu = clamp(mu, -1.0f, 1.0f);
|
||||
muSun = clamp(muSun, -1.0f, 1.0f);
|
||||
r = clamp(r, Rg, Rt);
|
||||
mu = clamp(mu, -1.0, 1.0);
|
||||
muSun = clamp(muSun, -1.0, 1.0);
|
||||
|
||||
// s sigma | theta v
|
||||
// \ | /
|
||||
@@ -55,9 +55,9 @@ void inscatter(float r, float mu, float muSun, float nu, inout vec3 radianceJ) {
|
||||
// \ | / cos(theta) = mu
|
||||
// \ | / cos(sigma) = muSun
|
||||
// \|/ cos(ni) = nu
|
||||
float mu2 = mu * mu;
|
||||
float muSun2 = muSun * muSun;
|
||||
float sinThetaSinSigma = sqrt(1.0f - mu2) * sqrt(1.0f - muSun2);
|
||||
float mu2 = mu * mu;
|
||||
float muSun2 = muSun * muSun;
|
||||
float sinThetaSinSigma = sqrt(1.0 - mu2) * sqrt(1.0 - muSun2);
|
||||
// cos(sigma + theta) = cos(theta)cos(sigma)-sin(theta)sin(sigma)
|
||||
// cos(ni) = nu = mu * muSun - sqrt(1.0f - mu*mu)*sqrt(1.0 - muSun*muSun) // sin(theta) = sqrt(1.0 - mu*mu)
|
||||
// Now we make sure the angle between vec(s) and vec(v) is in the right range:
|
||||
@@ -67,8 +67,8 @@ void inscatter(float r, float mu, float muSun, float nu, inout vec3 radianceJ) {
|
||||
// theta is the angle between vec(v) and x
|
||||
// cos(PI-theta) = d/r
|
||||
// -cos(theta) = sqrt(r*r-Rg*Rg)/r
|
||||
float Rg2 = Rg * Rg;
|
||||
float r2 = r * r;
|
||||
float Rg2 = Rg * Rg;
|
||||
float r2 = r * r;
|
||||
float cosHorizon = -sqrt(r2 - Rg2)/r;
|
||||
|
||||
// Now we get vec(v) and vec(s) from mu, muSun and nu:
|
||||
@@ -80,7 +80,7 @@ void inscatter(float r, float mu, float muSun, float nu, inout vec3 radianceJ) {
|
||||
// sin(PI-theta) = x/||v|| => x = sin(theta) =? x = sqrt(1-mu*mu)
|
||||
// cos(PI-theta) = z/||v|| => z = cos(theta) = mu
|
||||
// v.y = 0 because ||v|| = 1
|
||||
vec3 v = vec3(sqrt(1.0 - mu2), 0.0, mu);
|
||||
vec3 v = vec3(sqrt(1.0 - mu2), 0.0, mu);
|
||||
|
||||
// To obtain vec(s), we use the following properties:
|
||||
// ||vec(s)|| = 1, ||vec(v)|| = 1
|
||||
@@ -89,7 +89,7 @@ void inscatter(float r, float mu, float muSun, float nu, inout vec3 radianceJ) {
|
||||
// So, from vec(s) dot vec(v) = cos(ni) = nu we have,
|
||||
// s.x*v.x +s.y*v.y + s.z*v.z = nu
|
||||
// s.x = (nu - s.z*v.z)/v.x = (nu - mu*muSun)/v.x
|
||||
float sx = (v.x == 0.0) ? 0.0 : (nu - muSun * mu) / v.x;
|
||||
float sx = (v.x == 0.0) ? 0.0 : (nu - muSun * mu) / v.x;
|
||||
// Also, ||vec(s)|| = 1, so:
|
||||
// 1 = sqrt(s.x*s.x + s.y*s.y + s.z*s.z)
|
||||
// s.y = sqrt(1 - s.x*s.x - s.z*s.z) = sqrt(1 - s.x*s.x - muSun*muSun)
|
||||
@@ -97,21 +97,21 @@ void inscatter(float r, float mu, float muSun, float nu, inout vec3 radianceJ) {
|
||||
|
||||
// In order to integrate over 4PI, we scan the sphere using the spherical coordinates
|
||||
// previously defined
|
||||
for (int theta_i = 0; theta_i < INSCATTER_SPHERICAL_INTEGRAL_SAMPLES; ++theta_i) {
|
||||
float theta = (float(theta_i) + 0.5f) * stepTheta;
|
||||
float cosineTheta = cos(theta);
|
||||
float cosineTheta2 = cosineTheta * cosineTheta;
|
||||
float distanceToGround = 0.0f;
|
||||
float groundReflectance = 0.0f;
|
||||
vec3 groundTransmittance = vec3(0.0f);
|
||||
for (int theta_i = 0; theta_i < INSCATTER_SPHERICAL_INTEGRAL_SAMPLES; theta_i++) {
|
||||
float theta = (float(theta_i) + 0.5) * stepTheta;
|
||||
float cosineTheta = cos(theta);
|
||||
float cosineTheta2 = cosineTheta * cosineTheta;
|
||||
float distanceToGround = 0.0;
|
||||
float groundReflectance = 0.0;
|
||||
vec3 groundTransmittance = vec3(0.0);
|
||||
|
||||
// If the ray w can see the ground we must compute the transmittance
|
||||
// effect from the starting point x to the ground point in direction -vec(v):
|
||||
if ( cosineTheta < cosHorizon ) { // ray hits ground
|
||||
if (cosineTheta < cosHorizon) { // ray hits ground
|
||||
// AverageGroundReflectance e [0,1]
|
||||
groundReflectance = AverageGroundReflectance / M_PI;
|
||||
// From cosine law: Rg*Rg = r*r + distanceToGround*distanceToGround - 2*r*distanceToGround*cos(PI-theta)
|
||||
distanceToGround = -r * cosineTheta - sqrt(r2 * (cosineTheta2 - 1.0f) + Rg2);
|
||||
distanceToGround = -r * cosineTheta - sqrt(r2 * (cosineTheta2 - 1.0) + Rg2);
|
||||
// |
|
||||
// | theta
|
||||
// |
|
||||
@@ -125,86 +125,84 @@ void inscatter(float r, float mu, float muSun, float nu, inout vec3 radianceJ) {
|
||||
// cos(alpha) = (-r*distG*cos(theta) - distG*distG)/(Rg*distG)
|
||||
// muGround = -(r*cos(theta) + distG)/Rg
|
||||
float muGround = -(r * cosineTheta + distanceToGround) / Rg;
|
||||
// We can use the same triangle in calculate the distanceToGround to calculate the cosine of the
|
||||
// angle between the ground touching point at height Rg and the zenith angle
|
||||
//float muGround = (r2 - distanceToGround*distanceToGround - Rg2)/(2*distanceToGround*Rg);
|
||||
// Acesss the Transmittance LUT in order to calculate the transmittance from the ground point Rg,
|
||||
// thorugh the atmosphere, at a distance: distanceToGround
|
||||
// We can use the same triangle in calculate the distanceToGround to calculate the
|
||||
// cosine of the angle between the ground touching point at height Rg and the zenith
|
||||
// angle
|
||||
// float muGround = (r2 - distanceToGround*distanceToGround - Rg2)/(2*distanceToGround*Rg);
|
||||
// Access the Transmittance LUT in order to calculate the transmittance from the
|
||||
// ground point Rg, thorugh the atmosphere, at a distance: distanceToGround
|
||||
groundTransmittance = transmittance(Rg, muGround, distanceToGround);
|
||||
}
|
||||
//for ( int phi_i = 0; phi_i < 2*INSCATTER_SPHERICAL_INTEGRAL_SAMPLES; ++phi_i ) {
|
||||
|
||||
for (int phi_i = 0; phi_i < INSCATTER_SPHERICAL_INTEGRAL_SAMPLES; ++phi_i) {
|
||||
float phi = (float(phi_i) + 0.5) * stepPhi;
|
||||
float phi = (float(phi_i) + 0.5) * stepPhi;
|
||||
// spherical coordinates: dw = dtheta*dphi*sin(theta)*rho^2
|
||||
// rho = 1, we are integrating over a unit sphere
|
||||
float dw = stepTheta * stepPhi * sin(theta);
|
||||
float dw = stepTheta * stepPhi * sin(theta);
|
||||
// w = (rho*sin(theta)*cos(phi), rho*sin(theta)*sin(phi), rho*cos(theta))
|
||||
float sinPhi = sin(phi);
|
||||
float sinPhi = sin(phi);
|
||||
float sinTheta = sin(theta);
|
||||
float cosPhi = cos(phi);
|
||||
vec3 w = vec3(sinTheta * cosPhi, sinTheta * sinPhi, cosineTheta);
|
||||
float cosPhi = cos(phi);
|
||||
vec3 w = vec3(sinTheta * cosPhi, sinTheta * sinPhi, cosineTheta);
|
||||
|
||||
// We calculate the Rayleigh and Mie phase function for the new scattering angle:
|
||||
// cos(angle between vec(v) and vec(w)), ||v|| = ||w|| = 1
|
||||
float nuWV = dot(v, w);
|
||||
float nuWV = dot(v, w);
|
||||
float phaseRayleighWV = rayleighPhaseFunction(nuWV);
|
||||
float phaseMieWV = miePhaseFunction(nuWV);
|
||||
float phaseMieWV = miePhaseFunction(nuWV, mieG);
|
||||
|
||||
vec3 groundNormal = (vec3(0.0, 0.0, r) + distanceToGround * w) / Rg;
|
||||
vec3 groundNormal = (vec3(0.0, 0.0, r) + distanceToGround * w) / Rg;
|
||||
vec3 groundIrradiance = irradianceLUT(deltaETexture, dot(groundNormal, s), Rg);
|
||||
|
||||
// We finally calculate the radiance from the reflected ray from ground (0.0 if not reflected)
|
||||
// We finally calculate the radiance from the reflected ray from ground
|
||||
// (0.0 if not reflected)
|
||||
vec3 radianceJ1 = groundTransmittance * groundReflectance * groundIrradiance;
|
||||
|
||||
// We calculate the Rayleigh and Mie phase function for the new scattering angle:
|
||||
// cos(angle between vec(s) and vec(w)), ||s|| = ||w|| = 1
|
||||
float nuSW = dot(s, w);
|
||||
// The first iteraction is different from the others, that's because in the first
|
||||
// iteraction all the light InScattered are coming from the initial pre-computed
|
||||
// single InScattered light. We stored these values in the deltaS textures (Ray and Mie),
|
||||
// and in order to avoid problems with the high angle dependency in the phase functions,
|
||||
// we don't include the phase functions on those tables (that's why we calculate them now).
|
||||
if ( firstIteraction == 1 ) {
|
||||
// The first iteraction is different from the others. In the first iteraction all
|
||||
// the light InScattered is coming from the initial pre-computed single InScattered
|
||||
// light. We stored these values in the deltaS textures (Ray and Mie), and in order
|
||||
// to avoid problems with the high angle dependency in the phase functions, we don't
|
||||
// include the phase functions on those tables (that's why we calculate them now).
|
||||
if (firstIteraction == 1) {
|
||||
float phaseRaySW = rayleighPhaseFunction(nuSW);
|
||||
float phaseMieSW = miePhaseFunction(nuSW);
|
||||
float phaseMieSW = miePhaseFunction(nuSW, mieG);
|
||||
// We can now access the values for the single InScattering in the textures deltaS textures.
|
||||
vec3 singleRay = texture4D(deltaSRTexture, r, w.z, muSun, nuSW).rgb;
|
||||
vec3 singleMie = texture4D(deltaSMTexture, r, w.z, muSun, nuSW).rgb;
|
||||
vec3 singleRay = texture4D(deltaSRTexture, r, w.z, muSun, nuSW).rgb;
|
||||
vec3 singleMie = texture4D(deltaSMTexture, r, w.z, muSun, nuSW).rgb;
|
||||
|
||||
// Initial InScattering including the phase functions
|
||||
radianceJ1 += singleRay * phaseRaySW + singleMie * phaseMieSW;
|
||||
}
|
||||
else {
|
||||
// On line 9 of the algorithm, the texture table deltaSR is updated, so when we are not in the first
|
||||
// iteraction, we are getting the updated result of deltaSR (not the single inscattered light but the
|
||||
// accumulated (higher order) inscattered light.
|
||||
// On line 9 of the algorithm, the texture table deltaSR is updated, so when we
|
||||
// are not in the first iteraction, we are getting the updated result of deltaSR
|
||||
// (not the single inscattered light but the accumulated (higher order)
|
||||
// inscattered light.
|
||||
// w.z is the cosine(theta) = mu for vec(w)
|
||||
radianceJ1 += texture4D(deltaSRTexture, r, w.z, muSun, nuSW).rgb;
|
||||
}
|
||||
|
||||
// Finally, we add the atmospheric scale height (See: Radiation Transfer on the Atmosphere and Ocean from
|
||||
// Thomas and Stamnes, pg 9-10.
|
||||
radianceJ += radianceJ1 * (betaRayleigh * exp(-(r - Rg) / HR) * phaseRayleighWV +
|
||||
betaMieScattering * exp(-(r - Rg) / HM) * phaseMieWV) * dw;
|
||||
// Finally, we add the atmospheric scale height (See: Radiation Transfer on the
|
||||
// Atmosphere and Ocean from Thomas and Stamnes, pg 9-10.
|
||||
return radianceJ1 * (betaRayleigh * exp(-(r - Rg) / HR) * phaseRayleighWV +
|
||||
betaMieScattering * exp(-(r - Rg) / HM) * phaseMieWV) * dw;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void main() {
|
||||
// cosine variables to access deltaS textures
|
||||
// InScattering Radiance to be calculated at different points in the ray path
|
||||
// Unmapping the variables from texture texels coordinates to mapped coordinates
|
||||
float mu, muSun, nu;
|
||||
// InScattering Radiance to be calculated at
|
||||
// different points in the ray path
|
||||
vec3 radianceJ = vec3(0.0f);
|
||||
|
||||
// Unmapping the variables from texture texels coordinates
|
||||
// to mapped coordinates
|
||||
unmappingMuMuSunNu(r, dhdH, mu, muSun, nu);
|
||||
|
||||
// Calculate the the light inScattered in direction
|
||||
// -vec(v) for the point at height r (vec(y) following Bruneton and Neyret's paper
|
||||
inscatter(r, mu, muSun, nu, radianceJ);
|
||||
vec3 radianceJ = inscatter(r, mu, muSun, nu);
|
||||
|
||||
// Write to texture detaJ
|
||||
renderTarget1 = vec4(radianceJ, 1.0);
|
||||
renderTarget = vec4(radianceJ, 1.0);
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
uniform int layer;
|
||||
|
||||
layout (triangles) in;
|
||||
layout (triangle_strip, max_vertices = 3) out;
|
||||
|
||||
void main() {
|
||||
for (int n = 0; n < gl_in.length(); ++n) {
|
||||
gl_Position = gl_in[n].gl_Position;
|
||||
gl_Layer = layer;
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout(location = 0) in vec3 in_position;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(in_position, 1.0);
|
||||
}
|
||||
@@ -26,24 +26,21 @@
|
||||
|
||||
#include "atmosphere_common.glsl"
|
||||
|
||||
out vec4 renderTarget1;
|
||||
out vec4 renderTarget;
|
||||
|
||||
uniform int layer;
|
||||
|
||||
uniform sampler3D deltaSRTexture;
|
||||
uniform sampler3D deltaSMTexture;
|
||||
|
||||
void main() {
|
||||
// First we convert the window's fragment coordinate to
|
||||
// texel coordinates
|
||||
vec3 rst = vec3(gl_FragCoord.xy, float(layer) + 0.5f) /
|
||||
// First we convert the window's fragment coordinate to texel coordinates
|
||||
vec3 rst = vec3(gl_FragCoord.xy, float(layer) + 0.5) /
|
||||
vec3(ivec3(SAMPLES_MU_S * SAMPLES_NU, SAMPLES_MU, SAMPLES_R));
|
||||
|
||||
vec4 rayleighInscattering0 = texture(deltaSRTexture, rst);
|
||||
vec4 mieInscattering0 = texture(deltaSMTexture, rst);
|
||||
vec3 rayleighInscattering = texture(deltaSRTexture, rst).rgb;
|
||||
float mieInscattering = texture(deltaSMTexture, rst).r;
|
||||
|
||||
// We are using only the red component of the Mie scattering
|
||||
// See the Precomputed Atmosphere Scattering paper for details about
|
||||
// the angular precision.
|
||||
renderTarget1 = vec4(rayleighInscattering0.rgb, mieInscattering0.r);
|
||||
// We are using only the red component of the Mie scattering. See the Precomputed
|
||||
// Atmosphere Scattering paper for details about the angular precision
|
||||
renderTarget = vec4(rayleighInscattering, mieInscattering);
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
uniform int layer;
|
||||
|
||||
layout (triangles) in;
|
||||
layout (triangle_strip, max_vertices = 3) out;
|
||||
|
||||
void main() {
|
||||
for (int n = 0; n < gl_in.length(); ++n) {
|
||||
gl_Position = gl_in[n].gl_Position;
|
||||
gl_Layer = layer;
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout(location = 0) in vec3 in_position;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(in_position, 1.0);
|
||||
}
|
||||
@@ -26,20 +26,21 @@
|
||||
|
||||
#include "atmosphere_common.glsl"
|
||||
|
||||
out vec4 renderTarget1;
|
||||
out vec4 renderTarget;
|
||||
|
||||
uniform int layer;
|
||||
|
||||
uniform sampler3D deltaSTexture;
|
||||
|
||||
void main() {
|
||||
float x = gl_FragCoord.x - 0.5f;
|
||||
float y = gl_FragCoord.y - 0.5f;
|
||||
vec2 p = gl_FragCoord.xy - vec2(0.5);
|
||||
|
||||
float nu = -1.0f + floor(x / float(SAMPLES_MU_S)) / (float(SAMPLES_NU) - 1.0f) * 2.0f;
|
||||
vec3 uvw = vec3(gl_FragCoord.xy, float(layer) + 0.5f) / vec3(ivec3(SAMPLES_MU_S * SAMPLES_NU, SAMPLES_MU, SAMPLES_R));
|
||||
float nu = -1.0 + floor(p.x / float(SAMPLES_MU_S)) / (float(SAMPLES_NU) - 1.0) * 2.0;
|
||||
vec3 uvw = vec3(
|
||||
gl_FragCoord.xy,
|
||||
float(layer) + 0.5) / vec3(ivec3(SAMPLES_MU_S * SAMPLES_NU, SAMPLES_MU, SAMPLES_R)
|
||||
);
|
||||
|
||||
// See Bruneton and Neyret paper, "Angular Precision" paragraph to understanding why we are
|
||||
// dividing the S[L*] by the Rayleigh phase function.
|
||||
renderTarget1 = vec4(texture(deltaSTexture, uvw).rgb / rayleighPhaseFunction(nu), 0.0f);
|
||||
// See Bruneton and Neyret paper, "Angular Precision" paragraph to understanding why we
|
||||
// are dividing the S[L*] by the Rayleigh phase function.
|
||||
renderTarget = vec4(texture(deltaSTexture, uvw).rgb / rayleighPhaseFunction(nu), 0.0);
|
||||
}
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
uniform int layer;
|
||||
|
||||
layout (triangles) in;
|
||||
layout (triangle_strip, max_vertices = 3) out;
|
||||
|
||||
void main() {
|
||||
for (int n = 0; n < gl_in.length(); ++n) {
|
||||
gl_Position = gl_in[n].gl_Position;
|
||||
gl_Layer = layer;
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout(location = 0) in vec3 in_position;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(in_position, 1.0);
|
||||
}
|
||||
@@ -21,6 +21,7 @@
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
#include "atmosphere_common.glsl"
|
||||
@@ -31,64 +32,59 @@ layout(location = 1) out vec4 renderTarget2;
|
||||
uniform float r;
|
||||
uniform vec4 dhdH;
|
||||
|
||||
//uniform sampler2D transmittanceTexture;
|
||||
|
||||
void integrand(float r, float mu, float muSun, float nu,
|
||||
float y, out vec3 S_R, out vec3 S_M) {
|
||||
void integrand(float r, float mu, float muSun, float nu, float y, out vec3 S_R,
|
||||
out vec3 S_M)
|
||||
{
|
||||
// The integral's integrand is the single inscattering radiance:
|
||||
// S[L0] = P_M*S_M[L0] + P_R*S_R[L0]
|
||||
// where S_M[L0] = T*(betaMScattering * exp(-h/H_M))*L0 and
|
||||
// S_R[L0] = T*(betaRScattering * exp(-h/H_R))*L0.
|
||||
// T = transmittance.
|
||||
// One must remember that because the occlusion on L0, the integrand
|
||||
// here will be equal to 0 in that cases.
|
||||
// Also it is important to remember that the phase function for the
|
||||
// Rayleigh and Mie scattering are added during the rendering time
|
||||
// to increase the angular precision
|
||||
// One must remember that because the occlusion on L0, the integrand here will be equal
|
||||
// to 0 in that cases. Also it is important to remember that the phase function for the
|
||||
// Rayleigh and Mie scattering are added during the rendering time to increase the
|
||||
// angular precision
|
||||
S_R = vec3(0.0);
|
||||
S_M = vec3(0.0);
|
||||
|
||||
// cosine law
|
||||
float ri = max(sqrt(r * r + y * y + 2.0 * r * mu * y), Rg);
|
||||
|
||||
// Considering the Sun as a parallel light source,
|
||||
// thew vector s_i = s.
|
||||
// Considering the Sun as a parallel light source, thew vector s_i = s.
|
||||
// So muSun_i = (vec(y_i) dot vec(s))/r_i = ((vec(x) + vec(yi-x)) dot vec(s))/r_i
|
||||
// muSun_i = (vec(x) dot vec(s) + vec(yi-x) dot vec(s))/r_i = (r*muSun + yi*nu)/r_i
|
||||
float muSun_i = (nu * y + muSun * r) / ri;
|
||||
|
||||
// If the muSun_i is smaller than the angle to horizon (no sun radiance
|
||||
// hitting the point y), we return S_R = S_M = 0.0f.
|
||||
// If the muSun_i is smaller than the angle to horizon (no sun radiance hitting the
|
||||
// point y), we return S_R = S_M = 0.0.
|
||||
if (muSun_i >= -sqrt(1.0 - Rg * Rg / (ri * ri))) {
|
||||
// It's the transmittance from the point y (ri) to the top of atmosphere
|
||||
// in direction of the sun (muSun_i) and the transmittance from the observer
|
||||
// at x (r) to y (ri).
|
||||
vec3 transmittanceY = transmittance(r, mu, y) * transmittanceLUT(ri, muSun_i);
|
||||
// It's the transmittance from the point y (ri) to the top of atmosphere in direction
|
||||
// of the sun (muSun_i) and the transmittance from the observer at x (r) to y (ri).
|
||||
vec3 transmittanceY = transmittance(r, mu, y) * transmittance(ri, muSun_i);
|
||||
// exp(-h/H)*T(x,v)
|
||||
if (ozoneLayerEnabled) {
|
||||
S_R = (exp(-(ri - Rg) / HO) + exp( -(ri - Rg) / HR )) * transmittanceY;
|
||||
S_M = exp( -(ri - Rg) / HM ) * transmittanceY;
|
||||
S_R = (exp(-(ri - Rg) / HO) + exp(-(ri - Rg) / HR)) * transmittanceY;
|
||||
S_M = exp(-(ri - Rg) / HM) * transmittanceY;
|
||||
}
|
||||
else {
|
||||
S_R = exp( -(ri - Rg) / HR ) * transmittanceY;
|
||||
S_M = exp( -(ri - Rg) / HM ) * transmittanceY;
|
||||
S_R = exp(-(ri - Rg) / HR) * transmittanceY;
|
||||
S_M = exp(-(ri - Rg) / HM) * transmittanceY;
|
||||
}
|
||||
// The L0 (sun radiance) is added in real-time.
|
||||
}
|
||||
}
|
||||
|
||||
void inscatter(float r, float mu, float muSun, float nu, out vec3 S_R, out vec3 S_M) {
|
||||
// Let's calculate S_M and S_R by integration along the eye ray path inside
|
||||
// the atmosphere, given a position r, a view angle (cosine) mu, a sun
|
||||
// position angle (cosine) muSun, and the angle (cosine) between the sun position
|
||||
// and the view direction, nu.
|
||||
// Integrating using the Trapezoidal rule:
|
||||
// Let's calculate S_M and S_R by integration along the eye ray path inside the
|
||||
// atmosphere, given a position r, a view angle (cosine) mu, a sun position angle
|
||||
// (cosine) muSun, and the angle (cosine) between the sun position and the view
|
||||
// direction, nu. Integrating using the Trapezoidal rule:
|
||||
// Integral(f(y)dy)(from a to b) = (b-a)/2n_steps*(Sum(f(y_i+1)+f(y_i)))
|
||||
S_R = vec3(0.0f);
|
||||
S_M = vec3(0.0f);
|
||||
S_R = vec3(0.0);
|
||||
S_M = vec3(0.0);
|
||||
|
||||
float rayDist = rayDistance(r, mu);
|
||||
float dy = rayDist / float(INSCATTER_INTEGRAL_SAMPLES);
|
||||
float yi = 0.0f;
|
||||
float dy = rayDist / float(INSCATTER_INTEGRAL_SAMPLES);
|
||||
vec3 S_Ri;
|
||||
vec3 S_Mi;
|
||||
integrand(r, mu, muSun, nu, 0.0, S_Ri, S_Mi);
|
||||
@@ -99,38 +95,33 @@ void inscatter(float r, float mu, float muSun, float nu, out vec3 S_R, out vec3
|
||||
integrand(r, mu, muSun, nu, yj, S_Rj, S_Mj);
|
||||
S_R += (S_Ri + S_Rj);
|
||||
S_M += (S_Mi + S_Mj);
|
||||
yi = yj;
|
||||
S_Ri = S_Rj;
|
||||
S_Mi = S_Mj;
|
||||
}
|
||||
S_R *= betaRayleigh * (rayDist / (2.0f * float(INSCATTER_INTEGRAL_SAMPLES)));
|
||||
S_M *= betaMieScattering * (rayDist / (2.0f * float(INSCATTER_INTEGRAL_SAMPLES)));
|
||||
S_R *= betaRayleigh * (rayDist / (2.0 * float(INSCATTER_INTEGRAL_SAMPLES)));
|
||||
S_M *= betaMieScattering * (rayDist / (2.0 * float(INSCATTER_INTEGRAL_SAMPLES)));
|
||||
}
|
||||
|
||||
void main() {
|
||||
vec3 S_R; // First Order Rayleigh InScattering
|
||||
vec3 S_M; // First Order Mie InScattering
|
||||
float mu, muSun, nu; // parametrization angles
|
||||
|
||||
// From the layer interpolation (see C++ code for layer to r)
|
||||
// and the textures parameters (uv), we unmapping mu, muSun and nu.
|
||||
// From the layer interpolation (see C++ code for layer to r) and the textures
|
||||
// parameters (uv), we unmapping mu, muSun and nu.
|
||||
float mu, muSun, nu;
|
||||
unmappingMuMuSunNu(r, dhdH, mu, muSun, nu);
|
||||
|
||||
// Here we calculate the single inScattered light.
|
||||
// Because this is a single inscattering, the light
|
||||
// that arrives at a point y in the path from the
|
||||
// eye to the infinity (top of atmosphere or planet's
|
||||
// ground), comes only from the light source, i.e., the
|
||||
// sun. So, the there is no need to integrate over the
|
||||
// whole solid angle (4pi), we need only to consider
|
||||
// the Sun position (cosine of sun pos = muSun).
|
||||
// Then, following the paper notation:
|
||||
// Here we calculate the single inScattered light. Because this is a single
|
||||
// inscattering, the light that arrives at a point y in the path from the eye to the
|
||||
// infinity (top of atmosphere or planet's ground), comes only from the light source,
|
||||
// i.e., the sun. So, the there is no need to integrate over the whole solid angle
|
||||
// (4pi), we need only to consider the Sun position (cosine of sun pos = muSun). Then,
|
||||
// following the paper notation:
|
||||
// S[L] = P_R*S_R[L0] + P_M*S_M[L0] + S[L*]
|
||||
// For single inscattering only:
|
||||
// S[L0] = P_R*S_R[L0] + P_M*S_M[L0]
|
||||
// In order to save memory, we just store the red component
|
||||
// of S_M[L0], and later we use the proportionality rule
|
||||
// to calcule the other components.
|
||||
// In order to save memory, we just store the red component of S_M[L0], and later we use
|
||||
// the proportionality rule to calcule the other components.
|
||||
inscatter(r, mu, muSun, nu, S_R, S_M);
|
||||
renderTarget1 = vec4(S_R, 1.0);
|
||||
renderTarget2 = vec4(S_M, 1.0);
|
||||
|
||||
@@ -1,39 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
uniform int layer;
|
||||
|
||||
layout (triangles) in;
|
||||
layout (triangle_strip, max_vertices=3) out;
|
||||
|
||||
void main() {
|
||||
for (int n = 0; n < gl_in.length(); ++n) {
|
||||
gl_Position = gl_in[n].gl_Position;
|
||||
gl_Layer = layer;
|
||||
EmitVertex();
|
||||
}
|
||||
EndPrimitive();
|
||||
}
|
||||
@@ -1,31 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout(location = 0) in vec3 in_position;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(in_position, 1.0);
|
||||
}
|
||||
@@ -26,23 +26,21 @@
|
||||
|
||||
#include "atmosphere_common.glsl"
|
||||
|
||||
out vec4 renderTarget1;
|
||||
out vec4 renderTarget;
|
||||
|
||||
uniform float r;
|
||||
uniform vec4 dhdH;
|
||||
|
||||
//uniform sampler2D transmittanceTexture;
|
||||
uniform sampler3D deltaJTexture;
|
||||
|
||||
// The integrand here is the f(y) of the trapezoidal rule:
|
||||
vec3 integrand(float r, float mu, float muSun, float nu, float dist) {
|
||||
// We can calculate r_i by the cosine law: r_i^2=dist^2 + r^2 - 2*r*dist*cos(PI-theta)
|
||||
float r_i = sqrt(r * r + dist * dist + 2.0f * r * dist * mu);
|
||||
float r_i = sqrt(r * r + dist * dist + 2.0f * r * dist * mu);
|
||||
// r_i can be found using the dot product:
|
||||
// vec(y_i) dot vec(dist) = cos(theta_i) * ||vec(y_i)|| * ||vec(dist)||
|
||||
// But vec(y_i) = vec(x) + vec(dist), also: vec(x) dot vec(dist) = cos(theta) = mu
|
||||
// So, cos(theta_i) = mu_i = (r*dist**mu + dist*2)/(r_i*dist)
|
||||
float mu_i = (r * mu + dist) / r_i;
|
||||
float mu_i = (r * mu + dist) / r_i;
|
||||
// muSun_i can also be found by the dot product:
|
||||
// cos(sigma_i) = muSun_i = (vec(s) dot vec(y_i))/(||vec(y_i)|| * ||vec(s)||)
|
||||
// But vec(y_i) = vec(x) + vec(dist), and vec(x) dot vec(s) = muSun, cos(sigma_i + theta_i) = nu
|
||||
@@ -52,28 +50,29 @@ vec3 integrand(float r, float mu, float muSun, float nu, float dist) {
|
||||
}
|
||||
|
||||
vec3 inscatter(float r, float mu, float muSun, float nu) {
|
||||
vec3 inScatteringRadiance = vec3(0.0f);
|
||||
float dy = rayDistance(r, mu) / float(INSCATTER_INTEGRAL_SAMPLES);
|
||||
vec3 inScatteringRadiance_i = integrand(r, mu, muSun, nu, 0.0);
|
||||
vec3 inScatteringRadiance = vec3(0.0);
|
||||
float dy = rayDistance(r, mu) / float(INSCATTER_INTEGRAL_SAMPLES);
|
||||
vec3 inScatteringRadiance_i = integrand(r, mu, muSun, nu, 0.0);
|
||||
|
||||
// In order to solve the integral from equation (11) we use the trapezoidal
|
||||
// rule: Integral(f(y)dy)(from a to b) = ((b-a)/2n_steps)*(Sum(f(y_i+1)+f(y_i)))
|
||||
// In order to solve the integral from equation (11) we use the trapezoidal rule:
|
||||
// Integral(f(y)dy)(from a to b) = ((b-a)/2n_steps)*(Sum(f(y_i+1)+f(y_i)))
|
||||
// where y_i+1 = y_j
|
||||
for (int i = 1; i <= INSCATTER_INTEGRAL_SAMPLES; ++i) {
|
||||
float y_j = float(i) * dy;
|
||||
vec3 inScatteringRadiance_j = integrand(r, mu, muSun, nu, y_j);
|
||||
inScatteringRadiance += (inScatteringRadiance_i + inScatteringRadiance_j) / 2.0 * dy;
|
||||
inScatteringRadiance += (inScatteringRadiance_i + inScatteringRadiance_j) / 2.0 * dy;
|
||||
inScatteringRadiance_i = inScatteringRadiance_j;
|
||||
}
|
||||
return inScatteringRadiance;
|
||||
}
|
||||
|
||||
void main() {
|
||||
float mu = 0.0f, muSunun = 0.0f, nu = 0.0f;
|
||||
// Unmapping the variables from texture texels coordinates
|
||||
// to mapped coordinates
|
||||
unmappingMuMuSunNu(r, dhdH, mu, muSunun, nu);
|
||||
float mu = 0.0;
|
||||
float muSun = 0.0;
|
||||
float nu = 0.0;
|
||||
// Unmapping the variables from texture texels coordinates to mapped coordinates
|
||||
unmappingMuMuSunNu(r, dhdH, mu, muSun, nu);
|
||||
|
||||
// Write to texture deltaSR
|
||||
renderTarget1 = vec4(inscatter(r, mu, muSunun, nu), 1.0);
|
||||
renderTarget = vec4(inscatter(r, mu, muSun, nu), 1.0);
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout(location = 0) in vec3 in_position;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(in_position, 1.0);
|
||||
}
|
||||
@@ -21,23 +21,23 @@
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
#include "atmosphere_common.glsl"
|
||||
|
||||
out vec4 renderTableColor;
|
||||
|
||||
//uniform sampler2D transmittanceTexture;
|
||||
|
||||
void main() {
|
||||
float muSun, r;
|
||||
unmappingRAndMuSun(r, muSun);
|
||||
// We are calculating the Irradiance for L0, i.e.,
|
||||
// only the radiance comming from sun direction is accounted:
|
||||
// See Bruneton and Colliene to understand the mapping
|
||||
float muSun = -0.2 + (gl_FragCoord.x - 0.5) / (float(OTHER_TEXTURES.x) - 1.0) * 1.2;
|
||||
float r = Rg + (gl_FragCoord.y - 0.5) / (float(OTHER_TEXTURES.y) ) * RtMinusRg;
|
||||
|
||||
// We are calculating the Irradiance for L0, i.e., only the radiance coming from Sun
|
||||
// direction is accounted:
|
||||
// E[L0](x,s) = L0*dot(w,n) or 0 (if v!=s or the sun is occluded).
|
||||
// Because we consider the Planet as a perfect sphere and we are
|
||||
// considering only single scattering here, the
|
||||
// dot product dot(w,n) is equal to dot(s,n) that is equal to
|
||||
// Because we consider the Planet as a perfect sphere and we are considering only single
|
||||
// scattering here, the dot product dot(w,n) is equal to dot(s,n) that is equal to
|
||||
// dot(s, r/||r||) = muSun.
|
||||
renderTableColor = vec4(transmittanceLUT(r, muSun) * max(muSun, 0.0), 0.0);
|
||||
renderTableColor = vec4(transmittance(r, muSun) * max(muSun, 0.0), 0.0);
|
||||
}
|
||||
|
||||
@@ -31,7 +31,7 @@ out vec4 renderTableColor;
|
||||
uniform sampler2D deltaETexture;
|
||||
|
||||
void main() {
|
||||
vec2 uv = gl_FragCoord.xy / vec2(OTHER_TEXTURES_W, OTHER_TEXTURES_H);
|
||||
vec2 uv = gl_FragCoord.xy / vec2(OTHER_TEXTURES);
|
||||
|
||||
// Update texture E with E plus deltaE textures.
|
||||
renderTableColor = texture(deltaETexture, uv);
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout(location = 0) in vec3 in_position;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(in_position, 1.0);
|
||||
}
|
||||
@@ -29,60 +29,56 @@
|
||||
out vec4 renderTableColor;
|
||||
|
||||
uniform int firstIteraction;
|
||||
//uniform float firstIteraction;
|
||||
|
||||
// -- Spherical Coordinates Steps. phi e [0,2PI] and theta e [0, PI/2]
|
||||
const float stepPhi = (2.0f * M_PI) / float(IRRADIANCE_INTEGRAL_SAMPLES);
|
||||
const float stepTheta = M_PI / (2.0f * float(IRRADIANCE_INTEGRAL_SAMPLES));
|
||||
|
||||
//uniform sampler2D transmittanceTexture;
|
||||
uniform sampler3D deltaSRTexture;
|
||||
uniform sampler3D deltaSMTexture;
|
||||
|
||||
// Spherical Coordinates Steps. phi e [0,2PI] and theta e [0, PI/2]
|
||||
const float stepPhi = (2.0 * M_PI) / float(IRRADIANCE_INTEGRAL_SAMPLES);
|
||||
const float stepTheta = M_PI / (2.0 * float(IRRADIANCE_INTEGRAL_SAMPLES));
|
||||
|
||||
void main() {
|
||||
float r = 0.0f;
|
||||
float muSun = 0.0f;
|
||||
// Unmapping the variables from texture texels coordinates
|
||||
// to mapped coordinates
|
||||
unmappingRAndMuSunIrradiance(r, muSun);
|
||||
// See Bruneton and Colliene to understand the mapping.
|
||||
float muSun = -0.2 + (gl_FragCoord.x - 0.5) / (float(SKY.x) - 1.0) * 1.2;
|
||||
float r = Rg + (gl_FragCoord.y - 0.5) / (float(SKY.y) - 1.0) * RtMinusRg;
|
||||
|
||||
// We know that muSun = cos(sigma) = s.z/||s||
|
||||
// But, ||s|| = 1, so s.z = muSun. Also,
|
||||
// ||s|| = 1, so s.x = sin(sigma) = sqrt(1-muSun^2) and s.y = 0.0f
|
||||
vec3 s = vec3(max(sqrt(1.0f - muSun * muSun), 0.0f), 0.0f, muSun);
|
||||
vec3 s = vec3(max(sqrt(1.0 - muSun * muSun), 0.0), 0.0, muSun);
|
||||
|
||||
// In order to solve the integral from equation (15) we use the trapezoidal
|
||||
// rule: Integral(f(y)dy)(from a to b) = ((b-a)/2n_steps)*(Sum(f(y_i+1)+f(y_i)))
|
||||
vec3 irradianceE = vec3(0.0f);
|
||||
// In order to solve the integral from equation (15) we use the trapezoidal rule:
|
||||
// Integral(f(y)dy)(from a to b) = ((b-a)/2n_steps)*(Sum(f(y_i+1)+f(y_i)))
|
||||
vec3 irradianceE = vec3(0.0);
|
||||
for (int iphi = 0; iphi < IRRADIANCE_INTEGRAL_SAMPLES; ++iphi) {
|
||||
float phi = (float(iphi) + 0.5f) * stepPhi;
|
||||
float phi = (float(iphi) + 0.5) * stepPhi;
|
||||
for (int itheta = 0; itheta < IRRADIANCE_INTEGRAL_SAMPLES; ++itheta) {
|
||||
float theta = (float(itheta) + 0.5f) * stepTheta;
|
||||
float theta = (float(itheta) + 0.5) * stepTheta;
|
||||
// spherical coordinates: dw = dtheta*dphi*sin(theta)*rho^2
|
||||
// rho = 1, we are integrating over a unit sphere
|
||||
float dw = stepTheta * stepPhi * sin(theta);
|
||||
float dw = stepTheta * stepPhi * sin(theta);
|
||||
// w = (cos(phi) * sin(theta) * rho, sin(phi) * sin(theta) * rho, cos(theta) * rho)
|
||||
vec3 w = vec3(cos(phi) * sin(theta), sin(phi) * sin(theta), cos(theta));
|
||||
float nu = dot(s, w);
|
||||
vec3 w = vec3(cos(phi) * sin(theta), sin(phi) * sin(theta), cos(theta));
|
||||
float nu = dot(s, w);
|
||||
|
||||
// The first iteraction is different from the others, that's because in the first
|
||||
// iteraction all the light arriving are coming from the initial pre-computed
|
||||
// single scattered light. We stored these values in the deltaS textures (Ray and Mie),
|
||||
// and in order to avoid problems with the high angle dependency in the phase functions,
|
||||
// we don't include the phase functions on those tables (that's why we calculate them now).
|
||||
// single scattered light. We stored these values in the deltaS textures (Ray and
|
||||
// Mie), and in order to avoid problems with the high angle dependency in the phase
|
||||
// functions, we don't include the phase functions on those tables (that's why we
|
||||
// calculate them now)
|
||||
if (firstIteraction == 1) {
|
||||
float phaseRay = rayleighPhaseFunction(nu);
|
||||
float phaseMie = miePhaseFunction(nu);
|
||||
float phaseMie = miePhaseFunction(nu, mieG);
|
||||
vec3 singleRay = texture4D(deltaSRTexture, r, w.z, muSun, nu).rgb;
|
||||
vec3 singleMie = texture4D(deltaSMTexture, r, w.z, muSun, nu).rgb;
|
||||
// w.z is the cosine(theta) = mu for vec(w) and also vec(w) dot vec(n(xo))
|
||||
irradianceE += (singleRay * phaseRay + singleMie * phaseMie) * w.z * dw;
|
||||
}
|
||||
else {
|
||||
// On line 10 of the algorithm, the texture table deltaE is updated, so when we are not in the first
|
||||
// iteraction, we are getting the updated result of deltaE (not the single irradiance light but the
|
||||
// accumulated (higher order) irradiance light.
|
||||
// w.z is the cosine(theta) = mu for vec(w) and also vec(w) dot vec(n(xo))
|
||||
// On line 10 of the algorithm, the texture table deltaE is updated, so when we
|
||||
// are not in the first iteraction, we are getting the updated result of deltaE
|
||||
// (not the single irradiance light but the accumulated (higher order) irradiance
|
||||
// light. w.z is the cosine(theta) = mu for vec(w) and also vec(w) dot vec(n(xo))
|
||||
irradianceE += texture4D(deltaSRTexture, r, w.z, muSun, nu).rgb * w.z * dw;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout(location = 0) in vec3 in_position;
|
||||
|
||||
void main() {
|
||||
gl_Position = vec4(in_position, 1.0);
|
||||
}
|
||||
@@ -21,33 +21,31 @@
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
#include "atmosphere_common.glsl"
|
||||
|
||||
//layout(location = 1) out vec4 renderTableColor;
|
||||
out vec4 renderTableColor;
|
||||
|
||||
//-- Optical depth by integration, from ray starting at point vec(x), i.e,
|
||||
// height r and angle mu (cosine of vec(v)) until top of atmosphere
|
||||
// or planet's ground. --
|
||||
// Optical depth by integration, from ray starting at point vec(x), i.e, height r and
|
||||
// angle mu (cosine of vec(v)) until top of atmosphere or planet's ground.
|
||||
// r := height of starting point vect(x)
|
||||
// mu := cosine of the zeith angle of vec(v). Or mu = (vec(x) * vec(v))/r
|
||||
// H := Thickness of atmosphere if its density were uniform (can be used
|
||||
// for Rayleigh and Mie.
|
||||
// H := Thickness of atmosphere if its density were uniform (used for Rayleigh and Mie)
|
||||
float opticalDepth(float r, float mu, float H) {
|
||||
float r2 = r*r;
|
||||
// Is ray below horizon? The transmittance table will have only
|
||||
// the values for transmittance starting at r (x) until the
|
||||
// light ray touches the atmosphere or the ground and only for
|
||||
// view angles v between 0 and pi/2 + eps. That's because we
|
||||
// can calculate the transmittance for angles bigger than pi/2
|
||||
// just inverting the ray direction and starting and ending points.
|
||||
float r2 = r * r;
|
||||
// Is ray below horizon? The transmittance table will have only the values for
|
||||
// transmittance starting at r (x) until the light ray touches the atmosphere or the
|
||||
// ground and only for view angles v between 0 and pi/2 + eps. That's because we can
|
||||
// calculate the transmittance for angles bigger than pi/2 just inverting the ray
|
||||
// direction and starting and ending points.
|
||||
|
||||
// cosine law for triangles: y_i^2 = a^2 + b^2 - 2abcos(alpha)
|
||||
float cosZenithHorizon = -sqrt( 1.0f - ( ( Rg * Rg ) / r2 ) );
|
||||
if (mu < cosZenithHorizon)
|
||||
float cosZenithHorizon = -sqrt(1.0 - (Rg * Rg / r2));
|
||||
if (mu < cosZenithHorizon) {
|
||||
return 1e9;
|
||||
}
|
||||
|
||||
// Integrating using the Trapezoidal rule:
|
||||
// Integral(f(y)dy)(from a to b) = ((b-a)/2n_steps)*(Sum(f(y_i+1)+f(y_i)))
|
||||
@@ -56,36 +54,39 @@ float opticalDepth(float r, float mu, float H) {
|
||||
// cosine law
|
||||
float y_i = exp(-(r - Rg) / H);
|
||||
|
||||
float x_step = 0.0f;
|
||||
float accumulation = 0.0f;
|
||||
float accumulation = 0.0;
|
||||
for (int i = 1; i <= TRANSMITTANCE_STEPS; ++i) {
|
||||
float x_i = float(i) * deltaStep;
|
||||
// cosine law for triangles: y_i^2 = a^2 + b^2 - 2abcos(alpha)
|
||||
// In this case, a = r, b = x_i and cos(alpha) = cos(PI-zenithView) = mu
|
||||
float y_ii = exp(-(sqrt(r2 + x_i * x_i + 2.0 * x_i * r * mu) - Rg) / H);
|
||||
float y_ii = exp(-(sqrt(r2 + x_i * x_i + 2.0 * x_i * r * mu) - Rg) / H);
|
||||
accumulation += (y_ii + y_i);
|
||||
//x_step = x_i;
|
||||
y_i = y_ii;
|
||||
}
|
||||
return accumulation * ( b_a / ( 2 * TRANSMITTANCE_STEPS ) );
|
||||
return accumulation * (b_a / (2.0 * TRANSMITTANCE_STEPS));
|
||||
}
|
||||
|
||||
|
||||
void main() {
|
||||
float r, muSun;
|
||||
unmappingRAndMu(r, muSun);
|
||||
float u_mu = gl_FragCoord.x / float(TRANSMITTANCE.x);
|
||||
float u_r = gl_FragCoord.y / float(TRANSMITTANCE.y);
|
||||
|
||||
vec3 opDepth = vec3(0.0);
|
||||
// In the paper u_r^2 = (r^2-Rg^2)/(Rt^2-Rg^2)
|
||||
// So, extracting r from u_r in the above equation:
|
||||
float r = Rg + (u_r * u_r) * RtMinusRg;
|
||||
|
||||
// In the paper the Bruneton suggest mu = dot(v,x)/||x|| with ||v|| = 1.0
|
||||
// Later he proposes u_mu = (1-exp(-3mu-0.6))/(1-exp(-3.6))
|
||||
// But the below one is better. See Colliene.
|
||||
// One must remember that mu is defined from 0 to PI/2 + epsilon
|
||||
float muSun = -0.15 + tan(1.5 * u_mu) / tan(1.5) * 1.15;
|
||||
|
||||
vec3 ozoneContribution = vec3(0.0);
|
||||
if (ozoneLayerEnabled) {
|
||||
opDepth = betaOzoneExtinction * (0.0000006) * opticalDepth(r, muSun, HO) +
|
||||
ozoneContribution = betaOzoneExtinction * 0.0000006 * opticalDepth(r, muSun, HO);
|
||||
}
|
||||
vec3 opDepth = ozoneContribution +
|
||||
betaMieExtinction * opticalDepth(r, muSun, HM) +
|
||||
betaRayleigh * opticalDepth(r, muSun, HR);
|
||||
}
|
||||
else {
|
||||
opDepth = betaMieExtinction * opticalDepth(r, muSun, HM) +
|
||||
betaRayleigh * opticalDepth(r, muSun, HR);
|
||||
}
|
||||
|
||||
renderTableColor = vec4(exp(-opDepth), 0.0f);
|
||||
renderTableColor = vec4(exp(-opDepth), 0.0);
|
||||
}
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
/*****************************************************************************************
|
||||
* *
|
||||
* OpenSpace *
|
||||
* *
|
||||
* Copyright (c) 2014-2021 *
|
||||
* *
|
||||
* Permission is hereby granted, free of charge, to any person obtaining a copy of this *
|
||||
* software and associated documentation files (the "Software"), to deal in the Software *
|
||||
* without restriction, including without limitation the rights to use, copy, modify, *
|
||||
* merge, publish, distribute, sublicense, and/or sell copies of the Software, and to *
|
||||
* permit persons to whom the Software is furnished to do so, subject to the following *
|
||||
* conditions: *
|
||||
* *
|
||||
* The above copyright notice and this permission notice shall be included in all copies *
|
||||
* or substantial portions of the Software. *
|
||||
* *
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, *
|
||||
* INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A *
|
||||
* PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT *
|
||||
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF *
|
||||
* CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE *
|
||||
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
|
||||
****************************************************************************************/
|
||||
|
||||
#version __CONTEXT__
|
||||
|
||||
layout(location = 0) in vec4 in_position;
|
||||
|
||||
void main() {
|
||||
gl_Position = in_position;
|
||||
}
|
||||
@@ -112,9 +112,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation DashboardItemAngle::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_dashboarditem_angle";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("base_dashboarditem_angle");
|
||||
}
|
||||
|
||||
DashboardItemAngle::DashboardItemAngle(const ghoul::Dictionary& dictionary)
|
||||
|
||||
@@ -65,9 +65,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation DashboardItemDate::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_dashboarditem_date";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("base_dashboarditem_date");
|
||||
}
|
||||
|
||||
DashboardItemDate::DashboardItemDate(const ghoul::Dictionary& dictionary)
|
||||
|
||||
@@ -140,9 +140,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation DashboardItemDistance::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_dashboarditem_distance";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("base_dashboarditem_distance");
|
||||
}
|
||||
|
||||
DashboardItemDistance::DashboardItemDistance(const ghoul::Dictionary& dictionary)
|
||||
|
||||
@@ -148,9 +148,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation DashboardItemFramerate::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_dashboarditem_framerate";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("base_dashboarditem_framerate");
|
||||
}
|
||||
|
||||
DashboardItemFramerate::DashboardItemFramerate(const ghoul::Dictionary& dictionary)
|
||||
|
||||
@@ -62,9 +62,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation DashboardItemPropertyValue::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_dashboarditem_propertyvalue";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("base_dashboarditem_propertyvalue");
|
||||
}
|
||||
|
||||
DashboardItemPropertyValue::DashboardItemPropertyValue(
|
||||
|
||||
@@ -101,9 +101,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation DashboardItemSimulationIncrement::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_dashboarditem_simulationincrement";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("base_dashboarditem_simulationincrement");
|
||||
}
|
||||
|
||||
DashboardItemSimulationIncrement::DashboardItemSimulationIncrement(
|
||||
|
||||
@@ -46,9 +46,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation DashboardItemSpacing::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_dashboarditem_spacing";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("base_dashboarditem_spacing");
|
||||
}
|
||||
|
||||
DashboardItemSpacing::DashboardItemSpacing(const ghoul::Dictionary& dictionary)
|
||||
|
||||
@@ -50,9 +50,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation DashboardItemText::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_dashboarditem_text";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("base_dashboarditem_text");
|
||||
}
|
||||
|
||||
DashboardItemText::DashboardItemText(const ghoul::Dictionary& dictionary)
|
||||
|
||||
@@ -83,9 +83,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation DashboardItemVelocity::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_dashboarditem_velocity";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("base_dashboarditem_velocity");
|
||||
}
|
||||
|
||||
DashboardItemVelocity::DashboardItemVelocity(const ghoul::Dictionary& dictionary)
|
||||
|
||||
@@ -46,9 +46,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation CameraLightSource::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_camera_light_source";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("base_camera_light_source");
|
||||
}
|
||||
|
||||
CameraLightSource::CameraLightSource()
|
||||
|
||||
@@ -59,9 +59,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation SceneGraphLightSource::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_scene_graph_light_source";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("base_scene_graph_light_source");
|
||||
}
|
||||
|
||||
SceneGraphLightSource::SceneGraphLightSource()
|
||||
|
||||
@@ -72,9 +72,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation RenderableBoxGrid::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_renderable_boxgrid";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("base_renderable_boxgrid");
|
||||
}
|
||||
|
||||
RenderableBoxGrid::RenderableBoxGrid(const ghoul::Dictionary& dictionary)
|
||||
|
||||
@@ -82,9 +82,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation RenderableGrid::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_renderable_grid";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("base_renderable_grid");
|
||||
}
|
||||
|
||||
RenderableGrid::RenderableGrid(const ghoul::Dictionary& dictionary)
|
||||
|
||||
@@ -103,9 +103,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation RenderableRadialGrid::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_renderable_radialgrid";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("base_renderable_radialgrid");
|
||||
}
|
||||
|
||||
RenderableRadialGrid::RenderableRadialGrid(const ghoul::Dictionary& dictionary)
|
||||
|
||||
@@ -73,9 +73,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation RenderableSphericalGrid::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_renderable_sphericalgrid";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("base_renderable_sphericalgrid");
|
||||
}
|
||||
|
||||
RenderableSphericalGrid::RenderableSphericalGrid(const ghoul::Dictionary& dictionary)
|
||||
|
||||
@@ -75,9 +75,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation RenderableCartesianAxes::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_renderable_cartesianaxes";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("base_renderable_cartesianaxes");
|
||||
}
|
||||
|
||||
RenderableCartesianAxes::RenderableCartesianAxes(const ghoul::Dictionary& dictionary)
|
||||
|
||||
@@ -82,9 +82,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation RenderableDisc::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_renderable_disc";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("base_renderable_disc");
|
||||
}
|
||||
|
||||
RenderableDisc::RenderableDisc(const ghoul::Dictionary& dictionary)
|
||||
|
||||
@@ -259,7 +259,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation RenderableLabels::Documentation() {
|
||||
return codegen::doc<Parameters>();
|
||||
return codegen::doc<Parameters>("base_renderable_labels");
|
||||
}
|
||||
|
||||
RenderableLabels::RenderableLabels(const ghoul::Dictionary& dictionary)
|
||||
|
||||
@@ -203,13 +203,13 @@ namespace {
|
||||
std::optional<AnimationMode> animationMode;
|
||||
|
||||
// [[codegen::verbatim(AmbientIntensityInfo.description)]]
|
||||
std::optional<double> ambientIntensity;
|
||||
std::optional<float> ambientIntensity;
|
||||
|
||||
// [[codegen::verbatim(DiffuseIntensityInfo.description)]]
|
||||
std::optional<double> diffuseIntensity;
|
||||
std::optional<float> diffuseIntensity;
|
||||
|
||||
// [[codegen::verbatim(SpecularIntensityInfo.description)]]
|
||||
std::optional<double> specularIntensity;
|
||||
std::optional<float> specularIntensity;
|
||||
|
||||
// [[codegen::verbatim(ShadingInfo.description)]]
|
||||
std::optional<bool> performShading;
|
||||
@@ -242,9 +242,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation RenderableModel::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_renderable_model";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("base_renderable_model");
|
||||
}
|
||||
|
||||
RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary)
|
||||
@@ -262,8 +260,8 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary)
|
||||
glm::dmat3(1.0)
|
||||
)
|
||||
, _rotationVec(RotationVecInfo, glm::dvec3(0.0), glm::dvec3(0.0), glm::dvec3(360.0))
|
||||
, _enableOpacityBlending(EnableOpacityBlendingInfo, false)
|
||||
, _disableDepthTest(DisableDepthTestInfo, false)
|
||||
, _enableOpacityBlending(EnableOpacityBlendingInfo, false)
|
||||
, _blendingFuncOption(
|
||||
BlendingOptionInfo,
|
||||
properties::OptionProperty::DisplayType::Dropdown
|
||||
@@ -385,7 +383,9 @@ RenderableModel::RenderableModel(const ghoul::Dictionary& dictionary)
|
||||
throw ghoul::MissingCaseException();
|
||||
}
|
||||
|
||||
_geometry->setTimeScale(convertTime(1.0, timeUnit, TimeUnit::Second));
|
||||
_geometry->setTimeScale(static_cast<float>(
|
||||
convertTime(1.0, timeUnit, TimeUnit::Second))
|
||||
);
|
||||
}
|
||||
else {
|
||||
throw ghoul::MissingCaseException();
|
||||
|
||||
@@ -88,7 +88,6 @@ private:
|
||||
properties::BoolProperty _enableAnimation;
|
||||
|
||||
properties::FloatProperty _ambientIntensity;
|
||||
|
||||
properties::FloatProperty _diffuseIntensity;
|
||||
properties::FloatProperty _specularIntensity;
|
||||
|
||||
|
||||
@@ -104,9 +104,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation RenderableNodeLine::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_renderable_renderablenodeline";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("base_renderable_renderablenodeline");
|
||||
}
|
||||
|
||||
RenderableNodeLine::RenderableNodeLine(const ghoul::Dictionary& dictionary)
|
||||
|
||||
@@ -45,9 +45,9 @@
|
||||
namespace {
|
||||
constexpr const char* ProgramName = "Plane";
|
||||
|
||||
enum BlendMode {
|
||||
BlendModeNormal = 0,
|
||||
BlendModeAdditive
|
||||
enum class BlendMode {
|
||||
Normal = 0,
|
||||
Additive
|
||||
};
|
||||
|
||||
constexpr openspace::properties::Property::PropertyInfo BillboardInfo = {
|
||||
@@ -111,9 +111,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation RenderablePlane::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_renderable_plane";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("base_renderable_plane");
|
||||
}
|
||||
|
||||
RenderablePlane::RenderablePlane(const ghoul::Dictionary& dictionary)
|
||||
@@ -134,15 +132,15 @@ RenderablePlane::RenderablePlane(const ghoul::Dictionary& dictionary)
|
||||
_mirrorBackside = p.mirrorBackside.value_or(_mirrorBackside);
|
||||
|
||||
_blendMode.addOptions({
|
||||
{ BlendModeNormal, "Normal" },
|
||||
{ BlendModeAdditive, "Additive"}
|
||||
{ static_cast<int>(BlendMode::Normal), "Normal" },
|
||||
{ static_cast<int>(BlendMode::Additive), "Additive"}
|
||||
});
|
||||
_blendMode.onChange([&]() {
|
||||
switch (_blendMode) {
|
||||
case BlendModeNormal:
|
||||
case static_cast<int>(BlendMode::Normal):
|
||||
setRenderBinFromOpacity();
|
||||
break;
|
||||
case BlendModeAdditive:
|
||||
case static_cast<int>(BlendMode::Additive):
|
||||
setRenderBin(Renderable::RenderBin::PreDeferredTransparent);
|
||||
break;
|
||||
default:
|
||||
@@ -151,17 +149,17 @@ RenderablePlane::RenderablePlane(const ghoul::Dictionary& dictionary)
|
||||
});
|
||||
|
||||
_opacity.onChange([&]() {
|
||||
if (_blendMode == BlendModeNormal) {
|
||||
if (_blendMode == static_cast<int>(BlendMode::Normal)) {
|
||||
setRenderBinFromOpacity();
|
||||
}
|
||||
});
|
||||
|
||||
if (p.blendMode.has_value()) {
|
||||
if (*p.blendMode == Parameters::BlendMode::Normal) {
|
||||
_blendMode = BlendModeNormal;
|
||||
_blendMode = static_cast<int>(BlendMode::Normal);
|
||||
}
|
||||
else if (*p.blendMode == Parameters::BlendMode::Additive) {
|
||||
_blendMode = BlendModeAdditive;
|
||||
_blendMode = static_cast<int>(BlendMode::Additive);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -279,10 +277,14 @@ void RenderablePlane::render(const RenderData& data, RendererTasks&) {
|
||||
RenderEngine::RendererImplementation::ABuffer;
|
||||
|
||||
if (usingABufferRenderer) {
|
||||
_shader->setUniform("additiveBlending", _blendMode == BlendModeAdditive);
|
||||
_shader->setUniform(
|
||||
"additiveBlending",
|
||||
_blendMode == static_cast<int>(BlendMode::Additive)
|
||||
);
|
||||
}
|
||||
|
||||
bool additiveBlending = (_blendMode == BlendModeAdditive) && usingFramebufferRenderer;
|
||||
bool additiveBlending =
|
||||
(_blendMode == static_cast<int>(BlendMode::Additive)) && usingFramebufferRenderer;
|
||||
if (additiveBlending) {
|
||||
glDepthMask(false);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
|
||||
@@ -78,8 +78,9 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation RenderablePlaneImageLocal::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_renderable_plane_image_local";
|
||||
documentation::Documentation doc = codegen::doc<Parameters>(
|
||||
"base_renderable_plane_image_local"
|
||||
);
|
||||
|
||||
// @TODO cleanup
|
||||
// Insert the parents documentation entries until we have a verifier that can deal
|
||||
|
||||
@@ -52,8 +52,9 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation RenderablePlaneImageOnline::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_renderable_plane_image_online";
|
||||
documentation::Documentation doc = codegen::doc<Parameters>(
|
||||
"base_renderable_plane_image_online"
|
||||
);
|
||||
|
||||
// @TODO cleanup
|
||||
// Insert the parents documentation entries until we have a verifier that can deal
|
||||
|
||||
@@ -88,11 +88,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation RenderablePlaneTimeVaryingImage::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_renderable_plane_time_varying_image";
|
||||
return doc;
|
||||
|
||||
//return codegen::doc<Parameters>("base_renderable_plane_time_varying_image");
|
||||
return codegen::doc<Parameters>("base_renderable_plane_time_varying_image");
|
||||
}
|
||||
|
||||
RenderablePlaneTimeVaryingImage::RenderablePlaneTimeVaryingImage(
|
||||
|
||||
@@ -162,9 +162,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation RenderableSphere::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_renderable_sphere";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("base_renderable_sphere");
|
||||
}
|
||||
|
||||
RenderableSphere::RenderableSphere(const ghoul::Dictionary& dictionary)
|
||||
|
||||
@@ -163,9 +163,7 @@ namespace {
|
||||
|
||||
namespace openspace {
|
||||
documentation::Documentation RenderableTimeVaryingSphere::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_renderable_time_varying_sphere";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("base_renderable_time_varying_sphere");
|
||||
}
|
||||
|
||||
RenderableTimeVaryingSphere::RenderableTimeVaryingSphere(
|
||||
|
||||
@@ -181,9 +181,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation RenderableTrail::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_renderable_renderabletrail";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("base_renderable_renderabletrail");
|
||||
}
|
||||
|
||||
RenderableTrail::Appearance::Appearance()
|
||||
@@ -432,10 +430,10 @@ void RenderableTrail::render(const RenderData& data, RendererTasks&) {
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
}
|
||||
|
||||
const bool renderLines = (_appearance.renderingModes == RenderingModeLines) |
|
||||
const bool renderLines = (_appearance.renderingModes == RenderingModeLines) ||
|
||||
(_appearance.renderingModes == RenderingModeLinesPoints);
|
||||
|
||||
const bool renderPoints = (_appearance.renderingModes == RenderingModePoints) |
|
||||
const bool renderPoints = (_appearance.renderingModes == RenderingModePoints) ||
|
||||
(_appearance.renderingModes == RenderingModeLinesPoints);
|
||||
|
||||
if (renderLines) {
|
||||
|
||||
@@ -129,8 +129,9 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation RenderableTrailOrbit::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_renderable_renderabletrailorbit";
|
||||
documentation::Documentation doc = codegen::doc<Parameters>(
|
||||
"base_renderable_renderabletrailorbit"
|
||||
);
|
||||
|
||||
// Insert the parents documentation entries until we have a verifier that can deal
|
||||
// with class hierarchy
|
||||
|
||||
@@ -105,8 +105,9 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation RenderableTrailTrajectory::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_renderable_renderabletrailtrajectory";
|
||||
documentation::Documentation doc = codegen::doc<Parameters>(
|
||||
"base_renderable_renderabletrailtrajectory"
|
||||
);
|
||||
|
||||
// @TODO cleanup
|
||||
// Insert the parents documentation entries until we have a verifier that can deal
|
||||
|
||||
@@ -128,9 +128,7 @@ int removeDashboardItemsFromScreenSpace(lua_State* L) {
|
||||
} // namespace luascriptfunctions
|
||||
|
||||
documentation::Documentation ScreenSpaceDashboard::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_screenspace_dashboard";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("base_screenspace_dashboard");
|
||||
}
|
||||
|
||||
ScreenSpaceDashboard::ScreenSpaceDashboard(const ghoul::Dictionary& dictionary)
|
||||
|
||||
@@ -58,9 +58,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation ScreenSpaceImageLocal::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_screenspace_image_local";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("base_screenspace_image_local");
|
||||
}
|
||||
|
||||
ScreenSpaceImageLocal::ScreenSpaceImageLocal(const ghoul::Dictionary& dictionary)
|
||||
|
||||
@@ -58,9 +58,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation ScreenSpaceImageOnline::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_screenspace_image_online";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("base_screenspace_image_online");
|
||||
}
|
||||
|
||||
ScreenSpaceImageOnline::ScreenSpaceImageOnline(const ghoul::Dictionary& dictionary)
|
||||
|
||||
@@ -55,9 +55,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation ConstantRotation::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_transform_rotation_constant";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("base_transform_rotation_constant");
|
||||
}
|
||||
|
||||
ConstantRotation::ConstantRotation(const ghoul::Dictionary& dictionary)
|
||||
|
||||
@@ -231,9 +231,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation FixedRotation::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_transform_rotation_fixed";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("base_transform_rotation_fixed");
|
||||
}
|
||||
|
||||
FixedRotation::FixedRotation(const ghoul::Dictionary& dictionary)
|
||||
|
||||
@@ -56,9 +56,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation LuaRotation::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_transform_rotation_lua";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("base_transform_rotation_lua");
|
||||
}
|
||||
|
||||
LuaRotation::LuaRotation()
|
||||
|
||||
@@ -67,9 +67,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation StaticRotation::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_transform_rotation_static";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("base_transform_rotation_static");
|
||||
}
|
||||
|
||||
StaticRotation::StaticRotation()
|
||||
|
||||
@@ -42,9 +42,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation TimelineRotation::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_transform_rotation_keyframe";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("base_transform_rotation_keyframe");
|
||||
}
|
||||
|
||||
TimelineRotation::TimelineRotation(const ghoul::Dictionary& dictionary) {
|
||||
|
||||
@@ -55,9 +55,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation LuaScale::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_scale_lua";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("base_scale_lua");
|
||||
}
|
||||
|
||||
LuaScale::LuaScale()
|
||||
|
||||
@@ -45,9 +45,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation NonUniformStaticScale::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_scale_nonuniformstatic";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("base_scale_nonuniformstatic");
|
||||
}
|
||||
|
||||
glm::dvec3 NonUniformStaticScale::scaleValue(const UpdateData&) const {
|
||||
|
||||
@@ -45,9 +45,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation StaticScale::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_scale_static";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("base_scale_static");
|
||||
}
|
||||
|
||||
glm::dvec3 StaticScale::scaleValue(const UpdateData&) const {
|
||||
|
||||
@@ -71,9 +71,7 @@ namespace {
|
||||
namespace openspace {
|
||||
|
||||
documentation::Documentation TimeDependentScale::Documentation() {
|
||||
documentation::Documentation doc = codegen::doc<Parameters>();
|
||||
doc.id = "base_scale_timedependent";
|
||||
return doc;
|
||||
return codegen::doc<Parameters>("base_scale_timedependent");
|
||||
}
|
||||
|
||||
TimeDependentScale::TimeDependentScale(const ghoul::Dictionary& dictionary)
|
||||
|
||||
@@ -35,7 +35,7 @@ uniform vec3 zColor;
|
||||
Fragment getFragment() {
|
||||
Fragment frag;
|
||||
|
||||
vec3 colorComponents = step(0.01f, vs_positionModelSpace);
|
||||
vec3 colorComponents = step(0.01, vs_positionModelSpace);
|
||||
|
||||
frag.color.rgb = colorComponents.x * xColor +
|
||||
colorComponents.y * yColor +
|
||||
|
||||
@@ -37,7 +37,7 @@ void main() {
|
||||
vec4 positionViewSpace = modelViewTransform * vec4(in_position, 1.0);
|
||||
vec4 positionClipSpace = projectionTransform * positionViewSpace;
|
||||
vec4 positionScreenSpace = positionClipSpace;
|
||||
positionScreenSpace.z = 0.f;
|
||||
positionScreenSpace.z = 0.0;
|
||||
vs_positionModelSpace = in_position;
|
||||
vs_screenSpaceDepth = positionScreenSpace.w;
|
||||
vs_positionViewSpace = positionViewSpace;
|
||||
|
||||
@@ -33,13 +33,12 @@ uniform float opacity;
|
||||
Fragment getFragment() {
|
||||
Fragment frag;
|
||||
frag.color.rgb = gridColor;
|
||||
frag.color.a = opacity;
|
||||
frag.depth = vs_depthClipSpace;
|
||||
frag.color.a = opacity;
|
||||
frag.depth = vs_depthClipSpace;
|
||||
frag.gPosition = vs_positionViewSpace;
|
||||
|
||||
// There is no normal here
|
||||
frag.gNormal = vec4(0.0, 0.0, -1.0, 1.0);
|
||||
|
||||
return frag;
|
||||
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user