Skip to content

Commit

Permalink
Implement Vulkan renderer (#1420)
Browse files Browse the repository at this point in the history
This is an alternative to the DirectX renderer and will be used to render the samples on other platforms than Windows.
  • Loading branch information
jrouwe authored Dec 27, 2024
1 parent b40b2b6 commit f55e0e3
Show file tree
Hide file tree
Showing 69 changed files with 4,093 additions and 1,283 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -193,7 +193,7 @@ jobs:
update: true
- name: Configure CMake
working-directory: ${{github.workspace}}/Build
run: ./cmake_linux_mingw.sh ${{matrix.build_type}} g++ -DBUILD_SHARED_LIBS=${{matrix.shared_lib}}
run: ./cmake_linux_mingw.sh ${{matrix.build_type}} -DBUILD_SHARED_LIBS=${{matrix.shared_lib}}
- name: Build
run: cmake --build Build/MinGW_${{matrix.build_type}} -j $(nproc)
- name: Test
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
/snapshot.bin
/*.jor
/detlog.txt
/Assets/Shaders/*.spv
17 changes: 17 additions & 0 deletions Assets/Shaders/FontPixelShader.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#version 450

layout(set = 1, binding = 0) uniform sampler2D texSampler;

layout(location = 0) in vec2 iTex;
layout(location = 1) in vec4 iColor;

layout(location = 0) out vec4 oColor;

void main()
{
float t = texture(texSampler, iTex).x;
if (t < 0.5)
discard;

oColor = vec4(iColor.xyz, t);
}
2 changes: 2 additions & 0 deletions Assets/Shaders/FontPixelShader.hlsl
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ PS_OUTPUT main(PS_INPUT In)
PS_OUTPUT Output;

float t = ShaderTexture.Sample(SampleType, In.Tex).r;
if (t < 0.5)
discard;

Output.RGBColor = float4(In.Color.rgb, t);

Expand Down
17 changes: 17 additions & 0 deletions Assets/Shaders/FontVertexShader.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#version 450

#include "VertexConstantsVK.h"

layout(location = 0) in vec3 vPos;
layout(location = 1) in vec2 vTex;
layout(location = 2) in vec4 vCol;

layout(location = 0) out vec2 oTex;
layout(location = 1) out vec4 oColor;

void main()
{
gl_Position = c.Projection * c.View * vec4(vPos, 1.0f);
oTex = vTex;
oColor = vCol;
}
10 changes: 10 additions & 0 deletions Assets/Shaders/LinePixelShader.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#version 450

layout(location = 0) in vec4 iColor;

layout(location = 0) out vec4 oColor;

void main()
{
oColor = iColor;
}
14 changes: 14 additions & 0 deletions Assets/Shaders/LineVertexShader.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#version 450

#include "VertexConstantsVK.h"

layout(location = 0) in vec3 iPosition;
layout(location = 1) in vec4 iColor;

layout(location = 0) out vec4 oColor;

void main()
{
gl_Position = c.Projection * c.View * vec4(iPosition, 1.0);
oColor = iColor;
}
6 changes: 6 additions & 0 deletions Assets/Shaders/TriangleDepthPixelShader.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
#version 450

// We only write depth, so this shader does nothing
void main()
{
}
31 changes: 31 additions & 0 deletions Assets/Shaders/TriangleDepthVertexShader.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
#version 450

#include "VertexConstantsVK.h"

layout(location = 0) in vec3 vPos;
layout(location = 1) in vec3 vNorm;
layout(location = 2) in vec2 vTex;
layout(location = 3) in vec4 vCol;

layout(location = 4) in mat4 iModel;
layout(location = 8) in mat4 iModelInvTrans;
layout(location = 12) in vec4 iCol;

void main()
{
// Check if the alpha = 0
if (vCol.a * iCol.a == 0.0)
{
// Don't draw the triangle by moving it to an invalid location
gl_Position = vec4(0, 0, 0, 0);
}
else
{
// Transform the position from world space to homogeneous projection space for the light
vec4 pos = vec4(vPos, 1.0f);
pos = iModel * pos;
pos = c.LightView * pos;
pos = c.LightProjection * pos;
gl_Position = pos;
}
}
110 changes: 110 additions & 0 deletions Assets/Shaders/TrianglePixelShader.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
#version 450

layout(binding = 1) uniform PixelShaderConstantBuffer
{
vec3 CameraPos;
vec3 LightPos;
} c;

layout(location = 0) in vec3 iNormal;
layout(location = 1) in vec3 iWorldPos;
layout(location = 2) in vec2 iTex;
layout(location = 3) in vec4 iPositionL;
layout(location = 4) in vec4 iColor;

layout(location = 0) out vec4 oColor;

layout(set = 1, binding = 0) uniform sampler2DShadow LightDepthSampler;

void main()
{
// Constants
float AmbientFactor = 0.3;
vec3 DiffuseColor = vec3(iColor.r, iColor.g, iColor.b);
vec3 SpecularColor = vec3(1, 1, 1);
float SpecularPower = 100.0;
float bias = 1.0e-7;

// Homogenize position in light space
vec3 position_l = iPositionL.xyz / iPositionL.w;

// Calculate dot product between direction to light and surface normal and clamp between [0, 1]
vec3 view_dir = normalize(c.CameraPos - iWorldPos);
vec3 world_to_light = c.LightPos - iWorldPos;
vec3 light_dir = normalize(world_to_light);
vec3 normal = normalize(iNormal);
if (dot(view_dir, normal) < 0) // If we're viewing the triangle from the back side, flip the normal to get the correct lighting
normal = -normal;
float normal_dot_light_dir = clamp(dot(normal, light_dir), 0, 1);

// Calculate texture coordinates in light depth texture
vec2 tex_coord;
tex_coord.x = position_l.x / 2.0 + 0.5;
tex_coord.y = position_l.y / 2.0 + 0.5;

// Check that the texture coordinate is inside the depth texture, if not we don't know if it is lit or not so we assume lit
float shadow_factor = 1.0;
if (iColor.a > 0 // Alpha = 0 means don't receive shadows
&& tex_coord.x == clamp(tex_coord.x, 0, 1) && tex_coord.y == clamp(tex_coord.y, 0, 1))
{
// Modify shadow bias according to the angle between the normal and the light dir
float modified_bias = bias * tan(acos(normal_dot_light_dir));
modified_bias = min(modified_bias, 10.0 * bias);

// Get texture size
float width = 1.0 / 4096;
float height = 1.0 / 4096;

// Samples to take
uint num_samples = 16;
vec2 offsets[] = {
vec2(-1.5 * width, -1.5 * height),
vec2(-0.5 * width, -1.5 * height),
vec2(0.5 * width, -1.5 * height),
vec2(1.5 * width, -1.5 * height),

vec2(-1.5 * width, -0.5 * height),
vec2(-0.5 * width, -0.5 * height),
vec2(0.5 * width, -0.5 * height),
vec2(1.5 * width, -0.5 * height),

vec2(-1.5 * width, 0.5 * height),
vec2(-0.5 * width, 0.5 * height),
vec2(0.5 * width, 0.5 * height),
vec2(1.5 * width, 0.5 * height),

vec2(-1.5 * width, 1.5 * height),
vec2(-0.5 * width, 1.5 * height),
vec2(0.5 * width, 1.5 * height),
vec2(1.5 * width, 1.5 * height),
};

// Calculate depth of this pixel relative to the light
float light_depth = position_l.z + modified_bias;

// Sample shadow factor
shadow_factor = 0.0;
for (uint i = 0; i < num_samples; ++i)
{
vec3 location_and_reference = vec3(tex_coord + offsets[i], light_depth);
shadow_factor += texture(LightDepthSampler, location_and_reference);
}
shadow_factor /= num_samples;
}

// Calculate diffuse and specular
float diffuse = normal_dot_light_dir;
float specular = diffuse > 0.0? pow(clamp(-dot(reflect(light_dir, normal), view_dir), 0, 1), SpecularPower) : 0.0;

// Apply procedural pattern based on the uv coordinates
bvec2 less_half = lessThan(iTex - floor(iTex), vec2(0.5, 0.5));
float darken_factor = less_half.r ^^ less_half.g? 0.5 : 1.0;

// Fade out checkerboard pattern when it tiles too often
vec2 dx = dFdx(iTex), dy = dFdy(iTex);
float texel_distance = sqrt(dot(dx, dx) + dot(dy, dy));
darken_factor = mix(darken_factor, 0.75, clamp(5.0 * texel_distance - 1.5, 0.0, 1.0));

// Calculate color
oColor = vec4(clamp((AmbientFactor + diffuse * shadow_factor) * darken_factor * DiffuseColor + SpecularColor * specular * shadow_factor, 0, 1), 1);
}
48 changes: 48 additions & 0 deletions Assets/Shaders/TriangleVertexShader.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
#version 450

#include "VertexConstantsVK.h"

layout(location = 0) in vec3 vPos;
layout(location = 1) in vec3 vNorm;
layout(location = 2) in vec2 vTex;
layout(location = 3) in vec4 vCol;

layout(location = 4) in mat4 iModel;
layout(location = 8) in mat4 iModelInvTrans;
layout(location = 12) in vec4 iCol;

layout(location = 0) out vec3 oNormal;
layout(location = 1) out vec3 oWorldPos;
layout(location = 2) out vec2 oTex;
layout(location = 3) out vec4 oPositionL;
layout(location = 4) out vec4 oColor;

void main()
{
// Get world position
vec4 pos = vec4(vPos, 1.0f);
vec4 world_pos = iModel * pos;

// Transform the position from world space to homogeneous projection space
vec4 proj_pos = c.View * world_pos;
proj_pos = c.Projection * proj_pos;
gl_Position = proj_pos;

// Transform the position from world space to projection space of the light
vec4 proj_lpos = c.LightView * world_pos;
proj_lpos = c.LightProjection * proj_lpos;
oPositionL = proj_lpos;

// output normal
vec4 norm = vec4(vNorm, 0.0f);
oNormal = normalize(iModelInvTrans * norm).xyz;

// output world position of the vertex
oWorldPos = world_pos.xyz;

// output texture coordinates
oTex = vTex;

// output color
oColor = vCol * iCol;
}
13 changes: 13 additions & 0 deletions Assets/Shaders/UIPixelShader.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
#version 450

layout(set = 1, binding = 0) uniform sampler2D texSampler;

layout(location = 0) in vec4 iColor;
layout(location = 1) in vec2 iTex;

layout(location = 0) out vec4 oColor;

void main()
{
oColor = iColor * texture(texSampler, iTex);
}
10 changes: 10 additions & 0 deletions Assets/Shaders/UIPixelShaderUntextured.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#version 450

layout(location = 0) in vec4 iColor;

layout(location = 0) out vec4 oColor;

void main()
{
oColor = iColor;
}
17 changes: 17 additions & 0 deletions Assets/Shaders/UIVertexShader.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
#version 450

#include "VertexConstantsVK.h"

layout(location = 0) in vec3 vPos;
layout(location = 1) in vec2 vTex;
layout(location = 2) in vec4 vCol;

layout(location = 0) out vec4 oColor;
layout(location = 1) out vec2 oTex;

void main()
{
gl_Position = c.Projection * c.View * vec4(vPos, 1.0f);
oTex = vTex;
oColor = vCol;
}
7 changes: 7 additions & 0 deletions Assets/Shaders/VertexConstantsVK.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
layout(binding = 0) uniform VertexShaderConstantBuffer
{
mat4 View;
mat4 Projection;
mat4 LightView;
mat4 LightProjection;
} c;
3 changes: 3 additions & 0 deletions Build/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,9 @@ include(CMakeDependentOption)
# Windows Store only supports the DLL version
cmake_dependent_option(USE_STATIC_MSVC_RUNTIME_LIBRARY "Use the static MSVC runtime library" ON "MSVC;NOT WINDOWS_STORE" OFF)

# Enable Vulkan instead of DirectX
cmake_dependent_option(JPH_ENABLE_VULKAN "Enable Vulkan" OFF "WIN32" ON)

# Determine which configurations exist
if (CMAKE_CURRENT_SOURCE_DIR STREQUAL CMAKE_SOURCE_DIR) # Only do this when we're at the top level, see: https://gitlab.kitware.com/cmake/cmake/-/issues/24181
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC" OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU")
Expand Down
17 changes: 16 additions & 1 deletion TestFramework/Application/Application.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@
#include <Jolt/RegisterTypes.h>
#include <Renderer/DebugRendererImp.h>
#include <crtdbg.h>
#ifdef JPH_ENABLE_VULKAN
#include <Renderer/VK/RendererVK.h>
#else
#include <Renderer/DX12/RendererDX12.h>
#endif

// Constructor
Application::Application() :
Expand Down Expand Up @@ -52,7 +57,11 @@ Application::Application() :
DisableCustomMemoryHook dcmh;

// Create renderer
mRenderer = new Renderer;
#ifdef JPH_ENABLE_VULKAN
mRenderer = new RendererVK;
#else
mRenderer = new RendererDX12;
#endif
mRenderer->Initialize();

// Create font
Expand Down Expand Up @@ -226,6 +235,12 @@ void Application::Run()
// Start rendering
mRenderer->BeginFrame(mWorldCamera, GetWorldScale());

// Draw from light
static_cast<DebugRendererImp *>(mDebugRenderer)->DrawShadowPass();

// Start drawing normally
mRenderer->EndShadowPass();

// Draw debug information
static_cast<DebugRendererImp *>(mDebugRenderer)->Draw();

Expand Down
Loading

0 comments on commit f55e0e3

Please sign in to comment.