Merge remote-tracking branch 'origin/master' into feature/multiresvolume

This commit is contained in:
Matthew Territo
2017-07-14 09:14:32 -06:00
20 changed files with 828 additions and 617 deletions

View File

@@ -218,7 +218,9 @@ set(SHADER_FILES
${CMAKE_CURRENT_SOURCE_DIR}/shaders/texturetilemapping.hglsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/tile.hglsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/tilefragcolor.hglsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/tilevertexheight.hglsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/tileheight.hglsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/tilevertexskirt.hglsl
${CMAKE_CURRENT_SOURCE_DIR}/shaders/globeshading.hglsl
)
source_group("Shader Files" FILES ${SHADER_FILES})

View File

@@ -65,11 +65,12 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
BoolProperty("enabled", "Enabled", true),
BoolProperty("performShading", "perform shading", true),
BoolProperty("atmosphere", "atmosphere", false),
BoolProperty("useAccurateNormals", "useAccurateNormals", false),
FloatProperty("lodScaleFactor", "lodScaleFactor",10.0f, 1.0f, 50.0f),
FloatProperty("cameraMinHeight", "cameraMinHeight", 100.0f, 0.0f, 1000.0f)
FloatProperty("cameraMinHeight", "cameraMinHeight", 100.0f, 0.0f, 1000.0f),
FloatProperty("orenNayarRoughness", "orenNayarRoughness", 0.0f, 0.0f, 1.0f)
})
, _debugPropertyOwner("Debug")
, _texturePropertyOwner("Textures")
{
setName("RenderableGlobe");
@@ -114,8 +115,10 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
addProperty(_generalProperties.isEnabled);
addProperty(_generalProperties.atmosphereEnabled);
addProperty(_generalProperties.performShading);
addProperty(_generalProperties.useAccurateNormals);
addProperty(_generalProperties.lodScaleFactor);
addProperty(_generalProperties.cameraMinHeight);
addProperty(_generalProperties.orenNayarRoughness);
_debugPropertyOwner.addProperty(_debugProperties.saveOrThrowCamera);
_debugPropertyOwner.addProperty(_debugProperties.showChunkEdges);
@@ -138,6 +141,7 @@ RenderableGlobe::RenderableGlobe(const ghoul::Dictionary& dictionary)
_chunkedLodGlobe->notifyShaderRecompilation();
};
_generalProperties.atmosphereEnabled.onChange(notifyShaderRecompilation);
_generalProperties.useAccurateNormals.onChange(notifyShaderRecompilation);
_generalProperties.performShading.onChange(notifyShaderRecompilation);
_debugProperties.showChunkEdges.onChange(notifyShaderRecompilation);
_debugProperties.showHeightResolution.onChange(notifyShaderRecompilation);

View File

@@ -32,6 +32,7 @@
#include <openspace/properties/scalar/floatproperty.h>
#include <openspace/properties/scalar/intproperty.h>
#include <openspace/properties/scalar/boolproperty.h>
namespace openspace {
namespace globebrowsing {
@@ -74,8 +75,10 @@ public:
properties::BoolProperty isEnabled;
properties::BoolProperty performShading;
properties::BoolProperty atmosphereEnabled;
properties::BoolProperty useAccurateNormals;
properties::FloatProperty lodScaleFactor;
properties::FloatProperty cameraMinHeight;
properties::FloatProperty orenNayarRoughness;
};
RenderableGlobe(const ghoul::Dictionary& dictionary);
@@ -127,7 +130,6 @@ private:
DebugProperties _debugProperties;
GeneralProperties _generalProperties;
properties::PropertyOwner _debugPropertyOwner;
properties::PropertyOwner _texturePropertyOwner;
};
} // namespace globebrowsing

View File

@@ -112,6 +112,79 @@ ghoul::opengl::ProgramObject* ChunkRenderer::getActivatedProgramWithTileData(
return programObject;
}
void ChunkRenderer::setCommonUniforms(ghoul::opengl::ProgramObject& programObject,
const Chunk& chunk, const RenderData& data)
{
glm::dmat4 modelTransform = chunk.owner().modelTransform();
glm::dmat4 viewTransform = data.camera.combinedViewMatrix();
glm::dmat4 modelViewTransform = viewTransform * modelTransform;
const bool nightLayersActive =
!_layerManager->layerGroup(layergroupid::NightLayers).activeLayers().empty();
const bool waterLayersActive =
!_layerManager->layerGroup(layergroupid::WaterMasks).activeLayers().empty();
if (nightLayersActive ||
waterLayersActive ||
chunk.owner().generalProperties().atmosphereEnabled ||
chunk.owner().generalProperties().performShading)
{
glm::vec3 directionToSunWorldSpace =
glm::normalize(-data.modelTransform.translation);
glm::vec3 directionToSunCameraSpace =
(viewTransform * glm::dvec4(directionToSunWorldSpace, 0));
programObject.setUniform(
"lightDirectionCameraSpace", -directionToSunCameraSpace);
}
if (chunk.owner().generalProperties().performShading) {
programObject.setUniform(
"orenNayarRoughness",
chunk.owner().generalProperties().orenNayarRoughness);
}
if (chunk.owner().generalProperties().useAccurateNormals) {
glm::dvec3 corner00 = chunk.owner().ellipsoid().cartesianSurfacePosition(
chunk.surfacePatch().getCorner(Quad::SOUTH_WEST));
glm::dvec3 corner10 = chunk.owner().ellipsoid().cartesianSurfacePosition(
chunk.surfacePatch().getCorner(Quad::SOUTH_EAST));
glm::dvec3 corner01 = chunk.owner().ellipsoid().cartesianSurfacePosition(
chunk.surfacePatch().getCorner(Quad::NORTH_WEST));
glm::dvec3 corner11 = chunk.owner().ellipsoid().cartesianSurfacePosition(
chunk.surfacePatch().getCorner(Quad::NORTH_EAST));
// This is an assumption that the height tile has a resolution of 64 * 64
// If it does not it will still produce "correct" normals. If the resolution is
// higher the shadows will be softer, if it is lower, pixels will be visible.
// Since default is 64 this will most likely work fine.
float tileDelta = 1.0f / 64.0f;
glm::vec3 deltaTheta0 = glm::vec3(corner10 - corner00) * tileDelta;
glm::vec3 deltaTheta1 = glm::vec3(corner11 - corner01) * tileDelta;
glm::vec3 deltaPhi0 = glm::vec3(corner01 - corner00) * tileDelta;
glm::vec3 deltaPhi1 = glm::vec3(corner11 - corner10) * tileDelta;
// Transform to camera space
glm::mat3 modelViewTransformMat3 = glm::mat3(modelViewTransform);
deltaTheta0 = modelViewTransformMat3 * deltaTheta0;
deltaTheta1 = modelViewTransformMat3 * deltaTheta1;
deltaPhi0 = modelViewTransformMat3 * deltaPhi0;
deltaPhi1 = modelViewTransformMat3 * deltaPhi1;
// Upload uniforms
programObject.setUniform("deltaTheta0", glm::length(deltaTheta0));
programObject.setUniform("deltaTheta1", glm::length(deltaTheta1));
programObject.setUniform("deltaPhi0", glm::length(deltaPhi0));
programObject.setUniform("deltaPhi1", glm::length(deltaPhi1));
programObject.setUniform("tileDelta", tileDelta);
}
if (chunk.owner().generalProperties().performShading) {
programObject.setUniform(
"orenNayarRoughness",
chunk.owner().generalProperties().orenNayarRoughness);
}
}
void ChunkRenderer::renderChunkGlobally(const Chunk& chunk, const RenderData& data){
ghoul::opengl::ProgramObject* programObject = getActivatedProgramWithTileData(
@@ -159,16 +232,20 @@ void ChunkRenderer::renderChunkGlobally(const Chunk& chunk, const RenderData& da
_layerManager->layerGroup(
layergroupid::WaterMasks).activeLayers().size() > 0 ||
chunk.owner().generalProperties().atmosphereEnabled ||
chunk.owner().generalProperties().performShading) {
// This code temporary until real light sources can be implemented.
glm::vec3 directionToSunWorldSpace =
glm::normalize(-data.modelTransform.translation);
glm::vec3 directionToSunCameraSpace =
(viewTransform * glm::dvec4(directionToSunWorldSpace, 0));
chunk.owner().generalProperties().performShading)
{
programObject->setUniform("modelViewTransform", modelViewTransform);
programObject->setUniform(
"lightDirectionCameraSpace", -directionToSunCameraSpace);
}
if (chunk.owner().generalProperties().useAccurateNormals &&
_layerManager->layerGroup(layergroupid::HeightLayers).activeLayers().size() > 0)
{
// Apply an extra scaling to the height if the object is scaled
programObject->setUniform(
"heightScale", static_cast<float>(data.modelTransform.scale));
}
setCommonUniforms(*programObject, chunk, data);
// OpenGL rendering settings
glEnable(GL_DEPTH_TEST);
@@ -235,21 +312,16 @@ void ChunkRenderer::renderChunkLocally(const Chunk& chunk, const RenderData& dat
programObject->setUniform("patchNormalCameraSpace", patchNormalCameraSpace);
programObject->setUniform("projectionTransform", data.camera.sgctInternal.projectionMatrix());
if (_layerManager->layerGroup(
layergroupid::NightLayers).activeLayers().size() > 0 ||
_layerManager->layerGroup(
layergroupid::WaterMasks).activeLayers().size() > 0 ||
chunk.owner().generalProperties().atmosphereEnabled ||
chunk.owner().generalProperties().performShading)
{
glm::vec3 directionToSunWorldSpace =
glm::normalize(-data.modelTransform.translation);
glm::vec3 directionToSunCameraSpace =
(viewTransform * glm::dvec4(directionToSunWorldSpace, 0));
if (_layerManager->layerGroup(layergroupid::HeightLayers).activeLayers().size() > 0) {
// Apply an extra scaling to the height if the object is scaled
programObject->setUniform(
"lightDirectionCameraSpace", -directionToSunCameraSpace);
"heightScale", static_cast<float>(data.modelTransform.scale));
}
setCommonUniforms(*programObject, chunk, data);
// OpenGL rendering settings
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);

View File

@@ -87,6 +87,9 @@ private:
std::shared_ptr<GPULayerManager> gpuLayerManager,
const Chunk& chunk);
void setCommonUniforms(ghoul::opengl::ProgramObject& programObject,
const Chunk& chunk, const RenderData& data);
// shared pointer to a grid which can be the same for all rendered chunks.
std::shared_ptr<Grid> _grid;
std::shared_ptr<LayerManager> _layerManager;

View File

@@ -91,17 +91,22 @@ LayerShaderManager::LayerShaderPreprocessingData
preprocessingData.layeredTextureInfo[i] = layeredTextureInfo;
}
const auto& generalProps = globe.generalProperties();
const auto& debugProps = globe.debugProperties();
const RenderableGlobe::GeneralProperties& generalProps = globe.generalProperties();
const RenderableGlobe::DebugProperties& debugProps = globe.debugProperties();
auto& pairs = preprocessingData.keyValuePairs;
pairs.emplace_back("useAccurateNormals",
std::to_string(generalProps.useAccurateNormals)
);
pairs.emplace_back("useAtmosphere", std::to_string(generalProps.atmosphereEnabled));
pairs.emplace_back("performShading", std::to_string(generalProps.performShading));
pairs.emplace_back("showChunkEdges", std::to_string(debugProps.showChunkEdges));
pairs.emplace_back("showHeightResolution",
std::to_string(debugProps.showHeightResolution));
std::to_string(debugProps.showHeightResolution)
);
pairs.emplace_back("showHeightIntensities",
std::to_string(debugProps.showHeightIntensities));
std::to_string(debugProps.showHeightIntensities)
);
pairs.emplace_back("defaultHeight", std::to_string(Chunk::DEFAULT_HEIGHT));
pairs.emplace_back("tilePaddingStart",

View File

@@ -25,29 +25,25 @@
#ifndef BLENDING_HGLSL
#define BLENDING_HGLSL
vec4 blendNormal(vec4 oldColor, vec4 newColor)
{
vec4 toReturn;
toReturn.rgb =
(newColor.rgb * newColor.a + oldColor.rgb * oldColor.a * (1 - newColor.a)) /
(newColor.a + oldColor.a * (1 - newColor.a));
toReturn.a = newColor.a + oldColor.a * (1 - newColor.a);
return toReturn;
vec4 blendNormal(vec4 oldColor, vec4 newColor) {
vec4 toReturn;
toReturn.rgb =
(newColor.rgb * newColor.a + oldColor.rgb * oldColor.a * (1 - newColor.a)) /
(newColor.a + oldColor.a * (1 - newColor.a));
toReturn.a = newColor.a + oldColor.a * (1 - newColor.a);
return toReturn;
}
vec4 blendMultiply(vec4 oldColor, vec4 newColor)
{
return oldColor * newColor;
vec4 blendMultiply(vec4 oldColor, vec4 newColor) {
return oldColor * newColor;
}
vec4 blendAdd(vec4 oldColor, vec4 newColor)
{
return oldColor + newColor;
vec4 blendAdd(vec4 oldColor, vec4 newColor) {
return oldColor + newColor;
}
vec4 blendSubtract(vec4 oldColor, vec4 newColor)
{
return oldColor - newColor;
vec4 blendSubtract(vec4 oldColor, vec4 newColor) {
return oldColor - newColor;
}
/*
@@ -56,7 +52,7 @@ vec3 rgb2hsv(vec3 c)
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
//vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
//vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy);
vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy);
vec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx);
float d = q.x - min(q.w, q.y);
@@ -72,15 +68,13 @@ vec3 hsv2rgb(vec3 c)
}
*/
vec3 hsl2rgb( in vec3 c )
{
vec3 hsl2rgb( in vec3 c ) {
vec3 rgb = clamp( abs(mod(c.x*6.0+vec3(0.0,4.0,2.0),6.0)-3.0)-1.0, 0.0, 1.0 );
return c.z + c.y * (rgb-0.5)*(1.0-abs(2.0*c.z-1.0));
}
vec3 HueShift (in vec3 Color, in float Shift)
{
vec3 HueShift (in vec3 Color, in float Shift) {
vec3 P = vec3(0.55735)*dot(vec3(0.55735),Color);
vec3 U = Color-P;
@@ -92,45 +86,44 @@ vec3 HueShift (in vec3 Color, in float Shift)
return vec3(Color);
}
vec3 rgb2hsl( in vec3 c ){
vec3 rgb2hsl( in vec3 c ) {
float h = 0.0;
float s = 0.0;
float l = 0.0;
float r = c.r;
float g = c.g;
float b = c.b;
float cMin = min( r, min( g, b ) );
float cMax = max( r, max( g, b ) );
float s = 0.0;
float l = 0.0;
float r = c.r;
float g = c.g;
float b = c.b;
float cMin = min( r, min( g, b ) );
float cMax = max( r, max( g, b ) );
l = ( cMax + cMin ) / 2.0;
if ( cMax > cMin ) {
float cDelta = cMax - cMin;
l = ( cMax + cMin ) / 2.0;
if ( cMax > cMin ) {
float cDelta = cMax - cMin;
//s = l < .05 ? cDelta / ( cMax + cMin ) : cDelta / ( 2.0 - ( cMax + cMin ) ); Original
s = l < .0 ? cDelta / ( cMax + cMin ) : cDelta / ( 2.0 - ( cMax + cMin ) );
s = l < .0 ? cDelta / ( cMax + cMin ) : cDelta / ( 2.0 - ( cMax + cMin ) );
if ( r == cMax ) {
h = ( g - b ) / cDelta;
} else if ( g == cMax ) {
h = 2.0 + ( b - r ) / cDelta;
} else {
h = 4.0 + ( r - g ) / cDelta;
}
if ( r == cMax ) {
h = ( g - b ) / cDelta;
} else if ( g == cMax ) {
h = 2.0 + ( b - r ) / cDelta;
} else {
h = 4.0 + ( r - g ) / cDelta;
}
if ( h < 0.0) {
h += 6.0;
}
h = h / 6.0;
}
return vec3( h, s, l );
if ( h < 0.0) {
h += 6.0;
}
h = h / 6.0;
}
return vec3( h, s, l );
}
vec3 rgb2hsv(vec3 c)
{
vec3 rgb2hsv(vec3 c) {
vec4 K = vec4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
//vec4 p = mix(vec4(c.bg, K.wz), vec4(c.gb, K.xy), step(c.b, c.g));
//vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r));
vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy);
vec4 p = c.g < c.b ? vec4(c.bg, K.wz) : vec4(c.gb, K.xy);
vec4 q = c.r < p.x ? vec4(p.xyw, c.r) : vec4(c.r, p.yzx);
float d = q.x - min(q.w, q.y);
@@ -138,8 +131,7 @@ vec3 rgb2hsv(vec3 c)
return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x);
}
vec3 hsv2rgb(vec3 c)
{
vec3 hsv2rgb(vec3 c) {
vec4 K = vec4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www);
return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y);

View File

@@ -26,62 +26,62 @@
#define ELLIPSOID_HGLSL
struct PositionNormalPair {
vec3 position;
vec3 normal;
vec3 position;
vec3 normal;
};
struct Intersection {
bool intersects;
float nearParameter;// Along ray
float farParameter; // Along ray
float farParameter; // Along ray
};
vec3 geodeticSurfaceNormal(float latitude, float longitude)
{
float cosLat = cos(latitude);
return vec3(
cosLat * cos(longitude),
cosLat * sin(longitude),
sin(latitude));
float cosLat = cos(latitude);
return vec3(
cosLat * cos(longitude),
cosLat * sin(longitude),
sin(latitude));
}
PositionNormalPair geodetic3ToCartesian(
float latitude,
float longitude,
float height,
vec3 radiiSquared)
float latitude,
float longitude,
float height,
vec3 radiiSquared)
{
vec3 normal = geodeticSurfaceNormal(latitude, longitude);
vec3 k = radiiSquared * normal;
float gamma = sqrt(dot(k, normal));
vec3 rSurface = k / gamma;
PositionNormalPair toReturn;
toReturn.position = rSurface + height * normal;
toReturn.normal = normal;
return toReturn;
vec3 normal = geodeticSurfaceNormal(latitude, longitude);
vec3 k = radiiSquared * normal;
float gamma = sqrt(dot(k, normal));
vec3 rSurface = k / gamma;
PositionNormalPair toReturn;
toReturn.position = rSurface + height * normal;
toReturn.normal = normal;
return toReturn;
}
PositionNormalPair geodetic2ToCartesian(float latitude, float longitude, vec3 radiiSquared)
{
// Position on surface : height = 0
return geodetic3ToCartesian(latitude, longitude, 0, radiiSquared);
// Position on surface : height = 0
return geodetic3ToCartesian(latitude, longitude, 0, radiiSquared);
}
vec3 latLonToCartesian(float latitude, float longitude, float radius) {
return radius * vec3(
cos(latitude) * cos(longitude),
cos(latitude) * sin(longitude),
sin(latitude));
return radius * vec3(
cos(latitude) * cos(longitude),
cos(latitude) * sin(longitude),
sin(latitude));
}
//
// Assumes ellipsoid is at (0, 0, 0)
//
Intersection rayIntersectEllipsoid(
vec3 rayOrigin,
vec3 rayOriginSquared,
vec3 rayDirection,
vec3 oneOverEllipsoidRadiiSquared)
vec3 rayOrigin,
vec3 rayOriginSquared,
vec3 rayDirection,
vec3 oneOverEllipsoidRadiiSquared)
{
float a = dot(rayDirection * rayDirection, oneOverEllipsoidRadiiSquared);
float b = 2.0 * dot(rayOrigin * rayDirection, oneOverEllipsoidRadiiSquared);

View File

@@ -36,4 +36,3 @@ Fragment getFragment() {
frag.depth = fs_position.w;
return frag;
}

View File

@@ -28,7 +28,8 @@
#include <${MODULE_GLOBEBROWSING}/shaders/ellipsoid.hglsl>
#include <${MODULE_GLOBEBROWSING}/shaders/tile.hglsl>
#include <${MODULE_GLOBEBROWSING}/shaders/texturetilemapping.hglsl>
#include <${MODULE_GLOBEBROWSING}/shaders/tilevertexheight.hglsl>
#include <${MODULE_GLOBEBROWSING}/shaders/tileheight.hglsl>
#include <${MODULE_GLOBEBROWSING}/shaders/tilevertexskirt.hglsl>
uniform mat4 modelViewProjectionTransform;
uniform mat4 modelViewTransform;
@@ -39,6 +40,9 @@ uniform vec2 lonLatScalingFactor;
uniform vec3 cameraPosition;
uniform float chunkMinHeight;
uniform float distanceScaleFactor;
uniform int chunkLevel;
layout(location = 1) in vec2 in_uv;
out vec2 fs_uv;
@@ -47,16 +51,21 @@ out vec3 ellipsoidNormalCameraSpace;
out LevelWeights levelWeights;
out vec3 positionCameraSpace;
PositionNormalPair globalInterpolation() {
#if USE_ACCURATE_NORMALS
out vec3 ellipsoidTangentThetaCameraSpace;
out vec3 ellipsoidTangentPhiCameraSpace;
#endif //USE_ACCURATE_NORMALS
PositionNormalPair globalInterpolation(vec2 uv) {
vec2 lonLatInput;
lonLatInput.y = minLatLon.y + lonLatScalingFactor.y * in_uv.y; // Lat
lonLatInput.x = minLatLon.x + lonLatScalingFactor.x * in_uv.x; // Lon
lonLatInput.y = minLatLon.y + lonLatScalingFactor.y * uv.y; // Lat
lonLatInput.x = minLatLon.x + lonLatScalingFactor.x * uv.x; // Lon
PositionNormalPair positionPairModelSpace = geodetic2ToCartesian(lonLatInput.y, lonLatInput.x, radiiSquared);
return positionPairModelSpace;
}
void main() {
PositionNormalPair pair = globalInterpolation();
PositionNormalPair pair = globalInterpolation(in_uv);
float distToVertexOnEllipsoid =
length(pair.position + pair.normal * chunkMinHeight - cameraPosition);
@@ -70,11 +79,24 @@ void main() {
levelWeights = getLevelWeights(levelInterpolationParameter);
// Get the height value
float height = getTileVertexHeight(in_uv, levelWeights);
float height = getTileHeight(in_uv, levelWeights);
// Apply skirts
height -= getTileVertexSkirtLength();
#if USE_ACCURATE_NORMALS
// Calculate tangents
// tileDelta is a step length (epsilon). Should be small enough for accuracy but not
// Too small for precision. 1 / 512 is good.
float tileDelta = 1.0f / 512.0f;
PositionNormalPair pair10 = globalInterpolation(in_uv + vec2(1.0, 0.0) * tileDelta);
PositionNormalPair pair01 = globalInterpolation(in_uv + vec2(0.0, 1.0) * tileDelta);
vec3 ellipsoidTangentTheta = normalize(pair10.position - pair.position);
vec3 ellipsoidTangentPhi = normalize(pair01.position - pair.position);
ellipsoidTangentThetaCameraSpace = mat3(modelViewTransform) * ellipsoidTangentTheta;
ellipsoidTangentPhiCameraSpace = mat3(modelViewTransform) * ellipsoidTangentPhi;
#endif // USE_ACCURATE_NORMALS
// Add the height in the direction of the normal
pair.position += pair.normal * height;
vec4 positionClippingSpace = modelViewProjectionTransform * vec4(pair.position, 1);

View File

@@ -0,0 +1,61 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2017 *
* *
* 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. *
****************************************************************************************/
#ifndef GLOBESHADING_HGLSL
#define GLOBESHADING_HGLSL
float orenNayarDiffuse(
vec3 lightDirection,
vec3 viewDirection,
vec3 surfaceNormal,
float roughness)
{
// calculate intermediary values
float NdotL = dot(surfaceNormal, lightDirection);
float NdotV = dot(surfaceNormal, viewDirection);
float angleVN = acos(NdotV);
float angleLN = acos(NdotL);
float alpha = max(angleVN, angleLN);
float beta = min(angleVN, angleLN);
float gamma = dot(
viewDirection - surfaceNormal * dot(viewDirection, surfaceNormal),
lightDirection - surfaceNormal * dot(lightDirection, surfaceNormal)
);
float roughnessSquared = roughness * roughness;
// calculate A and B
float A = 1.0 - 0.5 * (roughnessSquared / (roughnessSquared + 0.57));
float B = 0.45 * (roughnessSquared / (roughnessSquared + 0.09));
float C = sin(alpha) * tan(beta);
// put it all together
float L1 = max(0.0, NdotL) * (A + B * max(0.0, gamma) * C);
return L1;
}
#endif // GLOBESHADING_HGLSL

View File

@@ -36,4 +36,3 @@ Fragment getFragment() {
frag.depth = fs_position.w;
return frag;
}

View File

@@ -28,7 +28,8 @@
#include <${MODULE_GLOBEBROWSING}/shaders/ellipsoid.hglsl>
#include <${MODULE_GLOBEBROWSING}/shaders/tile.hglsl>
#include <${MODULE_GLOBEBROWSING}/shaders/texturetilemapping.hglsl>
#include <${MODULE_GLOBEBROWSING}/shaders/tilevertexheight.hglsl>
#include <${MODULE_GLOBEBROWSING}/shaders/tileheight.hglsl>
#include <${MODULE_GLOBEBROWSING}/shaders/tilevertexskirt.hglsl>
uniform mat4 projectionTransform;
@@ -41,6 +42,9 @@ uniform vec3 p11;
uniform vec3 patchNormalCameraSpace;
uniform float chunkMinHeight;
uniform float distanceScaleFactor;
uniform int chunkLevel;
layout(location = 1) in vec2 in_uv;
out vec2 fs_uv;
@@ -49,6 +53,11 @@ out vec3 ellipsoidNormalCameraSpace;
out LevelWeights levelWeights;
out vec3 positionCameraSpace;
#if USE_ACCURATE_NORMALS
out vec3 ellipsoidTangentThetaCameraSpace;
out vec3 ellipsoidTangentPhiCameraSpace;
#endif // USE_ACCURATE_NORMALS
vec3 bilinearInterpolation(vec2 uv) {
vec3 p0 = (1 - uv.x) * p00 + uv.x * p10;
vec3 p1 = (1 - uv.x) * p01 + uv.x * p11;
@@ -75,7 +84,7 @@ void main() {
levelWeights = getLevelWeights(levelInterpolationParameter);
// Get the height value
float height = getTileVertexHeight(in_uv, levelWeights);
float height = getTileHeightScaled(in_uv, levelWeights);
// Apply skirts
height -= getTileVertexSkirtLength();
@@ -85,6 +94,12 @@ void main() {
vec4 positionClippingSpace = projectionTransform * vec4(p, 1);
#if USE_ACCURATE_NORMALS
// Calculate tangents
ellipsoidTangentThetaCameraSpace = normalize(p10 - p00);
ellipsoidTangentPhiCameraSpace = normalize(p01 - p00);
#endif // USE_ACCURATE_NORMALS
// Write output
fs_uv = in_uv;
fs_position = z_normalization(positionClippingSpace);

View File

@@ -27,6 +27,7 @@
#include <${MODULE_GLOBEBROWSING}/shaders/tile.hglsl>
#include <${MODULE_GLOBEBROWSING}/shaders/blending.hglsl>
#include <${MODULE_GLOBEBROWSING}/shaders/globeshading.hglsl>
// First layer type from LayerShaderManager is height map
#define NUMLAYERS_HEIGHTMAP #{lastLayerIndexHeightLayers} + 1
@@ -58,53 +59,54 @@
// Other key value pairs used for settings
#define USE_ATMOSPHERE #{useAtmosphere}
#define USE_ACCURATE_NORMALS #{useAccurateNormals}
#define PERFORM_SHADING #{performShading}
#define SHOW_CHUNK_EDGES #{showChunkEdges}
#define SHOW_HEIGHT_RESOLUTION #{showHeightResolution}
#define SHOW_HEIGHT_INTENSITIES #{showHeightIntensities}
float performLayerSettingsRGB(float currentValue, const LayerSettings settings) {
float newValue = currentValue;
float newValue = currentValue;
newValue = sign(newValue) * pow(abs(newValue), settings.gamma);
newValue = newValue * settings.multiplier;
newValue = newValue + settings.offset;
newValue = sign(newValue) * pow(abs(newValue), settings.gamma);
newValue = newValue * settings.multiplier;
newValue = newValue + settings.offset;
return newValue;
return newValue;
}
vec4 performLayerSettingsRGB(vec4 currentValue, const LayerSettings settings) {
vec4 newValue = vec4(
performLayerSettingsRGB(currentValue.r, settings),
performLayerSettingsRGB(currentValue.g, settings),
performLayerSettingsRGB(currentValue.b, settings),
currentValue.a);
vec4 newValue = vec4(
performLayerSettingsRGB(currentValue.r, settings),
performLayerSettingsRGB(currentValue.g, settings),
performLayerSettingsRGB(currentValue.b, settings),
currentValue.a);
return newValue;
return newValue;
}
float performLayerSettingsAlpha(float currentValue, const LayerSettings settings) {
float newValue = currentValue;
newValue = newValue * settings.opacity;
return newValue;
float newValue = currentValue;
newValue = newValue * settings.opacity;
return newValue;
}
vec4 performLayerSettingsAlpha(vec4 currentValue, const LayerSettings settings) {
vec4 newValue = currentValue;
newValue.a = performLayerSettingsAlpha(currentValue.a, settings);
return newValue;
vec4 newValue = currentValue;
newValue.a = performLayerSettingsAlpha(currentValue.a, settings);
return newValue;
}
float performLayerSettings(float currentValue, const LayerSettings settings) {
float newValue = performLayerSettingsRGB(currentValue, settings);
newValue = performLayerSettingsAlpha(newValue, settings);
return newValue;
float newValue = performLayerSettingsRGB(currentValue, settings);
newValue = performLayerSettingsAlpha(newValue, settings);
return newValue;
}
vec4 performLayerSettings(vec4 currentValue, const LayerSettings settings) {
vec4 newValue = performLayerSettingsRGB(currentValue, settings);
newValue = performLayerSettingsAlpha(newValue, settings);
return newValue;
vec4 newValue = performLayerSettingsRGB(currentValue, settings);
newValue = performLayerSettingsAlpha(newValue, settings);
return newValue;
}
@@ -112,32 +114,32 @@ vec4 performLayerSettings(vec4 currentValue, const LayerSettings settings) {
#for i in 0..#{lastLayerIndex#{layerGroup}}
vec4 getSample#{layerGroup}#{i}(
const vec2 uv,
const LevelWeights levelWeights,
const Layer #{layerGroup}[#{lastLayerIndex#{layerGroup}} + 1])
const vec2 uv,
const LevelWeights levelWeights,
const Layer #{layerGroup}[#{lastLayerIndex#{layerGroup}} + 1])
{
vec4 color = vec4(0,0,0,1);
// All tile layers are the same. Sample from texture
vec4 color = vec4(0,0,0,1);
// All tile layers are the same. Sample from texture
#if (#{#{layerGroup}#{i}LayerType} == 0) // DefaultTileLayer
color = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv);
color = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv);
#elif (#{#{layerGroup}#{i}LayerType} == 1) // SingleImageTileLayer
color = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv);
color = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv);
#elif (#{#{layerGroup}#{i}LayerType} == 2) // SizeReferenceTileLayer
color = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv);
color = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv);
#elif (#{#{layerGroup}#{i}LayerType} == 3) // TemporalTileLayer
color = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv);
color = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv);
#elif (#{#{layerGroup}#{i}LayerType} == 4) // TileIndexTileLayer
color = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv);
color = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv);
#elif (#{#{layerGroup}#{i}LayerType} == 5) // ByIndexTileLayer
color = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv);
color = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv);
#elif (#{#{layerGroup}#{i}LayerType} == 6) // ByLevelTileLayer
color = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv);
color = getTexVal(#{layerGroup}[#{i}].pile, levelWeights, uv);
#elif (#{#{layerGroup}#{i}LayerType} == 7) // SolidColor
color.rgb = #{layerGroup}[#{i}].color;
color.rgb = #{layerGroup}[#{i}].color;
#endif
return color;
return color;
}
#endfor
@@ -148,24 +150,24 @@ vec4 getSample#{layerGroup}#{i}(
vec4 blend#{layerGroup}#{i}(vec4 currentColor, vec4 newColor, float blendFactor) {
#if (#{#{layerGroup}#{i}BlendMode} == 0) // Default, Normal
return blendNormal(currentColor, vec4(newColor.rgb, newColor.a * blendFactor));
return blendNormal(currentColor, vec4(newColor.rgb, newColor.a * blendFactor));
#elif (#{#{layerGroup}#{i}BlendMode} == 1) // Multiply
return blendMultiply(currentColor, newColor * blendFactor);
return blendMultiply(currentColor, newColor * blendFactor);
#elif (#{#{layerGroup}#{i}BlendMode} == 2) // Add
return blendAdd(currentColor, newColor * blendFactor);
return blendAdd(currentColor, newColor * blendFactor);
#elif (#{#{layerGroup}#{i}BlendMode} == 3) // Subtract
return blendSubtract(currentColor, newColor * blendFactor);
return blendSubtract(currentColor, newColor * blendFactor);
#elif (#{#{layerGroup}#{i}BlendMode} == 4) // Color
// Convert color to grayscale
float gray = (newColor.r + newColor.g + newColor.b) / 3.0;
vec3 hsvCurrent = rgb2hsv(currentColor.rgb);
// Use gray from new color as value in hsv
vec3 hsvNew = vec3(hsvCurrent.x, hsvCurrent.y, gray);
vec3 rgbNew = hsv2rgb(hsvNew);
// Convert color to grayscale
float gray = (newColor.r + newColor.g + newColor.b) / 3.0;
vec3 hsvCurrent = rgb2hsv(currentColor.rgb);
// Use gray from new color as value in hsv
vec3 hsvNew = vec3(hsvCurrent.x, hsvCurrent.y, gray);
vec3 rgbNew = hsv2rgb(hsvNew);
vec4 color = blendNormal(currentColor, vec4(rgbNew, newColor.a * blendFactor));
return color;
vec4 color = blendNormal(currentColor, vec4(rgbNew, newColor.a * blendFactor));
return color;
#endif
}
@@ -178,18 +180,18 @@ vec4 blend#{layerGroup}#{i}(vec4 currentColor, vec4 newColor, float blendFactor)
vec4 performAdjustment#{layerGroup}#{i}(vec4 currentColor, const LayerAdjustment adjustment) {
#if (#{#{layerGroup}#{i}LayerAdjustmentType} == 0) // Default, None
return currentColor;
return currentColor;
#elif (#{#{layerGroup}#{i}LayerAdjustmentType} == 1) // ChromaKey
if (distance(currentColor.rgb, adjustment.chromaKeyColor) <= adjustment.chromaKeyTolerance) {
return vec4(0,0,0,0);
}
else {
return currentColor;
}
if (distance(currentColor.rgb, adjustment.chromaKeyColor) <= adjustment.chromaKeyTolerance) {
return vec4(0,0,0,0);
}
else {
return currentColor;
}
#elif (#{#{layerGroup}#{i}LayerAdjustmentType} == 2) // TransferFunction
return currentColor;
return currentColor;
#else
return currentColor;
return currentColor;
#endif
}
@@ -197,234 +199,241 @@ vec4 performAdjustment#{layerGroup}#{i}(vec4 currentColor, const LayerAdjustment
#endfor
float calculateUntransformedHeight(
vec2 uv,
LevelWeights levelWeights,
const Layer HeightLayers[NUMLAYERS_HEIGHTMAP]) {
vec2 uv,
LevelWeights levelWeights,
const Layer HeightLayers[NUMLAYERS_HEIGHTMAP]) {
float height = 0;
float height = 0;
// The shader compiler will remove unused code when variables are multiplied by
// a constant 0
// The shader compiler will remove unused code when variables are multiplied by
// a constant 0
#if !HEIGHTMAP_BLENDING_ENABLED
levelWeights = getDefaultLevelWeights();
levelWeights = getDefaultLevelWeights();
#endif // HEIGHTMAP_BLENDING_ENABLED
#for i in 0..#{lastLayerIndexHeightLayers}
{
vec4 colorSample = getSampleHeightLayers#{i}(uv, levelWeights, HeightLayers);
colorSample = performAdjustmentHeightLayers#{i}(colorSample, HeightLayers[#{i}].adjustment);
height = colorSample.r;
#for i in 0..#{lastLayerIndexHeightLayers}
{
vec4 colorSample = getSampleHeightLayers#{i}(uv, levelWeights, HeightLayers);
colorSample = performAdjustmentHeightLayers#{i}(colorSample, HeightLayers[#{i}].adjustment);
height = colorSample.r;
height = performLayerSettings(height, HeightLayers[#{i}].settings);
}
#endfor
return height;
height = performLayerSettings(height, HeightLayers[#{i}].settings);
}
#endfor
return height;
}
float calculateHeight(
vec2 uv,
LevelWeights levelWeights,
const Layer HeightLayers[NUMLAYERS_HEIGHTMAP]) {
vec2 uv,
LevelWeights levelWeights,
const Layer HeightLayers[NUMLAYERS_HEIGHTMAP]) {
float height = 0;
float height = 0;
// The shader compiler will remove unused code when variables are multiplied by
// a constant 0
// The shader compiler will remove unused code when variables are multiplied by
// a constant 0
#if !HEIGHTMAP_BLENDING_ENABLED
levelWeights = getDefaultLevelWeights();
levelWeights = getDefaultLevelWeights();
#endif // HEIGHTMAP_BLENDING_ENABLED
#for i in 0..#{lastLayerIndexHeightLayers}
{
vec4 colorSample = getSampleHeightLayers#{i}(uv, levelWeights, HeightLayers);
colorSample = performAdjustmentHeightLayers#{i}(colorSample, HeightLayers[#{i}].adjustment);
float untransformedHeight = colorSample.r;
#for i in 0..#{lastLayerIndexHeightLayers}
{
vec4 colorSample = getSampleHeightLayers#{i}(uv, levelWeights, HeightLayers);
colorSample = performAdjustmentHeightLayers#{i}(colorSample, HeightLayers[#{i}].adjustment);
float untransformedHeight = colorSample.r;
float heightSample = getTransformedTexVal(HeightLayers[#{i}].depthTransform, untransformedHeight);
if (heightSample > -100000) {
heightSample = performLayerSettings(heightSample, HeightLayers[#{i}].settings);
height = heightSample;
}
}
#endfor
return height;
float heightSample = getTransformedTexVal(HeightLayers[#{i}].depthTransform, untransformedHeight);
if (heightSample > -100000) {
heightSample = performLayerSettings(heightSample, HeightLayers[#{i}].settings);
height = heightSample;
}
}
#endfor
return height;
}
vec4 calculateColor(
const vec4 currentColor,
const vec2 uv,
LevelWeights levelWeights,
const Layer ColorLayers[NUMLAYERS_COLORTEXTURE]) {
const vec4 currentColor,
const vec2 uv,
LevelWeights levelWeights,
const Layer ColorLayers[NUMLAYERS_COLORTEXTURE]) {
vec4 color = currentColor;
vec4 color = currentColor;
// The shader compiler will remove unused code when variables are multiplied by
// a constant 0
// The shader compiler will remove unused code when variables are multiplied by
// a constant 0
#if !COLORTEXTURE_BLENDING_ENABLED
levelWeights = getDefaultLevelWeights();
levelWeights = getDefaultLevelWeights();
#endif // COLORTEXTURE_BLENDING_ENABLED
#for i in 0..#{lastLayerIndexColorLayers}
{
vec4 colorSample = getSampleColorLayers#{i}(uv, levelWeights, ColorLayers);
colorSample = performAdjustmentColorLayers#{i}(colorSample, ColorLayers[#{i}].adjustment);
colorSample = performLayerSettings(colorSample, ColorLayers[#{i}].settings);
#for i in 0..#{lastLayerIndexColorLayers}
{
vec4 colorSample = getSampleColorLayers#{i}(uv, levelWeights, ColorLayers);
colorSample = performAdjustmentColorLayers#{i}(colorSample, ColorLayers[#{i}].adjustment);
colorSample = performLayerSettings(colorSample, ColorLayers[#{i}].settings);
color = blendColorLayers#{i}(color, colorSample, 1.0);
}
#endfor
color = blendColorLayers#{i}(color, colorSample, 1.0);
}
#endfor
return color;
return color;
}
float gridDots(vec2 uv, vec2 gridResolution){
vec2 uvVertexSpace = fract((gridResolution) * uv) + 0.5;
vec2 uvVertexSpace = fract((gridResolution) * uv) + 0.5;
vec2 uvDotSpace = abs(2*(uvVertexSpace-0.5));
return 1-length(1-uvDotSpace);
vec2 uvDotSpace = abs(2*(uvVertexSpace-0.5));
return 1-length(1-uvDotSpace);
}
vec4 calculateDebugColor(vec2 uv, vec4 fragPos, vec2 vertexResolution){
vec2 uvVertexSpace = fract(vertexResolution * uv);
vec3 colorUv = vec3(0.3*uv.x, 0.3*uv.y, 0);
vec3 colorDistance = vec3(0, 0, min( 0.4*log(fragPos.w) - 3.9, 1));
vec3 colorVertex = (1.0-length(uvVertexSpace)) * vec3(0.5);
vec3 colorSum = colorUv + colorDistance + colorVertex;
return vec4(0.5 * colorSum, 1);
vec2 uvVertexSpace = fract(vertexResolution * uv);
vec3 colorUv = vec3(0.3*uv.x, 0.3*uv.y, 0);
vec3 colorDistance = vec3(0, 0, min( 0.4*log(fragPos.w) - 3.9, 1));
vec3 colorVertex = (1.0-length(uvVertexSpace)) * vec3(0.5);
vec3 colorSum = colorUv + colorDistance + colorVertex;
return vec4(0.5 * colorSum, 1);
}
float tileResolution(vec2 tileUV, const ChunkTile chunkTile){
vec2 heightResolution = textureSize(chunkTile.textureSampler, 0);
vec2 uv = TileUVToTextureSamplePosition(chunkTile, tileUV);
return gridDots(uv, heightResolution);
vec2 heightResolution = textureSize(chunkTile.textureSampler, 0);
vec2 uv = TileUVToTextureSamplePosition(chunkTile, tileUV);
return gridDots(uv, heightResolution);
}
vec4 calculateNight(
const vec4 currentColor,
const vec2 uv,
LevelWeights levelWeights,
const Layer NightLayers[NUMLAYERS_NIGHTTEXTURE],
const vec3 ellipsoidNormalCameraSpace,
const vec3 lightDirectionCameraSpace) {
const vec4 currentColor,
const vec2 uv,
LevelWeights levelWeights,
const Layer NightLayers[NUMLAYERS_NIGHTTEXTURE],
const vec3 ellipsoidNormalCameraSpace,
const vec3 lightDirectionCameraSpace) {
vec4 nightColor = vec4(0,0,0,0);
vec4 color = currentColor;
vec4 nightColor = vec4(0,0,0,0);
vec4 color = currentColor;
// The shader compiler will remove unused code when variables are multiplied by
// a constant 0
// The shader compiler will remove unused code when variables are multiplied by
// a constant 0
#if !NIGHTTEXTURE_BLENDING_ENABLED
levelWeights = getDefaultLevelWeights();
levelWeights = getDefaultLevelWeights();
#endif // NIGHTTEXTURE_BLENDING_ENABLED
vec3 n = normalize(ellipsoidNormalCameraSpace);
vec3 l = lightDirectionCameraSpace;
float cosineFactor = clamp(dot(l, normalize(n + 0.15 * l)) * 3 , 0, 1);
#for i in 0..#{lastLayerIndexNightLayers}
{
vec4 colorSample = getSampleNightLayers#{i}(uv, levelWeights, NightLayers);
colorSample = performAdjustmentNightLayers#{i}(colorSample, NightLayers[#{i}].adjustment);
colorSample = performLayerSettings(colorSample, NightLayers[#{i}].settings);
vec3 n = normalize(ellipsoidNormalCameraSpace);
vec3 l = lightDirectionCameraSpace;
float cosineFactor = clamp(dot(l, normalize(n + 0.15 * l)) * 3 , 0, 1);
#for i in 0..#{lastLayerIndexNightLayers}
{
vec4 colorSample = getSampleNightLayers#{i}(uv, levelWeights, NightLayers);
colorSample = performAdjustmentNightLayers#{i}(colorSample, NightLayers[#{i}].adjustment);
colorSample = performLayerSettings(colorSample, NightLayers[#{i}].settings);
float adjustedAlpha = cosineFactor * colorSample.a;
// Filter to night side
vec4 newColor = vec4(cosineFactor * colorSample.xyz, adjustedAlpha);
float adjustedAlpha = cosineFactor * colorSample.a;
// Filter to night side
vec4 newColor = vec4(cosineFactor * colorSample.xyz, adjustedAlpha);
color = blendNightLayers#{i}(currentColor, newColor, adjustedAlpha);
}
#endfor
color = blendNightLayers#{i}(currentColor, newColor, adjustedAlpha);
}
#endfor
return color;
return color;
}
vec4 calculateShadedColor(
const vec4 currentColor,
const vec3 ellipsoidNormalCameraSpace,
const vec3 lightDirectionCameraSpace) {
const vec4 currentColor,
const vec3 ellipsoidNormalCameraSpace,
const vec3 lightDirectionCameraSpace,
const vec3 viewDirectionCameraSpace,
float roughness)
{
vec3 shadedColor = currentColor.rgb * 0.05;
vec3 shadedColor = currentColor.rgb * 0.05;
vec3 n = normalize(ellipsoidNormalCameraSpace);
vec3 l = lightDirectionCameraSpace;
float power = orenNayarDiffuse(
-lightDirectionCameraSpace,
viewDirectionCameraSpace,
ellipsoidNormalCameraSpace,
roughness);
vec3 n = normalize(ellipsoidNormalCameraSpace);
vec3 l = lightDirectionCameraSpace;
float cosineFactor = pow(clamp(dot(-l, n), 0, 1), 0.8);
// Blend shaded color with base color
vec4 color = vec4(cosineFactor * currentColor.xyz + (1 - cosineFactor) * shadedColor, currentColor.a);
return color;
power = max(smoothstep(0.0f, 0.1f, max(dot(-l, n), 0.0f)) * power, 0.0f);
vec4 color = vec4(shadedColor + currentColor.rgb * power, currentColor.a);
return color;
}
vec4 calculateOverlay(
const vec4 currentColor,
const vec2 uv,
LevelWeights levelWeights,
const Layer Overlays[NUMLAYERS_OVERLAY]) {
const vec4 currentColor,
const vec2 uv,
LevelWeights levelWeights,
const Layer Overlays[NUMLAYERS_OVERLAY]) {
vec4 color = currentColor;
vec4 color = currentColor;
// The shader compiler will remove unused code when variables are multiplied by
// a constant 0
// The shader compiler will remove unused code when variables are multiplied by
// a constant 0
#if !OVERLAY_BLENDING_ENABLED
levelWeights = getDefaultLevelWeights();
levelWeights = getDefaultLevelWeights();
#endif // OVERLAY_BLENDING_ENABLED
#for i in 0..#{lastLayerIndexOverlays}
{
vec4 colorSample = getSampleOverlays#{i}(uv, levelWeights, Overlays);
colorSample = performAdjustmentOverlays#{i}(colorSample, Overlays[#{i}].adjustment);
#for i in 0..#{lastLayerIndexOverlays}
{
vec4 colorSample = getSampleOverlays#{i}(uv, levelWeights, Overlays);
colorSample = performAdjustmentOverlays#{i}(colorSample, Overlays[#{i}].adjustment);
colorSample = performLayerSettings(colorSample, Overlays[#{i}].settings);
colorSample = performLayerSettings(colorSample, Overlays[#{i}].settings);
color = blendNormal(color, colorSample);
color = blendOverlays#{i}(color, colorSample, 1.0);
}
#endfor
color = blendNormal(color, colorSample);
color = blendOverlays#{i}(color, colorSample, 1.0);
}
#endfor
return color;
return color;
}
vec4 calculateWater(
const vec4 currentColor,
const vec2 uv,
LevelWeights levelWeights,
const Layer WaterMasks[NUMLAYERS_WATERMASK],
const vec3 ellipsoidNormalCameraSpace,
const vec3 lightDirectionCameraSpace,
const vec3 positionCameraSpace) {
const vec4 currentColor,
const vec2 uv,
LevelWeights levelWeights,
const Layer WaterMasks[NUMLAYERS_WATERMASK],
const vec3 ellipsoidNormalCameraSpace,
const vec3 lightDirectionCameraSpace,
const vec3 positionCameraSpace) {
vec4 waterColor = vec4(0,0,0,0);
vec4 waterColor = vec4(0,0,0,0);
// The shader compiler will remove unused code when variables are multiplied by
// a constant 0
// The shader compiler will remove unused code when variables are multiplied by
// a constant 0
#if !WATERMASK_BLENDING_ENABLED
levelWeights = getDefaultLevelWeights();
levelWeights = getDefaultLevelWeights();
#endif // WATERMASK_BLENDING_ENABLED
#for i in 0..#{lastLayerIndexWaterMasks}
{
vec4 colorSample = getSampleWaterMasks#{i}(uv, levelWeights, WaterMasks);
colorSample = performAdjustmentWaterMasks#{i}(colorSample, WaterMasks[#{i}].adjustment);
#for i in 0..#{lastLayerIndexWaterMasks}
{
vec4 colorSample = getSampleWaterMasks#{i}(uv, levelWeights, WaterMasks);
colorSample = performAdjustmentWaterMasks#{i}(colorSample, WaterMasks[#{i}].adjustment);
colorSample = performLayerSettingsAlpha(colorSample, WaterMasks[#{i}].settings);
colorSample.a = performLayerSettingsRGB(colorSample.a, WaterMasks[#{i}].settings);
colorSample = performLayerSettingsAlpha(colorSample, WaterMasks[#{i}].settings);
colorSample.a = performLayerSettingsRGB(colorSample.a, WaterMasks[#{i}].settings);
waterColor = blendWaterMasks#{i}(waterColor, colorSample, 1.0);
}
#endfor
waterColor = blendWaterMasks#{i}(waterColor, colorSample, 1.0);
}
#endfor
vec3 directionToFragmentCameraSpace = normalize(positionCameraSpace - vec3(0, 0, 0));
vec3 reflectionDirectionCameraSpace = reflect(lightDirectionCameraSpace, ellipsoidNormalCameraSpace);
float cosineFactor = clamp(dot(-reflectionDirectionCameraSpace, directionToFragmentCameraSpace), 0, 1);
cosineFactor = pow(cosineFactor, 100);
vec3 directionToFragmentCameraSpace = normalize(positionCameraSpace - vec3(0, 0, 0));
vec3 reflectionDirectionCameraSpace = reflect(lightDirectionCameraSpace, ellipsoidNormalCameraSpace);
float cosineFactor = clamp(dot(-reflectionDirectionCameraSpace, directionToFragmentCameraSpace), 0, 1);
cosineFactor = pow(cosineFactor, 100);
vec3 specularColor = vec3(1, 1, 1);
float specularIntensity = 0.4;
vec3 specularColor = vec3(1, 1, 1);
float specularIntensity = 0.4;
vec3 specularTotal = specularColor * cosineFactor * specularIntensity * waterColor.a;
vec3 specularTotal = specularColor * cosineFactor * specularIntensity * waterColor.a;
//return blendNormal(currentColor, waterColor);
return currentColor + vec4(specularTotal, 1);
//return blendNormal(currentColor, waterColor);
return currentColor + vec4(specularTotal, 1);
}
#endif // TEXTURETILEMAPPING_HGLSL

View File

@@ -32,11 +32,11 @@
#define TILE_PIXEL_SIZE_DIFFERENCE #{tilePaddingSizeDiff}
vec4 patchBorderOverlay(vec2 uv, vec3 borderColor, float borderSize) {
vec2 uvOffset = uv - vec2(0.5);
float thres = 0.5 - borderSize/2;
bool isBorder = abs(uvOffset.x) > thres || abs(uvOffset.y) > thres;
vec3 color = isBorder ? borderColor : vec3(0);
return vec4(color, 0);
vec2 uvOffset = uv - vec2(0.5);
float thres = 0.5 - borderSize/2;
bool isBorder = abs(uvOffset.x) > thres || abs(uvOffset.y) > thres;
vec3 color = isBorder ? borderColor : vec3(0);
return vec4(color, 0);
}
@@ -50,11 +50,11 @@ struct TileDepthTransform {
};
float getTransformedTexVal(const TileDepthTransform transform, const float val){
return transform.depthOffset + transform.depthScale * val;
return transform.depthOffset + transform.depthScale * val;
}
vec4 getTransformedTexVal(const TileDepthTransform transform, const vec4 val){
return transform.depthOffset + transform.depthScale * val;
return transform.depthOffset + transform.depthScale * val;
}
/////////////////////////////////////////////////////////////////////
@@ -71,30 +71,30 @@ struct TileUvTransform {
// ChunkTile //
/////////////////////////////////////////////////////////////////////
struct ChunkTile {
sampler2D textureSampler;
TileUvTransform uvTransform;
sampler2D textureSampler;
TileUvTransform uvTransform;
};
vec2 compensateSourceTextureSampling(vec2 startOffset, vec2 sizeDiff, const ChunkTile chunkTile, vec2 tileUV){
ivec2 resolution = textureSize(chunkTile.textureSampler, 0);
ivec2 resolution = textureSize(chunkTile.textureSampler, 0);
vec2 sourceSize = vec2(resolution) + sizeDiff;
vec2 currentSize = vec2(resolution);
vec2 sourceToCurrentSize = currentSize / sourceSize;
tileUV = sourceToCurrentSize * (tileUV - startOffset / sourceSize);
return tileUV;
vec2 sourceSize = vec2(resolution) + sizeDiff;
vec2 currentSize = vec2(resolution);
vec2 sourceToCurrentSize = currentSize / sourceSize;
tileUV = sourceToCurrentSize * (tileUV - startOffset / sourceSize);
return tileUV;
}
vec2 TileUVToTextureSamplePosition(const ChunkTile chunkTile, vec2 tileUV){
vec2 uv = chunkTile.uvTransform.uvOffset + chunkTile.uvTransform.uvScale * tileUV;
uv = compensateSourceTextureSampling(TILE_PIXEL_START_OFFSET, TILE_PIXEL_SIZE_DIFFERENCE, chunkTile, uv);
return uv;
vec2 uv = chunkTile.uvTransform.uvOffset + chunkTile.uvTransform.uvScale * tileUV;
uv = compensateSourceTextureSampling(TILE_PIXEL_START_OFFSET, TILE_PIXEL_SIZE_DIFFERENCE, chunkTile, uv);
return uv;
}
vec4 getTexVal(const ChunkTile chunkTile, vec2 tileUV){
vec2 samplePosition = TileUVToTextureSamplePosition(chunkTile, tileUV);
vec4 texVal = texture(chunkTile.textureSampler, samplePosition);
return texVal;
vec2 samplePosition = TileUVToTextureSamplePosition(chunkTile, tileUV);
vec4 texVal = texture(chunkTile.textureSampler, samplePosition);
return texVal;
}
@@ -103,67 +103,67 @@ vec4 getTexVal(const ChunkTile chunkTile, vec2 tileUV){
// Chunk Tile Pile //
/////////////////////////////////////////////////////////////////////
struct ChunkTilePile {
ChunkTile chunkTile0;
ChunkTile chunkTile1;
ChunkTile chunkTile2;
ChunkTile chunkTile0;
ChunkTile chunkTile1;
ChunkTile chunkTile2;
};
struct LayerSettings {
float opacity;
float gamma;
float multiplier;
float offset;
float valueBlending;
float opacity;
float gamma;
float multiplier;
float offset;
float valueBlending;
};
struct LayerAdjustment {
vec3 chromaKeyColor;
float chromaKeyTolerance;
vec3 chromaKeyColor;
float chromaKeyTolerance;
};
struct Layer {
ChunkTilePile pile;
TileDepthTransform depthTransform;
LayerSettings settings;
LayerAdjustment adjustment;
// Other layer type properties stuff
vec3 color;
ChunkTilePile pile;
TileDepthTransform depthTransform;
LayerSettings settings;
LayerAdjustment adjustment;
// Other layer type properties stuff
vec3 color;
};
struct LevelWeights {
float w1;
float w2;
float w3;
float w1;
float w2;
float w3;
};
float getLevelInterpolationParameter(int chunkLevel, float distanceScaleFactor, float distToVertexOnEllipsoid){
float projectedScaleFactor = distanceScaleFactor / distToVertexOnEllipsoid;
float desiredLevel = log2(projectedScaleFactor);
return chunkLevel - desiredLevel;
float projectedScaleFactor = distanceScaleFactor / distToVertexOnEllipsoid;
float desiredLevel = log2(projectedScaleFactor);
return chunkLevel - desiredLevel;
}
LevelWeights getLevelWeights(float levelInterpolationParameter){
LevelWeights levelWeights;
levelWeights.w1 = clamp(1 - levelInterpolationParameter, 0 , 1);
levelWeights.w2 = (clamp(levelInterpolationParameter, 0 , 1) - clamp(levelInterpolationParameter - 1, 0 , 1));
levelWeights.w3 = clamp(levelInterpolationParameter - 1, 0 , 1);
return levelWeights;
LevelWeights levelWeights;
levelWeights.w1 = clamp(1 - levelInterpolationParameter, 0 , 1);
levelWeights.w2 = (clamp(levelInterpolationParameter, 0 , 1) - clamp(levelInterpolationParameter - 1, 0 , 1));
levelWeights.w3 = clamp(levelInterpolationParameter - 1, 0 , 1);
return levelWeights;
}
LevelWeights getDefaultLevelWeights(){
LevelWeights levelWeights;
levelWeights.w1 = 1;
levelWeights.w2 = 0;
levelWeights.w3 = 0;
return levelWeights;
LevelWeights levelWeights;
levelWeights.w1 = 1;
levelWeights.w2 = 0;
levelWeights.w3 = 0;
return levelWeights;
}
vec4 getTexVal(const ChunkTilePile chunkTilePile, const LevelWeights w, const vec2 uv){
return w.w1 * getTexVal(chunkTilePile.chunkTile0, uv) +
w.w2 * getTexVal(chunkTilePile.chunkTile1, uv) +
w.w3 * getTexVal(chunkTilePile.chunkTile2, uv);
return w.w1 * getTexVal(chunkTilePile.chunkTile0, uv) +
w.w2 * getTexVal(chunkTilePile.chunkTile1, uv) +
w.w3 * getTexVal(chunkTilePile.chunkTile2, uv);
}

View File

@@ -27,6 +27,7 @@
#include <${MODULE_GLOBEBROWSING}/shaders/tile.hglsl>
#include <${MODULE_GLOBEBROWSING}/shaders/texturetilemapping.hglsl>
#include <${MODULE_GLOBEBROWSING}/shaders/tileheight.hglsl>
#include "PowerScaling/powerScaling_fs.hglsl"
@@ -58,7 +59,11 @@ uniform vec2 vertexResolution;
#endif // USE_ATMOSPHERE
#if USE_NIGHTTEXTURE || USE_WATERMASK || USE_ATMOSPHERE || PERFORM_SHADING
uniform vec3 lightDirectionCameraSpace;
uniform vec3 lightDirectionCameraSpace;
#endif
#if PERFORM_SHADING
uniform float orenNayarRoughness;
#endif
in vec4 fs_position;
@@ -66,144 +71,123 @@ in vec2 fs_uv;
in vec3 ellipsoidNormalCameraSpace;
in vec3 positionCameraSpace;
#if USE_ACCURATE_NORMALS
in vec3 ellipsoidTangentThetaCameraSpace;
in vec3 ellipsoidTangentPhiCameraSpace;
#endif // USE_ACCURATE_NORMALS
// levelInterpolationParameter is used to interpolate between a tile and its parent tiles
// The value increases with the distance from the vertex (or fragment) to the camera
in LevelWeights levelWeights;
/////////////////////////////////////////////////////////////////////
// The heightmaps is only used in the fragment shader visually debugging
// the alignment and resolution of the heightmaps
#if USE_HEIGHTMAP
uniform Layer HeightLayers[NUMLAYERS_HEIGHTMAP];
#endif // USE_HEIGHTMAP
float getUntransformedTileVertexHeight(vec2 uv, LevelWeights levelWeights){
float height = CHUNK_DEFAULT_HEIGHT;
#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
HeightLayers); // Three textures to sample from
#endif // USE_HEIGHTMAP
return height;
}
/////////////////////////////////////////////////////////////////////
/**
* This method defines the fragment color pipeline which is used in both
* the local and global chunk rendering.
*
*/
vec4 getTileFragColor(){
vec4 getTileFragColor() {
vec4 color = vec4(0.3,0.3,0.3,1);
vec4 color = vec4(0.3,0.3,0.3,1);
vec3 normal = normalize(ellipsoidNormalCameraSpace);
#if USE_ACCURATE_NORMALS
normal = getTileNormal(fs_uv, levelWeights,
normalize(ellipsoidNormalCameraSpace),
normalize(ellipsoidTangentThetaCameraSpace),
normalize(ellipsoidTangentPhiCameraSpace));
#endif /// USE_ACCURATE_NORMALS
#if USE_COLORTEXTURE
color = calculateColor(
color,
fs_uv,
levelWeights,
ColorLayers);
color = calculateColor(
color,
fs_uv,
levelWeights,
ColorLayers);
#endif // USE_COLORTEXTURE
#if USE_WATERMASK
color = calculateWater(
color,
fs_uv,
levelWeights,
WaterMasks,
normalize(ellipsoidNormalCameraSpace),
lightDirectionCameraSpace, // Should already be normalized
positionCameraSpace);
color = calculateWater(
color,
fs_uv,
levelWeights,
WaterMasks,
normal,
lightDirectionCameraSpace, // Should already be normalized
positionCameraSpace);
#endif // USE_WATERMASK
#if USE_NIGHTTEXTURE
color = calculateNight(
color,
fs_uv,
levelWeights,
NightLayers,
normalize(ellipsoidNormalCameraSpace),
lightDirectionCameraSpace); // Should already be normalized
color = calculateNight(
color,
fs_uv,
levelWeights,
NightLayers,
normalize(ellipsoidNormalCameraSpace),
lightDirectionCameraSpace); // Should already be normalized
#endif // USE_NIGHTTEXTURE
#if PERFORM_SHADING
color = calculateShadedColor(
color,
normalize(ellipsoidNormalCameraSpace),
lightDirectionCameraSpace);
color = calculateShadedColor(
color,
normal,
lightDirectionCameraSpace,
normalize(positionCameraSpace),
orenNayarRoughness);
#endif // PERFORM_SHADING
#if USE_ATMOSPHERE
// Temporary until the real atmosphere code is here
//color = color + vec4(0.5,0.5,1,0) * 0.3; // Just to see something for now
vec3 n = normalize(ellipsoidNormalCameraSpace);
vec3 l = lightDirectionCameraSpace;
vec3 c = normalize(positionCameraSpace);
float cosFactor = 1 - clamp(dot(-n * 0.9, c), 0, 1);
cosFactor *= 1.1;
cosFactor -= 0.1;
cosFactor = clamp(cosFactor, 0, 1);
cosFactor = cosFactor + pow(cosFactor, 5);
float shadowLight = 0.15;
float cosFactorLight = pow(max(dot(-l, n), -shadowLight) + shadowLight, 0.8);
//float cosFactorScatter = pow(max(dot(l, n) + shadowLight, 0), 5);
//float cosFactorLight = max(dot(-lightDirectionCameraSpace, normalize(ellipsoidNormalCameraSpace)), 0);
//vec3 r = reflect(l, n);
//float scatteredLight = pow(clamp(dot(-r,c), 0, 1), 20);
vec3 atmosphereColor = vec3(0.5,0.5,1) * 2;
color = color + vec4(atmosphereColor,0) * cosFactor * cosFactorLight * 0.5;
// Temporary until the real atmosphere code is here
//color = color + vec4(0.5,0.5,1,0) * 0.3; // Just to see something for now
vec3 n = normalize(ellipsoidNormalCameraSpace);
vec3 l = lightDirectionCameraSpace;
vec3 c = normalize(positionCameraSpace);
float cosFactor = 1 - clamp(dot(-n * 0.9, c), 0, 1);
cosFactor *= 1.1;
cosFactor -= 0.1;
cosFactor = clamp(cosFactor, 0, 1);
cosFactor = cosFactor + pow(cosFactor, 5);
float shadowLight = 0.15;
float cosFactorLight = pow(max(dot(-l, n), -shadowLight) + shadowLight, 0.8);
//float cosFactorScatter = pow(max(dot(l, n) + shadowLight, 0), 5);
//float cosFactorLight = max(dot(-lightDirectionCameraSpace, normalize(ellipsoidNormalCameraSpace)), 0);
//vec3 r = reflect(l, n);
//float scatteredLight = pow(clamp(dot(-r,c), 0, 1), 20);
vec3 atmosphereColor = vec3(0.5,0.5,1) * 2;
color = color + vec4(atmosphereColor,0) * cosFactor * cosFactorLight * 0.5;
#endif // USE_ATMOSPHERE
#if USE_OVERLAY
color = calculateOverlay(
color,
fs_uv,
levelWeights,
Overlays);
color = calculateOverlay(
color,
fs_uv,
levelWeights,
Overlays);
#endif // USE_OVERLAY
#if SHOW_HEIGHT_INTENSITIES
color.r *= 0.1;
color.g *= 0.1;
color.b *= 0.1;
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;
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, HeightLayers[0].pile.chunkTile0) > 0.9 ? 1 : 0;
#endif
color += 0.0001*calculateDebugColor(fs_uv, fs_position, vertexResolution);
#if USE_HEIGHTMAP
color.r = min(color.r, 0.8);
color.r += tileResolution(fs_uv, HeightLayers[0].pile.chunkTile0) > 0.9 ? 1 : 0;
#endif
#endif
return color;
return color;
}

View File

@@ -0,0 +1,125 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2017 *
* *
* 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. *
****************************************************************************************/
#ifndef TILE_HEIGHT_HGLSL
#define TILE_HEIGHT_HGLSL
#include "PowerScaling/powerScaling_vs.hglsl"
#include <${MODULE_GLOBEBROWSING}/shaders/tile.hglsl>
#include <${MODULE_GLOBEBROWSING}/shaders/ellipsoid.hglsl>
#ifndef USE_HEIGHTMAP
#define USE_HEIGHTMAP #{useAccurateNormals}
#endif //USE_HEIGHTMAP
#ifndef USE_ACCURATE_NORMALS
#define USE_ACCURATE_NORMALS #{useAccurateNormals}
#endif //USE_ACCURATE_NORMALS
#if USE_HEIGHTMAP
uniform Layer HeightLayers[NUMLAYERS_HEIGHTMAP];
uniform float heightScale;
#endif // USE_HEIGHTMAP
#if USE_ACCURATE_NORMALS
uniform float deltaTheta0;
uniform float deltaTheta1;
uniform float deltaPhi0;
uniform float deltaPhi1;
uniform float tileDelta;
#endif //USE_ACCURATE_NORMALS
float getUntransformedTileHeight(vec2 uv, LevelWeights levelWeights){
float height = CHUNK_DEFAULT_HEIGHT;
#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
HeightLayers); // Three textures to sample from
#endif // USE_HEIGHTMAP
return height;
}
float getTileHeight(vec2 uv, LevelWeights levelWeights){
float height = CHUNK_DEFAULT_HEIGHT;
#if USE_HEIGHTMAP
// Calculate desired level based on distance to the vertex on the ellipsoid
// Before any heightmapping is done
height = calculateHeight(
uv,
levelWeights, // Variable to determine which texture to sample from
HeightLayers); // Three textures to sample from
#endif // USE_HEIGHTMAP
return height;
}
float getTileHeightScaled(vec2 uv, LevelWeights levelWeights){
float height = getTileHeight(uv, levelWeights);
#if USE_HEIGHTMAP
height *= heightScale;
#endif // USE_HEIGHTMAP
return height;
}
vec3 getTileNormal(
vec2 uv,
LevelWeights levelWeights,
vec3 ellipsoidNormalCameraSpace,
vec3 ellipsoidTangentThetaCameraSpace,
vec3 ellipsoidTangentPhiCameraSpace)
{
vec3 normal = ellipsoidNormalCameraSpace;
#if USE_ACCURATE_NORMALS
float deltaPhi = mix(deltaPhi0, deltaPhi1, uv.x);
float deltaTheta = mix(deltaTheta0, deltaTheta1, uv.y);
vec3 deltaPhiVec = ellipsoidTangentPhiCameraSpace * deltaPhi;
vec3 deltaThetaVec = ellipsoidTangentThetaCameraSpace * deltaTheta;
float height00 = getTileHeightScaled(uv, levelWeights);
float height10 = getTileHeightScaled(uv + vec2(tileDelta, 0.0f), levelWeights);
float height01 = getTileHeightScaled(uv + vec2(0.0f, tileDelta), levelWeights);
vec3 diffTheta = deltaThetaVec + ellipsoidNormalCameraSpace * (height10 - height00);
vec3 diffPhi = deltaPhiVec + ellipsoidNormalCameraSpace * (height01 - height00);
normal = normalize(cross(diffTheta, diffPhi));
#endif // USE_ACCURATE_NORMALS
return normal;
}
#endif // TILE_HEIGHT_HGLSL

View File

@@ -1,126 +0,0 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2017 *
* *
* 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. *
****************************************************************************************/
#ifndef TILE_VERTEX_HEIGHT_HGLSL
#define TILE_VERTEX_HEIGHT_HGLSL
#include "PowerScaling/powerScaling_vs.hglsl"
#include <${MODULE_GLOBEBROWSING}/shaders/tile.hglsl>
#if USE_HEIGHTMAP
uniform Layer HeightLayers[NUMLAYERS_HEIGHTMAP];
#endif // USE_HEIGHTMAP
uniform int xSegments;
uniform float skirtLength;
uniform float distanceScaleFactor;
uniform int chunkLevel;
float getUntransformedTileVertexHeight(vec2 uv, LevelWeights levelWeights){
float height = CHUNK_DEFAULT_HEIGHT;
#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
HeightLayers); // Three textures to sample from
#endif // USE_HEIGHTMAP
return height;
}
float getTileVertexHeight(vec2 uv, LevelWeights levelWeights){
float height = CHUNK_DEFAULT_HEIGHT;
#if USE_HEIGHTMAP
// Calculate desired level based on distance to the vertex on the ellipsoid
// Before any heightmapping is done
height = calculateHeight(
uv,
levelWeights, // Variable to determine which texture to sample from
HeightLayers); // Three textures to sample from
#endif // USE_HEIGHTMAP
return height;
}
// This function is currently not correct
vec3 getTileVertexNormal(
vec2 uv,
LevelWeights levelWeights,
vec3 ellipsoidNormal) {
vec3 normal = ellipsoidNormal;
#if USE_HEIGHTMAP
float sampleDelta = 1.0 / xSegments;
float heightCenter = calculateHeight(
uv,
levelWeights,
HeightLayers);
float heightOffsetX = calculateHeight(
uv + vec2(sampleDelta, 0.0),
levelWeights,
HeightLayers);
float heightOffsetY = calculateHeight(
uv + vec2(0.0, sampleDelta),
levelWeights,
HeightLayers);
vec3 e0 = normalize(cross(vec3(0,0,1), ellipsoidNormal));
vec3 e1 = cross(ellipsoidNormal, e0);
vec3 e2 = ellipsoidNormal;
vec3 v0 = e0 * sampleDelta * 3000000 + e2 * heightOffsetX;
vec3 v1 = e1 * sampleDelta * 3000000 + e2 * heightOffsetY;
vec3 n = cross(v0, v1);
normal = normalize(n);
#endif // USE_HEIGHTMAP
return normal;
}
bool tileVertexIsSkirtVertex(){
int vertexIDx = gl_VertexID % (xSegments + 3);
int vertexIDy = gl_VertexID / (xSegments + 3);
return vertexIDx == 0 || vertexIDy == 0 ||
vertexIDx == (xSegments + 2) || vertexIDy == (xSegments + 2);
}
float getTileVertexSkirtLength(){
return tileVertexIsSkirtVertex() ? skirtLength : 0.0;
}
#endif // TILE_VERTEX_HEIGHT_HGLSL

View File

@@ -0,0 +1,44 @@
/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014-2017 *
* *
* 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. *
****************************************************************************************/
#ifndef TILE_VERTEX_SKIRT_HGLSL
#define TILE_VERTEX_SKIRT_HGLSL
#include "PowerScaling/powerScaling_vs.hglsl"
uniform int xSegments;
uniform float skirtLength;
bool tileVertexIsSkirtVertex(){
int vertexIDx = gl_VertexID % (xSegments + 3);
int vertexIDy = gl_VertexID / (xSegments + 3);
return vertexIDx == 0 || vertexIDy == 0 ||
vertexIDx == (xSegments + 2) || vertexIDy == (xSegments + 2);
}
float getTileVertexSkirtLength(){
return tileVertexIsSkirtVertex() ? skirtLength : 0.0;
}
#endif // TILE_VERTEX_SKIRT_HGLSL

View File

@@ -24,7 +24,6 @@ return {
-- Streaming OpenSpace via Spout to OBS
-- SGCTConfig = sgct.config.single{2560, 1440, shared=true, name="WV_OBS_SPOUT1"},
--SGCTConfig = "${CONFIG}/openvr_oculusRiftCv1.xml",
--SGCTConfig = "${CONFIG}/openvr_htcVive.xml",