Skip to content

FShade EffectDebugger

Harald Steinlechner edited this page Jan 26, 2018 · 5 revisions

The EffectDebugger lets you interactively edit FShade effects at runtime. 🔥 👌 💯

FShade EffectDebugger

What you need:

  • Update to a recent FShade version
  • Add a reference to FShade.Debug (in paket.dependencies and the project you would like to debug)
  • In code, open FShade, FShade.Imperative, Aardvark.Base.ShaderReflection
  • Define an effect in a named function locally, also define the Vertex type locally
  • Use the named effect
  • call FShade.EffectDebugger.attach() before running the window

What you can do:

  • When you run the program, a folder [name of your startup-Project] is created on your Desktop (make sure not to let you overwrite your actual project!)
    • the folder contains .fsx shader files with the FShade code that created your shaders
    • there is a file watch on the folder. It triggers every time you modify a file
    • the folder is also a local git repository
  • You can edit the FShade code in the shader files. Every time you save, the shader gets compiled and hot-plugged into the running Aardvark program
    • The inputs/outputs must remain the same
    • You should not produce compile errors
    • Aardvark libraries are referenced
    • Same restrictions as in FShade apply
  • You can also jump around in your editing history. The local git repository makes a commit every time you modify a file. You can use this repository to collaborate with other people

We recommend VSCode as editor. An example program that runs the EffectDebugger can look like this. The shader is called "light" and appears as file "Examples\light.fsx":

namespace Examples


open System
open Aardvark.Base
open Aardvark.Application
open Aardvark.Base.Rendering
open Aardvark.Base.ShaderReflection
open FShade
open FShade.Imperative
open System.Reflection

module MyShader =

    type Vertex = {
        [<Position>]        pos     : V4d
        [<WorldPosition>]   wp      : V4d
        [<Normal>]          n       : V3d
        [<BiNormal>]        b       : V3d
        [<Tangent>]         t       : V3d
        [<Color>]           c       : V4d
        [<TexCoord>]        tc      : V2d
    }

    let light (v : Vertex) = 
        fragment {
            let lightpos = V3d(5.0,6.0,7.0)                

            let n = v.n |> Vec.normalize
            let c = lightpos - v.wp.XYZ |> Vec.normalize
            let r = 2.0 * (Vec.dot c n |> clamp 0.0 1.0) * n - c |> Vec.normalize
            let cam = uniform?PerView?CameraLocation
            let vd = cam - v.wp.XYZ |> Vec.normalize
    
            let ambient = 0.1
            let diffuse = Vec.dot c n |> clamp 0.0 1.0
            let specular = V3d.III * (max (pow (Vec.dot r vd) 50.0) 0.0)
        
            let l = v.c.XYZ * (ambient + (1.0 - ambient) * diffuse)
            let col = l + l.Length * specular
        
            return V4d(col, v.c.W)
        }

module IGPrimitives =
    let run() =
        
        let win = 
            window {
                display Display.Mono
                samples 1
                backend Backend.Vulkan

                debug false
            }
        
        let igs =
            [|
                IndexedGeometryPrimitives.solidPhiThetaSphere (Sphere3d(V3d.OOO,0.5)) 12 (C4b(160,120,190))
                IndexedGeometryPrimitives.solidPhiThetaSphere (Sphere3d(V3d.OOO,0.5)) 12 (C4b(160,120,190))
                IndexedGeometryPrimitives.Sphere.solidSubdivisionSphere (Sphere3d(V3d.OOO,0.5)) (2) ((C4b(120,0,240)))
                IndexedGeometryPrimitives.solidSubdivisionSphere (Sphere3d(V3d.OOO,0.5)) (2) ((C4b(120,0,240)))
            |]

        let sg = 
            [ 
                for i in 0..(igs.Length-1) do
                    yield igs.[i]
                           |> Sg.ofIndexedGeometry
                           |> Sg.translate (float i * 1.5) 0.0 0.0
            ]
                |> Sg.ofList
                |> Sg.transform (Trafo3d.FromBasis(V3d.IOO, V3d.OOI, V3d.OIO, V3d.Zero))
                |> Sg.shader {
                    do! DefaultSurfaces.trafo
                    do! MyShader.light

                }
        
        FShade.EffectDebugger.attach()

        win.Scene <- sg

        win.Run()

Common Problems

  • if attach fails somewhere in FSharpCompiler services, copy FSharp.Core.sigdata and FSharp.Core.opdata beside your binaries.
Clone this wiki locally
You can’t perform that action at this time.