Skip to content
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file not shown.
1,283 changes: 1,283 additions & 0 deletions assets/example_meshes/gltf/SpecularTest/SpecularTest.gltf

Large diffs are not rendered by default.

Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
17 changes: 15 additions & 2 deletions examples/render/950-pbr/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ int main(int argc, char** argv)
NORMAL_TENGENT_MIRROR_TEST,
COMPARE_AMBIENT_OCCLUSION,
DAMAGED_HELMET,
SPECULAR_TEST,
COUNT_EXAMPLES
};

Expand All @@ -44,9 +45,10 @@ int main(int argc, char** argv)
"/gltf/MetalRoughSpheres/MetalRoughSpheres.gltf",
"/gltf/NormalTangentMirrorTest/NormalTangentMirrorTest.gltf",
"/gltf/CompareAmbientOcclusion/CompareAmbientOcclusion.gltf",
"/gltf/DamagedHelmet/DamagedHelmet.gltf"};
"/gltf/DamagedHelmet/DamagedHelmet.gltf",
"/gltf/SpecularTest/SpecularTest.gltf"};

uint selectedExample = METAL_ROUGH_SPHERES;
uint selectedExample = SPECULAR_TEST;

enum PanoramasExamples {
COLOSSEUM_HDR,
Expand Down Expand Up @@ -88,6 +90,12 @@ int main(int argc, char** argv)
else if (type == EMISSIVE) {
typeName = "emissive";
}
else if (type == SPECULAR) {
typeName = "specular";
}
else if (type == SPECULAR_COLOR) {
typeName = "specularColor";
}

std::cout << " " << typeName << "Texture: ";
if (!texture.isNull()) {
Expand Down Expand Up @@ -120,11 +128,16 @@ int main(int argc, char** argv)
std::cout << " normalScale: " << mat.normalScale() << std::endl;
std::cout << " occlusionStrength: " << mat.occlusionStrength()
<< std::endl;
std::cout << " specularFactor: " << mat.specular() << std::endl;
std::cout << " specularColorFactor: " << mat.specularColor()
<< std::endl;
printTextureInfo(mat, BASE_COLOR);
printTextureInfo(mat, METALLIC_ROUGHNESS);
printTextureInfo(mat, NORMAL);
printTextureInfo(mat, OCCLUSION);
printTextureInfo(mat, EMISSIVE);
printTextureInfo(mat, SPECULAR);
printTextureInfo(mat, SPECULAR_COLOR);
std::cout << " ------------------------" << std::endl;
}
std::cout << "------------------------" << std::endl;
Expand Down
43 changes: 43 additions & 0 deletions vclib/core/include/vclib/io/mesh/gltf/detail/load_mesh.h
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,12 @@ int loadGltfPrimitiveMaterial(
bool doubleSided;
int baseColorTextureId, metallicRoughnessTextureId, normalTextureId,
occlusionTextureId, emissiveTextureId;

double specular = 1.0;
Point3f specularColor = Point3f(1.0, 1.0, 1.0);
int specularTextureId = -1;
int specularColorTextureId = -1;

const tinygltf::Material& mat = model.materials[p.material];

std::string matName = mat.name;
Expand Down Expand Up @@ -122,6 +128,37 @@ int loadGltfPrimitiveMaterial(
// occlusionStrength
occlusionStrength = mat.occlusionTexture.strength;

// specular
if(mat.extensions.contains("KHR_materials_specular"))
{
const auto& specularExt = mat.extensions.at("KHR_materials_specular");

if(specularExt.Has("specularFactor"))
specular = specularExt
.Get("specularFactor")
.GetNumberAsDouble();

if(specularExt.Has("specularColorFactor"))
for(uint i = 0; i < 3; i++)
specularColor[i] = specularExt
.Get("specularColorFactor")
.Get(i)
.GetNumberAsDouble();

if(specularExt.Has("specularTexture"))
specularTextureId = specularExt
.Get("specularTexture")
.Get("index")
.GetNumberAsInt();

if(specularExt.Has("specularColorTexture"))
specularColorTextureId = specularExt
.Get("specularColorTexture")
.Get("index")
.GetNumberAsInt();

}
Comment thread
alemuntoni marked this conversation as resolved.

// function to load a texture in a material
auto loadTextureInMaterial = [&](Material& mat,
int textureId,
Expand Down Expand Up @@ -195,6 +232,8 @@ int loadGltfPrimitiveMaterial(
mat.doubleSided() = doubleSided;
mat.normalScale() = normalScale;
mat.occlusionStrength() = occlusionStrength;
mat.specular() = specular;
mat.specularColor() = specularColor;
loadTextureInMaterial(
mat, baseColorTextureId, Material::TextureType::BASE_COLOR);
loadTextureInMaterial(
Expand All @@ -207,6 +246,10 @@ int loadGltfPrimitiveMaterial(
mat, occlusionTextureId, Material::TextureType::OCCLUSION);
loadTextureInMaterial(
mat, emissiveTextureId, Material::TextureType::EMISSIVE);
loadTextureInMaterial(
mat, specularTextureId, Material::TextureType::SPECULAR);
loadTextureInMaterial(
mat, specularColorTextureId, Material::TextureType::SPECULAR_COLOR);
m.pushMaterial(mat);
idx = m.materialCount() - 1; // index of the added material
if constexpr (HasColor<MeshType>) {
Expand Down
43 changes: 41 additions & 2 deletions vclib/core/include/vclib/space/core/material.h
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,8 @@ class Material
OCCLUSION, ///< The ambient occlusion map (R channel). Stored in linear
///< color space.
EMISSIVE, ///< The emissive color texture. Stored in sRGB color space.
SPECULAR,
SPECULAR_COLOR,
COUNT ///< Utility value to get the number of texture types.
};

Expand All @@ -78,7 +80,9 @@ class Material
"metallicRoughnessTex",
"normalTex",
"occlusionTex",
"emissiveTex"};
"emissiveTex",
"specularTex",
"specularColorTex"};

private:
inline static const uint N_TEXTURE_TYPE =
Expand Down Expand Up @@ -108,6 +112,11 @@ class Material

bool mDoubleSided = false;

float mSpecular = 1.0f;

// needs to be HDR
Point3f mSpecularColor = Point3f(1.0, 1.0, 1.0);

public:
/**
* @brief Default constructor.
Expand Down Expand Up @@ -253,6 +262,30 @@ class Material
*/
float& occlusionStrength() { return mOcclusionStrength; }

/**
* @brief Gets the strength of the specular effect.
* @return The spceular strength, in the range [0.0, 1.0].
Comment thread
alemuntoni marked this conversation as resolved.
Outdated
*/
float specular() const { return mSpecular; }

/**
* @brief Gets a mutable reference to the specular strength.
* @return A reference to the specular strength.
*/
float& specular() { return mSpecular; }

/**
* @brief Gets the specular color of the material.
* @return A const reference to the specular color.
*/
const Point3f& specularColor() const { return mSpecularColor; }

/**
* @brief Gets a mutable reference to the specular color of the material.
* @return A reference to the specular color.
*/
Point3f& specularColor() { return mSpecularColor; }

/**
* @brief Gets the texture descriptor for the base color texture.
* @return A const reference to the base color texture descriptor.
Expand Down Expand Up @@ -333,6 +366,8 @@ class Material
vcl::serialize(os, mAlphaMode, mAlphaCutoff);
vcl::serialize(os, mNormalScale);
vcl::serialize(os, mOcclusionStrength);
vcl::serialize(os, mSpecular);
mSpecularColor.serialize(os);
vcl::serialize(os, mTextureDescriptors);
vcl::serialize(os, mDoubleSided);
}
Expand All @@ -350,6 +385,8 @@ class Material
vcl::deserialize(is, mAlphaMode, mAlphaCutoff);
vcl::deserialize(is, mNormalScale);
vcl::deserialize(is, mOcclusionStrength);
vcl::deserialize(is, mSpecular);
mSpecularColor.deserialize(is);
vcl::deserialize(is, mTextureDescriptors);
vcl::deserialize(is, mDoubleSided);
}
Expand All @@ -376,10 +413,12 @@ class Material
{
switch (type) {
case TextureType::BASE_COLOR:
case TextureType::EMISSIVE: return Image::ColorSpace::SRGB;
case TextureType::EMISSIVE:
case TextureType::SPECULAR_COLOR: return Image::ColorSpace::SRGB;
case TextureType::METALLIC_ROUGHNESS:
case TextureType::NORMAL:
case TextureType::OCCLUSION:
case TextureType::SPECULAR:
default: return Image::ColorSpace::LINEAR;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ class DrawableEnvironment
Uniform("s_specular", bgfx::UniformType::Sampler);
// Sampler of mBrdfLuTexture
const Uniform mBrdfLutSamplerUniform =
Uniform("s_tex5", bgfx::UniformType::Sampler);
Uniform("s_tex7", bgfx::UniformType::Sampler);
Comment thread
alemuntoni marked this conversation as resolved.
Outdated

// The path of the environment image file provided as input.
std::string mImagePath;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ class DrawableMeshUniforms
NORMAL,
OCCLUSION,
EMISSIVE,
SPECULAR,
SPECULAR_COLOR,
BRDF_LUT,
Comment thread
alemuntoni marked this conversation as resolved.
COUNT
};
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -60,11 +60,16 @@ class MaterialUniforms
// .x : pbr settings
static inline std::array<float, 4> sSettings = {0.0, 0.0, 0.0, 0.0};

// specular color (RGB) and specular (A)
static inline std::array<float, 4> sSpecularPack = {1.0, 1.0, 1.0, 1.0};

static inline Uniform sBaseColorUniform;
static inline Uniform sFactorsPackUniform;
static inline Uniform sEmissiveAlphaCutoffPackUniform;
static inline Uniform sSettingsUniform;

static inline Uniform sSpecularPackUniform;

public:
MaterialUniforms() = delete;

Expand Down Expand Up @@ -109,6 +114,11 @@ class MaterialUniforms
sEmissiveAlphaCutoffPack[0] = m.emissiveColor().redF();
sEmissiveAlphaCutoffPack[1] = m.emissiveColor().greenF();
sEmissiveAlphaCutoffPack[2] = m.emissiveColor().blueF();

sSpecularPack[0] = m.specularColor()[0];
sSpecularPack[1] = m.specularColor()[1];
sSpecularPack[2] = m.specularColor()[2];
sSpecularPack[3] = m.specular();
}

static void bind()
Expand All @@ -127,10 +137,15 @@ class MaterialUniforms
if (!sSettingsUniform.isValid())
sSettingsUniform = Uniform("u_settings", bgfx::UniformType::Vec4);

if (!sSpecularPackUniform.isValid())
sSpecularPackUniform = Uniform("u_specularPack", bgfx::UniformType::Vec4);

sBaseColorUniform.bind(&sBaseColor);
sFactorsPackUniform.bind(&sFactorsPack);
sEmissiveAlphaCutoffPackUniform.bind(&sEmissiveAlphaCutoffPack);
sSettingsUniform.bind(&sSettings);

sSpecularPackUniform.bind(&sSpecularPack);
}
};

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -142,6 +142,14 @@ void main()

vec3 emissiveColor = u_emissiveFactor * emissiveTexture;

float specular = u_specularFactor;
if (useTexture && isSpecularTextureAvailable())
specular *= specularTex(texcoord).a;

vec3 specularColor = u_specularColorFactor;
if (useTexture && isSpecularColorTextureAvailable())
specularColor *= specularColorTex(texcoord).rgb;

if(useImageBasedLighting(u_pbr_settings))
{
// view direction
Expand All @@ -157,8 +165,7 @@ void main()

float NoV = clampedDot(normal, V);

vec3 f0_dielectric = vec3_splat(0.04);
vec3 f90 = vec3_splat(1.0);
vec3 f0_dielectric = min(vec3_splat(0.04) * specularColor, vec3_splat(1.0));

// diffuse light
vec3 diffuseLight = textureCube(s_irradiance, leftHand(normal)).rgb;
Expand All @@ -170,8 +177,8 @@ void main()

// Fresnel
vec2 brdf = brdfLutTex(vec2(NoV, roughness)).rg;
vec3 metalFresnel = iblGgxFresnel(brdf, NoV, roughness, baseColor.rgb);
vec3 dielectricFresnel = iblGgxFresnel(brdf, NoV, roughness, f0_dielectric);
vec3 metalFresnel = iblGgxFresnel(brdf, NoV, roughness, baseColor.rgb, 1.0);
vec3 dielectricFresnel = iblGgxFresnel(brdf, NoV, roughness, f0_dielectric, specular);

// occlusion
float occlusion = 1.0;
Expand Down Expand Up @@ -222,6 +229,8 @@ void main()
metallic,
roughness,
emissiveColor,
specular,
specularColor,
u_exposure,
u_toneMapping
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@ SAMPLER2D(s_tex2, 2);
SAMPLER2D(s_tex3, 3);
SAMPLER2D(s_tex4, 4);
SAMPLER2D(s_tex5, 5);
SAMPLER2D(s_tex6, 6);
SAMPLER2D(s_tex7, 7);

vec4 textureStage(uint stage, vec2 texcoord)
{
Expand All @@ -34,6 +36,10 @@ vec4 textureStage(uint stage, vec2 texcoord)
return texture2D(s_tex4, texcoord);
case 5u:
return texture2D(s_tex5, texcoord);
case 6u:
return texture2D(s_tex6, texcoord);
case 7u:
return texture2D(s_tex7, texcoord);
default:
// should never happen, return a magenta color to easily spot the error
return vec4(1.0, 0.0, 1.0, 1.0);
Expand All @@ -49,7 +55,9 @@ vec4 textureStage(uint stage, vec2 texcoord)
// 2 -> normal
// 3 -> occlusion
// 4 -> emissive
// 5 -> brdf lut
// 5 -> specular
// 6 -> specular color
// 7 -> brdf lut
//
// to get the actual stage index: textureStageBitField(u_textureStagesZ, pos)

Expand Down Expand Up @@ -103,14 +111,34 @@ vec4 emissiveTex(vec2 texcoord)
return textureStage(textureStageBitField(u_textureStagesZ, 4), texcoord);
}

bool isBrdfLutTextureAvailable()
bool isSpecularTextureAvailable()
{
return textureStageBitField(u_textureStagesZ, 5) != 0xF;
}

vec4 brdfLutTex(vec2 texcoord)
vec4 specularTex(vec2 texcoord)
{
return textureStage(textureStageBitField(u_textureStagesZ, 5), texcoord);
}

bool isSpecularColorTextureAvailable()
{
return textureStageBitField(u_textureStagesZ, 6) != 0xF;
}

vec4 specularColorTex(vec2 texcoord)
{
return textureStage(textureStageBitField(u_textureStagesZ, 6), texcoord);
}

bool isBrdfLutTextureAvailable()
{
return textureStageBitField(u_textureStagesZ, 7) != 0xF;
}

vec4 brdfLutTex(vec2 texcoord)
{
return textureStage(textureStageBitField(u_textureStagesZ, 7), texcoord);
}

#endif // VCL_EXT_BGFX_UNIFORMS_DRAWABLE_MESH_TEXTURE_UNIFORMS_SH
Loading
Loading