@galacean/engine 2.0.0-alpha.23 → 2.0.0-alpha.25

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/dist/browser.js CHANGED
@@ -9854,7 +9854,7 @@
9854
9854
  var pbr_helper = "#include <normal_get>\n#include <brdf>\n#include <btdf>\n\n// direct + indirect\n#include <direct_irradiance_frag_define>\n#include <ibl_frag_define>\n\nuniform sampler2D camera_AOTexture;\n\nfloat evaluateAmbientOcclusion(vec2 uv)\n{\n #ifdef MATERIAL_IS_TRANSPARENT\n return 1.0;\n #else\n return texture2D(camera_AOTexture, uv).r;\n #endif\n}\n\n\nfloat computeSpecularOcclusion(float ambientOcclusion, float roughness, float dotNV ) {\n return saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion );\n}\n\nfloat getAARoughnessFactor(vec3 normal) {\n // Kaplanyan 2016, \"Stable specular highlights\"\n // Tokuyoshi 2017, \"Error Reduction and Simplification for Shading Anti-Aliasing\"\n // Tokuyoshi and Kaplanyan 2019, \"Improved Geometric Specular Antialiasing\"\n #ifdef HAS_DERIVATIVES\n vec3 dxy = max( abs(dFdx(normal)), abs(dFdy(normal)) );\n return max( max(dxy.x, dxy.y), dxy.z );\n #else\n return 0.0;\n #endif\n}\n\n#ifdef MATERIAL_ENABLE_ANISOTROPY\n // Aniso Bent Normals\n // Mc Alley https://www.gdcvault.com/play/1022235/Rendering-the-World-of-Far \n vec3 getAnisotropicBentNormal(Geometry geometry, vec3 n, float roughness) {\n vec3 anisotropyDirection = geometry.anisotropy >= 0.0 ? geometry.anisotropicB : geometry.anisotropicT;\n vec3 anisotropicTangent = cross(anisotropyDirection, geometry.viewDir);\n vec3 anisotropicNormal = cross(anisotropicTangent, anisotropyDirection);\n // reduce stretching for (roughness < 0.2), refer to https://advances.realtimerendering.com/s2018/Siggraph%202018%20HDRP%20talk_with%20notes.pdf 80\n vec3 bentNormal = normalize( mix(n, anisotropicNormal, abs(geometry.anisotropy) * saturate( 5.0 * roughness)) );\n\n return bentNormal;\n }\n#endif\n\nvoid initGeometry(out Geometry geometry, bool isFrontFacing){\n geometry.position = v_pos;\n #ifdef CAMERA_ORTHOGRAPHIC\n geometry.viewDir = -camera_Forward;\n #else\n geometry.viewDir = normalize(camera_Position - v_pos);\n #endif\n #if defined(MATERIAL_HAS_NORMALTEXTURE) || defined(MATERIAL_HAS_CLEAR_COAT_NORMAL_TEXTURE) || defined(MATERIAL_ENABLE_ANISOTROPY)\n mat3 tbn = getTBN(isFrontFacing);\n #endif\n\n #ifdef MATERIAL_HAS_NORMALTEXTURE\n geometry.normal = getNormalByNormalTexture(tbn, material_NormalTexture, material_NormalIntensity, v_uv, isFrontFacing);\n #else\n geometry.normal = getNormal(isFrontFacing);\n #endif\n\n geometry.dotNV = saturate( dot(geometry.normal, geometry.viewDir) );\n\n\n #ifdef MATERIAL_ENABLE_CLEAR_COAT\n #ifdef MATERIAL_HAS_CLEAR_COAT_NORMAL_TEXTURE\n geometry.clearCoatNormal = getNormalByNormalTexture(tbn, material_ClearCoatNormalTexture, material_NormalIntensity, v_uv, isFrontFacing);\n #else\n geometry.clearCoatNormal = getNormal(isFrontFacing);\n #endif\n geometry.clearCoatDotNV = saturate( dot(geometry.clearCoatNormal, geometry.viewDir) );\n #endif\n\n #ifdef MATERIAL_ENABLE_ANISOTROPY\n float anisotropy = material_AnisotropyInfo.z;\n vec3 anisotropicDirection = vec3(material_AnisotropyInfo.xy, 0.0);\n #ifdef MATERIAL_HAS_ANISOTROPY_TEXTURE\n vec3 anisotropyTextureInfo = texture2D( material_AnisotropyTexture, v_uv ).rgb;\n anisotropy *= anisotropyTextureInfo.b;\n anisotropicDirection.xy *= anisotropyTextureInfo.rg * 2.0 - 1.0;\n #endif\n\n geometry.anisotropy = anisotropy;\n geometry.anisotropicT = normalize(tbn * anisotropicDirection);\n geometry.anisotropicB = normalize(cross(geometry.normal, geometry.anisotropicT));\n #endif\n}\n\nvoid initMaterial(out Material material, inout Geometry geometry){\n vec4 baseColor = material_BaseColor;\n float metal = material_Metal;\n float roughness = material_Roughness;\n float alphaCutoff = material_AlphaCutoff;\n material.IOR = material_IOR;\n\n #ifdef MATERIAL_HAS_BASETEXTURE\n baseColor *= texture2DSRGB(material_BaseTexture, v_uv);\n #endif\n\n #ifdef RENDERER_ENABLE_VERTEXCOLOR\n baseColor *= v_color;\n #endif\n\n\n #ifdef MATERIAL_IS_ALPHA_CUTOFF\n if( baseColor.a < alphaCutoff ) {\n discard;\n }\n #endif\n\n #ifdef MATERIAL_HAS_ROUGHNESS_METALLIC_TEXTURE\n vec4 metalRoughMapColor = texture2D( material_RoughnessMetallicTexture, v_uv );\n roughness *= metalRoughMapColor.g;\n metal *= metalRoughMapColor.b;\n #endif\n\n // Specular\n material.specularIntensity = material_SpecularIntensity;\n material.specularColor = material_SpecularColor;\n #ifdef MATERIAL_HAS_SPECULAR_TEXTURE\n material.specularIntensity *= texture2D( material_SpecularIntensityTexture, v_uv ).a;\n #endif\n\n #ifdef MATERIAL_ENABLE_CLEAR_COAT\n material.clearCoat = material_ClearCoat;\n material.clearCoatRoughness = material_ClearCoatRoughness;\n #ifdef MATERIAL_HAS_CLEAR_COAT_TEXTURE\n material.clearCoat *= texture2D( material_ClearCoatTexture, v_uv ).r;\n #endif\n #ifdef MATERIAL_HAS_CLEAR_COAT_ROUGHNESS_TEXTURE\n material.clearCoatRoughness *= texture2D( material_ClearCoatRoughnessTexture, v_uv ).g;\n #endif\n material.clearCoat = saturate( material.clearCoat );\n material.clearCoatRoughness = max(MIN_PERCEPTUAL_ROUGHNESS, min(material.clearCoatRoughness + getAARoughnessFactor(geometry.clearCoatNormal), 1.0));\n #endif\n\n #ifdef MATERIAL_IS_TRANSPARENT\n material.opacity = baseColor.a;\n #else\n material.opacity = 1.0;\n #endif\n\n material.roughness = max(MIN_PERCEPTUAL_ROUGHNESS, min(roughness + getAARoughnessFactor(geometry.normal), 1.0));\n\n #ifdef MATERIAL_ENABLE_ANISOTROPY\n geometry.anisotropicN = getAnisotropicBentNormal(geometry, geometry.normal, material.roughness);\n #endif\n\n vec3 dielectricBaseF0 = vec3(pow2( (material.IOR - 1.0) / (material.IOR + 1.0) ));\n vec3 dielectricF0 = min(dielectricBaseF0 * material.specularColor , vec3(1.0)) * material.specularIntensity;\n float dielectricF90 = material.specularIntensity; \n\n material.specularF0 = mix(dielectricF0, baseColor.rgb, metal);\n material.specularF90 = mix(dielectricF90, 1.0, metal);\n material.resolvedSpecularF0 = material.specularF0;\n\n // Simplify: albedoColor * mix((1.0 - max(max(dielectricF0.r,dielectricF0.g),dielectricF0.b)), 0.0, metallic);\n material.diffuseColor = baseColor.rgb * (1.0 - metal) * (1.0 - max(max(dielectricF0.r,dielectricF0.g),dielectricF0.b));\n // Environment BRDF\n vec2 dfg = envDFGApprox(material.roughness, geometry.dotNV);\n\n // AO\n float diffuseAO = 1.0;\n float specularAO = 1.0;\n\n #ifdef MATERIAL_HAS_OCCLUSION_TEXTURE\n vec2 aoUV = v_uv;\n #ifdef RENDERER_HAS_UV1\n if(material_OcclusionTextureCoord == 1.0){\n aoUV = v_uv1;\n }\n #endif\n diffuseAO = ((texture2D(material_OcclusionTexture, aoUV)).r - 1.0) * material_OcclusionIntensity + 1.0;\n #endif\n\n #ifdef SCENE_ENABLE_AMBIENT_OCCLUSION\n float ambientAO = evaluateAmbientOcclusion((v_PositionCS.xy / v_PositionCS.w) * 0.5 + 0.5);\n diffuseAO = min(diffuseAO, ambientAO);\n #endif\n\n #if (defined(MATERIAL_HAS_OCCLUSION_TEXTURE) || defined(SCENE_ENABLE_AMBIENT_OCCLUSION))&& defined(SCENE_USE_SPECULAR_ENV) \n specularAO = saturate( pow( geometry.dotNV + diffuseAO, exp2( - 16.0 * material.roughness - 1.0 ) ) - 1.0 + diffuseAO );\n #endif\n\n material.diffuseAO = diffuseAO;\n material.specularAO = specularAO;\n\n // Sheen\n #ifdef MATERIAL_ENABLE_SHEEN\n vec3 sheenColor = material_SheenColor;\n #ifdef MATERIAL_HAS_SHEEN_TEXTURE\n sheenColor *= texture2DSRGB(material_SheenTexture, v_uv).rgb;\n #endif\n material.sheenColor = sheenColor;\n\n material.sheenRoughness = material_SheenRoughness;\n #ifdef MATERIAL_HAS_SHEEN_ROUGHNESS_TEXTURE\n material.sheenRoughness *= texture2D(material_SheenRoughnessTexture, v_uv).a;\n #endif\n\n material.sheenRoughness = max(MIN_PERCEPTUAL_ROUGHNESS, min(material.sheenRoughness + getAARoughnessFactor(geometry.normal), 1.0));\n material.approxIBLSheenDG = prefilteredSheenDFG(geometry.dotNV, material.sheenRoughness);\n material.sheenScaling = 1.0 - material.approxIBLSheenDG * max(max(material.sheenColor.r, material.sheenColor.g), material.sheenColor.b);\n #endif\n\n // Iridescence\n #ifdef MATERIAL_ENABLE_IRIDESCENCE\n material.iridescenceFactor = material_IridescenceInfo.x;\n material.iridescenceIOR = material_IridescenceInfo.y;\n\n #ifdef MATERIAL_HAS_IRIDESCENCE_THICKNESS_TEXTURE\n float iridescenceThicknessWeight = texture2D( material_IridescenceThicknessTexture, v_uv).g;\n material.iridescenceThickness = mix(material_IridescenceInfo.z, material_IridescenceInfo.w, iridescenceThicknessWeight);\n #else\n material.iridescenceThickness = material_IridescenceInfo.w;\n #endif\n\n #ifdef MATERIAL_HAS_IRIDESCENCE_TEXTURE\n material.iridescenceFactor *= texture2D( material_IridescenceTexture, v_uv).r;\n #endif\n \n #ifdef MATERIAL_ENABLE_IRIDESCENCE\n float topIOR = 1.0;\n material.iridescenceSpecularColor = evalIridescenceSpecular(topIOR, geometry.dotNV, material.iridescenceIOR, material.specularF0, material.specularF90, material.iridescenceThickness);\n material.resolvedSpecularF0 = mix(material.resolvedSpecularF0, material.iridescenceSpecularColor, material.iridescenceFactor);\n #endif\n #endif\n\n material.envSpecularDFG = material.resolvedSpecularF0 * dfg.x + material.specularF90 * dfg.y;\n\n // Multi-scattering energy compensation\n // Ref: Kulla & Conty 2017, \"Revisiting Physically Based Shading at Imageworks\"\n // Ref: Lagarde & Golubev 2018, simplified multiplier approach\n material.energyCompensation = 1.0 + material.resolvedSpecularF0 * (1.0 / max(dfg.x + dfg.y, EPSILON) - 1.0);\n\n // Transmission\n #ifdef MATERIAL_ENABLE_TRANSMISSION \n material.transmission = material_Transmission;\n #ifdef MATERIAL_HAS_TRANSMISSION_TEXTURE\n material.transmission *= texture2D(material_TransmissionTexture, v_uv).r;\n #endif\n\n #ifdef MATERIAL_HAS_THICKNESS\n material.absorptionCoefficient = -log(material_AttenuationColor + HALF_EPS) / max(HALF_EPS, material_AttenuationDistance);\n material.thickness = max(material_Thickness, 0.0001);\n #ifdef MATERIAL_HAS_THICKNESS_TEXTURE\n material.thickness *= texture2D( material_ThicknessTexture, v_uv).g;\n #endif\n #endif \n #endif\n}\n\n"; // eslint-disable-line
9855
9855
  var brdf = "\n#ifdef MATERIAL_ENABLE_SHEEN\n uniform sampler2D scene_PrefilteredDFG;\n#endif\n\nfloat F_Schlick(float f0, float f90, float dotLH) {\n\treturn f0 + (f90 - f0) * (pow(1.0 - dotLH, 5.0));\n}\n\nvec3 F_Schlick(vec3 f0, float f90, float dotLH ) {\n\n\t// Original approximation by Christophe Schlick '94\n\t// float fresnel = pow( 1.0 - dotLH, 5.0 );\n\n\t// Optimized variant (presented by Epic at SIGGRAPH '13)\n\t// https://cdn2.unrealengine.com/Resources/files/2013SiggraphPresentationsNotes-26915738.pdf\n\tfloat fresnel = exp2( ( -5.55473 * dotLH - 6.98316 ) * dotLH );\n\n\treturn (f90 - f0 ) * fresnel + f0;\n\n}\n\n// Moving Frostbite to Physically Based Rendering 3.0 - page 12, listing 2\n// https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf\nfloat G_GGX_SmithCorrelated(float alpha, float dotNL, float dotNV ) {\n\n\tfloat a2 = pow2( alpha );\n\n\t// dotNL and dotNV are explicitly swapped. This is not a mistake.\n\tfloat gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) );\n\tfloat gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) );\n\n\treturn 0.5 / max( gv + gl, EPSILON );\n\n}\n\n#ifdef MATERIAL_ENABLE_ANISOTROPY\n // Heitz 2014, \"Understanding the Masking-Shadowing Function in Microfacet-Based BRDFs\"\n // Heitz http://jcgt.org/published/0003/02/03/paper.pdf\n float G_GGX_SmithCorrelated_Anisotropic(float at, float ab, float ToV, float BoV, float ToL, float BoL, float NoV, float NoL) {\n float lambdaV = NoL * length(vec3(at * ToV, ab * BoV, NoV));\n float lambdaL = NoV * length(vec3(at * ToL, ab * BoL, NoL));\n return 0.5 / max(lambdaV + lambdaL, EPSILON);\n }\n#endif\n\n// Microfacet Models for Refraction through Rough Surfaces - equation (33)\n// http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html\n// alpha is \"roughness squared\" in Disney’s reparameterization\nfloat D_GGX(float alpha, float dotNH ) {\n\n\tfloat a2 = pow2( alpha );\n\n\tfloat denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0; // avoid alpha = 0 with dotNH = 1\n\n\treturn RECIPROCAL_PI * a2 / pow2( denom );\n\n}\n\n#ifdef MATERIAL_ENABLE_SHEEN\n // http://www.aconty.com/pdf/s2017_pbs_imageworks_sheen.pdf\n float D_Charlie(float roughness, float dotNH) {\n float invAlpha = 1.0 / roughness;\n float cos2h = dotNH * dotNH;\n float sin2h = max(1.0 - cos2h, 0.0078125); // 2^(-14/2), so sin2h^2 > 0 in fp16\n return (2.0 + invAlpha) * pow(sin2h, invAlpha * 0.5) / (2.0 * PI);\n }\n\n // Neubelt and Pettineo 2013, \"Crafting a Next-gen Material Pipeline for The Order: 1886\".\n float V_Neubelt(float NoV, float NoL) {\n return saturate(1.0 / (4.0 * (NoL + NoV - NoL * NoV)));\n }\n\n vec3 sheenBRDF(vec3 incidentDirection, Geometry geometry, vec3 sheenColor, float sheenRoughness) {\n vec3 halfDir = normalize(incidentDirection + geometry.viewDir);\n float dotNL = saturate(dot(geometry.normal, incidentDirection));\n float dotNH = saturate(dot(geometry.normal, halfDir));\n float D = D_Charlie(sheenRoughness, dotNH);\n float V = V_Neubelt(geometry.dotNV, dotNL);\n vec3 F = sheenColor;\n return D * V * F;\n }\n\n float prefilteredSheenDFG(float dotNV, float sheenRoughness) {\n #ifdef HAS_TEX_LOD\n return texture2DLodEXT(scene_PrefilteredDFG, vec2(dotNV, sheenRoughness), 0.0).b;\n #else\n return texture2D(scene_PrefilteredDFG, vec2(dotNV, sheenRoughness),0.0).b;\n #endif \n }\n#endif\n\n#ifdef MATERIAL_ENABLE_ANISOTROPY\n // GGX Distribution Anisotropic\n // https://blog.selfshadow.com/publications/s2012-shading-course/burley/s2012_pbs_disney_brdf_notes_v3.pdf Addenda\n float D_GGX_Anisotropic(float at, float ab, float ToH, float BoH, float NoH) {\n float a2 = at * ab;\n vec3 d = vec3(ab * ToH, at * BoH, a2 * NoH);\n float d2 = dot(d, d);\n float b2 = a2 / d2;\n return a2 * b2 * b2 * RECIPROCAL_PI;\n }\n#endif\n\nfloat DG_GGX(float alpha, float dotNV, float dotNL, float dotNH) {\n\tfloat D = D_GGX( alpha, dotNH );\n\tfloat G = G_GGX_SmithCorrelated( alpha, dotNL, dotNV );\n return G * D;\n}\n\n#ifdef MATERIAL_ENABLE_ANISOTROPY\n float DG_GGX_anisotropic(vec3 h, vec3 l, Geometry geometry, float alpha, float dotNV, float dotNL, float dotNH) {\n vec3 t = geometry.anisotropicT;\n vec3 b = geometry.anisotropicB;\n vec3 v = geometry.viewDir;\n\n float dotTV = dot(t, v);\n float dotBV = dot(b, v);\n float dotTL = dot(t, l);\n float dotBL = dot(b, l);\n float dotTH = dot(t, h);\n float dotBH = dot(b, h);\n\n // Aniso parameter remapping\n // https://blog.selfshadow.com/publications/s2017-shading-course/imageworks/s2017_pbs_imageworks_slides_v2.pdf page 24\n float at = max(alpha * (1.0 + geometry.anisotropy), MIN_ROUGHNESS);\n float ab = max(alpha * (1.0 - geometry.anisotropy), MIN_ROUGHNESS);\n\n // specular anisotropic BRDF\n float D = D_GGX_Anisotropic(at, ab, dotTH, dotBH, dotNH);\n float G = G_GGX_SmithCorrelated_Anisotropic(at, ab, dotTV, dotBV, dotTL, dotBL, dotNV, dotNL);\n\n return G * D;\n }\n#endif\n\n#ifdef MATERIAL_ENABLE_IRIDESCENCE\n vec3 iorToFresnel0(vec3 transmittedIOR, float incidentIOR) {\n return pow((transmittedIOR - incidentIOR) / (transmittedIOR + incidentIOR),vec3(2.0));\n } \n\n float iorToFresnel0(float transmittedIOR, float incidentIOR) {\n return pow((transmittedIOR - incidentIOR) / (transmittedIOR + incidentIOR),2.0);\n } \n\n // Assume air interface for top\n // Note: We don't handle the case fresnel0 == 1\n vec3 fresnelToIOR(vec3 f0){\n vec3 sqrtF0 = sqrt(f0);\n return (vec3(1.0) + sqrtF0) / (vec3(1.0) - sqrtF0);\n }\n\n // Fresnel equations for dielectric/dielectric interfaces.\n // Ref: https://belcour.github.io/blog/research/publication/2017/05/01/brdf-thin-film.html\n // Evaluation XYZ sensitivity curves in Fourier space\n vec3 evalSensitivity(float opd, vec3 shift){\n // Use Gaussian fits, given by 3 parameters: val, pos and var\n float phase = 2.0 * PI * opd * 1.0e-9;\n const vec3 val = vec3(5.4856e-13, 4.4201e-13, 5.2481e-13);\n const vec3 pos = vec3(1.6810e+06, 1.7953e+06, 2.2084e+06);\n const vec3 var = vec3(4.3278e+09, 9.3046e+09, 6.6121e+09);\n vec3 xyz = val * sqrt(2.0 * PI * var) * cos(pos * phase + shift) * exp(-var * pow2(phase));\n xyz.x += 9.7470e-14 * sqrt(2.0 * PI * 4.5282e+09) * cos(2.2399e+06 * phase + shift[0]) * exp(-4.5282e+09 * pow2(phase));\n xyz /= 1.0685e-7;\n // XYZ to RGB color space\n const mat3 XYZ_TO_RGB = mat3( 3.2404542, -0.9692660, 0.0556434,\n -1.5371385, 1.8760108, -0.2040259,\n -0.4985314, 0.0415560, 1.0572252);\n vec3 rgb = XYZ_TO_RGB * xyz;\n return rgb;\n }\n\n vec3 evalIridescenceSpecular(float outsideIOR, float dotNV, float thinIOR, vec3 baseF0, float baseF90, float iridescenceThickness){ \n vec3 iridescence = vec3(1.0);\n // Force iridescenceIOR -> outsideIOR when thinFilmThickness -> 0.0\n float iridescenceIOR = mix( outsideIOR, thinIOR, smoothstep( 0.0, 0.03, iridescenceThickness ) );\n // Evaluate the cosTheta on the base layer (Snell law)\n float sinTheta2Sq = pow( outsideIOR / iridescenceIOR, 2.0) * (1.0 - pow( dotNV, 2.0));\n float cosTheta2Sq = 1.0 - sinTheta2Sq;\n // Handle total internal reflection\n if (cosTheta2Sq < 0.0) {\n return iridescence;\n }\n float cosTheta2 = sqrt(cosTheta2Sq);\n \n // First interface\n float f0 = iorToFresnel0(iridescenceIOR, outsideIOR);\n float reflectance = F_Schlick(f0, baseF90, dotNV);\n float t121 = 1.0 - reflectance;\n float phi12 = 0.0;\n // iridescenceIOR has limited greater than 1.0\n // if (iridescenceIOR < outsideIOR) {phi12 = PI;} \n float phi21 = PI - phi12;\n \n // Second interface\n vec3 baseIOR = fresnelToIOR(clamp(baseF0, 0.0, 0.9999)); // guard against 1.0\n vec3 r1 = iorToFresnel0(baseIOR, iridescenceIOR);\n vec3 r23 = F_Schlick(r1, baseF90, cosTheta2);\n vec3 phi23 =vec3(0.0);\n if (baseIOR[0] < iridescenceIOR) {phi23[0] = PI;}\n if (baseIOR[1] < iridescenceIOR) {phi23[1] = PI;}\n if (baseIOR[2] < iridescenceIOR) {phi23[2] = PI;}\n \n // Phase shift\n float opd = 2.0 * iridescenceIOR * iridescenceThickness * cosTheta2;\n vec3 phi = vec3(phi21) + phi23;\n \n // Compound terms\n vec3 r123 = clamp(reflectance * r23, 1e-5, 0.9999);\n vec3 sr123 = sqrt(r123);\n vec3 rs = pow2(t121) * r23 / (vec3(1.0) - r123);\n // Reflectance term for m = 0 (DC term amplitude)\n vec3 c0 = reflectance + rs;\n iridescence = c0;\n // Reflectance term for m > 0 (pairs of diracs)\n vec3 cm = rs - t121;\n for (int m = 1; m <= 2; ++m) {\n cm *= sr123;\n vec3 sm = 2.0 * evalSensitivity(float(m) * opd, float(m) * phi);\n iridescence += cm * sm;\n }\n return iridescence = max(iridescence, vec3(0.0)); \n }\n#endif\n\n// GGX Distribution, Schlick Fresnel, GGX-Smith Visibility\nvec3 BRDF_Specular_GGX(vec3 incidentDirection, Geometry geometry, Material material, vec3 normal, vec3 specularColor, float roughness ) {\n\n\tfloat alpha = pow2( roughness ); // UE4's roughness\n\n\tvec3 halfDir = normalize( incidentDirection + geometry.viewDir );\n\n\tfloat dotNL = saturate( dot( normal, incidentDirection ) );\n\tfloat dotNV = saturate( dot( normal, geometry.viewDir ) );\n\tfloat dotNH = saturate( dot( normal, halfDir ) );\n\tfloat dotLH = saturate( dot( incidentDirection, halfDir ) );\n\n vec3 F = F_Schlick( specularColor, material.specularF90, dotLH );\n #ifdef MATERIAL_ENABLE_IRIDESCENCE\n F = mix(F, material.iridescenceSpecularColor, material.iridescenceFactor);\n #endif\n\n #ifdef MATERIAL_ENABLE_ANISOTROPY\n float GD = DG_GGX_anisotropic(halfDir, incidentDirection, geometry, alpha, dotNV, dotNL, dotNH);\n #else\n float GD = DG_GGX(alpha, dotNV, dotNL, dotNH);\n #endif\n\n return F * GD;\n}\n\nvec3 BRDF_Diffuse_Lambert(vec3 diffuseColor ) {\n\treturn RECIPROCAL_PI * diffuseColor;\n}\n"; // eslint-disable-line
9856
9856
  var direct_irradiance_frag_define = "#include <ShadowFragmentDeclaration>\n\nvoid sheenLobe(Geometry geometry, Material material, vec3 incidentDirection, vec3 attenuationIrradiance, inout vec3 diffuseColor, inout vec3 specularColor){\n #ifdef MATERIAL_ENABLE_SHEEN\n diffuseColor *= material.sheenScaling;\n specularColor *= material.sheenScaling;\n\n specularColor += attenuationIrradiance * sheenBRDF(incidentDirection, geometry, material.sheenColor, material.sheenRoughness);\n #endif\n}\n\nvoid addDirectRadiance(vec3 incidentDirection, vec3 color, Geometry geometry, Material material, inout ReflectedLight reflectedLight) {\n float attenuation = 1.0;\n\n #ifdef MATERIAL_ENABLE_CLEAR_COAT\n float clearCoatDotNL = saturate( dot( geometry.clearCoatNormal, incidentDirection ) );\n vec3 clearCoatIrradiance = clearCoatDotNL * color;\n\n reflectedLight.directSpecular += material.clearCoat * clearCoatIrradiance * BRDF_Specular_GGX( incidentDirection, geometry, material, geometry.clearCoatNormal, vec3( 0.04 ), material.clearCoatRoughness );\n attenuation -= material.clearCoat * F_Schlick(0.04, 1.0, geometry.clearCoatDotNV);\n #endif\n\n float dotNL = saturate( dot( geometry.normal, incidentDirection ) );\n vec3 irradiance = dotNL * color * PI;\n\n reflectedLight.directSpecular += attenuation * irradiance * BRDF_Specular_GGX( incidentDirection, geometry, material, geometry.normal, material.specularF0, material.roughness) * material.energyCompensation;\n reflectedLight.directDiffuse += attenuation * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\n // Sheen Lobe\n sheenLobe(geometry, material, incidentDirection, attenuation * irradiance, reflectedLight.directDiffuse, reflectedLight.directSpecular);\n\n}\n\n#ifdef SCENE_DIRECT_LIGHT_COUNT\n\n void addDirectionalDirectLightRadiance(DirectLight directionalLight, Geometry geometry, Material material, inout ReflectedLight reflectedLight) {\n vec3 color = directionalLight.color;\n vec3 direction = -directionalLight.direction;\n\n\t\taddDirectRadiance( direction, color, geometry, material, reflectedLight );\n\n }\n\n#endif\n\n#ifdef SCENE_POINT_LIGHT_COUNT\n\n\tvoid addPointDirectLightRadiance(PointLight pointLight, Geometry geometry, Material material, inout ReflectedLight reflectedLight) {\n\n\t\tvec3 lVector = pointLight.position - geometry.position;\n\t\tvec3 direction = normalize( lVector );\n\n\t\tfloat lightDistance = length( lVector );\n\n\t\tvec3 color = pointLight.color;\n\t\tcolor *= clamp(1.0 - pow(lightDistance/pointLight.distance, 4.0), 0.0, 1.0);\n\n\t\taddDirectRadiance( direction, color, geometry, material, reflectedLight );\n\n\t}\n\n#endif\n\n#ifdef SCENE_SPOT_LIGHT_COUNT\n\n\tvoid addSpotDirectLightRadiance(SpotLight spotLight, Geometry geometry, Material material, inout ReflectedLight reflectedLight) {\n\n\t\tvec3 lVector = spotLight.position - geometry.position;\n\t\tvec3 direction = normalize( lVector );\n\n\t\tfloat lightDistance = length( lVector );\n\t\tfloat angleCos = dot( direction, -spotLight.direction );\n\n\t\tfloat spotEffect = smoothstep( spotLight.penumbraCos, spotLight.angleCos, angleCos );\n\t\tfloat decayEffect = clamp(1.0 - pow(lightDistance/spotLight.distance, 4.0), 0.0, 1.0);\n\n\t\tvec3 color = spotLight.color;\n\t\tcolor *= spotEffect * decayEffect;\n\n\t\taddDirectRadiance( direction, color, geometry, material, reflectedLight );\n\n\t}\n\n\n#endif\n\nvoid addTotalDirectRadiance(Geometry geometry, Material material, inout ReflectedLight reflectedLight){\n float shadowAttenuation = 1.0;\n\n #ifdef SCENE_DIRECT_LIGHT_COUNT\n shadowAttenuation = 1.0;\n #ifdef SCENE_IS_CALCULATE_SHADOWS\n shadowAttenuation *= sampleShadowMap();\n #endif\n\n DirectLight directionalLight;\n for ( int i = 0; i < SCENE_DIRECT_LIGHT_COUNT; i ++ ) {\n // warning: use `continue` syntax may trigger flickering bug in safri 16.1.\n if(!isRendererCulledByLight(renderer_Layer.xy, scene_DirectLightCullingMask[i])){\n directionalLight.color = scene_DirectLightColor[i];\n #ifdef SCENE_IS_CALCULATE_SHADOWS\n if (i == 0) { // Sun light index is always 0\n directionalLight.color *= shadowAttenuation;\n }\n #endif\n directionalLight.direction = scene_DirectLightDirection[i];\n addDirectionalDirectLightRadiance( directionalLight, geometry, material, reflectedLight );\n }\n }\n\n #endif\n\n #ifdef SCENE_POINT_LIGHT_COUNT\n\n PointLight pointLight;\n\n for ( int i = 0; i < SCENE_POINT_LIGHT_COUNT; i ++ ) {\n if(!isRendererCulledByLight(renderer_Layer.xy, scene_PointLightCullingMask[i])){\n pointLight.color = scene_PointLightColor[i];\n pointLight.position = scene_PointLightPosition[i];\n pointLight.distance = scene_PointLightDistance[i];\n\n addPointDirectLightRadiance( pointLight, geometry, material, reflectedLight );\n } \n }\n\n #endif\n\n #ifdef SCENE_SPOT_LIGHT_COUNT\n\n SpotLight spotLight;\n\n for ( int i = 0; i < SCENE_SPOT_LIGHT_COUNT; i ++ ) {\n if(!isRendererCulledByLight(renderer_Layer.xy, scene_SpotLightCullingMask[i])){\n spotLight.color = scene_SpotLightColor[i];\n spotLight.position = scene_SpotLightPosition[i];\n spotLight.direction = scene_SpotLightDirection[i];\n spotLight.distance = scene_SpotLightDistance[i];\n spotLight.angleCos = scene_SpotLightAngleCos[i];\n spotLight.penumbraCos = scene_SpotLightPenumbraCos[i];\n\n addSpotDirectLightRadiance( spotLight, geometry, material, reflectedLight );\n } \n }\n\n #endif\n}"; // eslint-disable-line
9857
- var ibl_frag_define = "// ------------------------Diffuse------------------------\n\n// sh need be pre-scaled in CPU.\nvec3 getLightProbeIrradiance(vec3 sh[9], vec3 normal){\n normal.x = -normal.x;\n vec3 result = sh[0] +\n\n sh[1] * (normal.y) +\n sh[2] * (normal.z) +\n sh[3] * (normal.x) +\n\n sh[4] * (normal.y * normal.x) +\n sh[5] * (normal.y * normal.z) +\n sh[6] * (3.0 * normal.z * normal.z - 1.0) +\n sh[7] * (normal.z * normal.x) +\n sh[8] * (normal.x * normal.x - normal.y * normal.y);\n \n return max(result, vec3(0.0));\n\n}\n\n// ------------------------Specular------------------------\n\n// Returns raw DFG approximation coefficients (split-sum LUT approximation)\nvec2 envDFGApprox(float roughness, float dotNV) {\n const vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n const vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n vec4 r = roughness * c0 + c1;\n float a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n return vec2( -1.04, 1.04 ) * a004 + r.zw;\n}\n\n// ref: https://www.unrealengine.com/blog/physically-based-shading-on-mobile - environmentBRDF for GGX on mobile\nvec3 envBRDFApprox(vec3 f0, float f90, float roughness, float dotNV ) {\n vec2 AB = envDFGApprox(roughness, dotNV);\n return f0 * AB.x + f90 * AB.y;\n}\n\n\nfloat getSpecularMIPLevel(float roughness, int maxMIPLevel ) {\n return roughness * float(maxMIPLevel);\n}\n\nvec3 getReflectedVector(Geometry geometry, vec3 n) {\n #ifdef MATERIAL_ENABLE_ANISOTROPY\n vec3 r = reflect(-geometry.viewDir, geometry.anisotropicN);\n #else\n vec3 r = reflect(-geometry.viewDir, n);\n #endif\n\n return r;\n}\n\nvec3 getLightProbeRadiance(Geometry geometry, vec3 normal, float roughness, int maxMIPLevel, float specularIntensity) {\n\n #ifndef SCENE_USE_SPECULAR_ENV\n return vec3(0);\n #else\n vec3 reflectVec = getReflectedVector(geometry, normal);\n reflectVec.x = -reflectVec.x; // TextureCube is left-hand,so x need inverse\n \n float specularMIPLevel = getSpecularMIPLevel(roughness, maxMIPLevel );\n\n #ifdef HAS_TEX_LOD\n vec4 envMapColor = textureCubeLodEXT( scene_EnvSpecularSampler, reflectVec, specularMIPLevel );\n #else\n vec4 envMapColor = textureCube( scene_EnvSpecularSampler, reflectVec, specularMIPLevel );\n #endif\n\n #ifdef ENGINE_NO_SRGB\n envMapColor = sRGBToLinear(envMapColor);\n #endif\n \n return envMapColor.rgb * specularIntensity;\n\n #endif\n\n}\n\n\nvoid evaluateSheenIBL(Geometry geometry, Material material, float radianceAttenuation, inout vec3 diffuseColor, inout vec3 specularColor){\n #ifdef MATERIAL_ENABLE_SHEEN\n diffuseColor *= material.sheenScaling;\n specularColor *= material.sheenScaling;\n\n vec3 reflectance = material.specularAO * radianceAttenuation * material.approxIBLSheenDG * material.sheenColor;\n specularColor += reflectance;\n #endif\n}"; // eslint-disable-line
9857
+ var ibl_frag_define = "// ------------------------Diffuse------------------------\n\n// sh need be pre-scaled in CPU.\nvec3 getLightProbeIrradiance(vec3 sh[9], vec3 normal){\n vec3 result = sh[0] +\n\n sh[1] * (normal.y) +\n sh[2] * (normal.z) +\n sh[3] * (normal.x) +\n\n sh[4] * (normal.y * normal.x) +\n sh[5] * (normal.y * normal.z) +\n sh[6] * (3.0 * normal.z * normal.z - 1.0) +\n sh[7] * (normal.z * normal.x) +\n sh[8] * (normal.x * normal.x - normal.y * normal.y);\n \n return max(result, vec3(0.0));\n\n}\n\n// ------------------------Specular------------------------\n\n// Returns raw DFG approximation coefficients (split-sum LUT approximation)\nvec2 envDFGApprox(float roughness, float dotNV) {\n const vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 );\n const vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 );\n vec4 r = roughness * c0 + c1;\n float a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y;\n return vec2( -1.04, 1.04 ) * a004 + r.zw;\n}\n\n// ref: https://www.unrealengine.com/blog/physically-based-shading-on-mobile - environmentBRDF for GGX on mobile\nvec3 envBRDFApprox(vec3 f0, float f90, float roughness, float dotNV ) {\n vec2 AB = envDFGApprox(roughness, dotNV);\n return f0 * AB.x + f90 * AB.y;\n}\n\n\nfloat getSpecularMIPLevel(float roughness, int maxMIPLevel ) {\n return roughness * float(maxMIPLevel);\n}\n\nvec3 getReflectedVector(Geometry geometry, vec3 n) {\n #ifdef MATERIAL_ENABLE_ANISOTROPY\n vec3 r = reflect(-geometry.viewDir, geometry.anisotropicN);\n #else\n vec3 r = reflect(-geometry.viewDir, n);\n #endif\n\n return r;\n}\n\nvec3 getLightProbeRadiance(Geometry geometry, vec3 normal, float roughness, int maxMIPLevel, float specularIntensity) {\n\n #ifndef SCENE_USE_SPECULAR_ENV\n return vec3(0);\n #else\n vec3 reflectVec = getReflectedVector(geometry, normal);\n\n float specularMIPLevel = getSpecularMIPLevel(roughness, maxMIPLevel );\n\n #ifdef HAS_TEX_LOD\n vec4 envMapColor = textureCubeLodEXT( scene_EnvSpecularSampler, reflectVec, specularMIPLevel );\n #else\n vec4 envMapColor = textureCube( scene_EnvSpecularSampler, reflectVec, specularMIPLevel );\n #endif\n\n #ifdef ENGINE_NO_SRGB\n envMapColor = sRGBToLinear(envMapColor);\n #endif\n \n return envMapColor.rgb * specularIntensity;\n\n #endif\n\n}\n\n\nvoid evaluateSheenIBL(Geometry geometry, Material material, float radianceAttenuation, inout vec3 diffuseColor, inout vec3 specularColor){\n #ifdef MATERIAL_ENABLE_SHEEN\n diffuseColor *= material.sheenScaling;\n specularColor *= material.sheenScaling;\n\n vec3 reflectance = material.specularAO * radianceAttenuation * material.approxIBLSheenDG * material.sheenColor;\n specularColor += reflectance;\n #endif\n}"; // eslint-disable-line
9858
9858
  var pbr_frag = "Geometry geometry;\nMaterial material;\nReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );\n\ninitGeometry(geometry, gl_FrontFacing);\ninitMaterial(material, geometry);\n\n// Direct Light\naddTotalDirectRadiance(geometry, material, reflectedLight);\n\n// IBL diffuse\n#ifdef SCENE_USE_SH\n vec3 irradiance = getLightProbeIrradiance(scene_EnvSH, geometry.normal);\n irradiance *= scene_EnvMapLight.diffuseIntensity;\n#else\n vec3 irradiance = scene_EnvMapLight.diffuse * scene_EnvMapLight.diffuseIntensity;\n irradiance *= PI;\n#endif\n\nreflectedLight.indirectDiffuse += material.diffuseAO * irradiance * BRDF_Diffuse_Lambert( material.diffuseColor );\n\n// IBL specular\nvec3 radiance = getLightProbeRadiance(geometry, geometry.normal, material.roughness, int(scene_EnvMapLight.mipMapLevel), scene_EnvMapLight.specularIntensity);\nfloat radianceAttenuation = 1.0;\n\n// IBL Clear Coat\n#ifdef MATERIAL_ENABLE_CLEAR_COAT\n vec3 clearCoatRadiance = getLightProbeRadiance( geometry, geometry.clearCoatNormal, material.clearCoatRoughness, int(scene_EnvMapLight.mipMapLevel), scene_EnvMapLight.specularIntensity );\n\n reflectedLight.indirectSpecular += material.specularAO * clearCoatRadiance * material.clearCoat * envBRDFApprox(vec3( 0.04 ), 1.0, material.clearCoatRoughness, geometry.clearCoatDotNV);\n radianceAttenuation -= material.clearCoat * F_Schlick(0.04, 1.0, geometry.clearCoatDotNV);\n#endif\n\nreflectedLight.indirectSpecular += material.specularAO * radianceAttenuation * radiance * envBRDFApprox(material.resolvedSpecularF0, material.specularF90, material.roughness, geometry.dotNV) * material.energyCompensation;\n\n\n// IBL Sheen\nevaluateSheenIBL(geometry, material, radianceAttenuation, reflectedLight.indirectDiffuse, reflectedLight.indirectSpecular);\n\n\n// Final color\nvec3 totalDiffuseColor = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse;\nvec3 totalSpecularColor = reflectedLight.directSpecular + reflectedLight.indirectSpecular;\n\n#ifdef MATERIAL_ENABLE_TRANSMISSION \n vec3 refractionTransmitted = evaluateTransmission(geometry, material);\n totalDiffuseColor = mix(totalDiffuseColor, refractionTransmitted, material.transmission);\n#endif\n\nvec4 finalColor = vec4(totalDiffuseColor + totalSpecularColor, material.opacity);\n\n\n// Emissive\nvec3 emissiveRadiance = material_EmissiveColor;\n#ifdef MATERIAL_HAS_EMISSIVETEXTURE\n emissiveRadiance *= texture2DSRGB(material_EmissiveTexture, v_uv).rgb;\n#endif\n\nfinalColor.rgb += emissiveRadiance;\n\n\ngl_FragColor = finalColor;\n"; // eslint-disable-line
9859
9859
  var btdf = "#include <refraction>\n\n#ifdef MATERIAL_ENABLE_TRANSMISSION \n uniform sampler2D camera_OpaqueTexture;\n vec3 evaluateTransmission(Geometry geometry, Material material) {\n RefractionModelResult ray;\n #if REFRACTION_MODE == 0 \n // RefractionMode.Sphere\n refractionModelSphere(-geometry.viewDir, geometry.position, geometry.normal, material.IOR, material.thickness, ray);\n #elif REFRACTION_MODE == 1\n // RefractionMode.Planar\n refractionModelPlanar(-geometry.viewDir, geometry.position, geometry.normal, material.IOR, material.thickness, ray);\n #endif\n\n vec3 refractedRayExit = ray.positionExit;\n\n // We calculate the screen space position of the refracted point\n vec4 samplingPositionNDC = camera_ProjMat * camera_ViewMat * vec4( refractedRayExit, 1.0 );\n vec2 refractionCoords = (samplingPositionNDC.xy / samplingPositionNDC.w) * 0.5 + 0.5;\n\n // Sample the opaque texture to get the transmitted light\n vec3 refractionTransmitted = texture2DSRGB(camera_OpaqueTexture, refractionCoords).rgb;\n refractionTransmitted *= material.diffuseColor;\n \n // Use specularFGD as an approximation of the fresnel effect\n // https://blog.selfshadow.com/publications/s2017-shading-course/imageworks/s2017_pbs_imageworks_slides_v2.pdf\n refractionTransmitted *= (1.0 - material.envSpecularDFG);\n\n #ifdef MATERIAL_HAS_THICKNESS\n // Absorption coefficient from Disney: http://blog.selfshadow.com/publications/s2015-shading-course/burley/s2015_pbs_disney_bsdf_notes.pdf\n vec3 transmittance = min(vec3(1.0), exp(-material.absorptionCoefficient * ray.transmissionLength));\n refractionTransmitted *= transmittance;\n #endif\n \n return refractionTransmitted;\n }\n#endif"; // eslint-disable-line
9860
9860
  var refraction = "#ifdef MATERIAL_ENABLE_TRANSMISSION \n\tstruct RefractionModelResult {\n\t float transmissionLength; // length of the transmission during refraction through the shape\n\t vec3 positionExit; // out ray position\n\t // vec3 directionExit; // out ray direction\n\t};\n\n\t//https://docs.unity3d.com/Packages/com.unity.render-pipelines.high-definition@15.0/manual/refraction-models.html\n\t void refractionModelSphere(vec3 V, vec3 positionWS, vec3 normalWS, float ior, float thickness, out RefractionModelResult ray) {\n\t // Refracted ray\n\t vec3 R1 = refract(V, normalWS, 1.0 / ior);\n\t // Center of the tangent sphere\n\t // vec3 C = positionWS - normalWS * thickness * 0.5;\n\n\t // Second refraction (tangent sphere out)\n\t float dist = dot(-normalWS, R1) * thickness;\n\t // Out hit point in the tangent sphere\n\t vec3 P1 = positionWS + R1 * dist;\n\t // Out normal\n\t // vec3 N1 = safeNormalize(C - P1);\n\t // Out refracted ray\n\t // vec3 R2 = refract(R1, N1, ior);\n\n\t ray.transmissionLength = dist;\n\t ray.positionExit = P1;\n\t // ray.directionExit = R2; \n\t}\n\n\tvoid refractionModelPlanar(vec3 V, vec3 positionWS, vec3 normalWS, float ior, float thickness, out RefractionModelResult ray) {\n\t // Refracted ray\n\t vec3 R = refract(V, normalWS, 1.0 / ior);\n\t // Optical depth within the thin plane\n\t float dist = thickness / max(dot(-normalWS, R), 1e-5f);\n\n\t ray.transmissionLength = dist;\n\t ray.positionExit = vec3(positionWS + R * dist);\n\t // ray.directionExit = V;\n\t}\n\n#endif"; // eslint-disable-line
@@ -9892,7 +9892,7 @@
9892
9892
  var sphere_billboard = "#ifdef RENDERER_MODE_SPHERE_BILLBOARD\n\tvec2 corner = a_CornerTextureCoordinate.xy + renderer_PivotOffset.xy;\n\tvec3 sideVector = normalize(cross(camera_Forward, camera_Up));\n\tvec3 upVector = normalize(cross(sideVector, camera_Forward));\n\tcorner *= computeParticleSizeBillboard(a_StartSize.xy, normalizedAge);\n #if defined(RENDERER_ROL_CONSTANT_MODE) || defined(RENDERER_ROL_CURVE_MODE)\n if (renderer_ThreeDStartRotation) {\n vec3 rotation = radians(vec3(a_StartRotation0.xy, computeParticleRotationFloat(a_StartRotation0.z, age, normalizedAge)));\n center += renderer_SizeScale.xzy * rotationByEuler(corner.x * sideVector + corner.y * upVector, rotation);\n } else {\n float rot = radians(computeParticleRotationFloat(a_StartRotation0.x, age, normalizedAge));\n float c = cos(rot);\n float s = sin(rot);\n mat2 rotation = mat2(c, -s, s, c);\n corner = rotation * corner;\n center += renderer_SizeScale.xzy * (corner.x * sideVector + corner.y * upVector);\n }\n #else\n if (renderer_ThreeDStartRotation) {\n center += renderer_SizeScale.xzy * rotationByEuler(corner.x * sideVector + corner.y * upVector, radians(a_StartRotation0));\n } else {\n float c = cos(radians(a_StartRotation0.x));\n float s = sin(radians(a_StartRotation0.x));\n mat2 rotation = mat2(c, -s, s, c);\n corner = rotation * corner;\n center += renderer_SizeScale.xzy * (corner.x * sideVector + corner.y * upVector);\n }\n #endif\n#endif"; // eslint-disable-line
9893
9893
  var stretched_billboard = "#ifdef RENDERER_MODE_STRETCHED_BILLBOARD\n\tvec2 corner = a_CornerTextureCoordinate.xy + renderer_PivotOffset.xy;\n\tvec3 velocity = rotationByQuaternions(renderer_SizeScale * localVelocity, worldRotation) + worldVelocity;\n\tvec3 cameraUpVector = normalize(velocity);\n\tvec3 direction = normalize(center - camera_Position);\n\tvec3 sideVector = normalize(cross(direction, normalize(velocity)));\n\n\tsideVector = renderer_SizeScale.xzy * sideVector;\n\tcameraUpVector = length(vec3(renderer_SizeScale.x, 0.0, 0.0)) * cameraUpVector;\n\n\tvec2 size = computeParticleSizeBillboard(a_StartSize.xy, normalizedAge);\n\n\tconst mat2 rotationZHalfPI = mat2(0.0, -1.0, 1.0, 0.0);\n\tcorner = rotationZHalfPI * corner;\n\tcorner.y = corner.y - abs(corner.y);\n\n\tfloat speed = length(velocity); // TODO:\n\tcenter += sign(renderer_SizeScale.x) * (sign(renderer_StretchedBillboardLengthScale) * size.x * corner.x * sideVector\n\t + (speed * renderer_StretchedBillboardSpeedScale + size.y * renderer_StretchedBillboardLengthScale) * corner.y * cameraUpVector);\n#endif"; // eslint-disable-line
9894
9894
  var vertical_billboard = "#ifdef RENDERER_MODE_VERTICAL_BILLBOARD\n\tvec2 corner = a_CornerTextureCoordinate.xy + renderer_PivotOffset.xy; // Billboard模式z轴无效\n\tconst vec3 cameraUpVector = vec3(0.0, 1.0, 0.0);\n\tvec3 sideVector = normalize(cross(camera_Forward, cameraUpVector));\n\n\tfloat rot = radians(computeParticleRotationFloat(a_StartRotation0.x, age, normalizedAge));\n\tfloat c = cos(rot);\n\tfloat s = sin(rot);\n\tmat2 rotation = mat2(c, -s, s, c);\n\tcorner = rotation * corner * cos(0.78539816339744830961566084581988); // TODO:临时缩小cos45,不确定U3D原因\n\tcorner *= computeParticleSizeBillboard(a_StartSize.xy, normalizedAge);\n\tcenter += renderer_SizeScale.xzy * (corner.x * sideVector + corner.y * cameraUpVector);\n#endif"; // eslint-disable-line
9895
- var horizontal_billboard = "#ifdef RENDERER_MODE_HORIZONTAL_BILLBOARD\n\tvec2 corner = a_CornerTextureCoordinate.xy + renderer_PivotOffset.xy; // Billboard模式z轴无效\n\tconst vec3 cameraUpVector = vec3(0.0, 0.0, 1.0);\n\tconst vec3 sideVector = vec3(-1.0, 0.0, 0.0);\n\n\tfloat rot = radians(computeParticleRotationFloat(a_StartRotation0.x, age, normalizedAge));\n\tfloat c = cos(rot);\n\tfloat s = sin(rot);\n\tmat2 rotation = mat2(c, -s, s, c);\n\tcorner = rotation * corner * cos(0.78539816339744830961566084581988); // TODO:临时缩小cos45,不确定U3D原因\n\tcorner *= computeParticleSizeBillboard(a_StartSize.xy, normalizedAge);\n\tcenter += renderer_SizeScale.xzy * (corner.x * sideVector + corner.y * cameraUpVector);\n#endif"; // eslint-disable-line
9895
+ var horizontal_billboard = "#ifdef RENDERER_MODE_HORIZONTAL_BILLBOARD\n\tvec2 corner = a_CornerTextureCoordinate.xy + renderer_PivotOffset.xy;\n\tconst vec3 sideVector = vec3(1.0, 0.0, 0.0);\n\tconst vec3 upVector = vec3(0.0, 0.0, -1.0);\n\tcorner *= computeParticleSizeBillboard(a_StartSize.xy, normalizedAge);\n\n\t// HorizontalBillboard rotates in XZ plane (around Y-axis normal).\n\t// Uses Z-axis rotation data to match Unity behavior.\n\tfloat rot;\n\tif (renderer_ThreeDStartRotation) {\n\t\trot = radians(computeParticleRotationFloat(a_StartRotation0.z, age, normalizedAge));\n\t} else {\n\t\trot = radians(computeParticleRotationFloat(a_StartRotation0.x, age, normalizedAge));\n\t}\n\n\tfloat c = cos(rot);\n\tfloat s = sin(rot);\n\tmat2 rotation = mat2(c, -s, s, c);\n\tcorner = rotation * corner;\n\tcenter += renderer_SizeScale.xzy * (corner.x * sideVector + corner.y * upVector);\n#endif"; // eslint-disable-line
9896
9896
  var particle_mesh = "// Only support local alignment mode\n#ifdef RENDERER_MODE_MESH\n #if defined(RENDERER_ROL_CONSTANT_MODE) || defined(RENDERER_ROL_CURVE_MODE)\n #define RENDERER_ROL_ENABLED\n #endif\n\n\tvec3 size = computeParticleSizeMesh(a_StartSize, normalizedAge);\n\n bool is3DRotation = renderer_ThreeDStartRotation;\n #if defined(RENDERER_ROL_ENABLED) && defined(RENDERER_ROL_IS_SEPARATE)\n is3DRotation = true;\n #endif\n\n if (is3DRotation) {\n #ifdef RENDERER_ROL_ENABLED\n vec3 startRotation = renderer_ThreeDStartRotation ? a_StartRotation0 : vec3(0.0, 0.0, a_StartRotation0.x);\n vec3 rotation = radians(computeParticleRotationVec3(startRotation, age, normalizedAge));\n #else\n vec3 rotation = radians(a_StartRotation0);\n #endif\n // 3D Start Rotation is same in local and world simulation space\n center += rotationByQuaternions(renderer_SizeScale * rotationByEuler(POSITION * size, rotation), worldRotation);\n } else {\n #ifdef RENDERER_ROL_ENABLED\n float angle = radians(computeParticleRotationFloat(a_StartRotation0.x, age, normalizedAge));\n #else\n float angle = radians(a_StartRotation0.x);\n #endif\n #ifdef RENDERER_EMISSION_SHAPE\n // Axis is side vector of emit position look at zero\n vec3 axis = vec3(a_ShapePositionStartLifeTime.xy, 0.0);\n if (renderer_SimulationSpace == 1){\n axis = rotationByQuaternions(axis, worldRotation);\n }\n vec3 crossResult = cross(axis, vec3(0.0, 0.0, -1.0));\n float crossLen = length(crossResult);\n vec3 rotateAxis = crossLen > 0.0001 ? crossResult / crossLen : vec3(0.0, 1.0, 0.0);\n #else\n // Axis is negative z\n vec3 rotateAxis = vec3(0.0, 0.0, -1.0);\n #endif\n center += rotationByQuaternions(renderer_SizeScale *rotationByAxis(POSITION * size, rotateAxis, angle), worldRotation);\n }\n #ifdef RENDERER_ENABLE_VERTEXCOLOR\n\t\tv_MeshColor = COLOR_0;\n\t#endif\n#endif"; // eslint-disable-line
9897
9897
  var ParticleShaderLib = {
9898
9898
  particle_common: particle_common,
@@ -28943,8 +28943,7 @@
28943
28943
  /** Plain text. */ AssetType["Text"] = "Text";
28944
28944
  /** JSON. */ AssetType["JSON"] = "JSON";
28945
28945
  /** ArrayBuffer. */ AssetType["Buffer"] = "Buffer";
28946
- /** 2D Texture. */ AssetType["Texture2D"] = "Texture2D";
28947
- /** Cube Texture. */ AssetType["TextureCube"] = "TextureCube";
28946
+ /** Texture. */ AssetType["Texture"] = "Texture";
28948
28947
  /** Material. */ AssetType["Material"] = "Material";
28949
28948
  /** Shader. */ AssetType["Shader"] = "Shader";
28950
28949
  /** Mesh. */ AssetType["Mesh"] = "Mesh";
@@ -31145,7 +31144,7 @@
31145
31144
  var shadowMapFs = "#ifdef ENGINE_NO_DEPTH_TEXTURE\n /**\n * Decompose and save depth value.\n */\n vec4 pack (float depth) {\n // Use rgba 4 bytes with a total of 32 bits to store the z value, and the accuracy of 1 byte is 1/256.\n const vec4 bitShift = vec4(1.0, 256.0, 256.0 * 256.0, 256.0 * 256.0 * 256.0);\n const vec4 bitMask = vec4(1.0/256.0, 1.0/256.0, 1.0/256.0, 0.0);\n\n vec4 rgbaDepth = fract(depth * bitShift); // Calculate the z value of each point\n\n // Cut off the value which do not fit in 8 bits\n rgbaDepth -= rgbaDepth.gbaa * bitMask;\n\n return rgbaDepth;\n }\n#endif\n\n\nuniform vec4 material_BaseColor;\nuniform sampler2D material_BaseTexture;\nuniform float material_AlphaCutoff;\nvarying vec2 v_uv;\n\nvoid main() {\n #if defined(MATERIAL_IS_ALPHA_CUTOFF) || (defined(SCENE_ENABLE_TRANSPARENT_SHADOW) && defined(MATERIAL_IS_TRANSPARENT))\n float alpha = material_BaseColor.a;\n #ifdef MATERIAL_HAS_BASETEXTURE\n alpha *= texture2D(material_BaseTexture, v_uv).a;\n #endif\n \n #ifdef MATERIAL_IS_ALPHA_CUTOFF\n if(alpha < material_AlphaCutoff){\n discard;\n }\n #endif\n \n #if defined(SCENE_ENABLE_TRANSPARENT_SHADOW) && defined(MATERIAL_IS_TRANSPARENT)\n // Interleaved gradient noise\n float noise = fract(52.982919 * fract(dot(vec2(0.06711, 0.00584), gl_FragCoord.xy)));\n if (alpha <= noise) {\n discard;\n };\n #endif\n #endif\n\n #ifdef ENGINE_NO_DEPTH_TEXTURE\n gl_FragColor = pack(gl_FragCoord.z);\n #else\n gl_FragColor = vec4(0.0, 0.0, 0.0, 0.0);\n #endif\n}"; // eslint-disable-line
31146
31145
  var shadowMapVs = "#include <common>\n#include <common_vert>\n#include <blendShape_input>\n#include <normal_share>\n#include <uv_share>\nuniform mat4 camera_VPMat;\nuniform vec2 scene_ShadowBias; // x: depth bias, y: normal bias\nuniform vec3 scene_LightDirection;\n\nvec3 applyShadowBias(vec3 positionWS) {\n positionWS -= scene_LightDirection * scene_ShadowBias.x;\n return positionWS;\n}\n\nvec3 applyShadowNormalBias(vec3 positionWS, vec3 normalWS) {\n float invNdotL = 1.0 - clamp(dot(-scene_LightDirection, normalWS), 0.0, 1.0);\n float scale = invNdotL * scene_ShadowBias.y;\n positionWS += normalWS * vec3(scale);\n return positionWS;\n}\n\nvoid main() {\n\n #include <begin_position_vert>\n #include <begin_normal_vert>\n #include <blendShape_vert>\n #include <skinning_vert>\n #include <uv_vert>\n \n vec4 positionWS = renderer_ModelMat * position;\n\n positionWS.xyz = applyShadowBias(positionWS.xyz);\n #ifndef MATERIAL_OMIT_NORMAL\n #ifdef RENDERER_HAS_NORMAL\n vec3 normalWS = normalize( mat3(renderer_NormalMat) * normal );\n positionWS.xyz = applyShadowNormalBias(positionWS.xyz, normalWS);\n #endif\n #endif\n\n\n vec4 positionCS = camera_VPMat * positionWS;\n positionCS.z = max(positionCS.z, -1.0);// clamp to min ndc z\n\n gl_Position = positionCS;\n\n}\n"; // eslint-disable-line
31147
31146
  var skyboxFs = "#include <common>\nuniform samplerCube material_CubeTexture;\n\nvarying vec3 v_cubeUV;\nuniform float material_Exposure;\nuniform vec4 material_TintColor;\n\nvoid main() {\n vec4 textureColor = textureCube( material_CubeTexture, v_cubeUV );\n\n #ifdef ENGINE_NO_SRGB\n textureColor = sRGBToLinear(textureColor);\n #endif\n\n textureColor.rgb *= material_Exposure * material_TintColor.rgb;\n \n gl_FragColor = textureColor;\n}\n"; // eslint-disable-line
31148
- var skyboxVs = "#include <common_vert>\n\nuniform mat4 camera_VPMat;\n\nvarying vec3 v_cubeUV;\nuniform float material_Rotation;\n\nvec4 rotateY(vec4 v, float angle) {\n\tconst float deg2rad = 3.1415926 / 180.0;\n\tfloat radian = angle * deg2rad;\n\tfloat sina = sin(radian);\n\tfloat cosa = cos(radian);\n\tmat2 m = mat2(cosa, -sina, sina, cosa);\n\treturn vec4(m * v.xz, v.yw).xzyw;\n}\n\nvoid main() {\n v_cubeUV = vec3( -POSITION.x, POSITION.yz ); // TextureCube is left-hand,so x need inverse\n gl_Position = camera_VPMat * rotateY(vec4(POSITION, 1.0), material_Rotation);\n}\n"; // eslint-disable-line
31147
+ var skyboxVs = "#include <common_vert>\n\nuniform mat4 camera_VPMat;\n\nvarying vec3 v_cubeUV;\nuniform float material_Rotation;\n\nvec4 rotateY(vec4 v, float angle) {\n\tconst float deg2rad = 3.1415926 / 180.0;\n\tfloat radian = angle * deg2rad;\n\tfloat sina = sin(radian);\n\tfloat cosa = cos(radian);\n\tmat2 m = mat2(cosa, -sina, sina, cosa);\n\treturn vec4(m * v.xz, v.yw).xzyw;\n}\n\nvoid main() {\n v_cubeUV = POSITION;\n gl_Position = camera_VPMat * rotateY(vec4(POSITION, 1.0), material_Rotation);\n}\n"; // eslint-disable-line
31149
31148
  var spriteMaskFs = "uniform sampler2D renderer_MaskTexture;\nuniform float renderer_MaskAlphaCutoff;\nvarying vec2 v_uv;\n\nvoid main()\n{\n vec4 color = texture2D(renderer_MaskTexture, v_uv);\n if (color.a < renderer_MaskAlphaCutoff) {\n discard;\n }\n\n gl_FragColor = color;\n}\n"; // eslint-disable-line
31150
31149
  var spriteMaskVs = "uniform mat4 camera_VPMat;\n\nattribute vec3 POSITION;\nattribute vec2 TEXCOORD_0;\n\nvarying vec2 v_uv;\n\nvoid main()\n{\n gl_Position = camera_VPMat * vec4(POSITION, 1.0);\n v_uv = TEXCOORD_0;\n}\n"; // eslint-disable-line
31151
31150
  var spriteFs = "#include <common>\nuniform sampler2D renderer_SpriteTexture;\n\nvarying vec2 v_uv;\nvarying vec4 v_color;\n\nvoid main()\n{\n vec4 baseColor = texture2DSRGB(renderer_SpriteTexture, v_uv);\n gl_FragColor = baseColor * v_color;\n}\n"; // eslint-disable-line
@@ -38083,7 +38082,8 @@
38083
38082
  renderModeMacro = ParticleRenderer._stretchedBillboardModeMacro;
38084
38083
  break;
38085
38084
  case ParticleRenderMode.HorizontalBillboard:
38086
- throw "Not implemented";
38085
+ renderModeMacro = ParticleRenderer._horizontalBillboardModeMacro;
38086
+ break;
38087
38087
  case ParticleRenderMode.VerticalBillboard:
38088
38088
  throw "Not implemented";
38089
38089
  case ParticleRenderMode.Mesh:
@@ -47716,11 +47716,189 @@
47716
47716
  };
47717
47717
  return ReflectionParser;
47718
47718
  }();
47719
- exports.Texture2DDecoder = /*#__PURE__*/ function() {
47719
+ /**
47720
+ * HDR (Radiance RGBE) image decoder.
47721
+ *
47722
+ * Decodes .hdr files into pixel data. Supports parsing the header
47723
+ * and decoding RLE-compressed RGBE scanlines into R16G16B16A16 half-float pixels.
47724
+ */ var HDRDecoder = /*#__PURE__*/ function() {
47725
+ function HDRDecoder() {}
47726
+ /**
47727
+ * Parse the header of an HDR file.
47728
+ * @returns Header info including width, height, and data start position.
47729
+ */ HDRDecoder.parseHeader = function parseHeader(uint8array) {
47730
+ var line = this._readStringLine(uint8array, 0);
47731
+ if (line[0] !== "#" || line[1] !== "?") {
47732
+ throw "HDRDecoder: invalid file header";
47733
+ }
47734
+ var endOfHeader = false;
47735
+ var findFormat = false;
47736
+ var lineIndex = 0;
47737
+ do {
47738
+ lineIndex += line.length + 1;
47739
+ line = this._readStringLine(uint8array, lineIndex);
47740
+ if (line === "FORMAT=32-bit_rle_rgbe") findFormat = true;
47741
+ else if (line.length === 0) endOfHeader = true;
47742
+ }while (!endOfHeader);
47743
+ if (!findFormat) {
47744
+ throw "HDRDecoder: unsupported format, expected 32-bit_rle_rgbe";
47745
+ }
47746
+ lineIndex += line.length + 1;
47747
+ line = this._readStringLine(uint8array, lineIndex);
47748
+ var match = /^\-Y (.*) \+X (.*)$/g.exec(line);
47749
+ if (!match || match.length < 3) {
47750
+ throw "HDRDecoder: missing image size, only -Y +X layout is supported";
47751
+ }
47752
+ var width = parseInt(match[2]);
47753
+ var height = parseInt(match[1]);
47754
+ if (width < 8 || width > 0x7fff) {
47755
+ throw "HDRDecoder: unsupported image width, must be between 8 and 32767";
47756
+ }
47757
+ return {
47758
+ height: height,
47759
+ width: width,
47760
+ dataPosition: lineIndex + line.length + 1
47761
+ };
47762
+ };
47763
+ /**
47764
+ * Decode an HDR file buffer into R16G16B16A16 half-float pixel data.
47765
+ * @param buffer - The full HDR file as Uint8Array.
47766
+ * @returns Object with width, height, and half-float pixel data.
47767
+ */ HDRDecoder.decode = function decode(buffer) {
47768
+ var header = this.parseHeader(buffer);
47769
+ var width = header.width, height = header.height, dataPosition = header.dataPosition;
47770
+ var rgbe = this._readPixels(buffer.subarray(dataPosition), width, height);
47771
+ var pixels = this._rgbeToHalfFloat(rgbe, width, height);
47772
+ return {
47773
+ width: width,
47774
+ height: height,
47775
+ pixels: pixels
47776
+ };
47777
+ };
47778
+ /**
47779
+ * Convert RGBE pixel data to R16G16B16A16 half-float.
47780
+ */ HDRDecoder._rgbeToHalfFloat = function _rgbeToHalfFloat(rgbe, width, height) {
47781
+ var floatView = this._floatView;
47782
+ var uint32View = this._uint32View;
47783
+ var _this__float2HalfTables = this._float2HalfTables, baseTable = _this__float2HalfTables.baseTable, shiftTable = _this__float2HalfTables.shiftTable;
47784
+ var one = 0x3c00; // Half float 1.0
47785
+ var pixelCount = width * height;
47786
+ var result = new Uint16Array(pixelCount * 4);
47787
+ for(var i = 0; i < pixelCount; i++){
47788
+ var srcIdx = i * 4;
47789
+ var dstIdx = i * 4;
47790
+ var scaleFactor = Math.pow(2, rgbe[srcIdx + 3] - 128 - 8);
47791
+ for(var c = 0; c < 3; c++){
47792
+ floatView[0] = Math.min(rgbe[srcIdx + c] * scaleFactor, 65504);
47793
+ var f = uint32View[0];
47794
+ var e = f >> 23 & 0x1ff;
47795
+ result[dstIdx + c] = baseTable[e] + ((f & 0x007fffff) >> shiftTable[e]);
47796
+ }
47797
+ result[dstIdx + 3] = one;
47798
+ }
47799
+ return result;
47800
+ };
47801
+ /**
47802
+ * Decode RLE-compressed RGBE scanlines into raw RGBE pixel data.
47803
+ */ HDRDecoder._readPixels = function _readPixels(buffer, width, height) {
47804
+ var byteLength = buffer.byteLength;
47805
+ var dataRGBA = new Uint8Array(4 * width * height);
47806
+ var offset = 0;
47807
+ var pos = 0;
47808
+ var ptrEnd = 4 * width;
47809
+ var scanLineBuffer = new Uint8Array(ptrEnd);
47810
+ var numScanLines = height;
47811
+ while(numScanLines > 0 && pos < byteLength){
47812
+ var a = buffer[pos++];
47813
+ var b = buffer[pos++];
47814
+ var c = buffer[pos++];
47815
+ var d = buffer[pos++];
47816
+ if (a !== 2 || b !== 2 || c & 0x80 || width < 8 || width > 32767) return buffer;
47817
+ if ((c << 8 | d) !== width) throw "HDRDecoder: wrong scanline width";
47818
+ var ptr = 0;
47819
+ while(ptr < ptrEnd && pos < byteLength){
47820
+ var count = buffer[pos++];
47821
+ var isEncodedRun = count > 128;
47822
+ if (isEncodedRun) count -= 128;
47823
+ if (count === 0 || ptr + count > ptrEnd) throw "HDRDecoder: bad scanline data";
47824
+ if (isEncodedRun) {
47825
+ var byteValue = buffer[pos++];
47826
+ for(var i = 0; i < count; i++)scanLineBuffer[ptr++] = byteValue;
47827
+ } else {
47828
+ scanLineBuffer.set(buffer.subarray(pos, pos + count), ptr);
47829
+ ptr += count;
47830
+ pos += count;
47831
+ }
47832
+ }
47833
+ for(var i1 = 0; i1 < width; i1++, offset += 4){
47834
+ dataRGBA[offset] = scanLineBuffer[i1];
47835
+ dataRGBA[offset + 1] = scanLineBuffer[i1 + width];
47836
+ dataRGBA[offset + 2] = scanLineBuffer[i1 + width * 2];
47837
+ dataRGBA[offset + 3] = scanLineBuffer[i1 + width * 3];
47838
+ }
47839
+ numScanLines--;
47840
+ }
47841
+ return dataRGBA;
47842
+ };
47843
+ HDRDecoder._generateFloat2HalfTables = function _generateFloat2HalfTables() {
47844
+ var baseTable = new Uint32Array(512);
47845
+ var shiftTable = new Uint32Array(512);
47846
+ for(var i = 0; i < 256; ++i){
47847
+ var e = i - 127;
47848
+ if (e < -27) {
47849
+ baseTable[i] = 0x0000;
47850
+ baseTable[i | 0x100] = 0x8000;
47851
+ shiftTable[i] = 24;
47852
+ shiftTable[i | 0x100] = 24;
47853
+ } else if (e < -14) {
47854
+ baseTable[i] = 0x0400 >> -e - 14;
47855
+ baseTable[i | 0x100] = 0x0400 >> -e - 14 | 0x8000;
47856
+ shiftTable[i] = -e - 1;
47857
+ shiftTable[i | 0x100] = -e - 1;
47858
+ } else if (e <= 15) {
47859
+ baseTable[i] = e + 15 << 10;
47860
+ baseTable[i | 0x100] = e + 15 << 10 | 0x8000;
47861
+ shiftTable[i] = 13;
47862
+ shiftTable[i | 0x100] = 13;
47863
+ } else if (e < 128) {
47864
+ baseTable[i] = 0x7c00;
47865
+ baseTable[i | 0x100] = 0xfc00;
47866
+ shiftTable[i] = 24;
47867
+ shiftTable[i | 0x100] = 24;
47868
+ } else {
47869
+ baseTable[i] = 0x7c00;
47870
+ baseTable[i | 0x100] = 0xfc00;
47871
+ shiftTable[i] = 13;
47872
+ shiftTable[i | 0x100] = 13;
47873
+ }
47874
+ }
47875
+ return {
47876
+ baseTable: baseTable,
47877
+ shiftTable: shiftTable
47878
+ };
47879
+ };
47880
+ HDRDecoder._readStringLine = function _readStringLine(uint8array, startIndex) {
47881
+ var line = "";
47882
+ for(var i = startIndex, n = uint8array.length; i < n; i++){
47883
+ var character = String.fromCharCode(uint8array[i]);
47884
+ if (character === "\n") break;
47885
+ line += character;
47886
+ }
47887
+ return line;
47888
+ };
47889
+ return HDRDecoder;
47890
+ }();
47891
+ HDRDecoder._float2HalfTables = HDRDecoder._generateFloat2HalfTables();
47892
+ HDRDecoder._floatView = new Float32Array(1);
47893
+ HDRDecoder._uint32View = new Uint32Array(HDRDecoder._floatView.buffer);
47894
+ /**
47895
+ * Data format: [url] [mipmap(1B)] [filterMode(1B)] [anisoLevel(1B)] [wrapModeU(1B)] [wrapModeV(1B)]
47896
+ * [format(1B)] [width(2B)] [height(2B)] [isSRGBColorSpace(1B)] [Uint32(imageSize) + imageBytes]
47897
+ */ var Texture2DDecoder = /*#__PURE__*/ function() {
47720
47898
  function Texture2DDecoder() {}
47721
47899
  Texture2DDecoder.decode = function decode(engine, bufferReader, restoredTexture) {
47722
47900
  return new AssetPromise(function(resolve, reject) {
47723
- var url = bufferReader.nextStr();
47901
+ bufferReader.nextStr();
47724
47902
  var mipmap = !!bufferReader.nextUint8();
47725
47903
  var filterMode = bufferReader.nextUint8();
47726
47904
  var anisoLevel = bufferReader.nextUint8();
@@ -47729,58 +47907,34 @@
47729
47907
  var format = bufferReader.nextUint8();
47730
47908
  var width = bufferReader.nextUint16();
47731
47909
  var height = bufferReader.nextUint16();
47732
- var isPixelBuffer = bufferReader.nextUint8();
47733
47910
  var isSRGBColorSpace = !!bufferReader.nextUint8();
47734
- var mipCount = bufferReader.nextUint8();
47735
- var imagesData = bufferReader.nextImagesData(mipCount);
47736
- var texture2D = restoredTexture || new Texture2D(engine, width, height, format, mipmap, isSRGBColorSpace);
47737
- texture2D.filterMode = filterMode;
47738
- texture2D.anisoLevel = anisoLevel;
47739
- texture2D.wrapModeU = wrapModeU;
47740
- texture2D.wrapModeV = wrapModeV;
47741
- if (isPixelBuffer) {
47742
- var pixelBuffer = imagesData[0];
47743
- texture2D.setPixelBuffer(pixelBuffer);
47744
- if (mipmap) {
47745
- texture2D.generateMipmaps();
47746
- for(var i = 1; i < mipCount; i++){
47747
- var pixelBuffer1 = imagesData[i];
47748
- texture2D.setPixelBuffer(pixelBuffer1, i);
47749
- }
47750
- }
47751
- // @ts-ignore
47752
- engine.resourceManager._objectPool[url] = texture2D;
47753
- resolve(texture2D);
47911
+ var imageData = bufferReader.nextImagesData(1)[0];
47912
+ var isHDR = imageData[0] === 0x23 && imageData[1] === 0x3f;
47913
+ var textureFormat = isHDR ? TextureFormat.R16G16B16A16 : format;
47914
+ var texture = restoredTexture || new Texture2D(engine, width, height, textureFormat, mipmap, isHDR ? false : isSRGBColorSpace);
47915
+ texture.filterMode = filterMode;
47916
+ texture.anisoLevel = anisoLevel;
47917
+ texture.wrapModeU = wrapModeU;
47918
+ texture.wrapModeV = wrapModeV;
47919
+ if (isHDR) {
47920
+ var pixels = HDRDecoder.decode(imageData).pixels;
47921
+ texture.setPixelBuffer(pixels);
47922
+ mipmap && texture.generateMipmaps();
47923
+ resolve(texture);
47754
47924
  } else {
47755
- var blob = new window.Blob([
47756
- imagesData[0]
47925
+ var blob = new Blob([
47926
+ imageData
47757
47927
  ]);
47758
47928
  var img = new Image();
47759
47929
  img.onload = function() {
47760
- texture2D.setImageSource(img);
47761
- var completedCount = 0;
47762
- var onComplete = function onComplete() {
47763
- completedCount++;
47764
- if (completedCount >= mipCount) {
47765
- resolve(texture2D);
47766
- }
47767
- };
47768
- onComplete();
47769
- if (mipmap) {
47770
- var _loop = function _loop(i) {
47771
- var blob = new window.Blob([
47772
- imagesData[i]
47773
- ]);
47774
- var img = new Image();
47775
- img.onload = function() {
47776
- texture2D.setImageSource(img, i);
47777
- onComplete();
47778
- };
47779
- img.src = URL.createObjectURL(blob);
47780
- };
47781
- texture2D.generateMipmaps();
47782
- for(var i = 1; i < mipCount; i++)_loop(i);
47783
- }
47930
+ URL.revokeObjectURL(img.src);
47931
+ texture.setImageSource(img);
47932
+ mipmap && texture.generateMipmaps();
47933
+ resolve(texture);
47934
+ };
47935
+ img.onerror = function(e) {
47936
+ URL.revokeObjectURL(img.src);
47937
+ reject(e);
47784
47938
  };
47785
47939
  img.src = URL.createObjectURL(blob);
47786
47940
  }
@@ -47788,9 +47942,71 @@
47788
47942
  };
47789
47943
  return Texture2DDecoder;
47790
47944
  }();
47791
- exports.Texture2DDecoder = __decorate([
47945
+ Texture2DDecoder = __decorate([
47792
47946
  decoder("Texture2D")
47793
- ], exports.Texture2DDecoder);
47947
+ ], Texture2DDecoder);
47948
+ /**
47949
+ * Data format: [url] [mipmap(1B)] [filterMode(1B)] [anisoLevel(1B)] [wrapModeU(1B)] [wrapModeV(1B)]
47950
+ * [format(1B)] [faceSize(2B)] [isSRGBColorSpace(1B)] [Uint32(size) + faceBytes] × 6
47951
+ */ var TextureCubeDecoder = /*#__PURE__*/ function() {
47952
+ function TextureCubeDecoder() {}
47953
+ TextureCubeDecoder.decode = function decode(engine, bufferReader, restoredTexture) {
47954
+ return new AssetPromise(function(resolve, reject) {
47955
+ bufferReader.nextStr();
47956
+ var mipmap = !!bufferReader.nextUint8();
47957
+ var filterMode = bufferReader.nextUint8();
47958
+ var anisoLevel = bufferReader.nextUint8();
47959
+ var wrapModeU = bufferReader.nextUint8();
47960
+ var wrapModeV = bufferReader.nextUint8();
47961
+ var format = bufferReader.nextUint8();
47962
+ var faceSize = bufferReader.nextUint16();
47963
+ var isSRGBColorSpace = !!bufferReader.nextUint8();
47964
+ var facesData = bufferReader.nextImagesData(6);
47965
+ // Detect format by first face's magic bytes
47966
+ var isHDR = facesData[0][0] === 0x23 && facesData[0][1] === 0x3f;
47967
+ var textureFormat = isHDR ? TextureFormat.R16G16B16A16 : format;
47968
+ var texture = restoredTexture || new TextureCube(engine, faceSize, textureFormat, mipmap, isSRGBColorSpace);
47969
+ texture.filterMode = filterMode;
47970
+ texture.anisoLevel = anisoLevel;
47971
+ texture.wrapModeU = wrapModeU;
47972
+ texture.wrapModeV = wrapModeV;
47973
+ if (isHDR) {
47974
+ for(var i = 0; i < 6; i++){
47975
+ var pixels = HDRDecoder.decode(facesData[i]).pixels;
47976
+ texture.setPixelBuffer(TextureCubeFace.PositiveX + i, pixels, 0);
47977
+ }
47978
+ mipmap && texture.generateMipmaps();
47979
+ resolve(texture);
47980
+ } else {
47981
+ var _loop = function _loop(i1) {
47982
+ var blob = new Blob([
47983
+ facesData[i1]
47984
+ ]);
47985
+ var img = new Image();
47986
+ img.onload = function() {
47987
+ URL.revokeObjectURL(img.src);
47988
+ texture.setImageSource(TextureCubeFace.PositiveX + i1, img);
47989
+ if (++loadedCount === 6) {
47990
+ mipmap && texture.generateMipmaps();
47991
+ resolve(texture);
47992
+ }
47993
+ };
47994
+ img.onerror = function(e) {
47995
+ URL.revokeObjectURL(img.src);
47996
+ reject(e);
47997
+ };
47998
+ img.src = URL.createObjectURL(blob);
47999
+ };
48000
+ var loadedCount = 0;
48001
+ for(var i1 = 0; i1 < 6; i1++)_loop(i1);
48002
+ }
48003
+ });
48004
+ };
48005
+ return TextureCubeDecoder;
48006
+ }();
48007
+ TextureCubeDecoder = __decorate([
48008
+ decoder("TextureCube")
48009
+ ], TextureCubeDecoder);
47794
48010
  function _instanceof1(left, right) {
47795
48011
  if (right != null && typeof Symbol !== "undefined" && right[Symbol.hasInstance]) {
47796
48012
  return !!right[Symbol.hasInstance](left);
@@ -50361,11 +50577,13 @@
50361
50577
  });
50362
50578
  var img = new Image();
50363
50579
  img.onerror = function() {
50580
+ URL.revokeObjectURL(img.src);
50364
50581
  reject(new Error("Failed to load image buffer"));
50365
50582
  };
50366
50583
  img.onload = function() {
50367
50584
  // Call requestAnimationFrame to avoid iOS's bug.
50368
50585
  requestAnimationFrame(function() {
50586
+ URL.revokeObjectURL(img.src);
50369
50587
  resolve(img);
50370
50588
  img.onload = null;
50371
50589
  img.onerror = null;
@@ -51783,7 +52001,7 @@
51783
52001
  if (uri) {
51784
52002
  var extIndex = uri.lastIndexOf(".");
51785
52003
  var ext = uri.substring(extIndex + 1);
51786
- var type = ext.startsWith("ktx") ? AssetType.KTX : AssetType.Texture2D;
52004
+ var type = ext.startsWith("ktx") ? AssetType.KTX : AssetType.Texture;
51787
52005
  texture = engine.resourceManager.load({
51788
52006
  url: Utils.resolveAbsoluteUrl(url, uri),
51789
52007
  type: type,
@@ -52640,7 +52858,7 @@
52640
52858
  var _atlasItem_type;
52641
52859
  chainPromises.push(resourceManager.load({
52642
52860
  url: Utils.resolveAbsoluteUrl(item.url, atlasItem.img),
52643
- type: (_atlasItem_type = atlasItem.type) != null ? _atlasItem_type : AssetType.Texture2D,
52861
+ type: (_atlasItem_type = atlasItem.type) != null ? _atlasItem_type : AssetType.Texture,
52644
52862
  params: {
52645
52863
  format: format,
52646
52864
  mipmap: mipmap
@@ -52775,26 +52993,12 @@
52775
52993
  "txt"
52776
52994
  ])
52777
52995
  ], TextLoader);
52778
- function loadImageFromBuffer(buffer) {
52779
- return new AssetPromise(function(resolve, reject) {
52780
- var blob = new Blob([
52781
- buffer
52782
- ]);
52783
- var img = new Image();
52784
- img.onload = function() {
52785
- URL.revokeObjectURL(img.src);
52786
- resolve(img);
52787
- };
52788
- img.onerror = reject;
52789
- img.src = URL.createObjectURL(blob);
52790
- });
52791
- }
52792
- var Texture2DLoader = /*#__PURE__*/ function(Loader) {
52793
- _inherits(Texture2DLoader, Loader);
52794
- function Texture2DLoader() {
52996
+ var TextureLoader = /*#__PURE__*/ function(Loader) {
52997
+ _inherits(TextureLoader, Loader);
52998
+ function TextureLoader() {
52795
52999
  return Loader.apply(this, arguments) || this;
52796
53000
  }
52797
- var _proto = Texture2DLoader.prototype;
53001
+ var _proto = TextureLoader.prototype;
52798
53002
  _proto.load = function load(item, resourceManager) {
52799
53003
  var _this = this;
52800
53004
  var url = item.url;
@@ -52804,427 +53008,136 @@
52804
53008
  return new AssetPromise(function(resolve, reject, setTaskCompleteProgress, setTaskDetailProgress) {
52805
53009
  resourceManager // @ts-ignore
52806
53010
  ._request(url, requestConfig).onProgress(setTaskCompleteProgress, setTaskDetailProgress).then(function(buffer) {
52807
- if (FileHeader.checkMagic(buffer)) {
52808
- decode(buffer, resourceManager.engine).then(function(texture) {
52809
- resourceManager.addContentRestorer(new Texture2DContentRestorer(texture, url, requestConfig));
52810
- resolve(texture);
52811
- }, reject);
52812
- } else {
52813
- loadImageFromBuffer(buffer).then(function(img) {
52814
- var texture = _this._createTexture(img, item, resourceManager);
52815
- resourceManager.addContentRestorer(new Texture2DContentRestorer(texture, url, requestConfig));
52816
- resolve(texture);
52817
- }, reject);
52818
- }
53011
+ _this._decode(buffer, item, resourceManager).then(function(texture) {
53012
+ resourceManager.addContentRestorer(new TextureContentRestorer(texture, url, requestConfig));
53013
+ resolve(texture);
53014
+ }, reject);
52819
53015
  }).catch(reject);
52820
53016
  });
52821
53017
  };
52822
- _proto._createTexture = function _createTexture(img, item, resourceManager) {
53018
+ _proto._decode = function _decode(buffer, item, resourceManager) {
53019
+ if (FileHeader.checkMagic(buffer)) {
53020
+ return decode(buffer, resourceManager.engine);
53021
+ }
53022
+ var bufferView = new Uint8Array(buffer);
53023
+ var isHDR = bufferView[0] === 0x23 && bufferView[1] === 0x3f;
53024
+ if (isHDR) {
53025
+ return this._decodeHDR(bufferView, item, resourceManager);
53026
+ }
53027
+ return this._decodeImage(buffer, item, resourceManager);
53028
+ };
53029
+ _proto._decodeHDR = function _decodeHDR(buffer, item, resourceManager) {
53030
+ var _this = this;
53031
+ return new AssetPromise(function(resolve, reject) {
53032
+ var engine = resourceManager.engine;
53033
+ if (!SystemInfo.supportsTextureFormat(engine, TextureFormat.R16G16B16A16)) {
53034
+ reject(new Error("TextureLoader: HDR texture requires half float support."));
53035
+ return;
53036
+ }
53037
+ var _HDRDecoder_decode = HDRDecoder.decode(buffer), width = _HDRDecoder_decode.width, height = _HDRDecoder_decode.height, pixels = _HDRDecoder_decode.pixels;
53038
+ var _item_params;
53039
+ var _ref = (_item_params = item.params) != null ? _item_params : {}, _ref_mipmap = _ref.mipmap, mipmap = _ref_mipmap === void 0 ? true : _ref_mipmap;
53040
+ var texture = new Texture2D(engine, width, height, TextureFormat.R16G16B16A16, mipmap, false);
53041
+ texture.setPixelBuffer(pixels);
53042
+ mipmap && texture.generateMipmaps();
53043
+ _this._applyParams(texture, item);
53044
+ resolve(texture);
53045
+ });
53046
+ };
53047
+ _proto._decodeImage = function _decodeImage(buffer, item, resourceManager) {
53048
+ var _this = this;
53049
+ return new AssetPromise(function(resolve, reject) {
53050
+ var blob = new Blob([
53051
+ buffer
53052
+ ]);
53053
+ var img = new Image();
53054
+ img.onload = function() {
53055
+ URL.revokeObjectURL(img.src);
53056
+ var _item_params;
53057
+ var _ref = (_item_params = item.params) != null ? _item_params : {}, _ref_format = _ref.format, format = _ref_format === void 0 ? TextureFormat.R8G8B8A8 : _ref_format, _ref_isSRGBColorSpace = _ref.isSRGBColorSpace, isSRGBColorSpace = _ref_isSRGBColorSpace === void 0 ? true : _ref_isSRGBColorSpace, _ref_mipmap = _ref.mipmap, mipmap = _ref_mipmap === void 0 ? true : _ref_mipmap;
53058
+ var engine = resourceManager.engine;
53059
+ var width = img.width, height = img.height;
53060
+ var generateMipmap = TextureUtils.supportGenerateMipmapsWithCorrection(engine, width, height, format, mipmap, isSRGBColorSpace);
53061
+ var texture = new Texture2D(engine, width, height, format, generateMipmap, isSRGBColorSpace);
53062
+ texture.setImageSource(img);
53063
+ generateMipmap && texture.generateMipmaps();
53064
+ _this._applyParams(texture, item);
53065
+ resolve(texture);
53066
+ };
53067
+ img.onerror = function(e) {
53068
+ URL.revokeObjectURL(img.src);
53069
+ reject(e);
53070
+ };
53071
+ img.src = URL.createObjectURL(blob);
53072
+ });
53073
+ };
53074
+ _proto._applyParams = function _applyParams(texture, item) {
52823
53075
  var _item_params;
52824
- var _ref = (_item_params = item.params) != null ? _item_params : {}, _ref_format = _ref.format, format = _ref_format === void 0 ? TextureFormat.R8G8B8A8 : _ref_format, anisoLevel = _ref.anisoLevel, wrapModeU = _ref.wrapModeU, wrapModeV = _ref.wrapModeV, filterMode = _ref.filterMode, _ref_isSRGBColorSpace = _ref.isSRGBColorSpace, isSRGBColorSpace = _ref_isSRGBColorSpace === void 0 ? true : _ref_isSRGBColorSpace, _ref_mipmap = _ref.mipmap, mipmap = _ref_mipmap === void 0 ? true : _ref_mipmap;
52825
- var width = img.width, height = img.height;
52826
- var engine = resourceManager.engine;
52827
- var generateMipmap = TextureUtils.supportGenerateMipmapsWithCorrection(engine, width, height, format, mipmap, isSRGBColorSpace);
52828
- var texture = new Texture2D(engine, width, height, format, generateMipmap, isSRGBColorSpace);
53076
+ var _ref = (_item_params = item.params) != null ? _item_params : {}, anisoLevel = _ref.anisoLevel, wrapModeU = _ref.wrapModeU, wrapModeV = _ref.wrapModeV, filterMode = _ref.filterMode;
52829
53077
  texture.anisoLevel = anisoLevel != null ? anisoLevel : texture.anisoLevel;
52830
53078
  texture.filterMode = filterMode != null ? filterMode : texture.filterMode;
52831
53079
  texture.wrapModeU = wrapModeU != null ? wrapModeU : texture.wrapModeU;
52832
53080
  texture.wrapModeV = wrapModeV != null ? wrapModeV : texture.wrapModeV;
52833
- texture.setImageSource(img);
52834
- generateMipmap && texture.generateMipmaps();
52835
53081
  var url = item.url;
52836
53082
  if (url.indexOf("data:") !== 0) {
52837
53083
  texture.name = url.substring(url.lastIndexOf("/") + 1);
52838
53084
  }
52839
- return texture;
52840
53085
  };
52841
- return Texture2DLoader;
53086
+ return TextureLoader;
52842
53087
  }(Loader);
52843
- Texture2DLoader = __decorate([
52844
- resourceLoader(AssetType.Texture2D, [
53088
+ TextureLoader = __decorate([
53089
+ resourceLoader(AssetType.Texture, [
53090
+ "tex",
52845
53091
  "png",
52846
53092
  "jpg",
52847
53093
  "webp",
52848
53094
  "jpeg",
52849
- "tex"
53095
+ "hdr"
52850
53096
  ])
52851
- ], Texture2DLoader);
52852
- var Texture2DContentRestorer = /*#__PURE__*/ function(ContentRestorer) {
52853
- _inherits(Texture2DContentRestorer, ContentRestorer);
52854
- function Texture2DContentRestorer(resource, url, requestConfig) {
53097
+ ], TextureLoader);
53098
+ var TextureContentRestorer = /*#__PURE__*/ function(ContentRestorer) {
53099
+ _inherits(TextureContentRestorer, ContentRestorer);
53100
+ function TextureContentRestorer(resource, url, requestConfig) {
52855
53101
  var _this;
52856
53102
  _this = ContentRestorer.call(this, resource) || this, _this.url = url, _this.requestConfig = requestConfig;
52857
53103
  return _this;
52858
53104
  }
52859
- var _proto = Texture2DContentRestorer.prototype;
53105
+ var _proto = TextureContentRestorer.prototype;
52860
53106
  _proto.restoreContent = function restoreContent() {
52861
- var texture = this.resource;
52862
- var engine = texture.engine;
52863
- return engine.resourceManager // @ts-ignore
53107
+ var _this = this;
53108
+ return this.resource.engine.resourceManager // @ts-ignore
52864
53109
  ._request(this.url, this.requestConfig).then(function(buffer) {
52865
53110
  if (FileHeader.checkMagic(buffer)) {
52866
- return decode(buffer, engine, texture);
52867
- } else {
52868
- return loadImageFromBuffer(buffer).then(function(img) {
52869
- texture.setImageSource(img);
52870
- texture.generateMipmaps();
52871
- return texture;
52872
- });
52873
- }
52874
- });
52875
- };
52876
- return Texture2DContentRestorer;
52877
- }(ContentRestorer);
52878
- /**
52879
- * HDR panorama to cubemap decoder.
52880
- */ var HDRDecoder = /*#__PURE__*/ function() {
52881
- function HDRDecoder() {}
52882
- HDRDecoder.parseHeader = function parseHeader(uint8array) {
52883
- var line = this._readStringLine(uint8array, 0);
52884
- if (line[0] !== "#" || line[1] !== "?") {
52885
- throw "HDRDecoder: invalid file header";
52886
- }
52887
- var endOfHeader = false;
52888
- var findFormat = false;
52889
- var lineIndex = 0;
52890
- do {
52891
- lineIndex += line.length + 1;
52892
- line = this._readStringLine(uint8array, lineIndex);
52893
- if (line === "FORMAT=32-bit_rle_rgbe") findFormat = true;
52894
- else if (line.length === 0) endOfHeader = true;
52895
- }while (!endOfHeader);
52896
- if (!findFormat) {
52897
- throw "HDRDecoder: unsupported format, expected 32-bit_rle_rgbe";
52898
- }
52899
- lineIndex += line.length + 1;
52900
- line = this._readStringLine(uint8array, lineIndex);
52901
- var match = /^\-Y (.*) \+X (.*)$/g.exec(line);
52902
- if (!match || match.length < 3) {
52903
- throw "HDRDecoder: missing image size, only -Y +X layout is supported";
52904
- }
52905
- var width = parseInt(match[2]);
52906
- var height = parseInt(match[1]);
52907
- if (width < 8 || width > 0x7fff) {
52908
- throw "HDRDecoder: unsupported image width, must be between 8 and 32767";
52909
- }
52910
- return {
52911
- height: height,
52912
- width: width,
52913
- dataPosition: lineIndex + line.length + 1
52914
- };
52915
- };
52916
- HDRDecoder.decodeFaces = function decodeFaces(bufferArray, header, onFace) {
52917
- var width = header.width, height = header.height, dataPosition = header.dataPosition;
52918
- var cubeSize = height >> 1;
52919
- var pixels = HDRDecoder._readPixels(bufferArray.subarray(dataPosition), width, height);
52920
- var faces = HDRDecoder._faces;
52921
- var faceBuffer = new Uint16Array(cubeSize * cubeSize * 4);
52922
- for(var faceIndex = 0; faceIndex < 6; faceIndex++){
52923
- HDRDecoder._createCubemapData(cubeSize, faces[faceIndex], pixels, width, height, faceBuffer);
52924
- onFace(faceIndex, faceBuffer);
52925
- }
52926
- };
52927
- HDRDecoder._generateFloat2HalfTables = function _generateFloat2HalfTables() {
52928
- var baseTable = new Uint32Array(512);
52929
- var shiftTable = new Uint32Array(512);
52930
- for(var i = 0; i < 256; ++i){
52931
- var e = i - 127;
52932
- if (e < -27) {
52933
- baseTable[i] = 0x0000;
52934
- baseTable[i | 0x100] = 0x8000;
52935
- shiftTable[i] = 24;
52936
- shiftTable[i | 0x100] = 24;
52937
- } else if (e < -14) {
52938
- baseTable[i] = 0x0400 >> -e - 14;
52939
- baseTable[i | 0x100] = 0x0400 >> -e - 14 | 0x8000;
52940
- shiftTable[i] = -e - 1;
52941
- shiftTable[i | 0x100] = -e - 1;
52942
- } else if (e <= 15) {
52943
- baseTable[i] = e + 15 << 10;
52944
- baseTable[i | 0x100] = e + 15 << 10 | 0x8000;
52945
- shiftTable[i] = 13;
52946
- shiftTable[i | 0x100] = 13;
52947
- } else if (e < 128) {
52948
- baseTable[i] = 0x7c00;
52949
- baseTable[i | 0x100] = 0xfc00;
52950
- shiftTable[i] = 24;
52951
- shiftTable[i | 0x100] = 24;
52952
- } else {
52953
- baseTable[i] = 0x7c00;
52954
- baseTable[i | 0x100] = 0xfc00;
52955
- shiftTable[i] = 13;
52956
- shiftTable[i | 0x100] = 13;
52957
- }
52958
- }
52959
- return {
52960
- baseTable: baseTable,
52961
- shiftTable: shiftTable
52962
- };
52963
- };
52964
- HDRDecoder._createCubemapData = function _createCubemapData(texSize, face, pixels, inputWidth, inputHeight, facePixels) {
52965
- var invSize = 1 / texSize;
52966
- var rotDX1X = (face[3] - face[0]) * invSize;
52967
- var rotDX1Y = (face[4] - face[1]) * invSize;
52968
- var rotDX1Z = (face[5] - face[2]) * invSize;
52969
- var rotDX2X = (face[9] - face[6]) * invSize;
52970
- var rotDX2Y = (face[10] - face[7]) * invSize;
52971
- var rotDX2Z = (face[11] - face[8]) * invSize;
52972
- var floatView = HDRDecoder._floatView;
52973
- var uint32View = HDRDecoder._uint32View;
52974
- var _HDRDecoder__float2HalfTables = HDRDecoder._float2HalfTables, baseTable = _HDRDecoder__float2HalfTables.baseTable, shiftTable = _HDRDecoder__float2HalfTables.shiftTable;
52975
- var one = HDRDecoder._one;
52976
- var fy = 0;
52977
- for(var y = 0; y < texSize; y++){
52978
- var xv1X = face[0], xv1Y = face[1], xv1Z = face[2];
52979
- var xv2X = face[6], xv2Y = face[7], xv2Z = face[8];
52980
- for(var x = 0; x < texSize; x++){
52981
- var dirX = xv1X + (xv2X - xv1X) * fy;
52982
- var dirY = xv1Y + (xv2Y - xv1Y) * fy;
52983
- var dirZ = xv1Z + (xv2Z - xv1Z) * fy;
52984
- var invLen = 1 / Math.sqrt(dirX * dirX + dirY * dirY + dirZ * dirZ);
52985
- dirX *= invLen;
52986
- dirY *= invLen;
52987
- dirZ *= invLen;
52988
- var px = Math.round((Math.atan2(dirZ, dirX) / Math.PI * 0.5 + 0.5) * inputWidth);
52989
- if (px < 0) px = 0;
52990
- else if (px >= inputWidth) px = inputWidth - 1;
52991
- var py = Math.round(Math.acos(dirY) / Math.PI * inputHeight);
52992
- if (py < 0) py = 0;
52993
- else if (py >= inputHeight) py = inputHeight - 1;
52994
- var srcIndex = (inputHeight - py - 1) * inputWidth * 4 + px * 4;
52995
- var scaleFactor = Math.pow(2, pixels[srcIndex + 3] - 128) / 255;
52996
- var dstIndex = y * texSize * 4 + x * 4;
52997
- for(var c = 0; c < 3; c++){
52998
- // Clamp to half-float max (65504) to prevent Infinity in R16G16B16A16
52999
- floatView[0] = Math.min(pixels[srcIndex + c] * scaleFactor, 65504);
53000
- var f = uint32View[0];
53001
- var e = f >> 23 & 0x1ff;
53002
- facePixels[dstIndex + c] = baseTable[e] + ((f & 0x007fffff) >> shiftTable[e]);
53003
- }
53004
- facePixels[dstIndex + 3] = one;
53005
- xv1X += rotDX1X;
53006
- xv1Y += rotDX1Y;
53007
- xv1Z += rotDX1Z;
53008
- xv2X += rotDX2X;
53009
- xv2Y += rotDX2Y;
53010
- xv2Z += rotDX2Z;
53011
- }
53012
- fy += invSize;
53013
- }
53014
- };
53015
- HDRDecoder._readStringLine = function _readStringLine(uint8array, startIndex) {
53016
- var line = "";
53017
- for(var i = startIndex, n = uint8array.length; i < n; i++){
53018
- var character = String.fromCharCode(uint8array[i]);
53019
- if (character === "\n") break;
53020
- line += character;
53021
- }
53022
- return line;
53023
- };
53024
- HDRDecoder._readPixels = function _readPixels(buffer, width, height) {
53025
- var byteLength = buffer.byteLength;
53026
- var dataRGBA = new Uint8Array(4 * width * height);
53027
- var offset = 0;
53028
- var pos = 0;
53029
- var ptrEnd = 4 * width;
53030
- var scanLineBuffer = new Uint8Array(ptrEnd);
53031
- var numScanLines = height;
53032
- while(numScanLines > 0 && pos < byteLength){
53033
- var a = buffer[pos++];
53034
- var b = buffer[pos++];
53035
- var c = buffer[pos++];
53036
- var d = buffer[pos++];
53037
- if (a !== 2 || b !== 2 || c & 0x80 || width < 8 || width > 32767) return buffer;
53038
- if ((c << 8 | d) !== width) throw "HDRDecoder: wrong scanline width";
53039
- var ptr = 0;
53040
- while(ptr < ptrEnd && pos < byteLength){
53041
- var count = buffer[pos++];
53042
- var isEncodedRun = count > 128;
53043
- if (isEncodedRun) count -= 128;
53044
- if (count === 0 || ptr + count > ptrEnd) throw "HDRDecoder: bad scanline data";
53045
- if (isEncodedRun) {
53046
- var byteValue = buffer[pos++];
53047
- for(var i = 0; i < count; i++)scanLineBuffer[ptr++] = byteValue;
53048
- } else {
53049
- scanLineBuffer.set(buffer.subarray(pos, pos + count), ptr);
53050
- ptr += count;
53051
- pos += count;
53052
- }
53053
- }
53054
- for(var i1 = 0; i1 < width; i1++, offset += 4){
53055
- dataRGBA[offset] = scanLineBuffer[i1];
53056
- dataRGBA[offset + 1] = scanLineBuffer[i1 + width];
53057
- dataRGBA[offset + 2] = scanLineBuffer[i1 + width * 2];
53058
- dataRGBA[offset + 3] = scanLineBuffer[i1 + width * 3];
53111
+ return decode(buffer, _this.resource.engine, _this.resource);
53112
+ }
53113
+ var bufferView = new Uint8Array(buffer);
53114
+ var texture = _this.resource;
53115
+ if (bufferView[0] === 0x23 && bufferView[1] === 0x3f) {
53116
+ var pixels = HDRDecoder.decode(bufferView).pixels;
53117
+ texture.setPixelBuffer(pixels);
53118
+ texture.mipmapCount > 1 && texture.generateMipmaps();
53119
+ return texture;
53059
53120
  }
53060
- numScanLines--;
53061
- }
53062
- return dataRGBA;
53063
- };
53064
- return HDRDecoder;
53065
- }();
53066
- // Float32 to Float16 lookup tables (http://www.fox-toolkit.org/ftp/fasthalffloatconversion.pdf)
53067
- HDRDecoder._float2HalfTables = HDRDecoder._generateFloat2HalfTables();
53068
- HDRDecoder._floatView = new Float32Array(1);
53069
- HDRDecoder._uint32View = new Uint32Array(HDRDecoder._floatView.buffer);
53070
- HDRDecoder._one = 0x3c00 // Half float for 1.0
53071
- ;
53072
- // prettier-ignore
53073
- HDRDecoder._faces = [
53074
- /* +X */ [
53075
- 1,
53076
- -1,
53077
- -1,
53078
- 1,
53079
- -1,
53080
- 1,
53081
- 1,
53082
- 1,
53083
- -1,
53084
- 1,
53085
- 1,
53086
- 1
53087
- ],
53088
- /* -X */ [
53089
- -1,
53090
- -1,
53091
- 1,
53092
- -1,
53093
- -1,
53094
- -1,
53095
- -1,
53096
- 1,
53097
- 1,
53098
- -1,
53099
- 1,
53100
- -1
53101
- ],
53102
- /* +Y */ [
53103
- -1,
53104
- -1,
53105
- 1,
53106
- 1,
53107
- -1,
53108
- 1,
53109
- -1,
53110
- -1,
53111
- -1,
53112
- 1,
53113
- -1,
53114
- -1
53115
- ],
53116
- /* -Y */ [
53117
- -1,
53118
- 1,
53119
- -1,
53120
- 1,
53121
- 1,
53122
- -1,
53123
- -1,
53124
- 1,
53125
- 1,
53126
- 1,
53127
- 1,
53128
- 1
53129
- ],
53130
- /* +Z */ [
53131
- -1,
53132
- -1,
53133
- -1,
53134
- 1,
53135
- -1,
53136
- -1,
53137
- -1,
53138
- 1,
53139
- -1,
53140
- 1,
53141
- 1,
53142
- -1
53143
- ],
53144
- /* -Z */ [
53145
- 1,
53146
- -1,
53147
- 1,
53148
- -1,
53149
- -1,
53150
- 1,
53151
- 1,
53152
- 1,
53153
- 1,
53154
- -1,
53155
- 1,
53156
- 1
53157
- ]
53158
- ];
53159
- var TextureCubeLoader = /*#__PURE__*/ function(Loader) {
53160
- _inherits(TextureCubeLoader, Loader);
53161
- function TextureCubeLoader() {
53162
- return Loader.apply(this, arguments) || this;
53163
- }
53164
- var _proto = TextureCubeLoader.prototype;
53165
- _proto.load = function load(item, resourceManager) {
53166
- return new AssetPromise(function(resolve, reject) {
53167
- var engine = resourceManager.engine;
53168
- var url = item.url;
53169
- var requestConfig = _extends({}, item, {
53170
- type: "arraybuffer"
53121
+ return new AssetPromise(function(resolve, reject) {
53122
+ var blob = new Blob([
53123
+ buffer
53124
+ ]);
53125
+ var img = new Image();
53126
+ img.onload = function() {
53127
+ URL.revokeObjectURL(img.src);
53128
+ texture.setImageSource(img);
53129
+ texture.mipmapCount > 1 && texture.generateMipmaps();
53130
+ resolve(texture);
53131
+ };
53132
+ img.onerror = function(e) {
53133
+ URL.revokeObjectURL(img.src);
53134
+ reject(e);
53135
+ };
53136
+ img.src = URL.createObjectURL(blob);
53171
53137
  });
53172
- resourceManager // @ts-ignore
53173
- ._request(url, requestConfig).then(function(buffer) {
53174
- if (!SystemInfo.supportsTextureFormat(engine, TextureFormat.R16G16B16A16)) {
53175
- reject(new Error("TextureCubeLoader: HDR texture requires half float support."));
53176
- return;
53177
- }
53178
- var _item_params;
53179
- var _ref = (_item_params = item.params) != null ? _item_params : {}, _ref_mipmap = _ref.mipmap, mipmap = _ref_mipmap === void 0 ? true : _ref_mipmap, anisoLevel = _ref.anisoLevel, wrapModeU = _ref.wrapModeU, wrapModeV = _ref.wrapModeV, filterMode = _ref.filterMode;
53180
- var bufferArray = new Uint8Array(buffer);
53181
- var header = HDRDecoder.parseHeader(bufferArray);
53182
- var texture = new TextureCube(engine, header.height >> 1, TextureFormat.R16G16B16A16, mipmap, false);
53183
- HDRDecoder.decodeFaces(bufferArray, header, function(faceIndex, data) {
53184
- texture.setPixelBuffer(TextureCubeFace.PositiveX + faceIndex, data, 0);
53185
- });
53186
- texture.generateMipmaps();
53187
- texture.anisoLevel = anisoLevel != null ? anisoLevel : texture.anisoLevel;
53188
- texture.filterMode = filterMode != null ? filterMode : texture.filterMode;
53189
- texture.wrapModeU = wrapModeU != null ? wrapModeU : texture.wrapModeU;
53190
- texture.wrapModeV = wrapModeV != null ? wrapModeV : texture.wrapModeV;
53191
- resourceManager.addContentRestorer(new HDRContentRestorer(texture, url, requestConfig));
53192
- resolve(texture);
53193
- }).catch(reject);
53194
- });
53195
- };
53196
- return TextureCubeLoader;
53197
- }(Loader);
53198
- TextureCubeLoader = __decorate([
53199
- resourceLoader(AssetType.TextureCube, [
53200
- "texCube",
53201
- "hdr"
53202
- ])
53203
- ], TextureCubeLoader);
53204
- var HDRContentRestorer = /*#__PURE__*/ function(ContentRestorer) {
53205
- _inherits(HDRContentRestorer, ContentRestorer);
53206
- function HDRContentRestorer(resource, url, requestConfig) {
53207
- var _this;
53208
- _this = ContentRestorer.call(this, resource) || this, _this.url = url, _this.requestConfig = requestConfig;
53209
- return _this;
53210
- }
53211
- var _proto = HDRContentRestorer.prototype;
53212
- _proto.restoreContent = function restoreContent() {
53213
- var _this = this;
53214
- return new AssetPromise(function(resolve, reject) {
53215
- var resource = _this.resource;
53216
- resource.engine.resourceManager // @ts-ignore
53217
- ._request(_this.url, _this.requestConfig).then(function(buffer) {
53218
- var bufferArray = new Uint8Array(buffer);
53219
- HDRDecoder.decodeFaces(bufferArray, HDRDecoder.parseHeader(bufferArray), function(faceIndex, data) {
53220
- resource.setPixelBuffer(TextureCubeFace.PositiveX + faceIndex, data, 0);
53221
- });
53222
- resource.generateMipmaps();
53223
- resolve(resource);
53224
- }).catch(reject);
53225
53138
  });
53226
53139
  };
53227
- return HDRContentRestorer;
53140
+ return TextureContentRestorer;
53228
53141
  }(ContentRestorer);
53229
53142
  var AudioLoader = /*#__PURE__*/ function(Loader) {
53230
53143
  _inherits(AudioLoader, Loader);
@@ -54055,7 +53968,7 @@
54055
53968
  ], EXT_texture_webp);
54056
53969
 
54057
53970
  //@ts-ignore
54058
- var version = "2.0.0-alpha.23";
53971
+ var version = "2.0.0-alpha.25";
54059
53972
  console.log("Galacean Engine Version: " + version);
54060
53973
  for(var key in CoreObjects){
54061
53974
  Loader.registerClass(key, CoreObjects[key]);