FShade


Tessellation

Since tessellation shaders typically involve both stages (TessControl and TessEval) we opted for a simpler API defining both at once.

A tessellation shader can be specified like this: (we're aware that those levels are stupid)

 1: 
 2: 
 3: 
 4: 
 5: 
 6: 
 7: 
 8: 
 9: 
10: 
11: 
12: 
13: 
14: 
15: 
16: 
17: 
18: 
type Vertex = { [<Position>] p : V4d }

let tessShader (tri : Triangle<Vertex>) =
    tessellation {
        // calculate tessellation levels (TessControl)
        let center = (tri.P0.p + tri.P1.p + tri.P2.p) / 3.0
        let level = 1.0 / center.Z
        let somePatchOutput = center

        // call tessellateTriangle/tessellateQuad
        let! coord = tessellateTriangle level (level, level, level)

        // interpolate the attributes (TessEval)
        let pos = coord.X * tri.P0.p + coord.Y * tri.P1.p + coord.Z * tri.P2.p
        return { p = pos + somePatchOutput }
    }

printGLSL (Effect.ofFunction tessShader)

which will compile to

#version 410

#ifdef Vertex
layout(location = 0) in vec4 Positions;
layout(location = 0) out vec4 tc_Positions;
void main()
{
    tc_Positions = Positions;
}

#endif

#ifdef TessControl
layout(vertices = 3) out;
layout(location = 0) in vec4 tc_Positions[];
layout(location = 0) out vec4 te_Positions[];
layout(location = 1) patch out vec4 te_somePatchOutput;
void main()
{
    if((gl_InvocationID == 0))
    {
        vec4 center = (((tc_Positions[0] + tc_Positions[1]) + tc_Positions[2]) / 3.0);
        float level = (1.0 / center.z);
        gl_TessLevelInner[0] = level;
        gl_TessLevelOuter[0] = level;
        gl_TessLevelOuter[1] = level;
        gl_TessLevelOuter[2] = level;
        te_somePatchOutput = center;
    }
    te_Positions[gl_InvocationID] = tc_Positions[gl_InvocationID];
}

#endif

#ifdef TessEval
layout(triangles, equal_spacing, ccw) in;
layout(location = 0) in vec4 te_Positions[];
layout(location = 1) patch in vec4 te_somePatchOutput;
layout(location = 0) out vec4 PositionsOut;
void main()
{
    PositionsOut = ((((gl_TessCoord.x * te_Positions[0]) + (gl_TessCoord.y * te_Positions[1])) + (gl_TessCoord.z * te_Positions[2])) + te_somePatchOutput);
}

#endif
namespace Microsoft
namespace Microsoft.FSharp
namespace Microsoft.FSharp.Quotations
namespace Aardvark
namespace Aardvark.Base
namespace FShade
namespace FShade.Imperative
module Utilities
type Vertex =
  {p: V4d;}
Multiple items
type PositionAttribute =
  inherit SemanticAttribute
  new : unit -> PositionAttribute

--------------------
new : unit -> PositionAttribute
Vertex.p: V4d
Multiple items
type V4d =
  struct
    new : v:int -> V4d + 25 overloads
    val X : float
    val Y : float
    val Z : float
    val W : float
    member Abs : V4d
    member AllDifferent : v:V4d -> bool + 1 overload
    member AllEqual : v:V4d -> bool + 1 overload
    member AllGreater : v:V4d -> bool + 1 overload
    member AllGreaterOrEqual : v:V4d -> bool + 1 overload
    ...
  end

--------------------
V4d ()
   (+0 other overloads)
V4d(v: int) : V4d
   (+0 other overloads)
V4d(a: int []) : V4d
   (+0 other overloads)
V4d(v: int64) : V4d
   (+0 other overloads)
V4d(a: int64 []) : V4d
   (+0 other overloads)
V4d(v: float32) : V4d
   (+0 other overloads)
V4d(a: float32 []) : V4d
   (+0 other overloads)
V4d(v: float) : V4d
   (+0 other overloads)
V4d(a: float []) : V4d
   (+0 other overloads)
V4d(index_fun: System.Func<int,float>) : V4d
   (+0 other overloads)
val tessShader : tri:Triangle<Vertex> -> Expr<Vertex>
val tri : Triangle<Vertex>
Multiple items
union case TriangleAdjacency.Triangle: 'a * 'a * 'a * 'a * 'a * 'a -> TriangleAdjacency<'a>

--------------------
type Triangle<'a> =
  | Triangle of 'a * 'a * 'a
    interface Primitive<'a>
    member Interpolate : coord:V3d -> 'v
    member Item : i:int -> 'a with get
    member P0 : 'a
    member P1 : 'a
    member P2 : 'a
    static member InputTopology : InputTopology
    static member VertexCount : int
val tessellation : TessBuilder
val center : V4d
val level : float
field V4d.Z: float
val somePatchOutput : V4d
val coord : V3d
val tessellateTriangle : li:float -> l01:float * l12:float * l20:float -> TessCoord<V3d>
val pos : V4d
field V3d.X: float
field V3d.Y: float
field V3d.Z: float
val printGLSL : effect:Effect -> unit
Multiple items
module Effect

from Utilities

--------------------
module Effect

from FShade

--------------------
type Effect =
  new : m:Lazy<Map<ShaderStage,Shader>> -> Effect
  new : m:Lazy<Map<ShaderStage,Shader>> * o:Effect list -> Effect
  private new : id:string * shaders:Lazy<Map<ShaderStage,Shader>> * composedOf:Effect list -> Effect
  member ComposedOf : Effect list
  member FirstShader : Shader option
  member FragmentShader : Shader option
  member GeometryShader : Shader option
  member Id : string
  member InputToplogy : InputTopology option
  member Inputs : Map<string,Type>
  ...

--------------------
new : m:System.Lazy<Map<ShaderStage,Shader>> -> Effect
new : m:System.Lazy<Map<ShaderStage,Shader>> * o:Effect list -> Effect
val ofFunction : shaderFunction:('a -> Expr<'b>) -> Effect
Fork me on GitHub