Giter Site home page Giter Site logo

krauthaufen / fshade Goto Github PK

View Code? Open in Web Editor NEW
75.0 17.0 9.0 41.67 MB

FShade is a Library allowing users to write Shaders in F# using code-quotations

Home Page: https://fshade.org/

License: Apache License 2.0

Shell 0.01% F# 99.98% Batchfile 0.02%
gpgpu aardvark quotations

fshade's Introduction

Windows MacOS Linux NuGet Discord

FShade

FShade is a library for writing Shaders in F# using code-quotations.

The main documentation is located at: http://www.fshade.org/

FShade is neatly integrated into Aardvark.Rendering, where example shaders and compositions are showcased. You can find compute shaders in Aardvark.GPGPU. Supplementary documentation is in this repository's wiki, including the Shader Debugger.

fshade's People

Contributors

aszabo314 avatar gnufu avatar haraldsteinlechner avatar hyazinthh avatar krauthaufen avatar luithefirst avatar plukers avatar stefanmaierhofer avatar thomasortner avatar walchandreas avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

fshade's Issues

Missing `step`

I currently use a local helper to use this intrinsic function:

/// x < edge ? 0.0 : 1.0
[<GLSLIntrinsic("step({0},{1})"); Inline>] 
let step (edge : 'a) (x : 'a) : 'a = onlyInShaderCode "step"

It would be nice if this is also natively supported. We would also need to add this to Aardvark.Base.

Version 4.0.1 produces invalid code

Updating from 4.0.0 to 4.0.1 introduced the following error:

[GL] Shader compiler returned errors: "Fragment:
0(96) : error C1008: undefined variable "WorldPosition"
0(97) : error C1008: undefined variable "Normals"
  
  1: #version 430
  2: #define __SHADER_STAGE__
  3:
  4:
  5:
  6:
  7: layout(std140, binding = 0)
  8: uniform PerMaterial
  9: {
 10:     float AlphaTestValue;
 11:     vec4 DiffuseColor;
 12:     bool HasColorTexture;
 13:     bool HasOpacityTexture;
 14:     float PerfectReflectionFresnel;
 15:     mat3x3 TexCoordTransform;
 16:     vec3 TransmissionColor;
 17:     bool UseDielectric;
 18: };
 19:
 20:
 21: layout(std140, binding = 1)
 22: uniform Global
 23: {
 24:     vec3 BiasParameters;
 25: };
 26:
 27:
 28: layout(std140, binding = 2)
 29: uniform PerView
 30: {
 31:     vec3 CameraLocation;
 32:     mat4x4 ProjTrafo;
 33:     mat4x4 ViewTrafo;
 34: };
 35:
 36:
 37: layout(std140, binding = 3)
 38: uniform GlobalHF
 39: {
 40:     vec4 ClipPlaneCoefficients;
 41: };
 42:
 43:
 44: layout(std140, binding = 4)
 45: uniform PerModel
 46: {
 47:     mat4x4 ModelTrafo;
 48:     mat3x3 NormalMatrix;
 49: };
 50:
 51:
 52: layout(binding = 0)
 53: uniform sampler2D alphaSampler;
 54: layout(binding = 1)
 55: uniform sampler2D secondaryDepthSampler;
 56: layout(binding = 2)
 57: uniform sampler2D texSampler;
 58:
 59: float HiliteShaders_ReflectionSampling_fresnel_a7mAmvWk3Rb00qZneUwhmGA(float r0, float dotVN)
 60: {
 61:     return clamp((r0 + ((1.0 - r0) * pow((1.0 - dotVN), 5.0))), 0.0, 1.0);
 62: }
 63:
 64:
 65:
 66: #ifdef Vertex
 67:
 68: layout(location = 0) in vec2 DiffuseColorCoordinates;
 69: layout(location = 1) in vec3 Normals;
 70: layout(location = 2) in vec4 Positions;
 71: layout(location = 0) out vec2 fs_DiffuseColorCoordinates;
 72: layout(location = 1) out vec3 fs_Normals;
 73: layout(location = 2) out vec4 fs_WorldPosition;
 74: void main()
 75: {
 76:     vec4 wp = (Positions * ModelTrafo);
 77:     vec4 vp = (wp * ViewTrafo);
 78:     vec4 pp = (vp * ProjTrafo);
 79:     float clipDistance = dot(wp, ClipPlaneCoefficients);
 80:     vec3 texCoord = (vec3(DiffuseColorCoordinates.x, DiffuseColorCoordinates.y, 1.0) * TexCoordTransform);
 81:     gl_ClipDistance[0] = clipDistance;
 82:     fs_DiffuseColorCoordinates = vec2(texCoord.x, (1.0 - texCoord.y));
 83:     fs_Normals = (Normals * NormalMatrix);
 84:     gl_Position = pp;
 85:     fs_WorldPosition = wp;
 86: }
 87:
 88: #endif
 89:
 90:
 91:
 92: #ifdef Fragment
 93:
 94: vec3 helper(vec4 WorldPosition1, vec3 Normals1)
 95: {
 96:     vec3 eye = normalize((CameraLocation - WorldPosition.xyz));
 97:     float dotVN = clamp(dot(eye, normalize(Normals)), 0.0, 1.0);
 98:     float f_refr = (UseDielectric ? (1.0 - HiliteShaders_ReflectionSampling_fresnel_a7mAmvWk3Rb00qZneUwhmGA(PerfectReflectionFresnel, dotVN)) : 1.0);
 99:     return (TransmissionColor * f_refr);
100: }
101:
102: layout(location = 0) in vec2 fs_DiffuseColorCoordinates;
103: layout(location = 1) in vec3 fs_Normals;
104: layout(location = 2) in vec4 fs_WorldPosition;
105: layout(location = 0) out vec4 ColorsOut;
106: void main()
107: {
108:     float depthNear = texelFetch(secondaryDepthSampler, ivec2(gl_FragCoord.xy), 0).x;
109:     bool valid = (gl_FragCoord.z > depthNear);
110:     if((!valid))
111:     {
112:         discard;
113:     }
114:     vec4 color = (vec4(1.0, 1.0, 1.0, 1.0) * DiffuseColor);
115:     vec4 color1 = (HasColorTexture ? (color * texture(texSampler, fs_DiffuseColorCoordinates)) : color);
116:     vec4 color2 = (HasOpacityTexture ? vec4(color1.xyz, (color1.w * texture(alphaSampler, fs_DiffuseColorCoordinates).x)) : color1);
117:     if((color2.w <= AlphaTestValue))
118:     {
119:         discard;
120:     }
121:     vec4 viewPos = (fs_WorldPosition * ViewTrafo);
122:     bool isOrtho = (ProjTrafo[3][3] == 1.0);
123:     vec3 l = (isOrtho ? ViewTrafo[2].xyz : normalize((CameraLocation - fs_WorldPosition.xyz)));
124:     float slope = dot(normalize(fs_Normals), l);
125:     float a = sqrt((1.0 - (slope * slope)));
126:     float b = max(BiasParameters.z, abs(slope));
127:     float bias = (BiasParameters.x + ((BiasParameters.y * a) / b));
128:     float bias1 = (bias * 2.0);
129:     float depthBias = (isOrtho ? (bias1 / (-((abs(ProjTrafo[0][0]) + abs(ProjTrafo[1][1])) * 0.5))) : ((bias1 * viewPos.z) * 2.0));
130:     vec4 viewPos1 = vec4(viewPos.x, viewPos.y, (viewPos.z + depthBias), viewPos.w);
131:     vec4 projPos = (viewPos1 * ProjTrafo);
132:     float ndc_depth = (projPos.z / projPos.w);
133:     float depth = ((((1.0 * ndc_depth) + 0.0) + 1.0) / 2.0);
134:     vec3 trans = ((dot(TransmissionColor, vec3(1.0, 1.0, 1.0)) > 0.0) ? helper(fs_WorldPosition, fs_Normals) : vec3(0.0, 0.0, 0.0));
135:     vec3 trans1 = mix(trans,vec3(1.0, 1.0, 1.0),(1.0 - color2.w));
136:     vec4 Colors2C = vec4(trans1, 1.0);
137:     ColorsOut = Colors2C;
138:     gl_FragDepth = depth;
139: }
140:
141: #endif

Record parameters not properly handled (null smuggled in)

for code


[<ReflectedDefinition>]
module Gah = 
    let bla (v : Vertex) = v.pos

let effectTest() =

    let vert (v : Vertex) =
        vertex {
            return {
                pos = Bla.hugo (uniform.Trafo * Gah.bla v) 
                tc = v.tc
                vi = 0
            }
        }``

the following bad code is generated:
``void main()
{
    fs_Bla = Bla;
    gl_Position = Program_Bla_hugo((Program_Gah_bla(null) * Trafo));
    fs_TexCoord = TexCoord;
..``

example here: https://github.com/schimi2/FShade/tree/brokenStructParameters

Missing vector swizzles

The support for vector swizzles is currently limited to permutations of 2 and 3 vector components. Missing are:

  • permutations of 4 components (e.g. WZXY to reorder the Gather4 result)
  • swizzles with constants (e.g. XYO)
  • swizzles with duplicates (e.g XXYY)

Cannot pass tessellation levels from TCS to TES

In order to visualize the derived tessellation level using vertex colors I wanted to pass an outer tessellation level from the control shader to the evaluation shader.

Unfortunately the shader code produced by FShade isn't correct.

let heightTess (t : Triangle<Vertex>) =
        tessellation {
            //TCS part
            let outer01 = tessScreenSpaceSphere t.P0.pos t.P1.pos t.P0.tc t.P1.tc
            let outer12 = tessScreenSpaceSphere t.P1.pos t.P2.pos t.P1.tc t.P2.tc
            let outer20 = tessScreenSpaceSphere t.P2.pos t.P0.pos t.P2.tc t.P0.tc

            let inner = (outer01 + outer12 + outer20) / 3.0

            let! coord = tessellateTriangle inner (outer12, outer20, outer01)

            //TES part
            let p = coord.X * t.P0.pos + coord.Y * t.P1.pos + coord.Z * t.P2.pos
            let tc = coord.X * t.P0.tc + coord.Y * t.P1.tc + coord.Z * t.P2.tc
            let c = coord.X * t.P0.c + coord.Y * t.P1.c + coord.Z * t.P2.c

            let h0 = heightMap.Sample(tc).X

            let p0 = V3d(p.X,p.Y,h0)

            return {
                pos = uniform.ModelViewProjTrafo * V4d(p0, 1.0)
                wp = uniform.ModelTrafo * V4d(p0, 1.0)
                n = V3d.OOI
                tc = tc
                c = c
                level = outer01
            }
        }

This correctly produces patch out float te_outer01; for the outer01 attribute in the control shader.
Instead of patch in float te_outer01; just in float te_outer01; is produced for the evaluation shader.

I think this leads to the following error message when compiling the shader code:

[GL] shader compiler returned errors: "Tessellation evaluation info
----------------------------
0(141) : error C7544: OpenGL requires tessellation evaluation inputs to be arrays
"

Invalid characters in function names

I've tried to use a function with a prime character in its name in a compute shader (like we do so often in the f# world). This is translated 1:1 to glsl:

...
float HiliteShaders_SpecularDenoiseCompute_getSpecMagicCurve'_zyS3pDZ51CZk00MS3tzYpQ1Q0FyI(float roughness, float power)
...

and then you get an error like: error C0160: invalid character literal

It would be nice if we add a check if a function name is valid (ascii only) and if not find an appropriate substitute. A general scheme might be to replace "invalid" chars with their char code as sting. The prime character would then be replaced by "U2023", which should give us a deterministic (almost) unique name (I would not expect someone to actually write another function with this exact name). This is just a suggestion to start the discussion, for me any other mechanism that lets me use the code I naturally write (without needing to remember all the FShade restrictions) would be fine.

M44d.TransformPosProj

It might be convenient also translate M44d.TransformPosProj to an appropriate shader code (like we already do with TransformDir and other).

let p = uniform.ProjTrafo.TransformPosProj someVec3

Compute shader integer image support

It's not possible to use an image e.g. with Formats.r32i since ImageXX has an IFloatingValue type constraint. It looks like we would need other image types e.g. Image2i to support these data formats.

Multiple Interpolation Qualifiers

It is not possible to define varyings with multiple interpolation qualifiers, e.g. "noperspective" and "sample". The Interpolation attribute can only be defined once and does not allow multiple arguments.

This is valid for certain combinations: https://www.khronos.org/registry/OpenGL/specs/gl/GLSLangSpec.4.40.pdf

Page 49: "The auxiliary storage qualifiers centroid and sample can also be applied, as well as the interpolation qualifiers flat, noperspective, and smooth."

Example: "noperspective centroid in vec2 myTexCoord;"

We already discussed this and changing the InterpolationMode to a flag enum would make this possible with a reasonable effort of changes. It should be acceptable that the user is responsible for only building valid combinations. The code would then look like this:

type VertexUV = {
    [<TexCoord; Interpolation(InterpolationMode.NoPerspective ||| InterpolationMode.Sample)>] tc : V2d
}

bad swizzle: 'o'

[<Test>]
let ``Foo``() =
    let input =
        <@
            fun (a : V3d) ->
                a.Normalized
        @>
    
    input |> Opt.run |> printfn "%A"

This test produces an exception with "bad swizzle: 'o'" in 5.2.12

Helper function created where both parameters have the same name

FShade fragment shader code:

let (clippedVa, clippedVc) = clipPatch(patch)

let (clampedPoint, _, _, _) = clampPointToPolygon clippedVa clippedVc point t2l

let clampedPoint2d = 
    let cp = t2l * (clampedPoint- clippedVa.[0])
    V2d(cp.X, cp.Y)

When this is compiled, the following GLSL code is generated to compute clampedPoint2d:

vec2 helper(tup_Aardvark_Base_Arrays_Arr2_N5_Aardvark_Base_V3d_int32 patternInput, mat3x3 t2l, tup_Aardvark_Base_V3d_int32_int32_int32 patternInput)
{
    vec3 cp = ((patternInput.Item0 - patternInput1.Item0[0]) * t2l);
    return vec2(cp.x, cp.y);
}

tup_Aardvark_Base_Arrays_Arr2_N5_Aardvark_Base_V3d_int32 patternInput = Render_EffectUtils_clipPatch_11MVozJCVzGFI0BA2ITmWQ(patch);

tup_Aardvark_Base_V3d_int32_int32_int32 patternInput1 = Render_EffectUtils_clampPointToPolygon_u3q3UoKGkBMzZDq5JTwd1Q(patternInput.Item0, patternInput.Item1, point, t2l);

vec2 clampedPoint2d = helper(patternInput, t2l, patternInput1);

The helper function has two parameters with the name patternInput, which leads to the error:

Message=[GL] surface compilation failed: Vertex:
    0(264) : error C1038: declaration of "patternInput" conflicts with previous declaration at 0(264)

Geometry Composition

Implement Compositions:

  • Geometry * Vertex -> Geometry
  • Geometry * Geometry -> Geometry

The second one might be hard and not needed so maybe drop it

Documentation of missing functions listed in tests

It would have been really helpful when I was messing with this a few months ago and couldn't figure out how to do "distance" :). Thanks for all the hard work on building this by the way, it's awesome!

Automatic passing for Geometry Shaders

Would be very helpful but is relatively hard to automatize.

There are basically two ways to go:

  • Let the user define the correspondence between In- and Out-Vertices
  • Some kind of automatic detection for "simple" cases

Tuples do not compile on AMD

The AMD compiler does not like typenames like "tup_vec3_8__int"

#version 410
#define __SHADER_STAGE__


struct tup_vec3_8__int
{
    vec3[8] e0;
    int e1;
};

tup_vec3_8__int tup_vec3_8__int_ctor(vec3[8] e0, int e1)
{
    tup_vec3_8__int result;
    result.e0 = e0;
    result.e1 = e1;
    return result;
}

uniform Global
{
...

Vertex:
Vertex shader failed to compile with the following errors:
ERROR: 0:5: error(#168) Reserved built-in name: tup_vec3_8__int
ERROR: 0:11: error(#132) Syntax error: "tup_vec3_8__int" parse error
ERROR: error(#273) 2 compilation errors. No code generated

PS: Code compiles after replacing "tup_vec3_8__int" with "myTupFOOOO"

Array of Structs

Is it possible to simulate or create an Arr of a product type?

type Shape =
    {ctr : V3d; size : V2d; _type : int}
let shapes : Arr<4 N, Shape> = Arr.ofList([{ ctr =  V3d(0.2, 0.0, 0.0);  size = V2d(0.3, 0.0); _type = 1}]); // size = V2d(0.3, 0.0); _type = Sphere} ])
        for shape in shapes do
            texColor.Y <- shape.size.X 

Gives

Unhandled exception. System.Exception: [FShade] encountered recursive type Microsoft.FSharp.Collections.FSharpList`1[Program+Shape]

Is there a way to use an f-sharp list and unroll it in the glsl, or the like?

autogenerate fragment shader

currently FShade does not generate a fragment shader if none was specified.
However it should create a fragment shader passing vertex colors....

Link to Aardvark.Rendering is broken

Currently the link points at
https://github.com/aardvark-platform/aardvark.rendering/tree/master/src/Aardvark.Base.Rendering/DefaultSurfaces

I'd suggest just pointing it at the whole repo instead of a specific part.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.