@gnsx/three 0.186.6 → 0.186.8

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.
@@ -3,7 +3,7 @@
3
3
  * Copyright 2010-2026 Three.js Authors
4
4
  * SPDX-License-Identifier: MIT
5
5
  */
6
- import { DynamicDrawUsage, RenderObjectRefreshType, Color, Vector2, Vector3, Vector4, Matrix2, Matrix3, Matrix4, error, UnsignedIntType, IntType, RedFormat, RedIntegerFormat, DepthFormat, DepthStencilFormat, AlphaFormat, RGFormat, RGIntegerFormat, RGBFormat, RGBIntegerFormat, EventDispatcher, MathUtils, warn, WebGLCoordinateSystem, WebGPUCoordinateSystem, ColorManagement, SRGBTransfer, NoToneMapping, StaticDrawUsage, InterleavedBufferAttribute, InterleavedBuffer, NoColorSpace, log as log$1, warnOnce, Texture, Compatibility, LessCompare, LessEqualCompare, GreaterCompare, GreaterEqualCompare, NearestFilter, Sphere, BackSide, DoubleSide, CubeTexture, CubeReflectionMapping, CubeRefractionMapping, TangentSpaceNormalMap, NoNormalPacking, NormalRGPacking, NormalGAPacking, ObjectSpaceNormalMap, RED_GREEN_RGTC2_Format, RG11_EAC_Format, InstancedBufferAttribute, InstancedInterleavedBuffer, DataTexture, RGBAFormat, FloatType, DataArrayTexture, FramebufferTexture, LinearMipmapLinearFilter, DepthTexture, NormalBlending, SrcAlphaFactor, OneMinusSrcAlphaFactor, AddEquation, MaterialBlending, NoBlending, Material, LineBasicMaterial, LineDashedMaterial, MeshNormalMaterial, SRGBColorSpace, RenderTarget, BoxGeometry, Mesh, Scene, LinearFilter, CubeCamera, EquirectangularReflectionMapping, EquirectangularRefractionMapping, AddOperation, MixOperation, MultiplyOperation, MeshBasicMaterial, MeshLambertMaterial, MeshPhongMaterial, HalfFloatType, ClampToEdgeWrapping, BufferGeometry, OrthographicCamera, PerspectiveCamera, LinearSRGBColorSpace, CubeUVReflectionMapping, BufferAttribute, MeshStandardMaterial, MeshPhysicalMaterial, MeshToonMaterial, MeshMatcapMaterial, SpriteMaterial, PointsMaterial, ShadowMaterial, Uint32BufferAttribute, Uint16BufferAttribute, ByteType, UnsignedByteType, ShortType, UnsignedShortType, UnsignedShort4444Type, UnsignedShort5551Type, UnsignedInt248Type, UnsignedInt5999Type, UnsignedInt101111Type, Object3D, LinearMipMapLinearFilter, Plane, Float32BufferAttribute, UVMapping, Data3DTexture, VSMShadowMap, PCFShadowMap, ProfilerService, BasicShadowMap, CubeDepthTexture, SphereGeometry, LinearMipmapNearestFilter, NearestMipmapLinearFilter, Float16BufferAttribute, yieldToMain, REVISION, ArrayCamera, PlaneGeometry, FrontSide, CustomBlending, ZeroFactor, CylinderGeometry, Quaternion, WebXRController, RAD2DEG, PCFSoftShadowMap, FrustumArray, Frustum, RGBAIntegerFormat, TimestampQuery, createCanvasElement, MaxEquation, MinEquation, ReverseSubtractEquation, SubtractEquation, OneMinusConstantAlphaFactor, ConstantAlphaFactor, OneMinusConstantColorFactor, ConstantColorFactor, OneMinusDstAlphaFactor, OneMinusDstColorFactor, OneMinusSrcColorFactor, DstAlphaFactor, DstColorFactor, SrcAlphaSaturateFactor, SrcColorFactor, OneFactor, CullFaceNone, CullFaceBack, CullFaceFront, MultiplyBlending, SubtractiveBlending, AdditiveBlending, NotEqualDepth, GreaterDepth, GreaterEqualDepth, EqualDepth, LessEqualDepth, LessDepth, AlwaysDepth, NeverDepth, ReversedDepthFuncs, RGB_S3TC_DXT1_Format, RGBA_S3TC_DXT1_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT5_Format, RGB_PVRTC_4BPPV1_Format, RGB_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGBA_PVRTC_2BPPV1_Format, RGB_ETC1_Format, RGB_ETC2_Format, RGBA_ETC2_EAC_Format, R11_EAC_Format, SIGNED_R11_EAC_Format, SIGNED_RG11_EAC_Format, RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_10x10_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGBA_BPTC_Format, RGB_BPTC_SIGNED_Format, RGB_BPTC_UNSIGNED_Format, RED_RGTC1_Format, SIGNED_RED_RGTC1_Format, SIGNED_RED_GREEN_RGTC2_Format, MirroredRepeatWrapping, RepeatWrapping, NearestMipmapNearestFilter, NotEqualCompare, EqualCompare, AlwaysCompare, NeverCompare, LinearTransfer, getByteLength, isTypedArray, NotEqualStencilFunc, GreaterStencilFunc, GreaterEqualStencilFunc, EqualStencilFunc, LessEqualStencilFunc, LessStencilFunc, AlwaysStencilFunc, NeverStencilFunc, DecrementWrapStencilOp, IncrementWrapStencilOp, DecrementStencilOp, IncrementStencilOp, InvertStencilOp, ReplaceStencilOp, ZeroStencilOp, KeepStencilOp, SpotLight, PointLight, DirectionalLight, RectAreaLight, AmbientLight, HemisphereLight, LightProbe, LinearToneMapping, ReinhardToneMapping, CineonToneMapping, ACESFilmicToneMapping, AgXToneMapping, NeutralToneMapping, Group, Loader, FileLoader, MaterialLoader, ObjectLoader } from './three.core.js';
6
+ import { DynamicDrawUsage, RenderObjectRefreshType, Color, Vector2, Vector3, Vector4, Matrix2, Matrix3, Matrix4, error, UnsignedIntType, IntType, RedFormat, RedIntegerFormat, DepthFormat, DepthStencilFormat, AlphaFormat, RGFormat, RGIntegerFormat, RGBFormat, RGBIntegerFormat, EventDispatcher, MathUtils, warn, WebGLCoordinateSystem, WebGPUCoordinateSystem, ColorManagement, SRGBTransfer, NoToneMapping, StaticDrawUsage, InterleavedBufferAttribute, InterleavedBuffer, NoColorSpace, log as log$1, warnOnce, Texture, Compatibility, LessCompare, LessEqualCompare, GreaterCompare, GreaterEqualCompare, NearestFilter, Sphere, BackSide, DoubleSide, CubeTexture, CubeReflectionMapping, CubeRefractionMapping, TangentSpaceNormalMap, NoNormalPacking, NormalRGPacking, NormalGAPacking, ObjectSpaceNormalMap, RED_GREEN_RGTC2_Format, RG11_EAC_Format, InstancedBufferAttribute, InstancedInterleavedBuffer, DataTexture, RGBAFormat, FloatType, DataArrayTexture, FramebufferTexture, LinearMipmapLinearFilter, DepthTexture, NormalBlending, SrcAlphaFactor, OneMinusSrcAlphaFactor, AddEquation, MaterialBlending, NoBlending, Material, LineBasicMaterial, LineDashedMaterial, MeshNormalMaterial, SRGBColorSpace, RenderTarget, BoxGeometry, Mesh, Scene, LinearFilter, CubeCamera, EquirectangularReflectionMapping, EquirectangularRefractionMapping, AddOperation, MixOperation, MultiplyOperation, MeshBasicMaterial, MeshLambertMaterial, MeshPhongMaterial, HalfFloatType, ClampToEdgeWrapping, BufferGeometry, OrthographicCamera, PerspectiveCamera, LinearSRGBColorSpace, CubeUVReflectionMapping, BufferAttribute, MeshStandardMaterial, MeshPhysicalMaterial, MeshToonMaterial, MeshMatcapMaterial, SpriteMaterial, PointsMaterial, ShadowMaterial, Uint32BufferAttribute, Uint16BufferAttribute, ByteType, UnsignedByteType, ShortType, UnsignedShortType, UnsignedShort4444Type, UnsignedShort5551Type, UnsignedInt248Type, UnsignedInt5999Type, UnsignedInt101111Type, Object3D, LinearMipMapLinearFilter, Plane, Float32BufferAttribute, UVMapping, Data3DTexture, VSMShadowMap, PCFShadowMap, ProfilerService, BasicShadowMap, CubeDepthTexture, SphereGeometry, LinearMipmapNearestFilter, NearestMipmapLinearFilter, Float16BufferAttribute, yieldToMain, REVISION, ArrayCamera, PlaneGeometry, FrontSide, CustomBlending, ZeroFactor, CylinderGeometry, Quaternion, WebXRController, RAD2DEG, PCFSoftShadowMap, FrustumArray, Frustum, EqualDepth, RGBAIntegerFormat, TimestampQuery, createCanvasElement, MaxEquation, MinEquation, ReverseSubtractEquation, SubtractEquation, OneMinusConstantAlphaFactor, ConstantAlphaFactor, OneMinusConstantColorFactor, ConstantColorFactor, OneMinusDstAlphaFactor, OneMinusDstColorFactor, OneMinusSrcColorFactor, DstAlphaFactor, DstColorFactor, SrcAlphaSaturateFactor, SrcColorFactor, OneFactor, CullFaceNone, CullFaceBack, CullFaceFront, MultiplyBlending, SubtractiveBlending, AdditiveBlending, NotEqualDepth, GreaterDepth, GreaterEqualDepth, LessEqualDepth, LessDepth, AlwaysDepth, NeverDepth, ReversedDepthFuncs, RGB_S3TC_DXT1_Format, RGBA_S3TC_DXT1_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT5_Format, RGB_PVRTC_4BPPV1_Format, RGB_PVRTC_2BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGBA_PVRTC_2BPPV1_Format, RGB_ETC1_Format, RGB_ETC2_Format, RGBA_ETC2_EAC_Format, R11_EAC_Format, SIGNED_R11_EAC_Format, SIGNED_RG11_EAC_Format, RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_10x10_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGBA_BPTC_Format, RGB_BPTC_SIGNED_Format, RGB_BPTC_UNSIGNED_Format, RED_RGTC1_Format, SIGNED_RED_RGTC1_Format, SIGNED_RED_GREEN_RGTC2_Format, MirroredRepeatWrapping, RepeatWrapping, NearestMipmapNearestFilter, NotEqualCompare, EqualCompare, AlwaysCompare, NeverCompare, LinearTransfer, getByteLength, isTypedArray, NotEqualStencilFunc, GreaterStencilFunc, GreaterEqualStencilFunc, EqualStencilFunc, LessEqualStencilFunc, LessStencilFunc, AlwaysStencilFunc, NeverStencilFunc, DecrementWrapStencilOp, IncrementWrapStencilOp, DecrementStencilOp, IncrementStencilOp, InvertStencilOp, ReplaceStencilOp, ZeroStencilOp, KeepStencilOp, SpotLight, PointLight, DirectionalLight, RectAreaLight, AmbientLight, HemisphereLight, LightProbe, LinearToneMapping, ReinhardToneMapping, CineonToneMapping, ACESFilmicToneMapping, AgXToneMapping, NeutralToneMapping, Group, Loader, FileLoader, MaterialLoader, ObjectLoader } from './three.core.js';
7
7
  export { AdditiveAnimationBlendMode, AnimationAction, AnimationClip, AnimationLoader, AnimationMixer, AnimationObjectGroup, AnimationUtils, ArcCurve, ArrowHelper, AttachedBindMode, Audio, AudioAnalyser, AudioContext, AudioListener, AudioLoader, AxesHelper, BasicDepthPacking, BatchedMesh, BezierInterpolant, Bone, BooleanKeyframeTrack, Box2, Box3, Box3Helper, BoxHelper, BufferGeometryLoader, Cache, Camera, CameraHelper, CanvasTexture, CapsuleGeometry, CatmullRomCurve3, CircleGeometry, Clock, ColorKeyframeTrack, CompressedArrayTexture, CompressedCubeTexture, CompressedTexture, CompressedTextureLoader, ConeGeometry, Controls, CubeTextureLoader, CubicBezierCurve, CubicBezierCurve3, CubicInterpolant, CullFaceFrontBack, Curve, CurvePath, CustomToneMapping, Cylindrical, DataTextureLoader, DataUtils, DefaultLoadingManager, DetachedBindMode, DirectionalLightHelper, DiscreteInterpolant, DodecahedronGeometry, DynamicCopyUsage, DynamicReadUsage, EdgesGeometry, EllipseCurve, Euler, ExternalTexture, ExtrudeGeometry, Fog, FogExp2, GLBufferAttribute, GLSL1, GLSL3, GridHelper, HTMLTexture, HemisphereLightHelper, IcosahedronGeometry, ImageBitmapLoader, ImageLoader, ImageUtils, InstancedBufferGeometry, InstancedMesh, Int16BufferAttribute, Int32BufferAttribute, Int8BufferAttribute, Interpolant, InterpolateBezier, InterpolateDiscrete, InterpolateLinear, InterpolateSmooth, InterpolationSamplingMode, InterpolationSamplingType, KeyframeTrack, LOD, LatheGeometry, Layers, Light, LightShadow, Line, Line3, LineCurve, LineCurve3, LineLoop, LineSegments, LinearInterpolant, LinearMipMapNearestFilter, LoaderUtils, LoadingManager, LoopOnce, LoopPingPong, LoopRepeat, MOUSE, MeshDepthMaterial, MeshDistanceMaterial, NearestMipMapLinearFilter, NearestMipMapNearestFilter, NodePath, NormalAnimationBlendMode, NumberKeyframeTrack, OctahedronGeometry, Path, PlaneHelper, PointLightHelper, Points, PolarGridHelper, PolyhedronGeometry, PositionalAudio, PropertyBinding, PropertyMixer, QuadraticBezierCurve, QuadraticBezierCurve3, QuaternionKeyframeTrack, QuaternionLinearInterpolant, RGBADepthPacking, RGBDepthPacking, RGDepthPacking, RawShaderMaterial, Ray, Raycaster, RenderTarget3D, RingGeometry, ShaderMaterial, Shape, ShapeGeometry, ShapePath, ShapeUtils, Skeleton, SkeletonHelper, SkinnedMesh, Source, Spherical, SphericalHarmonics3, SplineCurve, SpotLightHelper, Sprite, StaticCopyUsage, StaticReadUsage, StereoCamera, StreamCopyUsage, StreamDrawUsage, StreamReadUsage, StringKeyframeTrack, TOUCH, TetrahedronGeometry, TextureLoader, TextureSource, TextureUtils, Timer, TorusGeometry, TorusKnotGeometry, Triangle, TriangleFanDrawMode, TriangleStripDrawMode, TrianglesDrawMode, TubeGeometry, Uint8BufferAttribute, Uint8ClampedBufferAttribute, Uniform, UniformsGroup, VectorKeyframeTrack, VideoFrameTexture, VideoTexture, WebGL3DRenderTarget, WebGLArrayRenderTarget, WebGLRenderTarget, WireframeGeometry, WrapAroundEnding, XorShift32, ZeroCurvatureEnding, ZeroSlopeEnding, allocateNodeId, collectSiblingNodeIds, configureNodeIdSeed, ensureUniqueNodeIdAmongParentChildren, generateNodeId, getConsoleFunction, hashStringToUint32, isValidNodeId, nodeIdFromKey, nodeIdFromString, nodeIdToString, profile, profileClass, randomSeedUint32, setConsoleFunction, xorshift32 } from './three.core.js';
8
8
 
9
9
  const refreshUniforms = [
@@ -21768,7 +21768,8 @@ function bufferVisualizationOutput( buffer ) {
21768
21768
  const DEBUG_VIEW_NONE = 'none';
21769
21769
 
21770
21770
  /**
21771
- * Material-cost heatmap. Overlapping draws accumulate, then a fullscreen pass applies the ramp.
21771
+ * Material-cost heatmap. The nearest opaque surface wins, translucent draws add on top,
21772
+ * then a fullscreen pass applies the ramp.
21772
21773
  *
21773
21774
  * @type {string}
21774
21775
  */
@@ -21787,16 +21788,16 @@ const DEBUG_VIEW_LIGHTING_COMPLEXITY = 'lightingComplexity';
21787
21788
  *
21788
21789
  * @type {string}
21789
21790
  */
21790
- const DEBUG_VIEW_QUAD_OVERDRAW = 'quadOverdraw';
21791
+ const DEBUG_VIEW_OVERDRAW = 'overdraw';
21791
21792
 
21792
21793
  /**
21793
21794
  * Shader cost multiplied by the number of fragments that shaded the pixel, then the shader-complexity ramp.
21794
- * One opaque surface matches {@link DEBUG_VIEW_SHADER_COMPLEXITY}. Each extra overlapping fragment scales the summed cost.
21795
+ * One opaque surface matches {@link DEBUG_VIEW_SHADER_COMPLEXITY}. Each extra translucent fragment scales the summed cost.
21795
21796
  * WebGPU cannot count wasted lanes in a 2×2 quad, so the count is fragments that pass the depth test.
21796
21797
  *
21797
21798
  * @type {string}
21798
21799
  */
21799
- const DEBUG_VIEW_SHADER_COMPLEXITY_AND_QUADS = 'shaderComplexityAndQuads';
21800
+ const DEBUG_VIEW_SHADER_COMPLEXITY_AND_OVERDRAW = 'shaderComplexityAndOverdraw';
21800
21801
 
21801
21802
  /**
21802
21803
  * Proxy budget that fills the shader-complexity ramp.
@@ -21816,7 +21817,7 @@ const DEFAULT_SHADER_COMPLEXITY_BUDGET = 800;
21816
21817
  const DEFAULT_QUAD_OVERDRAW_BUDGET = 10;
21817
21818
 
21818
21819
  /**
21819
- * Storage scale for the overdraw count in {@link DEBUG_VIEW_SHADER_COMPLEXITY_AND_QUADS}.
21820
+ * Storage scale for the overdraw count in {@link DEBUG_VIEW_SHADER_COMPLEXITY_AND_OVERDRAW}.
21820
21821
  * Each fragment adds `1 / scale`, so an 8-bit target can hold this many layers.
21821
21822
  * The output pass multiplies that channel back to a count. Half-float targets hold the same count exactly.
21822
21823
  *
@@ -21974,7 +21975,7 @@ const colorizeQuadOverdraw = ( cost ) => {
21974
21975
  */
21975
21976
  function debugViewAccumulates( view ) {
21976
21977
 
21977
- return view === DEBUG_VIEW_SHADER_COMPLEXITY || view === DEBUG_VIEW_QUAD_OVERDRAW || view === DEBUG_VIEW_SHADER_COMPLEXITY_AND_QUADS;
21978
+ return view === DEBUG_VIEW_SHADER_COMPLEXITY || view === DEBUG_VIEW_OVERDRAW || view === DEBUG_VIEW_SHADER_COMPLEXITY_AND_OVERDRAW;
21978
21979
 
21979
21980
  }
21980
21981
 
@@ -21997,6 +21998,22 @@ function debugDrawAccumulates( renderer, material, object ) {
21997
21998
 
21998
21999
  }
21999
22000
 
22001
+ /**
22002
+ * Whether an accumulating draw replaces the stored cost instead of adding to it.
22003
+ * Three.js has no depth pre-pass, so adding every opaque fragment counts hidden surfaces
22004
+ * and changes as the camera reorders draws. Replacing, with the material's own depth test
22005
+ * and depth write, leaves the nearest opaque surface. Translucent draws and quad overdraw still add.
22006
+ *
22007
+ * @param {string} view - `renderer.debug.view`.
22008
+ * @param {Material} material - The material being drawn.
22009
+ * @return {boolean} `true` when the draw replaces the stored cost.
22010
+ */
22011
+ function debugDrawReplacesCost( view, material ) {
22012
+
22013
+ return ( view === DEBUG_VIEW_SHADER_COMPLEXITY || view === DEBUG_VIEW_SHADER_COMPLEXITY_AND_OVERDRAW ) && material.transparent !== true;
22014
+
22015
+ }
22016
+
22000
22017
  /**
22001
22018
  * Views that output data or a heatmap, so tone mapping would distort them.
22002
22019
  *
@@ -22128,7 +22145,7 @@ function shaderComplexityOutput( resultNode ) {
22128
22145
  * @param {Node} resultNode - The material's shaded output.
22129
22146
  * @return {Node<vec4>} Cost ratio in red, one scaled fragment in green.
22130
22147
  */
22131
- function shaderComplexityAndQuadsOutput( resultNode ) {
22148
+ function shaderComplexityAndOverdrawOutput( resultNode ) {
22132
22149
 
22133
22150
  const shaded = vec4( resultNode ).toVar();
22134
22151
  const ratio = new ShaderComplexityRatioNode();
@@ -22966,6 +22983,303 @@ function applyDrawCallDebug( builder, material ) {
22966
22983
 
22967
22984
  }
22968
22985
 
22986
+ // WITH_GENESYS
22987
+ // Front/back face. Both windings are drawn. The side facing the camera uses one color, the other side another.
22988
+ // !WITH_GENESYS
22989
+
22990
+
22991
+ /**
22992
+ * Front/back face. Culling is off. A fragment whose winding faces the camera is one color.
22993
+ * The opposite winding is another. Depth still hides a face behind the shell.
22994
+ *
22995
+ * @type {string}
22996
+ */
22997
+ const DEBUG_VIEW_FRONT_BACK_FACE = 'frontBackFace';
22998
+
22999
+ /**
23000
+ * Rasterizer front face, ignoring the material side shortcut in {@link frontFacing}.
23001
+ * `BackSide` materials otherwise report every fragment as back facing.
23002
+ */
23003
+ let GeometricFrontFacingNode$1 = class GeometricFrontFacingNode extends Node {
23004
+
23005
+ static get type() {
23006
+
23007
+ return 'GeometricFrontFacingNode';
23008
+
23009
+ }
23010
+
23011
+ constructor() {
23012
+
23013
+ super( 'bool' );
23014
+
23015
+ }
23016
+
23017
+ generate( builder ) {
23018
+
23019
+ if ( builder.shaderStage !== 'fragment' ) return 'true';
23020
+
23021
+ return builder.getFrontFacing();
23022
+
23023
+ }
23024
+
23025
+ };
23026
+
23027
+ const geometricFrontFacing$1 = /*@__PURE__*/ nodeImmutable( GeometricFrontFacingNode$1 );
23028
+
23029
+ const FRONT_COLOR$1 = /*@__PURE__*/ vec3( 0.72, 0.70, 0.66 );
23030
+ const BACK_COLOR$1 = /*@__PURE__*/ vec3( 0.25, 0.45, 0.85 );
23031
+
23032
+ /**
23033
+ * Replaces albedo with the front or back color after the material has written its channels.
23034
+ * Lit materials become a matte dielectric. Unlit materials become flat.
23035
+ *
23036
+ * @param {NodeBuilder} builder - The current node builder.
23037
+ * @param {NodeMaterial} material - The node material being set up.
23038
+ */
23039
+ function applyFrontBackFaceDebug( builder, material ) {
23040
+
23041
+ const colorNode = select( geometricFrontFacing$1, FRONT_COLOR$1, BACK_COLOR$1 );
23042
+
23043
+ diffuseColor.rgb.assign( colorNode );
23044
+
23045
+ if ( material.lights !== true ) return;
23046
+
23047
+ metalness.assign( float( 0 ) );
23048
+ diffuseContribution.assign( colorNode );
23049
+ roughness.assign( float( 1 ) );
23050
+ specularColor.assign( vec3( 0 ) );
23051
+ specularColorBlended.assign( vec3( 0 ) );
23052
+ specularF90.assign( float( 0 ) );
23053
+
23054
+ builder.context.ambientOcclusion = null;
23055
+
23056
+ if ( material.useClearcoat === true ) clearcoat.assign( float( 0 ) );
23057
+
23058
+ if ( material.useSheen === true ) sheen.assign( vec3( 0 ) );
23059
+
23060
+ if ( material.useIridescence === true ) iridescence.assign( float( 0 ) );
23061
+
23062
+ if ( material.useAnisotropy === true ) anisotropy.assign( float( 0 ) );
23063
+
23064
+ if ( material.useTransmission === true ) transmission.assign( float( 0 ) );
23065
+
23066
+ if ( material.useRetroreflection === true ) retroreflectivity.assign( float( 0 ) );
23067
+
23068
+ }
23069
+
23070
+ // WITH_GENESYS
23071
+ // Shadow casters. Green when the object casts a shadow, gray when it does not.
23072
+ // !WITH_GENESYS
23073
+
23074
+
23075
+ /**
23076
+ * Shadow casters. A mesh that casts shadows is green. One that does not is gray.
23077
+ * The color is lit, so form stays readable.
23078
+ *
23079
+ * Matches Unreal's simplified shadow-caster view (`GetCachedShadowCasterColorSimplified`):
23080
+ * green `(0, 1, 0)` casts, gray `(0.5, 0.5, 0.5)` does not. Contact-shadow yellow is omitted;
23081
+ * Three.js has no per-object contact-shadow flag.
23082
+ *
23083
+ * @type {string}
23084
+ */
23085
+ const DEBUG_VIEW_SHADOW_CASTER = 'shadowCaster';
23086
+
23087
+ const CASTS_COLOR = new Color( 0, 1, 0 );
23088
+ const NONE_COLOR = new Color( 0.5, 0.5, 0.5 );
23089
+
23090
+ /**
23091
+ * Replaces albedo with the caster color after the material has written its channels.
23092
+ * Lit materials become a matte dielectric. Unlit materials become flat.
23093
+ * The color is an object uniform, so meshes that share a material still differ.
23094
+ *
23095
+ * @param {NodeBuilder} builder - The current node builder.
23096
+ * @param {NodeMaterial} material - The node material being set up. `builder.material` can be the
23097
+ * source material of a converted one, such as a glTF `MeshStandardMaterial`.
23098
+ */
23099
+ function applyShadowCasterDebug( builder, material ) {
23100
+
23101
+ const colorNode = uniform( new Color() ).onObjectUpdate( ( { object }, self ) => {
23102
+
23103
+ if ( object === null ) return;
23104
+
23105
+ return self.value.copy( object.castShadow === true ? CASTS_COLOR : NONE_COLOR );
23106
+
23107
+ } );
23108
+
23109
+ diffuseColor.rgb.assign( colorNode );
23110
+
23111
+ if ( material.lights !== true ) return;
23112
+
23113
+ metalness.assign( float( 0 ) );
23114
+ diffuseContribution.assign( colorNode );
23115
+ roughness.assign( float( 1 ) );
23116
+ specularColor.assign( vec3( 0 ) );
23117
+ specularColorBlended.assign( vec3( 0 ) );
23118
+ specularF90.assign( float( 0 ) );
23119
+
23120
+ builder.context.ambientOcclusion = null;
23121
+
23122
+ if ( material.useClearcoat === true ) clearcoat.assign( float( 0 ) );
23123
+
23124
+ if ( material.useSheen === true ) sheen.assign( vec3( 0 ) );
23125
+
23126
+ if ( material.useIridescence === true ) iridescence.assign( float( 0 ) );
23127
+
23128
+ if ( material.useAnisotropy === true ) anisotropy.assign( float( 0 ) );
23129
+
23130
+ if ( material.useTransmission === true ) transmission.assign( float( 0 ) );
23131
+
23132
+ if ( material.useRetroreflection === true ) retroreflectivity.assign( float( 0 ) );
23133
+
23134
+ }
23135
+
23136
+ // WITH_GENESYS
23137
+ // Double sided. Gray is a single-sided surface or the front of a double-sided one.
23138
+ // Blue is a double-sided back face you can see. Red is a double-sided back face hidden behind the front.
23139
+ // !WITH_GENESYS
23140
+
23141
+
23142
+ /**
23143
+ * Double sided. A single-sided material is gray. A double-sided front face is gray.
23144
+ * A double-sided back face that is the nearest surface is blue. A later pass paints
23145
+ * a hidden double-sided back face red over the front.
23146
+ *
23147
+ * @type {string}
23148
+ */
23149
+ const DEBUG_VIEW_DOUBLE_SIDE = 'doubleSide';
23150
+
23151
+ /**
23152
+ * Rasterizer front face, ignoring the material side shortcut in {@link frontFacing}.
23153
+ */
23154
+ class GeometricFrontFacingNode extends Node {
23155
+
23156
+ static get type() {
23157
+
23158
+ return 'GeometricFrontFacingNode';
23159
+
23160
+ }
23161
+
23162
+ constructor() {
23163
+
23164
+ super( 'bool' );
23165
+
23166
+ }
23167
+
23168
+ generate( builder ) {
23169
+
23170
+ if ( builder.shaderStage !== 'fragment' ) return 'true';
23171
+
23172
+ return builder.getFrontFacing();
23173
+
23174
+ }
23175
+
23176
+ }
23177
+
23178
+ const geometricFrontFacing = /*@__PURE__*/ nodeImmutable( GeometricFrontFacingNode );
23179
+
23180
+ const hideCache = new WeakMap();
23181
+
23182
+ /**
23183
+ * A flat card or wall has normals that all point the same way, so its back face is the same
23184
+ * surface. A box or a closed shell has normals that face each other, so one side can hide the other.
23185
+ *
23186
+ * @param {BufferGeometry} geometry - The mesh geometry.
23187
+ * @return {boolean} `true` when some normals oppose the first one.
23188
+ */
23189
+ function meshCanHideOwnBack( geometry ) {
23190
+
23191
+ const normal = geometry.getAttribute( 'normal' );
23192
+ const cached = hideCache.get( geometry );
23193
+
23194
+ if ( cached !== undefined && cached.version === geometry.version ) return cached.hides;
23195
+
23196
+ let hides = false;
23197
+
23198
+ if ( normal !== undefined && normal.count > 1 ) {
23199
+
23200
+ const ax = normal.getX( 0 );
23201
+ const ay = normal.getY( 0 );
23202
+ const az = normal.getZ( 0 );
23203
+ const step = Math.max( 1, Math.floor( normal.count / 64 ) );
23204
+
23205
+ for ( let i = step; i < normal.count; i += step ) {
23206
+
23207
+ if ( ax * normal.getX( i ) + ay * normal.getY( i ) + az * normal.getZ( i ) < 0.25 ) {
23208
+
23209
+ hides = true;
23210
+ break;
23211
+
23212
+ }
23213
+
23214
+ }
23215
+
23216
+ }
23217
+
23218
+ hideCache.set( geometry, { version: geometry.version, hides } );
23219
+
23220
+ return hides;
23221
+
23222
+ }
23223
+
23224
+ const FRONT_COLOR = /*@__PURE__*/ vec3( 0.5, 0.5, 0.5 );
23225
+ const BACK_COLOR = /*@__PURE__*/ vec3( 0.25, 0.45, 0.85 );
23226
+ const HIDDEN_COLOR = /*@__PURE__*/ vec3( 0.85, 0.12, 0.1 );
23227
+
23228
+ /**
23229
+ * Makes a lit material a matte dielectric in the debug color. An unlit material stays flat.
23230
+ *
23231
+ * @param {NodeBuilder} builder - The current node builder.
23232
+ * @param {NodeMaterial} material - The node material being set up.
23233
+ * @param {Node} colorNode - The albedo written for this fragment.
23234
+ */
23235
+ function assignLitColor( builder, material, colorNode ) {
23236
+
23237
+ diffuseColor.rgb.assign( colorNode );
23238
+
23239
+ if ( material.lights !== true ) return;
23240
+
23241
+ metalness.assign( float( 0 ) );
23242
+ diffuseContribution.assign( colorNode );
23243
+ roughness.assign( float( 1 ) );
23244
+ specularColor.assign( vec3( 0 ) );
23245
+ specularColorBlended.assign( vec3( 0 ) );
23246
+ specularF90.assign( float( 0 ) );
23247
+
23248
+ builder.context.ambientOcclusion = null;
23249
+
23250
+ if ( material.useClearcoat === true ) clearcoat.assign( float( 0 ) );
23251
+
23252
+ if ( material.useSheen === true ) sheen.assign( vec3( 0 ) );
23253
+
23254
+ if ( material.useIridescence === true ) iridescence.assign( float( 0 ) );
23255
+
23256
+ if ( material.useAnisotropy === true ) anisotropy.assign( float( 0 ) );
23257
+
23258
+ if ( material.useTransmission === true ) transmission.assign( float( 0 ) );
23259
+
23260
+ if ( material.useRetroreflection === true ) retroreflectivity.assign( float( 0 ) );
23261
+
23262
+ }
23263
+
23264
+ /**
23265
+ * Replaces albedo after the material has written its channels.
23266
+ * The hidden pass forces red. The first pass uses gray, or blue on a visible double-sided back face.
23267
+ *
23268
+ * @param {NodeBuilder} builder - The current node builder.
23269
+ * @param {NodeMaterial} material - The node material being set up. `builder.material` can be the
23270
+ * source material of a converted one, such as a glTF `MeshStandardMaterial`.
23271
+ */
23272
+ function applyDoubleSideDebug( builder, material ) {
23273
+
23274
+ const hidden = builder.renderer.debug.doubleSideHidden === true;
23275
+ const visibleBack = builder.renderer.debug.doubleSideBack === true;
23276
+ const doubleSided = material.side === DoubleSide;
23277
+ const colorNode = hidden ? HIDDEN_COLOR : ( visibleBack ? BACK_COLOR : ( doubleSided ? select( geometricFrontFacing, FRONT_COLOR, BACK_COLOR ) : FRONT_COLOR ) );
23278
+
23279
+ assignLitColor( builder, material, colorNode );
23280
+
23281
+ }
23282
+
22969
23283
  /**
22970
23284
  * Replaces the color a material writes with a debug output. With MRT, only the `output`
22971
23285
  * attachment is replaced so the other attachments keep their members. Converting the
@@ -23508,6 +23822,18 @@ class NodeMaterial extends Material {
23508
23822
 
23509
23823
  applyDrawCallDebug( builder, this );
23510
23824
 
23825
+ } else if ( renderer.debug.view === DEBUG_VIEW_FRONT_BACK_FACE && this.isShadowPassMaterial !== true ) {
23826
+
23827
+ applyFrontBackFaceDebug( builder, this );
23828
+
23829
+ } else if ( renderer.debug.view === DEBUG_VIEW_SHADOW_CASTER && this.isShadowPassMaterial !== true ) {
23830
+
23831
+ applyShadowCasterDebug( builder, this );
23832
+
23833
+ } else if ( renderer.debug.view === DEBUG_VIEW_DOUBLE_SIDE && this.isShadowPassMaterial !== true ) {
23834
+
23835
+ applyDoubleSideDebug( builder, this );
23836
+
23511
23837
  }
23512
23838
  // !WITH_GENESYS
23513
23839
 
@@ -23591,10 +23917,10 @@ class NodeMaterial extends Material {
23591
23917
  builder.shaderComplexityBase = this.getShaderComplexity();
23592
23918
  resultNode = replaceColorOutput( resultNode, shaderComplexityOutput );
23593
23919
 
23594
- } else if ( renderer.debug.view === DEBUG_VIEW_SHADER_COMPLEXITY_AND_QUADS ) {
23920
+ } else if ( renderer.debug.view === DEBUG_VIEW_SHADER_COMPLEXITY_AND_OVERDRAW ) {
23595
23921
 
23596
23922
  builder.shaderComplexityBase = this.getShaderComplexity();
23597
- resultNode = replaceColorOutput( resultNode, shaderComplexityAndQuadsOutput );
23923
+ resultNode = replaceColorOutput( resultNode, shaderComplexityAndOverdrawOutput );
23598
23924
 
23599
23925
  } else {
23600
23926
 
@@ -23966,7 +24292,7 @@ class NodeMaterial extends Material {
23966
24292
  setupNormal( builder ) {
23967
24293
 
23968
24294
  // WITH_GENESYS
23969
- if ( ( builder.renderer.debug.view === DEBUG_VIEW_LIGHTING_ONLY || builder.renderer.debug.view === DEBUG_VIEW_DRAW_CALL ) && this.isShadowPassMaterial !== true && this.fragmentNode === null ) {
24295
+ if ( ( builder.renderer.debug.view === DEBUG_VIEW_LIGHTING_ONLY || builder.renderer.debug.view === DEBUG_VIEW_DRAW_CALL || builder.renderer.debug.view === DEBUG_VIEW_FRONT_BACK_FACE || builder.renderer.debug.view === DEBUG_VIEW_SHADOW_CASTER || builder.renderer.debug.view === DEBUG_VIEW_DOUBLE_SIDE ) && this.isShadowPassMaterial !== true && this.fragmentNode === null ) {
23970
24296
 
23971
24297
  return lightingOnlyNormal();
23972
24298
 
@@ -24171,7 +24497,7 @@ class NodeMaterial extends Material {
24171
24497
  // WITH_GENESYS
24172
24498
  // Lighting only and draw call substitute a plain lit material, so emissive is dropped.
24173
24499
  // Detail lighting keeps it.
24174
- if ( ( builder.renderer.debug.view === DEBUG_VIEW_LIGHTING_ONLY || builder.renderer.debug.view === DEBUG_VIEW_DRAW_CALL ) && this.isShadowPassMaterial !== true ) {
24500
+ if ( ( builder.renderer.debug.view === DEBUG_VIEW_LIGHTING_ONLY || builder.renderer.debug.view === DEBUG_VIEW_DRAW_CALL || builder.renderer.debug.view === DEBUG_VIEW_FRONT_BACK_FACE || builder.renderer.debug.view === DEBUG_VIEW_SHADOW_CASTER || builder.renderer.debug.view === DEBUG_VIEW_DOUBLE_SIDE ) && this.isShadowPassMaterial !== true ) {
24175
24501
 
24176
24502
  return outgoingLightNode;
24177
24503
 
@@ -33082,7 +33408,7 @@ class RenderObject {
33082
33408
 
33083
33409
  // WITH_GENESYS
33084
33410
  // hash() xors each argument as a number, so a view name has to be hashed first.
33085
- cacheKey = hash$1( cacheKey, hashString( this.renderer.debug.view ), hashString( this.renderer.debug.buffer ), this.renderer.debug.shaderComplexityBudget, this.renderer.debug.quadOverdrawBudget );
33411
+ cacheKey = hash$1( cacheKey, hashString( this.renderer.debug.view ), hashString( this.renderer.debug.buffer ), this.renderer.debug.shaderComplexityBudget, this.renderer.debug.quadOverdrawBudget, this.renderer.debug.doubleSideHidden === true ? 1 : 0, this.renderer.debug.doubleSideBack === true ? 1 : 0 );
33086
33412
  // !WITH_GENESYS
33087
33413
 
33088
33414
  return cacheKey;
@@ -53194,9 +53520,11 @@ class Background extends DataMap {
53194
53520
  //
53195
53521
 
53196
53522
  // WITH_GENESYS
53523
+ // Accumulating views start from zero cost. Alpha keeps the shaded pass coverage, so an
53524
+ // overlay pass such as a HUD stays transparent where it draws nothing when composited.
53197
53525
  if ( debugViewAccumulates( renderer.debug.view ) ) {
53198
53526
 
53199
- _clearColor.set( 0, 0, 0, 1 );
53527
+ _clearColor.set( 0, 0, 0, background !== null ? 1 : _clearColor.a );
53200
53528
 
53201
53529
  }
53202
53530
  // !WITH_GENESYS
@@ -60484,9 +60812,9 @@ class NodeManager extends DataMap {
60484
60812
  }
60485
60813
 
60486
60814
  // WITH_GENESYS
60487
- if ( renderer.debug.view === DEBUG_VIEW_SHADER_COMPLEXITY || renderer.debug.view === DEBUG_VIEW_SHADER_COMPLEXITY_AND_QUADS ) {
60815
+ if ( renderer.debug.view === DEBUG_VIEW_SHADER_COMPLEXITY || renderer.debug.view === DEBUG_VIEW_SHADER_COMPLEXITY_AND_OVERDRAW ) {
60488
60816
 
60489
- const complexity = renderer.debug.view === DEBUG_VIEW_SHADER_COMPLEXITY_AND_QUADS
60817
+ const complexity = renderer.debug.view === DEBUG_VIEW_SHADER_COMPLEXITY_AND_OVERDRAW
60490
60818
  ? sampled.r.mul( sampled.g ).mul( SHADER_COMPLEXITY_QUAD_COUNT_SCALE )
60491
60819
  : sampled.r;
60492
60820
 
@@ -60494,7 +60822,7 @@ class NodeManager extends DataMap {
60494
60822
 
60495
60823
  }
60496
60824
 
60497
- if ( renderer.debug.view === DEBUG_VIEW_QUAD_OVERDRAW ) {
60825
+ if ( renderer.debug.view === DEBUG_VIEW_OVERDRAW ) {
60498
60826
 
60499
60827
  return vec4( colorizeQuadOverdraw( sampled.r ), 1 ).renderOutput( NoToneMapping, renderer.currentColorSpace );
60500
60828
 
@@ -64459,7 +64787,7 @@ class Renderer {
64459
64787
  * @property {?Function} onNodeBuilderCreated - A callback function that is executed after a node builder has been created and before it is built.
64460
64788
  * @property {?Function} onShaderError - A callback function that is executed when a shader error happens. Only supported with WebGL 2 right now.
64461
64789
  * @property {Function} getShaderAsync - Allows the get the raw shader code for the given scene, camera and 3D object.
64462
- * @property {string} view - Debug view. `shaderComplexity`, `lightingComplexity`, `quadOverdraw`, and `shaderComplexityAndQuads` replace the shaded color with a heatmap. `shaderComplexityAndQuads` multiplies the shader cost by the overdraw count. `bufferVisualization` shows one material channel. `lightingOnly` and `detailLighting` light a flat gray surface. `drawCall` lights each submitted draw with its own diffuse color.
64790
+ * @property {string} view - Debug view. `shaderComplexity`, `lightingComplexity`, `overdraw`, and `shaderComplexityAndOverdraw` replace the shaded color with a heatmap. `shaderComplexityAndOverdraw` multiplies the shader cost by the overdraw count. `bufferVisualization` shows one material channel. `lightingOnly` and `detailLighting` light a flat gray surface. `drawCall` lights each submitted draw with its own diffuse color. `frontBackFace` draws both windings and tints the side facing the camera. `shadowCaster` lights a mesh green when it casts shadows and gray when it does not. `doubleSide` lights a single-sided surface gray, a visible double-sided back face blue, and a hidden double-sided back face red.
64463
64791
  * @property {string} buffer - Channel drawn by `bufferVisualization`: `baseColor`, `worldNormal`, `roughness`, `metallic`, `ambientOcclusion`, or `emissive`.
64464
64792
  * @property {number} shaderComplexityBudget - Proxy budget that fills the shader-complexity ramp.
64465
64793
  * @property {number} quadOverdrawBudget - Overlapping fragments that fill the quad-overdraw ramp.
@@ -64482,6 +64810,8 @@ class Renderer {
64482
64810
  buffer: DEFAULT_BUFFER,
64483
64811
  shaderComplexityBudget: DEFAULT_SHADER_COMPLEXITY_BUDGET,
64484
64812
  quadOverdrawBudget: DEFAULT_QUAD_OVERDRAW_BUDGET,
64813
+ doubleSideHidden: false,
64814
+ doubleSideBack: false,
64485
64815
  // !WITH_GENESYS
64486
64816
  getShaderAsync: async ( scene, camera, object ) => {
64487
64817
 
@@ -65702,6 +66032,10 @@ class Renderer {
65702
66032
  if ( this.opaque === true && opaqueObjects.length > 0 ) this._renderObjects( opaqueObjects, camera, sceneRef, lightsNode );
65703
66033
  if ( this.transparent === true && transparentObjects.length > 0 ) this._renderTransparents( transparentObjects, transparentDoublePassObjects, camera, sceneRef, lightsNode );
65704
66034
 
66035
+ // WITH_GENESYS
66036
+ this._renderDoubleSideHidden( opaqueObjects, transparentObjects, camera, sceneRef, lightsNode );
66037
+ // !WITH_GENESYS
66038
+
65705
66039
  // finish render pass
65706
66040
 
65707
66041
  this.backend.finishRender( renderContext );
@@ -67272,6 +67606,82 @@ class Renderer {
67272
67606
 
67273
67607
  }
67274
67608
 
67609
+ // WITH_GENESYS
67610
+ /**
67611
+ * Paints a double-sided mesh red where its own front face is the nearest surface and the
67612
+ * mesh has faces pointing the other way. A different mesh in front keeps its own color.
67613
+ * A flat card has no opposing faces, so it stays gray or blue. A shadow pass is left alone.
67614
+ *
67615
+ * @private
67616
+ * @param {Array<Object>} opaqueObjects - The opaque render list.
67617
+ * @param {Array<Object>} transparentObjects - The transparent render list.
67618
+ * @param {Camera} camera - The camera.
67619
+ * @param {Scene} scene - The scene.
67620
+ * @param {LightsNode} lightsNode - The current lights node.
67621
+ */
67622
+ _renderDoubleSideHidden( opaqueObjects, transparentObjects, camera, scene, lightsNode ) {
67623
+
67624
+ if ( this.debug.view !== DEBUG_VIEW_DOUBLE_SIDE ) return;
67625
+
67626
+ if ( scene.overrideMaterial !== null && scene.overrideMaterial.isShadowPassMaterial === true ) return;
67627
+
67628
+ const list = [];
67629
+ const saved = new Map();
67630
+
67631
+ const collect = ( objects ) => {
67632
+
67633
+ for ( let i = 0, l = objects.length; i < l; i ++ ) {
67634
+
67635
+ const entry = objects[ i ];
67636
+ const material = entry.material;
67637
+ const geometry = entry.object.geometry;
67638
+
67639
+ if ( entry.object.isMesh !== true || material.side !== DoubleSide || material.isShadowPassMaterial === true ) continue;
67640
+
67641
+ if ( geometry === undefined || meshCanHideOwnBack( geometry ) !== true ) continue;
67642
+
67643
+ list.push( entry );
67644
+
67645
+ if ( saved.has( material ) ) continue;
67646
+
67647
+ saved.set( material, {
67648
+ side: material.side,
67649
+ depthFunc: material.depthFunc,
67650
+ depthWrite: material.depthWrite
67651
+ } );
67652
+
67653
+ }
67654
+
67655
+ };
67656
+
67657
+ collect( opaqueObjects );
67658
+ collect( transparentObjects );
67659
+
67660
+ if ( list.length === 0 ) return;
67661
+
67662
+ for ( const material of saved.keys() ) {
67663
+
67664
+ material.side = FrontSide;
67665
+ material.depthFunc = EqualDepth;
67666
+ material.depthWrite = false;
67667
+
67668
+ }
67669
+
67670
+ this.debug.doubleSideHidden = true;
67671
+ this._renderObjects( list, camera, scene, lightsNode, 'doubleSideHidden' );
67672
+ this.debug.doubleSideHidden = false;
67673
+
67674
+ for ( const [ material, state ] of saved ) {
67675
+
67676
+ material.side = state.side;
67677
+ material.depthFunc = state.depthFunc;
67678
+ material.depthWrite = state.depthWrite;
67679
+
67680
+ }
67681
+
67682
+ }
67683
+ // !WITH_GENESYS
67684
+
67275
67685
  /**
67276
67686
  * Renders the transparent objects from the given render lists.
67277
67687
  *
@@ -72553,7 +72963,7 @@ class WebGLState {
72553
72963
 
72554
72964
  }
72555
72965
 
72556
- setMRTBlending( textures, mrt, material ) {
72966
+ setMRTBlending( textures, mrt, material, object = null ) {
72557
72967
 
72558
72968
  const gl = this.gl;
72559
72969
  const drawBuffersIndexedExt = this.backend.drawBuffersIndexedExt;
@@ -72566,6 +72976,24 @@ class WebGLState {
72566
72976
 
72567
72977
  }
72568
72978
 
72979
+ // WITH_GENESYS
72980
+ // Every attachment matches the single-target path. Opaque material blending would replace a sum that should add.
72981
+ if ( debugDrawAccumulates( this.backend.renderer, material, object ) ) {
72982
+
72983
+ const dst = debugDrawReplacesCost( this.backend.renderer.debug.view, material ) ? gl.ZERO : gl.ONE;
72984
+
72985
+ for ( let i = 0; i < textures.length; i ++ ) {
72986
+
72987
+ drawBuffersIndexedExt.blendEquationSeparateiOES( i, gl.FUNC_ADD, gl.FUNC_ADD );
72988
+ drawBuffersIndexedExt.blendFuncSeparateiOES( i, gl.ONE, dst, gl.ONE, gl.ZERO );
72989
+
72990
+ }
72991
+
72992
+ return;
72993
+
72994
+ }
72995
+ // !WITH_GENESYS
72996
+
72569
72997
  for ( let i = 0; i < textures.length; i ++ ) {
72570
72998
 
72571
72999
  const texture = textures[ i ];
@@ -73194,9 +73622,16 @@ class WebGLState {
73194
73622
 
73195
73623
  const { gl } = this;
73196
73624
 
73197
- material.side === DoubleSide
73625
+ // WITH_GENESYS
73626
+ const drawBothSides = material.side === DoubleSide || ( this.backend.renderer.debug.view === DEBUG_VIEW_FRONT_BACK_FACE && material.isShadowPassMaterial !== true );
73627
+
73628
+ drawBothSides
73198
73629
  ? this.disable( gl.CULL_FACE )
73199
73630
  : this.enable( gl.CULL_FACE );
73631
+ // !WITH_GENESYS
73632
+ // material.side === DoubleSide
73633
+ // ? this.disable( gl.CULL_FACE )
73634
+ // : this.enable( gl.CULL_FACE );
73200
73635
 
73201
73636
  let flipSided = ( material.side === BackSide );
73202
73637
  if ( frontFaceCW ) flipSided = ! flipSided;
@@ -73204,10 +73639,13 @@ class WebGLState {
73204
73639
  this.setFlipSided( flipSided );
73205
73640
 
73206
73641
  // WITH_GENESYS
73207
- // WebGL has no cached render pipeline. One+One is applied on each draw instead.
73642
+ // WebGL has no cached render pipeline. The accumulate blend is applied on each draw instead.
73643
+ // Alpha is replaced so it stays coverage, as in a shaded pass, for later compositing.
73208
73644
  if ( debugDrawAccumulates( this.backend.renderer, material, object ) ) {
73209
73645
 
73210
- this.setBlending( AdditiveBlending, AddEquation, OneFactor, OneFactor, AddEquation, OneFactor, OneFactor, material.blendColor, material.blendAlpha, true );
73646
+ const dstFactor = debugDrawReplacesCost( this.backend.renderer.debug.view, material ) ? ZeroFactor : OneFactor;
73647
+
73648
+ this.setBlending( CustomBlending, AddEquation, OneFactor, dstFactor, AddEquation, OneFactor, ZeroFactor, material.blendColor, material.blendAlpha, true );
73211
73649
 
73212
73650
  } else if ( material.blending === NormalBlending && material.transparent === false ) {
73213
73651
 
@@ -77462,7 +77900,10 @@ class WebGLBackend extends Backend {
77462
77900
 
77463
77901
  if ( context.mrt !== null && context.textures !== null ) {
77464
77902
 
77465
- state.setMRTBlending( context.textures, context.mrt, material );
77903
+ // WITH_GENESYS
77904
+ state.setMRTBlending( context.textures, context.mrt, material, object );
77905
+ // !WITH_GENESYS
77906
+ // state.setMRTBlending( context.textures, context.mrt, material );
77466
77907
 
77467
77908
  }
77468
77909
 
@@ -87912,18 +88353,22 @@ class WebGPUPipelineUtils {
87912
88353
  }
87913
88354
 
87914
88355
  // WITH_GENESYS
87915
- // Accumulate shader cost with One+One. Opaque materials normally disable blending.
88356
+ // Quad overdraw and translucent shader complexity add. Opaque shader complexity replaces
88357
+ // the stored cost, so the nearest surface wins without a depth pre-pass.
88358
+ // Alpha is replaced so it stays coverage, as in a shaded pass, for later compositing.
87916
88359
  if ( debugDrawAccumulates( backend.renderer, material, object ) ) {
87917
88360
 
88361
+ const replaceCost = debugDrawReplacesCost( backend.renderer.debug.view, material );
88362
+
87918
88363
  materialBlending = {
87919
88364
  color: {
87920
88365
  srcFactor: GPUBlendFactor.One,
87921
- dstFactor: GPUBlendFactor.One,
88366
+ dstFactor: replaceCost ? GPUBlendFactor.Zero : GPUBlendFactor.One,
87922
88367
  operation: GPUBlendOperation.Add
87923
88368
  },
87924
88369
  alpha: {
87925
88370
  srcFactor: GPUBlendFactor.One,
87926
- dstFactor: GPUBlendFactor.One,
88371
+ dstFactor: GPUBlendFactor.Zero,
87927
88372
  operation: GPUBlendOperation.Add
87928
88373
  }
87929
88374
  };
@@ -88744,7 +89189,12 @@ class WebGPUPipelineUtils {
88744
89189
 
88745
89190
  //
88746
89191
 
88747
- descriptor.cullMode = ( material.side === DoubleSide ) ? GPUCullMode.None : GPUCullMode.Back;
89192
+ // WITH_GENESYS
89193
+ // Front/back face draws both windings. Depth still hides a face behind the shell.
89194
+ const drawBothSides = material.side === DoubleSide || ( this.backend.renderer.debug.view === DEBUG_VIEW_FRONT_BACK_FACE && material.isShadowPassMaterial !== true );
89195
+ descriptor.cullMode = drawBothSides ? GPUCullMode.None : GPUCullMode.Back;
89196
+ // !WITH_GENESYS
89197
+ // descriptor.cullMode = ( material.side === DoubleSide ) ? GPUCullMode.None : GPUCullMode.Back;
88748
89198
 
88749
89199
  return descriptor;
88750
89200