Skip to content

Hardcoded Gouraud Mode

theproadam edited this page May 3, 2020 · 2 revisions

As renderXF is pixel fill rate limited, normally calculating Phong lightning in the pixel shader would result in high frametimes. To improve performance, the hard-coded Gouraud mode calculates lightning per vertex, and then just interpolates the data. Unfortunately this results in weird lightning issues with low poly objects and broken specular highlights.

Please note that manual Gouraud shading is still possible, however it will not perform as well as the built it Gouraud shader.

Creating the Shader

Gouraud mode doesn't require a fragment shader - it can be left null. All it needs a vertex shader.
Please note that by default renderXF automatically copies attributes over, however Gouraud mode does not allow this, so the SetOverrideAttributeCopy function will have to be used to override the attribute copy feature.

//Initialize the shader
Shader GouraudShader = new Shader(GouraudShader, null, GLRenderMode.TriangleGouraud);

//Display auto attribute copy!
GouraudShader.SetOverrideAttributeCopy(true);

renderXF's built in Gouraud mode can only interpolate 3 floats of data. This data can be set via the OUT pointer. The IN pointer will point to all the vertex data that was specified in the GLBuffer. It is not bound to any number, unlike the OUT pointer.

This table represents what the Shader expects for each OUT value. Exceeding [5] will corrupt the stack.
OUT Index Shader Input
OUT[0] World X Coordinate
OUT[1] World Y Coordinate
OUT[2] World Z Coordinate
OUT[3] Blue Color Value
OUT[4] Green Color Value
OUT[5] Red Color Value

Gouraud Sample Code:

unsafe void GouraudShader(float* OUT, float* IN, int FaceIndex)
{
    //1. Perform vertex operations
    OUT[0] = IN[0];
    OUT[1] = IN[1];
    OUT[2] = IN[2];

    //2. Calculate lightning data
    float R, G, B;
    LightningCalculations(IN, out R, out G, out B)

    //3. Output lightning data
    OUT[3] = R;
    OUT[4] = G;
    OUT[5] = B;
}
Page is WIP