Fix/improve alpha cutoff;

The current flag did not work because float shader flags are not
supported.  It was also not very useful because it was per-shader
and did not use the alpha cutoff property of glTF materials.

Instead, let's turn the shader flag into an enable/disable boolean,
and add a scalar material property named "alphacutoff" that gets
read by the glTF importer.

When the alphaCutoff flag is enabled, the material property will be
compared against the pixel's alpha value to decide whether it should
get discarded.
This commit is contained in:
bjorn 2021-12-28 21:04:20 +02:00
parent 8d3d233e91
commit 8462beef00
5 changed files with 10 additions and 3 deletions

View File

@ -132,6 +132,7 @@ StringEntry lovrMaterialColor[] = {
StringEntry lovrMaterialScalar[] = {
[SCALAR_METALNESS] = ENTRY("metalness"),
[SCALAR_ROUGHNESS] = ENTRY("roughness"),
[SCALAR_ALPHA_CUTOFF] = ENTRY("alphacutoff"),
{ 0 }
};

View File

@ -58,6 +58,7 @@ typedef struct {
typedef enum {
SCALAR_METALNESS,
SCALAR_ROUGHNESS,
SCALAR_ALPHA_CUTOFF,
MAX_MATERIAL_SCALARS
} MaterialScalar;

View File

@ -688,6 +688,7 @@ ModelData* lovrModelDataInitGltf(ModelData* model, Blob* source, ModelDataIO* io
for (int i = (token++)->size; i > 0; i--, material++) {
material->scalars[SCALAR_METALNESS] = 1.f;
material->scalars[SCALAR_ROUGHNESS] = 1.f;
material->scalars[SCALAR_ALPHA_CUTOFF] = 0.f;
material->colors[COLOR_DIFFUSE] = (Color) { 1.f, 1.f, 1.f, 1.f };
material->colors[COLOR_EMISSIVE] = (Color) { 0.f, 0.f, 0.f, 0.f };
memset(material->images, 0xff, MAX_MATERIAL_TEXTURES * sizeof(uint32_t));
@ -729,6 +730,8 @@ ModelData* lovrModelDataInitGltf(ModelData* model, Blob* source, ModelDataIO* io
material->colors[COLOR_EMISSIVE].r = NOM_FLOAT(json, token);
material->colors[COLOR_EMISSIVE].g = NOM_FLOAT(json, token);
material->colors[COLOR_EMISSIVE].b = NOM_FLOAT(json, token);
} else if (STR_EQ(key, "alphaCutoff")) {
material->scalars[SCALAR_ALPHA_CUTOFF] = NOM_FLOAT(json, token);
} else if (STR_EQ(key, "name")) {
gltfString name = NOM_STR(json, token);
map_set(&model->materialMap, hash64(name.data, name.length), model->materialCount - i);

View File

@ -21,7 +21,7 @@ Material* lovrMaterialCreate() {
material->ref = 1;
for (int i = 0; i < MAX_MATERIAL_SCALARS; i++) {
material->scalars[i] = 1.f;
material->scalars[i] = i == SCALAR_ALPHA_CUTOFF ? 0.f : 1.f;
}
for (int i = 0; i < MAX_MATERIAL_COLORS; i++) {

View File

@ -87,6 +87,7 @@ const char* lovrShaderFragmentPrefix = ""
"out vec4 lovrCanvas[gl_MaxDrawBuffers]; \n"
"uniform float lovrMetalness; \n"
"uniform float lovrRoughness; \n"
"uniform float lovrAlphaCutoff; \n"
"uniform vec4 lovrDiffuseColor; \n"
"uniform vec4 lovrEmissiveColor; \n"
"uniform sampler2D lovrDiffuseTexture; \n"
@ -124,7 +125,7 @@ const char* lovrShaderFragmentSuffix = ""
"#else \n"
" lovrCanvas[0] = color(lovrGraphicsColor, lovrDiffuseTexture, lovrTexCoord); \n"
"#ifdef FLAG_alphaCutoff \n"
" if (lovrCanvas[0].a < FLAG_alphaCutoff) { \n"
" if (lovrCanvas[0].a < lovrAlphaCutoff) { \n"
" discard; \n"
" } \n"
"#endif \n"
@ -372,7 +373,8 @@ const char* lovrFillVertexShader = ""
const char* lovrShaderScalarUniforms[] = {
"lovrMetalness",
"lovrRoughness"
"lovrRoughness",
"lovrAlphaCutoff"
};
const char* lovrShaderColorUniforms[] = {