mirror of
https://github.com/open-goal/jak-project
synced 2026-09-03 02:14:07 -04:00
custom models: envmap support (#3777)
Custom models and model replacements now support environment mapping. Also fixed some cases in Jak 3 where tfrags had missing textures (defaulting to texture 0 from tpage 0, which in Jak 3 is the default eye texture) and replaced them with more suitable alternatives. Fixes #3776 https://github.com/user-attachments/assets/7c11b0de-b254-40cb-9719-11238dfb3d43  
This commit is contained in:
@@ -1,5 +1,7 @@
|
||||
#include "gltf_util.h"
|
||||
|
||||
#include "image_resize.h"
|
||||
|
||||
#include "common/log/log.h"
|
||||
|
||||
namespace gltf_util {
|
||||
@@ -424,6 +426,64 @@ int texture_pool_add_texture(TexturePool* pool, const tinygltf::Image& tex, int
|
||||
return idx;
|
||||
}
|
||||
|
||||
int texture_pool_add_envmap_control_texture(TexturePool* pool,
|
||||
const tinygltf::Model& model,
|
||||
int rgb_image_id,
|
||||
int mr_image_id,
|
||||
bool wrap_w,
|
||||
bool wrap_h) {
|
||||
const auto& existing = pool->envmap_textures_by_gltf_id.find({rgb_image_id, mr_image_id});
|
||||
if (existing != pool->envmap_textures_by_gltf_id.end()) {
|
||||
lg::info("Reusing envmap textures");
|
||||
return existing->second;
|
||||
}
|
||||
const auto& rgb_tex = model.images.at(rgb_image_id);
|
||||
const auto& mr_tex = model.images.at(mr_image_id);
|
||||
lg::info("new envmap texture {} {}", rgb_tex.name, mr_tex.name);
|
||||
ASSERT(rgb_tex.bits == 8);
|
||||
ASSERT(rgb_tex.component == 4);
|
||||
ASSERT(rgb_tex.pixel_type == TINYGLTF_TEXTURE_TYPE_UNSIGNED_BYTE);
|
||||
|
||||
ASSERT(mr_tex.bits == 8);
|
||||
ASSERT(mr_tex.pixel_type == TINYGLTF_TEXTURE_TYPE_UNSIGNED_BYTE);
|
||||
ASSERT(mr_tex.component == 4);
|
||||
|
||||
std::vector<u8> resized_mr_tex;
|
||||
const u8* mr_src;
|
||||
if (rgb_tex.width == mr_tex.width && rgb_tex.height == mr_tex.height) {
|
||||
mr_src = mr_tex.image.data();
|
||||
} else {
|
||||
resized_mr_tex.resize(rgb_tex.width * rgb_tex.height * 4);
|
||||
resize_rgba_image(resized_mr_tex.data(), rgb_tex.width, rgb_tex.height, mr_tex.image.data(),
|
||||
mr_tex.width, mr_tex.height, wrap_w, wrap_h);
|
||||
mr_src = resized_mr_tex.data();
|
||||
}
|
||||
|
||||
size_t idx = pool->textures_by_idx.size();
|
||||
pool->envmap_textures_by_gltf_id[{rgb_image_id, mr_image_id}] = idx;
|
||||
auto& tt = pool->textures_by_idx.emplace_back();
|
||||
tt.w = rgb_tex.width;
|
||||
tt.h = rgb_tex.height;
|
||||
tt.debug_name = rgb_tex.name;
|
||||
tt.debug_tpage_name = "custom-level";
|
||||
tt.load_to_pool = false;
|
||||
tt.combo_id = 0; // doesn't matter, not a pool tex
|
||||
tt.data.resize(tt.w * tt.h);
|
||||
ASSERT(rgb_tex.image.size() >= tt.data.size());
|
||||
memcpy(tt.data.data(), rgb_tex.image.data(), tt.data.size() * 4);
|
||||
|
||||
// adjust alpha from metallic channel
|
||||
for (size_t i = 0; i < tt.data.size(); i++) {
|
||||
u32 rgb = tt.data[i];
|
||||
u32 metal = mr_src[4 * i + 2] / 4;
|
||||
rgb &= 0xff'ff'ff;
|
||||
rgb |= (metal << 24);
|
||||
tt.data[i] = rgb;
|
||||
}
|
||||
|
||||
return idx;
|
||||
}
|
||||
|
||||
math::Matrix4f affine_translation(const math::Vector3f& translation) {
|
||||
math::Matrix4f result = math::Matrix4f::identity();
|
||||
result(0, 3) = translation[0];
|
||||
@@ -607,6 +667,19 @@ void setup_draw_mode_from_sampler(const tinygltf::Sampler& sampler, DrawMode* mo
|
||||
}
|
||||
}
|
||||
|
||||
EnvmapSettings envmap_settings_from_gltf(const tinygltf::Material& mat) {
|
||||
EnvmapSettings settings;
|
||||
|
||||
ASSERT(mat.extensions.contains("KHR_materials_specular"));
|
||||
const auto& specular_extension = mat.extensions.at("KHR_materials_specular");
|
||||
ASSERT(specular_extension.Has("specularColorTexture"));
|
||||
|
||||
auto& texture = specular_extension.Get("specularColorTexture");
|
||||
ASSERT(texture.Has("index"));
|
||||
settings.texture_idx = texture.Get("index").Get<int>();
|
||||
return settings;
|
||||
}
|
||||
|
||||
std::optional<int> find_single_skin(const tinygltf::Model& model,
|
||||
const std::vector<NodeWithTransform>& all_nodes) {
|
||||
std::optional<int> skin_index;
|
||||
|
||||
Reference in New Issue
Block a user