Skip to content

Commit

Permalink
Updated the source code to the latest WIP
Browse files Browse the repository at this point in the history
  • Loading branch information
corporateshark committed Jun 19, 2024
1 parent 4f51a6c commit b8ff667
Show file tree
Hide file tree
Showing 20 changed files with 1,227 additions and 678 deletions.
1 change: 0 additions & 1 deletion Chapter02/03_GLM/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,6 @@ int main()
.cullMode = lvk::CullMode_Back,
});

// the storage must be alive until the pipeline exists
const uint32_t isWireframe = 1;

lvk::Holder<lvk::RenderPipelineHandle> pipelineWireframe = ctx->createRenderPipeline({
Expand Down
1 change: 0 additions & 1 deletion Chapter03/01_Assimp/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,6 @@ int main()
.cullMode = lvk::CullMode_Back,
});

// the storage must be alive until the pipeline exists
const uint32_t isWireframe = 1;

lvk::Holder<lvk::RenderPipelineHandle> pipelineWireframe = ctx->createRenderPipeline({
Expand Down
5 changes: 4 additions & 1 deletion Chapter06/03_FilterEnvmap/src/main.frag
Original file line number Diff line number Diff line change
Expand Up @@ -192,7 +192,10 @@ float computeLod(float pdf) {
// We achieved good results by using the original formulation from Krivanek & Colbert adapted to cubemaps

// https://cgg.mff.cuni.cz/~jaroslav/papers/2007-sketch-fis/Final_sap_0073.pdf
float lod = 0.5 * log2( 6.0 * float(perFrameData.width) * float(perFrameData.height) / (float(perFrameData.sampleCount) * pdf));
float width = float(perFrameData.width);
float height = float(perFrameData.height);
float sampleCount = float(perFrameData.sampleCount);
float lod = 0.5 * log2( 6.0 * with * height / (sampleCount * pdf));

return lod;
}
Expand Down
30 changes: 16 additions & 14 deletions Chapter06/04_MetallicRoughness/src/PBR.sp
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,10 @@ struct PBRInfo {
// specularWeight is introduced with KHR_materials_specular
vec3 getIBLRadianceLambertian(float NdotV, vec3 n, float roughness, vec3 diffuseColor, vec3 F0, float specularWeight) {
vec2 brdfSamplePoint = clamp(vec2(NdotV, roughness), vec2(0.0, 0.0), vec2(1.0, 1.0));
vec2 f_ab = sampleBRDF_LUT(brdfSamplePoint, getMaterialId()).rg;
EnvironmentMapDataGPU envMap = getEnvironment(getEnvironmentId());
vec2 f_ab = sampleBRDF_LUT(brdfSamplePoint, envMap).rg;

vec3 irradiance = sampleEnvMapIrradiance(n.xyz, getEnvironmentId()).rgb;
vec3 irradiance = sampleEnvMapIrradiance(n.xyz, envMap).rgb;

// see https://bruop.github.io/ibl/#single_scattering_results at Single Scattering Results
// Roughness dependent fresnel, from Fdez-Aguera
Expand All @@ -53,14 +54,15 @@ vec3 getIBLRadianceContributionGGX(PBRInfo pbrInputs, float specularWeight) {
vec3 n = pbrInputs.n;
vec3 v = pbrInputs.v;
vec3 reflection = -normalize(reflect(v, n));
float mipCount = float(sampleEnvMapQueryLevels(getMaterialId()));
EnvironmentMapDataGPU envMap = getEnvironment(getEnvironmentId());
float mipCount = float(sampleEnvMapQueryLevels(envMap));
float lod = pbrInputs.perceptualRoughness * (mipCount - 1);

// retrieve a scale and bias to F0. See [1], Figure 3
vec2 brdfSamplePoint = clamp(vec2(pbrInputs.NdotV, pbrInputs.perceptualRoughness), vec2(0.0, 0.0), vec2(1.0, 1.0));
vec3 brdf = sampleBRDF_LUT(brdfSamplePoint, getMaterialId()).rgb;
vec3 brdf = sampleBRDF_LUT(brdfSamplePoint, envMap).rgb;
// HDR envmaps are already linear
vec3 specularLight = sampleEnvMapLod(reflection.xyz, lod, getEnvironmentId()).rgb;
vec3 specularLight = sampleEnvMapLod(reflection.xyz, lod, envMap).rgb;

// see https://bruop.github.io/ibl/#single_scattering_results at Single Scattering Results
// Roughness dependent fresnel, from Fdez-Aguera
Expand Down Expand Up @@ -111,18 +113,18 @@ float microfacetDistribution(PBRInfo pbrInputs) {
PBRInfo calculatePBRInputsMetallicRoughness( vec4 albedo, vec3 normal, vec3 cameraPos, vec3 worldPos, vec4 mrSample) {
PBRInfo pbrInputs;

float perceptualRoughness = getRoughnessFactor(getMaterialId());
float metallic = getMetallicFactor(getMaterialId());
MetallicRoughnessDataGPU mat = getMaterial(getMaterialId());
float perceptualRoughness = getRoughnessFactor(mat);
float metallic = getMetallicFactor(mat) * mrSample.b;
metallic = clamp(metallic, 0.0, 1.0);

// Roughness is stored in the 'g' channel, metallic is stored in the 'b' channel.
// This layout intentionally reserves the 'r' channel for (optional) occlusion map data
perceptualRoughness = mrSample.g * perceptualRoughness;
metallic = mrSample.b * metallic;

const float c_MinRoughness = 0.04;

perceptualRoughness = clamp(perceptualRoughness, c_MinRoughness, 1.0);
metallic = clamp(metallic, 0.0, 1.0);

// Roughness is authored as perceptual roughness; as is convention,
// convert to material roughness by squaring the perceptual roughness [2].
float alphaRoughness = perceptualRoughness * perceptualRoughness;
Expand Down Expand Up @@ -162,13 +164,13 @@ PBRInfo calculatePBRInputsMetallicRoughness( vec4 albedo, vec3 normal, vec3 came
vec3 calculatePBRLightContribution( inout PBRInfo pbrInputs, vec3 lightDirection, vec3 lightColor ) {
vec3 n = pbrInputs.n;
vec3 v = pbrInputs.v;
vec3 l = normalize(lightDirection); // Vector from surface point to light
vec3 h = normalize(l+v); // Half vector between both l and v
vec3 ld = normalize(lightDirection); // Vector from surface point to light
vec3 h = normalize(ld+v); // Half vector between both l and v

float NdotV = pbrInputs.NdotV;
float NdotL = clamp(dot(n, l), 0.001, 1.0);
float NdotL = clamp(dot(n, ld), 0.001, 1.0);
float NdotH = clamp(dot(n, h), 0.0, 1.0);
float LdotH = clamp(dot(l, h), 0.0, 1.0);
float LdotH = clamp(dot(ld, h), 0.0, 1.0);
float VdotH = clamp(dot(v, h), 0.0, 1.0);

vec3 color = vec3(0);
Expand Down
49 changes: 17 additions & 32 deletions Chapter06/04_MetallicRoughness/src/inputs.frag
Original file line number Diff line number Diff line change
Expand Up @@ -53,81 +53,66 @@ MetallicRoughnessDataGPU getMaterial(uint idx) {
return perFrame.materials.material[idx];
}

EnvironmentMapDataGPU getEnvironmentMap(uint idx) {
EnvironmentMapDataGPU getEnvironment(uint idx) {
return perFrame.environments.environment[idx];
}

float getMetallicFactor(uint idx) {
MetallicRoughnessDataGPU mat = getMaterial(idx);
float getMetallicFactor(MetallicRoughnessDataGPU mat) {
return mat.metallicRoughnessNormalOcclusion.x;
}

float getRoughnessFactor(uint idx) {
MetallicRoughnessDataGPU mat = getMaterial(idx);
float getRoughnessFactor(MetallicRoughnessDataGPU mat) {
return mat.metallicRoughnessNormalOcclusion.y;
}

float getNormalScale(uint idx) {
MetallicRoughnessDataGPU mat = getMaterial(idx);
float getNormalScale(MetallicRoughnessDataGPU mat) {
return mat.metallicRoughnessNormalOcclusion.z;
}

float getOcclusionFactor(uint idx) {
MetallicRoughnessDataGPU mat = getMaterial(idx);
float getOcclusionFactor(MetallicRoughnessDataGPU mat) {
return mat.metallicRoughnessNormalOcclusion.w;
}

vec2 getNormalUV(InputAttributes tc, uint idx) {
MetallicRoughnessDataGPU mat = getMaterial(idx);
vec2 getNormalUV(InputAttributes tc, MetallicRoughnessDataGPU mat) {
return tc.uv[mat.normalTextureUV];
}

vec4 sampleAO(InputAttributes tc, uint idx) {
MetallicRoughnessDataGPU mat = getMaterial(idx);
vec4 sampleAO(InputAttributes tc, MetallicRoughnessDataGPU mat) {
return textureBindless2D(mat.occlusionTexture, mat.occlusionTextureSampler, tc.uv[mat.occlusionTextureUV]);
}

vec4 sampleEmissive(InputAttributes tc, uint idx) {
MetallicRoughnessDataGPU mat = getMaterial(idx);
vec4 sampleEmissive(InputAttributes tc, MetallicRoughnessDataGPU mat) {
return textureBindless2D(mat.emissiveTexture, mat.emissiveTextureSampler, tc.uv[mat.emissiveTextureUV]) * vec4(mat.emissiveFactorAlphaCutoff.xyz, 1.0f);
}

vec4 sampleAlbedo(InputAttributes tc, uint idx) {
MetallicRoughnessDataGPU mat = getMaterial(idx);
vec4 sampleAlbedo(InputAttributes tc, MetallicRoughnessDataGPU mat) {
return textureBindless2D(mat.baseColorTexture, mat.baseColorTextureSampler, tc.uv[mat.baseColorTextureUV]) * mat.baseColorFactor;
}

vec4 sampleMetallicRoughness(InputAttributes tc, uint idx) {
MetallicRoughnessDataGPU mat = getMaterial(idx);
vec4 sampleMetallicRoughness(InputAttributes tc, MetallicRoughnessDataGPU mat) {
return textureBindless2D(mat.metallicRoughnessTexture, mat.metallicRoughnessTextureSampler, tc.uv[mat.metallicRoughnessTextureUV]);
}

vec4 sampleNormal(InputAttributes tc, uint idx) {
MetallicRoughnessDataGPU mat = getMaterial(idx);
vec4 sampleNormal(InputAttributes tc, MetallicRoughnessDataGPU mat) {
return textureBindless2D(mat.normalTexture, mat.normalTextureSampler, tc.uv[mat.normalTextureUV]);
}

vec4 sampleBRDF_LUT(vec2 tc, uint idx) {
EnvironmentMapDataGPU map = getEnvironmentMap(idx);
vec4 sampleBRDF_LUT(vec2 tc, EnvironmentMapDataGPU map) {
return textureBindless2D(map.texBRDF_LUT, map.texBRDF_LUTSampler, tc);
}

vec4 sampleEnvMap(vec3 tc, uint idx) {
EnvironmentMapDataGPU map = getEnvironmentMap(idx);
vec4 sampleEnvMap(vec3 tc, EnvironmentMapDataGPU map) {
return textureBindlessCube(map.envMapTexture, map.envMapTextureSampler, tc);
}

vec4 sampleEnvMapLod(vec3 tc, float lod, uint idx) {
EnvironmentMapDataGPU map = getEnvironmentMap(idx);
vec4 sampleEnvMapLod(vec3 tc, float lod, EnvironmentMapDataGPU map) {
return textureBindlessCubeLod(map.envMapTexture, map.envMapTextureSampler, tc, lod);
}

vec4 sampleEnvMapIrradiance(vec3 tc, uint idx) {
EnvironmentMapDataGPU map = getEnvironmentMap(idx);
vec4 sampleEnvMapIrradiance(vec3 tc, EnvironmentMapDataGPU map) {
return textureBindlessCube(map.envMapTextureIrradiance, map.envMapTextureIrradianceSampler, tc);
}

int sampleEnvMapQueryLevels(uint idx) {
EnvironmentMapDataGPU map = getEnvironmentMap(idx);
return textureBindlessQueryLevels2D(map.envMapTexture);
int sampleEnvMapQueryLevels(EnvironmentMapDataGPU map) {
return textureBindlessQueryLevelsCube(map.envMapTexture);
}
12 changes: 6 additions & 6 deletions Chapter06/04_MetallicRoughness/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,11 +52,11 @@ struct MetallicRoughnessMaterialsPerFrame {
MetallicRoughnessDataGPU materials[kMaxMaterials];
};

glTFMaterialTextures loadMaterialTextures(
GLTFMaterialTextures loadMaterialTextures(
const std::unique_ptr<lvk::IContext>& ctx, const char* texAOFile, const char* texEmissiveFile, const char* texAlbedoFile,
const char* texMeRFile, const char* texNormalFile)
{
glTFMaterialTextures mat;
GLTFMaterialTextures mat;

mat.baseColorTexture = loadTexture(ctx, texAlbedoFile, lvk::TextureType_2D, true);
if (mat.baseColorTexture.empty()) {
Expand Down Expand Up @@ -89,7 +89,7 @@ glTFMaterialTextures loadMaterialTextures(
}

MetallicRoughnessDataGPU setupMetallicRoughnessData(
const glTFGlobalSamplers& samplers, const glTFMaterialTextures& mat, const aiMaterial* mtlDescriptor)
const GLTFGlobalSamplers& samplers, const GLTFMaterialTextures& mat, const aiMaterial* mtlDescriptor)
{
MetallicRoughnessDataGPU res = {
.baseColorFactor = vec4(1.0f, 1.0f, 1.0f, 1.0f),
Expand Down Expand Up @@ -173,7 +173,7 @@ int main()
const aiMesh* mesh = scene->mMeshes[0];

std::vector<Vertex> vertices;
for (unsigned int i = 0; i != mesh->mNumVertices; i++) {
for (uint32_t i = 0; i != mesh->mNumVertices; i++) {
const aiVector3D v = mesh->mVertices[i];
const aiVector3D n = mesh->mNormals ? mesh->mNormals[i] : aiVector3D(0.0f, 1.0f, 0.0f);
const aiColor4D c = mesh->mColors[0] ? mesh->mColors[0][i] : aiColor4D(1.0f, 1.0f, 1.0f, 1.0f);
Expand Down Expand Up @@ -208,7 +208,7 @@ int main()
.data = indices.data(),
.debugName = "Buffer: index" });

glTFMaterialTextures mat = loadMaterialTextures(
GLTFMaterialTextures mat = loadMaterialTextures(
ctx, "deps/src/glTF-Sample-Assets/Models/DamagedHelmet/glTF/Default_AO.jpg",
"deps/src/glTF-Sample-Assets/Models/DamagedHelmet/glTF/Default_emissive.jpg",
"deps/src/glTF-Sample-Assets/Models/DamagedHelmet/glTF/Default_albedo.jpg",
Expand All @@ -218,7 +218,7 @@ int main()
exit(255);
}

glTFGlobalSamplers samplers(ctx);
GLTFGlobalSamplers samplers(ctx);
EnvironmentMapTextures envMapTextures(ctx);

const lvk::VertexInput vdesc = {
Expand Down
22 changes: 11 additions & 11 deletions Chapter06/04_MetallicRoughness/src/main.frag
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,22 @@ void main()
tc.uv[0] = uv0uv1.xy;
tc.uv[1] = uv0uv1.zw;

vec4 Kao = sampleAO(tc, getMaterialId());
vec4 Ke = sampleEmissive(tc, getMaterialId());
vec4 Kd = sampleAlbedo(tc, getMaterialId()) * color;
vec4 mrSample = sampleMetallicRoughness(tc, getMaterialId());
MetallicRoughnessDataGPU mat = getMaterial(getMaterialId());

vec4 Kao = sampleAO(tc, mat);
vec4 Ke = sampleEmissive(tc, mat);
vec4 Kd = sampleAlbedo(tc, mat) * color;
vec4 mrSample = sampleMetallicRoughness(tc, mat);

// world-space normal
vec3 n = normalize(normal);

vec3 normalSample = sampleNormal(tc, getMaterialId()).xyz;
vec3 normalSample = sampleNormal(tc, mat).xyz;

// normal mapping
n = perturbNormal(n, worldPos, normalSample, getNormalUV(tc, getMaterialId()));
n = perturbNormal(n, worldPos, normalSample, getNormalUV(tc, mat));

if (!gl_FrontFacing) {
n *= -1.0f;
}
if (!gl_FrontFacing) n *= -1.0f;

PBRInfo pbrInputs = calculatePBRInputsMetallicRoughness(Kd, n, perFrame.drawable.cameraPos.xyz, worldPos, mrSample);

Expand All @@ -53,8 +53,8 @@ void main()
// out_FragColor = Ke;
// out_FragColor = Kd;
// vec2 MeR = mrSample.yz;
// MeR.x *= getMetallicFactor(getMaterialId());
// MeR.y *= getRoughnessFactor(getMaterialId());
// MeR.x *= getMetallicFactor(mat);
// MeR.y *= getRoughnessFactor(mat);
// out_FragColor = vec4(MeR.y,MeR.y,MeR.y, 1.0);
// out_FragColor = mrSample;
};
26 changes: 15 additions & 11 deletions Chapter06/05_SpecularGlossiness/src/PBR.sp
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,10 @@ struct PBRInfo {
vec3 getIBLRadianceLambertian(float NdotV, vec3 n, float roughness, vec3 diffuseColor, vec3 F0, float specularWeight)
{
vec2 brdfSamplePoint = clamp(vec2(NdotV, roughness), vec2(0.0, 0.0), vec2(1.0, 1.0));
vec2 f_ab = sampleBRDF_LUT(brdfSamplePoint, getMaterialId()).rg;
EnvironmentMapDataGPU envMap = getEnvironmentMap(getEnvironmentId());
vec2 f_ab = sampleBRDF_LUT(brdfSamplePoint, envMap).rg;

vec3 irradiance = sampleEnvMapIrradiance(n.xyz, getEnvironmentId()).rgb;
vec3 irradiance = sampleEnvMapIrradiance(n.xyz, envMap).rgb;

// see https://bruop.github.io/ibl/#single_scattering_results at Single Scattering Results
// Roughness dependent fresnel, from Fdez-Aguera
Expand All @@ -55,14 +56,15 @@ vec3 getIBLRadianceContributionGGX(PBRInfo pbrInputs, float specularWeight) {
vec3 n = pbrInputs.n;
vec3 v = pbrInputs.v;
vec3 reflection = -normalize(reflect(v, n));
float mipCount = float(sampleEnvMapQueryLevels(getEnvironmentId()));
EnvironmentMapDataGPU envMap = getEnvironmentMap(getEnvironmentId());
float mipCount = float(sampleEnvMapQueryLevels(envMap));
float lod = pbrInputs.perceptualRoughness * (mipCount - 1);

// retrieve a scale and bias to F0. See [1], Figure 3
vec2 brdfSamplePoint = clamp(vec2(pbrInputs.NdotV, pbrInputs.perceptualRoughness), vec2(0.0, 0.0), vec2(1.0, 1.0));
vec3 brdf = sampleBRDF_LUT(brdfSamplePoint, getEnvironmentId()).rgb;
vec3 brdf = sampleBRDF_LUT(brdfSamplePoint, envMap).rgb;
// HDR envmaps are already linear
vec3 specularLight = sampleEnvMapLod(reflection.xyz, lod, getEnvironmentId()).rgb;
vec3 specularLight = sampleEnvMapLod(reflection.xyz, lod, envMap).rgb;

// see https://bruop.github.io/ibl/#single_scattering_results at Single Scattering Results
// Roughness dependent fresnel, from Fdez-Aguera
Expand Down Expand Up @@ -113,13 +115,16 @@ float microfacetDistribution(PBRInfo pbrInputs) {
PBRInfo calculatePBRInputsMetallicRoughness( vec4 albedo, vec3 normal, vec3 cameraPos, vec3 worldPos, vec4 mrSample) {
PBRInfo pbrInputs;

bool isSpecularGlossiness = getMaterialType(getMaterialId()) == MaterialType_SpecularGlossiness;
SpecularGlossinessDataGPU mat = getMaterial(getMaterialId());

float perceptualRoughness = isSpecularGlossiness ? getGlossinessFactor(getMaterialId()): getRoughnessFactor(getMaterialId());
bool isSpecularGlossiness = getMaterialType(mat) == MaterialType_SpecularGlossiness;

float metallic = getMetallicFactor(getMaterialId());
float perceptualRoughness = isSpecularGlossiness ? getGlossinessFactor(mat): getRoughnessFactor(mat);

vec3 f0 = isSpecularGlossiness ? getSpecularFactor(getMaterialId()) * mrSample.rgb : vec3(0.04);
float metallic = getMetallicFactor(mat) * mrSample.b;
metallic = clamp(metallic, 0.0, 1.0);

vec3 f0 = isSpecularGlossiness ? getSpecularFactor(mat) * mrSample.rgb : vec3(0.04);
const float c_MinRoughness = 0.04;

// Metallic roughness:
Expand All @@ -129,8 +134,7 @@ PBRInfo calculatePBRInputsMetallicRoughness( vec4 albedo, vec3 normal, vec3 came
// Glossiness is stored in alpha channel
perceptualRoughness = isSpecularGlossiness ? 1.0 - mrSample.a * perceptualRoughness : clamp(mrSample.g * perceptualRoughness, c_MinRoughness, 1.0);

metallic = mrSample.b * metallic;
metallic = clamp(metallic, 0.0, 1.0);

// Roughness is authored as perceptual roughness; as is convention,
// convert to material roughness by squaring the perceptual roughness [2].
float alphaRoughness = perceptualRoughness * perceptualRoughness;
Expand Down
Loading

0 comments on commit b8ff667

Please sign in to comment.