From 39c63146e002df507da0fcbcb26475c4bdf2ddcd Mon Sep 17 00:00:00 2001 From: Philip Rideout Date: Mon, 11 Mar 2019 15:43:56 -0700 Subject: [PATCH] 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. --- CMakeLists.txt | 4 +- libs/gltfio/CMakeLists.txt | 77 +++++++++++++++++++- libs/gltfio/materials/ubershader.mat.in | 96 +++++++++++++++++++++++++ 3 files changed, 173 insertions(+), 4 deletions(-) create mode 100644 libs/gltfio/materials/ubershader.mat.in diff --git a/CMakeLists.txt b/CMakeLists.txt index 26a8389340..36804ab334 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/libs/gltfio/CMakeLists.txt b/libs/gltfio/CMakeLists.txt index f1b2d7a59c..a7b0e56629 100644 --- a/libs/gltfio/CMakeLists.txt +++ b/libs/gltfio/CMakeLists.txt @@ -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}) diff --git a/libs/gltfio/materials/ubershader.mat.in b/libs/gltfio/materials/ubershader.mat.in new file mode 100644 index 0000000000..0b245a25c3 --- /dev/null +++ b/libs/gltfio/materials/ubershader.mat.in @@ -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 + } +}