mirror of
https://github.com/JoeyDeVries/LearnOpenGL.git
synced 2026-01-02 04:37:54 +08:00
PBR Shader fix to code standard.
This commit is contained in:
@@ -3,7 +3,6 @@ out vec4 FragColor;
|
||||
in vec2 TexCoords;
|
||||
in vec3 WorldPos;
|
||||
in vec3 Normal;
|
||||
in mat3 TBN;
|
||||
|
||||
// material parameters
|
||||
uniform vec3 albedo;
|
||||
@@ -66,7 +65,7 @@ void main()
|
||||
vec3 V = normalize(camPos - WorldPos);
|
||||
|
||||
// calculate reflectance at normal incidence; if dia-electric (like plastic) use F0
|
||||
// of 0.04 and if it's a metal, use their albedo color as F0 (metallic workflow)
|
||||
// of 0.04 and if it's a metal, use the albedo color as F0 (metallic workflow)
|
||||
vec3 F0 = vec3(0.04);
|
||||
F0 = mix(F0, albedo, metallic);
|
||||
|
||||
@@ -120,4 +119,4 @@ void main()
|
||||
color = pow(color, vec3(1.0/2.2));
|
||||
|
||||
FragColor = vec4(color, 1.0);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
#version 330 core
|
||||
layout (location = 0) in vec3 pos;
|
||||
layout (location = 1) in vec2 texCoords;
|
||||
layout (location = 2) in vec3 normal;
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec2 aTexCoords;
|
||||
layout (location = 2) in vec3 aNormal;
|
||||
|
||||
out vec2 TexCoords;
|
||||
out vec3 WorldPos;
|
||||
@@ -13,9 +13,9 @@ uniform mat4 model;
|
||||
|
||||
void main()
|
||||
{
|
||||
TexCoords = texCoords;
|
||||
WorldPos = vec3(model * vec4(pos, 1.0f));
|
||||
Normal = mat3(model) * normal;
|
||||
TexCoords = aTexCoords;
|
||||
WorldPos = vec3(model * vec4(aPos, 1.0f));
|
||||
Normal = mat3(model) * aNormal;
|
||||
|
||||
gl_Position = projection * view * vec4(WorldPos, 1.0);
|
||||
}
|
||||
@@ -3,7 +3,6 @@ out vec4 FragColor;
|
||||
in vec2 TexCoords;
|
||||
in vec3 WorldPos;
|
||||
in vec3 Normal;
|
||||
in mat3 TBN;
|
||||
|
||||
// material parameters
|
||||
uniform sampler2D albedoMap;
|
||||
@@ -93,7 +92,7 @@ void main()
|
||||
vec3 V = normalize(camPos - WorldPos);
|
||||
|
||||
// calculate reflectance at normal incidence; if dia-electric (like plastic) use F0
|
||||
// of 0.04 and if it's a metal, use their albedo color as F0 (metallic workflow)
|
||||
// of 0.04 and if it's a metal, use the albedo color as F0 (metallic workflow)
|
||||
vec3 F0 = vec3(0.04);
|
||||
F0 = mix(F0, albedo, metallic);
|
||||
|
||||
@@ -147,4 +146,4 @@ void main()
|
||||
color = pow(color, vec3(1.0/2.2));
|
||||
|
||||
FragColor = vec4(color, 1.0);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
#version 330 core
|
||||
layout (location = 0) in vec3 pos;
|
||||
layout (location = 1) in vec2 texCoords;
|
||||
layout (location = 2) in vec3 normal;
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec2 aTexCoords;
|
||||
layout (location = 2) in vec3 aNormal;
|
||||
|
||||
out vec2 TexCoords;
|
||||
out vec3 WorldPos;
|
||||
@@ -13,9 +13,9 @@ uniform mat4 model;
|
||||
|
||||
void main()
|
||||
{
|
||||
TexCoords = texCoords;
|
||||
WorldPos = vec3(model * vec4(pos, 1.0f));
|
||||
Normal = mat3(model) * normal;
|
||||
TexCoords = aTexCoords;
|
||||
WorldPos = vec3(model * vec4(aPos, 1.0f));
|
||||
Normal = mat3(model) * aNormal;
|
||||
|
||||
gl_Position = projection * view * vec4(WorldPos, 1.0);
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
#version 330 core
|
||||
layout (location = 0) in vec3 pos;
|
||||
layout (location = 0) in vec3 aPos;
|
||||
|
||||
uniform mat4 projection;
|
||||
uniform mat4 view;
|
||||
@@ -8,7 +8,7 @@ out vec3 WorldPos;
|
||||
|
||||
void main()
|
||||
{
|
||||
WorldPos = pos;
|
||||
WorldPos = aPos;
|
||||
|
||||
mat4 rotView = mat4(mat3(view));
|
||||
vec4 clipPos = projection * rotView * vec4(WorldPos, 1.0);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#version 330 core
|
||||
layout (location = 0) in vec3 pos;
|
||||
layout (location = 0) in vec3 aPos;
|
||||
|
||||
out vec3 WorldPos;
|
||||
|
||||
@@ -8,7 +8,7 @@ uniform mat4 view;
|
||||
|
||||
void main()
|
||||
{
|
||||
WorldPos = pos;
|
||||
WorldPos = aPos;
|
||||
|
||||
gl_Position = projection * view * vec4(WorldPos, 1.0);
|
||||
}
|
||||
@@ -3,7 +3,6 @@ out vec4 FragColor;
|
||||
in vec2 TexCoords;
|
||||
in vec3 WorldPos;
|
||||
in vec3 Normal;
|
||||
in mat3 TBN;
|
||||
|
||||
// material parameters
|
||||
uniform vec3 albedo;
|
||||
@@ -71,7 +70,7 @@ void main()
|
||||
vec3 R = reflect(-V, N);
|
||||
|
||||
// calculate reflectance at normal incidence; if dia-electric (like plastic) use F0
|
||||
// of 0.04 and if it's a metal, use their albedo color as F0 (metallic workflow)
|
||||
// of 0.04 and if it's a metal, use the albedo color as F0 (metallic workflow)
|
||||
vec3 F0 = vec3(0.04);
|
||||
F0 = mix(F0, albedo, metallic);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#version 330 core
|
||||
layout (location = 0) in vec3 pos;
|
||||
layout (location = 1) in vec2 texCoords;
|
||||
layout (location = 2) in vec3 normal;
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec2 aTexCoords;
|
||||
layout (location = 2) in vec3 aNormal;
|
||||
|
||||
out vec2 TexCoords;
|
||||
out vec3 WorldPos;
|
||||
@@ -13,9 +13,9 @@ uniform mat4 model;
|
||||
|
||||
void main()
|
||||
{
|
||||
TexCoords = texCoords;
|
||||
WorldPos = vec3(model * vec4(pos, 1.0f));
|
||||
Normal = mat3(model) * normal;
|
||||
TexCoords = aTexCoords;
|
||||
WorldPos = vec3(model * vec4(aPos, 1.0f));
|
||||
Normal = mat3(model) * aNormal;
|
||||
|
||||
gl_Position = projection * view * vec4(WorldPos, 1.0);
|
||||
}
|
||||
@@ -75,9 +75,9 @@ int main()
|
||||
|
||||
// build and compile shaders
|
||||
// -------------------------
|
||||
Shader pbrShader("2.1.1.pbr.vs", "2.1.1.pbr.frag");
|
||||
Shader equirectangularToCubemapShader("2.1.1.cubemap.vs", "2.1.1.equirectangular_to_cubemap.frag");
|
||||
Shader backgroundShader("2.1.1.background.vs", "2.1.1.background.frag");
|
||||
Shader pbrShader("2.1.1.pbr.vs", "2.1.1.pbr.fs");
|
||||
Shader equirectangularToCubemapShader("2.1.1.cubemap.vs", "2.1.1.equirectangular_to_cubemap.fs");
|
||||
Shader backgroundShader("2.1.1.background.vs", "2.1.1.background.fs");
|
||||
|
||||
|
||||
pbrShader.use();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#version 330 core
|
||||
layout (location = 0) in vec3 pos;
|
||||
layout (location = 0) in vec3 aPos;
|
||||
|
||||
uniform mat4 projection;
|
||||
uniform mat4 view;
|
||||
@@ -8,7 +8,7 @@ out vec3 WorldPos;
|
||||
|
||||
void main()
|
||||
{
|
||||
WorldPos = pos;
|
||||
WorldPos = aPos;
|
||||
|
||||
mat4 rotView = mat4(mat3(view));
|
||||
vec4 clipPos = projection * rotView * vec4(WorldPos, 1.0);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#version 330 core
|
||||
layout (location = 0) in vec3 pos;
|
||||
layout (location = 0) in vec3 aPos;
|
||||
|
||||
out vec3 WorldPos;
|
||||
|
||||
@@ -8,7 +8,7 @@ uniform mat4 view;
|
||||
|
||||
void main()
|
||||
{
|
||||
WorldPos = pos;
|
||||
WorldPos = aPos;
|
||||
|
||||
gl_Position = projection * view * vec4(WorldPos, 1.0);
|
||||
}
|
||||
@@ -4,11 +4,11 @@ in vec3 WorldPos;
|
||||
|
||||
uniform samplerCube environmentMap;
|
||||
|
||||
const float PI = 3.14159265359f;
|
||||
const float PI = 3.14159265359;
|
||||
|
||||
void main()
|
||||
{
|
||||
// NOTE(Joey): the world vector acts as the normal of a tangent surface
|
||||
// The world vector acts as the normal of a tangent surface
|
||||
// from the origin, aligned to WorldPos. Given this normal, calculate all
|
||||
// incoming radiance of the environment. The result of this radiance
|
||||
// is the radiance of light coming from -Normal direction, which is what
|
||||
@@ -17,13 +17,13 @@ void main()
|
||||
|
||||
vec3 irradiance = vec3(0.0);
|
||||
|
||||
// NOTE(Joey): tangent space calculation from origin point
|
||||
// tangent space calculation from origin point
|
||||
vec3 up = vec3(0.0, 1.0, 0.0);
|
||||
vec3 right = cross(up, N);
|
||||
up = cross(N, right);
|
||||
|
||||
float sampleDelta = 0.025f;
|
||||
float nrSamples = 0.0f;
|
||||
float sampleDelta = 0.025;
|
||||
float nrSamples = 0.0;
|
||||
for(float phi = 0.0; phi < 2.0 * PI; phi += sampleDelta)
|
||||
{
|
||||
for(float theta = 0.0; theta < 0.5 * PI; theta += sampleDelta)
|
||||
@@ -3,7 +3,6 @@ out vec4 FragColor;
|
||||
in vec2 TexCoords;
|
||||
in vec3 WorldPos;
|
||||
in vec3 Normal;
|
||||
in mat3 TBN;
|
||||
|
||||
// material parameters
|
||||
uniform vec3 albedo;
|
||||
@@ -69,7 +68,7 @@ void main()
|
||||
vec3 R = reflect(-V, N);
|
||||
|
||||
// calculate reflectance at normal incidence; if dia-electric (like plastic) use F0
|
||||
// of 0.04 and if it's a metal, use their albedo color as F0 (metallic workflow)
|
||||
// of 0.04 and if it's a metal, use the albedo color as F0 (metallic workflow)
|
||||
vec3 F0 = vec3(0.04);
|
||||
F0 = mix(F0, albedo, metallic);
|
||||
|
||||
@@ -128,4 +127,4 @@ void main()
|
||||
color = pow(color, vec3(1.0/2.2));
|
||||
|
||||
FragColor = vec4(color , 1.0);
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
#version 330 core
|
||||
layout (location = 0) in vec3 pos;
|
||||
layout (location = 1) in vec2 texCoords;
|
||||
layout (location = 2) in vec3 normal;
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec2 aTexCoords;
|
||||
layout (location = 2) in vec3 aNormal;
|
||||
|
||||
out vec2 TexCoords;
|
||||
out vec3 WorldPos;
|
||||
@@ -13,9 +13,9 @@ uniform mat4 model;
|
||||
|
||||
void main()
|
||||
{
|
||||
TexCoords = texCoords;
|
||||
WorldPos = vec3(model * vec4(pos, 1.0f));
|
||||
Normal = mat3(model) * normal;
|
||||
TexCoords = aTexCoords;
|
||||
WorldPos = vec3(model * vec4(aPos, 1.0f));
|
||||
Normal = mat3(model) * aNormal;
|
||||
|
||||
gl_Position = projection * view * vec4(WorldPos, 1.0);
|
||||
}
|
||||
@@ -75,10 +75,10 @@ int main()
|
||||
|
||||
// build and compile shaders
|
||||
// -------------------------
|
||||
Shader pbrShader("2.1.2.pbr.vs", "2.1.2.pbr.frag");
|
||||
Shader equirectangularToCubemapShader("2.1.2.cubemap.vs", "2.1.2.equirectangular_to_cubemap.frag");
|
||||
Shader irradianceShader("2.1.2.cubemap.vs", "2.1.2.irradiance_convolution.frag");
|
||||
Shader backgroundShader("2.1.2.background.vs", "2.1.2.background.frag");
|
||||
Shader pbrShader("2.1.2.pbr.vs", "2.1.2.pbr.fs");
|
||||
Shader equirectangularToCubemapShader("2.1.2.cubemap.vs", "2.1.2.equirectangular_to_cubemap.fs");
|
||||
Shader irradianceShader("2.1.2.cubemap.vs", "2.1.2.irradiance_convolution.fs");
|
||||
Shader backgroundShader("2.1.2.background.vs", "2.1.2.background.fs");
|
||||
|
||||
|
||||
pbrShader.use();
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
#version 330 core
|
||||
layout (location = 0) in vec3 pos;
|
||||
layout (location = 0) in vec3 aPos;
|
||||
|
||||
uniform mat4 projection;
|
||||
uniform mat4 view;
|
||||
@@ -8,7 +8,7 @@ out vec3 WorldPos;
|
||||
|
||||
void main()
|
||||
{
|
||||
WorldPos = pos;
|
||||
WorldPos = aPos;
|
||||
|
||||
mat4 rotView = mat4(mat3(view));
|
||||
vec4 clipPos = projection * rotView * vec4(WorldPos, 1.0);
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
out vec2 FragColor;
|
||||
in vec2 TexCoords;
|
||||
|
||||
const float PI = 3.14159265359f;
|
||||
const float PI = 3.14159265359;
|
||||
// ----------------------------------------------------------------------------
|
||||
// http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
|
||||
// efficient VanDerCorpus calculation.
|
||||
@@ -29,13 +29,13 @@ vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness)
|
||||
float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a*a - 1.0) * Xi.y));
|
||||
float sinTheta = sqrt(1.0 - cosTheta*cosTheta);
|
||||
|
||||
// NOTE(Joey): from spherical coordinates to cartesian coordinates - halfway vector
|
||||
// from spherical coordinates to cartesian coordinates - halfway vector
|
||||
vec3 H;
|
||||
H.x = cos(phi) * sinTheta;
|
||||
H.y = sin(phi) * sinTheta;
|
||||
H.z = cosTheta;
|
||||
|
||||
// NOTE(Joey): from tangent-space H vector to world-space sample vector
|
||||
// from tangent-space H vector to world-space sample vector
|
||||
vec3 up = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
|
||||
vec3 tangent = normalize(cross(up, N));
|
||||
vec3 bitangent = cross(N, tangent);
|
||||
@@ -81,7 +81,7 @@ vec2 IntegrateBRDF(float NdotV, float roughness)
|
||||
const uint SAMPLE_COUNT = 1024u;
|
||||
for(uint i = 0u; i < SAMPLE_COUNT; ++i)
|
||||
{
|
||||
// NOTE(Joey): generates a sample vector that's biased towards the
|
||||
// generates a sample vector that's biased towards the
|
||||
// preferred alignment direction (importance sampling).
|
||||
vec2 Xi = Hammersley(i, SAMPLE_COUNT);
|
||||
vec3 H = ImportanceSampleGGX(Xi, N, roughness);
|
||||
@@ -1,11 +1,11 @@
|
||||
#version 330 core
|
||||
layout (location = 0) in vec3 pos;
|
||||
layout (location = 1) in vec2 texCoords;
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec2 aTexCoords;
|
||||
|
||||
out vec2 TexCoords;
|
||||
|
||||
void main()
|
||||
{
|
||||
TexCoords = texCoords;
|
||||
gl_Position = vec4(pos, 1.0);
|
||||
TexCoords = aTexCoords;
|
||||
gl_Position = vec4(aPos, 1.0);
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
#version 330 core
|
||||
layout (location = 0) in vec3 pos;
|
||||
layout (location = 0) in vec3 aPos;
|
||||
|
||||
out vec3 WorldPos;
|
||||
|
||||
@@ -8,7 +8,7 @@ uniform mat4 view;
|
||||
|
||||
void main()
|
||||
{
|
||||
WorldPos = pos;
|
||||
WorldPos = aPos;
|
||||
|
||||
gl_Position = projection * view * vec4(WorldPos, 1.0);
|
||||
}
|
||||
@@ -4,7 +4,7 @@ in vec3 WorldPos;
|
||||
|
||||
uniform samplerCube environmentMap;
|
||||
|
||||
const float PI = 3.14159265359f;
|
||||
const float PI = 3.14159265359;
|
||||
|
||||
void main()
|
||||
{
|
||||
@@ -17,7 +17,7 @@ void main()
|
||||
vec3 right = cross(up, N);
|
||||
up = cross(N, right);
|
||||
|
||||
float sampleDelta = 0.025f;
|
||||
float sampleDelta = 0.025;
|
||||
float nrSamples = 0.0f;
|
||||
for(float phi = 0.0; phi < 2.0 * PI; phi += sampleDelta)
|
||||
{
|
||||
@@ -3,7 +3,6 @@ out vec4 FragColor;
|
||||
in vec2 TexCoords;
|
||||
in vec3 WorldPos;
|
||||
in vec3 Normal;
|
||||
in mat3 TBN;
|
||||
|
||||
// material parameters
|
||||
uniform vec3 albedo;
|
||||
@@ -76,7 +75,7 @@ void main()
|
||||
vec3 R = reflect(-V, N);
|
||||
|
||||
// calculate reflectance at normal incidence; if dia-electric (like plastic) use F0
|
||||
// of 0.04 and if it's a metal, use their albedo color as F0 (metallic workflow)
|
||||
// of 0.04 and if it's a metal, use the albedo color as F0 (metallic workflow)
|
||||
vec3 F0 = vec3(0.04);
|
||||
F0 = mix(F0, albedo, metallic);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#version 330 core
|
||||
layout (location = 0) in vec3 pos;
|
||||
layout (location = 1) in vec2 texCoords;
|
||||
layout (location = 2) in vec3 normal;
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec2 aTexCoords;
|
||||
layout (location = 2) in vec3 aNormal;
|
||||
|
||||
out vec2 TexCoords;
|
||||
out vec3 WorldPos;
|
||||
@@ -13,9 +13,9 @@ uniform mat4 model;
|
||||
|
||||
void main()
|
||||
{
|
||||
TexCoords = texCoords;
|
||||
WorldPos = vec3(model * vec4(pos, 1.0f));
|
||||
Normal = mat3(model) * normal;
|
||||
TexCoords = aTexCoords;
|
||||
WorldPos = vec3(model * vec4(aPos, 1.0f));
|
||||
Normal = mat3(model) * aNormal;
|
||||
|
||||
gl_Position = projection * view * vec4(WorldPos, 1.0);
|
||||
}
|
||||
@@ -5,7 +5,7 @@ in vec3 WorldPos;
|
||||
uniform samplerCube environmentMap;
|
||||
uniform float roughness;
|
||||
|
||||
const float PI = 3.14159265359f;
|
||||
const float PI = 3.14159265359;
|
||||
// ----------------------------------------------------------------------------
|
||||
float DistributionGGX(vec3 N, vec3 H, float roughness)
|
||||
{
|
||||
@@ -79,12 +79,12 @@ int main()
|
||||
|
||||
// build and compile shaders
|
||||
// -------------------------
|
||||
Shader pbrShader("2.2.1.pbr.vs", "2.2.1.pbr.frag");
|
||||
Shader equirectangularToCubemapShader("2.2.1.cubemap.vs", "2.2.1.equirectangular_to_cubemap.frag");
|
||||
Shader irradianceShader("2.2.1.cubemap.vs", "2.2.1.irradiance_convolution.frag");
|
||||
Shader prefilterShader("2.2.1.cubemap.vs", "2.2.1.prefilter.frag");
|
||||
Shader brdfShader("2.2.1.brdf.vs", "2.2.1.brdf.frag");
|
||||
Shader backgroundShader("2.2.1.background.vs", "2.2.1.background.frag");
|
||||
Shader pbrShader("2.2.1.pbr.vs", "2.2.1.pbr.fs");
|
||||
Shader equirectangularToCubemapShader("2.2.1.cubemap.vs", "2.2.1.equirectangular_to_cubemap.fs");
|
||||
Shader irradianceShader("2.2.1.cubemap.vs", "2.2.1.irradiance_convolution.fs");
|
||||
Shader prefilterShader("2.2.1.cubemap.vs", "2.2.1.prefilter.fs");
|
||||
Shader brdfShader("2.2.1.brdf.vs", "2.2.1.brdf.fs");
|
||||
Shader backgroundShader("2.2.1.background.vs", "2.2.1.background.fs");
|
||||
|
||||
pbrShader.use();
|
||||
pbrShader.setInt("irradianceMap", 0);
|
||||
|
||||
16
src/6.pbr/2.2.2.ibl_specular_textured/2.2.2.background.fs
Normal file
16
src/6.pbr/2.2.2.ibl_specular_textured/2.2.2.background.fs
Normal file
@@ -0,0 +1,16 @@
|
||||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
in vec3 WorldPos;
|
||||
|
||||
uniform samplerCube environmentMap;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 envColor = textureLod(environmentMap, WorldPos, 0.0).rgb;
|
||||
|
||||
// HDR tonemap and gamma correct
|
||||
envColor = envColor / (envColor + vec3(1.0));
|
||||
envColor = pow(envColor, vec3(1.0/2.2));
|
||||
|
||||
FragColor = vec4(envColor, 1.0);
|
||||
}
|
||||
17
src/6.pbr/2.2.2.ibl_specular_textured/2.2.2.background.vs
Normal file
17
src/6.pbr/2.2.2.ibl_specular_textured/2.2.2.background.vs
Normal file
@@ -0,0 +1,17 @@
|
||||
#version 330 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
|
||||
uniform mat4 projection;
|
||||
uniform mat4 view;
|
||||
|
||||
out vec3 WorldPos;
|
||||
|
||||
void main()
|
||||
{
|
||||
WorldPos = aPos;
|
||||
|
||||
mat4 rotView = mat4(mat3(view));
|
||||
vec4 clipPos = projection * rotView * vec4(WorldPos, 1.0);
|
||||
|
||||
gl_Position = clipPos.xyww;
|
||||
}
|
||||
113
src/6.pbr/2.2.2.ibl_specular_textured/2.2.2.brdf.fs
Normal file
113
src/6.pbr/2.2.2.ibl_specular_textured/2.2.2.brdf.fs
Normal file
@@ -0,0 +1,113 @@
|
||||
#version 330 core
|
||||
out vec2 FragColor;
|
||||
in vec2 TexCoords;
|
||||
|
||||
const float PI = 3.14159265359;
|
||||
// ----------------------------------------------------------------------------
|
||||
// http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
|
||||
// efficient VanDerCorpus calculation.
|
||||
float RadicalInverse_VdC(uint bits)
|
||||
{
|
||||
bits = (bits << 16u) | (bits >> 16u);
|
||||
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
|
||||
bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
|
||||
bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
|
||||
bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
|
||||
return float(bits) * 2.3283064365386963e-10; // / 0x100000000
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
vec2 Hammersley(uint i, uint N)
|
||||
{
|
||||
return vec2(float(i)/float(N), RadicalInverse_VdC(i));
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness)
|
||||
{
|
||||
float a = roughness*roughness;
|
||||
|
||||
float phi = 2.0 * PI * Xi.x;
|
||||
float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a*a - 1.0) * Xi.y));
|
||||
float sinTheta = sqrt(1.0 - cosTheta*cosTheta);
|
||||
|
||||
// from spherical coordinates to cartesian coordinates - halfway vector
|
||||
vec3 H;
|
||||
H.x = cos(phi) * sinTheta;
|
||||
H.y = sin(phi) * sinTheta;
|
||||
H.z = cosTheta;
|
||||
|
||||
// from tangent-space H vector to world-space sample vector
|
||||
vec3 up = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
|
||||
vec3 tangent = normalize(cross(up, N));
|
||||
vec3 bitangent = cross(N, tangent);
|
||||
|
||||
vec3 sampleVec = tangent * H.x + bitangent * H.y + N * H.z;
|
||||
return normalize(sampleVec);
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
float GeometrySchlickGGX(float NdotV, float roughness)
|
||||
{
|
||||
// note that we use a different k for IBL
|
||||
float a = roughness;
|
||||
float k = (a * a) / 2.0;
|
||||
|
||||
float nom = NdotV;
|
||||
float denom = NdotV * (1.0 - k) + k;
|
||||
|
||||
return nom / denom;
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness)
|
||||
{
|
||||
float NdotV = max(dot(N, V), 0.0);
|
||||
float NdotL = max(dot(N, L), 0.0);
|
||||
float ggx2 = GeometrySchlickGGX(NdotV, roughness);
|
||||
float ggx1 = GeometrySchlickGGX(NdotL, roughness);
|
||||
|
||||
return ggx1 * ggx2;
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
vec2 IntegrateBRDF(float NdotV, float roughness)
|
||||
{
|
||||
vec3 V;
|
||||
V.x = sqrt(1.0 - NdotV*NdotV);
|
||||
V.y = 0.0;
|
||||
V.z = NdotV;
|
||||
|
||||
float A = 0.0;
|
||||
float B = 0.0;
|
||||
|
||||
vec3 N = vec3(0.0, 0.0, 1.0);
|
||||
|
||||
const uint SAMPLE_COUNT = 1024u;
|
||||
for(uint i = 0u; i < SAMPLE_COUNT; ++i)
|
||||
{
|
||||
// generates a sample vector that's biased towards the
|
||||
// preferred alignment direction (importance sampling).
|
||||
vec2 Xi = Hammersley(i, SAMPLE_COUNT);
|
||||
vec3 H = ImportanceSampleGGX(Xi, N, roughness);
|
||||
vec3 L = normalize(2.0 * dot(V, H) * H - V);
|
||||
|
||||
float NdotL = max(L.z, 0.0);
|
||||
float NdotH = max(H.z, 0.0);
|
||||
float VdotH = max(dot(V, H), 0.0);
|
||||
|
||||
if(NdotL > 0.0)
|
||||
{
|
||||
float G = GeometrySmith(N, V, L, roughness);
|
||||
float G_Vis = (G * VdotH) / (NdotH * NdotV);
|
||||
float Fc = pow(1.0 - VdotH, 5.0);
|
||||
|
||||
A += (1.0 - Fc) * G_Vis;
|
||||
B += Fc * G_Vis;
|
||||
}
|
||||
}
|
||||
A /= float(SAMPLE_COUNT);
|
||||
B /= float(SAMPLE_COUNT);
|
||||
return vec2(A, B);
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
void main()
|
||||
{
|
||||
vec2 integratedBRDF = IntegrateBRDF(TexCoords.x, TexCoords.y);
|
||||
FragColor = integratedBRDF;
|
||||
}
|
||||
11
src/6.pbr/2.2.2.ibl_specular_textured/2.2.2.brdf.vs
Normal file
11
src/6.pbr/2.2.2.ibl_specular_textured/2.2.2.brdf.vs
Normal file
@@ -0,0 +1,11 @@
|
||||
#version 330 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec2 aTexCoords;
|
||||
|
||||
out vec2 TexCoords;
|
||||
|
||||
void main()
|
||||
{
|
||||
TexCoords = aTexCoords;
|
||||
gl_Position = vec4(aPos, 1.0);
|
||||
}
|
||||
14
src/6.pbr/2.2.2.ibl_specular_textured/2.2.2.cubemap.vs
Normal file
14
src/6.pbr/2.2.2.ibl_specular_textured/2.2.2.cubemap.vs
Normal file
@@ -0,0 +1,14 @@
|
||||
#version 330 core
|
||||
layout (location = 0) in vec3 aPos;
|
||||
|
||||
out vec3 WorldPos;
|
||||
|
||||
uniform mat4 projection;
|
||||
uniform mat4 view;
|
||||
|
||||
void main()
|
||||
{
|
||||
WorldPos = aPos;
|
||||
|
||||
gl_Position = projection * view * vec4(WorldPos, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
in vec3 WorldPos;
|
||||
|
||||
uniform sampler2D equirectangularMap;
|
||||
|
||||
const vec2 invAtan = vec2(0.1591, 0.3183);
|
||||
vec2 SampleSphericalMap(vec3 v)
|
||||
{
|
||||
vec2 uv = vec2(atan(v.z, v.x), asin(v.y));
|
||||
uv *= invAtan;
|
||||
uv += 0.5;
|
||||
return uv;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec2 uv = SampleSphericalMap(normalize(WorldPos));
|
||||
vec3 color = texture(equirectangularMap, uv).rgb;
|
||||
|
||||
FragColor = vec4(color, 1.0);
|
||||
}
|
||||
@@ -0,0 +1,38 @@
|
||||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
in vec3 WorldPos;
|
||||
|
||||
uniform samplerCube environmentMap;
|
||||
|
||||
const float PI = 3.14159265359;
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 N = normalize(WorldPos);
|
||||
|
||||
vec3 irradiance = vec3(0.0);
|
||||
|
||||
// tangent space calculation from origin point
|
||||
vec3 up = vec3(0.0, 1.0, 0.0);
|
||||
vec3 right = cross(up, N);
|
||||
up = cross(N, right);
|
||||
|
||||
float sampleDelta = 0.025;
|
||||
float nrSamples = 0.0f;
|
||||
for(float phi = 0.0; phi < 2.0 * PI; phi += sampleDelta)
|
||||
{
|
||||
for(float theta = 0.0; theta < 0.5 * PI; theta += sampleDelta)
|
||||
{
|
||||
// spherical to cartesian (in tangent space)
|
||||
vec3 tangentSample = vec3(sin(theta) * cos(phi), sin(theta) * sin(phi), cos(theta));
|
||||
// tangent space to world
|
||||
vec3 sampleVec = tangentSample.x * right + tangentSample.y * up + tangentSample.z * N;
|
||||
|
||||
irradiance += texture(environmentMap, sampleVec).rgb * cos(theta) * sin(theta);
|
||||
nrSamples++;
|
||||
}
|
||||
}
|
||||
irradiance = PI * irradiance * (1.0 / float(nrSamples));
|
||||
|
||||
FragColor = vec4(irradiance, 1.0);
|
||||
}
|
||||
@@ -3,7 +3,6 @@ out vec4 FragColor;
|
||||
in vec2 TexCoords;
|
||||
in vec3 WorldPos;
|
||||
in vec3 Normal;
|
||||
in mat3 TBN;
|
||||
|
||||
// material parameters
|
||||
uniform sampler2D albedoMap;
|
||||
@@ -98,15 +97,14 @@ void main()
|
||||
float metallic = texture(metallicMap, TexCoords).r;
|
||||
float roughness = texture(roughnessMap, TexCoords).r;
|
||||
float ao = texture(aoMap, TexCoords).r;
|
||||
|
||||
|
||||
|
||||
// input lighting data
|
||||
vec3 N = getNormalFromMap();
|
||||
vec3 V = normalize(camPos - WorldPos);
|
||||
vec3 R = reflect(-V, N);
|
||||
|
||||
// calculate reflectance at normal incidence; if dia-electric (like plastic) use F0
|
||||
// of 0.04 and if it's a metal, use their albedo color as F0 (metallic workflow)
|
||||
// of 0.04 and if it's a metal, use the albedo color as F0 (metallic workflow)
|
||||
vec3 F0 = vec3(0.04);
|
||||
F0 = mix(F0, albedo, metallic);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#version 330 core
|
||||
layout (location = 0) in vec3 pos;
|
||||
layout (location = 1) in vec2 texCoords;
|
||||
layout (location = 2) in vec3 normal;
|
||||
layout (location = 0) in vec3 aPos;
|
||||
layout (location = 1) in vec2 aTexCoords;
|
||||
layout (location = 2) in vec3 aNormal;
|
||||
|
||||
out vec2 TexCoords;
|
||||
out vec3 WorldPos;
|
||||
@@ -13,9 +13,9 @@ uniform mat4 model;
|
||||
|
||||
void main()
|
||||
{
|
||||
TexCoords = texCoords;
|
||||
WorldPos = vec3(model * vec4(pos, 1.0f));
|
||||
Normal = mat3(model) * normal;
|
||||
TexCoords = aTexCoords;
|
||||
WorldPos = vec3(model * vec4(aPos, 1.0f));
|
||||
Normal = mat3(model) * aNormal;
|
||||
|
||||
gl_Position = projection * view * vec4(WorldPos, 1.0);
|
||||
}
|
||||
106
src/6.pbr/2.2.2.ibl_specular_textured/2.2.2.prefilter.fs
Normal file
106
src/6.pbr/2.2.2.ibl_specular_textured/2.2.2.prefilter.fs
Normal file
@@ -0,0 +1,106 @@
|
||||
#version 330 core
|
||||
out vec4 FragColor;
|
||||
in vec3 WorldPos;
|
||||
|
||||
uniform samplerCube environmentMap;
|
||||
uniform float roughness;
|
||||
|
||||
const float PI = 3.14159265359;
|
||||
// ----------------------------------------------------------------------------
|
||||
float DistributionGGX(vec3 N, vec3 H, float roughness)
|
||||
{
|
||||
float a = roughness*roughness;
|
||||
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;
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
// http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
|
||||
// efficient VanDerCorpus calculation.
|
||||
float RadicalInverse_VdC(uint bits)
|
||||
{
|
||||
bits = (bits << 16u) | (bits >> 16u);
|
||||
bits = ((bits & 0x55555555u) << 1u) | ((bits & 0xAAAAAAAAu) >> 1u);
|
||||
bits = ((bits & 0x33333333u) << 2u) | ((bits & 0xCCCCCCCCu) >> 2u);
|
||||
bits = ((bits & 0x0F0F0F0Fu) << 4u) | ((bits & 0xF0F0F0F0u) >> 4u);
|
||||
bits = ((bits & 0x00FF00FFu) << 8u) | ((bits & 0xFF00FF00u) >> 8u);
|
||||
return float(bits) * 2.3283064365386963e-10; // / 0x100000000
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
vec2 Hammersley(uint i, uint N)
|
||||
{
|
||||
return vec2(float(i)/float(N), RadicalInverse_VdC(i));
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
vec3 ImportanceSampleGGX(vec2 Xi, vec3 N, float roughness)
|
||||
{
|
||||
float a = roughness*roughness;
|
||||
|
||||
float phi = 2.0 * PI * Xi.x;
|
||||
float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (a*a - 1.0) * Xi.y));
|
||||
float sinTheta = sqrt(1.0 - cosTheta*cosTheta);
|
||||
|
||||
// from spherical coordinates to cartesian coordinates - halfway vector
|
||||
vec3 H;
|
||||
H.x = cos(phi) * sinTheta;
|
||||
H.y = sin(phi) * sinTheta;
|
||||
H.z = cosTheta;
|
||||
|
||||
// from tangent-space H vector to world-space sample vector
|
||||
vec3 up = abs(N.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
|
||||
vec3 tangent = normalize(cross(up, N));
|
||||
vec3 bitangent = cross(N, tangent);
|
||||
|
||||
vec3 sampleVec = tangent * H.x + bitangent * H.y + N * H.z;
|
||||
return normalize(sampleVec);
|
||||
}
|
||||
// ----------------------------------------------------------------------------
|
||||
void main()
|
||||
{
|
||||
vec3 N = normalize(WorldPos);
|
||||
|
||||
// make the simplyfying assumption that V equals R equals the normal
|
||||
vec3 R = N;
|
||||
vec3 V = R;
|
||||
|
||||
const uint SAMPLE_COUNT = 1024u;
|
||||
vec3 prefilteredColor = vec3(0.0);
|
||||
float totalWeight = 0.0;
|
||||
|
||||
for(uint i = 0u; i < SAMPLE_COUNT; ++i)
|
||||
{
|
||||
// generates a sample vector that's biased towards the preferred alignment direction (importance sampling).
|
||||
vec2 Xi = Hammersley(i, SAMPLE_COUNT);
|
||||
vec3 H = ImportanceSampleGGX(Xi, N, roughness);
|
||||
vec3 L = normalize(2.0 * dot(V, H) * H - V);
|
||||
|
||||
float NdotL = max(dot(N, L), 0.0);
|
||||
if(NdotL > 0.0)
|
||||
{
|
||||
// sample from the environment's mip level based on roughness/pdf
|
||||
float D = DistributionGGX(N, H, roughness);
|
||||
float NdotH = max(dot(N, H), 0.0);
|
||||
float HdotV = max(dot(H, V), 0.0);
|
||||
float pdf = D * NdotH / (4.0 * HdotV) + 0.0001;
|
||||
|
||||
float resolution = 512.0; // resolution of source cubemap (per face)
|
||||
float saTexel = 4.0 * PI / (6.0 * resolution * resolution);
|
||||
float saSample = 1.0 / (float(SAMPLE_COUNT) * pdf + 0.0001);
|
||||
|
||||
float mipLevel = roughness == 0.0 ? 0.0 : 0.5 * log2(saSample / saTexel);
|
||||
|
||||
prefilteredColor += textureLod(environmentMap, L, mipLevel).rgb * NdotL;
|
||||
totalWeight += NdotL;
|
||||
}
|
||||
}
|
||||
|
||||
prefilteredColor = prefilteredColor / totalWeight;
|
||||
|
||||
FragColor = vec4(prefilteredColor, 1.0);
|
||||
}
|
||||
@@ -80,12 +80,12 @@ int main()
|
||||
|
||||
// build and compile shaders
|
||||
// -------------------------
|
||||
Shader pbrShader("2.2.2.pbr.vs", "2.2.2.pbr.frag");
|
||||
Shader equirectangularToCubemapShader("2.2.1.cubemap.vs", "2.2.1.equirectangular_to_cubemap.frag");
|
||||
Shader irradianceShader("2.2.1.cubemap.vs", "2.2.1.irradiance_convolution.frag");
|
||||
Shader prefilterShader("2.2.1.cubemap.vs", "2.2.1.prefilter.frag");
|
||||
Shader brdfShader("2.2.1.brdf.vs", "2.2.1.brdf.frag");
|
||||
Shader backgroundShader("2.2.1.background.vs", "2.2.1.background.frag");
|
||||
Shader pbrShader("2.2.2.pbr.vs", "2.2.2.pbr.fs");
|
||||
Shader equirectangularToCubemapShader("2.2.2.cubemap.vs", "2.2.2.equirectangular_to_cubemap.fs");
|
||||
Shader irradianceShader("2.2.2.cubemap.vs", "2.2.2.irradiance_convolution.fs");
|
||||
Shader prefilterShader("2.2.2.cubemap.vs", "2.2.2.prefilter.fs");
|
||||
Shader brdfShader("2.2.2.brdf.vs", "2.2.2.brdf.fs");
|
||||
Shader backgroundShader("2.2.2.background.vs", "2.2.2.background.fs");
|
||||
|
||||
pbrShader.use();
|
||||
pbrShader.setInt("irradianceMap", 0);
|
||||
|
||||
Reference in New Issue
Block a user