Skip to content

Commit

Permalink
Expose new LambertHillshader
Browse files Browse the repository at this point in the history
  • Loading branch information
breki committed May 26, 2024
1 parent c381db4 commit 2b6f508
Show file tree
Hide file tree
Showing 10 changed files with 93 additions and 39 deletions.
1 change: 0 additions & 1 deletion Demeton.Tests/Aw3d/AW3D experiments.fs
Original file line number Diff line number Diff line change
Expand Up @@ -93,7 +93,6 @@ let ``Generate hillshading from AW3D`` () =
let pixelShader =
IgorHillshader.shadePixel
{ SunAzimuth = IgorHillshader.DefaultSunAzimuth |> degToRad
SunAltitude = IgorHillshader.DefaultSunAltitude |> degToRad
ShadingColor = 0u
Intensity = 1.
HeightsArrayIndex = 0 }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ let ``Geo area needed is calculated correctly`` () =
IgorHillshadingIntensity = 1.
SlopeShadingIntensity = 1.
SunAzimuth = IgorHillshader.DefaultSunAzimuth |> degToRad
SunAltitude = IgorHillshader.DefaultSunAltitude |> degToRad
SunAltitude = LambertHillshader.DefaultSunAltitude |> degToRad
WaterBodiesColor = "#49C8FF" |> Png.Rgba8Bit.parseColorHexValue
LocalCacheDir = TileShadeCommand.DefaultLocalCacheDir
OutputDir = TileShadeCommand.DefaultOutputDir
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ let ``Projection is created`` () =
IgorHillshadingIntensity = 1.
SlopeShadingIntensity = 1.
SunAzimuth = IgorHillshader.DefaultSunAzimuth |> degToRad
SunAltitude = IgorHillshader.DefaultSunAltitude |> degToRad
SunAltitude = LambertHillshader.DefaultSunAltitude |> degToRad
WaterBodiesColor = "#49C8FF" |> Png.Rgba8Bit.parseColorHexValue
LocalCacheDir = TileShadeCommand.DefaultLocalCacheDir
OutputDir = TileShadeCommand.DefaultOutputDir
Expand Down
3 changes: 0 additions & 3 deletions Demeton.Tests/Shaders/Building igor hillshading step.fs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
module Tests.Shaders.``Building igor hillshading step``

open Demeton.Shaders
open Demeton.Shaders.Pipeline.Common
open Demeton.Shaders.Pipeline.Parsing
open Demeton.Shaders.Pipeline.BuildingIgorHillshading
Expand All @@ -26,7 +25,6 @@ let ``Can parse step without parameters`` () =
step = Ok(
IgorHillshading(
{ SunAzimuth = degToRad -45.
SunAltitude = IgorHillshader.DefaultSunAltitude
ShadingColor = 0u
Intensity = 1.
HeightsArrayIndex = 0 }
Expand All @@ -49,7 +47,6 @@ let ``Can parse step with valid parameters`` () =
step = Ok(
IgorHillshading(
{ SunAzimuth = degToRad -90.
SunAltitude = IgorHillshader.DefaultSunAltitude
ShadingColor = 0x333333ffu
Intensity = 1.
HeightsArrayIndex = 0 }
Expand Down
1 change: 0 additions & 1 deletion Demeton.Tests/Shaders/Hillshading/Igor's shading method.fs
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,6 @@ let ``Igor shading properties test`` () =
col: Rgba8Bit.RgbaColor
) : IgorHillshader.ShaderParameters =
{ SunAzimuth = az
SunAltitude = IgorHillshader.DefaultSunAltitude
ShadingColor = col
Intensity = 1.
HeightsArrayIndex = 0 }
Expand Down
13 changes: 10 additions & 3 deletions Demeton/Commands/TileShadeCommand.fs
Original file line number Diff line number Diff line change
Expand Up @@ -163,7 +163,7 @@ let supportedParameters: CommandParameter[] =
Option.build SunAltitudeParameter
|> Option.desc
"The altitude of the sun in degrees, 0° representing the horizon (default is 45°)."
|> Option.defaultValue IgorHillshader.DefaultSunAltitude
|> Option.defaultValue LambertHillshader.DefaultSunAltitude
|> Option.asFloat
|> Option.toPar

Expand Down Expand Up @@ -205,7 +205,7 @@ let fillOptions parsedParameters =
IgorHillshadingIntensity = 1.
SlopeShadingIntensity = 1.
SunAzimuth = IgorHillshader.DefaultSunAzimuth |> degToRad
SunAltitude = IgorHillshader.DefaultSunAltitude |> degToRad
SunAltitude = LambertHillshader.DefaultSunAltitude |> degToRad
WaterBodiesColor = defaultWaterBodiesColor
LocalCacheDir = DefaultLocalCacheDir
OutputDir = DefaultOutputDir
Expand Down Expand Up @@ -462,6 +462,13 @@ let run (options: Options) : Result<unit, string> =

let igorHillshadingStep =
ShadingStep.IgorHillshading
{ SunAzimuth = options.SunAzimuth
ShadingColor = 0u
Intensity = options.IgorHillshadingIntensity
HeightsArrayIndex = 0 }

let lambertHillshadingStep =
ShadingStep.LambertHillshading
{ SunAzimuth = options.SunAzimuth
SunAltitude = options.SunAltitude
ShadingColor = 0u
Expand All @@ -477,7 +484,7 @@ let run (options: Options) : Result<unit, string> =

let hillshadingStep =
Compositing(
igorHillshadingStep,
lambertHillshadingStep,
slopeShadingStep,
CompositingFuncIdAlphaDarken
)
Expand Down
1 change: 1 addition & 0 deletions Demeton/Demeton.fsproj
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
<Compile Include="Shaders\SlopeShader.fs"/>
<Compile Include="Shaders\AspectShader.fs"/>
<Compile Include="Shaders\IgorHillshader.fs"/>
<Compile Include="Shaders\LambertHillshader.fs"/>
<Compile Include="Shaders\Pipeline\Common.fs"/>
<Compile Include="Shaders\Pipeline\Parsing.fs"/>
<Compile Include="Shaders\Pipeline\Building.fs"/>
Expand Down
39 changes: 10 additions & 29 deletions Demeton/Shaders/IgorHillshader.fs
Original file line number Diff line number Diff line change
Expand Up @@ -11,20 +11,15 @@ type ShaderParameters =
{
// https://en.wikipedia.org/wiki/Azimuth
SunAzimuth: float
SunAltitude: float
ShadingColor: Rgba8Bit.RgbaColor
Intensity: float
HeightsArrayIndex: int }

[<Literal>]
let DefaultSunAzimuth = -45.

[<Literal>]
let DefaultSunAltitude = 45.

let defaultParameters =
{ SunAzimuth = DefaultSunAzimuth |> degToRad
SunAltitude = DefaultSunAltitude |> degToRad
{ SunAzimuth = degToRad DefaultSunAzimuth
ShadingColor = 0u
Intensity = 1.
HeightsArrayIndex = 0 }
Expand All @@ -34,29 +29,15 @@ let shadePixel parameters : Hillshading.PixelHillshader =
match Double.IsNaN(aspect) with
| true -> Rgba8Bit.TransparentColor
| false ->
// let aspectDiff =
// differenceBetweenAngles
// aspect
// parameters.SunAzimuth
// (Math.PI * 2.)
//
// // "darkness" is a value from 0 (bright) to 1 (dark)
// let slopeDarkness = slope / (Math.PI / 2.)
// let aspectDarkness = aspectDiff / Math.PI
// let darkness = slopeDarkness * aspectDarkness * parameters.Intensity

let cosSolarElevation = sin parameters.SunAltitude
let sinSolarElevation = cos parameters.SunAltitude
let cosAspectMinusAzimuth = cos (aspect - parameters.SunAzimuth)
let sinSlope = sin slope

let darkness =
(cosSolarElevation * cos slope)
+ (sinSolarElevation * sinSlope * cosAspectMinusAzimuth)
|> max 0.0
|> min 1.0 // Ensure positive values

let darkness = 1. - darkness
let aspectDiff =
differenceBetweenAngles
aspect
parameters.SunAzimuth
(Math.PI * 2.)

let slopeDarkness = slope / (Math.PI / 2.)
let aspectDarkness = aspectDiff / Math.PI
let darkness = slopeDarkness * aspectDarkness * parameters.Intensity

let alpha = Hillshading.colorComponentRatioToByte darkness

Expand Down
63 changes: 63 additions & 0 deletions Demeton/Shaders/LambertHillshader.fs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
[<RequireQualifiedAccess>]
module Demeton.Shaders.LambertHillshader

open Demeton.Shaders
open Demeton.Geometry.Common
open Png

open System

type ShaderParameters =
{
// https://en.wikipedia.org/wiki/Azimuth
SunAzimuth: float
SunAltitude: float
ShadingColor: Rgba8Bit.RgbaColor
Intensity: float
HeightsArrayIndex: int }

[<Literal>]
let DefaultSunAzimuth = -45.

[<Literal>]
let DefaultSunAltitude = 45.

let defaultParameters =
{ SunAzimuth = DefaultSunAzimuth |> degToRad
SunAltitude = DefaultSunAltitude |> degToRad
ShadingColor = 0u
Intensity = 1.
HeightsArrayIndex = 0 }

let shadePixel parameters : Hillshading.PixelHillshader =
fun _ slope aspect ->
match Double.IsNaN(aspect) with
| true -> Rgba8Bit.TransparentColor
| false ->
// let aspectDiff =
// differenceBetweenAngles
// aspect
// parameters.SunAzimuth
// (Math.PI * 2.)
//
// // "darkness" is a value from 0 (bright) to 1 (dark)
// let slopeDarkness = slope / (Math.PI / 2.)
// let aspectDarkness = aspectDiff / Math.PI
// let darkness = slopeDarkness * aspectDarkness * parameters.Intensity

let cosSolarElevation = sin parameters.SunAltitude
let sinSolarElevation = cos parameters.SunAltitude
let cosAspectMinusAzimuth = cos (aspect - parameters.SunAzimuth)
let sinSlope = sin slope

let darkness =
(cosSolarElevation * cos slope)
+ (sinSolarElevation * sinSlope * cosAspectMinusAzimuth)
|> max 0.0
|> min 1.0 // Ensure positive values

let darkness = 1. - darkness

let alpha = Hillshading.colorComponentRatioToByte darkness

parameters.ShadingColor |> Rgba8Bit.withAlpha alpha
7 changes: 7 additions & 0 deletions Demeton/Shaders/Pipeline/Common.fs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ type ShadingStep =
| SolidBackground of SolidBackground.Parameters
| ElevationColoring of ElevationColoring.Parameters
| IgorHillshading of IgorHillshader.ShaderParameters
| LambertHillshading of LambertHillshader.ShaderParameters
| SlopeShading of SlopeShader.ShaderParameters
| AspectShading of AspectShader.ShaderParameters
| CustomShading of ShadingFuncId
Expand Down Expand Up @@ -127,6 +128,12 @@ let rec executeShadingStep
Hillshading.shadeRaster
parameters.HeightsArrayIndex
(IgorHillshader.shadePixel parameters)
| LambertHillshading parameters ->
Log.info "Running lambert hillshading step..."

Hillshading.shadeRaster
parameters.HeightsArrayIndex
(LambertHillshader.shadePixel parameters)
| SlopeShading parameters ->
Log.info "Running slope shading step..."

Expand Down

0 comments on commit 2b6f508

Please sign in to comment.