From: Seungho BAEK Date: Fri, 29 Apr 2022 06:48:30 +0000 (+0000) Subject: Merge changes I7b63ee17,I61bd1ed2 into devel/master X-Git-Tag: dali_2.1.21~10 X-Git-Url: http://review.tizen.org/git/?p=platform%2Fcore%2Fuifw%2Fdali-toolkit.git;a=commitdiff_plain;h=bee78157f19fa54ae961081782a2f6537cc8dd5a;hp=7027b808143d4f086636c21597336d37678ccb2b Merge changes I7b63ee17,I61bd1ed2 into devel/master * changes: Use default PBR shader to the scene-loader Fix Scene3d-View light issue --- 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 diff --git a/dali-toolkit/devel-api/controls/scene3d-view/scene3d-view.h b/dali-toolkit/devel-api/controls/scene3d-view/scene3d-view.h index 1f0effb..756a7a5 100644 --- a/dali-toolkit/devel-api/controls/scene3d-view/scene3d-view.h +++ b/dali-toolkit/devel-api/controls/scene3d-view/scene3d-view.h @@ -80,15 +80,9 @@ public: // Scene doesn't use both of point and directional light NONE = 0, // Scene use point light - POINT_LIGHT, + POINT_LIGHT = 1, // Scene use directional light - DIRECTIONAL_LIGHT, - // Scene use Image Based Lighting - IMAGE_BASED_LIGHT, - // Scene use Image Based Lighting and point light - IMAGE_BASED_LIGHT_AND_POINT_LIGHT, - // Scene use Image Based Lighting and directional light - IMAGE_BASED_LIGHT_AND_DIRECTIONAL_LIGHT + DIRECTIONAL_LIGHT = 2 }; /** diff --git a/dali-toolkit/internal/controls/scene3d-view/gltf-loader.cpp b/dali-toolkit/internal/controls/scene3d-view/gltf-loader.cpp index 2c8de12..55dfd8d 100644 --- a/dali-toolkit/internal/controls/scene3d-view/gltf-loader.cpp +++ b/dali-toolkit/internal/controls/scene3d-view/gltf-loader.cpp @@ -1509,7 +1509,7 @@ Actor Loader::AddNode(Scene3dView& scene3dView, uint32_t index) VERTEX_SHADER += SHADER_GLTF_PHYSICALLY_BASED_SHADER_VERT.data(); FRAGMENT_SHADER = SHADER_GLTF_GLES_VERSION_300_DEF.data(); - bool useIBL = (scene3dView.GetLightType() >= Toolkit::Scene3dView::LightType::IMAGE_BASED_LIGHT); + bool useIBL = scene3dView.HasImageBasedLighting(); if(isMaterial) { MaterialInfo materialInfo = mMaterialArray[meshInfo.materialsIdx]; @@ -1592,11 +1592,14 @@ Actor Loader::AddNode(Scene3dView& scene3dView, uint32_t index) actor.RotateBy(orientation); actor.SetProperty(Actor::Property::POSITION, translation); - shader.RegisterProperty("uLightType", (scene3dView.GetLightType() & ~Toolkit::Scene3dView::LightType::IMAGE_BASED_LIGHT)); + float hasLightSource = static_cast(!!(scene3dView.GetLightType() & (Toolkit::Scene3dView::LightType::POINT_LIGHT | Toolkit::Scene3dView::LightType::DIRECTIONAL_LIGHT))); + float isPointLight = static_cast(!!(scene3dView.GetLightType() & Toolkit::Scene3dView::LightType::POINT_LIGHT)); + shader.RegisterProperty("uHasLightSource", hasLightSource); + shader.RegisterProperty("uIsPointLight", isPointLight); shader.RegisterProperty("uLightVector", scene3dView.GetLightVector()); shader.RegisterProperty("uLightColor", scene3dView.GetLightColor()); - actor.RegisterProperty("uIsColor", meshInfo.attribute.COLOR.size() > 0); + actor.RegisterProperty("uHasVertexColor", meshInfo.attribute.COLOR.size() > 0 ? 1.0f : 0.0f); if(isMaterial) { MaterialInfo materialInfo = mMaterialArray[meshInfo.materialsIdx]; @@ -1605,15 +1608,15 @@ Actor Loader::AddNode(Scene3dView& scene3dView, uint32_t index) if(materialInfo.alphaMode == "OPAQUE") { - actor.RegisterProperty("alphaMode", 0); + actor.RegisterProperty("uAlphaMode", 0.0f); } else if(materialInfo.alphaMode == "MASK") { - actor.RegisterProperty("alphaMode", 1); + actor.RegisterProperty("uAlphaMode", 1.0f); } else { - actor.RegisterProperty("alphaMode", 2); + actor.RegisterProperty("uAlphaMode", 2.0f); } actor.RegisterProperty("alphaCutoff", materialInfo.alphaCutoff); diff --git a/dali-toolkit/internal/controls/scene3d-view/scene3d-view-impl.cpp b/dali-toolkit/internal/controls/scene3d-view/scene3d-view-impl.cpp index aa8438a..6231b64 100644 --- a/dali-toolkit/internal/controls/scene3d-view/scene3d-view-impl.cpp +++ b/dali-toolkit/internal/controls/scene3d-view/scene3d-view-impl.cpp @@ -54,7 +54,8 @@ Scene3dView::Scene3dView() mAnimationArray(), mLightType(Toolkit::Scene3dView::LightType::NONE), mLightVector(Vector3::ONE), - mLightColor(Vector3::ONE) + mLightColor(Vector3::ONE), + mUseIBL(false) { } @@ -130,20 +131,16 @@ bool Scene3dView::PlayAnimations() bool Scene3dView::SetLight(Toolkit::Scene3dView::LightType type, Vector3 lightVector, Vector3 lightColor) { - if(type > Toolkit::Scene3dView::LightType::DIRECTIONAL_LIGHT) - { - return false; - } - - mLightType = static_cast( - (mLightType >= Toolkit::Scene3dView::LightType::IMAGE_BASED_LIGHT) ? Toolkit::Scene3dView::LightType::IMAGE_BASED_LIGHT + type : type); - + mLightType = type; mLightVector = lightVector; mLightColor = lightColor; for(auto&& shader : mShaderArray) { - shader.RegisterProperty("uLightType", (GetLightType() & ~Toolkit::Scene3dView::LightType::IMAGE_BASED_LIGHT)); + float hasLightSource = static_cast(!!(GetLightType() & (Toolkit::Scene3dView::LightType::POINT_LIGHT | Toolkit::Scene3dView::LightType::DIRECTIONAL_LIGHT))); + float isPointLight = static_cast(!!(GetLightType() & Toolkit::Scene3dView::LightType::POINT_LIGHT)); + shader.RegisterProperty("uHasLightSource", hasLightSource); + shader.RegisterProperty("uIsPointLight", isPointLight); shader.RegisterProperty("uLightVector", lightVector); shader.RegisterProperty("uLightColor", lightColor); } @@ -203,8 +200,6 @@ void Scene3dView::UploadTextureFace(Texture& texture, Devel::PixelBuffer pixelBu void Scene3dView::SetCubeMap(const std::string& diffuseTexturePath, const std::string& specularTexturePath, Vector4 scaleFactor) { - mLightType = Toolkit::Scene3dView::LightType::IMAGE_BASED_LIGHT; - // BRDF texture const std::string imageDirPath = AssetManager::GetDaliImagePath(); const std::string imageBrdfUrl = imageDirPath + IMAGE_BRDF_FILE_NAME; @@ -235,6 +230,7 @@ void Scene3dView::SetCubeMap(const std::string& diffuseTexturePath, const std::s mSpecularTexture.GenerateMipmaps(); mIBLScaleFactor = scaleFactor; + mUseIBL = true; } bool Scene3dView::SetDefaultCamera(const Dali::Camera::Type type, const float nearPlane, const Vector3 cameraPosition) @@ -318,6 +314,11 @@ Texture Scene3dView::GetSpecularTexture() return mSpecularTexture; } +bool Scene3dView::HasImageBasedLighting() +{ + return mUseIBL; +} + Texture Scene3dView::GetDiffuseTexture() { return mDiffuseTexture; diff --git a/dali-toolkit/internal/controls/scene3d-view/scene3d-view-impl.h b/dali-toolkit/internal/controls/scene3d-view/scene3d-view-impl.h index 6dbe859..bc731d3 100644 --- a/dali-toolkit/internal/controls/scene3d-view/scene3d-view-impl.h +++ b/dali-toolkit/internal/controls/scene3d-view/scene3d-view-impl.h @@ -185,6 +185,11 @@ public: */ Texture GetSpecularTexture(); + /** + * @brief Get whether the scene has image based rendering or not. + */ + bool HasImageBasedLighting(); + private: /** * @brief Get Cropped image buffer. @@ -232,6 +237,7 @@ private: Texture mBRDFTexture; // BRDF texture for the PBR rendering Texture mSpecularTexture; // Specular cube map texture Texture mDiffuseTexture; // Diffuse cube map texture + bool mUseIBL; private: // Undefined copy constructor. diff --git a/dali-toolkit/internal/graphics/shaders/gltf-physically-based-shader.frag b/dali-toolkit/internal/graphics/shaders/gltf-physically-based-shader.frag index cefd19e..9477e40 100644 --- a/dali-toolkit/internal/graphics/shaders/gltf-physically-based-shader.frag +++ b/dali-toolkit/internal/graphics/shaders/gltf-physically-based-shader.frag @@ -1,13 +1,13 @@ uniform lowp vec3 uLightColor; uniform lowp vec4 uBaseColorFactor; uniform lowp vec2 uMetallicRoughnessFactors; -uniform lowp int alphaMode; uniform lowp float alphaCutoff; +uniform lowp float uAlphaMode; +uniform lowp float uHasLightSource; in lowp vec2 vUV[2]; in lowp mat3 vTBN; in lowp vec4 vColor; -flat in int visLight; in highp vec3 vLightDirection; in highp vec3 vPositionToCamera; @@ -30,20 +30,20 @@ const float c_MinRoughness = 0.04; vec3 getNormal() { #ifdef TEXTURE_NORMAL - lowp vec3 n = texture( uNormalSampler, vUV[uNormalTexCoordIndex] ).rgb; - n = normalize( vTBN * ( ( 2.0 * n - 1.0 ) * vec3( uNormalScale, uNormalScale, 1.0 ) ) ); + lowp vec3 n = texture(uNormalSampler, vUV[uNormalTexCoordIndex]).rgb; + n = normalize(vTBN * ((2.0 * n - 1.0) * vec3(uNormalScale, uNormalScale, 1.0))); #else lowp vec3 n = normalize( vTBN[2].xyz ); #endif return n; } -vec3 specularReflection( PBRInfo pbrInputs ) +vec3 specularReflection(PBRInfo pbrInputs) { - return pbrInputs.reflectance0 + ( pbrInputs.reflectance90 - pbrInputs.reflectance0 ) * pow( clamp( 1.0 - pbrInputs.VdotH, 0.0, 1.0 ), 5.0 ); + return pbrInputs.reflectance0 + (pbrInputs.reflectance90 - pbrInputs.reflectance0) * pow(clamp(1.0 - pbrInputs.VdotH, 0.0, 1.0), 5.0); } -float geometricOcclusion( PBRInfo pbrInputs ) +float geometricOcclusion(PBRInfo pbrInputs) { mediump float NdotL = pbrInputs.NdotL; mediump float NdotV = pbrInputs.NdotV; @@ -61,7 +61,7 @@ float microfacetDistribution(PBRInfo pbrInputs) return roughnessSq / (M_PI * f * f); } -vec3 linear( vec3 color ) +vec3 linear(vec3 color) { return pow(color,vec3(2.2)); } @@ -96,13 +96,13 @@ void main() lowp vec4 baseColor = vColor * uBaseColorFactor; #endif - if( alphaMode == 0 ) + if(uAlphaMode < 0.5f) { baseColor.w = 1.0; } - else if( alphaMode == 1 ) + else if(uAlphaMode < 1.5f) { - if( baseColor.w >= alphaCutoff ) + if(baseColor.w >= alphaCutoff) { baseColor.w = 1.0; } @@ -150,7 +150,7 @@ void main() // Calculate the shading terms for the microfacet specular shading model lowp vec3 color = vec3(0.0); - if( visLight == 1 ) + if( uHasLightSource > 0.5f ) { lowp vec3 F = specularReflection( pbrInputs ); lowp float G = geometricOcclusion( pbrInputs ); diff --git a/dali-toolkit/internal/graphics/shaders/gltf-physically-based-shader.vert b/dali-toolkit/internal/graphics/shaders/gltf-physically-based-shader.vert index 6628865..095e839 100644 --- a/dali-toolkit/internal/graphics/shaders/gltf-physically-based-shader.vert +++ b/dali-toolkit/internal/graphics/shaders/gltf-physically-based-shader.vert @@ -9,51 +9,34 @@ uniform mediump vec3 uSize; uniform mediump mat4 uModelMatrix; uniform mediump mat4 uViewMatrix; uniform mediump mat4 uProjection; -uniform lowp int uLightType; uniform mediump vec3 uLightVector; -uniform lowp int uIsColor; +uniform lowp float uIsPointLight; +uniform lowp float uHasVertexColor; out lowp vec2 vUV[2]; out lowp mat3 vTBN; out lowp vec4 vColor; -flat out int visLight; out highp vec3 vLightDirection; out highp vec3 vPositionToCamera; void main() { highp vec4 invY = vec4(1.0, -1.0, 1.0, 1.0); - highp vec4 positionW = uModelMatrix * vec4( aPosition * uSize, 1.0 ); - highp vec4 positionV = uViewMatrix * ( invY * positionW ); + highp vec4 positionW = uModelMatrix * vec4(aPosition * uSize, 1.0); + highp vec4 positionV = uViewMatrix * (invY * positionW); - vPositionToCamera = transpose( mat3( uViewMatrix ) ) * ( -vec3( positionV.xyz / positionV.w ) ); + vPositionToCamera = transpose(mat3(uViewMatrix)) * (-vec3(positionV.xyz / positionV.w)); vPositionToCamera *= invY.xyz; lowp vec3 bitangent = cross(aNormal, aTangent.xyz) * aTangent.w; - vTBN = mat3( uModelMatrix ) * mat3(aTangent.xyz, bitangent, aNormal); + vTBN = mat3(uModelMatrix) * mat3(aTangent.xyz, bitangent, aNormal); vUV[0] = aTexCoord0; vUV[1] = aTexCoord1; - visLight = 1; - if( uLightType == 1 ) - { - vLightDirection = ( invY.xyz * uLightVector ) - ( positionW.xyz / positionW.w ); - } - else if( uLightType == 2 ) - { - vLightDirection = -( invY.xyz * uLightVector ); - } - else - { - visLight = 0; - } - - vColor = vec4( 1.0 ); - if( uIsColor == 1 ) - { - vColor = aVertexColor; - } + vLightDirection = mix(-(invY.xyz * uLightVector), (invY.xyz * uLightVector) - (positionW.xyz / positionW.w), uIsPointLight); + + vColor = mix(vec4(1.0f), aVertexColor, uHasVertexColor); gl_Position = uProjection * positionV; // needs w for proper perspective correction gl_Position = gl_Position/gl_Position.w;