# BBC BASIC Programmers' Reference

## Tutorial 3 - Shaders and Effect System

by Richard Russell, August 2015

Note that the code in this tutorial requires Windows 8.1 or Windows 10

This tutorial is closely based on Microsoft's Direct 3D 11 Tutorial 3 but with the code translated from C++ to BBC BASIC for Windows. You should refer to the original for a detailed explanation of the code.

## Summary

In the previous tutorial, we set up a vertex buffer and passed one triangle to the GPU. Now, we will actually step through the graphics pipeline and look at how each stage works. The concept of shaders and the effect system will be explained.

Note that this tutorial shares the same source code as the previous one, but will emphasize a different section.

## Source

The source files, libraries etc. may be downloaded from here.

## The Graphics Pipeline

In the previous tutorial, we set up the vertex buffer, and then we associated a vertex layout with a vertex shader. Now, we will explain what a shader is and how it works. To fully understand the individual shaders, we will take a step back and look at the whole graphical pipeline.

In Direct3D 11, shaders reside in different stages of the graphics pipeline. They are short programs that, executed by the GPU, take certain input data, process that data, and then output the result to the next stage of the pipeline. Direct3D 11 supports three basic types of shaders: vertex shader, geometry shader, and pixel shader.

Vertex shaders are short programs that are executed by the GPU on vertices. Think of vertex shaders as C functions that take each vertex as input, process the input, and then output the modified vertex. In the Direct3D 11 tutorials, we will write our shaders in High-Level Shading Language (HLSL). Recall that our vertex data has a 3D position element, and the vertex shader will do no processing on the input at all. The resulting vertex shader looks like the following:

```      float4 VS( float4 Pos : POSITION ) : SV_POSITION
{
return Pos;
}```

A pixel shader's primary purpose is to compute the colour that each pixel should have. The shader takes certain input about the pixel being coloured, computes the pixel's colour, then outputs that colour back to the pipeline. The vertex shader we created above outputs a float4 with the semantics SV_POSITION. This will be the input of our pixel shader. Since pixel shaders output color values, the output of our pixel shader will be a float4. We give the output the semantics SV_TARGET to signify outputting to the render target format. The pixel shader looks like the following:

```      float4 PS( float4 Pos : SV_POSITION ) : SV_Target
{
return float4( 1.0f, 1.0f, 0.0f, 1.0f );    // Yellow, with Alpha = 1
}```

## Creating the Shaders

In the application code, we will need to create a vertex shader object and a pixel shader object. The code is demonstrated below:

```        REM Compile the vertex shader:
hr% = FN_CompileShaderFromFile(@dir\$+"Tutorial02.fx", "VS", "vs_4_0", ^pVSBlob%)
IF hr% ERROR 100, "The FX file could not be opened or " + \
\                 "the vertex shader could not be compiled"
!(^ID3D10Blob{}+4) = !pVSBlob%

REM Create the vertex shader:
SYS ID3D10Blob.GetBufferPointer%, pVSBlob% TO bp%
SYS ID3D10Blob.GetBufferSize%, pVSBlob% TO bs%
SYS ID3D11Device.CreateVertexShader%, pd3dDevice%, bp%, bs%, NULL, ^pVertexShader% TO hr%
IF hr% <> 0 OR pVertexShader% = 0 THEN
SYS ID3D10Blob.Release%, pVSBlob%
ERROR 100, "ID3D11Device::CreateVertexShader failed: "+STR\$~hr%
ENDIF

REM Compile the pixel shader:
hr% = FN_CompileShaderFromFile(@dir\$+"Tutorial02.fx", "PS", "ps_4_0", ^pPSBlob%)
IF hr% ERROR 100, "The FX file could not be opened or " + \
\                 "the pixel shader could not be compiled"
!(^ID3D10Blob{}+4) = !pPSBlob%

REM Create the pixel shader:
SYS ID3D10Blob.GetBufferPointer%, pPSBlob% TO bp%
SYS ID3D10Blob.GetBufferSize%, pPSBlob% TO bs%
SYS ID3D11Device.CreatePixelShader%, pd3dDevice%, bp%, bs%, NULL, ^pPixelShader% TO hr%
IF hr% <> 0 OR pPixelShader% = 0 THEN
SYS ID3D10Blob.Release%, pVSBlob%
ERROR 100, "ID3D11Device::CreatePixelShader failed: "+STR\$~hr%
ENDIF```

## Putting It Together

After walking through the graphics pipeline, we can start to understand the process of rendering the triangle we created at the beginning of Tutorial 2. Creating Direct3D applications requires two distinct steps. The first would be creating the source data in vertex data, as we've done in Tutorial 2. The second stage would be to create the shaders which would transform that data for rendering, which we showed in this tutorial.

This website uses cookies for visitor traffic analysis. By using the website, you agree with storing the cookies on your computer.More information