Merge branch 'feature/globebrowsing' of github.com:OpenSpace/OpenSpace-Development into feature/globebrowsing

This commit is contained in:
Kalle Bladin
2016-07-15 13:57:33 -04:00
12 changed files with 223 additions and 62 deletions

View File

@@ -100,20 +100,44 @@ namespace openspace {
// In the future, this should be abstracted away and more easily queryable.
// One must also handle how to sample pick one out of multiplte heightmaps
auto tileProvidermanager = owner()->getTileProviderManager();
auto heightMapProviders = tileProvidermanager->getTileProviderGroup(LayeredTextures::HeightMaps).getActiveTileProviders();
if (heightMapProviders.size() > 0) {
TileAndTransform tileAndTransform = TileSelector::getHighestResolutionTile(heightMapProviders[0].get(), _index);
if (tileAndTransform.tile.status == Tile::Status::OK) {
std::shared_ptr<TilePreprocessData> preprocessData = tileAndTransform.tile.preprocessData;
if ((preprocessData != nullptr) && preprocessData->maxValues.size() > 0) {
boundingHeights.max = preprocessData->maxValues[0];
auto tileProviderManager = owner()->getTileProviderManager();
auto heightMapProviders = tileProviderManager->getTileProviderGroup(LayeredTextures::HeightMaps).getActiveTileProviders();
const TileProviderGroup& heightmaps = tileProviderManager->getTileProviderGroup(LayeredTextures::HeightMaps);
TileAndTransform mostHighResHeightmap = TileSelector::getHighestResolutionTile(heightmaps, _index);
if (mostHighResHeightmap.tile.status == Tile::Status::OK) {
auto preprocessData = mostHighResHeightmap.tile.preprocessData;
if (preprocessData != nullptr && preprocessData->minValues[0] < preprocessData->maxValues[0]) {
boundingHeights.min = preprocessData->minValues[0];
boundingHeights.max = preprocessData->maxValues[0];
boundingHeights.available = true;
}
}
const TileProviderGroup& heightmapOverlays = tileProviderManager->getTileProviderGroup(LayeredTextures::HeightMapOverlays);
TileAndTransform mostHighResHeightmapOverlay = TileSelector::getHighestResolutionTile(heightmapOverlays, _index);
if (mostHighResHeightmapOverlay.tile.status == Tile::Status::OK) {
auto preprocessData = mostHighResHeightmapOverlay.tile.preprocessData;
if (preprocessData != nullptr && preprocessData->minValues[0] < preprocessData->maxValues[0]) {
if (boundingHeights.available) {
boundingHeights.min = std::min(boundingHeights.min, preprocessData->minValues[0]);
boundingHeights.max = std::max(boundingHeights.max, preprocessData->maxValues[0]);
}
else {
boundingHeights.min = preprocessData->minValues[0];
boundingHeights.max = preprocessData->maxValues[0];
boundingHeights.available = true;
if (preprocessData->hasMissingData[0]) {
boundingHeights.min = std::min(0.0f, preprocessData->minValues[0]);
boundingHeights.max = std::max(0.0f, preprocessData->maxValues[0]);
}
}
}
}
return boundingHeights;
}

View File

@@ -110,6 +110,8 @@ namespace openspace {
bool showChunkEdges = false;
bool showChunkBounds = false;
bool showChunkAABB = false;
bool showHeightResolution = false;
bool showHeightIntensities = false;
bool doHorizonCulling = true;
bool doFrustumCulling = true;

View File

@@ -186,6 +186,17 @@ namespace openspace {
std::to_string(chunk.owner()->debugOptions.showChunkEdges)));
layeredTexturePreprocessingData.keyValuePairs.push_back(
std::pair<std::string, std::string>(
"showHeightResolution",
std::to_string(chunk.owner()->debugOptions.showHeightResolution)));
layeredTexturePreprocessingData.keyValuePairs.push_back(
std::pair<std::string, std::string>(
"showHeightIntensities",
std::to_string(chunk.owner()->debugOptions.showHeightIntensities)));
// Now the shader program can be accessed
ProgramObject* programObject =
layeredTextureShaderProvider->getUpdatedShaderProgram(
@@ -308,7 +319,7 @@ namespace openspace {
programObject->setUniform("skirtLength", min(static_cast<float>(chunk.surfacePatch().halfSize().lat * 1000000), 8700.0f));
programObject->setUniform("xSegments", _grid->xSegments());
if (tileProviders[LayeredTextures::ColorTextures].size() == 0) {
if (chunk.owner()->debugOptions.showHeightResolution) {
programObject->setUniform("vertexResolution", glm::vec2(_grid->xSegments(), _grid->ySegments()));
}

View File

@@ -104,6 +104,8 @@ namespace openspace {
debugSelection.addOption("Show chunk edges", &_chunkedLodGlobe->debugOptions.showChunkEdges);
debugSelection.addOption("Show chunk bounds", &_chunkedLodGlobe->debugOptions.showChunkBounds);
debugSelection.addOption("Show chunk AABB", &_chunkedLodGlobe->debugOptions.showChunkAABB);
debugSelection.addOption("Show height resolution", &_chunkedLodGlobe->debugOptions.showHeightResolution);
debugSelection.addOption("Show height intensities", &_chunkedLodGlobe->debugOptions.showHeightIntensities);
debugSelection.addOption("Culling: Frustum", &_chunkedLodGlobe->debugOptions.doFrustumCulling);
debugSelection.addOption("Culling: Horizon", &_chunkedLodGlobe->debugOptions.doHorizonCulling);

View File

@@ -38,6 +38,13 @@ uniform vec2 minLatLon;
uniform vec2 lonLatScalingFactor;
uniform vec3 cameraPosition;
layout(location = 1) in vec2 in_uv;
out vec2 fs_uv;
out vec4 fs_position;
out vec3 ellipsoidNormalCameraSpace;
out LevelWeights levelWeights;
PositionNormalPair globalInterpolation() {
vec2 lonLatInput;
lonLatInput.y = minLatLon.y + lonLatScalingFactor.y * in_uv.y; // Lat
@@ -50,8 +57,13 @@ void main() {
PositionNormalPair pair = globalInterpolation();
float distToVertexOnEllipsoid = length(pair.position - cameraPosition);
float levelInterpolationParameter = getLevelInterpolationParameter(chunkLevel, distanceScaleFactor, distToVertexOnEllipsoid);
// use level weight for height sampling, and output to fragment shader
levelWeights = getLevelWeights(levelInterpolationParameter);
// Get the height value
float height = getTileVertexHeight(distToVertexOnEllipsoid);
float height = getTileVertexHeight(in_uv, levelWeights);
// Apply skirts
height -= getTileVertexSkirtLength();

View File

@@ -40,6 +40,14 @@ uniform vec3 p01;
uniform vec3 p11;
uniform vec3 patchNormalCameraSpace;
layout(location = 1) in vec2 in_uv;
out vec2 fs_uv;
out vec4 fs_position;
out vec3 ellipsoidNormalCameraSpace;
out LevelWeights levelWeights;
vec3 bilinearInterpolation(vec2 uv) {
vec3 p0 = (1 - uv.x) * p00 + uv.x * p10;
vec3 p1 = (1 - uv.x) * p01 + uv.x * p11;
@@ -48,16 +56,20 @@ vec3 bilinearInterpolation(vec2 uv) {
}
void main() {
// Position in cameraspace
vec3 p = bilinearInterpolation(in_uv);
// Calculate desired level based on distance to the vertex on the ellipsoid
// Before any heightmapping is done
float distToVertexOnEllipsoid = length(p);
float levelInterpolationParameter = getLevelInterpolationParameter(chunkLevel, distanceScaleFactor, distToVertexOnEllipsoid);
// use level weight for height sampling, and output to fragment shader
levelWeights = getLevelWeights(levelInterpolationParameter);
// Get the height value
float height = getTileVertexHeight(distToVertexOnEllipsoid);
float height = getTileVertexHeight(in_uv, levelWeights);
// Apply skirts
height -= getTileVertexSkirtLength();

View File

@@ -66,6 +66,35 @@
// Other key value pairs used for settings
#define USE_ATMOSPHERE #{useAtmosphere}
#define SHOW_CHUNK_EDGES #{showChunkEdges}
#define SHOW_HEIGHT_RESOLUTION #{showHeightResolution}
#define SHOW_HEIGHT_INTENSITIES #{showHeightIntensities}
float calculateUntransformedHeight(
vec2 uv,
LevelWeights levelWeights,
const Tile heightTiles[NUMLAYERS_HEIGHTMAP],
const Tile heightTilesParent1[NUMLAYERS_HEIGHTMAP],
const Tile heightTilesParent2[NUMLAYERS_HEIGHTMAP]) {
float height = 0;
// The shader compiler will remove unused code when variables are multiplied by
// a constant 0
#if !HEIGHTMAP_BLENDING_ENABLED
levelWeights = getDefaultLevelWeights();
#endif // HEIGHTMAP_BLENDING_ENABLED
#for i in 0..#{lastLayerIndexHeightMaps}
{
height =
levelWeights.w1 * getTexVal(heightTiles[#{i}], uv).r +
levelWeights.w2 * getTexVal(heightTilesParent1[#{i}], uv).r +
levelWeights.w3 * getTexVal(heightTilesParent2[#{i}], uv).r;
}
#endfor
return height;
}
float calculateHeight(
vec2 uv,
@@ -98,6 +127,43 @@ float calculateHeight(
return height;
}
float calculateUntransformedHeightOverlay(
float currentHeight,
vec2 uv,
LevelWeights levelWeights,
const Tile heightOverlayTiles[NUMLAYERS_HEIGHTMAP_OVERLAY],
const Tile heightOverlayTilesParent1[NUMLAYERS_HEIGHTMAP_OVERLAY],
const Tile heightOverlayTilesParent2[NUMLAYERS_HEIGHTMAP_OVERLAY]) {
float height = currentHeight;
// The shader compiler will remove unused code when variables are multiplied by
// a constant 0
#if !HEIGHTMAP_OVERLAY_BLENDING_ENABLED
levelWeights = getDefaultLevelWeights();
#endif // HEIGHTMAP_OVERLAY_BLENDING_ENABLED
#for i in 0..#{lastLayerIndexHeightMapOverlays}
{
vec4 untransformedHeightSample =
levelWeights.w1 * getTexVal(heightOverlayTiles[#{i}], uv) +
levelWeights.w2 * getTexVal(heightOverlayTilesParent1[#{i}], uv) +
levelWeights.w3 * getTexVal(heightOverlayTilesParent2[#{i}], uv);
if (untransformedHeightSample.g > 0.5){
// Float datasets will return un-normalized values, and needs to
// be downscaled in order to be visualized.
float scaleFactor = 0.00005;
height = scaleFactor * untransformedHeightSample.r;
}
}
#endfor
return height;
}
float calculateHeightOverlay(
float currentHeight,
vec2 uv,

View File

@@ -110,6 +110,12 @@ struct LevelWeights {
float w3;
};
float getLevelInterpolationParameter(int chunkLevel, float distanceScaleFactor, float distToVertexOnEllipsoid){
float projectedScaleFactor = distanceScaleFactor / distToVertexOnEllipsoid;
float desiredLevel = log2(projectedScaleFactor);
return chunkLevel - desiredLevel;
}
LevelWeights getLevelWeights(float levelInterpolationParameter){
LevelWeights levelWeights;
levelWeights.w1 = clamp(1 - levelInterpolationParameter, 0 , 1);

View File

@@ -22,6 +22,9 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef TILE_FRAG_COLOR_HGLSL
#define TILE_FRAG_COLOR_HGLSL
#include <${MODULE_GLOBEBROWSING}/shaders/tile.hglsl>
#include <${MODULE_GLOBEBROWSING}/shaders/texturetilemapping.hglsl>
#include "PowerScaling/powerScaling_fs.hglsl"
@@ -30,18 +33,7 @@
// The heightmaps is only used in the fragment shader visually debugging
// the alignment and resolution of the heightmaps
#if USE_HEIGHTMAP
uniform Tile HeightMaps[NUMLAYERS_HEIGHTMAP];
uniform Tile HeightMapsParent1[NUMLAYERS_HEIGHTMAP];
uniform Tile HeightMapsParent2[NUMLAYERS_HEIGHTMAP];
#endif // USE_HEIGHTMAP
#if USE_HEIGHTMAP_OVERLAY
uniform Tile HeightMapOverlays[NUMLAYERS_HEIGHTMAP_OVERLAY];
uniform Tile HeightMapOverlaysParent1[NUMLAYERS_HEIGHTMAP_OVERLAY];
uniform Tile HeightMapOverlaysParent2[NUMLAYERS_HEIGHTMAP_OVERLAY];
#endif // USE_HEIGHTMAP_OVERLAY
#include <${MODULE_GLOBEBROWSING}/shaders/tilevertexheight.hglsl>
@@ -78,14 +70,15 @@ uniform Tile WaterMasksParent1[NUMLAYERS_WATERMASK];
uniform Tile WaterMasksParent2[NUMLAYERS_WATERMASK];
#endif // USE_WATERMASK
#if SHOW_HEIGHT_RESOLUTION
uniform vec2 vertexResolution;
#endif
#if USE_ATMOSPHERE
// TODO atmosphere uniforms here
#endif // USE_ATMOSPHERE
uniform vec2 vertexResolution;
in vec4 fs_position;
in vec2 fs_uv;
in vec3 ellipsoidNormalCameraSpace;
@@ -112,14 +105,6 @@ vec4 getTileFragColor(){
ColorTextures,
ColorTexturesParent1,
ColorTexturesParent2);
#else
color = calculateDebugColor(fs_uv, fs_position, vertexResolution);
#if USE_HEIGHTMAP
color.r += tileResolution(fs_uv, HeightMaps[0]) > 0.9 ? 1 : 0;
#endif
#if USE_HEIGHTMAP_OVERLAY
color.g += tileResolution(fs_uv, HeightMapOverlays[0]) > 0.9 ? 1 : 0;
#endif // USE_HEIGHTMAP_OVERLAY
#endif // USE_COLORTEXTURE
@@ -178,5 +163,34 @@ vec4 getTileFragColor(){
#endif // USE_OVERLAY
#if SHOW_HEIGHT_INTENSITIES
color.r *= 0.1;
color.g *= 0.1;
color.b *= 0.1;
float untransformedHeight = getUntransformedTileVertexHeight(fs_uv, levelWeights);
float contourLine = fract(10*untransformedHeight) > 0.98 ? 1 : 0;
color.r += untransformedHeight;
color.b = contourLine;
#endif
#if SHOW_HEIGHT_RESOLUTION
color += 0.0001*calculateDebugColor(fs_uv, fs_position, vertexResolution);
#if USE_HEIGHTMAP
color.r = min(color.r, 0.8);
color.r += tileResolution(fs_uv, HeightMaps[0]) > 0.9 ? 1 : 0;
#endif
#if USE_HEIGHTMAP_OVERLAY
color.g = min(color.g, 0.8);
color.g += tileResolution(fs_uv, HeightMapOverlays[0]) > 0.9 ? 1 : 0;
#endif // USE_HEIGHTMAP_OVERLAY
#endif
return color;
}
}
#endif ///TILE_FRAG_COLOR_HGLSL

View File

@@ -22,6 +22,9 @@
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. *
****************************************************************************************/
#ifndef TILE_VERTEX_HEIGHT_HGLSL
#define TILE_VERTEX_HEIGHT_HGLSL
#include "PowerScaling/powerScaling_vs.hglsl"
#include <${MODULE_GLOBEBROWSING}/shaders/tile.hglsl>
@@ -45,28 +48,41 @@ uniform float skirtLength;
uniform float distanceScaleFactor;
uniform int chunkLevel;
layout(location = 1) in vec2 in_uv;
out vec2 fs_uv;
out vec4 fs_position;
out vec3 ellipsoidNormalCameraSpace;
float getUntransformedTileVertexHeight(vec2 uv, LevelWeights levelWeights){
float height = 0;
out LevelWeights levelWeights;
#if USE_HEIGHTMAP
// Calculate desired level based on distance to the vertex on the ellipsoid
// Before any heightmapping is done
height = calculateUntransformedHeight(
uv,
levelWeights, // Variable to determine which texture to sample from
HeightMaps, HeightMapsParent1, HeightMapsParent2); // Three textures to sample from
float getTileVertexHeight(float distToVertexOnEllipsoid){
float projectedScaleFactor = distanceScaleFactor / distToVertexOnEllipsoid;
float desiredLevel = log2(projectedScaleFactor);
#endif // USE_HEIGHTMAP
float levelInterpolationParameter = chunkLevel - desiredLevel;
levelWeights = getLevelWeights(levelInterpolationParameter);
#if USE_HEIGHTMAP_OVERLAY
height = calculateUntransformedHeightOverlay(
height,
uv,
levelWeights, // Variable to determine which texture to sample from
HeightMapOverlays, HeightMapOverlaysParent1, HeightMapOverlaysParent2); // Three textures to sample from
#endif // USE_HEIGHTMAP_OVERLAY
return height;
}
float getTileVertexHeight(vec2 uv, LevelWeights levelWeights){
float height = 0;
#if USE_HEIGHTMAP
// Calculate desired level based on distance to the vertex on the ellipsoid
// Before any heightmapping is done
height = calculateHeight(
in_uv,
uv,
levelWeights, // Variable to determine which texture to sample from
HeightMaps, HeightMapsParent1, HeightMapsParent2); // Three textures to sample from
@@ -75,7 +91,7 @@ float getTileVertexHeight(float distToVertexOnEllipsoid){
#if USE_HEIGHTMAP_OVERLAY
height = calculateHeightOverlay(
height,
in_uv,
uv,
levelWeights, // Variable to determine which texture to sample from
HeightMapOverlays, HeightMapOverlaysParent1, HeightMapOverlaysParent2); // Three textures to sample from
@@ -93,4 +109,6 @@ bool tileVertexIsSkirtVertex(){
float getTileVertexSkirtLength(){
return tileVertexIsSkirtVertex() ? skirtLength : 0.0;
}
}
#endif // TILE_VERTEX_HEIGHT_HGLSL

View File

@@ -675,13 +675,15 @@ namespace openspace {
TilePreprocessData* preprocessData = new TilePreprocessData();
preprocessData->maxValues.resize(_dataLayout.numRasters);
preprocessData->minValues.resize(_dataLayout.numRasters);
preprocessData->hasMissingData.resize(_dataLayout.numRasters);
std::vector<float> noDataValues;
noDataValues.resize(_dataLayout.numRasters);
for (size_t c = 0; c < _dataLayout.numRasters; c++) {
preprocessData->maxValues[c] = -FLT_MAX;
preprocessData->minValues[c] = FLT_MAX;
preprocessData->hasMissingData[c] = false;
noDataValues[c] = _dataset->GetRasterBand(1)->GetNoDataValue();
}
@@ -695,23 +697,14 @@ namespace openspace {
for (size_t x = 0; x < region.numPixels.x; x++) {
for (size_t c = 0; c < _dataLayout.numRasters; c++) {
//float lastMaxR = preprocessData->maxValues[0];
//float lastMinR = preprocessData->minValues[0];
float val = TileDataType::interpretFloat(_dataLayout.gdalType, &(result->imageData[yi + i]));
if (val != noDataValue) {
preprocessData->maxValues[c] = std::max(val, preprocessData->maxValues[c]);
preprocessData->minValues[c] = std::min(val, preprocessData->minValues[c]);
}
// ugly case for heightmap overlays and alpha
/*
if (c == 1 && _dataLayout.textureFormat.ghoulFormat == Texture::Format::RG) {
if (val < 0.5) {
preprocessData->maxValues[0] = lastMaxR;
preprocessData->minValues[0] = lastMinR;
}
}*/
else {
preprocessData->hasMissingData[c] = true;
}
i += _dataLayout.bytesPerDatum;
}
}

View File

@@ -46,6 +46,7 @@ namespace openspace {
struct TilePreprocessData {
std::vector<float> maxValues;
std::vector<float> minValues;
std::vector<bool> hasMissingData;
void serialize(std::ostream& s);
static TilePreprocessData deserialize(std::istream& s);