PBR material properties;

This commit is contained in:
bjorn 2018-02-11 19:16:40 -08:00
parent d5a1928b3d
commit cca1f32d10
12 changed files with 195 additions and 8 deletions

View File

@ -79,6 +79,7 @@ extern map_int_t HeadsetTypes;
extern map_int_t HorizontalAligns;
extern map_int_t JointTypes;
extern map_int_t MaterialColors;
extern map_int_t MaterialScalars;
extern map_int_t MaterialTextures;
extern map_int_t MatrixTypes;
extern map_int_t MeshDrawModes;

View File

@ -23,6 +23,7 @@ map_int_t DrawModes;
map_int_t FilterModes;
map_int_t HorizontalAligns;
map_int_t MaterialColors;
map_int_t MaterialScalars;
map_int_t MaterialTextures;
map_int_t MatrixTypes;
map_int_t MeshDrawModes;
@ -158,9 +159,19 @@ int l_lovrGraphicsInit(lua_State* L) {
map_init(&MaterialColors);
map_set(&MaterialColors, "diffuse", COLOR_DIFFUSE);
map_set(&MaterialColors, "emissive", COLOR_EMISSIVE);
map_init(&MaterialScalars);
map_set(&MaterialScalars, "metalness", SCALAR_METALNESS);
map_set(&MaterialScalars, "roughness", SCALAR_ROUGHNESS);
map_init(&MaterialTextures);
map_set(&MaterialTextures, "diffuse", TEXTURE_DIFFUSE);
map_set(&MaterialTextures, "emissive", TEXTURE_EMISSIVE);
map_set(&MaterialTextures, "metalness", TEXTURE_METALNESS);
map_set(&MaterialTextures, "roughness", TEXTURE_ROUGHNESS);
map_set(&MaterialTextures, "occlusion", TEXTURE_OCCLUSION);
map_set(&MaterialTextures, "normal", TEXTURE_NORMAL);
map_set(&MaterialTextures, "environment", TEXTURE_ENVIRONMENT_MAP);
map_init(&MatrixTypes);

View File

@ -25,6 +25,22 @@ int l_lovrMaterialSetColor(lua_State* L) {
return 0;
}
int l_lovrMaterialGetScalar(lua_State* L) {
Material* material = luax_checktype(L, 1, Material);
MaterialScalar scalarType = *(MaterialScalar*) luax_checkenum(L, 2, &MaterialScalars, "scalar");
float value = lovrMaterialGetScalar(material, scalarType);
lua_pushnumber(L, value);
return 1;
}
int l_lovrMaterialSetScalar(lua_State* L) {
Material* material = luax_checktype(L, 1, Material);
MaterialScalar scalarType = *(MaterialScalar*) luax_checkenum(L, 2, &MaterialScalars, "scalar");
float value = luaL_checknumber(L, 3);
lovrMaterialSetScalar(material, scalarType, value);
return 0;
}
int l_lovrMaterialGetTexture(lua_State* L) {
Material* material = luax_checktype(L, 1, Material);
MaterialTexture textureType = *(MaterialTexture*) luax_optenum(L, 2, "diffuse", &MaterialTextures, "texture");
@ -49,6 +65,8 @@ int l_lovrMaterialSetTexture(lua_State* L) {
const luaL_Reg lovrMaterial[] = {
{ "getColor", l_lovrMaterialGetColor },
{ "setColor", l_lovrMaterialSetColor },
{ "getScalar", l_lovrMaterialGetScalar },
{ "setScalar", l_lovrMaterialSetScalar },
{ "getTexture", l_lovrMaterialGetTexture },
{ "setTexture", l_lovrMaterialSetTexture },
{ NULL, NULL }

View File

@ -140,11 +140,27 @@ int l_lovrModelDataGetMaterialCount(lua_State* L) {
return 1;
}
int l_lovrModelDataGetDiffuseColor(lua_State* L) {
ModelData* modelData = luax_checktype(L, 1, ModelData);
int materialIndex = luaL_checkint(L, 2) - 1;
static ModelMaterial* luax_checkmodelmaterial(lua_State* L, int index) {
ModelData* modelData = luax_checktype(L, index, ModelData);
int materialIndex = luaL_checkint(L, index + 1) - 1;
lovrAssert(materialIndex >= 0 && materialIndex < modelData->materialCount, "Invalid material index: %d", materialIndex + 1);
ModelMaterial* material = &modelData->materials[materialIndex];
return &modelData->materials[materialIndex];
}
int l_lovrModelDataGetMetalness(lua_State* L) {
ModelMaterial* material = luax_checkmodelmaterial(L, 1);
lua_pushnumber(L, material->metalness);
return 1;
}
int l_lovrModelDataGetRoughness(lua_State* L) {
ModelMaterial* material = luax_checkmodelmaterial(L, 1);
lua_pushnumber(L, material->roughness);
return 1;
}
int l_lovrModelDataGetDiffuseColor(lua_State* L) {
ModelMaterial* material = luax_checkmodelmaterial(L, 1);
Color color = material->diffuseColor;
lua_pushnumber(L, color.r);
lua_pushnumber(L, color.g);
@ -153,16 +169,64 @@ int l_lovrModelDataGetDiffuseColor(lua_State* L) {
return 4;
}
int l_lovrModelDataGetEmissiveColor(lua_State* L) {
ModelMaterial* material = luax_checkmodelmaterial(L, 1);
Color color = material->emissiveColor;
lua_pushnumber(L, color.r);
lua_pushnumber(L, color.g);
lua_pushnumber(L, color.b);
lua_pushnumber(L, color.a);
return 4;
}
int l_lovrModelDataGetDiffuseTexture(lua_State* L) {
ModelData* modelData = luax_checktype(L, 1, ModelData);
int materialIndex = luaL_checkint(L, 2) - 1;
lovrAssert(materialIndex >= 0 && materialIndex < modelData->materialCount, "Invalid material index: %d", materialIndex + 1);
ModelMaterial* material = &modelData->materials[materialIndex];
ModelMaterial* material = luax_checkmodelmaterial(L, 1);
TextureData* textureData = modelData->textures.data[material->diffuseTexture];
luax_pushtype(L, TextureData, textureData);
return 1;
}
int l_lovrModelDataGetEmissiveTexture(lua_State* L) {
ModelData* modelData = luax_checktype(L, 1, ModelData);
ModelMaterial* material = luax_checkmodelmaterial(L, 1);
TextureData* textureData = modelData->textures.data[material->emissiveTexture];
luax_pushtype(L, TextureData, textureData);
return 1;
}
int l_lovrModelDataGetMetalnessTexture(lua_State* L) {
ModelData* modelData = luax_checktype(L, 1, ModelData);
ModelMaterial* material = luax_checkmodelmaterial(L, 1);
TextureData* textureData = modelData->textures.data[material->metalnessTexture];
luax_pushtype(L, TextureData, textureData);
return 1;
}
int l_lovrModelDataGetRoughnessTexture(lua_State* L) {
ModelData* modelData = luax_checktype(L, 1, ModelData);
ModelMaterial* material = luax_checkmodelmaterial(L, 1);
TextureData* textureData = modelData->textures.data[material->roughnessTexture];
luax_pushtype(L, TextureData, textureData);
return 1;
}
int l_lovrModelDataGetOcclusionTexture(lua_State* L) {
ModelData* modelData = luax_checktype(L, 1, ModelData);
ModelMaterial* material = luax_checkmodelmaterial(L, 1);
TextureData* textureData = modelData->textures.data[material->occlusionTexture];
luax_pushtype(L, TextureData, textureData);
return 1;
}
int l_lovrModelDataGetNormalTexture(lua_State* L) {
ModelData* modelData = luax_checktype(L, 1, ModelData);
ModelMaterial* material = luax_checkmodelmaterial(L, 1);
TextureData* textureData = modelData->textures.data[material->normalTexture];
luax_pushtype(L, TextureData, textureData);
return 1;
}
const luaL_Reg lovrModelData[] = {
{ "getVertexData", l_lovrModelDataGetVertexData },
{ "getTriangleCount", l_lovrModelDataGetTriangleCount },
@ -176,7 +240,15 @@ const luaL_Reg lovrModelData[] = {
{ "getNodeComponent", l_lovrModelDataGetNodeComponent },
{ "getAnimationCount", l_lovrModelDataGetAnimationCount },
{ "getMaterialCount", l_lovrModelDataGetMaterialCount },
{ "getMetalness", l_lovrModelDataGetMetalness },
{ "getRoughness", l_lovrModelDataGetRoughness },
{ "getDiffuseColor", l_lovrModelDataGetDiffuseColor },
{ "getEmissiveColor", l_lovrModelDataGetEmissiveColor },
{ "getDiffuseTexture", l_lovrModelDataGetDiffuseTexture },
{ "getEmissiveTexture", l_lovrModelDataGetEmissiveTexture },
{ "getMetalnessTexture", l_lovrModelDataGetMetalnessTexture },
{ "getRoughnessTexture", l_lovrModelDataGetRoughnessTexture },
{ "getOcclusionTexture", l_lovrModelDataGetOcclusionTexture },
{ "getNormalTexture", l_lovrModelDataGetNormalTexture },
{ NULL, NULL }
};

View File

@ -94,6 +94,15 @@ static void assimpNodeTraversal(ModelData* modelData, struct aiNode* assimpNode,
}
}
static float readMaterialScalar(struct aiMaterial* assimpMaterial, const char* key, unsigned int type, unsigned int index) {
float scalar;
if (aiGetMaterialFloatArray(assimpMaterial, key, type, index, &scalar, NULL) == aiReturn_SUCCESS) {
return scalar;
} else {
return 1.f;
}
}
static Color readMaterialColor(struct aiMaterial* assimpMaterial, const char* key, unsigned int type, unsigned int index) {
struct aiColor4D assimpColor;
if (aiGetMaterialColor(assimpMaterial, key, type, index, &assimpColor) == aiReturn_SUCCESS) {
@ -418,7 +427,15 @@ ModelData* lovrModelDataCreate(Blob* blob) {
struct aiMaterial* assimpMaterial = scene->mMaterials[m];
material->diffuseColor = readMaterialColor(assimpMaterial, AI_MATKEY_COLOR_DIFFUSE);
material->emissiveColor = readMaterialColor(assimpMaterial, AI_MATKEY_COLOR_EMISSIVE);
material->diffuseTexture = readMaterialTexture(assimpMaterial, aiTextureType_DIFFUSE, modelData, &textureCache, blob->name);
material->emissiveTexture = readMaterialTexture(assimpMaterial, aiTextureType_EMISSIVE, modelData, &textureCache, blob->name);
material->metalnessTexture = readMaterialTexture(assimpMaterial, aiTextureType_UNKNOWN, modelData, &textureCache, blob->name);
material->roughnessTexture = material->metalnessTexture;
material->occlusionTexture = readMaterialTexture(assimpMaterial, aiTextureType_LIGHTMAP, modelData, &textureCache, blob->name);
material->normalTexture = readMaterialTexture(assimpMaterial, aiTextureType_NORMALS, modelData, &textureCache, blob->name);
material->metalness = readMaterialScalar(assimpMaterial, "$mat.gltf.pbrMetallicRoughness.metallicFactor", 0, 0);
material->roughness = readMaterialScalar(assimpMaterial, "$mat.gltf.pbrMetallicRoughness.roughnessFactor", 0, 0);
}
map_deinit(&textureCache);

View File

@ -34,7 +34,15 @@ typedef struct ModelNode {
typedef struct {
Color diffuseColor;
Color emissiveColor;
int diffuseTexture;
int emissiveTexture;
int metalnessTexture;
int roughnessTexture;
int occlusionTexture;
int normalTexture;
float metalness;
float roughness;
} ModelMaterial;
typedef struct {

View File

@ -159,6 +159,11 @@ void lovrGraphicsPrepare(Material* material, float* pose) {
material = lovrGraphicsGetDefaultMaterial();
}
for (int i = 0; i < MAX_MATERIAL_SCALARS; i++) {
float value = lovrMaterialGetScalar(material, i);
lovrShaderSetFloat(shader, lovrShaderScalarUniforms[i], &value, 1);
}
for (int i = 0; i < MAX_MATERIAL_COLORS; i++) {
Color color = lovrMaterialGetColor(material, i);
gammaCorrectColor(&color);

View File

@ -7,6 +7,10 @@ Material* lovrMaterialCreate(bool isDefault) {
material->isDefault = isDefault;
for (int i = 0; i < MAX_MATERIAL_SCALARS; i++) {
material->scalars[i] = 1.f;
}
for (int i = 0; i < MAX_MATERIAL_COLORS; i++) {
material->colors[i] = (Color) { 1, 1, 1, 1 };
}
@ -28,6 +32,14 @@ void lovrMaterialDestroy(const Ref* ref) {
free(material);
}
float lovrMaterialGetScalar(Material* material, MaterialScalar scalarType) {
return material->scalars[scalarType];
}
void lovrMaterialSetScalar(Material* material, MaterialScalar scalarType, float value) {
material->scalars[scalarType] = value;
}
Color lovrMaterialGetColor(Material* material, MaterialColor colorType) {
return material->colors[colorType];
}

View File

@ -4,19 +4,32 @@
#pragma once
typedef enum {
SCALAR_METALNESS,
SCALAR_ROUGHNESS,
MAX_MATERIAL_SCALARS
} MaterialScalar;
typedef enum {
COLOR_DIFFUSE,
COLOR_EMISSIVE,
MAX_MATERIAL_COLORS
} MaterialColor;
typedef enum {
TEXTURE_DIFFUSE,
TEXTURE_EMISSIVE,
TEXTURE_METALNESS,
TEXTURE_ROUGHNESS,
TEXTURE_OCCLUSION,
TEXTURE_NORMAL,
TEXTURE_ENVIRONMENT_MAP,
MAX_MATERIAL_TEXTURES
} MaterialTexture;
typedef struct {
Ref ref;
float scalars[MAX_MATERIAL_SCALARS];
Color colors[MAX_MATERIAL_COLORS];
Texture* textures[MAX_MATERIAL_TEXTURES];
bool isDefault;
@ -24,6 +37,8 @@ typedef struct {
Material* lovrMaterialCreate(bool isDefault);
void lovrMaterialDestroy(const Ref* ref);
float lovrMaterialGetScalar(Material* material, MaterialScalar scalarType);
void lovrMaterialSetScalar(Material* material, MaterialScalar scalarType, float value);
Color lovrMaterialGetColor(Material* material, MaterialColor colorType);
void lovrMaterialSetColor(Material* material, MaterialColor colorType, Color color);
Texture* lovrMaterialGetTexture(Material* material, MaterialTexture textureType);

View File

@ -84,8 +84,16 @@ Model* lovrModelCreate(ModelData* modelData) {
for (int i = 0; i < modelData->materialCount; i++) {
ModelMaterial* materialData = &modelData->materials[i];
Material* material = lovrMaterialCreate(false);
lovrMaterialSetScalar(material, SCALAR_METALNESS, materialData->metalness);
lovrMaterialSetScalar(material, SCALAR_ROUGHNESS, materialData->roughness);
lovrMaterialSetColor(material, COLOR_DIFFUSE, materialData->diffuseColor);
lovrMaterialSetColor(material, COLOR_EMISSIVE, materialData->emissiveColor);
lovrMaterialSetTexture(material, TEXTURE_DIFFUSE, model->textures[materialData->diffuseTexture]);
lovrMaterialSetTexture(material, TEXTURE_EMISSIVE, model->textures[materialData->emissiveTexture]);
lovrMaterialSetTexture(material, TEXTURE_METALNESS, model->textures[materialData->metalnessTexture]);
lovrMaterialSetTexture(material, TEXTURE_ROUGHNESS, model->textures[materialData->roughnessTexture]);
lovrMaterialSetTexture(material, TEXTURE_OCCLUSION, model->textures[materialData->occlusionTexture]);
lovrMaterialSetTexture(material, TEXTURE_NORMAL, model->textures[materialData->normalTexture]);
model->materials[i] = material;
}
} else {

View File

@ -1,11 +1,22 @@
#include "resources/shaders.h"
const char* lovrShaderScalarUniforms[] = {
"lovrMetalness",
"lovrRoughness"
};
const char* lovrShaderColorUniforms[] = {
"lovrDiffuseColor"
"lovrDiffuseColor",
"lovrEmissiveColor"
};
const char* lovrShaderTextureUniforms[] = {
"lovrDiffuseTexture",
"lovrEmissiveTexture",
"lovrMetalnessTexture",
"lovrRoughnessTexture",
"lovrOcclusionTexture",
"lovrNormalTexture",
"lovrEnvironmentTexture"
};
@ -45,9 +56,17 @@ const char* lovrShaderFragmentPrefix = ""
"in vec2 texCoord; \n"
"in vec4 vertexColor; \n"
"out vec4 lovrFragColor; \n"
"uniform float lovrMetalness; \n"
"uniform float lovrRoughness; \n"
"uniform vec4 lovrColor; \n"
"uniform vec4 lovrDiffuseColor; \n"
"uniform vec4 lovrEmissiveColor; \n"
"uniform sampler2D lovrDiffuseTexture; \n"
"uniform sampler2D lovrEmissiveTexture; \n"
"uniform sampler2D lovrMetalnessTexture; \n"
"uniform sampler2D lovrRoughnessTexture; \n"
"uniform sampler2D lovrOcclusionTexture; \n"
"uniform sampler2D lovrNormalTexture; \n"
"uniform samplerCube lovrEnvironmentTexture; \n"
"#line 0 \n";

View File

@ -1,5 +1,6 @@
#pragma once
extern const char* lovrShaderScalarUniforms[];
extern const char* lovrShaderColorUniforms[];
extern const char* lovrShaderTextureUniforms[];
extern const char* lovrShaderVertexPrefix;