Skip to content

Commit

Permalink
Merge pull request #41 from CapsCollective/feature/2D-quad-renderer
Browse files Browse the repository at this point in the history
Implemented true 2D rendering
  • Loading branch information
Raelr committed May 31, 2023
2 parents b7c26ca + b9c49c2 commit 9e63f60
Show file tree
Hide file tree
Showing 39 changed files with 1,225 additions and 237 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ DEBUG ?= 1
ifeq ($(DEBUG), 1)
override CXXFLAGS += -g -DDEBUG -DCC_LOG_LEVEL=2
else
override CXXFLAGS += -DNDEBUG -DCC_LOG_LEVEL=0
override CXXFLAGS += -DNDEBUG -DCC_LOG_LEVEL=0 -O3
endif

# Set platform vars
Expand Down
66 changes: 66 additions & 0 deletions engine/render/assets/shaders/Grid2D.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
//
// Copyright (c) 2022 Jonathan Moallem (@J-Mo63) & Aryeh Zinn (@Raelr)
//
// This code is released under an unmodified zlib license.
// For conditions of distribution and use, please see:
// https://opensource.org/licenses/Zlib
//

#version 460

layout(location=0) in vec3 cellColour;
layout(location=1) in flat float cellSpacing;
layout(location=2) in flat float lineWidth;
layout(location=3) in flat float cellMultiple;
layout(location=4) in flat float fadeFactor;
layout(location=5) in flat float scale;

// output variables
layout(location = 0) out vec4 outColour;

float getAxisGridColour(float uv, float width, float factor, float derivative)
{
/**
* There are a few things happening here:
* 1. The fract function returns the fraction of the given value (the parts after the decimal place). This returns to us
* another normalised coordinate which we can then use to repeat patterns.
* 2. We get the fraction of the uv (remember the has been divided by the spacing we provided earlier), and offset it
* by half the screen.
* 3. We then get the absolute value of the new UV - half the screen (so that we don't get any negatives)
* 4. We divide this by the derivative to give us a smaller space (used for anti-aliasing)
* 5. We then use a step function to determine if the provided UV coordinate is within the cell borders
*/
return max(step(abs(fract(uv - 0.5) -0.5) / derivative, width), factor);
}

vec4 grid(float spacing, float width, vec2 uv, vec3 lColour)
{
float derivative = 1.0 / spacing;

vec4 colour = vec4(getAxisGridColour(uv.y, width, getAxisGridColour(uv.x, width, 0.0, derivative), derivative));

// Check if the uv sits within the range of the cell multiples
vec2 modCoords = vec2(mod(uv.x, cellMultiple), mod(uv.y, cellMultiple));

// Fade the cell colours depending on whether they fall within the cell multiples range or not
vec4 mixColour = mix(vec4(cellColour * fadeFactor, fadeFactor), vec4(cellColour, 1.0), float(modCoords.x < width || modCoords.y < width));

// Change the alpha based on whether the fragment is a grid line or not
colour = mix(colour, vec4(mixColour), colour.a);

return colour;
}

void main()
{
// Determine the spacing and width of our cells
const float spacing = cellSpacing * scale;
const float width = lineWidth / spacing;

// Determine the uv location of the fragment we're dealing with
// NOTE: in glsl, gl_FragCoord always provides the fragment location + 0.5. As such, fragment 0,0 is represented as
// (0.5,0.5)
vec2 uv = (gl_FragCoord.xy - 0.5) / spacing;

outColour = grid(spacing, width, uv, cellColour);
}
41 changes: 41 additions & 0 deletions engine/render/assets/shaders/Grid2D.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
//
// Copyright (c) 2022 Jonathan Moallem (@J-Mo63) & Aryeh Zinn (@Raelr)
//
// This code is released under an unmodified zlib license.
// For conditions of distribution and use, please see:
// https://opensource.org/licenses/Zlib
//

#version 450

vec2 quadVertices[4] = {
vec2(1.0, 1.0),
vec2(1.0, -1.0),
vec2(-1.0, -1.0),
vec2(-1.0, 1.0)
};

layout(location=0) out vec3 cellColour; // The colour of our grid lines
layout(location=1) out flat float cellSpacing; // the spacing between lines in pixels
layout(location=2) out flat float lineWidth; // the width of our lines
layout(location=3) out flat float cellMultiple; // determines how many cells will be encompassed in a sub-grid
layout(location=4) out flat float fadeFactor; // determines how much sub-cells are faded
layout(location=5) out flat float scale; // the DPI scale of the screen

layout (push_constant) uniform PushConstant {
vec4 cellColouring; // Stores the cellColour in xyz and fadeFactor in w
vec4 cellDimensions; // Stores the cell spacing in x, multiple in y, dimensions in z, and width in w
} pushConstant;

void main()
{
vec2 pos = quadVertices[gl_VertexIndex];
gl_Position = vec4(quadVertices[gl_VertexIndex], 0.0, 1.0);

cellColour = pushConstant.cellColouring.xyz;
fadeFactor = pushConstant.cellColouring.w;
cellSpacing = pushConstant.cellDimensions.x;
cellMultiple = pushConstant.cellDimensions.y;
scale = pushConstant.cellDimensions.z;
lineWidth = pushConstant.cellDimensions.w;
}
22 changes: 22 additions & 0 deletions engine/render/assets/shaders/Quad2DInstanced.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// Copyright (c) 2022 Jonathan Moallem (@J-Mo63) & Aryeh Zinn (@Raelr)
//
// This code is released under an unmodified zlib license.
// For conditions of distribution and use, please see:
// https://opensource.org/licenses/Zlib
//

#version 460

layout (location = 0) in vec4 inColour;
layout (location = 1) in vec2 uv;
layout (location = 2) in flat uint texId;

layout (location = 0) out vec4 outColour;

layout(binding = 1) uniform sampler2D tex[16];

void main() {
vec4 sampled = texture(tex[texId], uv);
outColour = sampled * inColour;
}
49 changes: 49 additions & 0 deletions engine/render/assets/shaders/Quad2DInstanced.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
//
// Copyright (c) 2022 Jonathan Moallem (@J-Mo63) & Aryeh Zinn (@Raelr)
//
// This code is released under an unmodified zlib license.
// For conditions of distribution and use, please see:
// https://opensource.org/licenses/Zlib
//

#version 460

// Per-instance vertex data
layout (location = 0) in mat4 inTransform;
layout (location = 4) in vec4 inColour;
layout (location = 5) in vec4 inUv;

layout (location = 0) out vec4 outColour;
layout (location = 1) out vec2 outUv;
layout (location = 2) out flat uint outTexId;

layout (push_constant) uniform PushConstant {
uint textureIndex;
} pushConstant;

vec2 quadVertices[4] = {
vec2(1.0, 1.0),
vec2(1.0, -1.0),
vec2(-1.0, -1.0),
vec2(-1.0, 1.0)
};

layout (binding = 0) uniform CameraData {
mat4 projectionMatrix;
mat4 viewMatrix;
} cameraData;

void main() {

vec4 vertexPosition = inTransform * vec4(quadVertices[gl_VertexIndex], 1.0, 1.0);
gl_Position = cameraData.projectionMatrix * cameraData.viewMatrix * vertexPosition;

float uvx = (float(gl_VertexIndex == 0 || gl_VertexIndex == 1) * (inUv.x + inUv.z))
+ (float(gl_VertexIndex == 2 || gl_VertexIndex == 3) * (inUv.x));
float uvy = (float(gl_VertexIndex == 0 || gl_VertexIndex == 3) * (inUv.y + inUv.w))
+ (float(gl_VertexIndex == 1 || gl_VertexIndex == 2) * (inUv.y));

outColour = inColour;
outUv = vec2(uvx, uvy);
outTexId = pushConstant.textureIndex;
}
22 changes: 22 additions & 0 deletions engine/render/assets/shaders/Quad3D.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
//
// Copyright (c) 2022 Jonathan Moallem (@J-Mo63) & Aryeh Zinn (@Raelr)
//
// This code is released under an unmodified zlib license.
// For conditions of distribution and use, please see:
// https://opensource.org/licenses/Zlib
//

#version 460

layout (location = 0) in vec4 fragColour;
layout (location = 1) in vec2 uv;
layout (location = 2) in flat uint texId;

layout (location = 0) out vec4 outColour;

layout(binding = 1) uniform sampler2D tex[16];

void main() {
vec4 sampled = texture(tex[texId], uv);
outColour = sampled * fragColour;
}
54 changes: 54 additions & 0 deletions engine/render/assets/shaders/Quad3D.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
//
// Copyright (c) 2022 Jonathan Moallem (@J-Mo63) & Aryeh Zinn (@Raelr)
//
// This code is released under an unmodified zlib license.
// For conditions of distribution and use, please see:
// https://opensource.org/licenses/Zlib
//

#version 450

// Per instance data
layout (location = 0) in mat4 inTransform;
layout (location = 4) in vec4 inColour;
layout (location = 5) in vec4 inUv;

layout (location = 0) out vec4 outColour;
layout (location = 1) out vec2 outUv;
layout (location = 2) out flat uint outTexId;

layout (push_constant) uniform PushConstant {
uint textureIndex;
} pushConstant;

vec3 quadVertices[4] = {
vec3(1.0, 1.0, 0),
vec3(1.0, -1.0, 0),
vec3(-1.0, -1.0, 0),
vec3(-1.0, 1.0, 0)
};

struct CameraData
{
mat4 projectionMatrix;
mat4 viewMatrix;
};

layout (binding = 0) uniform GlobalData {
CameraData cameraData;
} globalData;

CameraData camera = globalData.cameraData;

void main() {
gl_Position = camera.projectionMatrix * camera.viewMatrix * inTransform * vec4(quadVertices[gl_VertexIndex], 1.0);

float uvx = (float(gl_VertexIndex == 0 || gl_VertexIndex == 1) * (inUv.x + inUv.z))
+ (float(gl_VertexIndex == 2 || gl_VertexIndex == 3) * (inUv.x));
float uvy = (float(gl_VertexIndex == 0 || gl_VertexIndex == 3) * (inUv.y + inUv.w))
+ (float(gl_VertexIndex == 1 || gl_VertexIndex == 2) * (inUv.y));

outColour = inColour;
outUv = vec2(uvx, uvy);
outTexId = pushConstant.textureIndex;
}
25 changes: 25 additions & 0 deletions engine/render/assets/shaders/Text2DInstanced.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
//
// Copyright (c) 2022 Jonathan Moallem (@J-Mo63) & Aryeh Zinn (@Raelr)
//
// This code is released under an unmodified zlib license.
// For conditions of distribution and use, please see:
// https://opensource.org/licenses/Zlib
//

#version 460

layout (location = 0) in vec4 fragColour;
layout (location = 1) in vec2 uv;
layout (location = 2) in flat uint texId;

layout (location = 0) out vec4 outColour;

layout(binding = 1) uniform sampler2D tex[16];

void main() {
float distance = texture(tex[texId], uv).r;
float smoothWidth = fwidth(distance);
float alpha = smoothstep(0.5 - smoothWidth, 0.5 + smoothWidth, distance);

outColour = mix(vec4(fragColour.rgb, 0.0), fragColour, alpha);
}
52 changes: 52 additions & 0 deletions engine/render/assets/shaders/Text2DInstanced.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
//
// Copyright (c) 2022 Jonathan Moallem (@J-Mo63) & Aryeh Zinn (@Raelr)
//
// This code is released under an unmodified zlib license.
// For conditions of distribution and use, please see:
// https://opensource.org/licenses/Zlib
//

#version 450

// Per instance data
layout(location = 0) in mat4 transform;
layout(location = 4) in vec4 colour;
layout(location = 5) in vec4 texData; // Stores the minimum x and y values for the glyph in the texture + the glyph's dimensions in the texture
layout(location = 6) in vec4 coordinates; // stores x and y coordinates in space + the glyph's dimensions in space

layout(location = 0) out vec4 fragColor;
layout(location = 1) out vec2 outUv;
layout(location = 2) out uint outTexId;

layout (push_constant) uniform TextureData
{
uint textureIndex;
} textureData;

layout (binding = 0) uniform CameraData {
mat4 projectionMatrix;
mat4 viewMatrix;
} cameraData;

void main() {
vec2 coords = vec2(texData.xy);
vec2 dimensions = vec2(texData.zw);

// Find the UV based on the vertex index + min values = coordinate + dimension
float uvx = (float(gl_VertexIndex == 0 || gl_VertexIndex == 1) * (texData.x + texData.z))
+ (float(gl_VertexIndex == 2 || gl_VertexIndex == 3) * (texData.x));
float uvy = (float(gl_VertexIndex == 0 || gl_VertexIndex == 3) * (texData.y + texData.w))
+ (float(gl_VertexIndex == 1 || gl_VertexIndex == 2) * (texData.y));

// Find the vertex position based off the vertex index + min values = coordinate + dimension
float posX = (float(gl_VertexIndex == 0 || gl_VertexIndex == 1) * (coordinates.x + coordinates.z))
+ (float(gl_VertexIndex == 2 || gl_VertexIndex == 3) * coordinates.x);
float posY = (float(gl_VertexIndex == 0 || gl_VertexIndex == 3) * (coordinates.y + coordinates.w))
+ (float(gl_VertexIndex == 1 || gl_VertexIndex == 2) * coordinates.y);

gl_Position = cameraData.projectionMatrix * cameraData.viewMatrix * transform * vec4(posX, posY, 1.0, 1.0);

fragColor = colour;
outUv = vec2(uvx, uvy);
outTexId = textureData.textureIndex;
}
2 changes: 0 additions & 2 deletions engine/render/assets/shaders/grid.frag
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,4 @@ void main() {

outColor = (grid(fragPos3D, 1) + grid(fragPos3D, 1))* float(t > 0);
outColor.a *= fading;

if (outColor.a == 0) discard;
}
14 changes: 12 additions & 2 deletions engine/render/assets/shaders/text2D.frag
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,16 @@ layout (location = 0) out vec4 outColour;
layout(binding = 1) uniform sampler2D tex[16];

void main() {
vec4 sampled = vec4(1.0, 1.0, 1.0, texture(tex[texId], uv).r);
outColour = fragColour * sampled;
// Glyphs are stored as black and white textures. The actual colour values are stored in the red channel to save
// memory. We sample the red texture here.
float distance = texture(tex[texId], uv).r;
// We then compare the red channel of the current fragment with those of its surrounding fragments. The result is
// the difference between all the neighbouring pixels.
float smoothWidth = fwidth(distance);
// finally, we compute the alpha channel based on the width provided above. We start at a value of 0.5 as a base so
// that we have a smooth transition. This will interpolate the alpha based on the red channel so that all while pixels
// become 0 and all black pixels become 1. Thus white pixels become transparent while black ones stay on the image
float alpha = smoothstep(0.5 - smoothWidth, 0.5 + smoothWidth, distance);

outColour = mix(vec4(fragColour.rgb, 0.0), fragColour, alpha);
}
4 changes: 2 additions & 2 deletions engine/render/assets/shaders/text2D.vert
Original file line number Diff line number Diff line change
Expand Up @@ -39,13 +39,13 @@ void main() {
vec2 coords = vec2(texData.xy);
vec2 dimensions = vec2(texData.zw);

// Find the UV based on the vertex index - max values = coordinate + dimension
// Find the UV based on the vertex index + min values = coordinate + dimension
float uvx = (float(gl_VertexIndex == 0 || gl_VertexIndex == 1) * (texData.x + texData.z))
+ (float(gl_VertexIndex == 2 || gl_VertexIndex == 3) * (texData.x));
float uvy = (float(gl_VertexIndex == 0 || gl_VertexIndex == 3) * (texData.y + texData.w))
+ (float(gl_VertexIndex == 1 || gl_VertexIndex == 2) * (texData.y));

// Find the vertex position based off the vertex index - max values = coordinate + dimension
// Find the vertex position based off the vertex index + min values = coordinate + dimension
float posX = (float(gl_VertexIndex == 0 || gl_VertexIndex == 1) * (coordinates.x + coordinates.z))
+ (float(gl_VertexIndex == 2 || gl_VertexIndex == 3) * coordinates.x);
float posY = (float(gl_VertexIndex == 0 || gl_VertexIndex == 3) * (coordinates.y + coordinates.w))
Expand Down
Loading

0 comments on commit 9e63f60

Please sign in to comment.