Compare commits
277 Commits
develop
...
6d7a3a09b1
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
6d7a3a09b1 | ||
|
|
67916d0307 | ||
|
|
30b5ccc339 | ||
|
|
4f24372a2f | ||
|
|
08be51fc2d | ||
|
|
eac8c7aab0 | ||
|
|
a82e3dec04 | ||
|
|
e8c4af6e5c | ||
|
|
b73caaf8b7 | ||
|
|
aeac3a4e47 | ||
|
|
e18298a8cb | ||
|
|
bef8e3d204 | ||
|
|
8b7bdf6376 | ||
|
|
23cf27b120 | ||
|
|
163c3887ac | ||
|
|
85062d4de5 | ||
|
|
ce89e8b466 | ||
|
|
4052c14567 | ||
|
|
5c5289ee73 | ||
|
|
9a3919d633 | ||
|
|
0c4252be5e | ||
|
|
e2fd0644e4 | ||
|
|
54b7c4143f | ||
|
|
217a4fbcb6 | ||
|
|
8125d24926 | ||
|
|
d276e875a8 | ||
|
|
5da09282d0 | ||
|
|
a8c38a5a4e | ||
|
|
a809c5a568 | ||
|
|
d891762b3f | ||
|
|
d2b9ef97da | ||
|
|
62fe4b360d | ||
|
|
7f65a80ad0 | ||
|
|
a46ee129f0 | ||
|
|
710d63ad98 | ||
|
|
b8bedd6cb2 | ||
|
|
1af791293d | ||
|
|
57564645f2 | ||
|
|
5ce9fb6093 | ||
|
|
804d147492 | ||
|
|
cf80cd3471 | ||
|
|
153d7e423e | ||
|
|
f4fd6e78f3 | ||
|
|
1f219ba8bc | ||
|
|
e656c01bda | ||
|
|
ef29123dec | ||
|
|
3ceeb3e272 | ||
|
|
54eff5f454 | ||
|
|
b2510a4365 | ||
|
|
ad581b1d4e | ||
|
|
b959d4abc0 | ||
|
|
dc8d4c54ee | ||
|
|
7921723d72 | ||
|
|
193b64e177 | ||
|
|
6037d48210 | ||
|
|
5bb4303eff | ||
|
|
a516f09cf5 | ||
|
|
bff8ca2be1 | ||
|
|
1668363c4e | ||
|
|
00367c37c9 | ||
|
|
2908429b68 | ||
|
|
c9dfe2706e | ||
|
|
41dd201128 | ||
|
|
709633dce6 | ||
|
|
2df8cdf150 | ||
|
|
d6d9c380c4 | ||
|
|
06c6aab24e | ||
|
|
2876ee701b | ||
|
|
fff6997dd4 | ||
|
|
ef70a04da9 | ||
|
|
729ae9050d | ||
|
|
0f7a9ebfba | ||
|
|
13dd209424 | ||
|
|
3037813cf4 | ||
|
|
5ae981db06 | ||
|
|
a99d793b39 | ||
|
|
9dba0d2f4b | ||
|
|
68519dc28b | ||
|
|
e81da93173 | ||
|
|
155c9a8551 | ||
|
|
87ba90a6a0 | ||
|
|
c2d6a12aa5 | ||
|
|
6b7a19b5b6 | ||
|
|
b30f3192b6 | ||
|
|
e8fda9c544 | ||
|
|
58c2193356 | ||
|
|
eb33b8b241 | ||
|
|
1e0d79e0eb | ||
|
|
8d41c47a93 | ||
|
|
9252264154 | ||
|
|
85f0eb2c02 | ||
|
|
0243ef83cb | ||
|
|
e232d06ed3 | ||
|
|
ff50932aa4 | ||
|
|
c065f12801 | ||
|
|
994a5843cf | ||
|
|
f3e0267623 | ||
|
|
f491f51d7b | ||
|
|
f0d762b8a1 | ||
|
|
d0c8e84f50 | ||
|
|
7182f4c09b | ||
|
|
151d0be0f1 | ||
|
|
cede05a309 | ||
|
|
e09dbb671a | ||
|
|
809aea6974 | ||
|
|
ea503a1c85 | ||
|
|
ee36f98cdd | ||
|
|
6c3debff41 | ||
|
|
b10e437e35 | ||
|
|
5cc18788f7 | ||
|
|
d1523f1b17 | ||
|
|
80aa334bbc | ||
|
|
4335d0ac9c | ||
|
|
3635e1195c | ||
|
|
41c05f52a1 | ||
|
|
caa94aeff7 | ||
|
|
d9c495d0fd | ||
|
|
ce2b29ec1c | ||
|
|
8d92f68cc6 | ||
|
|
e95787824c | ||
|
|
21647c27cf | ||
|
|
bb7d7aafbc | ||
|
|
e99c8423a6 | ||
|
|
c13bd36a78 | ||
|
|
4dd5d2516e | ||
|
|
403446b45d | ||
|
|
f3b738758d | ||
|
|
17f96f5af2 | ||
|
|
447fa3cdad | ||
|
|
d2f36082a9 | ||
|
|
2ffe62ee01 | ||
|
|
bda0043ede | ||
|
|
02c05cf0c1 | ||
|
|
a278d960d1 | ||
|
|
680e5f1651 | ||
|
|
11490f0f57 | ||
|
|
9d30f160ba | ||
|
|
b51a6b1ccb | ||
|
|
c28b27f38e | ||
|
|
f1e6a10cb1 | ||
|
|
64edf33622 | ||
|
|
cd6eb2a682 | ||
|
|
f54fe85d09 | ||
|
|
edc4b16ffe | ||
|
|
f4a36c9a16 | ||
|
|
25185255cc | ||
|
|
74fee28303 | ||
|
|
1f3a5e02af | ||
|
|
a4e7e7d530 | ||
|
|
07f93c0509 | ||
|
|
16e7819ad8 | ||
|
|
916d7cf1b4 | ||
|
|
92a64f19ea | ||
|
|
e8a84c98ec | ||
|
|
9cceec7035 | ||
|
|
85eaa46ee3 | ||
|
|
e4d276974c | ||
|
|
3650041051 | ||
|
|
292031dbc2 | ||
|
|
475aceed9b | ||
|
|
31da43228b | ||
|
|
f6dd41ed9a | ||
|
|
7d0af312ef | ||
|
|
ea136b729c | ||
|
|
e5fc760938 | ||
|
|
4d316fe280 | ||
|
|
5347fab0ed | ||
|
|
83de729716 | ||
|
|
faf86c05a7 | ||
|
|
c4e79c61ed | ||
|
|
387b82d385 | ||
|
|
a3dc799692 | ||
|
|
7a2218824d | ||
|
|
b70211ee86 | ||
|
|
81bf61221b | ||
|
|
cf8e4cad4d | ||
|
|
8831407da0 | ||
|
|
ec9cbcf18b | ||
|
|
8faaef0ec6 | ||
|
|
1728b20cda | ||
|
|
148a792902 | ||
|
|
ebaf70dfbd | ||
|
|
745c6a1f32 | ||
|
|
89ebc5d012 | ||
|
|
ab534fe929 | ||
|
|
6b53ab6f8f | ||
|
|
51038f4579 | ||
|
|
6dc7765c70 | ||
|
|
476a1d6d95 | ||
|
|
cae58d8bf5 | ||
|
|
333ea73d3a | ||
|
|
9573eba60b | ||
|
|
d5e987a89d | ||
|
|
21150ba091 | ||
|
|
0ed6e06924 | ||
|
|
37fd764248 | ||
|
|
8c592ba87b | ||
|
|
e52bc15eaa | ||
|
|
c0f8e68daf | ||
|
|
1340d71799 | ||
|
|
64d3cb6e01 | ||
|
|
0725cafbf3 | ||
|
|
e717cbe68b | ||
|
|
28e902b176 | ||
|
|
2e95d7d2ad | ||
|
|
8b3f8aefe9 | ||
|
|
3a97be84b4 | ||
|
|
95b0e01f0e | ||
|
|
e203ac5bd8 | ||
|
|
890b1c44b2 | ||
|
|
3193ebd062 | ||
|
|
72440a362d | ||
|
|
d419d6019f | ||
|
|
da6b23cb07 | ||
|
|
2c8de739bd | ||
|
|
996c3e6e16 | ||
|
|
7e5a45de52 | ||
|
|
c0182293ec | ||
|
|
13730be45c | ||
|
|
95e1c38e0b | ||
|
|
5a0686bd17 | ||
|
|
194b81e114 | ||
|
|
8e8fa1cd6d | ||
|
|
a197ab62a6 | ||
|
|
e5671fd47b | ||
|
|
b40b0045b9 | ||
|
|
49f9f3bbe0 | ||
|
|
f0325e1ce9 | ||
|
|
e60c114acf | ||
|
|
3e92a6c7f4 | ||
|
|
d2cd2a542c | ||
|
|
2bad2b600a | ||
|
|
bb4b882ed4 | ||
|
|
d69c56bed8 | ||
|
|
0f5172eb04 | ||
|
|
ab09f8efb5 | ||
|
|
0dfa62988b | ||
|
|
3d5ad2e131 | ||
|
|
1471c2849d | ||
|
|
f3486bc316 | ||
|
|
3f6de89262 | ||
|
|
c67b9f18e5 | ||
|
|
2d07e3777e | ||
|
|
8d7f587d7e | ||
|
|
55901f8603 | ||
|
|
8548fc8133 | ||
|
|
604da83051 | ||
|
|
97ba783644 | ||
|
|
3e10ee032c | ||
|
|
342513e2e5 | ||
|
|
0efc76bfaa | ||
|
|
5f39899981 | ||
|
|
e8ad4be39d | ||
|
|
90c6652074 | ||
|
|
1164bd4b0f | ||
|
|
3bf57200af | ||
|
|
1a5a8608fc | ||
|
|
724459e0dd | ||
|
|
34bee233e2 | ||
|
|
4ea582ddf7 | ||
|
|
679eaa456a | ||
|
|
519d54df9b | ||
|
|
4897c8fb2c | ||
|
|
57c767d659 | ||
|
|
8680107227 | ||
|
|
d40144b9e7 | ||
|
|
002795d29d | ||
|
|
24c41f778e | ||
|
|
dfc5b6fa69 | ||
|
|
29130dde7f | ||
|
|
cd2e603733 | ||
|
|
39a0273595 | ||
|
|
b2d749244f | ||
|
|
5ba897ed46 | ||
|
|
fb677f8fe6 | ||
|
|
e5c252629b | ||
|
|
84a7d5e248 |
44
.gitmodules
vendored
@@ -1,33 +1,33 @@
|
||||
[submodule "Nuake/dependencies/assimp"]
|
||||
path = Nuake/dependencies/assimp
|
||||
[submodule "Nuake/Thirdparty/assimp"]
|
||||
path = Nuake/Thirdparty/assimp
|
||||
url = https://github.com/assimp/assimp.git
|
||||
[submodule "Nuake/dependencies/JoltPhysics"]
|
||||
path = Nuake/dependencies/JoltPhysics
|
||||
[submodule "Nuake/Thirdparty/JoltPhysics"]
|
||||
path = Nuake/Thirdparty/JoltPhysics
|
||||
url = https://github.com/antopilo/JoltPhysics.git
|
||||
[submodule "Nuake/dependencies/soloud"]
|
||||
path = Nuake/dependencies/soloud
|
||||
[submodule "Nuake/Thirdparty/soloud"]
|
||||
path = Nuake/Thirdparty/soloud
|
||||
url = https://github.com/antopilo/soloud.git
|
||||
[submodule "Nuake/dependencies/Coral"]
|
||||
path = Nuake/dependencies/Coral
|
||||
[submodule "Nuake/Thirdparty/Coral"]
|
||||
path = Nuake/Thirdparty/Coral
|
||||
url = https://github.com/antopilo/Coral.git
|
||||
[submodule "Nuake/dependencies/recastnavigation"]
|
||||
path = Nuake/dependencies/recastnavigation
|
||||
[submodule "Nuake/Thirdparty/recastnavigation"]
|
||||
path = Nuake/Thirdparty/recastnavigation
|
||||
url = https://github.com/antopilo/recastnavigation.git
|
||||
[submodule "Nuake/dependencies/tracy"]
|
||||
path = Nuake/dependencies/tracy
|
||||
[submodule "Nuake/Thirdparty/tracy"]
|
||||
path = Nuake/Thirdparty/tracy
|
||||
url = https://github.com/wolfpld/tracy.git
|
||||
[submodule "Nuake/dependencies/msdf-atlas-gen"]
|
||||
path = Nuake/dependencies/msdf-atlas-gen
|
||||
[submodule "Nuake/Thirdparty/msdf-atlas-gen"]
|
||||
path = Nuake/Thirdparty/msdf-atlas-gen
|
||||
url = https://github.com/antopilo/msdf-atlas-gen.git
|
||||
[submodule "Nuake/dependencies/yoga"]
|
||||
path = Nuake/dependencies/yoga
|
||||
[submodule "Nuake/Thirdparty/yoga"]
|
||||
path = Nuake/Thirdparty/yoga
|
||||
url = https://github.com/facebook/yoga.git
|
||||
[submodule "Nuake/dependencies/freetype"]
|
||||
path = Nuake/dependencies/freetype
|
||||
[submodule "Nuake/Thirdparty/freetype"]
|
||||
path = Nuake/Thirdparty/freetype
|
||||
url = https://github.com/freetype/freetype.git
|
||||
[submodule "Nuake/dependencies/entt"]
|
||||
path = Nuake/dependencies/entt
|
||||
[submodule "Nuake/Thirdparty/entt"]
|
||||
path = Nuake/Thirdparty/entt
|
||||
url = https://github.com/skypjack/entt.git
|
||||
[submodule "Nuake/dependencies/glfw"]
|
||||
path = Nuake/dependencies/glfw
|
||||
[submodule "Nuake/Thirdparty/glfw"]
|
||||
path = Nuake/Thirdparty/glfw
|
||||
url = https://github.com/antopilo/glfw.git
|
||||
|
||||
30
BuildScripts/build.bat
Normal file
@@ -0,0 +1,30 @@
|
||||
@echo off
|
||||
|
||||
REM Set default values for configuration and platform
|
||||
set CONFIG=Debug
|
||||
set PLATFORM=
|
||||
|
||||
REM Get solution file path
|
||||
set SOLUTION=Nuake.sln
|
||||
|
||||
REM Check if Configuration is provided
|
||||
if not "%~2"=="" (
|
||||
set CONFIG=%~2
|
||||
)
|
||||
|
||||
REM Check if Platform is provided
|
||||
if not "%~3"=="" (
|
||||
set PLATFORM=%~3
|
||||
)
|
||||
|
||||
REM Build the solution
|
||||
echo Building solution "%SOLUTION%" with Configuration=%CONFIG% and Platform=%PLATFORM%...
|
||||
"C:\Program Files\Microsoft Visual Studio\2022\Community\Msbuild\Current\Bin\MSBuild.exe" "Nuake.sln" -verbosity:minimal
|
||||
PAUSE
|
||||
REM Check if build succeeded
|
||||
if %ERRORLEVEL%==0 (
|
||||
echo Build succeeded.
|
||||
) else (
|
||||
echo Build failed.
|
||||
exit /b 1
|
||||
)
|
||||
@@ -1,2 +1,3 @@
|
||||
cd ..
|
||||
premake5 vs2022
|
||||
pause
|
||||
2099
Data/Data/gamecontrollerdb.txt
Normal file
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 4.5 KiB After Width: | Height: | Size: 4.5 KiB |
|
Before Width: | Height: | Size: 3.7 KiB After Width: | Height: | Size: 3.7 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 3.6 KiB After Width: | Height: | Size: 3.6 KiB |
|
Before Width: | Height: | Size: 3.1 KiB After Width: | Height: | Size: 3.1 KiB |
|
Before Width: | Height: | Size: 3.2 KiB After Width: | Height: | Size: 3.2 KiB |
|
Before Width: | Height: | Size: 2.8 KiB After Width: | Height: | Size: 2.8 KiB |
|
Before Width: | Height: | Size: 2.9 KiB After Width: | Height: | Size: 2.9 KiB |
|
Before Width: | Height: | Size: 988 B After Width: | Height: | Size: 988 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 223 B After Width: | Height: | Size: 223 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 849 B After Width: | Height: | Size: 849 B |
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
|
Before Width: | Height: | Size: 468 B After Width: | Height: | Size: 468 B |
|
Before Width: | Height: | Size: 985 B After Width: | Height: | Size: 985 B |
|
Before Width: | Height: | Size: 792 B After Width: | Height: | Size: 792 B |
|
Before Width: | Height: | Size: 281 B After Width: | Height: | Size: 281 B |
|
Before Width: | Height: | Size: 5.6 KiB After Width: | Height: | Size: 5.6 KiB |
|
Before Width: | Height: | Size: 13 KiB After Width: | Height: | Size: 13 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 205 B After Width: | Height: | Size: 205 B |
|
Before Width: | Height: | Size: 168 B After Width: | Height: | Size: 168 B |
BIN
Data/Images/missing_texture.png
Normal file
|
After Width: | Height: | Size: 243 B |
|
Before Width: | Height: | Size: 1.6 KiB After Width: | Height: | Size: 1.6 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
|
Before Width: | Height: | Size: 572 B After Width: | Height: | Size: 572 B |
|
Before Width: | Height: | Size: 240 B After Width: | Height: | Size: 240 B |
|
Before Width: | Height: | Size: 626 B After Width: | Height: | Size: 626 B |
|
Before Width: | Height: | Size: 1.4 MiB After Width: | Height: | Size: 1.4 MiB |
|
Before Width: | Height: | Size: 901 B After Width: | Height: | Size: 901 B |
|
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
|
Before Width: | Height: | Size: 1.1 KiB After Width: | Height: | Size: 1.1 KiB |
BIN
Data/Images/splash.png
Normal file
|
After Width: | Height: | Size: 170 KiB |
|
Before Width: | Height: | Size: 546 B After Width: | Height: | Size: 546 B |
|
Before Width: | Height: | Size: 1.2 KiB After Width: | Height: | Size: 1.2 KiB |
28
Data/Shaders/Vulkan/background.comp
Normal file
@@ -0,0 +1,28 @@
|
||||
// HLSL version for Shader Model 6.1
|
||||
RWTexture2D<float4> image : register(u0);
|
||||
|
||||
// Define the size of a thread group
|
||||
[numthreads(16, 16, 1)]
|
||||
void main(
|
||||
uint3 dispatchThreadID : SV_DispatchThreadID,
|
||||
uint3 groupThreadID : SV_GroupThreadID,
|
||||
uint3 groupID : SV_GroupID
|
||||
) {
|
||||
// Get the size of the image
|
||||
uint2 size;
|
||||
image.GetDimensions(size.x, size.y);
|
||||
|
||||
// Current texel coordinates
|
||||
uint2 texelCoord = dispatchThreadID.xy;
|
||||
|
||||
if (texelCoord.x < size.x && texelCoord.y < size.y) {
|
||||
float4 color = float4(0.0, 0.0, 0.0, 1.0);
|
||||
|
||||
if (groupThreadID.x != 0 && groupThreadID.y != 0) {
|
||||
color.x = float(texelCoord.x) / float(size.x);
|
||||
color.y = float(texelCoord.y) / float(size.y);
|
||||
}
|
||||
|
||||
image[texelCoord] = color;
|
||||
}
|
||||
}
|
||||
127
Data/Shaders/Vulkan/blur.frag
Normal file
@@ -0,0 +1,127 @@
|
||||
// Transforms
|
||||
struct ModelData
|
||||
{
|
||||
float4x4 model;
|
||||
};
|
||||
[[vk::binding(0, 0)]]
|
||||
StructuredBuffer<ModelData> model : register(t1);
|
||||
|
||||
// Vertex
|
||||
struct Vertex
|
||||
{
|
||||
float3 position;
|
||||
float uv_x;
|
||||
float3 normal;
|
||||
float uv_y;
|
||||
float3 tangent;
|
||||
float3 bitangent;
|
||||
};
|
||||
|
||||
[[vk::binding(0, 1)]]
|
||||
StructuredBuffer<Vertex> vertexBuffer : register(t2);
|
||||
|
||||
// Samplers
|
||||
[[vk::binding(0, 2)]]
|
||||
SamplerState mySampler : register(s0);
|
||||
|
||||
// Materials
|
||||
struct Material
|
||||
{
|
||||
bool hasAlbedo;
|
||||
float3 albedo;
|
||||
bool hasNormal;
|
||||
bool hasMetalness;
|
||||
bool hasRoughness;
|
||||
bool hasAO;
|
||||
float metalnessValue;
|
||||
float roughnessValue;
|
||||
float aoValue;
|
||||
int albedoTextureId;
|
||||
int normalTextureId;
|
||||
int metalnessTextureId;
|
||||
int roughnessTextureId;
|
||||
int aoTextureId;
|
||||
};
|
||||
[[vk::binding(0, 3)]]
|
||||
StructuredBuffer<Material> material;
|
||||
|
||||
// Textures
|
||||
[[vk::binding(0, 4)]]
|
||||
Texture2D textures[];
|
||||
|
||||
// Lights
|
||||
struct Light
|
||||
{
|
||||
float3 position;
|
||||
int type;
|
||||
float4 color;
|
||||
float3 direction;
|
||||
float outerConeAngle;
|
||||
float innerConeAngle;
|
||||
bool castShadow;
|
||||
int shadowMapTextureId[4];
|
||||
int transformId[4];
|
||||
};
|
||||
|
||||
[[vk::binding(0, 5)]]
|
||||
StructuredBuffer<Light> lights;
|
||||
|
||||
// Cameras
|
||||
struct CameraView {
|
||||
float4x4 View;
|
||||
float4x4 Projection;
|
||||
float4x4 ViewProjection;
|
||||
float4x4 InverseView;
|
||||
float4x4 InverseProjection;
|
||||
float3 Position;
|
||||
float Near;
|
||||
float Far;
|
||||
};
|
||||
[[vk::binding(0, 6)]]
|
||||
StructuredBuffer<CameraView> cameras;
|
||||
|
||||
[[vk::binding(0, 7)]]
|
||||
StructuredBuffer<float3> ssaoKernels;
|
||||
|
||||
struct PSInput {
|
||||
float4 Position : SV_Position;
|
||||
float2 UV : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct PSOutput {
|
||||
float4 oColor0 : SV_TARGET;
|
||||
};
|
||||
|
||||
struct BlurConstant
|
||||
{
|
||||
int blurSourceID;
|
||||
float2 sourceSize;
|
||||
};
|
||||
|
||||
[[vk::push_constant]]
|
||||
BlurConstant pushConstants;
|
||||
|
||||
float3 SampleTexture(int textureId, float2 uv)
|
||||
{
|
||||
return textures[textureId].Sample(mySampler, uv).rgb;
|
||||
}
|
||||
|
||||
PSOutput main(PSInput input)
|
||||
{
|
||||
float2 texelSize = 1.0 / pushConstants.sourceSize;
|
||||
float3 result = 0.0;
|
||||
for (int x = -2; x < 2; x++)
|
||||
{
|
||||
for (int y = -2; y < 2; y++)
|
||||
{
|
||||
float2 offset = float2(x, y) * texelSize;
|
||||
result += SampleTexture(pushConstants.blurSourceID, input.UV + offset);
|
||||
}
|
||||
}
|
||||
|
||||
result = result / (4.0 * 4.0);
|
||||
|
||||
PSOutput output;
|
||||
output.oColor0 = float4(result.rgb, 1.0f);
|
||||
return output;
|
||||
}
|
||||
110
Data/Shaders/Vulkan/blur.vert
Normal file
@@ -0,0 +1,110 @@
|
||||
// Transforms
|
||||
struct ModelData
|
||||
{
|
||||
float4x4 model;
|
||||
};
|
||||
[[vk::binding(0, 0)]]
|
||||
StructuredBuffer<ModelData> model : register(t1);
|
||||
|
||||
// Vertex
|
||||
struct Vertex
|
||||
{
|
||||
float3 position;
|
||||
float uv_x;
|
||||
float3 normal;
|
||||
float uv_y;
|
||||
float3 tangent;
|
||||
float3 bitangent;
|
||||
};
|
||||
|
||||
[[vk::binding(0, 1)]]
|
||||
StructuredBuffer<Vertex> vertexBuffer : register(t2);
|
||||
|
||||
// Samplers
|
||||
[[vk::binding(0, 2)]]
|
||||
SamplerState mySampler : register(s0);
|
||||
|
||||
// Materials
|
||||
struct Material
|
||||
{
|
||||
bool hasAlbedo;
|
||||
float3 albedo;
|
||||
bool hasNormal;
|
||||
bool hasMetalness;
|
||||
bool hasRoughness;
|
||||
bool hasAO;
|
||||
float metalnessValue;
|
||||
float roughnessValue;
|
||||
float aoValue;
|
||||
int albedoTextureId;
|
||||
int normalTextureId;
|
||||
int metalnessTextureId;
|
||||
int roughnessTextureId;
|
||||
int aoTextureId;
|
||||
};
|
||||
[[vk::binding(0, 3)]]
|
||||
StructuredBuffer<Material> material;
|
||||
|
||||
// Textures
|
||||
[[vk::binding(0, 4)]]
|
||||
Texture2D textures[];
|
||||
|
||||
// Lights
|
||||
struct Light
|
||||
{
|
||||
float3 position;
|
||||
int type;
|
||||
float4 color;
|
||||
float3 direction;
|
||||
float outerConeAngle;
|
||||
float innerConeAngle;
|
||||
bool castShadow;
|
||||
int shadowMapTextureId[4];
|
||||
int transformId[4];
|
||||
};
|
||||
|
||||
[[vk::binding(0, 5)]]
|
||||
StructuredBuffer<Light> lights;
|
||||
|
||||
// Cameras
|
||||
struct CameraView {
|
||||
float4x4 View;
|
||||
float4x4 Projection;
|
||||
float4x4 ViewProjection;
|
||||
float4x4 InverseView;
|
||||
float4x4 InverseProjection;
|
||||
float3 Position;
|
||||
float Near;
|
||||
float Far;
|
||||
};
|
||||
[[vk::binding(0, 6)]]
|
||||
StructuredBuffer<CameraView> cameras;
|
||||
|
||||
[[vk::binding(0, 7)]]
|
||||
StructuredBuffer<float3> ssaoKernels;
|
||||
|
||||
struct BlurConstant
|
||||
{
|
||||
int blurSourceID;
|
||||
};
|
||||
|
||||
[[vk::push_constant]]
|
||||
BlurConstant pushConstants;
|
||||
|
||||
// Outputs
|
||||
struct VSOutput {
|
||||
float4 Position : SV_Position;
|
||||
float2 UV : TEXCOORD0;
|
||||
};
|
||||
|
||||
// Main vertex shader
|
||||
VSOutput main(uint vertexIndex : SV_VertexID)
|
||||
{
|
||||
VSOutput output;
|
||||
|
||||
Vertex v = vertexBuffer[vertexIndex];
|
||||
output.UV = float2(v.uv_x, v.uv_y);
|
||||
output.Position = float4(v.position, 1.0f);
|
||||
|
||||
return output;
|
||||
}
|
||||
124
Data/Shaders/Vulkan/copy.frag
Normal file
@@ -0,0 +1,124 @@
|
||||
// Transforms
|
||||
struct ModelData
|
||||
{
|
||||
float4x4 model;
|
||||
};
|
||||
[[vk::binding(0, 0)]]
|
||||
StructuredBuffer<ModelData> model : register(t1);
|
||||
|
||||
// Vertex
|
||||
struct Vertex
|
||||
{
|
||||
float3 position;
|
||||
float uv_x;
|
||||
float3 normal;
|
||||
float uv_y;
|
||||
float3 tangent;
|
||||
float3 bitangent;
|
||||
};
|
||||
|
||||
[[vk::binding(0, 1)]]
|
||||
StructuredBuffer<Vertex> vertexBuffer : register(t2);
|
||||
|
||||
// Samplers
|
||||
[[vk::binding(0, 2)]]
|
||||
SamplerState mySampler : register(s0);
|
||||
|
||||
// Materials
|
||||
struct Material
|
||||
{
|
||||
bool hasAlbedo;
|
||||
float3 albedo;
|
||||
bool hasNormal;
|
||||
bool hasMetalness;
|
||||
bool hasRoughness;
|
||||
bool hasAO;
|
||||
float metalnessValue;
|
||||
float roughnessValue;
|
||||
float aoValue;
|
||||
int albedoTextureId;
|
||||
int normalTextureId;
|
||||
int metalnessTextureId;
|
||||
int roughnessTextureId;
|
||||
int aoTextureId;
|
||||
};
|
||||
[[vk::binding(0, 3)]]
|
||||
StructuredBuffer<Material> material;
|
||||
|
||||
// Textures
|
||||
[[vk::binding(0, 4)]]
|
||||
Texture2D textures[];
|
||||
|
||||
// Lights
|
||||
struct Light
|
||||
{
|
||||
float3 position;
|
||||
int type;
|
||||
float4 color;
|
||||
float3 direction;
|
||||
float outerConeAngle;
|
||||
float innerConeAngle;
|
||||
bool castShadow;
|
||||
int shadowMapTextureId[4];
|
||||
int transformId[4];
|
||||
};
|
||||
|
||||
[[vk::binding(0, 5)]]
|
||||
StructuredBuffer<Light> lights;
|
||||
|
||||
// Cameras
|
||||
struct CameraView {
|
||||
float4x4 View;
|
||||
float4x4 Projection;
|
||||
float4x4 ViewProjection;
|
||||
float4x4 InverseView;
|
||||
float4x4 InverseProjection;
|
||||
float3 Position;
|
||||
float Near;
|
||||
float Far;
|
||||
};
|
||||
[[vk::binding(0, 6)]]
|
||||
StructuredBuffer<CameraView> cameras;
|
||||
|
||||
struct PSInput
|
||||
{
|
||||
float4 Position : SV_Position;
|
||||
float2 UV : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct PSOutput {
|
||||
float4 oColor0 : SV_TARGET;
|
||||
};
|
||||
|
||||
struct CopyPushConstant
|
||||
{
|
||||
int SourceTextureID;
|
||||
int Source2TextureID;
|
||||
int Mode;
|
||||
};
|
||||
|
||||
[[vk::push_constant]]
|
||||
CopyPushConstant pushConstants;
|
||||
|
||||
PSOutput main(PSInput input)
|
||||
{
|
||||
PSOutput output;
|
||||
|
||||
int sourceTextureID = pushConstants.SourceTextureID;
|
||||
int source2TextureID = pushConstants.Source2TextureID;
|
||||
|
||||
float2 uv = input.UV;
|
||||
float4 sampleValue = textures[sourceTextureID].Sample(mySampler, input.UV);
|
||||
float4 sampleValue2 = textures[source2TextureID].Sample(mySampler, input.UV);
|
||||
|
||||
if(pushConstants.Mode == 0)
|
||||
{
|
||||
output.oColor0 = lerp(sampleValue, sampleValue2, 1.0 - sampleValue.a);
|
||||
}
|
||||
else if(pushConstants.Mode == 1)
|
||||
{
|
||||
output.oColor0 = sampleValue;
|
||||
output.oColor0 = sampleValue + sampleValue2;
|
||||
}
|
||||
return output;
|
||||
}
|
||||
110
Data/Shaders/Vulkan/copy.vert
Normal file
@@ -0,0 +1,110 @@
|
||||
// Transforms
|
||||
struct ModelData
|
||||
{
|
||||
float4x4 model;
|
||||
};
|
||||
[[vk::binding(0, 0)]]
|
||||
StructuredBuffer<ModelData> model : register(t1);
|
||||
|
||||
// Vertex
|
||||
struct Vertex
|
||||
{
|
||||
float3 position;
|
||||
float uv_x;
|
||||
float3 normal;
|
||||
float uv_y;
|
||||
float3 tangent;
|
||||
float3 bitangent;
|
||||
};
|
||||
|
||||
[[vk::binding(0, 1)]]
|
||||
StructuredBuffer<Vertex> vertexBuffer : register(t2);
|
||||
|
||||
// Samplers
|
||||
[[vk::binding(0, 2)]]
|
||||
SamplerState mySampler : register(s0);
|
||||
|
||||
// Materials
|
||||
struct Material
|
||||
{
|
||||
bool hasAlbedo;
|
||||
float3 albedo;
|
||||
bool hasNormal;
|
||||
bool hasMetalness;
|
||||
bool hasRoughness;
|
||||
bool hasAO;
|
||||
float metalnessValue;
|
||||
float roughnessValue;
|
||||
float aoValue;
|
||||
int albedoTextureId;
|
||||
int normalTextureId;
|
||||
int metalnessTextureId;
|
||||
int roughnessTextureId;
|
||||
int aoTextureId;
|
||||
};
|
||||
[[vk::binding(0, 3)]]
|
||||
StructuredBuffer<Material> material;
|
||||
|
||||
// Textures
|
||||
[[vk::binding(0, 4)]]
|
||||
Texture2D textures[];
|
||||
|
||||
// Lights
|
||||
struct Light
|
||||
{
|
||||
float3 position;
|
||||
int type;
|
||||
float4 color;
|
||||
float3 direction;
|
||||
float outerConeAngle;
|
||||
float innerConeAngle;
|
||||
bool castShadow;
|
||||
int shadowMapTextureId[4];
|
||||
int transformId[4];
|
||||
};
|
||||
|
||||
[[vk::binding(0, 5)]]
|
||||
StructuredBuffer<Light> lights;
|
||||
|
||||
// Cameras
|
||||
struct CameraView {
|
||||
float4x4 View;
|
||||
float4x4 Projection;
|
||||
float4x4 ViewProjection;
|
||||
float4x4 InverseView;
|
||||
float4x4 InverseProjection;
|
||||
float3 Position;
|
||||
float Near;
|
||||
float Far;
|
||||
};
|
||||
[[vk::binding(0, 6)]]
|
||||
StructuredBuffer<CameraView> cameras;
|
||||
|
||||
struct CopyPushConstant
|
||||
{
|
||||
int SourceTextureID;
|
||||
int Source2TextureID;
|
||||
int Mode;
|
||||
};
|
||||
|
||||
[[vk::push_constant]]
|
||||
CopyPushConstant pushConstants;
|
||||
|
||||
// Outputs
|
||||
struct VSOutput
|
||||
{
|
||||
float4 Position : SV_Position;
|
||||
float2 UV : TEXCOORD0;
|
||||
};
|
||||
|
||||
// Main vertex shader
|
||||
VSOutput main(uint vertexIndex : SV_VertexID)
|
||||
{
|
||||
VSOutput output;
|
||||
|
||||
Vertex v = vertexBuffer[vertexIndex];
|
||||
output.UV = float2(v.uv_x, v.uv_y);
|
||||
output.Position = float4(v.position, 1.0f);
|
||||
|
||||
return output;
|
||||
}
|
||||
160
Data/Shaders/Vulkan/depth_aware_blur.frag
Normal file
@@ -0,0 +1,160 @@
|
||||
// Transforms
|
||||
struct ModelData
|
||||
{
|
||||
float4x4 model;
|
||||
};
|
||||
[[vk::binding(0, 0)]]
|
||||
StructuredBuffer<ModelData> model : register(t1);
|
||||
|
||||
// Vertex
|
||||
struct Vertex
|
||||
{
|
||||
float3 position;
|
||||
float uv_x;
|
||||
float3 normal;
|
||||
float uv_y;
|
||||
float3 tangent;
|
||||
float3 bitangent;
|
||||
};
|
||||
|
||||
[[vk::binding(0, 1)]]
|
||||
StructuredBuffer<Vertex> vertexBuffer : register(t2);
|
||||
|
||||
// Samplers
|
||||
[[vk::binding(0, 2)]]
|
||||
SamplerState mySampler : register(s0);
|
||||
|
||||
// Materials
|
||||
struct Material
|
||||
{
|
||||
bool hasAlbedo;
|
||||
float3 albedo;
|
||||
bool hasNormal;
|
||||
bool hasMetalness;
|
||||
bool hasRoughness;
|
||||
bool hasAO;
|
||||
float metalnessValue;
|
||||
float roughnessValue;
|
||||
float aoValue;
|
||||
int albedoTextureId;
|
||||
int normalTextureId;
|
||||
int metalnessTextureId;
|
||||
int roughnessTextureId;
|
||||
int aoTextureId;
|
||||
};
|
||||
[[vk::binding(0, 3)]]
|
||||
StructuredBuffer<Material> material;
|
||||
|
||||
// Textures
|
||||
[[vk::binding(0, 4)]]
|
||||
Texture2D textures[];
|
||||
|
||||
// Lights
|
||||
struct Light
|
||||
{
|
||||
float3 position;
|
||||
int type;
|
||||
float4 color;
|
||||
float3 direction;
|
||||
float outerConeAngle;
|
||||
float innerConeAngle;
|
||||
bool castShadow;
|
||||
int shadowMapTextureId[4];
|
||||
int transformId[4];
|
||||
};
|
||||
|
||||
[[vk::binding(0, 5)]]
|
||||
StructuredBuffer<Light> lights;
|
||||
|
||||
// Cameras
|
||||
struct CameraView {
|
||||
float4x4 View;
|
||||
float4x4 Projection;
|
||||
float4x4 ViewProjection;
|
||||
float4x4 InverseView;
|
||||
float4x4 InverseProjection;
|
||||
float3 Position;
|
||||
float Near;
|
||||
float Far;
|
||||
};
|
||||
[[vk::binding(0, 6)]]
|
||||
StructuredBuffer<CameraView> cameras;
|
||||
|
||||
struct PSInput
|
||||
{
|
||||
float4 Position : SV_Position;
|
||||
float2 UV : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct PSOutput {
|
||||
float4 oColor0 : SV_TARGET;
|
||||
};
|
||||
|
||||
struct DepthAwareBlurConstant
|
||||
{
|
||||
int DepthTextureID;
|
||||
int VolumetricTextureID;
|
||||
};
|
||||
|
||||
[[vk::push_constant]]
|
||||
DepthAwareBlurConstant pushConstants;
|
||||
|
||||
float2 GetTextureSize(Texture2D tex)
|
||||
{
|
||||
uint width, height;
|
||||
tex.GetDimensions(width, height);
|
||||
return float2(width, height);
|
||||
}
|
||||
|
||||
float PixelToUV(float2 uv, Texture2D tex)
|
||||
{
|
||||
float2 texSize = GetTextureSize(tex);
|
||||
return uv / texSize;
|
||||
}
|
||||
|
||||
PSOutput main(PSInput input)
|
||||
{
|
||||
int depthTexture = pushConstants.DepthTextureID;
|
||||
float upSampledDepth = textures[depthTexture].Sample(mySampler, input.UV).r;
|
||||
float3 upSampledColor = textures[pushConstants.VolumetricTextureID].Sample(mySampler, input.UV).rgb;
|
||||
float3 color = 0.0f.xxx;
|
||||
float totalWeight = 0.0f;
|
||||
|
||||
int2 screenCoordinates = int2(input.Position.xy);
|
||||
int xOffset = (screenCoordinates.x % 2 == 0) ? -1 : 1;
|
||||
int yOffset = (screenCoordinates.y % 2 == 0) ? -1 : 1;
|
||||
|
||||
int2 offsets[] = {int2(0, 0),
|
||||
int2(0, yOffset),
|
||||
int2(xOffset, 0),
|
||||
int2(xOffset, yOffset)};
|
||||
|
||||
for (int i = 0; i < 4; i ++)
|
||||
{
|
||||
float2 uvOffset = float2(offsets[i].x * 4.0, offsets[i].y * 4.0) ;
|
||||
uvOffset = PixelToUV(uvOffset, textures[pushConstants.DepthTextureID]);
|
||||
float3 downscaledColor = textures[pushConstants.VolumetricTextureID].Sample(mySampler, input.UV + uvOffset).rgb;
|
||||
float downscaledDepth = textures[pushConstants.DepthTextureID].Sample(mySampler, input.UV + uvOffset).r;
|
||||
|
||||
float currentWeight = 1.0f;
|
||||
|
||||
if(abs(upSampledDepth - downscaledDepth) > 0.0001)
|
||||
{
|
||||
//color = float3(1, 0, 0);
|
||||
currentWeight *= 0.0f;
|
||||
}
|
||||
//currentWeight *= max(0.0f, 1.0f - abs(upSampledDepth - downscaledDepth));
|
||||
|
||||
color += downscaledColor * currentWeight;
|
||||
totalWeight += currentWeight;
|
||||
}
|
||||
|
||||
float3 volumetricLight;
|
||||
const float epsilon = 0.0001f;
|
||||
volumetricLight.xyz = color / (totalWeight + epsilon);
|
||||
|
||||
PSOutput output;
|
||||
output.oColor0 = float4(volumetricLight.x, volumetricLight.y, volumetricLight.z, 1.0f);
|
||||
//output.oColor0 = float4(upSampledColor.x, upSampledColor.y, upSampledColor.z, 1.0f);
|
||||
return output;
|
||||
}
|
||||
109
Data/Shaders/Vulkan/depth_aware_blur.vert
Normal file
@@ -0,0 +1,109 @@
|
||||
// Transforms
|
||||
struct ModelData
|
||||
{
|
||||
float4x4 model;
|
||||
};
|
||||
[[vk::binding(0, 0)]]
|
||||
StructuredBuffer<ModelData> model : register(t1);
|
||||
|
||||
// Vertex
|
||||
struct Vertex
|
||||
{
|
||||
float3 position;
|
||||
float uv_x;
|
||||
float3 normal;
|
||||
float uv_y;
|
||||
float3 tangent;
|
||||
float3 bitangent;
|
||||
};
|
||||
|
||||
[[vk::binding(0, 1)]]
|
||||
StructuredBuffer<Vertex> vertexBuffer : register(t2);
|
||||
|
||||
// Samplers
|
||||
[[vk::binding(0, 2)]]
|
||||
SamplerState mySampler : register(s0);
|
||||
|
||||
// Materials
|
||||
struct Material
|
||||
{
|
||||
bool hasAlbedo;
|
||||
float3 albedo;
|
||||
bool hasNormal;
|
||||
bool hasMetalness;
|
||||
bool hasRoughness;
|
||||
bool hasAO;
|
||||
float metalnessValue;
|
||||
float roughnessValue;
|
||||
float aoValue;
|
||||
int albedoTextureId;
|
||||
int normalTextureId;
|
||||
int metalnessTextureId;
|
||||
int roughnessTextureId;
|
||||
int aoTextureId;
|
||||
};
|
||||
[[vk::binding(0, 3)]]
|
||||
StructuredBuffer<Material> material;
|
||||
|
||||
// Textures
|
||||
[[vk::binding(0, 4)]]
|
||||
Texture2D textures[];
|
||||
|
||||
// Lights
|
||||
struct Light
|
||||
{
|
||||
float3 position;
|
||||
int type;
|
||||
float4 color;
|
||||
float3 direction;
|
||||
float outerConeAngle;
|
||||
float innerConeAngle;
|
||||
bool castShadow;
|
||||
int shadowMapTextureId[4];
|
||||
int transformId[4];
|
||||
};
|
||||
|
||||
[[vk::binding(0, 5)]]
|
||||
StructuredBuffer<Light> lights;
|
||||
|
||||
// Cameras
|
||||
struct CameraView {
|
||||
float4x4 View;
|
||||
float4x4 Projection;
|
||||
float4x4 ViewProjection;
|
||||
float4x4 InverseView;
|
||||
float4x4 InverseProjection;
|
||||
float3 Position;
|
||||
float Near;
|
||||
float Far;
|
||||
};
|
||||
[[vk::binding(0, 6)]]
|
||||
StructuredBuffer<CameraView> cameras;
|
||||
|
||||
struct DepthAwareBlurConstant
|
||||
{
|
||||
int DepthTextureID;
|
||||
int VolumetricTextureID;
|
||||
};
|
||||
|
||||
[[vk::push_constant]]
|
||||
DepthAwareBlurConstant pushConstants;
|
||||
|
||||
// Outputs
|
||||
struct VSOutput
|
||||
{
|
||||
float4 Position : SV_Position;
|
||||
float2 UV : TEXCOORD0;
|
||||
};
|
||||
|
||||
// Main vertex shader
|
||||
VSOutput main(uint vertexIndex : SV_VertexID)
|
||||
{
|
||||
VSOutput output;
|
||||
|
||||
Vertex v = vertexBuffer[vertexIndex];
|
||||
output.UV = float2(v.uv_x, v.uv_y);
|
||||
output.Position = float4(v.position, 1.0f);
|
||||
|
||||
return output;
|
||||
}
|
||||
146
Data/Shaders/Vulkan/gizmo.frag
Normal file
@@ -0,0 +1,146 @@
|
||||
// Transforms
|
||||
struct ModelData
|
||||
{
|
||||
float4x4 model;
|
||||
};
|
||||
[[vk::binding(0, 0)]]
|
||||
StructuredBuffer<ModelData> model : register(t1);
|
||||
|
||||
// Vertex
|
||||
struct Vertex
|
||||
{
|
||||
float3 position;
|
||||
float uv_x;
|
||||
float3 normal;
|
||||
float uv_y;
|
||||
float3 tangent;
|
||||
float3 bitangent;
|
||||
};
|
||||
|
||||
[[vk::binding(0, 1)]]
|
||||
StructuredBuffer<Vertex> vertexBuffer : register(t2);
|
||||
|
||||
// Samplers
|
||||
[[vk::binding(0, 2)]]
|
||||
SamplerState mySampler : register(s0);
|
||||
|
||||
// Materials
|
||||
struct Material
|
||||
{
|
||||
bool hasAlbedo;
|
||||
float3 albedo;
|
||||
bool hasNormal;
|
||||
bool hasMetalness;
|
||||
bool hasRoughness;
|
||||
bool hasAO;
|
||||
float metalnessValue;
|
||||
float roughnessValue;
|
||||
float aoValue;
|
||||
int albedoTextureId;
|
||||
int normalTextureId;
|
||||
int metalnessTextureId;
|
||||
int roughnessTextureId;
|
||||
int aoTextureId;
|
||||
};
|
||||
[[vk::binding(0, 3)]]
|
||||
StructuredBuffer<Material> material;
|
||||
|
||||
// Textures
|
||||
[[vk::binding(0, 4)]]
|
||||
Texture2D textures[];
|
||||
|
||||
// Lights
|
||||
struct Light
|
||||
{
|
||||
float3 position;
|
||||
int type;
|
||||
float4 color;
|
||||
float3 direction;
|
||||
float outerConeAngle;
|
||||
float innerConeAngle;
|
||||
bool castShadow;
|
||||
int shadowMapTextureId[4];
|
||||
int transformId[4];
|
||||
};
|
||||
|
||||
[[vk::binding(0, 5)]]
|
||||
StructuredBuffer<Light> lights;
|
||||
|
||||
// Cameras
|
||||
struct CameraView {
|
||||
float4x4 View;
|
||||
float4x4 Projection;
|
||||
float4x4 ViewProjection;
|
||||
float4x4 InverseView;
|
||||
float4x4 InverseProjection;
|
||||
float3 Position;
|
||||
float Near;
|
||||
float Far;
|
||||
};
|
||||
[[vk::binding(0, 6)]]
|
||||
StructuredBuffer<CameraView> cameras;
|
||||
|
||||
struct PSInput
|
||||
{
|
||||
float4 Position : SV_Position;
|
||||
float2 UV : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct PSOutput
|
||||
{
|
||||
float4 oColor0 : SV_TARGET;
|
||||
float4 oEntityID : SV_TARGET1;
|
||||
};
|
||||
|
||||
struct DebugConstant
|
||||
{
|
||||
float4 Color;
|
||||
float4x4 Transform;
|
||||
int TextureID;
|
||||
float EntityID;
|
||||
};
|
||||
|
||||
[[vk::push_constant]]
|
||||
DebugConstant pushConstants;
|
||||
|
||||
PSOutput main(PSInput input)
|
||||
{
|
||||
PSOutput output;
|
||||
|
||||
if(pushConstants.TextureID < 0)
|
||||
{
|
||||
output.oColor0 = float4(input.UV.x, input.UV.y, 0, 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
float2 uv = input.UV;
|
||||
float4 textureSample = textures[pushConstants.TextureID].Sample(mySampler, uv);
|
||||
|
||||
// Alpha scisorring
|
||||
if(textureSample.a < 0.1)
|
||||
{
|
||||
//discard;
|
||||
}
|
||||
|
||||
output.oColor0 = textureSample * pushConstants.Color;
|
||||
|
||||
if(pushConstants.EntityID != 0.0f)
|
||||
{
|
||||
float2 center = float2(0.5, 0.5);
|
||||
float dist = distance(uv, center);
|
||||
float radius = 0.5; // You can adjust this as needed
|
||||
|
||||
if (dist <= radius)
|
||||
{
|
||||
output.oEntityID = float4(pushConstants.EntityID, 0, 0, 1.0f);
|
||||
}
|
||||
else
|
||||
{
|
||||
output.oEntityID = float4(0, 0, 0, 0); // Or leave it unassigned if default is zero
|
||||
discard;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return output;
|
||||
}
|
||||
111
Data/Shaders/Vulkan/gizmo.vert
Normal file
@@ -0,0 +1,111 @@
|
||||
// Transforms
|
||||
struct ModelData
|
||||
{
|
||||
float4x4 model;
|
||||
};
|
||||
[[vk::binding(0, 0)]]
|
||||
StructuredBuffer<ModelData> model : register(t1);
|
||||
|
||||
// Vertex
|
||||
struct Vertex
|
||||
{
|
||||
float3 position;
|
||||
float uv_x;
|
||||
float3 normal;
|
||||
float uv_y;
|
||||
float3 tangent;
|
||||
float3 bitangent;
|
||||
};
|
||||
|
||||
[[vk::binding(0, 1)]]
|
||||
StructuredBuffer<Vertex> vertexBuffer : register(t2);
|
||||
|
||||
// Samplers
|
||||
[[vk::binding(0, 2)]]
|
||||
SamplerState mySampler : register(s0);
|
||||
|
||||
// Materials
|
||||
struct Material
|
||||
{
|
||||
bool hasAlbedo;
|
||||
float3 albedo;
|
||||
bool hasNormal;
|
||||
bool hasMetalness;
|
||||
bool hasRoughness;
|
||||
bool hasAO;
|
||||
float metalnessValue;
|
||||
float roughnessValue;
|
||||
float aoValue;
|
||||
int albedoTextureId;
|
||||
int normalTextureId;
|
||||
int metalnessTextureId;
|
||||
int roughnessTextureId;
|
||||
int aoTextureId;
|
||||
};
|
||||
[[vk::binding(0, 3)]]
|
||||
StructuredBuffer<Material> material;
|
||||
|
||||
// Textures
|
||||
[[vk::binding(0, 4)]]
|
||||
Texture2D textures[];
|
||||
|
||||
// Lights
|
||||
struct Light
|
||||
{
|
||||
float3 position;
|
||||
int type;
|
||||
float4 color;
|
||||
float3 direction;
|
||||
float outerConeAngle;
|
||||
float innerConeAngle;
|
||||
bool castShadow;
|
||||
int shadowMapTextureId[4];
|
||||
int transformId[4];
|
||||
};
|
||||
|
||||
[[vk::binding(0, 5)]]
|
||||
StructuredBuffer<Light> lights;
|
||||
|
||||
// Cameras
|
||||
struct CameraView {
|
||||
float4x4 View;
|
||||
float4x4 Projection;
|
||||
float4x4 ViewProjection;
|
||||
float4x4 InverseView;
|
||||
float4x4 InverseProjection;
|
||||
float3 Position;
|
||||
float Near;
|
||||
float Far;
|
||||
};
|
||||
[[vk::binding(0, 6)]]
|
||||
StructuredBuffer<CameraView> cameras;
|
||||
|
||||
struct DebugConstant
|
||||
{
|
||||
float4 Color;
|
||||
float4x4 Transform;
|
||||
int TextureID;
|
||||
float EntityID;
|
||||
};
|
||||
|
||||
[[vk::push_constant]]
|
||||
DebugConstant pushConstants;
|
||||
|
||||
// Outputs
|
||||
struct VSOutput
|
||||
{
|
||||
float4 Position : SV_Position;
|
||||
float2 UV : TEXCOORD0;
|
||||
};
|
||||
|
||||
// Main vertex shader
|
||||
VSOutput main(uint vertexIndex : SV_VertexID)
|
||||
{
|
||||
VSOutput output;
|
||||
|
||||
Vertex v = vertexBuffer[vertexIndex];
|
||||
output.UV = float2(v.uv_x, v.uv_y);
|
||||
output.Position = mul(pushConstants.Transform, float4(v.position, 1.0f));
|
||||
|
||||
return output;
|
||||
}
|
||||
110
Data/Shaders/Vulkan/line.frag
Normal file
@@ -0,0 +1,110 @@
|
||||
// Transforms
|
||||
struct ModelData
|
||||
{
|
||||
float4x4 model;
|
||||
};
|
||||
[[vk::binding(0, 0)]]
|
||||
StructuredBuffer<ModelData> model : register(t1);
|
||||
|
||||
// Vertex
|
||||
struct Vertex
|
||||
{
|
||||
float3 position;
|
||||
float uv_x;
|
||||
float3 normal;
|
||||
float uv_y;
|
||||
float3 tangent;
|
||||
float3 bitangent;
|
||||
};
|
||||
|
||||
[[vk::binding(0, 1)]]
|
||||
StructuredBuffer<Vertex> vertexBuffer : register(t2);
|
||||
|
||||
// Samplers
|
||||
[[vk::binding(0, 2)]]
|
||||
SamplerState mySampler : register(s0);
|
||||
|
||||
// Materials
|
||||
struct Material
|
||||
{
|
||||
bool hasAlbedo;
|
||||
float3 albedo;
|
||||
bool hasNormal;
|
||||
bool hasMetalness;
|
||||
bool hasRoughness;
|
||||
bool hasAO;
|
||||
float metalnessValue;
|
||||
float roughnessValue;
|
||||
float aoValue;
|
||||
int albedoTextureId;
|
||||
int normalTextureId;
|
||||
int metalnessTextureId;
|
||||
int roughnessTextureId;
|
||||
int aoTextureId;
|
||||
};
|
||||
[[vk::binding(0, 3)]]
|
||||
StructuredBuffer<Material> material;
|
||||
|
||||
// Textures
|
||||
[[vk::binding(0, 4)]]
|
||||
Texture2D textures[];
|
||||
|
||||
// Lights
|
||||
struct Light
|
||||
{
|
||||
float3 position;
|
||||
int type;
|
||||
float4 color;
|
||||
float3 direction;
|
||||
float outerConeAngle;
|
||||
float innerConeAngle;
|
||||
bool castShadow;
|
||||
int shadowMapTextureId[4];
|
||||
int transformId[4];
|
||||
};
|
||||
|
||||
[[vk::binding(0, 5)]]
|
||||
StructuredBuffer<Light> lights;
|
||||
|
||||
// Cameras
|
||||
struct CameraView {
|
||||
float4x4 View;
|
||||
float4x4 Projection;
|
||||
float4x4 ViewProjection;
|
||||
float4x4 InverseView;
|
||||
float4x4 InverseProjection;
|
||||
float3 Position;
|
||||
float Near;
|
||||
float Far;
|
||||
};
|
||||
[[vk::binding(0, 6)]]
|
||||
StructuredBuffer<CameraView> cameras;
|
||||
|
||||
struct PSInput
|
||||
{
|
||||
float4 Position : SV_Position;
|
||||
float2 UV : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct PSOutput
|
||||
{
|
||||
float4 oColor0 : SV_TARGET;
|
||||
};
|
||||
|
||||
struct LineConstant
|
||||
{
|
||||
float4x4 Transform;
|
||||
float4 Color;
|
||||
};
|
||||
|
||||
[[vk::push_constant]]
|
||||
LineConstant pushConstants;
|
||||
|
||||
PSOutput main(PSInput input)
|
||||
{
|
||||
PSOutput output;
|
||||
|
||||
output.oColor0 = pushConstants.Color;
|
||||
|
||||
return output;
|
||||
}
|
||||
109
Data/Shaders/Vulkan/line.vert
Normal file
@@ -0,0 +1,109 @@
|
||||
// Transforms
|
||||
struct ModelData
|
||||
{
|
||||
float4x4 model;
|
||||
};
|
||||
[[vk::binding(0, 0)]]
|
||||
StructuredBuffer<ModelData> model : register(t1);
|
||||
|
||||
// Vertex
|
||||
struct Vertex
|
||||
{
|
||||
float3 position;
|
||||
float uv_x;
|
||||
float3 normal;
|
||||
float uv_y;
|
||||
float3 tangent;
|
||||
float3 bitangent;
|
||||
};
|
||||
|
||||
[[vk::binding(0, 1)]]
|
||||
StructuredBuffer<Vertex> vertexBuffer : register(t2);
|
||||
|
||||
// Samplers
|
||||
[[vk::binding(0, 2)]]
|
||||
SamplerState mySampler : register(s0);
|
||||
|
||||
// Materials
|
||||
struct Material
|
||||
{
|
||||
bool hasAlbedo;
|
||||
float3 albedo;
|
||||
bool hasNormal;
|
||||
bool hasMetalness;
|
||||
bool hasRoughness;
|
||||
bool hasAO;
|
||||
float metalnessValue;
|
||||
float roughnessValue;
|
||||
float aoValue;
|
||||
int albedoTextureId;
|
||||
int normalTextureId;
|
||||
int metalnessTextureId;
|
||||
int roughnessTextureId;
|
||||
int aoTextureId;
|
||||
};
|
||||
[[vk::binding(0, 3)]]
|
||||
StructuredBuffer<Material> material;
|
||||
|
||||
// Textures
|
||||
[[vk::binding(0, 4)]]
|
||||
Texture2D textures[];
|
||||
|
||||
// Lights
|
||||
struct Light
|
||||
{
|
||||
float3 position;
|
||||
int type;
|
||||
float4 color;
|
||||
float3 direction;
|
||||
float outerConeAngle;
|
||||
float innerConeAngle;
|
||||
bool castShadow;
|
||||
int shadowMapTextureId[4];
|
||||
int transformId[4];
|
||||
};
|
||||
|
||||
[[vk::binding(0, 5)]]
|
||||
StructuredBuffer<Light> lights;
|
||||
|
||||
// Cameras
|
||||
struct CameraView {
|
||||
float4x4 View;
|
||||
float4x4 Projection;
|
||||
float4x4 ViewProjection;
|
||||
float4x4 InverseView;
|
||||
float4x4 InverseProjection;
|
||||
float3 Position;
|
||||
float Near;
|
||||
float Far;
|
||||
};
|
||||
[[vk::binding(0, 6)]]
|
||||
StructuredBuffer<CameraView> cameras;
|
||||
|
||||
struct LineConstant
|
||||
{
|
||||
float4x4 Transform;
|
||||
float4 Color;
|
||||
};
|
||||
|
||||
[[vk::push_constant]]
|
||||
LineConstant pushConstants;
|
||||
|
||||
// Outputs
|
||||
struct VSOutput
|
||||
{
|
||||
float4 Position : SV_Position;
|
||||
float2 UV : TEXCOORD0;
|
||||
};
|
||||
|
||||
// Main vertex shader
|
||||
VSOutput main(uint vertexIndex : SV_VertexID)
|
||||
{
|
||||
VSOutput output;
|
||||
|
||||
Vertex v = vertexBuffer[vertexIndex];
|
||||
output.UV = float2(v.uv_x, v.uv_y);
|
||||
output.Position = mul(pushConstants.Transform, float4(v.position, 1.0f));
|
||||
|
||||
return output;
|
||||
}
|
||||
186
Data/Shaders/Vulkan/outline.frag
Normal file
@@ -0,0 +1,186 @@
|
||||
// Transforms
|
||||
struct ModelData
|
||||
{
|
||||
float4x4 model;
|
||||
};
|
||||
[[vk::binding(0, 0)]]
|
||||
StructuredBuffer<ModelData> model : register(t1);
|
||||
|
||||
// Vertex
|
||||
struct Vertex
|
||||
{
|
||||
float3 position;
|
||||
float uv_x;
|
||||
float3 normal;
|
||||
float uv_y;
|
||||
float3 tangent;
|
||||
float3 bitangent;
|
||||
};
|
||||
|
||||
[[vk::binding(0, 1)]]
|
||||
StructuredBuffer<Vertex> vertexBuffer : register(t2);
|
||||
|
||||
// Samplers
|
||||
[[vk::binding(0, 2)]]
|
||||
SamplerState mySampler : register(s0);
|
||||
|
||||
// Materials
|
||||
struct Material
|
||||
{
|
||||
bool hasAlbedo;
|
||||
float3 albedo;
|
||||
bool hasNormal;
|
||||
bool hasMetalness;
|
||||
bool hasRoughness;
|
||||
bool hasAO;
|
||||
float metalnessValue;
|
||||
float roughnessValue;
|
||||
float aoValue;
|
||||
int albedoTextureId;
|
||||
int normalTextureId;
|
||||
int metalnessTextureId;
|
||||
int roughnessTextureId;
|
||||
int aoTextureId;
|
||||
};
|
||||
[[vk::binding(0, 3)]]
|
||||
StructuredBuffer<Material> material;
|
||||
|
||||
// Textures
|
||||
[[vk::binding(0, 4)]]
|
||||
Texture2D textures[];
|
||||
|
||||
// Lights
|
||||
struct Light
|
||||
{
|
||||
float3 position;
|
||||
int type;
|
||||
float4 color;
|
||||
float3 direction;
|
||||
float outerConeAngle;
|
||||
float innerConeAngle;
|
||||
bool castShadow;
|
||||
int shadowMapTextureId[4];
|
||||
int transformId[4];
|
||||
};
|
||||
|
||||
[[vk::binding(0, 5)]]
|
||||
StructuredBuffer<Light> lights;
|
||||
|
||||
// Cameras
|
||||
struct CameraView {
|
||||
float4x4 View;
|
||||
float4x4 Projection;
|
||||
float4x4 ViewProjection;
|
||||
float4x4 InverseView;
|
||||
float4x4 InverseProjection;
|
||||
float3 Position;
|
||||
float Near;
|
||||
float Far;
|
||||
};
|
||||
[[vk::binding(0, 6)]]
|
||||
StructuredBuffer<CameraView> cameras;
|
||||
|
||||
struct PSInput
|
||||
{
|
||||
float4 Position : SV_Position;
|
||||
float2 UV : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct PSOutput {
|
||||
float4 oColor0 : SV_TARGET;
|
||||
};
|
||||
|
||||
struct OutlinePushConstant
|
||||
{
|
||||
float4 Color;
|
||||
float Thickness;
|
||||
int SourceTextureID;
|
||||
int EntityIDTextureID;
|
||||
int DepthTextureID;
|
||||
float SelectedEntity;
|
||||
};
|
||||
|
||||
[[vk::push_constant]]
|
||||
OutlinePushConstant pushConstants;
|
||||
|
||||
float2 GetTexelSize(Texture2D tex)
|
||||
{
|
||||
uint width, height;
|
||||
tex.GetDimensions(width, height);
|
||||
return 1.0 / float2(width, height);
|
||||
}
|
||||
|
||||
float LinearizeDepth(float depth, float nearPlane, float farPlane)
|
||||
{
|
||||
return (2.0 * nearPlane) / (farPlane + nearPlane - (1.0 - depth) * (farPlane - nearPlane));
|
||||
}
|
||||
|
||||
PSOutput main(PSInput input)
|
||||
{
|
||||
PSOutput output;
|
||||
|
||||
float4 outlineColor = pushConstants.Color;
|
||||
float target = pushConstants.SelectedEntity;
|
||||
float radius = pushConstants.Thickness;
|
||||
float2 uv = input.UV;
|
||||
|
||||
int entityIDTextureID = pushConstants.EntityIDTextureID;
|
||||
float hasHit = 0.0f;
|
||||
|
||||
float sampleValue = textures[entityIDTextureID].Sample(mySampler, uv).r;
|
||||
float depth = textures[pushConstants.DepthTextureID].Sample(mySampler, uv).r;
|
||||
|
||||
float4 fragColor = float4(0, 0, 0, 0);
|
||||
const float TAU = 6.28318530;
|
||||
const float steps = 64.0;
|
||||
for(float i = 0.0f; i < TAU; i += TAU / steps)
|
||||
{
|
||||
float2 uvOffset = float2(cos(i), sin(i)) * (GetTexelSize(textures[entityIDTextureID])) * radius;
|
||||
|
||||
float2 sampleUV = uv + uvOffset;
|
||||
sampleUV.x = clamp(sampleUV.x, 0.0, 0.999);
|
||||
sampleUV.y = clamp(sampleUV.y, 0.0, 0.999);
|
||||
|
||||
float sample = textures[entityIDTextureID].Sample(mySampler, sampleUV).r;
|
||||
float sampleDepth = textures[pushConstants.DepthTextureID].Sample(mySampler, sampleUV).r;
|
||||
|
||||
//sampleDepth = LinearizeDepth(sampleDepth, 0.1f, 200.0f);
|
||||
//depth = LinearizeDepth(depth, 0.1f, 200.0f);
|
||||
bool passDepthTest = (sampleDepth > depth);
|
||||
if(sample == target && passDepthTest)
|
||||
{
|
||||
hasHit = 1.0f;
|
||||
if(passDepthTest && sampleValue == target)
|
||||
{
|
||||
//hasHit = 0.0f;
|
||||
}
|
||||
}
|
||||
|
||||
float alpha = smoothstep(0.1, 0.9, hasHit);
|
||||
float4 outputColor = float4(
|
||||
lerp(fragColor.r, outlineColor.r, alpha),
|
||||
lerp(fragColor.g, outlineColor.g, alpha),
|
||||
lerp(fragColor.b, outlineColor.b, alpha),
|
||||
lerp(fragColor.a, outlineColor.a, alpha)
|
||||
);
|
||||
|
||||
fragColor = outputColor;
|
||||
}
|
||||
|
||||
if(fragColor.a > 0.1)
|
||||
{
|
||||
fragColor.a = 1.0f;
|
||||
}
|
||||
|
||||
float3 sourceTexture = textures[pushConstants.SourceTextureID].Sample(mySampler, uv).rgb;
|
||||
float ratio = float(sampleValue != target && hasHit > 0.0f);
|
||||
float4 finalColor = float4(
|
||||
lerp(sourceTexture.r, fragColor.r, ratio),
|
||||
lerp(sourceTexture.g, fragColor.g, ratio),
|
||||
lerp(sourceTexture.b, fragColor.b, ratio),
|
||||
lerp(1.0f, fragColor.a, ratio)
|
||||
);
|
||||
|
||||
output.oColor0 = finalColor;
|
||||
return output;
|
||||
}
|
||||
113
Data/Shaders/Vulkan/outline.vert
Normal file
@@ -0,0 +1,113 @@
|
||||
// Transforms
|
||||
struct ModelData
|
||||
{
|
||||
float4x4 model;
|
||||
};
|
||||
[[vk::binding(0, 0)]]
|
||||
StructuredBuffer<ModelData> model : register(t1);
|
||||
|
||||
// Vertex
|
||||
struct Vertex
|
||||
{
|
||||
float3 position;
|
||||
float uv_x;
|
||||
float3 normal;
|
||||
float uv_y;
|
||||
float3 tangent;
|
||||
float3 bitangent;
|
||||
};
|
||||
|
||||
[[vk::binding(0, 1)]]
|
||||
StructuredBuffer<Vertex> vertexBuffer : register(t2);
|
||||
|
||||
// Samplers
|
||||
[[vk::binding(0, 2)]]
|
||||
SamplerState mySampler : register(s0);
|
||||
|
||||
// Materials
|
||||
struct Material
|
||||
{
|
||||
bool hasAlbedo;
|
||||
float3 albedo;
|
||||
bool hasNormal;
|
||||
bool hasMetalness;
|
||||
bool hasRoughness;
|
||||
bool hasAO;
|
||||
float metalnessValue;
|
||||
float roughnessValue;
|
||||
float aoValue;
|
||||
int albedoTextureId;
|
||||
int normalTextureId;
|
||||
int metalnessTextureId;
|
||||
int roughnessTextureId;
|
||||
int aoTextureId;
|
||||
};
|
||||
[[vk::binding(0, 3)]]
|
||||
StructuredBuffer<Material> material;
|
||||
|
||||
// Textures
|
||||
[[vk::binding(0, 4)]]
|
||||
Texture2D textures[];
|
||||
|
||||
// Lights
|
||||
struct Light
|
||||
{
|
||||
float3 position;
|
||||
int type;
|
||||
float4 color;
|
||||
float3 direction;
|
||||
float outerConeAngle;
|
||||
float innerConeAngle;
|
||||
bool castShadow;
|
||||
int shadowMapTextureId[4];
|
||||
int transformId[4];
|
||||
};
|
||||
|
||||
[[vk::binding(0, 5)]]
|
||||
StructuredBuffer<Light> lights;
|
||||
|
||||
// Cameras
|
||||
struct CameraView {
|
||||
float4x4 View;
|
||||
float4x4 Projection;
|
||||
float4x4 ViewProjection;
|
||||
float4x4 InverseView;
|
||||
float4x4 InverseProjection;
|
||||
float3 Position;
|
||||
float Near;
|
||||
float Far;
|
||||
};
|
||||
[[vk::binding(0, 6)]]
|
||||
StructuredBuffer<CameraView> cameras;
|
||||
|
||||
struct OutlinePushConstant
|
||||
{
|
||||
float4 Color;
|
||||
float Thickness;
|
||||
int SourceTextureID;
|
||||
int EntityIDTextureID;
|
||||
int DepthTextureID;
|
||||
float SelectedEntity;
|
||||
};
|
||||
|
||||
[[vk::push_constant]]
|
||||
OutlinePushConstant pushConstants;
|
||||
|
||||
// Outputs
|
||||
struct VSOutput
|
||||
{
|
||||
float4 Position : SV_Position;
|
||||
float2 UV : TEXCOORD0;
|
||||
};
|
||||
|
||||
// Main vertex shader
|
||||
VSOutput main(uint vertexIndex : SV_VertexID)
|
||||
{
|
||||
VSOutput output;
|
||||
|
||||
Vertex v = vertexBuffer[vertexIndex];
|
||||
output.UV = float2(v.uv_x, v.uv_y);
|
||||
output.Position = float4(v.position, 1.0f);
|
||||
|
||||
return output;
|
||||
}
|
||||
399
Data/Shaders/Vulkan/shading.frag
Normal file
@@ -0,0 +1,399 @@
|
||||
// Transforms
|
||||
struct ModelData
|
||||
{
|
||||
float4x4 model;
|
||||
};
|
||||
[[vk::binding(0, 0)]]
|
||||
StructuredBuffer<ModelData> model : register(t1);
|
||||
|
||||
// Vertex
|
||||
struct Vertex
|
||||
{
|
||||
float3 position;
|
||||
float uv_x;
|
||||
float3 normal;
|
||||
float uv_y;
|
||||
float3 tangent;
|
||||
float3 bitangent;
|
||||
};
|
||||
|
||||
[[vk::binding(0, 1)]]
|
||||
StructuredBuffer<Vertex> vertexBuffer : register(t2);
|
||||
|
||||
// Samplers
|
||||
[[vk::binding(0, 2)]]
|
||||
SamplerState mySampler : register(s0);
|
||||
|
||||
// Materials
|
||||
struct Material
|
||||
{
|
||||
bool hasAlbedo;
|
||||
float3 albedo;
|
||||
bool hasNormal;
|
||||
bool hasMetalness;
|
||||
bool hasRoughness;
|
||||
bool hasAO;
|
||||
float metalnessValue;
|
||||
float roughnessValue;
|
||||
float aoValue;
|
||||
int albedoTextureId;
|
||||
int normalTextureId;
|
||||
int metalnessTextureId;
|
||||
int roughnessTextureId;
|
||||
int aoTextureId;
|
||||
};
|
||||
[[vk::binding(0, 3)]]
|
||||
StructuredBuffer<Material> material;
|
||||
|
||||
// Textures
|
||||
[[vk::binding(0, 4)]]
|
||||
Texture2D textures[];
|
||||
|
||||
// Lights
|
||||
struct Light
|
||||
{
|
||||
float3 position;
|
||||
int type;
|
||||
float4 color;
|
||||
float3 direction;
|
||||
float outerConeAngle;
|
||||
float innerConeAngle;
|
||||
bool castShadow;
|
||||
int shadowMapTextureId[4];
|
||||
int transformId[4];
|
||||
};
|
||||
|
||||
[[vk::binding(0, 5)]]
|
||||
StructuredBuffer<Light> lights;
|
||||
|
||||
// Cameras
|
||||
struct CameraView {
|
||||
float4x4 View;
|
||||
float4x4 Projection;
|
||||
float4x4 ViewProjection;
|
||||
float4x4 InverseView;
|
||||
float4x4 InverseProjection;
|
||||
float3 Position;
|
||||
float Near;
|
||||
float Far;
|
||||
};
|
||||
[[vk::binding(0, 6)]]
|
||||
StructuredBuffer<CameraView> cameras;
|
||||
|
||||
struct PSInput
|
||||
{
|
||||
float4 Position : SV_Position;
|
||||
float2 UV : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct PSOutput {
|
||||
float4 oColor0 : SV_TARGET;
|
||||
};
|
||||
|
||||
struct ShadingPushConstant
|
||||
{
|
||||
int AlbedoInputTextureId;
|
||||
int DepthInputTextureId;
|
||||
int NormalInputTextureId;
|
||||
int MaterialInputTextureId;
|
||||
int LightCount;
|
||||
int CameraID;
|
||||
float cascadeDepth[4];
|
||||
float AmbientTerm;
|
||||
int SSAOTextureId;
|
||||
};
|
||||
|
||||
[[vk::push_constant]]
|
||||
ShadingPushConstant pushConstants;
|
||||
|
||||
float3 WorldPosFromDepth(float depth, float2 uv, float4x4 invProj, float4x4 invView)
|
||||
{
|
||||
float z = depth;
|
||||
float4 clipSpacePosition = float4(uv.x * 2.0 - 1.0, (uv.y * 2.0 - 1.0), z, 1.0f);
|
||||
float4 viewSpacePosition = mul(invProj, clipSpacePosition);
|
||||
viewSpacePosition /= viewSpacePosition.w;
|
||||
|
||||
float4 worldSpacePosition = mul(invView, viewSpacePosition);
|
||||
return worldSpacePosition.xyz;
|
||||
}
|
||||
|
||||
float LinearizeDepth(float depth, float nearPlane, float farPlane, bool reverseDepth)
|
||||
{
|
||||
if (reverseDepth)
|
||||
{
|
||||
// Reverse depth (near plane = 1.0, far plane = 0.0)
|
||||
return nearPlane * farPlane / lerp(farPlane, nearPlane, depth);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Standard depth (near plane = 0.0, far plane = 1.0)
|
||||
return (2.0 * nearPlane * farPlane) / (farPlane + nearPlane - depth * (farPlane - nearPlane));
|
||||
}
|
||||
}
|
||||
|
||||
float DistributionGGX(float3 N, float3 H, float a)
|
||||
{
|
||||
float PI = 3.141592653589793f;
|
||||
float a2 = a * a;
|
||||
float NdotH = max(dot(N, H), 0.0);
|
||||
float NdotH2 = NdotH * NdotH;
|
||||
|
||||
float nom = a2;
|
||||
float denom = (NdotH2 * (a2 - 1.0) + 1.0);
|
||||
denom = PI * denom * denom;
|
||||
|
||||
return nom / denom;
|
||||
}
|
||||
|
||||
float GeometrySchlickGGX(float NdotV, float k)
|
||||
{
|
||||
float nom = NdotV;
|
||||
float denom = NdotV * (1.0 - k) + k;
|
||||
|
||||
return nom / denom;
|
||||
}
|
||||
|
||||
float GeometrySmith(float3 N, float3 V, float3 L, float k)
|
||||
{
|
||||
float NdotV = max(dot(N, V), 0.0);
|
||||
float NdotL = max(dot(N, L), 0.0);
|
||||
float ggx1 = GeometrySchlickGGX(NdotV, k);
|
||||
float ggx2 = GeometrySchlickGGX(NdotL, k);
|
||||
|
||||
return ggx1 * ggx2;
|
||||
}
|
||||
|
||||
float3 fresnelSchlick(float cosTheta, float3 F0)
|
||||
{
|
||||
return F0 + (1.0 - F0) * pow(max(1.0 - cosTheta, 0.0), 5.0);
|
||||
}
|
||||
|
||||
float3 fresnelSchlickRoughness(float cosTheta, float3 F0, float roughness)
|
||||
{
|
||||
float roughnessTerm = 1.0f - roughness;
|
||||
return F0 + (max(float3(roughnessTerm, roughnessTerm, roughnessTerm), F0) - F0) * pow(max(1.0 - cosTheta, 0.0), 5.0);
|
||||
}
|
||||
|
||||
float linearDepth(float z, float near, float far) {
|
||||
return near * far / (far - z * (far - near));
|
||||
}
|
||||
|
||||
int GetCSMSplit(float depth)
|
||||
{
|
||||
for(int i = 0; i < 4; i++)
|
||||
{
|
||||
float csmSplitDepth = pushConstants.cascadeDepth[i];
|
||||
|
||||
if(depth < csmSplitDepth + 0.000001)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
float SampleShadowMap(int textureId, float2 coords, float compare)
|
||||
{
|
||||
return compare > textures[textureId].Sample(mySampler, coords.xy).r;
|
||||
}
|
||||
|
||||
float SampleShadowMapLinear(int textureId, float2 coords, float compare, float2 texelSize)
|
||||
{
|
||||
float2 pixelPos = coords / texelSize + float2(0.5f, 0.5f);
|
||||
float2 fracPart = frac(pixelPos);
|
||||
float2 startTexel = (pixelPos - fracPart) * texelSize;
|
||||
|
||||
float blTexel = SampleShadowMap(textureId, startTexel, compare);
|
||||
float brTexel = SampleShadowMap(textureId, startTexel + float2(texelSize.x, 0.0), compare);
|
||||
float tlTexel = SampleShadowMap(textureId, startTexel + float2(0.0, texelSize.y), compare);
|
||||
float trTexel = SampleShadowMap(textureId, startTexel + texelSize, compare);
|
||||
|
||||
float mixA = lerp(blTexel, tlTexel, fracPart.y);
|
||||
float mixB = lerp(brTexel, trTexel, fracPart.y);
|
||||
|
||||
return lerp(mixA, mixB, fracPart.x);
|
||||
}
|
||||
|
||||
float ShadowCalculation(Light light, float3 fragPos, float3 normal)
|
||||
{
|
||||
// Find correct CSM splits from depth
|
||||
CameraView camView = cameras[pushConstants.CameraID];
|
||||
float depth = length(fragPos - camView.Position);
|
||||
int splitIndex = GetCSMSplit(depth);
|
||||
|
||||
// Calculate shadows for found split
|
||||
CameraView lightView = cameras[light.transformId[splitIndex]];
|
||||
int shadowMap = light.shadowMapTextureId[0];
|
||||
float4 fragLightSpace = mul(lightView.Projection, mul(lightView.View, float4(fragPos, 1.0)));
|
||||
float3 projCoords = fragLightSpace.xyz / fragLightSpace.w;
|
||||
projCoords.xy = projCoords.xy * 0.5 + 0.5;
|
||||
|
||||
if (projCoords.x < 0.0 || projCoords.x > 1.0 || projCoords.y < 0.0 || projCoords.y > 1.0) {
|
||||
return 1.0;
|
||||
}
|
||||
|
||||
//projCoords.y = 1.0 - projCoords.y;
|
||||
float currentDepth = projCoords.z;
|
||||
float bias = max(0.005 * (1.0 - dot(normal, light.direction)), 0.0005);
|
||||
|
||||
if(splitIndex < 2)
|
||||
{
|
||||
const float NUM_SAMPLES = 4.0f;
|
||||
const float SAMPLES_START = (NUM_SAMPLES - 1.0f) / 2.0f;
|
||||
const float NUM_SAMPLES_SQUARED = NUM_SAMPLES * NUM_SAMPLES;
|
||||
|
||||
float2 texelSize = 1.0f / float2(4096, 4096);
|
||||
float result = 0.0f;
|
||||
for(float y = -SAMPLES_START; y <= SAMPLES_START; y += 1.0f)
|
||||
{
|
||||
for (float x = -SAMPLES_START; x <= SAMPLES_START; x += 1.0f)
|
||||
{
|
||||
float2 coordsOffset = float2(x, y) * texelSize;
|
||||
result += SampleShadowMapLinear(light.shadowMapTextureId[splitIndex], projCoords.xy + coordsOffset, currentDepth, texelSize);
|
||||
}
|
||||
}
|
||||
|
||||
return result /= NUM_SAMPLES_SQUARED;
|
||||
}
|
||||
|
||||
float shadowMapDepth = textures[light.shadowMapTextureId[splitIndex]].Sample(mySampler, projCoords.xy).r;
|
||||
|
||||
return (currentDepth > shadowMapDepth);//> 0.0 ? 1.0 : 0.0;
|
||||
}
|
||||
PSOutput main(PSInput input)
|
||||
{
|
||||
PSOutput output;
|
||||
CameraView camView = cameras[pushConstants.CameraID];
|
||||
|
||||
int depthTexture = pushConstants.DepthInputTextureId;
|
||||
float depth = textures[depthTexture].Sample(mySampler, input.UV).r;
|
||||
|
||||
if(depth == 0.0f)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
float3 worldPos = WorldPosFromDepth(depth, input.UV, camView.InverseProjection, camView.InverseView);
|
||||
|
||||
int albedoTextureId = pushConstants.AlbedoInputTextureId;
|
||||
float3 albedo = textures[albedoTextureId].Sample(mySampler, input.UV).xyz;
|
||||
float3 normal = textures[pushConstants.NormalInputTextureId].Sample(mySampler, input.UV).rgb;
|
||||
normal = normal * 2.0f - 1.0f;
|
||||
|
||||
float4 materialSample = textures[pushConstants.MaterialInputTextureId].Sample(mySampler, input.UV);
|
||||
float metallic = materialSample.r;
|
||||
float ao = materialSample.g;
|
||||
float roughness = materialSample.b;
|
||||
float ssao = textures[pushConstants.SSAOTextureId].Sample(mySampler, input.UV);
|
||||
|
||||
float3 N = normal;
|
||||
float3 V = normalize(camView.Position - worldPos);
|
||||
float3 R = reflect(-V, N);
|
||||
float3 F0 = float3(0.04, 0.04, 0.04);
|
||||
F0 = lerp(F0, albedo, metallic);
|
||||
|
||||
Light directionalLight;
|
||||
bool foundDirectional = false;
|
||||
for(int i = 0; i < pushConstants.LightCount; i++)
|
||||
{
|
||||
Light light = lights[i];
|
||||
if(light.type == 0)
|
||||
{
|
||||
directionalLight = light;
|
||||
foundDirectional = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
const float PI = 3.141592653589793f;
|
||||
float3 Lo = float3(0.0, 0.0, 0.0);
|
||||
float shadow = 1.0f;
|
||||
|
||||
if(foundDirectional == false)
|
||||
{
|
||||
shadow = 1.0f;
|
||||
}
|
||||
|
||||
//Directional
|
||||
if(foundDirectional)
|
||||
{
|
||||
Light light = directionalLight;
|
||||
float3 L = normalize(light.direction);
|
||||
float attenuation = 1.0f;
|
||||
|
||||
if(light.castShadow == true)
|
||||
{
|
||||
shadow *= ShadowCalculation(light, worldPos, N);
|
||||
//output.oColor0 = float4(albedo * 0.1 + float3(shadow, shadow, shadow), 1);
|
||||
//return output;
|
||||
}
|
||||
|
||||
// TODO: Shadow
|
||||
float3 radiance = light.color.rgb * attenuation;
|
||||
float3 H = normalize(V + L);
|
||||
float NDF = DistributionGGX(N, H, roughness);
|
||||
float G = GeometrySmith(N, V, L, roughness);
|
||||
float3 F = fresnelSchlick(max(dot(H, V), 0.0), F0);
|
||||
|
||||
float3 nominator = NDF * G * F;
|
||||
float denominator = 4 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0) + 0.001; // 0.001 to prevent divide by zero.
|
||||
float3 specular = nominator / denominator;
|
||||
|
||||
float3 kS = F;
|
||||
float3 kD = float3(1.0, 1.0, 1.0) - kS;
|
||||
kD *= 1.0 - metallic;
|
||||
|
||||
float NdotL = max(dot(N, L), 0.0);
|
||||
Lo += (kD * albedo / PI + specular) * radiance * NdotL * shadow;
|
||||
}
|
||||
|
||||
// other lights
|
||||
for(int i = 0; i < pushConstants.LightCount; i++)
|
||||
{
|
||||
Light light = lights[i];
|
||||
float3 L = normalize(light.position - worldPos);
|
||||
float distance = length(light.position - worldPos);
|
||||
float attenuation = 1.0 / (distance * distance);
|
||||
|
||||
float3 radiance = float3(0, 0, 0);
|
||||
if(light.type == 1) // point light
|
||||
{
|
||||
radiance = light.color * attenuation;
|
||||
}
|
||||
else if(light.type == 2)
|
||||
{
|
||||
float theta = dot(L, normalize(-light.direction));
|
||||
float epsilon = light.innerConeAngle - light.outerConeAngle;
|
||||
float intensity = clamp((theta - light.outerConeAngle) / epsilon, 0.0, 1.0);
|
||||
radiance = light.color * intensity * attenuation;
|
||||
}
|
||||
|
||||
float3 H = normalize(V + L);
|
||||
float NDF = DistributionGGX(N, H, roughness);
|
||||
float G = GeometrySmith(N, V, L, roughness);
|
||||
float3 F = fresnelSchlick(max(dot(H, V), 0.0), F0);
|
||||
|
||||
float3 nominator = NDF * G * F;
|
||||
float denominator = 4 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0) + 0.001; // 0.001 to prevent divide by zero.
|
||||
float3 specular = nominator / denominator;
|
||||
|
||||
float3 kS = F;
|
||||
float3 kD = float3(1.0, 1.0, 1.0) - kS;
|
||||
kD *= 1.0 - metallic;
|
||||
|
||||
float NdotL = max(dot(N, L), 0.0);
|
||||
Lo += (kD * albedo / PI + specular) * radiance * NdotL;
|
||||
}
|
||||
|
||||
float3 F = fresnelSchlickRoughness(max(dot(N, V), 0.0), F0, roughness);
|
||||
float3 kS = F;
|
||||
float3 kD = 1.0 - kS;
|
||||
kD *= 1.0 - metallic;
|
||||
|
||||
float3 ambient = (albedo) * ao * ssao * pushConstants.AmbientTerm;
|
||||
float3 color = (ambient) + Lo;
|
||||
|
||||
output.oColor0 = float4(color, 1);
|
||||
return output;
|
||||
}
|
||||
117
Data/Shaders/Vulkan/shading.vert
Normal file
@@ -0,0 +1,117 @@
|
||||
// Transforms
|
||||
struct ModelData
|
||||
{
|
||||
float4x4 model;
|
||||
};
|
||||
[[vk::binding(0, 0)]]
|
||||
StructuredBuffer<ModelData> model : register(t1);
|
||||
|
||||
// Vertex
|
||||
struct Vertex
|
||||
{
|
||||
float3 position;
|
||||
float uv_x;
|
||||
float3 normal;
|
||||
float uv_y;
|
||||
float3 tangent;
|
||||
float3 bitangent;
|
||||
};
|
||||
|
||||
[[vk::binding(0, 1)]]
|
||||
StructuredBuffer<Vertex> vertexBuffer : register(t2);
|
||||
|
||||
// Samplers
|
||||
[[vk::binding(0, 2)]]
|
||||
SamplerState mySampler : register(s0);
|
||||
|
||||
// Materials
|
||||
struct Material
|
||||
{
|
||||
bool hasAlbedo;
|
||||
float3 albedo;
|
||||
bool hasNormal;
|
||||
bool hasMetalness;
|
||||
bool hasRoughness;
|
||||
bool hasAO;
|
||||
float metalnessValue;
|
||||
float roughnessValue;
|
||||
float aoValue;
|
||||
int albedoTextureId;
|
||||
int normalTextureId;
|
||||
int metalnessTextureId;
|
||||
int roughnessTextureId;
|
||||
int aoTextureId;
|
||||
};
|
||||
[[vk::binding(0, 3)]]
|
||||
StructuredBuffer<Material> material;
|
||||
|
||||
// Textures
|
||||
[[vk::binding(0, 4)]]
|
||||
Texture2D textures[];
|
||||
|
||||
// Lights
|
||||
struct Light
|
||||
{
|
||||
float3 position;
|
||||
int type;
|
||||
float4 color;
|
||||
float3 direction;
|
||||
float outerConeAngle;
|
||||
float innerConeAngle;
|
||||
bool castShadow;
|
||||
int shadowMapTextureId[4];
|
||||
int transformId[4];
|
||||
};
|
||||
|
||||
[[vk::binding(0, 5)]]
|
||||
StructuredBuffer<Light> lights;
|
||||
|
||||
// Cameras
|
||||
struct CameraView {
|
||||
float4x4 View;
|
||||
float4x4 Projection;
|
||||
float4x4 ViewProjection;
|
||||
float4x4 InverseView;
|
||||
float4x4 InverseProjection;
|
||||
float3 Position;
|
||||
float Near;
|
||||
float Far;
|
||||
};
|
||||
[[vk::binding(0, 6)]]
|
||||
StructuredBuffer<CameraView> cameras;
|
||||
|
||||
struct ShadingPushConstant
|
||||
{
|
||||
int AlbedoInputTextureId;
|
||||
int DepthInputTextureId;
|
||||
int NormalInputTextureId;
|
||||
int MaterialInputTextureId;
|
||||
int LightCount;
|
||||
int CameraID;
|
||||
float cascadeDepth[4];
|
||||
float AmbientTerm;
|
||||
int SSAOTextureId;
|
||||
};
|
||||
|
||||
[[vk::push_constant]]
|
||||
ShadingPushConstant pushConstants;
|
||||
|
||||
// Outputs
|
||||
struct VSOutput
|
||||
{
|
||||
float4 Position : SV_Position;
|
||||
float2 UV : TEXCOORD0;
|
||||
};
|
||||
|
||||
|
||||
// Main vertex shader
|
||||
VSOutput main(uint vertexIndex : SV_VertexID)
|
||||
{
|
||||
VSOutput output;
|
||||
|
||||
Vertex v = vertexBuffer[vertexIndex];
|
||||
output.UV = float2(v.uv_x, v.uv_y);
|
||||
output.Position = float4(v.position, 1.0f);
|
||||
|
||||
return output;
|
||||
}
|
||||
100
Data/Shaders/Vulkan/shadow.frag
Normal file
@@ -0,0 +1,100 @@
|
||||
// Transforms
|
||||
struct ModelData
|
||||
{
|
||||
float4x4 model;
|
||||
};
|
||||
[[vk::binding(0, 0)]]
|
||||
StructuredBuffer<ModelData> model : register(t1);
|
||||
|
||||
// Vertex
|
||||
struct Vertex
|
||||
{
|
||||
float3 position;
|
||||
float uv_x;
|
||||
float3 normal;
|
||||
float uv_y;
|
||||
float3 tangent;
|
||||
float3 bitangent;
|
||||
};
|
||||
|
||||
[[vk::binding(0, 1)]]
|
||||
StructuredBuffer<Vertex> vertexBuffer : register(t2);
|
||||
|
||||
// Samplers
|
||||
[[vk::binding(0, 2)]]
|
||||
SamplerState mySampler : register(s0);
|
||||
|
||||
// Materials
|
||||
struct Material
|
||||
{
|
||||
bool hasAlbedo;
|
||||
float3 albedo;
|
||||
bool hasNormal;
|
||||
bool hasMetalness;
|
||||
bool hasRoughness;
|
||||
bool hasAO;
|
||||
float metalnessValue;
|
||||
float roughnessValue;
|
||||
float aoValue;
|
||||
int albedoTextureId;
|
||||
int normalTextureId;
|
||||
int metalnessTextureId;
|
||||
int roughnessTextureId;
|
||||
int aoTextureId;
|
||||
};
|
||||
[[vk::binding(0, 3)]]
|
||||
StructuredBuffer<Material> material;
|
||||
|
||||
// Textures
|
||||
[[vk::binding(0, 4)]]
|
||||
Texture2D textures[];
|
||||
|
||||
// Lights
|
||||
struct Light
|
||||
{
|
||||
float3 position;
|
||||
int type;
|
||||
float4 color;
|
||||
float3 direction;
|
||||
float outerConeAngle;
|
||||
float innerConeAngle;
|
||||
bool castShadow;
|
||||
int shadowMapTextureId[4];
|
||||
int transformId[4];
|
||||
};
|
||||
|
||||
[[vk::binding(0, 5)]]
|
||||
StructuredBuffer<Light> lights;
|
||||
|
||||
// Cameras
|
||||
struct CameraView {
|
||||
float4x4 View;
|
||||
float4x4 Projection;
|
||||
float4x4 ViewProjection;
|
||||
float4x4 InverseView;
|
||||
float4x4 InverseProjection;
|
||||
float3 Position;
|
||||
float Near;
|
||||
float Far;
|
||||
};
|
||||
[[vk::binding(0, 6)]]
|
||||
StructuredBuffer<CameraView> cameras;
|
||||
|
||||
struct PSInput
|
||||
{
|
||||
float4 Position : SV_Position;
|
||||
};
|
||||
|
||||
struct ModelPushConstant
|
||||
{
|
||||
int modelIndex; // Push constant data
|
||||
int materialIndex;
|
||||
int cameraID;
|
||||
};
|
||||
|
||||
[[vk::push_constant]]
|
||||
ModelPushConstant pushConstants;
|
||||
|
||||
void main(PSInput input)
|
||||
{
|
||||
}
|
||||
129
Data/Shaders/Vulkan/shadow.vert
Normal file
@@ -0,0 +1,129 @@
|
||||
// Transforms
|
||||
struct ModelData
|
||||
{
|
||||
float4x4 model;
|
||||
};
|
||||
[[vk::binding(0, 0)]]
|
||||
StructuredBuffer<ModelData> model : register(t1);
|
||||
|
||||
// Vertex
|
||||
struct Vertex
|
||||
{
|
||||
float3 position;
|
||||
float uv_x;
|
||||
float3 normal;
|
||||
float uv_y;
|
||||
float3 tangent;
|
||||
float3 bitangent;
|
||||
};
|
||||
|
||||
[[vk::binding(0, 1)]]
|
||||
StructuredBuffer<Vertex> vertexBuffer : register(t2);
|
||||
|
||||
// Samplers
|
||||
[[vk::binding(0, 2)]]
|
||||
SamplerState mySampler : register(s0);
|
||||
|
||||
// Materials
|
||||
struct Material
|
||||
{
|
||||
float hasAlbedo;
|
||||
float3 albedo;
|
||||
int hasNormal;
|
||||
int hasMetalness;
|
||||
int hasRoughness;
|
||||
int hasAO;
|
||||
float metalnessValue;
|
||||
float roughnessValue;
|
||||
float aoValue;
|
||||
int albedoTextureId;
|
||||
int normalTextureId;
|
||||
int metalnessTextureId;
|
||||
int roughnessTextureId;
|
||||
int aoTextureId;
|
||||
};
|
||||
[[vk::binding(0, 3)]]
|
||||
StructuredBuffer<Material> material;
|
||||
|
||||
// Textures
|
||||
[[vk::binding(0, 4)]]
|
||||
Texture2D textures[];
|
||||
|
||||
// Lights
|
||||
struct Light
|
||||
{
|
||||
float3 position;
|
||||
int type;
|
||||
float4 color;
|
||||
float3 direction;
|
||||
float outerConeAngle;
|
||||
float innerConeAngle;
|
||||
bool castShadow;
|
||||
int shadowMapTextureId[4];
|
||||
int transformId[4];
|
||||
};
|
||||
|
||||
[[vk::binding(0, 5)]]
|
||||
StructuredBuffer<Light> lights;
|
||||
|
||||
// Cameras
|
||||
struct CameraView {
|
||||
float4x4 View;
|
||||
float4x4 Projection;
|
||||
float4x4 ViewProjection;
|
||||
float4x4 InverseView;
|
||||
float4x4 InverseProjection;
|
||||
float3 Position;
|
||||
float Near;
|
||||
float Far;
|
||||
};
|
||||
[[vk::binding(0, 6)]]
|
||||
StructuredBuffer<CameraView> cameras;
|
||||
|
||||
struct ModelPushConstant
|
||||
{
|
||||
int modelIndex; // Push constant data
|
||||
int materialIndex;
|
||||
int cameraID;
|
||||
};
|
||||
|
||||
[[vk::push_constant]]
|
||||
ModelPushConstant pushConstants;
|
||||
|
||||
// Outputs
|
||||
struct VSOutput
|
||||
{
|
||||
float4 Position : SV_Position;
|
||||
};
|
||||
|
||||
float LinearizeDepth(float depth, float nearPlane, float farPlane, bool reverseDepth)
|
||||
{
|
||||
if (reverseDepth)
|
||||
{
|
||||
// Reverse depth (near plane = 1.0, far plane = 0.0)
|
||||
return nearPlane * farPlane / lerp(farPlane, nearPlane, depth);
|
||||
}
|
||||
else
|
||||
{
|
||||
// Standard depth (near plane = 0.0, far plane = 1.0)
|
||||
return (2.0 * nearPlane * farPlane) / (farPlane + nearPlane - depth * (farPlane - nearPlane));
|
||||
}
|
||||
}
|
||||
|
||||
// Main vertex shader
|
||||
VSOutput main(uint vertexIndex : SV_VertexID)
|
||||
{
|
||||
VSOutput output;
|
||||
|
||||
ModelData modelData = model[pushConstants.modelIndex];
|
||||
CameraView camView = cameras[pushConstants.cameraID];
|
||||
|
||||
// Load vertex data from the buffer
|
||||
Vertex v = vertexBuffer[vertexIndex];
|
||||
|
||||
// Output the position of each vertex
|
||||
output.Position = mul(camView.Projection, mul(camView.View,mul(modelData.model, float4(v.position, 1.0f))));
|
||||
|
||||
//output.Position.z = LinearizeDepth(output.Position.z, camView.Near, camView.Far, false);
|
||||
return output;
|
||||
}
|
||||
223
Data/Shaders/Vulkan/ssao.frag
Normal file
@@ -0,0 +1,223 @@
|
||||
// Transforms
|
||||
struct ModelData
|
||||
{
|
||||
float4x4 model;
|
||||
};
|
||||
[[vk::binding(0, 0)]]
|
||||
StructuredBuffer<ModelData> model : register(t1);
|
||||
|
||||
// Vertex
|
||||
struct Vertex
|
||||
{
|
||||
float3 position;
|
||||
float uv_x;
|
||||
float3 normal;
|
||||
float uv_y;
|
||||
float3 tangent;
|
||||
float3 bitangent;
|
||||
};
|
||||
|
||||
[[vk::binding(0, 1)]]
|
||||
StructuredBuffer<Vertex> vertexBuffer : register(t2);
|
||||
|
||||
// Samplers
|
||||
[[vk::binding(0, 2)]]
|
||||
SamplerState mySampler : register(s0);
|
||||
|
||||
// Materials
|
||||
struct Material
|
||||
{
|
||||
bool hasAlbedo;
|
||||
float3 albedo;
|
||||
bool hasNormal;
|
||||
bool hasMetalness;
|
||||
bool hasRoughness;
|
||||
bool hasAO;
|
||||
float metalnessValue;
|
||||
float roughnessValue;
|
||||
float aoValue;
|
||||
int albedoTextureId;
|
||||
int normalTextureId;
|
||||
int metalnessTextureId;
|
||||
int roughnessTextureId;
|
||||
int aoTextureId;
|
||||
};
|
||||
[[vk::binding(0, 3)]]
|
||||
StructuredBuffer<Material> material;
|
||||
|
||||
// Textures
|
||||
[[vk::binding(0, 4)]]
|
||||
Texture2D textures[];
|
||||
|
||||
// Lights
|
||||
struct Light
|
||||
{
|
||||
float3 position;
|
||||
int type;
|
||||
float4 color;
|
||||
float3 direction;
|
||||
float outerConeAngle;
|
||||
float innerConeAngle;
|
||||
bool castShadow;
|
||||
int shadowMapTextureId[4];
|
||||
int transformId[4];
|
||||
};
|
||||
|
||||
[[vk::binding(0, 5)]]
|
||||
StructuredBuffer<Light> lights;
|
||||
|
||||
// Cameras
|
||||
struct CameraView {
|
||||
float4x4 View;
|
||||
float4x4 Projection;
|
||||
float4x4 ViewProjection;
|
||||
float4x4 InverseView;
|
||||
float4x4 InverseProjection;
|
||||
float3 Position;
|
||||
float Near;
|
||||
float Far;
|
||||
};
|
||||
[[vk::binding(0, 6)]]
|
||||
StructuredBuffer<CameraView> cameras;
|
||||
|
||||
[[vk::binding(0, 7)]]
|
||||
StructuredBuffer<float3> ssaoKernels;
|
||||
|
||||
struct PSInput {
|
||||
float4 Position : SV_Position;
|
||||
float2 UV : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct PSOutput {
|
||||
float4 oColor0 : SV_TARGET;
|
||||
};
|
||||
|
||||
struct SSAOConstant
|
||||
{
|
||||
int noiseTextureID;
|
||||
int normalTextureID;
|
||||
int depthTextureID;
|
||||
int camViewID;
|
||||
float radius;
|
||||
float bias;
|
||||
float2 noiseScale;
|
||||
float power;
|
||||
};
|
||||
|
||||
[[vk::push_constant]]
|
||||
SSAOConstant pushConstants;
|
||||
|
||||
float3 ViewPosFromDepth(float depth, float2 uv, float4x4 invProj)
|
||||
{
|
||||
float z = depth;
|
||||
float4 clipSpacePosition = float4(uv.x * 2.0 - 1.0, (uv.y * 2.0 - 1.0), z, 1.0f);
|
||||
float4 viewSpacePosition = mul(invProj, clipSpacePosition);
|
||||
viewSpacePosition /= viewSpacePosition.w;
|
||||
return viewSpacePosition.xyz;
|
||||
}
|
||||
|
||||
float3 WorldPosFromDepth(float depth, float2 uv, CameraView camera)
|
||||
{
|
||||
float z = depth;
|
||||
float4 clipSpacePosition = float4(uv.x * 2.0 - 1.0, (uv.y * 2.0 - 1.0), z, 1.0f);
|
||||
float4 viewSpacePosition = mul(camera.InverseProjection, clipSpacePosition);
|
||||
viewSpacePosition /= viewSpacePosition.w;
|
||||
|
||||
float4 worldSpacePosition = mul(camera.InverseView, viewSpacePosition);
|
||||
worldSpacePosition /= worldSpacePosition.w;
|
||||
|
||||
return worldSpacePosition.xyz;
|
||||
}
|
||||
|
||||
float3 SampleTexture(int textureId, float2 uv)
|
||||
{
|
||||
return textures[textureId].Sample(mySampler, uv).rgb;
|
||||
}
|
||||
|
||||
float SampleDepth(float2 uv)
|
||||
{
|
||||
return textures[pushConstants.depthTextureID].Sample(mySampler, uv).r;
|
||||
}
|
||||
|
||||
float3x3 Inverse3x3(float3x3 m)
|
||||
{
|
||||
float3 r0 = cross(m[1], m[2]);
|
||||
float3 r1 = cross(m[2], m[0]);
|
||||
float3 r2 = cross(m[0], m[1]);
|
||||
|
||||
float det = dot(r2, m[2]);
|
||||
float invDet = 1.0 / det;
|
||||
|
||||
return float3x3(
|
||||
r0 * invDet,
|
||||
r1 * invDet,
|
||||
r2 * invDet
|
||||
);
|
||||
}
|
||||
|
||||
PSOutput main(PSInput input)
|
||||
{
|
||||
CameraView camera = cameras[pushConstants.camViewID];
|
||||
|
||||
float depth = SampleDepth(input.UV);
|
||||
|
||||
// Discard the sky
|
||||
if(depth < 0.00001)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
// Calculate TBN
|
||||
float3x3 normalMatrix = (float3x3)camera.View;
|
||||
//normalMatrix[0] *= -1.0; // Flip the Z basis vector
|
||||
float3 normal = SampleTexture(pushConstants.normalTextureID, input.UV).xyz * 2.0 - 1.0;
|
||||
normal = mul(normalMatrix, normal);
|
||||
|
||||
float2 randomVecSample = SampleTexture(pushConstants.noiseTextureID, input.UV * pushConstants.noiseScale).xy * 2.0 - 1.0;
|
||||
float3 randomVec = float3(randomVecSample.x, -randomVecSample.y, 0);
|
||||
//randomVec = float3(0, 1, 0);
|
||||
float3 tangent = normalize(randomVec - normal * dot(randomVec, normal));
|
||||
float3 bitangent = cross(normal, tangent);
|
||||
float3x3 TBN = float3x3(tangent, bitangent, normal);
|
||||
|
||||
float3 fragPos = ViewPosFromDepth(depth, input.UV, camera.InverseProjection);
|
||||
// Fix from: https://github.com/JoeyDeVries/LearnOpenGL/issues/364
|
||||
float4 fragWorldPos = mul(camera.InverseView, float4(fragPos, 1.0));
|
||||
fragWorldPos.xyz /= fragWorldPos.w;
|
||||
|
||||
PSOutput output;
|
||||
|
||||
float occlusion = 0.0f;
|
||||
for(int i = 0; i < 64; i++)
|
||||
{
|
||||
float3 samplePos = mul(ssaoKernels[i], TBN);
|
||||
|
||||
samplePos = fragPos + samplePos * pushConstants.radius;
|
||||
//samplePos = fragWorldPos + samplePos * pushConstants.radius;
|
||||
|
||||
//return output;
|
||||
// Fix from: https://github.com/JoeyDeVries/LearnOpenGL/issues/364
|
||||
float4 worldSamplePos = mul(camera.View, float4(samplePos, 1.0));
|
||||
worldSamplePos.xyz /= worldSamplePos.w;
|
||||
|
||||
//samplePos = worldSamplePos.xyz;
|
||||
float4 offset = float4(samplePos, 1.0f);
|
||||
offset = mul(camera.Projection, offset);
|
||||
offset.xyz /= offset.w;
|
||||
offset.xyz = offset.xyz * 0.5 + 0.5;
|
||||
|
||||
offset.x = clamp(offset.x, 0.00001, 0.999);
|
||||
offset.y = clamp(offset.y, 0.00001, 0.999);
|
||||
|
||||
float sampleDepth = ViewPosFromDepth(SampleDepth(offset.xy), offset.xy, camera.InverseProjection).z;
|
||||
float rangeCheck = smoothstep(0.0, 1.0, pushConstants.radius / abs(sampleDepth - fragPos.z));
|
||||
occlusion += (sampleDepth - pushConstants.bias >= samplePos.z ? 1.0 : 0.0) * rangeCheck;
|
||||
}
|
||||
|
||||
occlusion = 1.0 - (occlusion / 64.0);
|
||||
occlusion = pow(occlusion, pushConstants.power);
|
||||
|
||||
|
||||
output.oColor0 = float4(occlusion, occlusion, occlusion, 1.0f);
|
||||
return output;
|
||||
}
|
||||
116
Data/Shaders/Vulkan/ssao.vert
Normal file
@@ -0,0 +1,116 @@
|
||||
// Transforms
|
||||
struct ModelData
|
||||
{
|
||||
float4x4 model;
|
||||
};
|
||||
[[vk::binding(0, 0)]]
|
||||
StructuredBuffer<ModelData> model : register(t1);
|
||||
|
||||
// Vertex
|
||||
struct Vertex
|
||||
{
|
||||
float3 position;
|
||||
float uv_x;
|
||||
float3 normal;
|
||||
float uv_y;
|
||||
float3 tangent;
|
||||
float3 bitangent;
|
||||
};
|
||||
|
||||
[[vk::binding(0, 1)]]
|
||||
StructuredBuffer<Vertex> vertexBuffer : register(t2);
|
||||
|
||||
// Samplers
|
||||
[[vk::binding(0, 2)]]
|
||||
SamplerState mySampler : register(s0);
|
||||
|
||||
// Materials
|
||||
struct Material
|
||||
{
|
||||
bool hasAlbedo;
|
||||
float3 albedo;
|
||||
bool hasNormal;
|
||||
bool hasMetalness;
|
||||
bool hasRoughness;
|
||||
bool hasAO;
|
||||
float metalnessValue;
|
||||
float roughnessValue;
|
||||
float aoValue;
|
||||
int albedoTextureId;
|
||||
int normalTextureId;
|
||||
int metalnessTextureId;
|
||||
int roughnessTextureId;
|
||||
int aoTextureId;
|
||||
};
|
||||
[[vk::binding(0, 3)]]
|
||||
StructuredBuffer<Material> material;
|
||||
|
||||
// Textures
|
||||
[[vk::binding(0, 4)]]
|
||||
Texture2D textures[];
|
||||
|
||||
// Lights
|
||||
struct Light
|
||||
{
|
||||
float3 position;
|
||||
int type;
|
||||
float4 color;
|
||||
float3 direction;
|
||||
float outerConeAngle;
|
||||
float innerConeAngle;
|
||||
bool castShadow;
|
||||
int shadowMapTextureId[4];
|
||||
int transformId[4];
|
||||
};
|
||||
|
||||
[[vk::binding(0, 5)]]
|
||||
StructuredBuffer<Light> lights;
|
||||
|
||||
// Cameras
|
||||
struct CameraView {
|
||||
float4x4 View;
|
||||
float4x4 Projection;
|
||||
float4x4 ViewProjection;
|
||||
float4x4 InverseView;
|
||||
float4x4 InverseProjection;
|
||||
float3 Position;
|
||||
float Near;
|
||||
float Far;
|
||||
};
|
||||
[[vk::binding(0, 6)]]
|
||||
StructuredBuffer<CameraView> cameras;
|
||||
|
||||
[[vk::binding(0, 7)]]
|
||||
StructuredBuffer<float3> ssaoKernels;
|
||||
|
||||
struct SSAOConstant
|
||||
{
|
||||
int noiseTextureID;
|
||||
int normalTextureID;
|
||||
int depthTextureID;
|
||||
float radius;
|
||||
float bias;
|
||||
float2 noiseScale;
|
||||
float power;
|
||||
};
|
||||
|
||||
[[vk::push_constant]]
|
||||
SSAOConstant pushConstants;
|
||||
|
||||
// Outputs
|
||||
struct VSOutput {
|
||||
float4 Position : SV_Position;
|
||||
float2 UV : TEXCOORD0;
|
||||
};
|
||||
|
||||
// Main vertex shader
|
||||
VSOutput main(uint vertexIndex : SV_VertexID)
|
||||
{
|
||||
VSOutput output;
|
||||
|
||||
Vertex v = vertexBuffer[vertexIndex];
|
||||
output.UV = float2(v.uv_x, v.uv_y);
|
||||
output.Position = float4(v.position, 1.0f);
|
||||
|
||||
return output;
|
||||
}
|
||||
28
Data/Shaders/Vulkan/test.vert
Normal file
@@ -0,0 +1,28 @@
|
||||
struct VSInput
|
||||
{
|
||||
[[vk::location(0)]] float3 Position : POSITION0;
|
||||
[[vk::location(1)]] float3 Color : COLOR0;
|
||||
};
|
||||
|
||||
struct UBO
|
||||
{
|
||||
float4x4 projectionMatrix;
|
||||
float4x4 modelMatrix;
|
||||
float4x4 viewMatrix;
|
||||
};
|
||||
|
||||
cbuffer ubo : register(b0, space0) { UBO ubo; }
|
||||
|
||||
struct VSOutput
|
||||
{
|
||||
float4 Pos : SV_POSITION;
|
||||
[[vk::location(0)]] float3 Color : COLOR0;
|
||||
};
|
||||
|
||||
VSOutput main(VSInput input, uint VertexIndex : SV_VertexID)
|
||||
{
|
||||
VSOutput output = (VSOutput)0;
|
||||
output.Color = input.Color * float(VertexIndex);
|
||||
output.Pos = mul(ubo.projectionMatrix, mul(ubo.viewMatrix, mul(ubo.modelMatrix, float4(input.Position.xyz, 1.0))));
|
||||
return output;
|
||||
}
|
||||
132
Data/Shaders/Vulkan/tonemap.frag
Normal file
@@ -0,0 +1,132 @@
|
||||
// Transforms
|
||||
struct ModelData
|
||||
{
|
||||
float4x4 model;
|
||||
};
|
||||
[[vk::binding(0, 0)]]
|
||||
StructuredBuffer<ModelData> model : register(t1);
|
||||
|
||||
// Vertex
|
||||
struct Vertex
|
||||
{
|
||||
float3 position;
|
||||
float uv_x;
|
||||
float3 normal;
|
||||
float uv_y;
|
||||
float3 tangent;
|
||||
float3 bitangent;
|
||||
};
|
||||
|
||||
[[vk::binding(0, 1)]]
|
||||
StructuredBuffer<Vertex> vertexBuffer : register(t2);
|
||||
|
||||
// Samplers
|
||||
[[vk::binding(0, 2)]]
|
||||
SamplerState mySampler : register(s0);
|
||||
|
||||
// Materials
|
||||
struct Material
|
||||
{
|
||||
bool hasAlbedo;
|
||||
float3 albedo;
|
||||
bool hasNormal;
|
||||
bool hasMetalness;
|
||||
bool hasRoughness;
|
||||
bool hasAO;
|
||||
float metalnessValue;
|
||||
float roughnessValue;
|
||||
float aoValue;
|
||||
int albedoTextureId;
|
||||
int normalTextureId;
|
||||
int metalnessTextureId;
|
||||
int roughnessTextureId;
|
||||
int aoTextureId;
|
||||
};
|
||||
[[vk::binding(0, 3)]]
|
||||
StructuredBuffer<Material> material;
|
||||
|
||||
// Textures
|
||||
[[vk::binding(0, 4)]]
|
||||
Texture2D textures[];
|
||||
|
||||
// Lights
|
||||
struct Light
|
||||
{
|
||||
float3 position;
|
||||
int type;
|
||||
float4 color;
|
||||
float3 direction;
|
||||
float outerConeAngle;
|
||||
float innerConeAngle;
|
||||
bool castShadow;
|
||||
int shadowMapTextureId[4];
|
||||
int transformId[4];
|
||||
};
|
||||
|
||||
[[vk::binding(0, 5)]]
|
||||
StructuredBuffer<Light> lights;
|
||||
|
||||
// Cameras
|
||||
struct CameraView {
|
||||
float4x4 View;
|
||||
float4x4 Projection;
|
||||
float4x4 ViewProjection;
|
||||
float4x4 InverseView;
|
||||
float4x4 InverseProjection;
|
||||
float3 Position;
|
||||
float Near;
|
||||
float Far;
|
||||
};
|
||||
[[vk::binding(0, 6)]]
|
||||
StructuredBuffer<CameraView> cameras;
|
||||
|
||||
struct PSInput {
|
||||
float4 Position : SV_Position;
|
||||
float2 UV : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct PSOutput {
|
||||
float4 oColor0 : SV_TARGET;
|
||||
};
|
||||
|
||||
struct TonemapPushConstant
|
||||
{
|
||||
float Exposure;
|
||||
float Gamma;
|
||||
int SourceTextureID;
|
||||
};
|
||||
|
||||
[[vk::push_constant]]
|
||||
TonemapPushConstant pushConstants;
|
||||
|
||||
float3 PBRNeutralToneMapping(float3 color)
|
||||
{
|
||||
const float startCompression = 0.8 - 0.04;
|
||||
const float desaturation = 0.15;
|
||||
|
||||
float x = min(color.r, min(color.g, color.b));
|
||||
float offset = x < 0.08 ? x - 6.25 * x * x : 0.04;
|
||||
color -= offset;
|
||||
|
||||
float peak = max(color.r, max(color.g, color.b));
|
||||
if (peak < startCompression) return color;
|
||||
|
||||
const float d = 1. - startCompression;
|
||||
float newPeak = 1. - d * d / (peak + d - startCompression);
|
||||
color *= newPeak / peak;
|
||||
|
||||
float g = 1. - 1. / (desaturation * (peak - newPeak) + 1.);
|
||||
return lerp(color, newPeak * float3(1, 1, 1), g);
|
||||
}
|
||||
|
||||
PSOutput main(PSInput input)
|
||||
{
|
||||
PSOutput output;
|
||||
float3 color = textures[pushConstants.SourceTextureID].Sample(mySampler, input.UV).rgb;
|
||||
float3 mapped = float3(1.0, 1.0, 1.0) - exp(-color * pushConstants.Exposure);
|
||||
|
||||
color = pow(mapped, float3(pushConstants.Gamma, pushConstants.Gamma, pushConstants.Gamma));
|
||||
|
||||
output.oColor0 = float4(color, 1);
|
||||
return output;
|
||||
}
|
||||
110
Data/Shaders/Vulkan/tonemap.vert
Normal file
@@ -0,0 +1,110 @@
|
||||
// Transforms
|
||||
struct ModelData
|
||||
{
|
||||
float4x4 model;
|
||||
};
|
||||
[[vk::binding(0, 0)]]
|
||||
StructuredBuffer<ModelData> model : register(t1);
|
||||
|
||||
// Vertex
|
||||
struct Vertex
|
||||
{
|
||||
float3 position;
|
||||
float uv_x;
|
||||
float3 normal;
|
||||
float uv_y;
|
||||
float3 tangent;
|
||||
float3 bitangent;
|
||||
};
|
||||
|
||||
[[vk::binding(0, 1)]]
|
||||
StructuredBuffer<Vertex> vertexBuffer : register(t2);
|
||||
|
||||
// Samplers
|
||||
[[vk::binding(0, 2)]]
|
||||
SamplerState mySampler : register(s0);
|
||||
|
||||
// Materials
|
||||
struct Material
|
||||
{
|
||||
bool hasAlbedo;
|
||||
float3 albedo;
|
||||
bool hasNormal;
|
||||
bool hasMetalness;
|
||||
bool hasRoughness;
|
||||
bool hasAO;
|
||||
float metalnessValue;
|
||||
float roughnessValue;
|
||||
float aoValue;
|
||||
int albedoTextureId;
|
||||
int normalTextureId;
|
||||
int metalnessTextureId;
|
||||
int roughnessTextureId;
|
||||
int aoTextureId;
|
||||
};
|
||||
[[vk::binding(0, 3)]]
|
||||
StructuredBuffer<Material> material;
|
||||
|
||||
// Textures
|
||||
[[vk::binding(0, 4)]]
|
||||
Texture2D textures[];
|
||||
|
||||
// Lights
|
||||
struct Light
|
||||
{
|
||||
float3 position;
|
||||
int type;
|
||||
float4 color;
|
||||
float3 direction;
|
||||
float outerConeAngle;
|
||||
float innerConeAngle;
|
||||
bool castShadow;
|
||||
int shadowMapTextureId[4];
|
||||
int transformId[4];
|
||||
};
|
||||
|
||||
[[vk::binding(0, 5)]]
|
||||
StructuredBuffer<Light> lights;
|
||||
|
||||
// Cameras
|
||||
struct CameraView {
|
||||
float4x4 View;
|
||||
float4x4 Projection;
|
||||
float4x4 ViewProjection;
|
||||
float4x4 InverseView;
|
||||
float4x4 InverseProjection;
|
||||
float3 Position;
|
||||
float Near;
|
||||
float Far;
|
||||
};
|
||||
[[vk::binding(0, 6)]]
|
||||
StructuredBuffer<CameraView> cameras;
|
||||
|
||||
struct TonemapPushConstant
|
||||
{
|
||||
float Exposure;
|
||||
float Gamma;
|
||||
int SourceTextureID;
|
||||
};
|
||||
|
||||
[[vk::push_constant]]
|
||||
TonemapPushConstant pushConstants;
|
||||
|
||||
// Outputs
|
||||
struct VSOutput {
|
||||
float4 Position : SV_Position;
|
||||
float2 UV : TEXCOORD0;
|
||||
};
|
||||
|
||||
|
||||
// Main vertex shader
|
||||
VSOutput main(uint vertexIndex : SV_VertexID)
|
||||
{
|
||||
VSOutput output;
|
||||
|
||||
Vertex v = vertexBuffer[vertexIndex];
|
||||
output.UV = float2(v.uv_x, v.uv_y);
|
||||
output.Position = float4(v.position, 1.0f);
|
||||
|
||||
return output;
|
||||
}
|
||||
186
Data/Shaders/Vulkan/triangle.frag
Normal file
@@ -0,0 +1,186 @@
|
||||
// Transforms
|
||||
struct ModelData
|
||||
{
|
||||
float4x4 model;
|
||||
};
|
||||
[[vk::binding(0, 0)]]
|
||||
StructuredBuffer<ModelData> model : register(t1);
|
||||
|
||||
// Vertex
|
||||
struct Vertex
|
||||
{
|
||||
float3 position;
|
||||
float uv_x;
|
||||
float3 normal;
|
||||
float uv_y;
|
||||
float4 tangent;
|
||||
float4 bitangent;
|
||||
};
|
||||
|
||||
[[vk::binding(0, 1)]]
|
||||
StructuredBuffer<Vertex> vertexBuffer : register(t2);
|
||||
|
||||
// Samplers
|
||||
[[vk::binding(0, 2)]]
|
||||
SamplerState mySampler : register(s0);
|
||||
|
||||
// Materials
|
||||
struct Material
|
||||
{
|
||||
bool hasAlbedo;
|
||||
float3 albedo;
|
||||
bool hasNormal;
|
||||
bool hasMetalness;
|
||||
bool hasRoughness;
|
||||
bool hasAO;
|
||||
float metalnessValue;
|
||||
float roughnessValue;
|
||||
float aoValue;
|
||||
int albedoTextureId;
|
||||
int normalTextureId;
|
||||
int metalnessTextureId;
|
||||
int roughnessTextureId;
|
||||
int aoTextureId;
|
||||
};
|
||||
[[vk::binding(0, 3)]]
|
||||
StructuredBuffer<Material> material;
|
||||
|
||||
// Textures
|
||||
[[vk::binding(0, 4)]]
|
||||
Texture2D textures[];
|
||||
|
||||
// Lights
|
||||
struct Light
|
||||
{
|
||||
float3 position;
|
||||
int type;
|
||||
float4 color;
|
||||
float3 direction;
|
||||
float outerConeAngle;
|
||||
float innerConeAngle;
|
||||
bool castShadow;
|
||||
int shadowMapTextureId[4];
|
||||
int transformId[4];
|
||||
};
|
||||
|
||||
[[vk::binding(0, 5)]]
|
||||
StructuredBuffer<Light> lights;
|
||||
|
||||
// Cameras
|
||||
struct CameraView {
|
||||
float4x4 View;
|
||||
float4x4 Projection;
|
||||
float4x4 ViewProjection;
|
||||
float4x4 InverseView;
|
||||
float4x4 InverseProjection;
|
||||
float3 Position;
|
||||
float Near;
|
||||
float Far;
|
||||
};
|
||||
[[vk::binding(0, 6)]]
|
||||
StructuredBuffer<CameraView> cameras;
|
||||
|
||||
struct PSInput
|
||||
{
|
||||
float4 Position : SV_Position;
|
||||
float3 Color : TEXCOORD0;
|
||||
float2 UV : TEXCOORD1;
|
||||
float3 Normal : TEXCOORD2;
|
||||
float3 Tangent : TEXCOORD3;
|
||||
float3 Bitangent : TEXCOORD4;
|
||||
};
|
||||
|
||||
struct PSOutput {
|
||||
float4 oColor0 : SV_TARGET;
|
||||
float4 oNormal : SV_TARGET1;
|
||||
float4 oMaterial : SV_TARGET2;
|
||||
float4 oEntityID : SV_TARGET3;
|
||||
};
|
||||
|
||||
struct ModelPushConstant
|
||||
{
|
||||
int modelIndex; // Push constant data
|
||||
int materialIndex;
|
||||
int cameraID;
|
||||
float entityID;
|
||||
};
|
||||
|
||||
[[vk::push_constant]]
|
||||
ModelPushConstant pushConstants;
|
||||
|
||||
|
||||
|
||||
PSOutput main(PSInput input)
|
||||
{
|
||||
PSOutput output;
|
||||
|
||||
Material inMaterial = material[pushConstants.materialIndex];
|
||||
// NORMAL
|
||||
// TODO use TBN matrix
|
||||
float3 T = input.Tangent.xyz;
|
||||
float3 B = input.Bitangent.xyz;
|
||||
float3 N = input.Normal.xyz;
|
||||
float3x3 TBN = float3x3(T, B, N);
|
||||
|
||||
float3 normal = float3(0.0, 0.0, 1.0);
|
||||
if(inMaterial.hasNormal == 1)
|
||||
{
|
||||
normal = textures[inMaterial.normalTextureId].Sample(mySampler, input.UV).rgb;
|
||||
normal.xyz = normal.zxy;
|
||||
normal = normal * 2.0f - 1.0f;
|
||||
}
|
||||
else
|
||||
{
|
||||
normal = normal;
|
||||
}
|
||||
|
||||
//normal = input.Normal;
|
||||
normal = mul(transpose(TBN), normal);
|
||||
normal = normal / 2.0f + 0.5f;
|
||||
output.oNormal = float4(normal, 1.0f);
|
||||
|
||||
// MATERIAL
|
||||
|
||||
// ALBEDO COLOR
|
||||
float4 albedoColor = float4(inMaterial.albedo.xyz, 1.0f);
|
||||
if(inMaterial.hasAlbedo == 1)
|
||||
{
|
||||
float4 albedoSample = textures[inMaterial.albedoTextureId].Sample(mySampler, input.UV);
|
||||
|
||||
// Alpha cutout?
|
||||
if(albedoSample.a < 0.001f)
|
||||
{
|
||||
discard;
|
||||
}
|
||||
|
||||
albedoColor.xyz = albedoSample.xyz;
|
||||
}
|
||||
output.oColor0 = albedoColor;
|
||||
|
||||
// MATERIAL PROPERTIES
|
||||
float metalnessValue = inMaterial.metalnessValue;
|
||||
if(inMaterial.hasMetalness == 1)
|
||||
{
|
||||
// TODO: Sample from metal texture
|
||||
}
|
||||
|
||||
float aoValue = inMaterial.aoValue;
|
||||
if(inMaterial.hasAO == 1)
|
||||
{
|
||||
// TODO: Sample from AO texture
|
||||
}
|
||||
|
||||
float roughnessValue = inMaterial.roughnessValue;
|
||||
if(inMaterial.hasRoughness == 1)
|
||||
{
|
||||
// TODO: Sample from roughness texture
|
||||
}
|
||||
|
||||
float3 materialOuput = float3(inMaterial.metalnessValue, inMaterial.aoValue, inMaterial.roughnessValue);
|
||||
|
||||
output.oMaterial = float4(materialOuput, 1.0f);
|
||||
|
||||
output.oEntityID = float4(pushConstants.entityID, 0.0f, 0.0f, 1.0f);
|
||||
|
||||
return output;
|
||||
}
|
||||
154
Data/Shaders/Vulkan/triangle.vert
Normal file
@@ -0,0 +1,154 @@
|
||||
// Transforms
|
||||
struct ModelData
|
||||
{
|
||||
float4x4 model;
|
||||
};
|
||||
[[vk::binding(0, 0)]]
|
||||
StructuredBuffer<ModelData> model : register(t1);
|
||||
|
||||
// Vertex
|
||||
struct Vertex
|
||||
{
|
||||
float3 position;
|
||||
float uv_x;
|
||||
float3 normal;
|
||||
float uv_y;
|
||||
float4 tangent;
|
||||
float4 bitangent;
|
||||
};
|
||||
|
||||
[[vk::binding(0, 1)]]
|
||||
StructuredBuffer<Vertex> vertexBuffer : register(t2);
|
||||
|
||||
// Samplers
|
||||
[[vk::binding(0, 2)]]
|
||||
SamplerState mySampler : register(s0);
|
||||
|
||||
// Materials
|
||||
struct Material
|
||||
{
|
||||
bool hasAlbedo;
|
||||
float3 albedo;
|
||||
bool hasNormal;
|
||||
bool hasMetalness;
|
||||
bool hasRoughness;
|
||||
bool hasAO;
|
||||
float metalnessValue;
|
||||
float roughnessValue;
|
||||
float aoValue;
|
||||
int albedoTextureId;
|
||||
int normalTextureId;
|
||||
int metalnessTextureId;
|
||||
int roughnessTextureId;
|
||||
int aoTextureId;
|
||||
};
|
||||
[[vk::binding(0, 3)]]
|
||||
StructuredBuffer<Material> material;
|
||||
|
||||
// Textures
|
||||
[[vk::binding(0, 4)]]
|
||||
Texture2D textures[];
|
||||
|
||||
// Lights
|
||||
struct Light
|
||||
{
|
||||
float3 position;
|
||||
int type;
|
||||
float4 color;
|
||||
float3 direction;
|
||||
float outerConeAngle;
|
||||
float innerConeAngle;
|
||||
bool castShadow;
|
||||
int shadowMapTextureId[4];
|
||||
int transformId[4];
|
||||
};
|
||||
|
||||
[[vk::binding(0, 5)]]
|
||||
StructuredBuffer<Light> lights;
|
||||
|
||||
// Cameras
|
||||
struct CameraView {
|
||||
float4x4 View;
|
||||
float4x4 Projection;
|
||||
float4x4 ViewProjection;
|
||||
float4x4 InverseView;
|
||||
float4x4 InverseProjection;
|
||||
float3 Position;
|
||||
float Near;
|
||||
float Far;
|
||||
};
|
||||
[[vk::binding(0, 6)]]
|
||||
StructuredBuffer<CameraView> cameras;
|
||||
|
||||
struct ModelPushConstant
|
||||
{
|
||||
int modelIndex; // Push constant data
|
||||
int materialIndex;
|
||||
int cameraID;
|
||||
float entityID;
|
||||
};
|
||||
|
||||
[[vk::push_constant]]
|
||||
ModelPushConstant pushConstants;
|
||||
|
||||
// Outputs
|
||||
struct VSOutput
|
||||
{
|
||||
float4 Position : SV_Position;
|
||||
float3 Color : TEXCOORD0;
|
||||
float2 UV : TEXCOORD1;
|
||||
float3 Normal : TEXCOORD2;
|
||||
float3 Tangent : TEXCOORD3;
|
||||
float3 Bitangent : TEXCOORD4;
|
||||
};
|
||||
|
||||
float3x3 invert(float3x3 m)
|
||||
{
|
||||
float3 a = m[0];
|
||||
float3 b = m[1];
|
||||
float3 c = m[2];
|
||||
|
||||
float3 r0 = cross(b, c);
|
||||
float3 r1 = cross(c, a);
|
||||
float3 r2 = cross(a, b);
|
||||
|
||||
float det = dot(r2, c);
|
||||
|
||||
// Return identity if not invertible (optional fallback)
|
||||
if (abs(det) < 1e-6)
|
||||
return float3x3(1.0, 0.0, 0.0,
|
||||
0.0, 1.0, 0.0,
|
||||
0.0, 0.0, 1.0);
|
||||
|
||||
float invDet = 1.0 / det;
|
||||
|
||||
return float3x3(r0 * invDet,
|
||||
r1 * invDet,
|
||||
r2 * invDet);
|
||||
}
|
||||
|
||||
// Main vertex shader
|
||||
VSOutput main(uint vertexIndex : SV_VertexID)
|
||||
{
|
||||
VSOutput output;
|
||||
|
||||
CameraView camView = cameras[pushConstants.cameraID];
|
||||
ModelData modelData = model[pushConstants.modelIndex];
|
||||
|
||||
// Load vertex data from the buffer
|
||||
Vertex v = vertexBuffer[vertexIndex];
|
||||
|
||||
// Output the position of each vertex
|
||||
output.Position = mul(camView.Projection, mul(camView.View, mul(modelData.model, float4(v.position, 1.0f))));
|
||||
output.Color = normalize(float3(v.position.xyz));
|
||||
output.UV = float2(v.uv_x, v.uv_y);
|
||||
|
||||
float3x3 upper3x3 = (float3x3)modelData.model;
|
||||
float3x3 normalMatrix = transpose(invert(upper3x3));
|
||||
output.Bitangent = mul(normalMatrix, normalize(v.bitangent.xyz));
|
||||
output.Normal = mul(normalMatrix, normalize(v.normal.xyz));
|
||||
output.Tangent = mul(normalMatrix, normalize(v.tangent.xyz));
|
||||
|
||||
//output.Normal = v.normal.xyz;
|
||||
return output;
|
||||
}
|
||||
347
Data/Shaders/Vulkan/volumetric.frag
Normal file
@@ -0,0 +1,347 @@
|
||||
// Transforms
|
||||
struct ModelData
|
||||
{
|
||||
float4x4 model;
|
||||
};
|
||||
[[vk::binding(0, 0)]]
|
||||
StructuredBuffer<ModelData> model : register(t1);
|
||||
|
||||
// Vertex
|
||||
struct Vertex
|
||||
{
|
||||
float3 position;
|
||||
float uv_x;
|
||||
float3 normal;
|
||||
float uv_y;
|
||||
float3 tangent;
|
||||
float3 bitangent;
|
||||
};
|
||||
|
||||
[[vk::binding(0, 1)]]
|
||||
StructuredBuffer<Vertex> vertexBuffer : register(t2);
|
||||
|
||||
// Samplers
|
||||
[[vk::binding(0, 2)]]
|
||||
SamplerState mySampler : register(s0);
|
||||
|
||||
// Materials
|
||||
struct Material
|
||||
{
|
||||
bool hasAlbedo;
|
||||
float3 albedo;
|
||||
bool hasNormal;
|
||||
bool hasMetalness;
|
||||
bool hasRoughness;
|
||||
bool hasAO;
|
||||
float metalnessValue;
|
||||
float roughnessValue;
|
||||
float aoValue;
|
||||
int albedoTextureId;
|
||||
int normalTextureId;
|
||||
int metalnessTextureId;
|
||||
int roughnessTextureId;
|
||||
int aoTextureId;
|
||||
};
|
||||
[[vk::binding(0, 3)]]
|
||||
StructuredBuffer<Material> material;
|
||||
|
||||
// Textures
|
||||
[[vk::binding(0, 4)]]
|
||||
Texture2D textures[];
|
||||
|
||||
// Lights
|
||||
struct Light
|
||||
{
|
||||
float3 position;
|
||||
int type;
|
||||
float4 color;
|
||||
float3 direction;
|
||||
float outerConeAngle;
|
||||
float innerConeAngle;
|
||||
bool castShadow;
|
||||
int shadowMapTextureId[4];
|
||||
int transformId[4];
|
||||
};
|
||||
|
||||
[[vk::binding(0, 5)]]
|
||||
StructuredBuffer<Light> lights;
|
||||
|
||||
// Cameras
|
||||
struct CameraView {
|
||||
float4x4 View;
|
||||
float4x4 Projection;
|
||||
float4x4 ViewProjection;
|
||||
float4x4 InverseView;
|
||||
float4x4 InverseProjection;
|
||||
float3 Position;
|
||||
float Near;
|
||||
float Far;
|
||||
};
|
||||
[[vk::binding(0, 6)]]
|
||||
StructuredBuffer<CameraView> cameras;
|
||||
|
||||
struct PSInput
|
||||
{
|
||||
float4 Position : SV_Position;
|
||||
float2 UV : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct PSOutput {
|
||||
float4 oColor0 : SV_TARGET;
|
||||
};
|
||||
|
||||
struct VolumetricConstant
|
||||
{
|
||||
int DepthTextureID;
|
||||
int StepCount;
|
||||
float FogAmount;
|
||||
float Exponant;
|
||||
int CamViewID;
|
||||
int LightCount;
|
||||
float Ambient;
|
||||
float Time;
|
||||
float NoiseSpeed;
|
||||
float NoiseScale;
|
||||
float NoiseStrength;
|
||||
float CSMSplits[4];
|
||||
};
|
||||
|
||||
[[vk::push_constant]]
|
||||
VolumetricConstant pushConstants;
|
||||
|
||||
float2 GetTexelSize(Texture2D tex)
|
||||
{
|
||||
uint width, height;
|
||||
tex.GetDimensions(width, height);
|
||||
return 1.0 / float2(width, height);
|
||||
}
|
||||
|
||||
float LinearizeDepth(float depth, float nearPlane, float farPlane)
|
||||
{
|
||||
return (2.0 * nearPlane) / (farPlane + nearPlane - (1.0 - depth) * (farPlane - nearPlane));
|
||||
}
|
||||
|
||||
float ComputeScattering(float lightDotView)
|
||||
{
|
||||
float PI = 3.141592653589793f;
|
||||
float result = 1.0f - pushConstants.FogAmount;
|
||||
result /= (4.0f * PI * pow(1.0f + pushConstants.FogAmount * pushConstants.FogAmount - (1.0f * pushConstants.FogAmount) * lightDotView, 1.5f));
|
||||
return result;
|
||||
}
|
||||
|
||||
float3 WorldPosFromDepth(float depth, float2 uv, float4x4 invProj, float4x4 invView)
|
||||
{
|
||||
float z = depth;
|
||||
float4 clipSpacePosition = float4(uv.x * 2.0 - 1.0, (uv.y * 2.0 - 1.0), z, 1.0f);
|
||||
float4 viewSpacePosition = mul(invProj, clipSpacePosition);
|
||||
viewSpacePosition /= viewSpacePosition.w;
|
||||
|
||||
float4 worldSpacePosition = mul(invView, viewSpacePosition);
|
||||
return worldSpacePosition.xyz;
|
||||
}
|
||||
|
||||
// Simplex 3D Noise
|
||||
float mod289(float x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
|
||||
float3 mod289(float3 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
|
||||
float4 mod289(float4 x) { return x - floor(x * (1.0 / 289.0)) * 289.0; }
|
||||
|
||||
float4 permute(float4 x) { return mod289(((x*34.0)+1.0)*x); }
|
||||
|
||||
float4 taylorInvSqrt(float4 r) { return 1.79284291400159 - 0.85373472095314 * r; }
|
||||
|
||||
float snoise(float3 v)
|
||||
{
|
||||
const float2 C = float2(1.0/6.0, 1.0/3.0) ;
|
||||
const float4 D = float4(0.0, 0.5, 1.0, 2.0);
|
||||
|
||||
// First corner
|
||||
float3 i = floor(v + dot(v, C.yyy));
|
||||
float3 x0 = v - i + dot(i, C.xxx);
|
||||
|
||||
// Other corners
|
||||
float3 g = step(x0.yzx, x0.xyz);
|
||||
float3 l = 1.0 - g;
|
||||
float3 i1 = min(g.xyz, l.zxy);
|
||||
float3 i2 = max(g.xyz, l.zxy);
|
||||
|
||||
// x0 = x0 - 0.0 + 0.0 * C.xxx;
|
||||
float3 x1 = x0 - i1 + C.xxx;
|
||||
float3 x2 = x0 - i2 + C.yyy;
|
||||
float3 x3 = x0 - 1.0 + 3.0 * C.xxx;
|
||||
|
||||
// Permutations
|
||||
i = mod289(i);
|
||||
float4 p = permute(permute(permute(
|
||||
i.z + float4(0.0, i1.z, i2.z, 1.0))
|
||||
+ i.y + float4(0.0, i1.y, i2.y, 1.0))
|
||||
+ i.x + float4(0.0, i1.x, i2.x, 1.0));
|
||||
|
||||
// Gradients: 7x7 points over a cube, mapped onto a unit sphere
|
||||
float4 j = p - 49.0 * floor(p * (1.0 / 49.0)); // mod(p,7*7)
|
||||
|
||||
float4 x_ = floor(j * (1.0 / 7.0));
|
||||
float4 y_ = floor(j - 7.0 * x_); // mod(j,7)
|
||||
|
||||
float4 x = (x_ * 2.0 + 0.5) / 7.0 - 1.0;
|
||||
float4 y = (y_ * 2.0 + 0.5) / 7.0 - 1.0;
|
||||
|
||||
float4 h = 1.0 - abs(x) - abs(y);
|
||||
|
||||
float4 b0 = float4(x.xy, y.xy);
|
||||
float4 b1 = float4(x.zw, y.zw);
|
||||
|
||||
float4 s0 = floor(b0) * 2.0 + 1.0;
|
||||
float4 s1 = floor(b1) * 2.0 + 1.0;
|
||||
float4 sh = -step(h, 0.0);
|
||||
|
||||
float4 a0 = b0.xzyw + s0.xzyw * sh.xxyy;
|
||||
float4 a1 = b1.xzyw + s1.xzyw * sh.zzww;
|
||||
|
||||
float3 g0 = float3(a0.xy, h.x);
|
||||
float3 g1 = float3(a0.zw, h.y);
|
||||
float3 g2 = float3(a1.xy, h.z);
|
||||
float3 g3 = float3(a1.zw, h.w);
|
||||
|
||||
// Normalize gradients
|
||||
float4 norm = taylorInvSqrt(float4(dot(g0,g0), dot(g1,g1), dot(g2,g2), dot(g3,g3)));
|
||||
g0 *= norm.x;
|
||||
g1 *= norm.y;
|
||||
g2 *= norm.z;
|
||||
g3 *= norm.w;
|
||||
|
||||
// Mix final noise value
|
||||
float4 m = max(0.6 - float4(dot(x0,x0), dot(x1,x1), dot(x2,x2), dot(x3,x3)), 0.0);
|
||||
m = m * m;
|
||||
return 42.0 * dot(m*m, float4(dot(g0,x0), dot(g1,x1), dot(g2,x2), dot(g3,x3)));
|
||||
}
|
||||
|
||||
int GetCSMSplit(float depth)
|
||||
{
|
||||
for(int i = 0; i < 4; i++)
|
||||
{
|
||||
float csmSplitDepth = pushConstants.CSMSplits[i];
|
||||
|
||||
if(depth < csmSplitDepth + 0.000001)
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
PSOutput main(PSInput input)
|
||||
{
|
||||
float ditherPattern[4][4] = { { 0.0f, 0.5f, 0.125f, 0.625f},
|
||||
{ 0.75f, 0.22f, 0.875f, 0.375f},
|
||||
{ 0.1875f, 0.6875f, 0.0625f, 0.5625},
|
||||
{ 0.9375f, 0.4375f, 0.8125f, 0.3125} };
|
||||
|
||||
CameraView camView = cameras[pushConstants.CamViewID];
|
||||
float3 startPosition = camView.Position;
|
||||
|
||||
int depthTexture = pushConstants.DepthTextureID;
|
||||
float depth = textures[depthTexture].Sample(mySampler, input.UV).r;
|
||||
|
||||
float3 worldPos = WorldPosFromDepth(depth, input.UV, camView.InverseProjection, camView.InverseView);
|
||||
|
||||
float3 rayVector = worldPos - startPosition;
|
||||
|
||||
float rayLength = length(rayVector);
|
||||
|
||||
PSOutput output;
|
||||
if(rayLength > 1000.0)
|
||||
{
|
||||
output.oColor0 = float4(0.0f, 0.0f, 0, 0.0f);
|
||||
//return output;
|
||||
}
|
||||
|
||||
float stepLength = rayLength / pushConstants.StepCount;
|
||||
float3 rayDirection = rayVector / rayLength;
|
||||
float3 step = rayDirection * stepLength;
|
||||
|
||||
float3 accumFog = float3(0, 0, 0);
|
||||
float3 currentPosition = startPosition;
|
||||
for(int i = 0; i < pushConstants.StepCount; i++)
|
||||
{
|
||||
for(int l = 0; l < pushConstants.LightCount; l++)
|
||||
{
|
||||
Light light = lights[l];
|
||||
if(light.type == 0)
|
||||
{
|
||||
float lightDepth = length(worldPos - camView.Position);
|
||||
int splitIndex = GetCSMSplit(lightDepth);
|
||||
|
||||
if(splitIndex == -1)
|
||||
{
|
||||
accumFog += (ComputeScattering(dot(rayDirection, light.direction)).rrr * light.color.xyz) * pushConstants.Exponant;
|
||||
}
|
||||
else
|
||||
{
|
||||
CameraView lightView = cameras[light.transformId[splitIndex]];
|
||||
float4 fragPosLightSpace = mul(lightView.Projection, mul(lightView.View, float4(currentPosition, 1.0)));
|
||||
float3 projCoords = fragPosLightSpace.xyz / fragPosLightSpace.w;
|
||||
projCoords.xy = projCoords.xy * 0.5 + 0.5;
|
||||
|
||||
float currentDepth = projCoords.z;
|
||||
float closestDepth = textures[light.shadowMapTextureId[splitIndex]].Sample(mySampler, projCoords.xy).r;
|
||||
|
||||
float3 noiseOffset = float3(pushConstants.NoiseSpeed * pushConstants.Time, pushConstants.NoiseSpeed * pushConstants.Time, pushConstants.NoiseSpeed * pushConstants.Time);
|
||||
float3 noiseSamplePos = (currentPosition + noiseOffset) * pushConstants.NoiseScale;
|
||||
if(closestDepth < currentDepth)
|
||||
{
|
||||
accumFog += (ComputeScattering(dot(rayDirection, light.direction)).rrr * light.color.xyz) * pushConstants.Exponant * ((snoise(noiseSamplePos.xyz) + 1.0) / 2.0);
|
||||
}
|
||||
else
|
||||
{
|
||||
accumFog += (ComputeScattering(dot(rayDirection, light.direction)).rrr * light.color.xyz) * pushConstants.Ambient * ((snoise(noiseSamplePos.xyz) + 1.0) / 2.0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
else if(light.type == 1)
|
||||
{
|
||||
float3 lightToFrag = currentPosition - light.position;
|
||||
float distance = length(lightToFrag);
|
||||
float3 lightDir = normalize(-lightToFrag);
|
||||
float attenuation = 1.0 / (distance * distance);
|
||||
attenuation = 1.0 - smoothstep(0.0, 3.0f, distance);
|
||||
float3 noiseOffset = float3(pushConstants.NoiseSpeed * pushConstants.Time, pushConstants.NoiseSpeed * pushConstants.Time, pushConstants.NoiseSpeed * pushConstants.Time);
|
||||
float3 noiseSamplePos = (currentPosition + noiseOffset) * pushConstants.NoiseScale;
|
||||
float lightScatter = (snoise(noiseSamplePos.xyz) + 1.0) * 0.5;
|
||||
|
||||
float3 scatterTerm = ComputeScattering(dot(rayDirection, lightDir)).rrr * light.color.xyz;
|
||||
|
||||
accumFog += scatterTerm * lightScatter * pushConstants.Exponant * attenuation;
|
||||
}
|
||||
else if(light.type == 2)
|
||||
{
|
||||
float3 lightToFrag = currentPosition - light.position;
|
||||
float distance = length(lightToFrag);
|
||||
float3 lightDir = normalize(-lightToFrag);
|
||||
float attenuation = 1.0 / (distance * distance);
|
||||
attenuation = 1.0 - smoothstep(0.0, 6.0f, distance);
|
||||
float3 noiseOffset = float3(pushConstants.NoiseSpeed * pushConstants.Time, pushConstants.NoiseSpeed * pushConstants.Time, pushConstants.NoiseSpeed * pushConstants.Time);
|
||||
float3 noiseSamplePos = (currentPosition + noiseOffset) * pushConstants.NoiseScale;
|
||||
float lightScatter = (snoise(noiseSamplePos.xyz) + 1.0) * 0.5;
|
||||
|
||||
float theta = dot(lightDir, normalize(-light.direction));
|
||||
float epsilon = light.innerConeAngle - light.outerConeAngle;
|
||||
float intensity = clamp((theta - light.outerConeAngle) / epsilon, 0.0, 1.0);
|
||||
float3 scatterTerm = ComputeScattering(dot(rayDirection, lightDir)).rrr * light.color.xyz;
|
||||
accumFog += scatterTerm * lightScatter * pushConstants.Exponant * attenuation * intensity;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
currentPosition += step ;
|
||||
|
||||
}
|
||||
|
||||
accumFog /= pushConstants.StepCount;
|
||||
|
||||
output.oColor0 = float4(accumFog.x, accumFog.y, accumFog.z, 1.0f);
|
||||
return output;
|
||||
}
|
||||
119
Data/Shaders/Vulkan/volumetric.vert
Normal file
@@ -0,0 +1,119 @@
|
||||
// Transforms
|
||||
struct ModelData
|
||||
{
|
||||
float4x4 model;
|
||||
};
|
||||
[[vk::binding(0, 0)]]
|
||||
StructuredBuffer<ModelData> model : register(t1);
|
||||
|
||||
// Vertex
|
||||
struct Vertex
|
||||
{
|
||||
float3 position;
|
||||
float uv_x;
|
||||
float3 normal;
|
||||
float uv_y;
|
||||
float3 tangent;
|
||||
float3 bitangent;
|
||||
};
|
||||
|
||||
[[vk::binding(0, 1)]]
|
||||
StructuredBuffer<Vertex> vertexBuffer : register(t2);
|
||||
|
||||
// Samplers
|
||||
[[vk::binding(0, 2)]]
|
||||
SamplerState mySampler : register(s0);
|
||||
|
||||
// Materials
|
||||
struct Material
|
||||
{
|
||||
bool hasAlbedo;
|
||||
float3 albedo;
|
||||
bool hasNormal;
|
||||
bool hasMetalness;
|
||||
bool hasRoughness;
|
||||
bool hasAO;
|
||||
float metalnessValue;
|
||||
float roughnessValue;
|
||||
float aoValue;
|
||||
int albedoTextureId;
|
||||
int normalTextureId;
|
||||
int metalnessTextureId;
|
||||
int roughnessTextureId;
|
||||
int aoTextureId;
|
||||
};
|
||||
[[vk::binding(0, 3)]]
|
||||
StructuredBuffer<Material> material;
|
||||
|
||||
// Textures
|
||||
[[vk::binding(0, 4)]]
|
||||
Texture2D textures[];
|
||||
|
||||
// Lights
|
||||
struct Light
|
||||
{
|
||||
float3 position;
|
||||
int type;
|
||||
float4 color;
|
||||
float3 direction;
|
||||
float outerConeAngle;
|
||||
float innerConeAngle;
|
||||
bool castShadow;
|
||||
int shadowMapTextureId[4];
|
||||
int transformId[4];
|
||||
};
|
||||
|
||||
[[vk::binding(0, 5)]]
|
||||
StructuredBuffer<Light> lights;
|
||||
|
||||
// Cameras
|
||||
struct CameraView {
|
||||
float4x4 View;
|
||||
float4x4 Projection;
|
||||
float4x4 ViewProjection;
|
||||
float4x4 InverseView;
|
||||
float4x4 InverseProjection;
|
||||
float3 Position;
|
||||
float Near;
|
||||
float Far;
|
||||
};
|
||||
[[vk::binding(0, 6)]]
|
||||
StructuredBuffer<CameraView> cameras;
|
||||
|
||||
struct VolumetricConstant
|
||||
{
|
||||
int DepthTextureID;
|
||||
int StepCount;
|
||||
float FogAmount;
|
||||
float Exponant;
|
||||
int CamViewID;
|
||||
int LightCount;
|
||||
float Ambient;
|
||||
float Time;
|
||||
float NoiseSpeed;
|
||||
float NoiseScale;
|
||||
float NoiseStrength;
|
||||
float CSMSplits[4];
|
||||
};
|
||||
|
||||
[[vk::push_constant]]
|
||||
VolumetricConstant pushConstants;
|
||||
|
||||
// Outputs
|
||||
struct VSOutput
|
||||
{
|
||||
float4 Position : SV_Position;
|
||||
float2 UV : TEXCOORD0;
|
||||
};
|
||||
|
||||
// Main vertex shader
|
||||
VSOutput main(uint vertexIndex : SV_VertexID)
|
||||
{
|
||||
VSOutput output;
|
||||
|
||||
Vertex v = vertexBuffer[vertexIndex];
|
||||
output.UV = float2(v.uv_x, v.uv_y);
|
||||
output.Position = float4(v.position, 1.0f);
|
||||
|
||||
return output;
|
||||
}
|
||||