Merge branch 'main' of https://git.brossferatu.com/Bross/Crypt
This commit is contained in:
129
README.md
129
README.md
@@ -1,7 +1,10 @@
|
|||||||
# Shader Compiler
|
# Ink
|
||||||
|
|
||||||
A compiler for a custom, platform-agnostic shader language that compiles to platform specific shader languages (currently only HLSL).
|
A compiler for a custom, platform-agnostic shader language that compiles to platform specific shader languages (currently only HLSL).
|
||||||
|
|
||||||
|
Ink is not a standalone executable, but rather a library you use to compile your shaders. It has metaprogramming capabilities in the sense that all stages are exposed and data is editable at will.
|
||||||
|
In the future we will support a better API for adding code and possibly macros if we deem it necessary.
|
||||||
|
|
||||||
## Features
|
## Features
|
||||||
|
|
||||||
A simple passthrough shader (`passthrough.shd`) can look as follows
|
A simple passthrough shader (`passthrough.shd`) can look as follows
|
||||||
@@ -41,40 +44,55 @@ Camera_Data :: struct {
|
|||||||
projection : float4x4;
|
projection : float4x4;
|
||||||
view : float4x4;
|
view : float4x4;
|
||||||
}
|
}
|
||||||
```
|
|
||||||
And there is a special struct called `properties`, which is used for custom data you want to pass in.
|
|
||||||
#### ** Note: Properties will likely be deprecated, since the language now supports `@` hints to easily mark buffers and values with metadata.**
|
|
||||||
```hlsl
|
|
||||||
properties {
|
|
||||||
projection : float4x4;
|
|
||||||
view : float4x4;
|
|
||||||
}
|
|
||||||
```
|
|
||||||
which will be exposed in the compiled result. `properties` can be renamed to a custom/shorter name like
|
|
||||||
```
|
|
||||||
p :: properties {
|
|
||||||
...
|
|
||||||
|
|
||||||
|
|
||||||
```
|
```
|
||||||
|
|
||||||
You can also define constant buffers
|
You can also define constant buffers
|
||||||
|
|
||||||
```
|
```
|
||||||
camera :: constant_buffer {
|
camera :: Constant_Buffer {
|
||||||
projection : float4x4;
|
projection : float4x4;
|
||||||
view : float4x4;
|
view : float4x4;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
|
You can mark these with `@` hints to mark specific mappings for your engine
|
||||||
|
|
||||||
|
```
|
||||||
|
camera :: Constant_Buffer @camera {
|
||||||
|
projection : float4x4;
|
||||||
|
view : float4x4;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Structured buffers - simply called `Buffer` - are now also supported
|
||||||
|
|
||||||
|
```
|
||||||
|
buffer :: Buffer {
|
||||||
|
color : float4;
|
||||||
|
model : float4x4;
|
||||||
|
}
|
||||||
|
|
||||||
|
vertex main :: (position : float3 @position, instance_id : int) -> float4 @outposition {
|
||||||
|
return mul(position, buffer[instance_id].model);
|
||||||
|
}
|
||||||
|
|
||||||
|
pixel main :: (instance_id : int) {
|
||||||
|
return buffer[instance_id].color;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
You will get a `Buffer` instance returned in the compiled result which has all the fields in the buffer exposed. See more below.
|
||||||
|
|
||||||
## Jai Usage Example
|
## Jai Usage Example
|
||||||
|
|
||||||
To compile a shader and use the result, you can do the following in jai
|
To compile a shader and use the result, you can do the following in jai
|
||||||
```jai
|
```jai
|
||||||
|
|
||||||
// In the future, you can pass environment defines to the compiler.
|
|
||||||
ctx : Compiler_Context;
|
ctx : Compiler_Context;
|
||||||
compile_file(*compiler, "shader.shd", allocator);
|
|
||||||
|
add_define(*ctx, "SKINNING"); // Pass environment defines here, you can also use the `#add_define` in your shaders for debugging.
|
||||||
|
compile_file(*compiler, "shader.ink", allocator);
|
||||||
|
|
||||||
if ctx.had_error {
|
if ctx.had_error {
|
||||||
log_error("%\n", report_messages(ctx.messages),, temp);
|
log_error("%\n", report_messages(ctx.messages),, temp);
|
||||||
@@ -84,49 +102,14 @@ if ctx.had_error {
|
|||||||
// The ctx now contains all the needed information like the source text, entry points, constant buffers etc.
|
// The ctx now contains all the needed information like the source text, entry points, constant buffers etc.
|
||||||
```
|
```
|
||||||
|
|
||||||
When parsing a shader you get the following struct as a result
|
### Output data
|
||||||
|
|
||||||
|
When parsing a shader you pass a `Compiler_Context` struct which in turn will contain all the output data in the end. See `module.jai` for more info.
|
||||||
|
|
||||||
|
An example of output data are buffers (constant, structured)
|
||||||
|
|
||||||
```
|
```
|
||||||
Compiler_Context :: struct {
|
Buffer :: struct {
|
||||||
file : Input_File;
|
|
||||||
|
|
||||||
environment : Environment;
|
|
||||||
|
|
||||||
tokens : [..]Token;;
|
|
||||||
root : *AST_Node;
|
|
||||||
nodes : [..]AST_Node;
|
|
||||||
|
|
||||||
codegen_result_text : string;
|
|
||||||
|
|
||||||
constant_buffers : Static_Array(Type_Variable_Handle, 16);
|
|
||||||
|
|
||||||
scope_stack : Scope_Stack;
|
|
||||||
type_variables : [..]Type_Variable;
|
|
||||||
|
|
||||||
property_name : string;
|
|
||||||
|
|
||||||
vertex_entry_point : struct {
|
|
||||||
node : *AST_Node;
|
|
||||||
name : string;
|
|
||||||
input : [..]Field;
|
|
||||||
}
|
|
||||||
|
|
||||||
pixel_entry_point : struct {
|
|
||||||
node : *AST_Node;
|
|
||||||
name : string;
|
|
||||||
return_value : Field;
|
|
||||||
}
|
|
||||||
|
|
||||||
properties : Properties;
|
|
||||||
|
|
||||||
max_constant_buffers :: 16;
|
|
||||||
|
|
||||||
cbuffers : Static_Array(Constant_Buffer, max_constant_buffers);
|
|
||||||
|
|
||||||
had_error : bool;
|
|
||||||
messages : [..]Compiler_Message;
|
|
||||||
}
|
|
||||||
|
|
||||||
Constant_Buffer :: struct {
|
|
||||||
name : string;
|
name : string;
|
||||||
|
|
||||||
fields : Static_Array(Property_Field, 16);
|
fields : Static_Array(Property_Field, 16);
|
||||||
@@ -137,11 +120,6 @@ Constant_Buffer :: struct {
|
|||||||
buffer_index : u32;
|
buffer_index : u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
Properties :: struct {
|
|
||||||
fields : [..]Property_Field;
|
|
||||||
|
|
||||||
buffer_index : u32;
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
A field is just a simple struct with a name and type (and hints such as semantics or custom hints in the future)
|
A field is just a simple struct with a name and type (and hints such as semantics or custom hints in the future)
|
||||||
@@ -170,7 +148,7 @@ Field_Kind :: enum {
|
|||||||
|
|
||||||
Function;
|
Function;
|
||||||
Struct;
|
Struct;
|
||||||
Array; // Not yet supported
|
Array;
|
||||||
}
|
}
|
||||||
|
|
||||||
Field_Type :: struct {
|
Field_Type :: struct {
|
||||||
@@ -180,23 +158,14 @@ Field_Type :: struct {
|
|||||||
|
|
||||||
children : [..]Field;
|
children : [..]Field;
|
||||||
}
|
}
|
||||||
|
|
||||||
Hint_Kind :: enum {
|
|
||||||
None;
|
|
||||||
|
|
||||||
Position;
|
|
||||||
Target;
|
|
||||||
|
|
||||||
Custom;
|
|
||||||
}
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Notable missing features
|
## Notable missing features
|
||||||
|
|
||||||
- While
|
- While
|
||||||
- Arrays
|
|
||||||
- Multiple render targets
|
- Multiple render targets
|
||||||
- Custom buffers/structured buffers
|
|
||||||
- Interpolation specifiers
|
- Interpolation specifiers
|
||||||
- Proper variant handling with environment defines
|
- Importing files such as shared utils etc. with something other than textual `#load`
|
||||||
- Importing files such as shared utils etc. with something other than textual `#load`
|
- Other output languages
|
||||||
|
- compute shaders
|
||||||
|
- mesh/amplification shaders
|
||||||
Reference in New Issue
Block a user