/*
- * Copyright (c) 2023 Samsung Electronics Co., Ltd.
+ * Copyright (c) 2024 Samsung Electronics Co., Ltd.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
// CLASS HEADER
#include <dali-scene3d/public-api/loader/node-definition.h>
+// EXTERNAL INCLUDES
+#include <dali/integration-api/debug.h>
+
// INTERNAL INCLUDES
+#include <dali-scene3d/internal/light/light-impl.h>
#include <dali-scene3d/internal/model-components/material-impl.h>
+#include <dali-scene3d/internal/model-components/model-node-impl.h>
#include <dali-scene3d/internal/model-components/model-primitive-impl.h>
#include <dali-scene3d/public-api/loader/renderer-state.h>
#include <dali-scene3d/public-api/loader/utils.h>
-#include <dali/integration-api/debug.h>
-
namespace Dali
{
namespace
reflector.Reflect(ResourceType::Material, mMaterialIdx);
}
+// How many shader managers are there?!
void ModelRenderable::OnCreate(const NodeDefinition& nodeDefinition, NodeDefinition::CreateParams& params, ModelNode& node) const
{
DALI_ASSERT_DEBUG(mMeshIdx != INVALID_INDEX);
- Renderable::OnCreate(nodeDefinition, params, node);
+ ShaderOption::HashType shaderOptionHash{0u};
+ if(mShaderIdx == INVALID_INDEX)
+ {
+ ShaderOption option = params.mShaderManager->ProduceShaderOption(params.mResources.mMaterials[mMaterialIdx].first,
+ params.mResources.mMeshes[mMeshIdx].first);
+ shaderOptionHash = option.GetOptionHash();
+ Shader shader = params.mShaderManager->ProduceShader(option);
+
+ static Geometry defaultGeometry = Geometry::New();
+ Renderer renderer = Renderer::New(defaultGeometry, shader);
+
+ RendererState::Apply(params.mShaderManager->GetRendererState(params.mResources.mMaterials[mMaterialIdx].first), renderer);
+ Internal::GetImplementation(node).UpdateShader(params.mShaderManager);
+ node.AddRenderer(renderer);
+ }
+ else
+ {
+ Renderable::OnCreate(nodeDefinition, params, node);
+ }
auto& resources = params.mResources;
auto& mesh = resources.mMeshes[mMeshIdx];
{
mesh.first.mModelPrimitive = ModelPrimitive::New();
- auto primitive = mesh.first.mModelPrimitive;
- GetImplementation(primitive).SetRenderer(renderer);
+ auto& primitive = GetImplementation(mesh.first.mModelPrimitive);
+ primitive.SetRenderer(renderer);
- Index envIndex = resources.mMaterials[mMaterialIdx].first.mEnvironmentIdx;
+ Index envIndex = resources.mMaterials[mMaterialIdx].first.mEnvironmentIdx;
uint32_t specularMipmap = resources.mEnvironmentMaps[envIndex].second.mSpecularMipmapLevels;
- GetImplementation(primitive).SetImageBasedLightTexture(resources.mEnvironmentMaps[envIndex].second.mDiffuse,
- resources.mEnvironmentMaps[envIndex].second.mSpecular,
- resources.mEnvironmentMaps[envIndex].first.mIblIntensity,
- specularMipmap);
+ primitive.SetImageBasedLightTexture(resources.mEnvironmentMaps[envIndex].second.mDiffuse,
+ resources.mEnvironmentMaps[envIndex].second.mSpecular,
+ resources.mEnvironmentMaps[envIndex].first.mIblIntensity,
+ specularMipmap);
bool hasPositions = false;
bool hasNormals = false;
bool hasTangents = false;
mesh.first.RetrieveBlendShapeComponents(hasPositions, hasNormals, hasTangents);
- GetImplementation(primitive).SetBlendShapeOptions(hasPositions, hasNormals, hasTangents);
- GetImplementation(primitive).SetBlendShapeGeometry(mesh.second.blendShapeGeometry);
- GetImplementation(primitive).SetSkinned(mesh.first.IsSkinned());
+ primitive.SetBlendShapeOptions(hasPositions, hasNormals, hasTangents, mesh.first.mBlendShapeVersion);
+ primitive.SetBlendShapeGeometry(mesh.second.blendShapeGeometry);
+ primitive.SetSkinned(mesh.first.IsSkinned(), mesh.first.GetNumberOfJointSets());
+ primitive.SetVertexColor(mesh.first.HasVertexColor());
}
auto shader = renderer.GetShader();
renderer.RegisterProperty("uOcclusionStrength", matDef.mOcclusionStrength);
}
+ renderer.RegisterProperty("uBaseColorTextureTransformAvailable", 0.0f);
+ renderer.RegisterProperty("uNormalTextureTransformAvailable", 0.0f);
+ renderer.RegisterProperty("uNormalRoughnessTextureTransformAvailable", 0.0f);
+ renderer.RegisterProperty("uMetalRoughnessTextureTransformAvailable", 0.0f);
+ renderer.RegisterProperty("uOcclusionTextureTransformAvailable", 0.0f);
+ renderer.RegisterProperty("uEmissiveTextureTransformAvailable", 0.0f);
+
+ renderer.RegisterProperty("uBaseColorTextureTransform", Matrix3::IDENTITY);
+ renderer.RegisterProperty("uNormalRoughnessTextureTransform", Matrix3::IDENTITY);
+ renderer.RegisterProperty("uNormalTextureTransform", Matrix3::IDENTITY);
+ renderer.RegisterProperty("uMetalRoughnessTextureTransform", Matrix3::IDENTITY);
+ renderer.RegisterProperty("uOcclusionTextureTransform", Matrix3::IDENTITY);
+ renderer.RegisterProperty("uEmissiveTextureTransform", Matrix3::IDENTITY);
+
+ auto iTexture = matDef.mTextureStages.begin();
+ auto checkStage = [&](uint32_t flags) {
+ return iTexture != matDef.mTextureStages.end() && MaskMatch(iTexture->mSemantic, flags);
+ };
+
+ if(checkStage(MaterialDefinition::ALBEDO | MaterialDefinition::METALLIC))
+ {
+ renderer.RegisterProperty("uBaseColorTextureTransformAvailable", iTexture->mTexture.mTransform != Matrix3::IDENTITY);
+ renderer.RegisterProperty("uBaseColorTextureTransform", iTexture->mTexture.mTransform);
+ ++iTexture;
+
+ if(checkStage(MaterialDefinition::NORMAL | MaterialDefinition::ROUGHNESS))
+ {
+ renderer.RegisterProperty("uNormalRoughnessTextureTransformAvailable", iTexture->mTexture.mTransform != Matrix3::IDENTITY);
+ renderer.RegisterProperty("uNormalRoughnessTextureTransform", iTexture->mTexture.mTransform);
+ ++iTexture;
+ }
+ }
+ else if(checkStage(MaterialDefinition::ALBEDO))
+ {
+ renderer.RegisterProperty("uBaseColorTextureTransformAvailable", iTexture->mTexture.mTransform != Matrix3::IDENTITY);
+ renderer.RegisterProperty("uBaseColorTextureTransform", iTexture->mTexture.mTransform);
+ ++iTexture;
+ }
+
+ if(checkStage(MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS))
+ {
+ renderer.RegisterProperty("uMetalRoughnessTextureTransformAvailable", iTexture->mTexture.mTransform != Matrix3::IDENTITY);
+ renderer.RegisterProperty("uMetalRoughnessTextureTransform", iTexture->mTexture.mTransform);
+ ++iTexture;
+ }
+
+ if(checkStage(MaterialDefinition::NORMAL))
+ {
+ renderer.RegisterProperty("uNormalTextureTransformAvailable", iTexture->mTexture.mTransform != Matrix3::IDENTITY);
+ renderer.RegisterProperty("uNormalTextureTransform", iTexture->mTexture.mTransform);
+ ++iTexture;
+ }
+
+ if(checkStage(MaterialDefinition::OCCLUSION))
+ {
+ renderer.RegisterProperty("uOcclusionTextureTransformAvailable", iTexture->mTexture.mTransform != Matrix3::IDENTITY);
+ renderer.RegisterProperty("uOcclusionTextureTransform", iTexture->mTexture.mTransform);
+ ++iTexture;
+ }
+
+ if(checkStage(MaterialDefinition::EMISSIVE))
+ {
+ renderer.RegisterProperty("uEmissiveTextureTransformAvailable", iTexture->mTexture.mTransform != Matrix3::IDENTITY);
+ renderer.RegisterProperty("uEmissiveTextureTransform", iTexture->mTexture.mTransform);
+ ++iTexture;
+ }
+
float opaque = matDef.mIsOpaque ? 1.0f : 0.0f;
float mask = matDef.mIsMask ? 1.0f : 0.0f;
float alphaCutoff = matDef.GetAlphaCutoff();
renderer.RegisterProperty("uMask", mask);
renderer.RegisterProperty("uAlphaThreshold", alphaCutoff);
- Index envIndex = matDef.mEnvironmentIdx;
+ Index envIndex = matDef.mEnvironmentIdx;
uint32_t specularMipmap = resources.mEnvironmentMaps[envIndex].second.mSpecularMipmapLevels;
renderer.RegisterProperty(IBL_MAXLOD.data(), static_cast<float>(specularMipmap));
renderer.RegisterProperty(IBL_INTENSITY_STRING.data(), resources.mEnvironmentMaps[envIndex].first.mIblIntensity);
node.SetProperty(Actor::Property::COLOR, mColor);
+ // If user uses customshader, the properties of the shader could not be changed by Material.
+ if(mShaderIdx == INVALID_INDEX)
{
- matDef.mMaterial = Material::New();
- auto material = matDef.mMaterial;
+ matDef.mMaterial = Material::New();
+ auto material = matDef.mMaterial;
uint32_t textureIndexOffset = (mesh.second.blendShapeGeometry) ? 1 : 0;
uint32_t textureIndex = 0;
for(uint32_t i = 0; i < MAX_NUMBER_OF_MATERIAL_TEXTURE; ++i)
Internal::Material::TextureInformation textureInformation;
if(matDef.CheckTextures(SEMANTICS[i]))
{
- textureInformation.mTexture = textures.GetTexture(textureIndex + textureIndexOffset);
- textureInformation.mSampler = textures.GetSampler(textureIndex + textureIndexOffset);
- textureInformation.mUrl = matDef.mTextureStages[textureIndex].mTexture.mDirectoryPath + matDef.mTextureStages[textureIndex].mTexture.mImageUri;
+ textureInformation.mTexture = textures.GetTexture(textureIndex + textureIndexOffset);
+ textureInformation.mSampler = textures.GetSampler(textureIndex + textureIndexOffset);
+ textureInformation.mUrl = matDef.mTextureStages[textureIndex].mTexture.mDirectoryPath + matDef.mTextureStages[textureIndex].mTexture.mImageUri;
+ textureInformation.mTransform = matDef.mTextureStages[textureIndex].mTexture.mTransform;
textureIndex++;
}
textureInformation.mFactor = GetTextureFactor(matDef, SEMANTICS[i]);
material.SetProperty(Scene3D::Material::Property::ALPHA_CUTOFF, matDef.GetAlphaCutoff());
material.SetProperty(Scene3D::Material::Property::DOUBLE_SIDED, matDef.mDoubleSided);
material.SetProperty(Scene3D::Material::Property::IOR, matDef.mIor);
+
+ // This _should_ keep the same shader as generated at the top of the method.
GetImplementation(mesh.first.mModelPrimitive).SetMaterial(material, false);
GetImplementation(material).ResetFlag();
}
- node.AddModelPrimitive(mesh.first.mModelPrimitive);
+ Internal::GetImplementation(node).AddModelPrimitive(mesh.first.mModelPrimitive, shaderOptionHash);
}
void ArcRenderable::OnCreate(const NodeDefinition& nodeDefinition, NodeDefinition::CreateParams& params, ModelNode& node) const