From 3699bd6bb292750152ea1a19f702a641f50c9867 Mon Sep 17 00:00:00 2001 From: seungho Date: Fri, 15 Apr 2022 17:31:41 +0900 Subject: [PATCH] Use default PBR shader to the scene-loader - glTF uses built-in shader for rendering. - glTF features of Emission and Ambient Occlusion are added. Change-Id: I7b63ee171b8c66c777e1d8a0732860f7a35240e2 Signed-off-by: seungho --- .../src/dali-scene-loader/utc-Dali-Gltf2Loader.cpp | 18 ++ .../utc-Dali-ShaderDefinitionFactory.cpp | 7 - dali-scene-loader/internal/gltf2-asset.h | 1 + .../shaders/default-physically-based-shader.frag | 183 +++++++++++++++++++++ .../shaders/default-physically-based-shader.vert | 149 +++++++++++++++++ dali-scene-loader/public-api/gltf2-loader.cpp | 22 ++- .../public-api/material-definition.cpp | 12 +- dali-scene-loader/public-api/material-definition.h | 10 +- dali-scene-loader/public-api/node-definition.cpp | 8 + .../public-api/shader-definition-factory.cpp | 22 ++- dali-scene-loader/public-api/shader-definition.cpp | 32 ++-- dali-scene-loader/public-api/shader-definition.h | 4 +- 12 files changed, 432 insertions(+), 36 deletions(-) create mode 100644 dali-scene-loader/internal/graphics/shaders/default-physically-based-shader.frag create mode 100644 dali-scene-loader/internal/graphics/shaders/default-physically-based-shader.vert diff --git a/automated-tests/src/dali-scene-loader/utc-Dali-Gltf2Loader.cpp b/automated-tests/src/dali-scene-loader/utc-Dali-Gltf2Loader.cpp index 47515b3..b4dceb9 100644 --- a/automated-tests/src/dali-scene-loader/utc-Dali-Gltf2Loader.cpp +++ b/automated-tests/src/dali-scene-loader/utc-Dali-Gltf2Loader.cpp @@ -167,12 +167,15 @@ int UtcDaliGltfLoaderSuccess1(void) DALI_TEST_EQUAL(2u, materials.size()); const MaterialDefinition materialGroundTruth[]{ {MaterialDefinition::ALBEDO | MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS | + MaterialDefinition::EMISSIVE | MaterialDefinition::OCCLUSION | MaterialDefinition::NORMAL | MaterialDefinition::TRANSPARENCY | MaterialDefinition::GLTF_CHANNELS | (0x80 << MaterialDefinition::ALPHA_CUTOFF_SHIFT), 0, Vector4(1.f, .766f, .336f, 1.f), + Vector3(0.2, 0.1, 0.0), 1.f, 0.f, + 1.f, { {MaterialDefinition::ALBEDO, {"AnimatedCube_BaseColor.png", @@ -183,13 +186,22 @@ int UtcDaliGltfLoaderSuccess1(void) {MaterialDefinition::NORMAL, {"AnimatedCube_BaseColor.png", SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT)}}, + {MaterialDefinition::OCCLUSION, + {"AnimatedCube_BaseColor.png", + SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT)}}, + {MaterialDefinition::EMISSIVE, + {"AnimatedCube_BaseColor.png", + SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT)}}, }}, {MaterialDefinition::ALBEDO | MaterialDefinition::METALLIC | MaterialDefinition::ROUGHNESS | + MaterialDefinition::EMISSIVE | MaterialDefinition::OCCLUSION | MaterialDefinition::NORMAL | MaterialDefinition::GLTF_CHANNELS, 0, Vector4(1.f, .766f, .336f, 1.f), + Vector3(0.2, 0.1, 0.0), 1.f, 0.f, + 1.f, { {MaterialDefinition::ALBEDO, {"AnimatedCube_BaseColor.png", @@ -200,6 +212,12 @@ int UtcDaliGltfLoaderSuccess1(void) {MaterialDefinition::NORMAL, {"AnimatedCube_BaseColor.png", SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT)}}, + {MaterialDefinition::OCCLUSION, + {"AnimatedCube_BaseColor.png", + SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT)}}, + {MaterialDefinition::EMISSIVE, + {"AnimatedCube_BaseColor.png", + SamplerFlags::Encode(FilterMode::LINEAR_MIPMAP_LINEAR, FilterMode::LINEAR, WrapMode::CLAMP_TO_EDGE, WrapMode::REPEAT)}}, }}, }; diff --git a/automated-tests/src/dali-scene-loader/utc-Dali-ShaderDefinitionFactory.cpp b/automated-tests/src/dali-scene-loader/utc-Dali-ShaderDefinitionFactory.cpp index 80ed66d..3fd8fbb 100644 --- a/automated-tests/src/dali-scene-loader/utc-Dali-ShaderDefinitionFactory.cpp +++ b/automated-tests/src/dali-scene-loader/utc-Dali-ShaderDefinitionFactory.cpp @@ -31,11 +31,6 @@ using namespace Dali::SceneLoader; namespace { -bool EndsWith(const std::string& str, const std::string& suffix) // ends_width() is C++20 -{ - return str.size() >= suffix.size() && str.substr(str.size() - suffix.size()).compare(suffix) == 0; -} - MaterialDefinition& NewMaterialDefinition(ResourceBundle& resources) { resources.mMaterials.push_back({}); @@ -281,8 +276,6 @@ int UtcDaliShaderDefinitionFactoryProduceShader(void) DALI_TEST_EQUAL(ps.shaderIdx, shaderIdx); auto& shaderDef = ctx.resources.mShaders[shaderIdx].first; - DALI_TEST_CHECK(EndsWith(shaderDef.mVertexShaderPath, ".vsh")); - DALI_TEST_CHECK(EndsWith(shaderDef.mFragmentShaderPath, ".fsh")); DALI_TEST_EQUAL(shaderDef.mRendererState, rendererState); uint32_t definesUnmatched = shaderDef.mDefines.size(); diff --git a/dali-scene-loader/internal/gltf2-asset.h b/dali-scene-loader/internal/gltf2-asset.h index f5bd6b9..e074c28 100644 --- a/dali-scene-loader/internal/gltf2-asset.h +++ b/dali-scene-loader/internal/gltf2-asset.h @@ -317,6 +317,7 @@ struct TextureInfo Ref mTexture; uint32_t mTexCoord = 0; float mScale = 1.f; + float mStrength = 1.f; operator bool() const { diff --git a/dali-scene-loader/internal/graphics/shaders/default-physically-based-shader.frag b/dali-scene-loader/internal/graphics/shaders/default-physically-based-shader.frag new file mode 100644 index 0000000..2581ad6 --- /dev/null +++ b/dali-scene-loader/internal/graphics/shaders/default-physically-based-shader.frag @@ -0,0 +1,183 @@ +#version 300 es + +#ifdef HIGHP + precision highp float; +#else + precision mediump float; +#endif + +#ifdef THREE_TEX +#ifdef GLTF_CHANNELS +// https://github.com/KhronosGroup/glTF/tree/master/specification/2.0#pbrmetallicroughnessmetallicroughnesstexture +#define METALLIC b +#define ROUGHNESS g +#else //GLTF_CHANNELS +#define METALLIC r +#define ROUGHNESS a +#endif //GLTF_CHANNELS +#endif //THREE_TEX + +#ifdef THREE_TEX + uniform sampler2D sAlbedoAlpha; + uniform sampler2D sMetalRoughness; + uniform sampler2D sNormal; + +#ifdef ALPHA_TEST + uniform float uAlphaThreshold; +#endif //ALPHA_TEST + +#else + uniform sampler2D sAlbedoMetal; + uniform sampler2D sNormalRoughness; +#endif + +#ifdef OCCLUSION + uniform sampler2D sOcclusion; + uniform float uOcclusionStrength; +#endif + +#ifdef EMISSIVE + uniform sampler2D sEmissive; + uniform vec3 uEmissiveFactor; +#endif + +uniform samplerCube sDiffuse; +uniform samplerCube sSpecular; + +// Number of mip map levels in the texture +uniform float uMaxLOD; + +// Transformation matrix of the cubemap texture +uniform mat4 uCubeMatrix; + +uniform vec4 uColor; +uniform float uMetallicFactor; +uniform float uRoughnessFactor; + +//IBL Light intensity +uniform float uIblIntensity; + +// TODO: Multiple texture coordinate will be supported. +in vec2 vUV; +in vec3 vNormal; +in vec3 vTangent; +in vec3 vViewVec; + +out vec4 FragColor; + +// Functions for BRDF calculation come from +// https://www.unrealengine.com/blog/physically-based-shading-on-mobile +// Based on the paper by Dimitar Lazarov +// http://blog.selfshadow.com/publications/s2013-shading-course/lazarov/s2013_pbs_black_ops_2_notes.pdf +vec3 EnvBRDFApprox( vec3 SpecularColor, float Roughness, float NoV ) +{ + const vec4 c0 = vec4( -1.0, -0.0275, -0.572, 0.022 ); + const vec4 c1 = vec4( 1.0, 0.0425, 1.04, -0.04 ); + vec4 r = Roughness * c0 + c1; + float a004 = min( r.x * r.x, exp2( -9.28 * NoV ) ) * r.x + r.y; + vec2 AB = vec2( -1.04, 1.04 ) * a004 + r.zw; + + return SpecularColor * AB.x + AB.y; +} + +void main() +{ + // We get information from the maps (albedo, normal map, roughness, metalness + // I access the maps in the order they will be used +#ifdef THREE_TEX + vec4 albedoAlpha = texture(sAlbedoAlpha, vUV.st); + float alpha = albedoAlpha.a; +#ifdef ALPHA_TEST + if (alpha <= uAlphaThreshold) + { + discard; + } +#endif //ALPHA_TEST + vec3 albedoColor = albedoAlpha.rgb * uColor.rgb; + + vec4 metalRoughness = texture(sMetalRoughness, vUV.st); + float metallic = metalRoughness.METALLIC * uMetallicFactor; + float roughness = metalRoughness.ROUGHNESS * uRoughnessFactor; + + vec3 normalMap = texture(sNormal, vUV.st).rgb; +#else //THREE_TEX + vec4 albedoMetal = texture(sAlbedoMetal, vUV.st); + vec3 albedoColor = albedoMetal.rgb * uColor.rgb; + float metallic = albedoMetal.a * uMetallicFactor; + + vec4 normalRoughness = texture(sNormalRoughness, vUV.st); + vec3 normalMap = normalRoughness.rgb; + float roughness = normalRoughness.a * uRoughnessFactor; +#endif + //Normalize vectors + vec3 normal = normalize(vNormal); + vec3 tangent = normalize(vTangent); + + // NOTE: normal and tangent have to be orthogonal for the result of the cross() + // product to be a unit vector. We might find that we need to normalize(). + vec3 bitangent = cross(normal, tangent); + + vec3 viewVec = normalize(vViewVec); + + // Create Inverse Local to world matrix + mat3 vInvTBN = mat3(tangent, bitangent, normal); + + // Get normal map info in world space + normalMap = normalize(normalMap - 0.5); + vec3 newNormal = vInvTBN * normalMap.rgb; + + // Calculate normal dot view vector + float NoV = max(dot(newNormal, -viewVec), 0.0); + + // Reflect vector + vec3 reflectionVec = reflect(viewVec, newNormal); + + //transform it now to environment coordinates (used when the environment rotates) + vec3 reflecCube = (uCubeMatrix * vec4( reflectionVec, 0.0 ) ).xyz; + reflecCube = normalize( reflecCube ); + + //transform it now to environment coordinates + vec3 normalCube = ( uCubeMatrix * vec4( newNormal, 0.0 ) ).xyz; + normalCube = normalize( normalCube ); + + // Get irradiance from diffuse cubemap + vec3 irradiance = texture( sDiffuse, normalCube ).rgb; + + // Access reflection color using roughness value + float finalLod = mix( 0.0, uMaxLOD - 2.0, roughness); + vec3 reflectionColor = textureLod(sSpecular, reflecCube, finalLod).rgb; + + // We are supposed to be using DielectricColor (0.04) of a plastic (almost everything) + // http://blog.selfshadow.com/publications/s2014-shading-course/hoffman/s2014_pbs_physics_math_slides.pdf + // however that seems to prevent achieving very dark tones (i.e. get dark gray blacks). + vec3 DiffuseColor = albedoColor - albedoColor * metallic; // 1 mad + vec3 SpecularColor = mix( vec3(0.04), albedoColor, metallic); // 2 mad + + // Calculate specular color using Magic Function (takes original roughness and normal dot view). + vec3 specColor = reflectionColor.rgb * EnvBRDFApprox(SpecularColor, roughness, NoV ); + + // Multiply the result by albedo texture and do energy conservation + vec3 diffuseColor = irradiance * DiffuseColor; + + // Final color is the sum of the diffuse and specular term + vec3 finalColor = diffuseColor + specColor; + + finalColor = sqrt( finalColor ) * uIblIntensity; + + +#ifdef OCCLUSION + float ao = texture(sOcclusion, vUV.st).r; + finalColor = mix( finalColor, finalColor * ao, uOcclusionStrength ); +#endif + +#ifdef EMISSIVE + vec3 emissive = texture( sEmissive, vUV.st ).rgb * uEmissiveFactor; + finalColor += emissive; +#endif + +#ifdef THREE_TEX + FragColor = vec4( finalColor, alpha ); +#else //THREE_TEX + FragColor = vec4( finalColor, 1.0 ); +#endif //THREE_TEX +} diff --git a/dali-scene-loader/internal/graphics/shaders/default-physically-based-shader.vert b/dali-scene-loader/internal/graphics/shaders/default-physically-based-shader.vert new file mode 100644 index 0000000..e9381c5 --- /dev/null +++ b/dali-scene-loader/internal/graphics/shaders/default-physically-based-shader.vert @@ -0,0 +1,149 @@ +#version 300 es + +#ifdef HIGHP + precision highp float; +#else + precision mediump float; +#endif + +in vec3 aPosition; +in vec2 aTexCoord; +in vec3 aNormal; +in vec3 aTangent; + +#ifdef MORPH + uniform sampler2D sBlendShapeGeometry; +#endif + +out vec2 vUV; +out vec3 vNormal; +out vec3 vTangent; +out vec3 vViewVec; + +uniform highp mat4 uMvpMatrix; +uniform highp mat4 uViewMatrix; +uniform mat3 uNormalMatrix; +uniform mat4 uModelMatrix; +uniform mat4 uModelView; +uniform mat4 uProjection; + +#ifdef SKINNING + in vec4 aJoints; + in vec4 aWeights; + #define MAX_BONES 64 + uniform mat4 uBone[MAX_BONES]; +#endif + +#ifdef MORPH +#define MAX_BLEND_SHAPE_NUMBER 128 +uniform int uNumberOfBlendShapes; ///< Total number of blend shapes loaded. +uniform float uBlendShapeWeight[MAX_BLEND_SHAPE_NUMBER]; ///< The weight of each blend shape. +#ifdef MORPH_VERSION_2_0 +uniform float uBlendShapeUnnormalizeFactor; ///< Factor used to unnormalize the geometry of the blend shape. +#else +uniform float uBlendShapeUnnormalizeFactor[MAX_BLEND_SHAPE_NUMBER]; ///< Factor used to unnormalize the geometry of the blend shape. +#endif +uniform int uBlendShapeComponentSize; ///< The size in the texture of either the vertices, normals or tangents. Used to calculate the offset to address them. +#endif + +void main() +{ + vec4 position = vec4(aPosition, 1.0); + vec3 normal = aNormal; + vec3 tangent = aTangent; + +#ifdef MORPH + int width = textureSize( sBlendShapeGeometry, 0 ).x; + + int blendShapeBufferOffset = 0; + for( int index = 0; index < uNumberOfBlendShapes; ++index ) + { +#ifdef MORPH_POSITION + // Calculate the index to retrieve the geometry from the texture. + int vertexId = gl_VertexID + blendShapeBufferOffset; + int x = vertexId % width; + int y = vertexId / width; + + vec3 diff = vec3(0.0); + // Retrieves the blend shape geometry from the texture, unnormalizes it and multiply by the weight. + if( 0.0 != uBlendShapeWeight[index] ) + { +#ifdef MORPH_VERSION_2_0 + float unnormalizeFactor = uBlendShapeUnnormalizeFactor; +#else + float unnormalizeFactor = uBlendShapeUnnormalizeFactor[index]; +#endif + + diff = uBlendShapeWeight[index] * unnormalizeFactor * ( texelFetch( sBlendShapeGeometry, ivec2(x, y), 0 ).xyz - 0.5 ); + } + + position.xyz += diff; + + blendShapeBufferOffset += uBlendShapeComponentSize; +#endif + +#ifdef MORPH_NORMAL + // Calculate the index to retrieve the normal from the texture. + vertexId = gl_VertexID + blendShapeBufferOffset; + x = vertexId % width; + y = vertexId / width; + + // Retrieves the blend shape normal from the texture, unnormalizes it and multiply by the weight. + if( 0.0 != uBlendShapeWeight[index] ) + { + diff = uBlendShapeWeight[index] * 2.0 * ( texelFetch( sBlendShapeGeometry, ivec2(x, y), 0 ).xyz - 0.5 ); + } + + normal += diff.xyz; + + blendShapeBufferOffset += uBlendShapeComponentSize; +#endif + +#ifdef MORPH_TANGENT + // Calculate the index to retrieve the tangent from the texture. + vertexId = gl_VertexID + blendShapeBufferOffset; + x = vertexId % width; + y = vertexId / width; + + // Retrieves the blend shape tangent from the texture, unnormalizes it and multiply by the weight. + if( 0.0 != uBlendShapeWeight[index] ) + { + diff = uBlendShapeWeight[index] * 2.0 * ( texelFetch( sBlendShapeGeometry, ivec2(x, y), 0 ).xyz - 0.5 ); + } + + tangent += diff.xyz; + + blendShapeBufferOffset += uBlendShapeComponentSize; +#endif + } + +#endif + +#ifdef SKINNING + mat4 bone = uBone[int(aJoints.x)] * aWeights.x + + uBone[int(aJoints.y)] * aWeights.y + + uBone[int(aJoints.z)] * aWeights.z + + uBone[int(aJoints.w)] * aWeights.w; + position = bone * position; + normal = (bone * vec4(normal, 0.0)).xyz; + tangent = (bone * vec4(tangent, 0.0)).xyz; +#endif + + vec4 vPosition = uModelMatrix * position; + + vNormal = normalize(uNormalMatrix * normal); + + vTangent = normalize(uNormalMatrix * tangent); + + + vec4 viewPosition = uViewMatrix * vPosition; + gl_Position = uProjection * viewPosition; + +#ifdef FLIP_V + vUV = vec2(aTexCoord.x, 1.0 - aTexCoord.y); +#else + vUV = aTexCoord; +#endif + + vViewVec = viewPosition.xyz; +} diff --git a/dali-scene-loader/public-api/gltf2-loader.cpp b/dali-scene-loader/public-api/gltf2-loader.cpp index 923d0e4..be7e538 100644 --- a/dali-scene-loader/public-api/gltf2-loader.cpp +++ b/dali-scene-loader/public-api/gltf2-loader.cpp @@ -157,7 +157,8 @@ const auto TEXURE_READER = std::move(js::Reader() const auto TEXURE_INFO_READER = std::move(js::Reader() .Register(*js::MakeProperty("index", gt::RefReader::Read, >::TextureInfo::mTexture)) .Register(*js::MakeProperty("texCoord", js::Read::Number, >::TextureInfo::mTexCoord)) - .Register(*js::MakeProperty("scale", js::Read::Number, >::TextureInfo::mScale))); + .Register(*js::MakeProperty("scale", js::Read::Number, >::TextureInfo::mScale)) + .Register(*js::MakeProperty("strength", js::Read::Number, >::TextureInfo::mStrength))); const auto MATERIAL_PBR_READER = std::move(js::Reader() .Register(*js::MakeProperty("baseColorFactor", gt::ReadDaliVector, >::Material::Pbr::mBaseColorFactor)) @@ -440,7 +441,7 @@ void ConvertMaterial(const gt::Material& m, decltype(ResourceBundle::mMaterials) matDef.mColor = pbr.mBaseColorFactor; - matDef.mTextureStages.reserve(!!pbr.mBaseColorTexture + !!pbr.mMetallicRoughnessTexture + !!m.mNormalTexture); + matDef.mTextureStages.reserve(!!pbr.mBaseColorTexture + !!pbr.mMetallicRoughnessTexture + !!m.mNormalTexture + !!m.mOcclusionTexture + !!m.mEmissiveTexture); if(pbr.mBaseColorTexture) { const auto semantic = MaterialDefinition::ALBEDO; @@ -470,6 +471,23 @@ void ConvertMaterial(const gt::Material& m, decltype(ResourceBundle::mMaterials) } // TODO: handle doubleSided + if(m.mOcclusionTexture) + { + const auto semantic = MaterialDefinition::OCCLUSION; + matDef.mTextureStages.push_back({semantic, ConvertTextureInfo(m.mOcclusionTexture)}); + // TODO: and there had better be one + matDef.mFlags |= semantic; + matDef.mOcclusionStrength = m.mOcclusionTexture.mStrength; + } + + if(m.mEmissiveTexture) + { + const auto semantic = MaterialDefinition::EMISSIVE; + matDef.mTextureStages.push_back({semantic, ConvertTextureInfo(m.mEmissiveTexture)}); + // TODO: and there had better be one + matDef.mFlags |= semantic; + matDef.mEmissiveFactor = m.mEmissiveFactor; + } outMaterials.emplace_back(std::move(matDef), TextureSet()); } diff --git a/dali-scene-loader/public-api/material-definition.cpp b/dali-scene-loader/public-api/material-definition.cpp index 3c7a391..1342ced 100644 --- a/dali-scene-loader/public-api/material-definition.cpp +++ b/dali-scene-loader/public-api/material-definition.cpp @@ -110,7 +110,9 @@ MaterialDefinition::LoadRaw(const std::string& imagesPath) const RawData raw; const bool hasTransparency = MaskMatch(mFlags, TRANSPARENCY); - uint32_t numBuffers = mTextureStages.size() + (hasTransparency ? !CheckTextures(ALBEDO) + !CheckTextures(METALLIC | ROUGHNESS) + !CheckTextures(NORMAL) : !CheckTextures(ALBEDO | METALLIC) + !CheckTextures(NORMAL | ROUGHNESS)); + // Why we add additional count here? + uint32_t numBuffers = mTextureStages.size() + (hasTransparency ? !CheckTextures(ALBEDO) + !CheckTextures(METALLIC | ROUGHNESS) + !CheckTextures(NORMAL) + : !CheckTextures(ALBEDO | METALLIC) + !CheckTextures(NORMAL | ROUGHNESS)); if(numBuffers == 0) { return raw; @@ -210,7 +212,7 @@ MaterialDefinition::LoadRaw(const std::string& imagesPath) const } } - // Extra textures. TODO: emissive, occlusion etc. + // Extra textures. if(checkStage(SUBSURFACE)) { raw.mTextures.push_back({SyncImageLoader::Load(imagesPath + iTexture->mTexture.mImageUri), iTexture->mTexture.mSamplerFlags}); @@ -223,6 +225,12 @@ MaterialDefinition::LoadRaw(const std::string& imagesPath) const ++iTexture; } + if(checkStage(EMISSIVE)) + { + raw.mTextures.push_back({SyncImageLoader::Load(imagesPath + iTexture->mTexture.mImageUri), iTexture->mTexture.mSamplerFlags}); + ++iTexture; + } + return raw; } diff --git a/dali-scene-loader/public-api/material-definition.h b/dali-scene-loader/public-api/material-definition.h index 80e93e7..e36f74b 100644 --- a/dali-scene-loader/public-api/material-definition.h +++ b/dali-scene-loader/public-api/material-definition.h @@ -219,10 +219,12 @@ struct DALI_SCENE_LOADER_API MaterialDefinition public: // DATA uint32_t mFlags = 0x0; - Index mEnvironmentIdx = 0; - Vector4 mColor = Color::WHITE; - float mMetallic = 1.f; - float mRoughness = 1.f; + Index mEnvironmentIdx = 0; + Vector4 mColor = Color::WHITE; + Vector3 mEmissiveFactor = Vector3::ZERO; + float mMetallic = 1.f; + float mRoughness = 1.f; + float mOcclusionStrength = 1.f; std::vector mTextureStages; }; diff --git a/dali-scene-loader/public-api/node-definition.cpp b/dali-scene-loader/public-api/node-definition.cpp index 45e0b23..e8f6b82 100644 --- a/dali-scene-loader/public-api/node-definition.cpp +++ b/dali-scene-loader/public-api/node-definition.cpp @@ -153,6 +153,14 @@ void ModelNode::OnCreate(const NodeDefinition& node, NodeDefinition::CreateParam auto& matDef = resources.mMaterials[mMaterialIdx].first; actor.RegisterProperty("uMetallicFactor", matDef.mMetallic); actor.RegisterProperty("uRoughnessFactor", matDef.mRoughness); + if(matDef.mFlags & MaterialDefinition::OCCLUSION) + { + actor.RegisterProperty("uOcclusionStrength", matDef.mOcclusionStrength); + } + if(matDef.mFlags & MaterialDefinition::EMISSIVE) + { + actor.RegisterProperty("uEmissiveFactor", matDef.mEmissiveFactor); + } Index envIdx = matDef.mEnvironmentIdx; actor.RegisterProperty("uIblIntensity", resources.mEnvironmentMaps[envIdx].first.mIblIntensity); diff --git a/dali-scene-loader/public-api/shader-definition-factory.cpp b/dali-scene-loader/public-api/shader-definition-factory.cpp index bd6b168..6f9ab4e 100644 --- a/dali-scene-loader/public-api/shader-definition-factory.cpp +++ b/dali-scene-loader/public-api/shader-definition-factory.cpp @@ -56,8 +56,6 @@ struct ResourceReceiver : IResourceReceiver } }; -const std::string PBR_SHADER_NAME = "dli_pbr"; - void RetrieveBlendShapeComponents(const std::vector& blendShapes, bool& hasPositions, bool& hasNormals, bool& hasTangents) { for(const auto& blendShape : blendShapes) @@ -72,9 +70,6 @@ uint64_t HashNode(const NodeDefinition& nodeDef, const MaterialDefinition& mater { Hash hash; - // note: could be per vertex / fragment component - in WatchViewer, these have the same name. - hash.Add(PBR_SHADER_NAME); - const bool hasTransparency = MaskMatch(materialDef.mFlags, MaterialDefinition::TRANSPARENCY); hash.Add(hasTransparency); @@ -101,6 +96,11 @@ uint64_t HashNode(const NodeDefinition& nodeDef, const MaterialDefinition& mater hash.Add("OCCL" /*USION*/); } + if(MaskMatch(materialDef.mFlags, MaterialDefinition::EMISSIVE)) + { + hash.Add("EMIS" /*SIVE*/); + } + if(MaskMatch(materialDef.mFlags, MaterialDefinition::GLTF_CHANNELS)) { hash.Add("GLTF" /*_CHANNELS*/); @@ -192,8 +192,7 @@ Index ShaderDefinitionFactory::ProduceShader(const NodeDefinition& nodeDef) } ShaderDefinition shaderDef; - shaderDef.mVertexShaderPath = PBR_SHADER_NAME + ".vsh"; - shaderDef.mFragmentShaderPath = PBR_SHADER_NAME + ".fsh"; + shaderDef.mUseBuiltInShader = true; shaderDef.mRendererState = RendererState::DEPTH_TEST | RendererState::DEPTH_WRITE | RendererState::CULL_BACK; auto& materialDef = *receiver.mMaterialDef; @@ -222,12 +221,17 @@ Index ShaderDefinitionFactory::ProduceShader(const NodeDefinition& nodeDef) shaderDef.mDefines.push_back("SSS"); } - if(MaskMatch(receiver.mMaterialDef->mFlags, MaterialDefinition::OCCLUSION)) + if(MaskMatch(materialDef.mFlags, MaterialDefinition::OCCLUSION)) { shaderDef.mDefines.push_back("OCCLUSION"); } - if(MaskMatch(receiver.mMaterialDef->mFlags, MaterialDefinition::GLTF_CHANNELS)) + if(MaskMatch(materialDef.mFlags, MaterialDefinition::EMISSIVE)) + { + shaderDef.mDefines.push_back("EMISSIVE"); + } + + if(MaskMatch(materialDef.mFlags, MaterialDefinition::GLTF_CHANNELS)) { shaderDef.mDefines.push_back("GLTF_CHANNELS"); } diff --git a/dali-scene-loader/public-api/shader-definition.cpp b/dali-scene-loader/public-api/shader-definition.cpp index 73c18ba..71024f3 100644 --- a/dali-scene-loader/public-api/shader-definition.cpp +++ b/dali-scene-loader/public-api/shader-definition.cpp @@ -18,6 +18,7 @@ // INTERNAL INCLUDES #include "dali-scene-loader/public-api/shader-definition.h" #include "dali-scene-loader/public-api/utils.h" +#include namespace Dali { @@ -36,7 +37,8 @@ ShaderDefinition::ShaderDefinition(const ShaderDefinition& other) mFragmentShaderPath(other.mFragmentShaderPath), mDefines(other.mDefines), mHints(other.mHints), - mUniforms(other.mUniforms) + mUniforms(other.mUniforms), + mUseBuiltInShader(false) { } @@ -80,28 +82,38 @@ ShaderDefinition::LoadRaw(const std::string& shadersPath) const { RawData raw; - bool fail = false; - raw.mVertexShaderSource = LoadTextFile((shadersPath + mVertexShaderPath).c_str(), &fail); - if(!fail) + bool fail = false; + if(!mUseBuiltInShader) { - raw.mFragmentShaderSource = LoadTextFile((shadersPath + mFragmentShaderPath).c_str(), &fail); + raw.mVertexShaderSource = LoadTextFile((shadersPath + mVertexShaderPath).c_str(), &fail); if(!fail) { - for(auto definevar : mDefines) + raw.mFragmentShaderSource = LoadTextFile((shadersPath + mFragmentShaderPath).c_str(), &fail); + if(fail) { - ApplyDefine(raw.mVertexShaderSource, definevar); - ApplyDefine(raw.mFragmentShaderSource, definevar); + ExceptionFlinger(ASSERT_LOCATION) << "Failed to load shader source from '" << shadersPath + mFragmentShaderPath << "'."; } } else { - ExceptionFlinger(ASSERT_LOCATION) << "Failed to load shader source from '" << shadersPath + mFragmentShaderPath << "'."; + ExceptionFlinger(ASSERT_LOCATION) << "Failed to load shader source from '" << shadersPath + mVertexShaderPath << "'."; } } else { - ExceptionFlinger(ASSERT_LOCATION) << "Failed to load shader source from '" << shadersPath + mVertexShaderPath << "'."; + raw.mVertexShaderSource = SHADER_DEFAULT_PHYSICALLY_BASED_SHADER_VERT.data(); + raw.mFragmentShaderSource = SHADER_DEFAULT_PHYSICALLY_BASED_SHADER_FRAG.data(); + } + + if(!fail) + { + for(auto definevar : mDefines) + { + ApplyDefine(raw.mVertexShaderSource, definevar); + ApplyDefine(raw.mFragmentShaderSource, definevar); + } } + return raw; } diff --git a/dali-scene-loader/public-api/shader-definition.h b/dali-scene-loader/public-api/shader-definition.h index d7f390b..5d0a49e 100644 --- a/dali-scene-loader/public-api/shader-definition.h +++ b/dali-scene-loader/public-api/shader-definition.h @@ -79,8 +79,8 @@ public: // DATA std::string mFragmentShaderPath; std::vector mDefines; std::vector mHints; - - Property::Map mUniforms; + Property::Map mUniforms; + bool mUseBuiltInShader; }; } // namespace SceneLoader -- 2.7.4