-
Notifications
You must be signed in to change notification settings - Fork 9
Higher order functions
rookboom edited this page Nov 14, 2012
·
3 revisions
This sample is an implementation of Perlin noise as presented by Ken Perlin and Simon Green in GPU Gems Volumes 1 and 2 respectively.
Notable in this sample is the use of higher order functions. Each of the examples above uses bump mapping to perturb the surface normal in some way. Different functions can be passed as arguments to the bump mapping function to get the desired effects.
The details of the perlin noise calculation is elided below. You can find the full source code here
module Perlin =
[<ReflectedDefinition>]
type Shader(...) =
let perlin (pos:float3) =
...
...
let stripes x f =
let PI = 3.14159265f;
let t = 0.5f + 0.5f * sin(f * 2.0f*PI * x);
t * t - 0.5f;
let turbulance(pos:float3) =
let absNoise = perlin >> abs
let mutable t = -0.5f
let mutable f = 1.0f
for i in 1..7 do
let n = absNoise(pos*f)
t <- t + n/f
f <- f*2.0f
t
let bump F (input:PSInput) =
let perturbedNormal =
let normal = input.Normal |> normalize
let pos = input.PositionOS
let f0 = F(pos)
let epsilon = 0.01f
let dx = float3(epsilon,0.0f,0.0f)
let dy = float3(0.0f,epsilon,0.0f)
let dz = float3(0.0f,0.0f,epsilon)
let fx = F(pos + dx)
let fy = F(pos + dy)
let fz = F(pos + dz)
let dF = float3(fx-f0,fy-f0,fz-f0)/epsilon
normal - dF|> normalize
BlinnPhong.surfaceColor scene mat input.PositionWS perturbedNormal
[<PixelShader>]
member m.lumpy input =
bump(fun pos -> 0.03f*perlin(pos*10.0f)) input
[<PixelShader>]
member m.marbled input =
bump(fun pos -> 0.01f*stripes (pos.x + 2.0f*turbulance(pos)) 1.6f) input
[<PixelShader>]
member m.crinkled input =
bump(fun pos -> -0.15f*turbulance pos) input