mirror of
https://github.com/OpenSpace/OpenSpace.git
synced 2026-01-04 10:40:09 -06:00
390 lines
13 KiB
Plaintext
390 lines
13 KiB
Plaintext
/*****************************************************************************************
|
|
* *
|
|
* 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 TEXTURETILEMAPPING_HGLSL
|
|
#define TEXTURETILEMAPPING_HGLSL
|
|
|
|
#include <${MODULE_GLOBEBROWSING}/shaders/tile.hglsl>
|
|
#include <${MODULE_GLOBEBROWSING}/shaders/blending.hglsl>
|
|
|
|
// First layer type from LayerShaderManager is height map
|
|
#define NUMLAYERS_HEIGHTMAP #{lastLayerIndexHeightLayers} + 1
|
|
#define USE_HEIGHTMAP #{useHeightLayers}
|
|
#define HEIGHTMAP_BLENDING_ENABLED #{blendHeightLayers}
|
|
|
|
// Second layer type from LayerShaderManager is color texture
|
|
#define NUMLAYERS_COLORTEXTURE #{lastLayerIndexColorLayers} + 1
|
|
#define USE_COLORTEXTURE #{useColorLayers}
|
|
#define COLORTEXTURE_BLENDING_ENABLED #{blendColorLayers}
|
|
|
|
#define NUMLAYERS_GRAYSCALETEXTURE #{lastLayerIndexGrayScaleLayers} + 1
|
|
#define USE_GRAYSCALETEXTURE #{useGrayScaleLayers}
|
|
#define GRAYSCALETEXTURE_BLENDING_ENABLED #{blendGrayScaleLayers}
|
|
|
|
// Third layer type from LayerShaderManager is water mask
|
|
#define NUMLAYERS_WATERMASK #{lastLayerIndexWaterMasks} + 1
|
|
#define USE_WATERMASK #{useWaterMasks}
|
|
#define WATERMASK_BLENDING_ENABLED #{blendWaterMasks}
|
|
|
|
// Fourth layer type from LayerShaderManager is night texture
|
|
#define NUMLAYERS_NIGHTTEXTURE #{lastLayerIndexNightLayers} + 1
|
|
#define USE_NIGHTTEXTURE #{useNightLayers}
|
|
#define NIGHTTEXTURE_BLENDING_ENABLED #{blendNightLayers}
|
|
|
|
// Fifth layer type from LayerShaderManager is overlay
|
|
#define NUMLAYERS_OVERLAY #{lastLayerIndexColorOverlays} + 1
|
|
#define USE_OVERLAY #{useColorOverlays}
|
|
#define OVERLAY_BLENDING_ENABLED #{blendColorOverlays}
|
|
|
|
// Sixth layer type from LayerShaderManager is grayscale overlay
|
|
#define NUMLAYERS_GRAYSCALE_OVERLAY #{lastLayerIndexGrayScaleColorOverlays} + 1
|
|
#define USE_GRAYSCALE_OVERLAY #{useGrayScaleColorOverlays}
|
|
#define GRAYSCALE_OVERLAY_BLENDING_ENABLED #{blendGrayScaleColorOverlays}
|
|
|
|
// Global constants
|
|
#define CHUNK_DEFAULT_HEIGHT #{defaultHeight}
|
|
|
|
// Other key value pairs used for settings
|
|
#define USE_ATMOSPHERE #{useAtmosphere}
|
|
#define PERFORM_SHADING #{performShading}
|
|
#define SHOW_CHUNK_EDGES #{showChunkEdges}
|
|
#define SHOW_HEIGHT_RESOLUTION #{showHeightResolution}
|
|
#define SHOW_HEIGHT_INTENSITIES #{showHeightIntensities}
|
|
|
|
float performLayerSettings(float currentValue, const LayerSettings settings) {
|
|
float newValue = currentValue;
|
|
|
|
newValue = sign(newValue) * pow(abs(newValue), settings.gamma);
|
|
newValue = newValue * settings.multiplier;
|
|
newValue = newValue * settings.opacity;
|
|
|
|
return newValue;
|
|
}
|
|
|
|
|
|
vec4 performLayerSettings(vec4 currentValue, const LayerSettings settings) {
|
|
vec4 newValue = vec4(
|
|
performLayerSettings(currentValue.r, settings),
|
|
performLayerSettings(currentValue.g, settings),
|
|
performLayerSettings(currentValue.b, settings),
|
|
performLayerSettings(currentValue.a, settings));
|
|
|
|
return newValue;
|
|
}
|
|
|
|
float calculateUntransformedHeight(
|
|
vec2 uv,
|
|
LevelWeights levelWeights,
|
|
const Layer HeightTextures[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..#{lastLayerIndexHeightLayers}
|
|
{
|
|
height = getTexVal(HeightTextures[#{i}].pile, levelWeights, uv).r;
|
|
|
|
height = performLayerSettings(height, HeightTextures[#{i}].settings);
|
|
}
|
|
#endfor
|
|
return height;
|
|
}
|
|
|
|
float calculateHeight(
|
|
vec2 uv,
|
|
LevelWeights levelWeights,
|
|
const Layer HeightTextures[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..#{lastLayerIndexHeightLayers}
|
|
{
|
|
float untransformedHeight = getTexVal(HeightTextures[#{i}].pile, levelWeights, uv).r;
|
|
|
|
float heightSample = getTransformedTexVal(HeightTextures[#{i}].depthTransform, untransformedHeight);
|
|
if (heightSample > -100000) {
|
|
heightSample = performLayerSettings(heightSample, HeightTextures[#{i}].settings);
|
|
height = heightSample;
|
|
}
|
|
}
|
|
#endfor
|
|
return height;
|
|
}
|
|
|
|
vec4 calculateColor(
|
|
const vec2 uv,
|
|
LevelWeights levelWeights,
|
|
const Layer ColorLayers[NUMLAYERS_COLORTEXTURE]) {
|
|
|
|
vec4 color = vec4(0);
|
|
|
|
// The shader compiler will remove unused code when variables are multiplied by
|
|
// a constant 0
|
|
#if !COLORTEXTURE_BLENDING_ENABLED
|
|
levelWeights = getDefaultLevelWeights();
|
|
#endif // COLORTEXTURE_BLENDING_ENABLED
|
|
|
|
#for i in 0..#{lastLayerIndexColorLayers}
|
|
{
|
|
vec4 colorSample = getTexVal(ColorLayers[#{i}].pile, levelWeights, uv);
|
|
|
|
colorSample = performLayerSettings(colorSample, ColorLayers[#{i}].settings);
|
|
|
|
color = blendOver(color, colorSample);
|
|
}
|
|
#endfor
|
|
|
|
return color;
|
|
}
|
|
|
|
vec4 calculateGrayScale(
|
|
const vec4 currentColor,
|
|
const vec2 uv,
|
|
LevelWeights levelWeights,
|
|
const Layer GrayScaleLayers[NUMLAYERS_GRAYSCALETEXTURE]) {
|
|
|
|
vec4 colorGrayScale = currentColor;
|
|
|
|
// The shader compiler will remove unused code when variables are multiplied by
|
|
// a constant 0
|
|
#if !GRAYSCALETEXTURE_BLENDING_ENABLED
|
|
levelWeights = getDefaultLevelWeights();
|
|
#endif // GRAYSCALE_OVERLAY_BLENDING_ENABLED
|
|
|
|
#for i in 0..#{lastLayerIndexGrayScaleLayers}
|
|
{
|
|
vec4 colorSample = getTexVal(GrayScaleLayers[#{i}].pile, levelWeights, uv);
|
|
|
|
colorSample = vec4(colorSample.r, colorSample.r, colorSample.r, 1);
|
|
colorSample = performLayerSettings(colorSample, GrayScaleLayers[#{i}].settings);
|
|
|
|
colorGrayScale = blendOver(colorGrayScale, colorSample);
|
|
}
|
|
#endfor
|
|
|
|
return colorGrayScale;
|
|
}
|
|
|
|
float gridDots(vec2 uv, vec2 gridResolution){
|
|
vec2 uvVertexSpace = fract((gridResolution) * uv) + 0.5;
|
|
|
|
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);
|
|
}
|
|
|
|
float tileResolution(vec2 tileUV, const ChunkTile chunkTile){
|
|
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) {
|
|
|
|
vec4 nightColor = vec4(0,0,0,0);
|
|
|
|
// The shader compiler will remove unused code when variables are multiplied by
|
|
// a constant 0
|
|
#if !NIGHTTEXTURE_BLENDING_ENABLED
|
|
levelWeights = getDefaultLevelWeights();
|
|
#endif // NIGHTTEXTURE_BLENDING_ENABLED
|
|
|
|
#for i in 0..#{lastLayerIndexNightLayers}
|
|
{
|
|
vec4 colorSample = getTexVal(NightLayers[#{i}].pile, levelWeights, uv);
|
|
colorSample = performLayerSettings(colorSample, NightLayers[#{i}].settings);
|
|
|
|
nightColor = blendOver(nightColor, colorSample);
|
|
}
|
|
#endfor
|
|
|
|
|
|
vec3 n = normalize(ellipsoidNormalCameraSpace);
|
|
vec3 l = lightDirectionCameraSpace;
|
|
|
|
float cosineFactor = clamp(dot(l, normalize(n + 0.15 * l)) * 3 , 0, 1);
|
|
|
|
// Blend shaded color with base color
|
|
vec4 color = vec4(currentColor.rgb + (cosineFactor) * nightColor.xyz, currentColor.a);
|
|
|
|
return color;
|
|
}
|
|
|
|
vec4 calculateShadedColor(
|
|
const vec4 currentColor,
|
|
const vec3 ellipsoidNormalCameraSpace,
|
|
const vec3 lightDirectionCameraSpace) {
|
|
|
|
vec3 shadedColor = currentColor.rgb * 0.05;
|
|
|
|
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;
|
|
}
|
|
|
|
vec4 calculateOverlay(
|
|
const vec4 currentColor,
|
|
const vec2 uv,
|
|
LevelWeights levelWeights,
|
|
const Layer ColorOverlays[NUMLAYERS_OVERLAY]) {
|
|
|
|
vec4 color = currentColor;
|
|
|
|
// The shader compiler will remove unused code when variables are multiplied by
|
|
// a constant 0
|
|
#if !OVERLAY_BLENDING_ENABLED
|
|
levelWeights = getDefaultLevelWeights();
|
|
#endif // OVERLAY_BLENDING_ENABLED
|
|
|
|
#for i in 0..#{lastLayerIndexColorOverlays}
|
|
{
|
|
vec4 colorSample = getTexVal(ColorOverlays[#{i}].pile, levelWeights, uv);
|
|
colorSample = performLayerSettings(colorSample, ColorOverlays[#{i}].settings);
|
|
|
|
color = blendOver(color, colorSample);
|
|
}
|
|
#endfor
|
|
|
|
return color;
|
|
}
|
|
|
|
vec4 calculateGrayScaleOverlay(
|
|
const vec4 currentColor,
|
|
const vec2 uv,
|
|
LevelWeights levelWeights,
|
|
const Layer GrayScaleColorOverlays[NUMLAYERS_GRAYSCALE_OVERLAY]) {
|
|
|
|
vec4 colorGrayScale = currentColor;
|
|
|
|
// The shader compiler will remove unused code when variables are multiplied by
|
|
// a constant 0
|
|
#if !GRAYSCALE_OVERLAY_BLENDING_ENABLED
|
|
levelWeights = getDefaultLevelWeights();
|
|
#endif // GRAYSCALE_OVERLAY_BLENDING_ENABLED
|
|
|
|
#for i in 0..#{lastLayerIndexGrayScaleColorOverlays}
|
|
{
|
|
vec4 colorSample = getTexVal(GrayScaleColorOverlays[#{i}].pile, levelWeights, uv);
|
|
|
|
colorSample = vec4(colorSample.r, colorSample.r, colorSample.r, colorSample.g);
|
|
colorSample = performLayerSettings(colorSample, GrayScaleColorOverlays[#{i}].settings);
|
|
|
|
colorGrayScale = blendOver(colorGrayScale, colorSample);
|
|
}
|
|
#endfor
|
|
|
|
// HSV blending
|
|
vec3 hsvCurrent = rgb2hsv(currentColor.rgb);
|
|
vec3 hsvNew = vec3(hsvCurrent.x, hsvCurrent.y, colorGrayScale.r);
|
|
vec3 rgbNew = hsv2rgb(hsvNew);
|
|
/*
|
|
// HSL blending
|
|
vec3 hslCurrent = rgb2hsl(currentColor.rgb);
|
|
//hslCurrent.y = hslCurrent.z > 0.7 ? 0 : hslCurrent.y;
|
|
vec3 hslNew = vec3(hslCurrent.x, hslCurrent.y, colorGrayScale.r);
|
|
vec3 rgbNew = hsl2rgb(hslNew);
|
|
*/
|
|
// No color blending, use grayscale
|
|
//vec3 rgbNew = colorGrayScale.rgb;
|
|
vec4 color = blendOver(currentColor, vec4(rgbNew, colorGrayScale.a));
|
|
|
|
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) {
|
|
|
|
vec4 waterColor = vec4(0,0,0,0);
|
|
|
|
// The shader compiler will remove unused code when variables are multiplied by
|
|
// a constant 0
|
|
#if !WATERMASK_BLENDING_ENABLED
|
|
levelWeights = getDefaultLevelWeights();
|
|
#endif // WATERMASK_BLENDING_ENABLED
|
|
|
|
#for i in 0..#{lastLayerIndexWaterMasks}
|
|
{
|
|
vec4 colorSample = getTexVal(WaterMasks[#{i}].pile, levelWeights, uv);
|
|
|
|
colorSample = performLayerSettings(colorSample, WaterMasks[#{i}].settings);
|
|
|
|
waterColor = blendOver(waterColor, colorSample);
|
|
}
|
|
#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 specularColor = vec3(1, 1, 1);
|
|
float specularIntensity = 0.4;
|
|
|
|
vec3 specularTotal = specularColor * cosineFactor * specularIntensity * waterColor.a;
|
|
|
|
//return blendOver(currentColor, waterColor);
|
|
return currentColor + vec4(specularTotal, 1);
|
|
}
|
|
|
|
#endif // TEXTURETILEMAPPING_HGLSL
|