return (HasSucceeded()) ? mEnvironmentMapData.GetTexture() : Texture();
}
+uint32_t EnvironmentMapLoadTask::GetMipmapLevels()
+{
+ return (HasSucceeded()) ? mEnvironmentMapData.GetMipmapLevels() : 1u;
+}
+
} // namespace Internal
} // namespace Scene3D
*/
Dali::Texture GetLoadedTexture();
+ /**
+ * Retrieves Mipmap levels of loaded Ibl texture
+ * @return mipmap levels of loaded Ibl texture
+ */
+ uint32_t GetMipmapLevels();
+
private:
// Undefined
EnvironmentMapLoadTask(const EnvironmentMapLoadTask& task) = delete;
* @param[in] diffuseTexture cube map texture that can be used as a diffuse IBL source.
* @param[in] specularTexture cube map texture that can be used as a specular IBL source.
* @param[in] scaleFactor scale factor that controls light source intensity in [0.0f, 1.0f]. Default value is 1.0f.
+ * @param[in] specularMipmapLevels mipmap levels of specular texture
*/
- virtual void NotifyImageBasedLightTexture(Dali::Texture diffuseTexture, Dali::Texture specularTexture, float scaleFactor) = 0;
+ virtual void NotifyImageBasedLightTexture(Dali::Texture diffuseTexture, Dali::Texture specularTexture, float scaleFactor, uint32_t specularMipmapLevels) = 0;
/**
* @brief Notifies Scale Factor of Image Based Light is changed by parent SceneView.
mModelPivot(AnchorPoint::CENTER),
mSceneIblScaleFactor(1.0f),
mIblScaleFactor(1.0f),
+ mSceneSpecularMipmapLevels(1u),
+ mSpecularMipmapLevels(1u),
mModelChildrenSensitive(DEFAULT_MODEL_CHILDREN_SENSITIVE),
mModelChildrenFocusable(DEFAULT_MODEL_CHILDREN_FOCUSABLE),
mModelResourceReady(false),
NotifyResourceReady();
}
-void Model::SetImageBasedLightTexture(Dali::Texture diffuseTexture, Dali::Texture specularTexture, float scaleFactor)
-{
- // If input texture is wrong, Model is rendered with SceneView's IBL.
- if(mDiffuseTexture != diffuseTexture || mSpecularTexture != specularTexture)
- {
- mDiffuseTexture = diffuseTexture;
- mSpecularTexture = specularTexture;
- mIblScaleFactor = scaleFactor;
- UpdateImageBasedLightTexture();
- }
-}
-
void Model::SetImageBasedLightScaleFactor(float scaleFactor)
{
mIblScaleFactor = scaleFactor;
void Model::UpdateImageBasedLightTexture()
{
- Dali::Texture currentDiffuseTexture = (mDiffuseTexture && mSpecularTexture) ? mDiffuseTexture : mSceneDiffuseTexture;
- Dali::Texture currentSpecularTexture = (mDiffuseTexture && mSpecularTexture) ? mSpecularTexture : mSceneSpecularTexture;
- float currentIblScaleFactor = (mDiffuseTexture && mSpecularTexture) ? mIblScaleFactor : mSceneIblScaleFactor;
+ Dali::Texture currentDiffuseTexture = (mDiffuseTexture && mSpecularTexture) ? mDiffuseTexture : mSceneDiffuseTexture;
+ Dali::Texture currentSpecularTexture = (mDiffuseTexture && mSpecularTexture) ? mSpecularTexture : mSceneSpecularTexture;
+ float currentIblScaleFactor = (mDiffuseTexture && mSpecularTexture) ? mIblScaleFactor : mSceneIblScaleFactor;
+ uint32_t currentIblSpecularMipmapLevels = (mDiffuseTexture && mSpecularTexture) ? mSpecularMipmapLevels : mSceneSpecularMipmapLevels;
if(!currentDiffuseTexture || !currentSpecularTexture)
{
- currentDiffuseTexture = mDefaultDiffuseTexture;
- currentSpecularTexture = mDefaultSpecularTexture;
- currentIblScaleFactor = Dali::Scene3D::Loader::EnvironmentDefinition::GetDefaultIntensity();
+ currentDiffuseTexture = mDefaultDiffuseTexture;
+ currentSpecularTexture = mDefaultSpecularTexture;
+ currentIblScaleFactor = Dali::Scene3D::Loader::EnvironmentDefinition::GetDefaultIntensity();
+ currentIblSpecularMipmapLevels = 1u;
}
for(auto&& actor : mRenderableActors)
}
}
renderableActor.RegisterProperty(Dali::Scene3D::Loader::NodeDefinition::GetIblScaleFactorUniformName().data(), currentIblScaleFactor);
+ renderableActor.RegisterProperty(Dali::Scene3D::Loader::NodeDefinition::GetIblMaxLodUniformName().data(), static_cast<float>(currentIblSpecularMipmapLevels));
}
}
camera.SetProperty(Actor::Property::SCALE, resultScale);
}
-void Model::NotifyImageBasedLightTexture(Dali::Texture diffuseTexture, Dali::Texture specularTexture, float scaleFactor)
+void Model::NotifyImageBasedLightTexture(Dali::Texture diffuseTexture, Dali::Texture specularTexture, float scaleFactor, uint32_t specularMipmapLevels)
{
if(mSceneDiffuseTexture != diffuseTexture || mSceneSpecularTexture != specularTexture)
{
- mSceneDiffuseTexture = diffuseTexture;
- mSceneSpecularTexture = specularTexture;
- mSceneIblScaleFactor = scaleFactor;
+ mSceneDiffuseTexture = diffuseTexture;
+ mSceneSpecularTexture = specularTexture;
+ mSceneIblScaleFactor = scaleFactor;
+ mSceneSpecularMipmapLevels = specularMipmapLevels;
// If Model IBL is not set, use SceneView's IBL.
if(!mDiffuseTexture || !mSpecularTexture)
{
void Model::OnIblSpecularLoadComplete()
{
- mSpecularTexture = mIblSpecularLoadTask->GetLoadedTexture();
+ mSpecularTexture = mIblSpecularLoadTask->GetLoadedTexture();
+ mSpecularMipmapLevels = mIblSpecularLoadTask->GetMipmapLevels();
ResetResourceTask(mIblSpecularLoadTask);
mIblSpecularResourceReady = true;
if(mIblDiffuseResourceReady && mIblSpecularResourceReady)
void SetImageBasedLightSource(const std::string& diffuseUrl, const std::string& specularUrl, float scaleFactor);
/**
- * @copydoc Model::SetImageBasedLightTexture()
- */
- void SetImageBasedLightTexture(Dali::Texture diffuseTexture, Dali::Texture specularTexture, float scaleFactor);
-
- /**
* @copydoc Model::SetImageBasedLightScaleFactor()
*/
void SetImageBasedLightScaleFactor(float scaleFactor);
/**
* @copydoc Dali::Scene3D::Internal::ImageBasedLightObserver::NotifyImageBasedLightTexture()
*/
- void NotifyImageBasedLightTexture(Dali::Texture diffuseTexture, Dali::Texture specularTexture, float scaleFactor) override;
+ void NotifyImageBasedLightTexture(Dali::Texture diffuseTexture, Dali::Texture specularTexture, float scaleFactor, uint32_t specularMipmapLevels) override;
/**
* @copydoc Dali::Scene3D::Internal::ImageBasedLightObserver::NotifyImageBasedLightScaleFactor()
Vector3 mModelPivot;
float mSceneIblScaleFactor;
float mIblScaleFactor;
+ uint32_t mSceneSpecularMipmapLevels;
+ uint32_t mSpecularMipmapLevels;
bool mModelChildrenSensitive;
bool mModelChildrenFocusable;
bool mModelResourceReady;
{
if(item)
{
- item->NotifyImageBasedLightTexture(mDiffuseTexture, mSpecularTexture, mIblScaleFactor);
+ item->NotifyImageBasedLightTexture(mDiffuseTexture, mSpecularTexture, mIblScaleFactor, mSpecularMipmapLevels);
mItems.push_back(item);
}
}
mDiffuseTexture.Reset();
mSpecularTexture.Reset();
+ mSpecularMipmapLevels = 1u;
NotifyImageBasedLightTextureChange();
}
else
void SceneView::OnIblSpecularLoadComplete()
{
mSpecularTexture = mIblSpecularLoadTask->GetLoadedTexture();
+ mSpecularMipmapLevels = mIblSpecularLoadTask->GetMipmapLevels();
mIblSpecularResourceReady = true;
if(mIblDiffuseResourceReady && mIblSpecularResourceReady)
{
{
if(item)
{
- item->NotifyImageBasedLightTexture(mDiffuseTexture, mSpecularTexture, mIblScaleFactor);
+ item->NotifyImageBasedLightTexture(mDiffuseTexture, mSpecularTexture, mIblScaleFactor, mSpecularMipmapLevels);
}
}
}
Dali::Texture mDiffuseTexture;
Dali::Texture mSpecularTexture;
float mIblScaleFactor{1.0f};
+ uint32_t mSpecularMipmapLevels{1u};
bool mUseFrameBuffer{false};
bool mSkyboxResourceReady{true};
bool mIblDiffuseResourceReady{true};
uniform samplerCube sSpecularEnvSampler;
uniform float uIblIntensity;
uniform vec3 uYDirection;
+uniform float uMaxLOD;
// For Alpha Mode.
uniform lowp float uOpaque;
vec3 FssEss = specularWeight * (k_S * brdf.x + brdf.y);
// Specular Light
- lowp vec3 specularLight = linear(texture(sSpecularEnvSampler, reflection * uYDirection).rgb);
+ // uMaxLOD that means mipmap level of specular texture is used for bluring of reflection of specular following roughness.
+ float lod = perceptualRoughness * (uMaxLOD - 1.0);
+ lowp vec3 specularLight = linear(textureLod(sSpecularEnvSampler, reflection * uYDirection, lod).rgb);
lowp vec3 specular = specularLight * FssEss;
// Diffuse Light
GetImpl(*this).SetImageBasedLightSource(diffuseUrl, specularUrl, scaleFactor);
}
-void Model::SetImageBasedLightTexture(Texture diffuseTexture, Texture specularTexture, float scaleFactor)
-{
- GetImpl(*this).SetImageBasedLightTexture(diffuseTexture, specularTexture, scaleFactor);
-}
-
void Model::SetImageBasedLightScaleFactor(float scaleFactor)
{
GetImpl(*this).SetImageBasedLightScaleFactor(scaleFactor);
void SetImageBasedLightSource(const std::string& diffuseUrl, const std::string& specularUrl, float scaleFactor = 1.0f);
/**
- * @brief Sets Image Based Light Texture.
- *
- * @SINCE_2_1.41
- * @param[in] diffuseTexture cube map texture that can be used as a diffuse IBL source.
- * @param[in] specularTexture cube map texture that can be used as a specular IBL source.
- * @param[in] scaleFactor scale factor that controls light source intensity in [0.0f, 1.0f]. Default value is 1.0f.
- *
- * @note Both of diffuse texture and specular texture should be available. If not, nothing applied.
- */
- void SetImageBasedLightTexture(Texture diffuseTexture, Texture specularTexture, float scaleFactor = 1.0f);
-
- /**
* @brief Sets Scale Factor of Image Based Light Source.
*
* @SINCE_2_1.41
- * @note If SetImageBasedLightSource() or SetImageBasedLightTexture() method is called after this method, scaleFactor is overrided.
+ * @note If SetImageBasedLightSource() method is called after this method, scaleFactor is overrided.
*
* @param[in] scaleFactor scale factor that controls light source intensity in [0.0f, 1.0f].
*/
* @brief Sets Scale Factor of Image Based Light Source.
*
* @SINCE_2_1.41
- * @note If SetImageBasedLightSource() or SetImageBasedLightTexture() method is called after this method, scaleFactor is overriden.
+ * @note If SetImageBasedLightSource() method is called after this method, scaleFactor is overriden.
* @note Default value is 1.0f.
*
* @param[in] scaleFactor scale factor that controls light source intensity in [0.0f, 1.0f].
// This texture should have 6 faces and 6 mipmaps
if(!raw.mSpecular.mPixelData.empty())
{
- textures.mSpecular = raw.mSpecular.GetTexture();
+ textures.mSpecular = raw.mSpecular.GetTexture();
+ textures.mSpecularMipmapLevels = raw.mSpecular.GetMipmapLevels();
}
if(raw.mBrdf)
{
struct Textures
{
- Texture mDiffuse; // irradiance
- Texture mSpecular; // radiance
- Texture mBrdf; // pre-computed brdf
+ Texture mDiffuse; // irradiance
+ Texture mSpecular; // radiance
+ Texture mBrdf; // pre-computed brdf
+ uint32_t mSpecularMipmapLevels{1u};
bool IsLoaded() const
{
return mEnvironmentMapType;
}
+ void SetMipmapLevels(uint32_t mipmapLevels)
+ {
+ mMipmapLevels = mipmapLevels;
+ }
+
+ uint32_t GetMipmapLevels()
+ {
+ return mMipmapLevels;
+ }
+
public:
std::vector<std::vector<PixelData> > mPixelData;
Dali::Texture mEnvironmentMapTexture;
Dali::Shader mEnvironmentMapShader;
Dali::Scene3D::EnvironmentMapType mEnvironmentMapType{Dali::Scene3D::EnvironmentMapType::AUTO};
+ uint32_t mMipmapLevels{1u};
};
} // namespace Dali::Scene3D::Loader
// EXTERNAL INCLUDES
#include <dali/devel-api/adaptor-framework/image-loading.h>
#include <string.h>
+#include <cmath>
#include <filesystem>
// INTERNAL INCLUDES
{
environmentMapData.mPixelData[i][0] = GetCubeFace(pixelBuffer, i, cubeType, faceWidth, faceHeight);
}
+ uint32_t mipmap = static_cast<uint32_t>(1 + std::floor(std::log2(std::max(environmentMapData.mPixelData[0][0].GetWidth(), environmentMapData.mPixelData[0][0].GetHeight()))));
+ environmentMapData.SetMipmapLevels(mipmap);
environmentMapData.SetEnvironmentMapType(Scene3D::EnvironmentMapType::CUBEMAP);
}
else
std::string extension = modelPath.extension();
std::transform(extension.begin(), extension.end(), extension.begin(), ::tolower);
- return (extension == KTX_EXTENSION) ? Dali::Scene3D::Loader::LoadKtxData(environmentMapUrl, environmentMapData) : LoadEnvironmentMapData(environmentMapUrl, environmentMapData);
+ bool successed = (extension == KTX_EXTENSION) ? Dali::Scene3D::Loader::LoadKtxData(environmentMapUrl, environmentMapData) : LoadEnvironmentMapData(environmentMapUrl, environmentMapData);
+
+ return successed;
}
} // namespace Loader
header.numberOfArrayElements = std::max(header.numberOfArrayElements, 1u);
header.pixelDepth = std::max(header.pixelDepth, 1u);
header.pixelHeight = std::max(header.pixelHeight, 1u);
+ environmentMapData.SetMipmapLevels(header.numberOfMipmapLevels);
environmentMapData.mPixelData.resize(header.numberOfFaces);
for(uint32_t face = 0u; face < header.numberOfFaces; ++face)
{
constexpr std::string_view IBL_INTENSITY_STRING("uIblIntensity");
constexpr std::string_view IBL_Y_DIRECTION("uYDirection");
+constexpr std::string_view IBL_MAXLOD("uMaxLOD");
} // namespace
namespace Scene3D
return IBL_Y_DIRECTION;
}
+std::string_view NodeDefinition::GetIblMaxLodUniformName()
+{
+ return IBL_MAXLOD;
+}
+
bool NodeDefinition::GetExtents(const ResourceBundle& resources, Vector3& min, Vector3& max) const
{
if(mRenderables.empty())
renderer.SetTextures(textures);
+ uint32_t specularMipmap = resources.mEnvironmentMaps[envIdx].second.mSpecularMipmapLevels;
actor.SetProperty(Actor::Property::COLOR, mColor);
+ actor.RegisterProperty(IBL_MAXLOD.data(), static_cast<float>(specularMipmap));
}
void ArcRenderable::OnCreate(const NodeDefinition& node, NodeDefinition::CreateParams& params, Actor& actor) const
*/
static std::string_view GetIblYDirectionUniformName();
+ /**
+ * @brief Retrieves ibl MaxLod uniform name.
+ * This uniform name can be used to set max lod of ibl in shader.
+ * @return std::string_view of the Max Lod uniform name.
+ */
+ static std::string_view GetIblMaxLodUniformName();
+
public: // DATA
static const char* ORIGINAL_MATRIX_PROPERTY_NAME;
}
}
- shaderDef.mUniforms["uMaxLOD"] = 6.f;
shaderDef.mUniforms["uCubeMatrix"] = Matrix::IDENTITY;
Index result = resources.mShaders.size();