Files
OpenSpace/modules/globebrowsing/shaders/texturetilemapping.hglsl
T

436 lines
15 KiB
Plaintext

/*****************************************************************************************
* *
* OpenSpace *
* *
* Copyright (c) 2014 *
* *
* 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 LayeredTextureShaderProvider is height map
#define NUMLAYERS_HEIGHTMAP #{lastLayerIndexHeightMaps} + 1
#define USE_HEIGHTMAP #{useHeightMaps}
#define HEIGHTMAP_BLENDING_ENABLED #{blendHeightMaps}
// Second layer type from LayeredTextureShaderProvider is color texture
#define NUMLAYERS_COLORTEXTURE #{lastLayerIndexColorTextures} + 1
#define USE_COLORTEXTURE #{useColorTextures}
#define COLORTEXTURE_BLENDING_ENABLED #{blendColorTextures}
#define NUMLAYERS_GRAYSCALETEXTURE #{lastLayerIndexGrayScaleTextures} + 1
#define USE_GRAYSCALETEXTURE #{useGrayScaleTextures}
#define GRAYSCALETEXTURE_BLENDING_ENABLED #{blendGrayScaleTextures}
// Third layer type from LayeredTextureShaderProvider is water mask
#define NUMLAYERS_WATERMASK #{lastLayerIndexWaterMasks} + 1
#define USE_WATERMASK #{useWaterMasks}
#define WATERMASK_BLENDING_ENABLED #{blendWaterMasks}
// Fourth layer type from LayeredTextureShaderProvider is night texture
#define NUMLAYERS_NIGHTTEXTURE #{lastLayerIndexNightTextures} + 1
#define USE_NIGHTTEXTURE #{useNightTextures}
#define NIGHTTEXTURE_BLENDING_ENABLED #{blendNightTextures}
// Fifth layer type from LayeredTextureShaderProvider is overlay
#define NUMLAYERS_OVERLAY #{lastLayerIndexOverlays} + 1
#define USE_OVERLAY #{useOverlays}
#define OVERLAY_BLENDING_ENABLED #{blendOverlays}
// Sixth layer type from LayeredTextureShaderProvider is grayscale overlay
#define NUMLAYERS_GRAYSCALE_OVERLAY #{lastLayerIndexGrayScaleOverlays} + 1
#define USE_GRAYSCALE_OVERLAY #{useGrayScaleOverlays}
#define GRAYSCALE_OVERLAY_BLENDING_ENABLED #{blendGrayScaleOverlays}
// 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 PerLayerSettings settings) {
float newValue = currentValue;
newValue = sign(newValue) * pow(newValue, settings.gamma);
newValue = newValue * settings.multiplier;
newValue = newValue * settings.opacity;
return newValue;
}
vec4 performLayerSettings(vec4 currentValue, const PerLayerSettings 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 Tile heightTiles[NUMLAYERS_HEIGHTMAP],
const Tile heightTilesParent1[NUMLAYERS_HEIGHTMAP],
const Tile heightTilesParent2[NUMLAYERS_HEIGHTMAP],
const PerLayerSettings layerSettings[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;
height = performLayerSettings(height, layerSettings[#{i}]);
}
#endfor
return height;
}
float calculateHeight(
vec2 uv,
LevelWeights levelWeights,
const Tile heightTiles[NUMLAYERS_HEIGHTMAP],
const Tile heightTilesParent1[NUMLAYERS_HEIGHTMAP],
const Tile heightTilesParent2[NUMLAYERS_HEIGHTMAP],
const PerLayerSettings layerSettings[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}
{
float untransformedHeight =
levelWeights.w1 * getTexVal(heightTiles[#{i}], uv).r +
levelWeights.w2 * getTexVal(heightTilesParent1[#{i}], uv).r +
levelWeights.w3 * getTexVal(heightTilesParent2[#{i}], uv).r;
float heightSample = getTransformedTexVal(heightTiles[#{i}].depthTransform, untransformedHeight);
if (heightSample > -100000) {
heightSample = performLayerSettings(heightSample, layerSettings[#{i}]);
height = heightSample;
}
}
#endfor
return height;
}
vec4 calculateColor(
const vec2 uv,
LevelWeights levelWeights,
const Tile colorTiles[NUMLAYERS_COLORTEXTURE],
const Tile colorTilesParent1[NUMLAYERS_COLORTEXTURE],
const Tile colorTilesParent2[NUMLAYERS_COLORTEXTURE],
const PerLayerSettings layerSettings[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..#{lastLayerIndexColorTextures}
{
vec4 colorSample =
levelWeights.w1 * getTexVal(colorTiles[#{i}], uv) +
levelWeights.w2 * getTexVal(colorTilesParent1[#{i}], uv) +
levelWeights.w3 * getTexVal(colorTilesParent2[#{i}], uv);
colorSample = performLayerSettings(colorSample, layerSettings[#{i}]);
color = blendOver(color, colorSample);
}
#endfor
return color;
}
vec4 calculateGrayScale(
const vec4 currentColor,
const vec2 uv,
LevelWeights levelWeights,
const Tile grayscaleTextureTiles[NUMLAYERS_GRAYSCALETEXTURE],
const Tile grayscaleTextureTilesParent1[NUMLAYERS_GRAYSCALETEXTURE],
const Tile grayscaleTextureTilesParent2[NUMLAYERS_GRAYSCALETEXTURE],
const PerLayerSettings layerSettings[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..#{lastLayerIndexGrayScaleTextures}
{
vec4 colorSample =
levelWeights.w1 * getTexVal(grayscaleTextureTiles[#{i}], uv) +
levelWeights.w2 * getTexVal(grayscaleTextureTilesParent1[#{i}], uv) +
levelWeights.w3 * getTexVal(grayscaleTextureTilesParent2[#{i}], uv);
colorSample = vec4(colorSample.r, colorSample.r, colorSample.r, 1);
colorSample = performLayerSettings(colorSample, layerSettings[#{i}]);
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 Tile tile){
vec2 heightResolution = textureSize(tile.textureSampler, 0);
vec2 uv = TileUVToTextureSamplePosition(tile, tileUV);
return gridDots(uv, heightResolution);
}
vec4 calculateNight(
const vec4 currentColor,
const vec2 uv,
LevelWeights levelWeights,
const Tile nightTiles[NUMLAYERS_NIGHTTEXTURE],
const Tile nightTilesParent1[NUMLAYERS_NIGHTTEXTURE],
const Tile nightTilesParent2[NUMLAYERS_NIGHTTEXTURE],
const PerLayerSettings layerSettings[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..#{lastLayerIndexNightTextures}
{
vec4 colorSample =
levelWeights.w1 * getTexVal(nightTiles[#{i}], uv) +
levelWeights.w2 * getTexVal(nightTilesParent1[#{i}], uv) +
levelWeights.w3 * getTexVal(nightTilesParent2[#{i}], uv);
colorSample = performLayerSettings(colorSample, layerSettings[#{i}]);
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 Tile overlayTiles[NUMLAYERS_OVERLAY],
const Tile overlayTilesParent1[NUMLAYERS_OVERLAY],
const Tile overlayTilesParent2[NUMLAYERS_OVERLAY],
const PerLayerSettings layerSettings[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..#{lastLayerIndexOverlays}
{
vec4 colorSample =
levelWeights.w1 * getTexVal(overlayTiles[#{i}], uv) +
levelWeights.w2 * getTexVal(overlayTilesParent1[#{i}], uv) +
levelWeights.w3 * getTexVal(overlayTilesParent2[#{i}], uv);
colorSample = performLayerSettings(colorSample, layerSettings[#{i}]);
color = blendOver(color, colorSample);
}
#endfor
return color;
}
vec4 calculateGrayScaleOverlay(
const vec4 currentColor,
const vec2 uv,
LevelWeights levelWeights,
const Tile grayscaleOverlayTiles[NUMLAYERS_GRAYSCALE_OVERLAY],
const Tile grayscaleOverlayTilesParent1[NUMLAYERS_GRAYSCALE_OVERLAY],
const Tile grayscaleOverlayTilesParent2[NUMLAYERS_GRAYSCALE_OVERLAY],
const PerLayerSettings layerSettings[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..#{lastLayerIndexGrayScaleOverlays}
{
vec4 colorSample =
levelWeights.w1 * getTexVal(grayscaleOverlayTiles[#{i}], uv) +
levelWeights.w2 * getTexVal(grayscaleOverlayTilesParent1[#{i}], uv) +
levelWeights.w3 * getTexVal(grayscaleOverlayTilesParent2[#{i}], uv);
colorSample = vec4(colorSample.r, colorSample.r, colorSample.r, colorSample.g);
colorSample = performLayerSettings(colorSample, layerSettings[#{i}]);
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 Tile waterTiles[NUMLAYERS_WATERMASK],
const Tile waterTilesParent1[NUMLAYERS_WATERMASK],
const Tile waterTilesParent2[NUMLAYERS_WATERMASK],
const PerLayerSettings layerSettings[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 =
levelWeights.w1 * getTexVal(waterTiles[#{i}], uv) +
levelWeights.w2 * getTexVal(waterTilesParent1[#{i}], uv) +
levelWeights.w3 * getTexVal(waterTilesParent2[#{i}], uv);
colorSample = performLayerSettings(colorSample, layerSettings[#{i}]);
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