Skip to content

Commit

Permalink
[Examples] Add SPIR-V shaders for PBR example.
Browse files Browse the repository at this point in the history
- Added Vulkan GLSL and SPIR-V shaders for PBR example (derived from OpenGL GLSL shaders).
- Also use actual swap-chain sample count in MultiContext example instead of descriptor values (in case platform only supports lower sample count).
  • Loading branch information
LukasBanana committed Jul 28, 2024
1 parent f5f0c53 commit 17800ec
Show file tree
Hide file tree
Showing 14 changed files with 313 additions and 33 deletions.
7 changes: 7 additions & 0 deletions examples/Cpp/CompileAllGlslExamplesToSpirv.bat
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,13 @@ call :CompileGlslToSpirv MultiThreading/Example.450core.vert
call :CompileGlslToSpirv MultiThreading/Example.450core.frag
echo DONE

echo ####### PBR #######
call :CompileGlslToSpirv PBR/Example.Mesh.450core.vert
call :CompileGlslToSpirv PBR/Example.Mesh.450core.frag
call :CompileGlslToSpirv PBR/Example.Sky.450core.vert
call :CompileGlslToSpirv PBR/Example.Sky.450core.frag
echo DONE

echo ####### PostProcessing #######
call :CompileGlslToSpirv PostProcessing/Scene.450core.vert
call :CompileGlslToSpirv PostProcessing/Scene.450core.frag
Expand Down
4 changes: 2 additions & 2 deletions examples/Cpp/MultiContext/Example.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -194,13 +194,13 @@ int main(int argc, char* argv[])
pipelineDesc.fragmentShader = fragShader;
pipelineDesc.renderPass = swapChain1->GetRenderPass();
pipelineDesc.primitiveTopology = LLGL::PrimitiveTopology::TriangleStrip;
pipelineDesc.rasterizer.multiSampleEnabled = (swapChainDesc[0].samples > 1);
pipelineDesc.rasterizer.multiSampleEnabled = (swapChain1->GetSamples() > 1);
}
pipeline[0] = renderer->CreatePipelineState(pipelineDesc);

{
pipelineDesc.renderPass = swapChain2->GetRenderPass();
pipelineDesc.rasterizer.multiSampleEnabled = (swapChainDesc[1].samples > 1);
pipelineDesc.rasterizer.multiSampleEnabled = (swapChain2->GetSamples() > 1);

// Only enable logic operations if it's supported, otherwise an exception is thrown
if (logicOpSupported)
Expand Down
129 changes: 129 additions & 0 deletions examples/Cpp/PBR/Example.Mesh.450core.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
// PBR GLSL Mesh Fragment Shader

#version 450 core

#define M_PI 3.141592654

layout(std140, binding = 1) uniform Settings
{
mat4 cMatrix;
mat4 vpMatrix;
mat4 wMatrix;
vec2 aspectRatio;
float mipCount;
float _pad0;
vec4 lightDir;
uint skyboxLayer;
uint materialLayer;
uvec2 _pad1;
};

layout(binding = 2) uniform sampler smpl;
layout(binding = 3) uniform textureCubeArray skyBox;
layout(binding = 4) uniform texture2DArray colorMaps;
layout(binding = 5) uniform texture2DArray normalMaps;
layout(binding = 6) uniform texture2DArray roughnessMaps;
layout(binding = 7) uniform texture2DArray metallicMaps;

layout(location = 0) in VMeshOut
{
vec3 tangent;
vec3 bitangent;
vec3 normal;
vec2 texCoord;
vec4 worldPos;
}
inp;

layout(location = 0) out vec4 outColor;

// Schlick's approximation of the fresnel term
vec3 SchlickFresnel(vec3 f0, float cosT)
{
return f0 + (1.0 - f0) * pow(1.0 - cosT, 5.0);
}

float GeometricOcclusion(float a, float NdotV)
{
float a2 = a*2;
return 2.0 * NdotV / (NdotV + sqrt(a2 + (1.0 - a2) * (NdotV * NdotV)));
}

// GGX normal distribution
float NormalDistribution(float a, float NdotH)
{
float a2 = a*a;
float d = NdotH * NdotH * (a2 - 1.0) + 1.0;
return a2 / (M_PI * d * d);
}

vec3 SampleEnvironment(float roughness, vec3 reflection)
{
float lod = roughness * mipCount;
return texture(samplerCubeArray(skyBox, smpl), vec4(reflection, float(skyboxLayer)), lod).rgb;
}

vec3 BRDF(vec3 albedo, vec3 normal, vec3 viewVec, vec3 lightVec, float roughness, float metallic)
{
// Compute color at normal incidence
vec3 f0 = vec3(1.0 - 0.04);
f0 = abs((1.0 - f0) / (1.0 + f0));
f0 = f0 * f0;
f0 = mix(f0, albedo, metallic);

// Compute half vector and all scalar products
vec3 halfVec = normalize(viewVec + lightVec);
float NdotL = clamp(dot(normal, lightVec), 0.0, 1.0);
float NdotV = clamp(dot(normal, viewVec), 0.001, 1.0);
float NdotH = clamp(dot(normal, halfVec), 0.001, 1.0);
float LdotH = clamp(dot(lightVec, halfVec), 0.0, 1.0);
float VdotH = clamp(dot(viewVec, halfVec), 0.0, 1.0);

// Compute Cook-Torance microfacet BRDF
float alpha = roughness * roughness;
vec3 F = SchlickFresnel(f0, VdotH);
float G = GeometricOcclusion(alpha, NdotV);
float D = NormalDistribution(alpha, NdotH);

// Compute specular term and accumulate light
vec3 specular = F * G * D / (4.0 * NdotV);

vec3 reflection = -normalize(reflect(viewVec, normal));
vec3 lighting = SampleEnvironment(roughness, reflection);

return (albedo * (NdotL + lighting * 0.2) + specular * metallic);
}

void main()
{
vec3 texCoord = vec3(inp.texCoord, float(materialLayer));

// Sample textures
vec4 albedo = texture(sampler2DArray(colorMaps, smpl), texCoord);
vec3 normal = texture(sampler2DArray(normalMaps, smpl), texCoord).rgb;
float roughness = texture(sampler2DArray(roughnessMaps, smpl), texCoord).r;
float metallic = texture(sampler2DArray(metallicMaps, smpl), texCoord).r;

// Compute final normal
mat3 tangentSpace = mat3(
normalize(inp.bitangent),
normalize(inp.tangent),
normalize(inp.normal)
);

normal = normalize(tangentSpace * (normal * 2.0 - 1.0));

// Get view and light directions
vec3 viewPos = (cMatrix * vec4(0, 0, 0, 1)).xyz;
vec3 viewVec = normalize(viewPos - inp.worldPos.xyz);

// Sample incoming light from environment map
vec3 reflection = -normalize(reflect(viewVec, normal));
vec3 lighting = SampleEnvironment(roughness, reflection);

// Compute microfacet BRDF
vec3 color = BRDF(albedo.rgb, normal, viewVec, lightDir.xyz, roughness, metallic);

outColor = vec4(color, albedo.a);
}

Binary file added examples/Cpp/PBR/Example.Mesh.450core.frag.spv
Binary file not shown.
50 changes: 50 additions & 0 deletions examples/Cpp/PBR/Example.Mesh.450core.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
// PBR GLSL Mesh Vertex Shader

#version 450 core

layout(std140, binding = 1) uniform Settings
{
mat4 cMatrix;
mat4 vpMatrix;
mat4 wMatrix;
vec2 aspectRatio;
float mipCount;
float _pad0;
vec4 lightDir;
uint skyboxLayer;
uint materialLayer;
uvec2 _pad1;
};

layout(location = 0) in vec3 position;
layout(location = 1) in vec3 normal;
layout(location = 2) in vec3 tangent;
layout(location = 3) in vec3 bitangent;
layout(location = 4) in vec2 texCoord;

layout(location = 0) out VMeshOut
{
vec3 tangent;
vec3 bitangent;
vec3 normal;
vec2 texCoord;
vec4 worldPos;
}
outp;

out gl_PerVertex
{
vec4 gl_Position;
};

void main()
{
outp.worldPos = wMatrix * vec4(position, 1);
gl_Position = vpMatrix * outp.worldPos;
outp.tangent = normalize(wMatrix * vec4(tangent, 0)).xyz;
outp.bitangent = normalize(wMatrix * vec4(bitangent, 0)).xyz;
outp.normal = normalize(wMatrix * vec4(normal, 0)).xyz;
outp.texCoord = texCoord;
}


Binary file added examples/Cpp/PBR/Example.Mesh.450core.vert.spv
Binary file not shown.
30 changes: 10 additions & 20 deletions examples/Cpp/PBR/Example.Mesh.frag
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,12 @@ float NormalDistribution(float a, float NdotH)
return a2 / (M_PI * d * d);
}

vec3 SampleEnvironment(float roughness, vec3 reflection)
{
float lod = roughness * mipCount;
return texture(skyBox, vec4(reflection, float(skyboxLayer)), lod).rgb;
}

vec3 BRDF(vec3 albedo, vec3 normal, vec3 viewVec, vec3 lightVec, float roughness, float metallic)
{
// Compute color at normal incidence
Expand All @@ -81,13 +87,10 @@ vec3 BRDF(vec3 albedo, vec3 normal, vec3 viewVec, vec3 lightVec, float roughness
// Compute specular term and accumulate light
vec3 specular = F * G * D / (4.0 * NdotV);

return (albedo * NdotL + specular);
}
vec3 reflection = -normalize(reflect(viewVec, normal));
vec3 lighting = SampleEnvironment(roughness, reflection);

vec3 SampleEnvironment(float roughness, vec3 reflection)
{
float lod = roughness * mipCount;
return texture(skyBox, vec4(reflection, float(skyboxLayer)), lod).rgb;
return (albedo * (NdotL + lighting * 0.2) + specular * metallic);
}

void main()
Expand All @@ -97,38 +100,25 @@ void main()
// Sample textures
vec4 albedo = texture(colorMaps, texCoord);
vec3 normal = texture(normalMaps, texCoord).rgb;
float roughness = 0.0;//0.6;//texture(roughnessMaps, texCoord).r;
float roughness = texture(roughnessMaps, texCoord).r;
float metallic = texture(metallicMaps, texCoord).r;

// Compute final normal
#if 1
normal = normalize(inp.normal);
#else
mat3 tangentSpace = mat3(
normalize(inp.bitangent),
normalize(inp.tangent),
normalize(inp.normal)
);

normal = normalize(tangentSpace * (normal * 2.0 - 1.0));
#endif

// Get view and light directions
vec3 viewPos = (cMatrix * vec4(0, 0, 0, 1)).xyz;
vec3 viewVec = normalize(viewPos - inp.worldPos.xyz);

// Sample incoming light from environment map
vec3 reflection = -normalize(reflect(viewVec, normal));
vec3 lighting = SampleEnvironment(roughness, reflection);

// Compute microfacet BRDF
vec3 color = BRDF(albedo.rgb, normal, viewVec, lightDir.xyz, roughness, metallic);

#if 1
//color += lighting * 0.2;
color = lighting;
#endif

outColor = vec4(color, albedo.a);
}

38 changes: 38 additions & 0 deletions examples/Cpp/PBR/Example.Sky.450core.frag
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
// PBR GLSL Skybox Fragment Shader

#version 450 core

layout(std140, binding = 1) uniform Settings
{
mat4 cMatrix;
mat4 vpMatrix;
mat4 wMatrix;
vec2 aspectRatio;
float mipCount;
float _pad0;
vec4 lightDir;
uint skyboxLayer;
uint materialLayer;
uvec2 _pad1;
};

// SKYBOX SHADER

layout(location = 0) in VSkyOut
{
vec4 viewRay;
}
inp;

layout(location = 0) out vec4 outColor;

layout(binding = 2) uniform sampler smpl;
layout(binding = 3) uniform textureCubeArray skyBox;

void main()
{
vec3 texCoord = normalize(cMatrix * inp.viewRay).xyz;
outColor = texture(samplerCubeArray(skyBox, smpl), vec4(texCoord, float(skyboxLayer)));
}


Binary file added examples/Cpp/PBR/Example.Sky.450core.frag.spv
Binary file not shown.
68 changes: 68 additions & 0 deletions examples/Cpp/PBR/Example.Sky.450core.vert
Original file line number Diff line number Diff line change
@@ -0,0 +1,68 @@
// PBR GLSL Skybox Vertex Shader

#version 450 core

layout(std140, binding = 1) uniform Settings
{
mat4 cMatrix;
mat4 vpMatrix;
mat4 wMatrix;
vec2 aspectRatio;
float mipCount;
float _pad0;
vec4 lightDir;
uint skyboxLayer;
uint materialLayer;
uvec2 _pad1;
};

// SKYBOX SHADER

layout(location = 0) out VSkyOut
{
vec4 viewRay;
}
outp;

out gl_PerVertex
{
vec4 gl_Position;
};

/*
This function generates the coordinates for a fullscreen triangle with its vertex IDs:
(-1,+3)
*
| \
| \
| \
| \
(-1,+1) (+1,+1)
*----------*\
| | \
| screen | \
| | \
*----------*--------*
(-1,-1) (+1,-1) (+3,-1)
*/
vec4 GetFullscreenTriangleVertex(uint id)
{
return vec4(
(id == 2 ? 3.0 : -1.0),
(id == 0 ? 3.0 : -1.0),
1.0,
1.0
);
}

void main()
{
// Generate coorindate for fullscreen triangle
gl_Position = GetFullscreenTriangleVertex(gl_VertexIndex);

// Generate view ray by vertex coordinate
outp.viewRay = vec4(gl_Position.xy * aspectRatio, 1, 0);
}


Binary file added examples/Cpp/PBR/Example.Sky.450core.vert.spv
Binary file not shown.
2 changes: 0 additions & 2 deletions examples/Cpp/PBR/Example.Sky.frag
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@

#version 450 core

#define M_PI 3.141592654

uniform Settings
{
mat4 cMatrix;
Expand Down
Loading

0 comments on commit 17800ec

Please sign in to comment.