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",
{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",
{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)}},
}},
};
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({});
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();
Ref<gltf2::Texture> mTexture;
uint32_t mTexCoord = 0;
float mScale = 1.f;
+ float mStrength = 1.f;
operator bool() const
{
--- /dev/null
+#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
+}
--- /dev/null
+#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;
+}
const auto TEXURE_INFO_READER = std::move(js::Reader<gt::TextureInfo>()
.Register(*js::MakeProperty("index", gt::RefReader<gt::Document>::Read<gt::Texture, >::Document::mTextures>, >::TextureInfo::mTexture))
.Register(*js::MakeProperty("texCoord", js::Read::Number<uint32_t>, >::TextureInfo::mTexCoord))
- .Register(*js::MakeProperty("scale", js::Read::Number<float>, >::TextureInfo::mScale)));
+ .Register(*js::MakeProperty("scale", js::Read::Number<float>, >::TextureInfo::mScale))
+ .Register(*js::MakeProperty("strength", js::Read::Number<float>, >::TextureInfo::mStrength)));
const auto MATERIAL_PBR_READER = std::move(js::Reader<gt::Material::Pbr>()
.Register(*js::MakeProperty("baseColorFactor", gt::ReadDaliVector<Vector4>, >::Material::Pbr::mBaseColorFactor))
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;
}
// 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());
}
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;
}
}
- // Extra textures. TODO: emissive, occlusion etc.
+ // Extra textures.
if(checkStage(SUBSURFACE))
{
raw.mTextures.push_back({SyncImageLoader::Load(imagesPath + iTexture->mTexture.mImageUri), iTexture->mTexture.mSamplerFlags});
++iTexture;
}
+ if(checkStage(EMISSIVE))
+ {
+ raw.mTextures.push_back({SyncImageLoader::Load(imagesPath + iTexture->mTexture.mImageUri), iTexture->mTexture.mSamplerFlags});
+ ++iTexture;
+ }
+
return raw;
}
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<TextureStage> mTextureStages;
};
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);
}
};
-const std::string PBR_SHADER_NAME = "dli_pbr";
-
void RetrieveBlendShapeComponents(const std::vector<MeshDefinition::BlendShape>& blendShapes, bool& hasPositions, bool& hasNormals, bool& hasTangents)
{
for(const auto& blendShape : blendShapes)
{
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);
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*/);
}
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;
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");
}
// INTERNAL INCLUDES
#include "dali-scene-loader/public-api/shader-definition.h"
#include "dali-scene-loader/public-api/utils.h"
+#include <dali-scene-loader/internal/graphics/builtin-shader-extern-gen.h>
namespace Dali
{
mFragmentShaderPath(other.mFragmentShaderPath),
mDefines(other.mDefines),
mHints(other.mHints),
- mUniforms(other.mUniforms)
+ mUniforms(other.mUniforms),
+ mUseBuiltInShader(false)
{
}
{
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;
}
std::string mFragmentShaderPath;
std::vector<std::string> mDefines;
std::vector<std::string> mHints;
-
- Property::Map mUniforms;
+ Property::Map mUniforms;
+ bool mUseBuiltInShader;
};
} // namespace SceneLoader
// Scene doesn't use both of point and directional light\r
NONE = 0,\r
// Scene use point light\r
- POINT_LIGHT,\r
+ POINT_LIGHT = 1,\r
// Scene use directional light\r
- DIRECTIONAL_LIGHT,\r
- // Scene use Image Based Lighting\r
- IMAGE_BASED_LIGHT,\r
- // Scene use Image Based Lighting and point light\r
- IMAGE_BASED_LIGHT_AND_POINT_LIGHT,\r
- // Scene use Image Based Lighting and directional light\r
- IMAGE_BASED_LIGHT_AND_DIRECTIONAL_LIGHT\r
+ DIRECTIONAL_LIGHT = 2\r
};\r
\r
/**\r
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];
actor.RotateBy(orientation);
actor.SetProperty(Actor::Property::POSITION, translation);
- shader.RegisterProperty("uLightType", (scene3dView.GetLightType() & ~Toolkit::Scene3dView::LightType::IMAGE_BASED_LIGHT));
+ float hasLightSource = static_cast<float>(!!(scene3dView.GetLightType() & (Toolkit::Scene3dView::LightType::POINT_LIGHT | Toolkit::Scene3dView::LightType::DIRECTIONAL_LIGHT)));
+ float isPointLight = static_cast<float>(!!(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];
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);
mAnimationArray(),
mLightType(Toolkit::Scene3dView::LightType::NONE),
mLightVector(Vector3::ONE),
- mLightColor(Vector3::ONE)
+ mLightColor(Vector3::ONE),
+ mUseIBL(false)
{
}
bool Scene3dView::SetLight(Toolkit::Scene3dView::LightType type, Vector3 lightVector, Vector3 lightColor)
{
- if(type > Toolkit::Scene3dView::LightType::DIRECTIONAL_LIGHT)
- {
- return false;
- }
-
- mLightType = static_cast<Toolkit::Scene3dView::LightType>(
- (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<float>(!!(GetLightType() & (Toolkit::Scene3dView::LightType::POINT_LIGHT | Toolkit::Scene3dView::LightType::DIRECTIONAL_LIGHT)));
+ float isPointLight = static_cast<float>(!!(GetLightType() & Toolkit::Scene3dView::LightType::POINT_LIGHT));
+ shader.RegisterProperty("uHasLightSource", hasLightSource);
+ shader.RegisterProperty("uIsPointLight", isPointLight);
shader.RegisterProperty("uLightVector", lightVector);
shader.RegisterProperty("uLightColor", lightColor);
}
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;
mSpecularTexture.GenerateMipmaps();
mIBLScaleFactor = scaleFactor;
+ mUseIBL = true;
}
bool Scene3dView::SetDefaultCamera(const Dali::Camera::Type type, const float nearPlane, const Vector3 cameraPosition)
return mSpecularTexture;
}
+bool Scene3dView::HasImageBasedLighting()
+{
+ return mUseIBL;
+}
+
Texture Scene3dView::GetDiffuseTexture()
{
return mDiffuseTexture;
*/\r
Texture GetSpecularTexture();\r
\r
+ /**\r
+ * @brief Get whether the scene has image based rendering or not.\r
+ */\r
+ bool HasImageBasedLighting();\r
+\r
private:\r
/**\r
* @brief Get Cropped image buffer.\r
Texture mBRDFTexture; // BRDF texture for the PBR rendering\r
Texture mSpecularTexture; // Specular cube map texture\r
Texture mDiffuseTexture; // Diffuse cube map texture\r
+ bool mUseIBL;\r
\r
private:\r
// Undefined copy constructor.\r
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;
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;
return roughnessSq / (M_PI * f * f);
}
-vec3 linear( vec3 color )
+vec3 linear(vec3 color)
{
return pow(color,vec3(2.2));
}
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;
}
// 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 );
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;