matc: treat DYN DIR and SRE as spec constants
This commit does not exhaustively replace these variants with spec constants. Rather, this is a necessary first step into full replacement. As was the case before this commit, all combinations of variants are still generated as their own individual sources. However, matc has been changed in the way that it generates these variants, such that it will be trivial to later remove them. Firstly, instead of matc selectively generating specific uniform buffers and structs specific to these variants per-specialization, generates them *always* as long as the specialization "has lighting". Specifically, a specialization "has lighting" if all of the following conditions are true: - It's a lit material, or it's an unlit material with a shadow multiplier. - It's not an SSR variant. As a result, there is some redundant, potentially unused code generated in all variants. Additionally, all shader code has been refactored to replace `#if VARIANT_X` preprocessor directives with `if (MATERIAL_HAS_X)` statements, where `MATERIAL_HAS_X` is a spec constant. The *only difference* the code generated between a specialization with DYN, DIR, and SRE turned on or off is the *default value* of this spec constant. Technically, assuming that all shader code optimizations are deterministic, we should see some reduction of material file sizes, since only one line of code would differ between these variants being turned on and left off. However, we may add to some of that size given the redundant information added to all other variants. I tested this experimentally by compiling gltf_viewer at this commit and the commit before it in release mode and totalling the size of all of the filamat files generated. - Parent commit: 44.44 MiB - This commit: 36.67 MiB So we have a reduction of about 8 MiB, which is around 20% of the original file size. (Note that I took these measurements a long time ago and they might not be still accurate...)
This commit is contained in:
@@ -85,6 +85,9 @@ enum class ReservedSpecializationConstants : uint8_t {
|
||||
CONFIG_SH_BANDS_COUNT = 9,
|
||||
CONFIG_SHADOW_SAMPLING_METHOD = 10,
|
||||
CONFIG_FROXEL_RECORD_BUFFER_HEIGHT = 11,
|
||||
CONFIG_HAS_DIRECTIONAL_LIGHTING = 12,
|
||||
CONFIG_HAS_DYNAMIC_LIGHTING = 13,
|
||||
CONFIG_HAS_SHADOWING = 14,
|
||||
// check CONFIG_NEXT_RESERVED_SPEC_CONSTANT and CONFIG_MAX_RESERVED_SPEC_CONSTANTS below
|
||||
};
|
||||
|
||||
@@ -107,7 +110,7 @@ constexpr size_t CONFIG_MAX_LIGHT_INDEX = CONFIG_MAX_LIGHT_COUNT - 1;
|
||||
// Updating this value necessitates a material version bump.
|
||||
constexpr size_t CONFIG_MAX_RESERVED_SPEC_CONSTANTS = 16;
|
||||
// The number of the next unassigned reserved spec constant.
|
||||
constexpr size_t CONFIG_NEXT_RESERVED_SPEC_CONSTANT = 12;
|
||||
constexpr size_t CONFIG_NEXT_RESERVED_SPEC_CONSTANT = 15;
|
||||
|
||||
// The maximum number of shadow maps possible.
|
||||
// There is currently a maximum limit of 128 shadow maps.
|
||||
|
||||
@@ -358,6 +358,21 @@ utils::io::sstream& CodeGenerator::generateCommonProlog(utils::io::sstream& out,
|
||||
+ReservedSpecializationConstants::CONFIG_SRGB_SWAPCHAIN_EMULATION, false);
|
||||
}
|
||||
|
||||
// Generate specialization constants for "minor variants".
|
||||
//
|
||||
// HACK: Setting the default values like this is a temporary measure for switching variants to
|
||||
// spec constants.
|
||||
bool const litVariants = material.isLit || material.hasShadowMultiplier;
|
||||
generateSpecializationConstant(out, "CONFIG_HAS_DIRECTIONAL_LIGHTING",
|
||||
+ReservedSpecializationConstants::CONFIG_HAS_DIRECTIONAL_LIGHTING,
|
||||
litVariants && v.hasDirectionalLighting());
|
||||
generateSpecializationConstant(out, "CONFIG_HAS_DYNAMIC_LIGHTING",
|
||||
+ReservedSpecializationConstants::CONFIG_HAS_DYNAMIC_LIGHTING,
|
||||
litVariants && v.hasDynamicLighting());
|
||||
generateSpecializationConstant(out, "CONFIG_HAS_SHADOWING",
|
||||
+ReservedSpecializationConstants::CONFIG_HAS_SHADOWING,
|
||||
litVariants && filament::Variant::isShadowReceiverVariant(v));
|
||||
|
||||
out << '\n';
|
||||
out << SHADERS_COMMON_DEFINES_GLSL_DATA;
|
||||
|
||||
@@ -1160,10 +1175,9 @@ io::sstream& CodeGenerator::generateSurfaceLit(io::sstream& out, ShaderStage sta
|
||||
filament::Variant variant, Shading shading, bool customSurfaceShading) {
|
||||
if (stage == ShaderStage::FRAGMENT) {
|
||||
out << SHADERS_SURFACE_LIGHTING_FS_DATA;
|
||||
if (filament::Variant::isShadowReceiverVariant(variant)) {
|
||||
if (!filament::Variant::isSSRVariant(variant)) {
|
||||
out << SHADERS_SURFACE_SHADOWING_FS_DATA;
|
||||
}
|
||||
|
||||
// the only reason we have this assert here is that we used to have a check,
|
||||
// which seemed unnecessary.
|
||||
assert_invariant(shading != Shading::UNLIT);
|
||||
@@ -1191,14 +1205,8 @@ io::sstream& CodeGenerator::generateSurfaceLit(io::sstream& out, ShaderStage sta
|
||||
|
||||
out << SHADERS_SURFACE_AMBIENT_OCCLUSION_FS_DATA;
|
||||
out << SHADERS_SURFACE_LIGHT_INDIRECT_FS_DATA;
|
||||
|
||||
if (variant.hasDirectionalLighting()) {
|
||||
out << SHADERS_SURFACE_LIGHT_DIRECTIONAL_FS_DATA;
|
||||
}
|
||||
if (variant.hasDynamicLighting()) {
|
||||
out << SHADERS_SURFACE_LIGHT_PUNCTUAL_FS_DATA;
|
||||
}
|
||||
|
||||
out << SHADERS_SURFACE_LIGHT_DIRECTIONAL_FS_DATA;
|
||||
out << SHADERS_SURFACE_LIGHT_PUNCTUAL_FS_DATA;
|
||||
out << SHADERS_SURFACE_SHADING_LIT_FS_DATA;
|
||||
}
|
||||
return out;
|
||||
@@ -1207,10 +1215,8 @@ io::sstream& CodeGenerator::generateSurfaceLit(io::sstream& out, ShaderStage sta
|
||||
io::sstream& CodeGenerator::generateSurfaceUnlit(io::sstream& out, ShaderStage stage,
|
||||
filament::Variant variant, bool hasShadowMultiplier) {
|
||||
if (stage == ShaderStage::FRAGMENT) {
|
||||
if (hasShadowMultiplier) {
|
||||
if (filament::Variant::isShadowReceiverVariant(variant)) {
|
||||
out << SHADERS_SURFACE_SHADOWING_FS_DATA;
|
||||
}
|
||||
if (hasShadowMultiplier && !filament::Variant::isSSRVariant(variant)) {
|
||||
out << SHADERS_SURFACE_SHADOWING_FS_DATA;
|
||||
}
|
||||
out << SHADERS_SURFACE_SHADING_UNLIT_FS_DATA;
|
||||
}
|
||||
|
||||
@@ -51,14 +51,6 @@ void ShaderGenerator::generateSurfaceMaterialVariantDefines(io::sstream& out,
|
||||
ShaderStage const stage, MaterialBuilder::FeatureLevel featureLevel,
|
||||
MaterialInfo const& material, filament::Variant const variant) noexcept {
|
||||
|
||||
bool const litVariants = material.isLit || material.hasShadowMultiplier;
|
||||
|
||||
CodeGenerator::generateDefine(out, "VARIANT_HAS_DIRECTIONAL_LIGHTING",
|
||||
litVariants && variant.hasDirectionalLighting());
|
||||
CodeGenerator::generateDefine(out, "VARIANT_HAS_DYNAMIC_LIGHTING",
|
||||
litVariants && variant.hasDynamicLighting());
|
||||
CodeGenerator::generateDefine(out, "VARIANT_HAS_SHADOWING",
|
||||
litVariants && filament::Variant::isShadowReceiverVariant(variant));
|
||||
CodeGenerator::generateDefine(out, "VARIANT_HAS_VSM",
|
||||
filament::Variant::isShadowSampler2DVariant(variant) ||
|
||||
filament::Variant::isDepthMomentsVariant(variant));
|
||||
@@ -90,6 +82,8 @@ void ShaderGenerator::generateSurfaceMaterialVariantDefines(io::sstream& out,
|
||||
CodeGenerator::generateDefine(out, "MATERIAL_HAS_SHADOW_MULTIPLIER",
|
||||
material.hasShadowMultiplier);
|
||||
|
||||
CodeGenerator::generateDefine(out, "MATERIAL_HAS_LIGHTING", hasLighting(material, variant));
|
||||
|
||||
CodeGenerator::generateDefine(out, "MATERIAL_HAS_INSTANCES", material.instanced);
|
||||
|
||||
CodeGenerator::generateDefine(out, "MATERIAL_HAS_VERTEX_DOMAIN_DEVICE_JITTERED",
|
||||
@@ -465,8 +459,7 @@ std::string ShaderGenerator::createSurfaceVertexProgram(ShaderModel const shader
|
||||
+PerRenderableBindingPoints::OBJECT_UNIFORMS,
|
||||
UibGenerator::getPerRenderableUib());
|
||||
|
||||
const bool litVariants = material.isLit || material.hasShadowMultiplier;
|
||||
if (litVariants && filament::Variant::isShadowReceiverVariant(variant)) {
|
||||
if (hasLighting(material, variant)) {
|
||||
cg.generateUniforms(vs, ShaderStage::FRAGMENT,
|
||||
DescriptorSetBindingPoints::PER_VIEW,
|
||||
+PerViewBindingPoints::SHADOWS,
|
||||
@@ -573,22 +566,17 @@ std::string ShaderGenerator::createSurfaceFragmentProgram(ShaderModel const shad
|
||||
+PerRenderableBindingPoints::OBJECT_UNIFORMS,
|
||||
UibGenerator::getPerRenderableUib());
|
||||
|
||||
if (variant.hasDynamicLighting()) {
|
||||
if (hasLighting(material, variant)) {
|
||||
cg.generateUniforms(fs, ShaderStage::FRAGMENT,
|
||||
DescriptorSetBindingPoints::PER_VIEW,
|
||||
+PerViewBindingPoints::LIGHTS,
|
||||
UibGenerator::getLightsUib());
|
||||
}
|
||||
|
||||
bool const litVariants = material.isLit || material.hasShadowMultiplier;
|
||||
if (litVariants && filament::Variant::isShadowReceiverVariant(variant)) {
|
||||
cg.generateUniforms(fs, ShaderStage::FRAGMENT,
|
||||
DescriptorSetBindingPoints::PER_VIEW,
|
||||
+PerViewBindingPoints::SHADOWS,
|
||||
UibGenerator::getShadowUib());
|
||||
}
|
||||
|
||||
if (variant.hasDynamicLighting()) {
|
||||
cg.generateUniforms(fs, ShaderStage::FRAGMENT,
|
||||
DescriptorSetBindingPoints::PER_VIEW,
|
||||
+PerViewBindingPoints::RECORD_BUFFER,
|
||||
@@ -837,4 +825,10 @@ bool ShaderGenerator::hasStereo(
|
||||
&& featureLevel > MaterialBuilder::FeatureLevel::FEATURE_LEVEL_0;
|
||||
}
|
||||
|
||||
bool ShaderGenerator::hasLighting(
|
||||
MaterialInfo const& material, filament::Variant const variant) noexcept {
|
||||
return (material.isLit || material.hasShadowMultiplier)
|
||||
&& !filament::Variant::isSSRVariant(variant);
|
||||
}
|
||||
|
||||
} // namespace filament
|
||||
|
||||
@@ -130,6 +130,8 @@ private:
|
||||
filament::Variant variant,
|
||||
MaterialBuilder::FeatureLevel featureLevel) noexcept;
|
||||
|
||||
static bool hasLighting(MaterialInfo const& material, filament::Variant variant) noexcept;
|
||||
|
||||
MaterialBuilder::PropertyList mProperties;
|
||||
MaterialBuilder::VariableList mVariables;
|
||||
MaterialBuilder::OutputList mOutputs;
|
||||
|
||||
@@ -106,7 +106,8 @@ highp vec3 getNormalizedViewportCoord() {
|
||||
return vec3(logicalUv, gl_FragCoord.z);
|
||||
}
|
||||
|
||||
#if defined(VARIANT_HAS_SHADOWING) && defined(VARIANT_HAS_DYNAMIC_LIGHTING)
|
||||
#if defined(MATERIAL_HAS_LIGHTING)
|
||||
/* Depends on DYN | SRE */
|
||||
highp vec4 getSpotLightSpacePosition(int index, highp vec3 dir, highp float zLight) {
|
||||
highp mat4 lightFromWorldMatrix = shadowUniforms.shadows[index].lightFromWorldMatrix;
|
||||
|
||||
@@ -124,10 +125,12 @@ bool isDoubleSided() {
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(VARIANT_HAS_SHADOWING) && defined(VARIANT_HAS_DIRECTIONAL_LIGHTING)
|
||||
#if defined(MATERIAL_HAS_LIGHTING)
|
||||
|
||||
/**
|
||||
* Returns the cascade index for this fragment (between 0 and CONFIG_MAX_SHADOW_CASCADES - 1).
|
||||
*
|
||||
* Depends on DIR | SRE
|
||||
*/
|
||||
int getShadowCascade() {
|
||||
highp float z = mulMat4x4Float3(getViewFromWorldMatrix(), getWorldPosition()).z;
|
||||
@@ -136,6 +139,7 @@ int getShadowCascade() {
|
||||
return clamp(greaterZ.x + greaterZ.y + greaterZ.z + greaterZ.w, 0, cascadeCount - 1);
|
||||
}
|
||||
|
||||
/* Depends on DIR | SRE */
|
||||
highp vec4 getCascadeLightSpacePosition(int 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
|
||||
@@ -152,4 +156,3 @@ highp vec4 getCascadeLightSpacePosition(int cascade) {
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
@@ -48,8 +48,8 @@ void evaluateDirectionalLight(const MaterialInputs material,
|
||||
#endif
|
||||
|
||||
float visibility = 1.0;
|
||||
#if defined(VARIANT_HAS_SHADOWING)
|
||||
if (light.NoL > 0.0) {
|
||||
#if defined(MATERIAL_HAS_LIGHTING)
|
||||
if (CONFIG_HAS_SHADOWING && light.NoL > 0.0) {
|
||||
float ssContactShadowOcclusion = 0.0;
|
||||
|
||||
int cascade = getShadowCascade();
|
||||
|
||||
@@ -154,17 +154,19 @@ Light getLight(const uint lightIndex) {
|
||||
light.worldPosition = positionFalloff.xyz;
|
||||
light.channels = int(channels);
|
||||
light.contactShadows = bool(typeShadow & 0x10u);
|
||||
#if defined(VARIANT_HAS_DYNAMIC_LIGHTING)
|
||||
light.lightType = (typeShadow & 0x1u);
|
||||
#if defined(VARIANT_HAS_SHADOWING)
|
||||
light.shadowIndex = int((typeShadow >> 8u) & 0xFFu);
|
||||
light.castsShadows = bool(channels & 0x10000u);
|
||||
if (light.lightType == LIGHT_TYPE_SPOT) {
|
||||
light.zLight = dot(shadowUniforms.shadows[light.shadowIndex].lightFromWorldZ, vec4(worldPosition, 1.0));
|
||||
}
|
||||
#endif
|
||||
if (light.lightType == LIGHT_TYPE_SPOT) {
|
||||
light.attenuation *= getAngleAttenuation(-direction, light.l, scaleOffset);
|
||||
#if defined(MATERIAL_HAS_LIGHTING)
|
||||
if (CONFIG_HAS_DYNAMIC_LIGHTING) {
|
||||
light.lightType = (typeShadow & 0x1u);
|
||||
if (CONFIG_HAS_SHADOWING) {
|
||||
light.shadowIndex = int((typeShadow >> 8u) & 0xFFu);
|
||||
light.castsShadows = bool(channels & 0x10000u);
|
||||
if (light.lightType == LIGHT_TYPE_SPOT) {
|
||||
light.zLight = dot(shadowUniforms.shadows[light.shadowIndex].lightFromWorldZ, vec4(worldPosition, 1.0));
|
||||
}
|
||||
}
|
||||
if (light.lightType == LIGHT_TYPE_SPOT) {
|
||||
light.attenuation *= getAngleAttenuation(-direction, light.l, scaleOffset);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return light;
|
||||
@@ -207,8 +209,8 @@ void evaluatePunctualLights(const MaterialInputs material,
|
||||
#endif
|
||||
|
||||
float visibility = 1.0;
|
||||
#if defined(VARIANT_HAS_SHADOWING)
|
||||
if (light.NoL > 0.0) {
|
||||
#if defined(MATERIAL_HAS_LIGHTING)
|
||||
if (CONFIG_HAS_SHADOWING && light.NoL > 0.0) {
|
||||
if (light.castsShadows) {
|
||||
int shadowIndex = light.shadowIndex;
|
||||
if (light.lightType == LIGHT_TYPE_POINT) {
|
||||
|
||||
@@ -92,8 +92,10 @@ void main() {
|
||||
fragColor.rgb = fragColor.rgb * (1.0 - fogColor.a) + fogColor.rgb;
|
||||
#endif
|
||||
|
||||
#if defined(VARIANT_HAS_SHADOWING) && defined(VARIANT_HAS_DIRECTIONAL_LIGHTING)
|
||||
if (CONFIG_DEBUG_DIRECTIONAL_SHADOWMAP) {
|
||||
#if defined(MATERIAL_HAS_LIGHTING)
|
||||
if (CONFIG_HAS_SHADOWING
|
||||
&& CONFIG_HAS_DIRECTIONAL_LIGHTING
|
||||
&& CONFIG_DEBUG_DIRECTIONAL_SHADOWMAP) {
|
||||
float a = fragColor.a;
|
||||
highp vec4 p = getShadowPosition(getShadowCascade());
|
||||
p.xy = p.xy * (1.0 / p.w);
|
||||
|
||||
@@ -162,12 +162,14 @@ void main() {
|
||||
vertex_worldNormal = material.worldNormal;
|
||||
#endif
|
||||
|
||||
#if defined(VARIANT_HAS_SHADOWING) && defined(VARIANT_HAS_DIRECTIONAL_LIGHTING)
|
||||
vertex_lightSpacePosition = computeLightSpacePosition(
|
||||
vertex_worldPosition.xyz, vertex_worldNormal,
|
||||
frameUniforms.lightDirection,
|
||||
shadowUniforms.shadows[0].normalBias,
|
||||
shadowUniforms.shadows[0].lightFromWorldMatrix);
|
||||
#if defined(MATERIAL_HAS_LIGHTING)
|
||||
if (CONFIG_HAS_SHADOWING && CONFIG_HAS_DIRECTIONAL_LIGHTING) {
|
||||
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)
|
||||
|
||||
@@ -289,12 +289,14 @@ vec4 evaluateLights(const MaterialInputs material) {
|
||||
// it also saves 1 shader variant
|
||||
evaluateIBL(material, pixel, color);
|
||||
|
||||
#if defined(VARIANT_HAS_DIRECTIONAL_LIGHTING)
|
||||
evaluateDirectionalLight(material, pixel, color);
|
||||
#endif
|
||||
#if defined(MATERIAL_HAS_LIGHTING)
|
||||
if (CONFIG_HAS_DIRECTIONAL_LIGHTING) {
|
||||
evaluateDirectionalLight(material, pixel, color);
|
||||
}
|
||||
|
||||
#if defined(VARIANT_HAS_DYNAMIC_LIGHTING)
|
||||
evaluatePunctualLights(material, pixel, color);
|
||||
if (CONFIG_HAS_DYNAMIC_LIGHTING) {
|
||||
evaluatePunctualLights(material, pixel, color);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(BLEND_MODE_FADE) && !defined(SHADING_MODEL_UNLIT)
|
||||
|
||||
@@ -38,39 +38,43 @@ vec4 fixupAlpha(vec4 color) {
|
||||
vec4 evaluateMaterial(const MaterialInputs material) {
|
||||
vec4 color = material.baseColor;
|
||||
|
||||
#if defined(VARIANT_HAS_DIRECTIONAL_LIGHTING)
|
||||
#if defined(VARIANT_HAS_SHADOWING)
|
||||
float visibility = 1.0;
|
||||
int cascade = getShadowCascade();
|
||||
bool cascadeHasVisibleShadows = bool(frameUniforms.cascades & ((1 << cascade) << 8));
|
||||
bool hasDirectionalShadows = bool(frameUniforms.directionalShadows & 1);
|
||||
if (hasDirectionalShadows && cascadeHasVisibleShadows) {
|
||||
highp vec4 shadowPosition = getShadowPosition(cascade);
|
||||
visibility = shadow(true, sampler0_shadowMap, cascade, shadowPosition, 0.0);
|
||||
#if defined(MATERIAL_HAS_LIGHTING)
|
||||
if (CONFIG_HAS_DIRECTIONAL_LIGHTING) {
|
||||
if (CONFIG_HAS_SHADOWING) {
|
||||
float visibility = 1.0;
|
||||
int cascade = getShadowCascade();
|
||||
bool cascadeHasVisibleShadows = bool(frameUniforms.cascades & ((1 << cascade) << 8));
|
||||
bool hasDirectionalShadows = bool(frameUniforms.directionalShadows & 1);
|
||||
if (hasDirectionalShadows && cascadeHasVisibleShadows) {
|
||||
highp vec4 shadowPosition = getShadowPosition(cascade);
|
||||
visibility = shadow(true, sampler0_shadowMap, cascade, shadowPosition, 0.0);
|
||||
#if defined(MATERIAL_HAS_SHADOW_STRENGTH)
|
||||
applyShadowStrength(visibility, material.shadowStrength);
|
||||
#endif
|
||||
#if defined (FILAMENT_SHADOW_FAR_ATTENUATION)
|
||||
// shadow far attenuation
|
||||
highp vec3 v = getWorldPosition() - getWorldCameraPosition();
|
||||
// (viewFromWorld * v).z == dot(transpose(viewFromWorld), v)
|
||||
highp float z = dot(transpose(getViewFromWorldMatrix())[2].xyz, v);
|
||||
highp vec2 p = frameUniforms.shadowFarAttenuationParams;
|
||||
visibility = 1.0 - ((1.0 - visibility) * saturate(p.x - z * z * p.y));
|
||||
#endif
|
||||
}
|
||||
if ((frameUniforms.directionalShadows & 0x2) != 0 && visibility > 0.0) {
|
||||
if ((object_uniforms_flagsChannels & FILAMENT_OBJECT_CONTACT_SHADOWS_BIT) != 0) {
|
||||
visibility *= (1.0 - screenSpaceContactShadow(frameUniforms.lightDirection));
|
||||
}
|
||||
}
|
||||
color *= 1.0 - visibility;
|
||||
#else
|
||||
color = vec4(0.0);
|
||||
#endif
|
||||
#elif defined(MATERIAL_HAS_SHADOW_MULTIPLIER)
|
||||
color = vec4(0.0);
|
||||
#endif
|
||||
applyShadowStrength(visibility, material.shadowStrength);
|
||||
#endif // MATERIAL_HAS_SHADOW_STRENGTH
|
||||
#if defined(FILAMENT_SHADOW_FAR_ATTENUATION)
|
||||
// shadow far attenuation
|
||||
highp vec3 v = getWorldPosition() - getWorldCameraPosition();
|
||||
// (viewFromWorld * v).z == dot(transpose(viewFromWorld), v)
|
||||
highp float z = dot(transpose(getViewFromWorldMatrix())[2].xyz, v);
|
||||
highp vec2 p = frameUniforms.shadowFarAttenuationParams;
|
||||
visibility = 1.0 - ((1.0 - visibility) * saturate(p.x - z * z * p.y));
|
||||
#endif // FILAMENT_SHADOW_FAR_ATTENUATION
|
||||
}
|
||||
if ((frameUniforms.directionalShadows & 0x2) != 0 && visibility > 0.0) {
|
||||
if ((object_uniforms_flagsChannels & FILAMENT_OBJECT_CONTACT_SHADOWS_BIT) != 0) {
|
||||
visibility *= (1.0 - screenSpaceContactShadow(frameUniforms.lightDirection));
|
||||
}
|
||||
}
|
||||
color *= 1.0 - visibility;
|
||||
} else {
|
||||
color = vec4(0.0);
|
||||
} // CONFIG_HAS_SHADOWING
|
||||
} else {
|
||||
#if defined(MATERIAL_HAS_SHADOW_MULTIPLIER)
|
||||
color = vec4(0.0);
|
||||
#endif // MATERIAL_HAS_SHADOW_MULTIPLIER
|
||||
} // CONFIG_HAS_DIRECTIONAL_LIGHTING
|
||||
#endif // MATERIAL_HAS_LIGHTING
|
||||
|
||||
addEmissive(material, color);
|
||||
|
||||
|
||||
@@ -504,14 +504,14 @@ float screenSpaceContactShadow(vec3 lightDirection) {
|
||||
* the light intensity.
|
||||
*/
|
||||
|
||||
#if defined(MATERIAL_HAS_LIGHTING)
|
||||
// get texture coordinate for directional and spot shadow maps
|
||||
#if defined(VARIANT_HAS_DIRECTIONAL_LIGHTING)
|
||||
// Depends on DIR
|
||||
highp vec4 getShadowPosition(const int cascade) {
|
||||
return getCascadeLightSpacePosition(cascade);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(VARIANT_HAS_DYNAMIC_LIGHTING)
|
||||
// Depends on DYN
|
||||
highp vec4 getShadowPosition(const int index, const highp vec3 dir, const highp float zLight) {
|
||||
return getSpotLightSpacePosition(index, dir, zLight);
|
||||
}
|
||||
|
||||
@@ -2,13 +2,15 @@
|
||||
// Shadowing
|
||||
//------------------------------------------------------------------------------
|
||||
|
||||
#if defined(VARIANT_HAS_SHADOWING)
|
||||
#if defined(MATERIAL_HAS_LIGHTING)
|
||||
/**
|
||||
* Computes the light space position of the specified world space point.
|
||||
* The returned point may contain a bias to attempt to eliminate common
|
||||
* shadowing artifacts such as "acne". To achieve this, the world space
|
||||
* normal at the point must also be passed to this function.
|
||||
* Normal bias is not used for VSM.
|
||||
*
|
||||
* Depends on SRE
|
||||
*/
|
||||
|
||||
highp vec4 computeLightSpacePosition(highp vec3 p, const highp vec3 n,
|
||||
@@ -62,4 +64,4 @@ highp vec4 computeLightSpacePosition(highp vec3 p, const highp vec3 n,
|
||||
return mulMat4x4Float3(lightFromWorldMatrix, p);
|
||||
}
|
||||
|
||||
#endif // VARIANT_HAS_SHADOWING
|
||||
#endif // MATERIAL_HAS_LIGHTING
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
#if defined(VARIANT_HAS_SHADOWING)
|
||||
#if defined(MATERIAL_HAS_LIGHTING)
|
||||
// Adreno drivers seem to ignore precision qualifiers in structs, unless they're used in
|
||||
// UBOs, which is the case here.
|
||||
//
|
||||
// Depends on SRE
|
||||
struct ShadowData {
|
||||
highp mat4 lightFromWorldMatrix;
|
||||
highp vec4 lightFromWorldZ;
|
||||
|
||||
@@ -28,7 +28,8 @@ LAYOUT_LOCATION(10) flat VARYING highp int instance_index;
|
||||
highp int logical_instance_index;
|
||||
#endif
|
||||
|
||||
#if defined(VARIANT_HAS_SHADOWING) && defined(VARIANT_HAS_DIRECTIONAL_LIGHTING)
|
||||
#if defined(MATERIAL_HAS_LIGHTING)
|
||||
/* Depends on SRE | DIR */
|
||||
LAYOUT_LOCATION(11) VARYING highp vec4 vertex_lightSpacePosition;
|
||||
#endif
|
||||
|
||||
|
||||
Reference in New Issue
Block a user