From abea65b0be1c2fdd38dfff88b449af6cc7aea7ce Mon Sep 17 00:00:00 2001 From: Haroon Qureshi Date: Thu, 7 May 2026 07:50:30 -0700 Subject: [PATCH] Simplify materials. Merge shading model, material params, and material textures into a single "mjrMaterial" type. Remove redundant decor_line material. PiperOrigin-RevId: 911960222 Change-Id: Icce3772a8ea48467dfd610799c0c2f2ba752323e --- src/experimental/filament/CMakeLists.txt | 1 - .../filament/assets/unlit_line.mat | 29 ---- .../filament/compat/imgui_bridge.cc | 30 ++--- .../filament/compat/scene_geom_util.cc | 126 +++++++++--------- .../filament/filament/material.cc | 69 +++++----- src/experimental/filament/filament/material.h | 3 +- .../filament/filament/object_manager.cc | 1 - .../filament/filament/object_manager.h | 1 - .../filament/filament/renderable.cc | 64 ++++----- .../filament/filament/renderable.h | 23 +--- .../filament/filament/scene_view.cc | 20 +-- .../filament/render_context_filament.cc | 46 +++---- .../filament/render_context_filament.h | 99 ++++++++------ src/experimental/studio/index.html | 1 - 14 files changed, 228 insertions(+), 285 deletions(-) delete mode 100644 src/experimental/filament/assets/unlit_line.mat diff --git a/src/experimental/filament/CMakeLists.txt b/src/experimental/filament/CMakeLists.txt index 37105703..42261f11 100644 --- a/src/experimental/filament/CMakeLists.txt +++ b/src/experimental/filament/CMakeLists.txt @@ -117,7 +117,6 @@ set(MATERIAL_FILES phong_cube_reflect.mat unlit_decor.mat unlit_depth.mat - unlit_line.mat unlit_segmentation.mat unlit_ui.mat ) diff --git a/src/experimental/filament/assets/unlit_line.mat b/src/experimental/filament/assets/unlit_line.mat deleted file mode 100644 index 359bb319..00000000 --- a/src/experimental/filament/assets/unlit_line.mat +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright 2025 DeepMind Technologies Limited -// -// Licensed under the Apache License, Version 2.0 (the "License"); -// you may not use this file except in compliance with the License. -// You may obtain a copy of the License at -// -// http://www.apache.org/licenses/LICENSE-2.0 -// -// Unless required by applicable law or agreed to in writing, software -// distributed under the License is distributed on an "AS IS" BASIS, -// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -// See the License for the specific language governing permissions and -// limitations under the License. - -material { - name : unlit_segmentation, - shadingModel : unlit, - culling: none, - parameters : [ - { type : float4, name : BaseColorFactor } - ] -} - -fragment { - void material(inout MaterialInputs material) { - prepareMaterial(material); - material.baseColor = materialParams.BaseColorFactor; - } -} diff --git a/src/experimental/filament/compat/imgui_bridge.cc b/src/experimental/filament/compat/imgui_bridge.cc index f7fbdd65..30a2fdcf 100644 --- a/src/experimental/filament/compat/imgui_bridge.cc +++ b/src/experimental/filament/compat/imgui_bridge.cc @@ -253,26 +253,25 @@ void ImguiBridge::Update() { mjrf_setRenderableMesh(renderable.get(), mesh, index_offset, command.ElemCount); - mjrMaterialTextures textures; - mjr_defaultMaterialTextures(&textures); - textures.color = GetTexture(command.GetTexID()); + mjrMaterial material; + mjr_defaultMaterial(&material); + material.color_texture = GetTexture(command.GetTexID()); - mjrMaterialParams properties; - mjr_defaultMaterialParams(&properties); - properties.scissor[0] = command.ClipRect.x; - properties.scissor[1] = height - command.ClipRect.w; - properties.scissor[2] = command.ClipRect.z - command.ClipRect.x; - properties.scissor[3] = command.ClipRect.w - command.ClipRect.y; + material.decor_ux = true; + material.scissor[0] = command.ClipRect.x; + material.scissor[1] = height - command.ClipRect.w; + material.scissor[2] = command.ClipRect.z - command.ClipRect.x; + material.scissor[3] = command.ClipRect.w - command.ClipRect.y; // Modal dialogs try to cover the whole window, but also a little outside // of it. This doesn't work well with filament's scissor test, so we clip // them to the window. - if (properties.scissor[0] < 0 || properties.scissor[1] < 0) { - properties.scissor[0] = 0; - properties.scissor[1] = 0; - properties.scissor[2] = width; - properties.scissor[3] = height; + if (material.scissor[0] < 0 || material.scissor[1] < 0) { + material.scissor[0] = 0; + material.scissor[1] = 0; + material.scissor[2] = width; + material.scissor[3] = height; } - mjrf_setRenderableMaterial(renderable.get(), &properties, &textures); + mjrf_setRenderableMaterial(renderable.get(), &material); const float position[] = {0, 0, 0}; const float rotation[] = {1, 0, 0, 0, 1, 0, 0, 0, 1}; @@ -289,7 +288,6 @@ void ImguiBridge::PrepareRenderables(int count) { while (renderables_.size() < count) { mjrRenderableParams params; mjr_defaultRenderableParams(¶ms); - params.shading_model = mjSHADING_MODEL_UX; params.cast_shadows = false; params.receive_shadows = false; params.blend_order = static_cast(renderables_.size() + 1); diff --git a/src/experimental/filament/compat/scene_geom_util.cc b/src/experimental/filament/compat/scene_geom_util.cc index d255583a..e66a8630 100644 --- a/src/experimental/filament/compat/scene_geom_util.cc +++ b/src/experimental/filament/compat/scene_geom_util.cc @@ -183,20 +183,25 @@ static void UpdateGeomMaterial(mjrRenderable* renderable, const mjvGeom& geom, const mjModel* model = model_objs->GetModel(); const bool use_segid_color = scene->flags[mjRND_IDCOLOR]; - mjrMaterialParams params; - mjr_defaultMaterialParams(¶ms); - params.color[0] = geom.rgba[0]; - params.color[1] = geom.rgba[1]; - params.color[2] = geom.rgba[2]; - params.color[3] = geom.rgba[3]; + mjrMaterial material; + mjr_defaultMaterial(&material); + + if (geom.category == mjCAT_DECOR) { + material.decor_ux = true; + } + + material.color[0] = geom.rgba[0]; + material.color[1] = geom.rgba[1]; + material.color[2] = geom.rgba[2]; + material.color[3] = geom.rgba[3]; if (geom.type == mjGEOM_PLANE) { if (IsBehind(headpos, geom.pos, geom.mat)) { - params.color[3] *= 0.3; + material.color[3] *= 0.3; mjrf_setRenderableReceiveShadows(renderable, false); - params.reflective = false; + material.reflective = false; } else { mjrf_setRenderableReceiveShadows(renderable, true); - params.reflective = geom.reflectance > 0 && params.color[3] == 1.0f; + material.reflective = geom.reflectance > 0 && material.color[3] == 1.0f; } } mjrf_setRenderableLayerMask(renderable, geom.category); @@ -207,30 +212,28 @@ static void UpdateGeomMaterial(mjrRenderable* renderable, const mjvGeom& geom, mjrf_setRenderableWireframe(renderable, scene->flags[mjRND_WIREFRAME]); } - mjrMaterialTextures textures; - mjr_defaultMaterialTextures(&textures); if (geom.matid >= 0) { - textures.color = model_objs->GetTexture(geom.matid, mjTEXROLE_RGB); - textures.normal = model_objs->GetTexture(geom.matid, mjTEXROLE_NORMAL); - textures.emissive = model_objs->GetTexture(geom.matid, mjTEXROLE_EMISSIVE); - textures.orm = model_objs->GetTexture(geom.matid, mjTEXROLE_ORM); - textures.metallic = model_objs->GetTexture(geom.matid, mjTEXROLE_METALLIC); - textures.roughness = + material.color_texture = model_objs->GetTexture(geom.matid, mjTEXROLE_RGB); + material.normal_texture = + model_objs->GetTexture(geom.matid, mjTEXROLE_NORMAL); + material.emissive_texture = + model_objs->GetTexture(geom.matid, mjTEXROLE_EMISSIVE); + material.orm_texture = model_objs->GetTexture(geom.matid, mjTEXROLE_ORM); + material.metallic_texture = + model_objs->GetTexture(geom.matid, mjTEXROLE_METALLIC); + material.roughness_texture = model_objs->GetTexture(geom.matid, mjTEXROLE_ROUGHNESS); - textures.occlusion = + material.occlusion_texture = model_objs->GetTexture(geom.matid, mjTEXROLE_OCCLUSION); } - params.reflectance = geom.reflectance; - params.emissive = geom.emission; - params.specular = geom.specular; - params.glossiness = geom.shininess; + material.reflectance = geom.reflectance; + material.emissive = geom.emission; + material.specular = geom.specular; + material.glossiness = geom.shininess; if (geom.matid >= 0) { - params.metallic = model->mat_metallic[geom.matid]; - params.roughness = model->mat_roughness[geom.matid]; - params.tex_uniform = model->mat_texuniform[geom.matid]; - params.tex_repeat[0] = model->mat_texrepeat[(geom.matid * 2) + 0]; - params.tex_repeat[1] = model->mat_texrepeat[(geom.matid * 2) + 1]; + material.metallic = model->mat_metallic[geom.matid]; + material.roughness = model->mat_roughness[geom.matid]; } if (geom.segid >= 0) { @@ -246,9 +249,9 @@ static void UpdateGeomMaterial(mjrRenderable* renderable, const mjvGeom& geom, const uint8_t red = (segmentation_color >> 0) & 0xff; const uint8_t green = (segmentation_color >> 8) & 0xff; const uint8_t blue = (segmentation_color >> 16) & 0xff; - params.segmentation_color[0] = static_cast(red) / 255.0f; - params.segmentation_color[1] = static_cast(green) / 255.0f; - params.segmentation_color[2] = static_cast(blue) / 255.0f; + material.segmentation_color[0] = static_cast(red) / 255.0f; + material.segmentation_color[1] = static_cast(green) / 255.0f; + material.segmentation_color[2] = static_cast(blue) / 255.0f; } // UvScale only applies to objects that don't have explicit UV coordinates @@ -258,28 +261,33 @@ static void UpdateGeomMaterial(mjrRenderable* renderable, const mjvGeom& geom, // The material's `texuniform` and `texrepeat` parameters allow us to scale // the programmatic UVs. - if (textures.color) { - if (mjrf_getSamplerType(textures.color) == mjTEXTURE_2D) { + if (material.color_texture) { + const bool tex_uniform = model->mat_texuniform[geom.matid]; + if (mjrf_getSamplerType(material.color_texture) == mjTEXTURE_2D) { // For 2D textures, `tex_repeat` specifies how many times the texture // image is repeated. The `tex_uniform` flag determines if the repetition // is applied at in object space (false) or in world space (true). - params.uv_scale[0] = params.tex_repeat[0]; - params.uv_scale[1] = params.tex_repeat[1]; + float tex_repeat[2]; + tex_repeat[0] = model->mat_texrepeat[(geom.matid * 2) + 0]; + tex_repeat[1] = model->mat_texrepeat[(geom.matid * 2) + 1]; + material.uv_scale[0] = tex_repeat[0]; + material.uv_scale[1] = tex_repeat[1]; if (geom.dataid >= 0 && geom.type != mjGEOM_PLANE) { if (geom.size[0] > mjMINVAL) { - params.uv_scale[0] /= geom.size[0]; + material.uv_scale[0] /= geom.size[0]; } if (geom.size[1] > mjMINVAL) { - params.uv_scale[1] /= geom.size[1]; + material.uv_scale[1] /= geom.size[1]; } } - if (params.tex_uniform) { + + if (tex_uniform) { if (geom.size[0] > 0) { - params.uv_scale[0] *= geom.size[0]; + material.uv_scale[0] *= geom.size[0]; } if (geom.size[1] > 0) { - params.uv_scale[1] *= geom.size[1]; + material.uv_scale[1] *= geom.size[1]; } } const bool is_infinite_plane = @@ -289,11 +297,11 @@ static void UpdateGeomMaterial(mjrRenderable* renderable, const mjvGeom& geom, // re-centering in engine_vis_visualize.c. const float plane_scale = static_cast(mjMAXPLANEGRID) / 2.0f; const float tile_size_x = - GetPlaneTileSize(model, geom.matid, params.tex_repeat[0]); + GetPlaneTileSize(model, geom.matid, tex_repeat[0]); const float tile_size_y = - GetPlaneTileSize(model, geom.matid, params.tex_repeat[1]); - params.uv_scale[0] = 2.0f * plane_scale / tile_size_x; - params.uv_scale[1] = 2.0f * plane_scale / tile_size_y; + GetPlaneTileSize(model, geom.matid, tex_repeat[1]); + material.uv_scale[0] = 2.0f * plane_scale / tile_size_x; + material.uv_scale[1] = 2.0f * plane_scale / tile_size_y; } // We want to do the equivalent of: @@ -301,42 +309,34 @@ static void UpdateGeomMaterial(mjrRenderable* renderable, const mjvGeom& geom, // mjr_setf4(tplane, 0, -0.5 * scl.y, 0, -0.5); // glTexGenfv(GL_S, GL_OBJECT_PLANE, splane); // glTexGenfv(GL_T, GL_OBJECT_PLANE, tplane); - params.uv_scale[0] = 0.5f * params.uv_scale[0]; - params.uv_scale[1] = -0.5f * params.uv_scale[1]; - params.uv_offset[0] = -0.5f; - params.uv_offset[1] = -0.5f; + material.uv_scale[0] = 0.5f * material.uv_scale[0]; + material.uv_scale[1] = -0.5f * material.uv_scale[1]; + material.uv_offset[0] = -0.5f; + material.uv_offset[1] = -0.5f; } else { // For cube maps, if `tex_uniform` is true, then scale the texture so that // it covers a 1x1 area of world space rather than the area of the object. - if (params.tex_uniform) { - params.uv_scale[0] = 1.0f / (geom.size[0] ? geom.size[0] : 1.0f); - params.uv_scale[1] = 1.0f / (geom.size[1] ? geom.size[1] : 1.0f); - params.uv_scale[2] = 1.0f / (geom.size[2] ? geom.size[2] : 1.0f); + if (tex_uniform) { + material.uv_scale[0] = 1.0f / (geom.size[0] ? geom.size[0] : 1.0f); + material.uv_scale[1] = 1.0f / (geom.size[1] ? geom.size[1] : 1.0f); + material.uv_scale[2] = 1.0f / (geom.size[2] ? geom.size[2] : 1.0f); } } } // Apply material multipliers from the model. - params.emissive *= model_objs->GetEmissiveMultiplier(); - params.specular *= model_objs->GetSpecularMultiplier(); - params.glossiness *= model_objs->GetShininessMultiplier(); + material.emissive *= model_objs->GetEmissiveMultiplier(); + material.specular *= model_objs->GetSpecularMultiplier(); + material.glossiness *= model_objs->GetShininessMultiplier(); - mjrf_setRenderableMaterial(renderable, ¶ms, &textures); + mjrf_setRenderableMaterial(renderable, &material); } UniquePtr CreateGeomRenderable( const mjvGeom& geom, const mjvScene* scene, mjrfContext* ctx, ModelObjects* model_objs, const float headpos[3]) { - mjrShadingModel shading_model = mjSHADING_MODEL_SCENE_OBJECT; - if (geom.type == mjGEOM_LINE || geom.type == mjGEOM_LINEBOX) { - shading_model = mjSHADING_MODEL_DECOR_LINES; - } else if (geom.category == mjCAT_DECOR) { - shading_model = mjSHADING_MODEL_DECOR; - } - mjrRenderableParams params; mjr_defaultRenderableParams(¶ms); - params.shading_model = shading_model; auto renderable = CreateRenderable(ctx, params); PrepareGeomMeshes(renderable.get(), geom, scene, model_objs); UpdateGeomMaterial(renderable.get(), geom, scene, model_objs, headpos); diff --git a/src/experimental/filament/filament/material.cc b/src/experimental/filament/filament/material.cc index 672f7a40..5e074d68 100644 --- a/src/experimental/filament/filament/material.cc +++ b/src/experimental/filament/filament/material.cc @@ -28,48 +28,47 @@ namespace mujoco { void UpdateMaterialInstance(filament::MaterialInstance* instance, - const mjrMaterialParams& params, - const mjrMaterialTextures& textures, + const mjrMaterial& material, ObjectManager* object_mgr) { - if (params.scissor[2] != 0 && params.scissor[3] != 0) { - instance->setScissor(params.scissor[0], params.scissor[1], - params.scissor[2], params.scissor[3]); + if (material.scissor[2] != 0 && material.scissor[3] != 0) { + instance->setScissor(material.scissor[0], material.scissor[1], + material.scissor[2], material.scissor[3]); } - const filament::Material* material = instance->getMaterial(); - if (material->hasParameter("BaseColorFactor")) { + const filament::Material* fmaterial = instance->getMaterial(); + if (fmaterial->hasParameter("BaseColorFactor")) { instance->setParameter("BaseColorFactor", filament::RgbaType::sRGB, - ReadFloat4(params.color)); + ReadFloat4(material.color)); } - if (material->hasParameter("SegmentationColor")) { + if (fmaterial->hasParameter("SegmentationColor")) { instance->setParameter("SegmentationColor", filament::RgbaType::LINEAR, - ReadFloat4(params.segmentation_color)); + ReadFloat4(material.segmentation_color)); } - if (material->hasParameter("EmissiveFactor")) { - instance->setParameter("EmissiveFactor", params.emissive); + if (fmaterial->hasParameter("EmissiveFactor")) { + instance->setParameter("EmissiveFactor", material.emissive); } - if (material->hasParameter("SpecularFactor")) { - instance->setParameter("SpecularFactor", params.specular); + if (fmaterial->hasParameter("SpecularFactor")) { + instance->setParameter("SpecularFactor", material.specular); } - if (material->hasParameter("GlossinessFactor")) { - instance->setParameter("GlossinessFactor", params.glossiness); + if (fmaterial->hasParameter("GlossinessFactor")) { + instance->setParameter("GlossinessFactor", material.glossiness); } - if (material->hasParameter("MetallicFactor")) { + if (fmaterial->hasParameter("MetallicFactor")) { instance->setParameter("MetallicFactor", - params.metallic >= 0 ? params.metallic : 1.0f); + material.metallic >= 0 ? material.metallic : 1.0f); } - if (material->hasParameter("RoughnessFactor")) { + if (fmaterial->hasParameter("RoughnessFactor")) { instance->setParameter("RoughnessFactor", - params.roughness >= 0 ? params.roughness : 1.0f); + material.roughness >= 0 ? material.roughness : 1.0f); } - if (material->hasParameter("UvScale")) { - instance->setParameter("UvScale", ReadFloat3(params.uv_scale)); + if (fmaterial->hasParameter("UvScale")) { + instance->setParameter("UvScale", ReadFloat3(material.uv_scale)); } - if (material->hasParameter("UvOffset")) { - instance->setParameter("UvOffset", ReadFloat3(params.uv_offset)); + if (fmaterial->hasParameter("UvOffset")) { + instance->setParameter("UvOffset", ReadFloat3(material.uv_offset)); } - if (material->hasParameter("Reflectance")) { - instance->setParameter("Reflectance", params.reflectance); + if (fmaterial->hasParameter("Reflectance")) { + instance->setParameter("Reflectance", material.reflectance); } // All textures use the same default sampler. @@ -83,7 +82,7 @@ void UpdateMaterialInstance(filament::MaterialInstance* instance, auto TrySetTexture = [&](const char* name, const mjrTexture* texture, mjtTextureRole role) { - if (material->hasParameter(name)) { + if (fmaterial->hasParameter(name)) { if (texture != nullptr) { instance->setParameter( name, Texture::downcast(texture)->GetFilamentTexture(), sampler); @@ -94,14 +93,14 @@ void UpdateMaterialInstance(filament::MaterialInstance* instance, } }; - TrySetTexture("BaseColor", textures.color, mjTEXROLE_RGB); - TrySetTexture("Normal", textures.normal, mjTEXROLE_NORMAL); - TrySetTexture("Metallic", textures.metallic, mjTEXROLE_METALLIC); - TrySetTexture("Roughness", textures.roughness, mjTEXROLE_ROUGHNESS); - TrySetTexture("Occlusion", textures.occlusion, mjTEXROLE_OCCLUSION); - TrySetTexture("ORM", textures.orm, mjTEXROLE_ORM); - TrySetTexture("Emissive", textures.emissive, mjTEXROLE_EMISSIVE); - TrySetTexture("Reflection", textures.reflection, mjTEXROLE_USER); + TrySetTexture("BaseColor", material.color_texture, mjTEXROLE_RGB); + TrySetTexture("Normal", material.normal_texture, mjTEXROLE_NORMAL); + TrySetTexture("Metallic", material.metallic_texture, mjTEXROLE_METALLIC); + TrySetTexture("Roughness", material.roughness_texture, mjTEXROLE_ROUGHNESS); + TrySetTexture("Occlusion", material.occlusion_texture, mjTEXROLE_OCCLUSION); + TrySetTexture("ORM", material.orm_texture, mjTEXROLE_ORM); + TrySetTexture("Emissive", material.emissive_texture, mjTEXROLE_EMISSIVE); + TrySetTexture("Reflection", material.reflection_texture, mjTEXROLE_USER); } } // namespace mujoco diff --git a/src/experimental/filament/filament/material.h b/src/experimental/filament/filament/material.h index abc0f9a1..8e6ac65d 100644 --- a/src/experimental/filament/filament/material.h +++ b/src/experimental/filament/filament/material.h @@ -25,8 +25,7 @@ namespace mujoco { // Updates the material instances based on the currently set parameters and // textures. void UpdateMaterialInstance(filament::MaterialInstance* instance, - const mjrMaterialParams& params, - const mjrMaterialTextures& textures, + const mjrMaterial& material, ObjectManager* object_mgr); } // namespace mujoco diff --git a/src/experimental/filament/filament/object_manager.cc b/src/experimental/filament/filament/object_manager.cc index 487f95fd..1816b627 100644 --- a/src/experimental/filament/filament/object_manager.cc +++ b/src/experimental/filament/filament/object_manager.cc @@ -68,7 +68,6 @@ ObjectManager::ObjectManager(filament::Engine* engine) materials_[kPhongCubeFade] = LoadMaterial(engine, "phong_cube_fade.filamat"); materials_[kPhongCubeReflect] = LoadMaterial(engine, "phong_cube_reflect.filamat"); materials_[kUnlitSegmentation] = LoadMaterial(engine, "unlit_segmentation.filamat"); - materials_[kUnlitLine] = LoadMaterial(engine, "unlit_line.filamat"); materials_[kUnlitDecor] = LoadMaterial(engine, "unlit_decor.filamat"); materials_[kUnlitDepth] = LoadMaterial(engine, "unlit_depth.filamat"); materials_[kUnlitUi] = LoadMaterial(engine, "unlit_ui.filamat"); diff --git a/src/experimental/filament/filament/object_manager.h b/src/experimental/filament/filament/object_manager.h index 4365029b..00fc006c 100644 --- a/src/experimental/filament/filament/object_manager.h +++ b/src/experimental/filament/filament/object_manager.h @@ -56,7 +56,6 @@ class ObjectManager { kUnlitSegmentation, kUnlitDecor, kUnlitDepth, - kUnlitLine, kUnlitUi, kNumMaterials, }; diff --git a/src/experimental/filament/filament/renderable.cc b/src/experimental/filament/filament/renderable.cc index ad729b46..14655e0e 100644 --- a/src/experimental/filament/filament/renderable.cc +++ b/src/experimental/filament/filament/renderable.cc @@ -51,8 +51,7 @@ static constexpr float kArrowHeadSize = 1.75f; Renderable::Renderable(FilamentContext* ctx, const mjrRenderableParams& params) : object_mgr_(ctx->GetObjectManager()), params_(params) { - mjr_defaultMaterialParams(&material_params_); - mjr_defaultMaterialTextures(&material_textures_); + mjr_defaultMaterial(&material_); } Renderable::~Renderable() noexcept { @@ -202,21 +201,18 @@ void Renderable::RemoveFromScene(filament::Scene* scene) { assigned_scene_ = nullptr; } -void Renderable::UpdateMaterial(const mjrMaterialParams& params, - const mjrMaterialTextures& textures) { - material_params_ = params; - material_textures_ = textures; +void Renderable::UpdateMaterial(const mjrMaterial& material) { + material_ = material; AssignMaterial(mjDRAW_MODE_COLOR, GetColorMaterialType()); - if (params_.shading_model == mjSHADING_MODEL_SCENE_OBJECT) { + if (!material_.decor_ux) { AssignMaterial(mjDRAW_MODE_DEPTH, ObjectManager::kUnlitDepth); AssignMaterial(mjDRAW_MODE_SEGMENTATION, ObjectManager::kUnlitSegmentation); } for (int i = 0; i < mjNUM_DRAW_MODES; ++i) { if (instances_[i]) { - UpdateMaterialInstance(instances_[i], material_params_, - material_textures_, object_mgr_); + UpdateMaterialInstance(instances_[i], material_, object_mgr_); } } SetDrawMode(draw_mode_); @@ -241,17 +237,13 @@ void Renderable::AssignMaterial(mjrDrawMode mode, } } -const mjrMaterialParams& Renderable::GetMaterialParams() const { - return material_params_; -} - -const mjrMaterialTextures& Renderable::GetMaterialTextures() const { - return material_textures_; +const mjrMaterial& Renderable::GetMaterial() const { + return material_; } void Renderable::SetDrawMode(mjrDrawMode mode) { // Only SceneObjects support non-color draw modes. - if (params_.shading_model != mjSHADING_MODEL_SCENE_OBJECT) { + if (!material_.decor_ux) { mode = mjDRAW_MODE_COLOR; } @@ -347,21 +339,21 @@ void Renderable::SetWireframe(bool wireframe) { } ObjectManager::MaterialType Renderable::GetColorMaterialType() const { - if (params_.shading_model == mjSHADING_MODEL_DECOR_LINES) { - return ObjectManager::kUnlitLine; - } else if (params_.shading_model == mjSHADING_MODEL_DECOR) { - return ObjectManager::kUnlitDecor; - } else if (params_.shading_model == mjSHADING_MODEL_UX) { - return ObjectManager::kUnlitUi; - } else if (material_textures_.orm) { + if (material_.decor_ux) { + if (material_.color_texture) { + return ObjectManager::kUnlitUi; + } else { + return ObjectManager::kUnlitDecor; + } + } else if (material_.orm_texture) { return ObjectManager::kPbrPacked; - } else if (material_textures_.metallic) { + } else if (material_.metallic_texture) { return ObjectManager::kPbr; - } else if (material_textures_.roughness) { + } else if (material_.roughness_texture) { return ObjectManager::kPbr; - } else if (material_params_.metallic >= 0) { + } else if (material_.metallic >= 0) { return ObjectManager::kPbr; - } else if (material_params_.roughness >= 0) { + } else if (material_.roughness >= 0) { return ObjectManager::kPbr; } @@ -370,7 +362,7 @@ ObjectManager::MaterialType Renderable::GetColorMaterialType() const { // geometry) and `mesh_texcoordadr` stores the address of the mesh uvs if // it has them. bool has_texcoords = false; - const Texture* color_texture = Texture::downcast(material_textures_.color); + const Texture* color_texture = Texture::downcast(material_.color_texture); if (!parts_.empty()) { const auto attribs = parts_[0].mesh->GetVertexAttributes(); auto it = std::find(attribs.begin(), attribs.end(), @@ -379,33 +371,33 @@ ObjectManager::MaterialType Renderable::GetColorMaterialType() const { } if (color_texture == nullptr) { - if (material_params_.color[3] < 1.0f) { + if (material_.color[3] < 1.0f) { return ObjectManager::kPhongColorFade; - } else if (material_params_.reflective) { + } else if (material_.reflective) { return ObjectManager::kPhongColorReflect; } else { return ObjectManager::kPhongColor; } } else if (color_texture->GetSamplerType() == mjTEXTURE_CUBE) { - if (material_params_.color[3] < 1.0f) { + if (material_.color[3] < 1.0f) { return ObjectManager::kPhongCubeFade; - } else if (material_params_.reflective) { + } else if (material_.reflective) { return ObjectManager::kPhongCubeReflect; } else { return ObjectManager::kPhongCube; } } else if (has_texcoords) { - if (material_params_.color[3] < 1.0f) { + if (material_.color[3] < 1.0f) { return ObjectManager::kPhong2dUvFade; - } else if (material_params_.reflective) { + } else if (material_.reflective) { return ObjectManager::kPhong2dUvReflect; } else { return ObjectManager::kPhong2dUv; } } else { - if (material_params_.color[3] < 1.0f) { + if (material_.color[3] < 1.0f) { return ObjectManager::kPhong2dFade; - } else if (material_params_.reflective) { + } else if (material_.reflective) { return ObjectManager::kPhong2dReflect; } else { return ObjectManager::kPhong2d; diff --git a/src/experimental/filament/filament/renderable.h b/src/experimental/filament/filament/renderable.h index 58310d98..6e4f32c1 100644 --- a/src/experimental/filament/filament/renderable.h +++ b/src/experimental/filament/filament/renderable.h @@ -37,15 +37,6 @@ namespace mujoco { // The mesh describes the surface geometry of the object and the material // describes how that surface interacts with light (i.e. the color of each point // on the surface). -// -// Defining the mesh is easy; just call SetMesh. -// -// Defining a Material happens in two stages. First, the user specifies the -// ShadingModel to use for Rendering. This describes the overall intent of -// how the Renderable will appear (e.g. lit, unlit, wireframe, etc.). Next, -// the user specifies the MaterialParams and MaterialTextures to use with the -// ShadingModel. Its these properties that ultimately define the actual material -// of the Renderable. class Renderable : public mjrRenderable { public: Renderable(FilamentContext* ctx, const mjrRenderableParams& params); @@ -98,19 +89,14 @@ class Renderable : public mjrRenderable { // Removes the renderable from the given filament Scene. void RemoveFromScene(filament::Scene* scene); - // Further defines the material of the renderable. Only applies to renderables - // with a SceneObject shading model. + // Further defines the material of the renderable. void SetDrawMode(mjrDrawMode mode); // Updates the parameters for the material. - void UpdateMaterial(const mjrMaterialParams& params, - const mjrMaterialTextures& textures); + void UpdateMaterial(const mjrMaterial& material); // Returns the current material parameters. - const mjrMaterialParams& GetMaterialParams() const; - - // Returns the current material textures. - const mjrMaterialTextures& GetMaterialTextures() const; + const mjrMaterial& GetMaterial() const; // Returns the filament Engine managing the renderables. filament::Engine* GetEngine(); @@ -143,8 +129,7 @@ class Renderable : public mjrRenderable { ObjectManager* object_mgr_; mjrRenderableParams params_; filament::MaterialInstance* instances_[mjNUM_DRAW_MODES] = {nullptr}; - mjrMaterialParams material_params_; - mjrMaterialTextures material_textures_; + mjrMaterial material_; mjrDrawMode draw_mode_ = mjDRAW_MODE_COLOR; filament::Scene* assigned_scene_ = nullptr; std::vector parts_; diff --git a/src/experimental/filament/filament/scene_view.cc b/src/experimental/filament/filament/scene_view.cc index 3a217c59..3622f0ab 100644 --- a/src/experimental/filament/filament/scene_view.cc +++ b/src/experimental/filament/filament/scene_view.cc @@ -208,7 +208,7 @@ void SceneView::RemoveFromScene(Light* light) { void SceneView::AddToScene(Renderable* renderable) { if (renderables_.insert(renderable).second) { renderable->AddToScene(scene_); - if (renderable->GetMaterialParams().reflective) { + if (renderable->GetMaterial().reflective) { AddReflectiveRenderable(renderable); } } @@ -317,9 +317,9 @@ void SceneView::AddReflectiveRenderable(Renderable* renderable) { target->Prepare(viewport.width, viewport.height); if (reflections_enabled_) { - mjrMaterialTextures textures = renderable->GetMaterialTextures(); - textures.reflection = target->GetColorTexture(); - renderable->UpdateMaterial(renderable->GetMaterialParams(), textures); + mjrMaterial material = renderable->GetMaterial(); + material.reflection_texture = target->GetColorTexture(); + renderable->UpdateMaterial(material); } } @@ -349,18 +349,18 @@ void SceneView::EnableReflections() { for (int i = 0; i < reflectives_.size(); ++i) { Renderable* renderable = reflectives_[i]; - mjrMaterialTextures textures = renderable->GetMaterialTextures(); - textures.reflection = reflect_targets_[i]->GetColorTexture(); - renderable->UpdateMaterial(renderable->GetMaterialParams(), textures); + mjrMaterial material = renderable->GetMaterial(); + material.reflection_texture = reflect_targets_[i]->GetColorTexture(); + renderable->UpdateMaterial(material); } } void SceneView::DisableReflections() { reflections_enabled_ = false; for (Renderable* renderable : reflectives_) { - mjrMaterialTextures textures = renderable->GetMaterialTextures(); - textures.reflection = nullptr; - renderable->UpdateMaterial(renderable->GetMaterialParams(), textures); + mjrMaterial material = renderable->GetMaterial(); + material.reflection_texture = nullptr; + renderable->UpdateMaterial(material); } } diff --git a/src/experimental/filament/render_context_filament.cc b/src/experimental/filament/render_context_filament.cc index c58a3b2d..b923ed16 100644 --- a/src/experimental/filament/render_context_filament.cc +++ b/src/experimental/filament/render_context_filament.cc @@ -69,10 +69,11 @@ void mjr_defaultTextureConfig(mjrTextureConfig* config) { } void mjr_defaultMeshData(mjrMeshData* data) { - std::memset(data, 0, sizeof(mjrMeshData)); + memset(data, 0, sizeof(mjrMeshData)); } void mjr_defaultSceneParams(mjrSceneParams* params) { + memset(params, 0, sizeof(mjrSceneParams)); params->enable_post_processing = true; params->enable_reflections = true; params->enable_shadows = true; @@ -81,6 +82,7 @@ void mjr_defaultSceneParams(mjrSceneParams* params) { } void mjr_defaultLightParams(mjrLightParams* params) { + memset(params, 0, sizeof(mjrLightParams)); params->type = mjLIGHT_POINT; params->texture = nullptr; params->color[0] = 0; @@ -95,35 +97,20 @@ void mjr_defaultLightParams(mjrLightParams* params) { params->vsm_blur_width = 0.0f; } -void mjr_defaultMaterialTextures(mjrMaterialTextures* textures) { - textures->color = nullptr; - textures->normal = nullptr; - textures->metallic = nullptr; - textures->roughness = nullptr; - textures->occlusion = nullptr; - textures->orm = nullptr; - textures->emissive = nullptr; - textures->reflection = nullptr; -} - -void mjr_defaultMaterialParams(mjrMaterialParams* params) { - setf(params->color, {1.f, 1.f, 1.f, 1.f}); - setf(params->segmentation_color, {1, 1, 1, 1}); - setf(params->uv_scale, {1, 1, 1}); - setf(params->uv_offset, {0, 0, 0}); - setf(params->scissor, {0, 0, 0, 0}); - params->emissive = -1.0f; - params->specular = -1.0f; - params->glossiness = -1.0f; - params->metallic = -1.0f; - params->roughness = -1.0f; - params->reflectance = 0.0f; - params->tex_uniform = false; - params->reflective = false; +void mjr_defaultMaterial(mjrMaterial* material) { + memset(material, 0, sizeof(mjrMaterial)); + setf(material->color, {1.f, 1.f, 1.f, 1.f}); + setf(material->segmentation_color, {1, 1, 1, 1}); + setf(material->uv_scale, {1, 1, 1}); + material->emissive = -1.0f; + material->specular = -1.0f; + material->glossiness = -1.0f; + material->metallic = -1.0f; + material->roughness = -1.0f; } void mjr_defaultRenderableParams(mjrRenderableParams* params) { - params->shading_model = mjSHADING_MODEL_SCENE_OBJECT; + memset(params, 0, sizeof(mjrRenderableParams)); params->cast_shadows = true; params->receive_shadows = true; params->layer_mask = 0x01; @@ -265,9 +252,8 @@ void mjrf_setRenderableGeomMesh(mjrRenderable* renderable, mjtGeom type, } void mjrf_setRenderableMaterial(mjrRenderable* renderable, - const mjrMaterialParams* params, - const mjrMaterialTextures* textures) { - mujoco::Renderable::downcast(renderable)->UpdateMaterial(*params, *textures); + const mjrMaterial* material) { + mujoco::Renderable::downcast(renderable)->UpdateMaterial(*material); } void mjrf_setRenderableTransform(mjrRenderable* renderable, diff --git a/src/experimental/filament/render_context_filament.h b/src/experimental/filament/render_context_filament.h index b960244d..85ec2856 100644 --- a/src/experimental/filament/render_context_filament.h +++ b/src/experimental/filament/render_context_filament.h @@ -53,19 +53,6 @@ typedef enum mjrDrawMode_ { enum { mjNUM_DRAW_MODES = 3 }; -// The shading model (material) for a Renderable. -typedef enum mjrShadingModel_ { - // For renderables in the main 3D scene. - mjSHADING_MODEL_SCENE_OBJECT = 0, - // For UX renderables. - mjSHADING_MODEL_UX, - // For decorative elements in a Scene (e.g. contact points, force vectors, - // etc.). These objects will not be affected by lighting. - mjSHADING_MODEL_DECOR, - // As above, but uses a line primitives for drawing. - mjSHADING_MODEL_DECOR_LINES, -} mjrShadingModel; - // The type of data stored in an index buffer. typedef enum mjrIndexType_ { mjINDEX_TYPE_U16 = 0, @@ -124,41 +111,74 @@ typedef mjtColorSpace mjrColorSpace; typedef mjtLightType mjrLightType; typedef mjvGLCamera mjrCamera; -// The textures that can be assigned to the drawable's material. -struct mjrMaterialTextures { - const mjrTexture* color; - const mjrTexture* normal; - const mjrTexture* metallic; - const mjrTexture* roughness; - const mjrTexture* occlusion; - const mjrTexture* orm; - const mjrTexture* emissive; - const mjrTexture* reflection; -}; - -// Initializes the mjrMaterialTextures to default values. -void mjr_defaultMaterialTextures(mjrMaterialTextures* textures); - -// The parameters that can be applied to the drawable's material. -struct mjrMaterialParams { +// The material to be applied to a renderable. +struct mjrMaterial { + // The color of the object. Defaults to white. float color[4]; + + // The color to use for segmentation rendering. Defaults to white. float segmentation_color[4]; - float tex_repeat[2]; + + // Applies an addition scale to the UV coordinates of the object. Defaults to + // (1, 1, 1). float uv_scale[3]; + + // Applies an offset to the UV coordinates of the object. Defaults to (0, 0, + // 0). float uv_offset[3]; + + // Applies a scissor test to the object. float scissor[4]; - float specular; - float glossiness; + + // Factors for PBR metallic-roughness materials. float metallic; float roughness; + + // Factors for (non-PBR) specular-glossiness materials. + float specular; + float glossiness; + + // The emissive (glow) factor of the object. float emissive; - float reflectance; - mjtByte tex_uniform; + + // Whether or not the object is a reflective surface. Only applies to planes. mjtByte reflective; + // The blend factor to use for reflective surfaces. A value of 1.0 means that + // the surface is fully reflective (i.e. a mirror). + float reflectance; + + // If true, does not apply any lighting to the object. (Assumes the object is + // used for UX or decorative elements like contact forces and labels.) + mjtByte decor_ux; + + // The texture containing the base color of the object. + const mjrTexture* color_texture; + + // The normal map of the object. + const mjrTexture* normal_texture; + + // The metallic map of the object. + const mjrTexture* metallic_texture; + + // The roughness map of the object. + const mjrTexture* roughness_texture; + + // The occlusion map of the object. + const mjrTexture* occlusion_texture; + + // A texture containing the occlusion, roughness, and metallic maps packed + // into the R, G, B channels, respectively. + const mjrTexture* orm_texture; + + // An emissive texture for the object. + const mjrTexture* emissive_texture; + + // The reflection texture to use for the object. For internal use only. + const mjrTexture* reflection_texture; }; -// Initializes the mjrMaterialParams to default values. -void mjr_defaultMaterialParams(mjrMaterialParams* params); +// Initializes the mjrMaterial to default values. +void mjr_defaultMaterial(mjrMaterial* material); // The binary contents of a texture. struct mjrTextureData { @@ -205,8 +225,6 @@ void mjr_defaultTextureConfig(mjrTextureConfig* config); // Configuration parameters for a Renderable. struct mjrRenderableParams { - // The shading model to use for the Renderable. - mjrShadingModel shading_model; // Whether or not the Renderable casts shadows. mjtByte cast_shadows; // Whether or not the Renderable receives shadows. @@ -516,8 +534,7 @@ void mjrf_setRenderableGeomMesh(mjrRenderable* renderable, mjtGeom type, // Sets the material properties and textures of the renderable. void mjrf_setRenderableMaterial(mjrRenderable* renderable, - const mjrMaterialParams* params, - const mjrMaterialTextures* textures); + const mjrMaterial* material); // Sets the transform (position, rotation, and size) of the renderable. void mjrf_setRenderableTransform(mjrRenderable* renderable, diff --git a/src/experimental/studio/index.html b/src/experimental/studio/index.html index ec40e14e..8ab12f48 100644 --- a/src/experimental/studio/index.html +++ b/src/experimental/studio/index.html @@ -89,7 +89,6 @@ "assets/phong_cube_reflect.filamat", "assets/unlit_decor.filamat", "assets/unlit_depth.filamat", - "assets/unlit_line.filamat", "assets/unlit_segmentation.filamat", "assets/unlit_ui.filamat" ];