Skip to content

Commit

Permalink
[2D] - Massive overhaul of the lighting effect. The Begin/End and Ren…
Browse files Browse the repository at this point in the history
…der(texture) methods have been removed and only the gbuffer route remains (it works the best out of all of them). Limits on light count have been removed. Examples have been updated to show how to use the gbuffer with the lighting effect. NOTE: This is most certainly a breaking change.
  • Loading branch information
Tape-Worm committed Feb 9, 2022
1 parent 6e0d3ed commit 2e4fff2
Show file tree
Hide file tree
Showing 4 changed files with 131 additions and 429 deletions.
72 changes: 57 additions & 15 deletions Examples/Gorgon.Renderers.2D/Lights/Program.cs
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,9 @@ namespace Gorgon.Examples
/// <summary>
/// The main entry point for the application.
/// </summary>
/// <remarks>
/// This example shows how to use the G-Buffer and Lighting effect to provide lighting for your sprites.
/// </remarks>
static class Program
{
#region Variables.
Expand All @@ -65,6 +68,8 @@ static class Program
private static GorgonSprite _torchSprite;
// Our lighting effect.
private static Gorgon2DLightingEffect _lightEffect;
// The g-buffer which contains our buffers used for lighting.
private static Gorgon2DGBuffer _gbuffer;
// Flag to indicate the direction of light brightness.
private static bool _lightBrightDir = true;
// The actual light color value.
Expand All @@ -76,6 +81,8 @@ static class Program
// The point light that we control.
private static GorgonPointLight _light;
private static GorgonOrthoCamera _camera;
// Flag to indicate we should rotate the logo.
private static bool _rotate;
#endregion

#region Methods.
Expand Down Expand Up @@ -118,35 +125,56 @@ private static bool Idle()
_light.Color = new GorgonColor((_lightValue * 253.0f) / 255.0f, (_lightValue * 248.0f) / 255.0f, (_lightValue * 230.0f) / 255.0f);
_light.SpecularPower = (1.0f - (_lightValue / 1.2f)) * 256;

// Blit our final texture to the main screen.
_graphics.SetRenderTarget(_screen.RenderTargetView);
// Clear our buffers each frame.
_screen.RenderTargetView.Clear(GorgonColor.Black);
_gbuffer.ClearGBuffer();

// Gorgon uses a G-Buffer, a collection of render targets used to facilitate lighting and other effects in order
// provide a basis for lighting. Other techniques could be implemented, some faster, some slower, however this one
// makes deferred lighting easier and is the better option for rendering multiple sprites affected by lighting.
//
// Gorgon's G-Buffer has one other critical advantage: It supports rotating sprites. Without special considerations
// rotation of sprites when lighting will not look correct because the normals need to be rotated as well. This
// is done in the G-Buffer on your behalf so your lighting will look correct no matter the orientation of the
// sprite.

// What are the normal and specular maps used for?
// The Normal map is used to define how light behaves when it hits a surface in the scene. Without these, you will
// not be able to see any depth in the image, and the lighting will not update as the light passes over the scene.
// The Specular map is used to map out reflective spots on the image where the light will make the surface appear
// shiny or even wet.

// First we need to render the normal map, specular map and diffuse map to the buffer. For this example, these are
// stored in texture array indices #2, #1, and #0 respectively. This is why we pass the 2 and 1 as the first
// parameters for the gbuffer effect. We do not pass in the diffuse array index because the sprite being drawn
// will have that value in its TextureArrayIndex property.
_gbuffer.Begin(2, 1, camera: _camera);
_renderer.DrawSprite(_logoSprite);
_gbuffer.End();

// Render the lit sprite.
_lightEffect.Begin(2, 1, camera: _camera);
_logoSprite.Position = new Vector2(0, 0);
// Now we'll send it all to our screen using the lighting effect.
_graphics.SetRenderTarget(_screen.RenderTargetView);
_lightEffect.Render(_gbuffer, _screen.RenderTargetView);

if (_lightEffect.RotateNormals)
if (_rotate)
{
_logoSprite.Angle += 45 * GorgonTiming.Delta;
}

if (_logoSprite.Angle > 360.0f)
{
_logoSprite.Angle -= 360.0f;
}

_renderer.DrawSprite(_logoSprite);
_lightEffect.End();
}

// Draw the rest of the UI.
_renderer.Begin();

_renderer.DrawSprite(_torchSprite);

_renderer.DrawString($"Specular Power: {_light.SpecularPower:0.0}\n" +
$"Light [c #{GorgonColor.CornFlowerBlue.ToHex()}]Z/z[/c]: {_light.Position.Z:0}\n" +
$"Camera Position: {_camera.Position.X:0}, {_camera.Position.Y:0} ([c #{GorgonColor.CornFlowerBlue.ToHex()}]W[/c], [c #{GorgonColor.CornFlowerBlue.ToHex()}]A[/c], [c #{GorgonColor.CornFlowerBlue.ToHex()}]S[/c], [c #{GorgonColor.CornFlowerBlue.ToHex()}]D[/c])\n" +
$"[c #{GorgonColor.CornFlowerBlue.ToHex()}]N[/c]ormal Rotation: {(_lightEffect.RotateNormals ? "Yes" : "No")}",
$"[c #{GorgonColor.CornFlowerBlue.ToHex()}]R[/c]otation: {(_rotate ? "Yes" : "No")}",
new Vector2(0, 64));
_renderer.End();

Expand Down Expand Up @@ -188,10 +216,12 @@ private static FormMain Initialize()
Name = "Gorgon2D Effects Example Swap Chain"
});

_screen.SwapChainResized += Screen_SwapChainResized;

_camera = new GorgonOrthoCamera(_graphics, new DX.Size2F(_screen.Width, _screen.Height))
{
Anchor = new Vector2(0.5f, 0.5f),
Position = new Vector3(0.0f, 0.0f, -70),
Position = new Vector3(0, 0, -70),
AllowUpdateOnResize = false
};

Expand Down Expand Up @@ -220,7 +250,9 @@ private static FormMain Initialize()
});

// Initialize the renderer so that we are able to draw stuff.
_renderer = new Gorgon2D(_graphics);
_renderer = new Gorgon2D(_graphics);

_gbuffer = new Gorgon2DGBuffer(_renderer, _screen.Width, _screen.Height);

_logoSprite = new GorgonSprite
{
Expand Down Expand Up @@ -276,6 +308,15 @@ private static FormMain Initialize()
}
}

/// <summary>Handles the SwapChainResized event of the Screen control.</summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="SwapChainResizedEventArgs" /> instance containing the event data.</param>
private static void Screen_SwapChainResized(object sender, SwapChainResizedEventArgs e)
{
_gbuffer.Resize(e.Size.Width, e.Size.Height);
_camera.ViewDimensions = e.Size.ToSize2F();
}

/// <summary>
/// Windows the key down.
/// </summary>
Expand All @@ -291,8 +332,8 @@ private static void Window_KeyDown(object sender, KeyEventArgs e)
case Keys.Escape:
GorgonApplication.Quit();
return;
case Keys.N:
_lightEffect.RotateNormals = !_lightEffect.RotateNormals;
case Keys.R:
_rotate = !_rotate;
break;
case Keys.Z:
_light.Position =
Expand Down Expand Up @@ -369,6 +410,7 @@ static void Main()
{
GorgonExample.UnloadResources();

_gbuffer?.Dispose();
_lightEffect?.Dispose();
_renderer?.Dispose();
_backgroundLogoTexture?.Dispose();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,11 @@ namespace Gorgon.Renderers.Data
[StructLayout(LayoutKind.Sequential)]
public readonly struct GorgonGpuLightData
{
/// <summary>
/// An empty light data structure.
/// </summary>
public static readonly GorgonGpuLightData Empty = new();

/// <summary>
/// The number of bytes for this value type.
/// </summary>
Expand Down
Loading

0 comments on commit 2e4fff2

Please sign in to comment.