mirror of https://github.com/bjornbytes/lovr.git
PBR material properties;
This commit is contained in:
parent
d5a1928b3d
commit
cca1f32d10
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 }
|
||||
|
|
|
@ -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 }
|
||||
};
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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];
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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";
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#pragma once
|
||||
|
||||
extern const char* lovrShaderScalarUniforms[];
|
||||
extern const char* lovrShaderColorUniforms[];
|
||||
extern const char* lovrShaderTextureUniforms[];
|
||||
extern const char* lovrShaderVertexPrefix;
|
||||
|
|
Loading…
Reference in New Issue