Added support for more features in gltf_viewer sample

This commit is contained in:
magicwhale
2018-11-19 09:27:08 -08:00
committed by magicwhale
parent 1d392d38bd
commit fc0d587b40
15 changed files with 947 additions and 286 deletions
+8 -1
View File
@@ -12,6 +12,13 @@ set(MATERIAL_SRCS
materials/aiDefaultTrans.mat
materials/depthVisualizer.mat
materials/gltf2.mat
materials/gltf2DoubleSided.mat
materials/gltf2DoubleSidedMasked.mat
materials/gltf2DoubleSidedTrans.mat
materials/gltf2DoubleSidedUnlit.mat
materials/gltf2Masked.mat
materials/gltf2Trans.mat
materials/gltf2Unlit.mat
materials/groundShadow.mat
materials/sandboxCloth.mat
materials/sandboxLit.mat
@@ -70,7 +77,7 @@ set(APP_SRCS
app/IBL.cpp
app/Image.cpp
app/IcoSphere.cpp
app/Sphere.cpp gltf_viewer.cpp)
app/Sphere.cpp)
if (APPLE)
list(APPEND APP_SRCS app/NativeWindowHelperCocoa.mm)
-6
View File
@@ -1,6 +0,0 @@
//
// Created by Michael Wang on 10/8/18.
//
#include "GltfMeshAssimp.h"
-14
View File
@@ -1,14 +0,0 @@
//
// Created by Michael Wang on 10/8/18.
//
#ifndef TNT_GLTFMESHASSIMP_H
#define TNT_GLTFMESHASSIMP_H
#include "MeshAssimp.h"
class GltfMeshAssimp : public MeshAssimp {
};
#endif //TNT_GLTFMESHASSIMP_H
+381 -141
View File
@@ -17,6 +17,7 @@
#include "MeshAssimp.h"
#include <string.h>
#include <array>
#include <filament/Color.h>
#include <filament/VertexBuffer.h>
@@ -29,6 +30,8 @@
#include <filament/TransformManager.h>
#include <math/norm.h>
#include <math/vec3.h>
#include <math/TVecHelpers.h>
#include <assimp/Importer.hpp>
#include <assimp/postprocess.h>
@@ -37,6 +40,8 @@
#include <stb_image.h>
#include <stdlib.h>
using namespace filament;
using namespace filamat;
@@ -55,7 +60,85 @@ static constexpr uint8_t GLTF2_PACKAGE[] = {
#include "generated/material/gltf2.inc"
};
static constexpr uint8_t GLTF2_DS_PACKAGE[] = {
#include "generated/material/gltf2DoubleSided.inc"
};
static constexpr uint8_t GLTF2_TRANS_PACKAGE[] = {
#include "generated/material/gltf2Trans.inc"
};
static constexpr uint8_t GLTF2_DS_TRANS_PACKAGE[] = {
#include "generated/material/gltf2DoubleSidedTrans.inc"
};
static constexpr uint8_t GLTF2_MASKED_PACKAGE[] = {
#include "generated/material/gltf2Masked.inc"
};
static constexpr uint8_t GLTF2_DS_MASKED_PACKAGE[] = {
#include "generated/material/gltf2DoubleSidedMasked.inc"
};
static constexpr uint8_t GLTF2_UNLIT_PACKAGE[] = {
#include "generated/material/gltf2Unlit.inc"
};
static constexpr uint8_t GLTF2_DS_UNLIT_PACKAGE[] = {
#include "generated/material/gltf2DoubleSidedUnlit.inc"
};
Texture* MeshAssimp::createOneByOneTexture(uint32_t pixel) {
uint32_t *textureData = (uint32_t *) malloc(sizeof(uint32_t));
*textureData = pixel;
Texture *texturePtr = Texture::Builder()
.width(uint32_t(1))
.height(uint32_t(1))
.levels(0xff)
.format(driver::TextureFormat::RGB8)
.build(mEngine);
Texture::PixelBufferDescriptor defaultNormalBuffer(textureData,
size_t(1 * 1 * 3),
Texture::Format::RGB,
Texture::Type::UBYTE,
(driver::BufferDescriptor::Callback) &free);
texturePtr->setImage(mEngine, 0, std::move(defaultNormalBuffer));
texturePtr->generateMipmaps(mEngine);
return texturePtr;
}
MeshAssimp::MeshAssimp(Engine& engine) : mEngine(engine) {
//Initialize some things here
mDefaultMap = createOneByOneTexture(0xffffffff);
mDefaultNormalMap = createOneByOneTexture(0xffff8080);
mGltfMaterial = Material::Builder()
.package((void*) GLTF2_PACKAGE, sizeof(GLTF2_PACKAGE))
.build(mEngine);
mGltfMaterialDS = Material::Builder()
.package((void*) GLTF2_DS_PACKAGE, sizeof(GLTF2_DS_PACKAGE))
.build(mEngine);
mGltfMaterialTrans = Material::Builder()
.package((void*) GLTF2_TRANS_PACKAGE, sizeof(GLTF2_TRANS_PACKAGE))
.build(mEngine);
mGltfMaterialDSTrans = Material::Builder()
.package((void*) GLTF2_DS_TRANS_PACKAGE, sizeof(GLTF2_DS_TRANS_PACKAGE))
.build(mEngine);
mGltfMaterialMasked = Material::Builder()
.package((void*) GLTF2_MASKED_PACKAGE, sizeof(GLTF2_MASKED_PACKAGE))
.build(mEngine);
mGltfMaterialDSMasked = Material::Builder()
.package((void*) GLTF2_DS_MASKED_PACKAGE, sizeof(GLTF2_DS_MASKED_PACKAGE))
.build(mEngine);
mGltfMaterialUnlit = Material::Builder()
.package((void*) GLTF2_UNLIT_PACKAGE, sizeof(GLTF2_UNLIT_PACKAGE))
.build(mEngine);
mGltfMaterialDSUnlit = Material::Builder()
.package((void*) GLTF2_DS_UNLIT_PACKAGE, sizeof(GLTF2_DS_UNLIT_PACKAGE))
.build(mEngine);
}
MeshAssimp::~MeshAssimp() {
@@ -64,8 +147,16 @@ MeshAssimp::~MeshAssimp() {
mEngine.destroy(mDefaultColorMaterial);
mEngine.destroy(mDefaultTransparentColorMaterial);
mEngine.destroy(mGltfMaterial);
mEngine.destroy(mGltfMaterialDS);
mEngine.destroy(mGltfMaterialTrans);
mEngine.destroy(mGltfMaterialDSTrans);
mEngine.destroy(mGltfMaterialMasked);
mEngine.destroy(mGltfMaterialDSMasked);
mEngine.destroy(mGltfMaterialUnlit);
mEngine.destroy(mGltfMaterialDSUnlit);
mEngine.destroy(mDefaultNormalMap);
mEngine.destroy(mDefaultMap);
for (Entity renderable : mRenderables) {
mEngine.destroy(renderable);
}
@@ -91,22 +182,37 @@ struct State {
};
//TODO: Remove redundant method from sample_full_pbr
void loadTex(Engine* engine, const std::string& filePath, Texture** map, bool sRGB = true) {
static void loadTexture(Engine *engine, const std::string &filePath, Texture **map, bool sRGB, bool hasAlpha) {
if (!filePath.empty()) {
Path path(filePath);
if (path.exists()) {
int w, h, n;
unsigned char* data = stbi_load(path.getAbsolutePath().c_str(), &w, &h, &n, 3);
int numChannels = hasAlpha ? 4 : 3;
driver::TextureFormat inputFormat;
if (sRGB) {
inputFormat = hasAlpha ? driver::TextureFormat::SRGB8_A8 : driver::TextureFormat::SRGB8;
} else {
inputFormat = hasAlpha ? driver::TextureFormat::RGBA8 : driver::TextureFormat::RGB8;
}
Texture::Format outputFormat = hasAlpha ? Texture::Format::RGBA : Texture::Format::RGB;
uint8_t *data = stbi_load(path.getAbsolutePath().c_str(), &w, &h, &n, numChannels);
if (data != nullptr) {
*map = Texture::Builder()
.width(uint32_t(w))
.height(uint32_t(h))
.levels(0xff)
.format(sRGB ? driver::TextureFormat::SRGB8 : driver::TextureFormat::RGB8)
.format(inputFormat)
.build(*engine);
Texture::PixelBufferDescriptor buffer(data, size_t(w * h * 3),
Texture::Format::RGB, Texture::Type::UBYTE,
(driver::BufferDescriptor::Callback) &stbi_image_free);
Texture::PixelBufferDescriptor buffer(data,
size_t(w * h * numChannels),
outputFormat,
Texture::Type::UBYTE,
(driver::BufferDescriptor::Callback) &stbi_image_free);
(*map)->setImage(*engine, 0, std::move(buffer));
(*map)->generateMipmaps(*engine);
} else {
@@ -118,6 +224,128 @@ void loadTex(Engine* engine, const std::string& filePath, Texture** map, bool sR
}
}
void loadEmbeddedTexture(Engine *engine, aiTexture *embeddedTex, Texture **map, bool sRGB, bool hasAlpha) {
int w, h, n;
int numChannels = hasAlpha ? 4 : 3;
driver::TextureFormat inputFormat;
if (sRGB) {
inputFormat = hasAlpha ? driver::TextureFormat::SRGB8_A8 : driver::TextureFormat::SRGB8;
} else {
inputFormat = hasAlpha ? driver::TextureFormat::RGBA8 : driver::TextureFormat::RGB8;
}
Texture::Format outputFormat = hasAlpha ? Texture::Format::RGBA : Texture::Format::RGB;
uint8_t *data = stbi_load_from_memory((unsigned char *) embeddedTex->pcData,
embeddedTex->mWidth, &w, &h, &n, numChannels);
*map = Texture::Builder()
.width(uint32_t(w))
.height(uint32_t(h))
.levels(0xff)
.format(inputFormat)
.build(*engine);
Texture::PixelBufferDescriptor defaultBuffer(data,
size_t(w * h * numChannels),
outputFormat,
Texture::Type::UBYTE,
(driver::BufferDescriptor::Callback) &free);
(*map)->setImage(*engine, 0, std::move(defaultBuffer));
(*map)->generateMipmaps(*engine);
}
// Takes a texture filename and returns the index of the embedded texture, -1 if the texture is not embedded
int getEmbeddedTextureId(const aiString& path) {
const char *pathStr = path.C_Str();
if (path.length >= 2 && pathStr[0] == '*') {
for (int i; i < path.length; i++) {
if (!isdigit(pathStr[i]))
return -1;
}
return std::atoi(pathStr + 1);
}
return -1;
}
TextureSampler::WrapMode aiToFilamentMapMode(aiTextureMapMode mapMode) {
switch(mapMode) {
case aiTextureMapMode_Clamp :
return TextureSampler::WrapMode::CLAMP_TO_EDGE;
case aiTextureMapMode_Mirror :
return TextureSampler::WrapMode::MIRRORED_REPEAT;
default:
return TextureSampler::WrapMode::REPEAT;
}
}
// TODO: Change this to a member function (requires some alteration of cmakelsts.txt)
void setTextureFromPath(const aiScene *scene,
Engine *engine,
std::vector<filament::Texture*> textures,
const aiString &texFile,
const std::string &materialName,
const std::string &texDir,
aiTextureMapMode *mapMode,
const char *parameterName,
std::map<std::string, MaterialInstance *> &outMaterials) {
TextureSampler sampler;
if (mapMode) {
sampler = TextureSampler(TextureSampler::MinFilter::LINEAR_MIPMAP_LINEAR,
TextureSampler::MagFilter::LINEAR,
aiToFilamentMapMode(mapMode[0]),
aiToFilamentMapMode(mapMode[1]),
aiToFilamentMapMode(mapMode[2]));
} else {
sampler = TextureSampler(TextureSampler::MinFilter::LINEAR_MIPMAP_LINEAR,
TextureSampler::MagFilter::LINEAR, TextureSampler::WrapMode::REPEAT);
}
Texture* textureMap = nullptr;
int embeddedId = getEmbeddedTextureId(texFile);
//TODO: change this in refactor
bool isSRGB = strcmp(parameterName, "baseColorMap") == 0 || strcmp(parameterName, "emissiveMap") == 0;
bool hasAlpha = strcmp(parameterName, "baseColorMap") == 0;
if (embeddedId != -1) {
loadEmbeddedTexture(engine, scene->mTextures[embeddedId], &textureMap, isSRGB, hasAlpha);
} else {
loadTexture(engine, texDir + texFile.C_Str(), &textureMap, isSRGB, hasAlpha);
}
textures.push_back(textureMap);
if (textureMap != nullptr) {
outMaterials[materialName]->setParameter(
parameterName, textureMap, sampler);
}
}
float3 transformPoint(const float3 point, const mat4f transform) {
return (transform * float4(point, 1.0f)).xyz;
}
template<typename VECTOR, typename INDEX>
Box computeTransformedAABB(VECTOR const* vertices, INDEX const* indices, size_t count,
const mat4f& transform) noexcept {
size_t stride = sizeof(VECTOR);
math::float3 bmin(std::numeric_limits<float>::max());
math::float3 bmax(std::numeric_limits<float>::lowest());
for (size_t i = 0; i < count; ++i) {
VECTOR const* p = reinterpret_cast<VECTOR const*>(
(char const*)vertices + indices[i] * stride);
const math::float3 v(p->x, p->y, p->z);
float3 tv = transformPoint(v, transform);
bmin = min(bmin, tv);
bmax = max(bmax, tv);
}
return Box().set(bmin, bmax);
}
void MeshAssimp::addFromFile(const Path& path,
std::map<std::string, MaterialInstance*>& materials, bool overrideMaterial) {
@@ -134,43 +362,7 @@ void MeshAssimp::addFromFile(const Path& path,
// "command buffer" lifetime, we wouldn't need to have to deal with freeing the
// std::vectors here.
// Make default map for all textures except Normal
int defaultTexSize = 4;
unsigned char *defaultTexData = (unsigned char *) malloc(defaultTexSize*sizeof(unsigned char*));
for (int i=0; i < defaultTexSize; i++){
defaultTexData[i] = static_cast<unsigned char>(255);
}
mDefaultMap = Texture::Builder()
.width(uint32_t(1))
.height(uint32_t(1))
.levels(0xff)
.format(driver::TextureFormat::SRGB8)
.build(mEngine);
Texture::PixelBufferDescriptor defaultBuffer(defaultTexData, size_t(1 * 1 * 3),
Texture::Format::RGB, Texture::Type::UBYTE
,(driver::BufferDescriptor::Callback) &free);
mDefaultMap->setImage(mEngine, 0, std::move(defaultBuffer));
mDefaultMap->generateMipmaps(mEngine);
//Make default Normal Map
unsigned char *defaultNormalTexData = (unsigned char *) malloc(defaultTexSize*sizeof(unsigned char*));
defaultNormalTexData[0] = static_cast<unsigned char>(128);
defaultNormalTexData[1] = static_cast<unsigned char>(128);
defaultNormalTexData[2] = static_cast<unsigned char>(255);
defaultNormalTexData[3] = static_cast<unsigned char>(0);
mDefaultNormalMap = Texture::Builder()
.width(uint32_t(1))
.height(uint32_t(1))
.levels(0xff)
.format(driver::TextureFormat::SRGB8)
.build(mEngine);
Texture::PixelBufferDescriptor defaultNormalBuffer(defaultNormalTexData, size_t(1 * 1 * 3),
Texture::Format::RGB, Texture::Type::UBYTE
,(driver::BufferDescriptor::Callback) &free);
mDefaultNormalMap->setImage(mEngine, 0, std::move(defaultNormalBuffer));
mDefaultNormalMap->generateMipmaps(mEngine);
//TODO: a lot of these method arguments should probably be class or global variables
if (!setFromFile(path, indices, positions, tangents, texCoords, meshes, parents, materials)) {
return;
}
@@ -226,13 +418,14 @@ void MeshAssimp::addFromFile(const Path& path,
materials[AI_DEFAULT_MATERIAL_NAME] = mDefaultColorMaterial->createInstance();
}
size_t startIndex = mRenderables.size();
mRenderables.resize(startIndex + meshes.size());
EntityManager::get().create(meshes.size(), mRenderables.data() + startIndex);
EntityManager::get().create(1, &rootEntity);
TransformManager& tcm = mEngine.getTransformManager();
//Add root instance
tcm.create(rootEntity, TransformManager::Instance{}, mat4f());
for (auto& mesh : meshes) {
RenderableManager::Builder builder(mesh.parts.size());
@@ -245,15 +438,12 @@ void MeshAssimp::addFromFile(const Path& path,
if (overrideMaterial) {
builder.material(partIndex, materials[AI_DEFAULT_MATERIAL_NAME]);
} else {
auto pos = materials.find(part.material);
if (pos != materials.end()) {
builder.material(partIndex, pos->second);
} else {
std::cout << "I don't think this should be running" << std::endl;
MaterialInstance* colorMaterial;
if (part.opacity < 1.0f) {
colorMaterial = mDefaultTransparentColorMaterial->createInstance();
@@ -270,7 +460,6 @@ void MeshAssimp::addFromFile(const Path& path,
materials[part.material] = colorMaterial;
}
}
partIndex++;
}
@@ -281,7 +470,7 @@ void MeshAssimp::addFromFile(const Path& path,
}
auto pindex = parents[meshIndex];
TransformManager::Instance parent((pindex < 0) ?
TransformManager::Instance{} : tcm.getInstance(mRenderables[pindex]));
tcm.getInstance(rootEntity) : tcm.getInstance(mRenderables[pindex]));
tcm.create(entity, parent, mesh.transform);
}
}
@@ -307,6 +496,8 @@ bool MeshAssimp::setFromFile(const Path& file,
// normals and tangents
aiProcess_GenSmoothNormals |
aiProcess_CalcTangentSpace |
// UV Coordinates
aiProcess_GenUVCoords |
// topology optimization
aiProcess_FindInstances |
aiProcess_OptimizeMeshes |
@@ -317,10 +508,12 @@ bool MeshAssimp::setFromFile(const Path& file,
// we only support triangles
aiProcess_Triangulate);
if (!scene){
scene = importer.ApplyPostProcessing(aiProcess_CalcTangentSpace);
if (!scene) {
std::cout << "no scene" << std::endl;
}
if (!scene->mRootNode){
if (!scene->mRootNode) {
std::cout << "no root node" << std::endl;
}
@@ -361,14 +554,13 @@ bool MeshAssimp::setFromFile(const Path& file,
outMeshes.back().offset = outIndices.size();
outMeshes.back().transform = current;
mat4f parentTransform = parentIndex >= 0 ? outMeshes[parentIndex].accTransform : mat4f();
outMeshes.back().accTransform = parentTransform * current;
// Bias and scale factor when storing tangent frames in normalized short4
const float bias = 1.0f / 32767.0f;
const float factor = (float) (sqrt(1.0 - (double) bias * (double) bias));
mGltfMaterial = Material::Builder()
.package((void*) GLTF2_PACKAGE, sizeof(GLTF2_PACKAGE))
.build(mEngine);
for (size_t i = 0; i < node->mNumMeshes; i++) {
aiMesh const* mesh = scene->mMeshes[node->mMeshes[i]];
@@ -387,9 +579,23 @@ bool MeshAssimp::setFromFile(const Path& file,
size_t indicesOffset = outPositions.size();
for (size_t j = 0; j < numVertices; j++) {
quatf q = mat3f::packTangentFrame({tangents[j], bitangents[j], normals[j]});
float3 normal = normals[j];
float3 texCoord = texCoords ? texCoords[j] : float3{0.0};
float3 tangent;
float3 bitangent;
//If the tangent and bitangent don't exist, make arbitrary ones
if (!tangents) {
bitangent = norm(cross(normal, float3{1.0, 0.0, 0.0}));
tangent = norm(cross(normal, bitangent));
} else {
tangent = tangents[j];
bitangent = bitangents[j];
}
quatf q = mat3f::packTangentFrame({tangent, bitangent, normal});
outTangents.push_back(packSnorm16(q.xyzw));
outTexCoords.emplace_back(texCoords[j].xy);
outTexCoords.emplace_back(texCoord.xy);
outPositions.emplace_back(positions[j], 1.0_h);
}
@@ -408,38 +614,72 @@ bool MeshAssimp::setFromFile(const Path& file,
uint32_t materialId = mesh->mMaterialIndex;
aiMaterial const* material = scene->mMaterials[materialId];
//Get filepaths for PBR textures
for (i=0; i < material->mNumProperties; i++) {
std::cout << material->mProperties[i]->mKey.C_Str() << std::endl;
}
int texIndex = 0;
aiString baseColorPath;
aiString AOPath;
aiString MRPath;
aiString normalPath;
aiString emissivePath;
aiString name;
std::string materialName;
aiTextureMapMode mapMode[3];
std::string materialName;
if (material->Get(AI_MATKEY_NAME, name) != AI_SUCCESS) {
materialName = AI_DEFAULT_MATERIAL_NAME;
static int matCount = 0;
while (outMaterials.find("_mat_" + std::to_string(matCount)) != outMaterials.end()) {
matCount ++;
}
materialName = "_mat_" + std::to_string(matCount);
} else {
materialName = name.C_Str();
}
// TODO: Add support for non-image path values and binary gltf
TextureSampler sampler(TextureSampler::MinFilter::LINEAR_MIPMAP_LINEAR,
TextureSampler::MagFilter::LINEAR, TextureSampler::WrapMode::REPEAT);
sampler.setAnisotropy(8.0f);
std::string dirName = file.getParent();
std::cout << "directory: " << dirName << std::endl;
TextureSampler defaultSampler(TextureSampler::MinFilter::LINEAR_MIPMAP_LINEAR,
TextureSampler::MagFilter::LINEAR, TextureSampler::WrapMode::REPEAT);
if (outMaterials.find(materialName) == outMaterials.end()) {
outMaterials[materialName] = mGltfMaterial->createInstance();
bool materialIsDoubleSided = false;
material->Get("$mat.twosided", 0, 0, materialIsDoubleSided);
bool materialIsUnlit = false;
material->Get("$mat.gltf.unlit", 0, 0, materialIsUnlit);
aiString alphaMode;
if (materialIsUnlit) {
if (materialIsDoubleSided){
outMaterials[materialName] = mGltfMaterialDSUnlit->createInstance();
} else {
outMaterials[materialName] = mGltfMaterialUnlit->createInstance();
}
} else if (materialIsDoubleSided) {
material->Get("$mat.gltf.alphaMode", 0, 0, alphaMode);
if (strcmp(alphaMode.C_Str(), "BLEND") == 0) {
outMaterials[materialName] = mGltfMaterialDSTrans->createInstance();
} else if (strcmp(alphaMode.C_Str(), "MASK") == 0) {
outMaterials[materialName] = mGltfMaterialDSMasked->createInstance();
float maskThreshold = 0.5;
material->Get("$mat.gltf.alphaCutoff", 0, 0, maskThreshold);
outMaterials[materialName]->setParameter("maskThreshold", maskThreshold);
} else {
outMaterials[materialName] = mGltfMaterialDS->createInstance();
}
} else {
material->Get("$mat.gltf.alphaMode", 0, 0, alphaMode);
if (strcmp(alphaMode.C_Str(), "BLEND") == 0) {
outMaterials[materialName] = mGltfMaterialTrans->createInstance();
} else if (strcmp(alphaMode.C_Str(), "MASK") == 0) {
outMaterials[materialName] = mGltfMaterialMasked->createInstance();
float maskThreshold = 0.5;
material->Get("$mat.gltf.alphaCutoff", 0, 0, maskThreshold);
outMaterials[materialName]->setParameter("maskThreshold", maskThreshold);
} else {
outMaterials[materialName] = mGltfMaterial->createInstance();
}
}
// Load property values for gltf files
aiColor4D baseColorFactor;
@@ -449,102 +689,65 @@ bool MeshAssimp::setFromFile(const Path& file,
float metallicFactor = 1.0;
float roughnessFactor = 1.0;
// if(material->Get("$mat.gltf.occlusionTexture.strength", 0, 0, occlusionStrength) == AI_SUCCESS){
// std::cout << "hey" << std::endl;
// }
//TODO: is occlusion strength available on Assimp now?
// Load texture images for gltf files
if (material->GetTexture(aiTextureType_DIFFUSE, 1, &baseColorPath) == AI_SUCCESS) {
Texture* baseColorMap = nullptr;
loadTex(&mEngine, dirName + baseColorPath.C_Str(), &baseColorMap);
mTextures.push_back(baseColorMap);
if (baseColorMap != nullptr) {
outMaterials[materialName]->setParameter(
"baseColorMap", baseColorMap, sampler);
}
std::cout << dirName + baseColorPath.C_Str() << std::endl;
if (material->GetTexture(aiTextureType_DIFFUSE, 1, &baseColorPath, nullptr, nullptr,
nullptr, nullptr, mapMode) == AI_SUCCESS) {
setTextureFromPath(scene, &mEngine, mTextures, baseColorPath, materialName, dirName, mapMode, "baseColorMap", outMaterials);
} else {
if (mDefaultMap == nullptr){
std::cout << "default mat is null" << std::endl;
}
outMaterials[materialName]->setParameter("baseColorMap", mDefaultMap, sampler);
outMaterials[materialName]->setParameter("baseColorMap", mDefaultMap, defaultSampler);
}
if (material->GetTexture(aiTextureType_UNKNOWN, 0, &MRPath) == AI_SUCCESS) {
Texture* metallicRoughnessMap = nullptr;
loadTex(&mEngine, dirName + MRPath.C_Str(), &metallicRoughnessMap, false);
mTextures.push_back(metallicRoughnessMap);
if (material->GetTexture(aiTextureType_UNKNOWN, 0, &MRPath, nullptr, nullptr,
nullptr, nullptr, mapMode) == AI_SUCCESS) {
setTextureFromPath(scene, &mEngine, mTextures, MRPath, materialName, dirName, mapMode, "metallicRoughnessMap", outMaterials);
if (metallicRoughnessMap != nullptr) {
outMaterials[materialName]->setParameter(
"metallicRoughnessMap", metallicRoughnessMap, sampler);
}
std::cout << dirName + MRPath.C_Str() << std::endl;
} else {
outMaterials[materialName]->setParameter("metallicRoughnessMap", mDefaultMap, sampler);
outMaterials[materialName]->setParameter("metallicRoughnessMap", mDefaultMap, defaultSampler);
outMaterials[materialName]->setParameter("metallicFactor", mDefaultMetallic);
outMaterials[materialName]->setParameter("roughnessFactor", mDefaultRoughness);
}
if (material->GetTexture(aiTextureType_LIGHTMAP, 0, &AOPath) == AI_SUCCESS) {
Texture* aoMap = nullptr;
loadTex(&mEngine, dirName + AOPath.C_Str(), &aoMap, false);
mTextures.push_back(aoMap);
if (material->GetTexture(aiTextureType_LIGHTMAP, 0, &AOPath, nullptr, nullptr,
nullptr, nullptr, mapMode) == AI_SUCCESS) {
setTextureFromPath(scene, &mEngine, mTextures, AOPath, materialName, dirName, mapMode, "aoMap", outMaterials);
if (aoMap != nullptr) {
outMaterials[materialName]->setParameter(
"aoMap", aoMap, sampler);
}
std::cout << dirName + AOPath.C_Str() << std::endl;
} else {
outMaterials[materialName]->setParameter("aoMap", mDefaultMap, sampler);
outMaterials[materialName]->setParameter("aoMap", mDefaultMap, defaultSampler);
}
if (material->GetTexture(aiTextureType_NORMALS, 0, &normalPath) == AI_SUCCESS) {
Texture* normalMap = nullptr;
loadTex(&mEngine, dirName + normalPath.C_Str(), &normalMap, false);
mTextures.push_back(normalMap);
if (normalMap != nullptr) {
outMaterials[materialName]->setParameter(
"normalMap", normalMap, sampler);
}
std::cout << dirName + normalPath.C_Str() << std::endl;
if (material->GetTexture(aiTextureType_NORMALS, 0, &normalPath, nullptr, nullptr,
nullptr, nullptr, mapMode) == AI_SUCCESS) {
setTextureFromPath(scene, &mEngine, mTextures, normalPath, materialName, dirName, mapMode, "normalMap", outMaterials);
} else {
outMaterials[materialName]->setParameter("normalMap", mDefaultNormalMap, sampler);
outMaterials[materialName]->setParameter("normalMap", mDefaultNormalMap, defaultSampler);
}
if (material->GetTexture(aiTextureType_EMISSIVE, 0, &emissivePath) == AI_SUCCESS) {
Texture* emissiveMap = nullptr;
loadTex(&mEngine, dirName + emissivePath.C_Str(), &emissiveMap, false);
mTextures.push_back(emissiveMap);
if (material->GetTexture(aiTextureType_EMISSIVE, 0, &emissivePath, nullptr, nullptr,
nullptr, nullptr, mapMode) == AI_SUCCESS) {
setTextureFromPath(scene, &mEngine, mTextures, emissivePath, materialName, dirName, mapMode, "emissiveMap", outMaterials);
if (emissiveMap != nullptr) {
outMaterials[materialName]->setParameter(
"emissiveMap", emissiveMap, sampler);
}
std::cout << dirName + emissivePath.C_Str() << std::endl;
} else {
outMaterials[materialName]->setParameter("emissiveMap", mDefaultMap, sampler);
outMaterials[materialName]->setParameter("emissiveMap", mDefaultMap, defaultSampler);
outMaterials[materialName]->setParameter("emissiveFactor", mDefaultEmissive);
}
//If the gltf has texture factors, override the default factor values
if(material->Get("$mat.gltf.pbrMetallicRoughness.metallicFactor", 0, 0, metallicFactor) == AI_SUCCESS){
if(material->Get("$mat.gltf.pbrMetallicRoughness.metallicFactor", 0, 0, metallicFactor) == AI_SUCCESS) {
outMaterials[materialName]->setParameter("metallicFactor", metallicFactor);
}
if (material->Get("$mat.gltf.pbrMetallicRoughness.roughnessFactor", 0, 0, roughnessFactor) == AI_SUCCESS){
if (material->Get("$mat.gltf.pbrMetallicRoughness.roughnessFactor", 0, 0, roughnessFactor) == AI_SUCCESS) {
outMaterials[materialName]->setParameter("roughnessFactor", roughnessFactor);
}
if(material->Get(AI_MATKEY_COLOR_EMISSIVE, emissiveFactor) == AI_SUCCESS){
if(material->Get(AI_MATKEY_COLOR_EMISSIVE, emissiveFactor) == AI_SUCCESS) {
emissiveFactorCast = *reinterpret_cast<sRGBColor*>(&emissiveFactor);
outMaterials[materialName]->setParameter("emissiveFactor", emissiveFactorCast);
}
if(material->Get("$mat.gltf.pbrMetallicRoughness.baseColorFactor", 0, 0, baseColorFactor) == AI_SUCCESS){
if(material->Get("$mat.gltf.pbrMetallicRoughness.baseColorFactor", 0, 0, baseColorFactor) == AI_SUCCESS) {
baseColorFactorCast = *reinterpret_cast<sRGBColorA*>(&baseColorFactor);
outMaterials[materialName]->setParameter("baseColorFactor", baseColorFactorCast);
}
}
aiColor3D color;
@@ -600,8 +803,6 @@ bool MeshAssimp::setFromFile(const Path& file,
parentIndex = static_cast<int>(outMeshes.size()) - 1;
deep++;
depth = std::max(deep, depth);
// std::cout << depth << ": num children = " << node->mNumChildren
// << ", parent = " << parentIndex << std::endl;
for (size_t i = 0, c = node->mNumChildren; i < c; i++) {
processNode(node->mChildren[i], parentIndex);
}
@@ -626,16 +827,55 @@ bool MeshAssimp::setFromFile(const Path& file,
std::cout << "Hierarchy depth = " << depth << std::endl;
// compute the aabb
// compute the aabb and find bounding box of entire model
for (auto& mesh : outMeshes) {
mesh.aabb = RenderableManager::computeAABB(
outPositions.data(),
outIndices.data() + mesh.offset,
mesh.count);
}
Box transformedAabb = computeTransformedAABB(
outPositions.data(),
outIndices.data() + mesh.offset,
mesh.count,
mesh.accTransform);
float3 aabbMin = transformedAabb.getMin();
float3 aabbMax = transformedAabb.getMax();
if (!isinf(aabbMin.x) && !isinf(aabbMax.x)) {
if (minBound.x > maxBound.x) {
minBound.x = aabbMin.x;
maxBound.x = aabbMax.x;
} else {
minBound.x = fmin(minBound.x, aabbMin.x);
maxBound.x = fmax(maxBound.x, aabbMax.x);
}
}
if (!isinf(aabbMin.y) && !isinf(aabbMax.y)) {
if (minBound.y > maxBound.y) {
minBound.y = aabbMin.y;
maxBound.y = aabbMax.y;
} else {
minBound.y = fmin(minBound.y, aabbMin.y);
maxBound.y = fmax(maxBound.y, aabbMax.y);
}
}
if (!isinf(aabbMin.z) && !isinf(aabbMax.z)) {
if (minBound.z > maxBound.z) {
minBound.z = aabbMin.z;
maxBound.z = aabbMax.z;
} else {
minBound.z = fmin(minBound.z, aabbMin.z);
maxBound.z = fmax(maxBound.z, aabbMax.z);
}
}
}
return true;
}
return false;
}
+18 -3
View File
@@ -29,6 +29,7 @@ namespace filament {
#include <map>
#include <vector>
#include <math/mat3.h>
#include <math/mat4.h>
#include <math/quat.h>
#include <math/vec3.h>
@@ -40,6 +41,8 @@ namespace filament {
#include <filament/Color.h>
#include <filament/Box.h>
#include <filament/Texture.h>
#include <filament/TextureSampler.h>
#include <filament/TransformManager.h>
class MeshAssimp {
public:
@@ -58,6 +61,11 @@ public:
return mRenderables;
}
//For use with normalizing coordinates
math::float3 minBound = math::float3(1.0f);
math::float3 maxBound = math::float3(-1.0f);
utils::Entity rootEntity;
private:
struct Part {
size_t offset;
@@ -76,6 +84,7 @@ private:
std::vector<Part> parts;
filament::Box aabb;
mat4f transform;
mat4f accTransform;
};
bool setFromFile(const utils::Path& file,
@@ -88,22 +97,28 @@ private:
std::map<std::string, filament::MaterialInstance*>& outMaterials
);
filament::Texture* createOneByOneTexture(uint32_t textureData);
filament::Engine& mEngine;
filament::VertexBuffer* mVertexBuffer = nullptr;
filament::IndexBuffer* mIndexBuffer = nullptr;
filament::Material* mDefaultColorMaterial = nullptr;
filament::Material* mDefaultTransparentColorMaterial = nullptr;
filament::Material* mGltfMaterial = nullptr;
filament::Material* mGltfMaterial = nullptr; // Single sided gltf material
filament::Material* mGltfMaterialDS = nullptr; // Double sided gltf material
filament::Material* mGltfMaterialTrans = nullptr; // Transparent gltf material
filament::Material* mGltfMaterialDSTrans = nullptr; // Double sided Transparent gltf material
filament::Material* mGltfMaterialMasked = nullptr; // Transparent gltf material
filament::Material* mGltfMaterialDSMasked = nullptr; // Double sided Transparent gltf material
filament::Material* mGltfMaterialUnlit = nullptr;
filament::Material* mGltfMaterialDSUnlit = nullptr;
filament::Texture* mDefaultMap = nullptr;
filament::Texture* mDefaultNormalMap = nullptr;
float mDefaultMetallic = 0.0;
float mDefaultRoughness = 0.4;
filament::sRGBColor mDefaultEmissive = filament::sRGBColor({0.0f, 0.0f, 0.0f});
std::vector<utils::Entity> mRenderables;
std::vector<filament::Texture*> mTextures;
+27 -80
View File
@@ -14,14 +14,9 @@
* limitations under the License.
*/
#include <memory>
#include <map>
#include <string>
#include <vector>
#include <getopt/getopt.h>
#include <utils/Path.h>
#include "app/Config.h"
#include "app/FilamentApp.h"
#include "app/MeshAssimp.h"
#include <filament/Engine.h>
#include <filament/LightManager.h>
@@ -33,19 +28,21 @@
#include <filament/Texture.h>
#include <filament/IndirectLight.h>
#include <utils/Path.h>
#include <utils/EntityManager.h>
#include <math/mat3.h>
#include <math/mat4.h>
#include <math/vec3.h>
#include "app/Config.h"
#include "app/FilamentApp.h"
#include "app/MeshAssimp.h"
#include <getopt/getopt.h>
#include <stb_image.h>
#include <utils/EntityManager.h>
#include <filamat/MaterialBuilder.h>
#include <memory>
#include <map>
#include <string>
#include <vector>
using namespace math;
using namespace filament;
@@ -58,25 +55,14 @@ static std::map<std::string, MaterialInstance*> g_materialInstances;
static std::unique_ptr<MeshAssimp> g_meshSet;
static const Material* g_material;
static Entity g_light;
static Texture* g_metallicMap = nullptr;
static Texture* g_roughnessMap = nullptr;
static Texture* g_aoMap = nullptr;
static Texture* g_normalMap = nullptr;
static Texture* g_baseColorMap = nullptr;
static Config g_config;
static struct PbrConfig {
std::string materialDir;
bool clearCoat = false;
bool anisotropy = false;
} g_pbrConfig;
static void printUsage(char* name) {
std::string exec_name(Path(name).getName());
std::string usage(
"SAMPLE_PBR is an example of loading PBR assets with base color + packed metallic/roughness\n"
"gltf_viewer displays gltf models using the filament renderer\n"
"Usage:\n"
" SAMPLE_PBR [options] <OBJ/FBX/COLLADA>\n"
" gltf_viewer [options] <gltf/glb>\n"
"Options:\n"
" --help, -h\n"
" Prints this message\n\n"
@@ -84,38 +70,16 @@ static void printUsage(char* name) {
" Applies an IBL generated by cmgen's deploy option\n\n"
" --split-view, -v\n"
" Splits the window into 4 views\n\n"
" --scale=[number], -s [number]\n"
" Applies uniform scale\n\n"
" --material=<path>, -m <path>\n"
" Directory containing the textures named <DIR_NAME>_*.png where * is:\n"
" - AO\n"
" - Color\n"
" - Metallic\n"
" - Normal\n"
" - Roughness\n"
"\n"
" --clear-coat, -c\n"
" Add a clear coat layer to the material\n\n"
" --anisotropy, -a\n"
" Enable anisotropy on the material\n\n"
);
const std::string from("SAMPLE_PBR");
for (size_t pos = usage.find(from); pos != std::string::npos; pos = usage.find(from, pos)) {
usage.replace(pos, from.length(), exec_name);
}
std::cout << usage;
}
static int handleCommandLineArgments(int argc, char* argv[], Config* config) {
static constexpr const char* OPTSTR = "hi:vs:m:ca";
static constexpr const char* OPTSTR = "hi:v";
static const struct option OPTIONS[] = {
{ "help", no_argument, nullptr, 'h' },
{ "ibl", required_argument, nullptr, 'i' },
{ "split-view", no_argument, nullptr, 'v' },
{ "scale", required_argument, nullptr, 's' },
{ "material", required_argument, nullptr, 'm' },
{ "clear-coat", no_argument, nullptr, 'c' },
{ "anisotropy", no_argument, nullptr, 'a' },
{ 0, 0, 0, 0 } // termination of the option list
};
int opt;
@@ -130,27 +94,9 @@ static int handleCommandLineArgments(int argc, char* argv[], Config* config) {
case 'i':
config->iblDirectory = arg;
break;
case 's':
try {
config->scale = std::stof(arg);
} catch (std::invalid_argument& e) {
// keep scale of 1.0
} catch (std::out_of_range& e) {
// keep scale of 1.0
}
break;
case 'v':
config->splitView = true;
break;
case 'm':
g_pbrConfig.materialDir = arg;
break;
case 'c':
g_pbrConfig.clearCoat = true;
break;
case 'a':
g_pbrConfig.anisotropy = true;
break;
}
}
@@ -164,11 +110,6 @@ static void cleanup(Engine* engine, View* view, Scene* scene) {
}
g_meshSet.reset(nullptr);
engine->destroy(g_material);
engine->destroy(g_baseColorMap);
engine->destroy(g_metallicMap);
engine->destroy(g_roughnessMap);
engine->destroy(g_aoMap);
engine->destroy(g_normalMap);
EntityManager& em = EntityManager::get();
engine->destroy(g_light);
@@ -176,9 +117,6 @@ static void cleanup(Engine* engine, View* view, Scene* scene) {
}
static void setup(Engine* engine, View* view, Scene* scene) {
Path path(g_pbrConfig.materialDir);
std::string name(path.getName());
g_meshSet = std::make_unique<MeshAssimp>(*engine);
for (auto& filename : g_filenames) {
g_meshSet->addFromFile(filename, g_materialInstances, false);
@@ -186,11 +124,21 @@ static void setup(Engine* engine, View* view, Scene* scene) {
auto& rcm = engine->getRenderableManager();
auto& tcm = engine->getTransformManager();
// Compute the scale required to fit the model's bounding box into [-1, 1]
float maxExtent = 0;
maxExtent = std::max(g_meshSet->maxBound.x - g_meshSet->minBound.x, g_meshSet->maxBound.y - g_meshSet->minBound.y);
maxExtent = std::max(maxExtent, g_meshSet->maxBound.z - g_meshSet->minBound.z);
float scaleFactor = 2.0f / maxExtent;
float3 center = -1 * (g_meshSet->maxBound + g_meshSet->minBound) / 2.0f;
center.z -= 4.0f / scaleFactor;
auto rooti = tcm.getInstance(g_meshSet->rootEntity);
tcm.setTransform(rooti, mat4f::scale(float3(scaleFactor)) * mat4f::translate(center));
for (auto renderable : g_meshSet->getRenderables()) {
if (rcm.hasComponent(renderable)) {
auto ti = tcm.getInstance(renderable);
tcm.setTransform(ti, mat4f{ mat3f(g_config.scale), float3(0.0f, 0.0f, -4.0f) } *
tcm.getWorldTransform(ti));
scene->addEntity(renderable);
}
}
@@ -221,7 +169,6 @@ int main(int argc, char* argv[]) {
g_filenames.push_back(filename);
}
g_config.title = "gltf_viewer";
FilamentApp& filamentApp = FilamentApp::get();
filamentApp.run(g_config, setup, cleanup);
+12 -27
View File
@@ -53,33 +53,18 @@ material {
}
fragment {
// void material(inout MaterialInputs material) {
// material.normal = texture(materialParams_normalMap, getUV0()).xyz * 2.0 - 1.0;
// prepareMaterial(material);
// material.baseColor = texture(materialParams_baseColorMap, getUV0());
// material.roughness = texture(materialParams_metallicRoughnessMap, getUV0()).g;
// material.metallic = texture(materialParams_metallicRoughnessMap, getUV0()).b;
// material.ambientOcclusion = texture(materialParams_aoMap, getUV0()).r;
// }
void material(inout MaterialInputs material) {
material.normal = texture(materialParams_normalMap, getUV0()).xyz * 2.0 - 1.0;
material.normal.y = -material.normal.y;
prepareMaterial(material);
void material(inout MaterialInputs material) {
material.normal = texture(materialParams_normalMap, getUV0()).xyz * 2.0 - 1.0;
prepareMaterial(material);
// material.baseColor.rgb = float3(1.0, 0.75, 0.94);
// material.metallic = 0.0;
// material.roughness = 1.0;
// material.ambientOcclusion = 1.0;
material.baseColor = texture(materialParams_baseColorMap, getUV0());
material.baseColor.r *= materialParams.baseColorFactor[0];
material.baseColor.g *= materialParams.baseColorFactor[1];
material.baseColor.b *= materialParams.baseColorFactor[2];
material.roughness = materialParams.roughnessFactor * texture(materialParams_metallicRoughnessMap, getUV0()).g;
material.metallic = materialParams.metallicFactor * texture(materialParams_metallicRoughnessMap, getUV0()).b;
material.ambientOcclusion = texture(materialParams_aoMap, getUV0()).r;
material.emissive = texture(materialParams_emissiveMap, getUV0());
material.emissive.r *= materialParams.emissiveFactor[0];
material.emissive.g *= materialParams.emissiveFactor[1];
material.emissive.b *= materialParams.emissiveFactor[2];
material.baseColor = texture(materialParams_baseColorMap, getUV0());
material.baseColor.rgb *= materialParams.baseColorFactor.xyz;
}
material.roughness = materialParams.roughnessFactor * texture(materialParams_metallicRoughnessMap, getUV0()).g;
material.metallic = materialParams.metallicFactor * texture(materialParams_metallicRoughnessMap, getUV0()).b;
material.ambientOcclusion = texture(materialParams_aoMap, getUV0()).r;
material.emissive = texture(materialParams_emissiveMap, getUV0());
material.emissive.rgb *= materialParams.emissiveFactor.rgb;
}
}
+71
View File
@@ -0,0 +1,71 @@
material {
name : Lit,
requires : [
uv0
],
doubleSided : true,
shadingModel : lit,
parameters : [
{
type : sampler2d,
name : baseColorMap
},
{
type : float4,
name : baseColorFactor
},
{
type : sampler2d,
name : metallicRoughnessMap
},
{
type : float,
name : metallicFactor
},
{
type : float,
name : roughnessFactor
},
{
type : sampler2d,
name : normalMap
},
{
type : float,
name : normalScale
},
{
type : sampler2d,
name : aoMap
},
{
type : float,
name : aoStrength
},
{
type : sampler2d,
name : emissiveMap
},
{
type : float3,
name : emissiveFactor
}
],
}
fragment {
void material(inout MaterialInputs material) {
material.normal = texture(materialParams_normalMap, getUV0()).xyz * 2.0 - 1.0;
material.normal.y = -material.normal.y;
prepareMaterial(material);
material.baseColor = texture(materialParams_baseColorMap, getUV0());
material.baseColor.rgb *= materialParams.baseColorFactor.xyz;
material.roughness = materialParams.roughnessFactor * texture(materialParams_metallicRoughnessMap, getUV0()).g;
material.metallic = materialParams.metallicFactor * texture(materialParams_metallicRoughnessMap, getUV0()).b;
material.ambientOcclusion = texture(materialParams_aoMap, getUV0()).r;
material.emissive = texture(materialParams_emissiveMap, getUV0());
material.emissive.rgb *= materialParams.emissiveFactor.rgb;
}
}
@@ -0,0 +1,74 @@
material {
name : Lit,
requires : [
uv0
],
shadingModel : lit,
doubleSided : true,
blending : masked,
maskThreshold : 0.5,
transparency : default,
parameters : [
{
type : sampler2d,
name : baseColorMap
},
{
type : float4,
name : baseColorFactor
},
{
type : sampler2d,
name : metallicRoughnessMap
},
{
type : float,
name : metallicFactor
},
{
type : float,
name : roughnessFactor
},
{
type : sampler2d,
name : normalMap
},
{
type : float,
name : normalScale
},
{
type : sampler2d,
name : aoMap
},
{
type : float,
name : aoStrength
},
{
type : sampler2d,
name : emissiveMap
},
{
type : float3,
name : emissiveFactor
}
],
}
fragment {
void material(inout MaterialInputs material) {
material.normal = texture(materialParams_normalMap, getUV0()).xyz * 2.0 - 1.0;
material.normal.y = -material.normal.y;
prepareMaterial(material);
material.baseColor = texture(materialParams_baseColorMap, getUV0());
material.baseColor.rgb *= materialParams.baseColorFactor.xyz;
material.roughness = materialParams.roughnessFactor * texture(materialParams_metallicRoughnessMap, getUV0()).g;
material.metallic = materialParams.metallicFactor * texture(materialParams_metallicRoughnessMap, getUV0()).b;
material.ambientOcclusion = texture(materialParams_aoMap, getUV0()).r;
material.emissive = texture(materialParams_emissiveMap, getUV0());
material.emissive.rgb *= materialParams.emissiveFactor.rgb;
}
}
@@ -0,0 +1,74 @@
material {
name : Lit,
requires : [
uv0
],
shadingModel : lit,
doubleSided : true,
blending : transparent,
transparency : default,
parameters : [
{
type : sampler2d,
name : baseColorMap
},
{
type : float4,
name : baseColorFactor
},
{
type : sampler2d,
name : metallicRoughnessMap
},
{
type : float,
name : metallicFactor
},
{
type : float,
name : roughnessFactor
},
{
type : sampler2d,
name : normalMap
},
{
type : float,
name : normalScale
},
{
type : sampler2d,
name : aoMap
},
{
type : float,
name : aoStrength
},
{
type : sampler2d,
name : emissiveMap
},
{
type : float3,
name : emissiveFactor
}
],
}
fragment {
void material(inout MaterialInputs material) {
material.normal = texture(materialParams_normalMap, getUV0()).xyz * 2.0 - 1.0;
material.normal.y = -material.normal.y;
prepareMaterial(material);
material.baseColor = texture(materialParams_baseColorMap, getUV0());
material.baseColor.rgb *= materialParams.baseColorFactor.xyz;
material.baseColor.rgb *= material.baseColor.a;
material.roughness = materialParams.roughnessFactor * texture(materialParams_metallicRoughnessMap, getUV0()).g;
material.metallic = materialParams.metallicFactor * texture(materialParams_metallicRoughnessMap, getUV0()).b;
material.ambientOcclusion = texture(materialParams_aoMap, getUV0()).r;
material.emissive = texture(materialParams_emissiveMap, getUV0());
material.emissive.rgb *= materialParams.emissiveFactor.rgb;
}
}
@@ -0,0 +1,62 @@
material {
name : Unlit,
requires : [
uv0
],
doubleSided : true,
shadingModel : unlit,
parameters : [
{
type : sampler2d,
name : baseColorMap
},
{
type : float4,
name : baseColorFactor
},
{
type : sampler2d,
name : metallicRoughnessMap
},
{
type : float,
name : metallicFactor
},
{
type : float,
name : roughnessFactor
},
{
type : sampler2d,
name : normalMap
},
{
type : float,
name : normalScale
},
{
type : sampler2d,
name : aoMap
},
{
type : float,
name : aoStrength
},
{
type : sampler2d,
name : emissiveMap
},
{
type : float3,
name : emissiveFactor
}
],
}
fragment {
void material(inout MaterialInputs material) {
prepareMaterial(material);
material.baseColor = texture(materialParams_baseColorMap, getUV0());
material.baseColor.rgb *= materialParams.baseColorFactor.xyz;
}
}
+73
View File
@@ -0,0 +1,73 @@
material {
name : Lit,
requires : [
uv0
],
shadingModel : lit,
blending : masked,
maskThreshold : 0.5,
transparency : default,
parameters : [
{
type : sampler2d,
name : baseColorMap
},
{
type : float4,
name : baseColorFactor
},
{
type : sampler2d,
name : metallicRoughnessMap
},
{
type : float,
name : metallicFactor
},
{
type : float,
name : roughnessFactor
},
{
type : sampler2d,
name : normalMap
},
{
type : float,
name : normalScale
},
{
type : sampler2d,
name : aoMap
},
{
type : float,
name : aoStrength
},
{
type : sampler2d,
name : emissiveMap
},
{
type : float3,
name : emissiveFactor
}
],
}
fragment {
void material(inout MaterialInputs material) {
material.normal = texture(materialParams_normalMap, getUV0()).xyz * 2.0 - 1.0;
material.normal.y = -material.normal.y;
prepareMaterial(material);
material.baseColor = texture(materialParams_baseColorMap, getUV0());
material.baseColor.rgb *= materialParams.baseColorFactor.xyz;
material.roughness = materialParams.roughnessFactor * texture(materialParams_metallicRoughnessMap, getUV0()).g;
material.metallic = materialParams.metallicFactor * texture(materialParams_metallicRoughnessMap, getUV0()).b;
material.ambientOcclusion = texture(materialParams_aoMap, getUV0()).r;
material.emissive = texture(materialParams_emissiveMap, getUV0());
material.emissive.rgb *= materialParams.emissiveFactor.rgb;
}
}
+73
View File
@@ -0,0 +1,73 @@
material {
name : Lit,
requires : [
uv0
],
shadingModel : lit,
blending : transparent,
transparency : default,
parameters : [
{
type : sampler2d,
name : baseColorMap
},
{
type : float4,
name : baseColorFactor
},
{
type : sampler2d,
name : metallicRoughnessMap
},
{
type : float,
name : metallicFactor
},
{
type : float,
name : roughnessFactor
},
{
type : sampler2d,
name : normalMap
},
{
type : float,
name : normalScale
},
{
type : sampler2d,
name : aoMap
},
{
type : float,
name : aoStrength
},
{
type : sampler2d,
name : emissiveMap
},
{
type : float3,
name : emissiveFactor
}
],
}
fragment {
void material(inout MaterialInputs material) {
material.normal = texture(materialParams_normalMap, getUV0()).xyz * 2.0 - 1.0;
material.normal.y = -material.normal.y;
prepareMaterial(material);
material.baseColor = texture(materialParams_baseColorMap, getUV0());
material.baseColor.rgb *= materialParams.baseColorFactor.xyz;
material.baseColor.rgb *= material.baseColor.a;
material.roughness = materialParams.roughnessFactor * texture(materialParams_metallicRoughnessMap, getUV0()).g;
material.metallic = materialParams.metallicFactor * texture(materialParams_metallicRoughnessMap, getUV0()).b;
material.ambientOcclusion = texture(materialParams_aoMap, getUV0()).r;
material.emissive = texture(materialParams_emissiveMap, getUV0());
material.emissive.rgb *= materialParams.emissiveFactor.rgb;
}
}
+61
View File
@@ -0,0 +1,61 @@
material {
name : Unlit,
requires : [
uv0
],
shadingModel : unlit,
parameters : [
{
type : sampler2d,
name : baseColorMap
},
{
type : float4,
name : baseColorFactor
},
{
type : sampler2d,
name : metallicRoughnessMap
},
{
type : float,
name : metallicFactor
},
{
type : float,
name : roughnessFactor
},
{
type : sampler2d,
name : normalMap
},
{
type : float,
name : normalScale
},
{
type : sampler2d,
name : aoMap
},
{
type : float,
name : aoStrength
},
{
type : sampler2d,
name : emissiveMap
},
{
type : float3,
name : emissiveFactor
}
],
}
fragment {
void material(inout MaterialInputs material) {
prepareMaterial(material);
material.baseColor = texture(materialParams_baseColorMap, getUV0());
material.baseColor.rgb *= materialParams.baseColorFactor.xyz;
}
}
+13 -14
View File
@@ -14,14 +14,9 @@
* limitations under the License.
*/
#include <memory>
#include <map>
#include <string>
#include <vector>
#include <getopt/getopt.h>
#include <utils/Path.h>
#include "app/Config.h"
#include "app/FilamentApp.h"
#include "app/MeshAssimp.h"
#include <filament/Engine.h>
#include <filament/LightManager.h>
@@ -32,19 +27,23 @@
#include <filament/Scene.h>
#include <filament/Texture.h>
#include <filamat/MaterialBuilder.h>
#include <utils/Path.h>
#include <utils/EntityManager.h>
#include <math/mat3.h>
#include <math/mat4.h>
#include <math/vec3.h>
#include "app/Config.h"
#include "app/FilamentApp.h"
#include "app/MeshAssimp.h"
#include <getopt/getopt.h>
#include <stb_image.h>
#include <utils/EntityManager.h>
#include <filamat/MaterialBuilder.h>
#include <memory>
#include <map>
#include <string>
#include <vector>
using namespace math;
using namespace filament;