Expand description
Shader is a script for graphics card, it defines how to draw an object. It also defines a set of external resources needed for the rendering.
§Structure
Shader has rigid structure that could be described in this code snipped:
(
name: "MyShader",
// A set of resources, the maximum amount of resources is limited by your GPU. The engine
// guarantees, that there could at least 16 textures and 16 resource groups per shader.
resources: [
(
// Each resource binding must have a name.
name: "diffuseTexture",
// Value has limited set of possible variants.
kind: Texture(kind: Sampler2D, fallback: White),
binding: 0
),
(
name: "properties",
kind: PropertyGroup([
(
name: "diffuseColor",
kind: Color(r: 255, g: 255, b: 255, a: 255),
),
]),
binding: 0
),
// The following property groups are built-in and provides useful data for each shader.
(
name: "fyrox_instanceData",
kind: PropertyGroup([
// Autogenerated
]),
binding: 1
),
(
name: "fyrox_boneMatrices",
kind: PropertyGroup([
// Autogenerated
]),
binding: 2
),
(
name: "fyrox_graphicsSettings",
kind: PropertyGroup([
// Autogenerated
]),
binding: 3
),
(
name: "fyrox_cameraData",
kind: PropertyGroup([
// Autogenerated
]),
binding: 4
),
(
name: "fyrox_lightData",
kind: PropertyGroup([
// Autogenerated
]),
binding: 5
),
],
// A set of render passes (see a section `Render pass` for more info)
passes: [
(
// Name must match with the name of either standard render pass (see below) or
// one of your passes.
name: "Forward",
// A set of parameters that regulate renderer pipeline state.
// This is mandatory field of each render pass.
draw_parameters: DrawParameters(
// A face to cull. Either Front or Back.
cull_face: Some(Back),
// Color mask. Defines which colors should be written to render target.
color_write: ColorMask(
red: true,
green: true,
blue: true,
alpha: true,
),
// Whether to modify depth buffer or not.
depth_write: true,
// Whether to use stencil test or not.
stencil_test: None,
// Whether to perform depth test when drawing.
depth_test: Some(Less),
// Blending options.
blend: Some(BlendParameters(
func: BlendFunc(
sfactor: SrcAlpha,
dfactor: OneMinusSrcAlpha,
alpha_sfactor: SrcAlpha,
alpha_dfactor: OneMinusSrcAlpha,
),
equation: BlendEquation(
rgb: Add,
alpha: Add
)
)),
// Stencil options.
stencil_op: StencilOp(
fail: Keep,
zfail: Keep,
zpass: Keep,
write_mask: 0xFFFF_FFFF,
),
// Scissor box. Could be something like this:
//
// scissor_box: Some(ScissorBox(
// x: 10,
// y: 20,
// width: 100,
// height: 30
// ))
scissor_box: None
),
// Vertex shader code.
vertex_shader:
r#"
layout(location = 0) in vec3 vertexPosition;
layout(location = 1) in vec2 vertexTexCoord;
out vec2 texCoord;
void main()
{
texCoord = vertexTexCoord;
gl_Position = fyrox_instanceData.worldViewProjection * vec4(vertexPosition, 1.0);
}
"#,
// Fragment shader code.
fragment_shader:
r#"
out vec4 FragColor;
in vec2 texCoord;
void main()
{
FragColor = properties.diffuseColor * texture(diffuseTexture, texCoord);
}
"#,
)
],
)Shader should contain at least one render pass to actually do some job. A shader could not have properties at all. Currently only vertex and fragment programs are supported. Each program mush be written in GLSL. Comprehensive GLSL documentation can be found here
§Render pass
Modern rendering is a very complex thing that requires drawing an object multiple times with different “scripts”. For example to draw an object with shadows you need to draw an object twice: one directly in a render target, and one in a shadow map. Such stages called render passes.
Binding of shaders to render passes is done via names, each render pass has unique name.
§Predefined passes
There are number of predefined render passes:
-
GBuffer- A pass that fills a set of textures (render targets) with various data about each rendered object (depth, normal, albedo, etc.). These textures then are used for physically-based lighting. Use this pass when you want the standard lighting to work with your objects. -
Forward- A pass that draws an object directly in a render target. It could be used to render translucent objects. -
SpotShadow- A pass that emits depth values for an object, later this depth map will be used to render shadows. -
PointShadow- A pass that emits distance from a fragment to a point light, later this depth map will be used to render shadows. -
DirectionalShadow- A pass that emits depth values for an object, later this depth map will be used to render shadows for directional cascaded shadows.
§Resources
Each shader requires a specific set of external resources that will be used during the rendering.
This set is defined in resources section of the shader and could contain the following resources:
Texture- a texture of arbitrary typePropertyGroup- a group of numeric properties.
§Binding points
Shader resource must define a unique (over its type) binding index. The engine will use these points to prepare appropriate resource descriptor sets for GPU. Keep in mind, that binding point indices are unique per each type of resource. This means that a set of texture resource could use the same indices as property groups. The binding points must be unique in its group. If there are more than one resource of a certain type, that shares the same binding point, the engine will refuse to use such shader.
§Built-in resources
There are number of built-in resources, that Fyrox will try to assign automatically if they’re defined in your shader, something like this:
(
name: "fyrox_instanceData",
kind: PropertyGroup([
// Autogenerated
]),
binding: 1
),The full list of built-in resources is defined below.
§fyrox_instanceData
Property group. Provided for each rendered surface instance.
| Name | Type | Description |
|---|---|---|
| worldMatrix | mat4 | Local-to-world transformation. |
| worldViewProjection | mat4 | Local-to-clip-space transform. |
| blendShapesCount | int | Total amount of blend shapes. |
| useSkeletalAnimation | bool | Whether skinned meshes is rendering or not. |
| blendShapesWeights | vec4[32] | Blend shape weights. |
§fyrox_boneMatrices
Property group. Provided for each rendered surface, that has skeletal animation.
| Name | Type | Description |
|---|---|---|
| matrices | mat4[256] | Bone matrices |
§fyrox_cameraData
Property group. Contains camera properties. It contains info not only about scene camera, but also observer info when rendering shadow maps. In other words - it is generic observer properties.
| Name | Type | Description |
|---|---|---|
| viewProjectionMatrix | mat4 | World-to-clip-space transformation. |
| position | vec3 | World-space position of the camera. |
| upVector | vec3 | World-space up-vector of the camera. |
| sideVector | vec3 | World-space side-vector of the camera. |
| zNear | float | Near clipping plane location. |
| zFar | float | Far clipping plane location. |
| zRange | float | zFar - zNear |
§fyrox_lightData
Property group. Available only in shadow passes.
| Name | Type | Description |
|---|---|---|
| lightPosition | vec3 | World-space light source position. Only for shadow passes. |
| ambientLightColor | vec4 | Ambient lighting color of the scene. |
§fyrox_lightsBlock
Property group. Information about visible light sources
| Name | Type | Description |
|---|---|---|
| lightCount | int | Total amount of light sources visible on screen. |
| lightsColorRadius | vec4[16] | Color (xyz) and radius (w) of light source |
| lightsParameters | vec2[16] | Hot-spot cone angle cos (x) and half cone angle cos (y) |
| lightsPosition | vec3[16] | World-space light position. |
| lightsDirection | vec3[16] | World-space light direction |
§fyrox_graphicsSettings
Property group. Contains graphics options of the renderer.
| Name | Type | Description |
|---|---|---|
| usePom | bool | Whether to use parallax occlusion mapping or not. |
§fyrox_sceneDepth
Texture. Contains depth values of scene. Available only after opaque geometry is rendered (read - G-Buffer is filled). Typical usage is something like this:
(
name: "fyrox_sceneDepth",
kind: Texture(kind: Sampler2D, fallback: White),
binding: 1
),§Code generation
Fyrox automatically generates code for resource bindings. This is made specifically to prevent subtle mistakes. For example when you define this set of resources:
(
name: "MyShader",
resources: [
(
name: "diffuseTexture",
kind: Texture(kind: Sampler2D, fallback: White),
binding: 0
),
(
name: "normalTexture",
kind: Texture(kind: Sampler2D, fallback: Normal),
binding: 1
),
(
name: "properties",
kind: PropertyGroup([
(
name: "texCoordScale",
kind: Vector2((1.0, 1.0)),
),
(
name: "diffuseColor",
kind: Color(r: 255, g: 255, b: 255, a: 255),
),
]),
binding: 0
),
]
)The engine generates the following code and adds it to source code of every shader of every pass automatically:
uniform sampler2D diffuseTexture;
uniform sampler2D normalTexture;
struct Tproperties {
vec2 texCoordScale;
vec4 diffuseColor;
};
layout(std140) uniform Uproperties { Tproperties properties; }The most important thing is that the engine keeps properties in the struct Tproperties in
correct order and forces std140 layout on the generated uniform block. Since the engine knows
the layout of the properties from their definition section, it could easily form a memory block
with all required alignments and paddings that could be uploaded to GPU. The next important thing
is that the engine batches all the data needed into a large chunks of data and uploads them
all at once, which is much faster.
§Drawing parameters
Drawing parameters defines which GPU functions to use and at which state. For example, to render transparent objects you need to enable blending with specific blending rules. Or you need to disable culling to draw objects from both sides. This is when draw parameters comes in handy.
There are relatively large list of drawing parameters, and it could confuse a person who didn’t get used to work with graphics. The following list should help you to use drawing parameters correctly.
-
cull_face
- Defines which side of polygon should be culled.
- Possible values:
None, Some(CullFace::XXX)
-
color_write:
- Defines which components of color should be written to a render target
- Possible values: ColorMask(…)
-
depth_write:
- Whether to modify depth buffer or not.
- Possible values:
true/false
-
stencil_test:
- Whether to use stencil test or not.
- Possible values:
None- Some(StencilFunc)
-
depth_test:
- Whether to perform depth test when drawing.
- Possible values:
true/false
-
blend:
- Blending options.
- Possible values:
None- Some(BlendFunc)
-
stencil_op:
- Stencil options.
- Possible values: StencilOp
§Standard shader
By default, Fyrox uses standard material for rendering, it covers 95% of uses cases and it is very
flexible. To get standard shader instance, use ShaderResource::standard
let standard_shader = ShaderResource::standard();Usually you don’t need to get this shader manually, using of Material::standard is enough.
Modules§
- loader
- Shader loader.
Structs§
- Render
Pass Definition - A render pass definition. See
ShaderResourcedocs for more info about render passes. - Shader
- Internal state of the shader.
- Shader
Definition - A definition of the shader.
- Shader
Resource Definition - Shader resource definition.
Enums§
- Sampler
Fallback - A fallback value for the sampler.
- Shader
Error - A set of possible error variants that can occur during shader loading.
- Shader
Resource Kind - Shader property with default value.
Constants§
- STANDARD_
2D_ SHADER_ NAME - A name of the standard 2D shader.
- STANDARD_
2D_ SHADER_ SRC - A source code of the standard 2D shader.
- STANDARD_
PARTICLE_ SYSTEM_ SHADER_ NAME - A name of the standard particle system shader.
- STANDARD_
PARTICLE_ SYSTEM_ SHADER_ SRC - A source code of the standard particle system shader.
- STANDARD_
SHADER_ NAME - A name of the standard shader.
- STANDARD_
SHADER_ NAMES - A list of names of standard shaders.
- STANDARD_
SHADER_ SOURCES - A list of source code of standard shaders.
- STANDARD_
SHADER_ SRC - A source code of the standard shader.
- STANDARD_
SPRITE_ SHADER_ NAME - A name of the standard sprite shader.
- STANDARD_
SPRITE_ SHADER_ SRC - A source code of the standard sprite shader.
- STANDARD_
TERRAIN_ SHADER_ NAME - A name of the standard terrain shader.
- STANDARD_
TERRAIN_ SHADER_ SRC - A source code of the standard terrain shader.
- STANDARD_
TILE_ SHADER_ NAME - A name of the standard tile shader.
- STANDARD_
TWOSIDES_ SHADER_ NAME - A name of the standard two-sides shader.
- STANDARD_
TWOSIDES_ SHADER_ SRC - A source code of the standard two-sides shader.
Traits§
- Shader
Resource Extension - Extension trait for shader resources.
Type Aliases§
- Shader
Resource - Type alias for shader resources.