Eric Mellino 8 anni fa
parent
commit
3754acfa02
1 ha cambiato i file con 215 aggiunte e 0 eliminazioni
  1. 215 0
      README.md

+ 215 - 0
README.md

@@ -0,0 +1,215 @@
+# ShaderGen
+
+A proof-of-concept library which generates shader code from C#. Currently, the project can generate HLSL (D3D11), GLSL-330 (core-GL-compatible) and GLSL-450 (Vulkan-compatible) shader code from a single shader source specified in C#.
+
+## Shaders in C#
+
+Writing shader code in C# could have quite a few benefits:
+
+* Easily share type definitions between graphics code in C# and shaders.
+  * For example, one could re-use the same structure to describe the input to a vertex shader, as well as to store the actual vertex data in your C# program.
+  * Shader uniforms ("constant buffers") can be shared as well.
+* Analysis done at code-generation time can be used to build extra metadata about the shaders, enabling reflection-like capabilities.
+  * The full vertex input specification can be generated when doing the C# analysis for code generation.
+  * The layouts and order for all global shader resources can be captured.
+  * Validation can be performed to ensure, for example, uniforms are multiples of 16-bytes in size, etc.
+* C# refactoring tools can be used.
+* C# niceties like inheritance, composition, partial declarations, etc. can be leveraged for easier shader writing (speculative).
+
+## Example Shader
+
+Here is an example vertex and fragment shader, written in C# with ShaderGen:
+
+```C#
+public class MinExample
+{
+    [Resource] public Matrix4x4 Projection;
+    [Resource] public Matrix4x4 View;
+    [Resource] public Matrix4x4 World;
+    [Resource] public Texture2DResource SurfaceTexture;
+    [Resource] public SamplerResource Sampler;
+
+    public struct VertexInput
+    {
+        [VertexSemantic(SemanticType.Position)] public Vector3 Position;
+        [VertexSemantic(SemanticType.TextureCoordinate)] public Vector2 TextureCoord;
+    }
+
+    public struct FragmentInput
+    {
+        [VertexSemantic(SemanticType.Position)] public Vector4 Position;
+        [VertexSemantic(SemanticType.TextureCoordinate)] public Vector2 TextureCoord;
+    }
+
+    [VertexShader]
+    public FragmentInput VertexShaderFunc(VertexInput input)
+    {
+        FragmentInput output;
+        Vector4 worldPosition = Mul(World, new Vector4(input.Position, 1));
+        Vector4 viewPosition = Mul(View, worldPosition);
+        output.Position = Mul(Projection, viewPosition);
+        output.TextureCoord = input.TextureCoord;
+        return output;
+    }
+
+    [FragmentShader]
+    public Vector4 FragmentShaderFunc(FragmentInput input)
+    {
+        return Sample(SurfaceTexture, Sampler, input.TextureCoord);
+    }
+}
+```
+
+Here is some representative output from the library (subject to change, etc.):
+
+HLSL Vertex Shader
+```HLSL
+struct MinExample_VertexInput
+{
+    float3 Position : POSITION0;
+    float2 TextureCoord : TEXCOORD0;
+};
+
+struct MinExample_FragmentInput
+{
+    float4 Position : POSITION0;
+    float2 TextureCoord : TEXCOORD0;
+};
+
+struct MinExample_FragmentInput__FRAGSEMANTICS
+{
+    float4 Position : SV_POSITION;
+    float2 TextureCoord : TEXCOORD0;
+};
+
+cbuffer ProjectionBuffer : register(b0)
+{
+    float4x4 Projection;
+}
+
+cbuffer ViewBuffer : register(b1)
+{
+    float4x4 View;
+}
+
+cbuffer WorldBuffer : register(b2)
+{
+    float4x4 World;
+}
+
+MinExample_FragmentInput__FRAGSEMANTICS VertexShaderFunc(MinExample_VertexInput input)
+{
+    MinExample_FragmentInput output;
+    float4 worldPosition = mul(World, float4(input.Position, 1));
+    float4 viewPosition = mul(View, worldPosition);
+    output.Position = mul(Projection, viewPosition);
+    output.TextureCoord = input.TextureCoord;
+    return output;
+}
+```
+
+HLSL Fragment Shader
+```HLSL
+struct MinExample_FragmentInput__FRAGSEMANTICS
+{
+    float4 Position : SV_POSITION;
+    float2 TextureCoord : TEXCOORD0;
+};
+
+Texture2D SurfaceTexture : register(t0);
+SamplerState Sampler : register(s0);
+
+float4 FragmentShaderFunc(MinExample_FragmentInput__FRAGSEMANTICS input) : SV_Target
+{
+    return SurfaceTexture.Sample(Sampler, input.TextureCoord);
+}
+```
+
+GLSL (450) Vertex Shader
+```GLSL
+#version 450
+#extension GL_ARB_separate_shader_objects : enable
+#extension GL_ARB_shading_language_420pack : enable
+struct MinExample_VertexInput
+{
+    vec3 Position;
+    vec2 TextureCoord;
+};
+
+struct MinExample_FragmentInput
+{
+    vec4 Position;
+    vec2 TextureCoord;
+};
+
+layout(binding = 0) uniform ProjectionBuffer
+{
+    mat4 Projection;
+};
+layout(binding = 1) uniform ViewBuffer
+{
+    mat4 View;
+};
+layout(binding = 2) uniform WorldBuffer
+{
+    mat4 World;
+};
+
+MinExample_FragmentInput VertexShaderFunc(MinExample_VertexInput input_)
+{
+    MinExample_FragmentInput output_;
+    vec4 worldPosition = World * vec4(input_.Position, 1);
+    vec4 viewPosition = View * worldPosition;
+    output_.Position = Projection * viewPosition;
+    output_.TextureCoord = input_.TextureCoord;
+    return output_;
+}
+
+layout(location = 0) in vec3 Position;
+layout(location = 1) in vec2 TextureCoord;
+layout(location = 0) out vec2 out_TextureCoord;
+
+void main()
+{
+    MinExample_VertexInput input_;
+    input_.Position = Position;
+    input_.TextureCoord = TextureCoord;
+    MinExample_FragmentInput output_ = VertexShaderFunc(input_);
+    out_TextureCoord = output_.TextureCoord;
+    gl_Position = output_.Position;
+}
+```
+
+GLSL (450) Fragment Shader
+```GLSL
+#version 450
+#extension GL_ARB_separate_shader_objects : enable
+#extension GL_ARB_shading_language_420pack : enable
+
+struct MinExample_FragmentInput
+{
+    vec4 Position;
+    vec2 TextureCoord;
+};
+
+layout(binding = 3) uniform texture2D SurfaceTexture;
+layout(binding = 4) uniform sampler Sampler;
+
+vec4 FragmentShaderFunc(MinExample_FragmentInput input_)
+{
+    return texture(sampler2D(SurfaceTexture, Sampler), input_.TextureCoord);
+}
+
+layout(location = 0) in vec4 Position;
+layout(location = 1) in vec2 TextureCoord;
+layout(location = 0) out vec4 _outputColor_;
+
+void main()
+{
+    MinExample_FragmentInput input_;
+    input_.Position = Position;
+    input_.TextureCoord = TextureCoord;
+    vec4 output_ = FragmentShaderFunc(input_);
+    _outputColor_ = output_;
+}
+```