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
This commit is contained in:
Haroon Qureshi
2026-05-07 07:50:30 -07:00
committed by Copybara-Service
parent d5c5a989f2
commit abea65b0be
14 changed files with 228 additions and 285 deletions
-1
View File
@@ -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
)
@@ -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;
}
}
@@ -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(&params);
params.shading_model = mjSHADING_MODEL_UX;
params.cast_shadows = false;
params.receive_shadows = false;
params.blend_order = static_cast<std::uint16_t>(renderables_.size() + 1);
@@ -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(&params);
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<float>(red) / 255.0f;
params.segmentation_color[1] = static_cast<float>(green) / 255.0f;
params.segmentation_color[2] = static_cast<float>(blue) / 255.0f;
material.segmentation_color[0] = static_cast<float>(red) / 255.0f;
material.segmentation_color[1] = static_cast<float>(green) / 255.0f;
material.segmentation_color[2] = static_cast<float>(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<float>(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, &params, &textures);
mjrf_setRenderableMaterial(renderable, &material);
}
UniquePtr<mjrRenderable> 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(&params);
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);
+34 -35
View File
@@ -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
@@ -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
@@ -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");
@@ -56,7 +56,6 @@ class ObjectManager {
kUnlitSegmentation,
kUnlitDecor,
kUnlitDepth,
kUnlitLine,
kUnlitUi,
kNumMaterials,
};
@@ -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;
@@ -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<Part> parts_;
@@ -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);
}
}
@@ -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,
@@ -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,
-1
View File
@@ -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"
];