playcanvas 1.47.1 → 1.47.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/playcanvas-extras.js +1 -1
- package/build/playcanvas.dbg.js +26 -20
- package/build/playcanvas.js +26 -20
- package/build/playcanvas.min.js +2 -2
- package/build/playcanvas.mjs +26 -20
- package/build/playcanvas.prf.js +26 -20
- package/package.json +1 -1
package/build/playcanvas.dbg.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* PlayCanvas Engine v1.47.
|
|
3
|
+
* PlayCanvas Engine v1.47.2 revision b336e2bc9 (DEBUG PROFILER)
|
|
4
4
|
* Copyright 2011-2021 PlayCanvas Ltd. All rights reserved.
|
|
5
5
|
*/
|
|
6
6
|
(function (global, factory) {
|
|
@@ -634,8 +634,8 @@
|
|
|
634
634
|
return result;
|
|
635
635
|
}();
|
|
636
636
|
|
|
637
|
-
var version = "1.47.
|
|
638
|
-
var revision = "
|
|
637
|
+
var version = "1.47.2";
|
|
638
|
+
var revision = "b336e2bc9";
|
|
639
639
|
var config = {};
|
|
640
640
|
var common = {};
|
|
641
641
|
var apps = {};
|
|
@@ -5984,7 +5984,7 @@
|
|
|
5984
5984
|
|
|
5985
5985
|
var clusteredLightShadowsPS = "// Clustered Omni Sampling using atlas\n\n#ifdef GL2\n\nfloat getShadowOmniClusteredSingleSample(sampler2DShadow shadowMap, vec4 shadowParams, vec3 omniAtlasViewport, float shadowEdgePixels, vec3 dir) {\n\n\tfloat shadowTextureResolution = shadowParams.x;\n\tvec2 uv = getCubemapAtlasCoordinates(omniAtlasViewport, shadowEdgePixels, shadowTextureResolution, dir);\n\n\tfloat shadowZ = length(dir) * shadowParams.w + shadowParams.z;\n\treturn texture(shadowMap, vec3(uv, shadowZ));\n}\n\n\nfloat getShadowOmniClusteredPCF3x3(sampler2DShadow shadowMap, vec4 shadowParams, vec3 omniAtlasViewport, float shadowEdgePixels, vec3 dir) {\n\n\tfloat shadowTextureResolution = shadowParams.x;\n\tvec2 uv = getCubemapAtlasCoordinates(omniAtlasViewport, shadowEdgePixels, shadowTextureResolution, dir);\n\n\tfloat shadowZ = length(dir) * shadowParams.w + shadowParams.z;\n\tdShadowCoord = vec3(uv, shadowZ);\n\treturn getShadowPCF3x3(shadowMap, shadowParams.xyz);\n}\n\n#else\n\nfloat getShadowOmniClusteredSingleSample(sampler2D shadowMap, vec4 shadowParams, vec3 omniAtlasViewport, float shadowEdgePixels, vec3 dir) {\n\n\tfloat shadowTextureResolution = shadowParams.x;\n\tvec2 uv = getCubemapAtlasCoordinates(omniAtlasViewport, shadowEdgePixels, shadowTextureResolution, dir);\n\n\t// no filter shadow sampling\n\tfloat depth = unpackFloat(texture2D(shadowMap, uv));\n\tfloat shadowZ = length(dir) * shadowParams.w + shadowParams.z;\n\treturn depth > shadowZ ? 1.0 : 0.0;\n}\n\nfloat getShadowOmniClusteredPCF3x3(sampler2D shadowMap, vec4 shadowParams, vec3 omniAtlasViewport, float shadowEdgePixels, vec3 dir) {\n\n\tfloat shadowTextureResolution = shadowParams.x;\n\tvec2 uv = getCubemapAtlasCoordinates(omniAtlasViewport, shadowEdgePixels, shadowTextureResolution, dir);\n\n\t// pcf3\n\tfloat shadowZ = length(dir) * shadowParams.w + shadowParams.z;\n\tdShadowCoord = vec3(uv, shadowZ);\n\treturn getShadowPCF3x3(shadowMap, shadowParams.xyz);\n}\n\n#endif\n";
|
|
5986
5986
|
|
|
5987
|
-
var clusteredLightPS = "uniform sampler2D clusterWorldTexture;\nuniform sampler2D lightsTexture8;\nuniform highp sampler2D lightsTextureFloat;\n\n#ifdef GL2\n\t// TODO: when VSM shadow is supported, it needs to use sampler2D in webgl2\n\tuniform sampler2DShadow shadowAtlasTexture;\n#else\n\tuniform sampler2D shadowAtlasTexture;\n#endif\n\nuniform sampler2D cookieAtlasTexture;\n\nuniform float clusterPixelsPerCell;\nuniform vec3 clusterCellsCountByBoundsSize;\nuniform vec4 lightsTextureInvSize;\nuniform vec3 clusterTextureSize;\nuniform vec3 clusterBoundsMin;\nuniform vec3 clusterBoundsDelta;\nuniform vec3 clusterCellsDot;\nuniform vec3 clusterCellsMax;\nuniform vec2 clusterCompressionLimit0;\nuniform vec2 shadowAtlasParams;\n\n// structure storing light properties of a clustered light\nstruct ClusterLightData {\n\n\t// v coordinate to look up the light textures\n\tfloat lightV;\n\n\t// true if spot light, false for omni light\n\tbool isSpot;\n\n\t// area light shape\n\tfloat shape;\n\n\t// light follow mode\n\tfloat falloffMode;\n\n\t// true if the light is shadow casting\n\tbool castShadows;\n\n\t// shadow bias values\n\tfloat shadowBias;\n\tfloat shadowNormalBias;\n\n\t// shadow (spot light only) / cookie projection matrix\n\tmat4 lightProjectionMatrix;\n\n\t// world space position\n\tvec3 position;\n\n\t// world space direction (spot light only)\n\tvec3 direction;\n\n\t// range of the light\n\tfloat range;\n\n\t// spot light inner and outer angle cosine\n\tfloat innerConeAngleCos;\n\tfloat outerConeAngleCos;\n\n\t// color\n\tvec3 color;\n\n\t// atlas viewport for omni light shadow and cookie (.xy is offset to the viewport slot, .z is size of the face in the atlas)\n\tvec3 omniAtlasViewport;\n\n\t// true if the light has a cookie texture\n\tbool isCookie;\n\n\t// true if cookie texture is rgb, false is using a single channel selectable by cookieChannelMask\n\tbool isCookieRgb;\n\n\t// invensity of the cookie\n\tfloat cookieIntensity;\n\n\t// channel mask - one of the channels has 1, the others are 0\n\tvec4 cookieChannelMask;\n};\n\nvec4 decodeClusterLowRange4Vec4(vec4 d0, vec4 d1, vec4 d2, vec4 d3) {\n\treturn vec4(\n\t\tbytes2floatRange4(d0, -2.0, 2.0),\n\t\tbytes2floatRange4(d1, -2.0, 2.0),\n\t\tbytes2floatRange4(d2, -2.0, 2.0),\n\t\tbytes2floatRange4(d3, -2.0, 2.0)\n\t);\n}\n\nvec4 sampleLightsTexture8(const ClusterLightData clusterLightData, float index) {\n\treturn texture2D(lightsTexture8, vec2(index * lightsTextureInvSize.z, clusterLightData.lightV));\n}\n\nvec4 sampleLightTextureF(const ClusterLightData clusterLightData, float index) {\n\treturn texture2D(lightsTextureFloat, vec2(index * lightsTextureInvSize.x, clusterLightData.lightV));\n}\n\nvoid decodeClusterLightCore(inout ClusterLightData clusterLightData, float lightIndex) {\n\n\t// read omni light properties\n\tclusterLightData.lightV = (lightIndex + 0.5) * lightsTextureInvSize.w;\n\n\t// shared data from 8bit texture\n\tvec4 lightInfo = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_FLAGS);\n\tclusterLightData.isSpot = lightInfo.x > 0.5;\n\tclusterLightData.shape = lightInfo.y;\n\tclusterLightData.falloffMode = lightInfo.z;\n\tclusterLightData.castShadows = lightInfo.w > 0.5;\n\n\t// color\n\tvec4 colorA = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_COLOR_A);\n\tvec4 colorB = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_COLOR_B);\n\tclusterLightData.color = vec3(bytes2float2(colorA.xy), bytes2float2(colorA.zw), bytes2float2(colorB.xy)) * clusterCompressionLimit0.y;\n\n\t// isCookie\n\tclusterLightData.isCookie = colorB.z > 0.5;\n\n\t#ifdef CLUSTER_TEXTURE_FLOAT\n\n\t\tvec4 lightPosRange = sampleLightTextureF(clusterLightData, CLUSTER_TEXTURE_F_POSITION_RANGE);\n\t\tclusterLightData.position = lightPosRange.xyz;\n\t\tclusterLightData.range = lightPosRange.w;\n\n\t\t// spot light direction\n\t\tvec4 lightDir_Unused = sampleLightTextureF(clusterLightData, CLUSTER_TEXTURE_F_SPOT_DIRECTION);\n\t\tclusterLightData.direction = lightDir_Unused.xyz;\n\n\t#else // 8bit\n\n\t\tvec4 encPosX = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_POSITION_X);\n\t\tvec4 encPosY = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_POSITION_Y);\n\t\tvec4 encPosZ = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_POSITION_Z);\n\t\tclusterLightData.position = vec3(bytes2float4(encPosX), bytes2float4(encPosY), bytes2float4(encPosZ)) * clusterBoundsDelta + clusterBoundsMin;\n\n\t\tvec4 encRange = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_RANGE);\n\t\tclusterLightData.range = bytes2float4(encRange) * clusterCompressionLimit0.x;\n\n\t\t// spot light direction\n\t\tvec4 encDirX = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_SPOT_DIRECTION_X);\n\t\tvec4 encDirY = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_SPOT_DIRECTION_Y);\n\t\tvec4 encDirZ = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_SPOT_DIRECTION_Z);\n\t\tclusterLightData.direction = vec3(bytes2float4(encDirX), bytes2float4(encDirY), bytes2float4(encDirZ)) * 2.0 - 1.0;\n\n\t#endif\n}\n\nvoid decodeClusterLightSpot(inout ClusterLightData clusterLightData) {\n\n\t// spot light cos angles\n\tvec4 coneAngle = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_SPOT_ANGLES);\n\tclusterLightData.innerConeAngleCos = bytes2float2(coneAngle.xy) * 2.0 - 1.0;\n\tclusterLightData.outerConeAngleCos = bytes2float2(coneAngle.zw) * 2.0 - 1.0;\n}\n\nvoid decodeClusterLightOmniAtlasViewport(inout ClusterLightData clusterLightData) {\n\t#ifdef CLUSTER_TEXTURE_FLOAT\n\t\tclusterLightData.omniAtlasViewport = sampleLightTextureF(clusterLightData, CLUSTER_TEXTURE_F_PROJ_MAT_0).xyz;\n\t#else\n\t\tvec4 viewportA = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_ATLAS_VIEWPORT_A);\n\t\tvec4 viewportB = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_ATLAS_VIEWPORT_B);\n\t\tclusterLightData.omniAtlasViewport = vec3(bytes2float2(viewportA.xy), bytes2float2(viewportA.zw), bytes2float2(viewportB.xy));\n\t#endif\n}\n\nvoid decodeClusterLightProjectionMatrixData(inout ClusterLightData clusterLightData) {\n\t\n\t// shadow matrix\n\t#ifdef CLUSTER_TEXTURE_FLOAT\n\t\tvec4 m0 = sampleLightTextureF(clusterLightData, CLUSTER_TEXTURE_F_PROJ_MAT_0);\n\t\tvec4 m1 = sampleLightTextureF(clusterLightData, CLUSTER_TEXTURE_F_PROJ_MAT_1);\n\t\tvec4 m2 = sampleLightTextureF(clusterLightData, CLUSTER_TEXTURE_F_PROJ_MAT_2);\n\t\tvec4 m3 = sampleLightTextureF(clusterLightData, CLUSTER_TEXTURE_F_PROJ_MAT_3);\n\t#else\n\t\tvec4 m00 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_00);\n\t\tvec4 m01 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_01);\n\t\tvec4 m02 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_02);\n\t\tvec4 m03 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_03);\n\t\tvec4 m0 = decodeClusterLowRange4Vec4(m00, m01, m02, m03);\n\n\t\tvec4 m10 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_10);\n\t\tvec4 m11 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_11);\n\t\tvec4 m12 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_12);\n\t\tvec4 m13 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_13);\n\t\tvec4 m1 = decodeClusterLowRange4Vec4(m10, m11, m12, m13);\n\n\t\tvec4 m20 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_20);\n\t\tvec4 m21 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_21);\n\t\tvec4 m22 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_22);\n\t\tvec4 m23 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_23);\n\t\tvec4 m2 = decodeClusterLowRange4Vec4(m20, m21, m22, m23);\n\n\t\tvec4 m30 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_30);\n\t\tvec4 m31 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_31);\n\t\tvec4 m32 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_32);\n\t\tvec4 m33 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_33);\n\t\tvec4 m3 = vec4(mantisaExponent2Float(m30), mantisaExponent2Float(m31), mantisaExponent2Float(m32), mantisaExponent2Float(m33));\n\t#endif\n\t\n\tclusterLightData.lightProjectionMatrix = mat4(m0, m1, m2, m3);\n}\n\nvoid decodeClusterLightShadowData(inout ClusterLightData clusterLightData) {\n\t\n\t// shadow biases\n\tvec4 biases = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_SHADOW_BIAS);\n\tclusterLightData.shadowBias = bytes2floatRange2(biases.xy, -1.0, 20.0),\n\tclusterLightData.shadowNormalBias = bytes2float2(biases.zw);\n}\n\nvoid decodeClusterLightCookieData(inout ClusterLightData clusterLightData) {\n\n\tvec4 cookieA = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_COOKIE_A);\n\tclusterLightData.cookieIntensity = cookieA.x;\n\tclusterLightData.isCookieRgb = cookieA.y > 0.5;\n\n\tclusterLightData.cookieChannelMask = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_COOKIE_B);\n}\n\nvoid evaluateLight(ClusterLightData light) {\n\n\tdAtten3 = vec3(1.0);\n\n\t// evaluate omni part of the light\n\tgetLightDirPoint(light.position);\n\tdAtten = getFalloffLinear(light.range);\n\tif (dAtten > 0.00001) {\n\n\t\tdAtten *= getLightDiffuse();\n\n\t\t// spot light falloff\n\t\tif (light.isSpot == true) {\n\t\t\tdecodeClusterLightSpot(light);\n\t\t\tdAtten *= getSpotEffect(light.direction, light.innerConeAngleCos, light.outerConeAngleCos);\n\t\t}\n\n\t\tif (dAtten > 0.00001) {\n\n\t\t\t// shadow / cookie\n\t\t\tif (light.castShadows == true || light.isCookie == true) {\n\n\t\t\t\t// shared shadow / cookie data depends on light type\n\t\t\t\tif (light.isSpot == true) {\n\t\t\t\t\tdecodeClusterLightProjectionMatrixData(light);\n\t\t\t\t} else {\n\t\t\t\t\tdecodeClusterLightOmniAtlasViewport(light);\n\t\t\t\t}\n\n\t\t\t\tfloat shadowTextureResolution = shadowAtlasParams.x;\n\t\t\t\tfloat shadowEdgePixels = shadowAtlasParams.y;\n\n\t\t\t\t// cookie\n\t\t\t\tif (light.isCookie == true) {\n\t\t\t\t\tdecodeClusterLightCookieData(light);\n\n\t\t\t\t\tif (light.isSpot == true) {\n\t\t\t\t\t\tdAtten3 = getCookie2DClustered(cookieAtlasTexture, light.lightProjectionMatrix, vPositionW, light.cookieIntensity, light.isCookieRgb, light.cookieChannelMask);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdAtten3 = getCookieCubeClustered(cookieAtlasTexture, dLightDirW, light.cookieIntensity, light.isCookieRgb, light.cookieChannelMask, shadowTextureResolution, shadowEdgePixels, light.omniAtlasViewport);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// shadow\n\t\t\t\tif (light.castShadows== true) {\n\t\t\t\t\tdecodeClusterLightShadowData(light);\n\n\t\t\t\t\tvec4 shadowParams = vec4(shadowTextureResolution, light.shadowNormalBias, light.shadowBias, 1.0 / light.range);\n\n\t\t\t\t\tif (light.isSpot == true) {\n\n\t\t\t\t\t\t// spot shadow\n\t\t\t\t\t\tgetShadowCoordPerspZbufferNormalOffset(light.lightProjectionMatrix, shadowParams);\n\t\t\t\t\t\tdAtten *= getShadowSpotPCF3x3(shadowAtlasTexture, shadowParams);\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// omni shadow\n\t\t\t\t\t\tnormalOffsetPointShadow(shadowParams); // normalBias adjusted for distance\n\t\t\t\t\t\tdAtten *= getShadowOmniClusteredPCF3x3(shadowAtlasTexture, shadowParams, light.omniAtlasViewport, shadowEdgePixels, dLightDirW);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tdDiffuseLight += dAtten * light.color * dAtten3;\n\t}\n}\n\nvoid evaluateClusterLight(float lightIndex) {\n\n\t// decode core light data from textures\n\tClusterLightData clusterLightData;\n\tdecodeClusterLightCore(clusterLightData, lightIndex);\n\n\t// evaluate light\n\tevaluateLight(clusterLightData);\n}\n\nvoid addClusteredLights() {\n\t// world space position to 3d integer cell cordinates in the cluster structure\n\tvec3 cellCoords = floor((vPositionW - clusterBoundsMin) * clusterCellsCountByBoundsSize);\n\n\t// no lighting when cell coordinate is out of range\n\tif (!(any(lessThan(cellCoords, vec3(0.0))) || any(greaterThanEqual(cellCoords, clusterCellsMax)))) {\n\n\t\t// cell index (mapping from 3d cell coordinates to linear memory)\n\t\tfloat cellIndex = dot(clusterCellsDot, cellCoords);\n\n\t\t// convert cell index to uv coordinates\n\t\tfloat clusterV = floor(cellIndex * clusterTextureSize.y);\n\t\tfloat clusterU = cellIndex - (clusterV * clusterTextureSize.x);\n\t\tclusterV = (clusterV + 0.5) * clusterTextureSize.z;\n\n\t\t// loop over maximum possible number of supported light cells\n\t\tconst float maxLightCells = 256.0 / 4.0; // 8 bit index, each stores 4 lights\n\t\tfor (float lightCellIndex = 0.5; lightCellIndex < maxLightCells; lightCellIndex++) {\n\n\t\t\tvec4 lightIndices = texture2D(clusterWorldTexture, vec2(clusterTextureSize.y * (clusterU + lightCellIndex), clusterV));\n\t\t\tvec4 indices = lightIndices * 255.0;\n\n\t\t\tif (indices.x <= 0.0)\n\t\t\t\tbreak;\n\n\t\t\tevaluateClusterLight(indices.x);\n\n\t\t\tif (indices.y <= 0.0)\n\t\t\t\tbreak;\n\n\t\t\tevaluateClusterLight(indices.y);\n\n\t\t\tif (indices.z <= 0.0)\n\t\t\t\tbreak;\n\n\t\t\tevaluateClusterLight(indices.z);\n\n\t\t\tif (indices.w <= 0.0)\n\t\t\t\tbreak;\n\n\t\t\tevaluateClusterLight(indices.w);\n\n\t\t\t// end of the cell array\n\t\t\tif (lightCellIndex > clusterPixelsPerCell) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n";
|
|
5987
|
+
var clusteredLightPS = "uniform sampler2D clusterWorldTexture;\nuniform sampler2D lightsTexture8;\nuniform highp sampler2D lightsTextureFloat;\n\n#ifdef GL2\n\t// TODO: when VSM shadow is supported, it needs to use sampler2D in webgl2\n\tuniform sampler2DShadow shadowAtlasTexture;\n#else\n\tuniform sampler2D shadowAtlasTexture;\n#endif\n\nuniform sampler2D cookieAtlasTexture;\n\nuniform float clusterPixelsPerCell;\nuniform vec3 clusterCellsCountByBoundsSize;\nuniform vec4 lightsTextureInvSize;\nuniform vec3 clusterTextureSize;\nuniform vec3 clusterBoundsMin;\nuniform vec3 clusterBoundsDelta;\nuniform vec3 clusterCellsDot;\nuniform vec3 clusterCellsMax;\nuniform vec2 clusterCompressionLimit0;\nuniform vec2 shadowAtlasParams;\n\n// structure storing light properties of a clustered light\nstruct ClusterLightData {\n\n\t// v coordinate to look up the light textures\n\tfloat lightV;\n\n\t// true if spot light, false for omni light\n\tbool isSpot;\n\n\t// area light shape\n\tfloat shape;\n\n\t// light follow mode\n\tfloat falloffMode;\n\n\t// true if the light is shadow casting\n\tbool castShadows;\n\n\t// shadow bias values\n\tfloat shadowBias;\n\tfloat shadowNormalBias;\n\n\t// shadow (spot light only) / cookie projection matrix\n\tmat4 lightProjectionMatrix;\n\n\t// world space position\n\tvec3 position;\n\n\t// world space direction (spot light only)\n\tvec3 direction;\n\n\t// range of the light\n\tfloat range;\n\n\t// spot light inner and outer angle cosine\n\tfloat innerConeAngleCos;\n\tfloat outerConeAngleCos;\n\n\t// color\n\tvec3 color;\n\n\t// atlas viewport for omni light shadow and cookie (.xy is offset to the viewport slot, .z is size of the face in the atlas)\n\tvec3 omniAtlasViewport;\n\n\t// true if the light has a cookie texture\n\tbool isCookie;\n\n\t// true if cookie texture is rgb, false is using a single channel selectable by cookieChannelMask\n\tbool isCookieRgb;\n\n\t// invensity of the cookie\n\tfloat cookieIntensity;\n\n\t// channel mask - one of the channels has 1, the others are 0\n\tvec4 cookieChannelMask;\n};\n\nvec4 decodeClusterLowRange4Vec4(vec4 d0, vec4 d1, vec4 d2, vec4 d3) {\n\treturn vec4(\n\t\tbytes2floatRange4(d0, -2.0, 2.0),\n\t\tbytes2floatRange4(d1, -2.0, 2.0),\n\t\tbytes2floatRange4(d2, -2.0, 2.0),\n\t\tbytes2floatRange4(d3, -2.0, 2.0)\n\t);\n}\n\nvec4 sampleLightsTexture8(const ClusterLightData clusterLightData, float index) {\n\treturn texture2D(lightsTexture8, vec2(index * lightsTextureInvSize.z, clusterLightData.lightV));\n}\n\nvec4 sampleLightTextureF(const ClusterLightData clusterLightData, float index) {\n\treturn texture2D(lightsTextureFloat, vec2(index * lightsTextureInvSize.x, clusterLightData.lightV));\n}\n\nvoid decodeClusterLightCore(inout ClusterLightData clusterLightData, float lightIndex) {\n\n\t// read omni light properties\n\tclusterLightData.lightV = (lightIndex + 0.5) * lightsTextureInvSize.w;\n\n\t// shared data from 8bit texture\n\tvec4 lightInfo = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_FLAGS);\n\tclusterLightData.isSpot = lightInfo.x > 0.5;\n\tclusterLightData.shape = lightInfo.y;\n\tclusterLightData.falloffMode = lightInfo.z;\n\tclusterLightData.castShadows = lightInfo.w > 0.5;\n\n\t// color\n\tvec4 colorA = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_COLOR_A);\n\tvec4 colorB = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_COLOR_B);\n\tclusterLightData.color = vec3(bytes2float2(colorA.xy), bytes2float2(colorA.zw), bytes2float2(colorB.xy)) * clusterCompressionLimit0.y;\n\n\t// isCookie\n\tclusterLightData.isCookie = colorB.z > 0.5;\n\n\t#ifdef CLUSTER_TEXTURE_FLOAT\n\n\t\tvec4 lightPosRange = sampleLightTextureF(clusterLightData, CLUSTER_TEXTURE_F_POSITION_RANGE);\n\t\tclusterLightData.position = lightPosRange.xyz;\n\t\tclusterLightData.range = lightPosRange.w;\n\n\t\t// spot light direction\n\t\tvec4 lightDir_Unused = sampleLightTextureF(clusterLightData, CLUSTER_TEXTURE_F_SPOT_DIRECTION);\n\t\tclusterLightData.direction = lightDir_Unused.xyz;\n\n\t#else // 8bit\n\n\t\tvec4 encPosX = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_POSITION_X);\n\t\tvec4 encPosY = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_POSITION_Y);\n\t\tvec4 encPosZ = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_POSITION_Z);\n\t\tclusterLightData.position = vec3(bytes2float4(encPosX), bytes2float4(encPosY), bytes2float4(encPosZ)) * clusterBoundsDelta + clusterBoundsMin;\n\n\t\tvec4 encRange = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_RANGE);\n\t\tclusterLightData.range = bytes2float4(encRange) * clusterCompressionLimit0.x;\n\n\t\t// spot light direction\n\t\tvec4 encDirX = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_SPOT_DIRECTION_X);\n\t\tvec4 encDirY = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_SPOT_DIRECTION_Y);\n\t\tvec4 encDirZ = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_SPOT_DIRECTION_Z);\n\t\tclusterLightData.direction = vec3(bytes2float4(encDirX), bytes2float4(encDirY), bytes2float4(encDirZ)) * 2.0 - 1.0;\n\n\t#endif\n}\n\nvoid decodeClusterLightSpot(inout ClusterLightData clusterLightData) {\n\n\t// spot light cos angles\n\tvec4 coneAngle = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_SPOT_ANGLES);\n\tclusterLightData.innerConeAngleCos = bytes2float2(coneAngle.xy) * 2.0 - 1.0;\n\tclusterLightData.outerConeAngleCos = bytes2float2(coneAngle.zw) * 2.0 - 1.0;\n}\n\nvoid decodeClusterLightOmniAtlasViewport(inout ClusterLightData clusterLightData) {\n\t#ifdef CLUSTER_TEXTURE_FLOAT\n\t\tclusterLightData.omniAtlasViewport = sampleLightTextureF(clusterLightData, CLUSTER_TEXTURE_F_PROJ_MAT_0).xyz;\n\t#else\n\t\tvec4 viewportA = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_ATLAS_VIEWPORT_A);\n\t\tvec4 viewportB = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_ATLAS_VIEWPORT_B);\n\t\tclusterLightData.omniAtlasViewport = vec3(bytes2float2(viewportA.xy), bytes2float2(viewportA.zw), bytes2float2(viewportB.xy));\n\t#endif\n}\n\nvoid decodeClusterLightProjectionMatrixData(inout ClusterLightData clusterLightData) {\n\t\n\t// shadow matrix\n\t#ifdef CLUSTER_TEXTURE_FLOAT\n\t\tvec4 m0 = sampleLightTextureF(clusterLightData, CLUSTER_TEXTURE_F_PROJ_MAT_0);\n\t\tvec4 m1 = sampleLightTextureF(clusterLightData, CLUSTER_TEXTURE_F_PROJ_MAT_1);\n\t\tvec4 m2 = sampleLightTextureF(clusterLightData, CLUSTER_TEXTURE_F_PROJ_MAT_2);\n\t\tvec4 m3 = sampleLightTextureF(clusterLightData, CLUSTER_TEXTURE_F_PROJ_MAT_3);\n\t#else\n\t\tvec4 m00 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_00);\n\t\tvec4 m01 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_01);\n\t\tvec4 m02 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_02);\n\t\tvec4 m03 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_03);\n\t\tvec4 m0 = decodeClusterLowRange4Vec4(m00, m01, m02, m03);\n\n\t\tvec4 m10 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_10);\n\t\tvec4 m11 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_11);\n\t\tvec4 m12 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_12);\n\t\tvec4 m13 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_13);\n\t\tvec4 m1 = decodeClusterLowRange4Vec4(m10, m11, m12, m13);\n\n\t\tvec4 m20 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_20);\n\t\tvec4 m21 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_21);\n\t\tvec4 m22 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_22);\n\t\tvec4 m23 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_23);\n\t\tvec4 m2 = decodeClusterLowRange4Vec4(m20, m21, m22, m23);\n\n\t\tvec4 m30 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_30);\n\t\tvec4 m31 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_31);\n\t\tvec4 m32 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_32);\n\t\tvec4 m33 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_33);\n\t\tvec4 m3 = vec4(mantisaExponent2Float(m30), mantisaExponent2Float(m31), mantisaExponent2Float(m32), mantisaExponent2Float(m33));\n\t#endif\n\t\n\tclusterLightData.lightProjectionMatrix = mat4(m0, m1, m2, m3);\n}\n\nvoid decodeClusterLightShadowData(inout ClusterLightData clusterLightData) {\n\t\n\t// shadow biases\n\tvec4 biases = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_SHADOW_BIAS);\n\tclusterLightData.shadowBias = bytes2floatRange2(biases.xy, -1.0, 20.0),\n\tclusterLightData.shadowNormalBias = bytes2float2(biases.zw);\n}\n\nvoid decodeClusterLightCookieData(inout ClusterLightData clusterLightData) {\n\n\tvec4 cookieA = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_COOKIE_A);\n\tclusterLightData.cookieIntensity = cookieA.x;\n\tclusterLightData.isCookieRgb = cookieA.y > 0.5;\n\n\tclusterLightData.cookieChannelMask = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_COOKIE_B);\n}\n\nvoid evaluateLight(ClusterLightData light) {\n\n\tdAtten3 = vec3(1.0);\n\n\t// evaluate omni part of the light\n\tgetLightDirPoint(light.position);\n\tdAtten = getFalloffLinear(light.range);\n\tif (dAtten > 0.00001) {\n\n\t\tdAtten *= getLightDiffuse();\n\n\t\t// spot light falloff\n\t\tif (light.isSpot == true) {\n\t\t\tdecodeClusterLightSpot(light);\n\t\t\tdAtten *= getSpotEffect(light.direction, light.innerConeAngleCos, light.outerConeAngleCos);\n\t\t}\n\n\t\tif (dAtten > 0.00001) {\n\n\t\t\t// shadow / cookie\n\t\t\tif (light.castShadows == true || light.isCookie == true) {\n\n\t\t\t\t// shared shadow / cookie data depends on light type\n\t\t\t\tif (light.isSpot == true) {\n\t\t\t\t\tdecodeClusterLightProjectionMatrixData(light);\n\t\t\t\t} else {\n\t\t\t\t\tdecodeClusterLightOmniAtlasViewport(light);\n\t\t\t\t}\n\n\t\t\t\tfloat shadowTextureResolution = shadowAtlasParams.x;\n\t\t\t\tfloat shadowEdgePixels = shadowAtlasParams.y;\n\n\t\t\t\t// cookie\n\t\t\t\tif (light.isCookie == true) {\n\t\t\t\t\tdecodeClusterLightCookieData(light);\n\n\t\t\t\t\tif (light.isSpot == true) {\n\t\t\t\t\t\tdAtten3 = getCookie2DClustered(cookieAtlasTexture, light.lightProjectionMatrix, vPositionW, light.cookieIntensity, light.isCookieRgb, light.cookieChannelMask);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdAtten3 = getCookieCubeClustered(cookieAtlasTexture, dLightDirW, light.cookieIntensity, light.isCookieRgb, light.cookieChannelMask, shadowTextureResolution, shadowEdgePixels, light.omniAtlasViewport);\n\t\t\t\t\t}\n\t\t\t\t}\n\n\t\t\t\t// shadow\n\t\t\t\tif (light.castShadows== true) {\n\t\t\t\t\tdecodeClusterLightShadowData(light);\n\n\t\t\t\t\tvec4 shadowParams = vec4(shadowTextureResolution, light.shadowNormalBias, light.shadowBias, 1.0 / light.range);\n\n\t\t\t\t\tif (light.isSpot == true) {\n\n\t\t\t\t\t\t// spot shadow\n\t\t\t\t\t\tgetShadowCoordPerspZbufferNormalOffset(light.lightProjectionMatrix, shadowParams);\n\t\t\t\t\t\tdAtten *= getShadowSpotPCF3x3(shadowAtlasTexture, shadowParams);\n\n\t\t\t\t\t} else {\n\n\t\t\t\t\t\t// omni shadow\n\t\t\t\t\t\tnormalOffsetPointShadow(shadowParams); // normalBias adjusted for distance\n\t\t\t\t\t\tdAtten *= getShadowOmniClusteredPCF3x3(shadowAtlasTexture, shadowParams, light.omniAtlasViewport, shadowEdgePixels, dLightDirW);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\n\t\tdDiffuseLight += dAtten * light.color * dAtten3;\n\t}\n}\n\nvoid evaluateClusterLight(float lightIndex) {\n\n\t// decode core light data from textures\n\tClusterLightData clusterLightData;\n\tdecodeClusterLightCore(clusterLightData, lightIndex);\n\n\t// evaluate light\n\tevaluateLight(clusterLightData);\n}\n\nconst vec4 channelSelector[4] = vec4[4] (\n\tvec4(1., 0., 0., 0.),\n\tvec4(0., 1., 0., 0.),\n\tvec4(0., 0., 1., 0.),\n\tvec4(0., 0., 0., 1.)\n);\n\nvoid addClusteredLights() {\n\t// world space position to 3d integer cell cordinates in the cluster structure\n\tvec3 cellCoords = floor((vPositionW - clusterBoundsMin) * clusterCellsCountByBoundsSize);\n\n\t// no lighting when cell coordinate is out of range\n\tif (!(any(lessThan(cellCoords, vec3(0.0))) || any(greaterThanEqual(cellCoords, clusterCellsMax)))) {\n\n\t\t// cell index (mapping from 3d cell coordinates to linear memory)\n\t\tfloat cellIndex = dot(clusterCellsDot, cellCoords);\n\n\t\t// convert cell index to uv coordinates\n\t\tfloat clusterV = floor(cellIndex * clusterTextureSize.y);\n\t\tfloat clusterU = cellIndex - (clusterV * clusterTextureSize.x);\n\t\tclusterV = (clusterV + 0.5) * clusterTextureSize.z;\n\n\t\t// loop over maximum possible number of supported light cells\n\t\tconst float maxLightCells = 256.0 / 4.0; // 8 bit index, each stores 4 lights\n\t\tfor (float lightCellIndex = 0.5; lightCellIndex < maxLightCells; lightCellIndex++) {\n\n\t\t\tvec4 lightIndices = texture2D(clusterWorldTexture, vec2(clusterTextureSize.y * (clusterU + lightCellIndex), clusterV));\n\t\t\tvec4 indices = lightIndices * 255.0;\n\n\t\t\t// evaluate up to 4 lights. This is written using a loop instead of manually unrolling to keep shader compile time smaller\n\t\t\tfor (int i = 0; i < 4; i++) {\n\t\t\t\tfloat index = dot(channelSelector[i], indices);\n\t\t\t\tif (index <= 0.0)\n\t\t\t\t\treturn;\n\n\t\t\t\tevaluateClusterLight(index); \n\t\t\t}\n\n\t\t\t// end of the cell array\n\t\t\tif (lightCellIndex > clusterPixelsPerCell) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n";
|
|
5988
5988
|
|
|
5989
5989
|
var combineClearCoatPS = "vec3 combineColorCC() {\n\treturn combineColor()+(ccSpecularLight*ccSpecularity+ccReflection.rgb*ccSpecularity*ccReflection.a);\n}\n";
|
|
5990
5990
|
|
|
@@ -11675,6 +11675,7 @@
|
|
|
11675
11675
|
var useVsm = false;
|
|
11676
11676
|
var usePerspZbufferShadow = false;
|
|
11677
11677
|
var light;
|
|
11678
|
+
var isClustered = LayerComposition.clusteredLightingEnabled;
|
|
11678
11679
|
var hasAreaLights = options.lights.some(function (light) {
|
|
11679
11680
|
return light._shape && light._shape !== LIGHTSHAPE_PUNCTUAL;
|
|
11680
11681
|
});
|
|
@@ -11697,6 +11698,7 @@
|
|
|
11697
11698
|
for (i = 0; i < options.lights.length; i++) {
|
|
11698
11699
|
light = options.lights[i];
|
|
11699
11700
|
lightType = light._type;
|
|
11701
|
+
if (isClustered && lightType !== LIGHTTYPE_DIRECTIONAL) continue;
|
|
11700
11702
|
|
|
11701
11703
|
if (hasAreaLights && light._shape) {
|
|
11702
11704
|
lightShape = light._shape;
|
|
@@ -38844,7 +38846,7 @@
|
|
|
38844
38846
|
};
|
|
38845
38847
|
|
|
38846
38848
|
_proto.readU64 = function readU64() {
|
|
38847
|
-
return this.
|
|
38849
|
+
return this.readU32() + Math.pow(2, 32) * this.readU32();
|
|
38848
38850
|
};
|
|
38849
38851
|
|
|
38850
38852
|
_proto.readU32be = function readU32be() {
|
|
@@ -72175,12 +72177,11 @@
|
|
|
72175
72177
|
}
|
|
72176
72178
|
};
|
|
72177
72179
|
|
|
72178
|
-
_proto.calculateLightmapSize = function calculateLightmapSize(
|
|
72180
|
+
_proto.calculateLightmapSize = function calculateLightmapSize(node) {
|
|
72179
72181
|
var data;
|
|
72180
72182
|
var sizeMult = this.scene.lightmapSizeMultiplier || 16;
|
|
72181
72183
|
var scale = tempVec;
|
|
72182
72184
|
var srcArea, lightmapSizeMultiplier;
|
|
72183
|
-
var node = bakeNode.node;
|
|
72184
72185
|
|
|
72185
72186
|
if (node.model) {
|
|
72186
72187
|
lightmapSizeMultiplier = node.model.lightmapSizeMultiplier;
|
|
@@ -72230,7 +72231,9 @@
|
|
|
72230
72231
|
area.x *= areaMult;
|
|
72231
72232
|
area.y *= areaMult;
|
|
72232
72233
|
area.z *= areaMult;
|
|
72233
|
-
|
|
72234
|
+
var component = node.render || node.model;
|
|
72235
|
+
var bounds = this.computeNodeBounds(component.meshInstances);
|
|
72236
|
+
scale.copy(bounds.halfExtents);
|
|
72234
72237
|
var totalArea = area.x * scale.y * scale.z + area.y * scale.x * scale.z + area.z * scale.x * scale.y;
|
|
72235
72238
|
totalArea /= area.uv;
|
|
72236
72239
|
totalArea = Math.sqrt(totalArea);
|
|
@@ -72335,7 +72338,7 @@
|
|
|
72335
72338
|
_proto.allocateTextures = function allocateTextures(bakeNodes, passCount) {
|
|
72336
72339
|
for (var i = 0; i < bakeNodes.length; i++) {
|
|
72337
72340
|
var bakeNode = bakeNodes[i];
|
|
72338
|
-
var size = this.calculateLightmapSize(bakeNode);
|
|
72341
|
+
var size = this.calculateLightmapSize(bakeNode.node);
|
|
72339
72342
|
|
|
72340
72343
|
for (var pass = 0; pass < passCount; pass++) {
|
|
72341
72344
|
var tex = this.createTexture(size, TEXTURETYPE_DEFAULT, "lightmapper_lightmap_" + i);
|
|
@@ -72416,21 +72419,24 @@
|
|
|
72416
72419
|
}
|
|
72417
72420
|
};
|
|
72418
72421
|
|
|
72419
|
-
_proto.computeNodeBounds = function computeNodeBounds(
|
|
72422
|
+
_proto.computeNodeBounds = function computeNodeBounds(meshInstances) {
|
|
72420
72423
|
var bounds = new BoundingBox();
|
|
72421
72424
|
|
|
72422
|
-
|
|
72423
|
-
|
|
72424
|
-
|
|
72425
|
-
if (meshInstances.length > 0) {
|
|
72426
|
-
bounds.copy(meshInstances[0].aabb);
|
|
72425
|
+
if (meshInstances.length > 0) {
|
|
72426
|
+
bounds.copy(meshInstances[0].aabb);
|
|
72427
72427
|
|
|
72428
|
-
|
|
72429
|
-
|
|
72430
|
-
}
|
|
72428
|
+
for (var m = 1; m < meshInstances.length; m++) {
|
|
72429
|
+
bounds.add(meshInstances[m].aabb);
|
|
72431
72430
|
}
|
|
72431
|
+
}
|
|
72432
72432
|
|
|
72433
|
-
|
|
72433
|
+
return bounds;
|
|
72434
|
+
};
|
|
72435
|
+
|
|
72436
|
+
_proto.computeNodesBounds = function computeNodesBounds(nodes) {
|
|
72437
|
+
for (var i = 0; i < nodes.length; i++) {
|
|
72438
|
+
var meshInstances = nodes[i].meshInstances;
|
|
72439
|
+
nodes[i].bounds = this.computeNodeBounds(meshInstances);
|
|
72434
72440
|
}
|
|
72435
72441
|
};
|
|
72436
72442
|
|
|
@@ -72589,7 +72595,7 @@
|
|
|
72589
72595
|
|
|
72590
72596
|
scene.layers._update();
|
|
72591
72597
|
|
|
72592
|
-
this.
|
|
72598
|
+
this.computeNodesBounds(bakeNodes);
|
|
72593
72599
|
this.allocateTextures(bakeNodes, passCount);
|
|
72594
72600
|
var allLights = [],
|
|
72595
72601
|
bakeLights = [];
|
package/build/playcanvas.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* @license
|
|
3
|
-
* PlayCanvas Engine v1.47.
|
|
3
|
+
* PlayCanvas Engine v1.47.2 revision b336e2bc9
|
|
4
4
|
* Copyright 2011-2021 PlayCanvas Ltd. All rights reserved.
|
|
5
5
|
*/
|
|
6
6
|
(function (global, factory) {
|
|
@@ -634,8 +634,8 @@
|
|
|
634
634
|
return result;
|
|
635
635
|
}();
|
|
636
636
|
|
|
637
|
-
var version = "1.47.
|
|
638
|
-
var revision = "
|
|
637
|
+
var version = "1.47.2";
|
|
638
|
+
var revision = "b336e2bc9";
|
|
639
639
|
var config = {};
|
|
640
640
|
var common = {};
|
|
641
641
|
var apps = {};
|
|
@@ -5976,7 +5976,7 @@
|
|
|
5976
5976
|
|
|
5977
5977
|
var clusteredLightShadowsPS = "\n#ifdef GL2\nfloat getShadowOmniClusteredSingleSample(sampler2DShadow shadowMap, vec4 shadowParams, vec3 omniAtlasViewport, float shadowEdgePixels, vec3 dir) {\n\tfloat shadowTextureResolution = shadowParams.x;\n\tvec2 uv = getCubemapAtlasCoordinates(omniAtlasViewport, shadowEdgePixels, shadowTextureResolution, dir);\n\tfloat shadowZ = length(dir) * shadowParams.w + shadowParams.z;\n\treturn texture(shadowMap, vec3(uv, shadowZ));\n}\nfloat getShadowOmniClusteredPCF3x3(sampler2DShadow shadowMap, vec4 shadowParams, vec3 omniAtlasViewport, float shadowEdgePixels, vec3 dir) {\n\tfloat shadowTextureResolution = shadowParams.x;\n\tvec2 uv = getCubemapAtlasCoordinates(omniAtlasViewport, shadowEdgePixels, shadowTextureResolution, dir);\n\tfloat shadowZ = length(dir) * shadowParams.w + shadowParams.z;\n\tdShadowCoord = vec3(uv, shadowZ);\n\treturn getShadowPCF3x3(shadowMap, shadowParams.xyz);\n}\n#else\nfloat getShadowOmniClusteredSingleSample(sampler2D shadowMap, vec4 shadowParams, vec3 omniAtlasViewport, float shadowEdgePixels, vec3 dir) {\n\tfloat shadowTextureResolution = shadowParams.x;\n\tvec2 uv = getCubemapAtlasCoordinates(omniAtlasViewport, shadowEdgePixels, shadowTextureResolution, dir);\n\tfloat depth = unpackFloat(texture2D(shadowMap, uv));\n\tfloat shadowZ = length(dir) * shadowParams.w + shadowParams.z;\n\treturn depth > shadowZ ? 1.0 : 0.0;\n}\nfloat getShadowOmniClusteredPCF3x3(sampler2D shadowMap, vec4 shadowParams, vec3 omniAtlasViewport, float shadowEdgePixels, vec3 dir) {\n\tfloat shadowTextureResolution = shadowParams.x;\n\tvec2 uv = getCubemapAtlasCoordinates(omniAtlasViewport, shadowEdgePixels, shadowTextureResolution, dir);\n\tfloat shadowZ = length(dir) * shadowParams.w + shadowParams.z;\n\tdShadowCoord = vec3(uv, shadowZ);\n\treturn getShadowPCF3x3(shadowMap, shadowParams.xyz);\n}\n#endif\n";
|
|
5978
5978
|
|
|
5979
|
-
var clusteredLightPS = "uniform sampler2D clusterWorldTexture;\nuniform sampler2D lightsTexture8;\nuniform highp sampler2D lightsTextureFloat;\n#ifdef GL2\n\tuniform sampler2DShadow shadowAtlasTexture;\n#else\n\tuniform sampler2D shadowAtlasTexture;\n#endif\nuniform sampler2D cookieAtlasTexture;\nuniform float clusterPixelsPerCell;\nuniform vec3 clusterCellsCountByBoundsSize;\nuniform vec4 lightsTextureInvSize;\nuniform vec3 clusterTextureSize;\nuniform vec3 clusterBoundsMin;\nuniform vec3 clusterBoundsDelta;\nuniform vec3 clusterCellsDot;\nuniform vec3 clusterCellsMax;\nuniform vec2 clusterCompressionLimit0;\nuniform vec2 shadowAtlasParams;\nstruct ClusterLightData {\n\tfloat lightV;\n\tbool isSpot;\n\tfloat shape;\n\tfloat falloffMode;\n\tbool castShadows;\n\tfloat shadowBias;\n\tfloat shadowNormalBias;\n\tmat4 lightProjectionMatrix;\n\tvec3 position;\n\tvec3 direction;\n\tfloat range;\n\tfloat innerConeAngleCos;\n\tfloat outerConeAngleCos;\n\tvec3 color;\n\tvec3 omniAtlasViewport;\n\tbool isCookie;\n\tbool isCookieRgb;\n\tfloat cookieIntensity;\n\tvec4 cookieChannelMask;\n};\nvec4 decodeClusterLowRange4Vec4(vec4 d0, vec4 d1, vec4 d2, vec4 d3) {\n\treturn vec4(\n\t\tbytes2floatRange4(d0, -2.0, 2.0),\n\t\tbytes2floatRange4(d1, -2.0, 2.0),\n\t\tbytes2floatRange4(d2, -2.0, 2.0),\n\t\tbytes2floatRange4(d3, -2.0, 2.0)\n\t);\n}\nvec4 sampleLightsTexture8(const ClusterLightData clusterLightData, float index) {\n\treturn texture2D(lightsTexture8, vec2(index * lightsTextureInvSize.z, clusterLightData.lightV));\n}\nvec4 sampleLightTextureF(const ClusterLightData clusterLightData, float index) {\n\treturn texture2D(lightsTextureFloat, vec2(index * lightsTextureInvSize.x, clusterLightData.lightV));\n}\nvoid decodeClusterLightCore(inout ClusterLightData clusterLightData, float lightIndex) {\n\tclusterLightData.lightV = (lightIndex + 0.5) * lightsTextureInvSize.w;\n\tvec4 lightInfo = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_FLAGS);\n\tclusterLightData.isSpot = lightInfo.x > 0.5;\n\tclusterLightData.shape = lightInfo.y;\n\tclusterLightData.falloffMode = lightInfo.z;\n\tclusterLightData.castShadows = lightInfo.w > 0.5;\n\tvec4 colorA = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_COLOR_A);\n\tvec4 colorB = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_COLOR_B);\n\tclusterLightData.color = vec3(bytes2float2(colorA.xy), bytes2float2(colorA.zw), bytes2float2(colorB.xy)) * clusterCompressionLimit0.y;\n\tclusterLightData.isCookie = colorB.z > 0.5;\n\t#ifdef CLUSTER_TEXTURE_FLOAT\n\t\tvec4 lightPosRange = sampleLightTextureF(clusterLightData, CLUSTER_TEXTURE_F_POSITION_RANGE);\n\t\tclusterLightData.position = lightPosRange.xyz;\n\t\tclusterLightData.range = lightPosRange.w;\n\t\tvec4 lightDir_Unused = sampleLightTextureF(clusterLightData, CLUSTER_TEXTURE_F_SPOT_DIRECTION);\n\t\tclusterLightData.direction = lightDir_Unused.xyz;\n\t#else\n\t\tvec4 encPosX = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_POSITION_X);\n\t\tvec4 encPosY = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_POSITION_Y);\n\t\tvec4 encPosZ = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_POSITION_Z);\n\t\tclusterLightData.position = vec3(bytes2float4(encPosX), bytes2float4(encPosY), bytes2float4(encPosZ)) * clusterBoundsDelta + clusterBoundsMin;\n\t\tvec4 encRange = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_RANGE);\n\t\tclusterLightData.range = bytes2float4(encRange) * clusterCompressionLimit0.x;\n\t\tvec4 encDirX = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_SPOT_DIRECTION_X);\n\t\tvec4 encDirY = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_SPOT_DIRECTION_Y);\n\t\tvec4 encDirZ = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_SPOT_DIRECTION_Z);\n\t\tclusterLightData.direction = vec3(bytes2float4(encDirX), bytes2float4(encDirY), bytes2float4(encDirZ)) * 2.0 - 1.0;\n\t#endif\n}\nvoid decodeClusterLightSpot(inout ClusterLightData clusterLightData) {\n\tvec4 coneAngle = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_SPOT_ANGLES);\n\tclusterLightData.innerConeAngleCos = bytes2float2(coneAngle.xy) * 2.0 - 1.0;\n\tclusterLightData.outerConeAngleCos = bytes2float2(coneAngle.zw) * 2.0 - 1.0;\n}\nvoid decodeClusterLightOmniAtlasViewport(inout ClusterLightData clusterLightData) {\n\t#ifdef CLUSTER_TEXTURE_FLOAT\n\t\tclusterLightData.omniAtlasViewport = sampleLightTextureF(clusterLightData, CLUSTER_TEXTURE_F_PROJ_MAT_0).xyz;\n\t#else\n\t\tvec4 viewportA = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_ATLAS_VIEWPORT_A);\n\t\tvec4 viewportB = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_ATLAS_VIEWPORT_B);\n\t\tclusterLightData.omniAtlasViewport = vec3(bytes2float2(viewportA.xy), bytes2float2(viewportA.zw), bytes2float2(viewportB.xy));\n\t#endif\n}\nvoid decodeClusterLightProjectionMatrixData(inout ClusterLightData clusterLightData) {\n\t#ifdef CLUSTER_TEXTURE_FLOAT\n\t\tvec4 m0 = sampleLightTextureF(clusterLightData, CLUSTER_TEXTURE_F_PROJ_MAT_0);\n\t\tvec4 m1 = sampleLightTextureF(clusterLightData, CLUSTER_TEXTURE_F_PROJ_MAT_1);\n\t\tvec4 m2 = sampleLightTextureF(clusterLightData, CLUSTER_TEXTURE_F_PROJ_MAT_2);\n\t\tvec4 m3 = sampleLightTextureF(clusterLightData, CLUSTER_TEXTURE_F_PROJ_MAT_3);\n\t#else\n\t\tvec4 m00 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_00);\n\t\tvec4 m01 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_01);\n\t\tvec4 m02 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_02);\n\t\tvec4 m03 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_03);\n\t\tvec4 m0 = decodeClusterLowRange4Vec4(m00, m01, m02, m03);\n\t\tvec4 m10 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_10);\n\t\tvec4 m11 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_11);\n\t\tvec4 m12 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_12);\n\t\tvec4 m13 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_13);\n\t\tvec4 m1 = decodeClusterLowRange4Vec4(m10, m11, m12, m13);\n\t\tvec4 m20 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_20);\n\t\tvec4 m21 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_21);\n\t\tvec4 m22 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_22);\n\t\tvec4 m23 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_23);\n\t\tvec4 m2 = decodeClusterLowRange4Vec4(m20, m21, m22, m23);\n\t\tvec4 m30 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_30);\n\t\tvec4 m31 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_31);\n\t\tvec4 m32 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_32);\n\t\tvec4 m33 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_33);\n\t\tvec4 m3 = vec4(mantisaExponent2Float(m30), mantisaExponent2Float(m31), mantisaExponent2Float(m32), mantisaExponent2Float(m33));\n\t#endif\n\tclusterLightData.lightProjectionMatrix = mat4(m0, m1, m2, m3);\n}\nvoid decodeClusterLightShadowData(inout ClusterLightData clusterLightData) {\n\tvec4 biases = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_SHADOW_BIAS);\n\tclusterLightData.shadowBias = bytes2floatRange2(biases.xy, -1.0, 20.0),\n\tclusterLightData.shadowNormalBias = bytes2float2(biases.zw);\n}\nvoid decodeClusterLightCookieData(inout ClusterLightData clusterLightData) {\n\tvec4 cookieA = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_COOKIE_A);\n\tclusterLightData.cookieIntensity = cookieA.x;\n\tclusterLightData.isCookieRgb = cookieA.y > 0.5;\n\tclusterLightData.cookieChannelMask = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_COOKIE_B);\n}\nvoid evaluateLight(ClusterLightData light) {\n\tdAtten3 = vec3(1.0);\n\tgetLightDirPoint(light.position);\n\tdAtten = getFalloffLinear(light.range);\n\tif (dAtten > 0.00001) {\n\t\tdAtten *= getLightDiffuse();\n\t\tif (light.isSpot == true) {\n\t\t\tdecodeClusterLightSpot(light);\n\t\t\tdAtten *= getSpotEffect(light.direction, light.innerConeAngleCos, light.outerConeAngleCos);\n\t\t}\n\t\tif (dAtten > 0.00001) {\n\t\t\tif (light.castShadows == true || light.isCookie == true) {\n\t\t\t\tif (light.isSpot == true) {\n\t\t\t\t\tdecodeClusterLightProjectionMatrixData(light);\n\t\t\t\t} else {\n\t\t\t\t\tdecodeClusterLightOmniAtlasViewport(light);\n\t\t\t\t}\n\t\t\t\tfloat shadowTextureResolution = shadowAtlasParams.x;\n\t\t\t\tfloat shadowEdgePixels = shadowAtlasParams.y;\n\t\t\t\tif (light.isCookie == true) {\n\t\t\t\t\tdecodeClusterLightCookieData(light);\n\t\t\t\t\tif (light.isSpot == true) {\n\t\t\t\t\t\tdAtten3 = getCookie2DClustered(cookieAtlasTexture, light.lightProjectionMatrix, vPositionW, light.cookieIntensity, light.isCookieRgb, light.cookieChannelMask);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdAtten3 = getCookieCubeClustered(cookieAtlasTexture, dLightDirW, light.cookieIntensity, light.isCookieRgb, light.cookieChannelMask, shadowTextureResolution, shadowEdgePixels, light.omniAtlasViewport);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (light.castShadows== true) {\n\t\t\t\t\tdecodeClusterLightShadowData(light);\n\t\t\t\t\tvec4 shadowParams = vec4(shadowTextureResolution, light.shadowNormalBias, light.shadowBias, 1.0 / light.range);\n\t\t\t\t\tif (light.isSpot == true) {\n\t\t\t\t\t\tgetShadowCoordPerspZbufferNormalOffset(light.lightProjectionMatrix, shadowParams);\n\t\t\t\t\t\tdAtten *= getShadowSpotPCF3x3(shadowAtlasTexture, shadowParams);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnormalOffsetPointShadow(shadowParams);\n\t\t\t\t\t\tdAtten *= getShadowOmniClusteredPCF3x3(shadowAtlasTexture, shadowParams, light.omniAtlasViewport, shadowEdgePixels, dLightDirW);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tdDiffuseLight += dAtten * light.color * dAtten3;\n\t}\n}\nvoid evaluateClusterLight(float lightIndex) {\n\tClusterLightData clusterLightData;\n\tdecodeClusterLightCore(clusterLightData, lightIndex);\n\tevaluateLight(clusterLightData);\n}\nvoid addClusteredLights() {\n\tvec3 cellCoords = floor((vPositionW - clusterBoundsMin) * clusterCellsCountByBoundsSize);\n\tif (!(any(lessThan(cellCoords, vec3(0.0))) || any(greaterThanEqual(cellCoords, clusterCellsMax)))) {\n\t\tfloat cellIndex = dot(clusterCellsDot, cellCoords);\n\t\tfloat clusterV = floor(cellIndex * clusterTextureSize.y);\n\t\tfloat clusterU = cellIndex - (clusterV * clusterTextureSize.x);\n\t\tclusterV = (clusterV + 0.5) * clusterTextureSize.z;\n\t\tconst float maxLightCells = 256.0 / 4.0;\n\t\tfor (float lightCellIndex = 0.5; lightCellIndex < maxLightCells; lightCellIndex++) {\n\t\t\tvec4 lightIndices = texture2D(clusterWorldTexture, vec2(clusterTextureSize.y * (clusterU + lightCellIndex), clusterV));\n\t\t\tvec4 indices = lightIndices * 255.0;\n\t\t\tif (indices.x <= 0.0)\n\t\t\t\tbreak;\n\t\t\tevaluateClusterLight(indices.x);\n\t\t\tif (indices.y <= 0.0)\n\t\t\t\tbreak;\n\t\t\tevaluateClusterLight(indices.y);\n\t\t\tif (indices.z <= 0.0)\n\t\t\t\tbreak;\n\t\t\tevaluateClusterLight(indices.z);\n\t\t\tif (indices.w <= 0.0)\n\t\t\t\tbreak;\n\t\t\tevaluateClusterLight(indices.w);\n\t\t\tif (lightCellIndex > clusterPixelsPerCell) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n";
|
|
5979
|
+
var clusteredLightPS = "uniform sampler2D clusterWorldTexture;\nuniform sampler2D lightsTexture8;\nuniform highp sampler2D lightsTextureFloat;\n#ifdef GL2\n\tuniform sampler2DShadow shadowAtlasTexture;\n#else\n\tuniform sampler2D shadowAtlasTexture;\n#endif\nuniform sampler2D cookieAtlasTexture;\nuniform float clusterPixelsPerCell;\nuniform vec3 clusterCellsCountByBoundsSize;\nuniform vec4 lightsTextureInvSize;\nuniform vec3 clusterTextureSize;\nuniform vec3 clusterBoundsMin;\nuniform vec3 clusterBoundsDelta;\nuniform vec3 clusterCellsDot;\nuniform vec3 clusterCellsMax;\nuniform vec2 clusterCompressionLimit0;\nuniform vec2 shadowAtlasParams;\nstruct ClusterLightData {\n\tfloat lightV;\n\tbool isSpot;\n\tfloat shape;\n\tfloat falloffMode;\n\tbool castShadows;\n\tfloat shadowBias;\n\tfloat shadowNormalBias;\n\tmat4 lightProjectionMatrix;\n\tvec3 position;\n\tvec3 direction;\n\tfloat range;\n\tfloat innerConeAngleCos;\n\tfloat outerConeAngleCos;\n\tvec3 color;\n\tvec3 omniAtlasViewport;\n\tbool isCookie;\n\tbool isCookieRgb;\n\tfloat cookieIntensity;\n\tvec4 cookieChannelMask;\n};\nvec4 decodeClusterLowRange4Vec4(vec4 d0, vec4 d1, vec4 d2, vec4 d3) {\n\treturn vec4(\n\t\tbytes2floatRange4(d0, -2.0, 2.0),\n\t\tbytes2floatRange4(d1, -2.0, 2.0),\n\t\tbytes2floatRange4(d2, -2.0, 2.0),\n\t\tbytes2floatRange4(d3, -2.0, 2.0)\n\t);\n}\nvec4 sampleLightsTexture8(const ClusterLightData clusterLightData, float index) {\n\treturn texture2D(lightsTexture8, vec2(index * lightsTextureInvSize.z, clusterLightData.lightV));\n}\nvec4 sampleLightTextureF(const ClusterLightData clusterLightData, float index) {\n\treturn texture2D(lightsTextureFloat, vec2(index * lightsTextureInvSize.x, clusterLightData.lightV));\n}\nvoid decodeClusterLightCore(inout ClusterLightData clusterLightData, float lightIndex) {\n\tclusterLightData.lightV = (lightIndex + 0.5) * lightsTextureInvSize.w;\n\tvec4 lightInfo = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_FLAGS);\n\tclusterLightData.isSpot = lightInfo.x > 0.5;\n\tclusterLightData.shape = lightInfo.y;\n\tclusterLightData.falloffMode = lightInfo.z;\n\tclusterLightData.castShadows = lightInfo.w > 0.5;\n\tvec4 colorA = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_COLOR_A);\n\tvec4 colorB = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_COLOR_B);\n\tclusterLightData.color = vec3(bytes2float2(colorA.xy), bytes2float2(colorA.zw), bytes2float2(colorB.xy)) * clusterCompressionLimit0.y;\n\tclusterLightData.isCookie = colorB.z > 0.5;\n\t#ifdef CLUSTER_TEXTURE_FLOAT\n\t\tvec4 lightPosRange = sampleLightTextureF(clusterLightData, CLUSTER_TEXTURE_F_POSITION_RANGE);\n\t\tclusterLightData.position = lightPosRange.xyz;\n\t\tclusterLightData.range = lightPosRange.w;\n\t\tvec4 lightDir_Unused = sampleLightTextureF(clusterLightData, CLUSTER_TEXTURE_F_SPOT_DIRECTION);\n\t\tclusterLightData.direction = lightDir_Unused.xyz;\n\t#else\n\t\tvec4 encPosX = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_POSITION_X);\n\t\tvec4 encPosY = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_POSITION_Y);\n\t\tvec4 encPosZ = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_POSITION_Z);\n\t\tclusterLightData.position = vec3(bytes2float4(encPosX), bytes2float4(encPosY), bytes2float4(encPosZ)) * clusterBoundsDelta + clusterBoundsMin;\n\t\tvec4 encRange = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_RANGE);\n\t\tclusterLightData.range = bytes2float4(encRange) * clusterCompressionLimit0.x;\n\t\tvec4 encDirX = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_SPOT_DIRECTION_X);\n\t\tvec4 encDirY = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_SPOT_DIRECTION_Y);\n\t\tvec4 encDirZ = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_SPOT_DIRECTION_Z);\n\t\tclusterLightData.direction = vec3(bytes2float4(encDirX), bytes2float4(encDirY), bytes2float4(encDirZ)) * 2.0 - 1.0;\n\t#endif\n}\nvoid decodeClusterLightSpot(inout ClusterLightData clusterLightData) {\n\tvec4 coneAngle = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_SPOT_ANGLES);\n\tclusterLightData.innerConeAngleCos = bytes2float2(coneAngle.xy) * 2.0 - 1.0;\n\tclusterLightData.outerConeAngleCos = bytes2float2(coneAngle.zw) * 2.0 - 1.0;\n}\nvoid decodeClusterLightOmniAtlasViewport(inout ClusterLightData clusterLightData) {\n\t#ifdef CLUSTER_TEXTURE_FLOAT\n\t\tclusterLightData.omniAtlasViewport = sampleLightTextureF(clusterLightData, CLUSTER_TEXTURE_F_PROJ_MAT_0).xyz;\n\t#else\n\t\tvec4 viewportA = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_ATLAS_VIEWPORT_A);\n\t\tvec4 viewportB = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_ATLAS_VIEWPORT_B);\n\t\tclusterLightData.omniAtlasViewport = vec3(bytes2float2(viewportA.xy), bytes2float2(viewportA.zw), bytes2float2(viewportB.xy));\n\t#endif\n}\nvoid decodeClusterLightProjectionMatrixData(inout ClusterLightData clusterLightData) {\n\t#ifdef CLUSTER_TEXTURE_FLOAT\n\t\tvec4 m0 = sampleLightTextureF(clusterLightData, CLUSTER_TEXTURE_F_PROJ_MAT_0);\n\t\tvec4 m1 = sampleLightTextureF(clusterLightData, CLUSTER_TEXTURE_F_PROJ_MAT_1);\n\t\tvec4 m2 = sampleLightTextureF(clusterLightData, CLUSTER_TEXTURE_F_PROJ_MAT_2);\n\t\tvec4 m3 = sampleLightTextureF(clusterLightData, CLUSTER_TEXTURE_F_PROJ_MAT_3);\n\t#else\n\t\tvec4 m00 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_00);\n\t\tvec4 m01 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_01);\n\t\tvec4 m02 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_02);\n\t\tvec4 m03 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_03);\n\t\tvec4 m0 = decodeClusterLowRange4Vec4(m00, m01, m02, m03);\n\t\tvec4 m10 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_10);\n\t\tvec4 m11 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_11);\n\t\tvec4 m12 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_12);\n\t\tvec4 m13 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_13);\n\t\tvec4 m1 = decodeClusterLowRange4Vec4(m10, m11, m12, m13);\n\t\tvec4 m20 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_20);\n\t\tvec4 m21 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_21);\n\t\tvec4 m22 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_22);\n\t\tvec4 m23 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_23);\n\t\tvec4 m2 = decodeClusterLowRange4Vec4(m20, m21, m22, m23);\n\t\tvec4 m30 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_30);\n\t\tvec4 m31 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_31);\n\t\tvec4 m32 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_32);\n\t\tvec4 m33 = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_PROJ_MAT_33);\n\t\tvec4 m3 = vec4(mantisaExponent2Float(m30), mantisaExponent2Float(m31), mantisaExponent2Float(m32), mantisaExponent2Float(m33));\n\t#endif\n\tclusterLightData.lightProjectionMatrix = mat4(m0, m1, m2, m3);\n}\nvoid decodeClusterLightShadowData(inout ClusterLightData clusterLightData) {\n\tvec4 biases = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_SHADOW_BIAS);\n\tclusterLightData.shadowBias = bytes2floatRange2(biases.xy, -1.0, 20.0),\n\tclusterLightData.shadowNormalBias = bytes2float2(biases.zw);\n}\nvoid decodeClusterLightCookieData(inout ClusterLightData clusterLightData) {\n\tvec4 cookieA = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_COOKIE_A);\n\tclusterLightData.cookieIntensity = cookieA.x;\n\tclusterLightData.isCookieRgb = cookieA.y > 0.5;\n\tclusterLightData.cookieChannelMask = sampleLightsTexture8(clusterLightData, CLUSTER_TEXTURE_8_COOKIE_B);\n}\nvoid evaluateLight(ClusterLightData light) {\n\tdAtten3 = vec3(1.0);\n\tgetLightDirPoint(light.position);\n\tdAtten = getFalloffLinear(light.range);\n\tif (dAtten > 0.00001) {\n\t\tdAtten *= getLightDiffuse();\n\t\tif (light.isSpot == true) {\n\t\t\tdecodeClusterLightSpot(light);\n\t\t\tdAtten *= getSpotEffect(light.direction, light.innerConeAngleCos, light.outerConeAngleCos);\n\t\t}\n\t\tif (dAtten > 0.00001) {\n\t\t\tif (light.castShadows == true || light.isCookie == true) {\n\t\t\t\tif (light.isSpot == true) {\n\t\t\t\t\tdecodeClusterLightProjectionMatrixData(light);\n\t\t\t\t} else {\n\t\t\t\t\tdecodeClusterLightOmniAtlasViewport(light);\n\t\t\t\t}\n\t\t\t\tfloat shadowTextureResolution = shadowAtlasParams.x;\n\t\t\t\tfloat shadowEdgePixels = shadowAtlasParams.y;\n\t\t\t\tif (light.isCookie == true) {\n\t\t\t\t\tdecodeClusterLightCookieData(light);\n\t\t\t\t\tif (light.isSpot == true) {\n\t\t\t\t\t\tdAtten3 = getCookie2DClustered(cookieAtlasTexture, light.lightProjectionMatrix, vPositionW, light.cookieIntensity, light.isCookieRgb, light.cookieChannelMask);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tdAtten3 = getCookieCubeClustered(cookieAtlasTexture, dLightDirW, light.cookieIntensity, light.isCookieRgb, light.cookieChannelMask, shadowTextureResolution, shadowEdgePixels, light.omniAtlasViewport);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tif (light.castShadows== true) {\n\t\t\t\t\tdecodeClusterLightShadowData(light);\n\t\t\t\t\tvec4 shadowParams = vec4(shadowTextureResolution, light.shadowNormalBias, light.shadowBias, 1.0 / light.range);\n\t\t\t\t\tif (light.isSpot == true) {\n\t\t\t\t\t\tgetShadowCoordPerspZbufferNormalOffset(light.lightProjectionMatrix, shadowParams);\n\t\t\t\t\t\tdAtten *= getShadowSpotPCF3x3(shadowAtlasTexture, shadowParams);\n\t\t\t\t\t} else {\n\t\t\t\t\t\tnormalOffsetPointShadow(shadowParams);\n\t\t\t\t\t\tdAtten *= getShadowOmniClusteredPCF3x3(shadowAtlasTexture, shadowParams, light.omniAtlasViewport, shadowEdgePixels, dLightDirW);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tdDiffuseLight += dAtten * light.color * dAtten3;\n\t}\n}\nvoid evaluateClusterLight(float lightIndex) {\n\tClusterLightData clusterLightData;\n\tdecodeClusterLightCore(clusterLightData, lightIndex);\n\tevaluateLight(clusterLightData);\n}\nconst vec4 channelSelector[4] = vec4[4] (\n\tvec4(1., 0., 0., 0.),\n\tvec4(0., 1., 0., 0.),\n\tvec4(0., 0., 1., 0.),\n\tvec4(0., 0., 0., 1.)\n);\nvoid addClusteredLights() {\n\tvec3 cellCoords = floor((vPositionW - clusterBoundsMin) * clusterCellsCountByBoundsSize);\n\tif (!(any(lessThan(cellCoords, vec3(0.0))) || any(greaterThanEqual(cellCoords, clusterCellsMax)))) {\n\t\tfloat cellIndex = dot(clusterCellsDot, cellCoords);\n\t\tfloat clusterV = floor(cellIndex * clusterTextureSize.y);\n\t\tfloat clusterU = cellIndex - (clusterV * clusterTextureSize.x);\n\t\tclusterV = (clusterV + 0.5) * clusterTextureSize.z;\n\t\tconst float maxLightCells = 256.0 / 4.0;\n\t\tfor (float lightCellIndex = 0.5; lightCellIndex < maxLightCells; lightCellIndex++) {\n\t\t\tvec4 lightIndices = texture2D(clusterWorldTexture, vec2(clusterTextureSize.y * (clusterU + lightCellIndex), clusterV));\n\t\t\tvec4 indices = lightIndices * 255.0;\n\t\t\tfor (int i = 0; i < 4; i++) {\n\t\t\t\tfloat index = dot(channelSelector[i], indices);\n\t\t\t\tif (index <= 0.0)\n\t\t\t\t\treturn;\n\t\t\t\tevaluateClusterLight(index);\n\t\t\t}\n\t\t\tif (lightCellIndex > clusterPixelsPerCell) {\n\t\t\t\tbreak;\n\t\t\t}\n\t\t}\n\t}\n}\n";
|
|
5980
5980
|
|
|
5981
5981
|
var combineClearCoatPS = "vec3 combineColorCC() {\n\treturn combineColor()+(ccSpecularLight*ccSpecularity+ccReflection.rgb*ccSpecularity*ccReflection.a);\n}\n";
|
|
5982
5982
|
|
|
@@ -11580,6 +11580,7 @@
|
|
|
11580
11580
|
var useVsm = false;
|
|
11581
11581
|
var usePerspZbufferShadow = false;
|
|
11582
11582
|
var light;
|
|
11583
|
+
var isClustered = LayerComposition.clusteredLightingEnabled;
|
|
11583
11584
|
var hasAreaLights = options.lights.some(function (light) {
|
|
11584
11585
|
return light._shape && light._shape !== LIGHTSHAPE_PUNCTUAL;
|
|
11585
11586
|
});
|
|
@@ -11602,6 +11603,7 @@
|
|
|
11602
11603
|
for (i = 0; i < options.lights.length; i++) {
|
|
11603
11604
|
light = options.lights[i];
|
|
11604
11605
|
lightType = light._type;
|
|
11606
|
+
if (isClustered && lightType !== LIGHTTYPE_DIRECTIONAL) continue;
|
|
11605
11607
|
|
|
11606
11608
|
if (hasAreaLights && light._shape) {
|
|
11607
11609
|
lightShape = light._shape;
|
|
@@ -38354,7 +38356,7 @@
|
|
|
38354
38356
|
};
|
|
38355
38357
|
|
|
38356
38358
|
_proto.readU64 = function readU64() {
|
|
38357
|
-
return this.
|
|
38359
|
+
return this.readU32() + Math.pow(2, 32) * this.readU32();
|
|
38358
38360
|
};
|
|
38359
38361
|
|
|
38360
38362
|
_proto.readU32be = function readU32be() {
|
|
@@ -71540,12 +71542,11 @@
|
|
|
71540
71542
|
}
|
|
71541
71543
|
};
|
|
71542
71544
|
|
|
71543
|
-
_proto.calculateLightmapSize = function calculateLightmapSize(
|
|
71545
|
+
_proto.calculateLightmapSize = function calculateLightmapSize(node) {
|
|
71544
71546
|
var data;
|
|
71545
71547
|
var sizeMult = this.scene.lightmapSizeMultiplier || 16;
|
|
71546
71548
|
var scale = tempVec;
|
|
71547
71549
|
var srcArea, lightmapSizeMultiplier;
|
|
71548
|
-
var node = bakeNode.node;
|
|
71549
71550
|
|
|
71550
71551
|
if (node.model) {
|
|
71551
71552
|
lightmapSizeMultiplier = node.model.lightmapSizeMultiplier;
|
|
@@ -71595,7 +71596,9 @@
|
|
|
71595
71596
|
area.x *= areaMult;
|
|
71596
71597
|
area.y *= areaMult;
|
|
71597
71598
|
area.z *= areaMult;
|
|
71598
|
-
|
|
71599
|
+
var component = node.render || node.model;
|
|
71600
|
+
var bounds = this.computeNodeBounds(component.meshInstances);
|
|
71601
|
+
scale.copy(bounds.halfExtents);
|
|
71599
71602
|
var totalArea = area.x * scale.y * scale.z + area.y * scale.x * scale.z + area.z * scale.x * scale.y;
|
|
71600
71603
|
totalArea /= area.uv;
|
|
71601
71604
|
totalArea = Math.sqrt(totalArea);
|
|
@@ -71689,7 +71692,7 @@
|
|
|
71689
71692
|
_proto.allocateTextures = function allocateTextures(bakeNodes, passCount) {
|
|
71690
71693
|
for (var i = 0; i < bakeNodes.length; i++) {
|
|
71691
71694
|
var bakeNode = bakeNodes[i];
|
|
71692
|
-
var size = this.calculateLightmapSize(bakeNode);
|
|
71695
|
+
var size = this.calculateLightmapSize(bakeNode.node);
|
|
71693
71696
|
|
|
71694
71697
|
for (var pass = 0; pass < passCount; pass++) {
|
|
71695
71698
|
var tex = this.createTexture(size, TEXTURETYPE_DEFAULT, "lightmapper_lightmap_" + i);
|
|
@@ -71770,21 +71773,24 @@
|
|
|
71770
71773
|
}
|
|
71771
71774
|
};
|
|
71772
71775
|
|
|
71773
|
-
_proto.computeNodeBounds = function computeNodeBounds(
|
|
71776
|
+
_proto.computeNodeBounds = function computeNodeBounds(meshInstances) {
|
|
71774
71777
|
var bounds = new BoundingBox();
|
|
71775
71778
|
|
|
71776
|
-
|
|
71777
|
-
|
|
71778
|
-
|
|
71779
|
-
if (meshInstances.length > 0) {
|
|
71780
|
-
bounds.copy(meshInstances[0].aabb);
|
|
71779
|
+
if (meshInstances.length > 0) {
|
|
71780
|
+
bounds.copy(meshInstances[0].aabb);
|
|
71781
71781
|
|
|
71782
|
-
|
|
71783
|
-
|
|
71784
|
-
}
|
|
71782
|
+
for (var m = 1; m < meshInstances.length; m++) {
|
|
71783
|
+
bounds.add(meshInstances[m].aabb);
|
|
71785
71784
|
}
|
|
71785
|
+
}
|
|
71786
71786
|
|
|
71787
|
-
|
|
71787
|
+
return bounds;
|
|
71788
|
+
};
|
|
71789
|
+
|
|
71790
|
+
_proto.computeNodesBounds = function computeNodesBounds(nodes) {
|
|
71791
|
+
for (var i = 0; i < nodes.length; i++) {
|
|
71792
|
+
var meshInstances = nodes[i].meshInstances;
|
|
71793
|
+
nodes[i].bounds = this.computeNodeBounds(meshInstances);
|
|
71788
71794
|
}
|
|
71789
71795
|
};
|
|
71790
71796
|
|
|
@@ -71940,7 +71946,7 @@
|
|
|
71940
71946
|
|
|
71941
71947
|
scene.layers._update();
|
|
71942
71948
|
|
|
71943
|
-
this.
|
|
71949
|
+
this.computeNodesBounds(bakeNodes);
|
|
71944
71950
|
this.allocateTextures(bakeNodes, passCount);
|
|
71945
71951
|
var allLights = [],
|
|
71946
71952
|
bakeLights = [];
|