Update GLTF support to include loading color for albdeo (saved in the color value of the materialmap), support occlussion and emmission maps.. as well as some quality of life updates.
This commit is contained in:
parent
ea40bda88c
commit
6eab63dab0
77
src/models.c
77
src/models.c
|
|
@ -3376,9 +3376,9 @@ static unsigned char *DecodeBase64(char *input, int *size)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load texture from cgltf_image
|
// Load texture from cgltf_image
|
||||||
static Texture LoadTextureFromCgltfImage(cgltf_image *image, const char *texPath, Color tint)
|
static Image LoadImageFromCgltfImage(cgltf_image *image, const char *texPath, Color tint)
|
||||||
{
|
{
|
||||||
Texture texture = { 0 };
|
Image rimage = { 0 };
|
||||||
|
|
||||||
if (image->uri)
|
if (image->uri)
|
||||||
{
|
{
|
||||||
|
|
@ -3409,8 +3409,6 @@ static Texture LoadTextureFromCgltfImage(cgltf_image *image, const char *texPath
|
||||||
|
|
||||||
// TODO: Tint shouldn't be applied here!
|
// TODO: Tint shouldn't be applied here!
|
||||||
ImageColorTint(&rimage, tint);
|
ImageColorTint(&rimage, tint);
|
||||||
texture = LoadTextureFromImage(rimage);
|
|
||||||
UnloadImage(rimage);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
@ -3419,8 +3417,6 @@ static Texture LoadTextureFromCgltfImage(cgltf_image *image, const char *texPath
|
||||||
|
|
||||||
// TODO: Tint shouldn't be applied here!
|
// TODO: Tint shouldn't be applied here!
|
||||||
ImageColorTint(&rimage, tint);
|
ImageColorTint(&rimage, tint);
|
||||||
texture = LoadTextureFromImage(rimage);
|
|
||||||
UnloadImage(rimage);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (image->buffer_view)
|
else if (image->buffer_view)
|
||||||
|
|
@ -3444,36 +3440,31 @@ static Texture LoadTextureFromCgltfImage(cgltf_image *image, const char *texPath
|
||||||
|
|
||||||
// TODO: Tint shouldn't be applied here!
|
// TODO: Tint shouldn't be applied here!
|
||||||
ImageColorTint(&rimage, tint);
|
ImageColorTint(&rimage, tint);
|
||||||
texture = LoadTextureFromImage(rimage);
|
|
||||||
UnloadImage(rimage);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Image rimage = LoadImageEx(&tint, 1, 1);
|
Image rimage = LoadImageEx(&tint, 1, 1);
|
||||||
texture = LoadTextureFromImage(rimage);
|
|
||||||
UnloadImage(rimage);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return texture;
|
return rimage;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load glTF mesh data
|
// LoadGLTF loads in model data from given filename, supporting both .gltf and .glb
|
||||||
static Model LoadGLTF(const char *fileName)
|
static Model LoadGLTF(const char *fileName)
|
||||||
{
|
{
|
||||||
/***********************************************************************************
|
/***********************************************************************************
|
||||||
|
|
||||||
Function implemented by Wilhem Barbier (@wbrbr)
|
Function implemented by Wilhem Barbier(@wbrbr), with modifications by Tyler Bezera(@gamerfiend)
|
||||||
|
|
||||||
Features:
|
Features:
|
||||||
- Supports .gltf and .glb files
|
- Supports .gltf and .glb files
|
||||||
- Supports embedded (base64) or external textures
|
- Supports embedded (base64) or external textures
|
||||||
- Loads the albedo/diffuse texture (other maps could be added)
|
- Loads all raylib supported material textures, values and colors
|
||||||
- Supports multiple mesh per model and multiple primitives per model
|
- Supports multiple mesh per model and multiple primitives per model
|
||||||
|
|
||||||
Some restrictions (not exhaustive):
|
Some restrictions (not exhaustive):
|
||||||
- Triangle-only meshes
|
- Triangle-only meshes
|
||||||
- Not supported node hierarchies or transforms
|
- Not supported node hierarchies or transforms
|
||||||
- Only loads the diffuse texture... but not too hard to support other maps (normal, roughness/metalness...)
|
|
||||||
- Only supports unsigned short indices (no byte/unsigned int)
|
- Only supports unsigned short indices (no byte/unsigned int)
|
||||||
- Only supports float for texture coordinates (no byte/unsigned short)
|
- Only supports float for texture coordinates (no byte/unsigned short)
|
||||||
|
|
||||||
|
|
@ -3546,44 +3537,62 @@ static Model LoadGLTF(const char *fileName)
|
||||||
//Ensure material follows raylib support for PBR (metallic/roughness flow)
|
//Ensure material follows raylib support for PBR (metallic/roughness flow)
|
||||||
if (data->materials[i].has_pbr_metallic_roughness)
|
if (data->materials[i].has_pbr_metallic_roughness)
|
||||||
{
|
{
|
||||||
float roughness = data->materials[i].pbr_metallic_roughness.roughness_factor;
|
tint.r = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[0] * 255);
|
||||||
float metallic = data->materials[i].pbr_metallic_roughness.metallic_factor;
|
tint.g = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[1] * 255);
|
||||||
|
tint.b = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[2] * 255);
|
||||||
|
tint.a = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[3] * 255);
|
||||||
|
|
||||||
// NOTE: Material name not used for the moment
|
model.materials[i].maps[MAP_ALBEDO].color = tint;
|
||||||
//if (model.materials[i].name && data->materials[i].name) strcpy(model.materials[i].name, data->materials[i].name);
|
|
||||||
|
|
||||||
// TODO: REview: shouldn't these be *255 ???
|
|
||||||
tint.r = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[0]*255);
|
|
||||||
tint.g = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[1]*255);
|
|
||||||
tint.b = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[2]*255);
|
|
||||||
tint.a = (unsigned char)(data->materials[i].pbr_metallic_roughness.base_color_factor[3]*255);
|
|
||||||
|
|
||||||
model.materials[i].maps[MAP_ROUGHNESS].color = tint;
|
|
||||||
|
|
||||||
if (data->materials[i].pbr_metallic_roughness.base_color_texture.texture)
|
if (data->materials[i].pbr_metallic_roughness.base_color_texture.texture)
|
||||||
{
|
{
|
||||||
model.materials[i].maps[MAP_ALBEDO].texture = LoadTextureFromCgltfImage(data->materials[i].pbr_metallic_roughness.base_color_texture.texture->image, texPath, tint);
|
Image albedo = LoadImageFromCgltfImage(data->materials[i].pbr_metallic_roughness.base_color_texture.texture->image, texPath, tint);
|
||||||
|
model.materials[i].maps[MAP_ALBEDO].texture = LoadTextureFromImage(albedo);
|
||||||
|
UnloadImage(albedo);
|
||||||
}
|
}
|
||||||
|
|
||||||
// NOTE: Tint isn't need for other textures.. pass null or clear?
|
//Set tint to white after it's been used by Albedo
|
||||||
// Just set as white, multiplying by white has no effect
|
|
||||||
tint = WHITE;
|
tint = WHITE;
|
||||||
|
|
||||||
if (data->materials[i].pbr_metallic_roughness.metallic_roughness_texture.texture)
|
if (data->materials[i].pbr_metallic_roughness.metallic_roughness_texture.texture)
|
||||||
{
|
{
|
||||||
model.materials[i].maps[MAP_ROUGHNESS].texture = LoadTextureFromCgltfImage(data->materials[i].pbr_metallic_roughness.metallic_roughness_texture.texture->image, texPath, tint);
|
Image metallicRoughness = LoadImageFromCgltfImage(data->materials[i].pbr_metallic_roughness.metallic_roughness_texture.texture->image, texPath, tint);
|
||||||
}
|
model.materials[i].maps[MAP_ROUGHNESS].texture = LoadTextureFromImage(metallicRoughness);
|
||||||
|
|
||||||
|
float roughness = data->materials[i].pbr_metallic_roughness.roughness_factor;
|
||||||
model.materials[i].maps[MAP_ROUGHNESS].value = roughness;
|
model.materials[i].maps[MAP_ROUGHNESS].value = roughness;
|
||||||
|
|
||||||
|
float metallic = data->materials[i].pbr_metallic_roughness.metallic_factor;
|
||||||
model.materials[i].maps[MAP_METALNESS].value = metallic;
|
model.materials[i].maps[MAP_METALNESS].value = metallic;
|
||||||
|
|
||||||
|
UnloadImage(metallicRoughness);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
if (data->materials[i].normal_texture.texture)
|
if (data->materials[i].normal_texture.texture)
|
||||||
{
|
{
|
||||||
model.materials[i].maps[MAP_NORMAL].texture = LoadTextureFromCgltfImage(data->materials[i].normal_texture.texture->image, texPath, tint);
|
Image normalImage = LoadImageFromCgltfImage(data->materials[i].normal_texture.texture->image, texPath, tint);
|
||||||
|
model.materials[i].maps[MAP_NORMAL].texture = LoadTextureFromImage(normalImage);
|
||||||
|
UnloadImage(normalImage);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (data->materials[i].occlusion_texture.texture)
|
if (data->materials[i].occlusion_texture.texture)
|
||||||
{
|
{
|
||||||
model.materials[i].maps[MAP_OCCLUSION].texture = LoadTextureFromCgltfImage(data->materials[i].occlusion_texture.texture->image, texPath, tint);
|
Image occulsionImage = LoadImageFromCgltfImage(data->materials[i].occlusion_texture.texture->image, texPath, tint);
|
||||||
|
model.materials[i].maps[MAP_OCCLUSION].texture = LoadTextureFromImage(occulsionImage);
|
||||||
|
UnloadImage(occulsionImage);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data->materials[i].emissive_texture.texture)
|
||||||
|
{
|
||||||
|
Image emissiveImage = LoadImageFromCgltfImage(data->materials[i].emissive_texture.texture->image, texPath, tint);
|
||||||
|
model.materials[i].maps[MAP_EMISSION].texture = LoadTextureFromImage(emissiveImage);
|
||||||
|
tint.r = (unsigned char)(data->materials[i].emissive_factor[0] * 255);
|
||||||
|
tint.g = (unsigned char)(data->materials[i].emissive_factor[1] * 255);
|
||||||
|
tint.b = (unsigned char)(data->materials[i].emissive_factor[2] * 255);
|
||||||
|
model.materials[i].maps[MAP_EMISSION].color = tint;
|
||||||
|
UnloadImage(emissiveImage);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user