/***************************************************************************************** * * * 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; } // Get the Reflectance from Here (JCC) 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