Compare commits
15 Commits
bjd/fix-op
...
bjd/debugg
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
18dab53920 | ||
|
|
b754b81e6f | ||
|
|
65bb66f90c | ||
|
|
a0af84d034 | ||
|
|
3cdaf3feeb | ||
|
|
da7d1b6fa9 | ||
|
|
3129226839 | ||
|
|
6935acafff | ||
|
|
d8103f4fd6 | ||
|
|
09a13f4015 | ||
|
|
e888023102 | ||
|
|
f62f4736f0 | ||
|
|
a378272d56 | ||
|
|
3d61938fcf | ||
|
|
a9f3937da6 |
@@ -31,7 +31,7 @@ repositories {
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation 'com.google.android.filament:filament-android:1.29.0'
|
||||
implementation 'com.google.android.filament:filament-android:1.28.2'
|
||||
}
|
||||
```
|
||||
|
||||
@@ -51,7 +51,7 @@ Here are all the libraries available in the group `com.google.android.filament`:
|
||||
iOS projects can use CocoaPods to install the latest release:
|
||||
|
||||
```
|
||||
pod 'Filament', '~> 1.29.0'
|
||||
pod 'Filament', '~> 1.28.2'
|
||||
```
|
||||
|
||||
### Snapshots
|
||||
|
||||
@@ -5,8 +5,6 @@ A new header is inserted each time a *tag* is created.
|
||||
|
||||
## main branch
|
||||
|
||||
## v1.29.0
|
||||
|
||||
- gltfio: calculate primitive's AABB correctly.
|
||||
- gltfio: recompute bounding boxes with morph targets
|
||||
- engine: add missing getters on `MaterialInstance`
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
GROUP=com.google.android.filament
|
||||
VERSION_NAME=1.29.0
|
||||
VERSION_NAME=1.28.2
|
||||
|
||||
POM_DESCRIPTION=Real-time physically based rendering engine for Android.
|
||||
|
||||
|
||||
@@ -750,11 +750,6 @@ void RenderPass::Executor::execute(backend::DriverApi& driver,
|
||||
continue;
|
||||
}
|
||||
|
||||
// primitiveHandle may be invalid if no geometry was set on the renderable.
|
||||
if (UTILS_UNLIKELY(!first->primitive.primitiveHandle)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
// per-renderable uniform
|
||||
const PrimitiveInfo info = first->primitive;
|
||||
pipeline.rasterState = info.rasterState;
|
||||
|
||||
@@ -413,10 +413,41 @@ ShadowMap::ShaderParameters ShadowMap::updateDirectional(FEngine& engine,
|
||||
return shaderParameters;
|
||||
}
|
||||
|
||||
ShadowMap::ShaderParameters ShadowMap::updateSpotOrPoint(
|
||||
mat4f const& Mv, float outerConeAngle, float nearPlane, float farPlane,
|
||||
const ShadowMapInfo& shadowMapInfo, const FLightManager::ShadowParams& params) noexcept {
|
||||
const mat4f Mp = mat4f::perspective(outerConeAngle * f::RAD_TO_DEG * 2.0f, 1.0f, nearPlane, farPlane);
|
||||
ShadowMap::ShaderParameters ShadowMap::updateSpot(FEngine& engine,
|
||||
const FScene::LightSoa& lightData, size_t index,
|
||||
filament::CameraInfo const& camera,
|
||||
const ShadowMapInfo& shadowMapInfo,
|
||||
FScene const& scene, SceneInfo sceneInfo) noexcept {
|
||||
|
||||
ShaderParameters shaderParameters;
|
||||
|
||||
auto& lcm = engine.getLightManager();
|
||||
auto li = lightData.elementAt<FScene::LIGHT_INSTANCE>(index);
|
||||
auto position = lightData.elementAt<FScene::POSITION_RADIUS>(index).xyz;
|
||||
auto direction = lightData.elementAt<FScene::DIRECTION>(index);
|
||||
auto radius = lightData.elementAt<FScene::POSITION_RADIUS>(index).w;
|
||||
auto outerConeAngle = lcm.getSpotLightOuterCone(li);
|
||||
const FLightManager::ShadowParams& params = lcm.getShadowParams(li);
|
||||
|
||||
/*
|
||||
* Compute the light model matrix.
|
||||
*/
|
||||
|
||||
// Choose a reasonable value for the near plane.
|
||||
const mat4f Mv = getDirectionalLightViewMatrix(direction, position);
|
||||
|
||||
// find decent near/far
|
||||
ShadowMap::updateSceneInfoSpot(Mv, scene, sceneInfo);
|
||||
|
||||
// if the scene was empty, near > far
|
||||
mHasVisibleShadows = -sceneInfo.lsNearFar[0] < -sceneInfo.lsNearFar[1];
|
||||
|
||||
// FIXME: we need a configuration for minimum near plane (for now hardcoded to 1cm)
|
||||
float nearPlane = std::max(0.01f, -sceneInfo.lsNearFar[0]);
|
||||
float farPlane = std::min(radius, -sceneInfo.lsNearFar[1]);
|
||||
|
||||
float outerConeAngleDegrees = outerConeAngle * f::RAD_TO_DEG;
|
||||
const mat4f Mp = mat4f::perspective(outerConeAngleDegrees * 2.0f, 1.0f, nearPlane, farPlane);
|
||||
const mat4f MpMv(math::highPrecisionMultiply(Mp, Mv));
|
||||
|
||||
// Final shadow transform
|
||||
@@ -438,9 +469,7 @@ ShadowMap::ShaderParameters ShadowMap::updateSpotOrPoint(
|
||||
// = zInLightSpace * texelSizeAtOneMeter
|
||||
// = zInLightSpace * (2*tan(halfConeAngle)/dimension)
|
||||
// Note: this would not work with LISPSM, which warps the texture space.
|
||||
ShaderParameters shaderParameters;
|
||||
shaderParameters.texelSizeAtOneMeterWs =
|
||||
(2.0f * std::tan(outerConeAngle) / float(shadowMapInfo.shadowDimension));
|
||||
shaderParameters.texelSizeAtOneMeterWs = (2.0f * std::tan(outerConeAngle) / float(shadowMapInfo.shadowDimension));
|
||||
shaderParameters.lightFromWorldZ = -transpose(Mv)[2]; // negate because camera looks in -Z
|
||||
|
||||
if (!shadowMapInfo.vsm) {
|
||||
@@ -449,7 +478,78 @@ ShadowMap::ShaderParameters ShadowMap::updateSpotOrPoint(
|
||||
shaderParameters.lightSpace = computeVsmLightSpaceMatrix(St, Mv, nearPlane, farPlane);
|
||||
}
|
||||
|
||||
const float constantBias = shadowMapInfo.vsm ? 0.0f : params.options.constantBias;
|
||||
const mat4f b = mat4f::translation(direction * constantBias);
|
||||
const mat4f Sb = S * b;
|
||||
|
||||
// It's important to set the light camera's model matrix separately from its projection, so that
|
||||
// the cameraPosition uniform gets set correctly.
|
||||
// mLightSpace is used in the shader to access the shadow map texture, and has the model matrix
|
||||
// baked in.
|
||||
|
||||
// The model matrix below is in fact inverted to get the view matrix and passed to the
|
||||
// shader as 'viewFromWorldMatrix', and is used in the VSM case to compute the depth metric.
|
||||
// (see depth_main.fs). Note that in the case of VSM, 'b' below is identity.
|
||||
mCamera->setModelMatrix(mat4{ FCamera::rigidTransformInverse(Mv * b) });
|
||||
mCamera->setCustomProjection(mat4(Mp), nearPlane, farPlane);
|
||||
|
||||
// for the debug camera, we need to undo the world origin
|
||||
mDebugCamera->setCustomProjection(mat4(Sb * camera.worldOrigin), nearPlane, radius);
|
||||
|
||||
return shaderParameters;
|
||||
}
|
||||
|
||||
ShadowMap::ShaderParameters ShadowMap::updatePoint(FEngine& engine,
|
||||
const FScene::LightSoa& lightData, size_t index,
|
||||
filament::CameraInfo const& camera, const ShadowMapInfo& shadowMapInfo, FScene const& scene,
|
||||
SceneInfo, uint8_t face) noexcept {
|
||||
|
||||
ShaderParameters shaderParameters;
|
||||
|
||||
// check if this shadow map has anything to render
|
||||
mHasVisibleShadows = false;
|
||||
FScene::RenderableSoa const& UTILS_RESTRICT soa = scene.getRenderableData();
|
||||
auto const* const UTILS_RESTRICT visibleMasks = soa.data<FScene::VISIBLE_MASK>();
|
||||
size_t c = soa.size();
|
||||
for (size_t i = 0; i < c; i++) {
|
||||
if (visibleMasks[i] & VISIBLE_DYN_SHADOW_RENDERABLE) {
|
||||
mHasVisibleShadows = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!mHasVisibleShadows) {
|
||||
return shaderParameters;
|
||||
}
|
||||
|
||||
auto& lcm = engine.getLightManager();
|
||||
|
||||
auto li = lightData.elementAt<FScene::LIGHT_INSTANCE>(index);
|
||||
auto position = lightData.elementAt<FScene::POSITION_RADIUS>(index).xyz;
|
||||
auto radius = lightData.elementAt<FScene::POSITION_RADIUS>(index).w;
|
||||
const FLightManager::ShadowParams& params = lcm.getShadowParams(li);
|
||||
|
||||
/*
|
||||
* Compute the light model matrix.
|
||||
*/
|
||||
|
||||
const mat4f Mv = getPointLightViewMatrix(TextureCubemapFace(face), position);
|
||||
const float3 direction = -transpose(Mv)[2].xyz;
|
||||
|
||||
// TODO: don't hardcode near plane
|
||||
// Choose a reasonable value for the near plane.
|
||||
float nearPlane = 0.01f;
|
||||
float farPlane = radius;
|
||||
const mat4f Mp = mat4f::perspective(90.0f, 1.0f, nearPlane, farPlane);
|
||||
|
||||
// For calculating the point light normal bias, we need the texel size in world space at the
|
||||
// sample location. Using Thales's theorem, we find:
|
||||
// texelSize(zInLightSpace) = zInLightSpace * texelSizeOnTheNearPlane / near
|
||||
// = zInLightSpace * texelSizeAtOneMeter
|
||||
// = zInLightSpace * (2*tan(halfConeAngle)/dimension)
|
||||
// Note: this would not work with LISPSM, which warps the texture space.
|
||||
shaderParameters.texelSizeAtOneMeterWs =
|
||||
(2.0f * std::tan(f::PI_4) / float(shadowMapInfo.shadowDimension));
|
||||
|
||||
const float constantBias = shadowMapInfo.vsm ? 0.0f : params.options.constantBias;
|
||||
const mat4f b = mat4f::translation(direction * constantBias);
|
||||
|
||||
@@ -467,65 +567,6 @@ ShadowMap::ShaderParameters ShadowMap::updateSpotOrPoint(
|
||||
return shaderParameters;
|
||||
}
|
||||
|
||||
ShadowMap::ShaderParameters ShadowMap::updateSpot(FEngine& engine,
|
||||
const FScene::LightSoa& lightData, size_t index,
|
||||
filament::CameraInfo const& camera,
|
||||
const ShadowMapInfo& shadowMapInfo,
|
||||
FScene const& scene, SceneInfo sceneInfo) noexcept {
|
||||
|
||||
auto& lcm = engine.getLightManager();
|
||||
auto position = lightData.elementAt<FScene::POSITION_RADIUS>(index).xyz;
|
||||
auto direction = lightData.elementAt<FScene::DIRECTION>(index);
|
||||
auto radius = lightData.elementAt<FScene::POSITION_RADIUS>(index).w;
|
||||
auto li = lightData.elementAt<FScene::LIGHT_INSTANCE>(index);
|
||||
const FLightManager::ShadowParams& params = lcm.getShadowParams(li);
|
||||
const mat4f Mv = getDirectionalLightViewMatrix(direction, position);
|
||||
|
||||
// find decent near/far
|
||||
ShadowMap::updateSceneInfoSpot(Mv, scene, sceneInfo);
|
||||
|
||||
// if the scene was empty, near > far
|
||||
mHasVisibleShadows = -sceneInfo.lsNearFar[0] < -sceneInfo.lsNearFar[1];
|
||||
if (!mHasVisibleShadows) {
|
||||
return {};
|
||||
}
|
||||
|
||||
// FIXME: we need a configuration for minimum near plane (for now hardcoded to 1cm)
|
||||
float nearPlane = std::max(0.01f, -sceneInfo.lsNearFar[0]);
|
||||
float farPlane = std::min(radius, -sceneInfo.lsNearFar[1]);
|
||||
auto outerConeAngle = lcm.getSpotLightOuterCone(li);
|
||||
return updateSpotOrPoint(Mv, outerConeAngle, nearPlane, farPlane, shadowMapInfo, params);
|
||||
}
|
||||
|
||||
ShadowMap::ShaderParameters ShadowMap::updatePoint(FEngine& engine,
|
||||
const FScene::LightSoa& lightData, size_t index,
|
||||
filament::CameraInfo const& camera, const ShadowMapInfo& shadowMapInfo, FScene const& scene,
|
||||
SceneInfo, uint8_t face) noexcept {
|
||||
|
||||
// check if this shadow map has anything to render
|
||||
mHasVisibleShadows = false;
|
||||
FScene::RenderableSoa const& UTILS_RESTRICT soa = scene.getRenderableData();
|
||||
auto const* const UTILS_RESTRICT visibleMasks = soa.data<FScene::VISIBLE_MASK>();
|
||||
size_t c = soa.size();
|
||||
for (size_t i = 0; i < c; i++) {
|
||||
if (visibleMasks[i] & VISIBLE_DYN_SHADOW_RENDERABLE) {
|
||||
mHasVisibleShadows = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!mHasVisibleShadows) {
|
||||
return {};
|
||||
}
|
||||
|
||||
auto& lcm = engine.getLightManager();
|
||||
auto position = lightData.elementAt<FScene::POSITION_RADIUS>(index).xyz;
|
||||
auto radius = lightData.elementAt<FScene::POSITION_RADIUS>(index).w;
|
||||
auto li = lightData.elementAt<FScene::LIGHT_INSTANCE>(index);
|
||||
const FLightManager::ShadowParams& params = lcm.getShadowParams(li);
|
||||
const mat4f Mv = getPointLightViewMatrix(TextureCubemapFace(face), position);
|
||||
return updateSpotOrPoint(Mv, 45.0f * f::DEG_TO_RAD, 0.01f, radius, shadowMapInfo, params);
|
||||
}
|
||||
|
||||
mat4f ShadowMap::applyLISPSM(mat4f& Wp,
|
||||
filament::CameraInfo const& camera, FLightManager::ShadowParams const& params,
|
||||
mat4f const& LMpMv,
|
||||
|
||||
@@ -214,11 +214,6 @@ private:
|
||||
// 8 corners, 12 segments w/ 2 intersection max -- all of this twice (8 + 12 * 2) * 2 (768 bytes)
|
||||
using FrustumBoxIntersection = std::array<math::float3, 64>;
|
||||
|
||||
ShaderParameters updateSpotOrPoint(
|
||||
math::mat4f const& Mv, float outerConeAngle, float nearPlane, float farPlane,
|
||||
const ShadowMapInfo& shadowMapInfo,
|
||||
const FLightManager::ShadowParams& params) noexcept;
|
||||
|
||||
static math::mat4f applyLISPSM(math::mat4f& Wp,
|
||||
filament::CameraInfo const& camera, FLightManager::ShadowParams const& params,
|
||||
const math::mat4f& LMpMv,
|
||||
|
||||
@@ -690,7 +690,7 @@ void ShadowMapManager::prepareSpotShadowMap(ShadowMap& shadowMap,
|
||||
s.shadows[shadowIndex].elvsm = options->vsm.elvsm;
|
||||
s.shadows[shadowIndex].bulbRadiusLs =
|
||||
mSoftShadowOptions.penumbraScale * options->shadowBulbRadius
|
||||
/ wsTexelSizeAtOneMeter;
|
||||
/ wsTexelSizeAtOneMeter;
|
||||
|
||||
}
|
||||
}
|
||||
@@ -763,10 +763,15 @@ void ShadowMapManager::preparePointShadowMap(ShadowMap& shadowMap,
|
||||
const double n = shadowMap.getCamera().getNear();
|
||||
const double f = shadowMap.getCamera().getCullingFar();
|
||||
s.shadows[shadowIndex].layer = shadowMap.getLayer();
|
||||
s.shadows[shadowIndex].lightFromWorldMatrix = shaderParameters.lightSpace;
|
||||
s.shadows[shadowIndex].lightFromWorldMatrix = {}; // no texture matrix for point lights
|
||||
s.shadows[shadowIndex].direction = {}; // no direction of point lights
|
||||
s.shadows[shadowIndex].normalBias = normalBias * wsTexelSizeAtOneMeter;
|
||||
s.shadows[shadowIndex].lightFromWorldZ = shaderParameters.lightFromWorldZ;
|
||||
s.shadows[shadowIndex].lightFromWorldZ = {
|
||||
-((n + f) / (f - n)) * 0.5f + 0.5f,
|
||||
(f * n) / (f - n),
|
||||
-n / (f - n),
|
||||
1.0f / (f - n),
|
||||
};
|
||||
s.shadows[shadowIndex].texelSizeAtOneMeter = wsTexelSizeAtOneMeter;
|
||||
s.shadows[shadowIndex].nearOverFarMinusNear = float(n / (f - n));
|
||||
s.shadows[shadowIndex].elvsm = options->vsm.elvsm;
|
||||
|
||||
@@ -442,15 +442,9 @@ Program FMaterial::getProgramBuilderWithVariants(
|
||||
}
|
||||
}
|
||||
|
||||
int platformId = 0;
|
||||
#if defined(IOS)
|
||||
platformId = 1;
|
||||
#endif
|
||||
|
||||
program.specializationConstants({
|
||||
{ 0, (int)mEngine.getSupportedFeatureLevel() },
|
||||
{ 1, (int)CONFIG_MAX_INSTANCES },
|
||||
{ 2, platformId }
|
||||
{ 1, (int)CONFIG_MAX_INSTANCES }
|
||||
});
|
||||
|
||||
return program;
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
Pod::Spec.new do |spec|
|
||||
spec.name = "Filament"
|
||||
spec.version = "1.29.0"
|
||||
spec.version = "1.28.2"
|
||||
spec.license = { :type => "Apache 2.0", :file => "LICENSE" }
|
||||
spec.homepage = "https://google.github.io/filament"
|
||||
spec.authors = "Google LLC."
|
||||
spec.summary = "Filament is a real-time physically based rendering engine for Android, iOS, Windows, Linux, macOS, and WASM/WebGL."
|
||||
spec.platform = :ios, "11.0"
|
||||
spec.source = { :http => "https://github.com/google/filament/releases/download/v1.29.0/filament-v1.29.0-ios.tgz" }
|
||||
spec.source = { :http => "https://github.com/google/filament/releases/download/v1.28.2/filament-v1.28.2-ios.tgz" }
|
||||
|
||||
# Fix linking error with Xcode 12; we do not yet support the simulator on Apple silicon.
|
||||
spec.pod_target_xcconfig = {
|
||||
|
||||
@@ -247,10 +247,10 @@ static_assert(sizeof(LightsUib) == 64,
|
||||
struct ShadowUib { // NOLINT(cppcoreguidelines-pro-type-member-init)
|
||||
static constexpr std::string_view _name{ "ShadowUniforms" };
|
||||
struct alignas(16) ShadowData {
|
||||
math::mat4f lightFromWorldMatrix; // 64
|
||||
math::float3 direction; // 12
|
||||
float normalBias; // 4
|
||||
math::float4 lightFromWorldZ; // 16
|
||||
math::mat4f lightFromWorldMatrix; // 64 - unused for point lights
|
||||
math::float3 direction; // 12 - unused for point lights
|
||||
float normalBias; // 4 - unused for point lights
|
||||
math::float4 lightFromWorldZ; // 16 - point lights { depth reconstruction values }
|
||||
|
||||
float texelSizeAtOneMeter; // 4
|
||||
float bulbRadiusLs; // 4
|
||||
|
||||
@@ -35,11 +35,6 @@ Variant Variant::filterUserVariant(
|
||||
if (filterMask & (uint32_t)UserVariantFilterBit::FOG) {
|
||||
variant.key &= ~(filterMask & FOG);
|
||||
}
|
||||
} else {
|
||||
// depth variants can have their VSM bit filtered
|
||||
if (filterMask & (uint32_t)UserVariantFilterBit::VSM) {
|
||||
variant.key &= ~(filterMask & VSM);
|
||||
}
|
||||
}
|
||||
if (!isSSRVariant(variant)) {
|
||||
// SSR variant needs to be handled separately
|
||||
@@ -58,6 +53,8 @@ Variant Variant::filterUserVariant(
|
||||
return variant;
|
||||
}
|
||||
|
||||
|
||||
|
||||
namespace details {
|
||||
|
||||
// compile time sanity-check tests
|
||||
|
||||
@@ -123,7 +123,6 @@ utils::io::sstream& CodeGenerator::generateProlog(utils::io::sstream& out, Shade
|
||||
out << '\n';
|
||||
generateSpecificationConstant(out, "BACKEND_FEATURE_LEVEL", 0, 1);
|
||||
generateSpecificationConstant(out, "CONFIG_MAX_INSTANCES", 1, (int)CONFIG_MAX_INSTANCES);
|
||||
generateSpecificationConstant(out, "TARGET_PLATFORM", 2, 0);
|
||||
|
||||
out << '\n';
|
||||
out << SHADERS_COMMON_DEFINES_GLSL_DATA;
|
||||
|
||||
@@ -22,11 +22,3 @@
|
||||
|
||||
#define float3x3 mat3
|
||||
#define float4x4 mat4
|
||||
|
||||
#define TARGET_PLATFORM_UNKNOWN 0
|
||||
#define TARGET_PLATFORM_IOS 1
|
||||
#if defined(TARGET_GLES_ENVIRONMENT)
|
||||
const bool openGlesIos = TARGET_PLATFORM == TARGET_PLATFORM_IOS;
|
||||
#else
|
||||
const bool openGlesIos = false;
|
||||
#endif
|
||||
|
||||
@@ -128,7 +128,7 @@ highp vec4 getCascadeLightSpacePosition(uint cascade) {
|
||||
// For the first cascade, return the interpolated light space position.
|
||||
// This branch will be coherent (mostly) for neighboring fragments, and it's worth avoiding
|
||||
// the matrix multiply inside computeLightSpacePosition.
|
||||
if (cascade == 0u && !openGlesIos) {
|
||||
if (cascade == 0u) {
|
||||
// Note: this branch may cause issues with derivatives
|
||||
return vertex_lightSpacePosition;
|
||||
}
|
||||
|
||||
@@ -211,15 +211,18 @@ void evaluatePunctualLights(const MaterialInputs material,
|
||||
if (light.NoL > 0.0) {
|
||||
if (light.castsShadows) {
|
||||
uint shadowIndex = light.shadowIndex;
|
||||
highp vec4 shadowPosition;
|
||||
if (light.type == LIGHT_TYPE_POINT) {
|
||||
// point-light shadows are sampled from a direction
|
||||
highp vec3 r = getWorldPosition() - light.worldPosition;
|
||||
uint face = getPointLightFace(r);
|
||||
highp uint face = 0u;
|
||||
// getShadowPosition returns zLight which is needed for PCSS/DPCF
|
||||
shadowPosition = getShadowPosition(r, shadowIndex, light.zLight, face);
|
||||
shadowIndex += face;
|
||||
light.zLight = dot(shadowUniforms.shadows[shadowIndex].lightFromWorldZ,
|
||||
vec4(getWorldPosition(), 1.0));
|
||||
} else {
|
||||
// getShadowPosition needs zLight for applying the normal bias
|
||||
shadowPosition = getShadowPosition(false, shadowIndex, 0u, light.zLight);
|
||||
}
|
||||
highp vec4 shadowPosition = getShadowPosition(false, shadowIndex, 0u, light.zLight);
|
||||
visibility = shadow(false, light_shadowMap, shadowIndex,
|
||||
shadowPosition, light.zLight);
|
||||
}
|
||||
|
||||
@@ -141,16 +141,11 @@ void main() {
|
||||
#endif
|
||||
|
||||
#if defined(VARIANT_HAS_SHADOWING) && defined(VARIANT_HAS_DIRECTIONAL_LIGHTING)
|
||||
if (openGlesIos) {
|
||||
// Hack for OpenGL ES on iOS.
|
||||
vertex_lightSpacePosition = vec4(1.0);
|
||||
} else {
|
||||
vertex_lightSpacePosition = computeLightSpacePosition(
|
||||
vertex_worldPosition.xyz, vertex_worldNormal,
|
||||
frameUniforms.lightDirection,
|
||||
shadowUniforms.shadows[0].normalBias,
|
||||
shadowUniforms.shadows[0].lightFromWorldMatrix);
|
||||
}
|
||||
vertex_lightSpacePosition = computeLightSpacePosition(
|
||||
vertex_worldPosition.xyz, vertex_worldNormal,
|
||||
frameUniforms.lightDirection,
|
||||
shadowUniforms.shadows[0].normalBias,
|
||||
shadowUniforms.shadows[0].lightFromWorldMatrix);
|
||||
#endif
|
||||
|
||||
#endif // !defined(USE_OPTIMIZED_DEPTH_VERTEX_SHADER)
|
||||
|
||||
@@ -494,20 +494,51 @@ highp vec4 getShadowPosition(const bool DIRECTIONAL,
|
||||
return p;
|
||||
}
|
||||
|
||||
|
||||
uint getPointLightFace(const highp vec3 r) {
|
||||
// get {texture coordinate, layer} for point shadow maps
|
||||
highp vec4 getShadowPosition(const highp vec3 r, const highp uint shadowIndex,
|
||||
out highp float d, out highp uint face) {
|
||||
highp vec4 tc;
|
||||
highp float rx = abs(r.x);
|
||||
highp float ry = abs(r.y);
|
||||
highp float rz = abs(r.z);
|
||||
highp float d = max(rx, max(ry, rz));
|
||||
d = max(rx, max(ry, rz));
|
||||
highp float ma = 1.0 / d;
|
||||
if (d == rx) {
|
||||
return (r.x >= 0.0 ? 0u : 1u);
|
||||
tc.x = r.x >= 0.0 ? r.z : -r.z;
|
||||
tc.y = r.y;
|
||||
face = (r.x >= 0.0 ? 0u : 1u);
|
||||
} else if (d == ry) {
|
||||
return (r.y >= 0.0 ? 2u : 3u);
|
||||
tc.x = r.y >= 0.0 ? r.x : -r.x;
|
||||
tc.y = r.z;
|
||||
face = (r.y >= 0.0 ? 2u : 3u);
|
||||
} else {
|
||||
return (r.z >= 0.0 ? 4u : 5u);
|
||||
tc.x = r.z >= 0.0 ? -r.x : r.x;
|
||||
tc.y = r.y;
|
||||
face = (r.z >= 0.0 ? 4u : 5u);
|
||||
}
|
||||
|
||||
// ma is guaranteed to be >= sc and tc
|
||||
tc.xy = (tc.xy * ma + vec2(1.0)) * 0.5;
|
||||
|
||||
highp vec4 nf = shadowUniforms.shadows[shadowIndex + face].lightFromWorldZ;
|
||||
|
||||
// z coordinate of the normalized fragment position in light-space
|
||||
// i.e.: remap [near, far] to [0,1] : d = (d - n) / (f - n)
|
||||
d = nf[2] + nf[3] * d;
|
||||
|
||||
if (frameUniforms.shadowSamplingType == SHADOW_SAMPLING_RUNTIME_EVSM) {
|
||||
// for VSM, the depth metric is linear normalized in light-space
|
||||
tc.z = d;
|
||||
} else {
|
||||
// for other types of shadows it's clip-space depth. Below is an optimized version of
|
||||
// (lightProjection * position).z
|
||||
tc.z = nf[0] + nf[1] * ma;
|
||||
}
|
||||
|
||||
// FIXME: the normal bias is not applied
|
||||
|
||||
tc.w = 1.0;
|
||||
return tc;
|
||||
}
|
||||
|
||||
// PCF sampling
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "filament",
|
||||
"version": "1.29.0",
|
||||
"version": "1.28.2",
|
||||
"description": "Real-time physically based rendering engine",
|
||||
"main": "filament.js",
|
||||
"module": "filament.js",
|
||||
|
||||
Reference in New Issue
Block a user