Revision Difference
ShadingModel#562709
<cat>Material.ShaderBasic</cat>
<title>Shading Model</title>
# What is a Shading Model
Shading Models determines how a surface will interact with light.
They dictate how the Material's input data is utilized to produce the final visual output.
Not only can you use one of these pre-defined shading models, but you can also create your own shading model to shade your surface the way you want.
S&box currently ships with two shading models `ShadingModelStandard` which should be what most people would use and `ShadingModelCustom` as a base for custom shading models to be developed from, they will handle things like atmospherics and debug visualizations for you without a fuzz.
S&box currently ships with one shading model `ShadingModelStandard` which should be what most people would use.
# Using built-in shading models
```c++
PS
{
#include "common/pixel.hlsl"
float4 MainPs( PixelInput i ) : SV_Target0
{
Material m = Material::From( i );
/* m.Metalness = 1.0f; // Forces the object to be metalic */
return ShadingModelStandard::Shade( i, m );
}
}
```
# Creating a shading model
## Structure
## Light Structure
We provide the following light types to be used from shader code:
* `DynamicLight`
* `StaticLight`
* `EnvironmentMapLight`
* `AmbientLight`
All can be created with `Light::From()` and all but `AmbientLight` can be iterated with `Light::Count()`,
Light types already handle everything from tiled rendering to shadowing seamlessly, for example:
```c++
//
// Shade direct lighting for dynamic lights
//
for ( uint index = 0; index < DynamicLight::Count( i ); index++ )
for ( uint index = 0; index < DynamicLight::Count( material.ScreenPosition ); index++ )
{
Light light = DynamicLight::From( i, index );
Light light = DynamicLight::From( material.ScreenPosition, material.WorldPosition, index );
vResult += light.Color * dot( material.Normal, light.Direction );
}```
Each light structure gives you the following data to be consumed:
```c++
//-----------------------------------------------------------------------------
// Light structure
//-----------------------------------------------------------------------------
struct Light
{
// The color is an RGB value in the linear sRGB color space.
float3 Color;
// The normalized light vector, in world space (direction from the
// current fragment's position to the light).
// Skipped by Ambient Light⤶
float3 Direction;
// The position of the light in world space. This value is the same as
// Direction for directional lights.
float3 Position;
// Attenuation of the light based on the distance from the current
// fragment to the light in world space. This value between 0.0 and 1.0
// is computed differently for each type of light (it's always 1.0 for
// directional lights).
// Skipped by Ambient Light⤶
float Attenuation;
// Visibility factor computed from shadow maps or other occlusion data
// specific to the light being evaluated. This value is between 0.0 and
// 1.0.
// 1.0. (It's always 1.0 for ambient lights)
float Visibility;
};
```
Note that ambient lights skip some of this data.
⤶
## Applying Fog⤶
You can apply fog to shaders by using `DoAtmospherics()`⤶
```⤶
vColor = DoAtmospherics( material.WorldPosition, material.ScreenPosition.xy, vColor );⤶
return vColor;⤶
```⤶
## Usage
## Example ShadingModel
Here's an example of doing a simple Toon shader from the structure you get from lights