gltfio: add ubershader template.

We will need 6 pre-compiled materials (lit vs nonlit and the 3 blend
modes). This uses CMake's "configure_file" functionality to generate 6
mat files, then invokes matc on each one. They are then combined using
resgen.
This commit is contained in:
Philip Rideout
2019-03-11 15:43:56 -07:00
parent 960d1321e6
commit 39c63146e0
3 changed files with 173 additions and 4 deletions

View File

@@ -303,7 +303,9 @@ endif()
# ==================================================================================================
# Sets the following variables: RESGEN_HEADER, RESGEN_SOURCE, RESGEN_FLAGS, RESGEN_SOURCE_FLAGS,
# and RESGEN_OUTPUTS
# and RESGEN_OUTPUTS. Please pass in an ARCHIVE_NAME that is unique to your project, otherwise the
# incbin directive will happily consume a blob from the wrong project without warnings or errors.
# Also be sure to include the ASM language in the CMake "project" directive for your project.
function(get_resgen_vars ARCHIVE_DIR ARCHIVE_NAME)
set(OUTPUTS
${ARCHIVE_DIR}/${ARCHIVE_NAME}.bin

View File

@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.1)
project(gltfio)
project(gltfio C ASM)
set(TARGET gltfio)
set(PUBLIC_HDR_DIR include)
@@ -29,14 +29,85 @@ set(SRCS
src/upcast.h
)
# ==================================================================================================
# Build materials
# ==================================================================================================
set(RESOURCE_DIR ${CMAKE_CURRENT_BINARY_DIR})
if (CMAKE_CROSSCOMPILING)
include(${IMPORT_EXECUTABLES})
endif()
if (ANDROID OR WEBGL OR IOS)
set(MATC_TARGET mobile)
else()
set(MATC_TARGET desktop)
endif()
set(MATC_FLAGS -a all)
if (NOT CMAKE_BUILD_TYPE MATCHES Release)
set(MATC_FLAGS -g ${MATC_FLAGS})
endif()
function(generate_mat SHADINGMODEL BLENDING)
set(GENERATED_MAT "${RESOURCE_DIR}/${SHADINGMODEL}_${BLENDING}.mat")
configure_file(materials/ubershader.mat.in ${GENERATED_MAT})
set(MATERIAL_SRCS ${MATERIAL_SRCS} ${GENERATED_MAT} PARENT_SCOPE)
endfunction()
set(MATERIAL_SRCS)
generate_mat(lit transparent)
generate_mat(lit opaque)
generate_mat(lit masked)
generate_mat(unlit transparent)
generate_mat(unlit opaque)
generate_mat(unlit masked)
set(RESOURCE_BINS)
foreach (input_path ${MATERIAL_SRCS})
get_filename_component(basename "${input_path}" NAME_WE)
set(output_path "${RESOURCE_DIR}/${basename}.filamat")
add_custom_command(
OUTPUT ${output_path}
COMMAND matc ${MATC_FLAGS} -p ${MATC_TARGET} -m material
-o ${output_path} ${input_path}
MAIN_DEPENDENCY ${input_path}
DEPENDS matc
COMMENT "Compiling material ${mat_src} to ${output_path}"
)
list(APPEND RESOURCE_BINS ${output_path})
endforeach()
# ==================================================================================================
# Build resources library
# ==================================================================================================
get_resgen_vars(${RESOURCE_DIR} gltfresources)
add_custom_command(
OUTPUT ${RESGEN_OUTPUTS}
COMMAND resgen ${RESGEN_FLAGS} ${RESOURCE_BINS}
DEPENDS resgen ${RESOURCE_BINS}
)
if (DEFINED RESGEN_SOURCE_FLAGS)
set_source_files_properties(${RESGEN_SOURCE} PROPERTIES COMPILE_FLAGS ${RESGEN_SOURCE_FLAGS})
endif()
set(DUMMY_SRC "${RESOURCE_DIR}/dummy.c")
add_custom_command(OUTPUT ${DUMMY_SRC} COMMAND echo "//" > ${DUMMY_SRC})
add_library(gltfio_resources ${DUMMY_SRC} ${RESGEN_SOURCE})
# ==================================================================================================
# Include and target definitions
# ==================================================================================================
include_directories(${PUBLIC_HDR_DIR})
include_directories(${PUBLIC_HDR_DIR} ${RESOURCE_DIR})
add_library(${TARGET} STATIC ${PUBLIC_HDRS} ${SRCS})
target_link_libraries(${TARGET} PUBLIC math utils filamat filament cgltf stb geometry)
target_link_libraries(${TARGET} PUBLIC math utils filamat filament cgltf stb geometry gltfio_resources)
target_include_directories(${TARGET} PUBLIC ${PUBLIC_HDR_DIR})

View File

@@ -0,0 +1,96 @@
material {
name : ubershader,
requires : [ uv0, uv1, color ],
shadingModel : ${SHADINGMODEL},
blending : ${BLENDING},
parameters : [
// Base Color
{ type : int, name : baseColorIndex },
{ type : float4, name : baseColorFactor },
{ type : sampler2d, name : baseColorMap },
{ type : mat3, name : baseColorUvMatrix },
// Metallic-Roughness Map
{ type : int, name : metallicRoughnessIndex },
{ type : float, name : metallicFactor },
{ type : float, name : roughnessFactor },
{ type : sampler2d, name : metallicRoughnessMap },
{ type : mat3, name : metallicRoughnessUvMatrix },
// Normal Map
{ type : int, name : normalIndex },
{ type : float, name : normalScale },
{ type : sampler2d, name : normalMap },
{ type : mat3, name : normalUvMatrix },
// Ambient Occlusion
{ type : int, name : aoIndex },
{ type : float, name : aoStrength },
{ type : sampler2d, name : occlusionMap },
{ type : mat3, name : occlusionUvMatrix },
// Emissive Map
{ type : int, name : emissiveIndex },
{ type : float3, name : emissiveFactor },
{ type : sampler2d, name : emissiveMap },
{ type : mat3, name : emissiveUvMatrix }
],
}
fragment {
void material(inout MaterialInputs material) {
float2 uvs[2];// = { getUV0(), getUV1() };
uvs[0] = getUV0();
uvs[1] = getUV1();
#if !defined(SHADING_MODEL_UNLIT)
if (materialParams.normalIndex > -1) {
float2 uv = uvs[materialParams.normalIndex];
uv = (vec3(uv, 1.0) * materialParams.normalUvMatrix).xy;
material.normal = texture(materialParams_normalMap, uv).xyz * 2.0 - 1.0;
material.normal.y = -material.normal.y;
material.normal.xy *= materialParams.normalScale;
}
#endif
prepareMaterial(material);
material.baseColor = materialParams.baseColorFactor;
if (materialParams.baseColorIndex > -1) {
float2 uv = uvs[materialParams.baseColorIndex];
uv = (vec3(uv, 1.0) * materialParams.baseColorUvMatrix).xy;
material.baseColor *= texture(materialParams_baseColorMap, uv);
}
#if defined(BLEND_MODE_TRANSPARENT)
material.baseColor.rgb *= material.baseColor.a;
#endif
material.baseColor *= getColor();
#if !defined(SHADING_MODEL_UNLIT)
material.roughness = materialParams.roughnessFactor;
material.metallic = materialParams.metallicFactor;
material.emissive.rgb = materialParams.emissiveFactor.rgb;
material.emissive.a = 3.0;
if (materialParams.metallicRoughnessIndex > -1) {
float2 uv = uvs[materialParams.metallicRoughnessIndex];
uv = (vec3(uv, 1.0) * materialParams.metallicRoughnessUvMatrix).xy;
vec4 roughness = texture(materialParams_metallicRoughnessMap, uv);
material.roughness *= roughness.g;
material.metallic *= roughness.b;
}
if (materialParams.aoIndex > -1) {
float2 uv = uvs[materialParams.aoIndex];
uv = (vec3(uv, 1.0) * materialParams.occlusionUvMatrix).xy;
material.ambientOcclusion = texture(materialParams_occlusionMap, uv).r *
materialParams.aoStrength;
}
if (materialParams.emissiveIndex > -1) {
float2 uv = uvs[materialParams.emissiveIndex];
uv = (vec3(uv, 1.0) * materialParams.emissiveUvMatrix).xy;
material.emissive.rgb *= texture(materialParams_emissiveMap, uv).rgb;
}
#endif
}
}