Textured PBR IBL example
This commit is contained in:
parent
5912aa0a7c
commit
3bf12c69d3
22 changed files with 2232 additions and 0 deletions
19
data/shaders/pbrtexture/filtercube.vert
Normal file
19
data/shaders/pbrtexture/filtercube.vert
Normal file
|
|
@ -0,0 +1,19 @@
|
|||
#version 450
|
||||
|
||||
layout (location = 0) in vec3 inPos;
|
||||
|
||||
layout(push_constant) uniform PushConsts {
|
||||
layout (offset = 0) mat4 mvp;
|
||||
} pushConsts;
|
||||
|
||||
layout (location = 0) out vec3 outUVW;
|
||||
|
||||
out gl_PerVertex {
|
||||
vec4 gl_Position;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
outUVW = inPos;
|
||||
gl_Position = pushConsts.mvp * vec4(inPos.xyz, 1.0);
|
||||
}
|
||||
BIN
data/shaders/pbrtexture/filtercube.vert.spv
Normal file
BIN
data/shaders/pbrtexture/filtercube.vert.spv
Normal file
Binary file not shown.
90
data/shaders/pbrtexture/genbrdflut.frag
Normal file
90
data/shaders/pbrtexture/genbrdflut.frag
Normal file
|
|
@ -0,0 +1,90 @@
|
|||
#version 450
|
||||
|
||||
layout (location = 0) in vec2 inUV;
|
||||
layout (location = 0) out vec4 outColor;
|
||||
layout (constant_id = 0) const uint NUM_SAMPLES = 1024u;
|
||||
|
||||
const float PI = 3.1415926536;
|
||||
|
||||
// Based omn http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/
|
||||
float random(vec2 co)
|
||||
{
|
||||
float a = 12.9898;
|
||||
float b = 78.233;
|
||||
float c = 43758.5453;
|
||||
float dt= dot(co.xy ,vec2(a,b));
|
||||
float sn= mod(dt,3.14);
|
||||
return fract(sin(sn) * c);
|
||||
}
|
||||
|
||||
vec2 hammersley2d(uint i, uint N)
|
||||
{
|
||||
// Radical inverse based on http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
|
||||
uint bits = (i << 16u) | (i >> 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);
|
||||
float rdi = float(bits) * 2.3283064365386963e-10;
|
||||
return vec2(float(i) /float(N), rdi);
|
||||
}
|
||||
|
||||
// Based on http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_slides.pdf
|
||||
vec3 importanceSample_GGX(vec2 Xi, float roughness, vec3 normal)
|
||||
{
|
||||
// Maps a 2D point to a hemisphere with spread based on roughness
|
||||
float alpha = roughness * roughness;
|
||||
float phi = 2.0 * PI * Xi.x + random(normal.xz) * 0.1;
|
||||
float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (alpha*alpha - 1.0) * Xi.y));
|
||||
float sinTheta = sqrt(1.0 - cosTheta * cosTheta);
|
||||
vec3 H = vec3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta);
|
||||
|
||||
// Tangent space
|
||||
vec3 up = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
|
||||
vec3 tangentX = normalize(cross(up, normal));
|
||||
vec3 tangentY = normalize(cross(normal, tangentX));
|
||||
|
||||
// Convert to world Space
|
||||
return normalize(tangentX * H.x + tangentY * H.y + normal * H.z);
|
||||
}
|
||||
|
||||
// Geometric Shadowing function
|
||||
float G_SchlicksmithGGX(float dotNL, float dotNV, float roughness)
|
||||
{
|
||||
float k = (roughness * roughness) / 2.0;
|
||||
float GL = dotNL / (dotNL * (1.0 - k) + k);
|
||||
float GV = dotNV / (dotNV * (1.0 - k) + k);
|
||||
return GL * GV;
|
||||
}
|
||||
|
||||
vec2 BRDF(float NoV, float roughness)
|
||||
{
|
||||
// Normal always points along z-axis for the 2D lookup
|
||||
const vec3 N = vec3(0.0, 0.0, 1.0);
|
||||
vec3 V = vec3(sqrt(1.0 - NoV*NoV), 0.0, NoV);
|
||||
|
||||
vec2 LUT = vec2(0.0);
|
||||
for(uint i = 0u; i < NUM_SAMPLES; i++) {
|
||||
vec2 Xi = hammersley2d(i, NUM_SAMPLES);
|
||||
vec3 H = importanceSample_GGX(Xi, roughness, N);
|
||||
vec3 L = 2.0 * dot(V, H) * H - V;
|
||||
|
||||
float dotNL = max(dot(N, L), 0.0);
|
||||
float dotNV = max(dot(N, V), 0.0);
|
||||
float dotVH = max(dot(V, H), 0.0);
|
||||
float dotNH = max(dot(H, N), 0.0);
|
||||
|
||||
if (dotNL > 0.0) {
|
||||
float G = G_SchlicksmithGGX(dotNL, dotNV, roughness);
|
||||
float G_Vis = (G * dotVH) / (dotNH * dotNV);
|
||||
float Fc = pow(1.0 - dotVH, 5.0);
|
||||
LUT += vec2((1.0 - Fc) * G_Vis, Fc * G_Vis);
|
||||
}
|
||||
}
|
||||
return LUT / float(NUM_SAMPLES);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
outColor = vec4(BRDF(inUV.s, 1.0-inUV.t), 0.0, 1.0);
|
||||
}
|
||||
BIN
data/shaders/pbrtexture/genbrdflut.frag.spv
Normal file
BIN
data/shaders/pbrtexture/genbrdflut.frag.spv
Normal file
Binary file not shown.
9
data/shaders/pbrtexture/genbrdflut.vert
Normal file
9
data/shaders/pbrtexture/genbrdflut.vert
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
#version 450
|
||||
|
||||
layout (location = 0) out vec2 outUV;
|
||||
|
||||
void main()
|
||||
{
|
||||
outUV = vec2((gl_VertexIndex << 1) & 2, gl_VertexIndex & 2);
|
||||
gl_Position = vec4(outUV * 2.0f - 1.0f, 0.0f, 1.0f);
|
||||
}
|
||||
BIN
data/shaders/pbrtexture/genbrdflut.vert.spv
Normal file
BIN
data/shaders/pbrtexture/genbrdflut.vert.spv
Normal file
Binary file not shown.
37
data/shaders/pbrtexture/irradiancecube.frag
Normal file
37
data/shaders/pbrtexture/irradiancecube.frag
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
// Generates an irradiance cube from an environment map using convolution
|
||||
|
||||
#version 450
|
||||
|
||||
layout (location = 0) in vec3 inPos;
|
||||
layout (location = 0) out vec4 outColor;
|
||||
layout (binding = 0) uniform samplerCube samplerEnv;
|
||||
|
||||
layout(push_constant) uniform PushConsts {
|
||||
layout (offset = 64) float deltaPhi;
|
||||
layout (offset = 68) float deltaTheta;
|
||||
} consts;
|
||||
|
||||
#define PI 3.1415926535897932384626433832795
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 N = normalize(inPos);
|
||||
vec3 up = vec3(0.0, 1.0, 0.0);
|
||||
vec3 right = normalize(cross(up, N));
|
||||
up = cross(N, right);
|
||||
|
||||
const float TWO_PI = PI * 2.0;
|
||||
const float HALF_PI = PI * 0.5;
|
||||
|
||||
vec3 color = vec3(0.0);
|
||||
uint sampleCount = 0u;
|
||||
for (float phi = 0.0; phi < TWO_PI; phi += consts.deltaPhi) {
|
||||
for (float theta = 0.0; theta < HALF_PI; theta += consts.deltaTheta) {
|
||||
vec3 tempVec = cos(phi) * right + sin(phi) * up;
|
||||
vec3 sampleVector = cos(theta) * N + sin(theta) * tempVec;
|
||||
color += texture(samplerEnv, sampleVector).rgb * cos(theta) * sin(theta);
|
||||
sampleCount++;
|
||||
}
|
||||
}
|
||||
outColor = vec4(PI * color / float(sampleCount), 1.0);
|
||||
}
|
||||
BIN
data/shaders/pbrtexture/irradiancecube.frag.spv
Normal file
BIN
data/shaders/pbrtexture/irradiancecube.frag.spv
Normal file
Binary file not shown.
178
data/shaders/pbrtexture/pbrtexture.frag
Normal file
178
data/shaders/pbrtexture/pbrtexture.frag
Normal file
|
|
@ -0,0 +1,178 @@
|
|||
#version 450
|
||||
|
||||
layout (location = 0) in vec3 inWorldPos;
|
||||
layout (location = 1) in vec3 inNormal;
|
||||
layout (location = 2) in vec2 inUV;
|
||||
|
||||
layout (binding = 0) uniform UBO {
|
||||
mat4 projection;
|
||||
mat4 model;
|
||||
mat4 view;
|
||||
vec3 camPos;
|
||||
} ubo;
|
||||
|
||||
layout (binding = 1) uniform UBOParams {
|
||||
vec4 lights[4];
|
||||
float exposure;
|
||||
float gamma;
|
||||
} uboParams;
|
||||
|
||||
layout (binding = 2) uniform samplerCube samplerIrradiance;
|
||||
layout (binding = 3) uniform sampler2D samplerBRDFLUT;
|
||||
layout (binding = 4) uniform samplerCube prefilteredMap;
|
||||
|
||||
layout (binding = 5) uniform sampler2D albedoMap;
|
||||
layout (binding = 6) uniform sampler2D normalMap;
|
||||
layout (binding = 7) uniform sampler2D aoMap;
|
||||
layout (binding = 8) uniform sampler2D metallicMap;
|
||||
layout (binding = 9) uniform sampler2D roughnessMap;
|
||||
|
||||
|
||||
layout (location = 0) out vec4 outColor;
|
||||
|
||||
#define PI 3.1415926535897932384626433832795
|
||||
#define ALBEDO pow(texture(albedoMap, inUV).rgb, vec3(2.2))
|
||||
|
||||
// From http://filmicgames.com/archives/75
|
||||
vec3 Uncharted2Tonemap(vec3 x)
|
||||
{
|
||||
float A = 0.15;
|
||||
float B = 0.50;
|
||||
float C = 0.10;
|
||||
float D = 0.20;
|
||||
float E = 0.02;
|
||||
float F = 0.30;
|
||||
return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F;
|
||||
}
|
||||
|
||||
// Normal Distribution function --------------------------------------
|
||||
float D_GGX(float dotNH, float roughness)
|
||||
{
|
||||
float alpha = roughness * roughness;
|
||||
float alpha2 = alpha * alpha;
|
||||
float denom = dotNH * dotNH * (alpha2 - 1.0) + 1.0;
|
||||
return (alpha2)/(PI * denom*denom);
|
||||
}
|
||||
|
||||
// Geometric Shadowing function --------------------------------------
|
||||
float G_SchlicksmithGGX(float dotNL, float dotNV, float roughness)
|
||||
{
|
||||
float r = (roughness + 1.0);
|
||||
float k = (r*r) / 8.0;
|
||||
float GL = dotNL / (dotNL * (1.0 - k) + k);
|
||||
float GV = dotNV / (dotNV * (1.0 - k) + k);
|
||||
return GL * GV;
|
||||
}
|
||||
|
||||
// Fresnel function ----------------------------------------------------
|
||||
vec3 F_Schlick(float cosTheta, vec3 F0)
|
||||
{
|
||||
return F0 + (1.0 - F0) * pow(1.0 - cosTheta, 5.0);
|
||||
}
|
||||
vec3 F_SchlickR(float cosTheta, vec3 F0, float roughness)
|
||||
{
|
||||
return F0 + (max(vec3(1.0 - roughness), F0) - F0) * pow(1.0 - cosTheta, 5.0);
|
||||
}
|
||||
|
||||
vec3 prefilteredReflection(vec3 R, float roughness)
|
||||
{
|
||||
const float MAX_REFLECTION_LOD = 9.0; // todo: param/const
|
||||
float lod = roughness * MAX_REFLECTION_LOD;
|
||||
float lodf = floor(lod);
|
||||
float lodc = ceil(lod);
|
||||
vec3 a = textureLod(prefilteredMap, R, lodf).rgb;
|
||||
vec3 b = textureLod(prefilteredMap, R, lodc).rgb;
|
||||
return mix(a, b, lod - lodf);
|
||||
}
|
||||
|
||||
vec3 specularContribution(vec3 L, vec3 V, vec3 N, vec3 F0, float metallic, float roughness)
|
||||
{
|
||||
// Precalculate vectors and dot products
|
||||
vec3 H = normalize (V + L);
|
||||
float dotNH = clamp(dot(N, H), 0.0, 1.0);
|
||||
float dotNV = clamp(dot(N, V), 0.0, 1.0);
|
||||
float dotNL = clamp(dot(N, L), 0.0, 1.0);
|
||||
|
||||
// Light color fixed
|
||||
vec3 lightColor = vec3(1.0);
|
||||
|
||||
vec3 color = vec3(0.0);
|
||||
|
||||
if (dotNL > 0.0) {
|
||||
// D = Normal distribution (Distribution of the microfacets)
|
||||
float D = D_GGX(dotNH, roughness);
|
||||
// G = Geometric shadowing term (Microfacets shadowing)
|
||||
float G = G_SchlicksmithGGX(dotNL, dotNV, roughness);
|
||||
// F = Fresnel factor (Reflectance depending on angle of incidence)
|
||||
vec3 F = F_Schlick(dotNV, F0);
|
||||
vec3 spec = D * F * G / (4.0 * dotNL * dotNV + 0.001);
|
||||
vec3 kD = (vec3(1.0) - F) * (1.0 - metallic);
|
||||
color += (kD * ALBEDO / PI + spec) * dotNL;
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
// See http://www.thetenthplanet.de/archives/1180
|
||||
vec3 perturbNormal()
|
||||
{
|
||||
vec3 tangentNormal = texture(normalMap, inUV).xyz * 2.0 - 1.0;
|
||||
|
||||
vec3 q1 = dFdx(inWorldPos);
|
||||
vec3 q2 = dFdy(inWorldPos);
|
||||
vec2 st1 = dFdx(inUV);
|
||||
vec2 st2 = dFdy(inUV);
|
||||
|
||||
vec3 N = normalize(inNormal);
|
||||
vec3 T = normalize(q1 * st2.t - q2 * st1.t);
|
||||
vec3 B = -normalize(cross(N, T));
|
||||
mat3 TBN = mat3(T, B, N);
|
||||
|
||||
return normalize(TBN * tangentNormal);
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 N = perturbNormal();
|
||||
vec3 V = normalize(ubo.camPos - inWorldPos);
|
||||
vec3 R = reflect(-V, N);
|
||||
|
||||
float metallic = texture(metallicMap, inUV).r;
|
||||
float roughness = texture(roughnessMap, inUV).r;
|
||||
|
||||
vec3 F0 = vec3(0.04);
|
||||
F0 = mix(F0, ALBEDO, metallic);
|
||||
|
||||
vec3 Lo = vec3(0.0);
|
||||
for(int i = 0; i < uboParams.lights[i].length(); i++) {
|
||||
vec3 L = normalize(uboParams.lights[i].xyz - inWorldPos);
|
||||
Lo += specularContribution(L, V, N, F0, metallic, roughness);
|
||||
}
|
||||
|
||||
vec2 brdf = texture(samplerBRDFLUT, vec2(max(dot(N, V), 0.0), roughness)).rg;
|
||||
vec3 reflection = prefilteredReflection(R, roughness).rgb;
|
||||
vec3 irradiance = texture(samplerIrradiance, N).rgb;
|
||||
|
||||
// Diffuse based on irradiance
|
||||
vec3 diffuse = irradiance * ALBEDO;
|
||||
|
||||
vec3 F = F_SchlickR(max(dot(N, V), 0.0), F0, roughness);
|
||||
|
||||
// Specular reflectance
|
||||
vec3 specular = reflection * (F * brdf.x + brdf.y);
|
||||
|
||||
// Ambient part
|
||||
vec3 kD = 1.0 - F;
|
||||
kD *= 1.0 - metallic;
|
||||
vec3 ambient = (kD * diffuse + specular) * texture(aoMap, inUV).rrr;
|
||||
|
||||
vec3 color = ambient + Lo;
|
||||
|
||||
// Tone mapping
|
||||
color = Uncharted2Tonemap(color * uboParams.exposure);
|
||||
color = color * (1.0f / Uncharted2Tonemap(vec3(11.2f)));
|
||||
// Gamma correction
|
||||
color = pow(color, vec3(1.0f / uboParams.gamma));
|
||||
|
||||
outColor = vec4(color, 1.0);
|
||||
}
|
||||
BIN
data/shaders/pbrtexture/pbrtexture.frag.spv
Normal file
BIN
data/shaders/pbrtexture/pbrtexture.frag.spv
Normal file
Binary file not shown.
35
data/shaders/pbrtexture/pbrtexture.vert
Normal file
35
data/shaders/pbrtexture/pbrtexture.vert
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
#version 450
|
||||
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
#extension GL_ARB_shading_language_420pack : enable
|
||||
|
||||
layout (location = 0) in vec3 inPos;
|
||||
layout (location = 1) in vec3 inNormal;
|
||||
layout (location = 2) in vec2 inUV;
|
||||
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 projection;
|
||||
mat4 model;
|
||||
mat4 view;
|
||||
vec3 camPos;
|
||||
} ubo;
|
||||
|
||||
layout (location = 0) out vec3 outWorldPos;
|
||||
layout (location = 1) out vec3 outNormal;
|
||||
layout (location = 2) out vec2 outUV;
|
||||
|
||||
out gl_PerVertex
|
||||
{
|
||||
vec4 gl_Position;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 locPos = vec3(ubo.model * vec4(inPos, 1.0));
|
||||
outWorldPos = locPos;
|
||||
outNormal = mat3(ubo.model) * inNormal;
|
||||
outUV = inUV;
|
||||
outUV.t = 1.0 - inUV.t;
|
||||
gl_Position = ubo.projection * ubo.view * vec4(outWorldPos, 1.0);
|
||||
}
|
||||
BIN
data/shaders/pbrtexture/pbrtexture.vert.spv
Normal file
BIN
data/shaders/pbrtexture/pbrtexture.vert.spv
Normal file
Binary file not shown.
105
data/shaders/pbrtexture/prefilterenvmap.frag
Normal file
105
data/shaders/pbrtexture/prefilterenvmap.frag
Normal file
|
|
@ -0,0 +1,105 @@
|
|||
#version 450
|
||||
|
||||
layout (location = 0) in vec3 inPos;
|
||||
layout (location = 0) out vec4 outColor;
|
||||
|
||||
layout (binding = 0) uniform samplerCube samplerEnv;
|
||||
|
||||
layout(push_constant) uniform PushConsts {
|
||||
layout (offset = 64) float roughness;
|
||||
layout (offset = 68) uint numSamples;
|
||||
} consts;
|
||||
|
||||
const float PI = 3.1415926536;
|
||||
|
||||
// Based omn http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/
|
||||
float random(vec2 co)
|
||||
{
|
||||
float a = 12.9898;
|
||||
float b = 78.233;
|
||||
float c = 43758.5453;
|
||||
float dt= dot(co.xy ,vec2(a,b));
|
||||
float sn= mod(dt,3.14);
|
||||
return fract(sin(sn) * c);
|
||||
}
|
||||
|
||||
vec2 hammersley2d(uint i, uint N)
|
||||
{
|
||||
// Radical inverse based on http://holger.dammertz.org/stuff/notes_HammersleyOnHemisphere.html
|
||||
uint bits = (i << 16u) | (i >> 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);
|
||||
float rdi = float(bits) * 2.3283064365386963e-10;
|
||||
return vec2(float(i) /float(N), rdi);
|
||||
}
|
||||
|
||||
// Based on http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_slides.pdf
|
||||
vec3 importanceSample_GGX(vec2 Xi, float roughness, vec3 normal)
|
||||
{
|
||||
// Maps a 2D point to a hemisphere with spread based on roughness
|
||||
float alpha = roughness * roughness;
|
||||
float phi = 2.0 * PI * Xi.x + random(normal.xz) * 0.1;
|
||||
float cosTheta = sqrt((1.0 - Xi.y) / (1.0 + (alpha*alpha - 1.0) * Xi.y));
|
||||
float sinTheta = sqrt(1.0 - cosTheta * cosTheta);
|
||||
vec3 H = vec3(sinTheta * cos(phi), sinTheta * sin(phi), cosTheta);
|
||||
|
||||
// Tangent space
|
||||
vec3 up = abs(normal.z) < 0.999 ? vec3(0.0, 0.0, 1.0) : vec3(1.0, 0.0, 0.0);
|
||||
vec3 tangentX = normalize(cross(up, normal));
|
||||
vec3 tangentY = normalize(cross(normal, tangentX));
|
||||
|
||||
// Convert to world Space
|
||||
return normalize(tangentX * H.x + tangentY * H.y + normal * H.z);
|
||||
}
|
||||
|
||||
// Normal Distribution function
|
||||
float D_GGX(float dotNH, float roughness)
|
||||
{
|
||||
float alpha = roughness * roughness;
|
||||
float alpha2 = alpha * alpha;
|
||||
float denom = dotNH * dotNH * (alpha2 - 1.0) + 1.0;
|
||||
return (alpha2)/(PI * denom*denom);
|
||||
}
|
||||
|
||||
vec3 prefilterEnvMap(vec3 R, float roughness)
|
||||
{
|
||||
vec3 N = R;
|
||||
vec3 V = R;
|
||||
vec3 color = vec3(0.0);
|
||||
float totalWeight = 0.0;
|
||||
float envMapDim = float(textureSize(samplerEnv, 0).s);
|
||||
for(uint i = 0u; i < consts.numSamples; i++) {
|
||||
vec2 Xi = hammersley2d(i, consts.numSamples);
|
||||
vec3 H = importanceSample_GGX(Xi, roughness, N);
|
||||
vec3 L = 2.0 * dot(V, H) * H - V;
|
||||
float dotNL = clamp(dot(N, L), 0.0, 1.0);
|
||||
if(dotNL > 0.0) {
|
||||
// Filtering based on https://placeholderart.wordpress.com/2015/07/28/implementation-notes-runtime-environment-map-filtering-for-image-based-lighting/
|
||||
|
||||
float dotNH = clamp(dot(N, H), 0.0, 1.0);
|
||||
float dotVH = clamp(dot(V, H), 0.0, 1.0);
|
||||
|
||||
// Probability Distribution Function
|
||||
float pdf = D_GGX(dotNH, roughness) * dotNH / (4.0 * dotVH) + 0.0001;
|
||||
// Slid angle of current smple
|
||||
float omegaS = 1.0 / (float(consts.numSamples) * pdf);
|
||||
// Solid angle of 1 pixel across all cube faces
|
||||
float omegaP = 4.0 * PI / (6.0 * envMapDim * envMapDim);
|
||||
// Biased (+1.0) mip level for better result
|
||||
float mipLevel = roughness == 0.0 ? 0.0 : max(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f);
|
||||
color += textureLod(samplerEnv, L, mipLevel).rgb * dotNL;
|
||||
totalWeight += dotNL;
|
||||
|
||||
}
|
||||
}
|
||||
return (color / totalWeight);
|
||||
}
|
||||
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 N = normalize(inPos);
|
||||
outColor = vec4(prefilterEnvMap(N, consts.roughness), 1.0);
|
||||
}
|
||||
BIN
data/shaders/pbrtexture/prefilterenvmap.frag.spv
Normal file
BIN
data/shaders/pbrtexture/prefilterenvmap.frag.spv
Normal file
Binary file not shown.
39
data/shaders/pbrtexture/skybox.frag
Normal file
39
data/shaders/pbrtexture/skybox.frag
Normal file
|
|
@ -0,0 +1,39 @@
|
|||
#version 450
|
||||
|
||||
layout (binding = 2) uniform samplerCube samplerEnv;
|
||||
|
||||
layout (location = 0) in vec3 inUVW;
|
||||
|
||||
layout (location = 0) out vec4 outColor;
|
||||
|
||||
layout (binding = 1) uniform UBOParams {
|
||||
vec4 lights[4];
|
||||
float exposure;
|
||||
float gamma;
|
||||
} uboParams;
|
||||
|
||||
// From http://filmicworlds.com/blog/filmic-tonemapping-operators/
|
||||
vec3 Uncharted2Tonemap(vec3 color)
|
||||
{
|
||||
float A = 0.15;
|
||||
float B = 0.50;
|
||||
float C = 0.10;
|
||||
float D = 0.20;
|
||||
float E = 0.02;
|
||||
float F = 0.30;
|
||||
float W = 11.2;
|
||||
return ((color*(A*color+C*B)+D*E)/(color*(A*color+B)+D*F))-E/F;
|
||||
}
|
||||
|
||||
void main()
|
||||
{
|
||||
vec3 color = texture(samplerEnv, inUVW).rgb;
|
||||
|
||||
// Tone mapping
|
||||
color = Uncharted2Tonemap(color * uboParams.exposure);
|
||||
color = color * (1.0f / Uncharted2Tonemap(vec3(11.2f)));
|
||||
// Gamma correction
|
||||
color = pow(color, vec3(1.0f / uboParams.gamma));
|
||||
|
||||
outColor = vec4(color, 1.0);
|
||||
}
|
||||
BIN
data/shaders/pbrtexture/skybox.frag.spv
Normal file
BIN
data/shaders/pbrtexture/skybox.frag.spv
Normal file
Binary file not shown.
27
data/shaders/pbrtexture/skybox.vert
Normal file
27
data/shaders/pbrtexture/skybox.vert
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
#version 450
|
||||
|
||||
#extension GL_ARB_separate_shader_objects : enable
|
||||
#extension GL_ARB_shading_language_420pack : enable
|
||||
|
||||
layout (location = 0) in vec3 inPos;
|
||||
layout (location = 1) in vec3 inNormal;
|
||||
layout (location = 2) in vec2 inUV;
|
||||
|
||||
layout (binding = 0) uniform UBO
|
||||
{
|
||||
mat4 projection;
|
||||
mat4 model;
|
||||
} ubo;
|
||||
|
||||
layout (location = 0) out vec3 outUVW;
|
||||
|
||||
out gl_PerVertex
|
||||
{
|
||||
vec4 gl_Position;
|
||||
};
|
||||
|
||||
void main()
|
||||
{
|
||||
outUVW = inPos;
|
||||
gl_Position = ubo.projection * ubo.model * vec4(inPos.xyz, 1.0);
|
||||
}
|
||||
BIN
data/shaders/pbrtexture/skybox.vert.spv
Normal file
BIN
data/shaders/pbrtexture/skybox.vert.spv
Normal file
Binary file not shown.
1506
pbrtexture/main.cpp
Normal file
1506
pbrtexture/main.cpp
Normal file
File diff suppressed because it is too large
Load diff
106
pbrtexture/pbrtexture.vcxproj
Normal file
106
pbrtexture/pbrtexture.vcxproj
Normal file
|
|
@ -0,0 +1,106 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Globals">
|
||||
<ProjectGuid>{60316D67-E879-4671-B9BA-ED6B26F13AC7}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<WindowsTargetPlatformVersion>8.1</WindowsTargetPlatformVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<PlatformToolset>v140</PlatformToolset>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'" Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)\bin\</OutDir>
|
||||
<IntDir>$(SolutionDir)\bin\intermediate\$(ProjectName)\$(ConfigurationName)</IntDir>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
<OutDir>$(SolutionDir)\bin\</OutDir>
|
||||
<IntDir>$(SolutionDir)\bin\intermediate\$(ProjectName)\$(ConfigurationName)</IntDir>
|
||||
</PropertyGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;_DEBUG;_WINDOWS;VK_USE_PLATFORM_WIN32_KHR;_USE_MATH_DEFINES;NOMINMAX;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDebugDLL</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<AdditionalIncludeDirectories>..\base;..\external\glm;..\external\gli;..\external\assimp;..\external;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalOptions>/FS %(AdditionalOptions)</AdditionalOptions>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<AdditionalDependencies>..\libs\vulkan\vulkan-1.lib;..\libs\assimp\assimp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|x64'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;NDEBUG;_WINDOWS;VK_USE_PLATFORM_WIN32_KHR;_USE_MATH_DEFINES;NOMINMAX;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<RuntimeLibrary>MultiThreadedDLL</RuntimeLibrary>
|
||||
<WarningLevel>Level3</WarningLevel>
|
||||
<DebugInformationFormat>ProgramDatabase</DebugInformationFormat>
|
||||
<AdditionalIncludeDirectories>..\base;..\external\glm;..\external\gli;..\external\assimp;..\external;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<GenerateDebugInformation>true</GenerateDebugInformation>
|
||||
<SubSystem>Windows</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<AdditionalDependencies>..\libs\vulkan\vulkan-1.lib;..\libs\assimp\assimp.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\base\vulkandebug.cpp" />
|
||||
<ClCompile Include="..\base\vulkanexamplebase.cpp" />
|
||||
<ClCompile Include="..\base\vulkantools.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\base\vulkandebug.h" />
|
||||
<ClInclude Include="..\base\vulkanexamplebase.h" />
|
||||
<ClInclude Include="..\base\vulkantools.h" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\data\shaders\pbrtexture\genbrdflut.frag" />
|
||||
<None Include="..\data\shaders\pbrtexture\genbrdflut.vert" />
|
||||
<None Include="..\data\shaders\pbrtexture\irradiancecube.frag" />
|
||||
<None Include="..\data\shaders\pbrtexture\pbrtexture.frag" />
|
||||
<None Include="..\data\shaders\pbrtexture\pbrtexture.vert" />
|
||||
<None Include="..\data\shaders\pbrtexture\prefilterenvmap.frag" />
|
||||
<None Include="..\data\shaders\pbrtexture\filtercube.vert" />
|
||||
<None Include="..\data\shaders\pbrtexture\skybox.frag" />
|
||||
<None Include="..\data\shaders\pbrtexture\skybox.vert" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
74
pbrtexture/pbrtexture.vcxproj.filters
Normal file
74
pbrtexture/pbrtexture.vcxproj.filters
Normal file
|
|
@ -0,0 +1,74 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Shaders">
|
||||
<UniqueIdentifier>{3adf072b-32a9-412a-8eb5-5329a601df1a}</UniqueIdentifier>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="..\base\vulkandebug.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\base\vulkanexamplebase.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="..\base\vulkantools.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="main.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="..\base\vulkandebug.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\base\vulkanexamplebase.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="..\base\vulkantools.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="..\data\shaders\pbrtexture\pbrtexture.frag">
|
||||
<Filter>Shaders</Filter>
|
||||
</None>
|
||||
<None Include="..\data\shaders\pbrtexture\pbrtexture.vert">
|
||||
<Filter>Shaders</Filter>
|
||||
</None>
|
||||
<None Include="..\data\shaders\pbrtexture\skybox.frag">
|
||||
<Filter>Shaders</Filter>
|
||||
</None>
|
||||
<None Include="..\data\shaders\pbrtexture\skybox.vert">
|
||||
<Filter>Shaders</Filter>
|
||||
</None>
|
||||
<None Include="..\data\shaders\pbrtexture\prefilterenvmap.frag">
|
||||
<Filter>Shaders</Filter>
|
||||
</None>
|
||||
<None Include="..\data\shaders\pbrtexture\genbrdflut.frag">
|
||||
<Filter>Shaders</Filter>
|
||||
</None>
|
||||
<None Include="..\data\shaders\pbrtexture\genbrdflut.vert">
|
||||
<Filter>Shaders</Filter>
|
||||
</None>
|
||||
<None Include="..\data\shaders\pbrtexture\filtercube.vert">
|
||||
<Filter>Shaders</Filter>
|
||||
</None>
|
||||
<None Include="..\data\shaders\pbrtexture\irradiancecube.frag">
|
||||
<Filter>Shaders</Filter>
|
||||
</None>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -149,6 +149,8 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "viewportarray", "viewportar
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "imgui", "imgui\imgui.vcxproj", "{3BC2A597-A8BD-41AE-816B-2C242579D64E}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pbrtexture", "pbrtexture\pbrtexture.vcxproj", "{60316D67-E879-4671-B9BA-ED6B26F13AC7}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|x64 = Debug|x64
|
||||
|
|
@ -363,6 +365,10 @@ Global
|
|||
{3BC2A597-A8BD-41AE-816B-2C242579D64E}.Debug|x64.Build.0 = Debug|x64
|
||||
{3BC2A597-A8BD-41AE-816B-2C242579D64E}.Release|x64.ActiveCfg = Release|x64
|
||||
{3BC2A597-A8BD-41AE-816B-2C242579D64E}.Release|x64.Build.0 = Release|x64
|
||||
{60316D67-E879-4671-B9BA-ED6B26F13AC7}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{60316D67-E879-4671-B9BA-ED6B26F13AC7}.Debug|x64.Build.0 = Debug|x64
|
||||
{60316D67-E879-4671-B9BA-ED6B26F13AC7}.Release|x64.ActiveCfg = Release|x64
|
||||
{60316D67-E879-4671-B9BA-ED6B26F13AC7}.Release|x64.Build.0 = Release|x64
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
@ -387,5 +393,6 @@ Global
|
|||
{6B4BC372-5897-40FB-91D4-421C2817F656} = {6B47BC47-0394-429E-9441-867EC23DFCD4}
|
||||
{659987E9-863C-4B9B-A3D4-CBA7D67A9516} = {BE290A75-7E65-4D0A-B419-774A309B6A60}
|
||||
{92B2640A-0CC5-48EA-B34C-520BA13938D1} = {BE290A75-7E65-4D0A-B419-774A309B6A60}
|
||||
{60316D67-E879-4671-B9BA-ED6B26F13AC7} = {BE290A75-7E65-4D0A-B419-774A309B6A60}
|
||||
EndGlobalSection
|
||||
EndGlobal
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue