# Custom Shading Model

This model allows the user to create and customize their own **Shading Model**. The specifications are given via configuration files in the **Attributes**:

* [`Vertex Shader`](#vertex-shader)
* [`Fragment Shader`](#fragment-shader)
* [`Uniforms`](#uniforms)

All these **Attributes** are described in greater detail below.

![](https://2561100106-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Ff6JZovzOqBctA4C1o76u%2Fuploads%2Fgit-blob-8929baa48adb45d73fc9f36f091c21eabe031982%2Fcustomshadingmodel.gif?alt=media)

## Attributes

### Material

![Material](https://2561100106-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Ff6JZovzOqBctA4C1o76u%2Fuploads%2Fgit-blob-9b65a4b6c2954c125243c6c25a0aa014e54d7f64%2Fcustomshadingmodel2.png?alt=media)

This **Attribute** provides the `Name` of the **Custom Material** as well as the `Shading model` type. It also sets the `Alpha` value if it is toggled on.

The `Alpha` channel is additional to the RGB channels and adds a kind of transparency to the object by mixing the background and foreground colors. For example, if the `Alpha` value is set to 0.5, then this would result in a 50% mix of the object and its background, providing a semi-translucent quality.

### Shaders

There are two types of *shaders* that can be used for this model: [`Vertex Shader`](#vertex-shader) and [`Fragment Shader`](#fragment-shader).

Find below a detailed explanation of how to configure these *shaders*.

#### Shaders Configuration

Across the configuration of both, two uniform variables can be used:

* `incTime`: **Float** that keeps the time from the start of the application.
* `incResolution`: **Vector2** containing the **Screen** resolution.

#### Vertex Shader

*Vertex Shaders* influence the rendering of the vertices of **Objects**.

![](https://2561100106-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Ff6JZovzOqBctA4C1o76u%2Fuploads%2Fgit-blob-041899e4696b735048fa052f839ab1ba1de058f5%2Fcustomshading-vertex.png?alt=media)

The `Vertex Shader` is configured via an **Asset** with `.vert` extension. This **Asset** consists of code and can be edited in **Incari** with the [**Code Editor**](https://docs.incari.com/incari-studio/2023.2/modules/code-editor).

This is the code that is generated by default when creating a `.vert` **Asset** in the [**Asset Manager**](https://docs.incari.com/incari-studio/2023.2/modules/asset-manager):

{% code title="My Vertex Shader.vert" lineNumbers="true" %}

```
void mainPosition(in mat4 projectionMatrix, in mat4 modelMatrix, in vec3 viewPosition, in vec4 worldPosition)
{
    gl_Position = projectionMatrix * vec4(viewPosition, 1.0);
}
```

{% endcode %}

A *vertex shader* requires a main function named `mainPosition`, which is called once per vertex each time the **Scene** is rendered. This function receives as inputs:

* `projectionMatrix`: $$4x4$$ matrix that represents the perspective of the **Camera**.
* `modelMatrix`: $$4x4$$ matrix that represents where the vertex is.
* `viewPosition`: **Vector3** that contains the relative position of the vertex.
* `worldPosition`: **Vector4** that contains the absolute position of the vertex.

It is always necessary to calculate:

* `gl_Position`: **Vector4** that contains the position of the vertex in *clip space*.

#### Fragment Shader

*Fragment Shaders* influence the rendering of each *pixel* of **Objects**.

![](https://2561100106-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Ff6JZovzOqBctA4C1o76u%2Fuploads%2Fgit-blob-e203f7a9ad83888f4fc4fc771ae764d0df4e894f%2Fcustomshading-fragment.png?alt=media)

The `Fragment Shader` is configured via an **Asset** with `.frag` extension. This **Asset** consists of code and can be edited in **Incari** with the [**Code Editor**](https://docs.incari.com/incari-studio/2023.2/modules/code-editor).

This is the code that is generated by default when creating a `.frag` **Asset** in the [**Asset Manager**](https://docs.incari.com/incari-studio/2023.2/modules/asset-manager):

{% code title="My Fragment Shader.frag" lineNumbers="true" %}

```
‌void mainImage(out vec4 fragColor, in vec2 fragCoord)
{
 vec2 uv = (fragCoord * incResolution) / incResolution.xy;
 vec3 col = 0.5 + 0.5 * cos(incTime + uv.xyx + vec3(0, 2, 4));
 fragColor = vec4(col, 1.0);
}
```

{% endcode %}

A *fragment shader* requires a main function named `mainImage`, which is called once per pixel each time the **Scene** is rendered. The argument for this function is:

* `fragCoord`: **Vector2** that contains the 2-dimensional coordinates of the pixel.

And the output is:

* `fragColor`: **Vector4** that stores the color that the pixel will be set to.

The *uv coordinates* can be obtained by using:

`vec2 uv = (fragCoord * incResolution) / incResolution.xy;`

It is also possible to use shaders from [*ShaderToy*](https://www.shadertoy.com/). To do so, simply locate a shader which uses the [*GLSL\_ES*](https://www.khronos.org/files/opengles_shading_language.pdf) standards.

Once there, copy the code on the right-hand side of the page.

![Example Shader from shadertoy.com.](https://2561100106-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Ff6JZovzOqBctA4C1o76u%2Fuploads%2Fgit-blob-83e72b2a634779c432e7c4845c835599b5361444%2Fshadertoyexample.png?alt=media)

Then paste that into a `.frag` file in **Incari**. It is imperative that one add `#define USE_RESOLUTION_RANGE` to the very beginning of the file (before all the code that has been pasted).

![Fragment Shader Example.](https://2561100106-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Ff6JZovzOqBctA4C1o76u%2Fuploads%2Fgit-blob-291261de9252c7b03c9507ed7b0d14e4ea264796%2Ffragshaderexample.png?alt=media)

This makes a shader from *shadertoy.com* useable in **Incari**. Now one just needs to add the file to a **Custom Shading Model** in the `Fragment Shader` section.

### Uniforms

**Incari** makes it possible for the user to set values in **Fragment** and **Vertex Shader** files. This can also be done on runtime by using the [**Set Material Property Node**](https://docs.incari.com/incari-studio/2023.2/toolbox/incari/material/setmaterialproperty).

Here, the user can set the values for several variables. These variables correspond to those present in the files given in the *shaders*. Please note that *shaders* should be conform to the [*GLSL\_ES*](https://www.khronos.org/files/opengles_shading_language.pdf) standards.

There are five types of variables:

* [Channels](#channels)
* [Integers](#integers)
* [Floats](#floats)
* [Vectors](#vectors)
* [Booleans](#booleans)

Please note that for the `Uniforms` to have any effect, the names in the files must match the **Attribute** names seen here in the `Custom Shading Model`.

![Custom Shading Model Example.](https://2561100106-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Ff6JZovzOqBctA4C1o76u%2Fuploads%2Fgit-blob-a7af4b76db58274e60faa03f2a3bceaf1bdf3c26%2Fcustomshaderexample2.png?alt=media)

#### Channels

![](https://2561100106-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Ff6JZovzOqBctA4C1o76u%2Fuploads%2Fgit-blob-e732989287dd6d819f54b7a0e53422df60844fc2%2Funiformschannels.png?alt=media)

These **Attributes** can take any file that is an image or *texture map*. With these, it is possible to add other textures and/or visual components to the already existing **Custom Material**. It is possible to set up to four of these currently in **Incari**.

For example, the user could switch between two *texture* *maps*. After setting *textures* for `iChannel1` and `iChannel2`, the code for the `Fragment Shader` could use these in an *if/else* statement:

```
if( iBool0 ) {
fragColor = texture( iChannel1 , uv );
}
else
{
fragColor = texture( iChannel2 , uv );
}
```

#### Integers

![](https://2561100106-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Ff6JZovzOqBctA4C1o76u%2Fuploads%2Fgit-blob-dba459be8e0d56434185eee4cc91520ea76696b6%2Funiformsints.png?alt=media)

These **Attributes** set the values for **Ints**. This can be used to set the `x`, `y`, `z` , and/or `w` values for a **Vector4** in the code for the `Fragment Shader`, for example. It is possible to set up to four of these currently in **Incari**.

#### Floats

![](https://2561100106-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Ff6JZovzOqBctA4C1o76u%2Fuploads%2Fgit-blob-753cf3d2c8b56fed2a73259891d6891b6fdf48eb%2Funiformsfloats.png?alt=media)

These **Attributes** set the values for **Floats**. This can be used to multiply the time variable present in the code for the `Fragment Shader` by some **Float** during runtime, for example. It is possible to set up to four of these currently in **Incari**.

#### Vectors

![](https://2561100106-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Ff6JZovzOqBctA4C1o76u%2Fuploads%2Fgit-blob-a86fa0afe4918947857c4c85b95d7db38e5ff0a5%2Funiformsvectors.png?alt=media)

These **Attributes** set the values for **Vector4s**. This can be used to set certain RGB values, for example. The first value corresponds to the red value, the second for green, the third for blue, and the fourth for the alpha overchannel. It is possible to set up to four of these currently in **Incari**.

#### Booleans

![](https://2561100106-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2Ff6JZovzOqBctA4C1o76u%2Fuploads%2Fgit-blob-f3b6e8f6090f064ded064a80203863002b738500%2Funiformsbools.png?alt=media)

These **Attributes** set the *true* or *false* values for **Bools**. This can be used to execute a certain condition in the code for the `Fragment Shader`, for example. It is possible to set up to four of these currently in **Incari**.

### Property Names

It is possible to hover over each **Attribute** and access their property names to be used in code or **Nodes**. A complete list of these names is as follows:

* iChannel0
* iChannel1
* iChannel2
* iChannel3
* iInt0
* iInt1
* iInt2
* iInt3
* iFloat0
* iFloat1
* iFloat2
* iFloat3
* iVec40
* iVec41
* iVec42
* iVec43
* iBool0
* iBool1
* iBool2
* iBool3

## External Links

* [*Vertex Shader*](https://www.khronos.org/opengl/wiki/Vertex_Shader) on OpenGL Wiki.
* [*Vertex Shader*](https://shader-tutorial.dev/basics/vertex-shader/) on GPU Shader Tutorial.
* [*Fragment Shader*](https://www.khronos.org/opengl/wiki/Fragment_Shader) on OpenGL Wiki.
* [*Fragment Shader*](https://shader-tutorial.dev/basics/fragment-shader/) on GPU Shader Tutorial.
* [*Shaders*](https://learnopengl.com/Getting-started/Shaders) in Learn OpenGL.
