From 96b3469414e8306d376400e495b5e817b5548bae Mon Sep 17 00:00:00 2001 From: Knightro <50028636+Knightro63@users.noreply.github.com> Date: Fri, 23 Jan 2026 16:26:00 -0500 Subject: [PATCH 01/17] removed native array --- .../webgl_geometry_spline_editor.dart | 3 +- .../webgl_interactive_raycasting_points.dart | 9 +-- examples/lib/line/webgl_lines_fat.dart | 5 +- .../lib/line/webgl_lines_fat_raycasting.dart | 9 +-- examples/lib/loaders/webgl_loader_glb.dart | 1 + examples/lib/material/webgl_materials.dart | 3 +- ...webgl_materials_physical_transmission.dart | 3 +- .../modifers/webgl_modifer_tessellation.dart | 5 +- examples/lib/multi_views/multi_views.dart | 3 +- .../lib/multi_views/webgl_multi_views.dart | 3 +- ..._buffergeometry_instancing_billboards.dart | 2 +- .../others/webgl_custom_attributes_lines.dart | 7 +- .../webgl_postprocessing_fxaa.dart | 3 +- examples/lib/rollercoster/rollercoaster.dart | 19 ++--- .../rollercoster/webxr_vr_rollercoaster.dart | 5 +- .../lib/screenshot/opengl_screenshot.dart | 6 +- .../shadow/webgl_shadowmap_pointlight.dart | 3 +- examples/lib/shadow/webgl_simple_gi.dart | 6 +- examples/lib/terrain/three_terrain.dart | 8 +-- .../lib/terrain/webgl_geometry_terrain.dart | 9 +-- .../webgl_geometry_terrain_raycast.dart | 9 +-- .../texture/webgl_materials_video_webcam.dart | 4 +- .../lib/texture/webgl_opengl_texture.dart | 6 +- examples/lib/volume/webgl_volume_cloud.dart | 3 +- examples/lib/volume/webgl_volume_perlin.dart | 3 +- examples/pubspec.yaml | 55 +++++++++++++- .../lib/usdz/image_export_app.dart | 3 +- .../lib/usdz/image_export_web.dart | 5 +- .../lib/dds_loader.dart | 22 +++--- .../lib/gltf/gltf_helper.dart | 15 ++-- .../lib/gltf/gltf_parser.dart | 23 ++++-- .../lib/ktx_loader.dart | 4 +- .../lib/pcd_loader.dart | 4 +- .../lib/rgbe_loader.dart | 6 +- .../lib/tga_loader.dart | 2 +- .../lib/usdz/usdz_loader.dart | 4 +- .../lib/animations/keyframe_track.dart | 10 +-- packages/three_js_bvh_csg/lib/csg/csg.dart | 2 +- packages/three_js_core/CHANGELOG.md | 5 ++ packages/three_js_core/example/lib/main.dart | 8 ++- packages/three_js_core/example/pubspec.yaml | 8 ++- .../three_js_core/lib/core/object_3d.dart | 7 +- packages/three_js_core/lib/core/uniform.dart | 3 +- .../lib/geometries/buffer_geometry.dart | 16 ++--- packages/three_js_core/lib/lights/light.dart | 4 +- .../three_js_core/lib/materials/material.dart | 3 +- .../lib/materials/projected_material.dart | 9 +-- .../lib/materials/shader_material.dart | 7 +- .../lib/objects/batched_mesh.dart | 42 +++-------- .../lib/objects/instanced_mesh.dart | 12 ++-- .../three_js_core/lib/objects/skeleton.dart | 10 +-- .../lib/others/three_viewer.dart | 3 +- .../three_js_core/lib/renderers/index.dart | 2 +- .../lib/renderers/web_gl_renderer.dart | 8 +-- .../lib/renderers/webgl/index.dart | 1 + .../renderers/webgl/web_gl_attributes.dart | 9 ++- .../renderers/webgl/web_gl_geometries.dart | 2 +- .../renderers/webgl/web_gl_morphtargets.dart | 10 +-- .../lib/renderers/webgl/web_gl_state.dart | 18 ++--- .../lib/renderers/webgl/web_gl_textures.dart | 13 ++-- .../webgl/web_gl_uniforms_groups.dart | 2 +- .../webgl/web_gl_uniforms_helper.dart | 10 +-- .../lib/textures/data_3d_texture.dart | 4 +- .../lib/textures/data_array_texture.dart | 2 +- .../lib/textures/data_texture.dart | 7 +- .../lib/textures/flutter_texture.dart | 13 ++-- .../lib/textures/image_element.dart | 12 +--- .../three_js_core/lib/textures/source.dart | 8 ++- packages/three_js_core/pubspec.yaml | 10 ++- .../lib/ImageLoader/image_loader_app.dart | 3 +- packages/three_js_gpu/lib/common/buffer.dart | 10 ++- .../lib/common/render_object.dart | 2 +- .../lib/common/storage_buffer_attribute.dart | 35 ++++----- .../storage_instanced_buffer_attribute.dart | 3 +- packages/three_js_gpu/lib/gpu_backend.dart | 6 +- packages/three_js_line/lib/line_geometry.dart | 6 +- packages/three_js_line/lib/line_material.dart | 8 ++- .../three_js_line/lib/line_segments2.dart | 4 +- .../lib/line_segments_geometry.dart | 5 +- packages/three_js_line/lib/wireframe.dart | 4 +- packages/three_js_math/CHANGELOG.md | 4 ++ .../lib/buffer/base_buffer_attribute.dart | 5 +- .../lib/buffer/buffer_attribute.dart | 72 +++++++++---------- .../lib/buffer/interleaved_buffer.dart | 11 ++- .../buffer/interleaved_buffer_attribute.dart | 7 +- .../three_js_math/lib/math/math_util.dart | 45 +++++++----- .../three_js_math/lib/matrix/matrix2.dart | 54 +++++++------- .../three_js_math/lib/matrix/matrix3.dart | 5 +- .../three_js_math/lib/matrix/matrix4.dart | 24 +++++++ .../three_js_math/lib/others/color_util.dart | 24 +++---- packages/three_js_math/lib/three_js_math.dart | 1 - packages/three_js_math/lib/vector/vector.dart | 7 +- .../three_js_math/lib/vector/vector2.dart | 7 +- .../three_js_math/lib/vector/vector3.dart | 5 +- .../three_js_math/lib/vector/vector4.dart | 5 +- packages/three_js_math/pubspec.yaml | 6 +- .../lib/buffergeometry_utils.dart | 12 ++-- .../lib/edge_split_modifier.dart | 16 +++-- .../lib/loop_subdivision.dart | 2 +- .../lib/simplify_modifer.dart | 2 +- .../lib/gpu_computation_renderer.dart | 4 +- .../light_probe_generator_platform.dart | 7 +- .../lib/lights/light_probe_generator_web.dart | 7 +- .../three_js_objects/lib/marching_cubes.dart | 28 ++++---- .../three_js_objects/lib/tube_painter.dart | 31 ++++---- .../three_js_particles/lib/particles.dart | 3 +- packages/three_js_particles/lib/utils.dart | 4 +- .../lib/post/effect_composer.dart | 2 +- .../lib/post/glitch_pass.dart | 4 +- .../lib/post/smaa_pass.dart | 5 +- .../lib/ply_loader.dart | 5 -- .../lib/vox_loder.dart | 2 +- .../three_js_svg/lib/export/projector.dart | 27 +++---- .../three_js_terrain/example/lib/main.dart | 8 +-- packages/three_js_terrain/lib/core.dart | 8 +-- packages/three_js_terrain/lib/generators.dart | 4 +- .../three_js_text/lib/typrdart/tabs/svg.dart | 2 +- .../lib/buffer_geometry_loader.dart | 19 ++--- .../lib/object_loader.dart | 4 +- .../lib/video_texture_platform.dart | 7 +- three_cad/lib/src/cad/draw_types.dart | 4 +- three_cad/lib/src/cad_old/draw_types.dart | 24 +++---- three_js_editor/lib/ui/line_material.dart | 8 ++- .../lib/rollercoster/rollercoaster.dart | 19 ++--- xr_examples/lib/src/atlas/platform.dart | 5 +- .../lib/vr/webxr_vr_rollercoaster.dart | 11 +-- 126 files changed, 672 insertions(+), 540 deletions(-) diff --git a/examples/lib/geometry/webgl_geometry_spline_editor.dart b/examples/lib/geometry/webgl_geometry_spline_editor.dart index 509c9de9..a601f30e 100644 --- a/examples/lib/geometry/webgl_geometry_spline_editor.dart +++ b/examples/lib/geometry/webgl_geometry_spline_editor.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'dart:math' as math; +import 'dart:typed_data'; import 'package:example/src/gui.dart'; import 'package:flutter/material.dart'; import 'package:example/src/statistics.dart'; @@ -167,7 +168,7 @@ class _State extends State { } final geometry = three.BufferGeometry(); - geometry.setAttributeFromString( 'position', three.Float32BufferAttribute( three.Float32Array( ARC_SEGMENTS * 3 ), 3 ) ); + geometry.setAttributeFromString( 'position', three.Float32BufferAttribute( Float32List( ARC_SEGMENTS * 3 ), 3 ) ); three.CatmullRomCurve3 curve = three.CatmullRomCurve3( points:positions ); three.Line mesh; diff --git a/examples/lib/geometry/webgl_interactive_raycasting_points.dart b/examples/lib/geometry/webgl_interactive_raycasting_points.dart index b9153b6b..17d0dd6a 100644 --- a/examples/lib/geometry/webgl_interactive_raycasting_points.dart +++ b/examples/lib/geometry/webgl_interactive_raycasting_points.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'dart:math' as math; +import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:example/src/statistics.dart'; import 'package:three_js/three_js.dart' as three; @@ -110,8 +111,8 @@ class _State extends State { final geometry = three.BufferGeometry(); final numPoints = (width * length).toInt(); - final positions = three.Float32Array( numPoints * 3 ); - final colors = three.Float32Array( numPoints * 3 ); + final positions = Float32List( numPoints * 3 ); + final colors = Float32List( numPoints * 3 ); int k = 0; @@ -153,7 +154,7 @@ class _State extends State { three.Points generateIndexedPointcloud(three.Color color, int width, int length ) { final geometry = generatePointCloudGeometry( color, width, length ); final numPoints = (width * length).toInt(); - final indices = three.Uint16Array( numPoints ); + final indices = Uint16List( numPoints ); int k = 0; @@ -172,7 +173,7 @@ class _State extends State { three.Points generateIndexedWithOffsetPointcloud(three.Color color, int width, int length ) { final geometry = generatePointCloudGeometry( color, width, length ); final numPoints = (width * length).toInt(); - final indices = three.Uint16Array( numPoints ); + final indices = Uint16List( numPoints ); int k = 0; diff --git a/examples/lib/line/webgl_lines_fat.dart b/examples/lib/line/webgl_lines_fat.dart index 109ba422..f82d98b0 100644 --- a/examples/lib/line/webgl_lines_fat.dart +++ b/examples/lib/line/webgl_lines_fat.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:typed_data'; import 'package:example/src/geometry_utils.dart'; import 'package:example/src/gui.dart'; import 'package:flutter/material.dart'; @@ -106,8 +107,8 @@ class _State extends State { // Line2 ( LineGeometry, LineMaterial ) final geometry = LineGeometry(); - geometry.setPositions(three.Float32Array.fromList(positions)); - geometry.setColors(three.Float32Array.fromList(colors)); + geometry.setPositions(Float32List.fromList(positions)); + geometry.setColors(Float32List.fromList(colors)); matLine = LineMaterial.fromMap( { 'color': 0xffffff, diff --git a/examples/lib/line/webgl_lines_fat_raycasting.dart b/examples/lib/line/webgl_lines_fat_raycasting.dart index 7540331e..7cf68828 100644 --- a/examples/lib/line/webgl_lines_fat_raycasting.dart +++ b/examples/lib/line/webgl_lines_fat_raycasting.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'dart:math' as math; +import 'dart:typed_data'; import 'package:example/src/gui.dart'; import 'package:flutter/material.dart'; import 'package:example/src/statistics.dart'; @@ -147,12 +148,12 @@ class _State extends State { } final lineGeometry = LineGeometry(); - lineGeometry.setPositions(three.Float32Array.fromList(positions)); - lineGeometry.setColors(three.Float32Array.fromList(colors)); + lineGeometry.setPositions(Float32List.fromList(positions)); + lineGeometry.setColors(Float32List.fromList(colors)); final segmentsGeometry = LineSegmentsGeometry(); - segmentsGeometry.setPositions(three.Float32Array.fromList(positions)); - segmentsGeometry.setColors(three.Float32Array.fromList(colors)); + segmentsGeometry.setPositions(Float32List.fromList(positions)); + segmentsGeometry.setColors(Float32List.fromList(colors)); segments = LineSegments2( segmentsGeometry, matLine ); segments.computeLineDistances(); diff --git a/examples/lib/loaders/webgl_loader_glb.dart b/examples/lib/loaders/webgl_loader_glb.dart index d159f13a..1da2aa1c 100644 --- a/examples/lib/loaders/webgl_loader_glb.dart +++ b/examples/lib/loaders/webgl_loader_glb.dart @@ -84,6 +84,7 @@ class _MyAppState extends State { three.GLTFData? result = await loader.fromAsset( 'dash.glb' ); final object = result!.scene; + object.frustumCulled = false; threeJs.scene.add(object); mixer = three.AnimationMixer(object); mixer.clipAction(result.animations![4], null, null)!.play(); diff --git a/examples/lib/material/webgl_materials.dart b/examples/lib/material/webgl_materials.dart index 6b74f725..f7fb68b1 100644 --- a/examples/lib/material/webgl_materials.dart +++ b/examples/lib/material/webgl_materials.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'dart:math' as math; +import 'dart:typed_data'; import 'package:example/src/statistics.dart'; import 'package:flutter/material.dart'; import 'package:three_js/three_js.dart' as three; @@ -144,7 +145,7 @@ class _MyAppState extends State { } three.ImageElement generateTexture() { - final pixels = three.Uint8Array(256 * 256 * 4); + final pixels = Uint8List(256 * 256 * 4); int x = 0, y = 0, l = pixels.length; diff --git a/examples/lib/material/webgl_materials_physical_transmission.dart b/examples/lib/material/webgl_materials_physical_transmission.dart index 7c6c46ca..42bdc44d 100644 --- a/examples/lib/material/webgl_materials_physical_transmission.dart +++ b/examples/lib/material/webgl_materials_physical_transmission.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'dart:math' as math; +import 'dart:typed_data'; import 'package:example/src/gui.dart'; import 'package:flutter/material.dart'; import 'package:example/src/statistics.dart'; @@ -208,7 +209,7 @@ class _State extends State { return three.ImageElement( width: 2, height: 2, - data: three.Uint8Array.fromList([0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255]) + data: Uint8List.fromList([0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255]) ); } } diff --git a/examples/lib/modifers/webgl_modifer_tessellation.dart b/examples/lib/modifers/webgl_modifer_tessellation.dart index 613027ff..4a597ae1 100644 --- a/examples/lib/modifers/webgl_modifer_tessellation.dart +++ b/examples/lib/modifers/webgl_modifer_tessellation.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'dart:math' as math; +import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:example/src/statistics.dart'; import 'package:three_js/three_js.dart' as three; @@ -80,8 +81,8 @@ class _State extends State { final geometry = tessellateModifier.modify( textG ); final numFaces = geometry.attributes['position'].count ~/ 3; - final colors = three.Float32Array( numFaces * 3 * 3 ); - final displacement = three.Float32Array( numFaces * 3 * 3 ); + final colors = Float32List( numFaces * 3 * 3 ); + final displacement = Float32List( numFaces * 3 * 3 ); final color = three.Color(); for (int f = 0; f < numFaces; f ++ ) { diff --git a/examples/lib/multi_views/multi_views.dart b/examples/lib/multi_views/multi_views.dart index 344ac7ce..43078316 100644 --- a/examples/lib/multi_views/multi_views.dart +++ b/examples/lib/multi_views/multi_views.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'package:flutter/material.dart' hide Matrix4; import 'package:three_js/three_js.dart' as three; +import 'package:flutter_angle/flutter_angle.dart'; class MultiViews extends StatefulWidget { const MultiViews({super.key}); @@ -9,7 +10,7 @@ class MultiViews extends StatefulWidget { } class _MyAppState extends State { - List textures = []; + List textures = []; ScrollController controller = ScrollController(); @override diff --git a/examples/lib/multi_views/webgl_multi_views.dart b/examples/lib/multi_views/webgl_multi_views.dart index 78a85aaa..83255214 100644 --- a/examples/lib/multi_views/webgl_multi_views.dart +++ b/examples/lib/multi_views/webgl_multi_views.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'dart:math' as math; +import 'dart:typed_data'; import 'package:example/src/statistics.dart'; import 'package:flutter/material.dart'; import 'package:three_js/three_js.dart' as three; @@ -156,7 +157,7 @@ class _MyAppState extends State { final geometry1 = IcosahedronGeometry( radius, 1 ); final count = geometry1.attributes['position'].count; - geometry1.setAttributeFromString( 'color', three.Float32BufferAttribute( three.Float32Array( count * 3 ), 3 ) ); + geometry1.setAttributeFromString( 'color', three.Float32BufferAttribute( Float32List( count * 3 ), 3 ) ); final geometry2 = geometry1.clone(); final geometry3 = geometry1.clone(); diff --git a/examples/lib/others/webgl_buffergeometry_instancing_billboards.dart b/examples/lib/others/webgl_buffergeometry_instancing_billboards.dart index 0ac868fb..5d85b18a 100644 --- a/examples/lib/others/webgl_buffergeometry_instancing_billboards.dart +++ b/examples/lib/others/webgl_buffergeometry_instancing_billboards.dart @@ -68,7 +68,7 @@ class _State extends State { const particleCount = 75000; - final translateArray = three.Float32Array( particleCount * 3 ); + final translateArray = Float32List( particleCount * 3 ); for ( int i = 0, i3 = 0, l = particleCount; i < l; i ++, i3 += 3 ) { translateArray[ i3 + 0 ] = math.Random().nextDouble() * 2 - 1; diff --git a/examples/lib/others/webgl_custom_attributes_lines.dart b/examples/lib/others/webgl_custom_attributes_lines.dart index 7c0ef0cf..49f1337d 100644 --- a/examples/lib/others/webgl_custom_attributes_lines.dart +++ b/examples/lib/others/webgl_custom_attributes_lines.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'dart:math' as math; +import 'dart:typed_data'; import 'package:example/src/statistics.dart'; import 'package:flutter/material.dart'; import 'package:three_js/three_js.dart' as three; @@ -120,17 +121,17 @@ class _State extends State { geometry.center(); final count = geometry.attributes['position'].count; - final displacement = three.Float32BufferAttribute(three.Float32Array( count * 3), 3 ); + final displacement = three.Float32BufferAttribute(Float32List( count * 3), 3 ); geometry.setAttributeFromString( 'displacement', displacement ); - final customColor = three.Float32BufferAttribute(three.Float32Array( count * 3), 3 ); + final customColor = three.Float32BufferAttribute(Float32List( count * 3), 3 ); geometry.setAttributeFromString( 'customColor', customColor ); final color = three.Color( 0xffffff ); for (int i = 0, l = customColor.count; i < l; i ++ ) { color.setHSL( i / l, 0.5, 0.5 ); - color.copyIntoArray( customColor.array, i * customColor.itemSize ); + color.copyIntoList( customColor.array, i * customColor.itemSize ); } final line = three.Line( geometry, shaderMaterial ); diff --git a/examples/lib/postprocessing/webgl_postprocessing_fxaa.dart b/examples/lib/postprocessing/webgl_postprocessing_fxaa.dart index c456bb0c..2de035b5 100644 --- a/examples/lib/postprocessing/webgl_postprocessing_fxaa.dart +++ b/examples/lib/postprocessing/webgl_postprocessing_fxaa.dart @@ -4,6 +4,7 @@ import 'package:example/src/statistics.dart'; import 'package:three_js/three_js.dart' as three; import 'dart:math' as math; import 'package:three_js_postprocessing/three_js_postprocessing.dart'; +import 'package:flutter_angle/flutter_angle.dart'; class WebglPostprocessingFXAA extends StatefulWidget { const WebglPostprocessingFXAA({super.key}); @@ -119,7 +120,7 @@ class _State extends State { threeJs.customRenderer = renderer; } - Future renderer(three.Scene scene, three.Camera camera, three.FlutterAngleTexture texture,[dt]) async{ + Future renderer(three.Scene scene, three.Camera camera, FlutterAngleTexture texture,[dt]) async{ final halfWidth = threeJs.width / 2; controls.update(); diff --git a/examples/lib/rollercoster/rollercoaster.dart b/examples/lib/rollercoster/rollercoaster.dart index 4f82152e..db8e4f01 100644 --- a/examples/lib/rollercoster/rollercoaster.dart +++ b/examples/lib/rollercoster/rollercoaster.dart @@ -1,4 +1,5 @@ import 'dart:math' as math; +import 'dart:typed_data'; import 'package:three_js/three_js.dart'; @@ -198,9 +199,9 @@ class RollerCoasterGeometry extends BufferGeometry { // console.log( vertices.length ); - this.setAttributeFromString( 'position', Float32BufferAttribute( Float32Array.fromList( vertices ), 3 ) ); - this.setAttributeFromString( 'normal', Float32BufferAttribute( Float32Array.fromList( normals ), 3 ) ); - this.setAttributeFromString( 'color', Float32BufferAttribute( Float32Array.fromList( colors ), 3 ) ); + this.setAttributeFromString( 'position', Float32BufferAttribute( Float32List.fromList( vertices ), 3 ) ); + this.setAttributeFromString( 'normal', Float32BufferAttribute( Float32List.fromList( normals ), 3 ) ); + this.setAttributeFromString( 'color', Float32BufferAttribute( Float32List.fromList( colors ), 3 ) ); } } @@ -363,8 +364,8 @@ class RollerCoasterLiftersGeometry extends BufferGeometry { } } - this.setAttributeFromString( 'position', Float32BufferAttribute( Float32Array.fromList( vertices ), 3 ) ); - this.setAttributeFromString( 'normal', Float32BufferAttribute( Float32Array.fromList( normals ), 3 ) ); + this.setAttributeFromString( 'position', Float32BufferAttribute( Float32List.fromList( vertices ), 3 ) ); + this.setAttributeFromString( 'normal', Float32BufferAttribute( Float32List.fromList( normals ), 3 ) ); } } @@ -429,7 +430,7 @@ class RollerCoasterShadowGeometry extends BufferGeometry { prevQuaternion.setFrom( quaternion ); } - this.setAttributeFromString( 'position', Float32BufferAttribute( Float32Array.fromList( vertices ), 3 ) ); + this.setAttributeFromString( 'position', Float32BufferAttribute( Float32List.fromList( vertices ), 3 ) ); } } @@ -455,7 +456,7 @@ class SkyGeometry extends BufferGeometry { vertices.addAll([ x - size, y, z + size ]); } - this.setAttributeFromString( 'position', Float32BufferAttribute( Float32Array.fromList( vertices ), 3 ) ); + this.setAttributeFromString( 'position', Float32BufferAttribute( Float32List.fromList( vertices ), 3 ) ); } } @@ -504,8 +505,8 @@ class TreesGeometry extends BufferGeometry { } } - this.setAttributeFromString( 'position', Float32BufferAttribute( Float32Array.fromList( vertices ), 3 ) ); - this.setAttributeFromString( 'color', Float32BufferAttribute( Float32Array.fromList( colors ), 3 ) ); + this.setAttributeFromString( 'position', Float32BufferAttribute( Float32List.fromList( vertices ), 3 ) ); + this.setAttributeFromString( 'color', Float32BufferAttribute( Float32List.fromList( colors ), 3 ) ); } diff --git a/examples/lib/rollercoster/webxr_vr_rollercoaster.dart b/examples/lib/rollercoster/webxr_vr_rollercoaster.dart index d5c17564..afb1f049 100644 --- a/examples/lib/rollercoster/webxr_vr_rollercoaster.dart +++ b/examples/lib/rollercoster/webxr_vr_rollercoaster.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'dart:math' as math; +import 'dart:typed_data'; import 'package:example/rollercoster/rollercoaster.dart'; import 'package:flutter/material.dart'; import 'package:example/src/statistics.dart'; @@ -7,7 +8,7 @@ import 'package:three_js/three_js.dart' as three; import 'package:three_js_geometry/three_js_geometry.dart'; extension on three.Vector3{ - three.Float32Array toNativeArray(three.Float32Array array, [int offset = 0]) { + Float32List toNativeArray(Float32List array, [int offset = 0]) { array[offset] = storage[0]; array[offset + 1] = storage[1]; array[offset + 2] = storage[2]; @@ -94,7 +95,7 @@ class _State extends State { final vertex = three.Vector3(); for (int i = 0; i < positions.length; i += 3 ) { - vertex.fromNativeArray( positions, i ); + vertex.fromArray( positions, i ); vertex.x += math.Random().nextDouble() * 10 - 5; vertex.z += math.Random().nextDouble() * 10 - 5; diff --git a/examples/lib/screenshot/opengl_screenshot.dart b/examples/lib/screenshot/opengl_screenshot.dart index ef6b2968..1897699f 100644 --- a/examples/lib/screenshot/opengl_screenshot.dart +++ b/examples/lib/screenshot/opengl_screenshot.dart @@ -16,7 +16,7 @@ class _State extends State { List data = List.filled(60, 0, growable: true); late Timer timer; late three.ThreeJS threeJs; - late final three.Uint8Array buffer; + late final Uint8List buffer; late final three.WebGLRenderTarget rt; @override @@ -54,7 +54,7 @@ class _State extends State { img.Image image = img.Image.fromBytes( width: desiredWidth, height: desiredHeight, - bytes: buffer.toDartList().buffer, + bytes: buffer.buffer, numChannels: 4, order: img.ChannelOrder.rgb ); @@ -89,7 +89,7 @@ class _State extends State { int desiredHeight = 1080; Future setup() async { - buffer = three.Uint8Array( desiredWidth * desiredHeight * 4 ); + buffer = Uint8List( desiredWidth * desiredHeight * 4 ); rt = three.WebGLRenderTarget( desiredWidth, desiredHeight, three.WebGLRenderTargetOptions({ 'colorSpace': three.SRGBColorSpace, 'samples': 4, diff --git a/examples/lib/shadow/webgl_shadowmap_pointlight.dart b/examples/lib/shadow/webgl_shadowmap_pointlight.dart index 178c705d..c5966ed4 100644 --- a/examples/lib/shadow/webgl_shadowmap_pointlight.dart +++ b/examples/lib/shadow/webgl_shadowmap_pointlight.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'dart:math' as math; +import 'dart:typed_data'; import 'package:example/src/statistics.dart'; import 'package:flutter/material.dart'; import 'package:three_js/three_js.dart' as three; @@ -153,7 +154,7 @@ class _State extends State { return three.ImageElement( width: 2, height: 2, - data: three.Uint8Array.fromList([0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255]) + data: Uint8List.fromList([0,0,0,0,0,0,0,0,255,255,255,255,255,255,255,255]) ); } } diff --git a/examples/lib/shadow/webgl_simple_gi.dart b/examples/lib/shadow/webgl_simple_gi.dart index 776ae899..88cdd4fb 100644 --- a/examples/lib/shadow/webgl_simple_gi.dart +++ b/examples/lib/shadow/webgl_simple_gi.dart @@ -119,7 +119,7 @@ class _State extends State { int currentVertex = 0; final color = Float32List( 3 ); - final three.Uint8Array buffer = three.Uint8Array( SIZE2 * 4 ); + final Uint8List buffer = Uint8List( SIZE2 * 4 ); void compute([double? dt]) { if ( bounces == 3 ) return; @@ -143,10 +143,10 @@ class _State extends State { for (int i = 0; i < 32; i ++ ) { if ( currentVertex >= totalVertex ) break; - position.fromNativeArray( positions, currentVertex * 3 ); + position.fromArray( positions, currentVertex * 3 ); position.applyMatrix4( object.matrixWorld ); - normal.fromNativeArray( normals, currentVertex * 3 ); + normal.fromArray( normals, currentVertex * 3 ); normal.applyMatrix3( normalMatrix.getNormalMatrix( object.matrixWorld ) ).normalize(); camera.position.setFrom( position ); diff --git a/examples/lib/terrain/three_terrain.dart b/examples/lib/terrain/three_terrain.dart index 70f031c9..b4f9955b 100644 --- a/examples/lib/terrain/three_terrain.dart +++ b/examples/lib/terrain/three_terrain.dart @@ -154,7 +154,7 @@ class _State extends State { applySmoothing(val, lastOptions); scatterMeshes(); if (lastOptions.heightmap != null) { - terrain.Terrain.toHeightmap(terrainScene!.children[0].geometry!.attributes['position'].array.toDartList(), lastOptions); + terrain.Terrain.toHeightmap(terrainScene!.children[0].geometry!.attributes['position'].array, lastOptions); } }) ..addSlider(guiSettings,'segments', 7, 127).onFinishChange((){regenerate(blend);}) @@ -216,7 +216,7 @@ class _State extends State { void applySmoothing(smoothing, terrain.TerrainOptions o) { three.Object3D m = terrainScene!.children[0]; - Float32List g = terrain.Terrain.toArray1D(m.geometry!.attributes['position'].array.toDartList()); + Float32List g = terrain.Terrain.toArray1D(m.geometry!.attributes['position'].array); if (smoothing == 'Conservative (0.5)') terrain.Terrain.smoothConservative(g, o, 0.5); if (smoothing == 'Conservative (1)') terrain.Terrain.smoothConservative(g, o, 1); if (smoothing == 'Conservative (10)'){ terrain.Terrain.smoothConservative(g, o, 10);} @@ -230,7 +230,7 @@ class _State extends State { else if (smoothing == 'Mean (1)'){ terrain.Terrain.smooth(g, o, 1);} else if (smoothing == 'Mean (8)'){ terrain.Terrain.smooth(g, o, 8);} else if (smoothing == 'Median'){ terrain.Terrain.smoothMedian(g, o);} - terrain.Terrain.fromArray1D(m.geometry!.attributes['position'].array.toDartList(), g); + terrain.Terrain.fromArray1D(m.geometry!.attributes['position'].array, g); terrain.Terrain.normalize(m, o); } @@ -441,7 +441,7 @@ class _State extends State { // var he = document.getElementById('heightmap'); // if (he != null) { // o.heightmap = he; - heightMapImage = terrain.Terrain.toHeightmap(terrainScene!.children[0].geometry!.attributes['position'].array.toDartList(), o); + heightMapImage = terrain.Terrain.toHeightmap(terrainScene!.children[0].geometry!.attributes['position'].array, o); // } heightMapImage = rgba2bitmap(heightMapImage!, o.xSegments+1, o.ySegments+1); lastOptions = o; diff --git a/examples/lib/terrain/webgl_geometry_terrain.dart b/examples/lib/terrain/webgl_geometry_terrain.dart index c241d6fd..eec073a4 100644 --- a/examples/lib/terrain/webgl_geometry_terrain.dart +++ b/examples/lib/terrain/webgl_geometry_terrain.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'dart:math' as math; +import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:example/src/statistics.dart'; import 'package:three_js/three_js.dart' as three; @@ -97,7 +98,7 @@ class _State extends State { }); } - three.Uint8Array generateHeight(int width,int height ) { + Uint8List generateHeight(int width,int height ) { double seed = math.pi / 4; double random() { final x = math.sin( seed ++ ) * 10000; @@ -105,7 +106,7 @@ class _State extends State { } int size = width * height; - final data = three.Uint8Array( size ); + final data = Uint8List( size ); final perlin = ImprovedNoise(); double z = random() * 100; @@ -124,12 +125,12 @@ class _State extends State { return data; } - three.ImageElement generateTexture(three.Uint8Array data,int width,int height ) { + three.ImageElement generateTexture(Uint8List data,int width,int height ) { final vector3 = three.Vector3( 0, 0, 0 ); final sun = three.Vector3( 1, 1, 1 ); sun.normalize(); - final imageData = three.Uint8Array.fromList(List.filled(width*height*4, 255)); + final imageData = Uint8List.fromList(List.filled(width*height*4, 255)); for (int i = 0, j = 0; i < imageData.length; i += 4, j ++ ) { vector3.x = data[ j - 2 ] - data[ j + 2 ] *1.0; diff --git a/examples/lib/terrain/webgl_geometry_terrain_raycast.dart b/examples/lib/terrain/webgl_geometry_terrain_raycast.dart index c845377a..a1dafb9e 100644 --- a/examples/lib/terrain/webgl_geometry_terrain_raycast.dart +++ b/examples/lib/terrain/webgl_geometry_terrain_raycast.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'dart:math' as math; +import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:example/src/statistics.dart'; import 'package:three_js/three_js.dart' as three; @@ -111,7 +112,7 @@ class _State extends State { threeJs.domElement.addEventListener(three.PeripheralType.pointerHover, onPointerMove ); } - three.Uint8Array generateHeight(int width,int height ) { + Uint8List generateHeight(int width,int height ) { double seed = math.pi / 4; double random() { final x = math.sin( seed ++ ) * 10000; @@ -119,7 +120,7 @@ class _State extends State { } int size = width * height; - final data = three.Uint8Array( size ); + final data = Uint8List( size ); final perlin = ImprovedNoise(); double z = random() * 100; @@ -138,12 +139,12 @@ class _State extends State { return data; } - three.ImageElement generateTexture(three.Uint8Array data,int width,int height ) { + three.ImageElement generateTexture(Uint8List data,int width,int height ) { final vector3 = three.Vector3( 0, 0, 0 ); final sun = three.Vector3( 1, 1, 1 ); sun.normalize(); - final imageData = three.Uint8Array.fromList(List.filled(width*height*4, 255)); + final imageData = Uint8List.fromList(List.filled(width*height*4, 255)); for (int i = 0, j = 0; i < imageData.length; i += 4, j ++ ) { vector3.x = data[ j - 2 ] - data[ j + 2 ] *1.0; diff --git a/examples/lib/texture/webgl_materials_video_webcam.dart b/examples/lib/texture/webgl_materials_video_webcam.dart index 9efc8467..a84d7acc 100644 --- a/examples/lib/texture/webgl_materials_video_webcam.dart +++ b/examples/lib/texture/webgl_materials_video_webcam.dart @@ -24,7 +24,7 @@ class _State extends State { bool loading = true; three.ThreeJS? threeJs; three.CanvasTexture? texture; - late three.Uint8Array image; + late Uint8List image; Size imageSize = const Size(640,480); @override @@ -37,7 +37,7 @@ class _State extends State { await camera.startLiveFeed((InputImage i){ if(threeJs == null){ imageSize = i.metadata!.size; - image = three.Uint8Array((imageSize.width*imageSize.height*4).toInt()); + image = Uint8List((imageSize.width*imageSize.height*4).toInt()); threeJs = three.ThreeJS( onSetupComplete: (){setState(() {});}, setup: setup, diff --git a/examples/lib/texture/webgl_opengl_texture.dart b/examples/lib/texture/webgl_opengl_texture.dart index fa4e744f..4a23a02d 100644 --- a/examples/lib/texture/webgl_opengl_texture.dart +++ b/examples/lib/texture/webgl_opengl_texture.dart @@ -1,8 +1,10 @@ import 'dart:async'; +import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:example/src/statistics.dart'; import 'package:three_js/three_js.dart' as three; import 'package:flutter_angle/flutter_angle.dart'; +import 'package:flutter_angle/flutter_angle.dart'; class WebglOpenglTexture extends StatefulWidget { const WebglOpenglTexture({super.key}); @@ -82,11 +84,11 @@ class _State extends State { final cubes = []; // just an array we can use to rotate the cubes { - final three.RenderingContext gl = threeJs.renderer!.getContext(); + final RenderingContext gl = threeJs.renderer!.getContext(); final glTex = gl.createTexture(); gl.bindTexture(WebGL.TEXTURE_2D, glTex); gl.texImage2D(WebGL.TEXTURE_2D, 0, WebGL.RGBA, 2, 2, 0, - WebGL.RGBA, WebGL.UNSIGNED_BYTE, Uint8Array.fromList([ + WebGL.RGBA, WebGL.UNSIGNED_BYTE, Uint8List.fromList([ 255, 0, 0, 255, 0, 255, 0, 255, 0, 0, 255, 255, diff --git a/examples/lib/volume/webgl_volume_cloud.dart b/examples/lib/volume/webgl_volume_cloud.dart index 816f605d..b495feeb 100644 --- a/examples/lib/volume/webgl_volume_cloud.dart +++ b/examples/lib/volume/webgl_volume_cloud.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:example/src/statistics.dart'; import 'package:three_js/three_js.dart' as three; @@ -62,7 +63,7 @@ class _State extends State { controls = three.OrbitControls( threeJs.camera, threeJs.globalKey ); const size = 128; - final data = three.Uint8Array( size * size * size ); + final data = Uint8List( size * size * size ); int i = 0; const scale = 0.05; diff --git a/examples/lib/volume/webgl_volume_perlin.dart b/examples/lib/volume/webgl_volume_perlin.dart index 771c1492..30bf2c2d 100644 --- a/examples/lib/volume/webgl_volume_perlin.dart +++ b/examples/lib/volume/webgl_volume_perlin.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:typed_data'; import 'package:flutter/material.dart'; import 'package:example/src/statistics.dart'; import 'package:three_js/three_js.dart' as three; @@ -69,7 +70,7 @@ class _State extends State { // Texture const size = 128; - final data = three.Uint8Array( size * size * size ); + final data = Uint8List( size * size * size ); int i = 0; final perlin = ImprovedNoise(); diff --git a/examples/pubspec.yaml b/examples/pubspec.yaml index dc90ba74..b8ff8c7f 100644 --- a/examples/pubspec.yaml +++ b/examples/pubspec.yaml @@ -4,7 +4,7 @@ publish_to: 'none' # Remove this line if you wish to publish to pub.dev version: 1.0.0+1 environment: - sdk: '>=3.3.3 <4.0.0' + sdk: '>=3.8.1 <4.0.0' dependencies: flutter: @@ -54,7 +54,58 @@ dependency_overrides: file_picker: ^10.1.9 three_js_objects: path: ../packages/three_js_objects - + three_js_math: + path: ../packages/three_js_math + three_js_core: + path: ../packages/three_js_core + flutter_angle: + path: ../../flutter_angle/flutter_angle + three_js_animations: + path: ../packages/three_js_animations + three_js_audio: + path: ../packages/three_js_audio + three_js_audio_latency: + path: ../packages/three_js_audio_latency + three_js_exporters: + path: ../packages/three_js_exporters + three_js_helpers: + path: ../packages/three_js_helpers + three_js_line: + path: ../packages/three_js_line + three_js_modifers: + path: ../packages/three_js_modifers + three_js_postprocessing: + path: ../packages/three_js_postprocessing + three_js_svg: + path: ../packages/three_js_svg + three_js_tjs_loader: + path: ../packages/three_js_tjs_loader + three_js_terrain: + path: ../packages/three_js_terrain + three_js_video_texture: + path: ../packages/three_js_video_texture + three_js_advanced_exporters: + path: ../packages/three_js_advanced_exporters + three_js_advanced_loaders: + path: ../packages/three_js_advanced_loaders + three_js_bvh_csg: + path: ../packages/three_js_bvh_csg + three_js_transform_controls: + path: ../packages/three_js_transform_controls + three_js_controls: + path: ../packages/three_js_controls + three_js_core_loaders: + path: ../packages/three_js_core_loaders + three_js_curves: + path: ../packages/three_js_curves + three_js_simple_loaders: + path: ../packages/three_js_simple_loaders + three_js_text: + path: ../packages/three_js_text + three_js_geometry: + path: ../packages/three_js_geometry + + flutter: uses-material-design: true assets: diff --git a/packages/three_js_advanced_exporters/lib/usdz/image_export_app.dart b/packages/three_js_advanced_exporters/lib/usdz/image_export_app.dart index dbc10265..c1e17d58 100644 --- a/packages/three_js_advanced_exporters/lib/usdz/image_export_app.dart +++ b/packages/three_js_advanced_exporters/lib/usdz/image_export_app.dart @@ -1,11 +1,10 @@ import 'dart:typed_data'; import 'package:image/image.dart' hide Color; import 'package:three_js_core/three_js_core.dart'; -import 'package:three_js_math/three_js_math.dart'; class ImageExport{ static Future decodeImageFromList(ImageElement element, bool flipY, int maxTextureSize) async { - ByteBuffer bytes = Uint8List.fromList((element.data as Uint8Array).toDartList()).buffer; + final ByteBuffer bytes = element.data.buffer; Image image = Image.fromBytes( width: element.width.toInt(), diff --git a/packages/three_js_advanced_exporters/lib/usdz/image_export_web.dart b/packages/three_js_advanced_exporters/lib/usdz/image_export_web.dart index 74c4e7ac..05e31e6a 100644 --- a/packages/three_js_advanced_exporters/lib/usdz/image_export_web.dart +++ b/packages/three_js_advanced_exporters/lib/usdz/image_export_web.dart @@ -5,12 +5,11 @@ import 'dart:math' as math; import 'package:web/web.dart'; import 'package:image/image.dart' hide Color; import 'package:three_js_core/three_js_core.dart' as core; -import 'package:three_js_math/three_js_math.dart'; class ImageExport{ static Future decodeImageFromList(core.ImageElement element, bool flipY, int maxTextureSize) async { - if(element.data is Uint8Array){ - ByteBuffer bytes = Uint8List.fromList((element.data as Uint8Array).toDartList()).buffer; + if(element.data is Uint8List){ + final ByteBuffer bytes = element.data.buffer; Image image = Image.fromBytes( width: element.width.toInt(), height: element.height.toInt(), diff --git a/packages/three_js_advanced_loaders/lib/dds_loader.dart b/packages/three_js_advanced_loaders/lib/dds_loader.dart index cb74977b..88a5fd61 100644 --- a/packages/three_js_advanced_loaders/lib/dds_loader.dart +++ b/packages/three_js_advanced_loaders/lib/dds_loader.dart @@ -157,10 +157,10 @@ class DDSLoader extends CompressedTextureLoader { ]); } - Uint8Array loadARGBMip(ByteBuffer buffer, int dataOffset, int width, int height ) { + Uint8List loadARGBMip(ByteBuffer buffer, int dataOffset, int width, int height ) { final dataLength = width * height * 4; - final srcBuffer = new Uint8Array.fromList( buffer.asUint8List(dataOffset, dataLength)); - final byteArray = new Uint8Array( dataLength ); + final srcBuffer = Uint8List.fromList( buffer.asUint8List(dataOffset, dataLength)); + final byteArray = Uint8List( dataLength ); int dst = 0; int src = 0; @@ -177,14 +177,14 @@ class DDSLoader extends CompressedTextureLoader { } } - srcBuffer.dispose(); + //srcBuffer.dispose(); return byteArray; } - Uint8Array loadRGBMip(ByteBuffer buffer, int dataOffset, int width, int height ) { + Uint8List loadRGBMip(ByteBuffer buffer, int dataOffset, int width, int height ) { final dataLength = width * height * 3; - final srcBuffer = new Uint8Array.fromList(buffer.asUint8List(dataOffset, dataLength)); - final byteArray = new Uint8Array( width * height * 4 ); + final srcBuffer = Uint8List.fromList(buffer.asUint8List(dataOffset, dataLength)); + final byteArray = Uint8List( width * height * 4 ); int dst = 0; int src = 0; @@ -241,7 +241,7 @@ class DDSLoader extends CompressedTextureLoader { // Parse header - final header = new Int32Array.fromList(buffer.asInt32List(0, headerLengthInt)); + final header = new Int32List.fromList(buffer.asInt32List(0, headerLengthInt)); if ( header[ off_magic ] != DDS_MAGIC ) { console.error( 'THREE.DDSLoader.parse: Invalid magic number in DDS header.' ); @@ -275,7 +275,7 @@ class DDSLoader extends CompressedTextureLoader { } else if(FOURCC_DX10 == fourCC){ dataOffset += extendedHeaderLengthInt * 4; - final extendedHeader = new Int32Array.fromList( buffer.asInt32List(( headerLengthInt + 1 ) * 4, extendedHeaderLengthInt)); + final extendedHeader = new Int32List.fromList( buffer.asInt32List(( headerLengthInt + 1 ) * 4, extendedHeaderLengthInt)); final dxgiFormat = extendedHeader[ off_dxgiFormat ]; if( DXGI_FORMAT_BC6H_SF16 == dxgiFormat){ @@ -351,7 +351,7 @@ class DDSLoader extends CompressedTextureLoader { int height = dds.height; for (int i = 0; i < dds.mipmapCount; i ++ ) { - NativeArray byteArray; + TypedDataList byteArray; int dataLength; if ( isRGBAUncompressed ) { @@ -364,7 +364,7 @@ class DDSLoader extends CompressedTextureLoader { } else { dataLength = (math.max( 4, width ) / 4 * math.max( 4, height ) / 4 * blockBytes).toInt(); - byteArray = new Uint8Array.fromList( buffer.asUint8List(dataOffset, dataLength)); + byteArray = Uint8List.fromList( buffer.asUint8List(dataOffset, dataLength)); } final mipmap = { 'data': byteArray, 'width': width, 'height': height }; diff --git a/packages/three_js_advanced_loaders/lib/gltf/gltf_helper.dart b/packages/three_js_advanced_loaders/lib/gltf/gltf_helper.dart index 1edadc87..299a1e66 100755 --- a/packages/three_js_advanced_loaders/lib/gltf/gltf_helper.dart +++ b/packages/three_js_advanced_loaders/lib/gltf/gltf_helper.dart @@ -1,7 +1,6 @@ import 'dart:async'; import 'dart:typed_data'; import 'dart:math' as math; -import 'package:flutter/foundation.dart'; import 'gltf_registry.dart'; import 'gltf_parser.dart'; @@ -107,13 +106,13 @@ class GLTypeData { } } -final MapwebglComponentTypes = { - 5120: (int s){return Int8Array(s);}, - 5121: (int s){return Uint8Array(s);}, - 5122: (int s){return Int16Array(s);}, - 5123: (int s){return Uint16Array(s);}, - 5125: (int s){return Uint32Array(s);}, - 5126: (int s){return Float32Array(s);} +final MapwebglComponentTypes = { + 5120: (int s){return Int8List(s);}, + 5121: (int s){return Uint8List(s);}, + 5122: (int s){return Int16List(s);}, + 5123: (int s){return Uint16List(s);}, + 5125: (int s){return Uint32List(s);}, + 5126: (int s){return Float32List(s);} }; final webglCTBPE = { diff --git a/packages/three_js_advanced_loaders/lib/gltf/gltf_parser.dart b/packages/three_js_advanced_loaders/lib/gltf/gltf_parser.dart index dfbe3d47..b7e1b860 100755 --- a/packages/three_js_advanced_loaders/lib/gltf/gltf_parser.dart +++ b/packages/three_js_advanced_loaders/lib/gltf/gltf_parser.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'dart:typed_data'; +import 'dart:math' as math; import 'package:flutter/foundation.dart'; import 'package:three_js_advanced_loaders/gltf/gltf_extensions.dart'; @@ -466,13 +467,25 @@ class GLTFParser { final int stride = byteStride ~/ elementBytes; int totalLen = array.length; if(array is Uint8List){ - ib = InterleavedBuffer(Uint8Array(totalLen).set(array.buffer.asUint8List()), 1); + ib = InterleavedBuffer(Uint8List(totalLen).set(array.buffer.asUint8List()), 1); } else if(array is Int8List){ - ib = InterleavedBuffer(Int8Array(totalLen).set(array.buffer.asInt8List()), 1); + ib = InterleavedBuffer(Int8List(totalLen).set(array.buffer.asInt8List()), 1); + } + else if(array is Int16List){ + ib = InterleavedBuffer(Int16List(totalLen).set(array.buffer.asInt16List()), 1); + } + else if(array is Int32List){ + ib = InterleavedBuffer(Int32List(totalLen).set(array.buffer.asInt32List()), 1); + } + else if(array is Uint16List){ + ib = InterleavedBuffer(Uint16List(totalLen).set(array.buffer.asUint16List()), 1); + } + else if(array is Uint32List){ + ib = InterleavedBuffer(Uint32List(totalLen).set(array.buffer.asUint32List()), 1); } else{ - ib = InterleavedBuffer(Float32Array(totalLen).set(array.buffer.asFloat32List()), stride); + ib = InterleavedBuffer(Float32List(totalLen).set(array.buffer.asFloat32List()), stride); } parser.cache.add(ibCacheKey, ib); @@ -1298,7 +1311,7 @@ class GLTFParser { targetNames.add(targetName); } - dynamic outputArray = outputAccessor.array.toDartList(); + dynamic outputArray = outputAccessor.array; if (outputAccessor.normalized) { final scale = getNormalizedComponentScale(outputArray.runtimeType); @@ -1315,7 +1328,7 @@ class GLTFParser { for (int j = 0, jl = targetNames.length; j < jl; j++) { final track = typedKeyframeTrack.createTrack( targetNames[j] + '.' + PathProperties.getValue(target["path"]), - inputAccessor.array.toDartList(), + inputAccessor.array, outputArray, interpolation); diff --git a/packages/three_js_advanced_loaders/lib/ktx_loader.dart b/packages/three_js_advanced_loaders/lib/ktx_loader.dart index 561beb57..bb69176f 100644 --- a/packages/three_js_advanced_loaders/lib/ktx_loader.dart +++ b/packages/three_js_advanced_loaders/lib/ktx_loader.dart @@ -145,11 +145,11 @@ class KhronosTextureContainer { final mipmapCount = loadMipmaps ? numberOfMipmapLevels : 1; for ( int level = 0; level < mipmapCount; level ++ ) { - final imageSize = arrayBuffer.asInt32List(dataOffset, 1)[0];// Int32Array(arrayBuffer, )[ 0 ]; // size per face, since not supporting array cubemaps + final imageSize = arrayBuffer.asInt32List(dataOffset, 1)[0];// Int32List(arrayBuffer, )[ 0 ]; // size per face, since not supporting array cubemaps dataOffset += 4; // size of the image + 4 for the imageSize field for ( int face = 0; face < numberOfFaces; face ++ ) { - final byteArray = arrayBuffer.asUint8List().sublist(dataOffset, imageSize);//Uint8Array(arrayBuffer, dataOffset, imageSize ); + final byteArray = arrayBuffer.asUint8List().sublist(dataOffset, imageSize);//Uint8List(arrayBuffer, dataOffset, imageSize ); mipmaps.add( { 'data': byteArray, 'width': width, 'height': height } ); dataOffset += imageSize; diff --git a/packages/three_js_advanced_loaders/lib/pcd_loader.dart b/packages/three_js_advanced_loaders/lib/pcd_loader.dart index ac95db1d..b342294a 100644 --- a/packages/three_js_advanced_loaders/lib/pcd_loader.dart +++ b/packages/three_js_advanced_loaders/lib/pcd_loader.dart @@ -406,9 +406,9 @@ class PCDLoader extends Loader { if ( rgb_type == 'F' ) { // treat float values as int // https://github.com/daavoo/pyntcloud/pull/204/commits/7b4205e64d5ed09abe708b2e91b615690c24d518 - final farr = new Float32Array( 1 ); + final farr = new Float32List( 1 ); farr[ 0 ] = float; - rgb = new Int32Array.fromList( farr.toDartList().buffer.asInt32List() )[ 0 ]; + rgb = new Int32List.fromList( farr.buffer.asInt32List() )[ 0 ]; } final r = ( ( rgb >> 16 ) & 0x0000ff ) / 255; diff --git a/packages/three_js_advanced_loaders/lib/rgbe_loader.dart b/packages/three_js_advanced_loaders/lib/rgbe_loader.dart index a3d22ead..11e9f96e 100755 --- a/packages/three_js_advanced_loaders/lib/rgbe_loader.dart +++ b/packages/three_js_advanced_loaders/lib/rgbe_loader.dart @@ -401,7 +401,7 @@ class RGBELoader extends DataTextureLoader { destArray[destOffset + 3] = MathUtils.toHalfFloat(1.0); } - // final byteArray = Uint8Array( buffer ); + // final byteArray = Uint8List.fromList( buffer ); // byteArray.pos = 0; final byteArray = buffer; @@ -431,7 +431,7 @@ class RGBELoader extends DataTextureLoader { case FloatType: numElements = imageRgbaData.length ~/ 4; - final floatArray = Float32Array(numElements * 4); + final floatArray = Float32List(numElements * 4); for (int j = 0; j < numElements; j++) { rgbeByteToRGBFloat(imageRgbaData, j * 4, floatArray, j * 4); } @@ -442,7 +442,7 @@ class RGBELoader extends DataTextureLoader { case HalfFloatType: numElements = imageRgbaData.length ~/ 4; - final halfArray = Uint16Array(numElements * 4); + final halfArray = Uint16List(numElements * 4); for (int j = 0; j < numElements; j++) { rgbeByteToRGBHalf(imageRgbaData, j * 4, halfArray, j * 4); } diff --git a/packages/three_js_advanced_loaders/lib/tga_loader.dart b/packages/three_js_advanced_loaders/lib/tga_loader.dart index a40b52a7..e26f4269 100644 --- a/packages/three_js_advanced_loaders/lib/tga_loader.dart +++ b/packages/three_js_advanced_loaders/lib/tga_loader.dart @@ -477,7 +477,7 @@ class TGALoader extends DataTextureLoader { getTgaRGBA( imageData, header['width'] as int, header['height'] as int, result['pixel_data'], result['palettes'] ); final dt = DataTexture( - Uint8Array.fromList(imageData), + Uint8List.fromList(imageData), header['width'] as int, header['height'] as int, ); diff --git a/packages/three_js_advanced_loaders/lib/usdz/usdz_loader.dart b/packages/three_js_advanced_loaders/lib/usdz/usdz_loader.dart index f74d4b63..e09dd246 100644 --- a/packages/three_js_advanced_loaders/lib/usdz/usdz_loader.dart +++ b/packages/three_js_advanced_loaders/lib/usdz/usdz_loader.dart @@ -273,9 +273,9 @@ class USDZLoader extends Loader { } Float32BufferAttribute toFlatBufferAttribute(Float32BufferAttribute attribute, List indices ) { - final Float32Array array = attribute.array; + final Float32List array = attribute.array; final itemSize = attribute.itemSize; - late final Float32Array array2 = Float32Array(indices.length * itemSize);//array.constructor( indices.length * itemSize ); + late final Float32List array2 = Float32List(indices.length * itemSize);//array.constructor( indices.length * itemSize ); int index = 0, index2 = 0; for ( int i = 0, l = indices.length; i < l; i ++ ) { diff --git a/packages/three_js_animations/lib/animations/keyframe_track.dart b/packages/three_js_animations/lib/animations/keyframe_track.dart index de672f1b..71828fe8 100755 --- a/packages/three_js_animations/lib/animations/keyframe_track.dart +++ b/packages/three_js_animations/lib/animations/keyframe_track.dart @@ -63,11 +63,11 @@ class KeyframeTrack { /// [name] - the identifier for the `KeyframeTrack`. /// /// [times] - an array of keyframe times, converted internally to a - /// [Float32Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array). + /// [Float32List](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32List). /// /// [values] - an array with the values related to the times array, /// converted internally to a - /// [Float32Array](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32Array ). + /// [Float32List](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Float32List ). /// /// [interpolation] - the type of interpolation to use. See [Constants] for possible values. Default is [InterpolateLinear]. KeyframeTrack(this.name,List times,List values, [int? interpolation]) { @@ -115,7 +115,7 @@ class KeyframeTrack { /// Creates a new [DiscreteInterpolant] from the /// [times] and [values]. A - /// Float32Array can be passed which will receive the results. Otherwise a new + /// Float32List can be passed which will receive the results. Otherwise a new /// array with the appropriate size will be created automatically. Interpolant? interpolantFactoryMethodDiscrete(result) { return DiscreteInterpolant( @@ -128,7 +128,7 @@ class KeyframeTrack { /// Creates a new [LinearInterpolant] from the /// [times] and [values]. A - /// Float32Array can be passed which will receive the results. Otherwise a new + /// Float32List can be passed which will receive the results. Otherwise a new /// array with the appropriate size will be created automatically. Interpolant? interpolantFactoryMethodLinear(result) { return LinearInterpolant( @@ -141,7 +141,7 @@ class KeyframeTrack { /// Create a new [CubicInterpolant] from the /// [times] and [values]. A - /// Float32Array can be passed which will receive the results. Otherwise a new + /// Float32List can be passed which will receive the results. Otherwise a new /// array with the appropriate size will be created automatically. Interpolant? interpolantFactoryMethodSmooth(result) { return CubicInterpolant(times, values, getValueSize(), result); diff --git a/packages/three_js_bvh_csg/lib/csg/csg.dart b/packages/three_js_bvh_csg/lib/csg/csg.dart index 5f3942e2..fd33b3c1 100644 --- a/packages/three_js_bvh_csg/lib/csg/csg.dart +++ b/packages/three_js_bvh_csg/lib/csg/csg.dart @@ -255,7 +255,7 @@ class CSG { Uint16List index; if (geom.index != null){ - index = geom.index!.array.toDartList() as Uint16List; + index = geom.index!.array as Uint16List; } else { index = Uint16List((posattr.array.length ~/ posattr.itemSize) | 0); diff --git a/packages/three_js_core/CHANGELOG.md b/packages/three_js_core/CHANGELOG.md index a187d7fa..dd73b9d1 100755 --- a/packages/three_js_core/CHANGELOG.md +++ b/packages/three_js_core/CHANGELOG.md @@ -1,3 +1,8 @@ +## 0.3.0 + +* Removed NativeArray +* Put WebglRenderer into its own package + ## 0.2.8 * Added properties for [] operator. diff --git a/packages/three_js_core/example/lib/main.dart b/packages/three_js_core/example/lib/main.dart index e99a4129..3eafa263 100755 --- a/packages/three_js_core/example/lib/main.dart +++ b/packages/three_js_core/example/lib/main.dart @@ -66,14 +66,18 @@ class _State extends State { three.Mesh object; - final ambientLight = three.AmbientLight(0xcccccc, 0.4); + final ambientLight = three.AmbientLight(0xffffff, 0.8); threeJs.scene.add(ambientLight); final pointLight = three.PointLight(0xffffff, 0.8); threeJs.camera.add(pointLight); threeJs.scene.add(threeJs.camera); - final material = three.MeshPhongMaterial.fromMap({"side": tmath.DoubleSide}); + final material = three.MeshPhongMaterial.fromMap({ + "color": 0xffffff, + "side": tmath.DoubleSide, + "clipShadows": true + }); object = three.Mesh(three.SphereGeometry(75, 20, 10), material); object.position.setValues(-300, 0, 200); threeJs.scene.add(object); diff --git a/packages/three_js_core/example/pubspec.yaml b/packages/three_js_core/example/pubspec.yaml index 8c345b91..1adb7d20 100755 --- a/packages/three_js_core/example/pubspec.yaml +++ b/packages/three_js_core/example/pubspec.yaml @@ -19,9 +19,11 @@ dev_dependencies: sdk: flutter flutter_lints: ^3.0.0 -dependency_overrides: - flutter_angle: - path: ../../../../flutter_angle/flutter_angle +# dependency_overrides: +# flutter_angle: +# path: ../../../../flutter_angle/flutter_angle +# three_js_math: +# path: ../../three_js_math # The following section is specific to Flutter packages. flutter: diff --git a/packages/three_js_core/lib/core/object_3d.dart b/packages/three_js_core/lib/core/object_3d.dart index e921face..11a696fb 100755 --- a/packages/three_js_core/lib/core/object_3d.dart +++ b/packages/three_js_core/lib/core/object_3d.dart @@ -1,3 +1,5 @@ +import 'dart:typed_data'; + import 'package:three_js_core/three_js_core.dart'; import 'package:three_js_math/three_js_math.dart'; @@ -1328,10 +1330,13 @@ class Object3D with EventDispatcher { parent?.dispose(); - if(background is NativeArray || background is ImageElement || background is Texture){ + if(background is ImageElement || background is Texture){ background?.dispose(); background = null; } + else if(background is TypedDataList){ + background = null; + } children.clear(); userData.clear(); diff --git a/packages/three_js_core/lib/core/uniform.dart b/packages/three_js_core/lib/core/uniform.dart index 41de7b97..786ae3f5 100755 --- a/packages/three_js_core/lib/core/uniform.dart +++ b/packages/three_js_core/lib/core/uniform.dart @@ -1,3 +1,4 @@ +import 'dart:typed_data'; import 'package:three_js_math/three_js_math.dart'; /// Uniforms are global GLSL variables. They are passed to shader programs. @@ -14,7 +15,7 @@ import 'package:three_js_math/three_js_math.dart'; /// objects or ten `number`s. class Uniform { dynamic value; - Float32Array? data; + Float32List? data; int? offset; Uniform(this.value); diff --git a/packages/three_js_core/lib/geometries/buffer_geometry.dart b/packages/three_js_core/lib/geometries/buffer_geometry.dart index fa27cb41..2ed698a8 100755 --- a/packages/three_js_core/lib/geometries/buffer_geometry.dart +++ b/packages/three_js_core/lib/geometries/buffer_geometry.dart @@ -28,7 +28,7 @@ final _bufferGeometryvector = Vector3.zero(); /// /// // create a simple square shape. We duplicate the top left and bottom right /// // vertices because each vertex needs to appear once per triangle. -/// final vertices = Float32Array.fromList([ +/// final vertices = Float32List.fromList([ /// -1.0, -1.0, 1.0, // v0 /// 1.0, -1.0, 1.0, // v1 /// 1.0, 1.0, 1.0, // v2 @@ -518,13 +518,13 @@ class BufferGeometry with EventDispatcher { tdir = Vector3.zero(); void handleTriangle(int a, int b, int c) { - vA.fromNativeArray(positions, a * 3); - vB.fromNativeArray(positions, b * 3); - vC.fromNativeArray(positions, c * 3); + vA.fromArray(positions, a * 3); + vB.fromArray(positions, b * 3); + vC.fromArray(positions, c * 3); - uvA.fromNativeArray(uvs, a * 2); - uvB.fromNativeArray(uvs, b * 2); - uvC.fromNativeArray(uvs, c * 2); + uvA.fromArray(uvs, a * 2); + uvB.fromArray(uvs, b * 2); + uvC.fromArray(uvs, c * 2); vB.sub(vA); vC.sub(vA); @@ -584,7 +584,7 @@ class BufferGeometry with EventDispatcher { final n = Vector3.zero(), n2 = Vector3.zero(); void handleVertex(int v) { - n.fromNativeArray(normals, v * 3); + n.fromArray(normals, v * 3); n2.setFrom(n); final t = tan1[v]; diff --git a/packages/three_js_core/lib/lights/light.dart b/packages/three_js_core/lib/lights/light.dart index bec92fa4..1784f654 100755 --- a/packages/three_js_core/lib/lights/light.dart +++ b/packages/three_js_core/lib/lights/light.dart @@ -1,3 +1,5 @@ +import 'package:three_js_core/textures/index.dart'; + import '../core/index.dart'; import 'package:three_js_math/three_js_math.dart'; import 'light_shadow.dart'; @@ -20,7 +22,7 @@ class Light extends Object3D { double? width; double? height; - Map? map; + Texture? map; Color? groundColor; /// [color] - (optional) hexadecimal color of the light. Default diff --git a/packages/three_js_core/lib/materials/material.dart b/packages/three_js_core/lib/materials/material.dart index 6e6aa624..f040274b 100755 --- a/packages/three_js_core/lib/materials/material.dart +++ b/packages/three_js_core/lib/materials/material.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'dart:typed_data'; import 'package:three_js_core/others/index.dart'; import '../core/event_dispatcher.dart'; @@ -302,7 +303,7 @@ class Material with EventDispatcher { int? depthPacking; String? index0AttributeName; Map? extensions; - Map? defaultAttributeValues; + Map? defaultAttributeValues; bool? lights; bool? clipping; diff --git a/packages/three_js_core/lib/materials/projected_material.dart b/packages/three_js_core/lib/materials/projected_material.dart index 6559764d..3899ac83 100644 --- a/packages/three_js_core/lib/materials/projected_material.dart +++ b/packages/three_js_core/lib/materials/projected_material.dart @@ -1,4 +1,5 @@ import 'dart:async'; +import 'dart:typed_data'; import 'package:three_js_core/three_js_core.dart'; import 'package:three_js_math/three_js_math.dart'; @@ -570,19 +571,19 @@ class ProjectedMaterialUtils{ void allocateProjectionData(BufferGeometry geometry, int instancesCount) { geometry.setAttributeFromString( 'savedModelMatrix0', - InstancedBufferAttribute(Float32Array(instancesCount * 4), 4) + InstancedBufferAttribute(Float32List(instancesCount * 4), 4) ); geometry.setAttributeFromString( 'savedModelMatrix1', - InstancedBufferAttribute(Float32Array(instancesCount * 4), 4) + InstancedBufferAttribute(Float32List(instancesCount * 4), 4) ); geometry.setAttributeFromString( 'savedModelMatrix2', - InstancedBufferAttribute(Float32Array(instancesCount * 4), 4) + InstancedBufferAttribute(Float32List(instancesCount * 4), 4) ); geometry.setAttributeFromString( 'savedModelMatrix3', - InstancedBufferAttribute(Float32Array(instancesCount * 4), 4) + InstancedBufferAttribute(Float32List(instancesCount * 4), 4) ); } } \ No newline at end of file diff --git a/packages/three_js_core/lib/materials/shader_material.dart b/packages/three_js_core/lib/materials/shader_material.dart index 50e4a454..e5797eeb 100755 --- a/packages/three_js_core/lib/materials/shader_material.dart +++ b/packages/three_js_core/lib/materials/shader_material.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'dart:typed_data'; import 'package:three_js_core/three_js_core.dart'; import '../renderers/shaders/shader_chunk/default_fragment.glsl.dart'; import '../renderers/shaders/shader_chunk/default_vertex.glsl.dart'; @@ -132,9 +133,9 @@ class ShaderMaterial extends Material { // When rendered geometry doesn't include these attributes but the material does, // use these default values in WebGL. This avoids errors when buffer data is missing. defaultAttributeValues = { - 'color': [1, 1, 1], - 'uv': [0.0, 0.0], - 'uv2': [0.0, 0.0] + 'color': Float32List.fromList([1, 1, 1]), + 'uv': Float32List.fromList([0.0, 0.0]), + 'uv2': Float32List.fromList([0.0, 0.0]) }; index0AttributeName = null; diff --git a/packages/three_js_core/lib/objects/batched_mesh.dart b/packages/three_js_core/lib/objects/batched_mesh.dart index b3c12d0b..b48020d2 100644 --- a/packages/three_js_core/lib/objects/batched_mesh.dart +++ b/packages/three_js_core/lib/objects/batched_mesh.dart @@ -1,6 +1,5 @@ import 'dart:math' as math; import 'dart:typed_data'; -import 'package:flutter/foundation.dart'; import 'package:three_js_core/three_js_core.dart'; import 'package:three_js_math/three_js_math.dart'; @@ -16,28 +15,6 @@ int sortTransparent(Pool a, Pool b ) { return b.z - a.z; } -extension on NativeArray{ - NativeArray constructure(int s){ - switch (this.runtimeType) { - case Int8Array: - return Int8Array(s); - case Int16Array: - return Int16Array(s); - case Int32Array: - return Int32Array(s); - case Uint8Array: - return Uint8Array(s); - case Uint16Array: - return Uint16Array(s); - case Uint32Array: - return Uint32Array(s); - case Float32Array: - default: - return Float32Array(s); - } - } -} - class Bounds{ Bounds({ this.boxInitialized = false, @@ -235,7 +212,7 @@ class BatchedMesh extends Mesh { int size = ( sizeSqrt / 4 ).ceil() * 4; size = math.max( size, 4 ); - final matricesArray = Float32Array( size * size * 4 ); // 4 floats per RGBA pixel + final matricesArray = Float32List( size * size * 4 ); // 4 floats per RGBA pixel final matricesTexture = DataTexture( matricesArray, size, size, RGBAFormat, FloatType ); this.matricesTexture = matricesTexture; @@ -243,7 +220,7 @@ class BatchedMesh extends Mesh { void _initIndirectTexture() { int size = math.sqrt( maxInstanceCount ).ceil(); - final indirectArray = Uint32Array( size * size ); + final indirectArray = Uint32List( size * size ); indirectTexture = DataTexture( indirectArray, size, size, RedIntegerFormat, UnsignedIntType ); } @@ -259,21 +236,20 @@ class BatchedMesh extends Mesh { final int itemSize = srcAttribute.itemSize; final normalized = srcAttribute.normalized; - final dstArray = (array as NativeArray).constructure( maxVertexCount * itemSize); - final dstAttribute = BufferAttribute.fromUnknown( dstArray, itemSize, normalized ); + final dstAttribute = BufferAttribute.fromUnknown( array, itemSize, normalized ); geometry?.setAttributeFromString( attributeName, dstAttribute ); } if ( reference.getIndex() != null ) { final indexArray = maxVertexCount > 65536 - ? Uint32Array( maxIndexCount ) - : Uint16Array( maxIndexCount ); + ? Uint32List( maxIndexCount ) + : Uint16List( maxIndexCount ); - if(indexArray is Uint32Array){ + if(indexArray is Uint32List){ geometry?.setIndex( Uint32BufferAttribute( indexArray, 1 ) ); } - else if(indexArray is Uint16Array){ + else if(indexArray is Uint16List){ geometry?.setIndex( Uint16BufferAttribute( indexArray, 1 ) ); } } @@ -416,7 +392,7 @@ class BatchedMesh extends Mesh { final colorsTexture = this.colorsTexture; if ( colorsTexture != null) { - _whiteColor.copyIntoArray( colorsTexture.image.data, drawId * 4 ); + _whiteColor.copyIntoList( colorsTexture.image.data, drawId * 4 ); colorsTexture.needsUpdate = true; } @@ -857,7 +833,7 @@ class BatchedMesh extends Mesh { // the indexed version of the multi draw function requires specifying the start // offset in bytes. final index = geometry!.getIndex(); - final bytesPerElement = index == null ? 1 : index.array.BYTES_PER_ELEMENT; + final int bytesPerElement = index == null ? 1 : index.array.elementSizeInBytes; final instanceInfo = _instanceInfo; final multiDrawStarts = this.multiDrawStarts; diff --git a/packages/three_js_core/lib/objects/instanced_mesh.dart b/packages/three_js_core/lib/objects/instanced_mesh.dart index d8ae3f2f..f35f40a5 100755 --- a/packages/three_js_core/lib/objects/instanced_mesh.dart +++ b/packages/three_js_core/lib/objects/instanced_mesh.dart @@ -1,3 +1,5 @@ +import 'dart:typed_data'; + import 'package:three_js_core/three_js_core.dart'; import 'package:three_js_math/three_js_math.dart'; @@ -28,7 +30,7 @@ class InstancedMesh extends Mesh { InstancedMesh(super.geometry, super.material, int count){ type = "InstancedMesh"; - final dl = Float32Array(count * 16); + final dl = Float32List(count * 16); instanceMatrix = InstancedBufferAttribute(dl, 16, false); instanceColor = null; @@ -112,7 +114,7 @@ class InstancedMesh extends Mesh { /// [instanceColor][needsUpdate] to /// true after updating all the colors. void setColorAt(int index, Color color) { - instanceColor ??= InstancedBufferAttribute(Float32Array((instanceMatrix!.count * 3).toInt()), 3, false); + instanceColor ??= InstancedBufferAttribute(Float32List((instanceMatrix!.count * 3).toInt()), 3, false); color.copyIntoArray(instanceColor!.array, index * 3); } @@ -127,15 +129,15 @@ class InstancedMesh extends Mesh { /// sure you set [instanceMatrix][needsUpdate] /// to true after updating all the matrices. void setMatrixAt(int index, Matrix4 matrix) { - matrix.copyIntoArray(instanceMatrix!.array.toDartList(), index * 16); + matrix.copyIntoList(instanceMatrix!.array, index * 16); } void setMorphAt(int index, Object3D object ) { final objectInfluences = object.morphTargetInfluences; final len = objectInfluences.length + 1; // morphBaseInfluence + all influences - morphTexture ??= DataTexture( Float32Array(len * count!), len, count, RedFormat, FloatType ); - final Float32Array array = morphTexture!.source.data.data; + morphTexture ??= DataTexture( Float32List(len * count!), len, count, RedFormat, FloatType ); + final Float32List array = morphTexture!.source.data.data; double morphInfluencesSum = 0; for (int i = 0; i < objectInfluences.length; i ++ ) { diff --git a/packages/three_js_core/lib/objects/skeleton.dart b/packages/three_js_core/lib/objects/skeleton.dart index b7bb7202..bb4bf43c 100755 --- a/packages/three_js_core/lib/objects/skeleton.dart +++ b/packages/three_js_core/lib/objects/skeleton.dart @@ -1,3 +1,4 @@ +import 'dart:typed_data'; import 'package:three_js_core/others/index.dart'; import 'package:three_js_math/three_js_math.dart'; import '../textures/index.dart'; @@ -39,7 +40,7 @@ class Skeleton { String uuid = MathUtils.generateUUID(); late List bones; late List boneInverses; - Float32Array? boneMatrices; + Float32List? boneMatrices; DataTexture? boneTexture; late int boneTextureSize; double frame = -1; @@ -76,8 +77,7 @@ class Skeleton { int size = getSize.toInt(); boneTextureSize = size; - boneMatrices?.dispose(); - boneMatrices = Float32Array(size * size * 4); + boneMatrices = Float32List(size * size * 4); // calculate inverse bone matrices if necessary @@ -207,7 +207,7 @@ class Skeleton { if(disposed) return; disposed = true; boneTexture?.dispose(); - boneMatrices?.dispose(); + boneMatrices?.clear(); bones.forEach((bone){ bone.dispose(); @@ -265,7 +265,7 @@ class Skeleton { return data; } - Float32Array getValue(String name) { + Float32List getValue(String name) { if(name == "boneMatrices") { return boneMatrices!; } else { diff --git a/packages/three_js_core/lib/others/three_viewer.dart b/packages/three_js_core/lib/others/three_viewer.dart index ab6f11a0..1347f0e0 100644 --- a/packages/three_js_core/lib/others/three_viewer.dart +++ b/packages/three_js_core/lib/others/three_viewer.dart @@ -7,6 +7,7 @@ import 'package:three_js_core/others/index.dart'; import 'package:three_js_core/renderers/index.dart'; import 'package:three_js_core/three_js_core.dart' as core; import 'package:three_js_math/three_js_math.dart'; +import 'package:flutter_angle/flutter_angle.dart'; class Settings{ Settings({ @@ -193,7 +194,7 @@ class ThreeJS with WidgetsBindingObserver{ events.clear(); disposeEvents.clear(); - allNativeData.dispose(); + //allNativeData.dispose(); angle?.dispose([texture]); loadingWidget = null; diff --git a/packages/three_js_core/lib/renderers/index.dart b/packages/three_js_core/lib/renderers/index.dart index 88b11834..bbbadb6f 100755 --- a/packages/three_js_core/lib/renderers/index.dart +++ b/packages/three_js_core/lib/renderers/index.dart @@ -4,7 +4,7 @@ import 'dart:math' as math; import 'dart:typed_data'; import 'package:flutter/foundation.dart'; - +import 'package:flutter_angle/flutter_angle.dart'; import '../cameras/index.dart'; import '../others/index.dart'; import '../core/index.dart'; diff --git a/packages/three_js_core/lib/renderers/web_gl_renderer.dart b/packages/three_js_core/lib/renderers/web_gl_renderer.dart index 75b9067b..2dd63506 100755 --- a/packages/three_js_core/lib/renderers/web_gl_renderer.dart +++ b/packages/three_js_core/lib/renderers/web_gl_renderer.dart @@ -1831,7 +1831,7 @@ class WebGLRenderer { _currentMaterialId = -1; // reset current material to ensure correct uniform bindings } - void readRenderTargetPixels(WebGLRenderTarget renderTarget, int x, int y, int width, int height, NativeArray buffer, [activeCubeFaceIndex]) { + void readRenderTargetPixels(WebGLRenderTarget renderTarget, int x, int y, int width, int height, TypedData buffer, [int? activeCubeFaceIndex]) { dynamic framebuffer = properties.get(renderTarget)["__webglFramebuffer"]; //can be Map or int if (renderTarget is WebGLCubeRenderTarget && activeCubeFaceIndex != null) { @@ -1869,7 +1869,7 @@ class WebGLRenderer { // the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604) if ((x >= 0 && x <= (renderTarget.width - width)) && (y >= 0 && y <= (renderTarget.height - height))) { - _gl.readPixels(x, y, width, height, utils.convert(textureFormat), utils.convert(textureType), kIsWeb?buffer.data:buffer); + _gl.readPixels(x, y, width, height, utils.convert(textureFormat), utils.convert(textureType), buffer); } } finally { final framebuffer = (_currentRenderTarget != null) ? properties.get(_currentRenderTarget)["__webglFramebuffer"] : null; @@ -1889,8 +1889,8 @@ class WebGLRenderer { final width = (texture.image.width * levelScale).floor(); final height = (texture.image.height * levelScale).floor(); - final x = position != null ? position.x.toInt() : 0; - final y = position != null ? position.y.toInt() : 0; + final x = position != null && !position.x.isNaN ? position.x.toInt() : 0; + final y = position != null && !position.y.isNaN ? position.y.toInt() : 0; textures.setTexture2D(texture, 0); _gl.copyTexSubImage2D(WebGL.TEXTURE_2D, level, 0, 0, x, y, width, height); diff --git a/packages/three_js_core/lib/renderers/webgl/index.dart b/packages/three_js_core/lib/renderers/webgl/index.dart index e783f87c..1b51907d 100755 --- a/packages/three_js_core/lib/renderers/webgl/index.dart +++ b/packages/three_js_core/lib/renderers/webgl/index.dart @@ -18,6 +18,7 @@ import '../../lights/index.dart'; import '../shaders/index.dart'; import '../../math/frustum.dart'; import '../pmrem_generator.dart'; +import 'package:flutter_angle/flutter_angle.dart'; part 'web_gl_animation.dart'; part 'web_gl_attributes.dart'; diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_attributes.dart b/packages/three_js_core/lib/renderers/webgl/web_gl_attributes.dart index 8051a625..a4627e42 100755 --- a/packages/three_js_core/lib/renderers/webgl/web_gl_attributes.dart +++ b/packages/three_js_core/lib/renderers/webgl/web_gl_attributes.dart @@ -8,7 +8,7 @@ class WebGLAttributes { WebGLAttributes(this.gl); - Map createBuffer(dynamic attribute, int bufferType, {String? name}) {//BufferAttribute> + Map createBuffer(dynamic attribute, int bufferType, {String? name}) {//BufferAttribute final array = attribute.array; final usage = attribute.usage; @@ -126,10 +126,10 @@ class WebGLAttributes { updateRanges.length = mergeIndex + 1; for (int i = 0, l = updateRanges.length; i < l; i ++ ) { final range = updateRanges[i]; - Float32Array f = Float32Array.fromList(attribute.array.sublist(range.start,range.count) as List); + Float32List f = Float32List.fromList(attribute.array.sublist(range.start,range.count) as List); gl.bufferSubData( bufferType, - range.start * array.BYTES_PER_ELEMENT, + range.start * array.bytesPerElement, f, ); @@ -157,8 +157,7 @@ class WebGLAttributes { (len[i] as BufferAttribute).dispose(); remove(len[i]); } - else if(len[i] is NativeArray){ - //(len[i] as NativeArray).dispose(); + else if(len[i] is TypedDataList){ remove(len[i]); } } diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_geometries.dart b/packages/three_js_core/lib/renderers/webgl/web_gl_geometries.dart index 834c882e..082fe817 100755 --- a/packages/three_js_core/lib/renderers/webgl/web_gl_geometries.dart +++ b/packages/three_js_core/lib/renderers/webgl/web_gl_geometries.dart @@ -126,7 +126,7 @@ class WebGLGeometries { wireframeAttributes.set(geometry, attribute); } - BufferAttribute>? getWireframeAttribute(BufferGeometry geometry) { + BufferAttribute? getWireframeAttribute(BufferGeometry geometry) { final currentAttribute = wireframeAttributes.get(geometry); if (currentAttribute != null) { diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_morphtargets.dart b/packages/three_js_core/lib/renderers/webgl/web_gl_morphtargets.dart index f9afc6df..582caf5e 100755 --- a/packages/three_js_core/lib/renderers/webgl/web_gl_morphtargets.dart +++ b/packages/three_js_core/lib/renderers/webgl/web_gl_morphtargets.dart @@ -10,15 +10,15 @@ int absNumericalSort(a, b) { void denormalize(Vector morph, BufferAttribute attribute) { double denominator = 1; - NativeArray array = attribute is InterleavedBufferAttribute ? attribute.data!.array : attribute.array; + TypedDataList array = attribute is InterleavedBufferAttribute ? attribute.data!.array : attribute.array; - if (array is Int8Array) { + if (array is Int8List) { denominator = 127; } - else if (array is Int16Array) { + else if (array is Int16List) { denominator = 32767; } - else if (array is Int32Array) { + else if (array is Int32List) { denominator = 2147483647; } else { @@ -89,7 +89,7 @@ class WebGLMorphtargets { width = capabilities.maxTextureSize.toInt(); } - final buffer = Float32Array((width * height * 4 * morphTargetsCount).toInt()); + final buffer = Float32List((width * height * 4 * morphTargetsCount).toInt()); final texture = DataArrayTexture(buffer, width, height, morphTargetsCount); texture.type = FloatType; diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_state.dart b/packages/three_js_core/lib/renderers/webgl/web_gl_state.dart index f4390325..3b1f4a2d 100755 --- a/packages/three_js_core/lib/renderers/webgl/web_gl_state.dart +++ b/packages/three_js_core/lib/renderers/webgl/web_gl_state.dart @@ -124,7 +124,7 @@ class WebGLState { } WebGLTexture createTexture(int type, int target, int count) { - final data = Uint8Array(4); + final data = Uint8List(4); // 4 is required to match default unpack alignment of 4. // final texture = gl.createTexture(); @@ -231,7 +231,7 @@ class WebGLState { } if (needsUpdate) { - Uint32Array buf = Uint32Array.fromList(List.from(drawBuffers)); + Uint32List buf = Uint32List.fromList(List.from(drawBuffers)); gl.drawBuffers(buf); buf.dispose(); } @@ -526,7 +526,7 @@ class WebGLState { int height, int depth, int format, - NativeArray? data, + TypedData? data, ) { gl.compressedTexSubImage3D(target,level,xoffset,yoffset,zoffset,width,height,depth,format,data); } @@ -538,21 +538,21 @@ class WebGLState { int height, int depth, int border, - NativeArray? data, + TypedData? data, ) { gl.compressedTexImage3D(target,level,internalformat,width,height,depth,border,data); } - void compressedTexImage2D(int target, int level, int internalformat, int width, int height, int border, NativeArray? pixels) { + void compressedTexImage2D(int target, int level, int internalformat, int width, int height, int border, TypedData? pixels) { gl.compressedTexImage2D(target, level, internalformat, width, height, border, pixels); } - void texSubImage2D(int target, int level, int x, int y, num width, num height, int glFormat, int glType, NativeArray data) { + void texSubImage2D(int target, int level, int x, int y, num width, num height, int glFormat, int glType, TypedData data) { gl.texSubImage2D(target, level, x, y, width.toInt(), height.toInt(), glFormat, glType, data); } void texSubImage2DIf(int target, int level, int x, int y, int glFormat, int glType, ImageElement image) { - if (kIsWeb && image.data is! NativeArray) { + if (kIsWeb && image.data is! TypedData) { texSubImage2DNoSize(WebGL.TEXTURE_2D, 0, 0, 0, glFormat, glType, image.data); } else { @@ -569,7 +569,7 @@ class WebGLState { } } - void texSubImage3D(int target, int level, int xoffset, int yoffset, int zoffset, int width, int height, int depth, int format, int type, NativeArray? pixels) { + void texSubImage3D(int target, int level, int xoffset, int yoffset, int zoffset, int width, int height, int depth, int format, int type, TypedData? pixels) { gl.texSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); } @@ -581,7 +581,7 @@ class WebGLState { int width, int height, int format, - NativeArray? pixels, + TypedData? pixels, ) { gl.compressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, pixels); } diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_textures.dart b/packages/three_js_core/lib/renderers/webgl/web_gl_textures.dart index cc2e98ff..52d35bf5 100755 --- a/packages/three_js_core/lib/renderers/webgl/web_gl_textures.dart +++ b/packages/three_js_core/lib/renderers/webgl/web_gl_textures.dart @@ -1449,8 +1449,9 @@ class WebGLTextures { } } - final List invalidationArrayRead = []; - final List invalidationArrayDraw = []; + final Uint32List invalidationArrayDraw = Uint32List(1); + final Uint32List invalidationArrayRead = Uint32List(1); + void updateMultisampleRenderTarget(RenderTarget renderTarget) { if ( renderTarget.samples > 0 ) { if ( !useMultisampledRTT( renderTarget )) { @@ -1527,13 +1528,15 @@ class WebGLTextures { state.bindFramebuffer( WebGL.DRAW_FRAMEBUFFER, renderTargetProperties['__webglMultisampledFramebuffer'] ); } else { if ( renderTarget.depthBuffer && !renderTarget.resolveDepthBuffer && supportsInvalidateFramebuffer ) { - final depthStyle = renderTarget.stencilBuffer ? WebGL.DEPTH_STENCIL_ATTACHMENT : WebGL.DEPTH_ATTACHMENT; - _gl.invalidateFramebuffer( WebGL.DRAW_FRAMEBUFFER, [ depthStyle ] ); + depthStyle[0] = renderTarget.stencilBuffer ? WebGL.DEPTH_STENCIL_ATTACHMENT : WebGL.DEPTH_ATTACHMENT; + _gl.invalidateFramebuffer( WebGL.DRAW_FRAMEBUFFER, depthStyle ); } } } } - + + Uint32List depthStyle = Uint32List.fromList([WebGL.DEPTH_ATTACHMENT]); + bool useMultisampledRenderToTexture(RenderTarget renderTarget) { final renderTargetProperties = properties.get(renderTarget); diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_uniforms_groups.dart b/packages/three_js_core/lib/renderers/webgl/web_gl_uniforms_groups.dart index 141229d9..523d5c12 100644 --- a/packages/three_js_core/lib/renderers/webgl/web_gl_uniforms_groups.dart +++ b/packages/three_js_core/lib/renderers/webgl/web_gl_uniforms_groups.dart @@ -196,7 +196,7 @@ class WebGLUniformsGroups{ } // the following two properties will be used for partial buffer updates - uniform.data = Float32Array( info['storage']! ~/ Float32List.bytesPerElement); + uniform.data = Float32List( info['storage']! ~/ Float32List.bytesPerElement); uniform.offset = offset; // Update the global offset diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_uniforms_helper.dart b/packages/three_js_core/lib/renderers/webgl/web_gl_uniforms_helper.dart index f50e4f51..29ec7e29 100755 --- a/packages/three_js_core/lib/renderers/webgl/web_gl_uniforms_helper.dart +++ b/packages/three_js_core/lib/renderers/webgl/web_gl_uniforms_helper.dart @@ -149,8 +149,10 @@ mixin WebGLUniformsHelper { cache.clear(); } - List flatten(List? array, int nBlocks, int blockSize) { - if(array == null || array.isEmpty) return []; + Float32List flat = Float32List(0); + + Float32List flatten(List? array, int nBlocks, int blockSize) { + if(array == null || array.isEmpty) return Float32List(0); final firstElem = array[0]; if (firstElem is num || firstElem is double || firstElem is int) { @@ -160,7 +162,7 @@ mixin WebGLUniformsHelper { array2.add(element.toDouble()); } - return array2; + return Float32List.fromList(array2); } final n = nBlocks * blockSize; @@ -382,7 +384,6 @@ mixin WebGLUniformsHelper { if (arraysEqual(cache, elements)) { return; } - gl.uniformMatrix4fv(addr, false, elements); copyArray(cache, elements); } @@ -621,7 +622,6 @@ mixin WebGLUniformsHelper { void setValueM4Array(RenderingContext gl, v, [WebGLTextures? textures]) { final data = flatten(v, size, 16); - gl.uniformMatrix4fv(addr, false, data); } diff --git a/packages/three_js_core/lib/textures/data_3d_texture.dart b/packages/three_js_core/lib/textures/data_3d_texture.dart index ad080f58..cd9ba4cd 100755 --- a/packages/three_js_core/lib/textures/data_3d_texture.dart +++ b/packages/three_js_core/lib/textures/data_3d_texture.dart @@ -1,3 +1,5 @@ +import 'dart:typed_data'; + import 'package:three_js_math/three_js_math.dart'; import 'image_element.dart'; import './texture.dart'; @@ -15,7 +17,7 @@ class Data3DTexture extends Texture { /// /// [depth] -- depth of the texture. /// - Data3DTexture([NativeArray? data, int width = 1, int height = 1, int depth = 1]):super() { + Data3DTexture([TypedDataList? data, int width = 1, int height = 1, int depth = 1]):super() { image = ImageElement(data: data, width: width, height: height, depth: depth); magFilter = LinearFilter; diff --git a/packages/three_js_core/lib/textures/data_array_texture.dart b/packages/three_js_core/lib/textures/data_array_texture.dart index 3d9c11c0..a682c6d6 100755 --- a/packages/three_js_core/lib/textures/data_array_texture.dart +++ b/packages/three_js_core/lib/textures/data_array_texture.dart @@ -19,7 +19,7 @@ class DataArrayTexture extends Texture { /// /// For the packed types, UnsignedShort4444Type and /// UnsignedShort5551Type all color components of one texel can be - /// addressed as bitfields within an integer element of a Uint16Array. + /// addressed as bitfields within an integer element of a Uint16List. /// /// In order to use the types FloatType and HalfFloatType, the /// WebGL implementation must support the respective extensions diff --git a/packages/three_js_core/lib/textures/data_texture.dart b/packages/three_js_core/lib/textures/data_texture.dart index 6f824002..d12f8b7c 100755 --- a/packages/three_js_core/lib/textures/data_texture.dart +++ b/packages/three_js_core/lib/textures/data_texture.dart @@ -1,6 +1,7 @@ +import 'dart:typed_data'; + import 'image_element.dart'; import './texture.dart'; -import 'package:three_js_math/three_js_math.dart'; /// Creates a texture directly from raw data, width and height. class DataTexture extends Texture { @@ -18,7 +19,7 @@ class DataTexture extends Texture { /// /// For the packed types, UnsignedShort4444Type and /// UnsignedShort5551Type all color components of one texel can be - /// addressed as bitfields within an integer element of a Uint16Array. + /// addressed as bitfields within an integer element of a Uint16List. /// /// In order to use the types FloatType and HalfFloatType, the /// WebGL implementation must support the respective extensions @@ -51,7 +52,7 @@ class DataTexture extends Texture { /// texture.needsUpdate = true; /// ``` DataTexture([ - NativeArray? data, + TypedDataList? data, int? width, int? height, int? format, diff --git a/packages/three_js_core/lib/textures/flutter_texture.dart b/packages/three_js_core/lib/textures/flutter_texture.dart index a86cf3e1..d57859ab 100644 --- a/packages/three_js_core/lib/textures/flutter_texture.dart +++ b/packages/three_js_core/lib/textures/flutter_texture.dart @@ -1,3 +1,4 @@ +import 'dart:typed_data'; import 'dart:ui' as ui; import 'package:flutter/rendering.dart' as rend; import 'package:flutter/widgets.dart' as wid; @@ -150,17 +151,17 @@ class FlutterTexture extends Texture { imageElement.width = image.width; imageElement.height = image.height; if(imageElement.data == null){ - imageElement.data = Uint8Array.fromList(data); + imageElement.data = Uint8List.fromList(data); } else{ - (imageElement.data as Uint8Array).set(data); + (imageElement.data as Uint8List).setAll(0, data); } return imageElement; } return ImageElement( width: image.width, height: image.height, - data: Uint8Array.fromList(data) + data: Uint8List.fromList(data) ); } catch (e) { rethrow; @@ -185,17 +186,17 @@ class FlutterTexture extends Texture { imageElement.width = image.width; imageElement.height = image.height; if(imageElement.data == null){ - imageElement.data = Uint8Array.fromList(data); + imageElement.data = Uint8List.fromList(data); } else{ - (imageElement.data as Uint8Array).set(data); + (imageElement.data as Uint8List).setAll(0, data); } return imageElement; } return ImageElement( width: image.width, height: image.height, - data: Uint8Array.fromList(data) + data: Uint8List.fromList(data) ); } catch (e) { diff --git a/packages/three_js_core/lib/textures/image_element.dart b/packages/three_js_core/lib/textures/image_element.dart index 1d6353ea..ce1221b7 100755 --- a/packages/three_js_core/lib/textures/image_element.dart +++ b/packages/three_js_core/lib/textures/image_element.dart @@ -1,5 +1,3 @@ -import 'package:three_js_math/three_js_math.dart'; - class ImageElement { String? uuid; dynamic url; @@ -8,7 +6,7 @@ class ImageElement { String? src; bool complete = true; - // NativeArray or ImageElement + // TypedeData or ImageElement dynamic data; int depth; @@ -21,17 +19,13 @@ class ImageElement { this.depth = 0, }); - void dispose() { - if(data is NativeArray){ - data?.dispose(); - } - } + void dispose() {} @override String toString(){ return { 'uuid': uuid, - 'widht': width, + 'width': width, 'height': height, 'src': src, 'complete': complete, diff --git a/packages/three_js_core/lib/textures/source.dart b/packages/three_js_core/lib/textures/source.dart index 1b9ffdb1..94591e78 100755 --- a/packages/three_js_core/lib/textures/source.dart +++ b/packages/three_js_core/lib/textures/source.dart @@ -1,3 +1,5 @@ +import 'dart:typed_data'; + import 'package:three_js_core/others/index.dart'; import 'package:three_js_core/textures/index.dart'; import 'package:three_js_math/three_js_math.dart'; @@ -24,7 +26,7 @@ class Source { void dispose(){ if(data is List){ for(final temp in data){ - if(temp is NativeArray){ + if(temp is TypedDataList){ temp.dispose(); } else if(temp is ImageElement){ @@ -35,8 +37,8 @@ class Source { else if(data is ImageElement){ (data as ImageElement).dispose(); } - else if(data is NativeArray){ - (data as NativeArray).dispose(); + else if(data is TypedDataList){ + (data as TypedDataList).dispose(); } } diff --git a/packages/three_js_core/pubspec.yaml b/packages/three_js_core/pubspec.yaml index 736da4e8..ce022457 100755 --- a/packages/three_js_core/pubspec.yaml +++ b/packages/three_js_core/pubspec.yaml @@ -1,10 +1,10 @@ name: three_js_core description: "Flutter three_js_core package converted from threejs and three_dart package made for three_js." -version: 0.2.8 +version: 0.3.0 homepage: https://github.com/Knightro63/three_js/tree/main/packages/three_js_core environment: - sdk: '>=3.3.2 <4.0.0' + sdk: '>=3.5.0 <4.0.0' flutter: ">=1.17.0" dependencies: @@ -13,9 +13,15 @@ dependencies: logger: ^2.5.0 three_js_math: ^0.2.5 web: ^1.1.1 + flutter_angle: ^0.3.9 dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^5.0.0 +dependency_overrides: + three_js_math: + path: ../three_js_math + flutter_angle: + path: ../../../flutter_angle/flutter_angle \ No newline at end of file diff --git a/packages/three_js_core_loaders/lib/ImageLoader/image_loader_app.dart b/packages/three_js_core_loaders/lib/ImageLoader/image_loader_app.dart index 254f2d55..0895f3a3 100644 --- a/packages/three_js_core_loaders/lib/ImageLoader/image_loader_app.dart +++ b/packages/three_js_core_loaders/lib/ImageLoader/image_loader_app.dart @@ -1,7 +1,6 @@ import 'dart:isolate'; import 'dart:io'; import '../utils/blob.dart'; -import 'package:three_js_math/three_js_math.dart'; import 'package:flutter/foundation.dart'; import 'package:flutter/services.dart'; import 'package:http/http.dart' as http; @@ -91,7 +90,7 @@ Future processImage(Uint8List? bytes, String? url, bool flipY) as return image != null?ImageElement( url: url, src: url, - data: Uint8Array.fromList(image.getBytes()), + data: Uint8List.fromList(image.getBytes()), width: image.width, height: image.height ):null; diff --git a/packages/three_js_gpu/lib/common/buffer.dart b/packages/three_js_gpu/lib/common/buffer.dart index aec43902..311f8880 100644 --- a/packages/three_js_gpu/lib/common/buffer.dart +++ b/packages/three_js_gpu/lib/common/buffer.dart @@ -1,6 +1,4 @@ import 'dart:typed_data'; -import 'package:three_js_math/three_js_math.dart'; - import './binding.dart'; import './buffer_utils.dart'; @@ -13,14 +11,14 @@ import './buffer_utils.dart'; */ class Buffer extends Binding { int bytesPerElement = Float32List.bytesPerElement; - Float32Array? _buffer; - Float32Array? get buffer => _buffer; + Float32List? _buffer; + Float32List? get buffer => _buffer; - Buffer(super.name,[Float32Array? buffer]) { + Buffer(super.name,[Float32List? buffer]) { _buffer = buffer; } - int get byteLength => getFloatLength(_buffer?.byteLength ); + int get byteLength => getFloatLength(_buffer?.lengthInBytes ); bool update() { return true; diff --git a/packages/three_js_gpu/lib/common/render_object.dart b/packages/three_js_gpu/lib/common/render_object.dart index 82443125..5bec71a9 100644 --- a/packages/three_js_gpu/lib/common/render_object.dart +++ b/packages/three_js_gpu/lib/common/render_object.dart @@ -231,7 +231,7 @@ class RenderObject { final nodeAttributes = this.getNodeBuilderState().nodeAttributes; final geometry = this.geometry; - final List>> attributes = []; + final List attributes = []; final vertexBuffers = new Set(); final attributesId = {}; diff --git a/packages/three_js_gpu/lib/common/storage_buffer_attribute.dart b/packages/three_js_gpu/lib/common/storage_buffer_attribute.dart index 2deb6fc8..cb316e38 100644 --- a/packages/three_js_gpu/lib/common/storage_buffer_attribute.dart +++ b/packages/three_js_gpu/lib/common/storage_buffer_attribute.dart @@ -1,31 +1,32 @@ -import "package:three_js_math/three_js_math.dart"; +import "dart:typed_data"; +import 'package:three_js_math/three_js_math.dart'; class StorageBufferAttribute extends BufferAttribute { StorageBufferAttribute(super.array, super.itemSize ); - factory StorageBufferAttribute.create(int count, int itemSize, [Type typeClass = Float32Array]) { - late final NativeArray data; + factory StorageBufferAttribute.create(int count, int itemSize, [Type typeClass = Float32List]) { + late final TypedDataList data; - if (typeClass == Int8Array) { - data = Int8Array(count*itemSize); + if (typeClass == Int8List) { + data = Int8List(count*itemSize); } - else if (typeClass == Uint8Array) { - data = Uint8Array(count*itemSize); + else if (typeClass == Uint8List) { + data = Uint8List(count*itemSize); } - else if (typeClass == Int16Array) { - data = Int16Array(count*itemSize); + else if (typeClass == Int16List) { + data = Int16List(count*itemSize); } - else if (typeClass == Uint16Array) { - data = Uint16Array(count*itemSize); + else if (typeClass == Uint16List) { + data = Uint16List(count*itemSize); } - else if (typeClass == Int32Array) { - data = Int32Array(count*itemSize); + else if (typeClass == Int32List) { + data = Int32List(count*itemSize); } - else if (typeClass == Uint32Array) { - data = Uint32Array(count*itemSize); + else if (typeClass == Uint32List) { + data = Uint32List(count*itemSize); } - else if (typeClass == Float32Array) { - data = Float32Array(count*itemSize); + else if (typeClass == Float32List) { + data = Float32List(count*itemSize); } return StorageBufferAttribute(data, itemSize); diff --git a/packages/three_js_gpu/lib/common/storage_instanced_buffer_attribute.dart b/packages/three_js_gpu/lib/common/storage_instanced_buffer_attribute.dart index c8bf70ac..49cfb644 100644 --- a/packages/three_js_gpu/lib/common/storage_instanced_buffer_attribute.dart +++ b/packages/three_js_gpu/lib/common/storage_instanced_buffer_attribute.dart @@ -1,8 +1,9 @@ import "package:three_js_math/three_js_math.dart"; +import 'dart:typed_data'; class StorageInstancedBufferAttribute extends InstancedBufferAttribute { StorageInstancedBufferAttribute(super.array, super.itemSize); factory StorageInstancedBufferAttribute.create( int count, int itemSize) { - return StorageInstancedBufferAttribute(Float32Array( count * itemSize ),itemSize); + return StorageInstancedBufferAttribute(Float32List( count * itemSize ),itemSize); } } \ No newline at end of file diff --git a/packages/three_js_gpu/lib/gpu_backend.dart b/packages/three_js_gpu/lib/gpu_backend.dart index 018582e9..0a82189f 100644 --- a/packages/three_js_gpu/lib/gpu_backend.dart +++ b/packages/three_js_gpu/lib/gpu_backend.dart @@ -1460,7 +1460,7 @@ class WebGPUBackend extends Backend { if ( currentSets.index != index ) { final buffer = this.get( index ).buffer; - final indexFormat = ( index.array instanceof Uint16Array ) ? GPUIndexFormat.Uint16 : GPUIndexFormat.Uint32; + final indexFormat = ( index.array instanceof Uint16List ) ? GPUIndexFormat.Uint16 : GPUIndexFormat.Uint32; passEncoderGPU.setIndexBuffer( buffer, indexFormat ); @@ -1592,9 +1592,9 @@ class WebGPUBackend extends Backend { final bindingsData = this.get( cameraIndex ); final indexesGPU = []; - final data = new Uint32Array( [ 0, 0, 0, 0 ] ); + final data = Uint32List.fromList( [ 0, 0, 0, 0 ] ); - for ( let i = 0, len = cameras.length; i < len; i ++ ) { + for ( int i = 0, len = cameras.length; i < len; i ++ ) { data[ 0 ] = i; diff --git a/packages/three_js_line/lib/line_geometry.dart b/packages/three_js_line/lib/line_geometry.dart index 66491326..a2a8995e 100644 --- a/packages/three_js_line/lib/line_geometry.dart +++ b/packages/three_js_line/lib/line_geometry.dart @@ -1,5 +1,5 @@ +import 'dart:typed_data'; import 'line_segments_geometry.dart'; -import 'package:three_js_math/three_js_math.dart'; class LineGeometry extends LineSegmentsGeometry { @@ -10,7 +10,7 @@ class LineGeometry extends LineSegmentsGeometry { LineGeometry setPositions( array ) { // converts [ x1, y1, z1, x2, y2, z2, ... ] to pairs format final length = array.length - 3; - final points = new Float32Array( 2 * length ); + final points = new Float32List( 2 * length ); for (int i = 0; i < length; i += 3 ) { points[ 2 * i ] = array[ i ]; @@ -30,7 +30,7 @@ class LineGeometry extends LineSegmentsGeometry { LineGeometry setColors( array ) { // converts [ r1, g1, b1, r2, g2, b2, ... ] to pairs format final length = array.length - 3; - final colors = new Float32Array( 2 * length ); + final colors = new Float32List( 2 * length ); for (int i = 0; i < length; i += 3 ) { colors[ 2 * i ] = array[ i ]; diff --git a/packages/three_js_line/lib/line_material.dart b/packages/three_js_line/lib/line_material.dart index fcb4cf54..dde684d3 100644 --- a/packages/three_js_line/lib/line_material.dart +++ b/packages/three_js_line/lib/line_material.dart @@ -1,3 +1,5 @@ +import 'dart:typed_data'; + import 'package:three_js_core/three_js_core.dart'; import 'package:three_js_math/three_js_math.dart'; @@ -425,9 +427,9 @@ class LineMaterial extends ShaderMaterial { clipping = true; // required for clipping support defaultAttributeValues = { - 'color': [1.0, 1.0, 1.0], - 'uv': [0.0, 0.0], - 'uv2': [0.0, 0.0] + 'color': Float32List.fromList([1.0, 1.0, 1.0]), + 'uv': Float32List.fromList([0.0, 0.0]), + 'uv2': Float32List.fromList([0.0, 0.0]) }; } diff --git a/packages/three_js_line/lib/line_segments2.dart b/packages/three_js_line/lib/line_segments2.dart index cb807034..46153f25 100644 --- a/packages/three_js_line/lib/line_segments2.dart +++ b/packages/three_js_line/lib/line_segments2.dart @@ -1,3 +1,5 @@ +import 'dart:typed_data'; + import 'line_material.dart'; import 'line_segments_geometry.dart'; import 'package:three_js_core/three_js_core.dart'; @@ -258,7 +260,7 @@ class LineSegments2 extends Mesh { final instanceStart = geometry.attributes['instanceStart']; final instanceEnd = geometry.attributes['instanceEnd']; - final lineDistances = Float32Array( (2 * instanceStart.count).toInt() ); + final lineDistances = Float32List( (2 * instanceStart.count).toInt() ); for ( int i = 0, j = 0, l = instanceStart.count; i < l; i ++, j += 2 ) { _start.fromBuffer( instanceStart, i ); diff --git a/packages/three_js_line/lib/line_segments_geometry.dart b/packages/three_js_line/lib/line_segments_geometry.dart index 3d11a6dd..14355e7a 100644 --- a/packages/three_js_line/lib/line_segments_geometry.dart +++ b/packages/three_js_line/lib/line_segments_geometry.dart @@ -1,3 +1,4 @@ +import 'dart:typed_data'; import 'package:three_js_core/three_js_core.dart'; import 'package:three_js_geometry/three_js_geometry.dart'; import 'package:three_js_math/three_js_math.dart'; @@ -40,7 +41,7 @@ class LineSegmentsGeometry extends InstancedBufferGeometry { return this; } - LineSegmentsGeometry setPositions(Float32Array lineSegments ) { + LineSegmentsGeometry setPositions(Float32List lineSegments ) { final instanceBuffer = new InstancedInterleavedBuffer( lineSegments, 6, 1 ); // xyz, xyz this.setAttributeFromString( 'instanceStart', new InterleavedBufferAttribute( instanceBuffer, 3, 0 ) ); // xyz @@ -52,7 +53,7 @@ class LineSegmentsGeometry extends InstancedBufferGeometry { return this; } - LineSegmentsGeometry setColors(Float32Array colors ) { + LineSegmentsGeometry setColors(Float32List colors ) { final instanceColorBuffer = new InstancedInterleavedBuffer( colors, 6, 1 ); // rgb, rgb this.setAttributeFromString( 'instanceColorStart', new InterleavedBufferAttribute( instanceColorBuffer, 3, 0 ) ); // rgb diff --git a/packages/three_js_line/lib/wireframe.dart b/packages/three_js_line/lib/wireframe.dart index ce562471..810f6e50 100644 --- a/packages/three_js_line/lib/wireframe.dart +++ b/packages/three_js_line/lib/wireframe.dart @@ -1,3 +1,5 @@ +import 'dart:typed_data'; + import 'line_material.dart'; import 'line_segments_geometry.dart'; import 'package:three_js_core/three_js_core.dart'; @@ -26,7 +28,7 @@ class Wireframe extends Mesh { final instanceStart = geometry.attributes['instanceStart']; final instanceEnd = geometry.attributes['instanceEnd']; - final lineDistances = Float32Array( (2 * instanceStart.count).toInt() ); + final lineDistances = Float32List( (2 * instanceStart.count).toInt() ); for (int i = 0, j = 0, l = instanceStart.count; i < l; i ++, j += 2 ) { _start.fromBuffer( instanceStart, i ); diff --git a/packages/three_js_math/CHANGELOG.md b/packages/three_js_math/CHANGELOG.md index f2577e91..b1ddcffc 100755 --- a/packages/three_js_math/CHANGELOG.md +++ b/packages/three_js_math/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.0 + +* Removed FlutterAngle + ## 0.2.6 * Added cloning support for Uint32BufferAttribute in BufferAttribute.clone diff --git a/packages/three_js_math/lib/buffer/base_buffer_attribute.dart b/packages/three_js_math/lib/buffer/base_buffer_attribute.dart index 41ea8780..3c2e96c3 100755 --- a/packages/three_js_math/lib/buffer/base_buffer_attribute.dart +++ b/packages/three_js_math/lib/buffer/base_buffer_attribute.dart @@ -1,6 +1,7 @@ +import 'dart:typed_data'; import 'package:three_js_math/three_js_math.dart'; -abstract class BaseBufferAttribute { +abstract class BaseBufferAttribute { late TData array; late int itemSize; @@ -22,7 +23,7 @@ abstract class BaseBufferAttribute { BaseBufferAttribute(); void dispose(){ - array.dispose(); + //array.dispose(); data?.dispose(); data = null; } diff --git a/packages/three_js_math/lib/buffer/buffer_attribute.dart b/packages/three_js_math/lib/buffer/buffer_attribute.dart index e06b7738..46b09ebe 100755 --- a/packages/three_js_math/lib/buffer/buffer_attribute.dart +++ b/packages/three_js_math/lib/buffer/buffer_attribute.dart @@ -20,7 +20,7 @@ class Ranges{ /// [Vector3], /// [Vector4], and /// [Color] classes may be helpful. -abstract class BufferAttribute extends BaseBufferAttribute { +abstract class BufferAttribute extends BaseBufferAttribute { final _vector = Vector3.zero(); final _vector2 = Vector2.zero(); List updateRanges = []; @@ -47,9 +47,9 @@ abstract class BufferAttribute extends BaseBufferAttr /// [normalized] -- (optional) Applies to integer data only. /// Indicates how the underlying data in the buffer maps to the values in the /// GLSL code. For instance, if [array] is an instance of - /// UInt16Array, and [normalized] is true, the values `0 - + /// Uint16List, and [normalized] is true, the values `0 - /// +65535` in the array data will be mapped to 0.0f - +1.0f in the GLSL - /// attribute. An Int16Array (signed) would map from -32768 - +32767 to -1.0f + /// attribute. An Int16List (signed) would map from -32768 - +32767 to -1.0f /// - +1.0f. If [normalized] is false, the values will be /// converted to floats unmodified, i.e. 32767 becomes 32767.0f. BufferAttribute(TData arrayList, int itemSize, [bool normalized = false]) { @@ -384,16 +384,16 @@ abstract class BufferAttribute extends BaseBufferAttr // return BufferAttribute(array, itemSize, false).copy(this); // } else if (type == "Float32BufferAttribute") { - final typed = array as Float32Array; + final typed = array as Float32List; return Float32BufferAttribute.fromList(Float32List(typed.length), itemSize, false).copy(this); } else if (type == "Uint8BufferAttribute") { - final typed = array as Uint8Array; + final typed = array as Uint8List; return Uint8BufferAttribute.fromList(Uint8List(typed.length), itemSize, false).copy(this); } else if (type == "Uint16BufferAttribute") { - final typed = array as Uint16Array; + final typed = array as Uint16List; return Uint16BufferAttribute.fromList(Uint16List(typed.length), itemSize, false).copy(this); } else if (type == "Uint32BufferAttribute") { - final typed = array as Uint32Array; + final typed = array as Uint32List; return Uint32BufferAttribute.fromList(Uint32List(typed.length), itemSize, false).copy(this); } else { throw ("BufferAttribute type: $type clone need support .... "); @@ -417,32 +417,32 @@ abstract class BufferAttribute extends BaseBufferAttr return result; } - static BufferAttribute fromUnknown(NativeArray arrayList, int itemSize, [bool normalized = false]){ - if(arrayList is Int8Array){ + static BufferAttribute fromUnknown(TypedData arrayList, int itemSize, [bool normalized = false]){ + if(arrayList is Int8List){ return Int8BufferAttribute(arrayList,itemSize,normalized); } - else if(arrayList is Uint8Array){ + else if(arrayList is Uint8List){ return Uint8BufferAttribute(arrayList,itemSize,normalized); } - else if(arrayList is Int16Array){ + else if(arrayList is Int16List){ return Int16BufferAttribute(arrayList,itemSize,normalized); } - else if(arrayList is Uint16Array){ + else if(arrayList is Uint16List){ return Uint16BufferAttribute(arrayList,itemSize,normalized); } - else if(arrayList is Int32Array){ + else if(arrayList is Int32List){ return Int32BufferAttribute(arrayList,itemSize,normalized); } - else if(arrayList is Uint32Array){ + else if(arrayList is Uint32List){ return Uint32BufferAttribute(arrayList,itemSize,normalized); } - else if(arrayList is Float32Array){ + else if(arrayList is Float32List){ return Float16BufferAttribute(arrayList,itemSize,normalized); } - else if(arrayList is Float32Array){ + else if(arrayList is Float32List){ return Float32BufferAttribute(arrayList,itemSize,normalized); } - else if(arrayList is Float64Array){ + else if(arrayList is Float64List){ return Float64BufferAttribute(arrayList,itemSize,normalized); } else{ @@ -451,69 +451,69 @@ abstract class BufferAttribute extends BaseBufferAttr } } -class Int8BufferAttribute extends BufferAttribute { +class Int8BufferAttribute extends BufferAttribute { Int8BufferAttribute(super.array, super.itemSize, [super.normalized = false]){ type = "Int8BufferAttribute"; } factory Int8BufferAttribute.fromList(List list, int itemSize,[bool normalized = false]){ - return Int8BufferAttribute(Int8Array.fromList(list),itemSize,normalized); + return Int8BufferAttribute(Int8List.fromList(list),itemSize,normalized); } } -class Uint8BufferAttribute extends BufferAttribute { +class Uint8BufferAttribute extends BufferAttribute { Uint8BufferAttribute(super.array, super.itemSize,[super.normalized = false]){ type = "Uint8BufferAttribute"; } factory Uint8BufferAttribute.fromList(List list, int itemSize,[bool normalized = false]){ - return Uint8BufferAttribute(Uint8Array.fromList(list),itemSize,normalized); + return Uint8BufferAttribute(Uint8List.fromList(list),itemSize,normalized); } } -class Uint8ClampedBufferAttribute extends BufferAttribute { +class Uint8ClampedBufferAttribute extends BufferAttribute { Uint8ClampedBufferAttribute(super.array, super.itemSize,[super.normalized = false]){ type = "Uint8ClampedBufferAttribute"; } factory Uint8ClampedBufferAttribute.fromList(List list, int itemSize,[bool normalized = false]){ - return Uint8ClampedBufferAttribute(Uint8Array.fromList(list),itemSize,normalized); + return Uint8ClampedBufferAttribute(Uint8List.fromList(list),itemSize,normalized); } } -class Int16BufferAttribute extends BufferAttribute { +class Int16BufferAttribute extends BufferAttribute { Int16BufferAttribute(super.array, super.itemSize,[super.normalized = false]){ type = "Int16BufferAttribute"; } factory Int16BufferAttribute.fromList(List list, int itemSize,[bool normalized = false]){ - return Int16BufferAttribute(Int16Array.fromList(list),itemSize,normalized); + return Int16BufferAttribute(Int16List.fromList(list),itemSize,normalized); } } // Int16BufferAttribute.prototype = Object.create( BufferAttribute.prototype ); // Int16BufferAttribute.prototype.constructor = Int16BufferAttribute; -class Uint16BufferAttribute extends BufferAttribute { +class Uint16BufferAttribute extends BufferAttribute { Uint16BufferAttribute(super.array, super.itemSize,[super.normalized = false]){ type = "Uint16BufferAttribute"; } factory Uint16BufferAttribute.fromList(List list, int itemSize,[bool normalized = false]){ - return Uint16BufferAttribute(Uint16Array.fromList(list),itemSize,normalized); + return Uint16BufferAttribute(Uint16List.fromList(list),itemSize,normalized); } } -class Int32BufferAttribute extends BufferAttribute { +class Int32BufferAttribute extends BufferAttribute { Int32BufferAttribute(super.array, super.itemSize,[super.normalized = false]){ type = "Int32BufferAttribute"; } factory Int32BufferAttribute.fromList(List list, int itemSize,[bool normalized = false]){ - return Int32BufferAttribute(Int32Array.fromList(list),itemSize,normalized); + return Int32BufferAttribute(Int32List.fromList(list),itemSize,normalized); } } -class Uint32BufferAttribute extends BufferAttribute { +class Uint32BufferAttribute extends BufferAttribute { Uint32BufferAttribute(super.array, super.itemSize,[super.normalized = false]){ type = "Uint32BufferAttribute"; } factory Uint32BufferAttribute.fromList(List list, int itemSize,[bool normalized = false]){ - return Uint32BufferAttribute(Uint32Array.fromList(list),itemSize,normalized); + return Uint32BufferAttribute(Uint32List.fromList(list),itemSize,normalized); } } @@ -522,24 +522,24 @@ class Float16BufferAttribute extends BufferAttribute { type = "Float16BufferAttribute"; } factory Float16BufferAttribute.fromList(List list, int itemSize,[bool normalized = false]){ - return Float16BufferAttribute(Float32Array.fromList(list),itemSize,normalized); + return Float16BufferAttribute(Float32List.fromList(list),itemSize,normalized); } } -class Float32BufferAttribute extends BufferAttribute { +class Float32BufferAttribute extends BufferAttribute { Float32BufferAttribute(super.array, super.itemSize,[super.normalized = false]){ type = "Float32BufferAttribute"; } factory Float32BufferAttribute.fromList(List list, int itemSize,[bool normalized = false]){ - return Float32BufferAttribute(Float32Array.fromList(list),itemSize,normalized); + return Float32BufferAttribute(Float32List.fromList(list),itemSize,normalized); } } -class Float64BufferAttribute extends BufferAttribute { +class Float64BufferAttribute extends BufferAttribute { Float64BufferAttribute(super.array, super.itemSize,[super.normalized = false]){ type = "Float64BufferAttribute"; } factory Float64BufferAttribute.fromList(List list, int itemSize,[bool normalized = false]){ - return Float64BufferAttribute(Float64Array.fromList(list),itemSize,normalized); + return Float64BufferAttribute(Float64List.fromList(list),itemSize,normalized); } } diff --git a/packages/three_js_math/lib/buffer/interleaved_buffer.dart b/packages/three_js_math/lib/buffer/interleaved_buffer.dart index 52ed0a5e..3ffa507e 100755 --- a/packages/three_js_math/lib/buffer/interleaved_buffer.dart +++ b/packages/three_js_math/lib/buffer/interleaved_buffer.dart @@ -1,7 +1,6 @@ import 'dart:typed_data'; import '../others/constants.dart'; import '../math/index.dart'; -import 'package:flutter_angle/flutter_angle.dart'; /// [Interleaved] means that multiple attributes, possibly of different types, /// (e.g., position, normal, uv, color) are packed into a single array buffer. @@ -9,7 +8,7 @@ import 'package:flutter_angle/flutter_angle.dart'; /// An introduction into interleaved arrays can be found here: /// [Interleaved array basics](https://blog.tojicode.com/2011/05/interleaved-array-basics.html) class InterleavedBuffer { - NativeArray array; + TypedDataList array; int stride; late int meshPerAttribute; late int count; @@ -26,7 +25,7 @@ class InterleavedBuffer { String type = "InterleavedBuffer"; void dispose(){ - array.dispose(); + //array.dispose(); } /// [array] -- A typed array with a shared buffer. Stores the @@ -44,7 +43,7 @@ class InterleavedBuffer { /// [stride] -- The number of typed-array elements per vertex. factory InterleavedBuffer.fromList(TypedData array, int stride) { final totalLen = array.lengthInBytes; - return InterleavedBuffer(Float32Array(totalLen).set(array.buffer.asFloat32List()), stride); + return InterleavedBuffer(Float32List(totalLen).set(array.buffer.asFloat32List()), stride); } set needsUpdate(bool value) { @@ -69,7 +68,7 @@ class InterleavedBuffer { /// Copies another [source] to this [source]. InterleavedBuffer copy(InterleavedBuffer source) { - array = source.array.clone(); + array = source.array.sublist(0) as TypedDataList; count = source.count; stride = source.stride; usage = source.usage; @@ -144,7 +143,7 @@ class InterleavedBuffer { // if ( data.arrayBuffers[ this.array.buffer._uuid ] == null ) { - // data.arrayBuffers[ this.array.buffer._uuid ] = Array.prototype.slice.call( new Uint32Array( this.array.buffer ) ); + // data.arrayBuffers[ this.array.buffer._uuid ] = Array.prototype.slice.call( Uint32List.fromList( this.array.buffer ) ); // } diff --git a/packages/three_js_math/lib/buffer/interleaved_buffer_attribute.dart b/packages/three_js_math/lib/buffer/interleaved_buffer_attribute.dart index fa2b3fce..2599b1e2 100755 --- a/packages/three_js_math/lib/buffer/interleaved_buffer_attribute.dart +++ b/packages/three_js_math/lib/buffer/interleaved_buffer_attribute.dart @@ -1,4 +1,5 @@ import 'package:three_js_math/three_js_math.dart'; +import 'dart:typed_data'; final Vector3 _vector = Vector3.zero(); @@ -15,7 +16,7 @@ class InterleavedBufferAttribute extends BufferAttribute{ int itemSize, this.offset, [bool _normalized = false] - ):super(Float32Array(0),itemSize, _normalized){ + ):super(Float32List(0),itemSize, _normalized){ this.data = data; type = "InterleavedBufferAttribute"; this.itemSize = itemSize; @@ -28,8 +29,8 @@ class InterleavedBufferAttribute extends BufferAttribute{ } @override - NativeArray get array { - return data?.array ?? Uint16Array(0); + TypedDataList get array { + return data?.array ?? Uint16List(0); } @override diff --git a/packages/three_js_math/lib/math/math_util.dart b/packages/three_js_math/lib/math/math_util.dart index bebe552a..49347fd4 100755 --- a/packages/three_js_math/lib/math/math_util.dart +++ b/packages/three_js_math/lib/math/math_util.dart @@ -1,4 +1,3 @@ -import 'package:flutter_angle/flutter_angle.dart'; import 'package:uuid/uuid.dart'; import 'dart:typed_data'; import 'dart:math' as math; @@ -7,8 +6,16 @@ final _floatView = Float32List(1); final _int32View = Int32List.view(_floatView.buffer); extension ListExtension on List{ - void set(List newList, [int index = 0]) { - setAll(index, newList.sublist(0, math.min(newList.length, length))); + void dispose(){} + + dynamic set(List newList, [int index = 0]) { + this.setAll(index, newList.sublist(0, math.min(newList.length, length))); + + return this; + } + + dynamic copy(List newList){ + return set(newList); } T? getMinValue() { @@ -211,21 +218,21 @@ class MathUtils{ /// @param {TypedArray} array - The typed array that defines the data type of the value. /// @return {number} The denormalize (float) value in the range `[0,1]`. /// - static double denormalize(num value, NativeArray array ) { + static double denormalize(num value, TypedData array ) { switch (array.runtimeType) { - case Float32Array: + case Float32List: return value*1.0; - case Uint32Array: + case Uint32List: return value / 4294967295.0; - case Uint16Array: + case Uint16List: return value / 65535.0; - case Uint8Array: + case Uint8List: return value / 255.0; - case Int32Array: + case Int32List: return math.max( value / 2147483647.0, - 1.0 ); - case Int16Array: + case Int16List: return math.max( value / 32767.0, - 1.0 ); - case Int8Array: + case Int8List: return math.max( value / 127.0, - 1.0 ); default: throw( 'Invalid component type.' ); @@ -239,21 +246,21 @@ class MathUtils{ /// @param {TypedArray} array - The typed array that defines the data type of the value. /// @return {number} The normalize value. /// - static double normalize( num value, NativeArray array ) { + static double normalize( num value, TypedData array ) { switch ( array.runtimeType ) { - case Float32Array: + case Float32List: return value.toDouble(); - case Uint32Array: + case Uint32List: return ( value * 4294967295.0 ).roundToDouble(); - case Uint16Array: + case Uint16List: return ( value * 65535.0 ).roundToDouble(); - case Uint8Array: + case Uint8List: return ( value * 255.0 ).roundToDouble(); - case Int32Array: + case Int32List: return ( value * 2147483647.0 ).roundToDouble(); - case Int16Array: + case Int16List: return ( value * 32767.0 ).roundToDouble(); - case Int8Array: + case Int8List: return ( value * 127.0 ).roundToDouble(); default: throw( 'Invalid component type.' ); diff --git a/packages/three_js_math/lib/matrix/matrix2.dart b/packages/three_js_math/lib/matrix/matrix2.dart index 40ade1dd..cbfcf770 100644 --- a/packages/three_js_math/lib/matrix/matrix2.dart +++ b/packages/three_js_math/lib/matrix/matrix2.dart @@ -1,33 +1,29 @@ import 'dart:typed_data'; -import 'package:three_js_math/three_js_math.dart'; - -/** - * Represents a 2x2 matrix. - * - * A Note on Row-Major and Column-Major Ordering: - * - * The constructor and {@link Matrix2#set} method take arguments in - * [row-major]{@link https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order} - * order, while internally they are stored in the {@link Matrix2#elements} array in column-major order. - * This means that calling: - * ```js - * const m = new THREE.Matrix2(); - * m.set( 11, 12, - * 21, 22 ); - * ``` - * will result in the elements array containing: - * ```js - * m.elements = [ 11, 21, - * 12, 22 ]; - * ``` - * and internally all calculations are performed using column-major ordering. - * However, as the actual ordering makes no difference mathematically and - * most people are used to thinking about matrices in row-major order, the - * three.js documentation shows matrices in row-major order. Just bear in - * mind that if you are reading the source code, you'll have to take the - * transpose of any matrices outlined here to make sense of the calculations. - */ +/// +/// Represents a 2x2 matrix. +/// +/// A Note on Row-Major and Column-Major Ordering: +/// +/// The constructor and {@link Matrix2#set} method take arguments in +/// [row-major]{@link https://en.wikipedia.org/wiki/Row-_and_column-major_order#Column-major_order} +/// order, while internally they are stored in the {@link Matrix2#elements} array in column-major order. +/// This means that calling: +/// ```dart +/// final m = Matrix2(); +/// m.set( 11, 12, 21, 22 ); +/// ``` +/// will result in the elements array containing: +/// ```dart +/// m.storage = [ 11, 21, 12, 22 ]; +/// ``` +/// and internally all calculations are performed using column-major ordering. +/// However, as the actual ordering makes no difference mathematically and +/// most people are used to thinking about matrices in row-major order, the +/// three.js documentation shows matrices in row-major order. Just bear in +/// mind that if you are reading the source code, you'll have to take the +/// transpose of any matrices outlined here to make sense of the calculations. +/// class Matrix2 { String type = "Matrix2"; late Float32List storage; @@ -64,7 +60,7 @@ class Matrix2 { return this; } - Matrix2 fromNativeArray(NativeArray array, [int offset = 0 ]) { + Matrix2 fromList(TypedDataList array, [int offset = 0 ]) { for (int i = 0; i < 4; i ++ ) { this.storage[ i ] = array[ i + offset ].toDouble(); } diff --git a/packages/three_js_math/lib/matrix/matrix3.dart b/packages/three_js_math/lib/matrix/matrix3.dart index 1168090e..b2dc5ec4 100755 --- a/packages/three_js_math/lib/matrix/matrix3.dart +++ b/packages/three_js_math/lib/matrix/matrix3.dart @@ -1,9 +1,6 @@ import 'dart:typed_data'; - -import 'package:flutter_angle/flutter_angle.dart'; import 'package:three_js_math/three_js_math.dart'; import 'dart:math' as math; -import 'index.dart'; /// A class representing a 3x3 /// [matrix](https://en.wikipedia.org/wiki/Matrix_(mathematics)). @@ -351,7 +348,7 @@ class Matrix3 { return true; } - Matrix3 factory(NativeArray array, {int offset = 0}) { + Matrix3 factory(List array, {int offset = 0}) { for (int i = 0; i < 9; i++) { storage[i] = array[i + offset].toDouble(); } diff --git a/packages/three_js_math/lib/matrix/matrix4.dart b/packages/three_js_math/lib/matrix/matrix4.dart index cbc42e1c..101cd249 100755 --- a/packages/three_js_math/lib/matrix/matrix4.dart +++ b/packages/three_js_math/lib/matrix/matrix4.dart @@ -1006,7 +1006,31 @@ class Matrix4 { return array; } + TypedDataList copyIntoList(TypedDataList array, [int offset = 0]) { + final te = storage; + + array[offset] = te[0]; + array[offset + 1] = te[1]; + array[offset + 2] = te[2]; + array[offset + 3] = te[3]; + array[offset + 4] = te[4]; + array[offset + 5] = te[5]; + array[offset + 6] = te[6]; + array[offset + 7] = te[7]; + + array[offset + 8] = te[8]; + array[offset + 9] = te[9]; + array[offset + 10] = te[10]; + array[offset + 11] = te[11]; + + array[offset + 12] = te[12]; + array[offset + 13] = te[13]; + array[offset + 14] = te[14]; + array[offset + 15] = te[15]; + + return array; + } List toList() { return storage.sublist(0); } diff --git a/packages/three_js_math/lib/others/color_util.dart b/packages/three_js_math/lib/others/color_util.dart index 84650df1..ad82e03f 100755 --- a/packages/three_js_math/lib/others/color_util.dart +++ b/packages/three_js_math/lib/others/color_util.dart @@ -130,15 +130,15 @@ class Color{ return this; } - Color fromNativeArray(NativeArray list,[int offset = 0]) { - storage[0] = list[offset].toDouble(); - storage[1] = list[offset+1].toDouble(); - storage[2] = list[offset+2].toDouble(); - if(list.length > 3){ - storage[3] = list[offset+3].toDouble(); - } - return this; - } + // Color fromNativeArray(NativeArray list,[int offset = 0]) { + // storage[0] = list[offset].toDouble(); + // storage[1] = list[offset+1].toDouble(); + // storage[2] = list[offset+2].toDouble(); + // if(list.length > 3){ + // storage[3] = list[offset+3].toDouble(); + // } + // return this; + // } Color fromUnknown(list,[int offset = 0]) { storage[0] = list[offset].toDouble(); storage[1] = list[offset+1].toDouble(); @@ -148,7 +148,7 @@ class Color{ } return this; } - Color fromList(List list,[int offset = 0]) { + Color fromList(List list,[int offset = 0]) { storage[0] = list[offset].toDouble(); storage[1] = list[offset+1].toDouble(); storage[2] = list[offset+2].toDouble(); @@ -157,7 +157,7 @@ class Color{ } return this; } - Color copyFromArray(List list,[int offset = 0]) { + Color copyFromArray(List list,[int offset = 0]) { storage[0] = list[offset].toDouble(); storage[1] = list[offset+1].toDouble(); storage[2] = list[offset+2].toDouble(); @@ -166,7 +166,7 @@ class Color{ } return this; } - NativeArray copyIntoArray(array, [int offset = 0]) { + TypedDataList copyIntoArray(TypedDataList array, [int offset = 0]) { array[offset] = storage[0]; array[offset + 1] = storage[1]; array[offset + 2] = storage[2]; diff --git a/packages/three_js_math/lib/three_js_math.dart b/packages/three_js_math/lib/three_js_math.dart index 6d057adf..b6269324 100755 --- a/packages/three_js_math/lib/three_js_math.dart +++ b/packages/three_js_math/lib/three_js_math.dart @@ -8,4 +8,3 @@ export 'rotation/index.dart'; export 'buffer/index.dart'; export 'others/index.dart'; export 'math/index.dart'; -export 'package:flutter_angle/flutter_angle.dart'; \ No newline at end of file diff --git a/packages/three_js_math/lib/vector/vector.dart b/packages/three_js_math/lib/vector/vector.dart index 304e4aed..1d25347d 100755 --- a/packages/three_js_math/lib/vector/vector.dart +++ b/packages/three_js_math/lib/vector/vector.dart @@ -1,5 +1,4 @@ import 'dart:typed_data'; -import 'package:flutter_angle/flutter_angle.dart'; import '../buffer/index.dart'; import '../matrix/matrix3.dart'; @@ -52,10 +51,12 @@ abstract class Vector { Vector normalize(); //double angle(); Vector setLength(double length); - Vector fromNativeArray(NativeArray array, [int offset = 0]); + //Vector fromNativeArray(NativeArray array, [int offset = 0]); + Vector fromArray(List array, [int offset = 0]); Vector copyFromUnknown(array, [int offset = 0]); List toNumArray(List array, [int offset = 0]); - NativeArray copyIntoNativeArray(NativeArray array, [int offset = 0]); + //NativeArray copyIntoNativeArray(NativeArray array, [int offset = 0]); + Float32List copyIntoList(Float32List array, [int offset = 0]); Vector copyFromArray(List array, [int offset = 0]); List copyIntoArray([List array, int offset = 0]); diff --git a/packages/three_js_math/lib/vector/vector2.dart b/packages/three_js_math/lib/vector/vector2.dart index b397d55d..ca289a94 100755 --- a/packages/three_js_math/lib/vector/vector2.dart +++ b/packages/three_js_math/lib/vector/vector2.dart @@ -1,8 +1,9 @@ +import 'dart:typed_data'; + import '../buffer/index.dart'; import 'dart:math' as math; import '../matrix/matrix3.dart'; import 'vector.dart'; -import 'package:flutter_angle/flutter_angle.dart'; class Vector2 extends Vector{ @@ -331,7 +332,7 @@ class Vector2 extends Vector{ return array; } @override - NativeArray copyIntoNativeArray(NativeArray array, [int offset = 0]) { + Float32List copyIntoList(Float32List array, [int offset = 0]) { array[offset] = storage[0]; array[offset + 1] = storage[1]; @@ -352,7 +353,7 @@ class Vector2 extends Vector{ return this; } @override - Vector2 fromNativeArray(NativeArray array, [int offset = 0]) { + Vector2 fromArray(List array, [int offset = 0]) { x = array[offset].toDouble(); y = array[offset + 1].toDouble(); diff --git a/packages/three_js_math/lib/vector/vector3.dart b/packages/three_js_math/lib/vector/vector3.dart index 5c69f077..80877fce 100755 --- a/packages/three_js_math/lib/vector/vector3.dart +++ b/packages/three_js_math/lib/vector/vector3.dart @@ -5,7 +5,6 @@ import 'dart:math' as math; import '../math/index.dart'; import '../buffer/index.dart'; import 'index.dart'; -import 'package:flutter_angle/flutter_angle.dart'; final _vector3 = Vector3(0, 0, 0); final _quaternion = Quaternion(); @@ -630,7 +629,7 @@ class Vector3 extends Vector{ return (v.x == x) && (v.y == y); } @override - Vector3 fromNativeArray(NativeArray array, [int offset = 0]) { + Vector3 fromArray(List array, [int offset = 0]) { x = array[offset].toDouble(); y = array[offset + 1].toDouble(); z = array[offset + 2].toDouble(); @@ -646,7 +645,7 @@ class Vector3 extends Vector{ return array; } @override - NativeArray copyIntoNativeArray(NativeArray array, [int offset = 0]) { + Float32List copyIntoList(Float32List array, [int offset = 0]) { array[offset] = storage[0]; array[offset + 1] = storage[1]; array[offset + 2] = storage[2]; diff --git a/packages/three_js_math/lib/vector/vector4.dart b/packages/three_js_math/lib/vector/vector4.dart index 73d0c94f..c00299a4 100755 --- a/packages/three_js_math/lib/vector/vector4.dart +++ b/packages/three_js_math/lib/vector/vector4.dart @@ -4,7 +4,6 @@ import 'dart:math' as math; import '../matrix/index.dart'; import '../rotation/index.dart'; import 'index.dart'; -import 'package:flutter_angle/flutter_angle.dart'; class Vector4 extends Vector{ String type = "Vector4"; @@ -635,7 +634,7 @@ class Vector4 extends Vector{ return array; } @override - NativeArray copyIntoNativeArray(NativeArray array, [int offset = 0]) { + Float32List copyIntoList(Float32List array, [int offset = 0]) { array[offset] = storage[0]; array[offset + 1] = storage[1]; array[offset + 2] = storage[2]; @@ -644,7 +643,7 @@ class Vector4 extends Vector{ return array; } @override - Vector4 fromNativeArray(NativeArray array, [int offset = 0]) { + Vector4 fromArray(List array, [int offset = 0]) { x = array[offset].toDouble(); y = array[offset + 1].toDouble(); z = array[offset + 2].toDouble(); diff --git a/packages/three_js_math/pubspec.yaml b/packages/three_js_math/pubspec.yaml index dd809385..1db282c4 100755 --- a/packages/three_js_math/pubspec.yaml +++ b/packages/three_js_math/pubspec.yaml @@ -1,17 +1,17 @@ name: three_js_math description: "Flutter three_js_math package converted from threejs and three_dart package to be used with three_js." -version: 0.2.6 +version: 0.3.0 homepage: https://github.com/Knightro63/three_js/tree/main/packages/three_js_math environment: - sdk: '>=3.3.2 <4.0.0' + sdk: '>=3.5.0 <4.0.0' flutter: ">=1.17.0" dependencies: flutter: sdk: flutter uuid: ^4.4.0 - flutter_angle: ^0.3.9 + #flutter_angle: ^0.3.9 dev_dependencies: flutter_test: diff --git a/packages/three_js_modifers/lib/buffergeometry_utils.dart b/packages/three_js_modifers/lib/buffergeometry_utils.dart index 2b41376e..7740e42b 100644 --- a/packages/three_js_modifers/lib/buffergeometry_utils.dart +++ b/packages/three_js_modifers/lib/buffergeometry_utils.dart @@ -1,5 +1,5 @@ import 'dart:math' as math; - +import 'dart:typed_data'; import 'package:three_js_core/three_js_core.dart'; import 'package:three_js_math/three_js_math.dart'; @@ -31,7 +31,7 @@ class BufferGeometryUtils{ final name = attributeNames[ i ]; final attr = geometry.attributes[ name ]; tmpAttributes[ name ] = Float32BufferAttribute( - Float32Array( attr.count * attr.itemSize ), + Float32List( attr.count * attr.itemSize ), attr.itemSize, attr.normalized ); @@ -41,7 +41,7 @@ class BufferGeometryUtils{ if ( ! tmpMorphAttributes[ name ] ) tmpMorphAttributes[ name ] = []; int j = 0; morphAttributes.forEach( ( morphAttr){ - final array = Float32Array(morphAttr.count * morphAttr.itemSize);//morphAttr.array.constructor( morphAttr.count * morphAttr.itemSize ); + final array = Float32List(morphAttr.count * morphAttr.itemSize);//morphAttr.array.constructor( morphAttr.count * morphAttr.itemSize ); tmpMorphAttributes[ name ][ j ] = Float32BufferAttribute(array, morphAttr.itemSize, morphAttr.normalized);//morphAttr.constructor( array, morphAttr.itemSize, morphAttr.normalized ); j++; } ); @@ -281,12 +281,12 @@ class BufferGeometryUtils{ } // Create a new array to hold all merged attribute data - final array = Float32Array(count * itemSize); + final array = Float32List(count * itemSize); int offset = 0; for (final attr in attributes) { - final Float32Array srcArray = attr.array as Float32Array; - array.set(srcArray.toDartList(), offset); + final Float32List srcArray = attr.array as Float32List; + array.set(srcArray, offset); offset += srcArray.length; } return Float32BufferAttribute(array, itemSize, normalized); diff --git a/packages/three_js_modifers/lib/edge_split_modifier.dart b/packages/three_js_modifers/lib/edge_split_modifier.dart index fdd2ea30..3b707d10 100644 --- a/packages/three_js_modifers/lib/edge_split_modifier.dart +++ b/packages/three_js_modifers/lib/edge_split_modifier.dart @@ -1,3 +1,5 @@ +import 'dart:typed_data'; + import 'package:three_js_core/three_js_core.dart'; import 'package:three_js_math/three_js_math.dart'; import './buffergeometry_utils.dart'; @@ -10,7 +12,7 @@ class EdgeSplitModifier { BufferGeometry modify(BufferGeometry geometry, cutOffAngle, [bool tryKeepNormals = true ]) { bool hadNormals = false; - Float32Array? oldNormals; + Float32List? oldNormals; if ( geometry.attributes['normal'] != null) { hadNormals = true; @@ -28,15 +30,15 @@ class EdgeSplitModifier { geometry = BufferGeometryUtils.mergeVertices( geometry ); } - final NativeArray indexes = geometry.index!.array as NativeArray; + final TypedDataList indexes = geometry.index!.array; final positions = geometry.getAttributeFromString( 'position' ).array; - late Float32Array normals; + late Float32List normals; late List pointToIndexMap; final splitIndexes = []; void computeNormals() { - normals = Float32Array( indexes.length * 3 ); + normals = Float32List( indexes.length * 3 ); for (int i = 0; i < indexes.length; i += 3 ) { num index = indexes[ i ]; @@ -151,13 +153,13 @@ class EdgeSplitModifier { final newAttributes = {}; for ( final name in geometry.attributes.keys) { final oldAttribute = geometry.attributes[ name ] as Float32BufferAttribute; - final newArray = Float32Array(( indexes.length + splitIndexes.length ) * oldAttribute.itemSize);//oldAttribute.array.constructor( ( indexes.length + splitIndexes.length ) * oldAttribute.itemSize ); + final newArray = Float32List(( indexes.length + splitIndexes.length ) * oldAttribute.itemSize);//oldAttribute.array.constructor( ( indexes.length + splitIndexes.length ) * oldAttribute.itemSize ); newArray.set( oldAttribute.array.toList() ); newAttributes[name] = Float32BufferAttribute( newArray, oldAttribute.itemSize, oldAttribute.normalized ); } - final newIndexes = Uint32Array( indexes.length ); - newIndexes.set( indexes.toDartList() ); + final newIndexes = Uint32List( indexes.length ); + newIndexes.set( indexes ); for (int i = 0; i < splitIndexes.length; i ++ ) { diff --git a/packages/three_js_modifers/lib/loop_subdivision.dart b/packages/three_js_modifers/lib/loop_subdivision.dart index c0b2ea12..937f65ca 100644 --- a/packages/three_js_modifers/lib/loop_subdivision.dart +++ b/packages/three_js_modifers/lib/loop_subdivision.dart @@ -284,7 +284,7 @@ class LoopSubdivision { const newTriangles = 4; /* maximum number of triangles */ final arrayLength = (vertexCount * attribute.itemSize) * newTriangles; final List floatArray = List.filled(arrayLength, 0, growable: true);//attribute.array.sublist(0,arrayLength);//.constructor(arrayLength); - floatArray.replaceRange(0, attribute.array.length, attribute.array.sublist(0)); + floatArray.replaceRange(0, attribute.array.length, List.from(attribute.array)); final processGroups = (attributeName == 'position' && ! morph && existing.groups.length > 0); int? groupStart; int? groupMaterial; diff --git a/packages/three_js_modifers/lib/simplify_modifer.dart b/packages/three_js_modifers/lib/simplify_modifer.dart index aca80828..7f847b23 100644 --- a/packages/three_js_modifers/lib/simplify_modifer.dart +++ b/packages/three_js_modifers/lib/simplify_modifer.dart @@ -64,7 +64,7 @@ class SimplifyModifier { // add faces - BufferAttribute>? index = geometry.getIndex(); + BufferAttribute? index = geometry.getIndex(); if ( index != null ) { for (int i = 0; i < index.count; i += 3 ) { diff --git a/packages/three_js_objects/lib/gpu_computation_renderer.dart b/packages/three_js_objects/lib/gpu_computation_renderer.dart index 1f6bfe22..23a17cd9 100644 --- a/packages/three_js_objects/lib/gpu_computation_renderer.dart +++ b/packages/three_js_objects/lib/gpu_computation_renderer.dart @@ -1,3 +1,5 @@ +import 'dart:typed_data'; + import 'package:three_js_core/three_js_core.dart'; import 'package:three_js_math/three_js_math.dart'; @@ -326,7 +328,7 @@ class GPUComputationRenderer { }; createTexture = () { - final data = Float32Array( sizeX * sizeY * 4 ); + final data = Float32List( sizeX * sizeY * 4 ); final texture = DataTexture( data, sizeX, sizeY, RGBAFormat, FloatType ); texture.needsUpdate = true; return texture; diff --git a/packages/three_js_objects/lib/lights/light_probe_generator_platform.dart b/packages/three_js_objects/lib/lights/light_probe_generator_platform.dart index 53c6b668..2133f323 100644 --- a/packages/three_js_objects/lib/lights/light_probe_generator_platform.dart +++ b/packages/three_js_objects/lib/lights/light_probe_generator_platform.dart @@ -1,4 +1,5 @@ import 'dart:math' as math; +import 'dart:typed_data'; import 'package:three_js_core/three_js_core.dart'; import 'package:three_js_math/three_js_math.dart'; @@ -93,14 +94,14 @@ class LightProbeGenerator { for (int faceIndex = 0; faceIndex < 6; faceIndex ++ ) { final imageWidth = cubeRenderTarget.width; // assumed to be square - NativeArray data; + TypedDataList data; if ( dataType == HalfFloatType ) { - data = Uint16Array( imageWidth * imageWidth * 4 ); + data = Uint16List( imageWidth * imageWidth * 4 ); } else { // assuming UnsignedByteType - data = Uint8Array( imageWidth * imageWidth * 4 ); + data = Uint8List( imageWidth * imageWidth * 4 ); } renderer.readRenderTargetPixels( cubeRenderTarget, 0, 0, imageWidth, imageWidth, data, faceIndex ); diff --git a/packages/three_js_objects/lib/lights/light_probe_generator_web.dart b/packages/three_js_objects/lib/lights/light_probe_generator_web.dart index 8bdd206d..ee15403f 100644 --- a/packages/three_js_objects/lib/lights/light_probe_generator_web.dart +++ b/packages/three_js_objects/lib/lights/light_probe_generator_web.dart @@ -1,5 +1,6 @@ import 'dart:js_interop'; import 'dart:math' as math; +import 'dart:typed_data'; import 'package:web/web.dart' as html; import 'package:three_js_core/three_js_core.dart'; import 'package:three_js_math/three_js_math.dart'; @@ -108,14 +109,14 @@ class LightProbeGenerator { for (int faceIndex = 0; faceIndex < 6; faceIndex ++ ) { final imageWidth = cubeRenderTarget.width; // assumed to be square - NativeArray data; + TypedDataList data; if ( dataType == HalfFloatType ) { - data = Uint16Array( imageWidth * imageWidth * 4 ); + data = Uint16List( imageWidth * imageWidth * 4 ); } else { // assuming UnsignedByteType - data = Uint8Array( imageWidth * imageWidth * 4 ); + data = Uint8List( imageWidth * imageWidth * 4 ); } renderer.readRenderTargetPixels( cubeRenderTarget, 0, 0, imageWidth, imageWidth, data, faceIndex ); diff --git a/packages/three_js_objects/lib/marching_cubes.dart b/packages/three_js_objects/lib/marching_cubes.dart index 7631dcc7..0e75c0aa 100644 --- a/packages/three_js_objects/lib/marching_cubes.dart +++ b/packages/three_js_objects/lib/marching_cubes.dart @@ -17,13 +17,13 @@ class MarchingCubes extends Mesh{ late double halfsize; late double delta; - late Float32Array field; - late Float32Array normalCache; - late Float32Array palette; - late Float32Array positionArray; - late Float32Array normalArray; - late Float32Array uvArray; - late Float32Array colorArray; + late Float32List field; + late Float32List normalCache; + late Float32List palette; + late Float32List positionArray; + late Float32List normalArray; + late Float32List uvArray; + late Float32List colorArray; int maxPolyCount; late int yd; @@ -52,25 +52,25 @@ class MarchingCubes extends Mesh{ yd = size.toInt(); zd = size2.toInt(); - field = Float32Array(size3.toInt()); - normalCache = Float32Array(size3.toInt() * 3); - palette = Float32Array(size3.toInt() * 3); + field = Float32List(size3.toInt()); + normalCache = Float32List(size3.toInt() * 3); + palette = Float32List(size3.toInt() * 3); final maxVertexCount = maxPolyCount * 3; - positionArray = Float32Array(maxVertexCount * 3); + positionArray = Float32List(maxVertexCount * 3); geometry!.setAttributeFromString('position', Float32BufferAttribute(positionArray,3)); - normalArray = Float32Array( maxVertexCount * 3); + normalArray = Float32List( maxVertexCount * 3); geometry!.setAttributeFromString('normal', Float32BufferAttribute(normalArray,3)); if(enableUvs){ - uvArray = Float32Array(maxVertexCount * 2 ); + uvArray = Float32List(maxVertexCount * 2 ); geometry!.setAttributeFromString('uv', Float32BufferAttribute(uvArray,3)); } if (enableColors){ - colorArray = Float32Array(maxVertexCount * 3 ); + colorArray = Float32List(maxVertexCount * 3 ); geometry!.setAttributeFromString('color',Float32BufferAttribute(colorArray,3)); } diff --git a/packages/three_js_objects/lib/tube_painter.dart b/packages/three_js_objects/lib/tube_painter.dart index effd6205..71683b37 100644 --- a/packages/three_js_objects/lib/tube_painter.dart +++ b/packages/three_js_objects/lib/tube_painter.dart @@ -1,6 +1,7 @@ import 'package:three_js_core/three_js_core.dart'; import 'package:three_js_math/three_js_math.dart'; import 'dart:math' as math; +import 'dart:typed_data'; class TubePainter{ int BUFFER_SIZE = 1000000 * 3; @@ -30,13 +31,13 @@ class TubePainter{ final matrix2 = new Matrix4(); TubePainter(){ - positions = Float32BufferAttribute( new Float32Array( BUFFER_SIZE ), 3 ); + positions = Float32BufferAttribute(Float32List( BUFFER_SIZE ), 3 ); positions.usage = DynamicDrawUsage; - normals = Float32BufferAttribute( new Float32Array( BUFFER_SIZE ), 3 ); + normals = Float32BufferAttribute(Float32List( BUFFER_SIZE ), 3 ); normals.usage = DynamicDrawUsage; - colors = Float32BufferAttribute( new Float32Array( BUFFER_SIZE ), 3 ); + colors = Float32BufferAttribute(Float32List( BUFFER_SIZE ), 3 ); colors.usage = DynamicDrawUsage; geometry.setAttributeFromString( 'position', positions ); @@ -79,13 +80,13 @@ class TubePainter{ vector3.setFrom( vertex2 ).applyMatrix4( matrix1 ).add( position1 ); vector4.setFrom( vertex1 ).applyMatrix4( matrix1 ).add( position1 ); - vector1.copyIntoNativeArray( positions.array, ( count + 0 ) * 3 ); - vector2.copyIntoNativeArray( positions.array, ( count + 1 ) * 3 ); - vector4.copyIntoNativeArray( positions.array, ( count + 2 ) * 3 ); + vector1.copyIntoList( positions.array, ( count + 0 ) * 3 ); + vector2.copyIntoList( positions.array, ( count + 1 ) * 3 ); + vector4.copyIntoList( positions.array, ( count + 2 ) * 3 ); - vector2.copyIntoNativeArray( positions.array, ( count + 3 ) * 3 ); - vector3.copyIntoNativeArray( positions.array, ( count + 4 ) * 3 ); - vector4.copyIntoNativeArray( positions.array, ( count + 5 ) * 3 ); + vector2.copyIntoList( positions.array, ( count + 3 ) * 3 ); + vector3.copyIntoList( positions.array, ( count + 4 ) * 3 ); + vector4.copyIntoList( positions.array, ( count + 5 ) * 3 ); // normals @@ -94,13 +95,13 @@ class TubePainter{ vector3.setFrom( vertex2 ).applyMatrix4( matrix1 ).normalize(); vector4.setFrom( vertex1 ).applyMatrix4( matrix1 ).normalize(); - vector1.copyIntoNativeArray( normals.array, ( count + 0 ) * 3 ); - vector2.copyIntoNativeArray( normals.array, ( count + 1 ) * 3 ); - vector4.copyIntoNativeArray( normals.array, ( count + 2 ) * 3 ); + vector1.copyIntoList( normals.array, ( count + 0 ) * 3 ); + vector2.copyIntoList( normals.array, ( count + 1 ) * 3 ); + vector4.copyIntoList( normals.array, ( count + 2 ) * 3 ); - vector2.copyIntoNativeArray( normals.array, ( count + 3 ) * 3 ); - vector3.copyIntoNativeArray( normals.array, ( count + 4 ) * 3 ); - vector4.copyIntoNativeArray( normals.array, ( count + 5 ) * 3 ); + vector2.copyIntoList( normals.array, ( count + 3 ) * 3 ); + vector3.copyIntoList( normals.array, ( count + 4 ) * 3 ); + vector4.copyIntoList( normals.array, ( count + 5 ) * 3 ); // colors color.copyIntoArray( colors.array, ( count + 0 ) * 3 ); diff --git a/packages/three_js_particles/lib/particles.dart b/packages/three_js_particles/lib/particles.dart index 8be720b0..abda3598 100644 --- a/packages/three_js_particles/lib/particles.dart +++ b/packages/three_js_particles/lib/particles.dart @@ -1,4 +1,5 @@ import 'dart:math' as math; +import 'dart:typed_data'; import 'package:three_js_particles/Gyroscope.dart'; import 'package:three_js_particles/noise/fmb.dart'; @@ -157,7 +158,7 @@ class Particles { List? factory, }){ final ba = three.Float32BufferAttribute( - factory != null?three.Float32Array.fromList(factory):three.Float32Array(maxParticles), + factory != null?Float32List.fromList(factory):Float32List(maxParticles), 1 ); geometry.setAttributeFromString(propertyName,ba); diff --git a/packages/three_js_particles/lib/utils.dart b/packages/three_js_particles/lib/utils.dart index e52278d2..90e6934d 100644 --- a/packages/three_js_particles/lib/utils.dart +++ b/packages/three_js_particles/lib/utils.dart @@ -1,3 +1,5 @@ +import 'dart:typed_data'; + import 'package:three_js/three_js.dart'; import 'bezier.dart'; import 'enums.dart'; @@ -211,7 +213,7 @@ class Utils{ static CanvasTexture? createDefaultParticleTexture(){ int width = 12; int height = 12; - Uint8Array rgbaData = Uint8Array(width * height * 4); + Uint8List rgbaData = Uint8List(width * height * 4); double radius = 6; double centerX = (width - 1) / 2; double centerY = (height - 1) / 2; diff --git a/packages/three_js_postprocessing/lib/post/effect_composer.dart b/packages/three_js_postprocessing/lib/post/effect_composer.dart index 554f1752..fc65931a 100644 --- a/packages/three_js_postprocessing/lib/post/effect_composer.dart +++ b/packages/three_js_postprocessing/lib/post/effect_composer.dart @@ -11,7 +11,7 @@ class EffectComposer { late WebGLRenderTarget writeBuffer; late WebGLRenderTarget readBuffer; - final FlutterAngleTexture? texture; + final dynamic texture; bool renderToScreen = true; diff --git a/packages/three_js_postprocessing/lib/post/glitch_pass.dart b/packages/three_js_postprocessing/lib/post/glitch_pass.dart index 4bd3ce6e..3e9d4714 100644 --- a/packages/three_js_postprocessing/lib/post/glitch_pass.dart +++ b/packages/three_js_postprocessing/lib/post/glitch_pass.dart @@ -1,3 +1,5 @@ +import 'dart:typed_data'; + import 'package:three_js_core/three_js_core.dart'; import 'package:three_js_math/three_js_math.dart'; import 'package:three_js_postprocessing/post/index.dart'; @@ -77,7 +79,7 @@ class GlitchPass extends Pass { } DataTexture generateHeightmap(int dtSize) { - final dataArr = Float32Array(dtSize * dtSize * 3); + final dataArr = Float32List(dtSize * dtSize * 3); final length = dtSize * dtSize; for (int i = 0; i < length; i++) { diff --git a/packages/three_js_postprocessing/lib/post/smaa_pass.dart b/packages/three_js_postprocessing/lib/post/smaa_pass.dart index 59278d99..9eec2b83 100644 --- a/packages/three_js_postprocessing/lib/post/smaa_pass.dart +++ b/packages/three_js_postprocessing/lib/post/smaa_pass.dart @@ -1,4 +1,5 @@ import 'dart:convert'; +import 'dart:typed_data'; import 'package:three_js_core/three_js_core.dart'; import 'package:three_js_math/three_js_math.dart'; @@ -38,7 +39,7 @@ class SMAAPass extends Pass { // final areaTextureImage = ImageElement( - // data: Uint8Array.fromList(base64Decode(this.getAreaTexture().split(',').last)), + // data: Uint8List.fromList(base64Decode(this.getAreaTexture().split(',').last)), // width: 256, // height: 256 // ); @@ -52,7 +53,7 @@ class SMAAPass extends Pass { this.areaTexture.needsUpdate = true; final searchTextureImage = ImageElement( - data: Uint8Array.fromList(base64Decode(this.getSearchTexture().split(',').last)), + data: Uint8List.fromList(base64Decode(this.getSearchTexture().split(',').last)), width: 256, height: 256 ); diff --git a/packages/three_js_simple_loaders/lib/ply_loader.dart b/packages/three_js_simple_loaders/lib/ply_loader.dart index c7ef8930..9217a577 100644 --- a/packages/three_js_simple_loaders/lib/ply_loader.dart +++ b/packages/three_js_simple_loaders/lib/ply_loader.dart @@ -550,7 +550,6 @@ class PLYLoader extends Loader { } BufferGeometry geometry; - //if ( data is NativeArray ) { final bytes = data.sublist(0); final temp = extractHeaderText( bytes ); final headerText = temp['headerText']; @@ -564,10 +563,6 @@ class PLYLoader extends Loader { else { geometry = parseBinary( data.buffer.asByteData(), header ); } - // } - // else { - // geometry = parseASCII( data, parseHeader( data ) ); - // } return geometry; } diff --git a/packages/three_js_simple_loaders/lib/vox_loder.dart b/packages/three_js_simple_loaders/lib/vox_loder.dart index 91559def..28420da6 100644 --- a/packages/three_js_simple_loaders/lib/vox_loder.dart +++ b/packages/three_js_simple_loaders/lib/vox_loder.dart @@ -274,7 +274,7 @@ class VOXData3DTexture extends Data3DTexture { final offsety = size.x; final offsetz = size.x * size.y; - final array = Uint8Array( (size.x * size.y * size.z).toInt() ); + final array = Uint8List( (size.x * size.y * size.z).toInt() ); for (int j = 0; j < data!.length; j += 4 ) { final x = data[ j + 0 ]; diff --git a/packages/three_js_svg/lib/export/projector.dart b/packages/three_js_svg/lib/export/projector.dart index 0257646b..26e7e777 100644 --- a/packages/three_js_svg/lib/export/projector.dart +++ b/packages/three_js_svg/lib/export/projector.dart @@ -1,4 +1,5 @@ import 'dart:math' as math; +import 'dart:typed_data'; import 'package:three_js_math/three_js_math.dart'; import 'package:three_js_core/three_js_core.dart'; @@ -386,7 +387,7 @@ class Projector{ Map attributes = geometry!.attributes; List> groups = geometry.groups; if (attributes['position'] == null) continue; - NativeArray positions = attributes['position'].array; + List positions = attributes['position'].array; for(int i = 0; i < positions.length; i += 3) { double x = positions[i]; double y = positions[i + 1]; @@ -418,28 +419,28 @@ class Projector{ } if (attributes['normal'] != null){ - NativeArray normals = attributes['normal'].array; - this.normals += normals.toDartList(); + List normals = attributes['normal'].array; + this.normals += normals; // for (int i = 0; i < normals.length; i += 3) { // pushNormal(normals[i],normals[i+1], normals[i+2]); // } } if ( attributes['color'] != null){ - NativeArray colors = attributes['color'].array; - this.colors += colors.toDartList(); + List colors = attributes['color'].array; + this.colors += colors; // for(int i = 0; i < colors.length; i += 3 ) { // pushColor( colors[ i ], colors[ i + 1 ], colors[ i + 2 ] ); // } } if(attributes['uv'] != null ) { - NativeArray uvs = attributes['uv'].array; - this.uvs += uvs.toDartList(); + List uvs = attributes['uv'].array; + this.uvs += uvs; // for (int i = 0; i < uvs.length; i += 2 ) { // pushUv( uvs[i], uvs[i + 1]); // } } if ( geometry.index != null){ - NativeArray indices = geometry.index!.array; + TypedDataList indices = geometry.index!.array; if(groups.isNotEmpty){ for(int g = 0; g < groups.length; g++) { Map group = groups[g]; @@ -479,21 +480,21 @@ class Projector{ Map attributes = geometry!.attributes; if(attributes['position'] != null){ - NativeArray positions = attributes['position'].array; + List positions = attributes['position'].array; for ( int i = 0, l = positions.length; i < l; i += 3 ) { pushVertex( positions[i].toDouble(), positions[i + 1].toDouble(), positions[i + 2].toDouble()); } if (attributes['color'] != null ) { - NativeArray colors = attributes['color'].array; + List colors = attributes['color'].array; // for (int i = 0, l = colors.length; i < l; i += 3 ) { // pushColor( colors[ i ].toDouble(), colors[ i + 1 ].toDouble(), colors[ i + 2 ].toDouble()); // } - this.colors += colors.toDartList(); + this.colors += colors; } if (geometry.index != null){ - NativeArray indices = geometry.index!.array; + TypedDataList indices = geometry.index!.array; for (int i = 0, l = indices.length; i < l; i += 2 ) { pushLine( indices[i], indices[ i + 1 ] ); } @@ -509,7 +510,7 @@ class Projector{ _modelViewProjectionMatrix.multiply2( _viewProjectionMatrix, _modelMatrix ); Map attributes = geometry!.attributes; if ( attributes['position'] != null ) { - NativeArray positions = attributes['position'].array; + List positions = attributes['position'].array; for ( int i = 0, l = positions.length; i < l; i += 3 ) { _vector4.setValues( positions[ i ].toDouble(), positions[ i + 1 ].toDouble(), positions[ i + 2 ].toDouble(), 1 ); _vector4.applyMatrix4( _modelViewProjectionMatrix ); diff --git a/packages/three_js_terrain/example/lib/main.dart b/packages/three_js_terrain/example/lib/main.dart index 89c593f2..917293a4 100644 --- a/packages/three_js_terrain/example/lib/main.dart +++ b/packages/three_js_terrain/example/lib/main.dart @@ -161,7 +161,7 @@ class _TerrainPageState extends State { applySmoothing(val, lastOptions); scatterMeshes(); if (lastOptions.heightmap != null) { - terrain.Terrain.toHeightmap(terrainScene!.children[0].geometry!.attributes['position'].array.toDartList(), lastOptions); + terrain.Terrain.toHeightmap(terrainScene!.children[0].geometry!.attributes['position'].array, lastOptions); } }) ..addSlider(guiSettings,'segments', 7, 127).onFinishChange((){regenerate(blend);}) @@ -246,7 +246,7 @@ class _TerrainPageState extends State { void applySmoothing(smoothing, terrain.TerrainOptions o) { three.Object3D m = terrainScene!.children[0]; - Float32List g = terrain.Terrain.toArray1D(m.geometry!.attributes['position'].array.toDartList()); + Float32List g = terrain.Terrain.toArray1D(m.geometry!.attributes['position'].array); if (smoothing == 'Conservative (0.5)') terrain.Terrain.smoothConservative(g, o, 0.5); if (smoothing == 'Conservative (1)') terrain.Terrain.smoothConservative(g, o, 1); if (smoothing == 'Conservative (10)'){ terrain.Terrain.smoothConservative(g, o, 10);} @@ -260,7 +260,7 @@ class _TerrainPageState extends State { else if (smoothing == 'Mean (1)'){ terrain.Terrain.smooth(g, o, 1);} else if (smoothing == 'Mean (8)'){ terrain.Terrain.smooth(g, o, 8);} else if (smoothing == 'Median'){ terrain.Terrain.smoothMedian(g, o);} - terrain.Terrain.fromArray1D(m.geometry!.attributes['position'].array.toDartList(), g); + terrain.Terrain.fromArray1D(m.geometry!.attributes['position'].array, g); terrain.Terrain.normalize(m, o); } @@ -476,7 +476,7 @@ class _TerrainPageState extends State { // var he = document.getElementById('heightmap'); // if (he != null) { // o.heightmap = he; - heightMapImage = terrain.Terrain.toHeightmap(terrainScene!.children[0].geometry!.attributes['position'].array.toDartList(), o); + heightMapImage = terrain.Terrain.toHeightmap(terrainScene!.children[0].geometry!.attributes['position'].array, o); // } heightMapImage = rgba2bitmap(heightMapImage!, o.xSegments+1, o.ySegments+1); lastOptions = o; diff --git a/packages/three_js_terrain/lib/core.dart b/packages/three_js_terrain/lib/core.dart index da7ee507..efa5c354 100644 --- a/packages/three_js_terrain/lib/core.dart +++ b/packages/three_js_terrain/lib/core.dart @@ -542,7 +542,7 @@ class Terrain{ ); // Assign elevation data to the terrain plane from a heightmap or function. - final zs = toArray1D(mesh.geometry!.attributes['position'].array.toDartList()); + final zs = toArray1D(mesh.geometry!.attributes['position'].array); if (options.heightmap is Uint8List) { fromHeightmap(zs, options); } @@ -553,7 +553,7 @@ class Terrain{ console.warning('An invalid value was passed for `options.heightmap`: ${options.heightmap.runtimeType}'); } - fromArray1D(mesh.geometry!.attributes['position'].array.toDartList(), zs); + fromArray1D(mesh.geometry!.attributes['position'].array, zs); normalize(mesh, options); // lod.addLevel(mesh, options.unit*10*Math.pow(2, lodLevel)); @@ -576,7 +576,7 @@ class Terrain{ /// displayed. Valid options are the same as for {@link Terrain}(). /// static void normalize(Object3D mesh, TerrainOptions options) { - final zs = toArray1D(mesh.geometry!.attributes['position'].array.toDartList()); + final zs = toArray1D(mesh.geometry!.attributes['position'].array); if (options.turbulent) { turbulence(zs, options); } @@ -590,7 +590,7 @@ class Terrain{ // Call the "after" callback options.after?.call(zs, options); - fromArray1D(mesh.geometry!.attributes['position'].array.toDartList(), zs); + fromArray1D(mesh.geometry!.attributes['position'].array, zs); // Mark the geometry as having changed and needing updates. mesh.geometry?.computeBoundingSphere(); diff --git a/packages/three_js_terrain/lib/generators.dart b/packages/three_js_terrain/lib/generators.dart index 94f49f92..fd31c354 100644 --- a/packages/three_js_terrain/lib/generators.dart +++ b/packages/three_js_terrain/lib/generators.dart @@ -132,7 +132,7 @@ extension Generators on Terrain{ int segments = MathUtils.ceilPowerOfTwo(math.max(options.xSegments, options.ySegments) + 1).toInt(); // Initialize heightmap - final List heightmap = []; + final List heightmap = []; double smoothing = (options.maxHeight! - options.minHeight!); int i, size = segments + 1, @@ -141,7 +141,7 @@ extension Generators on Terrain{ yl = options.ySegments + 1; for (i = 0; i <= segments; i++) { - heightmap.add(new Float64Array(segments+1)); + heightmap.add(Float64List(segments+1)); } // Generate heightmap diff --git a/packages/three_js_text/lib/typrdart/tabs/svg.dart b/packages/three_js_text/lib/typrdart/tabs/svg.dart index a8469235..5756482c 100644 --- a/packages/three_js_text/lib/typrdart/tabs/svg.dart +++ b/packages/three_js_text/lib/typrdart/tabs/svg.dart @@ -31,7 +31,7 @@ class Typr_SVG { var svgDocLength = TyprBin.readUint(data, offset); offset += 4; - // var sbuf = new Uint8Array(data.buffer, offset0 + svgDocOffset + svgDocIndexOffset, svgDocLength); + // final sbuf = new Uint8List(data.buffer, offset0 + svgDocOffset + svgDocIndexOffset, svgDocLength); int _offset = offset0 + svgDocOffset + svgDocIndexOffset; int _length = svgDocLength; var sbuf = data.sublist(_offset, _offset + _length); diff --git a/packages/three_js_tjs_loader/lib/buffer_geometry_loader.dart b/packages/three_js_tjs_loader/lib/buffer_geometry_loader.dart index ad05e893..9c032f3a 100644 --- a/packages/three_js_tjs_loader/lib/buffer_geometry_loader.dart +++ b/packages/three_js_tjs_loader/lib/buffer_geometry_loader.dart @@ -1,6 +1,7 @@ import 'dart:async'; import 'dart:convert' as convert; import 'dart:io'; +import 'dart:typed_data'; import 'package:flutter/services.dart'; import 'package:three_js_core/three_js_core.dart'; import 'package:three_js_math/three_js_math.dart'; @@ -80,7 +81,7 @@ class BufferGeometryLoader extends Loader { final arrayBuffers = json.arrayBuffers; final arrayBuffer = arrayBuffers[uuid]; - final ab = Uint32Array(arrayBuffer).buffer; + final ab = Uint32List.fromList(arrayBuffer).buffer; arrayBufferMap[uuid] = ab; @@ -225,29 +226,29 @@ class BufferGeometryLoader extends Loader { } } -NativeArray getTypedArray(String type, List buffer) { +TypedDataList getTypedArray(String type, List buffer) { if (type == "Uint32Array" || type == "Uint32List") { - return Uint32Array.fromList(List.from(buffer)); + return Uint32List.fromList(List.from(buffer)); } else if (type == "Uint16Array" || type == "Uint16List") { - return Uint16Array.fromList(List.from(buffer)); + return Uint16List.fromList(List.from(buffer)); } else if (type == "Float32Array" || type == "Float32List") { List b = []; for(int i = 0; i < buffer.length;i++){ b.add(buffer[i].toDouble()); } - return Float32Array.fromList(List.from(b)); + return Float32List.fromList(List.from(b)); } else { throw (" Util.dart getTypedArray type: $type is not support "); } } -BufferAttribute getTypedAttribute(NativeArray array, int itemSize, +BufferAttribute getTypedAttribute(TypedData array, int itemSize, [bool normalized = false]) { - if (array is Uint32Array) { + if (array is Uint32List) { return Uint32BufferAttribute(array, itemSize, normalized); - } else if (array is Uint16Array) { + } else if (array is Uint16List) { return Uint16BufferAttribute(array, itemSize, normalized); - } else if (array is Float32Array) { + } else if (array is Float32List) { return Float32BufferAttribute(array, itemSize, normalized); } else { throw (" Util.dart getTypedArray type: ${array.runtimeType} is not support "); diff --git a/packages/three_js_tjs_loader/lib/object_loader.dart b/packages/three_js_tjs_loader/lib/object_loader.dart index 783ae517..6813c252 100644 --- a/packages/three_js_tjs_loader/lib/object_loader.dart +++ b/packages/three_js_tjs_loader/lib/object_loader.dart @@ -592,9 +592,9 @@ class ObjectLoader extends Loader { final instanceColor = data["instanceColor"]; object = InstancedMesh(geometry, material, count); - object.instanceMatrix = InstancedBufferAttribute(Float32Array(instanceMatrix.array), 16, false); + object.instanceMatrix = InstancedBufferAttribute(Float32List.fromList(instanceMatrix.array), 16, false); if (instanceColor != null) { - object.instanceColor = InstancedBufferAttribute(Float32Array(instanceColor.array), instanceColor.itemSize, false); + object.instanceColor = InstancedBufferAttribute(Float32List.fromList(instanceColor.array), instanceColor.itemSize, false); } break; diff --git a/packages/three_js_video_texture/lib/video_texture_platform.dart b/packages/three_js_video_texture/lib/video_texture_platform.dart index d7404531..b248a3dd 100644 --- a/packages/three_js_video_texture/lib/video_texture_platform.dart +++ b/packages/three_js_video_texture/lib/video_texture_platform.dart @@ -1,4 +1,5 @@ import 'dart:io'; +import 'dart:typed_data'; import 'package:media_kit_video/media_kit_video.dart'; import 'package:three_js_core/three_js_core.dart'; @@ -115,7 +116,7 @@ class VideoTextureWorker extends VideoTexture { ]){ final image = ImageElement( url: options, - //data: Uint8Array(391680),//((options.width ?? 0)*(options.height ?? 0)*4).toInt()), + //data: Uint8List(391680),//((options.width ?? 0)*(options.height ?? 0)*4).toInt()), src: options.asset, width: options.width?.toInt() ?? 0, height: options.height?.toInt() ?? 0 @@ -149,12 +150,12 @@ class VideoTextureWorker extends VideoTexture { if(image != null && v != null){ if(image?.data == null || image?.data?.length != v.length){ print('getyweduwb'); - image!.data = Uint8Array.fromList(v); + image!.data = Uint8List.fromList(v); image!.width = _player?.state.width; image!.height = _player?.state.height; } else{ - (image!.data as Uint8Array).set(v); + (image!.data as Uint8List).set(v); } } needsUpdate = true; diff --git a/three_cad/lib/src/cad/draw_types.dart b/three_cad/lib/src/cad/draw_types.dart index 2410442a..72dc9cff 100644 --- a/three_cad/lib/src/cad/draw_types.dart +++ b/three_cad/lib/src/cad/draw_types.dart @@ -1,3 +1,5 @@ +import 'dart:typed_data'; + import 'package:three_cad/src/cad/constraints.dart'; import 'package:three_cad/src/cad/sketchTypes/sketch_point.dart'; import 'package:three_cad/src/cad/sketchTypes/sketch_spline.dart'; @@ -228,7 +230,7 @@ enum DrawType{ final geometry = BufferGeometry(); geometry.setAttributeFromString( 'position', - segments == 0?Float32BufferAttribute.fromList(position.storage+position.storage,3):Float32BufferAttribute( Float32Array( segments * 3 ), 3 ) + segments == 0?Float32BufferAttribute.fromList(position.storage+position.storage,3):Float32BufferAttribute( Float32List( segments * 3 ), 3 ) ); return Line( geometry, matLine..color.setFromHex32(color)) diff --git a/three_cad/lib/src/cad_old/draw_types.dart b/three_cad/lib/src/cad_old/draw_types.dart index 79cb4fc3..ec488b99 100644 --- a/three_cad/lib/src/cad_old/draw_types.dart +++ b/three_cad/lib/src/cad_old/draw_types.dart @@ -1,5 +1,5 @@ +import 'dart:typed_data'; import 'package:three_js/three_js.dart'; -import 'dart:math' as math; import 'package:three_js_line/three_js_line.dart'; enum DrawType{ @@ -22,7 +22,7 @@ enum DrawType{ static Group createSpline(Vector3 position, int color){ final g = Group()..name = 'spline'; // final geometry = BufferGeometry(); - // geometry.setAttributeFromString('position',Float32BufferAttribute( Float32Array( 200 * 3 ), 3 ) ); + // geometry.setAttributeFromString('position',Float32BufferAttribute( Float32List( 200 * 3 ), 3 ) ); // final line = Line( // geometry, // LineBasicMaterial.fromMap( { @@ -42,7 +42,7 @@ enum DrawType{ static Group createCircleSpline(Vector3 position, int color){ Group objects = Group()..name = 'circleSpline'; // final geometry = BufferGeometry(); - // geometry.setAttributeFromString('position',Float32BufferAttribute( Float32Array( 64 * 3 ), 3 ) ); + // geometry.setAttributeFromString('position',Float32BufferAttribute( Float32List( 64 * 3 ), 3 ) ); // final line = Line( // geometry, @@ -219,16 +219,16 @@ enum DrawType{ final geometry = BufferGeometry(); geometry.setAttributeFromString( 'position', - segments == 0?Float32BufferAttribute.fromList(position.storage+position.storage,3):Float32BufferAttribute( Float32Array( segments * 3 ), 3 ) + segments == 0?Float32BufferAttribute.fromList(position.storage+position.storage,3):Float32BufferAttribute( Float32List( segments * 3 ), 3 ) ); - final constructionLine = LineDashedMaterial.fromMap( { - 'color': 0xffff00, - 'transparent': true, - 'opacity': 0.5, - 'linewidth': 5, - 'gapSize': 1, - 'dashSize': 0.5 - }); + // final constructionLine = LineDashedMaterial.fromMap( { + // 'color': 0xffff00, + // 'transparent': true, + // 'opacity': 0.5, + // 'linewidth': 5, + // 'gapSize': 1, + // 'dashSize': 0.5 + // }); final matLine = LineBasicMaterial.fromMap( { 'color': color,//construction?0xffff00:215910, diff --git a/three_js_editor/lib/ui/line_material.dart b/three_js_editor/lib/ui/line_material.dart index 34950eac..92449a23 100644 --- a/three_js_editor/lib/ui/line_material.dart +++ b/three_js_editor/lib/ui/line_material.dart @@ -1,3 +1,5 @@ +import 'dart:typed_data'; + import 'package:three_js/three_js.dart'; @@ -426,9 +428,9 @@ class LineMaterial extends ShaderMaterial { clipping = true; // required for clipping support defaultAttributeValues = { - 'color': [1.0, 1.0, 1.0], - 'uv': [0.0, 0.0], - 'uv2': [0.0, 0.0] + 'color': Float32List.fromList([1.0, 1.0, 1.0]), + 'uv': Float32List.fromList([0.0, 0.0]), + 'uv2': Float32List.fromList([0.0, 0.0]) }; } diff --git a/xr_examples/lib/rollercoster/rollercoaster.dart b/xr_examples/lib/rollercoster/rollercoaster.dart index 4f82152e..db8e4f01 100644 --- a/xr_examples/lib/rollercoster/rollercoaster.dart +++ b/xr_examples/lib/rollercoster/rollercoaster.dart @@ -1,4 +1,5 @@ import 'dart:math' as math; +import 'dart:typed_data'; import 'package:three_js/three_js.dart'; @@ -198,9 +199,9 @@ class RollerCoasterGeometry extends BufferGeometry { // console.log( vertices.length ); - this.setAttributeFromString( 'position', Float32BufferAttribute( Float32Array.fromList( vertices ), 3 ) ); - this.setAttributeFromString( 'normal', Float32BufferAttribute( Float32Array.fromList( normals ), 3 ) ); - this.setAttributeFromString( 'color', Float32BufferAttribute( Float32Array.fromList( colors ), 3 ) ); + this.setAttributeFromString( 'position', Float32BufferAttribute( Float32List.fromList( vertices ), 3 ) ); + this.setAttributeFromString( 'normal', Float32BufferAttribute( Float32List.fromList( normals ), 3 ) ); + this.setAttributeFromString( 'color', Float32BufferAttribute( Float32List.fromList( colors ), 3 ) ); } } @@ -363,8 +364,8 @@ class RollerCoasterLiftersGeometry extends BufferGeometry { } } - this.setAttributeFromString( 'position', Float32BufferAttribute( Float32Array.fromList( vertices ), 3 ) ); - this.setAttributeFromString( 'normal', Float32BufferAttribute( Float32Array.fromList( normals ), 3 ) ); + this.setAttributeFromString( 'position', Float32BufferAttribute( Float32List.fromList( vertices ), 3 ) ); + this.setAttributeFromString( 'normal', Float32BufferAttribute( Float32List.fromList( normals ), 3 ) ); } } @@ -429,7 +430,7 @@ class RollerCoasterShadowGeometry extends BufferGeometry { prevQuaternion.setFrom( quaternion ); } - this.setAttributeFromString( 'position', Float32BufferAttribute( Float32Array.fromList( vertices ), 3 ) ); + this.setAttributeFromString( 'position', Float32BufferAttribute( Float32List.fromList( vertices ), 3 ) ); } } @@ -455,7 +456,7 @@ class SkyGeometry extends BufferGeometry { vertices.addAll([ x - size, y, z + size ]); } - this.setAttributeFromString( 'position', Float32BufferAttribute( Float32Array.fromList( vertices ), 3 ) ); + this.setAttributeFromString( 'position', Float32BufferAttribute( Float32List.fromList( vertices ), 3 ) ); } } @@ -504,8 +505,8 @@ class TreesGeometry extends BufferGeometry { } } - this.setAttributeFromString( 'position', Float32BufferAttribute( Float32Array.fromList( vertices ), 3 ) ); - this.setAttributeFromString( 'color', Float32BufferAttribute( Float32Array.fromList( colors ), 3 ) ); + this.setAttributeFromString( 'position', Float32BufferAttribute( Float32List.fromList( vertices ), 3 ) ); + this.setAttributeFromString( 'color', Float32BufferAttribute( Float32List.fromList( colors ), 3 ) ); } diff --git a/xr_examples/lib/src/atlas/platform.dart b/xr_examples/lib/src/atlas/platform.dart index 185e1d37..2db5f35a 100644 --- a/xr_examples/lib/src/atlas/platform.dart +++ b/xr_examples/lib/src/atlas/platform.dart @@ -1,7 +1,6 @@ import 'package:three_js/three_js.dart' as three; import 'dart:typed_data'; import 'package:image/image.dart' hide Color; -import 'package:three_js_math/three_js_math.dart'; class Atlas{ List getTexturesFromAtlasFile(String atlasImgUrl, int tilesNum ) { @@ -15,7 +14,7 @@ class Atlas{ loader.fromAsset(atlasImgUrl).then(( imageObj ) { final int tileWidth = imageObj!.height.toInt(); - ByteBuffer bytes = Uint8List.fromList((imageObj.data as Uint8Array).toDartList()).buffer; + final ByteBuffer bytes = imageObj.data.buffer; Image image = Image.fromBytes( bytes: bytes, width: imageObj.width.toInt(), @@ -33,7 +32,7 @@ class Atlas{ ).getBytes(); textures[ i ].colorSpace = three.SRGBColorSpace; textures[ i ].image = three.ImageElement( - data: Uint8Array.fromList(canvas), + data: Uint8List.fromList(canvas), width: tileWidth, height: tileWidth ); diff --git a/xr_examples/lib/vr/webxr_vr_rollercoaster.dart b/xr_examples/lib/vr/webxr_vr_rollercoaster.dart index 2b2ded2b..396ba5cf 100644 --- a/xr_examples/lib/vr/webxr_vr_rollercoaster.dart +++ b/xr_examples/lib/vr/webxr_vr_rollercoaster.dart @@ -7,15 +7,6 @@ import 'package:three_js/three_js.dart' as three; import 'package:three_js_geometry/three_js_geometry.dart'; import 'package:three_js_xr/three_js_xr.dart'; -extension on three.Vector3{ - three.Float32Array toNativeArray(three.Float32Array array, [int offset = 0]) { - array[offset] = storage[0]; - array[offset + 1] = storage[1]; - array[offset + 2] = storage[2]; - return array; - } -} - class WebXRVRRollercoaster extends StatefulWidget { const WebXRVRRollercoaster({super.key, required this.fullScreen}); final void Function(bool) fullScreen; @@ -127,7 +118,7 @@ class _State extends State { final distance = ( vertex.distanceTo( threeJs.scene.position ) / 5 ) - 25; vertex.y = math.Random().nextDouble() * math.max( 0, distance ); - vertex.toNativeArray( positions, i ); + vertex.copyFromUnknown( positions, i ); } geometry.computeVertexNormals(); From 1e57bfdc242ea789967e7fea89bb85c5f264f9aa Mon Sep 17 00:00:00 2001 From: Knightro <50028636+Knightro63@users.noreply.github.com> Date: Fri, 23 Jan 2026 18:25:53 -0500 Subject: [PATCH 02/17] updated yaml files for release --- packages/three_js/CHANGELOG.md | 4 ++ packages/three_js/pubspec.yaml | 22 +++++----- .../three_js_advanced_exporters/CHANGELOG.md | 4 ++ .../three_js_advanced_exporters/pubspec.yaml | 8 ++-- .../three_js_advanced_loaders/CHANGELOG.md | 4 ++ .../three_js_advanced_loaders/pubspec.yaml | 16 +++---- packages/three_js_animations/CHANGELOG.md | 4 ++ packages/three_js_animations/pubspec.yaml | 6 +-- packages/three_js_audio/CHANGELOG.md | 4 ++ packages/three_js_audio/pubspec.yaml | 8 ++-- packages/three_js_audio_latency/CHANGELOG.md | 4 ++ packages/three_js_audio_latency/pubspec.yaml | 8 ++-- packages/three_js_bvh_csg/CHANGELOG.md | 4 ++ packages/three_js_bvh_csg/pubspec.yaml | 6 +-- packages/three_js_controls/CHANGELOG.md | 4 ++ packages/three_js_controls/pubspec.yaml | 14 +++---- packages/three_js_core/CHANGELOG.md | 1 + .../lib/materials/line_dashed_material.dart | 6 +++ .../lib/materials/mesh_gouraund_material.dart | 6 +++ .../lib/materials/mesh_matcap_material.dart | 6 +++ .../lib/materials/mesh_normal_material.dart | 6 +++ .../lib/materials/points_material.dart | 6 +++ .../three_js_core/lib/objects/skeleton.dart | 9 ++-- packages/three_js_core/pubspec.yaml | 2 +- packages/three_js_core_loaders/CHANGELOG.md | 4 ++ packages/three_js_core_loaders/pubspec.yaml | 4 +- packages/three_js_curves/CHANGELOG.md | 4 ++ packages/three_js_curves/pubspec.yaml | 2 +- packages/three_js_exporters/CHANGELOG.md | 4 ++ packages/three_js_exporters/pubspec.yaml | 4 +- packages/three_js_geometry/CHANGELOG.md | 4 ++ packages/three_js_geometry/pubspec.yaml | 8 ++-- packages/three_js_helpers/CHANGELOG.md | 4 ++ packages/three_js_helpers/pubspec.yaml | 8 ++-- packages/three_js_line/CHANGELOG.md | 4 ++ packages/three_js_line/pubspec.yaml | 8 ++-- packages/three_js_math/CHANGELOG.md | 1 + packages/three_js_math/pubspec.yaml | 1 - packages/three_js_modifers/CHANGELOG.md | 4 ++ packages/three_js_modifers/pubspec.yaml | 4 +- packages/three_js_objects/CHANGELOG.md | 4 ++ packages/three_js_objects/pubspec.yaml | 8 ++-- packages/three_js_postprocessing/CHANGELOG.md | 4 ++ packages/three_js_postprocessing/pubspec.yaml | 4 +- packages/three_js_sensors/CHANGELOG.md | 4 ++ packages/three_js_sensors/pubspec.yaml | 2 +- packages/three_js_simple_loaders/CHANGELOG.md | 4 ++ packages/three_js_simple_loaders/pubspec.yaml | 8 ++-- packages/three_js_svg/CHANGELOG.md | 4 ++ packages/three_js_svg/pubspec.yaml | 8 ++-- packages/three_js_terrain/CHANGELOG.md | 3 +- packages/three_js_terrain/pubspec.yaml | 4 +- packages/three_js_text/CHANGELOG.md | 4 ++ packages/three_js_text/pubspec.yaml | 8 ++-- packages/three_js_tjs_loader/CHANGELOG.md | 4 ++ .../lib/material_loader.dart | 42 ++++++++++++++++--- packages/three_js_tjs_loader/pubspec.yaml | 12 +++--- .../three_js_transform_controls/CHANGELOG.md | 4 ++ .../three_js_transform_controls/pubspec.yaml | 10 ++--- packages/three_js_video_texture/CHANGELOG.md | 4 ++ packages/three_js_video_texture/pubspec.yaml | 6 +-- packages/three_js_xr/CHANGELOG.md | 4 ++ packages/three_js_xr/pubspec.yaml | 12 +++--- 63 files changed, 281 insertions(+), 116 deletions(-) diff --git a/packages/three_js/CHANGELOG.md b/packages/three_js/CHANGELOG.md index d26038fc..af9e6e5a 100755 --- a/packages/three_js/CHANGELOG.md +++ b/packages/three_js/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.0 + +* Removed NativeArray for Zero-Allocation Updates. + ## 0.2.8 * Updated to the latest version of three_js apis diff --git a/packages/three_js/pubspec.yaml b/packages/three_js/pubspec.yaml index b53753d5..b6e17034 100755 --- a/packages/three_js/pubspec.yaml +++ b/packages/three_js/pubspec.yaml @@ -1,6 +1,6 @@ name: three_js description: "Flutter package converted from threejs and three_dart to allow users to view, edit, and control 3D models." -version: 0.2.8 +version: 0.3.0 homepage: https://github.com/Knightro63/three_js/tree/main/packages/three_js topics: @@ -17,16 +17,16 @@ environment: dependencies: flutter: sdk: flutter - three_js_math: ^0.2.6 - three_js_advanced_loaders: ^0.2.5 - three_js_animations: ^0.2.3 - three_js_controls: ^0.2.2 - three_js_core: ^0.2.8 - three_js_core_loaders: ^0.2.2 - three_js_curves: ^0.2.1 - three_js_simple_loaders: ^0.2.2 - three_js_text: ^0.2.0 - three_js_geometry: ^0.2.1 + three_js_math: ^0.3.0 + three_js_advanced_loaders: ^0.3.0 + three_js_animations: ^0.3.0 + three_js_controls: ^0.3.0 + three_js_core: ^0.3.0 + three_js_core_loaders: ^0.3.0 + three_js_curves: ^0.3.0 + three_js_simple_loaders: ^0.3.0 + three_js_text: ^0.3.0 + three_js_geometry: ^0.3.0 dev_dependencies: flutter_test: diff --git a/packages/three_js_advanced_exporters/CHANGELOG.md b/packages/three_js_advanced_exporters/CHANGELOG.md index 9b7b03ba..0858c59d 100755 --- a/packages/three_js_advanced_exporters/CHANGELOG.md +++ b/packages/three_js_advanced_exporters/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.0 + +* Removed NativeArray for Zero-Allocation Updates. + ## 0.0.1 * Initial release. \ No newline at end of file diff --git a/packages/three_js_advanced_exporters/pubspec.yaml b/packages/three_js_advanced_exporters/pubspec.yaml index 12aaef82..01090332 100755 --- a/packages/three_js_advanced_exporters/pubspec.yaml +++ b/packages/three_js_advanced_exporters/pubspec.yaml @@ -1,6 +1,6 @@ name: three_js_advanced_exporters description: "Flutter three_js_advanced_exporters package exports usdz from three_js." -version: 0.0.1 +version: 0.1.0 homepage: https://github.com/Knightro63/three_js/tree/main/packages/three_js_advanced_exporters environment: @@ -14,9 +14,9 @@ dependencies: path_provider: ^2.1.5 image: ^4.5.4 web: ^1.1.1 - three_js_exporters: ^0.2.0 - three_js_core: ^0.2.0 - three_js_math: ^0.2.0 + three_js_exporters: ^0.3.0 + three_js_core: ^0.3.0 + three_js_math: ^0.3.0 dev_dependencies: flutter_test: diff --git a/packages/three_js_advanced_loaders/CHANGELOG.md b/packages/three_js_advanced_loaders/CHANGELOG.md index 14afeb82..b2cac606 100755 --- a/packages/three_js_advanced_loaders/CHANGELOG.md +++ b/packages/three_js_advanced_loaders/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.0 + +* Removed NativeArray for Zero-Allocation Updates. + ## 0.2.5 * Added PCD Loader diff --git a/packages/three_js_advanced_loaders/pubspec.yaml b/packages/three_js_advanced_loaders/pubspec.yaml index 3ed613a8..2387812f 100755 --- a/packages/three_js_advanced_loaders/pubspec.yaml +++ b/packages/three_js_advanced_loaders/pubspec.yaml @@ -1,6 +1,6 @@ name: three_js_advanced_loaders description: "Flutter advanced loaders package e.g.(gltf, glb and fbx) converted from threejs and three_dart package." -version: 0.2.5 +version: 0.3.0 homepage: https://github.com/Knightro63/three_js/tree/main/packages/three_js_advanced_loaders topics: @@ -18,13 +18,13 @@ dependencies: xml: ^6.5.0 flutter: sdk: flutter - three_js_core: ^0.2.0 - three_js_core_loaders: ^0.2.1 - three_js_curves: ^0.2.0 - three_js_math: ^0.2.0 - three_js_geometry: ^0.2.0 - three_js_animations: ^0.2.1 - three_js_controls: ^0.2.0 + three_js_core: ^0.3.0 + three_js_core_loaders: ^0.3.0 + three_js_curves: ^0.3.0 + three_js_math: ^0.3.0 + three_js_geometry: ^0.3.0 + three_js_animations: ^0.3.0 + three_js_controls: ^0.3.0 archive: ^4.0.7 dev_dependencies: diff --git a/packages/three_js_animations/CHANGELOG.md b/packages/three_js_animations/CHANGELOG.md index 036b7410..eb1ca80b 100755 --- a/packages/three_js_animations/CHANGELOG.md +++ b/packages/three_js_animations/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.0 + +* Removed NativeArray for Zero-Allocation Updates. + ## 0.2.3 * Fixed property mixer bug. diff --git a/packages/three_js_animations/pubspec.yaml b/packages/three_js_animations/pubspec.yaml index 8abba14d..4b0d83f4 100755 --- a/packages/three_js_animations/pubspec.yaml +++ b/packages/three_js_animations/pubspec.yaml @@ -1,6 +1,6 @@ name: three_js_animations description: "Flutter three_js_animations package converted from threejs and three_dart package created for three_js." -version: 0.2.3 +version: 0.3.0 homepage: https://github.com/Knightro63/three_js/tree/main/packages/three_js_animations environment: @@ -10,8 +10,8 @@ environment: dependencies: flutter: sdk: flutter - three_js_core: ^0.2.0 - three_js_math: ^0.2.0 + three_js_core: ^0.3.0 + three_js_math: ^0.3.0 dev_dependencies: flutter_test: diff --git a/packages/three_js_audio/CHANGELOG.md b/packages/three_js_audio/CHANGELOG.md index 9618a585..c669822f 100644 --- a/packages/three_js_audio/CHANGELOG.md +++ b/packages/three_js_audio/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.0 + +* Removed NativeArray for Zero-Allocation Updates. + ## 0.2.1 * Made Audio an abstract class. diff --git a/packages/three_js_audio/pubspec.yaml b/packages/three_js_audio/pubspec.yaml index 23b4f55f..c0cf3dbf 100644 --- a/packages/three_js_audio/pubspec.yaml +++ b/packages/three_js_audio/pubspec.yaml @@ -1,6 +1,6 @@ name: three_js_audio description: "Flutter audio package converted from threejs and three_dart package." -version: 0.2.1 +version: 0.3.0 homepage: https://github.com/Knightro63/three_js/tree/main/packages/three_js_audio environment: @@ -11,9 +11,9 @@ dependencies: flutter: sdk: flutter audioplayers: ^6.5.0 - three_js_core: ^0.2.1 - three_js_math: ^0.2.1 - three_js_core_loaders: ^0.2.0 + three_js_core: ^0.3.0 + three_js_math: ^0.3.0 + three_js_core_loaders: ^0.3.0 dev_dependencies: flutter_test: diff --git a/packages/three_js_audio_latency/CHANGELOG.md b/packages/three_js_audio_latency/CHANGELOG.md index 9b7b03ba..0858c59d 100644 --- a/packages/three_js_audio_latency/CHANGELOG.md +++ b/packages/three_js_audio_latency/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.0 + +* Removed NativeArray for Zero-Allocation Updates. + ## 0.0.1 * Initial release. \ No newline at end of file diff --git a/packages/three_js_audio_latency/pubspec.yaml b/packages/three_js_audio_latency/pubspec.yaml index 4f8b8a18..1a7180ec 100644 --- a/packages/three_js_audio_latency/pubspec.yaml +++ b/packages/three_js_audio_latency/pubspec.yaml @@ -1,6 +1,6 @@ name: three_js_audio_latency description: "Flutter audio package converted from threejs and three_dart package." -version: 0.0.1 +version: 0.1.0 homepage: https://github.com/Knightro63/three_js/tree/main/packages/three_js_audio_latency environment: @@ -11,9 +11,9 @@ dependencies: flutter: sdk: flutter flutter_soloud: ^3.2.1 - three_js_core: ^0.2.1 - three_js_math: ^0.2.1 - three_js_core_loaders: ^0.2.0 + three_js_core: ^0.3.0 + three_js_math: ^0.3.0 + three_js_core_loaders: ^0.3.0 dev_dependencies: flutter_test: diff --git a/packages/three_js_bvh_csg/CHANGELOG.md b/packages/three_js_bvh_csg/CHANGELOG.md index b7d44d7f..4da28956 100644 --- a/packages/three_js_bvh_csg/CHANGELOG.md +++ b/packages/three_js_bvh_csg/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.0 + +* Removed NativeArray for Zero-Allocation Updates. + ## 0.2.0 * Updated to newest version of three_js packages. diff --git a/packages/three_js_bvh_csg/pubspec.yaml b/packages/three_js_bvh_csg/pubspec.yaml index 4f1daf73..99baf8b9 100644 --- a/packages/three_js_bvh_csg/pubspec.yaml +++ b/packages/three_js_bvh_csg/pubspec.yaml @@ -1,6 +1,6 @@ name: three_js_bvh_csg description: "Flutter three_js_bvh_csg is a api that helps with cutting and combining meshes in three_js." -version: 0.2.0 +version: 0.3.0 homepage: https://github.com/Knightro63/three_js/tree/main/packages/three_js_bvh_csg environment: @@ -10,8 +10,8 @@ environment: dependencies: flutter: sdk: flutter - three_js_math: ^0.2.0 - three_js_core: ^0.2.0 + three_js_math: ^0.3.0 + three_js_core: ^0.3.0 dev_dependencies: flutter_test: diff --git a/packages/three_js_controls/CHANGELOG.md b/packages/three_js_controls/CHANGELOG.md index 5cb0eeab..79334188 100755 --- a/packages/three_js_controls/CHANGELOG.md +++ b/packages/three_js_controls/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.0 + +* Removed NativeArray for Zero-Allocation Updates. + ## 0.2.2 * Fixed: Some cloning issues. diff --git a/packages/three_js_controls/pubspec.yaml b/packages/three_js_controls/pubspec.yaml index 679a73b6..91dbd4a0 100755 --- a/packages/three_js_controls/pubspec.yaml +++ b/packages/three_js_controls/pubspec.yaml @@ -1,6 +1,6 @@ name: three_js_controls description: "Flutter controls package converted from threejs and three_dart package." -version: 0.2.2 +version: 0.3.0 homepage: https://github.com/Knightro63/three_js/tree/main/packages/three_js_controls environment: @@ -10,12 +10,12 @@ environment: dependencies: flutter: sdk: flutter - three_js_core: ^0.2.0 - three_js_core_loaders: ^0.2.0 - three_js_math: ^0.2.0 - three_js_geometry: ^0.2.0 - three_js_curves: ^0.2.0 - three_js_sensors: ^0.1.1 + three_js_core: ^0.3.0 + three_js_core_loaders: ^0.3.0 + three_js_math: ^0.3.0 + three_js_geometry: ^0.3.0 + three_js_curves: ^0.3.0 + three_js_sensors: ^0.2.0 dev_dependencies: flutter_test: diff --git a/packages/three_js_core/CHANGELOG.md b/packages/three_js_core/CHANGELOG.md index dd73b9d1..fe549eca 100755 --- a/packages/three_js_core/CHANGELOG.md +++ b/packages/three_js_core/CHANGELOG.md @@ -2,6 +2,7 @@ * Removed NativeArray * Put WebglRenderer into its own package +* Removed NativeArray for Zero-Allocation Updates. ## 0.2.8 diff --git a/packages/three_js_core/lib/materials/line_dashed_material.dart b/packages/three_js_core/lib/materials/line_dashed_material.dart index f328ac49..0de9f0e2 100755 --- a/packages/three_js_core/lib/materials/line_dashed_material.dart +++ b/packages/three_js_core/lib/materials/line_dashed_material.dart @@ -41,4 +41,10 @@ class LineDashedMaterial extends LineBasicMaterial { gapSize = source.gapSize; return this; } + + /// Return a new material with the same parameters as this material. + @override + LineDashedMaterial clone() { + return LineDashedMaterial()..copy(this); + } } diff --git a/packages/three_js_core/lib/materials/mesh_gouraund_material.dart b/packages/three_js_core/lib/materials/mesh_gouraund_material.dart index e5c7cfb4..72edb67c 100644 --- a/packages/three_js_core/lib/materials/mesh_gouraund_material.dart +++ b/packages/three_js_core/lib/materials/mesh_gouraund_material.dart @@ -396,4 +396,10 @@ class MeshGouraudMaterial extends ShaderMaterial { return this; } + + /// Return a new material with the same parameters as this material. + @override + MeshGouraudMaterial clone() { + return MeshGouraudMaterial()..copy(this); + } } \ No newline at end of file diff --git a/packages/three_js_core/lib/materials/mesh_matcap_material.dart b/packages/three_js_core/lib/materials/mesh_matcap_material.dart index eaa00720..21cefeeb 100755 --- a/packages/three_js_core/lib/materials/mesh_matcap_material.dart +++ b/packages/three_js_core/lib/materials/mesh_matcap_material.dart @@ -86,4 +86,10 @@ class MeshMatcapMaterial extends Material { return this; } + + /// Return a new material with the same parameters as this material. + @override + MeshMatcapMaterial clone() { + return MeshMatcapMaterial()..copy(this); + } } diff --git a/packages/three_js_core/lib/materials/mesh_normal_material.dart b/packages/three_js_core/lib/materials/mesh_normal_material.dart index da9f34b0..6837fa6c 100755 --- a/packages/three_js_core/lib/materials/mesh_normal_material.dart +++ b/packages/three_js_core/lib/materials/mesh_normal_material.dart @@ -40,4 +40,10 @@ class MeshNormalMaterial extends Material { return this; } + + /// Return a new material with the same parameters as this material. + @override + MeshNormalMaterial clone() { + return MeshNormalMaterial()..copy(this); + } } diff --git a/packages/three_js_core/lib/materials/points_material.dart b/packages/three_js_core/lib/materials/points_material.dart index 1e80e729..ede8f43d 100755 --- a/packages/three_js_core/lib/materials/points_material.dart +++ b/packages/three_js_core/lib/materials/points_material.dart @@ -62,4 +62,10 @@ class PointsMaterial extends Material { return this; } + + /// Return a new material with the same parameters as this material. + @override + PointsMaterial clone() { + return PointsMaterial()..copy(this); + } } diff --git a/packages/three_js_core/lib/objects/skeleton.dart b/packages/three_js_core/lib/objects/skeleton.dart index bb4bf43c..89caac5f 100755 --- a/packages/three_js_core/lib/objects/skeleton.dart +++ b/packages/three_js_core/lib/objects/skeleton.dart @@ -40,7 +40,7 @@ class Skeleton { String uuid = MathUtils.generateUUID(); late List bones; late List boneInverses; - Float32List? boneMatrices; + late final Float32List boneMatrices; DataTexture? boneTexture; late int boneTextureSize; double frame = -1; @@ -154,7 +154,8 @@ class Skeleton { final matrix = bones[i].matrixWorld; _offsetMatrix.multiply2(matrix, boneInverses[i]); - _offsetMatrix.copyIntoArray(boneMatrices!.toList(), i * 16); + //_offsetMatrix.copyIntoArray(boneMatrices.toList(), i * 16); + boneMatrices.setAll(i * 16, _offsetMatrix.storage); } if (boneTexture != null) { @@ -207,7 +208,7 @@ class Skeleton { if(disposed) return; disposed = true; boneTexture?.dispose(); - boneMatrices?.clear(); + //boneMatrices.clear(); bones.forEach((bone){ bone.dispose(); @@ -267,7 +268,7 @@ class Skeleton { Float32List getValue(String name) { if(name == "boneMatrices") { - return boneMatrices!; + return boneMatrices; } else { throw("Skeleton getValue name: $name is not support "); } diff --git a/packages/three_js_core/pubspec.yaml b/packages/three_js_core/pubspec.yaml index ce022457..0a6308bc 100755 --- a/packages/three_js_core/pubspec.yaml +++ b/packages/three_js_core/pubspec.yaml @@ -11,7 +11,7 @@ dependencies: flutter: sdk: flutter logger: ^2.5.0 - three_js_math: ^0.2.5 + three_js_math: ^0.3.0 web: ^1.1.1 flutter_angle: ^0.3.9 diff --git a/packages/three_js_core_loaders/CHANGELOG.md b/packages/three_js_core_loaders/CHANGELOG.md index 9e8ad3c6..1fb2bf52 100644 --- a/packages/three_js_core_loaders/CHANGELOG.md +++ b/packages/three_js_core_loaders/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.0 + +* Removed NativeArray for Zero-Allocation Updates. + ## 0.2.2 * Fixed minor bug for WASM diff --git a/packages/three_js_core_loaders/pubspec.yaml b/packages/three_js_core_loaders/pubspec.yaml index bec5697a..495f5942 100644 --- a/packages/three_js_core_loaders/pubspec.yaml +++ b/packages/three_js_core_loaders/pubspec.yaml @@ -10,8 +10,8 @@ environment: dependencies: flutter: sdk: flutter - three_js_core: ^0.2.7 - three_js_math: ^0.2.6 + three_js_core: ^0.3.0 + three_js_math: ^0.3.0 image: ^4.5.4 http: ^1.3.0 web: ^1.1.1 diff --git a/packages/three_js_curves/CHANGELOG.md b/packages/three_js_curves/CHANGELOG.md index 6f842540..54803b70 100644 --- a/packages/three_js_curves/CHANGELOG.md +++ b/packages/three_js_curves/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.0 + +* Removed NativeArray for Zero-Allocation Updates. + ## 0.2.1 * Fixed: Some cloning issues. diff --git a/packages/three_js_curves/pubspec.yaml b/packages/three_js_curves/pubspec.yaml index 732877e4..5f432bd6 100644 --- a/packages/three_js_curves/pubspec.yaml +++ b/packages/three_js_curves/pubspec.yaml @@ -10,7 +10,7 @@ environment: dependencies: flutter: sdk: flutter - three_js_math: ^0.2.0 + three_js_math: ^0.3.0 dev_dependencies: flutter_test: diff --git a/packages/three_js_exporters/CHANGELOG.md b/packages/three_js_exporters/CHANGELOG.md index e70e2a0a..c23e58d2 100755 --- a/packages/three_js_exporters/CHANGELOG.md +++ b/packages/three_js_exporters/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.0 + +* Removed NativeArray for Zero-Allocation Updates. + ## 0.2.0 * Updated to the newest version of three_js_math package. diff --git a/packages/three_js_exporters/pubspec.yaml b/packages/three_js_exporters/pubspec.yaml index fcf89eef..c33776d8 100755 --- a/packages/three_js_exporters/pubspec.yaml +++ b/packages/three_js_exporters/pubspec.yaml @@ -13,8 +13,8 @@ dependencies: file_picker: ^10.1.9 web: ^1.1.1 path_provider: ^2.1.5 - three_js_core: ^0.2.0 - three_js_math: ^0.2.0 + three_js_core: ^0.3.0 + three_js_math: ^0.3.0 dev_dependencies: flutter_test: diff --git a/packages/three_js_geometry/CHANGELOG.md b/packages/three_js_geometry/CHANGELOG.md index 06863402..9a35afc8 100755 --- a/packages/three_js_geometry/CHANGELOG.md +++ b/packages/three_js_geometry/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.0 + +* Removed NativeArray for Zero-Allocation Updates. + ## 0.2.1 * Removed some global variables. diff --git a/packages/three_js_geometry/pubspec.yaml b/packages/three_js_geometry/pubspec.yaml index 11822224..4d5709f1 100755 --- a/packages/three_js_geometry/pubspec.yaml +++ b/packages/three_js_geometry/pubspec.yaml @@ -1,6 +1,6 @@ name: three_js_geometry description: "Flutter three_js_geometry package converted from threejs and three_dart package created for three_js." -version: 0.2.1 +version: 0.3.0 homepage: https://github.com/Knightro63/three_js/tree/main/packages/three_js_geometry environment: @@ -10,9 +10,9 @@ environment: dependencies: flutter: sdk: flutter - three_js_core: ^0.2.0 - three_js_math: ^0.2.0 - three_js_curves: ^0.2.0 + three_js_core: ^0.3.0 + three_js_math: ^0.3.0 + three_js_curves: ^0.3.0 dev_dependencies: flutter_test: diff --git a/packages/three_js_helpers/CHANGELOG.md b/packages/three_js_helpers/CHANGELOG.md index 9221c9f2..c0b35c27 100755 --- a/packages/three_js_helpers/CHANGELOG.md +++ b/packages/three_js_helpers/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.0 + +* Removed NativeArray for Zero-Allocation Updates. + ## 0.2.3 * Removed globale variables. diff --git a/packages/three_js_helpers/pubspec.yaml b/packages/three_js_helpers/pubspec.yaml index a2362aff..b651239b 100755 --- a/packages/three_js_helpers/pubspec.yaml +++ b/packages/three_js_helpers/pubspec.yaml @@ -10,10 +10,10 @@ environment: dependencies: flutter: sdk: flutter - three_js_core: ^0.2.0 - three_js_math: ^0.2.0 - three_js_geometry: ^0.2.0 - three_js_animations: ^0.2.0 + three_js_core: ^0.3.0 + three_js_math: ^0.3.0 + three_js_geometry: ^0.3.0 + three_js_animations: ^0.3.0 dev_dependencies: flutter_test: diff --git a/packages/three_js_line/CHANGELOG.md b/packages/three_js_line/CHANGELOG.md index 6db095c0..9eb511a5 100644 --- a/packages/three_js_line/CHANGELOG.md +++ b/packages/three_js_line/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.0 + +* Removed NativeArray for Zero-Allocation Updates. + ## 0.2.1 * Removed some gloable variables. diff --git a/packages/three_js_line/pubspec.yaml b/packages/three_js_line/pubspec.yaml index 39c2c6aa..8c42353a 100644 --- a/packages/three_js_line/pubspec.yaml +++ b/packages/three_js_line/pubspec.yaml @@ -1,6 +1,6 @@ name: three_js_line description: "Flutter three_js_line package converted from threejs to increase the thickness of line geometry." -version: 0.2.1 +version: 0.3.0 homepage: https://github.com/Knightro63/three_js/tree/main/packages/three_js_line environment: @@ -10,9 +10,9 @@ environment: dependencies: flutter: sdk: flutter - three_js_core: ^0.2.0 - three_js_math: ^0.2.0 - three_js_geometry: ^0.2.0 + three_js_core: ^0.3.0 + three_js_math: ^0.3.0 + three_js_geometry: ^0.3.0 dev_dependencies: flutter_test: diff --git a/packages/three_js_math/CHANGELOG.md b/packages/three_js_math/CHANGELOG.md index b1ddcffc..a4af3afa 100755 --- a/packages/three_js_math/CHANGELOG.md +++ b/packages/three_js_math/CHANGELOG.md @@ -1,6 +1,7 @@ ## 0.3.0 * Removed FlutterAngle +* Removed NativeArray for Zero-Allocation Updates. ## 0.2.6 diff --git a/packages/three_js_math/pubspec.yaml b/packages/three_js_math/pubspec.yaml index 1db282c4..334eea08 100755 --- a/packages/three_js_math/pubspec.yaml +++ b/packages/three_js_math/pubspec.yaml @@ -11,7 +11,6 @@ dependencies: flutter: sdk: flutter uuid: ^4.4.0 - #flutter_angle: ^0.3.9 dev_dependencies: flutter_test: diff --git a/packages/three_js_modifers/CHANGELOG.md b/packages/three_js_modifers/CHANGELOG.md index e8faf42c..df28addf 100644 --- a/packages/three_js_modifers/CHANGELOG.md +++ b/packages/three_js_modifers/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.0 + +* Removed NativeArray for Zero-Allocation Updates. + ## 0.2.1 * Updated buffergeometry utils. diff --git a/packages/three_js_modifers/pubspec.yaml b/packages/three_js_modifers/pubspec.yaml index e8d15c32..de843fdf 100644 --- a/packages/three_js_modifers/pubspec.yaml +++ b/packages/three_js_modifers/pubspec.yaml @@ -10,8 +10,8 @@ environment: dependencies: flutter: sdk: flutter - three_js_core: ^0.2.0 - three_js_math: ^0.2.0 + three_js_core: ^0.3.0 + three_js_math: ^0.3.0 dev_dependencies: flutter_test: diff --git a/packages/three_js_objects/CHANGELOG.md b/packages/three_js_objects/CHANGELOG.md index d2267978..9b9ac7ee 100644 --- a/packages/three_js_objects/CHANGELOG.md +++ b/packages/three_js_objects/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.0 + +* Removed NativeArray for Zero-Allocation Updates. + ## 0.2.2 * Added planet generator. diff --git a/packages/three_js_objects/pubspec.yaml b/packages/three_js_objects/pubspec.yaml index 926b220f..4d317fc5 100644 --- a/packages/three_js_objects/pubspec.yaml +++ b/packages/three_js_objects/pubspec.yaml @@ -10,10 +10,10 @@ environment: dependencies: flutter: sdk: flutter - three_js_core: ^0.2.0 - three_js_core_loaders: ^0.2.0 - three_js_math: ^0.2.0 - three_js_helpers: ^0.2.0 + three_js_core: ^0.3.0 + three_js_core_loaders: ^0.3.0 + three_js_math: ^0.3.0 + three_js_helpers: ^0.3.0 web: ^1.1.1 dev_dependencies: diff --git a/packages/three_js_postprocessing/CHANGELOG.md b/packages/three_js_postprocessing/CHANGELOG.md index f65c3703..99d8a3e2 100644 --- a/packages/three_js_postprocessing/CHANGELOG.md +++ b/packages/three_js_postprocessing/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.0 + +* Removed NativeArray for Zero-Allocation Updates. + ## 0.2.1 * Added FXAA pass diff --git a/packages/three_js_postprocessing/pubspec.yaml b/packages/three_js_postprocessing/pubspec.yaml index 3fe1f0b9..7b7369be 100644 --- a/packages/three_js_postprocessing/pubspec.yaml +++ b/packages/three_js_postprocessing/pubspec.yaml @@ -10,8 +10,8 @@ environment: dependencies: flutter: sdk: flutter - three_js_core: ^0.2.0 - three_js_math: ^0.2.0 + three_js_core: ^0.3.0 + three_js_math: ^0.3.0 dev_dependencies: flutter_test: diff --git a/packages/three_js_sensors/CHANGELOG.md b/packages/three_js_sensors/CHANGELOG.md index ae8ebabd..1a7ead20 100644 --- a/packages/three_js_sensors/CHANGELOG.md +++ b/packages/three_js_sensors/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.2.0 + +* Updated to newest version of three_js packages. + ## 0.1.2 * Added Quant export for AbsoluteOrientation diff --git a/packages/three_js_sensors/pubspec.yaml b/packages/three_js_sensors/pubspec.yaml index fa2549c0..5eeb7098 100644 --- a/packages/three_js_sensors/pubspec.yaml +++ b/packages/three_js_sensors/pubspec.yaml @@ -1,6 +1,6 @@ name: three_js_sensors description: "Flutter plugin for accessing accelerometer, gyroscope, and magnetometer sensors." -version: 0.1.2 +version: 0.2.0 homepage: https://github.com/Knightro63/three_js/tree/main/packages/three_js_sensors environment: diff --git a/packages/three_js_simple_loaders/CHANGELOG.md b/packages/three_js_simple_loaders/CHANGELOG.md index a572ba4b..9fd2ea92 100755 --- a/packages/three_js_simple_loaders/CHANGELOG.md +++ b/packages/three_js_simple_loaders/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.0 + +* Removed NativeArray for Zero-Allocation Updates. + ## 0.2.2 * Removed some global variables. diff --git a/packages/three_js_simple_loaders/pubspec.yaml b/packages/three_js_simple_loaders/pubspec.yaml index 0c0b74e1..257a2a44 100755 --- a/packages/three_js_simple_loaders/pubspec.yaml +++ b/packages/three_js_simple_loaders/pubspec.yaml @@ -1,6 +1,6 @@ name: three_js_simple_loaders description: "three_js simple loader package e.g.(obj and stl) converted from threejs and three_dart package." -version: 0.2.2 +version: 0.3.0 homepage: https://github.com/Knightro63/three_js/tree/main/packages/three_js_simple_loaders topics: @@ -17,9 +17,9 @@ environment: dependencies: flutter: sdk: flutter - three_js_core_loaders: ^0.2.0 - three_js_core: ^0.2.0 - three_js_math: ^0.2.0 + three_js_core_loaders: ^0.3.0 + three_js_core: ^0.3.0 + three_js_math: ^0.3.0 dev_dependencies: flutter_test: diff --git a/packages/three_js_svg/CHANGELOG.md b/packages/three_js_svg/CHANGELOG.md index dba428be..09e46498 100644 --- a/packages/three_js_svg/CHANGELOG.md +++ b/packages/three_js_svg/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.0 + +* Removed NativeArray for Zero-Allocation Updates. + ## 0.2.1 * Removed some gloable variables. diff --git a/packages/three_js_svg/pubspec.yaml b/packages/three_js_svg/pubspec.yaml index 4a6b06a3..63f2b55c 100644 --- a/packages/three_js_svg/pubspec.yaml +++ b/packages/three_js_svg/pubspec.yaml @@ -10,10 +10,10 @@ environment: dependencies: flutter: sdk: flutter - three_js_curves: ^0.2.0 - three_js_core_loaders: ^0.2.0 - three_js_core: ^0.2.0 - three_js_math: ^0.2.0 + three_js_curves: ^0.3.0 + three_js_core_loaders: ^0.3.0 + three_js_core: ^0.3.0 + three_js_math: ^0.3.0 xml: ^6.5.0 dev_dependencies: diff --git a/packages/three_js_terrain/CHANGELOG.md b/packages/three_js_terrain/CHANGELOG.md index 0f6019a3..d3214a90 100644 --- a/packages/three_js_terrain/CHANGELOG.md +++ b/packages/three_js_terrain/CHANGELOG.md @@ -1,5 +1,6 @@ -## 0.2.1 +## 0.3.0 +* Removed NativeArray for Zero-Allocation Updates. * Added HexTilingMaterial Support. ## 0.2.0 diff --git a/packages/three_js_terrain/pubspec.yaml b/packages/three_js_terrain/pubspec.yaml index 16d49b03..c734412e 100644 --- a/packages/three_js_terrain/pubspec.yaml +++ b/packages/three_js_terrain/pubspec.yaml @@ -11,8 +11,8 @@ dependencies: flutter: sdk: flutter image: ^4.5.4 - three_js_core: ^0.2.7 - three_js_math: ^0.2.0 + three_js_core: ^0.3.0 + three_js_math: ^0.3.0 dev_dependencies: flutter_test: diff --git a/packages/three_js_text/CHANGELOG.md b/packages/three_js_text/CHANGELOG.md index ac3ff6ed..e13bff79 100755 --- a/packages/three_js_text/CHANGELOG.md +++ b/packages/three_js_text/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.0 + +* Removed NativeArray for Zero-Allocation Updates. + ## 0.2.0 * Added WASM support. diff --git a/packages/three_js_text/pubspec.yaml b/packages/three_js_text/pubspec.yaml index badb76ac..f71ca82c 100755 --- a/packages/three_js_text/pubspec.yaml +++ b/packages/three_js_text/pubspec.yaml @@ -12,10 +12,10 @@ dependencies: sdk: flutter opentype_dart: ^0.0.1 - three_js_core: ^0.2.0 - three_js_math: ^0.2.0 - three_js_curves: ^0.2.0 - three_js_core_loaders: ^0.2.0 + three_js_core: ^0.3.0 + three_js_math: ^0.3.0 + three_js_curves: ^0.3.0 + three_js_core_loaders: ^0.3.0 xml: ^6.5.0 dev_dependencies: diff --git a/packages/three_js_tjs_loader/CHANGELOG.md b/packages/three_js_tjs_loader/CHANGELOG.md index 9ef0498b..2d2e702c 100644 --- a/packages/three_js_tjs_loader/CHANGELOG.md +++ b/packages/three_js_tjs_loader/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.0 + +* Removed NativeArray for Zero-Allocation Updates. + ## 0.2.2 * Updated Materials to be loaded. diff --git a/packages/three_js_tjs_loader/lib/material_loader.dart b/packages/three_js_tjs_loader/lib/material_loader.dart index af6056be..078a3243 100644 --- a/packages/three_js_tjs_loader/lib/material_loader.dart +++ b/packages/three_js_tjs_loader/lib/material_loader.dart @@ -89,15 +89,47 @@ class MaterialLoader extends Loader { if (json["type"] == "MeshBasicMaterial") { material = MeshBasicMaterial(); - } else if (json["type"] == "MeshLambertMaterial") { + } + else if (json["type"] == "MeshLambertMaterial") { material = MeshLambertMaterial(); - } else if (json["type"] == "MeshPhongMaterial") { + } + else if (json["type"] == "MeshDepthMaterial") { + material = MeshDepthMaterial(); + } + else if (json["type"] == "MeshDistanceMaterial") { + material = MeshDistanceMaterial(); + } + else if (json["type"] == "MeshPhongMaterial") { material = MeshPhongMaterial(); - } else if (json["type"] == "MeshMatcapMaterial") { + } + else if (json["type"] == "MeshMatcapMaterial") { material = MeshMatcapMaterial(); - } else if (json["type"] == "MeshPhysicalMaterial") { + } + else if (json["type"] == "MeshGouraudMaterial") { + material = MeshGouraudMaterial(); + } + else if (json["type"] == "MeshNormalMaterial") { + material = MeshNormalMaterial(); + } + else if (json["type"] == "MeshStandardMaterial") { + material = MeshStandardMaterial(); + } + else if (json["type"] == "MeshPhysicalMaterial") { material = MeshPhysicalMaterial(); - } else if (json["type"] == "HexTilingMaterial") { + } + else if (json["type"] == "MeshToonMaterial") { + material = MeshToonMaterial(); + } + else if (json["type"] == "PointsMaterial") { + material = PointsMaterial(); + } + else if (json["type"] == "LineDashedMaterial") { + material = LineDashedMaterial(); + } + else if (json["type"] == "LineBasicMaterial") { + material = LineBasicMaterial(); + } + else if (json["type"] == "HexTilingMaterial") { material = HexTilingMaterial( HexTilingParams.fromJson(json['hexTiling'] ?? {}), ); diff --git a/packages/three_js_tjs_loader/pubspec.yaml b/packages/three_js_tjs_loader/pubspec.yaml index fc0b47a0..1549067c 100644 --- a/packages/three_js_tjs_loader/pubspec.yaml +++ b/packages/three_js_tjs_loader/pubspec.yaml @@ -10,12 +10,12 @@ environment: dependencies: flutter: sdk: flutter - three_js_core: ^0.2.0 - three_js_core_loaders: ^0.2.0 - three_js_curves: ^0.2.0 - three_js_math: ^0.2.0 - three_js_geometry: ^0.2.0 - three_js_animations: ^0.2.0 + three_js_core: ^0.3.0 + three_js_core_loaders: ^0.3.0 + three_js_curves: ^0.3.0 + three_js_math: ^0.3.0 + three_js_geometry: ^0.3.0 + three_js_animations: ^0.3.0 dev_dependencies: flutter_test: diff --git a/packages/three_js_transform_controls/CHANGELOG.md b/packages/three_js_transform_controls/CHANGELOG.md index 3fe265b1..17313239 100644 --- a/packages/three_js_transform_controls/CHANGELOG.md +++ b/packages/three_js_transform_controls/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.3.0 + +* Removed NativeArray for Zero-Allocation Updates. + ## 0.2.1 * Removed some gloable variables. diff --git a/packages/three_js_transform_controls/pubspec.yaml b/packages/three_js_transform_controls/pubspec.yaml index 74e0fddd..8a4d825c 100644 --- a/packages/three_js_transform_controls/pubspec.yaml +++ b/packages/three_js_transform_controls/pubspec.yaml @@ -10,11 +10,11 @@ environment: dependencies: flutter: sdk: flutter - three_js_core: ^0.2.0 - three_js_math: ^0.2.0 - three_js_geometry: ^0.2.0 - three_js_curves: ^0.2.0 - three_js_helpers: ^0.2.0 + three_js_core: ^0.3.0 + three_js_math: ^0.3.0 + three_js_geometry: ^0.3.0 + three_js_curves: ^0.3.0 + three_js_helpers: ^0.3.0 dev_dependencies: flutter_test: diff --git a/packages/three_js_video_texture/CHANGELOG.md b/packages/three_js_video_texture/CHANGELOG.md index 3af0f4ad..011f993a 100644 --- a/packages/three_js_video_texture/CHANGELOG.md +++ b/packages/three_js_video_texture/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.0 + +* Updated to newest version of three_js packages. + ## 0.0.2 * Removed unnecessary file. diff --git a/packages/three_js_video_texture/pubspec.yaml b/packages/three_js_video_texture/pubspec.yaml index 02200155..02cd88b4 100644 --- a/packages/three_js_video_texture/pubspec.yaml +++ b/packages/three_js_video_texture/pubspec.yaml @@ -1,6 +1,6 @@ name: three_js_video_texture description: "A three_js package that helps with video textures." -version: 0.0.2 +version: 0.1.0 homepage: https://github.com/Knightro63/three_js/tree/main/packages/three_js_video_texture environment: @@ -10,8 +10,8 @@ environment: dependencies: flutter: sdk: flutter - three_js_core: ^0.2.1 - three_js_math: ^0.2.1 + three_js_core: ^0.3.0 + three_js_math: ^0.3.0 media_kit: ^1.2.0 media_kit_video: ^1.2.5 media_kit_libs_video: ^1.0.5 diff --git a/packages/three_js_xr/CHANGELOG.md b/packages/three_js_xr/CHANGELOG.md index dbae9db2..d92af1f7 100644 --- a/packages/three_js_xr/CHANGELOG.md +++ b/packages/three_js_xr/CHANGELOG.md @@ -1,3 +1,7 @@ +## 0.1.0 + +* Removed NativeArray for Zero-Allocation Updates. + ## 0.0.2 * Added vr for android and ios. diff --git a/packages/three_js_xr/pubspec.yaml b/packages/three_js_xr/pubspec.yaml index a04112b5..099dd6ff 100644 --- a/packages/three_js_xr/pubspec.yaml +++ b/packages/three_js_xr/pubspec.yaml @@ -10,12 +10,12 @@ environment: dependencies: flutter: sdk: flutter - three_js_math: ^0.2.4 - three_js_advanced_loaders: ^0.2.4 - three_js_core: ^0.2.5 - three_js_geometry: ^0.2.1 - three_js_core_loaders: ^0.2.1 - three_js_sensors: ^0.1.2 + three_js_math: ^0.3.0 + three_js_advanced_loaders: ^0.3.0 + three_js_core: ^0.3.0 + three_js_geometry: ^0.3.0 + three_js_core_loaders: ^0.3.0 + three_js_sensors: ^0.3.0 web: ^1.1.1 dev_dependencies: From 70ca754dfbf7382e60b67b7192997a83559eac6b Mon Sep 17 00:00:00 2001 From: Knightro <50028636+Knightro63@users.noreply.github.com> Date: Sat, 24 Jan 2026 22:21:47 -0500 Subject: [PATCH 03/17] increasing speed --- examples/lib/loaders/webgl_loader_svg.dart | 8 ++++---- examples/lib/material/webgl_materials_video.dart | 2 -- examples/pubspec.yaml | 3 ++- packages/three_js_core/lib/renderers/pmrem_generator.dart | 6 +++--- .../lib/renderers/webgl/web_gl_attributes.dart | 2 +- .../lib/renderers/webgl/web_gl_geometries.dart | 2 +- .../lib/renderers/webgl/web_gl_morphtargets.dart | 2 +- .../three_js_core/lib/renderers/webgl/web_gl_state.dart | 5 +++-- .../lib/renderers/webgl/web_gl_uniforms_groups.dart | 8 ++++---- .../lib/renderers/webgl/web_gl_uniforms_helper.dart | 4 +++- 10 files changed, 22 insertions(+), 20 deletions(-) diff --git a/examples/lib/loaders/webgl_loader_svg.dart b/examples/lib/loaders/webgl_loader_svg.dart index bb14af26..3eacd8d3 100644 --- a/examples/lib/loaders/webgl_loader_svg.dart +++ b/examples/lib/loaders/webgl_loader_svg.dart @@ -133,8 +133,9 @@ class _MyAppState extends State { final strokeColor = path.userData?["style"]["stroke"]; if (guiData["drawStrokes"] == true && - strokeColor != null && - strokeColor != 'none') { + strokeColor != null && + strokeColor != 'none' + ) { three.MeshBasicMaterial material = three.MeshBasicMaterial.fromMap({ "color": three.Color().setStyle(strokeColor).convertSRGBToLinear(), "opacity": path.userData?["style"]["strokeOpacity"], @@ -146,8 +147,7 @@ class _MyAppState extends State { for (int j = 0, jl = path.subPaths.length; j < jl; j++) { three.Path subPath = path.subPaths[j]; - final geometry = SVGLoader.pointsToStroke( - subPath.getPoints(), path.userData?["style"]); + final geometry = SVGLoader.pointsToStroke(subPath.getPoints(), path.userData?["style"]); if (geometry != null) { final mesh = three.Mesh(geometry, material); diff --git a/examples/lib/material/webgl_materials_video.dart b/examples/lib/material/webgl_materials_video.dart index e5872dd0..ad50c987 100644 --- a/examples/lib/material/webgl_materials_video.dart +++ b/examples/lib/material/webgl_materials_video.dart @@ -4,8 +4,6 @@ import 'package:flutter/material.dart'; import 'package:example/src/statistics.dart'; import 'package:three_js/three_js.dart' as three; import 'package:three_js_postprocessing/post/effect_composer.dart'; -// import 'package:three_js_postprocessing/post/bloom_pass.dart'; -// import 'package:three_js_postprocessing/post/outpass.dart'; import 'package:three_js_postprocessing/post/render_pass.dart'; import 'package:three_js_video_texture/three_js_video_texture.dart'; diff --git a/examples/pubspec.yaml b/examples/pubspec.yaml index b8ff8c7f..ad6f32b2 100644 --- a/examples/pubspec.yaml +++ b/examples/pubspec.yaml @@ -104,7 +104,8 @@ dependency_overrides: path: ../packages/three_js_text three_js_geometry: path: ../packages/three_js_geometry - + three_js_sensors: + path: ../packages/three_js_sensors flutter: uses-material-design: true diff --git a/packages/three_js_core/lib/renderers/pmrem_generator.dart b/packages/three_js_core/lib/renderers/pmrem_generator.dart index e8a0e7a1..af3d5b0a 100755 --- a/packages/three_js_core/lib/renderers/pmrem_generator.dart +++ b/packages/three_js_core/lib/renderers/pmrem_generator.dart @@ -439,13 +439,13 @@ class PMREMGenerator { console.warning("sigmaRadians, $sigmaRadians, is too large and will clip, as it requested $samples samples when the maximum is set to $maxSamples"); } - List weights = []; + Float32List weights = Float32List(maxSamples); double sum = 0; for (int i = 0; i < maxSamples; ++i) { final x = i / sigmaPixels; final weight = math.exp(-x * x / 2); - weights.add(weight); + weights[i] = weight; if (i == 0) { sum += weight; @@ -460,7 +460,7 @@ class PMREMGenerator { blurUniforms['envMap']["value"] = targetIn?.texture; blurUniforms['samples']["value"] = samples; - blurUniforms['weights']["value"] = Float32List.fromList(weights); + blurUniforms['weights']["value"] = weights; blurUniforms['latitudinal']["value"] = direction == 'latitudinal'; if (poleAxis != null) { diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_attributes.dart b/packages/three_js_core/lib/renderers/webgl/web_gl_attributes.dart index a4627e42..11c38c5d 100755 --- a/packages/three_js_core/lib/renderers/webgl/web_gl_attributes.dart +++ b/packages/three_js_core/lib/renderers/webgl/web_gl_attributes.dart @@ -133,7 +133,7 @@ class WebGLAttributes { f, ); - f.dispose(); + //f.dispose(); } attribute.clearUpdateRanges(); diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_geometries.dart b/packages/three_js_core/lib/renderers/webgl/web_gl_geometries.dart index 082fe817..a602e36a 100755 --- a/packages/three_js_core/lib/renderers/webgl/web_gl_geometries.dart +++ b/packages/three_js_core/lib/renderers/webgl/web_gl_geometries.dart @@ -75,7 +75,7 @@ class WebGLGeometries { } void updateWireframeAttribute(BufferGeometry geometry) { - List indices = []; + Uint32List indices = Uint32List(0); final geometryIndex = geometry.index; final geometryPosition = geometry.attributes["position"]; diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_morphtargets.dart b/packages/three_js_core/lib/renderers/webgl/web_gl_morphtargets.dart index 582caf5e..00380f0a 100755 --- a/packages/three_js_core/lib/renderers/webgl/web_gl_morphtargets.dart +++ b/packages/three_js_core/lib/renderers/webgl/web_gl_morphtargets.dart @@ -58,7 +58,7 @@ class WebGLMorphtargets { } void update(Object3D object, BufferGeometry geometry, WebGLProgram program) { - List? objectInfluences = object.morphTargetInfluences; + Float32List? objectInfluences = Float32List.fromList(object.morphTargetInfluences); final morphAttribute = geometry.morphAttributes["position"] ?? geometry.morphAttributes["normal"] ?? geometry.morphAttributes["color"]; final morphTargetsCount = (morphAttribute != null) ? morphAttribute.length : 0; diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_state.dart b/packages/three_js_core/lib/renderers/webgl/web_gl_state.dart index 3b1f4a2d..170f1f05 100755 --- a/packages/three_js_core/lib/renderers/webgl/web_gl_state.dart +++ b/packages/three_js_core/lib/renderers/webgl/web_gl_state.dart @@ -123,8 +123,9 @@ class WebGLState { currentViewport = Vector4.identity(); } + final data = Uint8List(4); + WebGLTexture createTexture(int type, int target, int count) { - final data = Uint8List(4); // 4 is required to match default unpack alignment of 4. // final texture = gl.createTexture(); @@ -137,7 +138,7 @@ class WebGLState { gl.texImage2D(target + i, 0, WebGL.RGBA, 1, 1, 0, WebGL.RGBA, WebGL.UNSIGNED_BYTE, data); } - data.dispose(); + //data.dispose(); return texture; } diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_uniforms_groups.dart b/packages/three_js_core/lib/renderers/webgl/web_gl_uniforms_groups.dart index 523d5c12..353c61be 100644 --- a/packages/three_js_core/lib/renderers/webgl/web_gl_uniforms_groups.dart +++ b/packages/three_js_core/lib/renderers/webgl/web_gl_uniforms_groups.dart @@ -7,7 +7,7 @@ class WebGLUniformsGroups{ Map buffers = {}; Map updateList = {}; - List allocatedBindingPoints = []; + late final Uint32List allocatedBindingPoints = Uint32List(maxBindingPoints); RenderingContext gl; late final int maxBindingPoints; // binding points are global whereas block indices are per shader program @@ -64,8 +64,8 @@ class WebGLUniformsGroups{ int allocateBindingPointIndex() { for (int i = 0; i < maxBindingPoints; i ++ ) { - if (!allocatedBindingPoints.contains( i )) { - allocatedBindingPoints.add( i ); + if (allocatedBindingPoints[i] == 0) { + allocatedBindingPoints[i] = 1; return i; } } @@ -271,7 +271,7 @@ class WebGLUniformsGroups{ gl.deleteBuffer( buffers[ id ] ); } - allocatedBindingPoints = []; + allocatedBindingPoints.clear(); buffers = {}; updateList = {}; } diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_uniforms_helper.dart b/packages/three_js_core/lib/renderers/webgl/web_gl_uniforms_helper.dart index 29ec7e29..844063fd 100755 --- a/packages/three_js_core/lib/renderers/webgl/web_gl_uniforms_helper.dart +++ b/packages/three_js_core/lib/renderers/webgl/web_gl_uniforms_helper.dart @@ -457,11 +457,13 @@ mixin WebGLUniformsHelper { cache[0] = v; } + Int32List iv = Int32List(2); void setValueV2i(RenderingContext gl, Vector v, [WebGLTextures? textures]) { final cache = this.cache; if (arraysEqual(cache, v)) return; - Int32List iv = Int32List.fromList([v.x.toInt(),v.y.toInt()]); + iv[0] = v.x.toInt(); + iv[1] = v.y.toInt(); gl.uniform2iv(addr, iv); copyArray(cache, v.copyIntoArray()); } From de1eccee582e5ef62fc5fb676b283bfd6687e625 Mon Sep 17 00:00:00 2001 From: Knightro <50028636+Knightro63@users.noreply.github.com> Date: Mon, 26 Jan 2026 16:59:46 -0500 Subject: [PATCH 04/17] seperated renderers from core Now there is webgl renderer which is similar to three_dart renderer angle which is similar to three.js webgl renderer future impeller and gpu --- .gitignore | 1 + README.md | 7 + packages/three_js/CHANGELOG.md | 1 + packages/three_js/README.md | 7 + packages/three_js/pubspec.yaml | 1 + packages/three_js_angle/.gitignore | 141 ++ packages/three_js_angle/CHANGELOG.md | 3 + packages/three_js_angle/LICENSE | 21 + packages/three_js_angle/README.md | 469 ++++ packages/three_js_angle/lib/three_js.dart | 14 + packages/three_js_angle/pubspec.yaml | 43 + packages/three_js_angle_renderer/.gitignore | 143 ++ packages/three_js_angle_renderer/CHANGELOG.md | 3 + packages/three_js_angle_renderer/LICENSE | 21 + packages/three_js_angle_renderer/README.md | 21 + .../example/.gitignore | 45 + .../three_js_angle_renderer/example/README.md | 16 + .../example/lib/main.dart | 114 + .../example/pubspec.yaml | 33 + .../lib/angle/angle_animation.dart | 36 + .../lib/angle/angle_attributes.dart | 211 ++ .../lib/angle/angle_background.dart | 234 ++ .../lib/angle/angle_binding_states.dart | 466 ++++ .../lib/angle/angle_buffer_renderer.dart | 107 + .../lib/angle/angle_capabilities.dart | 117 + .../lib/angle/angle_clipping.dart | 138 ++ .../lib/angle/angle_cube_maps.dart | 74 + .../lib/angle/angle_cube_uv_maps.dart | 102 + .../lib/angle/angle_extensions.dart | 127 + .../lib/angle/angle_geometries.dart | 160 ++ .../angle/angle_indexed_buffer_renderer.dart | 79 + .../lib/angle/angle_info.dart | 51 + .../lib/angle/angle_lights.dart | 586 +++++ .../lib/angle/angle_materials.dart | 386 +++ .../lib/angle/angle_morphtargets.dart | 170 ++ .../lib/angle/angle_objects.dart | 76 + .../lib/angle/angle_parameters.dart | 670 +++++ .../lib/angle/angle_program.dart | 521 ++++ .../lib/angle/angle_program_extra.dart | 424 ++++ .../lib/angle/angle_programs.dart | 509 ++++ .../lib/angle/angle_properties.dart | 38 + .../lib/angle/angle_render_list.dart | 228 ++ .../lib/angle/angle_render_lists.dart | 30 + .../lib/angle/angle_render_states.dart | 92 + .../lib/angle/angle_shader.dart | 19 + .../lib/angle/angle_shader_cache.dart | 92 + .../lib/angle/angle_shadow_map.dart | 348 +++ .../lib/angle/angle_state.dart | 1011 ++++++++ .../lib/angle/angle_textures.dart | 1632 +++++++++++++ .../lib/angle/angle_uniforms.dart | 107 + .../lib/angle/angle_uniforms_groups.dart | 278 +++ .../lib/angle/angle_uniforms_helper.dart | 756 ++++++ .../lib/angle/angle_utils.dart | 184 ++ .../lib/angle/index.dart | 48 + .../lib/materials/hex_tiling_material.dart | 10 +- .../lib/renderers/3d_render_target.dart | 9 + .../lib/renderers/array_render_target.dart | 9 + .../lib/renderers/cube_render_target.dart | 126 + .../lib/renderers/index.dart | 16 + .../lib/renderers/pmrem_generator.dart | 13 +- .../lib/renderers/render_target.dart | 44 + .../lib/renderers/renderer.dart | 2160 +++++++++++++++++ .../lib/shaders/index.dart | 13 + .../lib/shaders/mesh_gouraund_material.dart | 306 +++ .../lib}/shaders/shader_chunk.dart | 0 .../shader_chunk/alphahash_fragment.glsl.dart | 0 .../alphahash_pars_fragment.glsl.dart | 0 .../shader_chunk/alphamap_fragment.glsl.dart | 0 .../alphamap_pars_fragment.glsl.dart | 0 .../shader_chunk/alphatest_fragment.glsl.dart | 0 .../alphatest_pars_fragment.glsl.dart | 0 .../shader_chunk/aomap_fragment.glsl.dart | 0 .../aomap_pars_fragment.glsl.dart | 0 .../batching_pars_vertex.glsl.dart | 0 .../shader_chunk/batching_vertex.glsl.dart | 0 .../shader_chunk/begin_vertex.glsl.dart | 0 .../shader_chunk/beginnormal_vertex.glsl.dart | 0 .../lib}/shaders/shader_chunk/bsdfs.glsl.dart | 0 .../bumpmap_pars_fragment.glsl.dart | 0 .../clearcoat_normal_fragment_begin.glsl.dart | 0 .../clearcoat_normal_fragment_maps.glsl.dart | 0 .../clearcoat_pars_fragment.glsl.dart | 0 .../clipping_planes_fragment.glsl.dart | 0 .../clipping_planes_pars_fragment.glsl.dart | 0 .../clipping_planes_pars_vertex.glsl.dart | 0 .../clipping_planes_vertex.glsl.dart | 0 .../shader_chunk/color_fragment.glsl.dart | 0 .../color_pars_fragment.glsl.dart | 0 .../shader_chunk/color_pars_vertex.glsl.dart | 0 .../shader_chunk/color_vertex.glsl.dart | 0 .../shader_chunk/colorspace_fragment.dart | 0 .../colorspace_pars_fragment.glsl.dart | 0 .../shaders/shader_chunk/common.glsl.dart | 0 .../cube_uv_reflection_fragment.glsl.dart | 0 .../shader_chunk/default_fragment.glsl.dart | 0 .../shader_chunk/default_vertex.glsl.dart | 0 .../defaultnormal_vertex.glsl.dart | 0 .../displacementmap_pars_vertex.glsl.dart | 0 .../displacementmap_vertex.glsl.dart | 0 .../shader_chunk/dithering_fragment.glsl.dart | 0 .../dithering_pars_fragment.glsl.dart | 0 .../emissivemap_fragment.glsl.dart | 0 .../emissivemap_pars_fragment.glsl.dart | 0 .../shader_chunk/encodings_fragment.glsl.dart | 0 .../encodings_pars_fragment.glsl.dart | 0 .../envmap_common_pars_fragment.glsl.dart | 0 .../shader_chunk/envmap_fragment.glsl.dart | 0 .../envmap_pars_fragment.glsl.dart | 0 .../shader_chunk/envmap_pars_vertex.glsl.dart | 0 .../envmap_physical_pars_fragment.glsl.dart | 0 .../shader_chunk/envmap_vertex.glsl.dart | 0 .../shader_chunk/fog_fragment.glsl.dart | 0 .../shader_chunk/fog_pars_fragment.glsl.dart | 0 .../shader_chunk/fog_pars_vertex.glsl.dart | 0 .../shaders/shader_chunk/fog_vertex.glsl.dart | 0 .../gradientmap_pars_fragment.glsl.dart | 0 .../lib/shaders/shader_chunk/index.dart | 114 + .../iridescence_fragment.glsl.dart | 0 .../iridescence_pars_fragment.glsl.dart | 0 .../shader_chunk/lightmap_fragment.glsl.dart | 0 .../lightmap_pars_fragment.glsl.dart | 0 .../lights_fragment_begin.glsl.dart | 0 .../lights_fragment_end.glsl.dart | 0 .../lights_fragment_maps.glsl.dart | 0 .../lights_lambert_fragment.glsl.dart | 0 .../lights_lambert_pars_fragment.glsl.dart | 0 .../lights_lambert_vertex.glsl.dart | 0 .../shader_chunk/lights_pars_begin.glsl.dart | 0 .../lights_phong_fragment.glsl.dart | 0 .../lights_phong_pars_fragment.glsl.dart | 0 .../lights_physical_fragment.glsl.dart | 0 .../lights_physical_pars_fragment.glsl.dart | 0 .../lights_toon_fragment.glsl.dart | 0 .../lights_toon_pars_fragment.glsl.dart | 0 .../logdepthbuf_fragment.glsl.dart | 0 .../logdepthbuf_pars_fragment.glsl.dart | 0 .../logdepthbuf_pars_vertex.glsl.dart | 0 .../shader_chunk/logdepthbuf_vertex.glsl.dart | 0 .../shader_chunk/map_fragment.glsl.dart | 0 .../shader_chunk/map_pars_fragment.glsl.dart | 0 .../map_particle_fragment.glsl.dart | 0 .../map_particle_pars_fragment.glsl.dart | 0 .../metalnessmap_fragment.glsl.dart | 0 .../metalnessmap_pars_fragment.glsl.dart | 0 .../shader_chunk/morphcolor_vertex.glsl.dart | 0 .../morphinstance_vertex.glsl.dart | 0 .../shader_chunk/morphnormal_vertex.glsl.dart | 0 .../morphtarget_pars_vertex.glsl.dart | 0 .../shader_chunk/morphtarget_vertex.glsl.dart | 0 .../normal_fragment_begin.glsl.dart | 0 .../normal_fragment_maps.glsl.dart | 0 .../normal_pars_fragment.glsl.dart | 0 .../shader_chunk/normal_pars_vertex.glsl.dart | 0 .../shader_chunk/normal_vertex.glsl.dart | 0 .../normalmap_pars_fragment.glsl.dart | 0 .../shader_chunk/opaque_fragment.glsl.dart | 0 .../shader_chunk/output_fragment.glsl.dart | 0 .../shaders/shader_chunk/packing.glsl.dart | 0 .../premultiplied_alpha_fragment.glsl.dart | 0 .../shader_chunk/project_vertex.glsl.dart | 0 .../roughnessmap_fragment.glsl.dart | 0 .../roughnessmap_pars_fragment.glsl.dart | 0 .../shadowmap_pars_fragment.glsl.dart | 0 .../shadowmap_pars_vertex.glsl.dart | 0 .../shader_chunk/shadowmap_vertex.glsl.dart | 0 .../shadowmask_pars_fragment.glsl.dart | 0 .../shader_chunk/skinbase_vertex.glsl.dart | 0 .../skinning_pars_vertex.glsl.dart | 0 .../shader_chunk/skinning_vertex.glsl.dart | 0 .../shader_chunk/skinnormal_vertex.glsl.dart | 0 .../specularmap_fragment.glsl.dart | 0 .../specularmap_pars_fragment.glsl.dart | 0 .../tonemapping_fragment.glsl.dart | 0 .../tonemapping_pars_fragment.glsl.dart | 0 .../transmission_fragment.glsl.dart | 0 .../transmission_pars_fragment.glsl.dart | 0 .../shader_chunk/uv2_pars_fragment.glsl.dart | 0 .../shader_chunk/uv2_pars_vertex.glsl.dart | 0 .../shaders/shader_chunk/uv2_vertex.glsl.dart | 0 .../shader_chunk/uv_pars_fragment.glsl.dart | 0 .../shader_chunk/uv_pars_vertex.glsl.dart | 0 .../shaders/shader_chunk/uv_vertex.glsl.dart | 0 .../shader_chunk/worldpos_vertex.glsl.dart | 0 .../lib}/shaders/shader_lib.dart | 0 .../shader_lib/background_cube_frag.glsl.dart | 0 .../shader_lib/background_cube_vert.glsl.dart | 0 .../shader_lib/background_frag.glsl.dart | 0 .../shader_lib/background_vert.glsl.dart | 0 .../shaders/shader_lib/cube_frag.glsl.dart | 0 .../shaders/shader_lib/cube_vert.glsl.dart | 0 .../shaders/shader_lib/depth_frag.glsl.dart | 0 .../shaders/shader_lib/depth_vert.glsl.dart | 0 .../shader_lib/distanceRGBA_frag.glsl.dart | 0 .../shader_lib/distanceRGBA_vert.glsl.dart | 0 .../shader_lib/equirect_frag.glsl.dart | 0 .../shader_lib/equirect_vert.glsl.dart | 0 .../shader_lib/horizontal_blur_shader.dart | 0 .../lib/shaders/shader_lib/index.dart | 36 + .../shader_lib/linedashed_frag.glsl.dart | 0 .../shader_lib/linedashed_vert.glsl.dart | 0 .../shader_lib/meshbasic_frag.glsl.dart | 0 .../shader_lib/meshbasic_vert.glsl.dart | 0 .../shader_lib/meshlambert_frag.glsl.dart | 0 .../shader_lib/meshlambert_vert.glsl.dart | 0 .../shader_lib/meshmatcap_frag.glsl.dart | 0 .../shader_lib/meshmatcap_vert.glsl.dart | 0 .../shader_lib/meshnormal_frag.glsl.dart | 0 .../shader_lib/meshnormal_vert.glsl.dart | 0 .../shader_lib/meshphong_frag.glsl.dart | 0 .../shader_lib/meshphong_vert.glsl.dart | 0 .../shader_lib/meshphysical_frag.glsl.dart | 0 .../shader_lib/meshphysical_vert.glsl.dart | 0 .../shader_lib/meshtoon_frag.glsl.dart | 0 .../shader_lib/meshtoon_vert.glsl.dart | 0 .../shaders/shader_lib/points_frag.glsl.dart | 0 .../shaders/shader_lib/points_vert.glsl.dart | 0 .../shaders/shader_lib/shadow_frag.glsl.dart | 0 .../shaders/shader_lib/shadow_vert.glsl.dart | 0 .../shaders/shader_lib/sprite_frag.glsl.dart | 0 .../shaders/shader_lib/sprite_vert.glsl.dart | 0 .../shader_lib/vertical_blur_shader.dart | 0 .../shaders/shader_lib/vsm_frag.glsl.dart | 0 .../shaders/shader_lib/vsm_vert.glsl.dart | 0 .../lib}/shaders/uniforms_lib.dart | 0 .../lib/three_js_angle_renderer.dart | 8 + .../lib}/three_viewer.dart | 17 +- packages/three_js_angle_renderer/pubspec.yaml | 30 + .../lib/cameras/cube_camera.dart | 4 +- .../three_js_core/lib/core/object_3d.dart | 6 +- .../three_js_core/lib/materials/index.dart | 3 +- .../lib/materials/mesh_gouraund_material.dart | 315 +-- .../lib/materials/shader_material.dart | 14 +- .../lib/objects/batched_mesh.dart | 4 +- packages/three_js_core/lib/others/index.dart | 3 +- .../lib/renderers/cube_render_target.dart | 7 + .../three_js_core/lib/renderers/index.dart | 33 +- ..._render_target.dart => render_target.dart} | 59 +- .../three_js_core/lib/renderers/renderer.dart | 44 + .../{shaders => }/uniforms_utils.dart | 5 +- .../web_xr_manager.dart => xr_manager.dart} | 10 +- packages/three_js_core/lib/three_js_core.dart | 7 +- packages/three_js_core/pubspec.yaml | 1 - .../three_js_gpu/lib/common/animation.dart | 66 +- packages/three_js_gpu/lib/common/backend.dart | 686 +++--- .../three_js_gpu/lib/common/background.dart | 19 +- .../lib/common/extras/pmrem_generator.dart | 24 +- .../lib/common/nodes/node_library.dart | 114 +- .../common/nodes/node_sampled_texture.dart | 84 +- .../lib/common/nodes/node_sampler.dart | 31 +- .../lib/common/nodes/node_storage_buffer.dart | 34 +- .../lib/common/nodes/node_uniform.dart | 104 +- .../lib/common/nodes/node_uniform_buffer.dart | 24 +- packages/three_js_gpu/lib/gpu_backend.dart | 378 ++- packages/three_js_gpu/lib/gpu_renderer.dart | 2 +- ...LNodeBuilder.js => wgsl_node_builder.dart} | 148 +- .../lib/src/materialx/lib/mx_hsv.dart | 122 + .../lib/src/materialx/lib/mx_noise.dart | 1315 ++++++++++ .../src/materialx/lib/mx_transform_color.dart | 18 + .../lib/src/materialx/materialx_nodes.dart | 79 + .../three_js_gpu/lib/src/tsl/tsl_base.dart | 31 + .../three_js_gpu/lib/src/tsl/tsl_core.dart | 862 +++++++ .../lib/utils/WebGPUPipelineUtils.js | 789 ------ .../lib/utils/WebGPUTexturePassUtils.js | 439 ---- .../lib/utils/WebGPUTextureUtils.js | 1415 ----------- .../lib/utils/web_gpu_pipeline_utils.dart | 759 ++++++ .../lib/utils/web_gpu_texture_pass_utils.dart | 436 ++++ .../lib/utils/web_gpu_texture_utils.dart | 1383 +++++++++++ .../three_js_impeller_renderer/.gitignore | 143 ++ .../three_js_impeller_renderer/CHANGELOG.md | 3 + packages/three_js_impeller_renderer/LICENSE | 21 + packages/three_js_impeller_renderer/README.md | 21 + .../example/.gitignore | 45 + .../example/README.md | 16 + .../example/lib/main.dart | 114 + .../example/pubspec.yaml | 33 + .../lib/renderers/index.dart | 9 + .../lib/renderers/renderer.dart | 164 ++ .../lib/three_js_impeller_renderer.dart | 3 + .../lib/three_viewer.dart | 425 ++++ .../three_js_impeller_renderer/pubspec.yaml | 32 + packages/three_js_webgl/.gitignore | 141 ++ packages/three_js_webgl/CHANGELOG.md | 3 + packages/three_js_webgl/LICENSE | 21 + packages/three_js_webgl/README.md | 469 ++++ packages/three_js_webgl/lib/three_js.dart | 14 + packages/three_js_webgl/pubspec.yaml | 43 + packages/three_js_webgl_renderer/.gitignore | 143 ++ packages/three_js_webgl_renderer/CHANGELOG.md | 3 + packages/three_js_webgl_renderer/LICENSE | 21 + packages/three_js_webgl_renderer/README.md | 21 + .../example/.gitignore | 45 + .../three_js_webgl_renderer/example/README.md | 16 + .../example/lib/main.dart | 114 + .../example/pubspec.yaml | 33 + .../lib/renderers/index.dart | 17 + .../lib/renderers/pmrem_generator.dart | 780 ++++++ .../renderers/web_gl_3d_render_target.dart | 2 +- .../renderers/web_gl_array_render_target.dart | 2 +- .../renderers/web_gl_cube_render_target.dart | 10 +- .../lib/renderers/web_gl_render_target.dart | 167 ++ .../lib/renderers/web_gl_renderer.dart | 152 +- .../lib}/shaders/index.dart | 2 +- .../lib/shaders/shader_chunk.dart | 154 ++ .../shader_chunk/alphahash_fragment.glsl.dart | 7 + .../alphahash_pars_fragment.glsl.dart | 68 + .../shader_chunk/alphamap_fragment.glsl.dart | 7 + .../alphamap_pars_fragment.glsl.dart | 7 + .../shader_chunk/alphatest_fragment.glsl.dart | 16 + .../alphatest_pars_fragment.glsl.dart | 5 + .../shader_chunk/aomap_fragment.glsl.dart | 26 + .../aomap_pars_fragment.glsl.dart | 8 + .../batching_pars_vertex.glsl.dart | 19 + .../shader_chunk/batching_vertex.glsl.dart | 5 + .../shader_chunk/begin_vertex.glsl.dart | 9 + .../shader_chunk/beginnormal_vertex.glsl.dart | 9 + .../lib/shaders/shader_chunk/bsdfs.glsl.dart | 31 + .../bumpmap_pars_fragment.glsl.dart | 43 + .../clearcoat_normal_fragment_begin.glsl.dart | 7 + .../clearcoat_normal_fragment_maps.glsl.dart | 10 + .../clearcoat_pars_fragment.glsl.dart | 20 + .../clipping_planes_fragment.glsl.dart | 78 + .../clipping_planes_pars_fragment.glsl.dart | 9 + .../clipping_planes_pars_vertex.glsl.dart | 7 + .../clipping_planes_vertex.glsl.dart | 7 + .../shader_chunk/color_fragment.glsl.dart | 11 + .../color_pars_fragment.glsl.dart | 11 + .../shader_chunk/color_pars_vertex.glsl.dart | 11 + .../shader_chunk/color_vertex.glsl.dart | 23 + .../shader_chunk/colorspace_fragment.dart | 3 + .../colorspace_pars_fragment.glsl.dart | 43 + .../lib/shaders/shader_chunk/common.glsl.dart | 147 ++ .../cube_uv_reflection_fragment.glsl.dart | 186 ++ .../shader_chunk/default_fragment.glsl.dart | 5 + .../shader_chunk/default_vertex.glsl.dart | 5 + .../defaultnormal_vertex.glsl.dart | 62 + .../displacementmap_pars_vertex.glsl.dart | 9 + .../displacementmap_vertex.glsl.dart | 7 + .../shader_chunk/dithering_fragment.glsl.dart | 7 + .../dithering_pars_fragment.glsl.dart | 20 + .../emissivemap_fragment.glsl.dart | 9 + .../emissivemap_pars_fragment.glsl.dart | 7 + .../shader_chunk/encodings_fragment.glsl.dart | 3 + .../encodings_pars_fragment.glsl.dart | 10 + .../envmap_common_pars_fragment.glsl.dart | 15 + .../shader_chunk/envmap_fragment.glsl.dart | 62 + .../envmap_pars_fragment.glsl.dart | 21 + .../shader_chunk/envmap_pars_vertex.glsl.dart | 22 + .../envmap_physical_pars_fragment.glsl.dart | 69 + .../shader_chunk/envmap_vertex.glsl.dart | 37 + .../shader_chunk/fog_fragment.glsl.dart | 17 + .../shader_chunk/fog_pars_fragment.glsl.dart | 19 + .../shader_chunk/fog_pars_vertex.glsl.dart | 7 + .../shaders/shader_chunk/fog_vertex.glsl.dart | 7 + .../gradientmap_pars_fragment.glsl.dart | 27 + .../lib}/shaders/shader_chunk/index.dart | 0 .../iridescence_fragment.glsl.dart | 119 + .../iridescence_pars_fragment.glsl.dart | 13 + .../shader_chunk/lightmap_fragment.glsl.dart | 10 + .../lightmap_pars_fragment.glsl.dart | 8 + .../lights_fragment_begin.glsl.dart | 202 ++ .../lights_fragment_end.glsl.dart | 13 + .../lights_fragment_maps.glsl.dart | 40 + .../lights_lambert_fragment.glsl.dart | 5 + .../lights_lambert_pars_fragment.glsl.dart | 28 + .../lights_lambert_vertex.glsl.dart | 125 + .../shader_chunk/lights_pars_begin.glsl.dart | 228 ++ .../lights_phong_fragment.glsl.dart | 7 + .../lights_phong_pars_fragment.glsl.dart | 32 + .../lights_physical_fragment.glsl.dart | 157 ++ .../lights_physical_pars_fragment.glsl.dart | 562 +++++ .../lights_toon_fragment.glsl.dart | 4 + .../lights_toon_pars_fragment.glsl.dart | 26 + .../logdepthbuf_fragment.glsl.dart | 9 + .../logdepthbuf_pars_fragment.glsl.dart | 9 + .../logdepthbuf_pars_vertex.glsl.dart | 8 + .../shader_chunk/logdepthbuf_vertex.glsl.dart | 8 + .../shader_chunk/map_fragment.glsl.dart | 17 + .../shader_chunk/map_pars_fragment.glsl.dart | 7 + .../map_particle_fragment.glsl.dart | 27 + .../map_particle_pars_fragment.glsl.dart | 27 + .../metalnessmap_fragment.glsl.dart | 12 + .../metalnessmap_pars_fragment.glsl.dart | 7 + .../shader_chunk/morphcolor_vertex.glsl.dart | 24 + .../morphinstance_vertex.glsl.dart | 14 + .../shader_chunk/morphnormal_vertex.glsl.dart | 27 + .../morphtarget_pars_vertex.glsl.dart | 47 + .../shader_chunk/morphtarget_vertex.glsl.dart | 36 + .../normal_fragment_begin.glsl.dart | 76 + .../normal_fragment_maps.glsl.dart | 32 + .../normal_pars_fragment.glsl.dart | 14 + .../shader_chunk/normal_pars_vertex.glsl.dart | 14 + .../shader_chunk/normal_vertex.glsl.dart | 14 + .../normalmap_pars_fragment.glsl.dart | 43 + .../shader_chunk/opaque_fragment.glsl.dart | 11 + .../shader_chunk/output_fragment.glsl.dart | 12 + .../shaders/shader_chunk/packing.glsl.dart | 68 + .../premultiplied_alpha_fragment.glsl.dart | 8 + .../shader_chunk/project_vertex.glsl.dart | 19 + .../roughnessmap_fragment.glsl.dart | 12 + .../roughnessmap_pars_fragment.glsl.dart | 7 + .../shadowmap_pars_fragment.glsl.dart | 324 +++ .../shadowmap_pars_vertex.glsl.dart | 67 + .../shader_chunk/shadowmap_vertex.glsl.dart | 65 + .../shadowmask_pars_fragment.glsl.dart | 66 + .../shader_chunk/skinbase_vertex.glsl.dart | 10 + .../skinning_pars_vertex.glsl.dart | 25 + .../shader_chunk/skinning_vertex.glsl.dart | 15 + .../shader_chunk/skinnormal_vertex.glsl.dart | 20 + .../specularmap_fragment.glsl.dart | 14 + .../specularmap_pars_fragment.glsl.dart | 7 + .../tonemapping_fragment.glsl.dart | 7 + .../tonemapping_pars_fragment.glsl.dart | 200 ++ .../transmission_fragment.glsl.dart | 36 + .../transmission_pars_fragment.glsl.dart | 235 ++ .../shader_chunk/uv2_pars_fragment.glsl.dart | 7 + .../shader_chunk/uv2_pars_vertex.glsl.dart | 10 + .../shaders/shader_chunk/uv2_vertex.glsl.dart | 7 + .../shader_chunk/uv_pars_fragment.glsl.dart | 119 + .../shader_chunk/uv_pars_vertex.glsl.dart | 145 ++ .../shaders/shader_chunk/uv_vertex.glsl.dart | 122 + .../shader_chunk/worldpos_vertex.glsl.dart | 21 + .../lib/shaders/shader_lib.dart | 279 +++ .../shader_lib/background_cube_frag.glsl.dart | 45 + .../shader_lib/background_cube_vert.glsl.dart | 16 + .../shader_lib/background_frag.glsl.dart | 27 + .../shader_lib/background_vert.glsl.dart | 12 + .../shaders/shader_lib/cube_frag.glsl.dart | 19 + .../shaders/shader_lib/cube_vert.glsl.dart | 16 + .../shaders/shader_lib/depth_frag.glsl.dart | 52 + .../shaders/shader_lib/depth_vert.glsl.dart | 44 + .../shader_lib/distanceRGBA_frag.glsl.dart | 35 + .../shader_lib/distanceRGBA_vert.glsl.dart | 42 + .../shader_lib/equirect_frag.glsl.dart | 20 + .../shader_lib/equirect_vert.glsl.dart | 14 + .../shader_lib/horizontal_blur_shader.dart | 41 + .../lib}/shaders/shader_lib/index.dart | 0 .../shader_lib/linedashed_frag.glsl.dart | 44 + .../shader_lib/linedashed_vert.glsl.dart | 31 + .../shader_lib/meshbasic_frag.glsl.dart | 72 + .../shader_lib/meshbasic_vert.glsl.dart | 43 + .../shader_lib/meshlambert_frag.glsl.dart | 73 + .../shader_lib/meshlambert_vert.glsl.dart | 51 + .../shader_lib/meshmatcap_frag.glsl.dart | 64 + .../shader_lib/meshmatcap_vert.glsl.dart | 47 + .../shader_lib/meshnormal_frag.glsl.dart | 38 + .../shader_lib/meshnormal_vert.glsl.dart | 48 + .../shader_lib/meshphong_frag.glsl.dart | 75 + .../shader_lib/meshphong_vert.glsl.dart | 51 + .../shader_lib/meshphysical_frag.glsl.dart | 168 ++ .../shader_lib/meshphysical_vert.glsl.dart | 60 + .../shader_lib/meshtoon_frag.glsl.dart | 69 + .../shader_lib/meshtoon_vert.glsl.dart | 49 + .../shaders/shader_lib/points_frag.glsl.dart | 36 + .../shaders/shader_lib/points_vert.glsl.dart | 50 + .../shaders/shader_lib/shadow_frag.glsl.dart | 25 + .../shaders/shader_lib/shadow_vert.glsl.dart | 32 + .../shaders/shader_lib/sprite_frag.glsl.dart | 36 + .../shaders/shader_lib/sprite_vert.glsl.dart | 44 + .../shader_lib/vertical_blur_shader.dart | 41 + .../lib/shaders/shader_lib/vsm_frag.glsl.dart | 45 + .../lib/shaders/shader_lib/vsm_vert.glsl.dart | 7 + .../lib/shaders/uniforms_lib.dart | 175 ++ .../lib/three_js_webgl_renderer.dart | 7 + .../lib/three_viewer.dart | 426 ++++ .../lib}/webgl/index.dart | 17 +- .../lib}/webgl/web_gl_animation.dart | 0 .../lib}/webgl/web_gl_attributes.dart | 9 +- .../lib}/webgl/web_gl_background.dart | 0 .../lib}/webgl/web_gl_binding_states.dart | 33 +- .../lib}/webgl/web_gl_buffer_renderer.dart | 0 .../lib}/webgl/web_gl_capabilities.dart | 4 +- .../lib}/webgl/web_gl_clipping.dart | 0 .../lib}/webgl/web_gl_cube_maps.dart | 0 .../lib}/webgl/web_gl_cube_uv_maps.dart | 2 +- .../lib}/webgl/web_gl_extensions.dart | 29 +- .../lib}/webgl/web_gl_geometries.dart | 2 +- .../webgl/web_gl_indexed_buffer_renderer.dart | 0 .../lib}/webgl/web_gl_info.dart | 0 .../lib}/webgl/web_gl_lights.dart | 0 .../lib}/webgl/web_gl_materials.dart | 10 +- .../lib}/webgl/web_gl_morphtargets.dart | 2 +- .../lib}/webgl/web_gl_objects.dart | 0 .../lib}/webgl/web_gl_parameters.dart | 0 .../lib}/webgl/web_gl_program.dart | 0 .../lib}/webgl/web_gl_program_extra.dart | 0 .../lib}/webgl/web_gl_programs.dart | 0 .../lib}/webgl/web_gl_properties.dart | 3 +- .../lib}/webgl/web_gl_render_list.dart | 0 .../lib}/webgl/web_gl_render_lists.dart | 0 .../lib}/webgl/web_gl_render_states.dart | 0 .../lib}/webgl/web_gl_shader.dart | 0 .../lib}/webgl/web_gl_shader_cache.dart | 0 .../lib}/webgl/web_gl_shadow_map.dart | 2 +- .../lib}/webgl/web_gl_state.dart | 25 +- .../lib}/webgl/web_gl_textures.dart | 296 +-- .../lib}/webgl/web_gl_uniforms.dart | 0 .../lib}/webgl/web_gl_uniforms_groups.dart | 8 +- .../lib}/webgl/web_gl_uniforms_helper.dart | 18 +- .../lib}/webgl/web_gl_utils.dart | 0 packages/three_js_webgl_renderer/pubspec.yaml | 30 + 500 files changed, 31084 insertions(+), 4366 deletions(-) create mode 100755 packages/three_js_angle/.gitignore create mode 100755 packages/three_js_angle/CHANGELOG.md create mode 100755 packages/three_js_angle/LICENSE create mode 100755 packages/three_js_angle/README.md create mode 100755 packages/three_js_angle/lib/three_js.dart create mode 100755 packages/three_js_angle/pubspec.yaml create mode 100755 packages/three_js_angle_renderer/.gitignore create mode 100755 packages/three_js_angle_renderer/CHANGELOG.md create mode 100755 packages/three_js_angle_renderer/LICENSE create mode 100755 packages/three_js_angle_renderer/README.md create mode 100755 packages/three_js_angle_renderer/example/.gitignore create mode 100755 packages/three_js_angle_renderer/example/README.md create mode 100755 packages/three_js_angle_renderer/example/lib/main.dart create mode 100755 packages/three_js_angle_renderer/example/pubspec.yaml create mode 100755 packages/three_js_angle_renderer/lib/angle/angle_animation.dart create mode 100755 packages/three_js_angle_renderer/lib/angle/angle_attributes.dart create mode 100755 packages/three_js_angle_renderer/lib/angle/angle_background.dart create mode 100755 packages/three_js_angle_renderer/lib/angle/angle_binding_states.dart create mode 100755 packages/three_js_angle_renderer/lib/angle/angle_buffer_renderer.dart create mode 100755 packages/three_js_angle_renderer/lib/angle/angle_capabilities.dart create mode 100755 packages/three_js_angle_renderer/lib/angle/angle_clipping.dart create mode 100755 packages/three_js_angle_renderer/lib/angle/angle_cube_maps.dart create mode 100755 packages/three_js_angle_renderer/lib/angle/angle_cube_uv_maps.dart create mode 100755 packages/three_js_angle_renderer/lib/angle/angle_extensions.dart create mode 100755 packages/three_js_angle_renderer/lib/angle/angle_geometries.dart create mode 100755 packages/three_js_angle_renderer/lib/angle/angle_indexed_buffer_renderer.dart create mode 100755 packages/three_js_angle_renderer/lib/angle/angle_info.dart create mode 100755 packages/three_js_angle_renderer/lib/angle/angle_lights.dart create mode 100755 packages/three_js_angle_renderer/lib/angle/angle_materials.dart create mode 100755 packages/three_js_angle_renderer/lib/angle/angle_morphtargets.dart create mode 100755 packages/three_js_angle_renderer/lib/angle/angle_objects.dart create mode 100755 packages/three_js_angle_renderer/lib/angle/angle_parameters.dart create mode 100755 packages/three_js_angle_renderer/lib/angle/angle_program.dart create mode 100755 packages/three_js_angle_renderer/lib/angle/angle_program_extra.dart create mode 100755 packages/three_js_angle_renderer/lib/angle/angle_programs.dart create mode 100755 packages/three_js_angle_renderer/lib/angle/angle_properties.dart create mode 100755 packages/three_js_angle_renderer/lib/angle/angle_render_list.dart create mode 100755 packages/three_js_angle_renderer/lib/angle/angle_render_lists.dart create mode 100755 packages/three_js_angle_renderer/lib/angle/angle_render_states.dart create mode 100755 packages/three_js_angle_renderer/lib/angle/angle_shader.dart create mode 100755 packages/three_js_angle_renderer/lib/angle/angle_shader_cache.dart create mode 100755 packages/three_js_angle_renderer/lib/angle/angle_shadow_map.dart create mode 100755 packages/three_js_angle_renderer/lib/angle/angle_state.dart create mode 100755 packages/three_js_angle_renderer/lib/angle/angle_textures.dart create mode 100755 packages/three_js_angle_renderer/lib/angle/angle_uniforms.dart create mode 100644 packages/three_js_angle_renderer/lib/angle/angle_uniforms_groups.dart create mode 100755 packages/three_js_angle_renderer/lib/angle/angle_uniforms_helper.dart create mode 100755 packages/three_js_angle_renderer/lib/angle/angle_utils.dart create mode 100755 packages/three_js_angle_renderer/lib/angle/index.dart rename packages/{three_js_core => three_js_angle_renderer}/lib/materials/hex_tiling_material.dart (98%) create mode 100755 packages/three_js_angle_renderer/lib/renderers/3d_render_target.dart create mode 100755 packages/three_js_angle_renderer/lib/renderers/array_render_target.dart create mode 100755 packages/three_js_angle_renderer/lib/renderers/cube_render_target.dart create mode 100755 packages/three_js_angle_renderer/lib/renderers/index.dart rename packages/{three_js_core => three_js_angle_renderer}/lib/renderers/pmrem_generator.dart (98%) create mode 100755 packages/three_js_angle_renderer/lib/renderers/render_target.dart create mode 100755 packages/three_js_angle_renderer/lib/renderers/renderer.dart create mode 100755 packages/three_js_angle_renderer/lib/shaders/index.dart create mode 100644 packages/three_js_angle_renderer/lib/shaders/mesh_gouraund_material.dart rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/alphahash_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/alphahash_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/alphamap_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/alphamap_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/alphatest_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/alphatest_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/aomap_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/aomap_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/batching_pars_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/batching_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/begin_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/beginnormal_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/bsdfs.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/bumpmap_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/clearcoat_normal_fragment_begin.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/clearcoat_normal_fragment_maps.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/clearcoat_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/clipping_planes_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/clipping_planes_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/clipping_planes_pars_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/clipping_planes_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/color_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/color_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/color_pars_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/color_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/colorspace_fragment.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/colorspace_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/common.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/cube_uv_reflection_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/default_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/default_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/defaultnormal_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/displacementmap_pars_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/displacementmap_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/dithering_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/dithering_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/emissivemap_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/emissivemap_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/encodings_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/encodings_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/envmap_common_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/envmap_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/envmap_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/envmap_pars_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/envmap_physical_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/envmap_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/fog_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/fog_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/fog_pars_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/fog_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/gradientmap_pars_fragment.glsl.dart (100%) create mode 100755 packages/three_js_angle_renderer/lib/shaders/shader_chunk/index.dart rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/iridescence_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/iridescence_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/lightmap_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/lightmap_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/lights_fragment_begin.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/lights_fragment_end.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/lights_fragment_maps.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/lights_lambert_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/lights_lambert_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/lights_lambert_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/lights_pars_begin.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/lights_phong_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/lights_phong_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/lights_physical_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/lights_physical_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/lights_toon_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/lights_toon_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/logdepthbuf_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/logdepthbuf_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/logdepthbuf_pars_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/logdepthbuf_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/map_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/map_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/map_particle_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/map_particle_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/metalnessmap_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/metalnessmap_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/morphcolor_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/morphinstance_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/morphnormal_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/morphtarget_pars_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/morphtarget_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/normal_fragment_begin.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/normal_fragment_maps.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/normal_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/normal_pars_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/normal_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/normalmap_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/opaque_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/output_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/packing.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/premultiplied_alpha_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/project_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/roughnessmap_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/roughnessmap_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/shadowmap_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/shadowmap_pars_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/shadowmap_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/shadowmask_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/skinbase_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/skinning_pars_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/skinning_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/skinnormal_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/specularmap_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/specularmap_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/tonemapping_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/tonemapping_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/transmission_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/transmission_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/uv2_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/uv2_pars_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/uv2_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/uv_pars_fragment.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/uv_pars_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/uv_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_chunk/worldpos_vertex.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/background_cube_frag.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/background_cube_vert.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/background_frag.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/background_vert.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/cube_frag.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/cube_vert.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/depth_frag.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/depth_vert.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/distanceRGBA_frag.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/distanceRGBA_vert.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/equirect_frag.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/equirect_vert.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/horizontal_blur_shader.dart (100%) create mode 100755 packages/three_js_angle_renderer/lib/shaders/shader_lib/index.dart rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/linedashed_frag.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/linedashed_vert.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/meshbasic_frag.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/meshbasic_vert.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/meshlambert_frag.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/meshlambert_vert.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/meshmatcap_frag.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/meshmatcap_vert.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/meshnormal_frag.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/meshnormal_vert.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/meshphong_frag.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/meshphong_vert.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/meshphysical_frag.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/meshphysical_vert.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/meshtoon_frag.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/meshtoon_vert.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/points_frag.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/points_vert.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/shadow_frag.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/shadow_vert.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/sprite_frag.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/sprite_vert.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/vertical_blur_shader.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/vsm_frag.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/shader_lib/vsm_vert.glsl.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_angle_renderer/lib}/shaders/uniforms_lib.dart (100%) create mode 100755 packages/three_js_angle_renderer/lib/three_js_angle_renderer.dart rename packages/{three_js_core/lib/others => three_js_angle_renderer/lib}/three_viewer.dart (96%) create mode 100755 packages/three_js_angle_renderer/pubspec.yaml create mode 100755 packages/three_js_core/lib/renderers/cube_render_target.dart mode change 100755 => 100644 packages/three_js_core/lib/renderers/index.dart rename packages/three_js_core/lib/renderers/{web_gl_render_target.dart => render_target.dart} (85%) mode change 100755 => 100644 create mode 100644 packages/three_js_core/lib/renderers/renderer.dart rename packages/three_js_core/lib/renderers/{shaders => }/uniforms_utils.dart (91%) rename packages/three_js_core/lib/renderers/{webxr/web_xr_manager.dart => xr_manager.dart} (75%) rename packages/three_js_gpu/lib/nodes/{WGSLNodeBuilder.js => wgsl_node_builder.dart} (93%) create mode 100644 packages/three_js_gpu/lib/src/materialx/lib/mx_hsv.dart create mode 100644 packages/three_js_gpu/lib/src/materialx/lib/mx_noise.dart create mode 100644 packages/three_js_gpu/lib/src/materialx/lib/mx_transform_color.dart create mode 100644 packages/three_js_gpu/lib/src/materialx/materialx_nodes.dart create mode 100644 packages/three_js_gpu/lib/src/tsl/tsl_base.dart create mode 100644 packages/three_js_gpu/lib/src/tsl/tsl_core.dart delete mode 100644 packages/three_js_gpu/lib/utils/WebGPUPipelineUtils.js delete mode 100644 packages/three_js_gpu/lib/utils/WebGPUTexturePassUtils.js delete mode 100644 packages/three_js_gpu/lib/utils/WebGPUTextureUtils.js create mode 100644 packages/three_js_gpu/lib/utils/web_gpu_pipeline_utils.dart create mode 100644 packages/three_js_gpu/lib/utils/web_gpu_texture_pass_utils.dart create mode 100644 packages/three_js_gpu/lib/utils/web_gpu_texture_utils.dart create mode 100755 packages/three_js_impeller_renderer/.gitignore create mode 100755 packages/three_js_impeller_renderer/CHANGELOG.md create mode 100755 packages/three_js_impeller_renderer/LICENSE create mode 100755 packages/three_js_impeller_renderer/README.md create mode 100755 packages/three_js_impeller_renderer/example/.gitignore create mode 100755 packages/three_js_impeller_renderer/example/README.md create mode 100755 packages/three_js_impeller_renderer/example/lib/main.dart create mode 100755 packages/three_js_impeller_renderer/example/pubspec.yaml create mode 100644 packages/three_js_impeller_renderer/lib/renderers/index.dart create mode 100755 packages/three_js_impeller_renderer/lib/renderers/renderer.dart create mode 100755 packages/three_js_impeller_renderer/lib/three_js_impeller_renderer.dart create mode 100644 packages/three_js_impeller_renderer/lib/three_viewer.dart create mode 100755 packages/three_js_impeller_renderer/pubspec.yaml create mode 100755 packages/three_js_webgl/.gitignore create mode 100755 packages/three_js_webgl/CHANGELOG.md create mode 100755 packages/three_js_webgl/LICENSE create mode 100755 packages/three_js_webgl/README.md create mode 100755 packages/three_js_webgl/lib/three_js.dart create mode 100755 packages/three_js_webgl/pubspec.yaml create mode 100755 packages/three_js_webgl_renderer/.gitignore create mode 100755 packages/three_js_webgl_renderer/CHANGELOG.md create mode 100755 packages/three_js_webgl_renderer/LICENSE create mode 100755 packages/three_js_webgl_renderer/README.md create mode 100755 packages/three_js_webgl_renderer/example/.gitignore create mode 100755 packages/three_js_webgl_renderer/example/README.md create mode 100755 packages/three_js_webgl_renderer/example/lib/main.dart create mode 100755 packages/three_js_webgl_renderer/example/pubspec.yaml create mode 100755 packages/three_js_webgl_renderer/lib/renderers/index.dart create mode 100755 packages/three_js_webgl_renderer/lib/renderers/pmrem_generator.dart rename packages/{three_js_core => three_js_webgl_renderer}/lib/renderers/web_gl_3d_render_target.dart (78%) rename packages/{three_js_core => three_js_webgl_renderer}/lib/renderers/web_gl_array_render_target.dart (78%) rename packages/{three_js_core => three_js_webgl_renderer}/lib/renderers/web_gl_cube_render_target.dart (90%) create mode 100755 packages/three_js_webgl_renderer/lib/renderers/web_gl_render_target.dart rename packages/{three_js_core => three_js_webgl_renderer}/lib/renderers/web_gl_renderer.dart (94%) rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/shaders/index.dart (91%) create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk.dart create mode 100644 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/alphahash_fragment.glsl.dart create mode 100644 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/alphahash_pars_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/alphamap_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/alphamap_pars_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/alphatest_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/alphatest_pars_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/aomap_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/aomap_pars_fragment.glsl.dart create mode 100644 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/batching_pars_vertex.glsl.dart create mode 100644 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/batching_vertex.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/begin_vertex.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/beginnormal_vertex.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/bsdfs.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/bumpmap_pars_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/clearcoat_normal_fragment_begin.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/clearcoat_normal_fragment_maps.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/clearcoat_pars_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/clipping_planes_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/clipping_planes_pars_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/clipping_planes_pars_vertex.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/clipping_planes_vertex.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/color_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/color_pars_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/color_pars_vertex.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/color_vertex.glsl.dart create mode 100644 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/colorspace_fragment.dart create mode 100644 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/colorspace_pars_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/common.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/cube_uv_reflection_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/default_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/default_vertex.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/defaultnormal_vertex.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/displacementmap_pars_vertex.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/displacementmap_vertex.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/dithering_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/dithering_pars_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/emissivemap_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/emissivemap_pars_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/encodings_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/encodings_pars_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/envmap_common_pars_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/envmap_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/envmap_pars_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/envmap_pars_vertex.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/envmap_physical_pars_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/envmap_vertex.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/fog_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/fog_pars_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/fog_pars_vertex.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/fog_vertex.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/gradientmap_pars_fragment.glsl.dart rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/shaders/shader_chunk/index.dart (100%) create mode 100644 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/iridescence_fragment.glsl.dart create mode 100644 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/iridescence_pars_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lightmap_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lightmap_pars_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_fragment_begin.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_fragment_end.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_fragment_maps.glsl.dart create mode 100644 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_lambert_fragment.glsl.dart create mode 100644 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_lambert_pars_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_lambert_vertex.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_pars_begin.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_phong_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_phong_pars_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_physical_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_physical_pars_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_toon_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_toon_pars_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/logdepthbuf_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/logdepthbuf_pars_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/logdepthbuf_pars_vertex.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/logdepthbuf_vertex.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/map_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/map_pars_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/map_particle_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/map_particle_pars_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/metalnessmap_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/metalnessmap_pars_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/morphcolor_vertex.glsl.dart create mode 100644 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/morphinstance_vertex.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/morphnormal_vertex.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/morphtarget_pars_vertex.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/morphtarget_vertex.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/normal_fragment_begin.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/normal_fragment_maps.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/normal_pars_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/normal_pars_vertex.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/normal_vertex.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/normalmap_pars_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/opaque_fragment.glsl.dart create mode 100644 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/output_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/packing.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/premultiplied_alpha_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/project_vertex.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/roughnessmap_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/roughnessmap_pars_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/shadowmap_pars_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/shadowmap_pars_vertex.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/shadowmap_vertex.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/shadowmask_pars_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/skinbase_vertex.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/skinning_pars_vertex.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/skinning_vertex.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/skinnormal_vertex.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/specularmap_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/specularmap_pars_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/tonemapping_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/tonemapping_pars_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/transmission_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/transmission_pars_fragment.glsl.dart create mode 100644 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/uv2_pars_fragment.glsl.dart create mode 100644 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/uv2_pars_vertex.glsl.dart create mode 100644 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/uv2_vertex.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/uv_pars_fragment.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/uv_pars_vertex.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/uv_vertex.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_chunk/worldpos_vertex.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib.dart create mode 100644 packages/three_js_webgl_renderer/lib/shaders/shader_lib/background_cube_frag.glsl.dart create mode 100644 packages/three_js_webgl_renderer/lib/shaders/shader_lib/background_cube_vert.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib/background_frag.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib/background_vert.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib/cube_frag.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib/cube_vert.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib/depth_frag.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib/depth_vert.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib/distanceRGBA_frag.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib/distanceRGBA_vert.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib/equirect_frag.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib/equirect_vert.glsl.dart create mode 100644 packages/three_js_webgl_renderer/lib/shaders/shader_lib/horizontal_blur_shader.dart rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/shaders/shader_lib/index.dart (100%) create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib/linedashed_frag.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib/linedashed_vert.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshbasic_frag.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshbasic_vert.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshlambert_frag.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshlambert_vert.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshmatcap_frag.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshmatcap_vert.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshnormal_frag.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshnormal_vert.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshphong_frag.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshphong_vert.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshphysical_frag.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshphysical_vert.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshtoon_frag.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshtoon_vert.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib/points_frag.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib/points_vert.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib/shadow_frag.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib/shadow_vert.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib/sprite_frag.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib/sprite_vert.glsl.dart create mode 100644 packages/three_js_webgl_renderer/lib/shaders/shader_lib/vertical_blur_shader.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib/vsm_frag.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib/vsm_vert.glsl.dart create mode 100755 packages/three_js_webgl_renderer/lib/shaders/uniforms_lib.dart create mode 100755 packages/three_js_webgl_renderer/lib/three_js_webgl_renderer.dart create mode 100644 packages/three_js_webgl_renderer/lib/three_viewer.dart rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/webgl/index.dart (76%) rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/webgl/web_gl_animation.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/webgl/web_gl_attributes.dart (97%) rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/webgl/web_gl_background.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/webgl/web_gl_binding_states.dart (92%) rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/webgl/web_gl_buffer_renderer.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/webgl/web_gl_capabilities.dart (95%) rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/webgl/web_gl_clipping.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/webgl/web_gl_cube_maps.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/webgl/web_gl_cube_uv_maps.dart (98%) rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/webgl/web_gl_extensions.dart (78%) rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/webgl/web_gl_geometries.dart (99%) rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/webgl/web_gl_indexed_buffer_renderer.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/webgl/web_gl_info.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/webgl/web_gl_lights.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/webgl/web_gl_materials.dart (99%) rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/webgl/web_gl_morphtargets.dart (98%) rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/webgl/web_gl_objects.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/webgl/web_gl_parameters.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/webgl/web_gl_program.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/webgl/web_gl_program_extra.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/webgl/web_gl_programs.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/webgl/web_gl_properties.dart (97%) rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/webgl/web_gl_render_list.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/webgl/web_gl_render_lists.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/webgl/web_gl_render_states.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/webgl/web_gl_shader.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/webgl/web_gl_shader_cache.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/webgl/web_gl_shadow_map.dart (99%) rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/webgl/web_gl_state.dart (98%) rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/webgl/web_gl_textures.dart (88%) rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/webgl/web_gl_uniforms.dart (100%) rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/webgl/web_gl_uniforms_groups.dart (97%) rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/webgl/web_gl_uniforms_helper.dart (98%) rename packages/{three_js_core/lib/renderers => three_js_webgl_renderer/lib}/webgl/web_gl_utils.dart (100%) create mode 100755 packages/three_js_webgl_renderer/pubspec.yaml diff --git a/.gitignore b/.gitignore index ea69f5dd..8ca099cc 100755 --- a/.gitignore +++ b/.gitignore @@ -15,6 +15,7 @@ *.ipr *.iws .idea/ +.renderers/ .metadata analysis_options.yaml diff --git a/README.md b/README.md index 6e58832a..0ec1838e 100644 --- a/README.md +++ b/README.md @@ -57,6 +57,7 @@ This is a dart conversion of three.js and three_dart, originally created by [@mr - WebGL2 supported. please add `` to your index.html to load the js_interop file. **Linux** + - Currenlty only works for flutter < 3.27 - Ubuntu supported (Tested on Linux Mint) - OpenGL supported @@ -69,6 +70,12 @@ Please use [Permission Handler](https://pub.dev/packages/permission_handler) pac This project is a simple 3D rendering engine for flutter to view, edit, or manipulate 3D models. +## Legacy + +Please use [three_js_webgl](https://pub.dev/packages/three_js_webgl) for three_dart type renderer. + +As this project moves twards impeller renderer google's ANGLE will be removed and this version will be moved to three_js_angle, which currenly does not exists. + ## Example Find the example for this API [here](https://github.com/Knightro63/three_js/tree/main/packages/three_js/example/), for more examples you can click [here](https://github.com/Knightro63/three_js/tree/main/examples/), and for a preview go [here](https://knightro63.github.io/three_js/). diff --git a/packages/three_js/CHANGELOG.md b/packages/three_js/CHANGELOG.md index af9e6e5a..4d1f2446 100755 --- a/packages/three_js/CHANGELOG.md +++ b/packages/three_js/CHANGELOG.md @@ -1,6 +1,7 @@ ## 0.3.0 * Removed NativeArray for Zero-Allocation Updates. +* Added: three_js_angle_renderer ## 0.2.8 diff --git a/packages/three_js/README.md b/packages/three_js/README.md index 6e58832a..0ec1838e 100755 --- a/packages/three_js/README.md +++ b/packages/three_js/README.md @@ -57,6 +57,7 @@ This is a dart conversion of three.js and three_dart, originally created by [@mr - WebGL2 supported. please add `` to your index.html to load the js_interop file. **Linux** + - Currenlty only works for flutter < 3.27 - Ubuntu supported (Tested on Linux Mint) - OpenGL supported @@ -69,6 +70,12 @@ Please use [Permission Handler](https://pub.dev/packages/permission_handler) pac This project is a simple 3D rendering engine for flutter to view, edit, or manipulate 3D models. +## Legacy + +Please use [three_js_webgl](https://pub.dev/packages/three_js_webgl) for three_dart type renderer. + +As this project moves twards impeller renderer google's ANGLE will be removed and this version will be moved to three_js_angle, which currenly does not exists. + ## Example Find the example for this API [here](https://github.com/Knightro63/three_js/tree/main/packages/three_js/example/), for more examples you can click [here](https://github.com/Knightro63/three_js/tree/main/examples/), and for a preview go [here](https://knightro63.github.io/three_js/). diff --git a/packages/three_js/pubspec.yaml b/packages/three_js/pubspec.yaml index b6e17034..506206d9 100755 --- a/packages/three_js/pubspec.yaml +++ b/packages/three_js/pubspec.yaml @@ -17,6 +17,7 @@ environment: dependencies: flutter: sdk: flutter + three_js_angle_renderer: ^0.0.1 three_js_math: ^0.3.0 three_js_advanced_loaders: ^0.3.0 three_js_animations: ^0.3.0 diff --git a/packages/three_js_angle/.gitignore b/packages/three_js_angle/.gitignore new file mode 100755 index 00000000..2e198e1d --- /dev/null +++ b/packages/three_js_angle/.gitignore @@ -0,0 +1,141 @@ +# Miscellaneous +*.class +*.lock +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ +.metadata + +# Visual Studio Code related +.classpath +.project +.settings/ +.vscode/* + +*/macos +*/web +*/ios +*/android +*/linux +*/windows + +# Flutter repo-specific +/bin/cache/ +/bin/internal/bootstrap.bat +/bin/internal/bootstrap.sh +/bin/mingit/ +/dev/benchmarks/mega_gallery/ +/dev/bots/.recipe_deps +/dev/bots/android_tools/ +/dev/devicelab/ABresults*.json +/dev/docs/doc/ +/dev/docs/flutter.docs.zip +/dev/docs/lib/ +/dev/docs/pubspec.yaml +/dev/integration_tests/**/xcuserdata +/dev/integration_tests/**/Pods +/packages/flutter/coverage/ +version +analysis_benchmark.json + +# packages file containing multi-root paths +.packages.generated + +# Flutter/Dart/Pub related +**/doc/api/ +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +**/generated_plugin_registrant.dart +.packages +.pub-preload-cache/ +.pub/ +build/ +flutter_*.png +linked_*.ds +unlinked.ds +unlinked_spec.ds + +# Android related +**/android/**/gradle-wrapper.jar +.gradle/ +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java +**/android/key.properties +*.jks + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/.last_build_id +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Flutter.podspec +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/ephemeral +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/Flutter/flutter_export_environment.sh +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# macOS +**/Flutter/ephemeral/ +**/Pods/ +**/macos/Flutter/GeneratedPluginRegistrant.swift +**/macos/Flutter/ephemeral +**/xcuserdata/ + +# Windows +**/windows/flutter/generated_plugin_registrant.cc +**/windows/flutter/generated_plugin_registrant.h +**/windows/flutter/generated_plugins.cmake + +# Linux +**/linux/flutter/generated_plugin_registrant.cc +**/linux/flutter/generated_plugin_registrant.h +**/linux/flutter/generated_plugins.cmake + +# Coverage +coverage/ + +# Symbols +app.*.symbols + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +!/dev/ci/**/Gemfile.lock +!.vscode/settings.json \ No newline at end of file diff --git a/packages/three_js_angle/CHANGELOG.md b/packages/three_js_angle/CHANGELOG.md new file mode 100755 index 00000000..9b7b03ba --- /dev/null +++ b/packages/three_js_angle/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.0.1 + +* Initial release. \ No newline at end of file diff --git a/packages/three_js_angle/LICENSE b/packages/three_js_angle/LICENSE new file mode 100755 index 00000000..383b4da5 --- /dev/null +++ b/packages/three_js_angle/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright © 2010-2024 three.js authors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/packages/three_js_angle/README.md b/packages/three_js_angle/README.md new file mode 100755 index 00000000..58590e20 --- /dev/null +++ b/packages/three_js_angle/README.md @@ -0,0 +1,469 @@ +# three_js_angle + +[![Pub Version](https://img.shields.io/pub/v/three_js_angle)](https://pub.dev/packages/three_js_angle) +[![License: MIT](https://img.shields.io/badge/license-MIT-purple.svg)](https://opensource.org/licenses/MIT) + +A 3D rendering engine for dart (based on [three.js](https://github.com/mrdoob/three.js) and [three_dart](https://github.com/wasabia/three_dart)) that allows users to view, edit and manipulate their 3D objects. The current builds uses [angle](https://github.com/google/angle) for desktop and mobile, and WebGL2 for web applications. + +## Features + +![Gif of dash playing a game.](https://raw.githubusercontent.com/Knightro63/three_js/master/assets/flutter_game.gif) + +This is a dart conversion of three.js and three_dart, originally created by [@mrdoob](https://github.com/mrdoob) and has a coverted dart fork by [@wasabia](https://github.com/wasabia). + +## Requirements + +**MacOS** + - Minimum os Deployment Target: 10.15 + - Xcode 13 or newer + - Swift 5 + - Metal supported + +**iOS** + - Minimum os Deployment Target: 13.0 + - Xcode 13 or newer + - Swift 5 + - Metal supported + +**iOS-Simulator** + - Minimum os Deployment Target: 13.0 + - Xcode 13 or newer + - Swift 5 + - Metal supported + +**Android** + - compileSdkVersion: 34 + - minSdk: 21 + - OpenGL supported + - Vulkan supported + +**Android Emulator** + - compileSdkVersion: 34 + - minSdk: 21 + - OpenGL supported + +**Windows** + - Intel supported + - AMD supported + - Qualcom supported + - Direct3D 11 supported + - OpenGL supported + +**Web** + - WebGL2 supported. please add `` to your index.html to load the js_interop file. + +**WASM** + - WebGL2 supported. please add `` to your index.html to load the js_interop file. + +**Linux** + - Currenlty only works for flutter < 3.27 + - Ubuntu supported (Tested on Linux Mint) + - OpenGL supported + +## Getting started + +To get started add three_js to your pubspec.yaml file. Adding permissions for audio and video is required if using either item. +Please use [Permission Handler](https://pub.dev/packages/permission_handler) package to help with this. + +## Usage + +This project is a simple 3D rendering engine for flutter to view, edit, or manipulate 3D models. + +## Example + +Find the example for this API [here](https://github.com/Knightro63/three_js/tree/main/packages/three_js/example/), for more examples you can click [here](https://github.com/Knightro63/three_js/tree/main/examples/), and for a preview go [here](https://knightro63.github.io/three_js/). + +## Know Issues + +**All** + - MD2 annimations do not work + - Collada animations do not work + - Collada kinnametics does not work + - PMREM gives weird artifacts or is completely black + +**MacOS** + - N/A + +**iOS** + - Protoplanets does not function correctly + +**Android** + - Morphtargets does not work on some devices + - Some RGBELoaders cause app to crash + +**Windows** + - Tonemapping turns screen black + - Some RGBELoaders cause app to crash + +**Web** + - Lens Flare not working correctly + - Simplify modifer has weird artifacts + + **WASM** + - Simple GI does not work + - Simplify modifer has weird artifacts + +**Linux** + - Tonemapping turns screen black + - Postprocessing does not work + - Track pad does not zoom out + - Some RGBELoaders cause app to crash + +## Libraries and Plugins + +**Other Libs** + - [Advanced Exporters](https://pub.dev/packages/three_js_advanced_exporters) a USDZ exporter to your three_js project. + - [Audio](https://pub.dev/packages/three_js_audio) an audio api using flutters audioplayer from pub.dev do not use with any other audio package.. + - [Audio Latency](https://pub.dev/packages/three_js_audio_latency) an audio api using SoLoud from pub.dev do not use with any other audio package.. + - [BVH CSG](https://pub.dev/packages/three_js_bvh_csg) a bvh csg api for three_js. + - [Exporters](https://pub.dev/packages/three_js_exporters) an api to add STL, OBJ or PLY exporter for three_js. + - [Geometry](https://pub.dev/packages/three_js_geometry) an api to add complex geometries to three_js. + - [Line](https://pub.dev/packages/three_js_line) an api to add more line types to three_js. + - [Helpers](https://pub.dev/packages/three_js_helpers) an api to add helpers to three_js. + - [Modifers](https://pub.dev/packages/three_js_modifers) an api to add simplify or subdivision to three_js. + - [Post Processing](https://pub.dev/packages/three_js_postprocessing) a post processor to three_js. + - [SVG](https://pub.dev/packages/three_js_svg) an api to add a svg importer and exporter to three_js. + - [Three JS Loader](https://pub.dev/packages/three_js_tjs_loader) a loader to add three js json files to three_js. + - [Transfrom Controls](https://pub.dev/packages/three_js_transform_controls) a transfor controller for 3d objects for three_js. + - [Video Texture](https://pub.dev/packages/three_js_video_texture) an api to add videos and audio to three_js do not use with any other audio package. + +**ADD-ONS** + - [Omio](https://pub.dev/packages/oimo_physics) a physics engine for three_js. + - [Cannon](https://pub.dev/packages/cannon_physics) a physics engine for three_js. + - [Terrain](https://pub.dev/packages/three_js_terrain) a map generator for three_js. + - [XR](https://pub.dev/packages/three_js_xr) a VR/AR/MR sdk for three_js. (web only) + - [Yuka](https://pub.dev/packages/yuka) a game ai sdk for three_js. + +## Contributing + +Contributions are welcome. +In case of any problems look at [existing issues](https://github.com/Knightro63/three_js/issues), if you cannot find anything related to your problem then open an issue. +Create an issue before opening a [pull request](https://github.com/Knightro63/three_js/pulls) for non trivial fixes. +In case of trivial fixes open a [pull request](https://github.com/Knightro63/three_js/pulls) directly. + +## Supported Features + +All of the current webgl2 core features are supported at this time.
+GPU is currently under development, so it is currently not supported.
+Please review the following table for all the supported Modules. + + - ✅ Currently Supported + - ⚠️ Upon request + - ❗ Waiting on GPU update + - ❌ Not intended + +| Module | Plugin | Web | Mobile | Desktop | +|-----------------------------------------------------------------------------------------------|--------|------------|---------|-----| +| | **Animation** | | | | +| AnimationClipCreator | | ⚠️ | ⚠️ | ⚠️ | +| CCDIKSolver | | ❌ | ❌ | ❌ | +| | **Controls** | | | | +| [ArcballControls](https://github.com/Knightro63/three_js/blob/main/packages/three_js_transform_controls/lib/arcball_controls.dart) | [three_js_transform_controls](https://pub.dev/packages/three_js_transform_controls) | ✅ | ✅ | ✅ | +| [DragControls](https://github.com/Knightro63/three_js/blob/main/packages/three_js_controls/lib/drag_controls.dart) | [three_js_controls](https://pub.dev/packages/three_js_controls) | ✅ | ✅ | ✅ | +| [FirstPersonControls](https://github.com/Knightro63/three_js/blob/main/packages/three_js_controls/lib/first_person_controls.dart) | [three_js_controls](https://pub.dev/packages/three_js_controls) | ✅ | ✅ | ✅ | +| [FlyControls](https://github.com/Knightro63/three_js/blob/main/packages/three_js_controls/lib/fly_controls.dart) | [three_js_controls](https://pub.dev/packages/three_js_controls) | ✅ | ✅ | ✅ | +| [MapControls](https://github.com/Knightro63/three_js/blob/main/packages/three_js_controls/lib/orbit_controls.dart) | [three_js_controls](https://pub.dev/packages/three_js_controls) | ✅ | ✅ | ✅ | +| [OrbitControls](https://github.com/Knightro63/three_js/blob/main/packages/three_js_controls/lib/orbit_controls.dart) | [three_js_controls](https://pub.dev/packages/three_js_controls) | ✅ | ✅ | ✅ | +| [PointerLockControls](https://github.com/Knightro63/three_js/blob/main/packages/three_js_controls/lib/pointer_lock_controls.dart) | [three_js_controls](https://pub.dev/packages/three_js_controls) | ✅ | ✅ | ✅ | +| [TrackballControls](https://github.com/Knightro63/three_js/blob/main/packages/three_js_controls/lib/trackball_controls.dart) | [three_js_controls](https://pub.dev/packages/three_js_controls) | ✅ | ✅ | ✅ | +| [TransformControls](https://github.com/Knightro63/three_js/blob/main/packages/three_js_transform_controls/lib/transform_controls.dart) | [three_js_transform_controls](https://pub.dev/packages/three_js_transform_controls) | ✅ | ✅ | ✅ | +| | **CSM** | | | | +| [CSM](https://github.com/Knightro63/three_js/blob/main/packages/three_js_objects/lib/csm/csm.dart) | [three_js_objects](https://pub.dev/packages/three_js_objects) | ✅ | ✅ | ✅ | +| [CSMFrustum](https://github.com/Knightro63/three_js/blob/main/packages/three_js_objects/lib/csm/csm_frustum.dart) | [three_js_objects](https://pub.dev/packages/three_js_objects) | ✅ | ✅ | ✅ | +| [CSMHelper](https://github.com/Knightro63/three_js/blob/main/packages/three_js_objects/lib/csm/csm_helper.dart) | [three_js_objects](https://pub.dev/packages/three_js_objects) | ✅ | ✅ | ✅ | +| [CSMShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_objects/lib/csm/csm_shader.dart) | [three_js_objects](https://pub.dev/packages/three_js_objects) | ✅ | ✅ | ✅ | +| CSMShadowNode | | ❗ | ❗ | ❗ | +| | **Curves** | | | | +| [EXTRAS](https://github.com/Knightro63/three_js/blob/main/packages/three_js_curves/lib/curves/extra.dart) | [three_js_curves](https://pub.dev/packages/three_js_curves) | ✅ | ✅ | ✅ | +| [NURBSCurve](https://github.com/Knightro63/three_js/blob/main/packages/three_js_curves/lib/nurbs/nurbs_curve.dart) | [three_js_curves](https://pub.dev/packages/three_js_curves) | ✅ | ✅ | ✅ | +| [NURBSSurface](https://github.com/Knightro63/three_js/blob/main/packages/three_js_curves/lib/nurbs/nurbs_surface.dart) | [three_js_curves](https://pub.dev/packages/three_js_curves) | ✅ | ✅ | ✅ | +| [NURBSUtils](https://github.com/Knightro63/three_js/blob/main/packages/three_js_curves/lib/nurbs/nurbs_utils.dart) | [three_js_curves](https://pub.dev/packages/three_js_curves) | ✅ | ✅ | ✅ | +| NURBSVolume | | ⚠️ | ⚠️ | ⚠️ | +| | **Effects** | | | | +| AnaglyphEffect | | ⚠️ | ⚠️ | ⚠️ | +| AsciiEffect | | ⚠️ | ⚠️ | ⚠️ | +| OutlineEffect | | ⚠️ | ⚠️ | ⚠️ | +| ParallaxBarrierEffect | | ⚠️ | ⚠️ | ⚠️ | +| [StereoEffect](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/stero_effect.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| | **Enviroments** | | | | +| [DebugEnvironment](https://github.com/Knightro63/three_js/blob/main/packages/three_js_helpers/lib/enviroments/debug_environment.dart) | [three_js_helpers](https://pub.dev/packages/three_js_helpers) | ✅ | ✅ | ✅ | +| [RoomEnvironment](https://github.com/Knightro63/three_js/blob/main/packages/three_js_helpers/lib/enviroments/room_environment.dart) | [three_js_helpers](https://pub.dev/packages/three_js_helpers) | ✅ | ✅ | ✅ | +| | **Exporters** | | | | +| DRACOExporter | | ❌ | ❌ | ❌ | +| EXRExporter | | ❌ | ❌ | ❌ | +| GLTFExporter | | ⚠️ | ⚠️ | ⚠️ | +| KTX2Exporter | | ❌ | ❌ | ❌ | +| [OBJExporter](https://github.com/Knightro63/three_js/blob/main/packages/three_js_exporters/lib/obj_exporter.dart) | [three_js_simple_exporters](https://pub.dev/packages/three_js_exporters) | ✅ | ✅ | ✅ | +| [PLYExporter](https://github.com/Knightro63/three_js/blob/main/packages/three_js_exporters/lib/ply_exporter.dart) | [three_js_simple_exporters](https://pub.dev/packages/three_js_exporters) | ✅ | ✅ | ✅ | +| [STLExporter](https://github.com/Knightro63/three_js/blob/main/packages/three_js_exporters/lib/stl_exporter.dart) | [three_js_simple_exporters](https://pub.dev/packages/three_js_exporters) | ✅ | ✅ | ✅ | +| [USDZExporter](https://github.com/Knightro63/three_js/blob/main/packages/three_js_advanced_exporters/lib/usdz_exporter.dart) | [three_js_advanced_exporters](https://pub.dev/packages/three_js_advanced_exporters) | ✅ | ✅ | ✅ | +| | **Geometry** | | | | +| [BoxLineGeometry](https://github.com/Knightro63/three_js/blob/main/packages/three_js_geometry/lib/box_line_geometry.dart) | [three_js_geometry](https://pub.dev/packages/three_js_geometry) | ✅ | ✅ | ✅ | +| [ConvexGeometry](https://github.com/Knightro63/three_js/blob/main/packages/three_js_geometry/lib/convex.dart) | [three_js_geometry](https://pub.dev/packages/three_js_geometry) | ✅ | ✅ | ✅ | +| [DecalGeometry](https://github.com/Knightro63/three_js/blob/main/packages/three_js_geometry/lib/decal_geometry.dart) | [three_js_geometry](https://pub.dev/packages/three_js_geometry) | ✅ | ✅ | ✅ | +| [ParametricFunctions](https://github.com/Knightro63/three_js/blob/main/packages/three_js_geometry/lib/parametric_gemoetries.dart) | [three_js_geometry](https://pub.dev/packages/three_js_geometry) | ✅ | ✅ | ✅ | +| [ParametricGeometry](https://github.com/Knightro63/three_js/blob/main/packages/three_js_geometry/lib/parametric.dart) | [three_js_geometry](https://pub.dev/packages/three_js_geometry) | ✅ | ✅ | ✅ | +| RoundedBoxGeometry | | ⚠️ | ⚠️ | ⚠️ | +| TeapotGeometry | | ⚠️ | ⚠️ | ⚠️ | +| [TextGeometry](https://github.com/Knightro63/three_js/blob/main/packages/three_js_text/lib/text/text.dart) | [three_js_text](https://pub.dev/packages/three_js_text) | ✅ | ✅ | ✅ | +| | **Helpers** | | | | +| [LightProbeHelper](https://github.com/Knightro63/three_js/blob/main/packages/three_js_helpers/lib/light_probe_helper.dart) | [three_js_helpers](https://pub.dev/packages/three_js_helpers) | ✅ | ✅ | ✅ | +| LightProbeHelperGPU | | ❗ | ❗ | ❗ | +| [OctreeHelper](https://github.com/Knightro63/three_js/blob/main/packages/three_js_objects/lib/octree_helper.dart) | [three_js_objects](https://pub.dev/packages/three_js_objects) | ✅ | ✅ | ✅ | +| [PositionalAudioHelper](https://github.com/Knightro63/three_js/blob/main/packages/three_js_core/lib/audio/positional_audio_helper.dart) | [three_js_core](https://pub.dev/packages/three_js_core) | ✅ | ✅ | ✅ | +| RapierHelper | | ❌ | ❌ | ❌ | +| [RectAreaLightHelper](https://github.com/Knightro63/three_js/blob/main/packages/three_js_helpers/lib/rect_area_light_helper.dart) | [three_js_helpers](https://pub.dev/packages/three_js_helpers) | ✅ | ✅ | ✅ | +| TextureHelper | | ⚠️ | ⚠️ | ⚠️ | +| [VertexNormalsHelper](https://github.com/Knightro63/three_js/blob/main/packages/three_js_helpers/lib/vertex_normals_helper.dart) | [three_js_helpers](https://pub.dev/packages/three_js_helpers) | ✅ | ✅ | ✅ | +| [VertexTangentsHelper](https://github.com/Knightro63/three_js/blob/main/packages/three_js_helpers/lib/vertex_tangents_helper.dart) | [three_js_helpers](https://pub.dev/packages/three_js_helpers) | ✅ | ✅ | ✅ | +| [ViewHelper](https://github.com/Knightro63/three_js/blob/main/packages/three_js_helpers/lib/view_helper.dart) | [three_js_helpers](https://pub.dev/packages/three_js_helpers) | ✅ | ✅ | ✅ | +| | **Interactive** | | | | +| HTMLMesh | | ❌ | ❌ | ❌ | +| [InteractiveGroup](https://github.com/Knightro63/three_js/blob/main/packages/three_js_xr/lib/other/interactive_group.dart) | [three_js_xr](https://pub.dev/packages/three_js_xr) | ✅ | ❌ | ❌ | +| [SelectionBox](https://github.com/Knightro63/three_js/blob/main/packages/three_js_helpers/lib/selection/selection_box.dart) | [three_js_helpers](https://pub.dev/packages/three_js_helpers) | ✅ | ✅ | ✅ | +| [SelectionHelper](https://github.com/Knightro63/three_js/blob/main/packages/three_js_helpers/lib/selection/selection_helper.dart) | [three_js_helpers](https://pub.dev/packages/three_js_helpers) | ✅ | ✅ | ✅ | +| | **Lighting** | | | | +| TiledLighting | | ❗ | ❗ | ❗ | +| | **Lights** | | | | +| [LightProbeGenerator](https://github.com/Knightro63/three_js/blob/main/packages/three_js_objects/lib/lights/light_probe_generator.dart) | [three_js_objects](https://pub.dev/packages/three_js_objects) | ✅ | ✅ | ✅ | +| RectAreaLightTexturesLib | | ⚠️ | ⚠️ | ⚠️ | +| RectAreaLightUniformsLib | | ⚠️ | ⚠️ | ⚠️ | +| | **Lines** | | | | +| [Line2](https://github.com/Knightro63/three_js/blob/main/packages/three_js_line/lib/line2.dart) | [three_js_line](https://pub.dev/packages/three_js_line) | ✅ | ✅ | ✅ | +| [LineGeometry](https://github.com/Knightro63/three_js/blob/main/packages/three_js_line/lib/line_geometry.dart) | [three_js_line](https://pub.dev/packages/three_js_line) | ✅ | ✅ | ✅ | +| [LineMaterial](https://github.com/Knightro63/three_js/blob/main/packages/three_js_line/lib/line_material.dart) | [three_js_line](https://pub.dev/packages/three_js_line) | ✅ | ✅ | ✅ | +| [LineSegments2](https://github.com/Knightro63/three_js/blob/main/packages/three_js_line/lib/line_segments2.dart) | [three_js_line](https://pub.dev/packages/three_js_line) | ✅ | ✅ | ✅ | +| [LineSegmentsGeometry](https://github.com/Knightro63/three_js/blob/main/packages/three_js_line/lib/line_segments_geometry.dart) | [three_js_line](https://pub.dev/packages/three_js_line) | ✅ | ✅ | ✅ | +| [Wireframe](https://github.com/Knightro63/three_js/blob/main/packages/three_js_line/lib/wireframe.dart) | [three_js_line](https://pub.dev/packages/three_js_line) | ✅ | ✅ | ✅ | +| [WireframeGeometry2](https://github.com/Knightro63/three_js/blob/main/packages/three_js_line/lib/wireframe_geometry2.dart) | [three_js_line](https://pub.dev/packages/three_js_line) | ✅ | ✅ | ✅ | +| | **Loaders** | | | | +| Rhino3dmLoader | | ❌ | ❌ | ❌ | +| ThreeMFLoader | | ❌ | ❌ | ❌ | +| AMFLoader | | ❌ | ❌ | ❌ | +| [BVHLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_advanced_loaders/lib/bvh_loader.dart) | [three_js_advanced_loaders](https://pub.dev/packages/three_js_advanced_loaders) | ✅ | ✅ | ✅ | +| [ColladaLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_advanced_loaders/lib/collada/collada_loader.dart) | [three_js_advanced_loaders](https://pub.dev/packages/three_js_advanced_loaders) | ✅ | ✅ | ✅ | +| [DDSLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_advanced_loaders/lib/dds_loader.dart) | [three_js_advanced_loaders](https://pub.dev/packages/three_js_advanced_loaders) | ✅ | ✅ | ✅ | +| DRACOLoader | | ❌ | ❌ | ❌ | +| EXRLoader | | ⚠️ | ⚠️ | ⚠️ | +| [FBXLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_advanced_loaders/lib/fbx_loader.dart) | [three_js_advanced_loaders](https://pub.dev/packages/three_js_advanced_loaders) | ✅ | ✅ | ✅ | +| [FontLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_text/lib/loaders/font_loader.dart) | [three_js_text](https://pub.dev/packages/three_js_text) | ✅ | ✅ | ✅ | +| [GCodeLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_simple_loaders/lib/gcode_loder.dart) | [three_js_simple_loaders](https://pub.dev/packages/three_js_simple_loaders) | ✅ | ✅ | ✅ | +| [GLTFLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_advanced_loaders/lib/gltf/gltf_loader.dart) | [three_js_advanced_loaders](https://pub.dev/packages/three_js_advanced_loaders) | ✅ | ✅ | ✅ | +| HDRCubeTextureLoader | | ⚠️ | ⚠️ | ⚠️ | +| IESLoader | | ⚠️ | ⚠️ | ⚠️ | +| KMZLoader | | ❌ | ❌ | ❌ | +| KTX2Loader | | ❌ | ❌ | ❌ | +| [KTXLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_advanced_loaders/lib/ktx_loader.dart) | [three_js_advanced_loaders](https://pub.dev/packages/three_js_advanced_loaders) | ✅ | ✅ | ✅ | +| LDrawLoader | | ⚠️ | ⚠️ | ⚠️ | +| LottieLoader | | ❌ | ❌ | ❌ | +| LUT3dlLoader | | ⚠️ | ⚠️ | ⚠️ | +| [LUTCubeLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_simple_loaders/lib/lut_cube_loder.dart) | [three_js_simple_loaders](https://pub.dev/packages/three_js_simple_loaders) | ✅ | ✅ | ✅ | +| LUTImageLoader | | ⚠️ | ⚠️ | ⚠️ | +| LWOLoader | | ❌ | ❌ | ❌ | +| MaterialXLoader | | ❌ | ❌ | ❌ | +| [MD2Loader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_advanced_loaders/lib/md2/md2_loader.dart) | [three_js_advanced_loaders](https://pub.dev/packages/three_js_advanced_loaders) | ✅ | ✅ | ✅ | +| MDDLoader | | ⚠️ | ⚠️ | ⚠️ | +| [MTLLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_simple_loaders/lib/obj/mtl_loder.dart) | [three_js_simple_loaders](https://pub.dev/packages/three_js_simple_loaders) | ✅ | ✅ | ✅ | +| NRRDLoader | | ⚠️ | ⚠️ | ⚠️ | +| [OBJLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_simple_loaders/lib/obj/obj_loder.dart) | [three_js_simple_loaders](https://pub.dev/packages/three_js_simple_loaders) | ✅ | ✅ | ✅ | +| [PCDLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_advanced_loaders/lib/pcd_loader.dart) | [three_js_advanced_loaders](https://pub.dev/packages/three_js_advanced_loaders) | ✅ | ✅ | ✅ | +| PBDLoader | | ⚠️ | ⚠️ | ⚠️ | +| [PLYLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_simple_loaders/lib/ply_loder.dart) | [three_js_simple_loaders](https://pub.dev/packages/three_js_simple_loaders) | ✅ | ✅ | ✅ | +| PVRLoader | | ⚠️ | ⚠️ | ⚠️ | +| [RGBELoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_advanced_loaders/lib/rgbe_loader.dart) | [three_js_advanced_loaders](https://pub.dev/packages/three_js_advanced_loaders) | ✅ | ✅ | ✅ | +| RGBMLoader | | ⚠️ | ⚠️ | ⚠️ | +| [STLLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_simple_loaders/lib/stl_loder.dart) | [three_js_simple_loaders](https://pub.dev/packages/three_js_simple_loaders) | ✅ | ✅ | ✅ | +| [SVGLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_svg/lib/import/svg_loder.dart) | [three_js_svg](https://pub.dev/packages/three_js_svg) | ✅ | ✅ | ✅ | +| TDSLoader | | ⚠️ | ⚠️ | ⚠️ | +| [TGALoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_advanced_loaders/lib/tga_loader.dart) | [three_js_advanced_loaders](https://pub.dev/packages/three_js_advanced_loaders) | ✅ | ✅ | ✅ | +| TIFFLoader | | ❌ | ❌ | ❌ | +| [TTFLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_text/lib/loaders/ttf_loader.dart) | [three_js_text](https://pub.dev/packages/three_js_text) | ✅ | ✅ | ✅ | +| UltraHDRLoader | | ⚠️ | ⚠️ | ⚠️ | +| [USDLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_advanced_loaders/lib/usdz/usdz_loader.dart) | [three_js_advanced_loaders](https://pub.dev/packages/three_js_advanced_loaders) | ✅ | ✅ | ✅ | +| [USDZLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_advanced_loaders/lib/usdz/usdz_loader.dart) | [three_js_advanced_loaders](https://pub.dev/packages/three_js_advanced_loaders) | ✅ | ✅ | ✅ | +| [VOXLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_simple_loaders/lib/vox_loder.dart) | [three_js_simple_loaders](https://pub.dev/packages/three_js_simple_loaders) | ✅ | ✅ | ✅ | +| VRMLoader | | ❌ | ❌ | ❌ | +| VTKLoader | | ⚠️ | ⚠️ | ⚠️ | +| [XYZLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_simple_loaders/lib/xyz_loder.dart) | [three_js_simple_loaders](https://pub.dev/packages/three_js_simple_loaders) | ✅ | ✅ | ✅ | +| | **Materials** | | | | +| LDrawConditionalLineMaterial | | ❌ | ❌ | ❌ | +| LDrawConditionalLineNodeMaterial | | ❌ | ❌ | ❌ | +| [MeshGouraudMaterial](https://github.com/Knightro63/three_js/blob/main/packages/three_js_core/lib/materials/mesh_gouraud_loader.dart) | [three_js_core](https://pub.dev/packages/three_js_core) | ✅ | ✅ | ✅ | +| MeshPostProcessingMaterial | | ⚠️ | ⚠️ | ⚠️ | +| | **Math** | | | | +| [Capsule](https://github.com/Knightro63/three_js/blob/main/packages/three_js_objects/lib/octree/capsule.dart) | [three_js_objects](https://pub.dev/packages/three_js_objects) | ✅ | ✅ | ✅ | +| ColorConverter | | ⚠️ | ⚠️ | ⚠️ | +| ColorSpaces | | ⚠️ | ⚠️ | ⚠️ | +| [ConvexHull](https://github.com/Knightro63/three_js/blob/main/packages/three_js_geometry/lib/convex_hull.dart) | [three_js_geometry](https://pub.dev/packages/three_js_geometry) | ✅ | ✅ | ✅ | +| [ImprovedNoise](https://github.com/Knightro63/three_js/blob/main/packages/three_js_objects/lib/noise/improved_noise.dart) | [three_js_objects](https://pub.dev/packages/three_js_objects) | ✅ | ✅ | ✅ | +| Lut | | ⚠️ | ⚠️ | ⚠️ | +| [MeshSurfaceSampler](https://github.com/Knightro63/three_js/blob/main/packages/three_js_helpers/lib/utils/mesh_surface_sampler.dart) | [three_js_helpers](https://pub.dev/packages/three_js_helpers) | ✅ | ✅ | ✅ | +| OBB | | ⚠️ | ⚠️ | ⚠️ | +| [Octree](https://github.com/Knightro63/three_js/blob/main/packages/three_js_objects/lib/octree/octree.dart) | [three_js_objects](https://pub.dev/packages/three_js_objects) | ✅ | ✅ | ✅ | +| SimplexNoise | | ⚠️ | ⚠️ | ⚠️ | +| | **Misc** | | | | +| ConvexObjectBreaker | | ⚠️ | ⚠️ | ⚠️ | +| GPUComputationRenderer | | ❗ | ❗ | ❗ | +| [Gyroscope](https://github.com/Knightro63/three_js/blob/main/packages/three_js_particles/lib/gyroscope.dart) | [three_js_particles](https://pub.dev/packages/three_js_particles) | ✅ | ✅ | ✅ | +| [MD2Character](https://github.com/Knightro63/three_js/blob/main/packages/three_js_advanced_loaders/lib/md2/md2_charcter.dart) | [three_js_advanced_loaders](https://pub.dev/packages/three_js_advanced_loaders) | ✅ | ✅ | ✅ | +| [MD2Loader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_advanced_loaders/lib/md2/md2_loader.dart) | [three_js_advanced_loaders](https://pub.dev/packages/three_js_advanced_loaders) | ✅ | ✅ | ✅ | +| MD2CharacterComplex | | ❌ | ❌ | ❌ | +| [MorphAnimMesh](https://github.com/Knightro63/three_js/blob/main/packages/three_js_advanced_loaders/lib/md2/morph_anim_mesh.dart) | [three_js_advanced_loaders](https://pub.dev/packages/three_js_advanced_loaders) | ✅ | ✅ | ✅ | +| MorphBlendMesh | | ⚠️ | ⚠️ | ⚠️ | +| ProgressiveLightMap | | ⚠️ | ⚠️ | ⚠️ | +| ProgressiveLightMapGPU | | ❗ | ❗ | ❌❗ | +| [RollerCoasterGeometry](https://github.com/Knightro63/three_js/blob/main/examples/lib/rollercoster/rollercoaster.dart) | | ✅ | ✅ | ✅ | +| [TubePainter](https://github.com/Knightro63/three_js/blob/main/packages/three_js_objects/lib/tube_painter.dart) | [three_js_objects](https://pub.dev/packages/three_js_objects) | ✅ | ✅ | ✅ | +| Volume | | ⚠️ | ⚠️ | ⚠️ | +| VolumeSlice | | ❌ | ❌ | ❌ | +| | **Modifers** | | | | +| CurveModifier | | ❌ | ❌ | ❌ | +| CurveModifierGPU | | ❌ | ❌ | ❌ | +| [EdgeSplitModifier](https://github.com/Knightro63/three_js/blob/main/packages/three_js_modifers/lib/edge_split_modifier.dart) | [three_js_modifers](https://pub.dev/packages/three_js_modifers) | ✅ | ✅ | ✅ | +| [SimplifyModifier](https://github.com/Knightro63/three_js/blob/main/packages/three_js_modifers/lib/simplify_modifer.dart) | [three_js_modifers](https://pub.dev/packages/three_js_modifers) | ✅ | ✅ | ✅ | +| [TessellateModifier](https://github.com/Knightro63/three_js/blob/main/packages/three_js_modifers/lib/tesselate_modifer.dart) | [three_js_modifers](https://pub.dev/packages/three_js_modifers) | ✅ | ✅ | ✅ | +| | **Objects** | | | | +| GroundedSkybox | | ⚠️ | ⚠️ | ⚠️ | +| [Lensflare](https://github.com/Knightro63/three_js/blob/main/packages/three_js_objects/lib/lens_flare.dart) | [three_js_objects](https://pub.dev/packages/three_js_objects) | ✅ | ✅ | ✅ | +| LensflareMesh | | ❗ | ❗ | ❗ | +| [MarchingCubes](https://github.com/Knightro63/three_js/blob/main/packages/three_js_objects/lib/marching_cubes.dart) | [three_js_objects](https://pub.dev/packages/three_js_objects) | ✅ | ✅ | ✅ | +| [Reflector](https://github.com/Knightro63/three_js/blob/main/packages/three_js_objects/lib/water/reflector.dart) | [three_js_objects](https://pub.dev/packages/three_js_objects) | ✅ | ✅ | ✅ | +| ReflectorForSSRPass | | ⚠️ | ⚠️ | ⚠️ | +| [Refractor](https://github.com/Knightro63/three_js/blob/main/packages/three_js_objects/lib/water/refractor.dart) | [three_js_objects](https://pub.dev/packages/three_js_objects) | ✅ | ✅ | ✅ | +| ShadowMesh | | ⚠️ | ⚠️ | ⚠️ | +| [Sky](https://github.com/Knightro63/three_js/blob/main/packages/three_js_objects/lib/sky/sky.dart) | [three_js_objects](https://pub.dev/packages/three_js_objects) | ✅ | ✅ | ✅ | +| SkyMesh | | ❗ | ❗ | ❗ | +| Water | | ⚠️ | ⚠️ | ⚠️ | +| [Water2](https://github.com/Knightro63/three_js/blob/main/packages/three_js_objects/lib/water/water2.dart) | [three_js_objects](https://pub.dev/packages/three_js_objects) | ✅ | ✅ | ✅ | +| Water2Mesh | | ❗ | ❗ | ❗ | +| WaterMesh | | ❗ | ❗ | ❗ | +| | **Off Screen** | | | | +| Jank | | ⚠️ | ⚠️ | ⚠️ | +| OffScreen | | ❌ | ❌ | ❌ | +| Scene | | ❌ | ❌ | ❌ | +| | **Physics** | | | | +| AmmoPhysics | | ❌ | ❌ | ❌ | +| JoltPhysics | | ❌ | ❌ | ❌ | +| RapierPhysics | | ❌ | ❌ | ❌ | +| | **Post Porcessing** | | | | +| [AfterimagePass](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/afterimage_pass.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| [BloomPass](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/bloom_pass.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| BokehPass | | ⚠️ | ⚠️ | ⚠️ | +| ClearPass | | ⚠️ | ⚠️ | ⚠️ | +| CubeTexturePass | | ⚠️ | ⚠️ | ⚠️ | +| [DotScreenPass](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/dot_screen_pass.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| [EffectComposer](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/effect_composer.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| [FilmPass](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/film_pass.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| [FXAAPass](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/fxaa_pass.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| [GlitchPass](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/glitch_pass.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| GTAOPass | | ⚠️ | ⚠️ | ⚠️ | +| HalftonePass | | ⚠️ | ⚠️ | ⚠️ | +| [LUTPass](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/lut_pass.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| [MaskPass](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/mask_pass.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| OutlinePass | | ⚠️ | ⚠️ | ⚠️ | +| [OutputPass](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/output_pass.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| [Pass](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/pass.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| [RenderPass](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/render_pass.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| RenderPixelatedPass | | ⚠️ | ⚠️ | ⚠️ | +| RenderTransitionPass | | ⚠️ | ⚠️ | ⚠️ | +| SAOPass | | ⚠️ | ⚠️ | ⚠️ | +| SavePass | | ⚠️ | ⚠️ | ⚠️ | +| [ShaderPass](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/shader_pass.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| [SMAAPass](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/smaa_pass.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| [SSAARenderPass](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/ssaa_render_pass.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| SSAOPass | | ⚠️ | ⚠️ | ⚠️ | +| SSRPass | | ⚠️ | ⚠️ | ⚠️ | +| [TAARenderPass](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/taa_render_pass.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| [TexturePass](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/texture_pass.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| [UnrealBloomPass](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/unreal_bloom_pass.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| | **Renderers** | | | | +| CSS2DRenderer | | ❌ | ❌ | ❌ | +| CSS3DRenderer | | ❌ | ❌ | ❌ | +| [Projector](https://github.com/Knightro63/three_js/blob/main/packages/three_js_svg/lib/export/projector.dart) | [three_js_svg](https://pub.dev/packages/three_js_svg) | ✅ | ✅ | ✅ | +| [SVGRenderer](https://github.com/Knightro63/three_js/blob/main/packages/three_js_svg/lib/export/svg_renderer.dart) | [three_js_svg](https://pub.dev/packages/three_js_svg) | ✅ | ✅ | ✅ | +| | **Shaders** | | | | +| ACESFilmicToneMappingShader | | ⚠️ | ⚠️ | ⚠️ | +| [AfterimageShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/afterimage_shader.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| BasicShader | | ⚠️ | ⚠️ | ⚠️ | +| [BleachBypassShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/bleach_bypass_shader.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| BlendShader | | ⚠️ | ⚠️ | ⚠️ | +| BokehShader | | ⚠️ | ⚠️ | ⚠️ | +| BokehShader2 | | ⚠️ | ⚠️ | ⚠️ | +| BrightnessContrastShader | | ⚠️ | ⚠️ | ⚠️ | +| ColorCorrectionShader | | ⚠️ | ⚠️ | ⚠️ | +| ColorifyShader | | ⚠️ | ⚠️ | ⚠️ | +| [ConvolutionShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/convolution_shader.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| [CopyShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/copy_shader.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| DepthLimitedBlurShader | | ⚠️ | ⚠️ | ⚠️ | +| [DigitalGlitch](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/digital_glitch.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| DOFMipMapShader | | ⚠️ | ⚠️ | ⚠️ | +| [DotScreenShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/dot_screen_shader.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| ExposureShader | | ⚠️ | ⚠️ | ⚠️ | +| [FilmShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/film_shader.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| FocusShader | | ⚠️ | ⚠️ | ⚠️ | +| FreiChenShader | | ⚠️ | ⚠️ | ⚠️ | +| [FXAAShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/fxaa_shader.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| [GammaCorrectionShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/gamma_correction_shader.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| GodRaysDepthMaskShader | | ⚠️ | ⚠️ | ⚠️ | +| GTAOShader | | ⚠️ | ⚠️ | ⚠️ | +| HalftoneShader | | ⚠️ | ⚠️ | ⚠️ | +| [HorizontalBlurShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/horizontal_blur_shader.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| HorizontalTiltShiftShader | | ⚠️ | ⚠️ | ⚠️ | +| HueSaturationShader | | ⚠️ | ⚠️ | ⚠️ | +| KaleidoShader | | ⚠️ | ⚠️ | ⚠️ | +| [LuminosityHighPassShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/luminosity_high_pass_shader.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| [LuminosityShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/luminosity_shader.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| MirrorShader | | ⚠️ | ⚠️ | ⚠️ | +| NormalMapShader | | ⚠️ | ⚠️ | ⚠️ | +| [OutputShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/outpass_shader.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| PoissonDenoiseShader | | ⚠️ | ⚠️ | ⚠️ | +| RGBShiftShader | | ⚠️ | ⚠️ | ⚠️ | +| SAOShader | | ⚠️ | ⚠️ | ⚠️ | +| SepiaShader | | ⚠️ | ⚠️ | ⚠️ | +| [SMAAShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/smaa_shader.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| [SobelOperatorShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/sobel_operator_shader.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| SSAOShader | | ⚠️ | ⚠️ | ⚠️ | +| SSRShader | | ⚠️ | ⚠️ | ⚠️ | +| SubsurfaceScatteringShader | | ⚠️ | ⚠️ | ⚠️ | +| TechnicolorShader | | ⚠️ | ⚠️ | ⚠️ | +| ToonShader | | ⚠️ | ⚠️ | ⚠️ | +| TriangleBlurShader | | ⚠️ | ⚠️ | ⚠️ | +| [UnpackDepthRGBAShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/unpack_depth_rgba_shader.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| VelocityShader | | ⚠️ | ⚠️ | ⚠️ | +| [VerticalBlurShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/vertical_blur_shader.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| VerticalTiltShiftShader | | ⚠️ | ⚠️ | ⚠️ | +| [VignetteShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/vignette_shader.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| VolumeShader | | ⚠️ | ⚠️ | ⚠️ | +| WaterRefractionShader | | ⚠️ | ⚠️ | ⚠️ | +| | **Textures** | | | | +| FlakesTexture | | ⚠️ | ⚠️ | ⚠️ | +| | **Transpiler** | ❗ | ❗ | ❗ | +| | **TSL** | ❗ | ❗ | ❗ | +| | **Utils** | | | | +| [BufferGeometryUtils](https://github.com/Knightro63/three_js/blob/main/packages/three_js_modifers/lib/buffergeometry_utils.dart) | [three_js_modifers](https://pub.dev/packages/three_js_modifers) | ✅ | ✅ | ✅ | +| [CameraUtils](https://github.com/Knightro63/three_js/blob/main/packages/three_js_helpers/lib/utils/camera_utils.dart) | [three_js_helpers](https://pub.dev/packages/three_js_helpers) | ✅ | ✅ | ✅ | +| GeometryCompressionUtils | | ⚠️ | ⚠️ | ⚠️ | +| GeometryUtils | | ⚠️ | ⚠️ | ⚠️ | +| LDrawUtils | | ⚠️ | ⚠️ | ⚠️ | +| SceneOptimizer | | ⚠️ | ⚠️ | ⚠️ | +| SceneUtils | | ⚠️ | ⚠️ | ⚠️ | +| ShadowMapViewer | | ⚠️ | ⚠️ | ⚠️ | +| ShadowMapViewerGPU | | ❗ | ❗ | ❗ | +| [SkeletonUtils](https://github.com/Knightro63/three_js/blob/main/packages/three_js_helpers/lib/utils/skeleton_utils.dart) | [three_js_helpers](https://pub.dev/packages/three_js_helpers) | ✅ | ✅ | ✅ | +| SortUtils | | ⚠️ | ⚠️ | ⚠️ | +| UVsDebug | | ⚠️ | ⚠️ | ⚠️ | +| WebGLTextureUtils | | ⚠️ | ⚠️ | ⚠️ | +| WebGPUTextureUtils | | ❗ | ❗ | ❗ | +| | **WebXR** | | | | +| [ARButton](https://github.com/Knightro63/three_js/blob/main/packages/three_js_xr/lib/buttons/ar_button.dart) | [three_js_xr](https://pub.dev/packages/three_js_xr) | ✅ | ❌ | ❌ | +| OculusHandModel | | ❌ | ❌ | ❌ | +| OculusHandPointerModel | | ❌ | ❌ | ❌ | +| Text2D | | ❌ | ❌ | ❌ | +| [VRButton](https://github.com/Knightro63/three_js/blob/main/packages/three_js_xr/lib/buttons/vr_button.dart) | [three_js_xr](https://pub.dev/packages/three_js_xr) | ✅ | ❌ | ❌ | +| [XRButton](https://github.com/Knightro63/three_js/blob/main/packages/three_js_xr/lib/buttons/xr_button.dart) | [three_js_xr](https://pub.dev/packages/three_js_xr) | ✅ | ❌ | ❌ | +| [XRControllerModelFactory](https://github.com/Knightro63/three_js/blob/main/packages/three_js_xr/lib/models/hand/xr_controller_model_factory.dart) | [three_js_xr](https://pub.dev/packages/three_js_xr) | ✅ | ❌ | ❌ | +| XREstimatedLight | | ❌ | ❌ | ❌ | +| [XRHandMeshModel](https://github.com/Knightro63/three_js/blob/main/packages/three_js_xr/lib/models/hand/xr_hand_mesh_modle.dart) | [three_js_xr](https://pub.dev/packages/three_js_xr) | ✅ | ❌ | ❌ | +| [XRHandModelFactory](https://github.com/Knightro63/three_js/blob/main/packages/three_js_xr/lib/models/hand/xr_hand_modle_factory.dart) | [three_js_xr](https://pub.dev/packages/three_js_xr) | ✅ | ❌ | ❌ | +| [XRHandPrimitiveModel](https://github.com/Knightro63/three_js/blob/main/packages/three_js_xr/lib/models/hand/xr_hand_primitive_modle.dart) | [three_js_xr](https://pub.dev/packages/three_js_xr) | ✅ | ❌ | ❌ | +| [XRPlanes](https://github.com/Knightro63/three_js/blob/main/packages/three_js_xr/lib/models/xr_planes.dart) | [three_js_xr](https://pub.dev/packages/three_js_xr) | ✅ | ❌ | ❌ | diff --git a/packages/three_js_angle/lib/three_js.dart b/packages/three_js_angle/lib/three_js.dart new file mode 100755 index 00000000..c185bbd1 --- /dev/null +++ b/packages/three_js_angle/lib/three_js.dart @@ -0,0 +1,14 @@ +library three_js; + +/// Export all the packages that relies on Three_JS to work +export 'package:three_js_math/three_js_math.dart'; +export 'package:three_js_advanced_loaders/three_js_advanced_loaders.dart'; +export 'package:three_js_animations/three_js_animations.dart'; +export 'package:three_js_controls/three_js_controls.dart'; +export 'package:three_js_core/three_js_core.dart'; +export 'package:three_js_core_loaders/three_js_core_loaders.dart'; +export 'package:three_js_curves/three_js_curves.dart'; +export 'package:three_js_simple_loaders/three_js_simple_loaders.dart'; +export 'package:three_js_text/three_js_text.dart'; +export 'package:three_js_geometry/three_js_geometry.dart'; +export 'package:three_js_angle_renderer/three_js_angle_renderer.dart'; diff --git a/packages/three_js_angle/pubspec.yaml b/packages/three_js_angle/pubspec.yaml new file mode 100755 index 00000000..f06ad5eb --- /dev/null +++ b/packages/three_js_angle/pubspec.yaml @@ -0,0 +1,43 @@ +name: three_js_angle +description: "Flutter package converted from threejs and three_dart to allow users to view, edit, and control 3D models." +version: 0.0.1 +homepage: https://github.com/Knightro63/three_js/tree/main/packages/three_js_angle + +topics: + - threejs + - games + - animations + - flutter3d + - model3d + +environment: + sdk: '>=3.3.2 <4.0.0' + flutter: ">=1.17.0" + +dependencies: + flutter: + sdk: flutter + three_js_math: ^0.3.0 + three_js_advanced_loaders: ^0.3.0 + three_js_animations: ^0.3.0 + three_js_controls: ^0.3.0 + three_js_core: ^0.3.0 + three_js_core_loaders: ^0.3.0 + three_js_curves: ^0.3.0 + three_js_simple_loaders: ^0.3.0 + three_js_text: ^0.3.0 + three_js_geometry: ^0.3.0 + three_js_angle_renderer: ^0.0.1 + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^5.0.0 + +platforms: + android: + ios: + macos: + web: + windows: + linux: \ No newline at end of file diff --git a/packages/three_js_angle_renderer/.gitignore b/packages/three_js_angle_renderer/.gitignore new file mode 100755 index 00000000..fbf43d48 --- /dev/null +++ b/packages/three_js_angle_renderer/.gitignore @@ -0,0 +1,143 @@ +# Miscellaneous +*.class +*.lock +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +renderers_old/ +renderers_new/ +# Visual Studio Code related +.classpath +.project +.settings/ +.vscode/* +.metadata + +*/macos +*/web +*/ios +*/android +*/linux +*/windows + +# Flutter repo-specific +/bin/cache/ +/bin/internal/bootstrap.bat +/bin/internal/bootstrap.sh +/bin/mingit/ +/dev/benchmarks/mega_gallery/ +/dev/bots/.recipe_deps +/dev/bots/android_tools/ +/dev/devicelab/ABresults*.json +/dev/docs/doc/ +/dev/docs/flutter.docs.zip +/dev/docs/lib/ +/dev/docs/pubspec.yaml +/dev/integration_tests/**/xcuserdata +/dev/integration_tests/**/Pods +/packages/flutter/coverage/ +version +analysis_benchmark.json + +# packages file containing multi-root paths +.packages.generated + +# Flutter/Dart/Pub related +**/doc/api/ +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +**/generated_plugin_registrant.dart +.packages +.pub-preload-cache/ +.pub/ +build/ +flutter_*.png +linked_*.ds +unlinked.ds +unlinked_spec.ds + +# Android related +**/android/**/gradle-wrapper.jar +.gradle/ +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java +**/android/key.properties +*.jks + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/.last_build_id +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Flutter.podspec +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/ephemeral +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/Flutter/flutter_export_environment.sh +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# macOS +**/Flutter/ephemeral/ +**/Pods/ +**/macos/Flutter/GeneratedPluginRegistrant.swift +**/macos/Flutter/ephemeral +**/xcuserdata/ + +# Windows +**/windows/flutter/generated_plugin_registrant.cc +**/windows/flutter/generated_plugin_registrant.h +**/windows/flutter/generated_plugins.cmake + +# Linux +**/linux/flutter/generated_plugin_registrant.cc +**/linux/flutter/generated_plugin_registrant.h +**/linux/flutter/generated_plugins.cmake + +# Coverage +coverage/ + +# Symbols +app.*.symbols + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +!/dev/ci/**/Gemfile.lock +!.vscode/settings.json \ No newline at end of file diff --git a/packages/three_js_angle_renderer/CHANGELOG.md b/packages/three_js_angle_renderer/CHANGELOG.md new file mode 100755 index 00000000..9b7b03ba --- /dev/null +++ b/packages/three_js_angle_renderer/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.0.1 + +* Initial release. \ No newline at end of file diff --git a/packages/three_js_angle_renderer/LICENSE b/packages/three_js_angle_renderer/LICENSE new file mode 100755 index 00000000..383b4da5 --- /dev/null +++ b/packages/three_js_angle_renderer/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright © 2010-2024 three.js authors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/packages/three_js_angle_renderer/README.md b/packages/three_js_angle_renderer/README.md new file mode 100755 index 00000000..a918e082 --- /dev/null +++ b/packages/three_js_angle_renderer/README.md @@ -0,0 +1,21 @@ +# three_js_angle_renderer + +[![Pub Version](https://img.shields.io/pub/v/three_js_angle_renderer)](https://pub.dev/packages/three_js_angle_renderer) +[![License: MIT](https://img.shields.io/badge/license-MIT-purple.svg)](https://opensource.org/licenses/MIT) + +This is one of the renderers for three_js to allow users to view their 3D objects in their projects. + +## Usage + +This is a renderer for three_js using google's ANGLE. + +## Example + +Find the example for this API [here](https://github.com/Knightro63/three_js/tree/main/packages/three_js_angle_renderer/example/lib/main.dart). + +## Contributing + +Contributions are welcome. +In case of any problems look at [existing issues](https://github.com/Knightro63/three_js/issues), if you cannot find anything related to your problem then open an issue. +Create an issue before opening a [pull request](https://github.com/Knightro63/three_js/pulls) for non trivial fixes. +In case of trivial fixes open a [pull request](https://github.com/Knightro63/three_js/pulls) directly. diff --git a/packages/three_js_angle_renderer/example/.gitignore b/packages/three_js_angle_renderer/example/.gitignore new file mode 100755 index 00000000..79c113f9 --- /dev/null +++ b/packages/three_js_angle_renderer/example/.gitignore @@ -0,0 +1,45 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.build/ +.buildlog/ +.history +.svn/ +.swiftpm/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.pub-cache/ +.pub/ +/build/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/packages/three_js_angle_renderer/example/README.md b/packages/three_js_angle_renderer/example/README.md new file mode 100755 index 00000000..2b3fce4c --- /dev/null +++ b/packages/three_js_angle_renderer/example/README.md @@ -0,0 +1,16 @@ +# example + +A new Flutter project. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) + +For help getting started with Flutter development, view the +[online documentation](https://docs.flutter.dev/), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/packages/three_js_angle_renderer/example/lib/main.dart b/packages/three_js_angle_renderer/example/lib/main.dart new file mode 100755 index 00000000..6b8099d1 --- /dev/null +++ b/packages/three_js_angle_renderer/example/lib/main.dart @@ -0,0 +1,114 @@ +import 'dart:async'; +import 'package:flutter/material.dart'; +import 'package:three_js_core/three_js_core.dart' as three; +import 'package:three_js_math/three_js_math.dart' as tmath; +import 'package:three_js_angle_renderer/three_js_angle_renderer.dart'; +import 'dart:math' as math; + +void main() { + runApp(const MyApp()); +} + +class MyApp extends StatelessWidget { + const MyApp({super.key}); + + // This widget is the root of your application. + @override + Widget build(BuildContext context) { + return MaterialApp( + theme: ThemeData( + colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), + useMaterial3: true, + ), + home: const WebglGeometries(), + ); + } +} + +class WebglGeometries extends StatefulWidget { + const WebglGeometries({super.key}); + + @override + createState() => _State(); +} + +class _State extends State { + late ThreeJS threeJs; + + @override + void initState() { + threeJs = ThreeJS( + onSetupComplete: (){setState(() {});}, + setup: setup, + settings: Settings( + localClippingEnabled: true, + ) + ); + super.initState(); + } + @override + void dispose() { + threeJs.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return threeJs.build(); + } + + int startTime = 0; + + Future setup() async { + threeJs.camera = three.PerspectiveCamera(45, threeJs.width / threeJs.height, 1, 2000); + threeJs.camera.position.y = 400; + + threeJs.scene = three.Scene(); + + three.Mesh object; + + final ambientLight = three.AmbientLight(0xffffff, 0.8); + threeJs.scene.add(ambientLight); + + final pointLight = three.PointLight(0xffffff, 0.8); + threeJs.camera.add(pointLight); + threeJs.scene.add(threeJs.camera); + + final material = three.MeshPhongMaterial.fromMap({ + "color": 0xffffff, + "side": tmath.DoubleSide, + "clipShadows": true + }); + object = three.Mesh(three.SphereGeometry(75, 20, 10), material); + object.position.setValues(-300, 0, 200); + threeJs.scene.add(object); + + object = three.Mesh(three.PlaneGeometry(100, 100, 4, 4), material); + object.position.setValues(-300, 0, 0); + threeJs.scene.add(object); + + object = three.Mesh(three.BoxGeometry(100, 100, 100, 4, 4, 4), material); + object.position.setValues(-100, 0, 0); + threeJs.scene.add(object); + + + startTime = DateTime.now().millisecondsSinceEpoch; + + threeJs.addAnimationEvent((dt){ + final timer = DateTime.now().millisecondsSinceEpoch * 0.0001; + + threeJs.camera.position.x = math.cos(timer) * 800; + threeJs.camera.position.z = math.sin(timer) * 800; + threeJs.camera.lookAt(threeJs.scene.position); + + threeJs.scene.traverse((object) { + if (object is three.Mesh) { + object.rotation.x = timer * 5; + object.rotation.y = timer * 2.5; + } + }); + }); + } +} + + diff --git a/packages/three_js_angle_renderer/example/pubspec.yaml b/packages/three_js_angle_renderer/example/pubspec.yaml new file mode 100755 index 00000000..475e1bd2 --- /dev/null +++ b/packages/three_js_angle_renderer/example/pubspec.yaml @@ -0,0 +1,33 @@ +name: example +description: "A new Flutter project." +publish_to: 'none' # Remove this line if you wish to publish to pub.dev +version: 1.0.0+1 + +environment: + sdk: '>=3.3.2 <4.0.0' + +dependencies: + flutter: + sdk: flutter + cupertino_icons: ^1.0.6 + three_js_angle_renderer: + path: ../ + three_js_math: ^0.2.0 + three_js_core: ^0.2.0 + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^3.0.0 + +dependency_overrides: + flutter_angle: + path: ../../../../flutter_angle/flutter_angle + three_js_math: + path: ../../three_js_math + three_js_core: + path: ../../three_js_core + +# The following section is specific to Flutter packages. +flutter: + uses-material-design: true \ No newline at end of file diff --git a/packages/three_js_angle_renderer/lib/angle/angle_animation.dart b/packages/three_js_angle_renderer/lib/angle/angle_animation.dart new file mode 100755 index 00000000..0301405f --- /dev/null +++ b/packages/three_js_angle_renderer/lib/angle/angle_animation.dart @@ -0,0 +1,36 @@ +part of three_webgl; + +class AngleAnimation { + dynamic context; + bool isAnimating = false; + dynamic animationLoop; + dynamic requestId; + + AngleAnimation(); + + void onAnimationFrame(double time, int frame) { + animationLoop(time, frame); + requestId = context.requestAnimationFrame(onAnimationFrame); + } + + void start() { + if (isAnimating == true) return; + if (animationLoop == null) return; + + requestId = context.requestAnimationFrame(onAnimationFrame); + isAnimating = true; + } + + void stop() { + context?.cancelAnimationFrame(requestId); + isAnimating = false; + } + + void setAnimationLoop(callback) { + animationLoop = callback; + } + + void setContext(value) { + context = value; + } +} diff --git a/packages/three_js_angle_renderer/lib/angle/angle_attributes.dart b/packages/three_js_angle_renderer/lib/angle/angle_attributes.dart new file mode 100755 index 00000000..b2878c42 --- /dev/null +++ b/packages/three_js_angle_renderer/lib/angle/angle_attributes.dart @@ -0,0 +1,211 @@ +part of three_webgl; + +class AngleAttributes { + RenderingContext gl; + bool isWebGL2 = true; + + WeakMap buffers = WeakMap(); + + AngleAttributes(this.gl); + + Map createBuffer(dynamic attribute, int bufferType, {String? name}) {//BufferAttribute + final array = attribute.array; + final usage = attribute.usage; + + dynamic type = WebGL.FLOAT; + int bytesPerElement = 4; + + final buffer = gl.createBuffer(); + + gl.bindBuffer(bufferType, buffer); + gl.bufferData(bufferType, array, usage); + + attribute.onUploadCallback?.call(); + + if (attribute is Float32BufferAttribute) { + type = WebGL.FLOAT; + bytesPerElement = Float32List.bytesPerElement; + } + else if (attribute is Float64BufferAttribute) { + console.error('WebGLAttributes: Unsupported data buffer format: Float64Array.'); + } + else if (attribute is Float16BufferAttribute) { + if (isWebGL2) { + bytesPerElement = 2; + type = WebGL.HALF_FLOAT; + } else { + console.error('WebGLAttributes: Usage of Float16BufferAttribute requires WebGL2.'); + } + } else if (attribute is Uint16BufferAttribute) { + bytesPerElement = Uint16List.bytesPerElement; + type = WebGL.UNSIGNED_SHORT; + } else if (attribute is Int16BufferAttribute) { + bytesPerElement = Int16List.bytesPerElement; + + type = WebGL.SHORT; + } else if (attribute is Uint32BufferAttribute) { + bytesPerElement = Uint32List.bytesPerElement; + + type = WebGL.UNSIGNED_INT; + } else if (attribute is Int32BufferAttribute) { + bytesPerElement = Int32List.bytesPerElement; + type = WebGL.INT; + } else if (attribute is Int8BufferAttribute) { + bytesPerElement = Int8List.bytesPerElement; + type = WebGL.BYTE; + } else if (attribute is Uint8BufferAttribute) { + bytesPerElement = Uint8List.bytesPerElement; + type = WebGL.UNSIGNED_BYTE; + } + + return { + "buffer": buffer, + "type": type, + "bytesPerElement": bytesPerElement, + "array": array, + "version": attribute.version + }; + } + + void updateBuffer(Buffer buffer, attribute, int bufferType) { + final updateRange = attribute.updateRange; + + gl.bindBuffer(bufferType, buffer); + + if (updateRange!["count"] == -1) { + // Not using update ranges + gl.bufferSubData(bufferType, 0, attribute.array); + } + else { + console.info(" WebGLAttributes.dart gl.bufferSubData need debug confirm.... "); + gl.bufferSubData(bufferType, updateRange["offset"]! * attribute.itemSize, attribute.array); + updateRange["count"] = -1; // reset range + } + } + + void updateBufferNew(Buffer buffer, attribute, int bufferType) { + final array = attribute.array; + final updateRanges = attribute.updateRanges; + + gl.bindBuffer(bufferType, buffer); + + if (updateRanges!["length"] == 0) { + // Not using update ranges + gl.bufferSubData(bufferType, 0, attribute.array); + } + // else { + // console.info(" WebGLAttributes.dart gl.bufferSubData need debug confirm.... "); + // gl.bufferSubData(bufferType, updateRange["offset"]! * attribute.itemSize, attribute.array); + // updateRange["count"] = -1; // reset range + // } + + // print(updateRanges); + + else{ + updateRanges.sort( ( a, b ) => a.start - b.start ); + + int mergeIndex = 0; + + for ( int i = 1; i < updateRanges.length; i ++ ) { + final previousRange = updateRanges[ mergeIndex ]; + final range = updateRanges[ i ]; + + // We add one here to merge adjacent ranges. This is safe because ranges + // operate over positive integers. + if ( range.start <= previousRange.start + previousRange.count + 1 ) { + previousRange.count = math.max( + previousRange.count, + range.start + range.count - previousRange.start + ); + } + else { + ++ mergeIndex; + updateRanges[ mergeIndex ] = range; + } + } + updateRanges.length = mergeIndex + 1; + for (int i = 0, l = updateRanges.length; i < l; i ++ ) { + final range = updateRanges[i]; + Float32List f = Float32List.fromList(attribute.array.sublist(range.start,range.count) as List); + gl.bufferSubData( + bufferType, + range.start * array.bytesPerElement, + f, + ); + + //f.dispose(); + } + + attribute.clearUpdateRanges(); + } + + attribute.onUploadCallback?.call(); + } + + dynamic get(BaseBufferAttribute attribute) { + if (attribute is InterleavedBufferAttribute) { + return buffers.get(attribute.data); + } + else { + return buffers.get(attribute); + } + } + void dispose(){ + final len = buffers.keys.toList(); + for(int i = 0; i < len.length;i++){ + if(len[i] is BufferAttribute){ + (len[i] as BufferAttribute).dispose(); + remove(len[i]); + } + else if(len[i] is TypedDataList){ + remove(len[i]); + } + } + buffers.clear(); + } + void remove(BufferAttribute attribute) { + if (attribute is InterleavedBufferAttribute) { + final data = buffers.get(attribute.data); + + if (data != null) { + gl.deleteBuffer(data['buffer']); + buffers.delete(attribute.data); + } + } else { + final data = buffers.get(attribute); + + if (data != null) { + gl.deleteBuffer(data["buffer"]); + + buffers.delete(attribute); + } + } + } + + void update(attribute, bufferType, {String? name}) { + if (attribute is GLBufferAttribute) { + final cached = buffers.get(attribute); + if (cached == null || cached["version"] < attribute.version) { + buffers.add(key: attribute, value: createBuffer(attribute, bufferType, name: name)); + } + return; + } + + if (attribute is InterleavedBufferAttribute) { + attribute = attribute.data; + } + + final data = buffers.get(attribute); + + if (data == null && attribute != null) { + buffers.add( + key: attribute, + value: createBuffer(attribute, bufferType, name: name) + ); + } + else if(data?["version"] != null && data["version"] < attribute.version) { + updateBuffer(data["buffer"], attribute, bufferType); + data["version"] = attribute.version; + } + } +} diff --git a/packages/three_js_angle_renderer/lib/angle/angle_background.dart b/packages/three_js_angle_renderer/lib/angle/angle_background.dart new file mode 100755 index 00000000..a0b5eeb8 --- /dev/null +++ b/packages/three_js_angle_renderer/lib/angle/angle_background.dart @@ -0,0 +1,234 @@ +part of three_webgl; + +final _e1 = Euler(); +final _m1 = Matrix4(); + +class AngleBackground { + bool _didDispose = false; + AngleCubeMaps cubemaps; + AngleCubeUVMaps cubeuvmaps; + AngleState state; + + AngleRenderer renderer; + AngleObjects objects; + bool alpha; + bool premultipliedAlpha; + + Color clearColor = Color(0x000000); + double clearAlpha = 0; + + Mesh? planeMesh; + Mesh? boxMesh; + + dynamic currentBackground; + int currentBackgroundVersion = 0; + late int currentTonemapping; + + AngleBackground(this.renderer, this.cubemaps, this.cubeuvmaps, this.state, this.objects, this.alpha, this.premultipliedAlpha) { + clearAlpha = alpha == true ? 0.0 : 1.0; + } + + dynamic getBackground(Object3D? scene ) { + dynamic background = scene is Scene? scene.background : null; + + if ( background != null && background is Texture ) { + final usePMREM = (scene as Scene).backgroundBlurriness > 0; // use PMREM if the user wants to blur the background + background = usePMREM ? cubeuvmaps.get(background) : cubemaps.get(background); + } + + return background; + } + + void render(Object3D scene) { + bool forceClear = false; + dynamic background = getBackground(scene);//scene is Scene ? scene.background : null; + + if (background == null) { + setClear(clearColor, clearAlpha); + } + else if (background != null && background is Color) { + setClear(background, 1); + forceClear = true; + } + + final environmentBlendMode = renderer.xr.getEnvironmentBlendMode(); + + if (environmentBlendMode == 'additive' ) { + state.buffers['color'].setClear( 0, 0, 0, 1, premultipliedAlpha ); + } + else if (environmentBlendMode == 'alpha-blend' ) { + state.buffers['color'].setClear( 0, 0, 0, 0, premultipliedAlpha ); + } + + if (renderer.autoClear || forceClear) { + state.buffers['depth'].setTest( true ); + state.buffers['depth'].setMask( true ); + state.buffers['color'].setMask( true ); + + renderer.clear(renderer.autoClearColor, renderer.autoClearDepth, renderer.autoClearStencil); + } + } + + void addToRenderList(AngleRenderList renderList, Object3D scene) { + final background = getBackground( scene ); + + if ( background != null && ( background is CubeTexture || (background is Texture && background.mapping == CubeUVReflectionMapping)) ) { + if ( boxMesh == null ) { + boxMesh = Mesh( + BoxGeometry( 1, 1, 1 ), + ShaderMaterial.fromMap( { + 'name': 'BackgroundCubeMaterial', + 'uniforms': cloneUniforms( shaderLib['backgroundCube']['uniforms'] ), + 'vertexShader': shaderLib['backgroundCube']['vertexShader'], + 'fragmentShader': shaderLib['backgroundCube']['fragmentShader'], + 'side': BackSide, + 'depthTest': false, + 'depthWrite': false, + 'fog': false + }) + ); + + boxMesh!.geometry?.deleteAttributeFromString( 'normal' ); + boxMesh!.geometry?.deleteAttributeFromString( 'uv' ); + + boxMesh!.onBeforeRender = ({ + renderer, + scene, + camera, + renderTarget, + mesh, + geometry, + material, + group + }) { + boxMesh!.matrixWorld.copyPosition(camera!.matrixWorld); + }; + + planeMesh?.material?.envMap = planeMesh?.material?.uniforms['envMap']['value']; + objects.update(boxMesh!); + } + + (scene as Scene); + _e1.copy(scene.backgroundRotation); + + // accommodate left-handed frame + _e1.x *= - 1; _e1.y *= - 1; _e1.z *= - 1; + + if ( background is CubeTexture && !background.isRenderTargetTexture) { + // environment maps which are not cube render targets or PMREMs follow a different convention + _e1.y *= - 1; + _e1.z *= - 1; + } + + boxMesh!.material!.uniforms['envMap']['value'] = background; + boxMesh!.material!.uniforms['flipEnvMap']['value'] = ( background is CubeTexture && !background.isRenderTargetTexture) ? - 1 : 1; + boxMesh!.material!.uniforms['backgroundBlurriness']['value'] = scene.backgroundBlurriness; + boxMesh!.material!.uniforms['backgroundIntensity']['value'] = scene.backgroundIntensity; + boxMesh!.material!.uniforms['backgroundRotation']['value'].setFromMatrix4( _m1.makeRotationFromEuler( _e1 ) ); + boxMesh!.material!.toneMapped = ColorManagement.getTransfer( ColorSpace.fromString( background.colorSpace )) != SRGBTransfer; + + if ( currentBackground != background || + currentBackgroundVersion != background.version || + currentTonemapping != renderer.toneMapping ) { + boxMesh!.material?.needsUpdate = true; + + currentBackground = background; + currentBackgroundVersion = background.version; + currentTonemapping = renderer.toneMapping; + } + + boxMesh!.layers.enableAll(); + + // push to the pre-sorted opaque render list + renderList.unshift(boxMesh!, boxMesh!.geometry, boxMesh!.material, 0, 0, null ); + + } + else if ( background != null && background is Texture ) { + if (planeMesh == null ) { + + planeMesh = Mesh( + PlaneGeometry( 2, 2 ), + ShaderMaterial.fromMap( { + 'name': 'BackgroundMaterial', + 'uniforms': cloneUniforms( shaderLib['background']['uniforms'] ), + 'vertexShader': shaderLib['background']['vertexShader'], + 'fragmentShader': shaderLib['background']['fragmentShader'], + 'side': FrontSide, + 'depthTest': false, + 'depthWrite': false, + 'fog': false + } ) + ); + + planeMesh!.geometry?.deleteAttributeFromString( 'normal' ); + planeMesh!.material?.map = planeMesh!.material!.uniforms['t2D']['value']; + + objects.update(planeMesh!); + } + + planeMesh!.material?.uniforms['t2D']['value'] = background; + planeMesh!.material?.uniforms['backgroundIntensity']['value'] = (scene as Scene).backgroundIntensity; + planeMesh!.material?.toneMapped = ColorManagement.getTransfer( ColorSpace.fromString(background.colorSpace)) != SRGBTransfer; + + if ( background.matrixAutoUpdate) { + background.updateMatrix(); + } + + planeMesh!.material?.uniforms['uvTransform']['value'].setFrom( background.matrix ); + + if ( currentBackground != background || + currentBackgroundVersion != background.version || + currentTonemapping != renderer.toneMapping ) { + + planeMesh!.material?.needsUpdate = true; + + currentBackground = background; + currentBackgroundVersion = background.version; + currentTonemapping = renderer.toneMapping; + } + + planeMesh!.layers.enableAll(); + + // push to the pre-sorted opaque render list + renderList.unshift( planeMesh!, planeMesh!.geometry, planeMesh!.material, 0, 0, null ); + } + } + + void setClear(Color color, double alpha) { + state.buffers["color"].setClear(color.red, color.green, color.blue, alpha, premultipliedAlpha); + } + + Color getClearColor() { + return clearColor; + } + + void setClearColor(Color color, [double alpha = 1.0]) { + clearColor.setFrom(color); + clearAlpha = alpha; + setClear(clearColor, clearAlpha); + } + + double getClearAlpha() { + return clearAlpha; + } + + void setClearAlpha(double alpha) { + clearAlpha = alpha; + setClear(clearColor, clearAlpha); + } + + void dispose(){ + if(_didDispose) return; + _didDispose = true; + cubemaps.dispose(); + state.dispose(); + renderer.dispose(); + planeMesh?.dispose(); + boxMesh?.dispose(); + objects.dispose(); + + if(currentBackground is Texture){ + currentBackground.dispose(); + } + } +} diff --git a/packages/three_js_angle_renderer/lib/angle/angle_binding_states.dart b/packages/three_js_angle_renderer/lib/angle/angle_binding_states.dart new file mode 100755 index 00000000..92bbb629 --- /dev/null +++ b/packages/three_js_angle_renderer/lib/angle/angle_binding_states.dart @@ -0,0 +1,466 @@ +part of three_webgl; + +class AngleBindingStates { + bool _didDispose = false; + RenderingContext gl; + AngleAttributes attributes; + + late int maxVertexAttributes; + + dynamic extension; + + late Map defaultState; + late Map currentState; + late Map bindingStates; + + bool forceUpdate = false; + + AngleBindingStates( + this.gl, + this.attributes, + ) { + maxVertexAttributes = gl.getParameter(WebGL.MAX_VERTEX_ATTRIBS); + bindingStates = {}; + defaultState = createBindingState(null); + currentState = defaultState; + } + + void setup( + Object3D object, + Material material, + AngleProgram program, + BufferGeometry geometry, + BufferAttribute? index, + ) { + bool updateBuffers = false; + + final state = getBindingState(geometry, program, material); + + if (currentState != state) { + currentState = state; + bindVertexArrayObject(currentState["object"]); + } + + updateBuffers = needsUpdate(object, geometry, program, index); + + if (updateBuffers) saveCache(object, geometry, program, index); + + + if (index != null) { + attributes.update(index, WebGL.ELEMENT_ARRAY_BUFFER); + } + + if (updateBuffers || forceUpdate) { + forceUpdate = false; + + setupVertexAttributes(object, material, program, geometry); + + if (index != null) { + final buf = attributes.get(index)["buffer"]; + gl.bindBuffer(WebGL.ELEMENT_ARRAY_BUFFER, buf); + } + } + } + + VertexArrayObject createVertexArrayObject() { + return gl.createVertexArray(); + } + + void bindVertexArrayObject(VertexArrayObject? vao) { + if (vao != null) { + return gl.bindVertexArray(vao); + } + else { + console.warning(" WebGLBindingStates.dart bindVertexArrayObject VAO is null"); + return; + } + } + + void deleteVertexArrayObject(vao) { + return gl.deleteVertexArray(vao); + } + + getBindingState( + BufferGeometry geometry, + program, + Material material, + ) { + final wireframe = (material.wireframe == true); + + Map? programMap = bindingStates[geometry.id]; + + if (programMap == null) { + programMap = {}; + bindingStates[geometry.id] = programMap; + } + + Map? stateMap = programMap[program.id]; + + if (stateMap == null) { + stateMap = {}; + programMap[program.id] = stateMap; + } + + Map? state = stateMap[wireframe]; + + if (state == null) { + state = createBindingState(createVertexArrayObject()); + stateMap[wireframe] = state; + } + + return state; + } + + Map createBindingState(VertexArrayObject? vao) { + final newAttributes = List.filled(maxVertexAttributes, 0); + final enabledAttributes = List.filled(maxVertexAttributes, 0); + final attributeDivisors = List.filled(maxVertexAttributes, 0); + + // for (int i = 0; i < maxVertexAttributes; i++) { + // newAttributes[i] = 0; + // enabledAttributes[i] = 0; + // attributeDivisors[i] = 0; + // } + + return { + // for backward compatibility on non-VAO support browser + "geometry": null, + "program": null, + "wireframe": false, + + "newAttributes": newAttributes, + "enabledAttributes": enabledAttributes, + "attributeDivisors": attributeDivisors, + "object": vao, + "attributes": {}, + "index": null + }; + } + + bool needsUpdate(Object3D object, BufferGeometry geometry, AngleProgram program, BufferAttribute? index) { + final cachedAttributes = currentState["attributes"]; + final geometryAttributes = geometry.attributes; + int attributesNum = 0; + final programAttributes = program.getAttributes(); + for (final name in programAttributes.keys) { + AttributeLocations programAttribute = programAttributes[name]!; + + if (programAttribute.location.id >= 0) { + final cachedAttribute = cachedAttributes[name]; + BufferAttribute? geometryAttribute = geometryAttributes[name]; + + if (geometryAttribute == null) { + if (name == 'instanceMatrix' && object.instanceMatrix != null) geometryAttribute = object.instanceMatrix; + if (name == 'instanceColor' && object.instanceColor != null) geometryAttribute = object.instanceColor; + } + + if (cachedAttribute == null) return true; + + if (cachedAttribute["attribute"] != geometryAttribute) return true; + + if (geometryAttribute != null && cachedAttribute["data"] != geometryAttribute.data) return true; + + attributesNum++; + } + } + + if (currentState["attributesNum"] != attributesNum) return true; + if (currentState["index"] != index) return true; + return false; + } + + void saveCache(object, BufferGeometry geometry, AngleProgram program, BufferAttribute? index) { + final cache = {}; + final attributes = geometry.attributes; + int attributesNum = 0; + + final programAttributes = program.getAttributes(); + + for (final name in programAttributes.keys) { + AttributeLocations programAttribute = programAttributes[name]!; + + if (programAttribute.location.id >= 0) { + BufferAttribute? attribute = attributes[name]; + + if (attribute == null) { + if (name == 'instanceMatrix' && object.instanceMatrix != null) attribute = object.instanceMatrix; + if (name == 'instanceColor' && object.instanceColor != null) attribute = object.instanceColor; + } + + final data = {}; + data["attribute"] = attribute; + + if (attribute != null && attribute.data != null) { + data["data"] = attribute.data; + } + + cache[name] = data; + + attributesNum++; + } + } + + currentState["attributes"] = cache; + currentState["attributesNum"] = attributesNum; + + currentState["index"] = index; + } + + void initAttributes() { + final newAttributes = currentState["newAttributes"]; + + for (int i = 0, il = newAttributes.length; i < il; i++) { + newAttributes[i] = 0; + } + } + + void enableAttribute(int attribute) { + enableAttributeAndDivisor(attribute, 0); + } + + void enableAttributeAndDivisor(int attribute, int meshPerAttribute) { + final newAttributes = currentState["newAttributes"]; + final enabledAttributes = currentState["enabledAttributes"]; + final attributeDivisors = currentState["attributeDivisors"]; + + newAttributes[attribute] = 1; + + if (enabledAttributes[attribute] == 0) { + gl.enableVertexAttribArray(attribute); + enabledAttributes[attribute] = 1; + } + + if (attributeDivisors[attribute] != meshPerAttribute) { + gl.vertexAttribDivisor(attribute, meshPerAttribute); + attributeDivisors[attribute] = meshPerAttribute; + } + } + + void disableUnusedAttributes() { + final newAttributes = currentState["newAttributes"]; + final enabledAttributes = currentState["enabledAttributes"]; + + for (int i = 0, il = enabledAttributes.length; i < il; i++) { + if (enabledAttributes[i] != newAttributes[i]) { + gl.disableVertexAttribArray(i); + enabledAttributes[i] = 0; + } + } + } + + void vertexAttribPointer(int index, int size, int type, bool normalized, int stride, int offset, bool integer) { + if (integer){ + gl.vertexAttribIPointer(index, size, type, stride, offset); + } else { + gl.vertexAttribPointer(index, size, type, normalized, stride, offset); + } + } + + void setupVertexAttributes( + Object3D object, + Material material, + AngleProgram program, + BufferGeometry geometry, + ) { + initAttributes(); + + final geometryAttributes = geometry.attributes; + + final programAttributes = program.getAttributes(); + + final materialDefaultAttributeValues = material.defaultAttributeValues; + + for (final name in programAttributes.keys) { + final programAttribute = programAttributes[name]; + + if (programAttribute!.location.id >= 0) { + BufferAttribute? geometryAttribute = geometryAttributes[name]; + + if (geometryAttribute == null) { + if (name == 'instanceMatrix' && object is InstancedMesh) { + geometryAttribute = object.instanceMatrix; + } + if (name == 'instanceColor' && object is InstancedMesh && object.instanceColor != null) { + geometryAttribute = object.instanceColor; + } + } + + if (geometryAttribute != null) { + final normalized = geometryAttribute.normalized; + final size = geometryAttribute.itemSize; + + final attribute = attributes.get(geometryAttribute); + + // TODO Attribute may not be available on context restore + + if (attribute == null) { + console.warning("WebGLBindingState setupVertexAttributes name: $name attribute == null "); + continue; + } + + final buffer = attribute["buffer"]; + final type = attribute["type"]; + final bytesPerElement = attribute["bytesPerElement"]; + + final integer = ( type == WebGL.INT || type == WebGL.UNSIGNED_INT) && geometryAttribute.gpuType == IntType; + if (geometryAttribute is InterleavedBufferAttribute) { + final data = geometryAttribute.data; + final stride = data?.stride; + final offset = geometryAttribute.offset; + + if (data != null && data is InstancedInterleavedBuffer) { + for (int i = 0; i < programAttribute.locationSize; i++) { + enableAttributeAndDivisor(programAttribute.location.id + i, data.meshPerAttribute); + } + + if (object is! InstancedMesh && geometry.maxInstanceCount == null) { + geometry.maxInstanceCount = data.meshPerAttribute * data.count; + } + } + else { + for (int i = 0; i < programAttribute.locationSize; i++) { + enableAttribute(programAttribute.location.id + i); + } + } + + gl.bindBuffer(WebGL.ARRAY_BUFFER, buffer); + + for (int i = 0; i < programAttribute.locationSize; i++) { + vertexAttribPointer( + programAttribute.location.id + i, + size ~/ programAttribute.locationSize, + type, + normalized, + (stride! * bytesPerElement).toInt(), + ((offset + (size ~/ programAttribute.locationSize) * i) * bytesPerElement).toInt(), + integer + ); + } + } + else { + if (geometryAttribute is InstancedBufferAttribute) { + for (int i = 0; i < programAttribute.locationSize; i++) { + enableAttributeAndDivisor(programAttribute.location.id + i, geometryAttribute.meshPerAttribute); + } + geometry.maxInstanceCount ??= geometryAttribute.meshPerAttribute * geometryAttribute.count; + } + else { + for (int i = 0; i < programAttribute.locationSize; i++) { + enableAttribute(programAttribute.location.id + i); + } + } + + gl.bindBuffer(WebGL.ARRAY_BUFFER, buffer); + for (int i = 0; i < programAttribute.locationSize; i++) { + vertexAttribPointer( + programAttribute.location.id + i, + size ~/ programAttribute.locationSize, + type, + normalized, + (size * bytesPerElement).toInt(), + ((size ~/ programAttribute.locationSize) * i * bytesPerElement).toInt(), + integer + ); + } + } + } + else if (materialDefaultAttributeValues != null) { + final value = materialDefaultAttributeValues[name]; + + if (value != null) { + switch (value.length) { + case 2: + gl.vertexAttrib2fv(programAttribute.location.id, value); + break; + case 3: + gl.vertexAttrib3fv(programAttribute.location.id, value); + break; + case 4: + gl.vertexAttrib4fv(programAttribute.location.id, value); + break; + default: + gl.vertexAttrib1fv(programAttribute.location.id, value); + } + } + } + } + } + + disableUnusedAttributes(); + } + + void dispose() { + if(_didDispose) return; + _didDispose = true; + reset(); + + for ( final geometryId in bindingStates.keys ) { + final programMap = bindingStates[ geometryId ]; + for ( final programId in programMap.keys ) { + final stateMap = programMap[ programId ]; + for ( final wireframe in stateMap.keys) { + deleteVertexArrayObject( stateMap[ wireframe ]['object'] ); + } + stateMap.clear(); + } + programMap.clear(); + } + + bindingStates.clear(); + attributes.dispose(); + defaultState.clear(); + currentState.clear(); + attributes.dispose(); + } + + void releaseStatesOfGeometry(BufferGeometry geometry) { + if (bindingStates[geometry.id] == null) return; + + final programMap = bindingStates[geometry.id]; + for (final programId in programMap.keys) { + final stateMap = programMap[programId]; + for (final wireframe in stateMap.keys) { + deleteVertexArrayObject(stateMap[wireframe]["object"]); + } + stateMap.clear(); + } + programMap.clear(); + + bindingStates.remove(geometry.id); + } + + void releaseStatesOfProgram(program) { + console.info(" WebGLBindingStates releaseStatesOfProgram "); + + for (final geometryId in bindingStates.keys ) { + final programMap = bindingStates[ geometryId ]; + + if ( programMap[ program.id ] == null ) continue; + final stateMap = programMap[ program.id ]; + + for ( final wireframe in stateMap.keys ) { + deleteVertexArrayObject( stateMap[ wireframe ]['object'] ); + } + (stateMap as Map).clear(); + (programMap as Map).remove(program.id); + } + } + + void reset() { + resetDefaultState(); + forceUpdate = true; + + if (currentState == defaultState) return; + + currentState = defaultState; + bindVertexArrayObject(currentState["object"]); + } + + // for backward-compatilibity + + void resetDefaultState() { + defaultState["geometry"] = null; + defaultState["program"] = null; + defaultState["wireframe"] = false; + } +} diff --git a/packages/three_js_angle_renderer/lib/angle/angle_buffer_renderer.dart b/packages/three_js_angle_renderer/lib/angle/angle_buffer_renderer.dart new file mode 100755 index 00000000..e8996f91 --- /dev/null +++ b/packages/three_js_angle_renderer/lib/angle/angle_buffer_renderer.dart @@ -0,0 +1,107 @@ +part of three_webgl; + +class BaseAngleBufferRenderer { + void setIndex(value) { + throw (" BaseAngleBufferRenderer.setIndex value: $value "); + } + + void render(int start, int count) { + throw (" BaseWebGLBufferRenderer.render start: $start $count "); + } + + void renderInstances(int start, int count, int primcount) { + throw (" BaseWebGLBufferRenderer.renderInstances start: $start $count primcount: $primcount "); + } + + void setMode(value) { + throw (" BaseWebGLBufferRenderer.setMode value: $value "); + } + + void renderMultiDraw(List starts, List counts, int drawCount) { + throw (" BaseWebGLBufferRenderer.renderMultiDraw not supported "); + } + + void renderMultiDrawInstances(List starts, List counts, int drawCount, List primcount ) { + throw (" BaseWebGLBufferRenderer.renderMultiDrawInstances not supported "); + } +} + +class AngleBufferRenderer extends BaseAngleBufferRenderer { + bool _didDispose = false; + RenderingContext gl; + bool isWebGL2 = true; + dynamic mode; + AngleExtensions extensions; + AngleInfo info; + + AngleBufferRenderer(this.gl, this.extensions, this.info); + + void dispose(){ + if(_didDispose) return; + _didDispose = true; + extensions.dispose(); + info.dispose(); + } + + @override + void setMode(value) { + mode = value; + } + + @override + void render(int start, int count) { + gl.drawArrays(mode, start, count); + info.update(count, mode, 1); + } + + @override + void renderInstances(int start, int count, int primcount) { + if (primcount == 0) return; + gl.drawArraysInstanced(mode, start, count, primcount); + info.update(count, mode, primcount); + } + + @override + void renderMultiDraw(List starts, List counts, int drawCount) { + if ( drawCount == 0 ) return; + final extension = extensions.get( 'WEBGL_multi_draw' ); + + if ( extension == null ) { + for (int i = 0; i < drawCount; i ++ ) { + render(starts[i], counts[i]); + } + } + else { + extension.multiDrawArraysWEBGL( mode, starts, 0, counts, 0, drawCount ); + int elementCount = 0; + for (int i = 0; i < drawCount; i ++ ) { + elementCount += counts[i]; + } + + info.update( elementCount, mode, 1 ); + } + } + + @override + void renderMultiDrawInstances(List starts, List counts, int drawCount, List primcount ) { + if ( drawCount == 0 ) return; + final extension = extensions.get( 'WEBGL_multi_draw' ); + + if ( extension == null ) { + for (int i = 0; i < starts.length; i ++ ) { + renderInstances(starts[i], counts[i], primcount[i]); + } + } + else { + extension.multiDrawArraysInstancedWEBGL( mode, starts, 0, counts, 0, primcount, 0, drawCount ); + + int elementCount = 0; + for (int i = 0; i < drawCount; i ++ ) { + elementCount += counts[ i ]; + } + for (int i = 0; i < primcount.length; i ++ ) { + info.update(elementCount, mode, primcount[i]); + } + } + } +} diff --git a/packages/three_js_angle_renderer/lib/angle/angle_capabilities.dart b/packages/three_js_angle_renderer/lib/angle/angle_capabilities.dart new file mode 100755 index 00000000..a1e916d6 --- /dev/null +++ b/packages/three_js_angle_renderer/lib/angle/angle_capabilities.dart @@ -0,0 +1,117 @@ +part of three_webgl; + +class AngleCapabilities { + bool _didDispose = false; + bool isWebGL2 = true; + + AngleRendererParameters parameters; + RenderingContext gl; + AngleExtensions extensions; + AngleUtils utils; + + String precision = 'highp'; + String maxPrecision = "highp"; + + bool logarithmicDepthBuffer = false; + late int maxTextures; + late int maxVertexTextures; + late int maxTextureSize; + late int maxCubemapSize; + late int maxAttributes; + late int maxVertexUniforms; + late int maxVaryings; + late int maxFragmentUniforms; + late bool reverseDepthBuffer; + + num? maxAnisotropy; + + late bool vertexTextures; + late int maxSamples; + + bool drawBuffers = true; + + AngleCapabilities(this.gl, this.extensions, this.parameters, this.utils) { + precision = parameters.precision.name; + + maxPrecision = getMaxPrecision(precision); + if (maxPrecision != precision) { + console.warning('AngleRenderer: $precision not supported, using $maxPrecision instead.'); + precision = maxPrecision; + } + + logarithmicDepthBuffer = parameters.logarithmicDepthBuffer == true; + reverseDepthBuffer = parameters.reverseDepthBuffer == true && extensions.has( 'EXT_clip_control' ); + + maxTextures = gl.getParameter(WebGL.MAX_TEXTURE_IMAGE_UNITS); + maxVertexTextures = gl.getParameter(WebGL.MAX_VERTEX_TEXTURE_IMAGE_UNITS); + maxTextureSize = gl.getParameter(WebGL.MAX_TEXTURE_SIZE); + maxCubemapSize = gl.getParameter(WebGL.MAX_CUBE_MAP_TEXTURE_SIZE); + + maxAttributes = gl.getParameter(WebGL.MAX_VERTEX_ATTRIBS); + maxVertexUniforms = gl.getParameter(WebGL.MAX_VERTEX_UNIFORM_VECTORS); + maxVaryings = gl.getParameter(WebGL.MAX_VARYING_VECTORS); + maxFragmentUniforms = gl.getParameter(WebGL.MAX_FRAGMENT_UNIFORM_VECTORS); + + vertexTextures = maxVertexTextures > 0; + + maxSamples = gl.getParameter(WebGL.MAX_SAMPLES); + } + + num getMaxAnisotropy() { + if (maxAnisotropy != null) return maxAnisotropy!; + + final extension = extensions.get('EXT_texture_filter_anisotropic'); + + if (extension != null) { + maxAnisotropy = gl.getParameter(WebGL.MAX_TEXTURE_MAX_ANISOTROPY_EXT); + } else { + maxAnisotropy = 0; + } + + return maxAnisotropy!; + } + + bool textureFormatReadable(int textureFormat ) { + if ( textureFormat != RGBAFormat && utils.convert( textureFormat ) != gl.getParameter( WebGL.IMPLEMENTATION_COLOR_READ_FORMAT ) ) { + return false; + } + return true; + } + + bool textureTypeReadable(int textureType ) { + final halfFloatSupportedByExt = ( textureType == HalfFloatType ) && ( extensions.has( 'EXT_color_buffer_half_float' ) || extensions.has( 'EXT_color_buffer_float' ) ); + + if ( textureType != UnsignedByteType && utils.convert( textureType ) != gl.getParameter( WebGL.IMPLEMENTATION_COLOR_READ_TYPE ) && // Edge and Chrome Mac < 52 (#9513) + textureType != FloatType && ! halfFloatSupportedByExt ) { + return false; + } + + return true; + } + String getMaxPrecision([String? precision]) { + if ( precision == 'highp' ) { + if ( gl.getShaderPrecisionFormat( WebGL.VERTEX_SHADER, WebGL.HIGH_FLOAT ).precision > 0 && + gl.getShaderPrecisionFormat( WebGL.FRAGMENT_SHADER, WebGL.HIGH_FLOAT ).precision > 0 ) { + return 'highp'; + } + + precision = 'mediump'; + } + + if ( precision == 'mediump' ) { + if ( gl.getShaderPrecisionFormat( WebGL.VERTEX_SHADER, WebGL.MEDIUM_FLOAT ).precision > 0 && + gl.getShaderPrecisionFormat( WebGL.FRAGMENT_SHADER, WebGL.MEDIUM_FLOAT ).precision > 0 ) { + return 'mediump'; + } + } + + return 'lowp'; + } + + void dispose(){ + if(_didDispose) return; + _didDispose = true; + //parameters.clear(); + extensions.dispose(); + } +} diff --git a/packages/three_js_angle_renderer/lib/angle/angle_clipping.dart b/packages/three_js_angle_renderer/lib/angle/angle_clipping.dart new file mode 100755 index 00000000..7b63b7ef --- /dev/null +++ b/packages/three_js_angle_renderer/lib/angle/angle_clipping.dart @@ -0,0 +1,138 @@ +part of three_webgl; + +class AngleClipping { + bool _didDispose = false; + AngleProperties properties; + + Matrix3 viewNormalMatrix = Matrix3.identity(); + Plane plane = Plane(); + int numGlobalPlanes = 0; + + bool localClippingEnabled = false; + bool renderingShadows = false; + + dynamic globalState; + + Map uniform = {"value": null, "needsUpdate": false}; + + int numPlanes = 0; + int numIntersection = 0; + + AngleClipping(this.properties); + + void dispose(){ + if(_didDispose) return; + _didDispose = true; + properties.dispose(); + uniform.clear(); + } + + bool init(List planes, bool enableLocalClipping) { + final enabled = planes.isNotEmpty || + enableLocalClipping || + // enable state of previous frame - the clipping code has to + // run another frame in order to reset the state: + numGlobalPlanes != 0 || + localClippingEnabled; + + localClippingEnabled = enableLocalClipping; + + numGlobalPlanes = planes.length; + + return enabled; + } + + void beginShadows() { + renderingShadows = true; + projectPlanes(); + } + + void endShadows() { + renderingShadows = false; + } + + void setGlobalState(List planes,Camera camera ) { + globalState = projectPlanes( planes, camera, 0 ); + } + + + void setState(Material material, Camera camera, bool useCache) { + final planes = material.clippingPlanes; + final clipIntersection = material.clipIntersection; + final clipShadows = material.clipShadows; + + final materialProperties = properties.get(material); + + if (!localClippingEnabled || planes == null || planes.isEmpty || renderingShadows && !clipShadows) { + if (renderingShadows) { + projectPlanes(); + } + else { + resetGlobalState(); + } + } + else { + final nGlobal = renderingShadows ? 0 : numGlobalPlanes; + final lGlobal = nGlobal * 4; + + List? dstArray = materialProperties["clippingState"]; + + uniform["value"] = dstArray; // ensure unique state + + dstArray = projectPlanes(planes, camera, lGlobal, useCache); + + for (int i = 0; i != lGlobal; ++i) { + dstArray?[i] = globalState[i]; + } + + materialProperties["clippingState"] = dstArray; + numIntersection = clipIntersection ? numPlanes : 0; + numPlanes += nGlobal; + } + } + + void resetGlobalState() { + if (uniform["value"] != globalState) { + uniform["value"] = globalState; + uniform["needsUpdate"] = numGlobalPlanes > 0; + } + + numPlanes = numGlobalPlanes; + numIntersection = 0; + } + + List? projectPlanes([List? planes, Camera? camera, int dstOffset = 0, bool skipTransform = false]) { + final nPlanes = planes != null ? planes.length : 0; + List? dstArray; + + if (nPlanes != 0) { + dstArray = uniform["value"]; + + if (!skipTransform || dstArray == null) { + final flatSize = dstOffset + nPlanes * 4; + final viewMatrix = camera?.matrixWorldInverse ?? Matrix4.identity(); + + viewNormalMatrix.getNormalMatrix(viewMatrix); + + if (dstArray == null || dstArray.length < flatSize) { + dstArray = List.filled(flatSize, 0.0); + } + + for (int i = 0, i4 = dstOffset; i != nPlanes; ++i, i4 += 4) { + plane..copyFrom(planes![i])..applyMatrix4(viewMatrix, viewNormalMatrix); + + plane.normal.copyIntoArray(dstArray, i4); + dstArray[i4 + 3] = plane.constant; + } + } + + uniform["value"] = dstArray; + uniform["needsUpdate"] = true; + } + + numPlanes = nPlanes; + numIntersection = 0; + + return dstArray; + } +} diff --git a/packages/three_js_angle_renderer/lib/angle/angle_cube_maps.dart b/packages/three_js_angle_renderer/lib/angle/angle_cube_maps.dart new file mode 100755 index 00000000..ab46b62e --- /dev/null +++ b/packages/three_js_angle_renderer/lib/angle/angle_cube_maps.dart @@ -0,0 +1,74 @@ +part of three_webgl; + +class AngleCubeMaps { + bool _didDispose = false; + AngleRenderer renderer; + WeakMap cubemaps = WeakMap(); + + AngleCubeMaps(this.renderer); + + Texture mapTextureMapping(Texture texture, int? mapping) { + if (mapping == EquirectangularReflectionMapping) { + texture.mapping = CubeReflectionMapping; + } + else if (mapping == EquirectangularRefractionMapping) { + texture.mapping = CubeRefractionMapping; + } + return texture; + } + + Texture? get(Texture? texture) { + if (texture != null && !texture.isRenderTargetTexture) { + final mapping = texture.mapping; + + if (mapping == EquirectangularReflectionMapping || mapping == EquirectangularRefractionMapping) { + if (cubemaps.has(texture)) { + final cubemap = cubemaps.get(texture).texture; + return mapTextureMapping(cubemap, texture.mapping); + } + else { + final image = texture.image; + + if (image != null && image.height > 0) { + final renderTarget = AngleCubeRenderTarget(image.height ~/ 2); + renderTarget.fromEquirectangularTexture(renderer, texture); + cubemaps.add(key: texture, value: renderTarget); + + texture.addEventListener('dispose', onTextureDispose); + + return mapTextureMapping(renderTarget.texture, texture.mapping); + } + else { + // image not yet ready. try the conversion next frame + return null; + } + } + } + } + + return texture; + } + + void onTextureDispose(event) { + final texture = event.target; + + texture.removeEventListener('dispose', onTextureDispose); + + final cubemap = cubemaps.get(texture); + + if (cubemap != null) { + cubemaps.delete(texture); + cubemap.dispose(); + } + } + + void dispose() { + if(_didDispose) return; + _didDispose = true; + for(final key in cubemaps.keys){ + cubemaps[key].dispose(); + } + cubemaps.clear(); + renderer.dispose(); + } +} diff --git a/packages/three_js_angle_renderer/lib/angle/angle_cube_uv_maps.dart b/packages/three_js_angle_renderer/lib/angle/angle_cube_uv_maps.dart new file mode 100755 index 00000000..e5b5064d --- /dev/null +++ b/packages/three_js_angle_renderer/lib/angle/angle_cube_uv_maps.dart @@ -0,0 +1,102 @@ +part of three_webgl; + +class AngleCubeUVMaps { + bool _didDispose = false; + WeakMap cubeUVmaps = WeakMap(); + AngleRenderer renderer; + PMREMGenerator? pmremGenerator; + + AngleCubeUVMaps(this.renderer); + + Texture? get(Texture? texture) { + if (texture != null) { + final mapping = texture.mapping; + + bool isEquirectMap = (mapping == EquirectangularReflectionMapping || mapping == EquirectangularRefractionMapping); + bool isCubeMap = (mapping == CubeReflectionMapping || mapping == CubeRefractionMapping); + + // equirect/cube map to cubeUV conversion + if (isEquirectMap || isCubeMap) { + RenderTarget? renderTarget = cubeUVmaps.get( texture ); + final currentPMREMVersion = renderTarget != null ? renderTarget.texture.pmremVersion : 0; + + if (texture.isRenderTargetTexture && texture.pmremVersion != currentPMREMVersion) { + if ( pmremGenerator == null ) pmremGenerator = new PMREMGenerator( renderer ); + + renderTarget = isEquirectMap ? pmremGenerator?.fromEquirectangular( texture, renderTarget ) : pmremGenerator?.fromCubemap( texture, renderTarget ); + renderTarget?.texture.pmremVersion = texture.pmremVersion; + + cubeUVmaps.set( texture, renderTarget ); + + return renderTarget?.texture; + } + else { + if (renderTarget != null) { + return renderTarget.texture; + } + else { + final image = texture.image; + + if ((isEquirectMap && image != null && image.height > 0) || + (isCubeMap && image != null && isCubeTextureComplete(image))) { + pmremGenerator ??= PMREMGenerator(renderer); + + renderTarget = isEquirectMap ? pmremGenerator!.fromEquirectangular(texture) : pmremGenerator!.fromCubemap(texture); + cubeUVmaps.set(texture, renderTarget); + + texture.addEventListener('dispose', onTextureDispose); + + return renderTarget.texture; + } + else { + // image not yet ready. try the conversion next frame + + return null; + } + } + } + } + } + + return texture; + } + + bool isCubeTextureComplete(image) { + int count = 0; + const length = 6; + + for (int i = 0; i < length; i++) { + if (image[i] != null) count++; + } + + return count == length; + } + + void onTextureDispose(event) { + final texture = event.target; + texture.removeEventListener('dispose', onTextureDispose); + + final cubemapUV = cubeUVmaps.get(texture); + + if (cubemapUV != null) { + cubeUVmaps.delete(texture); + cubemapUV.dispose(); + } + } + + void dispose() { + if(_didDispose) return; + _didDispose = true; + for(final key in cubeUVmaps.keys){ + cubeUVmaps[key].dispose(); + } + cubeUVmaps.clear(); + + //if (pmremGenerator != null) { + pmremGenerator?.dispose(); + pmremGenerator = null; + //} + + renderer.dispose(); + } +} diff --git a/packages/three_js_angle_renderer/lib/angle/angle_extensions.dart b/packages/three_js_angle_renderer/lib/angle/angle_extensions.dart new file mode 100755 index 00000000..7d20814c --- /dev/null +++ b/packages/three_js_angle_renderer/lib/angle/angle_extensions.dart @@ -0,0 +1,127 @@ +part of three_webgl; + +class AngleExtensions { + Map extensions = {}; + RenderingContext gl; + + AngleExtensions(this.gl); + + void dispose(){ + extensions.clear(); + } + + dynamic getExtension(String name) { + return _has(name); + } + + void init() { + getExtension( 'EXT_color_buffer_float' ); + getExtension( 'WEBGL_clip_cull_distance' ); + getExtension( 'OES_texture_float_linear' ); + getExtension( 'EXT_color_buffer_half_float' ); + getExtension( 'WEBGL_multisampled_render_to_texture' ); + getExtension( 'WEBGL_render_shared_exponent' ); + } + + dynamic _has(String name) { + if (kIsWeb) { + return hasForWeb(name); + } + else { + return hasForApp(name); + } + } + + bool has(String name) { + if (kIsWeb) { + return hasForWeb(name) != null; + } + else { + return hasForApp(name) != null; + } + } + + dynamic hasForWeb(String name) { + if (extensions[name] != null) { + return extensions[name]; + } + + dynamic extension; + + switch (name) { + case 'WEBGL_depth_texture': + extension = gl.getExtension('WEBGL_depth_texture') ?? + gl.getExtension('MOZ_WEBGL_depth_texture') ?? + gl.getExtension('WEBKIT_WEBGL_depth_texture'); + break; + + case 'EXT_texture_filter_anisotropic': + extension = gl.getExtension('EXT_texture_filter_anisotropic') ?? + gl.getExtension('MOZ_EXT_texture_filter_anisotropic') ?? + gl.getExtension('WEBKIT_EXT_texture_filter_anisotropic'); + break; + + case 'WEBGL_compressed_texture_s3tc': + extension = gl.getExtension('WEBGL_compressed_texture_s3tc') ?? + gl.getExtension('MOZ_WEBGL_compressed_texture_s3tc') ?? + gl.getExtension('WEBKIT_WEBGL_compressed_texture_s3tc'); + break; + + case 'WEBGL_compressed_texture_pvrtc': + extension = gl.getExtension('WEBGL_compressed_texture_pvrtc') ?? + gl.getExtension('WEBKIT_WEBGL_compressed_texture_pvrtc'); + break; + + default: + extension = gl.getExtension(name); + } + + extensions[name] = extension; + + return extension; + } + + dynamic hasForApp(name) { + if (extensions.keys.isEmpty) { + List ex = gl.getExtension(name) as List? ?? []; + extensions = {}; + for (String element in ex) { + extensions[element] = element; + } + } + + Map names = { + "EXT_color_buffer_float": "GL_EXT_color_buffer_float", + "EXT_texture_filter_anisotropic": "GL_EXT_texture_filter_anisotropic", + "EXT_color_buffer_half_float": "GL_EXT_color_buffer_half_float", + "GL_OES_texture_compression_astc": "GL_OES_texture_compression_astc", + "GL_KHR_texture_compression_astc_ldr": "GL_KHR_texture_compression_astc_ldr", + "GL_KHR_texture_compression_astc_hdr": "GL_KHR_texture_compression_astc_hdr", + "GL_KHR_texture_compression_astc_sliced_3d": "GL_KHR_texture_compression_astc_sliced_3d", + "GL_EXT_texture_compression_astc_decode_mode": "GL_EXT_texture_compression_astc_decode_mode", + "GL_EXT_texture_compression_astc_decode_mode_rgb9e5": "GL_EXT_texture_compression_astc_decode_mode_rgb9e5" + }; + + String n = names[name] ?? name; + + // print(" has for app : ${name} "); + // developer.log( extensions.keys.toList().toString() ); + + if (extensions.containsKey(n)) { + return extensions[n];//s.containsKey(n); + } + else { + return null; + } + } + + dynamic get(String name) { + dynamic extension = getExtension(name); + + if (extension == null) { + console.warning('WebGLExtensions.get: $name extension not supported.'); + } + + return extension; + } +} diff --git a/packages/three_js_angle_renderer/lib/angle/angle_geometries.dart b/packages/three_js_angle_renderer/lib/angle/angle_geometries.dart new file mode 100755 index 00000000..b71265c5 --- /dev/null +++ b/packages/three_js_angle_renderer/lib/angle/angle_geometries.dart @@ -0,0 +1,160 @@ +part of three_webgl; + +class AngleGeometries { + bool _didDispose = false; + RenderingContext gl; + AngleAttributes attributes; + AngleInfo info; + AngleBindingStates bindingStates; + + Map geometries = {}; + final wireframeAttributes = WeakMap(); + + AngleGeometries(this.gl, this.attributes, this.info, this.bindingStates); + + void onGeometryDispose(Event event) { + final geometry = event.target; + + if (geometry.index != null) { + attributes.remove(geometry.index); + } + + for (String name in geometry.attributes.keys) { + attributes.remove(geometry.attributes[name]); + } + + for (final name in geometry.morphAttributes.keys) { + final array = geometry.morphAttributes[ name ]; + + for (int i = 0, l = array.length; i < l; i ++ ) { + attributes.remove( array[ i ] ); + } + } + + geometry.removeEventListener('dispose', onGeometryDispose); + + geometries.remove(geometry.id); + + final attribute = wireframeAttributes.get(geometry); + + if (attribute != null) { + attributes.remove(attribute); + wireframeAttributes.delete(geometry); + } + + bindingStates.releaseStatesOfGeometry(geometry); + + if (geometry is InstancedBufferGeometry) { + // geometry.remove("maxInstanceCount"); + geometry.maxInstanceCount = null; + } + + // + + info.memory["geometries"] = info.memory["geometries"]! - 1; + } + + BufferGeometry get(BufferGeometry geometry) { + if (geometries[geometry.id] == true) return geometry; + + geometry.addEventListener('dispose', onGeometryDispose); + + geometries[geometry.id] = true; + + info.memory["geometries"] = info.memory["geometries"]! + 1; + + return geometry; + } + + void update(BufferGeometry geometry) { + final geometryAttributes = geometry.attributes; + + for (final name in geometryAttributes.keys) { + attributes.update(geometryAttributes[name], WebGL.ARRAY_BUFFER); + } + } + + void updateWireframeAttribute(BufferGeometry geometry) { + Uint32List indices = Uint32List(0); + + final geometryIndex = geometry.index; + final geometryPosition = geometry.attributes["position"]; + int version = 0; + + if (geometryIndex != null) { + final array = geometryIndex.array; + version = geometryIndex.version; + for (int i = 0, l = array.length; i < l; i += 3) { + final a = array[i + 0].toInt(); + final b = array[i + 1].toInt(); + final c = array[i + 2].toInt(); + + indices.addAll([a, b, b, c, c, a]); + } + } + else if( geometryPosition != null ){ + final array = geometryPosition.array; + version = geometryPosition.version; + + for (int i = 0, l = (array.length ~/ 3) - 1; i < l; i += 3) { + final a = i + 0; + final b = i + 1; + final c = i + 2; + + indices.addAll([a, b, b, c, c, a]); + } + } + else{ + return; + } + + BufferAttribute attribute; + final max = indices.getMaxValue(); + if (max != null && max > 65535) { + attribute = Uint32BufferAttribute.fromList(indices, 1); + } + else { + attribute = Uint16BufferAttribute.fromList(indices, 1); + } + + attribute.version = version; + + // Updating index buffer in VAO now. See WebGLBindingStates + + final previousAttribute = wireframeAttributes.get(geometry); + if (previousAttribute != null) attributes.remove(previousAttribute); + wireframeAttributes.set(geometry, attribute); + } + + BufferAttribute? getWireframeAttribute(BufferGeometry geometry) { + final currentAttribute = wireframeAttributes.get(geometry); + + if (currentAttribute != null) { + final geometryIndex = geometry.index; + if (geometryIndex != null) { + // if the attribute is obsolete, create a new one + if (currentAttribute.version < geometryIndex.version) { + updateWireframeAttribute(geometry); + } + } + } + else { + updateWireframeAttribute(geometry); + } + return wireframeAttributes.get(geometry); + } + + void dispose() { + if(_didDispose) return; + _didDispose = true; + for(final key in wireframeAttributes.keys){ + (wireframeAttributes[key] as BufferAttribute).dispose(); + } + + wireframeAttributes.clear(); + geometries.clear(); + attributes.dispose(); + info.dispose(); + bindingStates.dispose(); + } +} diff --git a/packages/three_js_angle_renderer/lib/angle/angle_indexed_buffer_renderer.dart b/packages/three_js_angle_renderer/lib/angle/angle_indexed_buffer_renderer.dart new file mode 100755 index 00000000..a0d8420b --- /dev/null +++ b/packages/three_js_angle_renderer/lib/angle/angle_indexed_buffer_renderer.dart @@ -0,0 +1,79 @@ +part of three_webgl; + +class AngleIndexedBufferRenderer extends BaseAngleBufferRenderer { + bool _didDispose = false; + dynamic mode; + dynamic type; + late int bytesPerElement; + RenderingContext gl; + AngleExtensions extensions; + AngleInfo info; + + AngleIndexedBufferRenderer(this.gl, this.extensions, this.info); + + void dispose(){ + if(_didDispose) return; + _didDispose = true; + extensions.dispose(); + info.dispose(); + } + + @override + void setMode(value) { + mode = value; + } + + @override + void setIndex(value) { + type = value["type"]; + bytesPerElement = value["bytesPerElement"]; + } + + @override + void render(int start, int count) { + gl.drawElements(mode, count, type, start * bytesPerElement); + info.update(count, mode, 1); + } + + @override + void renderInstances(int start, int count, int primcount) { + if (primcount == 0) return; + gl.drawElementsInstanced(mode, count, type, start * bytesPerElement, primcount); + info.update(count, mode, primcount); + } + + void renderMultiDraw(List starts,List counts,int drawCount ) { + if ( drawCount == 0 ) return; + final extension = extensions.get( 'WEBGL_multi_draw' ); + + extension.multiDrawElementsWEBGL( mode, counts, 0, type, starts, 0, drawCount ); + int elementCount = 0; + for ( int i = 0; i < drawCount; i ++ ) { + elementCount += counts[ i ]; + } + info.update( elementCount, mode, 1 ); + } + + void renderMultiDrawInstances(List starts,List counts,int drawCount,List primcount ) { + if ( drawCount == 0 ) return; + final extension = extensions.get( 'WEBGL_multi_draw' ); + + if ( extension == null ) { + for (int i = 0; i < starts.length; i ++ ) { + renderInstances( starts[ i ] ~/ bytesPerElement, counts[ i ], primcount[ i ] ); + } + } + else { + extension.multiDrawElementsInstancedWEBGL( mode, counts, 0, type, starts, 0, primcount, 0, drawCount ); + + int elementCount = 0; + for (int i = 0; i < drawCount; i ++ ) { + elementCount += counts[ i ]; + } + + for (int i = 0; i < primcount.length; i ++ ) { + info.update( elementCount, mode, primcount[ i ] ); + } + } + } +} diff --git a/packages/three_js_angle_renderer/lib/angle/angle_info.dart b/packages/three_js_angle_renderer/lib/angle/angle_info.dart new file mode 100755 index 00000000..a5c013c7 --- /dev/null +++ b/packages/three_js_angle_renderer/lib/angle/angle_info.dart @@ -0,0 +1,51 @@ +part of three_webgl; + +class AngleInfo { + RenderingContext gl; + + Map memory = { + "geometries": 0, + "textures": 0 + }; + + Map render = { + "frame": 0.0, + "calls": 0.0, + "triangles": 0.0, + "points": 0.0, + "lines": 0.0 + }; + + dynamic programs; + bool autoReset = true; + + AngleInfo(this.gl); + + void update(count, mode, instanceCount) { + render["calls"] = render["calls"]! + 1; + + if (mode == WebGL.TRIANGLES) { + render["triangles"] = render["triangles"]! + instanceCount * (count / 3.0); + } else if (mode == WebGL.LINES) { + render["lines"] = render["lines"]! + instanceCount * (count / 2); + } else if (mode == WebGL.LINE_STRIP) { + render["lines"] = render["lines"]! + instanceCount * (count - 1); + } else if (mode == WebGL.LINE_LOOP) { + render["lines"] = render["lines"]! + instanceCount * count; + } else if (mode == WebGL.POINTS) { + render["points"] = render["points"]! + instanceCount * count; + } else { + console.warning('three.WebGLInfo: Unknown draw mode: $mode '); + } + } + + void reset() { + render["frame"] = render["frame"]! + 1; + render["calls"] = 0; + render["triangles"] = 0; + render["points"] = 0; + render["lines"] = 0; + } + + void dispose(){} +} diff --git a/packages/three_js_angle_renderer/lib/angle/angle_lights.dart b/packages/three_js_angle_renderer/lib/angle/angle_lights.dart new file mode 100755 index 00000000..3240b303 --- /dev/null +++ b/packages/three_js_angle_renderer/lib/angle/angle_lights.dart @@ -0,0 +1,586 @@ +part of three_webgl; + +class UniformsCache { + UniformsCache(); + + Map> lights = {}; + + void dispose(){ + lights.clear(); + } + + Map get(light) { + if (lights[light.id] != null) { + return lights[light.id]!; + } + + Map? uniforms; + + switch (light.type) { + case 'DirectionalLight': + uniforms = {"direction": Vector3.zero(), "color": Color(0, 0, 0)}; + break; + + case 'SpotLight': + uniforms = { + "position": Vector3.zero(), + "direction": Vector3.zero(), + "color": Color(0, 0, 0), + "distance": 0, + "coneCos": 0, + "penumbraCos": 0, + "decay": 0 + }; + break; + + case 'PointLight': + uniforms = {"position": Vector3.zero(), "color": Color(1, 1, 1), "distance": 0, "decay": 0}; + break; + + case 'HemisphereLight': + uniforms = {"direction": Vector3.zero(), "skyColor": Color(0, 0, 0), "groundColor": Color(0, 0, 0)}; + break; + + case 'RectAreaLight': + uniforms = { + "color": Color(0, 0, 0), + "position": Vector3.zero(), + "halfWidth": Vector3.zero(), + "halfHeight": Vector3.zero() + }; + break; + } + + lights[light.id] = uniforms!; + + return uniforms; + } +} + +class ShadowUniformsCache { + Map> lights = {}; + + void dispose(){ + lights.clear(); + } + + Map? get(light) { + if (lights[light.id] != null) { + return lights[light.id]; + } + + Map uniforms = {}; + + switch (light.type) { + case 'DirectionalLight': + uniforms = { + "shadowIntensity": 1, + "shadowBias": 0, + "shadowNormalBias": 0, + "shadowRadius": 1, + "shadowMapSize": Vector2.zero() + }; + break; + + case 'SpotLight': + uniforms = { + 'shadowIntensity': 1, + "shadowBias": 0, + "shadowNormalBias": 0, + "shadowRadius": 1, + "shadowMapSize": Vector2.zero() + }; + break; + + case 'PointLight': + uniforms = { + 'shadowIntensity': 1, + "shadowBias": 0, + "shadowNormalBias": 0, + "shadowRadius": 1, + "shadowMapSize": Vector2.zero(), + "shadowCameraNear": 1, + "shadowCameraFar": 1000 + }; + break; + + // TODO (abelnation): set RectAreaLight shadow uniforms + + } + + lights[light.id] = uniforms; + + return uniforms; + } +} + +int nextVersion = 0; + +int shadowCastingAndTexturingLightsFirst(Light lightA, Light lightB) { + return ( lightB.castShadow ? 2 : 0 ) - ( lightA.castShadow ? 2 : 0 ) + ( lightB.map != null? 1 : 0 ) - ( lightA.map != null? 1 : 0 ); +} + +class AngleLights { + late LightState state; + late UniformsCache cache; + late ShadowUniformsCache shadowCache; + late Vector3 vector3; + late Matrix4 matrix4; + late Matrix4 matrix42; + AngleExtensions extensions; + + AngleLights(this.extensions) { + cache = UniformsCache(); + shadowCache = ShadowUniformsCache(); + + state = LightState({ + "version": 0, + "hash": { + "directionalLength": -1, + "pointLength": -1, + "spotLength": -1, + "rectAreaLength": -1, + "hemiLength": -1, + + "numDirectionalShadows": -1, + "numPointShadows": -1, + "numSpotShadows": -1, + 'numSpotMaps': - 1, + + 'numLightProbes': - 1 + }, + "ambient": List.from([0.0, 0.0, 0.0]), + "probe": [], + "directional": [], + "directionalShadow": [], + "directionalShadowMap": [], + "directionalShadowMatrix": [], + "spot": [], + 'spotLightMap': [], + "spotShadow": [], + "spotShadowMap": [], + "spotShadowMatrix": [], + 'spotLightMatrix': [], + "rectArea": [], + "rectAreaLTC1": null, + "rectAreaLTC2": null, + "point": [], + "pointShadow": [], + "pointShadowMap": [], + "pointShadowMatrix": [], + "hemi": [], + 'numSpotLightShadowsWithMaps': 0, + 'numLightProbes': 0 + }); + + for (int i = 0; i < 9; i++) { + state.probe.add(Vector3.zero()); + } + + vector3 = Vector3.zero(); + matrix4 = Matrix4.identity(); + matrix42 = Matrix4.identity(); + } + + void setup(List lights, [bool? physicallyCorrectLights]) { + double r = 0.0; + double g = 0.0; + double b = 0.0; + + for (int i = 0; i < 9; i++) { + state.probe[i].setValues(0, 0, 0); + } + + int directionalLength = 0; + int pointLength = 0; + int spotLength = 0; + int rectAreaLength = 0; + int hemiLength = 0; + + int numDirectionalShadows = 0; + int numPointShadows = 0; + int numSpotShadows = 0; + int numSpotMaps = 0; + int numSpotShadowsWithMaps = 0; + int numLightProbes = 0; + + lights.sort((a, b) => shadowCastingAndTexturingLightsFirst(a, b)); + + // artist-friendly light intensity scaling factor + double scaleFactor = (physicallyCorrectLights != true) ? math.pi : 1.0; + + for (int i = 0, l = lights.length; i < l; i++) { + final light = lights[i]; + + final color = light.color ?? Color(); + final intensity = light.intensity; + final distance = light.distance; + + final shadowMap = (light.shadow != null && light.shadow!.map != null) ? light.shadow!.map!.texture : null; + + if (light is AmbientLight) { + r += color.red * intensity; + g += color.green * intensity; + b += color.blue * intensity; + } + else if (light is LightProbe) { + for (int j = 0; j < 9; j++) { + state.probe[j].addScaled(light.sh!.coefficients[j], intensity); + } + } + else if (light is DirectionalLight) { + final uniforms = cache.get(light); + + (uniforms["color"] as Color)..setFrom(light.color!)..scale(light.intensity * scaleFactor); + + if (light.castShadow) { + final shadow = light.shadow!; + + final shadowUniforms = shadowCache.get(light); + + shadowUniforms?["shadowIntensity"] = shadow.intensity; + shadowUniforms?["shadowBias"] = shadow.bias; + shadowUniforms?["shadowNormalBias"] = shadow.normalBias; + shadowUniforms?["shadowRadius"] = shadow.radius; + shadowUniforms?["shadowMapSize"] = shadow.mapSize; + + state.directionalShadow.listSetter(directionalLength, shadowUniforms); + state.directionalShadowMap.listSetter(directionalLength, shadowMap); + state.directionalShadowMatrix.listSetter( directionalLength, light.shadow!.matrix); + + numDirectionalShadows++; + } + + state.directional.listSetter(directionalLength, uniforms); + + directionalLength++; + } + else if (light is SpotLight) { + final uniforms = cache.get(light); + + (uniforms["position"] as Vector3).setFromMatrixPosition(light.matrixWorld); + (uniforms["color"] as Color)..setFrom(color)..scale(intensity * scaleFactor); + + uniforms["distance"] = distance; + + uniforms["coneCos"] = math.cos(light.angle!); + uniforms["penumbraCos"] = math.cos(light.angle! * (1 - light.penumbra!)); + uniforms["decay"] = light.decay; + + state.spot.listSetter(spotLength, uniforms); + final shadow = light.shadow!; + + if ( light.map != null) { + state.spotLightMap.listSetter(numSpotMaps, light.map); + numSpotMaps ++; + + // make sure the lightMatrix is up to date + // TODO : do it if required only + shadow.updateMatrices( light ); + if (light.castShadow) numSpotShadowsWithMaps ++; + } + + state.spotLightMatrix.add(shadow.matrix); + + if (light.castShadow) { + final shadowUniforms = shadowCache.get(light); + + shadowUniforms?['shadowIntensity'] = shadow.intensity; + shadowUniforms?["shadowBias"] = shadow.bias; + shadowUniforms?["shadowNormalBias"] = shadow.normalBias; + shadowUniforms?["shadowRadius"] = shadow.radius; + shadowUniforms?["shadowMapSize"] = shadow.mapSize; + + state.spotShadow.listSetter(spotLength, shadowUniforms); + state.spotShadowMap.listSetter(spotLength, shadowMap); + state.spotShadowMatrix.listSetter( spotLength, light.shadow!.matrix); + + numSpotShadows++; + } + + spotLength++; + } + else if (light is RectAreaLight) { + final uniforms = cache.get(light); + + // (a) intensity is the total visible light emitted + //uniforms.color.copy( color ).scale( intensity / ( light.width * light.height * math.PI ) ); + + // (b) intensity is the brightness of the light + uniforms["color"]..setFrom(color)..scale(intensity); + + uniforms["halfWidth"].setValues(light.width! * 0.5, 0.0, 0.0); + uniforms["halfHeight"].setValues(0.0, light.height! * 0.5, 0.0); + + // state.rectArea[ rectAreaLength ] = uniforms; + state.rectArea.listSetter(rectAreaLength, uniforms); + + rectAreaLength++; + } + else if (light is PointLight) { + final uniforms = cache.get(light); + + (uniforms["color"] as Color)..setFrom(light.color!)..scale(light.intensity * scaleFactor); + uniforms["distance"] = light.distance ?? 0; + uniforms["decay"] = light.decay; + + if (light.castShadow) { + final shadow = light.shadow!; + + final shadowUniforms = shadowCache.get(light); + + shadowUniforms?['shadowIntensity'] = shadow.intensity; + shadowUniforms?["shadowBias"] = shadow.bias; + shadowUniforms?["shadowNormalBias"] = shadow.normalBias; + shadowUniforms?["shadowRadius"] = shadow.radius; + shadowUniforms?["shadowMapSize"] = shadow.mapSize; + shadowUniforms?["shadowCameraNear"] = shadow.camera!.near; + shadowUniforms?["shadowCameraFar"] = shadow.camera!.far; + + state.pointShadow.listSetter(pointLength, shadowUniforms); + state.pointShadowMap.listSetter(pointLength, shadowMap); + state.pointShadowMatrix.listSetter(pointLength, light.shadow!.matrix); + + numPointShadows++; + } + + // state.point[ pointLength ] = uniforms; + state.point.listSetter(pointLength, uniforms); + + pointLength++; + } + else if (light is HemisphereLight) { + final uniforms = cache.get(light); + + uniforms["skyColor"]..setFrom(light.color)..scale(intensity * scaleFactor); + uniforms["groundColor"]..setFrom(light.groundColor)..scale(intensity * scaleFactor); + + // state.hemi[ hemiLength ] = uniforms; + state.hemi.listSetter(hemiLength, uniforms); + + hemiLength++; + } + else { + throw (" WebGLLigts type: ${light.type} is not support ..... "); + } + } + + if (rectAreaLength > 0) { + if ( extensions.has( 'OES_texture_float_linear' ) == true ) { + state.rectAreaLTC1 = uniformsLib["LTC_FLOAT_1"]; + state.rectAreaLTC2 = uniformsLib["LTC_FLOAT_2"]; + } + else{ + state.rectAreaLTC1 = uniformsLib["LTC_HALF_1"]; + state.rectAreaLTC2 = uniformsLib["LTC_HALF_2"]; + } + } + + state.ambient[0] = r.toDouble(); + state.ambient[1] = g.toDouble(); + state.ambient[2] = b.toDouble(); + + final hash = state.hash; + + if (hash["directionalLength"] != directionalLength || + hash["pointLength"] != pointLength || + hash["spotLength"] != spotLength || + hash["rectAreaLength"] != rectAreaLength || + hash["hemiLength"] != hemiLength || + hash["numDirectionalShadows"] != numDirectionalShadows || + hash["numPointShadows"] != numPointShadows || + hash["numSpotShadows"] != numSpotShadows || + hash['numSpotMaps'] != numSpotMaps || + hash['numLightProbes'] != numLightProbes ) { + + state.directional.length = directionalLength; + state.spot.length = spotLength; + state.rectArea.length = rectAreaLength; + state.point.length = pointLength; + state.hemi.length = hemiLength; + + state.directionalShadow.length = numDirectionalShadows; + state.directionalShadowMap.length = numDirectionalShadows; + state.pointShadow.length = numPointShadows; + state.pointShadowMap.length = numPointShadows; + state.spotShadow.length = numSpotShadows; + state.spotShadowMap.length = numSpotShadows; + state.directionalShadowMatrix.length = numDirectionalShadows; + state.pointShadowMatrix.length = numPointShadows; + state.spotLightMatrix.length = numSpotShadows + numSpotMaps - numSpotShadowsWithMaps; + state.spotLightMap.length = numSpotMaps; + state.numSpotLightShadowsWithMaps = numSpotShadowsWithMaps; + state.numLightProbes = numLightProbes; + + hash["directionalLength"] = directionalLength; + hash["pointLength"] = pointLength; + hash["spotLength"] = spotLength; + hash["rectAreaLength"] = rectAreaLength; + hash["hemiLength"] = hemiLength; + + hash["numDirectionalShadows"] = numDirectionalShadows; + hash["numPointShadows"] = numPointShadows; + hash["numSpotShadows"] = numSpotShadows; + + hash['numSpotMaps'] = numSpotMaps; + hash['numLightProbes'] = numLightProbes; + + state.version = nextVersion++; + } + } + + void setupView(List lights, Camera camera) { + int directionalLength = 0; + int pointLength = 0; + int spotLength = 0; + int rectAreaLength = 0; + int hemiLength = 0; + + final viewMatrix = camera.matrixWorldInverse; + + for (int i = 0, l = lights.length; i < l; i++) { + final light = lights[i]; + + if (light is DirectionalLight) { + final uniforms = state.directional[directionalLength]; + + uniforms["direction"].setFromMatrixPosition(light.matrixWorld); + vector3.setFromMatrixPosition(light.target!.matrixWorld); + uniforms["direction"].sub(vector3); + uniforms["direction"].transformDirection(viewMatrix); + + directionalLength++; + } + else if (light is SpotLight) { + final uniforms = state.spot[spotLength]; + + uniforms["position"].setFromMatrixPosition(light.matrixWorld); + uniforms["position"].applyMatrix4(viewMatrix); + + uniforms["direction"].setFromMatrixPosition(light.matrixWorld); + vector3.setFromMatrixPosition(light.target!.matrixWorld); + uniforms["direction"].sub(vector3); + uniforms["direction"].transformDirection(viewMatrix); + + spotLength++; + } + else if (light is RectAreaLight) { + final uniforms = state.rectArea[rectAreaLength]; + + uniforms["position"].setFromMatrixPosition(light.matrixWorld); + uniforms["position"].applyMatrix4(viewMatrix); + + // extract local rotation of light to derive width/height half vectors + matrix42.setFrom(Matrix4.identity()); + matrix4.setFrom(light.matrixWorld); + matrix4.multiply(viewMatrix); + matrix42.extractRotation(matrix4); + + uniforms["halfWidth"].setValues(light.width! * 0.5, 0.0, 0.0); + uniforms["halfHeight"].setValues(0.0, light.height! * 0.5, 0.0); + + uniforms["halfWidth"].applyMatrix4(matrix42); + uniforms["halfHeight"].applyMatrix4(matrix42); + + rectAreaLength++; + } + else if (light is PointLight) { + final uniforms = state.point[pointLength]; + + (uniforms["position"] as Vector3).setFromMatrixPosition(light.matrixWorld); + uniforms["position"].applyMatrix4(viewMatrix); + + pointLength++; + } + else if (light is HemisphereLight) { + final uniforms = state.hemi[hemiLength]; + + uniforms["direction"].setFromMatrixPosition(light.matrixWorld); + uniforms["direction"].transformDirection(viewMatrix); + + hemiLength++; + } + } + } + + void dispose(){ + state.dispose(); + cache.dispose(); + shadowCache.dispose(); + extensions.dispose(); + } +} + +class LightState { + late num version; + late Map hash; + late List ambient; + late List probe; + late List directional; + late List directionalShadow; + late List directionalShadowMap; + late List directionalShadowMatrix; + late List spot; + late List spotLightMap; + late List spotShadow; + late List spotShadowMap; + late List spotShadowMatrix; + late List spotLightMatrix; + late List rectArea; + late List point; + late List pointShadow; + late List pointShadowMap; + late List pointShadowMatrix; + late List hemi; + late int numLightProbes; + late int numSpotLightShadowsWithMaps; + + dynamic rectAreaLTC1; + dynamic rectAreaLTC2; + + LightState(Map json) { + version = json["version"]; + hash = json["hash"]; + ambient = List.from(json["ambient"]); + probe = List.from(json["probe"]); + directional = json["directional"]; + directionalShadow = json["directionalShadow"]; + directionalShadowMap = json["directionalShadowMap"]; + directionalShadowMatrix = json["directionalShadowMatrix"]; + spot = json["spot"]; + spotLightMap = json['spotLightMap']; + spotShadow = json["spotShadow"]; + spotShadowMap = json["spotShadowMap"]; + spotShadowMatrix = json["spotShadowMatrix"]; + spotLightMatrix = json["spotLightMatrix"]; + rectArea = json["rectArea"]; + point = json["point"]; + pointShadow = json["pointShadow"]; + pointShadowMap = json["pointShadowMap"]; + pointShadowMatrix = json["pointShadowMatrix"]; + hemi = json["hemi"]; + + numSpotLightShadowsWithMaps = json['numSpotLightShadowsWithMaps']; + numLightProbes = json['numLightProbes']; + } + + void dispose(){ + hash.clear(); + ambient.clear(); + probe.clear(); + directional.clear(); + directionalShadow.clear(); + directionalShadowMap.clear(); + directionalShadowMatrix.clear(); + spot.clear(); + spotShadow.clear(); + spotShadowMap.clear(); + spotShadowMatrix.clear(); + rectArea.clear(); + point.clear(); + pointShadow.clear(); + pointShadowMap.clear(); + pointShadowMatrix.clear(); + hemi.clear(); + } +} \ No newline at end of file diff --git a/packages/three_js_angle_renderer/lib/angle/angle_materials.dart b/packages/three_js_angle_renderer/lib/angle/angle_materials.dart new file mode 100755 index 00000000..d59fe344 --- /dev/null +++ b/packages/three_js_angle_renderer/lib/angle/angle_materials.dart @@ -0,0 +1,386 @@ +part of three_webgl; + +class AngleMaterials { + bool _didDispose = false; + AngleRenderer renderer; + AngleProperties properties; + + AngleMaterials(this.renderer, this.properties); + + void dispose(){ + if(_didDispose) return; + _didDispose = true; + properties.dispose(); + } + + void refreshTransformUniform(Texture? map, Map? uniform ) { + if(map == null) return; + if ( map.matrixAutoUpdate == true) { + map.updateMatrix(); + } + uniform?['value']?.setFrom( map.matrix ); + } + + void refreshFogUniforms(Map uniforms, FogBase fog) { + uniforms["fogColor"]["value"].setFrom(fog.color); + + if (fog.isFog) { + uniforms["fogNear"]["value"] = fog.near; + uniforms["fogFar"]["value"] = fog.far; + } + else if (fog.isFogExp2) { + uniforms["fogDensity"]["value"] = fog.density; + } + } + + void refreshMaterialUniforms(Map uniforms, Material material, double pixelRatio, double height, RenderTarget? transmissionRenderTarget) { + if (material is MeshBasicMaterial) { + refreshUniformsCommon(uniforms, material); + } else if (material is MeshLambertMaterial) { + refreshUniformsCommon(uniforms, material); + } else if (material is MeshToonMaterial) { + refreshUniformsCommon(uniforms, material); + refreshUniformsToon(uniforms, material); + } else if (material is MeshPhongMaterial) { + refreshUniformsCommon(uniforms, material); + refreshUniformsPhong(uniforms, material); + } else if (material is MeshPhysicalMaterial) { + refreshUniformsCommon(uniforms, material); + refreshUniformsStandard(uniforms, material); + refreshUniformsPhysical(uniforms, material, transmissionRenderTarget); + } else if (material is MeshStandardMaterial) { + refreshUniformsCommon(uniforms, material); + refreshUniformsStandard(uniforms, material); + if ( material is MeshPhysicalMaterial ) { + refreshUniformsPhysical( uniforms, material, transmissionRenderTarget ); + } + } else if (material is MeshMatcapMaterial) { + refreshUniformsCommon(uniforms, material); + refreshUniformsMatcap(uniforms, material); + } else if (material is MeshDepthMaterial) { + refreshUniformsCommon(uniforms, material); + } else if (material is MeshDistanceMaterial) { + refreshUniformsCommon(uniforms, material); + refreshUniformsDistance(uniforms, material); + } else if (material is MeshNormalMaterial) { + refreshUniformsCommon(uniforms, material); + } else if (material is LineBasicMaterial) { + refreshUniformsLine(uniforms, material); + }else if (material is LineDashedMaterial) { + refreshUniformsLine(uniforms, material); + refreshUniformsDash(uniforms, material); + }else if (material is PointsMaterial) { + refreshUniformsPoints(uniforms, material, pixelRatio, height); + } else if (material is SpriteMaterial) { + refreshUniformsSprites(uniforms, material); + } else if (material is ShadowMaterial) { + uniforms["color"]["value"].setFrom(material.color); + uniforms["opacity"]["value"] = material.opacity; + } else if (material is ShaderMaterial) { + material.uniformsNeedUpdate = false; // #15581 + } + } + + void refreshUniformsCommon(Map uniforms, Material material) { + uniforms["opacity"]["value"] = material.opacity; + + uniforms["diffuse"]["value"].setFrom(material.color); + + if (material.emissive != null) { + uniforms["emissive"]["value"].setFrom(material.emissive)?.scale(material.emissiveIntensity); + } + + if (material.map != null) { + uniforms["map"]["value"] = material.map; + refreshTransformUniform( material.map, uniforms['mapTransform'] ); + } + + if (material.alphaMap != null) { + uniforms["alphaMap"]["value"] = material.alphaMap; + refreshTransformUniform( material.alphaMap!, uniforms['alphaMapTransform'] ); + } + + if (material.bumpMap != null) { + uniforms["bumpMap"]["value"] = material.bumpMap; + refreshTransformUniform( material.bumpMap!, uniforms['bumpMapTransform'] ); + uniforms["bumpScale"]["value"] = material.bumpScale; + if (material.side == BackSide) uniforms["bumpScale"]["value"] *= -1; + } + + if (material.displacementMap != null) { + uniforms["displacementMap"]["value"] = material.displacementMap; + refreshTransformUniform( material.displacementMap!, uniforms['displacementMapTransform'] ); + uniforms["displacementScale"]["value"] = material.displacementScale; + uniforms["displacementBias"]["value"] = material.displacementBias; + } + + if (material.emissiveMap != null) { + uniforms["emissiveMap"]["value"] = material.emissiveMap; + refreshTransformUniform( material.emissiveMap!, uniforms['emissiveMapTransform'] ); + } + + if (material.normalMap != null) { + uniforms["normalMap"]["value"] = material.normalMap; + refreshTransformUniform( material.normalMap!, uniforms['normalMapTransform'] ); + uniforms["normalScale"]["value"].setFrom(material.normalScale); + if (material.side == BackSide) uniforms["normalScale"]["value"].negate(); + } + + if (material.specularMap != null) { + uniforms["specularMap"]["value"] = material.specularMap; + refreshTransformUniform( material.specularMap!, uniforms['specularMapTransform'] ); + } + + if (material.alphaTest > 0) { + uniforms["alphaTest"]["value"] = material.alphaTest; + } + + final materialProperties = properties.get( material ); + + final envMap = materialProperties['envMap']; + final envMapRotation = materialProperties['envMapRotation'] ?? Euler(); + + if (envMap != null) { + uniforms["envMap"]["value"] = envMap; + _e1.copy( envMapRotation ); + + // accommodate left-handed frame + _e1.x *= - 1; _e1.y *= - 1; _e1.z *= - 1; + + if ( envMap is CubeTexture && envMap is! Angle3DRenderTarget) { + // environment maps which are not cube render targets or PMREMs follow a different convention + _e1.y *= - 1; + _e1.z *= - 1; + } + + uniforms['envMapRotation']?['value'].setFromMatrix4( _m1.makeRotationFromEuler( _e1 ) ); + + uniforms["flipEnvMap"]?["value"] = (envMap is CubeTexture && envMap is! Angle3DRenderTarget) ? -1 : 1; + uniforms["reflectivity"]["value"] = material.reflectivity; + uniforms["ior"]["value"] = material.ior; + uniforms["refractionRatio"]["value"] = material.refractionRatio; + } + + if (material.lightMap != null) { + uniforms["lightMap"]["value"] = material.lightMap; + uniforms["lightMapIntensity"]["value"] = material.lightMapIntensity!; + refreshTransformUniform( material.lightMap!, uniforms['lightMapTransform'] ); + } + + if (material.aoMap != null) { + uniforms["aoMap"]["value"] = material.aoMap; + uniforms["aoMapIntensity"]["value"] = material.aoMapIntensity; + refreshTransformUniform( material.aoMap!, uniforms['aoMapTransform'] ); + } + } + + void refreshUniformsLine(Map uniforms, Material material) { + uniforms["diffuse"]["value"].setFrom(material.color); + uniforms["opacity"]["value"] = material.opacity; + + if (material.map != null) { + uniforms['map']['value'] = material.map; + refreshTransformUniform( material.map, uniforms['mapTransform'] ); + } + } + + void refreshUniformsDash(Map uniforms, Material material) { + uniforms["dashSize"]["value"] = material.dashSize; + uniforms["totalSize"]["value"] = (material.dashSize ?? 0) + (material.gapSize ?? 0); + uniforms["scale"]["value"] = material.scale; + } + + void refreshUniformsPoints(Map uniforms, Material material, double pixelRatio, double height) { + uniforms["diffuse"]["value"].setFrom(material.color); + uniforms["opacity"]["value"] = material.opacity; + uniforms["size"]["value"] = material.size! * pixelRatio; + uniforms["scale"]["value"] = height * 0.5; + + if (material.map != null) { + uniforms["map"]["value"] = material.map; + refreshTransformUniform( material.map, uniforms['uvTransform'] ); + } + + if (material.alphaMap != null) { + uniforms["alphaMap"]["value"] = material.alphaMap; + refreshTransformUniform( material.alphaMap!, uniforms['alphaMapTransform'] ); + } + + if (material.alphaTest > 0) { + uniforms["alphaTest"]["value"] = material.alphaTest; + } + } + + void refreshUniformsSprites(Map uniforms, Material material) { + uniforms["diffuse"]["value"].setFrom(material.color); + uniforms["opacity"]["value"] = material.opacity; + uniforms["rotation"]["value"] = material.rotation; + + if (material.map != null) { + uniforms["map"]["value"] = material.map; + refreshTransformUniform( material.map, uniforms['mapTransform'] ); + } + + if (material.alphaMap != null) { + uniforms["alphaMap"]["value"] = material.alphaMap; + refreshTransformUniform( material.alphaMap!, uniforms['alphaMapTransform'] ); + } + + if (material.alphaTest > 0) { + uniforms["alphaTest"]["value"] = material.alphaTest; + } + } + + void refreshUniformsPhong(Map uniforms, Material material) { + uniforms["specular"]["value"].setFrom(material.specular); + uniforms["shininess"]["value"] = math.max(material.shininess!, 1e-4); // to prevent pow( 0.0, 0.0 ) + } + + void refreshUniformsToon(Map uniforms, Material material) { + if (material.gradientMap != null) { + uniforms["gradientMap"]["value"] = material.gradientMap; + } + } + + void refreshUniformsStandard(Map uniforms, Material material) { + uniforms["metalness"]["value"] = material.metalness; + if (material.metalnessMap != null) { + uniforms["metalnessMap"]["value"] = material.metalnessMap; + refreshTransformUniform( material.metalnessMap, uniforms['metalnessMapTransform'] ); + } + + uniforms["roughness"]["value"] = material.roughness; + if (material.roughnessMap != null) { + uniforms["roughnessMap"]["value"] = material.roughnessMap; + refreshTransformUniform( material.roughnessMap, uniforms['roughnessMapTransform'] ); + } + + if (material.envMap != null) { + //uniforms.envMap.value = material.envMap; // part of uniforms common + uniforms["envMapIntensity"]["value"] = material.envMapIntensity; + } + } + + void refreshUniformsPhysical(Map uniforms,Material material, RenderTarget? transmissionRenderTarget) { + uniforms["ior"]["value"] = material.ior; // also part of uniforms common + + if (material.sheen > 0) { + uniforms["sheenColor"]["value"].setFrom(material.sheenColor).multiplyScalar( material.sheen ); + + uniforms["sheenRoughness"]["value"] = material.sheenRoughness; + + if (material.sheenColorMap != null) { + uniforms["sheenColorMap"]["value"] = material.sheenColorMap; + refreshTransformUniform( material.sheenColorMap!, uniforms['sheenColorMapTransform'] ); + } + + if (material.sheenRoughnessMap != null) { + uniforms["sheenRoughnessMap"]["value"] = material.sheenRoughnessMap; + refreshTransformUniform( material.sheenRoughnessMap!, uniforms['sheenRoughnessMapTransform'] ); + } + } + + if (material.clearcoat > 0) { + uniforms["clearcoat"]["value"] = material.clearcoat; + uniforms["clearcoatRoughness"]["value"] = material.clearcoatRoughness; + + if (material.clearcoatMap != null) { + uniforms["clearcoatMap"]["value"] = material.clearcoatMap; + refreshTransformUniform( material.clearcoatMap!, uniforms['clearcoatMapTransform'] ); + } + + if (material.clearcoatRoughnessMap != null) { + uniforms["clearcoatRoughnessMap"]["value"] = material.clearcoatRoughnessMap; + refreshTransformUniform( material.clearcoatRoughnessMap!, uniforms['clearcoatRoughnessMapTransform'] ); + } + + if (material.clearcoatNormalMap != null) { + uniforms["clearcoatNormalMap"]["value"] = material.clearcoatNormalMap; + refreshTransformUniform( material.clearcoatNormalMap!, uniforms['clearcoatNormalMapTransform'] ); + uniforms["clearcoatNormalScale"]["value"].setFrom(material.clearcoatNormalScale); + if (material.side == BackSide) { + uniforms["clearcoatNormalScale"]["value"].negate(); + } + } + } + + if (material is MeshPhysicalMaterial && material.dispersion > 0 ) { + uniforms['dispersion']['value'] = material.dispersion; + } + + if (material is MeshPhysicalMaterial && material.iridescence > 0 ) { + uniforms['iridescence']['value'] = material.iridescence; + uniforms['iridescenceIOR']['value'] = material.iridescenceIOR; + uniforms['iridescenceThicknessMinimum']['value'] = material.iridescenceThicknessRange[ 0 ]; + uniforms['iridescenceThicknessMaximum']['value'] = material.iridescenceThicknessRange[ 1 ]; + + if ( material.iridescenceMap != null) { + uniforms['iridescenceMap']['value'] = material.iridescenceMap; + refreshTransformUniform( material.iridescenceMap!, uniforms['iridescenceMapTransform'] ); + } + + if ( material.iridescenceThicknessMap != null) { + uniforms['iridescenceThicknessMap']['value'] = material.iridescenceThicknessMap; + refreshTransformUniform( material.iridescenceThicknessMap!, uniforms['iridescenceThicknessMapTransform'] ); + } + } + + if (material.transmission > 0) { + uniforms["transmission"]["value"] = material.transmission; + uniforms["transmissionSamplerMap"]["value"] = transmissionRenderTarget?.texture; + uniforms["transmissionSamplerSize"]["value"].setValues(transmissionRenderTarget?.width.toDouble() ?? 0.0, transmissionRenderTarget?.height.toDouble() ?? 0.0); + + if (material.transmissionMap != null) { + uniforms["transmissionMap"]["value"] = material.transmissionMap; + refreshTransformUniform( material.transmissionMap, uniforms['transmissionMapTransform'] ); + } + + uniforms["thickness"]["value"] = material.thickness; + + if (material.thicknessMap != null) { + uniforms["thicknessMap"]["value"] = material.thicknessMap; + refreshTransformUniform( material.thicknessMap!, uniforms['thicknessMapTransform'] ); + } + + uniforms["attenuationDistance"]["value"] = material.attenuationDistance; + uniforms["attenuationColor"]["value"].setFrom(material.attenuationColor); + } + + if (material is MeshPhysicalMaterial && material.anisotropy > 0 ) { + uniforms['anisotropyVector']['value'].setValues( material.anisotropy * math.cos( material.anisotropyRotation ), material.anisotropy * math.sin( material.anisotropyRotation ) ); + if ( material.anisotropyMap != null) { + uniforms['anisotropyMap']['value'] = material.anisotropyMap; + refreshTransformUniform( material.anisotropyMap!, uniforms['anisotropyMapTransform'] ); + } + } + + uniforms["specularIntensity"]["value"] = material.specularIntensity; + uniforms["attenuationColor"]["value"].setFrom(material.attenuationColor); + if (material.specularColorMap != null) { + uniforms["specularColorMap"]["value"] = material.specularColorMap; + refreshTransformUniform( material.specularColorMap!, uniforms['specularColorMapTransform'] ); + } + if (material.specularIntensityMap != null) { + uniforms["specularIntensityMap"]["value"] = material.specularIntensityMap; + refreshTransformUniform( material.specularIntensityMap!, uniforms['specularIntensityMapTransform'] ); + } + } + + void refreshUniformsMatcap(Map uniforms, Material material) { + if (material.matcap != null) { + uniforms["matcap"]["value"] = material.matcap; + } + } + + void refreshUniformsDistance(Map uniforms, MeshDistanceMaterial material) { + final light = properties.get( material )['light']; + + uniforms['referencePosition']['value'].setFromMatrixPosition( light.matrixWorld ); + uniforms['nearDistance']['value'] = light.shadow.camera.near; + uniforms['farDistance']['value'] = light.shadow.camera.far; + + // uniforms["referencePosition"]["value"].setFrom(material.referencePosition); + // uniforms["nearDistance"]["value"] = material.nearDistance; + // uniforms["farDistance"]["value"] = material.farDistance; + } +} diff --git a/packages/three_js_angle_renderer/lib/angle/angle_morphtargets.dart b/packages/three_js_angle_renderer/lib/angle/angle_morphtargets.dart new file mode 100755 index 00000000..9483bbc1 --- /dev/null +++ b/packages/three_js_angle_renderer/lib/angle/angle_morphtargets.dart @@ -0,0 +1,170 @@ +part of three_webgl; + +int numericalSort(a, b) { + return a[0] - b[0]; +} + +int absNumericalSort(a, b) { + return b[1].abs() >= a[1].abs() ? 1 : -1; +} + +void denormalize(Vector morph, BufferAttribute attribute) { + double denominator = 1; + TypedDataList array = attribute is InterleavedBufferAttribute ? attribute.data!.array : attribute.array; + + if (array is Int8List) { + denominator = 127; + } + else if (array is Int16List) { + denominator = 32767; + } + else if (array is Int32List) { + denominator = 2147483647; + } + else { + console.error('three.WebGLMorphtargets: Unsupported morph attribute data type: $array'); + } + + morph.divideScalar(denominator); +} + +class AngleMorphtargets { + bool _didDispose = false; + final influencesList = {}; + final morphInfluences = Float32List(8); + final morphTextures = WeakMap(); + final morph = Vector4.zero(); + + List> workInfluences = []; + + RenderingContext gl; + AngleCapabilities capabilities; + AngleTextures textures; + + AngleMorphtargets(this.gl, this.capabilities, this.textures) { + for (int i = 0; i < 8; i++) { + workInfluences.add([i, 0]); + } + } + + void dispose(){ + if(_didDispose) return; + _didDispose = true; + influencesList.clear(); + morphTextures.dispose(); + workInfluences.clear(); + capabilities.dispose(); + textures.dispose(); + } + + void update(Object3D object, BufferGeometry geometry, AngleProgram program) { + Float32List? objectInfluences = Float32List.fromList(object.morphTargetInfluences); + + final morphAttribute = geometry.morphAttributes["position"] ?? geometry.morphAttributes["normal"] ?? geometry.morphAttributes["color"]; + final morphTargetsCount = (morphAttribute != null) ? morphAttribute.length : 0; + + Map? entry = morphTextures.get(geometry); + + if (entry == null || (entry["count"] != morphTargetsCount)) { + if (entry != null) entry["texture"].dispose(); + + final hasMorphPosition = geometry.morphAttributes["position"] != null; + final hasMorphNormals = geometry.morphAttributes["normal"] != null; + final hasMorphColors = geometry.morphAttributes["color"] != null; + + final morphTargets = geometry.morphAttributes["position"] ?? []; + final morphNormals = geometry.morphAttributes["normal"] ?? []; + final morphColors = geometry.morphAttributes["color"] ?? []; + + int vertexDataCount = 0; + if (hasMorphPosition) vertexDataCount = 1; + if (hasMorphNormals) vertexDataCount = 2; + if (hasMorphColors) vertexDataCount = 3; + + int width = (geometry.attributes["position"].count * vertexDataCount).toInt(); + int height = 1; + + if (width > capabilities.maxTextureSize) { + height = (width / capabilities.maxTextureSize).ceil(); + width = capabilities.maxTextureSize.toInt(); + } + + final buffer = Float32List((width * height * 4 * morphTargetsCount).toInt()); + + final texture = DataArrayTexture(buffer, width, height, morphTargetsCount); + texture.type = FloatType; + texture.needsUpdate = true; + + int vertexDataStride = vertexDataCount * 4; + + for (int i = 0; i < morphTargetsCount; i++) { + final morphTarget = morphTargets[i]; + + int offset = (width * height * 4 * i).toInt(); + + for (int j = 0; j < morphTarget.count; j++) { + final stride = j * vertexDataStride; + + if (hasMorphPosition) { + morph.fromBuffer(morphTarget, j); + + buffer[offset + stride + 0] = morph.x; + buffer[offset + stride + 1] = morph.y; + buffer[offset + stride + 2] = morph.z; + buffer[offset + stride + 3] = 0; + } + + if (hasMorphNormals) { + final morphNormal = morphNormals[i]; + morph.fromBuffer(morphNormal, j); + + buffer[offset + stride + 4] = morph.x; + buffer[offset + stride + 5] = morph.y; + buffer[offset + stride + 6] = morph.z; + buffer[offset + stride + 7] = 0; + } + + if (hasMorphColors) { + final morphColor = morphColors[i]; + morph.fromBuffer(morphColor, j); + + buffer[offset + stride + 8] = morph.x; + buffer[offset + stride + 9] = morph.y; + buffer[offset + stride + 10] = morph.z; + buffer[offset + stride + 11] = ((morphColor.itemSize == 4) ? morph.w : 1); + } + } + } + + entry = {"count": morphTargetsCount, "texture": texture, "size": Vector2(width.toDouble(), height.toDouble())}; + + morphTextures.set(geometry, entry); + + void disposeTexture(event) { + texture.dispose(); + morphTextures.delete(geometry); + geometry.removeEventListener('dispose', disposeTexture); + } + + geometry.addEventListener('dispose', disposeTexture); + } + + if ( object is InstancedMesh && object.morphTexture != null ) { + program.getUniforms().setValue( gl, 'morphTexture', object.morphTexture, textures ); + } + else { + double morphInfluencesSum = 0; + + for (int i = 0; i < objectInfluences.length; i++) { + morphInfluencesSum += objectInfluences[i]; + } + + final morphBaseInfluence = geometry.morphTargetsRelative ? 1 : 1 - morphInfluencesSum; + program.getUniforms().setValue(gl, 'morphTargetBaseInfluence', morphBaseInfluence); + program.getUniforms().setValue(gl, 'morphTargetInfluences', objectInfluences); + } + + program.getUniforms().setValue(gl, 'morphTargetsTexture', entry["texture"], textures); + program.getUniforms().setValue(gl, 'morphTargetsTextureSize', entry["size"]); + } +} diff --git a/packages/three_js_angle_renderer/lib/angle/angle_objects.dart b/packages/three_js_angle_renderer/lib/angle/angle_objects.dart new file mode 100755 index 00000000..63016a1f --- /dev/null +++ b/packages/three_js_angle_renderer/lib/angle/angle_objects.dart @@ -0,0 +1,76 @@ +part of three_webgl; + +class AngleObjects { + bool _didDispose = false; + final updateMap = WeakMap(); + AngleInfo info; + RenderingContext gl; + AngleGeometries geometries; + AngleAttributes attributes; + + AngleObjects(this.gl, this.geometries, this.attributes, this.info); + + BufferGeometry update(Object3D object) { + num frame = info.render["frame"]!; + + final geometry = object.geometry; + + final buffergeometry = geometries.get(geometry!); + + // Update once per frame + + if (updateMap.get(buffergeometry) != frame) { + geometries.update(buffergeometry); + updateMap.add(key: buffergeometry, value: frame); + } + + // print(" WebGLObjects update object: ${object} ${object.type} "); + + if (object is InstancedMesh) { + if (object.hasEventListener('dispose', onInstancedMeshDispose) == false) { + object.addEventListener('dispose', onInstancedMeshDispose); + } + + if ( updateMap.get( object ) != frame ) { + // print(" WebGLObjects update 2 object: ${object} ${object.instanceMatrix} "); + attributes.update(object.instanceMatrix, WebGL.ARRAY_BUFFER); + + if (object.instanceColor != null) { + attributes.update(object.instanceColor, WebGL.ARRAY_BUFFER); + } + updateMap.set( object, frame ); + } + } + + if ( object is SkinnedMesh ) { + final skeleton = object.skeleton; + + if ( updateMap.get( skeleton ) != frame ) { + skeleton?.update(); + updateMap.set( skeleton, frame ); + } + } + + return buffergeometry; + } + + void dispose() { + if(_didDispose) return; + _didDispose = true; + updateMap.clear(); + attributes.dispose(); + geometries.dispose(); + info.dispose(); + } + void onInstancedMeshDispose(event) { + final instancedMesh = event.target; + + instancedMesh.removeEventListener('dispose', onInstancedMeshDispose); + + attributes.remove(instancedMesh.instanceMatrix); + + if (instancedMesh.instanceColor != null) { + attributes.remove(instancedMesh.instanceColor); + } + } +} diff --git a/packages/three_js_angle_renderer/lib/angle/angle_parameters.dart b/packages/three_js_angle_renderer/lib/angle/angle_parameters.dart new file mode 100755 index 00000000..50ce877a --- /dev/null +++ b/packages/three_js_angle_renderer/lib/angle/angle_parameters.dart @@ -0,0 +1,670 @@ +part of three_webgl; + +class AngleParameters { + int? customVertexShaderID; + int? customFragmentShaderID; + + bool rendererExtensionParallelShaderCompile = false; + + String? shaderID; + String? shaderType; + String outputColorSpace = NoColorSpace; + String shaderName = ''; + + String vertexShader = ''; + String fragmentShader = ''; + + Map? defines; + + bool isRawShaderMaterial = false; + String? glslVersion; + + late String precision; + + bool instancing = false; + bool instancingColor = false; + + bool supportsVertexTextures = false; + bool map = false; + bool matcap = false; + bool envMap = false; + int? envMapMode; + bool lightMap = false; + bool aoMap = false; + bool emissiveMap = false; + bool bumpMap = false; + bool normalMap = false; + bool normalMapObjectSpace = false; + bool normalMapTangentSpace = false; + + bool clearcoat = false; + bool clearcoatMap = false; + bool clearcoatRoughnessMap = false; + bool clearcoatNormalMap = false; + + bool displacementMap = false; + bool roughnessMap = false; + bool metalnessMap = false; + bool specularMap = false; + bool specularIntensityMap = false; + bool specularColorMap = false; + bool alphaMap = false; + bool sheenColorMap = false; + + bool gradientMap = false; + bool sheenRoughnessMap = false; + bool sheen = false; + bool transmission = false; + bool transmissionMap = false; + bool thicknessMap = false; + int? combine; + bool vertexTangents = false; + bool vertexColors = false; + bool vertexUvs = false; + bool pointsUvs = false; + bool fog = false; + bool useFog = false; + bool fogExp2 = false; + bool flatShading = false; + bool sizeAttenuation = false; + bool logarithmicDepthBuffer = false; + + bool skinning = false; + + bool morphTargets = false; + bool morphNormals = false; + bool morphColors = false; + + int numDirLights = 0; + int numPointLights = 0; + int numSpotLights = 0; + int numRectAreaLights = 0; + int numHemiLights = 0; + int numSpotLightMaps = 0; + + int numDirLightShadows = 0; + int numPointLightShadows = 0; + int numSpotLightShadows = 0; + int numLightProbes = 0; + int numSpotLightShadowsWithMaps = 0; + + int numClippingPlanes = 0; + int numClipIntersection = 0; + bool dithering = false; + bool shadowMapEnabled = false; + int? shadowMapType; + int? toneMapping; + bool useLegacyLights = false; + bool physicallyCorrectLights = false; + bool premultipliedAlpha = false; + bool alphaTest = false; + + bool doubleSided = false; + bool flipSided = false; + + bool useDepthPacking = false; + int? depthPacking; + + String? index0AttributeName; + + late bool extensionDerivatives; + late bool extensionFragDepth; + late bool extensionDrawBuffers; + late bool extensionShaderTextureLOD; + + late bool rendererExtensionFragDepth; + late bool rendererExtensionDrawBuffers; + late bool rendererExtensionShaderTextureLod; + String? customProgramCacheKey; + + bool decodeVideoTexture = false; + bool decodeVideoTextureEmissive = false; + + Map? uniforms; + + bool vertexAlphas = false; + bool opaque = false; + bool batching = false; + + bool anisotropy = false; + bool anisotropyMap = false; + + bool iridescence = false; + bool iridescenceMap = false; + bool iridescenceThicknessMap = false; + bool alphaHash = false; + bool dispersion = false; + bool batchingColor = false; + + int morphTargetsCount = 0; + num? cubeUVHeight; + + num? envMapCubeUVHeight; + bool instancingMorph = false; + bool alphaToCoverage = false; + int? morphTextureStride; + + bool extensionClipCullDistance = false; + bool extensionMultiDraw = false; + + String? mapUv; + String? aoMapUv; + String? lightMapUv; + String? bumpMapUv; + String? normalMapUv; + String? displacementMapUv; + String? emissiveMapUv; + + String? metalnessMapUv; + String? roughnessMapUv; + + String? anisotropyMapUv; + + String? clearcoatMapUv; + String? clearcoatNormalMapUv; + String? clearcoatRoughnessMapUv; + + String? iridescenceMapUv; + String? iridescenceThicknessMapUv; + + String? sheenColorMapUv; + String? sheenRoughnessMapUv; + + String? specularMapUv; + String? specularColorMapUv; + String? specularIntensityMapUv; + + String? transmissionMapUv; + String? thicknessMapUv; + + String? alphaMapUv; + + bool vertexUv1s = false; + bool vertexUv2s = false; + bool vertexUv3s = false; + + int morphAttributeCount = 0; + + bool tangentSpaceNormalMap = false; + bool objectSpaceNormalMap = false; + bool uvsVertexOnly = false; + int outputEncoding = 0; + + AngleParameters.create(); + + void dispose(){ + uniforms?.clear(); + } + + AngleParameters({ + this.shaderID, + this.shaderType, + this.shaderName = '', + this.vertexShader = '', + this.fragmentShader = '', + this.defines, + this.customVertexShaderID, + this.customFragmentShaderID, + this.isRawShaderMaterial = false, + this.glslVersion, + required this.precision, + this.batching = false, + this.instancing = false, + this.instancingColor = false, + this.instancingMorph = false, + this.supportsVertexTextures = false, + this.outputColorSpace = NoColorSpace, + this.alphaToCoverage = false, + this.map = false, + this.displacementMap = false, + this.matcap = false, + this.envMap = false, + this.envMapMode, + this.envMapCubeUVHeight, + this.lightMap = false, + this.aoMap = false, + this.emissiveMap = false, + this.bumpMap = false, + this.normalMap = false, + + this.morphAttributeCount = 0, + + this.normalMapObjectSpace = false, + this.normalMapTangentSpace = false, + this.roughnessMap = false, + this.metalnessMap = false, + + this.anisotropy = false, + this.anisotropyMap = false, + + this.clearcoat = false, + this.clearcoatMap = false, + this.clearcoatRoughnessMap = false, + this.clearcoatNormalMap = false, + + this.dispersion = false, + this.batchingColor = false, + + this.iridescence = false, + this.iridescenceMap = false, + this.iridescenceThicknessMap = false, + + this.sheen = false, + this.sheenColorMap = false, + this.sheenRoughnessMap = false, + + this.specularMap = false, + this.specularIntensityMap = false, + this.specularColorMap = false, + + this.transmission = false, + this.transmissionMap = false, + this.thicknessMap = false, + + this.gradientMap = false, + + this.opaque = false, + + this.alphaMap = false, + this.alphaTest = false, + this.alphaHash = false, + + this.combine, + + this.mapUv, + this.aoMapUv, + this.lightMapUv, + this.bumpMapUv, + this.normalMapUv, + this.displacementMapUv, + this.emissiveMapUv, + + this.metalnessMapUv, + this.roughnessMapUv, + + this.anisotropyMapUv, + + this.clearcoatMapUv, + this.clearcoatNormalMapUv, + this.clearcoatRoughnessMapUv, + + this.iridescenceMapUv, + this.iridescenceThicknessMapUv, + + this.sheenColorMapUv, + this.sheenRoughnessMapUv, + + this.specularMapUv, + this.specularColorMapUv, + this.specularIntensityMapUv, + + this.transmissionMapUv, + this.thicknessMapUv, + + this.alphaMapUv, + + this.vertexTangents = false, + this.vertexColors = false, + this.vertexAlphas = false, + + this.pointsUvs = false, + this.fog = false, + this.useFog = false, + this.fogExp2 = false, + + this.flatShading = false, + + this.sizeAttenuation = false, + this.logarithmicDepthBuffer = false, + + this.skinning = false, + + this.morphTargets = false, + this.morphNormals = false, + this.morphColors = false, + this.morphTargetsCount = 0, + this.morphTextureStride, + + this.numDirLights = 0, + this.numPointLights = 0, + this.numSpotLights = 0, + this.numSpotLightMaps = 0, + this.numRectAreaLights = 0, + this.numHemiLights = 0, + + this.numDirLightShadows = 0, + this.numPointLightShadows = 0, + this.numSpotLightShadows = 0, + this.numSpotLightShadowsWithMaps = 0, + this.numLightProbes = 0, + this.numClippingPlanes = 0, + this.numClipIntersection = 0, + + this.dithering = false, + + this.shadowMapEnabled = false, + this.shadowMapType, + + this.toneMapping, + this.useLegacyLights = false, + + this.decodeVideoTexture = false, + this.decodeVideoTextureEmissive = false, + + this.premultipliedAlpha = false, + + this.doubleSided = false, + this.flipSided = false, + + this.useDepthPacking = false, + this.depthPacking, + + this.index0AttributeName, + + this.extensionClipCullDistance = false, + this.extensionMultiDraw = false, + this.rendererExtensionParallelShaderCompile = false, + this.customProgramCacheKey, + }); + + AngleParameters.fromJson(Map json) { + shaderID = json['shaderID']; + shaderType = json['shaderType']; + shaderName = json['shaderName'] ?? ''; + + vertexShader = json['vertexShader'] ?? ''; + fragmentShader = json['fragmentShader'] ?? ''; + defines = json['defines']; + + customVertexShaderID = json['customVertexShaderID']; + customFragmentShaderID = json['customFragmentShaderID']; + + isRawShaderMaterial = json['isRawShaderMaterial'] ?? false; + glslVersion = json['glslVersion']; + + precision = json['precision'] ?? ''; + batching = json['batching'] ?? false; + instancing = json['instancing'] ?? false; + instancingColor = json['instancingColor'] ?? false; + instancingMorph = json['instancingMorph'] ?? false; + + supportsVertexTextures = json['supportsVertexTextures'] ?? false; + outputColorSpace = json['outputColorSpace'] ?? NoColorSpace; + alphaToCoverage = json['alphaToCoverage'] ?? false; + + map = json['map'] ?? false; + matcap = json['matcap'] ?? false; + envMap = json['envMap'] ?? false; + envMapMode = json['envMapMode'] ?? false; + envMapCubeUVHeight = json['envMapCubeUVHeight']; + lightMap = json['lightMap'] ?? false; + aoMap = json['aoMap'] ?? false; + emissiveMap = json['emissiveMap'] ?? false; + bumpMap = json['bumpMap'] ?? false; + normalMap = json['normalMap'] ?? false; + + normalMapObjectSpace = json['normalMapObjectSpace'] ?? false; + normalMapTangentSpace = json['normalMapTangentSpace'] ?? false; + roughnessMap = json['roughnessMap'] ?? false; + metalnessMap = json['metalnessMap'] ?? false; + + anisotropy = json['anisotropy'] ?? false; + anisotropyMap = json['anisotropyMap'] ?? false; + + clearcoat = json['clearcoat'] ?? false; + clearcoatMap = json['clearcoatMap'] ?? false; + clearcoatRoughnessMap = json['clearcoatRoughnessMap'] ?? false; + clearcoatNormalMap = json['clearcoatNormalMap'] ?? false; + + displacementMap = json['displacementMap'] ?? false; + + iridescence = json['iridescence'] ?? false; + iridescenceMap = json['iridescenceMap'] ?? false; + iridescenceThicknessMap = json['iridescenceThicknessMap'] ?? false; + + sheen = json['sheen'] ?? false; + sheenColorMap = json['sheenColorMap'] ?? false; + sheenRoughnessMap = json['sheenRoughnessMap'] ?? false; + + specularMap = json['specularMap'] ?? false; + specularIntensityMap = json['specularIntensityMap'] ?? false; + specularColorMap = json['specularColorMap'] ?? false; + + transmission = json['transmission'] ?? false; + transmissionMap = json['transmissionMap'] ?? false; + thicknessMap = json['thicknessMap'] ?? false; + + gradientMap = json['gradientMap'] ?? false; + + opaque = json['opaque'] ?? false; + dispersion = json['dispersion'] ?? false; + batchingColor = json['batchingColor'] ?? false; + + alphaMap = json['alphaMap'] ?? false; + alphaTest = json['alphaTest'] ?? false; + alphaHash = json['alphaHash'] ?? false; + + combine = json['combine']; + + mapUv = json['mapUv']; + aoMapUv = json['aoMapUv']; + lightMapUv = json['lightMapUv']; + bumpMapUv = json['bumpMapUv']; + normalMapUv = json['normalMapUv']; + displacementMapUv = json['displacementMapUv']; + emissiveMapUv = json['emissiveMapUv']; + + metalnessMapUv = json['metalnessMapUv']; + roughnessMapUv = json['roughnessMapUv']; + + anisotropyMapUv = json['anisotropyMapUv']; + + clearcoatMapUv = json['clearcoatMapUv']; + clearcoatNormalMapUv = json['clearcoatNormalMapUv']; + clearcoatRoughnessMapUv = json['clearcoatRoughnessMapUv']; + + iridescenceMapUv = json['iridescenceMapUv']; + iridescenceThicknessMapUv = json['iridescenceThicknessMapUv']; + + sheenColorMapUv = json['sheenColorMapUv']; + sheenRoughnessMapUv = json['sheenRoughnessMapUv']; + + specularMapUv = json['specularMapUv']; + specularColorMapUv = json['specularColorMapUv']; + specularIntensityMapUv = json['specularIntensityMapUv']; + + transmissionMapUv = json['transmissionMapUv']; + thicknessMapUv = json['thicknessMapUv']; + + alphaMapUv = json['alphaMapUv']; + + vertexTangents = json['vertexTangents'] ?? false; + vertexColors = json['vertexColors'] ?? false; + vertexAlphas = json['vertexAlphas'] ?? false; + + vertexUvs = json['vertexUvs'] ?? false; + + fog = json['fog'] ?? false; + useFog = json['useFog'] ?? false; + fogExp2 = json['fogExp2'] ?? false; + + flatShading = json['flatShading'] ?? false; + + sizeAttenuation = json['sizeAttenuation'] ?? false; + logarithmicDepthBuffer = json['logarithmicDepthBuffer'] ?? false; + + skinning = json['skinning'] ?? false; + + morphTargets = json['morphTargets'] ?? false; + morphNormals = json['morphNormals'] ?? false; + morphColors = json['morphColors'] ?? false; + morphTargetsCount = json['morphTargetsCount'] ?? 0; + morphTextureStride = json['morphTextureStride']; + + numDirLights = json['numDirLights'] ?? 0; + numPointLights = json['numPointLights'] ?? 0; + numSpotLights = json['numSpotLights'] ?? 0; + numSpotLightMaps = json['numSpotLightMaps'] ?? 0; + numRectAreaLights = json['numRectAreaLights'] ?? 0; + numHemiLights = json['numHemiLights'] ?? 0; + + numDirLightShadows = json['numDirLightShadows'] ?? 0; + numPointLightShadows = json['numPointLightShadows'] ?? 0; + numSpotLightShadows = json['numSpotLightShadows'] ?? 0; + numSpotLightShadowsWithMaps = json['numSpotLightShadowsWithMaps'] ?? 0; + + numLightProbes = json['numLightProbes'] ?? 0; + + numClippingPlanes = json['numClippingPlanes'] ?? 0; + numClipIntersection = json['numClipIntersection'] ?? 0; + + dithering = json['dithering'] ?? false; + + shadowMapEnabled = json['shadowMapEnabled'] ?? false; + shadowMapType = json['shadowMapType']; + + toneMapping = json['toneMapping']; + useLegacyLights = json['useLegacyLights'] ?? false; + + decodeVideoTexture = json['decodeVideoTexture'] ?? false; + decodeVideoTextureEmissive = json['decodeVideoTextureEmissive'] ?? false; + + premultipliedAlpha = json['premultipliedAlpha'] ?? false; + + doubleSided = json['doubleSided'] ?? false; + flipSided = json['flipSided'] ?? false; + + useDepthPacking = json['useDepthPacking'] ?? false; + depthPacking = json['depthPacking']; + + index0AttributeName = json['index0AttributeName']; + + pointsUvs = json['pointsUvs'] ?? false; + + extensionClipCullDistance = json['extensionClipCullDistance'] ?? false; + extensionMultiDraw = json['extensionMultiDraw'] ?? false; + + customProgramCacheKey = json['customProgramCacheKey']; + + tangentSpaceNormalMap = json["tangentSpaceNormalMap"]; + objectSpaceNormalMap = json["objectSpaceNormalMap"]; + uvsVertexOnly = json["uvsVertexOnly"]; + outputEncoding = json["outputEncoding"]; + } + + getValue(String name) { + Map json = toJson(); + + return json[name]; + } + + toJson() { + Map json = { + "shaderID": shaderID, + "customVertexShaderID": customVertexShaderID, + "customFragmentShaderID": customFragmentShaderID, + "shaderName": shaderName, + "vertexShader": vertexShader, + "fragmentShader": fragmentShader, + "defines": defines, + "isRawShaderMaterial": isRawShaderMaterial, + "glslVersion": glslVersion, + "precision": precision, + "instancing": instancing, + "instancingColor": instancingColor, + "supportsVertexTextures": supportsVertexTextures, + "outputColorSpace": outputColorSpace, + "outputEncoding": outputEncoding, + 'opaque': opaque, + 'dispersion': dispersion, + 'batchingColor': batchingColor, + "map": map, + "matcap": matcap, + "envMap": envMap, + "envMapMode": envMapMode, + "lightMap": lightMap, + "aoMap": aoMap, + "emissiveMap": emissiveMap, + "bumpMap": bumpMap, + "normalMap": normalMap, + "normalMapObjectSpace": normalMapObjectSpace, + "normalMapTangentSpace": normalMapTangentSpace, + "clearcoat": clearcoat, + "clearcoatMap": clearcoatMap, + "clearcoatRoughnessMap": clearcoatRoughnessMap, + "clearcoatNormalMap": clearcoatNormalMap, + "displacementMap": displacementMap, + "roughnessMap": roughnessMap, + "metalnessMap": metalnessMap, + "specularMap": specularMap, + "specularIntensityMap": specularIntensityMap, + "specularColorMap": specularColorMap, + "alphaMap": alphaMap, + "gradientMap": gradientMap, + "sheenColorMap": sheenColorMap, + "sheenRoughnessMap": sheenRoughnessMap, + "sheen": sheen, + "transmission": transmission, + "transmissionMap": transmissionMap, + "transmissionMapUv": transmissionMapUv, + "thicknessMap": thicknessMap, + "combine": combine, + "vertexTangents": vertexTangents, + "vertexColors": vertexColors, + "vertexUvs": vertexUvs, + "uvsVertexOnly": uvsVertexOnly, + "pointsUvs": pointsUvs, + "fog": fog, + "useFog": useFog, + "fogExp2": fogExp2, + "flatShading": flatShading, + "sizeAttenuation": sizeAttenuation, + "logarithmicDepthBuffer": logarithmicDepthBuffer, + "skinning": skinning, + "morphTargets": morphTargets, + "morphNormals": morphNormals, + "morphColors": morphColors, + "numDirLights": numDirLights, + "numPointLights": numPointLights, + "numSpotLights": numSpotLights, + "numRectAreaLights": numRectAreaLights, + "numHemiLights": numHemiLights, + "numDirLightShadows": numDirLightShadows, + "numPointLightShadows": numPointLightShadows, + "numSpotLightShadows": numSpotLightShadows, + "numClippingPlanes": numClippingPlanes, + "numClipIntersection": numClipIntersection, + "dithering": dithering, + "shadowMapEnabled": shadowMapEnabled, + "shadowMapType": shadowMapType, + "toneMapping": toneMapping, + "physicallyCorrectLights": physicallyCorrectLights, + "useLegacyLights": useLegacyLights, + "premultipliedAlpha": premultipliedAlpha, + "alphaTest": alphaTest, + "doubleSided": doubleSided, + "flipSided": flipSided, + "useDepthPacking": useDepthPacking, + "depthPacking": depthPacking, + "index0AttributeName": index0AttributeName, + "extensionDerivatives": extensionDerivatives, + "extensionFragDepth": extensionFragDepth, + "extensionDrawBuffers": extensionDrawBuffers, + "extensionShaderTextureLOD": extensionShaderTextureLOD, + "rendererExtensionFragDepth": rendererExtensionFragDepth, + "rendererExtensionDrawBuffers": rendererExtensionDrawBuffers, + "rendererExtensionShaderTextureLod": rendererExtensionShaderTextureLod, + "customProgramCacheKey": customProgramCacheKey, + "uniforms": uniforms, + "vertexAlphas": vertexAlphas, + "decodeVideoTexture": decodeVideoTexture, + 'decodeVideoTextureEmissive': decodeVideoTextureEmissive, + "morphTargetsCount": morphTargetsCount, + "cubeUVHeight": cubeUVHeight, + "envMapCubeUVHeight": envMapCubeUVHeight, + "morphTextureStride": morphTextureStride + }; + + return json; + } +} diff --git a/packages/three_js_angle_renderer/lib/angle/angle_program.dart b/packages/three_js_angle_renderer/lib/angle/angle_program.dart new file mode 100755 index 00000000..5684b1fe --- /dev/null +++ b/packages/three_js_angle_renderer/lib/angle/angle_program.dart @@ -0,0 +1,521 @@ +part of three_webgl; + +int programIdCount = 0; +const COMPLETION_STATUS_KHR = 0x91B1; + +class DefaultProgram { + int id = -1; +} + +class AngleProgram extends DefaultProgram with AngleProgramExtra { + bool _didDispose = false; + late String name; + AngleRenderer renderer; + String cacheKey; + AngleBindingStates bindingStates; + int usedTimes = 1; + late RenderingContext gl; + AngleParameters parameters; + late Program? program; + + late String vertexShader; + late String fragmentShader; + late Map diagnostics; + + AngleUniforms? cachedUniforms; + Map? cachedAttributes; + + late Function(AngleProgram) onFirstUse; + + AngleProgram(this.renderer, this.cacheKey, this.parameters, this.bindingStates) { + name = parameters.shaderName; + id = programIdCount++; + + gl = renderer.getContext(); + program = gl.createProgram(); + init(); + } + + void dispose(){ + if(_didDispose) return; + _didDispose = true; + renderer.dispose(); + bindingStates.dispose(); + parameters.dispose(); + diagnostics.clear(); + cachedUniforms?.dispose(); + cachedAttributes?.clear(); + } + + void init() { + final defines = parameters.defines; + + vertexShader = parameters.vertexShader; + fragmentShader = parameters.fragmentShader; + + final shadowMapTypeDefine = generateShadowMapTypeDefine(parameters); + final envMapTypeDefine = generateEnvMapTypeDefine(parameters); + final envMapModeDefine = generateEnvMapModeDefine(parameters); + final envMapBlendingDefine = generateEnvMapBlendingDefine(parameters); + + final envMapCubeUVSize = generateCubeUVSize(parameters); + final customVertexExtensions = generateVertexExtensions( parameters ); + + final customDefines = generateDefines( defines ); + + program ??= gl.createProgram(); + + String prefixVertex, prefixFragment; + String versionString = parameters.glslVersion != null ? '#version ${parameters.glslVersion}\n' : ''; + + if (parameters.isRawShaderMaterial) { + prefixVertex = [ + '#define SHADER_TYPE ${parameters.shaderType}', + '#define SHADER_NAME ${parameters.shaderName}', + customDefines + ].where((s) => filterEmptyLine(s)).join('\n'); + + if (prefixVertex.isNotEmpty) { + prefixVertex += "\n"; + } + + prefixFragment = [ + '#define SHADER_TYPE ${parameters.shaderType}', + '#define SHADER_NAME ${parameters.shaderName}', + customDefines + ].where((s) => filterEmptyLine(s)).join('\n'); + + if (prefixFragment.isNotEmpty) { + prefixFragment += "\n"; + } + } + else { + prefixVertex = [ + generatePrecision(parameters), + '#define SHADER_TYPE ${parameters.shaderType}', + '#define SHADER_NAME ${parameters.shaderName}', + + customDefines, + + parameters.extensionClipCullDistance ? '#define USE_CLIP_DISTANCE' : '', + parameters.batching ? '#define USE_BATCHING' : '', + parameters.instancing ? '#define USE_INSTANCING' : '', + parameters.instancingColor ? '#define USE_INSTANCING_COLOR' : '', + parameters.instancingMorph ? '#define USE_INSTANCING_MORPH' : '', + + parameters.useFog && parameters.fog ? '#define USE_FOG' : '', + parameters.useFog && parameters.fogExp2 ? '#define FOG_EXP2' : '', + + parameters.map ? '#define USE_MAP' : '', + parameters.envMap ? '#define USE_ENVMAP' : '', + parameters.envMap ? '#define $envMapModeDefine' : '', + parameters.lightMap ? '#define USE_LIGHTMAP' : '', + parameters.aoMap ? '#define USE_AOMAP' : '', + parameters.bumpMap ? '#define USE_BUMPMAP' : '', + parameters.normalMap ? '#define USE_NORMALMAP' : '', + parameters.normalMapObjectSpace ? '#define USE_NORMALMAP_OBJECTSPACE' : '', + parameters.normalMapTangentSpace ? '#define USE_NORMALMAP_TANGENTSPACE' : '', + parameters.displacementMap ? '#define USE_DISPLACEMENTMAP' : '', + parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '', + + parameters.anisotropy ? '#define USE_ANISOTROPY' : '', + parameters.anisotropyMap ? '#define USE_ANISOTROPYMAP' : '', + + parameters.clearcoatMap ? '#define USE_CLEARCOATMAP' : '', + parameters.clearcoatRoughnessMap ? '#define USE_CLEARCOAT_ROUGHNESSMAP' : '', + parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '', + + parameters.iridescenceMap ? '#define USE_IRIDESCENCEMAP' : '', + parameters.iridescenceThicknessMap ? '#define USE_IRIDESCENCE_THICKNESSMAP' : '', + + parameters.specularMap ? '#define USE_SPECULARMAP' : '', + parameters.specularColorMap ? '#define USE_SPECULAR_COLORMAP' : '', + parameters.specularIntensityMap ? '#define USE_SPECULAR_INTENSITYMAP' : '', + + parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '', + parameters.metalnessMap ? '#define USE_METALNESSMAP' : '', + parameters.alphaMap ? '#define USE_ALPHAMAP' : '', + parameters.alphaHash ? '#define USE_ALPHAHASH' : '', + + parameters.transmission ? '#define USE_TRANSMISSION' : '', + parameters.transmissionMap ? '#define USE_TRANSMISSIONMAP' : '', + parameters.thicknessMap ? '#define USE_THICKNESSMAP' : '', + + parameters.sheenColorMap ? '#define USE_SHEEN_COLORMAP' : '', + parameters.sheenRoughnessMap ? '#define USE_SHEEN_ROUGHNESSMAP' : '', + + parameters.mapUv != null? '#define MAP_UV ${parameters.mapUv!}': '', + parameters.alphaMapUv != null? '#define ALPHAMAP_UV ${parameters.alphaMapUv!}': '', + parameters.lightMapUv != null? '#define LIGHTMAP_UV ${parameters.lightMapUv!}': '', + parameters.aoMapUv != null? '#define AOMAP_UV ${parameters.aoMapUv!}' : '', + parameters.emissiveMapUv != null? '#define EMISSIVEMAP_UV ${parameters.emissiveMapUv!}' : '', + parameters.bumpMapUv != null? '#define BUMPMAP_UV ${parameters.bumpMapUv!}' : '', + parameters.normalMapUv != null? '#define NORMALMAP_UV ${parameters.normalMapUv!}': '', + parameters.displacementMapUv != null? '#define DISPLACEMENTMAP_UV ${parameters.displacementMapUv!}': '', + + parameters.metalnessMapUv != null? '#define METALNESSMAP_UV ${parameters.metalnessMapUv!}': '', + parameters.roughnessMapUv != null? '#define ROUGHNESSMAP_UV ${parameters.roughnessMapUv!}': '', + + parameters.anisotropyMapUv != null? '#define ANISOTROPYMAP_UV ${parameters.anisotropyMapUv!}': '', + + parameters.clearcoatMapUv != null? '#define CLEARCOATMAP_UV ${parameters.clearcoatMapUv!}': '', + parameters.clearcoatNormalMapUv != null? '#define CLEARCOAT_NORMALMAP_UV ${parameters.clearcoatNormalMapUv!}': '', + parameters.clearcoatRoughnessMapUv != null? '#define CLEARCOAT_ROUGHNESSMAP_UV ${parameters.clearcoatRoughnessMapUv!}' : '', + + parameters.iridescenceMapUv != null? '#define IRIDESCENCEMAP_UV ${parameters.iridescenceMapUv!}': '', + parameters.iridescenceThicknessMapUv != null? '#define IRIDESCENCE_THICKNESSMAP_UV ${parameters.iridescenceThicknessMapUv!}': '', + + parameters.sheenColorMapUv != null? '#define SHEEN_COLORMAP_UV ${parameters.sheenColorMapUv!}': '', + parameters.sheenRoughnessMapUv != null? '#define SHEEN_ROUGHNESSMAP_UV ${parameters.sheenRoughnessMapUv!}': '', + + parameters.specularMapUv != null? '#define SPECULARMAP_UV ${parameters.specularMapUv!}': '', + parameters.specularColorMapUv != null? '#define SPECULAR_COLORMAP_UV ${parameters.specularColorMapUv!}': '', + parameters.specularIntensityMapUv != null? '#define SPECULAR_INTENSITYMAP_UV ${parameters.specularIntensityMapUv!}' : '', + + parameters.transmissionMapUv != null? '#define TRANSMISSIONMAP_UV ${parameters.transmissionMapUv!}': '', + parameters.thicknessMapUv != null? '#define THICKNESSMAP_UV ${parameters.thicknessMapUv!}' : '', + + // + + parameters.vertexTangents && !parameters.flatShading? '#define USE_TANGENT' : '', + parameters.vertexColors ? '#define USE_COLOR' : '', + parameters.vertexAlphas ? '#define USE_COLOR_ALPHA' : '', + parameters.vertexUv1s ? '#define USE_UV1' : '', + parameters.vertexUv2s ? '#define USE_UV2' : '', + parameters.vertexUv3s ? '#define USE_UV3' : '', + + parameters.pointsUvs ? '#define USE_POINTS_UV' : '', + + parameters.flatShading ? '#define FLAT_SHADED' : '', + + parameters.skinning ? '#define USE_SKINNING' : '', + + parameters.morphTargets ? '#define USE_MORPHTARGETS' : '', + parameters.morphNormals && !parameters.flatShading? '#define USE_MORPHNORMALS' : '', + ( parameters.morphColors ) ? '#define USE_MORPHCOLORS' : '', + ( parameters.morphTargetsCount > 0 ) ? '#define MORPHTARGETS_TEXTURE' : '', + ( parameters.morphTargetsCount > 0 ) ? '#define MORPHTARGETS_TEXTURE_STRIDE ${parameters.morphTextureStride}' : '', + ( parameters.morphTargetsCount > 0 ) ? '#define MORPHTARGETS_COUNT ${parameters.morphTargetsCount}': '', + parameters.doubleSided ? '#define DOUBLE_SIDED' : '', + parameters.flipSided ? '#define FLIP_SIDED' : '', + + parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '', + parameters.shadowMapEnabled ? '#define $shadowMapTypeDefine': '', + + parameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '', + + parameters.numLightProbes > 0 ? '#define USE_LIGHT_PROBES' : '', + + parameters.useLegacyLights ? '#define LEGACY_LIGHTS' : '', + + parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '', + + 'uniform mat4 modelMatrix;', + 'uniform mat4 modelViewMatrix;', + 'uniform mat4 projectionMatrix;', + 'uniform mat4 viewMatrix;', + 'uniform mat3 normalMatrix;', + 'uniform vec3 cameraPosition;', + 'uniform bool isOrthographic;', + '#ifdef USE_INSTANCING', + ' attribute mat4 instanceMatrix;', + '#endif', + '#ifdef USE_INSTANCING_COLOR', + ' attribute vec3 instanceColor;', + '#endif', + + '#ifdef USE_INSTANCING_MORPH', + ' uniform sampler2D morphTexture;', + '#endif', + + 'attribute vec3 position;', + 'attribute vec3 normal;', + 'attribute vec2 uv;', + + '#ifdef USE_UV1', + ' attribute vec2 uv1;', + '#endif', + '#ifdef USE_UV2', + ' attribute vec2 uv2;', + '#endif', + '#ifdef USE_UV3', + ' attribute vec2 uv3;', + '#endif', + + '#ifdef USE_TANGENT', + ' attribute vec4 tangent;', + '#endif', + '#if defined( USE_COLOR_ALPHA )', + ' attribute vec4 color;', + '#elif defined( USE_COLOR )', + ' attribute vec3 color;', + '#endif', + '#if ( defined( USE_MORPHTARGETS ) && ! defined( MORPHTARGETS_TEXTURE ) )', + ' attribute vec3 morphTarget0;', + ' attribute vec3 morphTarget1;', + ' attribute vec3 morphTarget2;', + ' attribute vec3 morphTarget3;', + ' #ifdef USE_MORPHNORMALS', + ' attribute vec3 morphNormal0;', + ' attribute vec3 morphNormal1;', + ' attribute vec3 morphNormal2;', + ' attribute vec3 morphNormal3;', + ' #else', + ' attribute vec3 morphTarget4;', + ' attribute vec3 morphTarget5;', + ' attribute vec3 morphTarget6;', + ' attribute vec3 morphTarget7;', + ' #endif', + '#endif', + '#ifdef USE_SKINNING', + ' attribute vec4 skinIndex;', + ' attribute vec4 skinWeight;', + '#endif', + '\n' + ].where((s) => filterEmptyLine(s)).join('\n'); + + prefixFragment = [ + generatePrecision(parameters), + + '#define SHADER_TYPE ${parameters.shaderType}', + '#define SHADER_NAME ${parameters.shaderName}', + + customDefines, + + parameters.useFog && parameters.fog ? '#define USE_FOG' : '', + parameters.useFog && parameters.fogExp2 ? '#define FOG_EXP2' : '', + + parameters.alphaToCoverage ? '#define ALPHA_TO_COVERAGE' : '', + parameters.map ? '#define USE_MAP' : '', + parameters.matcap ? '#define USE_MATCAP' : '', + parameters.envMap ? '#define USE_ENVMAP' : '', + parameters.envMap ? '#define $envMapTypeDefine': '', + parameters.envMap ? '#define $envMapModeDefine': '', + parameters.envMap ? '#define $envMapBlendingDefine': '', + envMapCubeUVSize != null? '#define CUBEUV_TEXEL_WIDTH ${envMapCubeUVSize['texelWidth']}': '', + envMapCubeUVSize != null? '#define CUBEUV_TEXEL_HEIGHT ${envMapCubeUVSize['texelHeight']}' : '', + envMapCubeUVSize != null? '#define CUBEUV_MAX_MIP ${envMapCubeUVSize['maxMip']}.0' : '', + + parameters.lightMap ? '#define USE_LIGHTMAP' : '', + parameters.aoMap ? '#define USE_AOMAP' : '', + parameters.bumpMap ? '#define USE_BUMPMAP' : '', + parameters.normalMap ? '#define USE_NORMALMAP' : '', + parameters.normalMapObjectSpace ? '#define USE_NORMALMAP_OBJECTSPACE' : '', + parameters.normalMapTangentSpace ? '#define USE_NORMALMAP_TANGENTSPACE' : '', + parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '', + + parameters.anisotropy ? '#define USE_ANISOTROPY' : '', + parameters.anisotropyMap ? '#define USE_ANISOTROPYMAP' : '', + + parameters.clearcoat ? '#define USE_CLEARCOAT' : '', + parameters.clearcoatMap ? '#define USE_CLEARCOATMAP' : '', + parameters.clearcoatRoughnessMap ? '#define USE_CLEARCOAT_ROUGHNESSMAP' : '', + parameters.clearcoatNormalMap ? '#define USE_CLEARCOAT_NORMALMAP' : '', + + parameters.dispersion ? '#define USE_DISPERSION' : '', + + parameters.iridescence ? '#define USE_IRIDESCENCE' : '', + parameters.iridescenceMap ? '#define USE_IRIDESCENCEMAP' : '', + parameters.iridescenceThicknessMap ? '#define USE_IRIDESCENCE_THICKNESSMAP' : '', + + parameters.specularMap ? '#define USE_SPECULARMAP' : '', + parameters.specularColorMap ? '#define USE_SPECULAR_COLORMAP' : '', + parameters.specularIntensityMap ? '#define USE_SPECULAR_INTENSITYMAP' : '', + + parameters.roughnessMap ? '#define USE_ROUGHNESSMAP' : '', + parameters.metalnessMap ? '#define USE_METALNESSMAP' : '', + + parameters.alphaMap ? '#define USE_ALPHAMAP' : '', + parameters.alphaTest ? '#define USE_ALPHATEST' : '', + parameters.alphaHash ? '#define USE_ALPHAHASH' : '', + + parameters.sheen ? '#define USE_SHEEN' : '', + parameters.sheenColorMap ? '#define USE_SHEEN_COLORMAP' : '', + parameters.sheenRoughnessMap ? '#define USE_SHEEN_ROUGHNESSMAP' : '', + + parameters.transmission ? '#define USE_TRANSMISSION' : '', + parameters.transmissionMap ? '#define USE_TRANSMISSIONMAP' : '', + parameters.thicknessMap ? '#define USE_THICKNESSMAP' : '', + + parameters.vertexTangents && !parameters.flatShading? '#define USE_TANGENT' : '', + parameters.vertexColors || parameters.instancingColor ? '#define USE_COLOR' : '', + parameters.vertexAlphas ? '#define USE_COLOR_ALPHA' : '', + parameters.vertexUv1s ? '#define USE_UV1' : '', + parameters.vertexUv2s ? '#define USE_UV2' : '', + parameters.vertexUv3s ? '#define USE_UV3' : '', + + parameters.pointsUvs ? '#define USE_POINTS_UV' : '', + + parameters.gradientMap ? '#define USE_GRADIENTMAP' : '', + + parameters.flatShading ? '#define FLAT_SHADED' : '', + + parameters.doubleSided ? '#define DOUBLE_SIDED' : '', + parameters.flipSided ? '#define FLIP_SIDED' : '', + + parameters.shadowMapEnabled ? '#define USE_SHADOWMAP' : '', + parameters.shadowMapEnabled ? '#define $shadowMapTypeDefine': '', + + parameters.premultipliedAlpha ? '#define PREMULTIPLIED_ALPHA' : '', + + parameters.numLightProbes > 0 ? '#define USE_LIGHT_PROBES' : '', + + parameters.useLegacyLights ? '#define LEGACY_LIGHTS' : '', + + parameters.decodeVideoTexture ? '#define DECODE_VIDEO_TEXTURE' : '', + + parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '', + + 'uniform mat4 viewMatrix;', + 'uniform vec3 cameraPosition;', + 'uniform bool isOrthographic;', + + ( parameters.toneMapping != NoToneMapping ) ? '#define TONE_MAPPING' : '', + ( parameters.toneMapping != NoToneMapping ) ? shaderChunk[ 'tonemapping_pars_fragment' ] : '', // this code is required here because it is used by the toneMapping() function defined below + ( parameters.toneMapping != NoToneMapping ) ? getToneMappingFunction( 'toneMapping', parameters.toneMapping ) : '', + + parameters.dithering ? '#define DITHERING' : '', + parameters.opaque ? '#define OPAQUE' : '', + + shaderChunk[ 'colorspace_pars_fragment' ], // this code is required here because it is used by the various encoding/decoding function defined below + getTexelEncodingFunction( 'linearToOutputTexel', parameters.outputColorSpace ), + + parameters.useDepthPacking ? '#define DEPTH_PACKING ${parameters.depthPacking}': '', + + '\n' + ].where((s) => filterEmptyLine(s)).join('\n'); + } + + vertexShader = resolveIncludes(vertexShader); + vertexShader = replaceLightNums(vertexShader, parameters); + vertexShader = replaceClippingPlaneNums(vertexShader, parameters); + + fragmentShader = resolveIncludes(fragmentShader); + fragmentShader = replaceLightNums(fragmentShader, parameters); + fragmentShader = replaceClippingPlaneNums(fragmentShader, parameters); + + vertexShader = unrollLoops(vertexShader); + fragmentShader = unrollLoops(fragmentShader); + + if (!parameters.isRawShaderMaterial) { + // GLSL 3.0 conversion for built-in materials and ShaderMaterial + versionString = "#version 300 es\n"; + + prefixVertex = '${[ + customVertexExtensions, + '#define attribute in', + '#define varying out', + '#define texture2D texture' + ].join('\n')}\n$prefixVertex'; + + prefixFragment = '${[ + '#define varying in', + (parameters.glslVersion == GLSL3) ? '' : 'layout(location = 0) out highp vec4 pc_fragColor;', + (parameters.glslVersion == GLSL3) ? '' : '#define gl_FragColor pc_fragColor', + '#define gl_FragDepthEXT gl_FragDepth', + '#define texture2D texture', + '#define textureCube texture', + '#define texture2DProj textureProj', + '#define texture2DLodEXT textureLod', + '#define texture2DProjLodEXT textureProjLod', + '#define textureCubeLodEXT textureLod', + '#define texture2DGradEXT textureGrad', + '#define texture2DProjGradEXT textureProjGrad', + '#define textureCubeGradEXT textureGrad' + ].join('\n')}\n$prefixFragment'; + } + + String vertexGlsl = versionString + prefixVertex + vertexShader; + String fragmentGlsl = versionString + prefixFragment + fragmentShader; + + final glVertexShader = AngleShader(gl, WebGL.VERTEX_SHADER, vertexGlsl); + final glFragmentShader = AngleShader(gl, WebGL.FRAGMENT_SHADER, fragmentGlsl); + + gl.attachShader(program!, glVertexShader.shader); + gl.attachShader(program!, glFragmentShader.shader); + + // Force a particular attribute to index 0. + + if (parameters.index0AttributeName != null) { + gl.bindAttribLocation(program!, 0, parameters.index0AttributeName ?? ''); + } else if (parameters.morphTargets == true) { + // programs with morphTargets displace position out of attribute 0 + gl.bindAttribLocation(program!, 0, 'position'); + } + + gl.linkProgram(program!); + onFirstUse = (AngleProgram self ) { + // check for link errors + if (renderer.debug["checkShaderErrors"]) { + final programLog = gl.getProgramInfoLog(program!)?.trim(); + final vertexLog = gl.getShaderInfoLog(glVertexShader.shader)?.trim(); + final fragmentLog = gl.getShaderInfoLog(glFragmentShader.shader)?.trim(); + + bool runnable = true; + bool haveDiagnostics = true; + + if (gl.getProgramParameter(program!, WebGL.LINK_STATUS).id == 0) { + runnable = false; + + final vertexErrors = getShaderErrors(gl, glVertexShader, 'vertex'); + final fragmentErrors = getShaderErrors(gl, glFragmentShader, 'fragment'); + + console.error('WebGLProgram: shader error: ${gl.getError()} gl.VALIDATE_STATUS ${gl.getProgramParameter(program!, WebGL.VALIDATE_STATUS)} gl.getProgramInfoLog $programLog $vertexErrors $fragmentErrors '); + } else if (programLog != '' && programLog != null) { + console.error('WebGLProgram: gl.getProgramInfoLog() programLog: $programLog vertexLog: $vertexLog fragmentLog: $fragmentLog '); + } else if (vertexLog == '' || fragmentLog == '') { + haveDiagnostics = false; + } + + if (haveDiagnostics) { + self.diagnostics = { + "runnable": runnable, + "programLog": programLog, + "vertexShader": {"log": vertexLog, "prefix": prefixVertex}, + "fragmentShader": {"log": fragmentLog, "prefix": prefixFragment} + }; + } + } + + gl.deleteShader(glVertexShader.shader); + gl.deleteShader(glFragmentShader.shader); + + cachedUniforms = AngleUniforms( gl, this ); + cachedAttributes = fetchAttributeLocations( gl, program! ); + }; + } + // set up caching for attribute locations + + AngleUniforms getUniforms() { + if ( cachedUniforms == null ) { + onFirstUse.call(this); + } + return cachedUniforms!; + } + + Map getAttributes() { + if ( cachedUniforms == null ) { + onFirstUse.call(this); + } + + return cachedAttributes!; + } + + bool get programReady => ( parameters.rendererExtensionParallelShaderCompile == false ); + set programReady(value){ + return value; + } + bool isReady() { + if ( programReady == false ) { + programReady = gl.getProgramParameter( program!, COMPLETION_STATUS_KHR ).id; + } + return programReady; + } + + // free resource + void destroy() { + bindingStates.releaseStatesOfProgram(this); + gl.deleteProgram(program!); + program = null; + } +} diff --git a/packages/three_js_angle_renderer/lib/angle/angle_program_extra.dart b/packages/three_js_angle_renderer/lib/angle/angle_program_extra.dart new file mode 100755 index 00000000..014fe0ef --- /dev/null +++ b/packages/three_js_angle_renderer/lib/angle/angle_program_extra.dart @@ -0,0 +1,424 @@ +part of three_webgl; + +class AttributeLocations{ + AttributeLocations({ + this.location, + this.locationSize = 0, + this.type = 0 + }); + + final dynamic location; + final int type;//: info.type, + //"location": gl.getAttribLocation(program, name), + final int locationSize;//: locationSize +} + +mixin AngleProgramExtra { + String handleSource(String? string, int errorLine) { + final lines = string?.split('\n') ?? []; + final lines2 = []; + + int from = math.max(errorLine - 6, 0); + int to = math.min(errorLine + 6, lines.length); + + for (int i = 0; i < lines.length; i++) { + lines[i] = "${(i + 1)}: ${lines[i]}"; + } + + for (int i = from; i < to; i++) { + lines2.add("${(i + 1)}: ${lines[i]}"); + } + + return lines2.join('\n'); + } + + List getEncodingComponents(String colorSpace) { + final workingPrimaries = ColorManagement.getPrimaries(ColorManagement.workingColorSpace); + final encodingPrimaries = ColorManagement.getPrimaries(ColorSpace.fromString(colorSpace)); + + String gamutMapping = ''; + + if ( workingPrimaries == encodingPrimaries ) { + gamutMapping = ''; + } else if ( workingPrimaries == P3Primaries && encodingPrimaries == Rec709Primaries ) { + gamutMapping = 'LinearDisplayP3ToLinearSRGB'; + } else if ( workingPrimaries == Rec709Primaries && encodingPrimaries == P3Primaries ) { + gamutMapping = 'LinearSRGBToLinearDisplayP3'; + } + + switch ( colorSpace ) { + case LinearSRGBColorSpace: + case LinearDisplayP3ColorSpace: + return [ gamutMapping, 'LinearTransferOETF' ]; + case SRGBColorSpace: + case DisplayP3ColorSpace: + return [ gamutMapping, 'sRGBTransferOETF' ]; + default: + console.warning( 'THREE.WebGLProgram: Unsupported color space: $colorSpace'); + return [ gamutMapping, 'LinearTransferOETF' ]; + } + } + + String getShaderErrors(RenderingContext gl, AngleShader shader, type) { + final status = gl.getShaderParameter(shader.shader, WebGL.COMPILE_STATUS); + final errors = (gl.getShaderInfoLog(shader.shader)??'').trim(); + + if (status && errors == '') return ''; + + final regExp = RegExp(r"ERROR: 0:(\d+)"); + final match = regExp.firstMatch(errors); + + int errorLine = int.parse(match!.group(1)!); + + // --enable-privileged-webgl-extension + // console.log( '**' + type + '**', gl.getExtension( 'WEBGL_debug_shaders' ).getTranslatedShaderSource( shader ) ); + + final source = gl.getShaderSource(shader.shader); + + return 'three.WebGLShader: gl.getShaderInfoLog() $type\n$errors\n${handleSource(source, errorLine)}'; + } + + String getTexelEncodingFunction(String functionName, String encoding) { + final components = getEncodingComponents(encoding); + return 'vec4 $functionName( vec4 value ) { return ${components[ 0 ]}( ${components[ 1 ]}( value ) ); }'; + } + + String getToneMappingFunction(functionName, toneMapping) { + String toneMappingName; + + switch (toneMapping) { + case LinearToneMapping: + toneMappingName = 'Linear'; + break; + + case ReinhardToneMapping: + toneMappingName = 'Reinhard'; + break; + + case CineonToneMapping: + toneMappingName = 'OptimizedCineon'; + break; + + case ACESFilmicToneMapping: + toneMappingName = 'ACESFilmic'; + break; + + case AgXToneMapping: + toneMappingName = 'AgX'; + break; + + case NeutralToneMapping: + toneMappingName = 'Neutral'; + break; + + case CustomToneMapping: + toneMappingName = 'Custom'; + break; + + default: + console.error('three.WebGLProgram: Unsupported toneMapping: $toneMapping'); + toneMappingName = 'Linear'; + } + + return 'vec3 $functionName( vec3 color ) { return ${toneMappingName}ToneMapping( color ); }'; + } + + String generateVertexExtensions(AngleParameters parameters) { + final chunks = [ + parameters.extensionClipCullDistance ? '#extension GL_ANGLE_clip_cull_distance : require' : '', + parameters.extensionMultiDraw ? '#extension GL_ANGLE_multi_draw : require' : '', + ]; + + return chunks.where((s) => filterEmptyLine(s)).join('\n'); + } + + String generateDefines(defines) { + final chunks = []; + + if (defines != null) { + for (final name in defines.keys) { + final value = defines[name]; + + if (value == false) continue; + + // print("WebGLProgramExtra generateDefines name: ${name} value: ${value} "); + chunks.add('#define $name $value'); + } + } + + return chunks.join('\n'); + } + + Map fetchAttributeLocations(RenderingContext gl, Program program) { + Map attributes = {}; + + final n = gl.getProgramParameter(program, WebGL.ACTIVE_ATTRIBUTES).id; + + for (int i = 0; i < n; i++) { + final info = gl.getActiveAttrib(program, i); + final name = info.name; + + // print( "three.WebGLProgram: ACTIVE VERTEX ATTRIBUTE: name: ${name} i: ${i}"); + + // attributes[name] = gl.getAttribLocation(program, name); + + int locationSize = 1; + if (info.type == WebGL.FLOAT_MAT2) locationSize = 2; + if (info.type == WebGL.FLOAT_MAT3) locationSize = 3; + if (info.type == WebGL.FLOAT_MAT4) locationSize = 4; + + // console.log( 'three.WebGLProgram: ACTIVE VERTEX ATTRIBUTE:', name, i ); + + attributes[name] = AttributeLocations( + type: info.type, + location: gl.getAttribLocation(program, name), + locationSize: locationSize + ); + } + + return attributes; + } + + bool filterEmptyLine(string) { + return string != ''; + } + + String replaceLightNums(String string, AngleParameters parameters) { + final numSpotLightCoords = parameters.numSpotLightShadows + parameters.numSpotLightMaps - parameters.numSpotLightShadowsWithMaps; + + string = string.replaceAll("NUM_DIR_LIGHTS", parameters.numDirLights.toString() ); + string = string.replaceAll("NUM_SPOT_LIGHTS", parameters.numSpotLights.toString() ); + string = string.replaceAll("NUM_SPOT_LIGHT_MAPS", parameters.numSpotLightMaps.toString() ); + string = string.replaceAll("NUM_SPOT_LIGHT_COORDS", numSpotLightCoords.toString() ); + string = string.replaceAll("NUM_RECT_AREA_LIGHTS", parameters.numRectAreaLights.toString() ); + string = string.replaceAll("NUM_POINT_LIGHTS", parameters.numPointLights.toString() ); + string = string.replaceAll("NUM_HEMI_LIGHTS", parameters.numHemiLights.toString() ); + string = string.replaceAll("NUM_DIR_LIGHT_SHADOWS", parameters.numDirLightShadows.toString() ); + string = string.replaceAll("NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS", parameters.numSpotLightShadowsWithMaps.toString() ); + string = string.replaceAll("NUM_SPOT_LIGHT_SHADOWS", parameters.numSpotLightShadows.toString() ); + string = string.replaceAll("NUM_POINT_LIGHT_SHADOWS", parameters.numPointLightShadows.toString() ); + + return string; + } + + String replaceClippingPlaneNums(String string, AngleParameters parameters) { + string = string.replaceAll("NUM_CLIPPING_PLANES", parameters.numClippingPlanes.toString()); + string = string.replaceAll("UNION_CLIPPING_PLANES", (parameters.numClippingPlanes - parameters.numClipIntersection).toString()); + + return string; + } + + // Resolve Includes + + final includePattern = RegExp(r"[ \t]*#include +<([\w\d./]+)>"); //gm; + + String resolveIncludes(String string) { + // return string.replaceAll(includePattern, includeReplacer); + + // Loop through all matches. + for (final match in includePattern.allMatches(string)) { + /// Returns the string matched by the given [group]. + /// + /// If [group] is 0, returns the match of the pattern. + /// + /// The result may be `null` if the pattern didn't assign a value to it + /// as part of this match. + // print(" resolveIncludes "); + // print(match.group(0)); // 15, then 20 + + String includeString = match.group(1)!; + + // print(" includeString: ${includeString} "); + + String targetString = shaderChunk[includeString]!; + + String targetString2 = resolveIncludes(targetString); + + String fromString = match.group(0)!; + + string = string.replaceFirst(fromString, targetString2); + } + + return string; + } + + final shaderChunkMap = {}; + + String includeReplacer(match, include) { + String? string = shaderChunk[ include ]; + + if (string == null) { + final newInclude = shaderChunkMap[include]; + if ( newInclude != null ) { + string = shaderChunk[ newInclude ]; + console.warning( 'THREE.WebGLRenderer: Shader chunk "$include" has been deprecated. Use "$newInclude" instead.'); + } else { + throw( 'Can not resolve #include <$include>' ); + } + } + + return resolveIncludes( string! ); + } + +// Unroll Loops + + final unrollLoopPattern = RegExp(r"#pragma unroll_loop_start\s+for\s*\(\s*int\s+i\s*=\s*(\d+)\s*;\s*i\s*<\s*(\d+)\s*;\s*i\s*\+\+\s*\)\s*{([\s\S]+?)}\s+#pragma unroll_loop_end"); + + String unrollLoops(String string) { + string = unrollLoopPatternReplace(string); + return string; + } + + String unrollLoopPatternReplace(String string) { + final matches = unrollLoopPattern.allMatches(string); + + for (final match in matches) { + String stringResult = ''; + + int start = int.parse(match.group(1)!); + int end = int.parse(match.group(2)!); + final snippet = match.group(3)!; + + for (int i = start; i < end; i++) { + String snippet2 = snippet.replaceAll(RegExp(r"\[\s*i\s*\]"), "[$i]"); + snippet2 = snippet2.replaceAll(RegExp(r"UNROLLED_LOOP_INDEX"), i.toString()); + stringResult = stringResult + snippet2; + } + + string = string.replaceFirst(match.group(0)!, stringResult); + } + return string; + } + + String loopReplacer(match, s, e, snippet) { + String string = ''; + + int start = int.parse(s); + int end = int.parse(e); + + for (int i = start; i < end; i++) { + snippet = snippet + ..replaceAll(RegExp(r"\[\s*i\s*\]"), '[ $i ]') + ..replaceAll(RegExp(r"UNROLLED_LOOP_INDEX"), i); + + string += snippet; + } + + return string; + } + +// + + String generatePrecision(AngleParameters parameters) { + String precisionstring = '''precision ${parameters.precision} float; + precision ${parameters.precision} int; + precision ${parameters.precision} sampler2D; + precision ${parameters.precision} samplerCube; + precision ${parameters.precision} sampler3D; + precision ${parameters.precision} sampler2DArray; + precision ${parameters.precision} sampler2DShadow; + precision ${parameters.precision} samplerCubeShadow; + precision ${parameters.precision} sampler2DArrayShadow; + precision ${parameters.precision} isampler2D; + precision ${parameters.precision} isampler3D; + precision ${parameters.precision} isamplerCube; + precision ${parameters.precision} isampler2DArray; + precision ${parameters.precision} usampler2D; + precision ${parameters.precision} usampler3D; + precision ${parameters.precision} usamplerCube; + precision ${parameters.precision} usampler2DArray; + '''; + + if ( parameters.precision == 'highp' ) { + precisionstring += '\n#define HIGH_PRECISION'; + } else if ( parameters.precision == 'mediump' ) { + precisionstring += '\n#define MEDIUM_PRECISION'; + } else if ( parameters.precision == 'lowp' ) { + precisionstring += '\n#define LOW_PRECISION'; + } + + return precisionstring; + } + + String generateShadowMapTypeDefine(AngleParameters parameters) { + String shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC'; + + if (parameters.shadowMapType == PCFShadowMap) { + shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF'; + } else if (parameters.shadowMapType == PCFSoftShadowMap) { + shadowMapTypeDefine = 'SHADOWMAP_TYPE_PCF_SOFT'; + } else if (parameters.shadowMapType == VSMShadowMap) { + shadowMapTypeDefine = 'SHADOWMAP_TYPE_VSM'; + } + + return shadowMapTypeDefine; + } + + String generateEnvMapTypeDefine(AngleParameters parameters) { + String envMapTypeDefine = 'ENVMAP_TYPE_CUBE'; + + if (parameters.envMap) { + switch (parameters.envMapMode) { + case CubeReflectionMapping: + case CubeRefractionMapping: + envMapTypeDefine = 'ENVMAP_TYPE_CUBE'; + break; + + case CubeUVReflectionMapping: + envMapTypeDefine = 'ENVMAP_TYPE_CUBE_UV'; + break; + } + } + + return envMapTypeDefine; + } + + String generateEnvMapModeDefine (AngleParameters parameters) { + String envMapModeDefine = 'ENVMAP_MODE_REFLECTION'; + + if (parameters.envMap) { + switch (parameters.envMapMode) { + case CubeRefractionMapping: + envMapModeDefine = 'ENVMAP_MODE_REFRACTION'; + break; + } + } + + return envMapModeDefine; + } + + String generateEnvMapBlendingDefine(AngleParameters parameters) { + String envMapBlendingDefine = 'ENVMAP_BLENDING_NONE'; + + if (parameters.envMap) { + switch (parameters.combine) { + case MultiplyOperation: + envMapBlendingDefine = 'ENVMAP_BLENDING_MULTIPLY'; + break; + + case MixOperation: + envMapBlendingDefine = 'ENVMAP_BLENDING_MIX'; + break; + + case AddOperation: + envMapBlendingDefine = 'ENVMAP_BLENDING_ADD'; + break; + } + } + + return envMapBlendingDefine; + } + + Map? generateCubeUVSize(AngleParameters parameters) { + final imageHeight = parameters.envMapCubeUVHeight; + + if (imageHeight == null) return null; + + int maxMip = MathUtils.log2(imageHeight).toInt() - 2; + + final texelHeight = 1.0 / imageHeight; + final texelWidth = 1.0 / (3 * math.max(math.pow(2, maxMip), 7 * 16)); + + return {"texelWidth": texelWidth, "texelHeight": texelHeight, "maxMip": maxMip}; + } +} diff --git a/packages/three_js_angle_renderer/lib/angle/angle_programs.dart b/packages/three_js_angle_renderer/lib/angle/angle_programs.dart new file mode 100755 index 00000000..c007fb66 --- /dev/null +++ b/packages/three_js_angle_renderer/lib/angle/angle_programs.dart @@ -0,0 +1,509 @@ +part of three_webgl; + +class AnglePrograms { + final shaderIDs = { + "MeshDepthMaterial": 'depth', + "MeshDistanceMaterial": 'distanceRGBA', + "MeshNormalMaterial": 'normal', + "MeshBasicMaterial": 'basic', + "MeshLambertMaterial": 'lambert', + "MeshPhongMaterial": 'phong', + "MeshToonMaterial": 'toon', + "MeshStandardMaterial": 'physical', + "MeshPhysicalMaterial": 'physical', + "MeshMatcapMaterial": 'matcap', + "LineBasicMaterial": 'basic', + "LineDashedMaterial": 'dashed', + "PointsMaterial": 'points', + "ShadowMaterial": 'shadow', + "SpriteMaterial": 'sprite' + }; + + AngleRenderer renderer; + AngleCubeMaps cubemaps; + AngleCubeUVMaps cubeuvmaps; + AngleExtensions extensions; + AngleCapabilities capabilities; + AngleBindingStates bindingStates; + AngleClipping clipping; + + final _programLayers = Layers(); + final _customShaders = AngleShaderCache(); + List programs = []; + final List _activeChannels = []; + + late bool logarithmicDepthBuffer; + late bool vertexTextures; + late String precision; + bool _didDispose = false; + + AnglePrograms(this.renderer, this.cubemaps, this.cubeuvmaps, this.extensions, this.capabilities, this.bindingStates, this.clipping) { + logarithmicDepthBuffer = capabilities.logarithmicDepthBuffer; + vertexTextures = capabilities.vertexTextures; + + precision = capabilities.precision; + } + + void dispose(){ + if(_didDispose) return; + _didDispose = true; + renderer.dispose(); + cubemaps.dispose(); + extensions.dispose(); + capabilities.dispose(); + bindingStates.dispose(); + clipping.dispose(); + _customShaders.dispose(); + programs.clear(); + } + + String getChannel(int value ) { + _activeChannels.add( value ); + if ( value == 0 ) return 'uv'; + return 'uv$value'; + } + + AngleParameters getParameters(Material material, LightState lights, List shadows, Scene scene, Object3D object) { + final fog = scene.fog; + final geometry = object.geometry; + final environment = material is MeshStandardMaterial ? scene.environment : null; + + Texture? envMap = material is MeshStandardMaterial?cubeuvmaps.get(material.envMap ?? environment):cubemaps.get(material.envMap ?? environment); + + final envMapCubeUVHeight = (envMap != null) && (envMap.mapping == CubeUVReflectionMapping) ? envMap.image?.height : null; + + final shaderID = shaderIDs[material.shaderID]; + + // heuristics to create shader parameters according to lights in the scene + // (not to blow over maxLights budget) + + if (material.precision != null) { + precision = capabilities.getMaxPrecision(material.precision); + + if (precision != material.precision) { + console.warning('WebGLProgram.getParameters: ${material.precision} not supported, using $precision instead.'); + } + } + + final morphAttribute = geometry?.morphAttributes["position"] ?? geometry?.morphAttributes["normal"] ?? geometry?.morphAttributes["color"]; + final morphTargetsCount = (morphAttribute != null) ? morphAttribute.length : 0; + + int morphTextureStride = 0; + + if (geometry?.morphAttributes["position"] != null) morphTextureStride = 1; + if (geometry?.morphAttributes["normal"] != null) morphTextureStride = 2; + if (geometry?.morphAttributes["color"] != null) morphTextureStride = 3; + + // + + String? vertexShader, fragmentShader; + dynamic customVertexShaderID; + dynamic customFragmentShaderID; + + if (shaderID != null) { + final shader = shaderLib[shaderID]; + vertexShader = shader["vertexShader"]; + fragmentShader = shader["fragmentShader"]; + } else { + vertexShader = material.vertexShader; + fragmentShader = material.fragmentShader; + + _customShaders.update(material); + + customVertexShaderID = _customShaders.getVertexShaderID(material); + customFragmentShaderID = _customShaders.getFragmentShaderID(material); + } + + // print(" WebGLPrograms material : ${material.type} ${material.shaderID} ${material.id} object: ${object.type} ${object.id} shaderID: ${shaderID} vertexColors: ${material.vertexColors} "); + + final currentRenderTarget = renderer.getRenderTarget(); + + final useAlphaTest = material.alphaTest > 0; + final useClearcoat = material.clearcoat > 0; + + final parameters = AngleParameters( + shaderID: shaderID, + shaderType: material.type, + shaderName: "${material.type} - ${material.name}", + + vertexShader: vertexShader ?? '', + fragmentShader: fragmentShader ?? '', + defines: material.defines, + + customVertexShaderID: customVertexShaderID, + customFragmentShaderID: customFragmentShaderID, + + isRawShaderMaterial: material is RawShaderMaterial, + glslVersion: material.glslVersion, + + precision: precision, + + batching: object is BatchedMesh, + instancing: object is InstancedMesh, + instancingColor: object is InstancedMesh && object.instanceColor != null, + instancingMorph: object is InstancedMesh && object.morphTexture != null, + + supportsVertexTextures: vertexTextures, + outputColorSpace: ( currentRenderTarget == null ) ? renderer.outputColorSpace : ( currentRenderTarget.isXRRenderTarget? currentRenderTarget.texture.colorSpace : LinearSRGBColorSpace ), + alphaToCoverage: !! material.alphaToCoverage, + + map: material.map != null, + matcap: material.matcap != null, + envMap: envMap != null, + envMapMode: envMap?.mapping, + envMapCubeUVHeight: envMapCubeUVHeight, + aoMap: material.aoMap != null, + lightMap: material.lightMap != null, + bumpMap: material.bumpMap != null, + normalMap: material.normalMap != null, + displacementMap: capabilities.vertexTextures && material.displacementMap != null, + emissiveMap: material.emissiveMap != null, + + normalMapObjectSpace: material.normalMap != null && material.normalMapType == ObjectSpaceNormalMap, + normalMapTangentSpace: material.normalMap != null && material.normalMapType == TangentSpaceNormalMap, + + metalnessMap: material.metalnessMap != null, + roughnessMap: material.roughnessMap != null, + + anisotropy: material is MeshPhysicalMaterial && material.anisotropy > 0, + anisotropyMap: material is MeshPhysicalMaterial && material.anisotropy > 0 && material.anisotropyMap != null, + + clearcoat: useClearcoat, + clearcoatMap: useClearcoat && material.clearcoatMap != null, + clearcoatNormalMap: useClearcoat && material.clearcoatRoughnessMap != null, + clearcoatRoughnessMap: useClearcoat && material.clearcoatNormalMap != null, + + dispersion: material is MeshPhysicalMaterial && material.dispersion > 0, + + iridescence: material is MeshPhysicalMaterial && material.iridescence > 0, + iridescenceMap: material is MeshPhysicalMaterial && material.iridescence > 0 && material.iridescenceMap != null, + iridescenceThicknessMap: material is MeshPhysicalMaterial && material.iridescence > 0 && material.iridescenceThicknessMap != null, + + sheen: material.sheen > 0, + sheenColorMap: material.sheenColorMap != null, + sheenRoughnessMap: material.sheenRoughnessMap != null, + + specularMap: material.specularMap != null, + specularColorMap: material.specularColorMap != null, + specularIntensityMap: material.specularIntensityMap != null, + + transmission: material.transmission > 0, + transmissionMap: material.transmissionMap != null, + thicknessMap: material.thicknessMap != null, + + gradientMap: material.gradientMap != null, + + opaque: !material.transparent && material.blending == NormalBlending && !material.alphaToCoverage, + + alphaMap: material.alphaMap != null, + alphaTest: useAlphaTest, + alphaHash: material.alphaHash, + + combine: material.combine, + + // + + mapUv: material.map ==null?null: getChannel( material.map!.channel ), + aoMapUv: material.aoMap ==null?null:getChannel( material.aoMap!.channel ), + lightMapUv: material.lightMap ==null?null:getChannel( material.lightMap!.channel ), + bumpMapUv: material.bumpMap ==null?null:getChannel( material.bumpMap!.channel ), + normalMapUv:material.normalMap ==null?null:getChannel( material.normalMap!.channel ), + displacementMapUv: material.displacementMap ==null?null:getChannel( material.displacementMap!.channel ), + emissiveMapUv: material.emissiveMap ==null?null:getChannel( material.emissiveMap!.channel ), + + metalnessMapUv: material.metalnessMap ==null?null:getChannel( material.metalnessMap!.channel ), + roughnessMapUv: material.roughnessMap ==null?null:getChannel( material.roughnessMap!.channel ), + + anisotropyMapUv: material.anisotropyMap==null?null:getChannel( material.anisotropyMap!.channel ), + + clearcoatMapUv: material.clearcoatMap ==null?null:getChannel( material.clearcoatMap!.channel ), + clearcoatNormalMapUv: material.clearcoatNormalMap ==null?null:getChannel( material.clearcoatNormalMap!.channel ), + clearcoatRoughnessMapUv: material.clearcoatRoughnessMap ==null?null:getChannel( material.clearcoatRoughnessMap!.channel ), + + iridescenceMapUv: material.iridescenceMap ==null?null:getChannel( material.iridescenceMap!.channel ), + iridescenceThicknessMapUv: material.iridescenceThicknessMap ==null?null:getChannel( material.iridescenceThicknessMap!.channel ), + + sheenColorMapUv: material.sheenColorMap ==null?null:getChannel( material.sheenColorMap!.channel ), + sheenRoughnessMapUv: material.sheenRoughnessMap ==null?null:getChannel( material.sheenRoughnessMap!.channel ), + + specularMapUv: material.specularMap ==null?null:getChannel( material.specularMap!.channel ), + specularColorMapUv: material.specularColorMap ==null?null:getChannel( material.specularColorMap!.channel ), + specularIntensityMapUv: material.specularIntensityMap ==null?null:getChannel( material.specularIntensityMap!.channel ), + + transmissionMapUv: material.transmissionMap == null?null:getChannel( material.transmissionMap!.channel ), + thicknessMapUv: material.thicknessMap ==null?null:getChannel( material.thicknessMap!.channel ), + + alphaMapUv: material.alphaMap ==null?null:getChannel( material.alphaMap!.channel ), + + // + + vertexTangents: (material.normalMap != null && geometry != null && geometry.attributes["tangent"] != null), + vertexColors: material.vertexColors, + vertexAlphas: material.vertexColors == true && + geometry != null && + geometry.attributes["color"] != null && + geometry.attributes["color"].itemSize == 4, + + pointsUvs: object is Points && geometry?.attributes['uv'] != null && ( material.map != null || material.alphaMap != null ), + + fog: fog != null, + useFog: material.fog, + fogExp2: (fog != null && fog.isFogExp2), + + flatShading: material.flatShading, + + sizeAttenuation: material.sizeAttenuation, + logarithmicDepthBuffer: logarithmicDepthBuffer, + + skinning: object is SkinnedMesh, + + morphTargets: geometry?.morphAttributes['position'] != null, + morphNormals: geometry?.morphAttributes['normal'] != null, + morphColors: geometry?.morphAttributes['color'] != null, + morphTargetsCount: morphTargetsCount, + morphTextureStride: morphTextureStride, + + numDirLights: lights.directional.length, + numPointLights: lights.point.length, + numSpotLights: lights.spot.length, + numSpotLightMaps: lights.spotLightMap.length, + numRectAreaLights: lights.rectArea.length, + numHemiLights: lights.hemi.length, + + numDirLightShadows: lights.directionalShadowMap.length, + numPointLightShadows: lights.pointShadowMap.length, + numSpotLightShadows: lights.spotShadowMap.length, + numSpotLightShadowsWithMaps: lights.numSpotLightShadowsWithMaps, + + numLightProbes: lights.numLightProbes, + + numClippingPlanes: clipping.numPlanes, + numClipIntersection: clipping.numIntersection, + + dithering: material.dithering, + + shadowMapEnabled: renderer.shadowMap.enabled && shadows.length > 0, + shadowMapType: renderer.shadowMap.type, + + toneMapping: material.toneMapped ? renderer.toneMapping : NoToneMapping, + useLegacyLights: renderer.useLegacyLights, + + decodeVideoTexture: material.map != null && + ( material.map is VideoTexture) && + ( ColorManagement.getTransfer( ColorSpace.fromString(material.map!.colorSpace) ) == SRGBTransfer ), + + premultipliedAlpha: material.premultipliedAlpha, + + doubleSided: material.side == DoubleSide, + flipSided: material.side == BackSide, + + useDepthPacking: (material.depthPacking ?? 0) >= 0, + depthPacking: material.depthPacking ?? 0, + + index0AttributeName: material.index0AttributeName, + + extensionClipCullDistance: material.extensions != null && material.extensions?['clipCullDistance'] == true && extensions.has( 'WEBGL_clip_cull_distance' ), + extensionMultiDraw: material.extensions != null && material.extensions?['multiDraw'] == true && extensions.has( 'WEBGL_multi_draw' ), + + rendererExtensionParallelShaderCompile: extensions.has( 'KHR_parallel_shader_compile' ), + + customProgramCacheKey: material.customProgramCacheKey() + ); + + parameters.vertexUv1s = _activeChannels.contains( 1 ); + parameters.vertexUv2s = _activeChannels.contains( 2 ); + parameters.vertexUv3s = _activeChannels.contains( 3 ); + + _activeChannels.clear(); + + return parameters; + } + + String getProgramCacheKey(AngleParameters parameters) { + List array = []; + + if (parameters.shaderID != null) { + array.add(parameters.shaderID!); + } else { + array.add(parameters.customVertexShaderID); + array.add(parameters.customFragmentShaderID); + } + + if (parameters.defines != null) { + for (final name in parameters.defines!.keys) { + array.add(name); + array.add(parameters.defines![name].toString()); + } + } + + if (parameters is! RawShaderMaterial) { + getProgramCacheKeyParameters(array, parameters); + getProgramCacheKeyBooleans(array, parameters); + + array.add(renderer.outputEncoding.toString()); + } + array.add(parameters.customProgramCacheKey); + + return array.join(); + } + + void getProgramCacheKeyParameters(List array, AngleParameters parameters) { + array.add( parameters.precision ); + array.add( parameters.outputColorSpace ); + array.add( parameters.envMapMode ); + array.add( parameters.envMapCubeUVHeight ); + array.add( parameters.mapUv ); + array.add( parameters.alphaMapUv ); + array.add( parameters.lightMapUv ); + array.add( parameters.aoMapUv ); + array.add( parameters.bumpMapUv ); + array.add( parameters.normalMapUv ); + array.add( parameters.displacementMapUv ); + array.add( parameters.emissiveMapUv ); + array.add( parameters.metalnessMapUv ); + array.add( parameters.roughnessMapUv ); + array.add( parameters.anisotropyMapUv ); + array.add( parameters.clearcoatMapUv ); + array.add( parameters.clearcoatNormalMapUv ); + array.add( parameters.clearcoatRoughnessMapUv ); + array.add( parameters.iridescenceMapUv ); + array.add( parameters.iridescenceThicknessMapUv ); + array.add( parameters.sheenColorMapUv ); + array.add( parameters.sheenRoughnessMapUv ); + array.add( parameters.specularMapUv ); + array.add( parameters.specularColorMapUv ); + array.add( parameters.specularIntensityMapUv ); + array.add( parameters.transmissionMapUv ); + array.add( parameters.thicknessMapUv ); + array.add( parameters.combine ); + array.add( parameters.fogExp2 ); + array.add( parameters.sizeAttenuation ); + array.add( parameters.morphTargetsCount ); + array.add( parameters.morphAttributeCount ); + array.add( parameters.numDirLights ); + array.add( parameters.numPointLights ); + array.add( parameters.numSpotLights ); + array.add( parameters.numSpotLightMaps ); + array.add( parameters.numHemiLights ); + array.add( parameters.numRectAreaLights ); + array.add( parameters.numDirLightShadows ); + array.add( parameters.numPointLightShadows ); + array.add( parameters.numSpotLightShadows ); + array.add( parameters.numSpotLightShadowsWithMaps ); + array.add( parameters.numLightProbes ); + array.add( parameters.shadowMapType ); + array.add( parameters.toneMapping ); + array.add( parameters.numClippingPlanes ); + array.add( parameters.numClipIntersection ); + array.add( parameters.depthPacking ); + } + + void getProgramCacheKeyBooleans(List array, AngleParameters parameters) { + + _programLayers.disableAll(); + + if ( parameters.supportsVertexTextures )_programLayers.enable( 0 ); + if ( parameters.instancing )_programLayers.enable( 1 ); + if ( parameters.instancingColor )_programLayers.enable( 2 ); + if ( parameters.instancingMorph )_programLayers.enable( 3 ); + if ( parameters.matcap )_programLayers.enable( 4 ); + if ( parameters.envMap )_programLayers.enable( 5 ); + if ( parameters.normalMapObjectSpace )_programLayers.enable( 6 ); + if ( parameters.normalMapTangentSpace )_programLayers.enable( 7 ); + if ( parameters.clearcoat )_programLayers.enable( 8 ); + if ( parameters.iridescence )_programLayers.enable( 9 ); + if ( parameters.alphaTest )_programLayers.enable( 10 ); + if ( parameters.vertexColors )_programLayers.enable( 11 ); + if ( parameters.vertexAlphas )_programLayers.enable( 12 ); + if ( parameters.vertexUv1s )_programLayers.enable( 13 ); + if ( parameters.vertexUv2s )_programLayers.enable( 14 ); + if ( parameters.vertexUv3s )_programLayers.enable( 15 ); + if ( parameters.vertexTangents )_programLayers.enable( 16 ); + if ( parameters.anisotropy )_programLayers.enable( 17 ); + if ( parameters.alphaHash )_programLayers.enable( 18 ); + if ( parameters.batching )_programLayers.enable( 19 ); + if ( parameters.dispersion )_programLayers.enable( 20 ); + if ( parameters.batchingColor )_programLayers.enable( 21 ); + + array.add( _programLayers.mask ); + _programLayers.disableAll(); + + if ( parameters.fog )_programLayers.enable( 0 ); + if ( parameters.useFog )_programLayers.enable( 1 ); + if ( parameters.flatShading )_programLayers.enable( 2 ); + if ( parameters.logarithmicDepthBuffer )_programLayers.enable( 3 ); + if ( parameters.skinning )_programLayers.enable( 4 ); + if ( parameters.morphTargets )_programLayers.enable( 5 ); + if ( parameters.morphNormals )_programLayers.enable( 6 ); + if ( parameters.morphColors )_programLayers.enable( 7 ); + if ( parameters.premultipliedAlpha )_programLayers.enable( 8 ); + if ( parameters.shadowMapEnabled )_programLayers.enable( 9 ); + if ( parameters.useLegacyLights )_programLayers.enable( 10 ); + if ( parameters.doubleSided )_programLayers.enable( 11 ); + if ( parameters.flipSided )_programLayers.enable( 12 ); + if ( parameters.useDepthPacking )_programLayers.enable( 13 ); + if ( parameters.dithering )_programLayers.enable( 14 ); + if ( parameters.transmission )_programLayers.enable( 15 ); + if ( parameters.sheen )_programLayers.enable( 16 ); + if ( parameters.opaque )_programLayers.enable( 17 ); + if ( parameters.pointsUvs )_programLayers.enable( 18 ); + if ( parameters.decodeVideoTexture )_programLayers.enable( 19 ); + if ( parameters.decodeVideoTextureEmissive )_programLayers.enable( 20 ); + if ( parameters.alphaToCoverage )_programLayers.enable( 21 ); + + array.add( _programLayers.mask ); + } + + Map getUniforms(Material material) { + String? shaderID = shaderIDs[material.shaderID]; + Map uniforms; + + if (shaderID != null) { + final shader = shaderLib[shaderID]; + uniforms = cloneUniforms(shader["uniforms"]); + } else { + uniforms = material.uniforms; + } + + return uniforms; + } + + AngleProgram? acquireProgram(AngleParameters parameters, String cacheKey) { + AngleProgram? program; + + // Check if code has been already compiled + for (int p = 0, pl = programs.length; p < pl; p++) { + final preexistingProgram = programs[p]; + + if (preexistingProgram.cacheKey == cacheKey) { + program = preexistingProgram; + ++program.usedTimes; + + break; + } + } + + if (program == null) { + program = AngleProgram(renderer, cacheKey, parameters, bindingStates); + programs.add(program); + } + + return program; + } + + void releaseProgram(AngleProgram program) { + if (--program.usedTimes == 0) { + // Remove from unordered set + final i = programs.indexOf(program); + programs[i] = programs[programs.length - 1]; + programs.removeLast(); + + // Free WebGL resources + program.destroy(); + } + } + + void releaseShaderCache(Material material) { + _customShaders.remove(material); + } +} diff --git a/packages/three_js_angle_renderer/lib/angle/angle_properties.dart b/packages/three_js_angle_renderer/lib/angle/angle_properties.dart new file mode 100755 index 00000000..65482afa --- /dev/null +++ b/packages/three_js_angle_renderer/lib/angle/angle_properties.dart @@ -0,0 +1,38 @@ +part of three_webgl; + +class AngleProperties { + final properties = WeakMap?>(); + + bool has( object ) { + return properties.has( object ); + } + + Map get(object) { + Map map; + + if (!properties.contains(object)) { + map = {}; + properties[object] = map; + } + else { + map = properties[object]!; + } + + return map; + } + + void remove(object) { + properties.remove(object); + } + + void update(object, key, value) { + // final m = properties[object]!; + // m[key] = value; + + properties.get( object )![ key ] = value; + } + + void dispose() { + properties.clear(); + } +} diff --git a/packages/three_js_angle_renderer/lib/angle/angle_render_list.dart b/packages/three_js_angle_renderer/lib/angle/angle_render_list.dart new file mode 100755 index 00000000..5f4c2409 --- /dev/null +++ b/packages/three_js_angle_renderer/lib/angle/angle_render_list.dart @@ -0,0 +1,228 @@ +part of three_webgl; + +class RenderItem { + int id = 0; + Object3D? object; + BufferGeometry? geometry; + Material? material; + dynamic program; + int groupOrder = 0; + int renderOrder = 0; + double z = 0; + Map? group; + + void dispose(){ + material?.dispose(); + object?.dispose(); + geometry?.dispose(); + } + RenderItem({ + this.id = 0, + this.object, + this.geometry, + this.material, + this.program, + this.groupOrder = 0, + this.renderOrder = 0, + this.z = 0, + this.group + }); + RenderItem.fromMap(Map json) { + if (json["id"] != null) { + id = json["id"]; + } + if (json["object"] != null) { + object = json["object"]; + } + if (json["geometry"] != null) { + geometry = json["geometry"]; + } + if (json["material"] != null) { + material = json["material"]; + } + if (json["program"] != null) { + program = json["program"]; + } + if (json["groupOrder"] != null) { + groupOrder = json["groupOrder"]; + } + + if (json["renderOrder"] != null) { + renderOrder = json["renderOrder"]; + } + if (json["z"] != null) { + z = json["z"]; + } + if (json["group"] != null) { + group = json["group"]; + } + } +} + +class AngleRenderList { + AngleRenderList(); + + Map renderItems = {}; + int renderItemsIndex = 0; + + List opaque = []; + List transmissive = []; + List transparent = []; + + final defaultProgram = DefaultProgram(); + + void init() { + renderItemsIndex = 0; + opaque.clear(); + transmissive.clear(); + transparent.clear(); + } + + void dispose(){ + for(final key in renderItems.keys){ + renderItems[key]?.dispose(); + } + for(final o in opaque){ + o.dispose(); + } + for(final t in transmissive){ + t.dispose(); + } + for(final t in transparent){ + t.dispose(); + } + } + + RenderItem getNextRenderItem( + Object3D object, + BufferGeometry? geometry, + Material? material, + int groupOrder, + double z, + Map? group + ) { + RenderItem? renderItem = renderItems[renderItemsIndex]; + + if (renderItem == null) { + renderItem = RenderItem.fromMap({ + "id": object.id, + "object": object, + "geometry": geometry, + "material": material, + "groupOrder": groupOrder, + "renderOrder": object.renderOrder, + "z": z, + "group": group + }); + } + else { + renderItem = RenderItem( + id: object.id, + object: object, + geometry: geometry, + material: material, + groupOrder: groupOrder, + renderOrder: object.renderOrder, + z: z, + group: group + ); + } + + renderItems[renderItemsIndex] = renderItem; + renderItemsIndex++; + + return renderItem; + } + + void push(Object3D object, BufferGeometry geometry, Material material, int groupOrder, double z, Map? group) { + final renderItem = getNextRenderItem(object, geometry, material, groupOrder, z, group); + + if (material.transmission > 0.0) { + transmissive.add(renderItem); + } + else { + if (material.transparent) { + transparent.add(renderItem); + } + else { + opaque.add(renderItem); + } + } + } + + void unshift(Object3D object, BufferGeometry? geometry, Material? material, int groupOrder, double z, Map? group) { + final renderItem = getNextRenderItem(object, geometry, material, groupOrder, z, group); + + if ((material?.transmission ?? 0) > 0.0) { + transmissive.insert(0, renderItem); + } + else { + if (material?.transparent == true) { + transparent.insert(0, renderItem); + } + else { + opaque.insert(0, renderItem); + } + } + } + + void sort(customOpaqueSort, customTransparentSort) { + if (opaque.length > 1) { + opaque.sort(customOpaqueSort ?? painterSortStable); + } + + if (transmissive.length > 1) { + transmissive.sort(customTransparentSort ?? reversePainterSortStable); + } + + if (transparent.length > 1) { + transparent.sort(customTransparentSort ?? reversePainterSortStable); + } + } + + void finish() { + // Clear references from inactive renderItems in the list + + for (int i = renderItemsIndex, il = renderItems.length; i < il; i++) { + final renderItem = renderItems[i]!; + + if (renderItem.id == 0) break; + + renderItem.id = 0; + renderItem.object = null; + renderItem.geometry = null; + renderItem.material = null; + renderItem.program = null; + renderItem.group = null; + } + } + + int painterSortStable(RenderItem a, RenderItem b) { + if (a.groupOrder != b.groupOrder) { + return a.groupOrder - b.groupOrder; + } else if (a.renderOrder != b.renderOrder) { + return (a.renderOrder - b.renderOrder) > 0 ? 1 : -1; + } else if (a.program != b.program) { + return a.program.id - b.program.id; + } else if (a.material!.id != b.material!.id) { + return a.material!.id - b.material!.id; + } else if (a.z != b.z) { + return (a.z - b.z) > 0 ? 1 : -1; + } else { + return a.id - b.id; + } + } + + int reversePainterSortStable(RenderItem a, RenderItem b) { + if (a.groupOrder != b.groupOrder) { + return a.groupOrder - b.groupOrder; + } else if (a.renderOrder != b.renderOrder) { + return a.renderOrder - b.renderOrder; + } else if (a.z != b.z) { + final v = b.z - a.z; + return v > 0 ? 1 : -1; + } else { + return a.id - b.id; + } + } +} diff --git a/packages/three_js_angle_renderer/lib/angle/angle_render_lists.dart b/packages/three_js_angle_renderer/lib/angle/angle_render_lists.dart new file mode 100755 index 00000000..0245a487 --- /dev/null +++ b/packages/three_js_angle_renderer/lib/angle/angle_render_lists.dart @@ -0,0 +1,30 @@ +part of three_webgl; + +class AngleRenderLists { + AngleRenderLists(); + + WeakMap lists = WeakMap(); + + AngleRenderList get(scene, renderCallDepth) { + final listArray = lists.get( scene ); + dynamic list; + + if (lists.has(scene) == false) { + list = AngleRenderList(); + lists.add(key: scene, value: [list]); + } else { + if (renderCallDepth >= listArray.length) { + list = AngleRenderList(); + listArray.add(list); + } else { + list = listArray[renderCallDepth]; + } + } + + return list; + } + + void dispose() { + lists.clear(); + } +} diff --git a/packages/three_js_angle_renderer/lib/angle/angle_render_states.dart b/packages/three_js_angle_renderer/lib/angle/angle_render_states.dart new file mode 100755 index 00000000..453147d2 --- /dev/null +++ b/packages/three_js_angle_renderer/lib/angle/angle_render_states.dart @@ -0,0 +1,92 @@ +part of three_webgl; + +class AngleRenderState { + bool _didDispose = false; + late AngleLights lights; + AngleExtensions extensions; + List lightsArray = []; + List shadowsArray = []; + Map transmissionRenderTarget = {}; + late RenderState _renderState; + + AngleRenderState(this.extensions) { + lights = AngleLights(extensions); + _renderState = RenderState(lights, lightsArray, shadowsArray, null, {}); + } + + RenderState get state { + return _renderState; + } + + void dispose(){ + if(_didDispose) return; + _didDispose = true; + lightsArray.clear(); + shadowsArray.clear(); + lights.dispose(); + lights.dispose(); + extensions.dispose(); + } + + void init(Camera camera) { + state.camera = camera; + + lightsArray.length = 0; + shadowsArray.length = 0; + } + + void pushLight(Light light) { + lightsArray.add(light); + } + + void pushShadow(Light shadowLight) { + shadowsArray.add(shadowLight); + } + + void setupLights([bool? physicallyCorrectLights]) { + lights.setup(lightsArray, physicallyCorrectLights); + } + + void setupLightsView(Camera camera) { + lights.setupView(lightsArray, camera); + } +} + +class AngleRenderStates { + AngleExtensions extensions; + WeakMap renderStates = WeakMap(); + + AngleRenderStates(this.extensions); + + AngleRenderState get(Object3D scene, {int renderCallDepth = 0}) { + AngleRenderState renderState; + + if (!renderStates.has(scene)) { + renderState = AngleRenderState(extensions); + renderStates.add(key: scene, value: [renderState]); + } else { + if (renderCallDepth >= renderStates.get(scene).length) { + renderState = AngleRenderState(extensions); + renderStates.get(scene).add(renderState); + } else { + renderState = renderStates.get(scene)[renderCallDepth]; + } + } + + return renderState; + } + + void dispose() { + renderStates.clear(); + } +} + +class RenderState { + AngleLights lights; + List lightsArray; + List shadowsArray; + Camera? camera; + Map transmissionRenderTarget; + + RenderState(this.lights, this.lightsArray, this.shadowsArray, this.camera, this.transmissionRenderTarget); +} diff --git a/packages/three_js_angle_renderer/lib/angle/angle_shader.dart b/packages/three_js_angle_renderer/lib/angle/angle_shader.dart new file mode 100755 index 00000000..a5d4c30c --- /dev/null +++ b/packages/three_js_angle_renderer/lib/angle/angle_shader.dart @@ -0,0 +1,19 @@ +part of three_webgl; + +class AngleShader { + RenderingContext gl; + dynamic shader; + String content; + + AngleShader(this.gl, int type, this.content) { + shader = gl.createShader(type); + + gl.shaderSource(shader, content); + gl.compileShader(shader); + + final status = gl.getShaderParameter(shader, WebGL.COMPILE_STATUS); + if (!status) { + throw (" WebGLShader comile error.... _status: $content $status ${gl.getShaderInfoLog(shader)} "); + } + } +} diff --git a/packages/three_js_angle_renderer/lib/angle/angle_shader_cache.dart b/packages/three_js_angle_renderer/lib/angle/angle_shader_cache.dart new file mode 100755 index 00000000..0a54f14d --- /dev/null +++ b/packages/three_js_angle_renderer/lib/angle/angle_shader_cache.dart @@ -0,0 +1,92 @@ +part of three_webgl; + +int _id = 0; + +class AngleShaderCache { + final shaderCache = {}; + final materialCache = {}; + + AngleShaderCache(); + + AngleShaderCache update(Material material) { + final vertexShader = material.vertexShader; + final fragmentShader = material.fragmentShader; + + final vertexShaderStage = _getShaderStage(vertexShader!); + final fragmentShaderStage = _getShaderStage(fragmentShader!); + + final materialShaders = _getShaderCacheForMaterial(material); + + if (materialShaders.contains(vertexShaderStage) == false) { + materialShaders.add(vertexShaderStage); + vertexShaderStage.usedTimes++; + } + + if (materialShaders.contains(fragmentShaderStage) == false) { + materialShaders.add(fragmentShaderStage); + fragmentShaderStage.usedTimes++; + } + + return this; + } + + AngleShaderCache remove(Material material) { + final materialShaders = materialCache[material]; + if(materialShaders != null){ + for (final shaderStage in materialShaders) { + shaderStage.usedTimes--; + + if (shaderStage.usedTimes == 0) shaderCache.remove(shaderStage.code); + } + } + + materialCache.remove(material); + + return this; + } + + getVertexShaderID(Material material) { + return _getShaderStage(material.vertexShader!).id; + } + + getFragmentShaderID(Material material) { + return _getShaderStage(material.fragmentShader!).id; + } + + void dispose() { + shaderCache.clear(); + materialCache.clear(); + } + + _getShaderCacheForMaterial(Material material) { + final cache = materialCache; + + if (cache.containsKey(material) == false) { + cache[material] = []; + } + + return cache[material]; + } + + _getShaderStage(String code) { + final cache = shaderCache; + + if (cache.containsKey(code) == false) { + final stage = WebGLShaderStage(code); + cache[code] = stage; + } + + return cache[code]; + } +} + +class WebGLShaderStage { + late int id; + late int usedTimes; + late String code; + + WebGLShaderStage(this.code) { + id = _id++; + usedTimes = 0; + } +} diff --git a/packages/three_js_angle_renderer/lib/angle/angle_shadow_map.dart b/packages/three_js_angle_renderer/lib/angle/angle_shadow_map.dart new file mode 100755 index 00000000..c559b4f0 --- /dev/null +++ b/packages/three_js_angle_renderer/lib/angle/angle_shadow_map.dart @@ -0,0 +1,348 @@ +part of three_webgl; + +class AngleShadowMap { + bool _didDispose = false; + Frustum _frustum = Frustum(); + final _shadowMapSize = Vector2.zero(); + final _viewportSize = Vector2.zero(); + final _viewport = Vector4.identity(); + + final shadowSide = {0: BackSide, 1: FrontSide, 2: DoubleSide}; + + // HashMap _depthMaterials = HashMap(); + // HashMap _distanceMaterials = HashMap(); + + late MeshDepthMaterial _depthMaterial; + late MeshDistanceMaterial _distanceMaterial; + + final _materialCache = {}; + + late ShaderMaterial shadowMaterialVertical; + late ShaderMaterial shadowMaterialHorizontal; + + BufferGeometry fullScreenTri = BufferGeometry(); + + late Mesh fullScreenMesh; + + bool enabled = false; + + bool autoUpdate = true; + bool needsUpdate = false; + + int type = PCFShadowMap; + + late AngleShadowMap scope; + + final AngleRenderer _renderer; + final AngleObjects _objects; + final AngleCapabilities _capabilities; + late int _maxTextureSize; + + late int _previousType; + + AngleShadowMap(this._renderer, this._objects, this._capabilities) { + _previousType = type; + _maxTextureSize = _capabilities.maxTextureSize; + + _depthMaterial = MeshDepthMaterial.fromMap({"depthPacking": RGBADepthPacking}); + _distanceMaterial = MeshDistanceMaterial(null); + + shadowMaterialVertical = ShaderMaterial.fromMap({ + "defines": {"VSM_SAMPLES": 8}, + "uniforms": { + "shadow_pass": {"value": null}, + "resolution": {"value": Vector2.zero()}, + "radius": {"value": 4.0} + }, + "vertexShader": vsmVert, + "fragmentShader": vsmFrag + }); + + final float32List = Float32List.fromList([-1.0, -1.0, 0.5, 3.0, -1.0, 0.5, -1.0, 3.0, 0.5]); + + fullScreenTri.setAttributeFromString('position', Float32BufferAttribute.fromList(float32List, 3, false)); + + fullScreenMesh = Mesh(fullScreenTri, shadowMaterialVertical); + + shadowMaterialHorizontal = shadowMaterialVertical.clone(); + shadowMaterialHorizontal.defines!["HORIZONTAL_PASS"] = 1; + + scope = this; + } + + void dispose(){ + if(_didDispose) return; + _didDispose = true; + fullScreenMesh.dispose(); + fullScreenTri.dispose(); + + _depthMaterial.dispose(); + _distanceMaterial.dispose(); + + shadowMaterialVertical.dispose(); + shadowMaterialHorizontal.dispose(); + + _frustum.dispose(); + shadowSide.clear(); + + scope.dispose(); + _renderer.dispose(); + _objects.dispose(); + _capabilities.dispose(); + } + + void render(List lights, Object3D scene, Camera camera) { + if (!scope.enabled) return; + if (!scope.autoUpdate && !scope.needsUpdate) return; + + if (lights.isEmpty) return; + + final currentRenderTarget = _renderer.getRenderTarget(); + final activeCubeFace = _renderer.getActiveCubeFace(); + final activeMipmapLevel = _renderer.getActiveMipmapLevel(); + + final state = _renderer.state; + + // Set GL state for depth map. + state.setBlending(NoBlending); + state.buffers["color"].setClear(1.0, 1.0, 1.0, 1.0, false); + state.buffers["depth"].setTest(true); + state.setScissorTest(false); + + final toVSM = ( _previousType != VSMShadowMap && type == VSMShadowMap ); + final fromVSM = ( _previousType == VSMShadowMap && type != VSMShadowMap ); + + // render depth map + + for (int i = 0, il = lights.length; i < il; i++) { + final light = lights[i]; + final shadow = light.shadow; + + if (shadow == null) { + continue; + } + + if (!shadow.autoUpdate && !shadow.needsUpdate) continue; + + _shadowMapSize.setFrom(shadow.mapSize); + + final shadowFrameExtents = shadow.getFrameExtents(); + _shadowMapSize.multiply(shadowFrameExtents); + _viewportSize.setFrom(shadow.mapSize); + + if (_shadowMapSize.x > _maxTextureSize || _shadowMapSize.y > _maxTextureSize) { + if (_shadowMapSize.x > _maxTextureSize) { + _viewportSize.x = (_maxTextureSize / shadowFrameExtents.x).floorToDouble(); + _shadowMapSize.x = _viewportSize.x * shadowFrameExtents.x; + shadow.mapSize.x = _viewportSize.x; + } + + if (_shadowMapSize.y > _maxTextureSize) { + _viewportSize.y = (_maxTextureSize / shadowFrameExtents.y).floorToDouble(); + _shadowMapSize.y = _viewportSize.y * shadowFrameExtents.y; + shadow.mapSize.y = _viewportSize.y; + } + } + + if (shadow.map == null || toVSM || fromVSM && shadow is! PointLightShadow && type == VSMShadowMap) { + final Map pars = (type != VSMShadowMap ) ? { 'minFilter': NearestFilter, 'magFilter': NearestFilter } : {}; + + if ( shadow.map != null ) { + shadow.map?.dispose(); + } + + shadow.map = AngleRenderTarget(_shadowMapSize.x.toInt(), _shadowMapSize.y.toInt(), RenderTargetOptions(pars)); + shadow.map!.texture.name = '${light.name}.shadowMap'; + + shadow.camera!.updateProjectionMatrix(); + } + + _renderer.setRenderTarget(shadow.map); + _renderer.clear(); + + final viewportCount = shadow.getViewportCount(); + + for (int vp = 0; vp < viewportCount; vp++) { + final viewport = shadow.getViewport(vp); + _viewport.setValues(_viewportSize.x * viewport.x, _viewportSize.y * viewport.y, _viewportSize.x * viewport.z, _viewportSize.y * viewport.w); + state.viewport(_viewport); + shadow.updateMatrices(light, viewportIndex: vp); + _frustum = shadow.getFrustum(); + renderObject(scene, camera, shadow.camera!, light, type); + } + + // do blur pass for VSM + + if (shadow is! PointLightShadow && type == VSMShadowMap) { + vSMPass(shadow, camera); + } + + shadow.needsUpdate = false; + } + _previousType = type; + + scope.needsUpdate = false; + _renderer.setRenderTarget(currentRenderTarget, activeCubeFace, activeMipmapLevel); + } + + void vSMPass(LightShadow shadow, Camera camera) { + final geometry = _objects.update(fullScreenMesh); + + if (shadowMaterialVertical.defines!["VSM_SAMPLES"] != shadow.blurSamples) { + shadowMaterialVertical.defines!["VSM_SAMPLES"] = shadow.blurSamples; + shadowMaterialHorizontal.defines!["VSM_SAMPLES"] = shadow.blurSamples; + + shadowMaterialVertical.needsUpdate = true; + shadowMaterialHorizontal.needsUpdate = true; + } + + shadow.mapPass ??= AngleRenderTarget( _shadowMapSize.x.toInt(), _shadowMapSize.y.toInt() ); + + // vertical pass + + shadowMaterialVertical.uniforms["shadow_pass"]['value'] = shadow.map!.texture; + shadowMaterialVertical.uniforms["resolution"]['value'] = shadow.mapSize; + shadowMaterialVertical.uniforms["radius"]['value'] = shadow.radius; + + _renderer.setRenderTarget(shadow.mapPass); + _renderer.clear(); + _renderer.renderBufferDirect(camera, null, geometry, shadowMaterialVertical, fullScreenMesh, null); + + // horizontal pass + + shadowMaterialHorizontal.uniforms["shadow_pass"]['value'] = shadow.mapPass!.texture; + shadowMaterialHorizontal.uniforms["resolution"]['value'] = shadow.mapSize; + shadowMaterialHorizontal.uniforms["radius"]['value'] = shadow.radius; + + _renderer.setRenderTarget(shadow.map); + _renderer.clear(); + _renderer.renderBufferDirect(camera, null, geometry, shadowMaterialHorizontal, fullScreenMesh, null); + } + + Material getDepthMaterial( + Object3D object, + Material material, + Light light, + double shadowCameraNear, + double shadowCameraFar, + int type + ) { + Material? result; + + final customMaterial = light is PointLight ? object.customDistanceMaterial : object.customDepthMaterial; + + if (customMaterial != null) { + result = customMaterial; + } else { + result = light is PointLight ? _distanceMaterial : _depthMaterial; + + if (( + _renderer.localClippingEnabled && + material.clipShadows == true && + material.clippingPlanes!.isNotEmpty + ) || + (material.displacementMap != null && material.displacementScale != 0 ) || + ( material.alphaMap != null && material.alphaTest > 0 ) || + (material.map != null && material.alphaTest > 0) + ) { + // in this case we need a unique material instance reflecting the + // appropriate state + + final keyA = result.uuid; + final keyB = material.uuid; + + Map? materialsForVariant = _materialCache[keyA]; + + if (materialsForVariant == null) { + materialsForVariant = {}; + _materialCache[keyA] = materialsForVariant; + } + + Material? cachedMaterial = materialsForVariant[keyB]; + + if (cachedMaterial == null) { + cachedMaterial = result.clone(); + materialsForVariant[keyB] = cachedMaterial; + } + + result = cachedMaterial; + } + } + + result.visible = material.visible; + result.wireframe = material.wireframe; + + if (type == VSMShadowMap) { + result.side = (material.shadowSide != null) ? material.shadowSide! : material.side; + } + else { + result.side = (material.shadowSide != null) ? material.shadowSide! : shadowSide[material.side]!; + } + + result.alphaMap = material.alphaMap; + result.alphaTest = material.alphaTest; + result.map = material.map; + + result.clipShadows = material.clipShadows; + result.clippingPlanes = material.clippingPlanes; + result.clipIntersection = material.clipIntersection; + + result.wireframeLinewidth = material.wireframeLinewidth; + result.linewidth = material.linewidth; + + if (light is PointLight == true && result is MeshDistanceMaterial) { + // result.referencePosition.setFromMatrixPosition(light.matrixWorld); + // result.nearDistance = shadowCameraNear; + // result.farDistance = shadowCameraFar; + + final materialProperties = _renderer.properties.get( result ); + materialProperties['light'] = light; + } + + return result; + } + + void renderObject(Object3D object, Camera camera, Camera shadowCamera, Light light, int type) { + if (object.visible == false) return; + + final visible = object.layers.test(camera.layers); + + if (visible && (object is Mesh || object is Line || object is Points)) { + if ((object.castShadow || (object.receiveShadow && type == VSMShadowMap)) && + (!object.frustumCulled || _frustum.intersectsObject(object))) { + object.modelViewMatrix.multiply2(shadowCamera.matrixWorldInverse, object.matrixWorld); + + final geometry = _objects.update(object); + final material = object.material; + + if (material is GroupMaterial) { + final groups = geometry.groups; + + for (int k = 0, kl = groups.length; k < kl; k++) { + final group = groups[k]; + final groupMaterial = material.children[group["materialIndex"]]; + + if (groupMaterial.visible) {//groupMaterial != null && + final depthMaterial = getDepthMaterial(object, groupMaterial, light, shadowCamera.near, shadowCamera.far, type); + object.onBeforeShadow(renderer: _renderer, scene: object, camera: camera, shadowCamera: shadowCamera, geometry: geometry, material: depthMaterial, group: group); + _renderer.renderBufferDirect(shadowCamera, null, geometry, depthMaterial, object, group); + object.onAfterShadow(renderer: _renderer, scene: object, camera: camera, shadowCamera: shadowCamera, geometry: geometry, material: depthMaterial, group: group); + } + } + } + else if (material != null && material.visible) { + final depthMaterial = getDepthMaterial(object, material, light, shadowCamera.near, shadowCamera.far, type); + object.onBeforeShadow(renderer: _renderer, scene: object, camera: camera, shadowCamera: shadowCamera, geometry: geometry, material: depthMaterial); + _renderer.renderBufferDirect(shadowCamera, null, geometry, depthMaterial, object, null); + object.onAfterShadow(renderer: _renderer, scene: object, camera: camera, shadowCamera: shadowCamera, geometry: geometry, material: depthMaterial); + } + } + } + + final children = object.children; + + for (int i = 0, l = children.length; i < l; i++) { + renderObject(children[i], camera, shadowCamera, light, type); + } + } +} diff --git a/packages/three_js_angle_renderer/lib/angle/angle_state.dart b/packages/three_js_angle_renderer/lib/angle/angle_state.dart new file mode 100755 index 00000000..e4eb1a98 --- /dev/null +++ b/packages/three_js_angle_renderer/lib/angle/angle_state.dart @@ -0,0 +1,1011 @@ +part of three_webgl; + +class AngleState { + bool _didDispose = false; + RenderingContext gl; + + late ColorBuffer colorBuffer; + late DepthBuffer depthBuffer; + late StencilBuffer stencilBuffer; + + late int maxTextures; + + final emptyTextures = {}; + late Map equationToGL; + late Map factorToGL; + + Map get buffers => {"color": colorBuffer, "depth": depthBuffer, "stencil": stencilBuffer}; + Map enabledCapabilities = {}; + + Framebuffer? xrFramebuffer; + Map currentBoundFramebuffers = {}; + final uboBindings = WeakMap(); + final uboProgramMap = WeakMap(); + WeakMap currentDrawbuffers = WeakMap(); + List defaultDrawbuffers = []; + + dynamic currentProgram; + + bool currentBlendingEnabled = false; + + int? currentBlending; + int? currentBlendEquation; + int? currentBlendSrc; + int? currentBlendDst; + int? currentBlendEquationAlpha; + int? currentBlendSrcAlpha; + int? currentBlendDstAlpha; + bool? currentPremultipledAlpha; + Color currentBlendColor = Color( 0, 0, 0 ); + double currentBlendAlpha = 0; + + bool? currentFlipSided = false; + int? currentCullFace; + + double? currentLineWidth; + + double? currentPolygonOffsetFactor; + double? currentPolygonOffsetUnits; + + bool lineWidthAvailable = true; + + int? currentTextureSlot; + Map currentBoundTextures = {}; + + late Vector4 currentScissor; + late Vector4 currentViewport; + + dynamic scissorParam; + dynamic viewportParam; + AngleExtensions extensions; + + AngleState(this.gl, this.extensions) { + colorBuffer = ColorBuffer(gl); + depthBuffer = DepthBuffer(gl,extensions); + stencilBuffer = StencilBuffer(gl); + + colorBuffer.enable = enable; + colorBuffer.disable = disable; + + depthBuffer.enable = enable; + depthBuffer.disable = disable; + + stencilBuffer.enable = enable; + stencilBuffer.disable = disable; + + maxTextures = gl.getParameter(WebGL.MAX_COMBINED_TEXTURE_IMAGE_UNITS); + emptyTextures[WebGL.TEXTURE_2D] = createTexture(WebGL.TEXTURE_2D, WebGL.TEXTURE_2D, 1); + emptyTextures[WebGL.TEXTURE_CUBE_MAP] = createTexture(WebGL.TEXTURE_CUBE_MAP, WebGL.TEXTURE_CUBE_MAP_POSITIVE_X, 6); + + colorBuffer.setClear(0, 0, 0, 1, false); + depthBuffer.setClear(1); + stencilBuffer.setClear(0); + + enable(WebGL.DEPTH_TEST); + depthBuffer.setFunc(LessEqualDepth); + + setFlipSided(false); + setCullFace(CullFaceBack); + enable(WebGL.CULL_FACE); + + setBlending(NoBlending, null, null, null, null, null, null, false); + + equationToGL = { + AddEquation: WebGL.FUNC_ADD, + SubtractEquation: WebGL.FUNC_SUBTRACT, + ReverseSubtractEquation: WebGL.FUNC_REVERSE_SUBTRACT + }; + + equationToGL[MinEquation] = WebGL.MIN; + equationToGL[MaxEquation] = WebGL.MAX; + + factorToGL = { + ZeroFactor: WebGL.ZERO, + OneFactor: WebGL.ONE, + SrcColorFactor: WebGL.SRC_COLOR, + SrcAlphaFactor: WebGL.SRC_ALPHA, + SrcAlphaSaturateFactor: WebGL.SRC_ALPHA_SATURATE, + DstColorFactor: WebGL.DST_COLOR, + DstAlphaFactor: WebGL.DST_ALPHA, + OneMinusSrcColorFactor: WebGL.ONE_MINUS_SRC_COLOR, + OneMinusSrcAlphaFactor: WebGL.ONE_MINUS_SRC_ALPHA, + OneMinusDstColorFactor: WebGL.ONE_MINUS_DST_COLOR, + OneMinusDstAlphaFactor: WebGL.ONE_MINUS_DST_ALPHA + }; + + scissorParam = gl.getParameter(WebGL.SCISSOR_BOX); + viewportParam = gl.getParameter(WebGL.VIEWPORT); + + // currentScissor = new Vector4.identity().fromArray( scissorParam ); + // currentViewport = new Vector4.identity().fromArray( viewportParam ); + + currentScissor = Vector4.identity(); + currentViewport = Vector4.identity(); + } + + final data = Uint8List(4); + + WebGLTexture createTexture(int type, int target, int count) { + // 4 is required to match default unpack alignment of 4. + // + final texture = gl.createTexture(); + + gl.bindTexture(type, texture); + gl.texParameteri(type, WebGL.TEXTURE_MIN_FILTER, WebGL.NEAREST); + gl.texParameteri(type, WebGL.TEXTURE_MAG_FILTER, WebGL.NEAREST); + + for (int i = 0; i < count; i++) { + gl.texImage2D(target + i, 0, WebGL.RGBA, 1, 1, 0, WebGL.RGBA, WebGL.UNSIGNED_BYTE, data); + } + + //data.dispose(); + + return texture; + } + + void enable(id) { + if (enabledCapabilities[id] != true) { + gl.enable(id); + enabledCapabilities[id] = true; + } + } + + void disable(id) { + if (enabledCapabilities[id] != false) { + gl.disable(id); + enabledCapabilities[id] = false; + } + } + + void bindXRFramebuffer(Framebuffer? framebuffer) { + if (framebuffer != xrFramebuffer) { + gl.bindFramebuffer(WebGL.FRAMEBUFFER, framebuffer); + xrFramebuffer = framebuffer; + } + } + + bool bindFramebuffer(target, Framebuffer? framebuffer) { + if (framebuffer == null && xrFramebuffer != null) { + framebuffer = xrFramebuffer; + } // use active XR framebuffer if available + + if (currentBoundFramebuffers[target] != framebuffer) { + gl.bindFramebuffer(target, framebuffer); + + currentBoundFramebuffers[target] = framebuffer; + + // gl.DRAW_FRAMEBUFFER is equivalent to gl.FRAMEBUFFER + if (target == WebGL.DRAW_FRAMEBUFFER) { + currentBoundFramebuffers[WebGL.FRAMEBUFFER] = framebuffer; + } + + if (target == WebGL.FRAMEBUFFER) { + currentBoundFramebuffers[WebGL.DRAW_FRAMEBUFFER] = framebuffer; + } + + return true; + } + + return false; + } + + void drawBuffers(RenderTarget? renderTarget, Framebuffer? framebuffer) { + List? drawBuffers = defaultDrawbuffers; + + bool needsUpdate = false; + + if (renderTarget != null) { + drawBuffers = currentDrawbuffers.get(framebuffer); + + if (drawBuffers == null) { + drawBuffers = []; + currentDrawbuffers.set(framebuffer, drawBuffers); + } + + final textures = renderTarget.textures; + + if (drawBuffers.length != textures.length || (drawBuffers.isNotEmpty && drawBuffers[0] != WebGL.COLOR_ATTACHMENT0)) { + for (int i = 0, il = textures.length; i < il; i++) { + if(drawBuffers.length <= i){ + drawBuffers.add(WebGL.COLOR_ATTACHMENT0 + i); + }else{ + drawBuffers[i] = WebGL.COLOR_ATTACHMENT0 + i; + } + } + + drawBuffers.length = textures.length; + + needsUpdate = true; + } + } + else { + if (drawBuffers.isEmpty || drawBuffers[0] != WebGL.BACK) { + if (drawBuffers.isEmpty) { + drawBuffers.add(WebGL.BACK); + } else { + drawBuffers[0] = WebGL.BACK; + } + + drawBuffers.length = 1; + needsUpdate = true; + } + } + + if (needsUpdate) { + Uint32List buf = Uint32List.fromList(List.from(drawBuffers)); + gl.drawBuffers(buf); + buf.dispose(); + } + } + + bool useProgram(Program? program) { + if (currentProgram != program) { + gl.useProgram(program); + currentProgram = program; + return true; + } + + return false; + } + + void setBlending(int blending, + [int? blendEquation, + int? blendSrc, + int? blendDst, + int? blendEquationAlpha, + int? blendSrcAlpha, + int? blendDstAlpha, + bool premultipliedAlpha = false]) { + if (blending == NoBlending) { + if (currentBlendingEnabled) { + disable(WebGL.BLEND); + currentBlendingEnabled = false; + } + + return; + } + + if (!currentBlendingEnabled) { + enable(WebGL.BLEND); + currentBlendingEnabled = true; + } + + if (blending != CustomBlending) { + if (blending != currentBlending || premultipliedAlpha != currentPremultipledAlpha) { + if (currentBlendEquation != AddEquation || currentBlendEquationAlpha != AddEquation) { + gl.blendEquation(WebGL.FUNC_ADD); + + currentBlendEquation = AddEquation; + currentBlendEquationAlpha = AddEquation; + } + + if (premultipliedAlpha) { + switch (blending) { + case NormalBlending: + gl.blendFuncSeparate(WebGL.ONE, WebGL.ONE_MINUS_SRC_ALPHA, WebGL.ONE, WebGL.ONE_MINUS_SRC_ALPHA); + break; + + case AdditiveBlending: + gl.blendFunc(WebGL.ONE, WebGL.ONE); + break; + + case SubtractiveBlending: + gl.blendFuncSeparate(WebGL.ZERO, WebGL.ONE_MINUS_SRC_COLOR, WebGL.ZERO, WebGL.ONE); + break; + + case MultiplyBlending: + gl.blendFuncSeparate(WebGL.ZERO, WebGL.SRC_COLOR, WebGL.ZERO, WebGL.SRC_ALPHA); + break; + + default: + console.error('WebGLState: Invalid blending: $blending'); + break; + } + } + else { + switch (blending) { + case NormalBlending: + gl.blendFuncSeparate(WebGL.SRC_ALPHA, WebGL.ONE_MINUS_SRC_ALPHA, WebGL.ONE, WebGL.ONE_MINUS_SRC_ALPHA); + break; + + case AdditiveBlending: + gl.blendFunc(WebGL.SRC_ALPHA, WebGL.ONE); + break; + + case SubtractiveBlending: + gl.blendFuncSeparate(WebGL.ZERO, WebGL.ONE_MINUS_SRC_COLOR, WebGL.ZERO, WebGL.ONE); + break; + + case MultiplyBlending: + gl.blendFunc(WebGL.ZERO, WebGL.SRC_COLOR); + break; + + default: + console.error('WebGLState: Invalid blending: $blending'); + break; + } + } + + currentBlendSrc = null; + currentBlendDst = null; + currentBlendSrcAlpha = null; + currentBlendDstAlpha = null; + currentBlendColor.setValues( 0, 0, 0 ); + currentBlendAlpha = 0; + + currentBlending = blending; + currentPremultipledAlpha = premultipliedAlpha; + } + + return; + } + + blendEquationAlpha = blendEquationAlpha ?? blendEquation; + blendSrcAlpha = blendSrcAlpha ?? blendSrc; + blendDstAlpha = blendDstAlpha ?? blendDst; + + if (blendEquation != currentBlendEquation || blendEquationAlpha != currentBlendEquationAlpha) { + gl.blendEquationSeparate(equationToGL[blendEquation]!, equationToGL[blendEquationAlpha]!); + + currentBlendEquation = blendEquation; + currentBlendEquationAlpha = blendEquationAlpha; + } + + if (blendSrc != currentBlendSrc || + blendDst != currentBlendDst || + blendSrcAlpha != currentBlendSrcAlpha || + blendDstAlpha != currentBlendDstAlpha) { + gl.blendFuncSeparate(factorToGL[blendSrc]!, factorToGL[blendDst]!, factorToGL[blendSrcAlpha]!, factorToGL[blendDstAlpha]!); + + currentBlendSrc = blendSrc; + currentBlendDst = blendDst; + currentBlendSrcAlpha = blendSrcAlpha; + currentBlendDstAlpha = blendDstAlpha; + } + + currentBlending = blending; + currentPremultipledAlpha = null; + } + + void setMaterial(Material material, bool frontFaceCW) { + material.side == DoubleSide ? disable(WebGL.CULL_FACE) : enable(WebGL.CULL_FACE); + + bool flipSided = (material.side == BackSide); + if (frontFaceCW) flipSided = !flipSided; + + setFlipSided(flipSided); + + (material.blending == NormalBlending && material.transparent == false) + ? setBlending(NoBlending) + : setBlending(material.blending, material.blendEquation, material.blendSrc, material.blendDst,material.blendEquationAlpha, material.blendSrcAlpha, material.blendDstAlpha, material.premultipliedAlpha); + + depthBuffer.setFunc(material.depthFunc); + depthBuffer.setTest(material.depthTest); + depthBuffer.setMask(material.depthWrite); + colorBuffer.setMask(material.colorWrite); + + final stencilWrite = material.stencilWrite; + stencilBuffer.setTest(stencilWrite); + if (stencilWrite) { + stencilBuffer.setMask(material.stencilWriteMask); + stencilBuffer.setFunc(material.stencilFunc, material.stencilRef, material.stencilFuncMask); + stencilBuffer.setOp(material.stencilFail, material.stencilZFail, material.stencilZPass); + } + + setPolygonOffset(material.polygonOffset, material.polygonOffsetFactor, material.polygonOffsetUnits); + + material.alphaToCoverage == true ? enable(WebGL.SAMPLE_ALPHA_TO_COVERAGE) : disable(WebGL.SAMPLE_ALPHA_TO_COVERAGE); + } + + // + + void setFlipSided(bool flipSided) { + if (currentFlipSided != flipSided) { + if (flipSided) { + gl.frontFace(WebGL.CW); + } + else { + gl.frontFace(WebGL.CCW); + } + + currentFlipSided = flipSided; + } + } + + void setCullFace(int cullFace) { + if (cullFace != CullFaceNone) { + enable(WebGL.CULL_FACE); + + if (cullFace != currentCullFace) { + if (cullFace == CullFaceBack) { + gl.cullFace(WebGL.BACK); + } else if (cullFace == CullFaceFront) { + gl.cullFace(WebGL.FRONT); + } else { + gl.cullFace(WebGL.FRONT_AND_BACK); + } + } + } else { + disable(WebGL.CULL_FACE); + } + + currentCullFace = cullFace; + } + + void setLineWidth(width) { + if (width != currentLineWidth) { + if (lineWidthAvailable) gl.lineWidth(width); + + currentLineWidth = width; + } + } + + void setPolygonOffset(bool polygonOffset, [double? factor, double? units]) { + if (polygonOffset) { + enable(WebGL.POLYGON_OFFSET_FILL); + + if (currentPolygonOffsetFactor != factor || currentPolygonOffsetUnits != units) { + gl.polygonOffset(factor!, units!); + + currentPolygonOffsetFactor = factor; + currentPolygonOffsetUnits = units; + } + } else { + disable(WebGL.POLYGON_OFFSET_FILL); + } + } + + void setScissorTest(bool scissorTest) { + if (scissorTest) { + enable(WebGL.SCISSOR_TEST); + } else { + disable(WebGL.SCISSOR_TEST); + } + } + + // texture + + void activeTexture(int? webglSlot) { + webglSlot ??= WebGL.TEXTURE0 + maxTextures - 1; + + if (currentTextureSlot != webglSlot) { + gl.activeTexture(webglSlot); + + currentTextureSlot = webglSlot; + } + } + + void bindTexture(int webglType, WebGLTexture? webglTexture, [int? webglSlot]) { + if ( webglSlot == null ) { + if ( currentTextureSlot == null ) { + webglSlot = WebGL.TEXTURE0 + maxTextures - 1; + } + else { + webglSlot = currentTextureSlot; + } + } + + BoundTexture? boundTexture = currentBoundTextures[webglSlot]; + + if (boundTexture == null) { + boundTexture = BoundTexture(); + currentBoundTextures[webglSlot!] = boundTexture; + } + + if (boundTexture.type != webglType || boundTexture.texture != webglTexture) { + if ( currentTextureSlot != webglSlot ) { + gl.activeTexture( webglSlot! ); + currentTextureSlot = webglSlot; + } + + gl.bindTexture( + webglType, + webglTexture ?? emptyTextures[webglType] + ); + + boundTexture.type = webglType; + boundTexture.texture = webglTexture; + } + } + + void unbindTexture([WebGLTexture? texture]) { + final boundTexture = currentBoundTextures[currentTextureSlot]; + + if (boundTexture != null && boundTexture.type != null) { + gl.bindTexture(boundTexture.type!, kIsWeb?null:texture); + boundTexture.type = null; + boundTexture.texture = null; + } + } + void compressedTexSubImage3D( + int target, + int level, + int xoffset, + int yoffset, + int zoffset, + int width, + int height, + int depth, + int format, + TypedData? data, + ) { + gl.compressedTexSubImage3D(target,level,xoffset,yoffset,zoffset,width,height,depth,format,data); + } + void compressedTexImage3D( + int target, + int level, + int internalformat, + int width, + int height, + int depth, + int border, + TypedData? data, + ) { + gl.compressedTexImage3D(target,level,internalformat,width,height,depth,border,data); + } + + void compressedTexImage2D(int target, int level, int internalformat, int width, int height, int border, TypedData? pixels) { + gl.compressedTexImage2D(target, level, internalformat, width, height, border, pixels); + } + + void texSubImage2D(int target, int level, int x, int y, num width, num height, int glFormat, int glType, TypedData data) { + gl.texSubImage2D(target, level, x, y, width.toInt(), height.toInt(), glFormat, glType, data); + } + + void texSubImage2DIf(int target, int level, int x, int y, int glFormat, int glType, ImageElement image) { + if (kIsWeb && image.data is! TypedData) { + texSubImage2DNoSize(WebGL.TEXTURE_2D, 0, 0, 0, glFormat, glType, image.data); + } + else { + texSubImage2D(WebGL.TEXTURE_2D, 0, 0, 0, image.width, image.height, glFormat, glType, image.data); + } + } + + void texSubImage2DNoSize(int target, int level, int x, int y, int glFormat, int glType, data) { + if (kIsWeb) { + gl.texSubImage2D_NOSIZE(target, level, x, y, glFormat, glType, data); + } + else { + gl.texSubImage2D(target, level, 0, 0, x, y, glFormat, glType, data); + } + } + + void texSubImage3D(int target, int level, int xoffset, int yoffset, int zoffset, int width, int height, int depth, int format, int type, TypedData? pixels) { + gl.texSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); + } + + void compressedTexSubImage2D( + int target, + int level, + int xoffset, + int yoffset, + int width, + int height, + int format, + TypedData? pixels, + ) { + gl.compressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, pixels); + } + + void texStorage2D(int type, int levels, int glInternalFormat, int width, int height) { + gl.texStorage2D(type, levels, glInternalFormat, width, height); + } + + void texStorage3D(target, levels, internalformat, width, height, depth) { + gl.texStorage3D(target, levels, internalformat, width.toInt(), height.toInt(), depth); + } + + void texImage2DIf(int target, int level, int internalformat, int format, int type, image) { + if (kIsWeb) { + texImage2DNoSize(target, level, internalformat, format, type, image.data); + } + else { + texImage2D(target, level, internalformat, image.width, image.height, 0, format, type, image.data); + } + } + + void texImage2D(int target, int level, int internalformat, int width, int height, border, int format, int type, data) { + gl.texImage2D(target, level, internalformat, width, height, border, format, type, data); + } + + void texImage2DNoSize(int target, int level, int internalformat, int format, int type, data) { + gl.texImage2D_NOSIZE(target, level, internalformat, format, type, data); + } + + void texImage3D(int target, int level, int internalformat, int width, int height, int depth, int border, int format,int type, offset) { + gl.texImage3D(target, level, internalformat, width, height, depth, border, format, type, offset); + } + + void scissor(Vector4 scissor) { + if (!currentScissor.equals(scissor)) { + gl.scissor(scissor.x.toInt(), scissor.y.toInt(), scissor.z.toInt(), scissor.w.toInt()); + currentScissor.setFrom(scissor); + } + } + + void viewport(Vector4 viewport) { + if (!currentViewport.equals(viewport)) { + gl.viewport(viewport.x.toInt(), viewport.y.toInt(), viewport.z.toInt(), viewport.w.toInt()); + currentViewport.setFrom(viewport); + } + } + void updateUBOMapping(UniformsGroup uniformsGroup, Program program ) { + dynamic mapping = uboProgramMap.get( program ); + + if ( mapping == null ) { + mapping = WeakMap(); + uboProgramMap.set( program, mapping ); + } + + dynamic blockIndex = mapping.get( uniformsGroup ); + + if ( blockIndex == null ) { + blockIndex = gl.getUniformBlockIndex( program, uniformsGroup.name ); + mapping.set( uniformsGroup, blockIndex ); + } + } + + void uniformBlockBinding( uniformsGroup, program ) { + final mapping = uboProgramMap.get( program ); + final blockIndex = mapping.get( uniformsGroup ); + + if ( uboBindings.get( program ) != blockIndex ) { + // bind shader specific block index to global block point + gl.uniformBlockBinding( program, blockIndex, uniformsGroup['__bindingPointIndex'] ); + uboBindings.set( program, blockIndex ); + } + } + + void reset() { + gl.disable(WebGL.BLEND); + gl.disable(WebGL.CULL_FACE); + gl.disable(WebGL.DEPTH_TEST); + gl.disable(WebGL.POLYGON_OFFSET_FILL); + gl.disable(WebGL.SCISSOR_TEST); + gl.disable(WebGL.STENCIL_TEST); + gl.disable(WebGL.SAMPLE_ALPHA_TO_COVERAGE); + + gl.blendEquation(WebGL.FUNC_ADD); + gl.blendFunc(WebGL.ONE, WebGL.ZERO); + gl.blendFuncSeparate(WebGL.ONE, WebGL.ZERO, WebGL.ONE, WebGL.ZERO); + + gl.colorMask(true, true, true, true); + gl.clearColor(0, 0, 0, 0); + + gl.depthMask(true); + gl.depthFunc(WebGL.LESS); + gl.clearDepth(1); + + gl.stencilMask(0xffffffff); + gl.stencilFunc(WebGL.ALWAYS, 0, 0xffffffff); + gl.stencilOp(WebGL.KEEP, WebGL.KEEP, WebGL.KEEP); + gl.clearStencil(0); + + gl.cullFace(WebGL.BACK); + gl.frontFace(WebGL.CCW); + gl.polygonOffset(0, 0); + gl.activeTexture(WebGL.TEXTURE0); + + gl.bindFramebuffer(WebGL.DRAW_FRAMEBUFFER, null); // Equivalent to gl.FRAMEBUFFER + gl.bindFramebuffer(WebGL.READ_FRAMEBUFFER, null); + gl.bindFramebuffer(WebGL.FRAMEBUFFER, null); + + gl.useProgram(null); + gl.lineWidth(1); + gl.scissor(0, 0, 0, 0); + gl.viewport(0, 0, 0, 0); + + // reset internals + + enabledCapabilities = {}; + + currentTextureSlot = null; + currentBoundTextures = {}; + + xrFramebuffer = null; + currentBoundFramebuffers = {}; + currentDrawbuffers = WeakMap(); + defaultDrawbuffers = []; + + currentProgram = null; + + currentBlendingEnabled = false; + currentBlending = null; + currentBlendEquation = null; + currentBlendSrc = null; + currentBlendDst = null; + currentBlendEquationAlpha = null; + currentBlendSrcAlpha = null; + currentBlendDstAlpha = null; + currentPremultipledAlpha = false; + + currentFlipSided = null; + currentCullFace = null; + + currentLineWidth = null; + + currentPolygonOffsetFactor = null; + currentPolygonOffsetUnits = null; + + currentScissor.setValues( 0, 0, gl.width.toDouble(), gl.height.toDouble()); + currentViewport.setValues( 0, 0, gl.width.toDouble(), gl.height.toDouble()); + + colorBuffer.reset(); + depthBuffer.reset(); + stencilBuffer.reset(); + } + + void dispose(){ + if(_didDispose) return; + _didDispose = true; + + emptyTextures.clear(); + equationToGL.clear(); + factorToGL.clear(); + buffers.clear(); + enabledCapabilities.clear(); + currentBoundFramebuffers.clear(); + defaultDrawbuffers.clear(); + currentBoundTextures.clear(); + + extensions.dispose(); + currentDrawbuffers.dispose(); + } +} + +class ColorBuffer { + RenderingContext gl; + + bool locked = false; + + late Function enable; + late Function disable; + + Vector4 color = Vector4.identity(); + bool? currentColorMask; + Vector4 currentColorClear = Vector4(0, 0, 0, 0); + + ColorBuffer(this.gl); + + setMask(bool colorMask) { + if (currentColorMask != colorMask && !locked) { + gl.colorMask(colorMask, colorMask, colorMask, colorMask); + currentColorMask = colorMask; + } + } + + setLocked(lock) { + locked = lock; + } + + setClear(double r, double g, double b, double a, bool premultipliedAlpha) { + if (premultipliedAlpha == true) { + r *= a; + g *= a; + b *= a; + } + + color.setValues(r, g, b, a); + + if (currentColorClear.equals(color) == false) { + gl.clearColor(r, g, b, a); + currentColorClear.setFrom(color); + } + } + + void reset() { + locked = false; + + currentColorMask = null; + currentColorClear.setValues(-1, 0, 0, 0); // set to invalid state + } +} + +class DepthBuffer { + RenderingContext gl; + + bool locked = false; + bool reversed = false; + + late Function enable; + late Function disable; + + bool? currentDepthMask; + + int? currentDepthFunc; + double? currentDepthClear; + AngleExtensions extensions; + + DepthBuffer(this.gl,this.extensions); + + void setReversed(bool value ){ + if ( reversed != value ) { + final ext = extensions.get( 'EXT_clip_control' ); + if ( reversed ) { + ext.clipControlEXT( ext.LOWER_LEFT_EXT, ext.ZERO_TO_ONE_EXT ); + } else { + ext.clipControlEXT( ext.LOWER_LEFT_EXT, ext.NEGATIVE_ONE_TO_ONE_EXT ); + } + final oldDepth = currentDepthClear; + currentDepthClear = null; + this.setClear( oldDepth! ); + } + + reversed = value; + } + + bool getReversed() { + return reversed; + } + + void setTest(depthTest) { + if (depthTest) { + enable(WebGL.DEPTH_TEST); + } else { + disable(WebGL.DEPTH_TEST); + } + } + + void setMask(bool depthMask) { + if (currentDepthMask != depthMask && !locked) { + gl.depthMask(depthMask); + currentDepthMask = depthMask; + } + } + + void setFunc(int? depthFunc) { + if (currentDepthFunc != depthFunc) { + if (depthFunc != null) { + switch (depthFunc) { + case NeverDepth: + gl.depthFunc(WebGL.NEVER); + break; + + case AlwaysDepth: + gl.depthFunc(WebGL.ALWAYS); + break; + + case LessDepth: + gl.depthFunc(WebGL.LESS); + break; + + case LessEqualDepth: + gl.depthFunc(WebGL.LEQUAL); + break; + + case EqualDepth: + gl.depthFunc(WebGL.EQUAL); + break; + + case GreaterEqualDepth: + gl.depthFunc(WebGL.GEQUAL); + break; + + case GreaterDepth: + gl.depthFunc(WebGL.GREATER); + break; + + case NotEqualDepth: + gl.depthFunc(WebGL.NOTEQUAL); + break; + + default: + gl.depthFunc(WebGL.LEQUAL); + } + } else { + gl.depthFunc(WebGL.LEQUAL); + } + + currentDepthFunc = depthFunc; + } + } + + void setLocked(lock) { + locked = lock; + } + + void setClear(double depth) { + if (currentDepthClear != depth) { + gl.clearDepth(depth); + currentDepthClear = depth; + } + } + + void reset() { + locked = false; + + currentDepthMask = null; + currentDepthFunc = null; + currentDepthClear = null; + } +} + +class StencilBuffer { + RenderingContext gl; + + bool locked = false; + + late Function enable; + late Function disable; + + int? currentStencilMask; + int? currentStencilFunc; + int? currentStencilRef; + int? currentStencilFuncMask; + int? currentStencilFail; + int? currentStencilZFail; + int? currentStencilZPass; + int? currentStencilClear; + + StencilBuffer(this.gl); + + void setTest(bool stencilTest) { + if (!locked) { + if (stencilTest) { + enable(WebGL.STENCIL_TEST); + } else { + disable(WebGL.STENCIL_TEST); + } + } + } + + void setMask(int stencilMask) { + if (currentStencilMask != stencilMask && !locked) { + gl.stencilMask(stencilMask); + currentStencilMask = stencilMask; + } + } + + void setFunc(int stencilFunc, int stencilRef, int stencilMask) { + if (currentStencilFunc != stencilFunc || currentStencilRef != stencilRef || currentStencilFuncMask != stencilMask) { + gl.stencilFunc(stencilFunc, stencilRef, stencilMask); + + currentStencilFunc = stencilFunc; + currentStencilRef = stencilRef; + currentStencilFuncMask = stencilMask; + } + } + + void setOp(int stencilFail, int stencilZFail, int stencilZPass) { + if (currentStencilFail != stencilFail || + currentStencilZFail != stencilZFail || + currentStencilZPass != stencilZPass) { + gl.stencilOp(stencilFail, stencilZFail, stencilZPass); + + currentStencilFail = stencilFail; + currentStencilZFail = stencilZFail; + currentStencilZPass = stencilZPass; + } + } + + void setLocked(bool lock) { + locked = lock; + } + + void setClear(int stencil) { + if (currentStencilClear != stencil) { + gl.clearStencil(stencil); + currentStencilClear = stencil; + } + } + + void reset() { + locked = false; + + currentStencilMask = null; + currentStencilFunc = null; + currentStencilRef = null; + currentStencilFuncMask = null; + currentStencilFail = null; + currentStencilZFail = null; + currentStencilZPass = null; + currentStencilClear = null; + } +} + +class BoundTexture { + int? type; + dynamic texture; + + BoundTexture([this.type, this.texture]); +} diff --git a/packages/three_js_angle_renderer/lib/angle/angle_textures.dart b/packages/three_js_angle_renderer/lib/angle/angle_textures.dart new file mode 100755 index 00000000..311f4b72 --- /dev/null +++ b/packages/three_js_angle_renderer/lib/angle/angle_textures.dart @@ -0,0 +1,1632 @@ +part of three_webgl; + +class AngleTextures { + bool _didDispose = false; + RenderingContext gl; + RenderingContext get _gl => gl; + AngleExtensions extensions; + AngleState state; + AngleProperties properties; + AngleCapabilities capabilities; + AngleUtils utils; + AngleInfo info; + bool isWebGL2 = true; + + late int maxTextures; + late int maxCubemapSize; + late int maxTextureSize; + late int maxSamples; + + bool supportsInvalidateFramenbuffer = false; + + //final _imageDimensions = Vector2(); + final WeakMap _videoTextures = WeakMap(); + + final WeakMap _sources = WeakMap(); + // maps WebglTexture objects to instances of Source + + Map wrappingToGL = {}; + Map filterToGL = {}; + Map compareToGL = {}; + + dynamic multisampledRenderToTextureExtension; + dynamic multisampledRTTExt; + final bool supportsInvalidateFramebuffer = false;//typeof navigator === 'undefined' ? false : /OculusBrowser/g.test( navigator.userAgent ); + + AngleTextures(this.gl, this.extensions, this.state, this.properties, this.capabilities, this.utils, this.info) { + maxTextures = capabilities.maxTextures; + maxCubemapSize = capabilities.maxCubemapSize; + maxTextureSize = capabilities.maxTextureSize; + maxSamples = capabilities.maxSamples; + + multisampledRTTExt = extensions.has( 'WEBGL_multisampled_render_to_texture' )? extensions.get( 'WEBGL_multisampled_render_to_texture' ) : null; + multisampledRenderToTextureExtension = extensions.has('WEBGL_multisampled_render_to_texture')? extensions.get('WEBGL_multisampled_render_to_texture'): null; + + wrappingToGL[RepeatWrapping] = WebGL.REPEAT; + wrappingToGL[ClampToEdgeWrapping] = WebGL.CLAMP_TO_EDGE; + wrappingToGL[MirroredRepeatWrapping] = WebGL.MIRRORED_REPEAT; + + filterToGL[NearestFilter] = WebGL.NEAREST; + filterToGL[NearestMipmapNearestFilter] = WebGL.NEAREST_MIPMAP_NEAREST; + filterToGL[NearestMipmapLinearFilter] = WebGL.NEAREST_MIPMAP_LINEAR; + filterToGL[LinearFilter] = WebGL.LINEAR; + filterToGL[LinearMipmapNearestFilter] = WebGL.LINEAR_MIPMAP_NEAREST; + filterToGL[LinearMipmapLinearFilter] = WebGL.LINEAR_MIPMAP_LINEAR; + + compareToGL[ NeverCompare ] = WebGL.NEVER; + compareToGL[ AlwaysCompare ] = WebGL.ALWAYS; + compareToGL[ LessCompare ] = WebGL.LESS; + compareToGL[ LessEqualCompare ] = WebGL.LEQUAL; + compareToGL[ EqualCompare ] = WebGL.EQUAL; + compareToGL[ GreaterEqualCompare ] = WebGL.GEQUAL; + compareToGL[ GreaterCompare ] = WebGL.GREATER; + compareToGL[ NotEqualCompare ] = WebGL.NOTEQUAL; + + // TODO FIXME when on web && is OculusBrowser + // supportsInvalidateFramenbuffer = kIsWeb && RegExp(r"OculusBrowser").hasMatch( navigator.userAgent ); + } + + bool isPowerOfTwo(image) { + return MathUtils.isPowerOfTwo(image.width.toInt()) && MathUtils.isPowerOfTwo(image.height.toInt()); + } + + bool textureNeedsGenerateMipmaps(Texture texture) { + return texture.generateMipmaps; + } + + generateMipmap(target) { + gl.generateMipmap(target); + } + + int getInternalFormat(internalFormatName, int glFormat, int glType, String colorSpace, [bool forceLinearTransfer = false]) { + if ( internalFormatName != null ) { + if ( WebGL.get( internalFormatName ) != null ) return WebGL.get( internalFormatName )!; + console.warning( 'THREE.WebGLRenderer: Attempt to use non-existing WebGL internal format \'' + internalFormatName + '\'' ); + } + + int internalFormat = glFormat; + + if ( glFormat == WebGL.RED ) { + if ( glType == WebGL.FLOAT ) internalFormat = WebGL.R32F; + if ( glType == WebGL.HALF_FLOAT ) internalFormat = WebGL.R16F; + if ( glType == WebGL.UNSIGNED_BYTE ) internalFormat = WebGL.R8; + } + + if ( glFormat == WebGL.RED_INTEGER ) { + if ( glType == WebGL.UNSIGNED_BYTE ) internalFormat = WebGL.R8UI; + if ( glType == WebGL.UNSIGNED_SHORT ) internalFormat = WebGL.R16UI; + if ( glType == WebGL.UNSIGNED_INT ) internalFormat = WebGL.R32UI; + if ( glType == WebGL.BYTE ) internalFormat = WebGL.R8I; + if ( glType == WebGL.SHORT ) internalFormat = WebGL.R16I; + if ( glType == WebGL.INT ) internalFormat = WebGL.R32I; + } + + if ( glFormat == WebGL.RG ) { + if ( glType == WebGL.FLOAT ) internalFormat = WebGL.RG32F; + if ( glType == WebGL.HALF_FLOAT ) internalFormat = WebGL.RG16F; + if ( glType == WebGL.UNSIGNED_BYTE ) internalFormat = WebGL.RG8; + } + + if ( glFormat == WebGL.RG_INTEGER ) { + if ( glType == WebGL.UNSIGNED_BYTE ) internalFormat = WebGL.RG8UI; + if ( glType == WebGL.UNSIGNED_SHORT ) internalFormat = WebGL.RG16UI; + if ( glType == WebGL.UNSIGNED_INT ) internalFormat = WebGL.RG32UI; + if ( glType == WebGL.BYTE ) internalFormat = WebGL.RG8I; + if ( glType == WebGL.SHORT ) internalFormat = WebGL.RG16I; + if ( glType == WebGL.INT ) internalFormat = WebGL.RG32I; + } + + if ( glFormat == WebGL.RGB_INTEGER ) { + if ( glType == WebGL.UNSIGNED_BYTE ) internalFormat = WebGL.RGB8UI; + if ( glType == WebGL.UNSIGNED_SHORT ) internalFormat = WebGL.RGB16UI; + if ( glType == WebGL.UNSIGNED_INT ) internalFormat = WebGL.RGB32UI; + if ( glType == WebGL.BYTE ) internalFormat = WebGL.RGB8I; + if ( glType == WebGL.SHORT ) internalFormat = WebGL.RGB16I; + if ( glType == WebGL.INT ) internalFormat = WebGL.RGB32I; + } + + if ( glFormat == WebGL.RGBA_INTEGER ) { + + if ( glType == WebGL.UNSIGNED_BYTE ) internalFormat = WebGL.RGBA8UI; + if ( glType == WebGL.UNSIGNED_SHORT ) internalFormat = WebGL.RGBA16UI; + if ( glType == WebGL.UNSIGNED_INT ) internalFormat = WebGL.RGBA32UI; + if ( glType == WebGL.SHORT ) internalFormat = WebGL.RGBA16I; + if ( glType == WebGL.INT ) internalFormat = WebGL.RGBA32I; + + } + + if ( glFormat == WebGL.RGB ) { + if ( glType == WebGL.UNSIGNED_INT_5_9_9_9_REV ) internalFormat = WebGL.RGB9_E5; + } + + if ( glFormat == WebGL.RGBA ) { + final String transfer = forceLinearTransfer ? LinearTransfer : ColorManagement.getTransfer( ColorSpace.fromString(colorSpace)); + + if ( glType == WebGL.FLOAT ) internalFormat = WebGL.RGBA32F; + if ( glType == WebGL.HALF_FLOAT ) internalFormat = WebGL.RGBA16F; + if ( glType == WebGL.UNSIGNED_BYTE ) internalFormat = ( transfer == SRGBTransfer ) ? WebGL.SRGB8_ALPHA8 : WebGL.RGBA8; + if ( glType == WebGL.UNSIGNED_SHORT_4_4_4_4 ) internalFormat = WebGL.RGBA4; + if ( glType == WebGL.UNSIGNED_SHORT_5_5_5_1 ) internalFormat = WebGL.RGB5_A1; + } + + if ( internalFormat == WebGL.R16F || internalFormat == WebGL.R32F || + internalFormat == WebGL.RG16F || internalFormat == WebGL.RG32F || + internalFormat == WebGL.RGBA16F || internalFormat == WebGL.RGBA32F ) { + extensions.get( 'EXT_color_buffer_float' ); + } + + return internalFormat; + } + + int getInternalDepthFormat(bool useStencil, [int? depthType ]) { + late int glInternalFormat; + + if ( useStencil ) { + if ( depthType == null || depthType == UnsignedIntType || depthType == UnsignedInt248Type ) { + glInternalFormat = WebGL.DEPTH24_STENCIL8; + } else if ( depthType == FloatType ) { + glInternalFormat = WebGL.DEPTH32F_STENCIL8; + } else if ( depthType == UnsignedShortType ) { + glInternalFormat = WebGL.DEPTH24_STENCIL8; + console.warning( 'DepthTexture: 16 bit depth attachment is not supported with stencil. Using 24-bit attachment.' ); + } + } else { + if ( depthType == null || depthType == UnsignedIntType || depthType == UnsignedInt248Type ) { + glInternalFormat = WebGL.DEPTH_COMPONENT24; + } else if ( depthType == FloatType ) { + glInternalFormat = WebGL.DEPTH_COMPONENT32F; + } else if ( depthType == UnsignedShortType ) { + glInternalFormat = WebGL.DEPTH_COMPONENT16; + } + } + + return glInternalFormat; + } + + int getMipLevels(Texture texture, image) { + if ( + textureNeedsGenerateMipmaps(texture)|| + (texture is FramebufferTexture && + texture.minFilter != NearestFilter && + texture.minFilter != LinearFilter + ) + ){ + return MathUtils.log2( + math.max( + image.width, + image.height + ) + ).toInt() + 1; + } + else if (texture.mipmaps.isNotEmpty) { + // user-defined mipmaps + return texture.mipmaps.length; + } + else if (texture is CompressedTexture && texture.image is List) { + // Dart: TODO texture.image is List ??? + return image.mipmaps.length; + } + else { + // texture without mipmaps (only base level) + return 1; + } + } + + // + + void onTextureDispose(Event event) { + final texture = event.target; + + texture.removeEventListener('dispose', onTextureDispose); + + deallocateTexture(texture); + + if (texture is VideoTexture) { + _videoTextures.delete(texture); + } + } + + void onRenderTargetDispose(Event event) { + final renderTarget = event.target; + renderTarget.removeEventListener('dispose', onRenderTargetDispose); + deallocateRenderTarget(renderTarget); + } + + void deallocateTexture(Texture texture) { + final textureProperties = properties.get(texture); + + if (textureProperties["__webglInit"] == null) return; + + final source = texture.source; + final webglTextures = _sources.get(source); + + if (webglTextures != null) { + Map webglTexture = webglTextures[textureProperties["__cacheKey"]]; + webglTexture["usedTimes"]--; + + if (webglTexture["usedTimes"] == 0) { + deleteTexture(texture); + } + + if (webglTextures.keys.length == 0) { + _sources.delete(source); + } + } + + properties.remove(texture); + } + + void deleteTexture(Texture texture) { + final textureProperties = properties.get(texture); + _gl.deleteTexture(textureProperties["__webglTexture"]); + + final source = texture.source; + Map webglTextures = _sources.get(source); + webglTextures.remove(textureProperties["__cacheKey"]); + + info.memory["textures"] = info.memory["textures"]! - 1; + } + + void deallocateRenderTarget(RenderTarget renderTarget) { + final renderTargetProperties = properties.get(renderTarget); + + if (renderTarget.depthTexture != null) { + renderTarget.depthTexture!.dispose(); + properties.remove( renderTarget.depthTexture ); + } + + if (renderTarget is AngleCubeRenderTarget) { + for (int i = 0; i < 6; i++) { + gl.deleteFramebuffer(renderTargetProperties["__webglFramebuffer"][i]); + if (renderTargetProperties['__webglFramebuffer'][ i ] is List) { + for (int level = 0; level < renderTargetProperties['__webglFramebuffer'][ i ].length; level ++ ) _gl.deleteFramebuffer( renderTargetProperties['__webglFramebuffer'][ i ][ level ] ); + } else { + _gl.deleteFramebuffer( renderTargetProperties['__webglFramebuffer'][ i ] ); + } + if (renderTargetProperties["__webglDepthbuffer"] != null) { + gl.deleteRenderbuffer(renderTargetProperties["__webglDepthbuffer"][i]); + } + } + } else { + if (renderTargetProperties['__webglFramebuffer'] is List) { + for (int level = 0; level < renderTargetProperties['__webglFramebuffer'].length; level ++ ) _gl.deleteFramebuffer( renderTargetProperties['__webglFramebuffer'][ level ] ); + } else { + _gl.deleteFramebuffer( renderTargetProperties['__webglFramebuffer'] ); + } + + gl.deleteFramebuffer(renderTargetProperties["__webglFramebuffer"]); + if (renderTargetProperties["__webglDepthbuffer"] != null) { + gl.deleteRenderbuffer(renderTargetProperties["__webglDepthbuffer"]); + } + if (renderTargetProperties["__webglMultisampledFramebuffer"] != null) { + gl.deleteFramebuffer(renderTargetProperties["__webglMultisampledFramebuffer"]); + } + if (renderTargetProperties["__webglColorRenderbuffer"] != null) { + for (int i = 0; i < renderTargetProperties['__webglColorRenderbuffer'].length; i ++ ) { + if ( renderTargetProperties['__webglColorRenderbuffer'][ i ] != null) _gl.deleteRenderbuffer( renderTargetProperties['__webglColorRenderbuffer'][ i ] ); + } + } + if (renderTargetProperties["__webglDepthRenderbuffer"] != null) { + gl.deleteRenderbuffer(renderTargetProperties["__webglDepthRenderbuffer"]); + } + } + + final textures = renderTarget.textures; + for (int i = 0, il = textures.length; i < il; i++) { + final attachmentProperties = properties.get(textures[i]); + + if (attachmentProperties["__webglTexture"] != null) { + gl.deleteTexture(attachmentProperties["__webglTexture"]); + + info.memory["textures"] = info.memory["textures"]! - 1; + } + + properties.remove(textures[i]); + } + + properties.remove(renderTarget); + } + + // + + int textureUnits = 0; + + void resetTextureUnits() => textureUnits = 0; + + int allocateTextureUnit() { + int textureUnit = textureUnits; + + if (textureUnit >= maxTextures) { + console.warning('WebGLTextures: Trying to use $textureUnit texture units while this GPU supports only $maxTextures'); + } + + textureUnits += 1; + + return textureUnit; + } + + String getTextureCacheKey(Texture texture) { + final array = []; + + array.add(texture.wrapS); + array.add(texture.wrapT); + array.add(texture.wrapR); + array.add(texture.magFilter); + array.add(texture.minFilter); + array.add(texture.anisotropy); + array.add(texture.internalFormat); + array.add(texture.format); + array.add(texture.type); + array.add(texture.generateMipmaps); + array.add(texture.premultiplyAlpha); + array.add(texture.flipY); + array.add(texture.unpackAlignment); + array.add(texture.colorSpace); + + return array.join(); + } + + void setTexture2D(Texture texture, int slot) { + final textureProperties = properties.get(texture); + + if (texture is VideoTexture) updateVideoTexture(texture); + + if (!texture.isRenderTargetTexture && texture.version > 0 && textureProperties["__version"] != texture.version) { + final image = texture.image; + if (image == null) { + console.warning('WebGLRenderer: Texture marked for update but image is null'); + } + else if (image.complete == false) { + console.warning('WebGLRenderer: Texture marked for update but image is incomplete'); + } + else { + uploadTexture(textureProperties, texture, slot); + return; + } + } + state.activeTexture(WebGL.TEXTURE0 + slot); + state.bindTexture(WebGL.TEXTURE_2D, textureProperties["__webglTexture"]); + } + + void setTexture2DArray(Texture texture, int slot) { + final textureProperties = properties.get(texture); + + if (texture.version > 0 && textureProperties["__version"] != texture.version) { + uploadTexture(textureProperties, texture, slot); + return; + } + state.activeTexture(WebGL.TEXTURE0 + slot); + state.bindTexture(WebGL.TEXTURE_2D_ARRAY, textureProperties["__webglTexture"]); + } + + void setTexture3D(Texture texture, int slot) { + final textureProperties = properties.get(texture); + + if (texture.version > 0 && textureProperties["__version"] != texture.version) { + uploadTexture(textureProperties, texture, slot); + return; + } + state.activeTexture(WebGL.TEXTURE0 + slot); + state.bindTexture(WebGL.TEXTURE_3D, textureProperties["__webglTexture"]); + } + + void setTextureCube(Texture texture, int slot) { + final textureProperties = properties.get(texture); + + if (texture.version > 0 && textureProperties["__version"] != texture.version) { + uploadCubeTexture(textureProperties, texture, slot); + return; + } + + state.activeTexture(WebGL.TEXTURE0 + slot); + state.bindTexture(WebGL.TEXTURE_CUBE_MAP, textureProperties["__webglTexture"]); + } + + void setTextureParameters(textureType, Texture texture, [supportsMips]) { + if ( texture.type == FloatType && !extensions.has( 'OES_texture_float_linear' ) && + ( texture.magFilter == LinearFilter || texture.magFilter == LinearMipmapNearestFilter || texture.magFilter == NearestMipmapLinearFilter || texture.magFilter == LinearMipmapLinearFilter || + texture.minFilter == LinearFilter || texture.minFilter == LinearMipmapNearestFilter || texture.minFilter == NearestMipmapLinearFilter || texture.minFilter == LinearMipmapLinearFilter ) ) { + console.warning( 'THREE.WebGLRenderer: Unable to use linear filtering with floating point textures. OES_texture_float_linear not supported on this device.' ); + } + + _gl.texParameteri( textureType, WebGL.TEXTURE_WRAP_S, wrappingToGL[ texture.wrapS ]! ); + _gl.texParameteri( textureType, WebGL.TEXTURE_WRAP_T, wrappingToGL[ texture.wrapT ]! ); + + if ( textureType == WebGL.TEXTURE_3D || textureType == WebGL.TEXTURE_2D_ARRAY ) { + _gl.texParameteri( textureType, WebGL.TEXTURE_WRAP_R, wrappingToGL[ texture.wrapR ]! ); + } + + _gl.texParameteri( textureType, WebGL.TEXTURE_MAG_FILTER, filterToGL[ texture.magFilter ]! ); + _gl.texParameteri( textureType, WebGL.TEXTURE_MIN_FILTER, filterToGL[ texture.minFilter ]! ); + + if (texture is DepthTexture && texture.compareFunction != null) { + _gl.texParameteri( textureType, WebGL.TEXTURE_COMPARE_MODE, WebGL.COMPARE_REF_TO_TEXTURE ); + _gl.texParameteri( textureType, WebGL.TEXTURE_COMPARE_FUNC, compareToGL[ texture.compareFunction ]! ); + } + + if ( extensions.has( 'EXT_texture_filter_anisotropic' )) { + if ( texture.magFilter == NearestFilter ) return; + if ( texture.minFilter != NearestMipmapLinearFilter && texture.minFilter != LinearMipmapLinearFilter ) return; + if ( texture.type == FloatType && !extensions.has( 'OES_texture_float_linear' )) return; // verify extension + + if ( texture.anisotropy > 1 || properties.get( texture )['__currentAnisotropy'] != null) { + // final extension = extensions.get( 'EXT_texture_filter_anisotropic' ); + // if (kIsWeb && !kIsWasm) { + // gl.texParameterf(textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT,math.min(texture.anisotropy, capabilities.getMaxAnisotropy()).toDouble()); + // } + // else { + gl.texParameterf(textureType, WebGL.TEXTURE_MAX_ANISOTROPY_EXT,math.min(texture.anisotropy, capabilities.getMaxAnisotropy()).toDouble()); + //} + properties.get( texture )['__currentAnisotropy'] = texture.anisotropy; + } + } + } + + bool initTexture(Map textureProperties, Texture texture) { + bool forceUpload = false; + + if (textureProperties["__webglInit"] != true) { + textureProperties["__webglInit"] = true; + + texture.addEventListener('dispose', onTextureDispose); + } + + final source = texture.source; + Map? webglTextures = _sources.get(source); + + if (webglTextures == null) { + webglTextures = {}; + _sources.set(source, webglTextures); + } + + // check if there is already a WebGLTexture object for the given texture parameters + + final textureCacheKey = getTextureCacheKey(texture); + + if (textureCacheKey != textureProperties["__cacheKey"]) { + // if not, create a new instance of WebGLTexture + + if (webglTextures[textureCacheKey] == null) { + // create new entry + + webglTextures[textureCacheKey] = {"texture": _gl.createTexture(), "usedTimes": 0}; + + info.memory["textures"] = info.memory["textures"]! + 1; + + // when a new instance of WebGLTexture was created, a texture upload is required + // even if the image contents are identical + + forceUpload = true; + } + + webglTextures[textureCacheKey]["usedTimes"]++; + + // every time the texture cache key changes, it's necessary to check if an instance of + // WebGLTexture can be deleted in order to avoid a memory leak. + + final webglTexture = webglTextures[textureProperties["__cacheKey"]]; + + if (webglTexture != null) { + webglTextures[textureProperties["__cacheKey"]]["usedTimes"]--; + + if (webglTexture["usedTimes"] == 0) { + deleteTexture(texture); + } + } + + // store references to cache key and WebGLTexture object + + textureProperties["__cacheKey"] = textureCacheKey; + textureProperties["__webglTexture"] = webglTextures[textureCacheKey]["texture"]; + } + + return forceUpload; + } + + int getRow(int index, num rowLength, int componentStride ) { + return ( ( index / componentStride ).floor() / rowLength ).floor(); + } + + void updateTexture(Texture texture, ImageElement image, int glFormat, int glType ) { + int componentStride = 4; // only RGBA supported + final updateRanges = texture.updateRanges; + + if ( updateRanges.length == 0 ) { + state.texSubImage2D( WebGL.TEXTURE_2D, 0, 0, 0, image.width, image.height, glFormat, glType, image.data ); + } + else { + + // Before applying update ranges, we merge any adjacent / overlapping + // ranges to reduce load on `gl.texSubImage2D`. Empirically, this has led + // to performance improvements for applications which make heavy use of + // update ranges. Likely due to GPU command overhead. + // + // Note that to reduce garbage collection between frames, we merge the + // update ranges in-place. This is safe because this method will clear the + // update ranges once updated. + + updateRanges.sort( ( a, b ) => a.start - b.start ); + + // To merge the update ranges in-place, we work from left to right in the + // existing updateRanges array, merging ranges. This may result in a final + // array which is smaller than the original. This index tracks the last + // index representing a merged range, any data after this index can be + // trimmed once the merge algorithm is completed. + int mergeIndex = 0; + + for (int i = 1; i < updateRanges.length; i ++ ) { + final previousRange = updateRanges[ mergeIndex ]; + final range = updateRanges[ i ]; + + // Only merge if in the same row and overlapping/adjacent + final previousEnd = previousRange.start + previousRange.count; + final currentRow = getRow( range.start, image.width, componentStride ); + final previousRow = getRow( previousRange.start, image.width, componentStride ); + + // We add one here to merge adjacent ranges. This is safe because ranges + // operate over positive integers. + if ( + range.start <= previousEnd + 1 && + currentRow == previousRow && + getRow( range.start + range.count - 1, image.width, componentStride ) == currentRow // ensure range doesn't spill + ) { + + previousRange.count = math.max( + previousRange.count, + range.start + range.count - previousRange.start + ); + + } else { + ++ mergeIndex; + updateRanges[ mergeIndex ] = range; + } + } + + // Trim the array to only contain the merged ranges. + updateRanges.length = mergeIndex + 1; + + final currentUnpackRowLen = _gl.getParameter( WebGL.UNPACK_ROW_LENGTH ); + final currentUnpackSkipPixels = _gl.getParameter( WebGL.UNPACK_SKIP_PIXELS ); + final currentUnpackSkipRows = _gl.getParameter( WebGL.UNPACK_SKIP_ROWS ); + + _gl.pixelStorei( WebGL.UNPACK_ROW_LENGTH, image.width.toInt() ); + + for (int i = 0, l = updateRanges.length; i < l; i ++ ) { + final range = updateRanges[ i ]; + + final pixelStart = ( range.start / componentStride ).floor(); + final pixelCount = ( range.count / componentStride ).ceil(); + + final x = (pixelStart % image.width).toInt(); + final y = ( pixelStart / image.width ).floor(); + + // Assumes update ranges refer to contiguous memory + final width = pixelCount; + final height = 1; + + _gl.pixelStorei( WebGL.UNPACK_SKIP_PIXELS, x ); + _gl.pixelStorei( WebGL.UNPACK_SKIP_ROWS, y ); + + state.texSubImage2D( WebGL.TEXTURE_2D, 0, x, y, width, height, glFormat, glType, image.data ); + } + + texture.clearUpdateRanges(); + + _gl.pixelStorei( WebGL.UNPACK_ROW_LENGTH, currentUnpackRowLen ); + _gl.pixelStorei( WebGL.UNPACK_SKIP_PIXELS, currentUnpackSkipPixels ); + _gl.pixelStorei( WebGL.UNPACK_SKIP_ROWS, currentUnpackSkipRows ); + } + } + + void uploadTexture(Map textureProperties, Texture texture, int slot) { + dynamic textureType = WebGL.TEXTURE_2D; + + if (texture is DataArrayTexture) textureType = WebGL.TEXTURE_2D_ARRAY; + if (texture is Data3DTexture) textureType = WebGL.TEXTURE_3D; + + final forceUpload = initTexture(textureProperties, texture); + final source = texture.source; + + state.activeTexture(WebGL.TEXTURE0 + slot); + state.bindTexture(textureType, textureProperties["__webglTexture"]); + + if (source.version != source.currentVersion || forceUpload) { + + _gl.pixelStorei(WebGL.UNPACK_ALIGNMENT, texture.unpackAlignment); + if (kIsWeb) { + _gl.pixelStorei(WebGL.UNPACK_FLIP_Y_WEBGL, texture.flipY ? 1 : 0); + _gl.pixelStorei(WebGL.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha ? 1 : 0); + _gl.pixelStorei(WebGL.UNPACK_COLORSPACE_CONVERSION_WEBGL, WebGL.NONE); + } + + dynamic image = texture.image;//resizeImage(texture.image, needsPowerOfTwo, false, maxTextureSize); + image = verifyColorSpace(texture, image); + + final int glFormat = utils.convert(texture.format, texture.colorSpace); + int glType = utils.convert(texture.type); + int glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.colorSpace, texture is VideoTexture); + + setTextureParameters(textureType, texture); + + dynamic mipmap; + final mipmaps = texture.mipmaps; + + final useTexStorage = (isWebGL2 && texture is! VideoTexture); + final allocateMemory = (textureProperties["__version"] == null) || (forceUpload == true); + final dataReady = source.dataReady; + final levels = getMipLevels(texture, image); + + if (texture is DepthTexture) { + glInternalFormat = getInternalDepthFormat( texture.format == DepthStencilFormat, texture.type ); + if ( allocateMemory ) { + if ( useTexStorage ) { + state.texStorage2D( WebGL.TEXTURE_2D, 1, glInternalFormat, image.width, image.height ); + } else { + state.texImage2D( WebGL.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, null ); + } + } + } + else if (texture is DataTexture) { + // use manually created mipmaps if available + // if there are no manual mipmaps + // set 0 level mipmap and then use GL to generate other mipmap levels + + if (mipmaps.isNotEmpty) { + if (useTexStorage && allocateMemory) { + state.texStorage2D(WebGL.TEXTURE_2D, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height); + } + + for (int i = 0, il = mipmaps.length; i < il; i++) { + mipmap = mipmaps[i]; + if (useTexStorage && dataReady) { + state.texSubImage2D(WebGL.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data); + } + else { + state.texImage2D(WebGL.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data); + } + } + + texture.generateMipmaps = false; + } + else { + + if (useTexStorage) { + if (allocateMemory) { + state.texStorage2D(WebGL.TEXTURE_2D, levels, glInternalFormat, image.width.toInt(), image.height.toInt()); + } + if ( dataReady ) { + updateTexture( texture, image, glFormat, glType ); + } + } + else { + state.texImage2D(WebGL.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, image.data); + } + } + } + else if (texture is CompressedTexture) { + if ( texture is CompressedArrayTexture ) { + if ( useTexStorage && allocateMemory ) { + state.texStorage3D( WebGL.TEXTURE_2D_ARRAY, levels, glInternalFormat, mipmaps[ 0 ].width, mipmaps[ 0 ].height, image.depth ); + } + + for ( int i = 0, il = mipmaps.length; i < il; i ++ ) { + mipmap = mipmaps[ i ]; + if ( texture.format != RGBAFormat ) { + if ( glFormat > 0 ) { + if ( useTexStorage && dataReady) { + if ( texture.layerUpdates.isNotEmpty ) { + final layerByteLength = TextureUtils.getByteLength( mipmap.width, mipmap.height, texture.format, texture.type ); + for ( final layerIndex in texture.layerUpdates ) { + final layerData = mipmap.data.subarray( + layerIndex * layerByteLength / mipmap.data.BYTES_PER_ELEMENT, + ( layerIndex + 1 ) * layerByteLength / mipmap.data.BYTES_PER_ELEMENT + ); + state.compressedTexSubImage3D( WebGL.TEXTURE_2D_ARRAY, i, 0, 0, layerIndex, mipmap.width, mipmap.height, 1, glFormat, layerData ); + } + texture.clearLayerUpdates(); + } else { + state.compressedTexSubImage3D( WebGL.TEXTURE_2D_ARRAY, i, 0, 0, 0, mipmap.width, mipmap.height, image.depth, glFormat, mipmap.data ); + } + } else { + state.compressedTexImage3D( WebGL.TEXTURE_2D_ARRAY, i, glInternalFormat, mipmap.width, mipmap.height, image.depth, 0, mipmap.data);//, 0, 0 ); + } + } else { + console.warning( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()' ); + } + } else { + if ( useTexStorage && dataReady) { + state.texSubImage3D( WebGL.TEXTURE_2D_ARRAY, i, 0, 0, 0, mipmap.width, mipmap.height, image.depth, glFormat, glType, mipmap.data ); + } else { + state.texImage3D( WebGL.TEXTURE_2D_ARRAY, i, glInternalFormat, mipmap.width, mipmap.height, image.depth, 0, glFormat, glType, mipmap.data ); + } + } + } + } else { + if ( useTexStorage && allocateMemory ) { + state.texStorage2D( WebGL.TEXTURE_2D, levels, glInternalFormat, mipmaps[ 0 ].width, mipmaps[ 0 ].height ); + } + + for (int i = 0, il = mipmaps.length; i < il; i ++ ) { + mipmap = mipmaps[ i ]; + + if ( texture.format != RGBAFormat ) { + if ( glFormat > 0 ) { + if ( useTexStorage && dataReady) { + state.compressedTexSubImage2D( WebGL.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data ); + } else { + state.compressedTexImage2D( WebGL.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data ); + } + } else { + console.warning( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()' ); + } + } else { + if ( useTexStorage && dataReady) { + state.texSubImage2D( WebGL.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data ); + } else { + state.texImage2D( WebGL.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); + } + } + } + } + } + else if (texture is DataArrayTexture) { + if (useTexStorage) { + if (allocateMemory) { + state.texStorage3D(WebGL.TEXTURE_2D_ARRAY, levels, glInternalFormat, image.width, image.height, image.depth); + } + if(dataReady){ + if ( texture.layerUpdates.isNotEmpty ) { + final layerByteLength = TextureUtils.getByteLength( image.width, image.height, texture.format, texture.type ); + for ( final layerIndex in texture.layerUpdates ) { + final layerData = image.data.subarray( + layerIndex * layerByteLength / image.data.BYTES_PER_ELEMENT, + ( layerIndex + 1 ) * layerByteLength / image.data.BYTES_PER_ELEMENT + ); + state.texSubImage3D( WebGL.TEXTURE_2D_ARRAY, 0, 0, 0, layerIndex, image.width, image.height, 1, glFormat, glType, layerData ); + } + + texture.clearLayerUpdates(); + } + else { + state.texSubImage3D( WebGL.TEXTURE_2D_ARRAY, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data ); + } + } + } else { + state.texImage3D(WebGL.TEXTURE_2D_ARRAY, 0, glInternalFormat, image.width, image.height, image.depth, 0, + glFormat, glType, image.data); + } + } + else if (texture is Data3DTexture) { + if (useTexStorage) { + if (allocateMemory) { + state.texStorage3D(WebGL.TEXTURE_3D, levels, glInternalFormat, image.width, image.height, image.depth); + } + if(dataReady){ + state.texSubImage3D(WebGL.TEXTURE_3D, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data); + } + } else { + state.texImage3D(WebGL.TEXTURE_3D, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat,glType, image.data); + } + } + else if (texture is FramebufferTexture) { + if (allocateMemory) { + if (useTexStorage) { + state.texStorage2D(WebGL.TEXTURE_2D, levels, glInternalFormat, image.width, image.height); + } else{ + int width = image.width, height = image.height; + + for (int i = 0; i < levels; i++) { + state.texImage2D(WebGL.TEXTURE_2D, i, glInternalFormat, width, height, 0, glFormat, glType, null); + + width >>= 1; + height >>= 1; + } + } + } + } + else { + // regular Texture (image, video, canvas) + + // use manually created mipmaps if available + // if there are no manual mipmaps + // set 0 level mipmap and then use GL to generate other mipmap levels + + if (mipmaps.isNotEmpty) { + if (useTexStorage && allocateMemory) { + state.texStorage2D(WebGL.TEXTURE_2D, levels, glInternalFormat, mipmaps[0].width, mipmaps[0].height); + } + + for (int i = 0, il = mipmaps.length; i < il; i++) { + mipmap = mipmaps[i]; + if (useTexStorage && dataReady) { + state.texSubImage2DIf(WebGL.TEXTURE_2D, i, 0, 0, glFormat, glType, mipmap); + } + else { + state.texImage2DIf(WebGL.TEXTURE_2D, i, glInternalFormat, glFormat, glType, mipmap); + } + } + + texture.generateMipmaps = false; + } + else { + if (useTexStorage) { + if (allocateMemory) { + state.texStorage2D(WebGL.TEXTURE_2D, levels, glInternalFormat, image.width.toInt(), image.height.toInt()); + } + if(dataReady){ + state.texSubImage2DIf(WebGL.TEXTURE_2D, 0, 0, 0, glFormat, glType, image); + } + } + else { + state.texImage2DIf(WebGL.TEXTURE_2D, 0, glInternalFormat, glFormat, glType, image); + } + } + } + + if (textureNeedsGenerateMipmaps(texture)) { + generateMipmap(textureType); + } + + source.currentVersion = source.version; + + if (texture.onUpdate != null) texture.onUpdate!(texture); + } + + textureProperties["__version"] = texture.version; + } + + void uploadCubeTexture(Map textureProperties, Texture texture, int slot) { + if (texture.image.length != 6) return; + + final forceUpload = initTexture(textureProperties, texture); + final source = texture.source; + + state.activeTexture(WebGL.TEXTURE0 + slot); + state.bindTexture(WebGL.TEXTURE_CUBE_MAP, textureProperties['__webglTexture']); + + if (source.version != source.currentVersion || forceUpload) { + state.activeTexture(WebGL.TEXTURE0 + slot); + + + _gl.pixelStorei(WebGL.UNPACK_ALIGNMENT, texture.unpackAlignment); + if (kIsWeb) { + final workingPrimaries = ColorManagement.getPrimaries( ColorManagement.workingColorSpace ); + final texturePrimaries = texture.colorSpace == NoColorSpace ? null : ColorManagement.getPrimaries( ColorSpace.fromString(texture.colorSpace) ); + final unpackConversion = texture.colorSpace == NoColorSpace || workingPrimaries == texturePrimaries ? WebGL.NONE : WebGL.BROWSER_DEFAULT_WEBGL; + + _gl.pixelStorei(WebGL.UNPACK_FLIP_Y_WEBGL, texture.flipY ? 1 : 0); + _gl.pixelStorei(WebGL.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha ? 1 : 0); + _gl.pixelStorei(WebGL.UNPACK_COLORSPACE_CONVERSION_WEBGL, unpackConversion); + } + + final isCompressed = (texture.isCompressedTexture || texture is CompressedTexture); + final isDataTexture = (texture.image[0] != null && texture is DataTexture); + final isCubeTexture = (texture.image[0] != null && texture is CubeTexture); + print('here1'); + final cubeImage = []; + + for (int i = 0; i < 6; i++) { + if (!isCompressed && !isDataTexture) { + cubeImage.add(texture.image[i]); + } + else { + print('here2'); + cubeImage.add(isDataTexture ? texture.image[i].image : texture.image[i]); + } + + cubeImage[i] = verifyColorSpace(texture, cubeImage[i]); + } + + final image = cubeImage[0], + glFormat = utils.convert(texture.format, texture.colorSpace), + glType = utils.convert(texture.type), + glInternalFormat = getInternalFormat(texture.internalFormat, glFormat, glType, texture.colorSpace); + + final useTexStorage = (isWebGL2 && texture is! VideoTexture); + final allocateMemory = (textureProperties['__version'] == null); + final dataReady = source.dataReady; + int levels = getMipLevels(texture, image); + + setTextureParameters(WebGL.TEXTURE_CUBE_MAP, texture); + + dynamic mipmaps; + + if (isCompressed) { + if (useTexStorage && allocateMemory) { + state.texStorage2D(WebGL.TEXTURE_CUBE_MAP, levels, glInternalFormat, image.width, image.height); + } + + for (int i = 0; i < 6; i++) { + mipmaps = cubeImage[i].mipmaps; + + for (int j = 0; j < mipmaps.length; j++) { + final mipmap = mipmaps[j]; + + if (texture.format != RGBAFormat) { + if (glFormat != null) { + if (useTexStorage && dataReady) { + state.compressedTexSubImage2D(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data); + } + else { + state.compressedTexImage2D(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data); + } + } + else { + console.warning('WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()'); + } + } + else { + if (useTexStorage && dataReady) { + state.texSubImage2D(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, 0, 0, mipmap.width, mipmap.height, glFormat,glType, mipmap.data); + } + else { + state.texImage2D(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height,0, glFormat, glType, mipmap.data); + } + } + } + } + } + else { + mipmaps = texture.mipmaps; + + if (useTexStorage && allocateMemory) { + // TODO: Uniformly handle mipmap definitions + // Normal textures and compressed cube textures define base level + mips with their mipmap array + // Uncompressed cube textures use their mipmap array only for mips (no base level) + + if (mipmaps.length > 0) levels++; + + state.texStorage2D(WebGL.TEXTURE_CUBE_MAP, levels, glInternalFormat, cubeImage[0].width, cubeImage[0].height); + } + + for (int i = 0; i < 6; i++) { + if (isDataTexture || isCubeTexture) { + if (useTexStorage && dataReady) { + if( kIsWeb ){ + state.texSubImage2DNoSize(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, glFormat, glType, cubeImage[i].data); + } + else{ + state.texSubImage2D(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, cubeImage[i].width, cubeImage[i].height, glFormat, glType, cubeImage[i].data); + } + } + else { + if( kIsWeb ){ + state.texImage2DNoSize(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, glFormat, glType, cubeImage[i].data); + } + else{ + state.texImage2D(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, cubeImage[i].width,cubeImage[i].height, 0, glFormat, glType, cubeImage[i].data); + } + } + + for (int j = 0; j < mipmaps.length; j++) { + final mipmap = mipmaps[j]; + final mipmapImage = mipmap.image[i].image; + + if (useTexStorage && dataReady) { + state.texSubImage2D(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, mipmapImage.width,mipmapImage.height, glFormat, glType, mipmapImage.data); + } + else { + state.texImage2D(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, glInternalFormat, mipmapImage.width,mipmapImage.height, 0, glFormat, glType, mipmapImage.data); + } + } + } + else { + if (useTexStorage && dataReady) { + state.texSubImage2DIf(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, glFormat, glType, cubeImage[i]); + } + else { + state.texImage2DIf(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, glFormat, glType, cubeImage[i]); + } + + for (int j = 0; j < mipmaps.length; j++) { + final mipmap = mipmaps[j]; + + if (useTexStorage && dataReady) { + state.texSubImage2DIf(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, glFormat, glType, mipmap.image[i]); + } + else { + state.texImage2DIf(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, glInternalFormat, glFormat, glType, mipmap.image[i]); + } + } + } + } + } + + if (textureNeedsGenerateMipmaps(texture)) { + // We assume images for cube map have the same size. + generateMipmap(WebGL.TEXTURE_CUBE_MAP); + } + + source.currentVersion = source.version; + + if (texture.onUpdate != null) texture.onUpdate!(texture); + } + + textureProperties['__version'] = texture.version; + } + + // Render targets + + // Setup storage for target texture and bind it to correct framebuffer + void setupFrameBufferTexture(framebuffer, RenderTarget renderTarget, Texture texture, attachment, textureTarget, level ) { + final glFormat = utils.convert( texture.format, texture.colorSpace ); + final glType = utils.convert( texture.type ); + final glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.colorSpace ); + final renderTargetProperties = properties.get( renderTarget ); + final textureProperties = properties.get( texture ); + + textureProperties['__renderTarget'] = renderTarget; + + if (renderTargetProperties['__hasExternalTextures'] == null) { + + final width = math.max( 1, renderTarget.width >> level ); + final height = math.max( 1, renderTarget.height >> level ); + + if ( textureTarget == WebGL.TEXTURE_3D || textureTarget == WebGL.TEXTURE_2D_ARRAY ) { + state.texImage3D( textureTarget, level, glInternalFormat, width, height, renderTarget.depth, 0, glFormat, glType, null ); + } else { + state.texImage2D( textureTarget, level, glInternalFormat, width, height, 0, glFormat, glType, null ); + } + } + + state.bindFramebuffer( WebGL.FRAMEBUFFER, framebuffer ); + + if ( useMultisampledRTT( renderTarget ) && multisampledRTTExt != null) { + multisampledRTTExt.framebufferTexture2DMultisampleEXT( WebGL.FRAMEBUFFER, attachment, textureTarget, textureProperties['__webglTexture'], 0, getRenderTargetSamples( renderTarget ) ); + } + else if ( textureTarget == WebGL.TEXTURE_2D || ( textureTarget >= WebGL.TEXTURE_CUBE_MAP_POSITIVE_X && textureTarget <= WebGL.TEXTURE_CUBE_MAP_NEGATIVE_Z ) ) { // see #24753 + _gl.framebufferTexture2D( WebGL.FRAMEBUFFER, attachment, textureTarget, textureProperties['__webglTexture'], level ); + } + + state.bindFramebuffer( WebGL.FRAMEBUFFER, null ); + } + + // Setup storage for internal depth/stencil buffers and bind to correct framebuffer + void setupRenderBufferStorage(Renderbuffer renderbuffer, RenderTarget renderTarget, bool isMultisample) { + _gl.bindRenderbuffer( WebGL.RENDERBUFFER, renderbuffer ); + + if ( renderTarget.depthBuffer ) { + // retrieve the depth attachment types + final depthTexture = renderTarget.depthTexture; + final depthType = depthTexture != null && depthTexture.isDepthTexture ? depthTexture.type : null; + final glInternalFormat = getInternalDepthFormat( renderTarget.stencilBuffer, depthType ); + final glAttachmentType = renderTarget.stencilBuffer ? WebGL.DEPTH_STENCIL_ATTACHMENT : WebGL.DEPTH_ATTACHMENT; + + // set up the attachment + final samples = getRenderTargetSamples( renderTarget ); + final isUseMultisampledRTT = useMultisampledRTT( renderTarget ); + if ( isUseMultisampledRTT && multisampledRTTExt != null) { + multisampledRTTExt.renderbufferStorageMultisampleEXT( WebGL.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height ); + } + else if ( isMultisample ) { + _gl.renderbufferStorageMultisample( WebGL.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height ); + } else { + _gl.renderbufferStorage( WebGL.RENDERBUFFER, glInternalFormat, renderTarget.width, renderTarget.height ); + } + + _gl.framebufferRenderbuffer( WebGL.FRAMEBUFFER, glAttachmentType, WebGL.RENDERBUFFER, renderbuffer ); + } else { + final textures = renderTarget.textures; + + for (int i = 0; i < textures.length; i ++ ) { + final texture = textures[ i ]; + + final glFormat = utils.convert( texture.format, texture.colorSpace ); + final glType = utils.convert( texture.type ); + final glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.colorSpace ); + final samples = getRenderTargetSamples( renderTarget ); + + if ( isMultisample && useMultisampledRTT( renderTarget ) == false ) { + _gl.renderbufferStorageMultisample( WebGL.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height ); + } else if ( useMultisampledRTT( renderTarget ) ) { + multisampledRTTExt.renderbufferStorageMultisampleEXT( WebGL.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height ); + } else { + _gl.renderbufferStorage( WebGL.RENDERBUFFER, glInternalFormat, renderTarget.width, renderTarget.height ); + } + } + } + + _gl.bindRenderbuffer( WebGL.RENDERBUFFER, null ); + } + + + // Setup resources for a Depth Texture for a FBO (needs an extension) + void setupDepthTexture(framebuffer, AngleRenderTarget renderTarget) { + final renderTargetProperties = properties.get( renderTarget ); + final isCube = renderTarget is AngleCubeRenderTarget; + + // if the bound depth texture has changed + if ( renderTargetProperties['__boundDepthTexture'] != renderTarget.depthTexture ) { + // fire the dispose event to get rid of stored state associated with the previously bound depth buffer + final depthTexture = renderTarget.depthTexture; + if ( renderTargetProperties['__depthDisposeCallback'] != null) { + renderTargetProperties['__depthDisposeCallback'](); + } + + // set up dispose listeners to track when the currently attached buffer is implicitly unbound + if ( depthTexture != null) { + disposeEvent(){ + renderTargetProperties.remove('__boundDepthTexture');//delete renderTargetProperties.__boundDepthTexture; + renderTargetProperties.remove('__depthDisposeCallback');//delete renderTargetProperties.__depthDisposeCallback; + depthTexture.removeEventListener( 'dispose', disposeEvent ); + }; + + depthTexture.addEventListener( 'dispose', disposeEvent ); + renderTargetProperties['__depthDisposeCallback'] = disposeEvent; + } + renderTargetProperties['__boundDepthTexture'] = depthTexture; + } + + if ( renderTarget.depthTexture != null && ! renderTargetProperties['__autoAllocateDepthBuffer'] ) { + if ( isCube ) throw( 'target.depthTexture not supported in Cube render targets' ); + setupDepthTexture( renderTargetProperties['__webglFramebuffer'], renderTarget ); + } else { + if ( isCube ) { + renderTargetProperties['__webglDepthbuffer'] = []; + + for (int i = 0; i < 6; i ++ ) { + state.bindFramebuffer( WebGL.FRAMEBUFFER, renderTargetProperties['__webglFramebuffer'][ i ] ); + + if ( renderTargetProperties['__webglDepthbuffer'][ i ] == null ) { + renderTargetProperties['__webglDepthbuffer'][ i ] = _gl.createRenderbuffer(); + setupRenderBufferStorage( renderTargetProperties['__webglDepthbuffer'][ i ], renderTarget, false ); + } else { + // attach buffer if it's been created already + final glAttachmentType = renderTarget.stencilBuffer? WebGL.DEPTH_STENCIL_ATTACHMENT : WebGL.DEPTH_ATTACHMENT; + final renderbuffer = renderTargetProperties['__webglDepthbuffer'][ i ]; + _gl.bindRenderbuffer( WebGL.RENDERBUFFER, renderbuffer ); + _gl.framebufferRenderbuffer( WebGL.FRAMEBUFFER, glAttachmentType, WebGL.RENDERBUFFER, renderbuffer ); + } + } + } else { + state.bindFramebuffer( WebGL.FRAMEBUFFER, renderTargetProperties['__webglFramebuffer'] ); + + if ( renderTargetProperties['__webglDepthbuffer'] == null ) { + renderTargetProperties['__webglDepthbuffer'] = _gl.createRenderbuffer(); + setupRenderBufferStorage( renderTargetProperties['__webglDepthbuffer'], renderTarget, false ); + } else { + // attach buffer if it's been created already + final glAttachmentType = renderTarget.stencilBuffer ? WebGL.DEPTH_STENCIL_ATTACHMENT : WebGL.DEPTH_ATTACHMENT; + final renderbuffer = renderTargetProperties['__webglDepthbuffer']; + _gl.bindRenderbuffer( WebGL.RENDERBUFFER, renderbuffer ); + _gl.framebufferRenderbuffer( WebGL.FRAMEBUFFER, glAttachmentType, WebGL.RENDERBUFFER, renderbuffer ); + } + } + } + + state.bindFramebuffer( WebGL.FRAMEBUFFER, null ); + } + + // Setup GL resources for a non-texture depth buffer + void setupDepthRenderbuffer(AngleRenderTarget renderTarget) { + final renderTargetProperties = properties.get( renderTarget ); + final isCube = ( renderTarget is AngleCubeRenderTarget == true ); + + // if the bound depth texture has changed + if ( renderTargetProperties['__boundDepthTexture'] != renderTarget.depthTexture ) { + // fire the dispose event to get rid of stored state associated with the previously bound depth buffer + final depthTexture = renderTarget.depthTexture; + if ( renderTargetProperties['__depthDisposeCallback'] ) { + renderTargetProperties['__depthDisposeCallback'](); + } + + // set up dispose listeners to track when the currently attached buffer is implicitly unbound + if ( depthTexture != null) { + disposeEvent(){ + renderTargetProperties.remove('__boundDepthTexture');//delete renderTargetProperties.__boundDepthTexture; + renderTargetProperties.remove('__depthDisposeCallback');//delete renderTargetProperties.__depthDisposeCallback; + depthTexture.removeEventListener( 'dispose', disposeEvent ); + } + depthTexture.addEventListener( 'dispose', disposeEvent ); + renderTargetProperties['__depthDisposeCallback'] = disposeEvent; + } + renderTargetProperties['__boundDepthTexture'] = depthTexture; + } + + if ( renderTarget.depthTexture != null && !renderTargetProperties['__autoAllocateDepthBuffer'] ) { + if ( isCube ) throw( 'target.depthTexture not supported in Cube render targets' ); + setupDepthTexture( renderTargetProperties['__webglFramebuffer'], renderTarget ); + } else { + if (isCube) { + renderTargetProperties['__webglDepthbuffer'] = []; + + for (int i = 0; i < 6; i++) { + state.bindFramebuffer( WebGL.FRAMEBUFFER, renderTargetProperties['__webglFramebuffer'][ i ] ); + + if (renderTargetProperties['__webglDepthbuffer'].length <= i || renderTargetProperties['__webglDepthbuffer'][ i ] == null ) { + (renderTargetProperties['__webglDepthbuffer'] as List).listSetter(i,_gl.createRenderbuffer());// [ i ] = _gl.createRenderbuffer(); + setupRenderBufferStorage( renderTargetProperties['__webglDepthbuffer'][ i ], renderTarget, false ); + } else { + // attach buffer if it's been created already + final glAttachmentType = renderTarget.stencilBuffer ? WebGL.DEPTH_STENCIL_ATTACHMENT : WebGL.DEPTH_ATTACHMENT; + final renderbuffer = renderTargetProperties['__webglDepthbuffer'][ i ]; + _gl.bindRenderbuffer( WebGL.RENDERBUFFER, renderbuffer ); + _gl.framebufferRenderbuffer( WebGL.FRAMEBUFFER, glAttachmentType, WebGL.RENDERBUFFER, renderbuffer ); + } + } + } else { + state.bindFramebuffer( WebGL.FRAMEBUFFER, renderTargetProperties['__webglFramebuffer'] ); + + if ( renderTargetProperties['__webglDepthbuffer'] == null ) { + renderTargetProperties['__webglDepthbuffer'] = _gl.createRenderbuffer(); + setupRenderBufferStorage( renderTargetProperties['__webglDepthbuffer'], renderTarget, false ); + } else { + // attach buffer if it's been created already + final glAttachmentType = renderTarget.stencilBuffer ? WebGL.DEPTH_STENCIL_ATTACHMENT : WebGL.DEPTH_ATTACHMENT; + final renderbuffer = renderTargetProperties['__webglDepthbuffer']; + _gl.bindRenderbuffer( WebGL.RENDERBUFFER, renderbuffer ); + _gl.framebufferRenderbuffer( WebGL.FRAMEBUFFER, glAttachmentType, WebGL.RENDERBUFFER, renderbuffer ); + } + } + } + + state.bindFramebuffer( WebGL.FRAMEBUFFER, null ); + } + + // rebind framebuffer with external textures + void rebindTextures(AngleRenderTarget renderTarget, dynamic colorTexture, dynamic depthTexture) { + final renderTargetProperties = properties.get(renderTarget); + + if (colorTexture != null) { + setupFrameBufferTexture(renderTargetProperties["__webglFramebuffer"], renderTarget, renderTarget.texture, + WebGL.COLOR_ATTACHMENT0, WebGL.TEXTURE_2D,0); + } + + if (depthTexture != null) { + setupDepthRenderbuffer(renderTarget); + } + } + + // Set up GL resources for the render target + void setupRenderTarget(AngleRenderTarget renderTarget) { + final texture = renderTarget.texture; + + final renderTargetProperties = properties.get( renderTarget ); + final textureProperties = properties.get( texture ); + + renderTarget.addEventListener( 'dispose', onRenderTargetDispose ); + + final textures = renderTarget.textures; + + final isCube = renderTarget is AngleCubeRenderTarget; + final isMultipleRenderTargets = ( textures.length > 1 ); + + if ( ! isMultipleRenderTargets ) { + if ( textureProperties['__webglTexture'] == null ) { + textureProperties['__webglTexture'] = _gl.createTexture(); + } + + textureProperties['__version'] = texture.version; + info.memory['textures'] = info.memory['textures']! + 1; + } + + // Setup framebuffer + + if ( isCube ) { + renderTargetProperties['__webglFramebuffer'] = []; + for ( int i = 0; i < 6; i ++ ) { + if (texture.mipmaps.isNotEmpty ) { + renderTargetProperties['__webglFramebuffer'][ i ] = []; + for ( int level = 0; level < texture.mipmaps.length; level ++ ) { + renderTargetProperties['__webglFramebuffer'][ i ][ level ] = _gl.createFramebuffer(); + } + } else { + (renderTargetProperties['__webglFramebuffer'] as List).listSetter(i, _gl.createFramebuffer()); + } + } + } else { + if ( texture.mipmaps.isNotEmpty ) { + renderTargetProperties['__webglFramebuffer'] = []; + for ( int level = 0; level < texture.mipmaps.length; level ++ ) { + renderTargetProperties['__webglFramebuffer'][ level ] = _gl.createFramebuffer(); + } + } else { + renderTargetProperties['__webglFramebuffer'] = _gl.createFramebuffer(); + } + + if ( isMultipleRenderTargets ) { + for ( int i = 0, il = textures.length; i < il; i ++ ) { + final attachmentProperties = properties.get( textures[ i ] ); + if ( attachmentProperties['__webglTexture'] == null ) { + attachmentProperties['__webglTexture'] = _gl.createTexture(); + info.memory['textures'] = info.memory['textures']! +1;; + } + } + } + + if ( ( renderTarget.samples > 0 ) && useMultisampledRTT( renderTarget ) == false ) { + renderTargetProperties['__webglMultisampledFramebuffer'] = _gl.createFramebuffer(); + renderTargetProperties['__webglColorRenderbuffer'] = []; + + state.bindFramebuffer( WebGL.FRAMEBUFFER, renderTargetProperties['__webglMultisampledFramebuffer'] ); + + for ( int i = 0; i < textures.length; i ++ ) { + final texture = textures[ i ]; + (renderTargetProperties['__webglColorRenderbuffer'] as List).listSetter(i, _gl.createRenderbuffer()); + + _gl.bindRenderbuffer( WebGL.RENDERBUFFER, renderTargetProperties['__webglColorRenderbuffer'][ i ] ); + + final glFormat = utils.convert( texture.format, texture.colorSpace ); + final glType = utils.convert( texture.type ); + final glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.colorSpace, renderTarget.isXRRenderTarget == true ); + final samples = getRenderTargetSamples( renderTarget ); + + _gl.renderbufferStorageMultisample( WebGL.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height ); + _gl.framebufferRenderbuffer( WebGL.FRAMEBUFFER, WebGL.COLOR_ATTACHMENT0 + i, WebGL.RENDERBUFFER, renderTargetProperties['__webglColorRenderbuffer'][ i ] ); + } + + _gl.bindRenderbuffer( WebGL.RENDERBUFFER, null ); + + if ( renderTarget.depthBuffer ) { + renderTargetProperties['__webglDepthRenderbuffer'] = _gl.createRenderbuffer(); + setupRenderBufferStorage( renderTargetProperties['__webglDepthRenderbuffer'], renderTarget, true ); + } + + state.bindFramebuffer( WebGL.FRAMEBUFFER, null ); + } + } + + // Setup color buffer + + if ( isCube ) { + state.bindTexture( WebGL.TEXTURE_CUBE_MAP, textureProperties['__webglTexture'] ); + setTextureParameters( WebGL.TEXTURE_CUBE_MAP, texture ); + + for ( int i = 0; i < 6; i ++ ) { + if (texture.mipmaps.isNotEmpty ) { + for ( int level = 0; level < texture.mipmaps.length; level ++ ) { + setupFrameBufferTexture( renderTargetProperties['__webglFramebuffer'][ i ][ level ], renderTarget, texture, WebGL.COLOR_ATTACHMENT0, WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, level ); + } + } else { + setupFrameBufferTexture( renderTargetProperties['__webglFramebuffer'][ i ], renderTarget, texture, WebGL.COLOR_ATTACHMENT0, WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0 ); + } + } + + if ( textureNeedsGenerateMipmaps( texture ) ) { + generateMipmap( WebGL.TEXTURE_CUBE_MAP ); + } + + state.unbindTexture(); + + } else if ( isMultipleRenderTargets ) { + for ( int i = 0, il = textures.length; i < il; i ++ ) { + final attachment = textures[ i ]; + final attachmentProperties = properties.get( attachment ); + + state.bindTexture( WebGL.TEXTURE_2D, attachmentProperties['__webglTexture'] ); + setTextureParameters( WebGL.TEXTURE_2D, attachment ); + setupFrameBufferTexture( renderTargetProperties['__webglFramebuffer'], renderTarget, attachment, WebGL.COLOR_ATTACHMENT0 + i, WebGL.TEXTURE_2D, 0 ); + + if ( textureNeedsGenerateMipmaps( attachment ) ) { + generateMipmap( WebGL.TEXTURE_2D ); + } + } + + state.unbindTexture(); + } else { + int glTextureType = WebGL.TEXTURE_2D; + + if ( renderTarget is Angle3DRenderTarget || renderTarget is AngleArrayRenderTarget ) { + glTextureType = renderTarget is Angle3DRenderTarget ? WebGL.TEXTURE_3D : WebGL.TEXTURE_2D_ARRAY; + } + + state.bindTexture( glTextureType, textureProperties['__webglTexture'] ); + setTextureParameters( glTextureType, texture ); + + if (texture.mipmaps.isNotEmpty ) { + for ( int level = 0; level < texture.mipmaps.length; level ++ ) { + setupFrameBufferTexture( renderTargetProperties['__webglFramebuffer'][ level ], renderTarget, texture, WebGL.COLOR_ATTACHMENT0, glTextureType, level ); + } + } else { + setupFrameBufferTexture( renderTargetProperties['__webglFramebuffer'], renderTarget, texture, WebGL.COLOR_ATTACHMENT0, glTextureType, 0 ); + } + + if ( textureNeedsGenerateMipmaps( texture ) ) { + generateMipmap( glTextureType ); + } + state.unbindTexture(); + } + + + if ( renderTarget.depthBuffer ) { + setupDepthRenderbuffer( renderTarget ); + } + } + + void updateRenderTargetMipmap(AngleRenderTarget renderTarget) { + final textures = renderTarget.textures; + for (int i = 0, il = textures.length; i < il; i++) { + final texture = textures[i]; + + if (textureNeedsGenerateMipmaps(texture)) { + final target = renderTarget is AngleCubeRenderTarget ? WebGL.TEXTURE_CUBE_MAP : WebGL.TEXTURE_2D; + final webglTexture = properties.get(texture)["__webglTexture"]; + + state.bindTexture(target, webglTexture); + generateMipmap(target); + state.bindTexture(target, null); + } + } + } + + final Uint32List invalidationArrayDraw = Uint32List(1); + final Uint32List invalidationArrayRead = Uint32List(1); + + void updateMultisampleRenderTarget(AngleRenderTarget renderTarget) { + if ( renderTarget.samples > 0 ) { + if ( !useMultisampledRTT( renderTarget )) { + final textures = renderTarget.textures; + final width = renderTarget.width; + final height = renderTarget.height; + int mask = WebGL.COLOR_BUFFER_BIT; + final depthStyle = renderTarget.stencilBuffer ? WebGL.DEPTH_STENCIL_ATTACHMENT : WebGL.DEPTH_ATTACHMENT; + final renderTargetProperties = properties.get( renderTarget ); + final isMultipleRenderTargets = ( textures.length > 1 ); + + // If MRT we need to remove FBO attachments + if ( isMultipleRenderTargets ) { + for (int i = 0; i < textures.length; i ++ ) { + state.bindFramebuffer( WebGL.FRAMEBUFFER, renderTargetProperties['__webglMultisampledFramebuffer'] ); + _gl.framebufferRenderbuffer( WebGL.FRAMEBUFFER, WebGL.COLOR_ATTACHMENT0 + i, WebGL.RENDERBUFFER, null ); + + state.bindFramebuffer( WebGL.FRAMEBUFFER, renderTargetProperties['__webglFramebuffer'] ); + _gl.framebufferTexture2D( WebGL.DRAW_FRAMEBUFFER, WebGL.COLOR_ATTACHMENT0 + i, WebGL.TEXTURE_2D, null, 0 ); + } + } + + state.bindFramebuffer( WebGL.READ_FRAMEBUFFER, renderTargetProperties['__webglMultisampledFramebuffer'] ); + state.bindFramebuffer( WebGL.DRAW_FRAMEBUFFER, renderTargetProperties['__webglFramebuffer'] ); + + for (int i = 0; i < textures.length; i ++ ) { + if ( renderTarget.resolveDepthBuffer ) { + if ( renderTarget.depthBuffer ) mask |= WebGL.DEPTH_BUFFER_BIT; + if ( renderTarget.stencilBuffer && renderTarget.resolveStencilBuffer ) mask |= WebGL.STENCIL_BUFFER_BIT; + } + + if ( isMultipleRenderTargets ) { + _gl.framebufferRenderbuffer( WebGL.READ_FRAMEBUFFER, WebGL.COLOR_ATTACHMENT0, WebGL.RENDERBUFFER, renderTargetProperties['__webglColorRenderbuffer'][ i ] ); + + final webglTexture = properties.get( textures[ i ] )['__webglTexture']; + _gl.framebufferTexture2D( WebGL.DRAW_FRAMEBUFFER, WebGL.COLOR_ATTACHMENT0, WebGL.TEXTURE_2D, webglTexture, 0 ); + } + + _gl.blitFramebuffer( 0, 0, width, height, 0, 0, width, height, mask, WebGL.NEAREST ); + + if ( supportsInvalidateFramebuffer) { + invalidationArrayRead.length = 0; + invalidationArrayDraw.length = 0; + + invalidationArrayRead.add( WebGL.COLOR_ATTACHMENT0 + i ); + + if ( renderTarget.depthBuffer && !renderTarget.resolveDepthBuffer) { + invalidationArrayRead.add( depthStyle ); + invalidationArrayDraw.add( depthStyle ); + + _gl.invalidateFramebuffer( WebGL.DRAW_FRAMEBUFFER, invalidationArrayDraw ); + } + + _gl.invalidateFramebuffer( WebGL.READ_FRAMEBUFFER, invalidationArrayRead ); + } + } + + state.bindFramebuffer( WebGL.READ_FRAMEBUFFER, null ); + state.bindFramebuffer( WebGL.DRAW_FRAMEBUFFER, null ); + + // If MRT since pre-blit we removed the FBO we need to reconstruct the attachments + if ( isMultipleRenderTargets ) { + for (int i = 0; i < textures.length; i ++ ) { + state.bindFramebuffer( WebGL.FRAMEBUFFER, renderTargetProperties['__webglMultisampledFramebuffer'] ); + _gl.framebufferRenderbuffer( WebGL.FRAMEBUFFER, WebGL.COLOR_ATTACHMENT0 + i, WebGL.RENDERBUFFER, renderTargetProperties['__webglColorRenderbuffer'][ i ] ); + + final webglTexture = properties.get( textures[ i ] )['__webglTexture']; + + state.bindFramebuffer( WebGL.FRAMEBUFFER, renderTargetProperties['__webglFramebuffer'] ); + _gl.framebufferTexture2D( WebGL.DRAW_FRAMEBUFFER, WebGL.COLOR_ATTACHMENT0 + i, WebGL.TEXTURE_2D, webglTexture, 0 ); + } + } + + state.bindFramebuffer( WebGL.DRAW_FRAMEBUFFER, renderTargetProperties['__webglMultisampledFramebuffer'] ); + } else { + if ( renderTarget.depthBuffer && !renderTarget.resolveDepthBuffer && supportsInvalidateFramebuffer ) { + depthStyle[0] = renderTarget.stencilBuffer ? WebGL.DEPTH_STENCIL_ATTACHMENT : WebGL.DEPTH_ATTACHMENT; + _gl.invalidateFramebuffer( WebGL.DRAW_FRAMEBUFFER, depthStyle ); + } + } + } + } + + Uint32List depthStyle = Uint32List.fromList([WebGL.DEPTH_ATTACHMENT]); + + bool useMultisampledRenderToTexture(RenderTarget renderTarget) { + final renderTargetProperties = properties.get(renderTarget); + + return isWebGL2 && + renderTarget.samples > 0 && + extensions.has('WEBGL_multisampled_render_to_texture') == true && + renderTargetProperties["__useRenderToTexture"] != false; + } + + int getRenderTargetSamples(RenderTarget renderTarget) { + return math.min(maxSamples, renderTarget.samples); + } + + bool useMultisampledRTT(RenderTarget renderTarget) { + final renderTargetProperties = properties.get(renderTarget); + + return renderTarget.samples > 0 && + extensions.has('WEBGL_multisampled_render_to_texture') && + renderTargetProperties["__useRenderToTexture"] != false; + } + + void updateVideoTexture(VideoTexture texture) { + final frame = info.render["frame"]; + + // Check the last frame we updated the VideoTexture + + if (_videoTextures[texture] != frame) { + _videoTextures[texture] = frame; + texture.update(); + } + } + + void uploadOpenGLTexture(Map textureProperties, OpenGLTexture texture, int slot) { + final frame = info.render["frame"]; + if (_videoTextures[texture] != frame) { + _videoTextures[texture] = frame; + texture.update(); + } + + const textureType = WebGL.TEXTURE_2D; + + initTexture(textureProperties, texture); + + state.activeTexture(WebGL.TEXTURE0 + slot); + state.bindTexture(textureType, textureProperties["__webglTexture"]); + if( kIsWeb ){ + gl.pixelStorei(WebGL.UNPACK_FLIP_Y_WEBGL, texture.flipY ? 1 : 0); + gl.pixelStorei(WebGL.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha ? 1 : 0); + } + gl.pixelStorei(WebGL.UNPACK_ALIGNMENT, texture.unpackAlignment); + } + + verifyColorSpace(Texture texture, image) { + final colorSpace = texture.colorSpace; + final format = texture.format; + final type = texture.type; + + if ( texture.isCompressedTexture || texture is VideoTexture ) return image; + + if ( colorSpace != LinearSRGBColorSpace && colorSpace != NoColorSpace ) { + + // sRGB + + if ( ColorManagement.getTransfer( ColorSpace.fromString( colorSpace)) == SRGBTransfer ) { + + // in WebGL 2 uncompressed textures can only be sRGB encoded if they have the RGBA8 format + + if ( format != RGBAFormat || type != UnsignedByteType ) { + console.warning( 'THREE.WebGLTextures: sRGB encoded textures have to use RGBAFormat and UnsignedByteType.' ); + } + } else { + console.error( 'THREE.WebGLTextures: Unsupported texture color space: $colorSpace'); + } + } + + return image; + } + + void dispose(){ + if(_didDispose) return; + _didDispose = true; + extensions.dispose(); + state.dispose(); + properties.dispose(); + capabilities.dispose(); + utils.dispose(); + info.dispose(); + _videoTextures.clear(); + _sources.clear(); + wrappingToGL.clear(); + filterToGL.clear(); + } +} diff --git a/packages/three_js_angle_renderer/lib/angle/angle_uniforms.dart b/packages/three_js_angle_renderer/lib/angle/angle_uniforms.dart new file mode 100755 index 00000000..d118ef00 --- /dev/null +++ b/packages/three_js_angle_renderer/lib/angle/angle_uniforms.dart @@ -0,0 +1,107 @@ +/* + * Uniforms of a program. + * Those form a tree structure with a special top-level container for the root, + * which you get by calling 'new WebGLUniforms( gl, program )'. + * + * + * Properties of inner nodes including the top-level container: + * + * .seq - array of nested uniforms + * .map - nested uniforms by name + * + * + * Methods of all nodes except the top-level container: + * + * .setValue( gl, value, [textures] ) + * + * uploads a uniform value(s) + * the 'textures' parameter is needed for sampler uniforms + * + * + * Static methods of the top-level container (textures factorizations): + * + * .upload( gl, seq, values, textures ) + * + * sets uniforms in 'seq' to 'values[id].value' + * + * .seqWithValue( seq, values ) : filteredSeq + * + * filters 'seq' entries with corresponding entry in values + * + * + * Methods of the top-level container (textures factorizations): + * + * .setValue( gl, name, value, textures ) + * + * sets uniform with name 'name' to 'value' + * + * .setOptional( gl, obj, prop ) + * + * like .set for an optional property of the object + * + */ + +// Root Container + +part of three_webgl; + +class AngleUniforms with AngleUniform { + bool _didDispose = false; + RenderingContext gl; + AngleProgram program; + + AngleUniforms(this.gl, this.program) { + seq = []; + map = {}; + + final n = gl.getProgramParameter(program.program!, WebGL.ACTIVE_UNIFORMS); + + for (int i = 0; i < n.id; ++i) { + final info = gl.getActiveUniform(program.program!, i); + final addr = gl.getUniformLocation(program.program!, info.name); + parseUniform(info, addr, this); + } + } + + void dispose(){ + if(_didDispose) return; + _didDispose = true; + program.dispose(); + } + + void setValue(RenderingContext gl, String name, dynamic value, [AngleTextures? textures]) { + final u = map[name]; + if (u != null) u.setValue(gl, value, textures); + } + + void setOptional(RenderingContext gl, object, String name) { + final v = object.getValue(name); + if (v != null) setValue(gl, name, v); + } + + static void upload(RenderingContext gl, List seq, Map values, [AngleTextures? textures]) { + for (int i = 0, n = seq.length; i != n; ++i) { + final u = seq[i]; + final v = values[u.id]; + if (v["needsUpdate"] != false) { + // note: always updating when .needsUpdate is null + u.setValue(gl, v["value"], textures); + } + } + } + + static List seqWithValue(List seq, Map values) { + List r = []; + for (int i = 0, n = seq.length; i != n; ++i) { + final u = seq[i]; + // print("seqWithValue u.id: ${u.id} "); + + if (values.keys.contains(u.id)) { + r.add(u); + } else { + // print("seqWithValue u.id: ${u.id} is not add "); + } + } + return r; + } +} diff --git a/packages/three_js_angle_renderer/lib/angle/angle_uniforms_groups.dart b/packages/three_js_angle_renderer/lib/angle/angle_uniforms_groups.dart new file mode 100644 index 00000000..24238b8d --- /dev/null +++ b/packages/three_js_angle_renderer/lib/angle/angle_uniforms_groups.dart @@ -0,0 +1,278 @@ +part of three_webgl; + +class AngleUniformsGroups{ + AngleState state; + AngleCapabilities capabilities; + AngleInfo info; + + Map buffers = {}; + Map updateList = {}; + late final Uint32List allocatedBindingPoints = Uint32List(maxBindingPoints); + RenderingContext gl; + + late final int maxBindingPoints; // binding points are global whereas block indices are per shader program + + AngleUniformsGroups(this.gl, this.info, this.capabilities, this.state ){ + maxBindingPoints = gl.getParameter( WebGL.MAX_UNIFORM_BUFFER_BINDINGS ); + } + + void bind(UniformsGroup uniformsGroup, AngleProgram? program ) { + final webglProgram = program?.program; + state.uniformBlockBinding( uniformsGroup, webglProgram ); + } + + void update(uniformsGroup, AngleProgram? program ) { + dynamic buffer = buffers[uniformsGroup.id]; + + if ( buffer == null ) { + prepareUniformsGroup( uniformsGroup ); + buffer = createBuffer( uniformsGroup ); + buffers[ uniformsGroup.id ] = buffer; + uniformsGroup.addEventListener( 'dispose', onUniformsGroupsDispose ); + } + + // ensure to update the binding points/block indices mapping for this program + + final webglProgram = program?.program; + state.updateUBOMapping( uniformsGroup, webglProgram! ); + + // update UBO once per frame + + final frame = info.render['frame']; + + if ( updateList[ uniformsGroup.id ] != frame ) { + updateBufferData( uniformsGroup ); + updateList[ uniformsGroup.id ] = frame; + } + } + + Buffer createBuffer(UniformsGroup uniformsGroup ) { + final bindingPointIndex = allocateBindingPointIndex(); + uniformsGroup.bindingPointIndex = bindingPointIndex; + + final buffer = gl.createBuffer(); + final size = uniformsGroup.size; + final usage = uniformsGroup.usage; + + gl.bindBuffer( WebGL.UNIFORM_BUFFER, buffer ); + gl.bufferData( WebGL.UNIFORM_BUFFER, size!, usage); + gl.bindBuffer( WebGL.UNIFORM_BUFFER, null ); + gl.bindBufferBase( WebGL.UNIFORM_BUFFER, bindingPointIndex, buffer ); + + return buffer; + } + + int allocateBindingPointIndex() { + for (int i = 0; i < maxBindingPoints; i ++ ) { + if (allocatedBindingPoints[i] == 0) { + allocatedBindingPoints[i] = 1; + return i; + } + } + + console.error( 'THREE.WebGLRenderer: Maximum number of simultaneously usable uniforms groups reached.' ); + return 0; + } + + void updateBufferData(Map uniformsGroup ) { + final buffer = buffers[ uniformsGroup['id'] ]; + final uniforms = uniformsGroup['uniforms']; + final cache = uniformsGroup['__cache']; + + gl.bindBuffer( WebGL.UNIFORM_BUFFER, buffer ); + + for (int i = 0, il = uniforms.length; i < il; i ++ ) { + final uniformArray = uniforms[ i ] is List? uniforms[ i ] : [ uniforms[ i ] ]; + + for (int j = 0, jl = uniformArray.length; j < jl; j ++ ) { + final uniform = uniformArray[ j ]; + + if ( hasUniformChanged( uniform, i, j, cache ) == true ) { + final offset = uniform['__offset']; + final values = uniform['value'] is List? uniform['value'] : [ uniform['value'] ]; + int arrayOffset = 0; + + for (int k = 0; k < values.length; k ++ ) { + final value = values[ k ]; + final info = getUniformSize( value ); + + // TODO add integer and struct support + if (value is double || value is int || value is num || value is bool ) { + uniform['__data'][ 0 ] = value; + gl.bufferSubData( WebGL.UNIFORM_BUFFER, offset + arrayOffset, uniform['__data'] ); + } + else if ( value is Matrix3 ) { + uniform['__data'][ 0 ] = value.storage[ 0 ]; + uniform['__data'][ 1 ] = value.storage[ 1 ]; + uniform['__data'][ 2 ] = value.storage[ 2 ]; + uniform['__data'][ 3 ] = 0; + uniform['__data'][ 4 ] = value.storage[ 3 ]; + uniform['__data'][ 5 ] = value.storage[ 4 ]; + uniform['__data'][ 6 ] = value.storage[ 5 ]; + uniform['__data'][ 7 ] = 0; + uniform['__data'][ 8 ] = value.storage[ 6 ]; + uniform['__data'][ 9 ] = value.storage[ 7 ]; + uniform['__data'][ 10 ] = value.storage[ 8 ]; + uniform['__data'][ 11 ] = 0; + } + else { + value.toArray( uniform['__data'], arrayOffset ); + arrayOffset += info['storage']! ~/ Float32List.bytesPerElement; + } + } + + gl.bufferSubData( WebGL.UNIFORM_BUFFER, offset, uniform['__data'] ); + } + } + } + + gl.bindBuffer( WebGL.UNIFORM_BUFFER, null ); + } + + bool hasUniformChanged( uniform, int index, indexArray, cache ) { + final value = uniform['value']; + final indexString = '${index}_$indexArray'; + + if ( cache[ indexString ] == null ) { + if (value is double || value is int || value is num || value is bool ) { + cache[ indexString ] = value; + } else { + cache[ indexString ] = value.clone(); + } + + return true; + } + else { + final cachedObject = cache[ indexString ]; + + // compare current value with cached entry + + if (value is double || value is int || value is num || value is bool ) { + if ( cachedObject != value ) { + cache[ indexString ] = value; + return true; + } + } + else { + if ( cachedObject.equals( value ) == false ) { + cachedObject.copy( value ); + return true; + } + } + } + + return false; + } + + AngleUniformsGroups prepareUniformsGroup(UniformsGroup uniformsGroup ) { + // determine total buffer size according to the STD140 layout + // Hint: STD140 is the only supported layout in WebGL 2 + final uniforms = uniformsGroup.uniforms; + + int offset = 0; // global buffer offset in bytes + const int chunkSize = 16; // size of a chunk in bytes + + for (int i = 0, l = uniforms.length; i < l; i ++ ) { + final List uniformArray = [uniforms[ i ]]; + + for (int j = 0, jl = uniformArray.length; j < jl; j ++ ) { + final uniform = uniformArray[ j ]; + final values = uniform.value is List ? uniform.value : [ uniform.value ]; + + for (int k = 0, kl = values.length; k < kl; k ++ ) { + final value = values[ k ]; + final info = getUniformSize( value ); + // Calculate the chunk offset + final chunkOffset = offset % chunkSize; + final chunkPadding = chunkOffset % info['boundary']!; // required padding to match boundary + final chunkStart = chunkOffset + chunkPadding; // the start position in the current chunk for the data + + offset += chunkPadding; + + // Check for chunk overflow + if ( chunkStart != 0 && ( chunkSize - chunkStart ) < info['storage']! ) { + // Add padding and adjust offset + offset += ( chunkSize - chunkStart ); + } + + // the following two properties will be used for partial buffer updates + uniform.data = Float32List( info['storage']! ~/ Float32List.bytesPerElement); + uniform.offset = offset; + + // Update the global offset + offset += info['storage']!; + } + } + } + + // ensure correct final padding + + final chunkOffset = offset % chunkSize; + + if ( chunkOffset > 0 ) offset += ( chunkSize - chunkOffset ); + + uniformsGroup.size = offset; + uniformsGroup.cache = {}; + + return this; + } + + Map getUniformSize( value ) { + final Map info = { + 'boundary': 0, // bytes + 'storage': 0 // bytes + }; + + // determine sizes according to STD140 + + if (value is double || value is int || value is num || value is bool ) { + info['boundary'] = 4; + info['storage'] = 4; + } else if ( value is Vector2 ) { + info['boundary'] = 8; + info['storage'] = 8; + } else if ( value is Vector3 || value is Color ) { + info['boundary'] = 16; + info['storage'] = 12; // evil: vec3 must start on a 16-byte boundary but it only consumes 12 bytes + } else if ( value is Vector4 ) { + info['boundary'] = 16; + info['storage'] = 16; + } else if ( value is Matrix3 ) { + info['boundary'] = 48; + info['storage'] = 48; + } else if ( value is Matrix4 ) { + info['boundary'] = 64; + info['storage'] = 64; + } else if ( value is Texture ) { + console.warning( 'THREE.WebGLRenderer: Texture samplers can not be part of an uniforms group.' ); + } else { + console.warning( 'THREE.WebGLRenderer: Unsupported uniform value type. $value'); + } + + return info; + } + + void onUniformsGroupsDispose( event ) { + final uniformsGroup = event.target; + + uniformsGroup.removeEventListener( 'dispose', onUniformsGroupsDispose ); + + final index = allocatedBindingPoints.indexOf( uniformsGroup['__bindingPointIndex'] ); + allocatedBindingPoints.removeAt(index); + + gl.deleteBuffer( buffers[ uniformsGroup.id ] ); + + buffers.remove(uniformsGroup.id); + updateList.remove(uniformsGroup.id); + } + + void dispose() { + for ( final id in buffers.keys ) { + gl.deleteBuffer( buffers[ id ] ); + } + + allocatedBindingPoints.clear(); + buffers = {}; + updateList = {}; + } +} diff --git a/packages/three_js_angle_renderer/lib/angle/angle_uniforms_helper.dart b/packages/three_js_angle_renderer/lib/angle/angle_uniforms_helper.dart new file mode 100755 index 00000000..24f93a6e --- /dev/null +++ b/packages/three_js_angle_renderer/lib/angle/angle_uniforms_helper.dart @@ -0,0 +1,756 @@ +part of three_webgl; + +final emptyTexture = Texture(); +final emptyArrayTexture = DataArrayTexture(); +final empty3dTexture = Data3DTexture(); +final emptyCubeTexture = CubeTexture(); + +// --- Utilities --- + +// Array Caches (provide typed arrays for temporary by size) + +Map arrayCacheF32 = {}; +Map arrayCacheI32 = {}; + +// Float32List caches used for uploading Matrix uniforms + +final mat4array = Float32List(16); +final mat3array = Float32List(9); +final mat2array = Float32List(4); + +// --- Uniform Classes --- + +class SingleUniform with AngleUniformsHelper { + late Function setValue; + late int type; + late ActiveInfo activeInfo; + + SingleUniform(id, this.activeInfo, UniformLocation addr) { + this.id = id; + this.addr = addr; + cache = {}; + type = activeInfo.type; + setValue = getSingularSetter(activeInfo.type); + } +} + +class PureArrayUniform with AngleUniformsHelper { + late Function setValue; + late int type; + late ActiveInfo activeInfo; + + PureArrayUniform(id, this.activeInfo, addr) { + this.id = id; + this.addr = addr; + cache = {}; + size = activeInfo.size; + type = activeInfo.type; + setValue = getPureArraySetter(activeInfo.type); + } + + void updateCache(data) { + final cache = this.cache; + copyArray(cache, data); + } +} + +mixin AngleUniform { + late List seq; + late Map map; +} + +class StructuredUniform with AngleUniformsHelper, AngleUniform { + StructuredUniform(id) { + this.id = id; + seq = []; + map = {}; + } + + void setValue(gl, value, textures) { + final seq = this.seq; + + for (int i = 0, n = seq.length; i != n; ++i) { + final u = seq[i]; + u.setValue(gl, value[u.id], textures); + } + } +} + +// --- Top-level --- + +// Parser - builds up the property tree from the path strings + +final rePathPart = RegExp(r"(\w+)(\])?(\[|\.)?"); //g; + +// extracts +// - the identifier (member name or array index) +// - followed by an optional right bracket (found when array index) +// - followed by an optional left bracket or dot (type of subscript) +// +// Note: These portions can be read in a non-overlapping fashion and +// allow straightforward parsing of the hierarchy that WebGL encodes +// in the uniform names. + +void addUniform(AngleUniform container, uniformObject) { + container.seq.add(uniformObject); + container.map[uniformObject.id] = uniformObject; +} + +void parseUniform(ActiveInfo activeInfo, UniformLocation addr, AngleUniform container) { + final path = activeInfo.name; + final pathLength = path.length; + + //console.info("WebGLUniformsHelper.parseUniform path: $path addr: ${addr.id} "); + + // reset RegExp object, because of the early exit of a previous run + // RePathPart.lastIndex = 0; + + final matches = rePathPart.allMatches(path); + + for (final match in matches) { + dynamic id = match.group(1); + final idIsIndex = match.group(2) == ']'; + final subscript = match.group(3); + + if (idIsIndex) id = int.tryParse(id) ?? 0; // convert to integer + + final matchEnd = match.end; + + if (subscript == null || subscript == '[' && matchEnd + 2 == pathLength) { + // bare name or "pure" bottom-level array "[0]" suffix + addUniform(container, subscript == null ? SingleUniform(id, activeInfo, addr) : PureArrayUniform(id, activeInfo, addr)); + break; + } + else { + // step into inner node / create it in case it doesn't exist + + final map = container.map; + StructuredUniform? next = map[id]; + + if (next == null) { + next = StructuredUniform(id); + addUniform(container, next); + } + + container = next; + } + } +} + +mixin AngleUniformsHelper { + // Flattening for arrays of vectors and matrices + // id string || int + late dynamic id; + Map cache = {}; + UniformLocation addr = UniformLocation(0); + late int size; + + void dispose(){ + cache.clear(); + } + + Float32List flat = Float32List(0); + + Float32List flatten(List? array, int nBlocks, int blockSize) { + if(array == null || array.isEmpty) return Float32List(0); + final firstElem = array[0]; + + if (firstElem is num || firstElem is double || firstElem is int) { + List array2 = []; + + for (final element in array) { + array2.add(element.toDouble()); + } + + return Float32List.fromList(array2); + } + + final n = nBlocks * blockSize; + Float32List? r = arrayCacheF32[n]; + + if (r == null) { + r = Float32List(n); + arrayCacheF32[n] = r; + } + + if (nBlocks != 0) { + for (int i = 0; i < nBlocks; i++) { + List data = array[i].storage.toList(); + + data.asMap().forEach((index, element) { + int idx = i * blockSize + index; + r![idx] = element.toDouble(); + }); + } + } + return r; + } + + bool arraysEqual(Map a, b) { + if (a.keys.length != b.length) return false; + + for (int i = 0, l = a.keys.length; i < l; i++) { + if (a[i] != b[i]) return false; + } + + return true; + } + + void copyArray(Map a, b) { + final l = b.length; + a.clear(); + for (int i = 0; i < l; i++) { + a[i] = b[i]; + } + } + + // Texture unit allocation + + Int32List allocTexUnits(textures, n) { + Int32List? r = arrayCacheI32[n]; + + if (r == null) { + r = Int32List(n); + arrayCacheI32[n] = r; + } + + for (int i = 0; i != n; ++i) { + r[i] = textures.allocateTextureUnit(); + } + + return r; + } + + // --- Setters --- + + // Note: Defining these methods externally, because they come in a bunch + // and this way their names minify. + + // Single scalar + + void setValueV1f(RenderingContext gl, v, [AngleTextures? textures]) { + final cache = this.cache; + + if (cache[0] == v) return; + gl.uniform1f(addr, v.toDouble()); + + cache[0] = v; + } + + // Single float vector (from flat array or three.VectorN) + + void setValueV2f(RenderingContext gl, v, [AngleTextures? textures]) { + final cache = this.cache; + + if (v.x != null) { + if (cache[0] != v.x || cache[1] != v.y) { + gl.uniform2f(addr, v.x, v.y); + + cache[0] = v.x; + cache[1] = v.y; + } + } else { + if (arraysEqual(cache, v)) return; + + gl.uniform2fv(addr, v); + + copyArray(cache, v); + } + } + + void setValueV3f(RenderingContext gl, v, [AngleTextures? textures]) { + final cache = this.cache; + + if (v is Vector3) { + if (cache[0] != v.x || cache[1] != v.y || cache[2] != v.z) { + gl.uniform3f(addr, v.x, v.y, v.z); + + cache[0] = v.x; + cache[1] = v.y; + cache[2] = v.z; + } + } else if (v is Color) { + double cacheR = 0; + double cacheG = 0; + double cacheB = 0; + + if (cache.length >= 3) { + cacheR = cache[0]; + cacheG = cache[1]; + cacheB = cache[2]; + } + + if (cacheR != v.red || cacheG != v.green || cacheB != v.blue) { + gl.uniform3f(addr, v.red, v.green, v.blue); + + cache[0] = v.red; + cache[1] = v.green; + cache[2] = v.blue; + } + } else { + if (arraysEqual(cache, v)) return; + gl.uniform3fv(addr, Float32List.fromList(v)); + + copyArray(cache, v); + } + } + + void setValueV4f(RenderingContext gl, v, [AngleTextures? textures]) { + final cache = this.cache; + + if (v is Vector4) { + if (cache[0] != v.x || cache[1] != v.y || cache[2] != v.z || cache[3] != v.w) { + gl.uniform4f(addr, v.x, v.y, v.z, v.w); + + cache[0] = v.x; + cache[1] = v.y; + cache[2] = v.z; + cache[3] = v.w; + } + } else if (v is Color) { + if (cache[0] != v.red || cache[1] != v.green || cache[2] != v.blue || cache[3] != 1.0) { + gl.uniform4f(addr, v.red, v.green, v.blue, 1.0); + + cache[0] = v.red.toDouble(); + cache[1] = v.green.toDouble(); + cache[2] = v.blue.toDouble(); + cache[3] = 1.0; + } + } else if (v is List) { + if (cache[0] != v[0] || cache[1] != v[1] || cache[2] != v[2] || cache[3] != v[3]) { + gl.uniform4f(addr, v[0], v[1], v[2], v[3]); + + cache[0] = v[0]; + cache[1] = v[1]; + cache[2] = v[2]; + cache[3] = v[3]; + } + } else { + if (arraysEqual(cache, v)) return; + + gl.uniform4fv(addr, v); + + copyArray(cache, v); + } + } + + // Single matrix (from flat array or three.MatrixN) + + void setValueM2(RenderingContext gl, v, [AngleTextures? textures]) { + final cache = this.cache; + final elements = v?.storage; + + if (elements == null) { + if (arraysEqual(cache, v)) return; + + gl.uniformMatrix2fv(addr, false, v); + + copyArray(cache, v); + } else { + if (arraysEqual(cache, elements)) return; + + //mat2array.set(List.from(elements.map((e) => e.toDouble())), 0); + + gl.uniformMatrix2fv(addr, false, mat2array); + copyArray(cache, elements); + } + } + + void setValueM3(RenderingContext gl, Matrix3? v, [AngleTextures? textures]) { + final cache = this.cache; + final elements = v?.storage; + + if (elements == null) { + if (arraysEqual(cache, v)) return; + + gl.uniformMatrix3fv(addr, false, elements!); + + copyArray(cache, v); + } + else { + if (arraysEqual(cache, elements)) { + return; + } + + gl.uniformMatrix3fv(addr, false, elements); + copyArray(cache, elements); + } + } + + void setValueM4(RenderingContext gl, Matrix4 v, [AngleTextures? textures]) { + final cache = this.cache; + final elements = v.storage; + + if (arraysEqual(cache, elements)) { + return; + } + gl.uniformMatrix4fv(addr, false, elements); + copyArray(cache, elements); + } + + // Single texture (2D / Cube) + + void setValueT1(RenderingContext gl, Texture? v, AngleTextures textures) { + final cache = this.cache; + final unit = textures.allocateTextureUnit(); + + if (cache[0] != unit) { + gl.uniform1i(addr, unit); + cache[0] = unit; + } + + textures.setTexture2D(v ?? emptyTexture, unit); + } + + void setValueT2DArray1(RenderingContext gl,Texture? v, AngleTextures textures) { + final cache = this.cache; + final unit = textures.allocateTextureUnit(); + + if (cache[0] != unit) { + gl.uniform1i(addr, unit); + cache[0] = unit; + } + + textures.setTexture2DArray(v ?? emptyArrayTexture, unit); + } + + void setValueT3D1(RenderingContext gl,Texture? v, [AngleTextures? textures]) { + final cache = this.cache; + final unit = textures!.allocateTextureUnit(); + + if (cache[0] != unit) { + gl.uniform1i(addr, unit); + cache[0] = unit; + } + + textures.setTexture3D(v ?? empty3dTexture, unit); + } + + void setValueT6(RenderingContext gl,Texture? v, [AngleTextures? textures]) { + final cache = this.cache; + final unit = textures!.allocateTextureUnit(); + + if (cache[0] != unit) { + gl.uniform1i(addr, unit); + cache[0] = unit; + } + + textures.setTextureCube(v ?? emptyCubeTexture, unit); + } + + // Integer / Boolean vectors or arrays thereof (always flat arrays) + + void setValueV1i(RenderingContext gl, v, [AngleTextures? textures]) { + final cache = this.cache; + + if (cache[0] == v) return; + + if (v is bool) { + if (v) { + gl.uniform1i(addr, 1); + } else { + gl.uniform1i(addr, 0); + } + } else { + gl.uniform1i(addr, v.toInt()); + } + + cache[0] = v; + } + Int32List iv = Int32List(2); + + void setValueV2i(RenderingContext gl, Vector v, [AngleTextures? textures]) { + final cache = this.cache; + if (arraysEqual(cache, v)) return; + iv[0] = v.x.toInt(); + iv[1] = v.y.toInt(); + gl.uniform2iv(addr, iv); + copyArray(cache, v.copyIntoArray()); + } + + void setValueV3i(RenderingContext gl, v, [AngleTextures? textures]) { + final cache = this.cache; + if (arraysEqual(cache, v)) return; + gl.uniform3iv(addr, v); + copyArray(cache, v); + } + + void setValueV4i(RenderingContext gl, v, [AngleTextures? textures]) { + final cache = this.cache; + + if (arraysEqual(cache, v)) return; + + gl.uniform4iv(addr, v); + + copyArray(cache, v); + } + + // uint + + void setValueV1ui(RenderingContext gl, v, [AngleTextures? textures]) { + final cache = this.cache; + + if (cache[0] == v) return; + gl.uniform1ui(addr, v); + cache[0] = v; + } + + void setValueV2ui(RenderingContext gl, v, [AngleTextures? textures]) { + final cache = this.cache; + + if (arraysEqual(cache, v)) return; + gl.uniform2uiv(addr, v); + copyArray(cache, v); + } + + void setValueV3ui(RenderingContext gl, v, [AngleTextures? textures]) { + final cache = this.cache; + + if (arraysEqual(cache, v)) return; + gl.uniform3uiv(addr, v); + copyArray(cache, v); + } + + void setValueV4ui(RenderingContext gl, v, [AngleTextures? textures]) { + final cache = this.cache; + + if (arraysEqual(cache, v)) return; + gl.uniform4uiv(addr, v); + copyArray(cache, v); + } + + // Helper to pick the right setter for the singular case + + Function getSingularSetter(int type) { + switch (type) { + case 0x1406: return setValueV1f; // FLOAT + case 0x8b50: return setValueV2f; // _VEC2 + case 0x8b51: return setValueV3f; // _VEC3 + case 0x8b52: return setValueV4f; // _VEC4 + + case 0x8b5a: return setValueM2; // _MAT2 + case 0x8b5b: return setValueM3; // _MAT3 + case 0x8b5c: return setValueM4; // _MAT4 + + case 0x1404: case 0x8b56: return setValueV1i; // INT, BOOL + case 0x8b53: case 0x8b57: return setValueV2i; // _VEC2 + case 0x8b54: case 0x8b58: return setValueV3i; // _VEC3 + case 0x8b55: case 0x8b59: return setValueV4i; // _VEC4 + + case 0x1405: return setValueV1ui; // UINT + case 0x8dc6: return setValueV2ui; // _VEC2 + case 0x8dc7: return setValueV3ui; // _VEC3 + case 0x8dc8: return setValueV4ui; // _VEC4 + + case 0x8b5e: // SAMPLER_2D + case 0x8d66: // SAMPLER_EXTERNAL_OES + case 0x8dca: // INT_SAMPLER_2D + case 0x8dd2: // UNSIGNED_INT_SAMPLER_2D + case 0x8b62: // SAMPLER_2D_SHADOW + return setValueT1; + + case 0x8b5f: // SAMPLER_3D + case 0x8dcb: // INT_SAMPLER_3D + case 0x8dd3: // UNSIGNED_INT_SAMPLER_3D + return setValueT3D1; + + case 0x8b60: // SAMPLER_CUBE + case 0x8dcc: // INT_SAMPLER_CUBE + case 0x8dd4: // UNSIGNED_INT_SAMPLER_CUBE + case 0x8dc5: // SAMPLER_CUBE_SHADOW + return setValueT6; + + case 0x8dc1: // SAMPLER_2D_ARRAY + case 0x8dcf: // INT_SAMPLER_2D_ARRAY + case 0x8dd7: // UNSIGNED_INT_SAMPLER_2D_ARRAY + case 0x8dc4: // SAMPLER_2D_ARRAY_SHADOW + return setValueT2DArray1; + default: + throw ("getSingularSetter id: $id type: $type"); + } + } + + // Array of scalars + void setValueV1fArray(RenderingContext gl, v, [AngleTextures? textures]) { + final data = flatten(v, size, 1); + gl.uniform1fv(addr, data); + } + + // Integer / Boolean vectors or arrays thereof (always flat arrays) + void setValueV1iArray(RenderingContext gl, v, [AngleTextures? textures]) { + gl.uniform1iv(addr, v); + } + + void setValueV2iArray(RenderingContext gl, v, [AngleTextures? textures]) { + gl.uniform2iv(addr, v); + } + + void setValueV3iArray(RenderingContext gl, v, [AngleTextures? textures]) { + gl.uniform3iv(addr, v); + } + + void setValueV4iArray(RenderingContext gl, v, [AngleTextures? textures]) { + gl.uniform4iv(addr, v); + } + + // Array of vectors (flat or from THREE classes) + + void setValueV2fArray(RenderingContext gl, v, [AngleTextures? textures]) { + final data = flatten(v, size, 2); + gl.uniform2fv(addr, data); + } + + void setValueV3fArray(RenderingContext gl, v, [AngleTextures? textures]) { + final data = flatten(v, size, 3); + gl.uniform3fv(addr, data); + } + + void setValueV4fArray(RenderingContext gl, v, [AngleTextures? textures]) { + final data = flatten(v, size, 4); + gl.uniform4fv(addr, data); + } + + // Array of matrices (flat or from THREE clases) + + void setValueM2Array(RenderingContext gl, v, [AngleTextures? textures]) { + final data = flatten(v, size, 4); + gl.uniformMatrix2fv(addr, false, data); + } + + void setValueM3Array(RenderingContext gl, v, [AngleTextures? textures]) { + final data = flatten(v, size, 9); + gl.uniformMatrix3fv(addr, false, data); + } + + void setValueM4Array(RenderingContext gl, v, [AngleTextures? textures]) { + final data = flatten(v, size, 16); + gl.uniformMatrix4fv(addr, false, data); + } + + // Array of unsigned integer + + void setValueV1uiArray(RenderingContext gl, v, [AngleTextures? textures]) { + gl.uniform1uiv(addr, v); + } + + // Array of unsigned integer vectors (from flat array) + + void setValueV2uiArray(RenderingContext gl, v, [AngleTextures? textures]) { + gl.uniform2uiv(addr, v); + } + + void setValueV3uiArray(RenderingContext gl, v, [AngleTextures? textures]) { + gl.uniform3uiv(addr, v); + } + + void setValueV4uiArray(RenderingContext gl, v, [AngleTextures? textures]) { + gl.uniform4uiv(addr, v); + } + + // Array of textures (2D / 3D / Cube / 2DArray) + void setValueT1Array(RenderingContext gl, v, [AngleTextures? textures]) { + final n = v.length; + + final units = allocTexUnits(textures, n); + + if (!arraysEqual(cache, units)){ + gl.uniform1iv(addr, units); + copyArray(cache, units); + } + + for (int i = 0; i != n; ++i) { + textures?.setTexture2D(v[i] ?? emptyTexture, units[i]); + } + } + + void setValueT3DArray(RenderingContext gl, v, [AngleTextures? textures]) { + final n = v.length; + + final units = allocTexUnits(textures, n); + + gl.uniform1iv(addr, units); + + for (int i = 0; i != n; ++i) { + textures?.setTexture3D(v[i] ?? empty3dTexture, units[i]); + } + } + + void setValueT6Array(RenderingContext gl, v, [AngleTextures? textures]) { + final n = v.length; + + final units = allocTexUnits(textures, n); + + if (!arraysEqual(cache, units)){ + gl.uniform1iv(addr, units); + copyArray(cache, units); + } + + for (int i = 0; i != n; ++i) { + textures?.setTextureCube(v[i] ?? emptyCubeTexture, units[i]); + } + } + + void setValueT2DArrayArray(RenderingContext gl, v, [AngleTextures? textures]) { + final n = v.length; + + final units = allocTexUnits(textures, n); + + if (!arraysEqual(cache, units)){ + gl.uniform1iv(addr, units); + copyArray(cache, units); + } + + for (int i = 0; i != n; ++i) { + textures?.setTexture2DArray(v[i] ?? emptyArrayTexture, units[i]); + } + } + + // Helper to pick the right setter for a pure (bottom-level) array + + dynamic getPureArraySetter(int type) { + switch (type) { + case 0x1406: return setValueV1fArray; // FLOAT + case 0x8b50: return setValueV2fArray; // _VEC2 + case 0x8b51: return setValueV3fArray; // _VEC3 + case 0x8b52: return setValueV4fArray; // _VEC4 + + case 0x8b5a: return setValueM2Array; // _MAT2 + case 0x8b5b: return setValueM3Array; // _MAT3 + case 0x8b5c: return setValueM4Array; // _MAT4 + + case 0x1404: case 0x8b56: return setValueV1iArray; // INT, BOOL + case 0x8b53: case 0x8b57: return setValueV2iArray; // _VEC2 + case 0x8b54: case 0x8b58: return setValueV3iArray; // _VEC3 + case 0x8b55: case 0x8b59: return setValueV4iArray; // _VEC4 + + case 0x1405: return setValueV1uiArray; // UINT + case 0x8dc6: return setValueV2uiArray; // _VEC2 + case 0x8dc7: return setValueV3uiArray; // _VEC3 + case 0x8dc8: return setValueV4uiArray; // _VEC4 + + case 0x8b5e: // SAMPLER_2D + case 0x8d66: // SAMPLER_EXTERNAL_OES + case 0x8dca: // INT_SAMPLER_2D + case 0x8dd2: // UNSIGNED_INT_SAMPLER_2D + case 0x8b62: // SAMPLER_2D_SHADOW + return setValueT1Array; + + case 0x8b5f: // SAMPLER_3D + case 0x8dcb: // INT_SAMPLER_3D + case 0x8dd3: // UNSIGNED_INT_SAMPLER_3D + return setValueT3DArray; + + case 0x8b60: // SAMPLER_CUBE + case 0x8dcc: // INT_SAMPLER_CUBE + case 0x8dd4: // UNSIGNED_INT_SAMPLER_CUBE + case 0x8dc5: // SAMPLER_CUBE_SHADOW + return setValueT6Array; + + case 0x8dc1: // SAMPLER_2D_ARRAY + case 0x8dcf: // INT_SAMPLER_2D_ARRAY + case 0x8dd7: // UNSIGNED_INT_SAMPLER_2D_ARRAY + case 0x8dc4: // SAMPLER_2D_ARRAY_SHADOW + return setValueT2DArrayArray; + } + } +} diff --git a/packages/three_js_angle_renderer/lib/angle/angle_utils.dart b/packages/three_js_angle_renderer/lib/angle/angle_utils.dart new file mode 100755 index 00000000..b2b180ef --- /dev/null +++ b/packages/three_js_angle_renderer/lib/angle/angle_utils.dart @@ -0,0 +1,184 @@ +part of three_webgl; + +class AngleUtils { + bool _didDispose = false; + AngleExtensions extensions; + + AngleUtils(this.extensions); + + void dispose(){ + if(_didDispose) return; + _didDispose = true; + extensions.dispose(); + } + + dynamic convert(int p, [String colorSpace = NoColorSpace]) { + dynamic extension; + final transfer = ColorManagement.getTransfer(ColorSpace.fromString(colorSpace)); + + if (p == UnsignedByteType) return WebGL.UNSIGNED_BYTE; + if (p == UnsignedShort4444Type) return WebGL.UNSIGNED_SHORT_4_4_4_4; + if (p == UnsignedShort5551Type) return WebGL.UNSIGNED_SHORT_5_5_5_1; + if ( p == UnsignedInt5999Type ) return WebGL.UNSIGNED_INT_5_9_9_9_REV; + + if (p == ByteType) return WebGL.BYTE; + if (p == ShortType) return WebGL.SHORT; + if (p == UnsignedShortType) return WebGL.UNSIGNED_SHORT; + if (p == IntType) return WebGL.INT; + if (p == UnsignedIntType) return WebGL.UNSIGNED_INT; + if (p == FloatType) return WebGL.FLOAT; + if (p == HalfFloatType) return WebGL.HALF_FLOAT; + + if (p == AlphaFormat) return WebGL.ALPHA; + if (p == RGBFormat ) return WebGL.RGB; + if (p == RGBAFormat) return WebGL.RGBA; + if (p == LuminanceFormat) return WebGL.LUMINANCE; + if (p == LuminanceAlphaFormat) return WebGL.LUMINANCE_ALPHA; + if (p == DepthFormat) return WebGL.DEPTH_COMPONENT; + if (p == DepthStencilFormat) return WebGL.DEPTH_STENCIL; + + if (p == RedFormat) return WebGL.RED; + if (p == RedIntegerFormat ) return WebGL.RED_INTEGER; + if (p == RGFormat ) return WebGL.RG; + if (p == RGIntegerFormat ) return WebGL.RG_INTEGER; + if (p == RGBAIntegerFormat ) return WebGL.RGBA_INTEGER; + + // S3TC + + if (p == RGB_S3TC_DXT1_Format || + p == RGBA_S3TC_DXT1_Format || + p == RGBA_S3TC_DXT3_Format || + p == RGBA_S3TC_DXT5_Format + ) { + if (transfer == SRGBTransfer) { + extension = extensions.get('WEBGL_compressed_texture_s3tc_srgb'); + + if (extension != null) { + if ( p == RGB_S3TC_DXT1_Format ) return extension.COMPRESSED_SRGB_S3TC_DXT1_EXT; + if ( p == RGBA_S3TC_DXT1_Format ) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT; + if ( p == RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT; + if ( p == RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT; + } else { + return null; + } + } + else { + extension = extensions.get('WEBGL_compressed_texture_s3tc'); + + if (extension != null) { + if ( p == RGB_S3TC_DXT1_Format ) return extension.COMPRESSED_RGB_S3TC_DXT1_EXT; + if ( p == RGBA_S3TC_DXT1_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT1_EXT; + if ( p == RGBA_S3TC_DXT3_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT3_EXT; + if ( p == RGBA_S3TC_DXT5_Format ) return extension.COMPRESSED_RGBA_S3TC_DXT5_EXT; + } else { + return null; + } + } + } + + // PVRTC + + if (p == RGB_PVRTC_4BPPV1_Format || + p == RGB_PVRTC_2BPPV1_Format || + p == RGBA_PVRTC_4BPPV1_Format || + p == RGBA_PVRTC_2BPPV1_Format) { + extension = extensions.get('WEBGL_compressed_texture_pvrtc'); + + if (extension != null) { + if ( p == RGB_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_4BPPV1_IMG; + if ( p == RGB_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGB_PVRTC_2BPPV1_IMG; + if ( p == RGBA_PVRTC_4BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_4BPPV1_IMG; + if ( p == RGBA_PVRTC_2BPPV1_Format ) return extension.COMPRESSED_RGBA_PVRTC_2BPPV1_IMG; + } else { + return null; + } + } + + // ETC1 + + if (p == RGB_ETC1_Format || p == RGB_ETC2_Format || p == RGBA_ETC2_EAC_Format) { + extension = extensions.get('WEBGL_compressed_texture_etc1'); + if ( extension != null ) { + if ( p == RGB_ETC1_Format || p == RGB_ETC2_Format ) return ( transfer == SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ETC2 : extension.COMPRESSED_RGB8_ETC2; + if ( p == RGBA_ETC2_EAC_Format ) return ( transfer == SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ETC2_EAC : extension.COMPRESSED_RGBA8_ETC2_EAC; + } else { + return null; + } + } + + // ASTC + + if (p == RGBA_ASTC_4x4_Format || + p == RGBA_ASTC_5x4_Format || + p == RGBA_ASTC_5x5_Format || + p == RGBA_ASTC_6x5_Format || + p == RGBA_ASTC_6x6_Format || + p == RGBA_ASTC_8x5_Format || + p == RGBA_ASTC_8x6_Format || + p == RGBA_ASTC_8x8_Format || + p == RGBA_ASTC_10x5_Format || + p == RGBA_ASTC_10x6_Format || + p == RGBA_ASTC_10x8_Format || + p == RGBA_ASTC_10x10_Format || + p == RGBA_ASTC_12x10_Format || + p == RGBA_ASTC_12x12_Format) { + extension = extensions.get('WEBGL_compressed_texture_astc'); + + if (extension != null) { + if ( p == RGBA_ASTC_4x4_Format ) return ( transfer == SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_4x4_KHR : extension.COMPRESSED_RGBA_ASTC_4x4_KHR; + if ( p == RGBA_ASTC_5x4_Format ) return ( transfer == SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_5x4_KHR : extension.COMPRESSED_RGBA_ASTC_5x4_KHR; + if ( p == RGBA_ASTC_5x5_Format ) return ( transfer == SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_5x5_KHR : extension.COMPRESSED_RGBA_ASTC_5x5_KHR; + if ( p == RGBA_ASTC_6x5_Format ) return ( transfer == SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_6x5_KHR : extension.COMPRESSED_RGBA_ASTC_6x5_KHR; + if ( p == RGBA_ASTC_6x6_Format ) return ( transfer == SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_6x6_KHR : extension.COMPRESSED_RGBA_ASTC_6x6_KHR; + if ( p == RGBA_ASTC_8x5_Format ) return ( transfer == SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x5_KHR : extension.COMPRESSED_RGBA_ASTC_8x5_KHR; + if ( p == RGBA_ASTC_8x6_Format ) return ( transfer == SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x6_KHR : extension.COMPRESSED_RGBA_ASTC_8x6_KHR; + if ( p == RGBA_ASTC_8x8_Format ) return ( transfer == SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_8x8_KHR : extension.COMPRESSED_RGBA_ASTC_8x8_KHR; + if ( p == RGBA_ASTC_10x5_Format ) return ( transfer == SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x5_KHR : extension.COMPRESSED_RGBA_ASTC_10x5_KHR; + if ( p == RGBA_ASTC_10x6_Format ) return ( transfer == SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x6_KHR : extension.COMPRESSED_RGBA_ASTC_10x6_KHR; + if ( p == RGBA_ASTC_10x8_Format ) return ( transfer == SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x8_KHR : extension.COMPRESSED_RGBA_ASTC_10x8_KHR; + if ( p == RGBA_ASTC_10x10_Format ) return ( transfer == SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_10x10_KHR : extension.COMPRESSED_RGBA_ASTC_10x10_KHR; + if ( p == RGBA_ASTC_12x10_Format ) return ( transfer == SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_12x10_KHR : extension.COMPRESSED_RGBA_ASTC_12x10_KHR; + if ( p == RGBA_ASTC_12x12_Format ) return ( transfer == SRGBTransfer ) ? extension.COMPRESSED_SRGB8_ALPHA8_ASTC_12x12_KHR : extension.COMPRESSED_RGBA_ASTC_12x12_KHR; + } else { + return null; + } + } + + // BPTC + + if ( p == RGBA_BPTC_Format || p == RGB_BPTC_SIGNED_Format || p == RGB_BPTC_UNSIGNED_Format ) { + extension = extensions.get( 'EXT_texture_compression_bptc' ); + + if ( extension != null ) { + if ( p == RGBA_BPTC_Format ) return ( transfer == SRGBTransfer ) ? extension.COMPRESSED_SRGB_ALPHA_BPTC_UNORM_EXT : extension.COMPRESSED_RGBA_BPTC_UNORM_EXT; + if ( p == RGB_BPTC_SIGNED_Format ) return extension.COMPRESSED_RGB_BPTC_SIGNED_FLOAT_EXT; + if ( p == RGB_BPTC_UNSIGNED_Format ) return extension.COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_EXT; + } else { + return null; + } + } + + // RGTC + + if ( p == RED_RGTC1_Format || p == SIGNED_RED_RGTC1_Format || p == RED_GREEN_RGTC2_Format || p == SIGNED_RED_GREEN_RGTC2_Format ) { + extension = extensions.get( 'EXT_texture_compression_rgtc' ); + + if ( extension != null ) { + if ( p == RGBA_BPTC_Format ) return extension.COMPRESSED_RED_RGTC1_EXT; + if ( p == SIGNED_RED_RGTC1_Format ) return extension.COMPRESSED_SIGNED_RED_RGTC1_EXT; + if ( p == RED_GREEN_RGTC2_Format ) return extension.COMPRESSED_RED_GREEN_RGTC2_EXT; + if ( p == SIGNED_RED_GREEN_RGTC2_Format ) return extension.COMPRESSED_SIGNED_RED_GREEN_RGTC2_EXT; + } else { + return null; + } + } + + // + + if ( p == UnsignedInt248Type ) return WebGL.UNSIGNED_INT_24_8; + + // if "p" can't be resolved, assume the user defines a WebGL constant as a string (fallback/workaround for packed RGB formats) + + return (WebGL.get(p) != null) ? WebGL.get(p) : null; + } +} diff --git a/packages/three_js_angle_renderer/lib/angle/index.dart b/packages/three_js_angle_renderer/lib/angle/index.dart new file mode 100755 index 00000000..2b743863 --- /dev/null +++ b/packages/three_js_angle_renderer/lib/angle/index.dart @@ -0,0 +1,48 @@ +library three_webgl; + +import 'dart:typed_data'; +import 'dart:math' as math; + +import 'package:flutter/foundation.dart'; +import 'package:three_js_core/three_js_core.dart'; +import 'package:three_js_math/three_js_math.dart'; +import '../renderers/index.dart'; +import '../shaders/index.dart'; +import '../renderers/pmrem_generator.dart'; +import 'package:flutter_angle/flutter_angle.dart'; + +part 'angle_animation.dart'; +part 'angle_attributes.dart'; +part 'angle_background.dart'; +part 'angle_binding_states.dart'; +part 'angle_buffer_renderer.dart'; +part 'angle_capabilities.dart'; +part 'angle_clipping.dart'; +part 'angle_cube_maps.dart'; +part 'angle_extensions.dart'; +part 'angle_geometries.dart'; +part 'angle_indexed_buffer_renderer.dart'; +part 'angle_info.dart'; +part 'angle_lights.dart'; +part 'angle_materials.dart'; +part 'angle_morphtargets.dart'; +part 'angle_objects.dart'; +part 'angle_parameters.dart'; +part 'angle_program.dart'; +part 'angle_program_extra.dart'; +part 'angle_programs.dart'; +part 'angle_properties.dart'; +part 'angle_render_list.dart'; +part 'angle_render_lists.dart'; + +part 'angle_render_states.dart'; +part 'angle_shader.dart'; +part 'angle_shadow_map.dart'; +part 'angle_state.dart'; +part 'angle_textures.dart'; +part 'angle_uniforms.dart'; +part 'angle_uniforms_groups.dart'; +part 'angle_uniforms_helper.dart'; +part 'angle_utils.dart'; +part 'angle_cube_uv_maps.dart'; +part 'angle_shader_cache.dart'; diff --git a/packages/three_js_core/lib/materials/hex_tiling_material.dart b/packages/three_js_angle_renderer/lib/materials/hex_tiling_material.dart similarity index 98% rename from packages/three_js_core/lib/materials/hex_tiling_material.dart rename to packages/three_js_angle_renderer/lib/materials/hex_tiling_material.dart index 65a79916..045b488a 100644 --- a/packages/three_js_core/lib/materials/hex_tiling_material.dart +++ b/packages/three_js_angle_renderer/lib/materials/hex_tiling_material.dart @@ -1,4 +1,6 @@ -import 'package:three_js_core/renderers/webgl/index.dart'; +import 'package:three_js_angle/shaders/index.dart'; + +import '../angle/index.dart'; import 'package:three_js_core/three_js_core.dart'; import 'dart:math' as math; @@ -167,9 +169,9 @@ class HexTilingMaterial extends MeshPhysicalMaterial { } void patchMaterial(){ - final shaderMap = new Map(); + final shaderMap = new Map(); - this.onBeforeCompile = (WebGLParameters shader, WebGLRenderer renderer) { + this.onBeforeCompile = (shader, Renderer renderer) { final hexTilingID = genRandomStringID; this.hexTilingID = hexTilingID; shaderMap[hexTilingID] = shader; @@ -186,7 +188,7 @@ class HexTilingMaterial extends MeshPhysicalMaterial { // internal ID used to match the shader to the material so that the custom uniforms can be updated // from the material this.onBeforeRender = ( - WebGLRenderer? renderer, + Renderer? renderer, Scene? scene, Camera? camera, BufferGeometry? geometry, diff --git a/packages/three_js_angle_renderer/lib/renderers/3d_render_target.dart b/packages/three_js_angle_renderer/lib/renderers/3d_render_target.dart new file mode 100755 index 00000000..ab3ba6e7 --- /dev/null +++ b/packages/three_js_angle_renderer/lib/renderers/3d_render_target.dart @@ -0,0 +1,9 @@ +part of three_renderers; + +class Angle3DRenderTarget extends AngleRenderTarget { + Angle3DRenderTarget([int width = 1, int height = 1, int depth = 1, RenderTargetOptions? options]) : super(width, height, options) { + this.depth = depth; + texture = Data3DTexture(null, width, height, depth); + texture.isRenderTargetTexture = true; + } +} diff --git a/packages/three_js_angle_renderer/lib/renderers/array_render_target.dart b/packages/three_js_angle_renderer/lib/renderers/array_render_target.dart new file mode 100755 index 00000000..160edf59 --- /dev/null +++ b/packages/three_js_angle_renderer/lib/renderers/array_render_target.dart @@ -0,0 +1,9 @@ +part of three_renderers; + +class AngleArrayRenderTarget extends AngleRenderTarget { + AngleArrayRenderTarget([int width = 1, int height = 1, int depth = 1, RenderTargetOptions? options]) : super(width, height, options) { + this.depth = depth; + texture = DataArrayTexture(null, width, height, depth); + texture.isRenderTargetTexture = true; + } +} \ No newline at end of file diff --git a/packages/three_js_angle_renderer/lib/renderers/cube_render_target.dart b/packages/three_js_angle_renderer/lib/renderers/cube_render_target.dart new file mode 100755 index 00000000..0f247e86 --- /dev/null +++ b/packages/three_js_angle_renderer/lib/renderers/cube_render_target.dart @@ -0,0 +1,126 @@ +part of three_renderers; + +class AngleCubeRenderTarget extends CubeRenderTarget { + AngleCubeRenderTarget([int size = 1, RenderTargetOptions? options]) : super(size, options) { + // By convention -- likely based on the RenderMan spec from the 1990's -- cube maps are specified by WebGL (and three.js) + // in a coordinate system in which positive-x is to the right when looking up the positive-z axis -- in other words, + // in a left-handed coordinate system. By continuing this convention, preexisting cube maps continued to render correctly. + + // three.js uses a right-handed coordinate system. So environment maps used in three.js appear to have px and nx swapped + // and the flag isRenderTargetTexture controls this conversion. The flip is not required when using WebGLCubeRenderTarget.texture + // as a cube texture (this is detected when isRenderTargetTexture is set to true for cube textures). + final image = ImageElement(width: size, height: size, depth: 1); + final images = [image, image, image, image, image, image]; + + texture = CubeTexture( + images, + this.options.mapping, + this.options.wrapS, + this.options.wrapT, + this.options.magFilter, + this.options.minFilter, + this.options.format, + this.options.type, + this.options.anisotropy, + this.options.colorSpace + ); + texture.isRenderTargetTexture = true; + + texture.generateMipmaps = this.options.generateMipmaps; + texture.minFilter = this.options.minFilter ?? LinearFilter; + } + + @override + AngleCubeRenderTarget fromEquirectangularTexture(Renderer renderer, Texture texture) { + this.texture.type = texture.type; + this.texture.colorSpace = texture.colorSpace; + + this.texture.generateMipmaps = texture.generateMipmaps; + this.texture.minFilter = texture.minFilter; + this.texture.magFilter = texture.magFilter; + + final shader = { + "uniforms": { + "tEquirect": {'value': null}, + }, + "vertexShader": """ + + varying vec3 vWorldDirection; + + vec3 transformDirection( in vec3 dir, in mat4 matrix ) { + + return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz ); + + } + + void main() { + + vWorldDirection = transformDirection( position, modelMatrix ); + + #include + #include + + } + """, + "fragmentShader": """ + + uniform sampler2D tEquirect; + + varying vec3 vWorldDirection; + + #include + + void main() { + + vec3 direction = normalize( vWorldDirection ); + + vec2 sampleUV = equirectUv( direction ); + + gl_FragColor = texture2D( tEquirect, sampleUV ); + + } + """ + }; + + final geometry = BoxGeometry(5, 5, 5); + final material = ShaderMaterial.fromMap({ + "name": 'CubemapFromEquirect', + "uniforms": cloneUniforms(shader["uniforms"] as Map), + "vertexShader": shader["vertexShader"], + "fragmentShader": shader["fragmentShader"], + "side": BackSide, + "blending": NoBlending + }); + + material.uniforms["tEquirect"]["value"] = texture; + + final mesh = Mesh(geometry, material); + + final currentMinFilter = texture.minFilter; + + // Avoid blurred poles + if (texture.minFilter == LinearMipmapLinearFilter) { + texture.minFilter = LinearFilter; + } + + final camera = CubeCamera(1, 10, this); + camera.update(renderer, mesh); + + texture.minFilter = currentMinFilter; + + mesh.geometry!.dispose(); + mesh.material?.dispose(); + + return this; + } + + @override + void clear(Renderer renderer, [bool color = true, bool depth = true, bool stencil = true]) { + final currentRenderTarget = renderer.getRenderTarget(); + for (int i = 0; i < 6; i++) { + renderer.setRenderTarget(this, i); + renderer.clear(color, depth, stencil); + } + renderer.setRenderTarget(currentRenderTarget); + } +} \ No newline at end of file diff --git a/packages/three_js_angle_renderer/lib/renderers/index.dart b/packages/three_js_angle_renderer/lib/renderers/index.dart new file mode 100755 index 00000000..9409772f --- /dev/null +++ b/packages/three_js_angle_renderer/lib/renderers/index.dart @@ -0,0 +1,16 @@ +library three_renderers; + +import 'dart:math' as math; +import 'dart:typed_data'; + +import 'package:three_js_core/three_js_core.dart'; +import 'package:flutter/foundation.dart'; +import 'package:flutter_angle/flutter_angle.dart'; +import 'package:three_js_math/three_js_math.dart'; +import '../angle/index.dart'; + +part 'renderer.dart'; +part 'render_target.dart'; +part '3d_render_target.dart'; +part 'array_render_target.dart'; +part 'cube_render_target.dart'; diff --git a/packages/three_js_core/lib/renderers/pmrem_generator.dart b/packages/three_js_angle_renderer/lib/renderers/pmrem_generator.dart similarity index 98% rename from packages/three_js_core/lib/renderers/pmrem_generator.dart rename to packages/three_js_angle_renderer/lib/renderers/pmrem_generator.dart index af3d5b0a..f07d2909 100755 --- a/packages/three_js_core/lib/renderers/pmrem_generator.dart +++ b/packages/three_js_angle_renderer/lib/renderers/pmrem_generator.dart @@ -1,6 +1,7 @@ import 'package:flutter/foundation.dart'; import 'package:three_js_core/three_js_core.dart'; import 'package:three_js_math/three_js_math.dart'; +import './index.dart'; import 'dart:math' as math; final _origin = Vector3(); @@ -56,7 +57,7 @@ class PMREMGenerator { late final double invPhi; late final List _axisDirections; - late WebGLRenderer _renderer; + late AngleRenderer _renderer; dynamic _pingPongRenderTarget; dynamic _blurMaterial; dynamic _equirectMaterial; @@ -65,7 +66,7 @@ class PMREMGenerator { late int _lodMax; late int _cubeSize; - PMREMGenerator(WebGLRenderer renderer) { + PMREMGenerator(AngleRenderer renderer) { // Golden Ratio phi = (1 + math.sqrt(5)) / 2; invPhi = 1 / phi; @@ -105,7 +106,7 @@ class PMREMGenerator { /// * and far planes ensure the scene is rendered in its entirety (the cubeCamera /// * is placed at the origin). /// * - WebGLRenderTarget fromScene(Scene scene, {double sigma = 0, double near = 0.1, double far = 100, PMREMGeneratorOptions? options}) { + AngleRenderTarget fromScene(Scene scene, {double sigma = 0, double near = 0.1, double far = 100, PMREMGeneratorOptions? options}) { options ??= PMREMGeneratorOptions(); _oldTarget = _renderer.getRenderTarget(); @@ -236,7 +237,7 @@ class PMREMGenerator { return cubeUVRenderTarget; } - WebGLRenderTarget _allocateTargets() { + AngleRenderTarget _allocateTargets() { int width = 3 * math.max(_cubeSize, 16 * 7); int height = 4 * _cubeSize; @@ -551,8 +552,8 @@ class PMREMGenerator { return {"lodPlanes": lodPlanes, "sizeLods": sizeLods, "sigmas": sigmas}; } - WebGLRenderTarget _createRenderTarget(int width, int height, Map params) { - final cubeUVRenderTarget = WebGLRenderTarget(width, height, WebGLRenderTargetOptions(params)); + AngleRenderTarget _createRenderTarget(int width, int height, Map params) { + final cubeUVRenderTarget = AngleRenderTarget(width, height, RenderTargetOptions(params)); cubeUVRenderTarget.texture.mapping = CubeUVReflectionMapping; cubeUVRenderTarget.texture.name = 'PMREM.cubeUv'; cubeUVRenderTarget.scissorTest = true; diff --git a/packages/three_js_angle_renderer/lib/renderers/render_target.dart b/packages/three_js_angle_renderer/lib/renderers/render_target.dart new file mode 100755 index 00000000..6d27d043 --- /dev/null +++ b/packages/three_js_angle_renderer/lib/renderers/render_target.dart @@ -0,0 +1,44 @@ +/* + In options, we can specify: + * Texture parameters for an auto-generated target texture + * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers +*/ + +part of three_renderers; + +class AngleRenderTarget extends RenderTarget { + bool _didDispose = false; + + AngleRenderTarget(super.width, super.height, [super.options]); + + @override + AngleRenderTarget clone() { + return AngleRenderTarget(width, height, options)..copy(this); + } + + @override + AngleRenderTarget copy(RenderTarget source) { + super.copy(source); + return this; + } + + @override + bool is3D() { + return texture is Data3DTexture || texture is DataArrayTexture; + } + + @override + void dispose() { + if(_didDispose) return; + _didDispose = true; + dispatchEvent(Event(type: "dispose")); + depthTexture?.dispose(); + texture.dispose(); + options.dispose(); + + // textures.forEach((t){ + // t.dispose(); + // }); + // textures.clear(); + } +} \ No newline at end of file diff --git a/packages/three_js_angle_renderer/lib/renderers/renderer.dart b/packages/three_js_angle_renderer/lib/renderers/renderer.dart new file mode 100755 index 00000000..36d7808e --- /dev/null +++ b/packages/three_js_angle_renderer/lib/renderers/renderer.dart @@ -0,0 +1,2160 @@ +part of three_renderers; + +class AngleRendererParameters{ + double width; + double height; + RenderingContext gl; + bool stencil; + bool antialias; + bool alpha; + int clearColor; + double clearAlpha; + bool logarithmicDepthBuffer; + bool premultipliedAlpha; + bool preserveDrawingBuffer; + PowerPreference powerPreference; + bool reverseDepthBuffer; + bool failIfMajorPerformanceCaveat; + bool depth = true; + Precision precision; + XRManager Function(AngleRenderer renderer, dynamic gl)? xr; + + AngleRendererParameters({ + required this.width, + required this.height, + required this.gl, + this.stencil = true, + this.antialias = false, + this.alpha = false, + this.clearAlpha = 1.0, + this.clearColor = 0x000000, + this.logarithmicDepthBuffer = false, + this.depth = true, + this.premultipliedAlpha = true, + this.preserveDrawingBuffer = false, + this.powerPreference = PowerPreference.defaultp, + this.failIfMajorPerformanceCaveat = false, + this.reverseDepthBuffer = false, + this.precision = Precision.highp, + this.xr, + }); + + factory AngleRendererParameters.fromMap(Map map){ + return AngleRendererParameters( + width: map["width"].toDouble(), + height: map["height"].toDouble(), + depth: map["depth"] ?? true, + stencil: map["stencil"] ?? true, + antialias: map["antialias"] ?? false, + premultipliedAlpha: map["premultipliedAlpha"] ?? true, + preserveDrawingBuffer: map["preserveDrawingBuffer"] ?? false, + powerPreference: map["powerPreference"] ?? "default", + failIfMajorPerformanceCaveat: map["failIfMajorPerformanceCaveat"] ?? false, + alpha: map["alpha"] ?? false, + gl: map["gl"], + xr: map["xr"], + precision: map['precision'], + reverseDepthBuffer: map['reverseDepthBuffer'] + ); + } +} + +class AngleRenderer extends Renderer{ + late AngleRendererParameters parameters; + + bool _didDispose = false; + bool alpha = false; + bool depth = true; + bool stencil = true; + bool antialias = false; + + final currentClearColor = Color.fromHex32( 0x000000 ); + double currentClearAlpha = 0; + + bool premultipliedAlpha = true; + bool preserveDrawingBuffer = false; + PowerPreference powerPreference = PowerPreference.defaultp; + bool failIfMajorPerformanceCaveat = false; + bool reverseDepthBuffer = false; + + bool renderBackground = false; + AngleRenderList? currentRenderList; + AngleRenderState? currentRenderState; + + // render() can be called from within a callback triggered by another render. + + // We track this so that the nested render call gets its list and state isolated from the parent render call. + + List renderListStack = []; + List renderStateStack = []; + + // Debug configuration container + Map debug = { + /// Enables error checking and reporting when shader programs are being compiled + /// @type {boolean} + "checkShaderErrors": true + }; + + // clearing + + bool autoClear = true; + bool autoClearColor = true; + bool autoClearDepth = true; + bool autoClearStencil = true; + bool useLegacyLights = false; + + // scene graph + bool sortObjects = true; + + // user-defined clipping + + List clippingPlanes = []; + bool localClippingEnabled = false; + // physically based shading + + int outputEncoding = LinearEncoding; + + // physical lights + + bool physicallyCorrectLights = false; + + // tone mapping + + late double _width; + late double _height; + + double get width => _width; + double get height => _height; + + late Vector4 _viewport; + late Vector4 _scissor; + + // internal properties + + bool _isContextLost = false; + + // internal state cache + + int _currentActiveCubeFace = 0; + int _currentActiveMipmapLevel = 0; + AngleRenderTarget? _currentRenderTarget; + + int _currentMaterialId = -1; + Camera? _currentCamera; + + final _currentProjectionMatrix = Matrix4(); + final _currentViewport = Vector4.identity(); + final _currentScissor = Vector4.identity(); + bool? _currentScissorTest; + + double _pixelRatio = 1; + Function? _opaqueSort; + Function? _transparentSort; + + bool _scissorTest = false; + + // frustum + + final _frustum = Frustum(); + + // clipping + + bool _clippingEnabled = false; + bool _localClippingEnabled = false; + + // transmission + double transmissionResolutionScale = 1.0; + + // camera matrices cache + + final projScreenMatrix = Matrix4.identity(); + + final _vector3 = Vector3(); + final _vector4 = Vector4(); + + final _emptyScene = Scene(); + + double getTargetPixelRatio() => _currentRenderTarget == null ? _pixelRatio : 1.0; + + // initialize + + late RenderingContext _gl; + + RenderingContext get gl => _gl; + + final animation = AngleAnimation(); + late AngleExtensions extensions; + late AngleCapabilities capabilities; + late AngleState state; + late AngleInfo info; + late AngleProperties properties; + late AngleTextures textures; + late AngleCubeMaps cubemaps; + late AngleCubeUVMaps cubeuvmaps; + late AngleAttributes attributes; + late AngleGeometries geometries; + late AngleObjects objects; + late AnglePrograms programCache; + late AngleMaterials materials; + late AngleRenderLists renderLists; + late AngleRenderStates renderStates; + late AngleClipping clipping; + + late AngleBackground background; + late AngleMorphtargets morphtargets; + late BaseAngleBufferRenderer bufferRenderer; + late AngleIndexedBufferRenderer indexedBufferRenderer; + + late AngleUtils utils; + + late AngleBindingStates bindingStates; + + late XRManager Function(AngleRenderer renderer, dynamic gl)? _setXR; + late AngleUniformsGroups uniformsGroups; + late AngleShadowMap shadowMap; + + late final Framebuffer _scratchFrameBuffer; + late final Framebuffer _srcFramebuffer; + late final Framebuffer _dstFramebuffer; + AngleRenderer(this.parameters) { + _width = this.parameters.width; + _height = this.parameters.height; + + depth = this.parameters.depth; + stencil = this.parameters.stencil; + antialias = this.parameters.antialias; + premultipliedAlpha = this.parameters.premultipliedAlpha; + preserveDrawingBuffer = this.parameters.preserveDrawingBuffer; + powerPreference = this.parameters.powerPreference; + + failIfMajorPerformanceCaveat = this.parameters.failIfMajorPerformanceCaveat; + + alpha = this.parameters.alpha; + + _viewport = Vector4(0, 0, width, height); + _scissor = Vector4(0, 0, width, height); + + _gl = this.parameters.gl; + _setXR = this.parameters.xr; + + initGLContext(); + } + factory AngleRenderer.fromMap([Map? parameters]) { + return AngleRenderer(AngleRendererParameters.fromMap(parameters ?? {})); + } + + void initGLContext() { + _scratchFrameBuffer = _gl.createFramebuffer(); + _srcFramebuffer = _gl.createFramebuffer(); + _dstFramebuffer = _gl.createFramebuffer(); + + extensions = AngleExtensions(_gl); + extensions.init(); + utils = AngleUtils(extensions); + + capabilities = AngleCapabilities(_gl, extensions, parameters, utils); + state = AngleState(_gl,extensions); + + if ( capabilities.reverseDepthBuffer && reverseDepthBuffer ) { + state.buffers['depth'].setReversed( true ); + } + + info = AngleInfo(_gl); + properties = AngleProperties(); + textures = AngleTextures(_gl, extensions, state, properties, capabilities, utils, info); + cubemaps = AngleCubeMaps(this); + cubeuvmaps = AngleCubeUVMaps(this); + attributes = AngleAttributes(_gl); + bindingStates = AngleBindingStates(_gl, attributes); + geometries = AngleGeometries(_gl, attributes, info, bindingStates); + objects = AngleObjects(_gl, geometries, attributes, info); + morphtargets = AngleMorphtargets(_gl, capabilities, textures); + clipping = AngleClipping(properties); + programCache = AnglePrograms(this, cubemaps, cubeuvmaps, extensions, capabilities, bindingStates, clipping); + materials = AngleMaterials(this, properties); + renderLists = AngleRenderLists(); + renderStates = AngleRenderStates(extensions); + background = AngleBackground(this, cubemaps, cubeuvmaps, state, objects, alpha, premultipliedAlpha); + shadowMap = AngleShadowMap(this, objects, capabilities); + uniformsGroups = AngleUniformsGroups( _gl, info, capabilities, state ); + + bufferRenderer = AngleBufferRenderer(_gl, extensions, info); + indexedBufferRenderer = AngleIndexedBufferRenderer(_gl, extensions, info); + + info.programs = programCache.programs; + + xr = _setXR?.call(this,gl) ?? XRManager(this, _gl); + xr.init(); + xr.addEventListener( 'sessionstart', onXRSessionStart ); + xr.addEventListener( 'sessionend', onXRSessionEnd ); + } + + // API + + RenderingContext getContext() { + return _gl; + } + + dynamic getContextAttributes() { + return _gl.getContextAttributes(); + } + + void forceContextLoss() { + final extension = extensions.get('WEBGL_lose_context'); + if (extension) extension.loseContext(); + } + + void forceContextRestore() { + final extension = extensions.get('WEBGL_lose_context'); + if (extension) extension.restoreContext(); + } + + double getPixelRatio() { + return _pixelRatio; + } + + void setPixelRatio(double value) { + _pixelRatio = value; + setSize(width, height, false); + } + + Vector2 getSize(Vector2 target) { + return target.setValues(width.toDouble(), height.toDouble()); + } + + void setSize(double width, double height, [bool updateStyle = false]) { + if ( xr.isPresenting ) { + console.warning( 'WebGLRenderer: Can\'t change size while VR device is presenting.' ); + return; + } + + _width = width; + _height = height; + setViewport(0, 0, width, height); + } + + Vector2 getDrawingBufferSize(Vector2 target) { + return target.setValues(width * _pixelRatio, height * _pixelRatio).floor(); + } + + void setDrawingBufferSize(double width, double height, double pixelRatio) { + _width = width; + _height = height; + console.info("WebGLRenderer setDrawingBufferSize "); + setViewport(0, 0, width, height); + } + + Vector4 getCurrentViewport(Vector4 target) { + return target.setFrom(_currentViewport); + } + + Vector4 getViewport(Vector4 target) { + return target.setFrom(_viewport); + } + + void setViewport(double x, double y, double width, double height) { + _viewport.setValues(x, y, width, height); + _currentViewport.setFrom(_viewport); + _currentViewport.scale(_pixelRatio); + _currentViewport.floor(); + state.viewport(_currentViewport); + } + + Vector4 getScissor(Vector4 target) { + return target.setFrom(_scissor); + } + + void setScissor(double x, double y, double width, double height) { + _scissor.setValues(x, y, width, height); + _currentScissor.setFrom(_scissor); + _currentScissor.scale(_pixelRatio); + _currentScissor.floor(); + state.scissor(_currentScissor); + } + + bool getScissorTest() { + return _scissorTest; + } + + void setScissorTest(bool boolean) { + state.setScissorTest(_scissorTest = boolean); + } + + void setOpaqueSort(Function? method) { + _opaqueSort = method; + } + + void setTransparentSort(Function? method) { + _transparentSort = method; + } + + // Clearing + + Color getClearColor(Color target) { + target.setFrom(background.getClearColor()); + return target; + } + + // color same as Color.set + void setClearColor(Color color, [double alpha = 1.0]) { + background.setClearColor(color, alpha); + } + + double getClearAlpha() { + return background.getClearAlpha(); + } + + void setClearAlpha(double alpha) { + background.setClearAlpha(alpha); + } + + final uintClearColor = Uint32List( 4 ); + final intClearColor = Uint32List( 4 ); + + @override + void clear([bool color = true, bool depth = true, bool stencil = true]) { + int bits = 0; + + if ( color ) { + // check if we're trying to clear an integer target + bool isIntegerFormat = false; + if ( _currentRenderTarget != null ) { + final targetFormat = _currentRenderTarget!.texture.format; + isIntegerFormat = targetFormat == RGBAIntegerFormat || + targetFormat == RGIntegerFormat || + targetFormat == RedIntegerFormat; + } + + // use the appropriate clear functions to clear the target if it's a signed + // or unsigned integer target + if ( isIntegerFormat ) { + final targetType = _currentRenderTarget!.texture.type; + final isUnsignedType = targetType == UnsignedByteType || + targetType == UnsignedIntType || + targetType == UnsignedShortType || + targetType == UnsignedInt248Type || + targetType == UnsignedShort4444Type || + targetType == UnsignedShort5551Type; + + final clearColor = background.getClearColor(); + final a = background.getClearAlpha(); + final r = clearColor.red; + final g = clearColor.green; + final b = clearColor.blue; + + if ( isUnsignedType ) { + uintClearColor[ 0 ] = (r*255).toInt(); + uintClearColor[ 1 ] = (g*255).toInt(); + uintClearColor[ 2 ] = (b*255).toInt(); + uintClearColor[ 3 ] = (a*255).toInt(); + _gl.clearBufferuiv( WebGL.COLOR, 0, uintClearColor.buffer.asByteData().getUint32(0) ); + } + else { + intClearColor[ 0 ] = (r*255).toInt(); + intClearColor[ 1 ] = (g*255).toInt(); + intClearColor[ 2 ] = (b*255).toInt(); + intClearColor[ 3 ] = (a*255).toInt(); + _gl.clearBufferiv( WebGL.COLOR, 0, intClearColor.buffer.asByteData().getInt32(0) ); + } + + } + else { + bits |= WebGL.COLOR_BUFFER_BIT; + } + } + + if ( depth ) bits |= WebGL.DEPTH_BUFFER_BIT; + if ( stencil ) { + bits |= WebGL.STENCIL_BUFFER_BIT; + state.buffers['stencil'].setMask( 0xffffffff ); + } + + _gl.clear( bits ); + } + + void clearColor() { + clear(true, false, false); + } + + void clearDepth() { + clear(false, true, false); + } + + void clearStencil() { + clear(false, false, true); + } + + // + @override + void dispose() { + if(_didDispose) return; + _didDispose = true; + state.reset(); + attributes.dispose(); + renderLists.dispose(); + renderStates.dispose(); + cubemaps.dispose(); + cubeuvmaps.dispose(); + bindingStates.dispose(); + programCache.dispose(); + + currentRenderList?.dispose(); + for(final stack in renderListStack){ + stack.dispose(); + } + renderListStack.clear(); + for(final stack in renderStateStack){ + stack.dispose(); + } + + renderStateStack.clear(); + debug.clear(); + + _currentCamera?.clear(); + _frustum.dispose(); + _emptyScene.dispose(); + + extensions.dispose(); + capabilities.dispose(); + clipping.dispose(); + utils.dispose(); + + state.dispose(); + materials.dispose(); + objects.dispose(); + morphtargets.dispose(); + indexedBufferRenderer.dispose(); + background.dispose(); + textures.dispose(); + geometries.dispose(); + shadowMap.dispose(); + + properties.dispose(); + + _gl.deleteFramebuffer(_scratchFrameBuffer); + _gl.deleteFramebuffer(_srcFramebuffer); + _gl.deleteFramebuffer(_dstFramebuffer); + } + + // Events + void onContextLost( event ) { + //event.preventDefault(); + console.info( 'THREE.WebGLRenderer: Context Lost.' ); + _isContextLost = true; + } + + void onContextRestore() { + console.info('WebGLRenderer: Context Restored.'); + + _isContextLost = false; + + final infoAutoReset = info.autoReset; + final shadowMapEnabled = shadowMap.enabled; + final shadowMapAutoUpdate = shadowMap.autoUpdate; + final shadowMapNeedsUpdate = shadowMap.needsUpdate; + final shadowMapType = shadowMap.type; + + initGLContext(); + + info.autoReset = infoAutoReset; + shadowMap.enabled = shadowMapEnabled; + shadowMap.autoUpdate = shadowMapAutoUpdate; + shadowMap.needsUpdate = shadowMapNeedsUpdate; + shadowMap.type = shadowMapType; + } + + void onContextCreationError( event ) { + console.error( 'THREE.WebGLRenderer: A WebGL context could not be created. Reason: ${event.statusMessage}'); + } + + void onMaterialDispose(Event event) { + final material = event.target; + material.removeEventListener('dispose', onMaterialDispose); + deallocateMaterial(material); + } + + // Buffer deallocation + + void deallocateMaterial(Material material) { + releaseMaterialProgramReferences(material); + properties.remove(material); + } + + void releaseMaterialProgramReferences(Material material) { + final programs = properties.get(material)["programs"]; + + if (programs != null) { + programs.forEach((key, program) { + programCache.releaseProgram(program); + }); + + if (material is ShaderMaterial) { + programCache.releaseShaderCache(material); + } + } + } + + void renderBufferDirect( + Camera camera, + Object3D? scene, + BufferGeometry geometry, + Material material, + Object3D object, + Map? group, + ) { + // print("renderBufferDirect .............material: ${material.runtimeType} "); + // renderBufferDirect second parameter used to be fog (could be null) + scene ??= _emptyScene; + final frontFaceCW = (object is Mesh && object.matrixWorld.determinant() < 0); + + AngleProgram program = setProgram(camera, scene, geometry, material, object); + + state.setMaterial(material, frontFaceCW); + + BufferAttribute? index = geometry.index; + int rangeFactor = 1; + + if (material.wireframe) { + index = geometries.getWireframeAttribute(geometry); + if (index == null) return; + if(kIsWeb && !kIsWasm){ + rangeFactor = 2; + } + } + + if (geometry.morphAttributes["position"] != null || geometry.morphAttributes["normal"] != null) { + morphtargets.update(object, geometry, program); + } + + final drawRange = geometry.drawRange; + BufferAttribute? position = geometry.attributes["position"]; + int drawStart = (drawRange['start'] ?? 0) * rangeFactor; + int drawEnd = ( (drawRange['start'] ?? 0) + (drawRange['count'] ?? 0) ) * rangeFactor; + + if ( group != null ) { + drawStart = math.max( drawStart, group['start'] * rangeFactor ); + drawEnd = math.min( drawEnd, ( group['start'] + group['count'] ) * rangeFactor ); + } + + if ( index != null ) { + drawStart = math.max( drawStart, 0 ); + drawEnd = math.min( drawEnd, index.count ); + } else if (position != null) { + drawStart = math.max( drawStart, 0 ); + drawEnd = math.min( drawEnd, position.count ); + } + + final drawCount = drawEnd - drawStart; + if ( drawCount < 0 || drawCount == double.maxFinite.toInt() ) return; + + bindingStates.setup(object, material, program, geometry, index); + + Map attribute; + BaseAngleBufferRenderer renderer = bufferRenderer; + + if (index != null) { + attribute = attributes.get(index); + renderer = indexedBufferRenderer; + renderer.setIndex(attribute); + } + + if (object is Mesh) { + if (material.wireframe) { + state.setLineWidth(material.wireframeLinewidth! * getTargetPixelRatio()); + renderer.setMode(WebGL.LINES); + } + else { + renderer.setMode(WebGL.TRIANGLES); + } + } + else if (object is Line) { + double? lineWidth = material.linewidth; + + lineWidth ??= 1; // Not using Line*Material + + state.setLineWidth(lineWidth * getTargetPixelRatio()); + + if (object is LineSegments) { + renderer.setMode(WebGL.LINES); + } + else if (object is LineLoop) { + renderer.setMode(WebGL.LINE_LOOP); + } + else { + renderer.setMode(WebGL.LINE_STRIP); + } + } + else if (object is Points) { + renderer.setMode(WebGL.POINTS); + } + else if (object is Sprite) { + renderer.setMode(WebGL.TRIANGLES); + } + + if ( object is BatchedMesh ) { + if (object.multiDrawInstances != null ) { + renderer.renderMultiDrawInstances( object.multiDrawStarts, object.multiDrawCounts, object.multiDrawCount, object.multiDrawInstances! ); + } + else { + if ( ! extensions.get( 'WEBGL_multi_draw' ) ) { + final starts = object.multiDrawStarts; + final counts = object.multiDrawCounts; + final drawCount = object.multiDrawCount; + final bytesPerElement = index != null? attributes.get( index ).bytesPerElement : 1; + final uniforms = properties.get( material )['currentProgram'].getUniforms(); + + for ( int i = 0; i < drawCount; i ++ ) { + uniforms.setValue( _gl, '_gl_DrawID', i ); + renderer.render( starts[ i ] ~/ bytesPerElement, counts[ i ] ); + } + } + else { + renderer.renderMultiDraw( object.multiDrawStarts, object.multiDrawCounts, object.multiDrawCount ); + } + } + } + if (object is InstancedMesh) { + renderer.renderInstances(drawStart, drawCount, object.count!); + } + else if (geometry is InstancedBufferGeometry) { + final instanceCount = math.min(geometry.instanceCount!, geometry.maxInstanceCount ?? 0); + renderer.renderInstances(drawStart, drawCount, instanceCount); + } + else { + renderer.render(drawStart, drawCount); + } + } + + // Compile + void prepareMaterial(Material material, Object3D? scene, Object3D object ) { + + if ( material.transparent == true && material.side == DoubleSide && material.forceSinglePass == false ) { + + material.side = BackSide; + material.needsUpdate = true; + getProgram( material, scene, object ); + + material.side = FrontSide; + material.needsUpdate = true; + getProgram( material, scene, object ); + + material.side = DoubleSide; + + } else { + + getProgram( material, scene, object ); + + } + + } + Set compile(Object3D scene, Camera camera, [Object3D? targetScene]) { + targetScene ??= scene; + + currentRenderState = renderStates.get(targetScene); + currentRenderState!.init(camera); + renderStateStack.add(currentRenderState!); + + targetScene.traverseVisible((object) { + if (object is Light && object.layers.test(camera.layers)) { + currentRenderState!.pushLight(object); + + if (object.castShadow) { + currentRenderState!.pushShadow(object); + } + } + }); + + if ( scene != targetScene ) { + scene.traverseVisible((object){ + if (object is Light && object.layers.test( camera.layers ) ) { + currentRenderState!.pushLight( object ); + if ( object.castShadow ) { + currentRenderState!.pushShadow( object ); + } + } + }); + } + currentRenderState!.setupLights(); + + final materials = Set(); + + scene.traverse((object) { + if( ! ( object is Mesh || object is Points || object is Line || object is Sprite ) ) { + return; + } + + final material = object.material; + + if (material != null) { + if (material is GroupMaterial) { + for (int i = 0; i < material.children.length; i++) { + final material2 = material.children[i]; + prepareMaterial(material2, targetScene, object);//getProgram(material2, scene, object); + materials.add( material2 ); + } + } else { + prepareMaterial(material, targetScene, object);//getProgram(material, scene, object); + materials.add( material ); + } + } + }); + + currentRenderState = renderStateStack.removeLast(); + return materials; + } + + // Animation Loop + + void Function(double)? onAnimationFrameCallback; + + void onAnimationFrame(double time) { + if (onAnimationFrameCallback != null) onAnimationFrameCallback!(time); + } + + void onXRSessionStart(event) { + animation.stop(); + } + + void onXRSessionEnd(event) { + animation.start(); + } + + void setAnimationLoop( callback ) { + onAnimationFrameCallback = callback; + xr.setAnimationLoop( callback ); + ( callback == null ) ? animation.stop() : animation.start(); + } + // Rendering + + @override + void render(Object3D scene, Camera camera) { + + if (_isContextLost) return; + + // update scene graph + if (scene.matrixWorldAutoUpdate) scene.updateMatrixWorld(); + + // update camera matrices and frustum + + if (camera.parent == null && camera.matrixWorldAutoUpdate) camera.updateMatrixWorld(); + + if ( xr.enabled && xr.isPresenting ) { + if (xr.cameraAutoUpdate) xr.updateCamera( camera ); + if(kIsWeb) camera = xr.getCamera(); + } + + if (scene is Scene) { + scene.onBeforeRender?.call(renderer: this, scene: scene, camera: camera, renderTarget: _currentRenderTarget); + } + + currentRenderState = renderStates.get(scene, renderCallDepth: renderStateStack.length); + currentRenderState!.init(camera); + + renderStateStack.add(currentRenderState!); + + projScreenMatrix.multiply2(camera.projectionMatrix, camera.matrixWorldInverse); + + _frustum.setFromMatrix(projScreenMatrix); + + _localClippingEnabled = localClippingEnabled; + _clippingEnabled = clipping.init(clippingPlanes, _localClippingEnabled); + + currentRenderList = renderLists.get(scene, renderListStack.length); + currentRenderList!.init(); + + renderListStack.add(currentRenderList!); + + if ( xr.enabled && xr.isPresenting) { + final depthSensingMesh = xr.getDepthSensingMesh(); + if ( depthSensingMesh != null ) { + projectObject( depthSensingMesh, camera, - double.maxFinite.toInt(), this.sortObjects ); + } + } + + projectObject(scene, camera, 0, sortObjects); + + currentRenderList!.finish(); + + if (sortObjects) { + currentRenderList!.sort(_opaqueSort, _transparentSort); + } + + renderBackground = !xr.enabled || !xr.isPresenting || !xr.hasDepthSensing(); + if ( renderBackground ) { + background.addToRenderList( currentRenderList!, scene ); + } + + info.render['frame'] = info.render['frame']!+1; + + if (_clippingEnabled) clipping.beginShadows(); + final shadowsArray = currentRenderState!.state.shadowsArray; + if(kIsWeb){ + shadowMap.render(shadowsArray, scene, camera); + } + if (_clippingEnabled) clipping.endShadows(); + + if (info.autoReset) info.reset(); + + // render scene + final opaqueObjects = currentRenderList?.opaque; + final transmissiveObjects = currentRenderList?.transmissive; + + currentRenderState!.setupLights(physicallyCorrectLights); + + if (camera is ArrayCamera) { + + final cameras = camera.cameras; + if (transmissiveObjects != null && transmissiveObjects.isNotEmpty) { + for (int i = 0, l = cameras.length; i < l; i ++ ) { + final camera2 = cameras[ i ]; + renderTransmissionPass( opaqueObjects!, transmissiveObjects, scene, camera2); + } + } + if (renderBackground) background.render(scene); + for (int i = 0, l = cameras.length; i < l; i++) { + final camera2 = cameras[i]; + renderScene(currentRenderList!, scene, camera2, camera2.viewport); + } + } + else { + if ( renderBackground ) background.render( scene ); + renderScene(currentRenderList!, scene, camera); + if(transmissiveObjects != null && transmissiveObjects.isNotEmpty) renderTransmissionPass( opaqueObjects!, transmissiveObjects, scene, camera ); + } + + if(!kIsWeb){ + shadowMap.render(shadowsArray, scene, camera); + } + + if (_currentRenderTarget != null) { + // resolve multisample renderbuffers to a single-sample texture if necessary + textures.updateMultisampleRenderTarget(_currentRenderTarget!); + // Generate mipmap if we're using any kind of mipmap filtering + textures.updateRenderTargetMipmap(_currentRenderTarget!); + } + + if (scene is Scene) { + scene.onAfterRender?.call(renderer: this, scene: scene, camera: camera); + } + + _gl.flush(); + + bindingStates.resetDefaultState(); + _currentMaterialId = -1; + _currentCamera = null; + + renderStateStack.removeLast(); + if (renderStateStack.isNotEmpty) { + currentRenderState = renderStateStack[renderStateStack.length - 1]; + if (_clippingEnabled) clipping.setGlobalState(clippingPlanes, currentRenderState!.state.camera! ); + } + else { + currentRenderState = null; + } + + renderListStack.removeLast(); + + if (renderListStack.isNotEmpty) { + currentRenderList = renderListStack[renderListStack.length - 1]; + } + else { + currentRenderList = null; + } + } + + void projectObject(Object3D object, Camera camera, int groupOrder, bool sortObjects) { + if (!object.visible) return; + final visible = object.layers.test(camera.layers); + + if (visible) { + if (object is Group) { + groupOrder = object.renderOrder; + } + else if (object is LOD) { + dynamic u = object; + if (object.autoUpdate == true) u.update(camera); + } + else if (object is Light) { + currentRenderState!.pushLight(object); + + if (object.castShadow) { + currentRenderState!.pushShadow(object); + } + } + else if (object is Sprite) { + if (!object.frustumCulled || _frustum.intersectsSprite(object)) { + if (sortObjects) { + _vector4.setFromMatrixPosition(object.matrixWorld).applyMatrix4(projScreenMatrix); + } + + BufferGeometry geometry = objects.update(object); + final material = object.material; + + if (material != null && material.visible) { + currentRenderList!.push(object, geometry, material, groupOrder, _vector4.z, null); + } + } + } + else if (object is Mesh || object is Line || object is Points) { + // if (object is SkinnedMesh) { + // // update skeleton only once in a frame + // if (object.skeleton!.frame != info.render["frame"]) { + // object.skeleton!.update(); + // object.skeleton!.frame = info.render["frame"]!; + // } + // } + + // print("object: ${object.type} ${!object.frustumCulled} ${_frustum.intersectsObject(object)} "); + + if (!object.frustumCulled || _frustum.intersectsObject(object)) { + final geometry = objects.update(object); + final material = object.material; + + if (sortObjects) { + if (object.boundingSphere != null ) { + if (object.boundingSphere == null ) object.computeBoundingSphere(); + _vector4.setFrom(object.boundingSphere!.center ); + } + else { + if ( geometry.boundingSphere == null ) geometry.computeBoundingSphere(); + _vector4.setFrom( geometry.boundingSphere!.center ); + } + _vector4..applyMatrix4(object.matrixWorld)..applyMatrix4(projScreenMatrix); + } + + if (material is GroupMaterial) { + final groups = geometry.groups; + + if (groups.isNotEmpty) { + for (int i = 0, l = groups.length; i < l; i++) { + Map group = groups[i]; + final groupMaterial = material.children[group["materialIndex"]]; + + if (groupMaterial.visible) { + currentRenderList!.push(object, geometry, groupMaterial, groupOrder, _vector4.z, group); + } + } + } + else { + if (material.visible && material.children.isNotEmpty) { + currentRenderList!.push(object, geometry, material.children[0], groupOrder, _vector4.z, null); + } + } + } + else if (material != null && material.visible) { + currentRenderList!.push(object, geometry, material, groupOrder, _vector4.z, null); + } + } + } + } + + final children = object.children; + + for (int i = 0, l = children.length; i < l; i++) { + projectObject(children[i], camera, groupOrder, sortObjects); + } + } + + void renderScene(AngleRenderList currentRenderList, Object3D scene, Camera camera, [Vector4? viewport]) { + List opaqueObjects = currentRenderList.opaque; + final transmissiveObjects = currentRenderList.transmissive; + final transparentObjects = currentRenderList.transparent; + + currentRenderState!.setupLightsView(camera); + + if (_clippingEnabled) clipping.setGlobalState(clippingPlanes, camera ); + + if (viewport != null){ + _currentViewport.setFrom(viewport); + state.viewport(_currentViewport); + } + + if (opaqueObjects.isNotEmpty) renderObjects(opaqueObjects, scene, camera); + if (transmissiveObjects.isNotEmpty) renderObjects(transmissiveObjects, scene, camera); + if (transparentObjects.isNotEmpty) renderObjects(transparentObjects, scene, camera); + + // Ensure depth buffer writing is enabled so it can be cleared on next render + + state.buffers["depth"].setTest(true); + state.buffers["depth"].setMask(true); + state.buffers["color"].setMask(true); + + state.setPolygonOffset(false); + } + + void renderTransmissionPass(List opaqueObjects, List transmissiveObjects, Object3D scene, Camera camera) { + final overrideMaterial = scene is Scene? scene.overrideMaterial : null; + + if ( overrideMaterial != null ) { + return; + } + + AngleRenderTarget? transmissionRenderTarget = currentRenderState?.state.transmissionRenderTarget[ camera.id ]; + final activeViewport = camera.viewport ?? _currentViewport; + + if ( currentRenderState?.state.transmissionRenderTarget[ camera.id ] == null || + (activeViewport.w.toInt() != transmissionRenderTarget?.height || activeViewport.z.toInt() != transmissionRenderTarget?.width) + ) { + transmissionRenderTarget?.dispose(); + currentRenderState?.state.transmissionRenderTarget[ camera.id ] = AngleRenderTarget( 1, 1, RenderTargetOptions({ + 'generateMipmaps': true, + 'type': ( extensions.has( 'EXT_color_buffer_half_float' ) || extensions.has( 'EXT_color_buffer_float' ) ) ? HalfFloatType : UnsignedByteType, + 'minFilter': LinearMipmapLinearFilter, + 'samples': 4, + 'stencilBuffer': stencil, + 'resolveDepthBuffer': false, + 'resolveStencilBuffer': false, + 'colorSpace': ColorManagement.workingColorSpace.toString(), + })); + + transmissionRenderTarget = currentRenderState?.state.transmissionRenderTarget[ camera.id ]; + } + + transmissionRenderTarget!.setSize( (activeViewport.z * transmissionResolutionScale).toInt(), (activeViewport.w * transmissionResolutionScale).toInt()); + + final currentRenderTarget = getRenderTarget(); + setRenderTarget( transmissionRenderTarget ); + + getClearColor( currentClearColor ); + currentClearAlpha = getClearAlpha(); + if ( currentClearAlpha < 1 ) setClearColor( Color.fromHex32(0xffffff), 0.5 ); + clear(); + + if ( renderBackground ) background.render( scene ); + + // Turn off the features which can affect the frag color for opaque objects pass. + // Otherwise they are applied twice in opaque objects pass and transmission objects pass. + final currentToneMapping = toneMapping; + toneMapping = NoToneMapping; + + // Remove viewport from camera to avoid nested render calls resetting viewport to it (e.g Reflector). + // Transmission render pass requires viewport to match the transmissionRenderTarget. + final currentCameraViewport = camera.viewport; + if ( camera.viewport != null ) camera.viewport = null; + + currentRenderState?.setupLightsView( camera ); + + if ( _clippingEnabled == true ) clipping.setGlobalState( clippingPlanes, camera ); + + renderObjects( opaqueObjects, scene, camera ); + + textures.updateMultisampleRenderTarget( transmissionRenderTarget ); + textures.updateRenderTargetMipmap( transmissionRenderTarget ); + + if (!extensions.has( 'WEBGL_multisampled_render_to_texture' ) ) { // see #28131 + bool renderTargetNeedsUpdate = false; + + for ( int i = 0, l = transmissiveObjects.length; i < l; i ++ ) { + final renderItem = transmissiveObjects[ i ]; + + final object = renderItem.object; + final geometry = renderItem.geometry; + final material = renderItem.material; + final group = renderItem.group; + + if ( material!.side == DoubleSide && object!.layers.test( camera.layers ) ) { + final currentSide = material.side; + + material.side = BackSide; + material.needsUpdate = true; + + renderObject( object, scene, camera, geometry!, material, group ); + + material.side = currentSide; + material.needsUpdate = true; + + renderTargetNeedsUpdate = true; + } + } + + if ( renderTargetNeedsUpdate == true ) { + textures.updateMultisampleRenderTarget( transmissionRenderTarget ); + textures.updateRenderTargetMipmap( transmissionRenderTarget ); + } + } + + setRenderTarget( currentRenderTarget ); + setClearColor( currentClearColor, currentClearAlpha ); + + if (currentCameraViewport != null) camera.viewport = currentCameraViewport; + + toneMapping = currentToneMapping; + } + + void renderObjects(List renderList, Object3D scene, Camera camera) { + final overrideMaterial = scene is Scene ? scene.overrideMaterial : null; + for (int i = 0, l = renderList.length; i < l; i++) { + final renderItem = renderList[i]; + + final object = renderItem.object!; + final geometry = renderItem.geometry!; + final material = overrideMaterial ?? renderItem.material!; + final group = renderItem.group; + + if (object.layers.test(camera.layers)) { + renderObject(object, scene, camera, geometry, material, group); + } + } + } + + void renderObject(Object3D object, scene, Camera camera, BufferGeometry geometry, Material material, Map? group) { + object.onBeforeRender?.call( + renderer: this, + mesh: object, + scene: scene, + camera: camera, + geometry: geometry, + material: material, + group: group + ); + + object.modelViewMatrix.multiply2(camera.matrixWorldInverse, object.matrixWorld); + object.normalMatrix.getNormalMatrix(object.modelViewMatrix); + + material.onBeforeRender?.call( + this, + scene, + camera, + geometry, + object, + group + ); + + if (material.transparent && material.side == DoubleSide && !material.forceSinglePass) { + material.side = BackSide; + material.needsUpdate = true; + renderBufferDirect(camera, scene, geometry, material, object, group); + + material.side = FrontSide; + material.needsUpdate = true; + renderBufferDirect(camera, scene, geometry, material, object, group); + + material.side = DoubleSide; + } + else { + renderBufferDirect(camera, scene, geometry, material, object, group); + } + + object.onAfterRender?.call(renderer: this, scene: scene, camera: camera, geometry: geometry, material: material, group: group); + } + + AngleProgram? getProgram(Material material, Object3D? scene, Object3D object) { + if (scene is! Scene) scene = _emptyScene; + // scene could be a Mesh, Line, Points, ... + + final materialProperties = properties.get(material); + + final lights = currentRenderState!.state.lights; + final shadowsArray = currentRenderState!.state.shadowsArray; + + final lightsStateVersion = lights.state.version; + + final parameters = programCache.getParameters(material, lights.state, shadowsArray, scene, object); + final programCacheKey = programCache.getProgramCacheKey(parameters); + + Map? programs = materialProperties["programs"]; + + // always update environment and fog - changing these trigger an getProgram call, but it's possible that the program doesn't change + materialProperties["environment"] = material is MeshStandardMaterial ? scene.environment : null; + materialProperties["fog"] = scene.fog; + materialProperties['envMap'] = ( material is MeshStandardMaterial ? cubeuvmaps.get( material.envMap ?? materialProperties['environment'] ) : cubemaps.get( material.envMap ?? materialProperties['environment'] ) ); + materialProperties['envMapRotation'] = ( materialProperties['environment'] != null && material.envMap == null ) ? scene.environmentRotation : material.envMapRotation; + + if (programs == null) { + material.addEventListener('dispose', onMaterialDispose); + programs = {}; + materialProperties["programs"] = programs; + } + + AngleProgram? program = programs[programCacheKey]; + + if (program != null) { + // early out if program and light state is identical + if (materialProperties["currentProgram"] == program && materialProperties["lightsStateVersion"] == lightsStateVersion) { + updateCommonMaterialProperties(material, parameters); + return program; + } + } + else { + parameters.uniforms = programCache.getUniforms(material); + + //material.onBuild(parameters, this); + material.onBeforeCompile?.call(parameters, this); + program = programCache.acquireProgram(parameters, programCacheKey); + programs[programCacheKey] = program; + + materialProperties["uniforms"] = parameters.uniforms; + } + + Map uniforms = materialProperties["uniforms"]; + + if ((material is! ShaderMaterial && material is! RawShaderMaterial) || material.clipping == true) { + uniforms["clippingPlanes"] = clipping.uniform; + } + + updateCommonMaterialProperties(material, parameters); + + // store the light setup it was created for + + materialProperties["needsLights"] = materialNeedsLights(material); + materialProperties["lightsStateVersion"] = lightsStateVersion; + + if (materialProperties["needsLights"] == true) { + // wire up the material to this renderer's lighting state + + uniforms["ambientLightColor"]["value"] = lights.state.ambient; + uniforms["lightProbe"]["value"] = lights.state.probe; + uniforms["directionalLights"]["value"] = lights.state.directional; + uniforms["directionalLightShadows"]["value"] = lights.state.directionalShadow; + uniforms["spotLights"]["value"] = lights.state.spot; + uniforms["spotLightShadows"]["value"] = lights.state.spotShadow; + uniforms["rectAreaLights"]["value"] = lights.state.rectArea; + uniforms["ltc_1"]["value"] = lights.state.rectAreaLTC1; + uniforms["ltc_2"]["value"] = lights.state.rectAreaLTC2; + uniforms["pointLights"]["value"] = lights.state.point; + uniforms["pointLightShadows"]["value"] = lights.state.pointShadow; + uniforms["hemisphereLights"]["value"] = lights.state.hemi; + + uniforms["directionalShadowMap"]["value"] = lights.state.directionalShadowMap; + uniforms["directionalShadowMatrix"]["value"] = lights.state.directionalShadowMatrix; + uniforms["spotShadowMap"]["value"] = lights.state.spotShadowMap; + uniforms["spotLightMatrix"]["value"] = lights.state.spotLightMatrix; + uniforms["spotLightMap"]["value"] = lights.state.spotLightMap; + uniforms["pointShadowMap"]["value"] = lights.state.pointShadowMap; + uniforms["pointShadowMatrix"]["value"] = lights.state.pointShadowMatrix; + } + + materialProperties["currentProgram"] = program; + materialProperties["uniformsList"] = null; + + return program; + } + + List getUniformList(Map materialProperties ) { + if ( materialProperties['uniformsList'] == null ) { + final progUniforms = (materialProperties['currentProgram'] as AngleProgram).getUniforms(); + materialProperties['uniformsList'] = AngleUniforms.seqWithValue( progUniforms.seq, materialProperties['uniforms'] ); + } + + return materialProperties['uniformsList']; + } + void updateCommonMaterialProperties(Material material, AngleParameters parameters) { + final materialProperties = properties.get(material); + + materialProperties['outputColorSpace'] = parameters.outputColorSpace; + materialProperties['batching'] = parameters.batching; + materialProperties['batchingColor'] = parameters.batchingColor; + materialProperties['instancing'] = parameters.instancing; + materialProperties['instancingColor'] = parameters.instancingColor; + materialProperties['instancingMorph'] = parameters.instancingMorph; + materialProperties['skinning'] = parameters.skinning; + materialProperties['morphTargets'] = parameters.morphTargets; + materialProperties['morphNormals'] = parameters.morphNormals; + materialProperties['morphColors'] = parameters.morphColors; + materialProperties['morphTargetsCount'] = parameters.morphTargetsCount; + materialProperties['numClippingPlanes'] = parameters.numClippingPlanes; + materialProperties['numIntersection'] = parameters.numClipIntersection; + materialProperties['vertexAlphas'] = parameters.vertexAlphas; + materialProperties['vertexTangents'] = parameters.vertexTangents; + materialProperties['toneMapping'] = parameters.toneMapping; + } + + AngleProgram setProgram(Camera camera, Object3D? scene, BufferGeometry? geometry, Material material, Object3D object) { + if (scene is! Scene) scene = _emptyScene; // scene could be a Mesh, Line, Points, ... + textures.resetTextureUnits(); + + final fog = scene.fog; + final environment = material is MeshStandardMaterial ? scene.environment : null; + final colorSpace = ( _currentRenderTarget == null ) ? outputColorSpace : ( _currentRenderTarget?.isXRRenderTarget == true ? _currentRenderTarget?.texture.colorSpace : LinearSRGBColorSpace ); + final envMap = ( material is MeshStandardMaterial ? cubeuvmaps.get( material.envMap ?? environment ) : cubemaps.get( material.envMap ?? environment ) ); + final vertexAlphas = material.vertexColors && + geometry?.attributes['color'] != null && + geometry?.attributes['color'].itemSize == 4; + final vertexTangents = geometry?.attributes['tangent'] != null && (material.normalMap != null || (material is MeshPhysicalMaterial && material.anisotropy > 0)); + final morphTargets = geometry?.morphAttributes['position'] != null; + final morphNormals = geometry?.morphAttributes['normal'] != null; + final morphColors = geometry?.morphAttributes['color'] != null; + + int toneMapping = NoToneMapping; + + if ( material.toneMapped ) { + if ( _currentRenderTarget == null || _currentRenderTarget?.isXRRenderTarget == true ) { + toneMapping = toneMapping; + } + } + + final morphAttribute = geometry?.morphAttributes['position'] ?? geometry?.morphAttributes['normal'] ?? geometry?.morphAttributes['color']; + final morphTargetsCount = ( morphAttribute != null ) ? morphAttribute.length : 0; + + final materialProperties = properties.get( material ); + final lights = currentRenderState?.state.lights; + + if (_clippingEnabled) { + if (_localClippingEnabled || camera != _currentCamera ) { + final useCache = camera == _currentCamera && material.id == _currentMaterialId; + + // we might want to call this function with some ClippingGroup + // object instead of the material, once it becomes feasible + // (#8465, #8379) + clipping.setState( material, camera, useCache ); + } + } + + bool needsProgramChange = false; + + if ( material.version == materialProperties['__version'] ) { + if ( materialProperties['needsLights'] != null && ( materialProperties['lightsStateVersion'] != lights?.state.version ) ) { + needsProgramChange = true; + } else if ( materialProperties['outputColorSpace'] != colorSpace ) { + needsProgramChange = true; + } else if ( object is BatchedMesh && materialProperties['batching'] == false ) { + needsProgramChange = true; + } else if (object is! BatchedMesh && materialProperties['batching'] == true ) { + needsProgramChange = true; + }else if ( object is BatchedMesh && materialProperties['batchingColor'] == true && object.colorsTexture == null ) { + needsProgramChange = true; + } else if ( object is BatchedMesh && materialProperties['batchingColor'] == false && object.colorsTexture != null ) { + needsProgramChange = true; + }else if ( object is InstancedMesh && materialProperties['instancing'] == false ) { + needsProgramChange = true; + } else if (object is! InstancedMesh && materialProperties['instancing'] == true ) { + needsProgramChange = true; + } else if ( object is SkinnedMesh && materialProperties['skinning'] == false ) { + needsProgramChange = true; + } else if (object is! SkinnedMesh && materialProperties['skinning'] == true ) { + needsProgramChange = true; + } else if ( object is InstancedMesh && materialProperties['instancingColor'] == true && object.instanceColor == null ) { + needsProgramChange = true; + } else if ( object is InstancedMesh && materialProperties['instancingColor'] == false && object.instanceColor != null ) { + needsProgramChange = true; + } else if ( object is InstancedMesh && materialProperties['instancingMorph'] == true && object.morphTexture == null ) { + needsProgramChange = true; + } else if ( object is InstancedMesh && materialProperties['instancingMorph'] == false && object.morphTexture != null ) { + needsProgramChange = true; + } else if ( materialProperties['envMap'] != envMap ) { + needsProgramChange = true; + } else if ( material.fog == true && materialProperties['fog'] != fog ) { + needsProgramChange = true; + } else if ( materialProperties['numClippingPlanes'] != null && + ( materialProperties['numClippingPlanes'] != clipping.numPlanes || + materialProperties['numIntersection'] != clipping.numIntersection ) ) { + needsProgramChange = true; + } else if ( materialProperties['vertexAlphas'] != vertexAlphas ) { + needsProgramChange = true; + } else if ( materialProperties['vertexTangents'] != vertexTangents ) { + needsProgramChange = true; + } else if ( materialProperties['morphTargets'] != morphTargets ) { + needsProgramChange = true; + } else if ( materialProperties['morphNormals'] != morphNormals ) { + needsProgramChange = true; + } else if ( materialProperties['morphColors'] != morphColors ) { + needsProgramChange = true; + } else if ( materialProperties['toneMapping'] != toneMapping ) { + needsProgramChange = true; + } else if ( materialProperties['morphTargetsCount'] != morphTargetsCount ) { + needsProgramChange = true; + } + } else { + needsProgramChange = true; + materialProperties['__version'] = material.version; + } + + AngleProgram? program = materialProperties['currentProgram']; + + if (needsProgramChange) { + program = getProgram( material, scene, object ); + } + + bool refreshProgram = false; + bool refreshMaterial = false; + bool refreshLights = false; + + final AngleUniforms? pUniformS = program?.getUniforms(); + final Map mUniformS = materialProperties['uniforms']; + + if (state.useProgram( program?.program ) ) { + refreshProgram = true; + refreshMaterial = true; + refreshLights = true; + } + + if ( material.id != _currentMaterialId ) { + _currentMaterialId = material.id; + refreshMaterial = true; + } + + if ( refreshProgram || _currentCamera != camera ) { + + // common camera uniforms + final reverseDepthBuffer = (state.buffers['depth'] as DepthBuffer).getReversed(); + + if ( reverseDepthBuffer ) { + _currentProjectionMatrix.setFrom( camera.projectionMatrix ); + toNormalizedProjectionMatrix( _currentProjectionMatrix ); + toReversedProjectionMatrix( _currentProjectionMatrix ); + pUniformS?.setValue( _gl, 'projectionMatrix', _currentProjectionMatrix ); + } + else { + pUniformS?.setValue( _gl, 'projectionMatrix', camera.projectionMatrix ); + } + + pUniformS?.setValue( _gl, 'viewMatrix', camera.matrixWorldInverse ); + + final uCamPos = pUniformS?.map['cameraPosition']; + + if ( uCamPos != null ) { + uCamPos.setValue( _gl, _vector3.setFromMatrixPosition( camera.matrixWorld ) ); + } + + if ( capabilities.logarithmicDepthBuffer ) { + pUniformS?.setValue( _gl, 'logDepthBufFC', 2.0 / ( math.log( camera.far + 1.0 ) / math.ln2 ) ); + } + + // consider moving isOrthographic to UniformLib and WebGLMaterials, see https://github.com/mrdoob/three.js/pull/26467#issuecomment-1645185067 + + if ( material is MeshPhongMaterial || + material is MeshToonMaterial || + material is MeshLambertMaterial || + material is MeshBasicMaterial || + material is MeshStandardMaterial || + material is ShaderMaterial ) { + pUniformS?.setValue( _gl, 'isOrthographic', camera is OrthographicCamera); + } + + if ( _currentCamera != camera ) { + _currentCamera = camera; + + // lighting uniforms depend on the camera so enforce an update + // now, in case this material supports lights - or later, when + // the next material that does gets activated: + + refreshMaterial = true; // set to true on material change + refreshLights = true; // remains set until update done + } + } + + // skinning and morph target uniforms must be set even if material didn't change + // auto-setting of texture unit for bone and morph texture must go before other textures + // otherwise textures used for skinning and morphing can take over texture units reserved for other material textures + + if ( object is SkinnedMesh ) { + pUniformS?.setOptional( _gl, object, 'bindMatrix' ); + pUniformS?.setOptional( _gl, object, 'bindMatrixInverse' ); + + final skeleton = object.skeleton; + if ( skeleton != null) { + if ( skeleton.boneTexture == null ) skeleton.computeBoneTexture(); + pUniformS?.setValue( _gl, 'boneTexture', skeleton.boneTexture, textures ); + } + } + + if ( object is BatchedMesh ) { + pUniformS?.setOptional( _gl, object, 'batchingTexture' ); + pUniformS?.setValue( _gl, 'batchingTexture', object.matricesTexture, textures ); + + pUniformS?.setOptional( _gl, object, 'batchingIdTexture' ); + pUniformS?.setValue( _gl, 'batchingIdTexture', object.indirectTexture, textures ); + + pUniformS?.setOptional( _gl, object, 'batchingColorTexture' ); + if ( object.colorsTexture != null ) { + pUniformS?.setValue( _gl, 'batchingColorTexture', object.colorsTexture, textures ); + } + } + + final morphAttributes = geometry?.morphAttributes; + + if ( morphAttributes?['position'] != null || morphAttributes?['normal'] != null || ( morphAttributes?['color'] != null ) ) { + morphtargets.update( object, geometry!, program! ); + } + + if ( refreshMaterial || materialProperties['receiveShadow'] != object.receiveShadow ) { + materialProperties['receiveShadow'] = object.receiveShadow; + pUniformS?.setValue( _gl, 'receiveShadow', object.receiveShadow ); + } + + // https://github.com/mrdoob/three.js/pull/24467#issuecomment-1209031512 + + if ( material is MeshGouraudMaterial && material.envMap != null ) { + mUniformS['envMap']['value'] = envMap; + mUniformS['flipEnvMap']['value'] = ( envMap is CubeTexture && envMap.isRenderTargetTexture == false ) ? - 1 : 1; + } + + if ( material is MeshStandardMaterial && material.envMap == null && scene.environment != null ) { + mUniformS['envMapIntensity']['value'] = scene.environmentIntensity; + } + + if ( refreshMaterial ) { + pUniformS?.setValue( _gl, 'toneMappingExposure', toneMappingExposure ); + if ( materialProperties['needsLights'] == true) { + markUniformsLightsNeedsUpdate( mUniformS, refreshLights ); + } + + // refresh uniforms common to several materials + + if (fog != null && material.fog == true ) { + materials.refreshFogUniforms( mUniformS, fog ); + } + + materials.refreshMaterialUniforms( mUniformS, material, _pixelRatio, _height, currentRenderState?.state.transmissionRenderTarget[ camera.id ] ); + AngleUniforms.upload( _gl, getUniformList( materialProperties ), mUniformS, textures ); + } + + if ( material is ShaderMaterial && material.uniformsNeedUpdate == true ) { + AngleUniforms.upload( _gl, getUniformList( materialProperties ), mUniformS, textures ); + material.uniformsNeedUpdate = false; + } + + if ( material is SpriteMaterial ) { + pUniformS?.setValue( _gl, 'center', (object as Sprite).center ); + } + + // common matrices + + pUniformS?.setValue( _gl, 'modelViewMatrix', object.modelViewMatrix ); + pUniformS?.setValue( _gl, 'normalMatrix', object.normalMatrix ); + pUniformS?.setValue( _gl, 'modelMatrix', object.matrixWorld ); + + // UBOs + + if ( material is ShaderMaterial || material is RawShaderMaterial ) { + late final List groups; + if ( material is ShaderMaterial) { + groups = material.uniformsGroups; + } + else if(material is RawShaderMaterial){ + groups = material.uniformsGroups; + } + + for ( int i = 0, l = groups.length; i < l; i ++ ) { + final group = groups[i]; + uniformsGroups.update( group, program ); + uniformsGroups.bind( group, program ); + } + } + + return program!; + } + + void markUniformsLightsNeedsUpdate(Map uniforms, dynamic value) { + uniforms["ambientLightColor"]["needsUpdate"] = value; + uniforms["lightProbe"]["needsUpdate"] = value; + uniforms["directionalLights"]["needsUpdate"] = value; + uniforms["directionalLightShadows"]["needsUpdate"] = value; + uniforms["pointLights"]["needsUpdate"] = value; + uniforms["pointLightShadows"]["needsUpdate"] = value; + uniforms["spotLights"]["needsUpdate"] = value; + uniforms["spotLightShadows"]["needsUpdate"] = value; + uniforms["rectAreaLights"]["needsUpdate"] = value; + uniforms["hemisphereLights"]["needsUpdate"] = value; + } + + bool materialNeedsLights(Material material) { + return material is MeshLambertMaterial || + material is MeshToonMaterial || + material is MeshPhongMaterial || + material is MeshStandardMaterial || + material is ShadowMaterial || + (material is ShaderMaterial && material.lights == true); + } + + int getActiveCubeFace() { + return _currentActiveCubeFace; + } + + int getActiveMipmapLevel() { + return _currentActiveMipmapLevel; + } + + @override + RenderTarget? getRenderTarget() { + return _currentRenderTarget; + } + + void setRenderTargetTextures(RenderTarget renderTarget, colorTexture, depthTexture) { + properties.get(renderTarget.texture)["__webglTexture"] = colorTexture; + properties.get(renderTarget.depthTexture)["__webglTexture"] = depthTexture; + + final renderTargetProperties = properties.get(renderTarget); + renderTargetProperties["__hasExternalTextures"] = true; + + //if (renderTargetProperties["__hasExternalTextures"] == true) { + renderTargetProperties["__autoAllocateDepthBuffer"] = depthTexture == null; + + if (!(renderTargetProperties["__autoAllocateDepthBuffer"] == true)) { + if (extensions.has('WEBGL_multisampled_render_to_texture') == true) { + console.warning('WebGLRenderer: extension was disabled because an external texture was provided'); + renderTargetProperties['__useRenderToTexture'] = false; + } + } + //} + } + + void setRenderTargetFramebuffer(AngleRenderTarget renderTarget, Framebuffer? defaultFramebuffer) { + final renderTargetProperties = properties.get(renderTarget); + renderTargetProperties["__webglFramebuffer"] = defaultFramebuffer; + renderTargetProperties["__useDefaultFramebuffer"] = defaultFramebuffer == null; + } + + @override + void setRenderTarget(RenderTarget? renderTarget, [int activeCubeFace = 0, int activeMipmapLevel = 0]) { + renderTarget as AngleRenderTarget?; + _currentRenderTarget = renderTarget; + _currentActiveCubeFace = activeCubeFace; + _currentActiveMipmapLevel = activeMipmapLevel; + + bool useDefaultFramebuffer = true; + Framebuffer? framebuffer; + bool isCube = false; + bool isRenderTarget3D = false; + + if (renderTarget != null) { + final renderTargetProperties = properties.get(renderTarget); + + if (renderTargetProperties["__useDefaultFramebuffer"] != null) { + // We need to make sure to rebind the framebuffer. + state.bindFramebuffer(WebGL.FRAMEBUFFER, null); + useDefaultFramebuffer = false; + } + else if (renderTargetProperties["__webglFramebuffer"] == null) { + textures.setupRenderTarget(renderTarget); + } + else if (renderTargetProperties["__hasExternalTextures"] == true) { + // Color and depth texture must be rebound in order for the swapchain to update. + textures.rebindTextures(renderTarget, properties.get(renderTarget.texture)["__webglTexture"],properties.get(renderTarget.depthTexture)["__webglTexture"]); + }else if ( renderTarget.depthBuffer ) { + // check if the depth texture is already bound to the frame buffer and that it's been initialized + final depthTexture = renderTarget.depthTexture; + if ( renderTargetProperties['__boundDepthTexture'] != depthTexture ) { + + // check if the depth texture is compatible + if ( + depthTexture != null && + properties.has( depthTexture ) && + ( renderTarget.width != depthTexture.image.width || renderTarget.height != depthTexture.image.height ) + ) { + throw( 'WebGLRenderTarget: Attached DepthTexture is initialized to the incorrect size.' ); + } + + // Swap the depth buffer to the currently attached one + textures.setupDepthRenderbuffer( renderTarget ); + } + } + + final texture = renderTarget.texture; + + if (texture is Data3DTexture || texture is DataArrayTexture || texture is CompressedArrayTexture) { + isRenderTarget3D = true; + } + + final webglFramebuffer = properties.get(renderTarget)["__webglFramebuffer"]; + + if (renderTarget is CubeRenderTarget) { + if (webglFramebuffer[ activeCubeFace ] is List) { + framebuffer = webglFramebuffer[ activeCubeFace ][ activeMipmapLevel ]; + } + else { + framebuffer = webglFramebuffer[ activeCubeFace ]; + } + isCube = true; + } + else if ((renderTarget.samples > 0) && textures.useMultisampledRTT(renderTarget) == false) { + framebuffer = properties.get(renderTarget)["__webglMultisampledFramebuffer"]; + } + else { + if (webglFramebuffer is List) { + framebuffer = webglFramebuffer[ activeMipmapLevel ]; + } else { + framebuffer = webglFramebuffer; + } + } + + _currentViewport.setFrom(renderTarget.viewport); + _currentScissor.setFrom(renderTarget.scissor); + _currentScissorTest = renderTarget.scissorTest; + } + else { + _currentViewport.setFrom(_viewport).scale(_pixelRatio).floor(); + _currentScissor.setFrom(_scissor).scale(_pixelRatio).floor(); + _currentScissorTest = _scissorTest; + } + + // Use a scratch frame buffer if rendering to a mip level to avoid depth buffers + // being bound that are different sizes. + if ( activeMipmapLevel != 0 ) { + framebuffer = _scratchFrameBuffer; + } + + final framebufferBound = state.bindFramebuffer(WebGL.FRAMEBUFFER, framebuffer); + + if (framebufferBound && capabilities.drawBuffers && useDefaultFramebuffer) { + state.drawBuffers(renderTarget, framebuffer); + } + + state.viewport(_currentViewport); + state.scissor(_currentScissor); + state.setScissorTest(_currentScissorTest!); + + if (isCube) { + final textureProperties = properties.get(renderTarget!.texture); + _gl.framebufferTexture2D(WebGL.FRAMEBUFFER, WebGL.COLOR_ATTACHMENT0, WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + activeCubeFace, textureProperties["__webglTexture"], activeMipmapLevel); + } + else if (isRenderTarget3D) { + final textureProperties = properties.get(renderTarget!.texture); + final layer = activeCubeFace; + _gl.framebufferTextureLayer( WebGL.FRAMEBUFFER, WebGL.COLOR_ATTACHMENT0, textureProperties["__webglTexture"], activeMipmapLevel, layer); + } + else if ( renderTarget != null && activeMipmapLevel != 0 ) { + // Only bind the frame buffer if we are using a scratch frame buffer to render to a mipmap. + // If we rebind the texture when using a multi sample buffer then an error about inconsistent samples will be thrown. + final textureProperties = properties.get( renderTarget.texture ); + _gl.framebufferTexture2D( WebGL.FRAMEBUFFER, WebGL.COLOR_ATTACHMENT0, WebGL.TEXTURE_2D, textureProperties['__webglTexture'], activeMipmapLevel ); + } + + _currentMaterialId = -1; // reset current material to ensure correct uniform bindings + } + + void readRenderTargetPixels(AngleRenderTarget renderTarget, int x, int y, int width, int height, TypedData buffer, [int? activeCubeFaceIndex]) { + dynamic framebuffer = properties.get(renderTarget)["__webglFramebuffer"]; //can be Map or int + + if (renderTarget is CubeRenderTarget && activeCubeFaceIndex != null) { + framebuffer = framebuffer?[activeCubeFaceIndex]; + } + + if (framebuffer != null) { + state.bindFramebuffer(WebGL.FRAMEBUFFER, framebuffer); + + try { + final texture = renderTarget.texture; + final textureFormat = texture.format; + final textureType = texture.type; + + if (textureFormat != RGBAFormat && + utils.convert(textureFormat) != _gl.getParameter(WebGL.IMPLEMENTATION_COLOR_READ_FORMAT)) { + console.warning('WebGLRenderer.readRenderTargetPixels: renderTarget is not in RGBA or implementation defined format.'); + return; + } + + final halfFloatSupportedByExt = textureType == HalfFloatType && + (extensions.has('EXT_color_buffer_half_float') || + (capabilities.isWebGL2 && extensions.has('EXT_color_buffer_float'))); + + if (textureType != UnsignedByteType && + (kIsWeb && utils.convert(textureType) != _gl.getParameter(WebGL.IMPLEMENTATION_COLOR_READ_TYPE)) && // IE11, Edge and Chrome Mac < 52 (#9513) + !(textureType == FloatType && + (capabilities.isWebGL2 || + extensions.get('OES_texture_float') || + extensions.get('WEBGL_color_buffer_float'))) && // Chrome Mac >= 52 and Firefox + !halfFloatSupportedByExt) { + console.warning('WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.'); + return; + } + // the following if statement ensures valid read requests (no out-of-bounds pixels, see #8604) + + if ((x >= 0 && x <= (renderTarget.width - width)) && (y >= 0 && y <= (renderTarget.height - height))) { + _gl.readPixels(x, y, width, height, utils.convert(textureFormat), utils.convert(textureType), buffer); + } + } finally { + final framebuffer = (_currentRenderTarget != null) ? properties.get(_currentRenderTarget)["__webglFramebuffer"] : null; + state.bindFramebuffer(WebGL.FRAMEBUFFER, framebuffer); + } + } + } + + void copyFramebufferToTexture(Vector? position, Texture? texture, {int level = 0}) { + //console.warning('copyFramebufferToTexture not supported'); + if (texture is! FramebufferTexture) { + console.warning('WebGLRenderer: copyFramebufferToTexture() can only be used with FramebufferTexture.'); + return; + } + + final levelScale = math.pow(2, -level); + final width = (texture.image.width * levelScale).floor(); + final height = (texture.image.height * levelScale).floor(); + + final x = position != null && !position.x.isNaN ? position.x.toInt() : 0; + final y = position != null && !position.y.isNaN ? position.y.toInt() : 0; + + textures.setTexture2D(texture, 0); + _gl.copyTexSubImage2D(WebGL.TEXTURE_2D, level, 0, 0, x, y, width, height); + state.unbindTexture(WebGLTexture(WebGL.TEXTURE_2D)); + } + + void copyTextureToTexture(Texture srcTexture, Texture dstTexture, {srcRegion, dstPosition, int srcLevel = 0, dstLevel}) { + if ( dstLevel == null ) { + if ( srcLevel != 0 ) { + dstLevel = srcLevel; + srcLevel = 0; + } + else { + dstLevel = 0; + } + } + + // gather the necessary dimensions to copy + int width, height, depth, minX, minY, minZ; + int dstX, dstY, dstZ; + final image = srcTexture is CompressedTexture ? srcTexture.mipmaps[ dstLevel ] : srcTexture.image; + if ( srcRegion != null ) { + width = srcRegion.max.x - srcRegion.min.x; + height = srcRegion.max.y - srcRegion.min.y; + depth = srcRegion is BoundingBox ? (srcRegion.max.z - srcRegion.min.z).toInt() : 1; + minX = srcRegion.min.x; + minY = srcRegion.min.y; + minZ = srcRegion is BoundingBox ? srcRegion.min.z.toInt() : 0; + } + else { + final levelScale = math.pow( 2, - srcLevel ); + width = ( image.width * levelScale ).floor(); + height = ( image.height * levelScale ).floor(); + if ( srcTexture is DataArrayTexture ) { + depth = image.depth; + } + else if ( srcTexture is Data3DTexture ) { + depth = ( image.depth * levelScale ).floor(); + } + else { + depth = 1; + } + + minX = 0; + minY = 0; + minZ = 0; + } + + if ( dstPosition != null ) { + dstX = dstPosition.x; + dstY = dstPosition.y; + dstZ = dstPosition.z; + } + else { + dstX = 0; + dstY = 0; + dstZ = 0; + } + + // Set up the destination target + final glFormat = utils.convert( dstTexture.format ); + final glType = utils.convert( dstTexture.type ); + int glTarget = 0; + + if ( dstTexture is Data3DTexture ) { + textures.setTexture3D( dstTexture, 0 ); + glTarget = WebGL.TEXTURE_3D; + } + else if ( dstTexture is DataArrayTexture || dstTexture is CompressedArrayTexture ) { + textures.setTexture2DArray( dstTexture, 0 ); + glTarget = WebGL.TEXTURE_2D_ARRAY; + } + else { + textures.setTexture2D( dstTexture, 0 ); + glTarget = WebGL.TEXTURE_2D; + } + // if(kIsWeb){ + // _gl.pixelStorei( WebGL.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY?1:0 ); + // _gl.pixelStorei( WebGL.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha?1:0 ); + // _gl.pixelStorei( WebGL.UNPACK_ALIGNMENT, dstTexture.unpackAlignment ); + // } + + // used for copying data from cpu + final currentUnpackRowLen = _gl.getParameter( WebGL.UNPACK_ROW_LENGTH ); + final currentUnpackImageHeight = _gl.getParameter( WebGL.UNPACK_IMAGE_HEIGHT ); + final currentUnpackSkipPixels = _gl.getParameter( WebGL.UNPACK_SKIP_PIXELS ); + final currentUnpackSkipRows = _gl.getParameter( WebGL.UNPACK_SKIP_ROWS ); + final currentUnpackSkipImages = _gl.getParameter( WebGL.UNPACK_SKIP_IMAGES ); + + _gl.pixelStorei( WebGL.UNPACK_ROW_LENGTH, image.width ); + _gl.pixelStorei( WebGL.UNPACK_IMAGE_HEIGHT, image.height ); + _gl.pixelStorei( WebGL.UNPACK_SKIP_PIXELS, minX ); + _gl.pixelStorei( WebGL.UNPACK_SKIP_ROWS, minY ); + _gl.pixelStorei( WebGL.UNPACK_SKIP_IMAGES, minZ ); + + // set up the src texture + final isSrc3D = srcTexture is DataArrayTexture || srcTexture is Data3DTexture; + final isDst3D = dstTexture is DataArrayTexture || dstTexture is Data3DTexture; + if ( srcTexture.isDepthTexture ) { + + final srcTextureProperties = properties.get( srcTexture ); + final dstTextureProperties = properties.get( dstTexture ); + final srcRenderTargetProperties = properties.get( srcTextureProperties['__renderTarget'] ); + final dstRenderTargetProperties = properties.get( dstTextureProperties['__renderTarget'] ); + state.bindFramebuffer( WebGL.READ_FRAMEBUFFER, srcRenderTargetProperties['__webglFramebuffer'] ); + state.bindFramebuffer( WebGL.DRAW_FRAMEBUFFER, dstRenderTargetProperties['__webglFramebuffer'] ); + + for (int i = 0; i < depth; i ++ ) { + // if the source or destination are a 3d target then a layer needs to be bound + if ( isSrc3D ) { + _gl.framebufferTextureLayer( WebGL.READ_FRAMEBUFFER, WebGL.COLOR_ATTACHMENT0, properties.get( srcTexture )['__webglTexture'], srcLevel, minZ + i ); + _gl.framebufferTextureLayer( WebGL.DRAW_FRAMEBUFFER, WebGL.COLOR_ATTACHMENT0, properties.get( dstTexture )['__webglTexture'], dstLevel, dstZ + i ); + } + + _gl.blitFramebuffer( minX, minY, width, height, dstX, dstY, width, height, WebGL.DEPTH_BUFFER_BIT, WebGL.NEAREST ); + } + + state.bindFramebuffer( WebGL.READ_FRAMEBUFFER, null ); + state.bindFramebuffer( WebGL.DRAW_FRAMEBUFFER, null ); + + } + else if ( srcLevel != 0 || srcTexture.isRenderTargetTexture || properties.has( srcTexture ) ) { + // get the appropriate frame buffers + final srcTextureProperties = properties.get( srcTexture ); + final dstTextureProperties = properties.get( dstTexture ); + + // bind the frame buffer targets + state.bindFramebuffer( WebGL.READ_FRAMEBUFFER, _srcFramebuffer ); + state.bindFramebuffer( WebGL.DRAW_FRAMEBUFFER, _dstFramebuffer ); + + for (int i = 0; i < depth; i ++ ) { + + // assign the correct layers and mip maps to the frame buffers + if ( isSrc3D ) { + _gl.framebufferTextureLayer( WebGL.READ_FRAMEBUFFER, WebGL.COLOR_ATTACHMENT0, srcTextureProperties['__webglTexture'], srcLevel, minZ + i ); + } + else { + _gl.framebufferTexture2D( WebGL.READ_FRAMEBUFFER, WebGL.COLOR_ATTACHMENT0, WebGL.TEXTURE_2D, srcTextureProperties['__webglTexture'], srcLevel ); + } + + if ( isDst3D ) { + _gl.framebufferTextureLayer( WebGL.DRAW_FRAMEBUFFER, WebGL.COLOR_ATTACHMENT0, dstTextureProperties['__webglTexture'], dstLevel, dstZ + i ); + } + else { + _gl.framebufferTexture2D( WebGL.DRAW_FRAMEBUFFER, WebGL.COLOR_ATTACHMENT0, WebGL.TEXTURE_2D, dstTextureProperties['__webglTexture'], dstLevel ); + } + + // copy the data using the fastest function that can achieve the copy + if ( srcLevel != 0 ) { + _gl.blitFramebuffer( minX, minY, width, height, dstX, dstY, width, height, WebGL.COLOR_BUFFER_BIT, WebGL.NEAREST ); + } else if ( isDst3D ) { + _gl.copyTexSubImage3D( glTarget, dstLevel, dstX, dstY, dstZ + i, minX, minY, width, height ); + } else { + _gl.copyTexSubImage2D( glTarget, dstLevel, dstX, dstY, minX, minY, width, height ); + } + } + + // unbind read, draw buffers + state.bindFramebuffer( WebGL.READ_FRAMEBUFFER, null ); + state.bindFramebuffer( WebGL.DRAW_FRAMEBUFFER, null ); + } + else { + + if ( isDst3D ) { + // copy data into the 3d texture + if ( srcTexture is DataTexture || srcTexture is Data3DTexture ) { + _gl.texSubImage3D( glTarget, dstLevel, dstX, dstY, dstZ, width, height, depth, glFormat, glType, image.data ); + } + else if ( dstTexture is CompressedArrayTexture ) { + _gl.compressedTexSubImage3D( glTarget, dstLevel, dstX, dstY, dstZ, width, height, depth, glFormat, image.data ); + } + else { + _gl.texSubImage3D( glTarget, dstLevel, dstX, dstY, dstZ, width, height, depth, glFormat, glType, image ); + } + } + else { + // copy data into the 2d texture + if ( srcTexture is DataTexture ) { + _gl.texSubImage2D( WebGL.TEXTURE_2D, dstLevel, dstX, dstY, width, height, glFormat, glType, image.data ); + } + else if ( srcTexture.isCompressedTexture ) { + _gl.compressedTexSubImage2D( WebGL.TEXTURE_2D, dstLevel, dstX, dstY, image.width, image.height, glFormat, image.data ); + } + else { + _gl.texSubImage2D( WebGL.TEXTURE_2D, dstLevel, dstX, dstY, width, height, glFormat, glType, image ); + } + } + } + + // reset values + _gl.pixelStorei( WebGL.UNPACK_ROW_LENGTH, currentUnpackRowLen ); + _gl.pixelStorei( WebGL.UNPACK_IMAGE_HEIGHT, currentUnpackImageHeight ); + _gl.pixelStorei( WebGL.UNPACK_SKIP_PIXELS, currentUnpackSkipPixels ); + _gl.pixelStorei( WebGL.UNPACK_SKIP_ROWS, currentUnpackSkipRows ); + _gl.pixelStorei( WebGL.UNPACK_SKIP_IMAGES, currentUnpackSkipImages ); + + // Generate mipmaps only when copying level 0 + if ( dstLevel == 0 && dstTexture.generateMipmaps ) { + _gl.generateMipmap( glTarget ); + } + + state.unbindTexture(); + } + + void copyTextureToTexture3D( + Texture srcTexture, + Texture dstTexture, { + srcRegion, + dstPosition, + int level = 0, + }) { + return copyTextureToTexture( srcTexture, dstTexture, srcRegion: srcRegion, dstPosition: dstPosition, srcLevel: level); + } + + void initRenderTarget( target ) { + if ( properties.get( target )['__webglFramebuffer'] == null ) { + textures.setupRenderTarget( target ); + } + } + + void initTexture(Texture texture) { + if (texture is CubeTexture) { + textures.setTextureCube( texture, 0 ); + } + else if (texture is Data3DTexture ) { + textures.setTexture3D( texture, 0 ); + } + else if ( texture is DataArrayTexture || texture is CompressedArrayTexture ) { + textures.setTexture2DArray( texture, 0 ); + } + else{ + textures.setTexture2D(texture, 0); + } + + state.unbindTexture(); + } + + WebGLTexture getRenderTargetGLTexture(RenderTarget renderTarget) { + final textureProperties = properties.get(renderTarget.texture); + return textureProperties["__webglTexture"]; + } + + void resetState() { + _currentActiveCubeFace = 0; + _currentActiveMipmapLevel = 0; + _currentRenderTarget = null; + + state.reset(); + bindingStates.reset(); + } + + @override + void setOutputColorSpace(String colorSpace ) { + super.setOutputColorSpace(colorSpace); + + final gl = this.getContext(); + gl.drawingBufferColorSpace = colorSpace == DisplayP3ColorSpace ? 'display-p3' : 'srgb'; + gl.unpackColorSpace = ColorManagement.workingColorSpace == LinearDisplayP3ColorSpace ? 'display-p3' : 'srgb'; + } + + void toNormalizedProjectionMatrix(Matrix4 projectionMatrix ) { + final m = projectionMatrix.storage; + + // Convert [-1, 1] to [0, 1] projection matrix + m[ 2 ] = 0.5 * m[ 2 ] + 0.5 * m[ 3 ]; + m[ 6 ] = 0.5 * m[ 6 ] + 0.5 * m[ 7 ]; + m[ 10 ] = 0.5 * m[ 10 ] + 0.5 * m[ 11 ]; + m[ 14 ] = 0.5 * m[ 14 ] + 0.5 * m[ 15 ]; + } + + void toReversedProjectionMatrix(Matrix4 projectionMatrix ) { + final m = projectionMatrix.storage; + final isPerspectiveMatrix = m[ 11 ] == - 1; + + // Reverse [0, 1] projection matrix + if ( isPerspectiveMatrix ) { + m[ 10 ] = - m[ 10 ] - 1; + m[ 14 ] = - m[ 14 ]; + } + else { + m[ 10 ] = - m[ 10 ]; + m[ 14 ] = - m[ 14 ] + 1; + } + } +} diff --git a/packages/three_js_angle_renderer/lib/shaders/index.dart b/packages/three_js_angle_renderer/lib/shaders/index.dart new file mode 100755 index 00000000..89d75dd8 --- /dev/null +++ b/packages/three_js_angle_renderer/lib/shaders/index.dart @@ -0,0 +1,13 @@ +library three_shaders; + +import 'package:three_js_core/three_js_core.dart'; +import 'package:three_js_math/three_js_math.dart'; +import 'shader_chunk/index.dart'; +import 'shader_lib/index.dart'; + +export 'shader_lib/vsm_vert.glsl.dart'; +export 'shader_lib/vsm_frag.glsl.dart'; + +part 'shader_lib.dart'; +part 'uniforms_lib.dart'; +part 'shader_chunk.dart'; diff --git a/packages/three_js_angle_renderer/lib/shaders/mesh_gouraund_material.dart b/packages/three_js_angle_renderer/lib/shaders/mesh_gouraund_material.dart new file mode 100644 index 00000000..a1eb4c84 --- /dev/null +++ b/packages/three_js_angle_renderer/lib/shaders/mesh_gouraund_material.dart @@ -0,0 +1,306 @@ +import "package:three_js_angle/shaders/index.dart"; +import "package:three_js_math/three_js_math.dart"; +import "package:three_js_core/renderers/uniforms_utils.dart"; + +final Map gouraudShader = { + 'name': 'GouraudShader', + + 'uniforms': UniformsUtils.merge([ + uniformsLib['common'], + uniformsLib['specularmap'], + uniformsLib['envmap'], + uniformsLib['aomap'], + uniformsLib['lightmap'], + uniformsLib['emissivemap'], + uniformsLib['fog'], + uniformsLib['lights'], + { + 'emissive': { 'value': Color.fromHex32( 0x000000 )} + } + ]), + + 'vertexShader': /* glsl */''' + + #define GOURAUD + + varying vec3 vLightFront; + varying vec3 vIndirectFront; + + #ifdef DOUBLE_SIDED + varying vec3 vLightBack; + varying vec3 vIndirectBack; + #endif + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + void main() { + + #include + #include + #include + + #include + #include + #include + #include + #include + + #include + #include + #include + #include + #include + #include + + #include + #include + + // inlining legacy + + vec3 diffuse = vec3( 1.0 ); + + vec3 geometryPosition = mvPosition.xyz; + vec3 geometryNormal = normalize( transformedNormal ); + vec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( -mvPosition.xyz ); + + vec3 backGeometryNormal = - geometryNormal; + + vLightFront = vec3( 0.0 ); + vIndirectFront = vec3( 0.0 ); + #ifdef DOUBLE_SIDED + vLightBack = vec3( 0.0 ); + vIndirectBack = vec3( 0.0 ); + #endif + + IncidentLight directLight; + float dotNL; + vec3 directLightColor_Diffuse; + + vIndirectFront += getAmbientLightIrradiance( ambientLightColor ); + + #if defined( USE_LIGHT_PROBES ) + + vIndirectFront += getLightProbeIrradiance( lightProbe, geometryNormal ); + + #endif + + #ifdef DOUBLE_SIDED + + vIndirectBack += getAmbientLightIrradiance( ambientLightColor ); + + #if defined( USE_LIGHT_PROBES ) + + vIndirectBack += getLightProbeIrradiance( lightProbe, backGeometryNormal ); + + #endif + + #endif + + #if NUM_POINT_LIGHTS > 0 + + #pragma unroll_loop_start + for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) { + + getPointLightInfo( pointLights[ i ], geometryPosition, directLight ); + + dotNL = dot( geometryNormal, directLight.direction ); + directLightColor_Diffuse = directLight.color; + + vLightFront += saturate( dotNL ) * directLightColor_Diffuse; + + #ifdef DOUBLE_SIDED + + vLightBack += saturate( - dotNL ) * directLightColor_Diffuse; + + #endif + + } + #pragma unroll_loop_end + + #endif + + #if NUM_SPOT_LIGHTS > 0 + + #pragma unroll_loop_start + for ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) { + + getSpotLightInfo( spotLights[ i ], geometryPosition, directLight ); + + dotNL = dot( geometryNormal, directLight.direction ); + directLightColor_Diffuse = directLight.color; + + vLightFront += saturate( dotNL ) * directLightColor_Diffuse; + + #ifdef DOUBLE_SIDED + + vLightBack += saturate( - dotNL ) * directLightColor_Diffuse; + + #endif + } + #pragma unroll_loop_end + + #endif + + #if NUM_DIR_LIGHTS > 0 + + #pragma unroll_loop_start + for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) { + + getDirectionalLightInfo( directionalLights[ i ], directLight ); + + dotNL = dot( geometryNormal, directLight.direction ); + directLightColor_Diffuse = directLight.color; + + vLightFront += saturate( dotNL ) * directLightColor_Diffuse; + + #ifdef DOUBLE_SIDED + + vLightBack += saturate( - dotNL ) * directLightColor_Diffuse; + + #endif + + } + #pragma unroll_loop_end + + #endif + + #if NUM_HEMI_LIGHTS > 0 + + #pragma unroll_loop_start + for ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) { + + vIndirectFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometryNormal ); + + #ifdef DOUBLE_SIDED + + vIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometryNormal ); + + #endif + + } + #pragma unroll_loop_end + + #endif + + #include + #include + + }''', + + 'fragmentShader': /* glsl */''' + + #define GOURAUD + + uniform vec3 diffuse; + uniform vec3 emissive; + uniform float opacity; + + varying vec3 vLightFront; + varying vec3 vIndirectFront; + + #ifdef DOUBLE_SIDED + varying vec3 vLightBack; + varying vec3 vIndirectBack; + #endif + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + void main() { + + #include + + vec4 diffuseColor = vec4( diffuse, opacity ); + ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) ); + vec3 totalEmissiveRadiance = emissive; + + #include + #include + #include + #include + #include + #include + #include + + // accumulation + + #ifdef DOUBLE_SIDED + + reflectedLight.indirectDiffuse += ( gl_FrontFacing ) ? vIndirectFront : vIndirectBack; + + #else + + reflectedLight.indirectDiffuse += vIndirectFront; + + #endif + + #ifdef USE_LIGHTMAP + + vec4 lightMapTexel = texture2D( lightMap, vLightMapUv ); + vec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity; + reflectedLight.indirectDiffuse += lightMapIrradiance; + + #endif + + reflectedLight.indirectDiffuse *= BRDF_Lambert( diffuseColor.rgb ); + + #ifdef DOUBLE_SIDED + + reflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack; + + #else + + reflectedLight.directDiffuse = vLightFront; + + #endif + + reflectedLight.directDiffuse *= BRDF_Lambert( diffuseColor.rgb ) * getShadowMask(); + + // modulation + + #include + + vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance; + + #include + + #include + #include + #include + #include + #include + #include + + }''' + +}; \ No newline at end of file diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/alphahash_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/alphahash_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/alphahash_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/alphahash_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/alphahash_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/alphahash_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/alphahash_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/alphahash_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/alphamap_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/alphamap_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/alphamap_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/alphamap_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/alphamap_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/alphamap_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/alphamap_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/alphamap_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/alphatest_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/alphatest_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/alphatest_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/alphatest_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/alphatest_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/alphatest_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/alphatest_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/alphatest_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/aomap_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/aomap_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/aomap_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/aomap_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/aomap_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/aomap_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/aomap_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/aomap_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/batching_pars_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/batching_pars_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/batching_pars_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/batching_pars_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/batching_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/batching_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/batching_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/batching_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/begin_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/begin_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/begin_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/begin_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/beginnormal_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/beginnormal_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/beginnormal_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/beginnormal_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/bsdfs.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/bsdfs.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/bsdfs.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/bsdfs.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/bumpmap_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/bumpmap_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/bumpmap_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/bumpmap_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/clearcoat_normal_fragment_begin.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/clearcoat_normal_fragment_begin.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/clearcoat_normal_fragment_begin.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/clearcoat_normal_fragment_begin.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/clearcoat_normal_fragment_maps.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/clearcoat_normal_fragment_maps.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/clearcoat_normal_fragment_maps.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/clearcoat_normal_fragment_maps.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/clearcoat_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/clearcoat_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/clearcoat_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/clearcoat_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/clipping_planes_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/clipping_planes_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/clipping_planes_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/clipping_planes_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/clipping_planes_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/clipping_planes_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/clipping_planes_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/clipping_planes_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/clipping_planes_pars_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/clipping_planes_pars_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/clipping_planes_pars_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/clipping_planes_pars_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/clipping_planes_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/clipping_planes_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/clipping_planes_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/clipping_planes_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/color_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/color_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/color_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/color_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/color_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/color_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/color_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/color_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/color_pars_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/color_pars_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/color_pars_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/color_pars_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/color_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/color_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/color_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/color_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/colorspace_fragment.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/colorspace_fragment.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/colorspace_fragment.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/colorspace_fragment.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/colorspace_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/colorspace_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/colorspace_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/colorspace_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/common.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/common.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/common.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/common.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/cube_uv_reflection_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/cube_uv_reflection_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/cube_uv_reflection_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/cube_uv_reflection_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/default_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/default_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/default_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/default_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/default_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/default_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/default_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/default_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/defaultnormal_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/defaultnormal_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/defaultnormal_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/defaultnormal_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/displacementmap_pars_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/displacementmap_pars_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/displacementmap_pars_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/displacementmap_pars_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/displacementmap_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/displacementmap_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/displacementmap_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/displacementmap_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/dithering_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/dithering_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/dithering_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/dithering_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/dithering_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/dithering_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/dithering_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/dithering_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/emissivemap_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/emissivemap_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/emissivemap_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/emissivemap_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/emissivemap_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/emissivemap_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/emissivemap_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/emissivemap_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/encodings_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/encodings_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/encodings_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/encodings_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/encodings_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/encodings_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/encodings_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/encodings_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/envmap_common_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/envmap_common_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/envmap_common_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/envmap_common_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/envmap_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/envmap_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/envmap_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/envmap_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/envmap_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/envmap_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/envmap_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/envmap_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/envmap_pars_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/envmap_pars_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/envmap_pars_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/envmap_pars_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/envmap_physical_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/envmap_physical_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/envmap_physical_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/envmap_physical_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/envmap_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/envmap_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/envmap_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/envmap_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/fog_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/fog_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/fog_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/fog_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/fog_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/fog_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/fog_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/fog_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/fog_pars_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/fog_pars_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/fog_pars_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/fog_pars_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/fog_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/fog_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/fog_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/fog_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/gradientmap_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/gradientmap_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/gradientmap_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/gradientmap_pars_fragment.glsl.dart diff --git a/packages/three_js_angle_renderer/lib/shaders/shader_chunk/index.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/index.dart new file mode 100755 index 00000000..0528393d --- /dev/null +++ b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/index.dart @@ -0,0 +1,114 @@ +export 'alphahash_fragment.glsl.dart'; +export 'alphahash_pars_fragment.glsl.dart'; +export 'alphamap_fragment.glsl.dart'; +export 'alphamap_pars_fragment.glsl.dart'; +export 'alphatest_fragment.glsl.dart'; +export 'alphatest_pars_fragment.glsl.dart'; +export 'aomap_fragment.glsl.dart'; +export 'aomap_pars_fragment.glsl.dart'; +export 'batching_pars_vertex.glsl.dart'; +export 'batching_vertex.glsl.dart'; +export 'begin_vertex.glsl.dart'; +export 'beginnormal_vertex.glsl.dart'; +export 'bsdfs.glsl.dart'; +export 'bumpmap_pars_fragment.glsl.dart'; +export 'clearcoat_normal_fragment_begin.glsl.dart'; +export 'clearcoat_normal_fragment_maps.glsl.dart'; +export 'clearcoat_pars_fragment.glsl.dart'; +export 'clipping_planes_fragment.glsl.dart'; +export 'clipping_planes_pars_fragment.glsl.dart'; +export 'clipping_planes_pars_vertex.glsl.dart'; +export 'clipping_planes_vertex.glsl.dart'; +export 'color_fragment.glsl.dart'; +export 'color_pars_fragment.glsl.dart'; +export 'color_pars_vertex.glsl.dart'; +export 'color_vertex.glsl.dart'; +export 'colorspace_fragment.dart'; +export 'colorspace_pars_fragment.glsl.dart'; +export 'common.glsl.dart'; +export 'cube_uv_reflection_fragment.glsl.dart'; +export 'default_fragment.glsl.dart'; +export 'default_vertex.glsl.dart'; +export 'defaultnormal_vertex.glsl.dart'; +export 'displacementmap_pars_vertex.glsl.dart'; +export 'displacementmap_vertex.glsl.dart'; +export 'dithering_fragment.glsl.dart'; +export 'dithering_pars_fragment.glsl.dart'; +export 'emissivemap_fragment.glsl.dart'; +export 'emissivemap_pars_fragment.glsl.dart'; +export 'encodings_fragment.glsl.dart'; +export 'encodings_pars_fragment.glsl.dart'; +export 'envmap_common_pars_fragment.glsl.dart'; +export 'envmap_fragment.glsl.dart'; +export 'envmap_pars_fragment.glsl.dart'; +export 'envmap_pars_vertex.glsl.dart'; +export 'envmap_physical_pars_fragment.glsl.dart'; +export 'envmap_vertex.glsl.dart'; +export 'fog_fragment.glsl.dart'; +export 'fog_pars_fragment.glsl.dart'; +export 'fog_pars_vertex.glsl.dart'; +export 'fog_vertex.glsl.dart'; +export 'gradientmap_pars_fragment.glsl.dart'; +export 'iridescence_fragment.glsl.dart'; +export 'iridescence_pars_fragment.glsl.dart'; +export 'lightmap_fragment.glsl.dart'; +export 'lightmap_pars_fragment.glsl.dart'; +export 'lights_fragment_begin.glsl.dart'; +export 'lights_fragment_end.glsl.dart'; +export 'lights_fragment_maps.glsl.dart'; +export 'lights_lambert_fragment.glsl.dart'; +export 'lights_lambert_pars_fragment.glsl.dart'; +export 'lights_lambert_vertex.glsl.dart'; +export 'lights_pars_begin.glsl.dart'; +export 'lights_phong_fragment.glsl.dart'; +export 'lights_phong_pars_fragment.glsl.dart'; +export 'lights_physical_fragment.glsl.dart'; +export 'lights_physical_pars_fragment.glsl.dart'; +export 'lights_toon_fragment.glsl.dart'; +export 'lights_toon_pars_fragment.glsl.dart'; +export 'logdepthbuf_fragment.glsl.dart'; +export 'logdepthbuf_pars_fragment.glsl.dart'; +export 'logdepthbuf_pars_vertex.glsl.dart'; +export 'logdepthbuf_vertex.glsl.dart'; +export 'map_fragment.glsl.dart'; +export 'map_pars_fragment.glsl.dart'; +export 'map_particle_fragment.glsl.dart'; +export 'map_particle_pars_fragment.glsl.dart'; +export 'metalnessmap_fragment.glsl.dart'; +export 'metalnessmap_pars_fragment.glsl.dart'; +export 'morphcolor_vertex.glsl.dart'; +export 'morphinstance_vertex.glsl.dart'; +export 'morphnormal_vertex.glsl.dart'; +export 'morphtarget_pars_vertex.glsl.dart'; +export 'morphtarget_vertex.glsl.dart'; +export 'normal_fragment_begin.glsl.dart'; +export 'normal_fragment_maps.glsl.dart'; +export 'normal_pars_fragment.glsl.dart'; +export 'normal_pars_vertex.glsl.dart'; +export 'normal_vertex.glsl.dart'; +export 'normalmap_pars_fragment.glsl.dart'; +export 'opaque_fragment.glsl.dart'; +export 'packing.glsl.dart'; +export 'premultiplied_alpha_fragment.glsl.dart'; +export 'project_vertex.glsl.dart'; +export 'roughnessmap_fragment.glsl.dart'; +export 'roughnessmap_pars_fragment.glsl.dart'; +export 'shadowmap_pars_fragment.glsl.dart'; +export 'shadowmap_pars_vertex.glsl.dart'; +export 'shadowmap_vertex.glsl.dart'; +export 'shadowmask_pars_fragment.glsl.dart'; +export 'skinbase_vertex.glsl.dart'; +export 'skinning_pars_vertex.glsl.dart'; +export 'skinning_vertex.glsl.dart'; +export 'skinnormal_vertex.glsl.dart'; +export 'specularmap_fragment.glsl.dart'; +export 'specularmap_pars_fragment.glsl.dart'; +export 'tonemapping_fragment.glsl.dart'; +export 'tonemapping_pars_fragment.glsl.dart'; +export 'transmission_fragment.glsl.dart'; +export 'transmission_pars_fragment.glsl.dart'; +export 'uv_pars_fragment.glsl.dart'; +export 'uv_pars_vertex.glsl.dart'; +export 'uv_vertex.glsl.dart'; +export 'uv2_vertex.glsl.dart'; +export 'worldpos_vertex.glsl.dart'; diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/iridescence_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/iridescence_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/iridescence_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/iridescence_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/iridescence_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/iridescence_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/iridescence_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/iridescence_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/lightmap_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/lightmap_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/lightmap_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/lightmap_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/lightmap_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/lightmap_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/lightmap_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/lightmap_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/lights_fragment_begin.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/lights_fragment_begin.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/lights_fragment_begin.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/lights_fragment_begin.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/lights_fragment_end.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/lights_fragment_end.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/lights_fragment_end.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/lights_fragment_end.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/lights_fragment_maps.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/lights_fragment_maps.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/lights_fragment_maps.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/lights_fragment_maps.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/lights_lambert_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/lights_lambert_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/lights_lambert_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/lights_lambert_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/lights_lambert_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/lights_lambert_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/lights_lambert_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/lights_lambert_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/lights_lambert_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/lights_lambert_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/lights_lambert_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/lights_lambert_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/lights_pars_begin.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/lights_pars_begin.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/lights_pars_begin.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/lights_pars_begin.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/lights_phong_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/lights_phong_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/lights_phong_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/lights_phong_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/lights_phong_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/lights_phong_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/lights_phong_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/lights_phong_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/lights_physical_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/lights_physical_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/lights_physical_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/lights_physical_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/lights_physical_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/lights_physical_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/lights_physical_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/lights_physical_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/lights_toon_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/lights_toon_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/lights_toon_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/lights_toon_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/lights_toon_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/lights_toon_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/lights_toon_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/lights_toon_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/logdepthbuf_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/logdepthbuf_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/logdepthbuf_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/logdepthbuf_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/logdepthbuf_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/logdepthbuf_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/logdepthbuf_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/logdepthbuf_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/logdepthbuf_pars_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/logdepthbuf_pars_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/logdepthbuf_pars_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/logdepthbuf_pars_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/logdepthbuf_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/logdepthbuf_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/logdepthbuf_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/logdepthbuf_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/map_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/map_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/map_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/map_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/map_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/map_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/map_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/map_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/map_particle_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/map_particle_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/map_particle_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/map_particle_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/map_particle_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/map_particle_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/map_particle_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/map_particle_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/metalnessmap_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/metalnessmap_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/metalnessmap_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/metalnessmap_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/metalnessmap_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/metalnessmap_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/metalnessmap_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/metalnessmap_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/morphcolor_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/morphcolor_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/morphcolor_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/morphcolor_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/morphinstance_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/morphinstance_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/morphinstance_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/morphinstance_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/morphnormal_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/morphnormal_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/morphnormal_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/morphnormal_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/morphtarget_pars_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/morphtarget_pars_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/morphtarget_pars_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/morphtarget_pars_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/morphtarget_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/morphtarget_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/morphtarget_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/morphtarget_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/normal_fragment_begin.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/normal_fragment_begin.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/normal_fragment_begin.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/normal_fragment_begin.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/normal_fragment_maps.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/normal_fragment_maps.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/normal_fragment_maps.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/normal_fragment_maps.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/normal_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/normal_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/normal_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/normal_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/normal_pars_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/normal_pars_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/normal_pars_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/normal_pars_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/normal_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/normal_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/normal_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/normal_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/normalmap_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/normalmap_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/normalmap_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/normalmap_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/opaque_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/opaque_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/opaque_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/opaque_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/output_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/output_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/output_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/output_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/packing.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/packing.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/packing.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/packing.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/premultiplied_alpha_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/premultiplied_alpha_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/premultiplied_alpha_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/premultiplied_alpha_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/project_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/project_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/project_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/project_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/roughnessmap_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/roughnessmap_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/roughnessmap_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/roughnessmap_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/roughnessmap_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/roughnessmap_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/roughnessmap_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/roughnessmap_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/shadowmap_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/shadowmap_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/shadowmap_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/shadowmap_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/shadowmap_pars_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/shadowmap_pars_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/shadowmap_pars_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/shadowmap_pars_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/shadowmap_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/shadowmap_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/shadowmap_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/shadowmap_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/shadowmask_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/shadowmask_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/shadowmask_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/shadowmask_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/skinbase_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/skinbase_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/skinbase_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/skinbase_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/skinning_pars_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/skinning_pars_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/skinning_pars_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/skinning_pars_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/skinning_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/skinning_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/skinning_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/skinning_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/skinnormal_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/skinnormal_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/skinnormal_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/skinnormal_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/specularmap_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/specularmap_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/specularmap_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/specularmap_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/specularmap_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/specularmap_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/specularmap_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/specularmap_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/tonemapping_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/tonemapping_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/tonemapping_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/tonemapping_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/tonemapping_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/tonemapping_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/tonemapping_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/tonemapping_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/transmission_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/transmission_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/transmission_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/transmission_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/transmission_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/transmission_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/transmission_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/transmission_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/uv2_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/uv2_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/uv2_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/uv2_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/uv2_pars_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/uv2_pars_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/uv2_pars_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/uv2_pars_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/uv2_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/uv2_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/uv2_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/uv2_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/uv_pars_fragment.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/uv_pars_fragment.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/uv_pars_fragment.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/uv_pars_fragment.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/uv_pars_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/uv_pars_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/uv_pars_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/uv_pars_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/uv_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/uv_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/uv_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/uv_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/worldpos_vertex.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/worldpos_vertex.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/worldpos_vertex.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_chunk/worldpos_vertex.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/background_cube_frag.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/background_cube_frag.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/background_cube_frag.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/background_cube_frag.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/background_cube_vert.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/background_cube_vert.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/background_cube_vert.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/background_cube_vert.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/background_frag.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/background_frag.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/background_frag.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/background_frag.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/background_vert.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/background_vert.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/background_vert.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/background_vert.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/cube_frag.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/cube_frag.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/cube_frag.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/cube_frag.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/cube_vert.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/cube_vert.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/cube_vert.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/cube_vert.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/depth_frag.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/depth_frag.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/depth_frag.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/depth_frag.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/depth_vert.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/depth_vert.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/depth_vert.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/depth_vert.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/distanceRGBA_frag.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/distanceRGBA_frag.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/distanceRGBA_frag.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/distanceRGBA_frag.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/distanceRGBA_vert.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/distanceRGBA_vert.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/distanceRGBA_vert.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/distanceRGBA_vert.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/equirect_frag.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/equirect_frag.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/equirect_frag.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/equirect_frag.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/equirect_vert.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/equirect_vert.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/equirect_vert.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/equirect_vert.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/horizontal_blur_shader.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/horizontal_blur_shader.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/horizontal_blur_shader.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/horizontal_blur_shader.dart diff --git a/packages/three_js_angle_renderer/lib/shaders/shader_lib/index.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/index.dart new file mode 100755 index 00000000..e2ba6c02 --- /dev/null +++ b/packages/three_js_angle_renderer/lib/shaders/shader_lib/index.dart @@ -0,0 +1,36 @@ +export 'background_frag.glsl.dart'; +export 'background_vert.glsl.dart'; +export 'background_cube_frag.glsl.dart'; +export 'background_cube_vert.glsl.dart'; +export 'cube_frag.glsl.dart'; +export 'cube_vert.glsl.dart'; +export 'depth_frag.glsl.dart'; +export 'depth_vert.glsl.dart'; +export 'distanceRGBA_frag.glsl.dart'; +export 'distanceRGBA_vert.glsl.dart'; +export 'equirect_frag.glsl.dart'; +export 'equirect_vert.glsl.dart'; +export 'linedashed_frag.glsl.dart'; +export 'linedashed_vert.glsl.dart'; +export 'meshbasic_frag.glsl.dart'; +export 'meshbasic_vert.glsl.dart'; +export 'meshlambert_frag.glsl.dart'; +export 'meshlambert_vert.glsl.dart'; +export 'meshmatcap_frag.glsl.dart'; +export 'meshmatcap_vert.glsl.dart'; +export 'meshphong_frag.glsl.dart'; +export 'meshphong_vert.glsl.dart'; +export 'meshphysical_frag.glsl.dart'; +export 'meshphysical_vert.glsl.dart'; +export 'meshtoon_frag.glsl.dart'; +export 'meshtoon_vert.glsl.dart'; +export 'meshnormal_frag.glsl.dart'; +export 'meshnormal_vert.glsl.dart'; +export 'points_frag.glsl.dart'; +export 'points_vert.glsl.dart'; +export 'shadow_frag.glsl.dart'; +export 'shadow_vert.glsl.dart'; +export 'sprite_frag.glsl.dart'; +export 'sprite_vert.glsl.dart'; +export 'horizontal_blur_shader.dart'; +export 'vertical_blur_shader.dart'; \ No newline at end of file diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/linedashed_frag.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/linedashed_frag.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/linedashed_frag.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/linedashed_frag.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/linedashed_vert.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/linedashed_vert.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/linedashed_vert.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/linedashed_vert.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/meshbasic_frag.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/meshbasic_frag.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/meshbasic_frag.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/meshbasic_frag.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/meshbasic_vert.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/meshbasic_vert.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/meshbasic_vert.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/meshbasic_vert.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/meshlambert_frag.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/meshlambert_frag.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/meshlambert_frag.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/meshlambert_frag.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/meshlambert_vert.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/meshlambert_vert.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/meshlambert_vert.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/meshlambert_vert.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/meshmatcap_frag.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/meshmatcap_frag.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/meshmatcap_frag.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/meshmatcap_frag.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/meshmatcap_vert.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/meshmatcap_vert.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/meshmatcap_vert.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/meshmatcap_vert.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/meshnormal_frag.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/meshnormal_frag.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/meshnormal_frag.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/meshnormal_frag.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/meshnormal_vert.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/meshnormal_vert.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/meshnormal_vert.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/meshnormal_vert.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/meshphong_frag.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/meshphong_frag.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/meshphong_frag.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/meshphong_frag.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/meshphong_vert.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/meshphong_vert.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/meshphong_vert.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/meshphong_vert.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/meshphysical_frag.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/meshphysical_frag.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/meshphysical_frag.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/meshphysical_frag.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/meshphysical_vert.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/meshphysical_vert.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/meshphysical_vert.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/meshphysical_vert.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/meshtoon_frag.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/meshtoon_frag.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/meshtoon_frag.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/meshtoon_frag.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/meshtoon_vert.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/meshtoon_vert.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/meshtoon_vert.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/meshtoon_vert.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/points_frag.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/points_frag.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/points_frag.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/points_frag.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/points_vert.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/points_vert.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/points_vert.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/points_vert.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/shadow_frag.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/shadow_frag.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/shadow_frag.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/shadow_frag.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/shadow_vert.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/shadow_vert.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/shadow_vert.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/shadow_vert.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/sprite_frag.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/sprite_frag.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/sprite_frag.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/sprite_frag.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/sprite_vert.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/sprite_vert.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/sprite_vert.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/sprite_vert.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/vertical_blur_shader.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/vertical_blur_shader.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/vertical_blur_shader.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/vertical_blur_shader.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/vsm_frag.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/vsm_frag.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/vsm_frag.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/vsm_frag.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/vsm_vert.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_lib/vsm_vert.glsl.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/vsm_vert.glsl.dart rename to packages/three_js_angle_renderer/lib/shaders/shader_lib/vsm_vert.glsl.dart diff --git a/packages/three_js_core/lib/renderers/shaders/uniforms_lib.dart b/packages/three_js_angle_renderer/lib/shaders/uniforms_lib.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/uniforms_lib.dart rename to packages/three_js_angle_renderer/lib/shaders/uniforms_lib.dart diff --git a/packages/three_js_angle_renderer/lib/three_js_angle_renderer.dart b/packages/three_js_angle_renderer/lib/three_js_angle_renderer.dart new file mode 100755 index 00000000..df4891be --- /dev/null +++ b/packages/three_js_angle_renderer/lib/three_js_angle_renderer.dart @@ -0,0 +1,8 @@ +library three_js_angle_renderer; + +export 'shaders/index.dart'; +export 'renderers/index.dart'; +export 'shaders/shader_lib/index.dart'; +export 'renderers/pmrem_generator.dart'; +export 'three_viewer.dart'; +export 'materials/hex_tiling_material.dart'; \ No newline at end of file diff --git a/packages/three_js_core/lib/others/three_viewer.dart b/packages/three_js_angle_renderer/lib/three_viewer.dart similarity index 96% rename from packages/three_js_core/lib/others/three_viewer.dart rename to packages/three_js_angle_renderer/lib/three_viewer.dart index 1347f0e0..48b4518f 100644 --- a/packages/three_js_core/lib/others/three_viewer.dart +++ b/packages/three_js_angle_renderer/lib/three_viewer.dart @@ -3,6 +3,7 @@ import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; +import 'package:three_js_angle/renderers/index.dart'; import 'package:three_js_core/others/index.dart'; import 'package:three_js_core/renderers/index.dart'; import 'package:three_js_core/three_js_core.dart' as core; @@ -61,7 +62,7 @@ class Settings{ int clearColor; double clearAlpha; bool antialias; - WebXRManager Function(WebGLRenderer renderer, dynamic gl)? xr; + XRManager Function(AngleRenderer renderer, dynamic gl)? xr; double? screenResolution; bool animate; @@ -91,7 +92,7 @@ class ThreeJS with WidgetsBindingObserver{ this.postProcessor, this.windowResizeUpdate, Size? size, - core.WebGLRenderer? renderer, + AngleRenderer? renderer, this.renderNumber = 0, this.loadingWidget }){ @@ -116,8 +117,8 @@ class ThreeJS with WidgetsBindingObserver{ FlutterAngleTexture? texture; RenderingContext? gl; - core.WebGLRenderTarget? renderTarget; - core.WebGLRenderer? renderer; + AngleRenderTarget? renderTarget; + AngleRenderer? renderer; final core.Clock clock = core.Clock(); late final core.Scene scene; @@ -266,7 +267,7 @@ class ThreeJS with WidgetsBindingObserver{ } void initRenderer() { - WebGLRendererParameters options = WebGLRendererParameters( + AngleRendererParameters options = AngleRendererParameters( width: width, height: height, gl: gl!, @@ -286,7 +287,7 @@ class ThreeJS with WidgetsBindingObserver{ precision: settings.precision, ); - renderer = core.WebGLRenderer(options); + renderer = AngleRenderer(options); renderer!.setPixelRatio(_resolution!); renderer!.setSize(width, height, false); renderer!.alpha = settings.alpha; @@ -307,8 +308,8 @@ class ThreeJS with WidgetsBindingObserver{ renderer!.toneMappingExposure = settings.toneMappingExposure; if(settings.useSourceTexture){ - final core.WebGLRenderTargetOptions pars = core.WebGLRenderTargetOptions(settings.renderOptions); - renderTarget = core.WebGLRenderTarget((width * _resolution!).toInt(), (height * _resolution!).toInt(), pars); + final RenderTargetOptions pars = RenderTargetOptions(settings.renderOptions); + renderTarget = AngleRenderTarget((width * _resolution!).toInt(), (height * _resolution!).toInt(), pars); renderer!.setRenderTarget(renderTarget); sourceTexture = renderer!.getRenderTargetGLTexture(renderTarget!); } diff --git a/packages/three_js_angle_renderer/pubspec.yaml b/packages/three_js_angle_renderer/pubspec.yaml new file mode 100755 index 00000000..c170f090 --- /dev/null +++ b/packages/three_js_angle_renderer/pubspec.yaml @@ -0,0 +1,30 @@ +name: three_js_angle_renderer +description: "This is a renderer for three_js using angle." +version: 0.0.1 +homepage: https://github.com/Knightro63/three_js/tree/main/packages/three_js_angle_renderer + +environment: + sdk: '>=3.5.0 <4.0.0' + flutter: ">=1.17.0" + +dependencies: + flutter: + sdk: flutter + logger: ^2.5.0 + web: ^1.1.1 + three_js_core: ^0.3.0 + three_js_math: ^0.3.0 + flutter_angle: ^0.4.0 + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^5.0.0 + +dependency_overrides: + three_js_math: + path: ../three_js_math + three_js_core: + path: ../three_js_core + flutter_angle: + path: ../../../flutter_angle/flutter_angle \ No newline at end of file diff --git a/packages/three_js_core/lib/cameras/cube_camera.dart b/packages/three_js_core/lib/cameras/cube_camera.dart index 19f5252b..ac4764ee 100755 --- a/packages/three_js_core/lib/cameras/cube_camera.dart +++ b/packages/three_js_core/lib/cameras/cube_camera.dart @@ -31,7 +31,7 @@ import 'perspective_camera.dart'; /// ``` class CubeCamera extends Object3D { /// The destination cube render target. - late WebGLCubeRenderTarget renderTarget; + late CubeRenderTarget renderTarget; late PerspectiveCamera cameraPX; late PerspectiveCamera cameraNX; @@ -88,7 +88,7 @@ class CubeCamera extends Object3D { /// [scene]: The current scene /// /// Call this to update the [renderTarget]. - void update(WebGLRenderer renderer, Object3D scene) { + void update(Renderer renderer, Object3D scene) { if (parent == null) updateMatrixWorld(false); final currentRenderTarget = renderer.getRenderTarget(); diff --git a/packages/three_js_core/lib/core/object_3d.dart b/packages/three_js_core/lib/core/object_3d.dart index 11a696fb..3e260a9c 100755 --- a/packages/three_js_core/lib/core/object_3d.dart +++ b/packages/three_js_core/lib/core/object_3d.dart @@ -4,7 +4,7 @@ import 'package:three_js_core/three_js_core.dart'; import 'package:three_js_math/three_js_math.dart'; typedef OnRender = void Function({ - WebGLRenderer? renderer, + Renderer? renderer, RenderTarget? renderTarget, Object3D? mesh, Scene? scene, @@ -1024,7 +1024,7 @@ class Object3D with EventDispatcher { OnRender? customRender; void onBeforeShadow({ - WebGLRenderer? renderer, + Renderer? renderer, Object3D? scene, Camera? camera, Camera? shadowCamera, @@ -1036,7 +1036,7 @@ class Object3D with EventDispatcher { } void onAfterShadow({ - WebGLRenderer? renderer, + Renderer? renderer, Object3D? scene, Camera? camera, Camera? shadowCamera, diff --git a/packages/three_js_core/lib/materials/index.dart b/packages/three_js_core/lib/materials/index.dart index 9551bb37..eede8a83 100755 --- a/packages/three_js_core/lib/materials/index.dart +++ b/packages/three_js_core/lib/materials/index.dart @@ -20,5 +20,4 @@ export 'mesh_toon_material.dart'; export 'mesh_matcap_material.dart'; export 'shadow_material.dart'; export 'mesh_gouraund_material.dart'; -export 'projected_material.dart'; -export 'hex_tiling_material.dart'; \ No newline at end of file +export 'projected_material.dart'; \ No newline at end of file diff --git a/packages/three_js_core/lib/materials/mesh_gouraund_material.dart b/packages/three_js_core/lib/materials/mesh_gouraund_material.dart index 72edb67c..08d4f688 100644 --- a/packages/three_js_core/lib/materials/mesh_gouraund_material.dart +++ b/packages/three_js_core/lib/materials/mesh_gouraund_material.dart @@ -1,316 +1,13 @@ -import "package:three_js_core/materials/index.dart"; -import "package:three_js_core/renderers/shaders/index.dart"; -import "package:three_js_math/three_js_math.dart"; - -final Map gouraudShader = { - 'name': 'GouraudShader', - - 'uniforms': UniformsUtils.merge([ - uniformsLib['common'], - uniformsLib['specularmap'], - uniformsLib['envmap'], - uniformsLib['aomap'], - uniformsLib['lightmap'], - uniformsLib['emissivemap'], - uniformsLib['fog'], - uniformsLib['lights'], - { - 'emissive': { 'value': Color.fromHex32( 0x000000 )} - } - ]), - - 'vertexShader': /* glsl */''' - - #define GOURAUD - - varying vec3 vLightFront; - varying vec3 vIndirectFront; - - #ifdef DOUBLE_SIDED - varying vec3 vLightBack; - varying vec3 vIndirectBack; - #endif - - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - - void main() { - - #include - #include - #include - - #include - #include - #include - #include - #include - - #include - #include - #include - #include - #include - #include - - #include - #include - - // inlining legacy - - vec3 diffuse = vec3( 1.0 ); - - vec3 geometryPosition = mvPosition.xyz; - vec3 geometryNormal = normalize( transformedNormal ); - vec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( -mvPosition.xyz ); - - vec3 backGeometryNormal = - geometryNormal; - - vLightFront = vec3( 0.0 ); - vIndirectFront = vec3( 0.0 ); - #ifdef DOUBLE_SIDED - vLightBack = vec3( 0.0 ); - vIndirectBack = vec3( 0.0 ); - #endif - - IncidentLight directLight; - float dotNL; - vec3 directLightColor_Diffuse; - - vIndirectFront += getAmbientLightIrradiance( ambientLightColor ); - - #if defined( USE_LIGHT_PROBES ) - - vIndirectFront += getLightProbeIrradiance( lightProbe, geometryNormal ); - - #endif - - #ifdef DOUBLE_SIDED - - vIndirectBack += getAmbientLightIrradiance( ambientLightColor ); - - #if defined( USE_LIGHT_PROBES ) - - vIndirectBack += getLightProbeIrradiance( lightProbe, backGeometryNormal ); - - #endif - - #endif - - #if NUM_POINT_LIGHTS > 0 - - #pragma unroll_loop_start - for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) { - - getPointLightInfo( pointLights[ i ], geometryPosition, directLight ); - - dotNL = dot( geometryNormal, directLight.direction ); - directLightColor_Diffuse = directLight.color; - - vLightFront += saturate( dotNL ) * directLightColor_Diffuse; - - #ifdef DOUBLE_SIDED - - vLightBack += saturate( - dotNL ) * directLightColor_Diffuse; - - #endif - - } - #pragma unroll_loop_end - - #endif - - #if NUM_SPOT_LIGHTS > 0 - - #pragma unroll_loop_start - for ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) { - - getSpotLightInfo( spotLights[ i ], geometryPosition, directLight ); - - dotNL = dot( geometryNormal, directLight.direction ); - directLightColor_Diffuse = directLight.color; - - vLightFront += saturate( dotNL ) * directLightColor_Diffuse; - - #ifdef DOUBLE_SIDED - - vLightBack += saturate( - dotNL ) * directLightColor_Diffuse; - - #endif - } - #pragma unroll_loop_end - - #endif - - #if NUM_DIR_LIGHTS > 0 - - #pragma unroll_loop_start - for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) { - - getDirectionalLightInfo( directionalLights[ i ], directLight ); - - dotNL = dot( geometryNormal, directLight.direction ); - directLightColor_Diffuse = directLight.color; - - vLightFront += saturate( dotNL ) * directLightColor_Diffuse; - - #ifdef DOUBLE_SIDED - - vLightBack += saturate( - dotNL ) * directLightColor_Diffuse; - - #endif - - } - #pragma unroll_loop_end - - #endif - - #if NUM_HEMI_LIGHTS > 0 - - #pragma unroll_loop_start - for ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) { - - vIndirectFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometryNormal ); - - #ifdef DOUBLE_SIDED - - vIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometryNormal ); - - #endif - - } - #pragma unroll_loop_end - - #endif - - #include - #include - - }''', - - 'fragmentShader': /* glsl */''' - - #define GOURAUD - - uniform vec3 diffuse; - uniform vec3 emissive; - uniform float opacity; - - varying vec3 vLightFront; - varying vec3 vIndirectFront; - - #ifdef DOUBLE_SIDED - varying vec3 vLightBack; - varying vec3 vIndirectBack; - #endif - - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - #include - - void main() { - - #include - - vec4 diffuseColor = vec4( diffuse, opacity ); - ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) ); - vec3 totalEmissiveRadiance = emissive; - - #include - #include - #include - #include - #include - #include - #include - - // accumulation - - #ifdef DOUBLE_SIDED - - reflectedLight.indirectDiffuse += ( gl_FrontFacing ) ? vIndirectFront : vIndirectBack; - - #else - - reflectedLight.indirectDiffuse += vIndirectFront; - - #endif - - #ifdef USE_LIGHTMAP - - vec4 lightMapTexel = texture2D( lightMap, vLightMapUv ); - vec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity; - reflectedLight.indirectDiffuse += lightMapIrradiance; - - #endif - - reflectedLight.indirectDiffuse *= BRDF_Lambert( diffuseColor.rgb ); - - #ifdef DOUBLE_SIDED - - reflectedLight.directDiffuse = ( gl_FrontFacing ) ? vLightFront : vLightBack; - - #else - - reflectedLight.directDiffuse = vLightFront; - - #endif - - reflectedLight.directDiffuse *= BRDF_Lambert( diffuseColor.rgb ) * getShadowMask(); - - // modulation - - #include - - vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance; - - #include - - #include - #include - #include - #include - #include - #include - - }''' - -}; +import "package:three_js_core/three_js_core.dart"; class MeshGouraudMaterial extends ShaderMaterial { - MeshGouraudMaterial([Map? parameters]) : super() { + Map gouraudShader; + + MeshGouraudMaterial(this.gouraudShader,[Map? parameters]) : super() { _init(); setValues(parameters); } - MeshGouraudMaterial.fromMap([Map? parameters]) : super() { + MeshGouraudMaterial.fromMap(this.gouraudShader,[Map? parameters]) : super() { _init(); setValuesFromString(parameters); } @@ -400,6 +97,6 @@ class MeshGouraudMaterial extends ShaderMaterial { /// Return a new material with the same parameters as this material. @override MeshGouraudMaterial clone() { - return MeshGouraudMaterial()..copy(this); + return MeshGouraudMaterial(gouraudShader)..copy(this); } } \ No newline at end of file diff --git a/packages/three_js_core/lib/materials/shader_material.dart b/packages/three_js_core/lib/materials/shader_material.dart index e5797eeb..e6e4aea5 100755 --- a/packages/three_js_core/lib/materials/shader_material.dart +++ b/packages/three_js_core/lib/materials/shader_material.dart @@ -1,8 +1,6 @@ import 'dart:convert'; import 'dart:typed_data'; import 'package:three_js_core/three_js_core.dart'; -import '../renderers/shaders/shader_chunk/default_fragment.glsl.dart'; -import '../renderers/shaders/shader_chunk/default_vertex.glsl.dart'; /// A material rendered with custom shaders. A shader is a small program /// written in @@ -109,8 +107,16 @@ class ShaderMaterial extends Material { uniforms = {}; uniformsGroups = []; - vertexShader = defaultVertex; - fragmentShader = defaultFragment; + vertexShader = """ + void main() { + gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); + } + """; + fragmentShader = """ + void main() { + gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 ); + } + """; linewidth = 1; diff --git a/packages/three_js_core/lib/objects/batched_mesh.dart b/packages/three_js_core/lib/objects/batched_mesh.dart index b48020d2..580eed76 100644 --- a/packages/three_js_core/lib/objects/batched_mesh.dart +++ b/packages/three_js_core/lib/objects/batched_mesh.dart @@ -815,7 +815,7 @@ class BatchedMesh extends Mesh { @override OnRender? get onBeforeRender =>({ - WebGLRenderer? renderer, + Renderer? renderer, RenderTarget? renderTarget, Object3D? mesh, Scene? scene, @@ -940,7 +940,7 @@ class BatchedMesh extends Mesh { @override void onBeforeShadow({ - WebGLRenderer? renderer, + Renderer? renderer, Object3D? scene, Camera? camera, Camera? shadowCamera, diff --git a/packages/three_js_core/lib/others/index.dart b/packages/three_js_core/lib/others/index.dart index 943589ca..7169184a 100755 --- a/packages/three_js_core/lib/others/index.dart +++ b/packages/three_js_core/lib/others/index.dart @@ -1,4 +1,3 @@ export 'console.dart'; export 'peripherals.dart'; -export 'weak_map.dart'; -export 'three_viewer.dart'; \ No newline at end of file +export 'weak_map.dart'; \ No newline at end of file diff --git a/packages/three_js_core/lib/renderers/cube_render_target.dart b/packages/three_js_core/lib/renderers/cube_render_target.dart new file mode 100755 index 00000000..4037c14b --- /dev/null +++ b/packages/three_js_core/lib/renderers/cube_render_target.dart @@ -0,0 +1,7 @@ +import 'package:three_js_core/three_js_core.dart'; + +abstract class CubeRenderTarget extends RenderTarget { + CubeRenderTarget([int size = 1, RenderTargetOptions? options]) : super(size, size, options); + CubeRenderTarget fromEquirectangularTexture(Renderer renderer, Texture texture); + void clear(Renderer renderer, [bool color = true, bool depth = true, bool stencil = true]); +} \ No newline at end of file diff --git a/packages/three_js_core/lib/renderers/index.dart b/packages/three_js_core/lib/renderers/index.dart old mode 100755 new mode 100644 index bbbadb6f..d746515d --- a/packages/three_js_core/lib/renderers/index.dart +++ b/packages/three_js_core/lib/renderers/index.dart @@ -1,29 +1,6 @@ -library three_renderers; +export 'renderer.dart'; +export 'xr_manager.dart'; +export 'render_target.dart'; +export 'cube_render_target.dart'; +export 'uniforms_utils.dart'; -import 'dart:math' as math; -import 'dart:typed_data'; - -import 'package:flutter/foundation.dart'; -import 'package:flutter_angle/flutter_angle.dart'; -import '../cameras/index.dart'; -import '../others/index.dart'; -import '../core/index.dart'; -import '../geometries/index.dart'; -import '../materials/index.dart'; -import 'package:three_js_math/three_js_math.dart'; -import '../objects/index.dart'; -import '../scenes/index.dart'; -import '../textures/index.dart'; -import '../renderers/webgl/index.dart'; -import '../renderers/shaders/index.dart'; -import '../math/frustum.dart'; -import '../lights/index.dart'; - -part 'web_gl_cube_render_target.dart'; -part 'web_gl_renderer.dart'; -part 'web_gl_render_target.dart'; -// part 'web_gl_multisample_render_target.dart'; -// part 'web_gl_multiple_render_targets.dart'; -part 'webxr/web_xr_manager.dart'; -part 'web_gl_3d_render_target.dart'; -part 'web_gl_array_render_target.dart'; diff --git a/packages/three_js_core/lib/renderers/web_gl_render_target.dart b/packages/three_js_core/lib/renderers/render_target.dart old mode 100755 new mode 100644 similarity index 85% rename from packages/three_js_core/lib/renderers/web_gl_render_target.dart rename to packages/three_js_core/lib/renderers/render_target.dart index 0738a865..9a9fae91 --- a/packages/three_js_core/lib/renderers/web_gl_render_target.dart +++ b/packages/three_js_core/lib/renderers/render_target.dart @@ -1,14 +1,9 @@ -/* - In options, we can specify: - * Texture parameters for an auto-generated target texture - * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers -*/ - -part of three_renderers; +import 'package:three_js_core/three_js_core.dart'; +import 'package:three_js_math/three_js_math.dart'; class RenderTarget with EventDispatcher { String? name; - bool _didDispose = false; + late int width; late int height; int depth = 1; @@ -28,7 +23,7 @@ class RenderTarget with EventDispatcher { DepthTexture? _depthTexture; late int _samples; - late WebGLRenderTargetOptions options; + late RenderTargetOptions options; int get samples => _samples; @@ -57,13 +52,13 @@ class RenderTarget with EventDispatcher { DepthTexture? get depthTexture => _depthTexture; - RenderTarget([this.width = 1, this.height = 1, WebGLRenderTargetOptions? options]):super(){ + RenderTarget([this.width = 1, this.height = 1, RenderTargetOptions? options]):super(){ scissor = Vector4(0, 0, width.toDouble(), height.toDouble()); scissorTest = false; viewport = Vector4(0, 0, width.toDouble(), height.toDouble()); - this.options = options ?? WebGLRenderTargetOptions(); + this.options = options ?? RenderTargetOptions(); depth = this.options.depth; final image = ImageElement(width: width, height: height, depth: depth); @@ -178,43 +173,7 @@ class RenderTarget with EventDispatcher { } } -class WebGLRenderTarget extends RenderTarget { - - WebGLRenderTarget(super.width, super.height, [super.options]); - - @override - WebGLRenderTarget clone() { - return WebGLRenderTarget(width, height, options)..copy(this); - } - - @override - WebGLRenderTarget copy(RenderTarget source) { - super.copy(source); - return this; - } - - @override - bool is3D() { - return texture is Data3DTexture || texture is DataArrayTexture; - } - - @override - void dispose() { - if(_didDispose) return; - _didDispose = true; - dispatchEvent(Event(type: "dispose")); - depthTexture?.dispose(); - texture.dispose(); - options.dispose(); - - // textures.forEach((t){ - // t.dispose(); - // }); - // textures.clear(); - } -} - -class WebGLRenderTargetOptions { +class RenderTargetOptions { int? wrapS; int? wrapT; int? wrapR; @@ -250,7 +209,7 @@ class WebGLRenderTargetOptions { depthTexture = null; } - WebGLRenderTargetOptions.create({ + RenderTargetOptions.create({ this.wrapS, this.count = 1, this.resolveDepthBuffer = false, @@ -277,7 +236,7 @@ class WebGLRenderTargetOptions { this.multiview = false }); - WebGLRenderTargetOptions([Map? json]) { + RenderTargetOptions([Map? json]) { json ??= {}; wrapS = json["wrapS"]; count = json['count'] ?? 1; diff --git a/packages/three_js_core/lib/renderers/renderer.dart b/packages/three_js_core/lib/renderers/renderer.dart new file mode 100644 index 00000000..f10c33e7 --- /dev/null +++ b/packages/three_js_core/lib/renderers/renderer.dart @@ -0,0 +1,44 @@ +import 'package:three_js_math/three_js_math.dart'; +import 'xr_manager.dart'; +import '../cameras/camera.dart'; +import '../core/object_3d.dart'; +import 'render_target.dart'; + +enum RenderType{after,before,custom} +enum PowerPreference{high,defaultp,low; + + String get name => _name(); + String _name(){ + if(index == 0){ + return 'high-performance'; + } + else if(index == 2){ + return 'low-power'; + } + else{ + return 'default'; + } + } +} + +enum Precision{highp,mediump,lowp} + +abstract class Renderer { + late XRManager xr; + int toneMapping = NoToneMapping; + double toneMappingExposure = 1.0; + int get coordinateSystem => WebGLCoordinateSystem; + + String _outputColorSpace = SRGBColorSpace; + String get outputColorSpace => _outputColorSpace; + set outputColorSpace(String colorSpace )=>setOutputColorSpace(colorSpace); + + void setOutputColorSpace(String colorSpace ) { + _outputColorSpace = colorSpace; + } + void dispose(); + void clear([bool color = true, bool depth = true, bool stencil = true]); + void render(Object3D scene, Camera camera); + void setRenderTarget(RenderTarget? renderTarget, [int activeCubeFace = 0, int activeMipmapLevel = 0]); + RenderTarget? getRenderTarget(); +} diff --git a/packages/three_js_core/lib/renderers/shaders/uniforms_utils.dart b/packages/three_js_core/lib/renderers/uniforms_utils.dart similarity index 91% rename from packages/three_js_core/lib/renderers/shaders/uniforms_utils.dart rename to packages/three_js_core/lib/renderers/uniforms_utils.dart index 30cd53e4..cc89d7c1 100755 --- a/packages/three_js_core/lib/renderers/shaders/uniforms_utils.dart +++ b/packages/three_js_core/lib/renderers/uniforms_utils.dart @@ -1,4 +1,5 @@ -part of three_shaders; +import 'package:three_js_core/three_js_core.dart'; +import 'package:three_js_math/three_js_math.dart'; List cloneUniformsGroups( src ) { final dst = []; @@ -53,7 +54,7 @@ Map mergeUniforms(uniforms) { return merged; } -String getUnlitUniformColorSpace(WebGLRenderer renderer ) { +String getUnlitUniformColorSpace(Renderer renderer ) { final currentRenderTarget = renderer.getRenderTarget(); if ( currentRenderTarget == null ) { diff --git a/packages/three_js_core/lib/renderers/webxr/web_xr_manager.dart b/packages/three_js_core/lib/renderers/xr_manager.dart similarity index 75% rename from packages/three_js_core/lib/renderers/webxr/web_xr_manager.dart rename to packages/three_js_core/lib/renderers/xr_manager.dart index 379aa9d1..722b2507 100755 --- a/packages/three_js_core/lib/renderers/webxr/web_xr_manager.dart +++ b/packages/three_js_core/lib/renderers/xr_manager.dart @@ -1,15 +1,15 @@ -part of three_renderers; +import 'package:three_js_core/three_js_core.dart'; -class WebXRManager with EventDispatcher { +class XRManager with EventDispatcher { bool enabled = false; bool cameraAutoUpdate = true; - final WebGLRenderer renderer; - RenderingContext gl; + final Renderer renderer; + dynamic gl; bool isPresenting = false; Function? onXRSessionStart; Function? onXRSessionEnd; - WebXRManager(this.renderer, this.gl) : super(); + XRManager(this.renderer, this.gl) : super(); void init(){} void setAnimationLoop ( callback ) { diff --git a/packages/three_js_core/lib/three_js_core.dart b/packages/three_js_core/lib/three_js_core.dart index 8748c4a7..b60b1efd 100755 --- a/packages/three_js_core/lib/three_js_core.dart +++ b/packages/three_js_core/lib/three_js_core.dart @@ -3,15 +3,12 @@ library three_js_core; export 'cameras/index.dart'; export 'core/index.dart'; export 'geometries/index.dart'; -export 'renderers/shaders/index.dart'; export 'lights/index.dart'; export 'materials/index.dart'; export 'objects/index.dart'; -export 'renderers/index.dart'; export 'scenes/index.dart'; export 'textures/index.dart'; export 'others/index.dart'; export 'math/index.dart'; -export 'renderers/shaders/shader_lib/index.dart'; -export 'renderers/pmrem_generator.dart'; -export 'audio/index.dart'; \ No newline at end of file +export 'audio/index.dart'; +export 'renderers/index.dart'; \ No newline at end of file diff --git a/packages/three_js_core/pubspec.yaml b/packages/three_js_core/pubspec.yaml index 0a6308bc..3f760eff 100755 --- a/packages/three_js_core/pubspec.yaml +++ b/packages/three_js_core/pubspec.yaml @@ -13,7 +13,6 @@ dependencies: logger: ^2.5.0 three_js_math: ^0.3.0 web: ^1.1.1 - flutter_angle: ^0.3.9 dev_dependencies: flutter_test: diff --git a/packages/three_js_gpu/lib/common/animation.dart b/packages/three_js_gpu/lib/common/animation.dart index 21137df7..4270b241 100644 --- a/packages/three_js_gpu/lib/common/animation.dart +++ b/packages/three_js_gpu/lib/common/animation.dart @@ -2,11 +2,10 @@ import 'package:three_js_gpu/common/info.dart'; import 'package:three_js_gpu/common/nodes/nodes.dart'; -/** - * This module manages the internal animation loop of the renderer. - * - * @private - */ +/// This module manages the internal animation loop of the renderer. +/// +/// @private +/// class Animation { Nodes nodes; Info info; @@ -14,17 +13,15 @@ class Animation { int? _requestId; XRSession? _context; - /** - * Constructs a new animation loop management component. - * - * @param {Nodes} nodes - Renderer component for managing nodes related logic. - * @param {Info} info - Renderer component for managing metrics and monitoring data. - */ + /// Constructs a new animation loop management component. + /// + /// @param {Nodes} nodes - Renderer component for managing nodes related logic. + /// @param {Info} info - Renderer component for managing metrics and monitoring data. + /// Animation(this.nodes, this.info ); - /** - * Starts the internal animation loop. - */ + /// Starts the internal animation loop. + /// void start() { update( time, xrFrame ) { _requestId = _context.requestAnimationFrame( update ); @@ -45,45 +42,40 @@ class Animation { _requestId = null; } - /** - * Returns the user-level animation loop. - * - * @return {?Function} The animation loop. - */ + /// Returns the user-level animation loop. + /// + /// @return {?Function} The animation loop. + /// Function? getAnimationLoop() { return _animationLoop; } - /** - * Defines the user-level animation loop. - * - * @param {?Function} callback - The animation loop. - */ + /// Defines the user-level animation loop. + /// + /// @param {?Function} callback - The animation loop. + /// void setAnimationLoop( callback ) { _animationLoop = callback; } - /** - * Returns the animation context. - * - * @return {Window|XRSession} The animation context. - */ + /// Returns the animation context. + /// + /// @return {Window|XRSession} The animation context. + /// getContext() { return _context; } - /** - * Defines the context in which `requestAnimationFrame()` is executed. - * - * @param {Window|XRSession} context - The context to set. - */ + /// Defines the context in which `requestAnimationFrame()` is executed. + /// + /// @param {Window|XRSession} context - The context to set. + /// void setContext( context ) { _context = context; } - /** - * Frees all internal resources and stops the animation loop. - */ + /// Frees all internal resources and stops the animation loop. + /// void dispose() { stop(); } diff --git a/packages/three_js_gpu/lib/common/backend.dart b/packages/three_js_gpu/lib/common/backend.dart index b0ebfd30..17ca200e 100644 --- a/packages/three_js_gpu/lib/common/backend.dart +++ b/packages/three_js_gpu/lib/common/backend.dart @@ -12,18 +12,17 @@ import 'package:three_js_math/three_js_math.dart'; Vector2? _vector2; Color? _color4; -/** - * Most of the rendering related logic is implemented in the - * {@link Renderer} module and related management components. - * Sometimes it is required though to execute commands which are - * specific to the current 3D backend (which is WebGPU or WebGL 2). - * This abstract base class defines an interface that encapsulates - * all backend-related logic. Derived classes for each backend must - * implement the interface. - * - * @abstract - * @private - */ +/// Most of the rendering related logic is implemented in the +/// {@link Renderer} module and related management components. +/// Sometimes it is required though to execute commands which are +/// specific to the current 3D backend (which is WebGPU or WebGL 2). +/// This abstract base class defines an interface that encapsulates +/// all backend-related logic. Derived classes for each backend must +/// implement the interface. +/// +/// @abstract +/// @private +/// abstract class Backend { late final Map parameters; final data = WeakMap(); @@ -37,11 +36,10 @@ abstract class Backend { bool trackTimestamp = false; - /** - * Constructs a new backend. - * - * @param {Object} parameters - An object holding parameters for the backend. - */ + /// Constructs a new backend. + /// + /// @param {Object} parameters - An object holding parameters for the backend. + /// Backend(Map? parameters) { this.parameters = parameters ?? {}; trackTimestamp = parameters?['trackTimestamp'] == true; @@ -51,372 +49,344 @@ abstract class Backend { this.renderer = renderer; } - /** - * The coordinate system of the backend. - * - * @abstract - * @type {number} - * @readonly - */ + /// The coordinate system of the backend. + /// + /// @abstract + /// @type {number} + /// @readonly + /// get coordinateSystem; // render context - /** - * This method is executed at the beginning of a render call and - * can be used by the backend to prepare the state for upcoming - * draw calls. - * - * @abstract - * @param {RenderContext} renderContext - The render context. - */ + /// This method is executed at the beginning of a render call and + /// can be used by the backend to prepare the state for upcoming + /// draw calls. + /// + /// @abstract + /// @param {RenderContext} renderContext - The render context. + /// void beginRender() {} - /** - * This method is executed at the end of a render call and - * can be used by the backend to finalize work after draw - * calls. - * - * @abstract - * @param {RenderContext} renderContext - The render context. - */ + /// This method is executed at the end of a render call and + /// can be used by the backend to finalize work after draw + /// calls. + /// + /// @abstract + /// @param {RenderContext} renderContext - The render context. + /// void finishRender() {} - /** - * This method is executed at the beginning of a compute call and - * can be used by the backend to prepare the state for upcoming - * compute tasks. - * - * @abstract - * @param {Node|Array} computeGroup - The compute node(s). - */ + /// This method is executed at the beginning of a compute call and + /// can be used by the backend to prepare the state for upcoming + /// compute tasks. + /// + /// @abstract + /// @param {Node|Array} computeGroup - The compute node(s). + /// void beginCompute() {} - /** - * This method is executed at the end of a compute call and - * can be used by the backend to finalize work after compute - * tasks. - * - * @abstract - * @param {Node|Array} computeGroup - The compute node(s). - */ + /// This method is executed at the beginning of a compute call and + /// can be used by the backend to prepare the state for upcoming + /// compute tasks. + /// + /// @abstract + /// @param {Node|Array} computeGroup - The compute node(s). + /// + void beginCompute() {} + + /// This method is executed at the end of a compute call and + /// can be used by the backend to finalize work after compute + /// tasks. + /// + /// @abstract + /// @param {Node|Array} computeGroup - The compute node(s). + /// void finishCompute( /*computeGroup*/ ) {} // render object - /** - * Executes a draw command for the given render object. - * - * @abstract - * @param {RenderObject} renderObject - The render object to draw. - * @param {Info} info - Holds a series of statistical information about the GPU memory and the rendering process. - */ + /// Executes a draw command for the given render object. + /// + /// @abstract + /// @param {RenderObject} renderObject - The render object to draw. + /// @param {Info} info - Holds a series of statistical information about the GPU memory and the rendering process. + /// void draw( /*renderObject, info*/ ) { } // compute node - /** - * Executes a compute command for the given compute node. - * - * @abstract - * @param {Node|Array} computeGroup - The group of compute nodes of a compute call. Can be a single compute node. - * @param {Node} computeNode - The compute node. - * @param {Array} bindings - The bindings. - * @param {ComputePipeline} computePipeline - The compute pipeline. - */ - compute( /*computeGroup, computeNode, computeBindings, computePipeline*/ ) { } + /// Executes a compute command for the given compute node. + /// + /// @abstract + /// @param {Node|Array} computeGroup - The group of compute nodes of a compute call. Can be a single compute node. + /// @param {Node} computeNode - The compute node. + /// @param {Array} bindings - The bindings. + /// @param {ComputePipeline} computePipeline - The compute pipeline. + /// + void compute( /*computeGroup, computeNode, computeBindings, computePipeline*/ ) { } // program - /** - * Creates a shader program from the given programmable stage. - * - * @abstract - * @param {ProgrammableStage} program - The programmable stage. - */ + /// Creates a shader program from the given programmable stage. + /// + /// @abstract + /// @param {ProgrammableStage} program - The programmable stage. + /// void createProgram(ProgrammableStage program) { } - /** - * Destroys the shader program of the given programmable stage. - * - * @abstract - * @param {ProgrammableStage} program - The programmable stage. - */ + /// Destroys the shader program of the given programmable stage. + /// + /// @abstract + /// @param {ProgrammableStage} program - The programmable stage. + /// void destroyProgram(ProgrammableStage program) { } // bindings - /** - * Creates bindings from the given bind group definition. - * - * @abstract - * @param {BindGroup} bindGroup - The bind group. - * @param {Array} bindings - Array of bind groups. - * @param {number} cacheIndex - The cache index. - * @param {number} version - The version. - */ + /// Creates bindings from the given bind group definition. + /// + /// @abstract + /// @param {BindGroup} bindGroup - The bind group. + /// @param {Array} bindings - Array of bind groups. + /// @param {number} cacheIndex - The cache index. + /// @param {number} version - The version. + /// void createBindings(BindGroup bindGroup, List bindings, int cacheIndex,[int? version ]) { } - /** - * Updates the given bind group definition. - * - * @abstract - * @param {BindGroup} bindGroup - The bind group. - * @param {Array} bindings - Array of bind groups. - * @param {number} cacheIndex - The cache index. - * @param {number} version - The version. - */ - updateBindings( BindGroup bindGroup, List bindings, int cacheIndex, int version ) { } - - /** - * Updates a buffer binding. - * - * @abstract - * @param {Buffer} binding - The buffer binding to update. - */ + /// Updates the given bind group definition. + /// + /// @abstract + /// @param {BindGroup} bindGroup - The bind group. + /// @param {Array} bindings - Array of bind groups. + /// @param {number} cacheIndex - The cache index. + /// @param {number} version - The version. + /// + void updateBindings( BindGroup bindGroup, List bindings, int cacheIndex, int version ) { } + + /// Updates a buffer binding. + /// + /// @abstract + /// @param {Buffer} binding - The buffer binding to update. + /// void updateBinding(Buffer binding ) { } // pipeline - /** - * Creates a render pipeline for the given render object. - * - * @abstract - * @param {RenderObject} renderObject - The render object. - * @param {Array} promises - An array of compilation promises which are used in `compileAsync()`. - */ + /// Creates a render pipeline for the given render object. + /// + /// @abstract + /// @param {RenderObject} renderObject - The render object. + /// @param {Array} promises - An array of compilation promises which are used in `compileAsync()`. + /// void createRenderPipeline(RenderObject renderObject, [List? promises]) { } - /** - * Creates a compute pipeline for the given compute node. - * - * @abstract - * @param {ComputePipeline} computePipeline - The compute pipeline. - * @param {Array} bindings - The bindings. - */ + /// Creates a compute pipeline for the given compute node. + /// + /// @abstract + /// @param {ComputePipeline} computePipeline - The compute pipeline. + /// @param {Array} bindings - The bindings. + /// void createComputePipeline(ComputePipeline computePipeline, List bindings) { } // cache key - /** - * Returns `true` if the render pipeline requires an update. - * - * @abstract - * @param {RenderObject} renderObject - The render object. - * @return {boolean} Whether the render pipeline requires an update or not. - */ + /// Returns `true` if the render pipeline requires an update. + /// + /// @abstract + /// @param {RenderObject} renderObject - The render object. + /// @return {boolean} Whether the render pipeline requires an update or not. + /// bool needsRenderUpdate(RenderObject renderObject); - /** - * Returns a cache key that is used to identify render pipelines. - * - * @abstract - * @param {RenderObject} renderObject - The render object. - * @return {string} The cache key. - */ + /// Returns a cache key that is used to identify render pipelines. + /// + /// @abstract + /// @param {RenderObject} renderObject - The render object. + /// @return {string} The cache key. + /// String getRenderCacheKey(RenderObject renderObject ); // node builder - /** - * Returns a node builder for the given render object. - * - * @abstract - * @param {RenderObject} renderObject - The render object. - * @param {Renderer} renderer - The renderer. - * @return {NodeBuilder} The node builder. - */ + /// Returns a node builder for the given render object. + /// + /// @abstract + /// @param {RenderObject} renderObject - The render object. + /// @param {Renderer} renderer - The renderer. + /// @return {NodeBuilder} The node builder. + /// NodeBuilder createNodeBuilder(RenderObject renderObject, Renderer renderer ) { } // textures - /** - * Creates a GPU sampler for the given texture. - * - * @abstract - * @param {Texture} texture - The texture to create the sampler for. - */ + /// Creates a GPU sampler for the given texture. + /// + /// @abstract + /// @param {Texture} texture - The texture to create the sampler for. + /// void createSampler(Texture texture ); - /** - * Destroys the GPU sampler for the given texture. - * - * @abstract - * @param {Texture} texture - The texture to destroy the sampler for. - */ + /// Destroys the GPU sampler for the given texture. + /// + /// @abstract + /// @param {Texture} texture - The texture to destroy the sampler for. + /// void destroySampler(Texture texture ); - /** - * Creates a default texture for the given texture that can be used - * as a placeholder until the actual texture is ready for usage. - * - * @abstract - * @param {Texture} texture - The texture to create a default texture for. - */ + /// Creates a default texture for the given texture that can be used + /// as a placeholder until the actual texture is ready for usage. + /// + /// @abstract + /// @param {Texture} texture - The texture to create a default texture for. + /// void createDefaultTexture(Texture texture ) { } - /** - * Defines a texture on the GPU for the given texture object. - * - * @abstract - * @param {Texture} texture - The texture. - * @param {Object} [options={}] - Optional configuration parameter. - */ + /// Defines a texture on the GPU for the given texture object. + /// + /// @abstract + /// @param {Texture} texture - The texture. + /// @param {Object} [options={}] - Optional configuration parameter. + /// void createTexture(Texture texture, [Map? options]) { } - /** - * Uploads the updated texture data to the GPU. - * - * @abstract - * @param {Texture} texture - The texture. - * @param {Object} [options={}] - Optional configuration parameter. - */ + /// Uploads the updated texture data to the GPU. + /// + /// @abstract + /// @param {Texture} texture - The texture. + /// @param {Object} [options={}] - Optional configuration parameter. + /// void updateTexture(Texture texture, [Map? options]) { } - /** - * Generates mipmaps for the given texture. - * - * @abstract - * @param {Texture} texture - The texture. - */ + /// Generates mipmaps for the given texture. + /// + /// @abstract + /// @param {Texture} texture - The texture. + /// void generateMipmaps(Texture texture ) { } - /** - * Destroys the GPU data for the given texture object. - * - * @abstract - * @param {Texture} texture - The texture. - */ + /// Destroys the GPU data for the given texture object. + /// + /// @abstract + /// @param {Texture} texture - The texture. + /// void destroyTexture(Texture texture ) { } - /** - * Returns texture data as a typed array. - * - * @abstract - * @async - * @param {Texture} texture - The texture to copy. - * @param {number} x - The x coordinate of the copy origin. - * @param {number} y - The y coordinate of the copy origin. - * @param {number} width - The width of the copy. - * @param {number} height - The height of the copy. - * @param {number} faceIndex - The face index. - * @return {Promise} A Promise that resolves with a typed array when the copy operation has finished. - */ + /// Returns texture data as a typed array. + /// + /// @abstract + /// @async + /// @param {Texture} texture - The texture to copy. + /// @param {number} x - The x coordinate of the copy origin. + /// @param {number} y - The y coordinate of the copy origin. + /// @param {number} width - The width of the copy. + /// @param {number} height - The height of the copy. + /// @param {number} faceIndex - The face index. + /// @return {Promise} A Promise that resolves with a typed array when the copy operation has finished. + /// Future copyTextureToBuffer( Texture texture, int x, int y, int width, int height, int faceIndex ); - /** - * Copies data of the given source texture to the given destination texture. - * - * @abstract - * @param {Texture} srcTexture - The source texture. - * @param {Texture} dstTexture - The destination texture. - * @param {?(Box3|Box2)} [srcRegion=null] - The region of the source texture to copy. - * @param {?(Vector2|Vector3)} [dstPosition=null] - The destination position of the copy. - * @param {number} [srcLevel=0] - The source mip level to copy from. - * @param {number} [dstLevel=0] - The destination mip level to copy to. - */ + /// Copies data of the given source texture to the given destination texture. + /// + /// @abstract + /// @param {Texture} srcTexture - The source texture. + /// @param {Texture} dstTexture - The destination texture. + /// @param {?(Box3|Box2)} [srcRegion=null] - The region of the source texture to copy. + /// @param {?(Vector2|Vector3)} [dstPosition=null] - The destination position of the copy. + /// @param {number} [srcLevel=0] - The source mip level to copy from. + /// @param {number} [dstLevel=0] - The destination mip level to copy to. + /// copyTextureToTexture( /*srcTexture, dstTexture, srcRegion = null, dstPosition = null, srcLevel = 0, dstLevel = 0*/ ) {} - /** - * Copies the current bound framebuffer to the given texture. - * - * @abstract - * @param {Texture} texture - The destination texture. - * @param {RenderContext} renderContext - The render context. - * @param {Vector4} rectangle - A four dimensional vector defining the origin and dimension of the copy. - */ + /// Copies the current bound framebuffer to the given texture. + /// + /// @abstract + /// @param {Texture} texture - The destination texture. + /// @param {RenderContext} renderContext - The render context. + /// @param {Vector4} rectangle - A four dimensional vector defining the origin and dimension of the copy. + /// copyFramebufferToTexture(Texture texture, RenderContext renderContext, Vector4 rectangle) {} // attributes - /** - * Creates the GPU buffer of a shader attribute. - * - * @abstract - * @param {BufferAttribute} attribute - The buffer attribute. - */ + /// Creates the GPU buffer of a shader attribute. + /// + /// @abstract + /// @param {BufferAttribute} attribute - The buffer attribute. + /// createAttribute(BufferAttribute attribute) { } - /** - * Creates the GPU buffer of an indexed shader attribute. - * - * @abstract - * @param {BufferAttribute} attribute - The indexed buffer attribute. - */ + /// Creates the GPU buffer of an indexed shader attribute. + /// + /// @abstract + /// @param {BufferAttribute} attribute - The indexed buffer attribute. + /// createIndexAttribute(BufferAttribute attribute ) { } - /** - * Creates the GPU buffer of a storage attribute. - * - * @abstract - * @param {BufferAttribute} attribute - The buffer attribute. - */ + /// Creates the GPU buffer of a storage attribute. + /// + /// @abstract + /// @param {BufferAttribute} attribute - The buffer attribute. + /// createStorageAttribute( BufferAttribute attribute) { } - /** - * Updates the GPU buffer of a shader attribute. - * - * @abstract - * @param {BufferAttribute} attribute - The buffer attribute to update. - */ + /// Updates the GPU buffer of a shader attribute. + /// + /// @abstract + /// @param {BufferAttribute} attribute - The buffer attribute to update. + /// updateAttribute(BufferAttribute attribute ) { } - /** - * Destroys the GPU buffer of a shader attribute. - * - * @abstract - * @param {BufferAttribute} attribute - The buffer attribute to destroy. - */ + /// Destroys the GPU buffer of a shader attribute. + /// + /// @abstract + /// @param {BufferAttribute} attribute - The buffer attribute to destroy. + /// destroyAttribute(BufferAttribute attribute ) { } // canvas - /** - * Returns the backend's rendering context. - * - * @abstract - * @return {Object} The rendering context. - */ + /// Returns the backend's rendering context. + /// + /// @abstract + /// @return {Object} The rendering context. + /// getContext() { } - /** - * Backends can use this method if they have to run - * logic when the renderer gets resized. - * - * @abstract - */ + /// Backends can use this method if they have to run + /// logic when the renderer gets resized. + /// + /// @abstract + /// updateSize() { } - /** - * Updates the viewport with the values from the given render context. - * - * @abstract - * @param {RenderContext} renderContext - The render context. - */ + /// Updates the viewport with the values from the given render context. + /// + /// @abstract + /// @param {RenderContext} renderContext - The render context. + /// updateViewport( /*renderContext*/ ) {} // utils - /** - * Returns `true` if the given 3D object is fully occluded by other - * 3D objects in the scene. Backends must implement this method by using - * a Occlusion Query API. - * - * @abstract - * @param {RenderContext} renderContext - The render context. - * @param {Object3D} object - The 3D object to test. - * @return {boolean} Whether the 3D object is fully occluded or not. - */ + /// Returns `true` if the given 3D object is fully occluded by other + /// 3D objects in the scene. Backends must implement this method by using + /// a Occlusion Query API. + /// + /// @abstract + /// @param {RenderContext} renderContext - The render context. + /// @param {Object3D} object - The 3D object to test. + /// @return {boolean} Whether the 3D object is fully occluded or not. + /// isOccluded( /*renderContext, object*/ ) {} - /** - * Resolves the time stamp for the given render context and type. - * - * @async - * @abstract - * @param {string} [type='render'] - The type of the time stamp. - * @return {Promise} A Promise that resolves with the time stamp. - */ + /// Resolves the time stamp for the given render context and type. + /// + /// @async + /// @abstract + /// @param {string} [type='render'] - The type of the time stamp. + /// @return {Promise} A Promise that resolves with the time stamp. + /// Future resolveTimestampsAsync([String type = 'render' ]) async{ if (!this.trackTimestamp) { warnOnce( 'WebGPURenderer: Timestamp tracking is disabled.' ); @@ -436,77 +406,70 @@ abstract class Backend { return duration; } - /** - * Can be used to synchronize CPU operations with GPU tasks. So when this method is called, - * the CPU waits for the GPU to complete its operation (e.g. a compute task). - * - * @async - * @abstract - * @return {Promise} A Promise that resolves when synchronization has been finished. - */ + /// Can be used to synchronize CPU operations with GPU tasks. So when this method is called, + /// the CPU waits for the GPU to complete its operation (e.g. a compute task). + /// + /// @async + /// @abstract + /// @return {Promise} A Promise that resolves when synchronization has been finished. + /// Future waitForGPU() async{} - /** - * This method performs a readback operation by moving buffer data from - * a storage buffer attribute from the GPU to the CPU. - * - * @async - * @param {StorageBufferAttribute} attribute - The storage buffer attribute. - * @return {Promise} A promise that resolves with the buffer data when the data are ready. - */ + /// This method performs a readback operation by moving buffer data from + /// a storage buffer attribute from the GPU to the CPU. + /// + /// @async + /// @abstract + /// @param {StorageBufferAttribute} attribute - The storage buffer attribute. + /// @return {Promise} A promise that resolves with the buffer data when the data are ready. + /// Future getArrayBufferAsync( /* attribute */ ); - /** - * Checks if the given feature is supported by the backend. - * - * @async - * @abstract - * @param {string} name - The feature's name. - * @return {Promise} A Promise that resolves with a bool that indicates whether the feature is supported or not. - */ + /// Checks if the given feature is supported by the backend. + /// + /// @async + /// @abstract + /// @param {string} name - The feature's name. + /// @return {Promise} A Promise that resolves with a bool that indicates whether the feature is supported or not. + /// Future hasFeatureAsync(String name); - /** - * Checks if the given feature is supported by the backend. - * - * @abstract - * @param {string} name - The feature's name. - * @return {boolean} Whether the feature is supported or not. - */ + /// Checks if the given feature is supported by the backend. + /// + /// @abstract + /// @param {string} name - The feature's name. + /// @return {boolean} Whether the feature is supported or not. + /// bool hasFeature(String name); - /** - * Returns the maximum anisotropy texture filtering value. - * - * @abstract - * @return {number} The maximum anisotropy texture filtering value. - */ + /// Returns the maximum anisotropy texture filtering value. + /// + /// @abstract + /// @return {number} The maximum anisotropy texture filtering value. + /// double getMaxAnisotropy(); - /** - * Returns the drawing buffer size. - * - * @return {Vector2} The drawing buffer size. - */ + /// Returns the drawing buffer size. + /// + /// @return {Vector2} The drawing buffer size. + /// Vector2 getDrawingBufferSize() { _vector2 = _vector2 ?? new Vector2(); return this.renderer?.getDrawingBufferSize( _vector2 ); } - /** - * Defines the scissor test. - * - * @abstract - * @param {boolean} boolean - Whether the scissor test should be enabled or not. - */ + /// Defines the scissor test. + /// + /// @abstract + /// @param {boolean} boolean - Whether the scissor test should be enabled or not. + /// void setScissorTest( /*boolean*/ ) { } - /** - * Returns the clear color and alpha into a single - * color object. - * - * @return {Color4} The clear color. - */ + /// Returns the clear color and alpha into a single + /// color object. + /// + /// @return {Color4} The clear color. + /// Color? getClearColor() { final renderer = this.renderer; @@ -516,12 +479,11 @@ abstract class Backend { return _color4; } - /** - * Returns the DOM element. If no DOM element exists, the backend - * creates a new one. - * - * @return {HTMLCanvasElement} The DOM element. - */ + /// Returns the DOM element. If no DOM element exists, the backend + /// creates a new one. + /// + /// @return {HTMLCanvasElement} The DOM element. + /// getDomElement() { let domElement = this.domElement; @@ -539,23 +501,21 @@ abstract class Backend { return domElement; } - /** - * Sets a dictionary for the given object into the - * internal data structure. - * - * @param {Object} object - The object. - * @param {Object} value - The dictionary to set. - */ + /// Sets a dictionary for the given object into the + /// internal data structure. + /// + /// @param {Object} object - The object. + /// @param {Object} value - The dictionary to set. + /// set( object, value ) { this.data.set( object, value ); } - /** - * Returns the dictionary for the given object. - * - * @param {Object} object - The object. - * @return {Object} The object's dictionary. - */ + /// Returns the dictionary for the given object. + /// + /// @param {Object} object - The object. + /// @return {Object} The object's dictionary. + /// Map? get( object ) { Map? map = this.data.get( object ); diff --git a/packages/three_js_gpu/lib/common/background.dart b/packages/three_js_gpu/lib/common/background.dart index 77d785b4..badbb776 100644 --- a/packages/three_js_gpu/lib/common/background.dart +++ b/packages/three_js_gpu/lib/common/background.dart @@ -15,16 +15,15 @@ class Background extends DataMap { Background(this.renderer, this.nodes ):super(); - /** - * Updates the background for the given scene. Depending on how `Scene.background` - * or `Scene.backgroundNode` are configured, this method might configure a simple clear - * or add a mesh to the render list for rendering the background as a textured plane - * or skybox. - * - * @param {Scene} scene - The scene. - * @param {RenderList} renderList - The current render list. - * @param {RenderContext} renderContext - The current render context. - */ + /// Updates the background for the given scene. Depending on how `Scene.background` + /// or `Scene.backgroundNode` are configured, this method might configure a simple clear + /// or add a mesh to the render list for rendering the background as a textured plane + /// or skybox. + /// + /// @param {Scene} scene - The scene. + /// @param {RenderList} renderList - The current render list. + /// @param {RenderContext} renderContext - The current render context. + /// void update(Scene scene, RenderList renderList, RenderContext renderContext ) { final renderer = this.renderer; final background = this.nodes.getBackgroundNode( scene ) ?? scene.background; diff --git a/packages/three_js_gpu/lib/common/extras/pmrem_generator.dart b/packages/three_js_gpu/lib/common/extras/pmrem_generator.dart index bc5a64ee..f3b5c151 100755 --- a/packages/three_js_gpu/lib/common/extras/pmrem_generator.dart +++ b/packages/three_js_gpu/lib/common/extras/pmrem_generator.dart @@ -644,18 +644,18 @@ class PMREMGenerator { final CUBEUV_MAX_MIP = float( lodMax ); final materialUniforms = { - n, - latitudinal, - weights, - poleAxis, - outputDirection: _outputDirection, - dTheta, - samples, - envMap, - mipInt, - CUBEUV_TEXEL_WIDTH, - CUBEUV_TEXEL_HEIGHT, - CUBEUV_MAX_MIP + 'n': n, + 'latitudinal': latitudinal, + 'weights': weights, + 'poleAxis': poleAxis, + 'outputDirection': _outputDirection, + 'dTheta': dTheta, + 'samples': samples, + 'envMap': envMap, + 'mipInt': mipInt, + 'CUBEUV_TEXEL_WIDTH': CUBEUV_TEXEL_WIDTH, + 'CUBEUV_TEXEL_HEIGHT': CUBEUV_TEXEL_HEIGHT, + 'CUBEUV_MAX_MIP': CUBEUV_MAX_MIP }; final material = _getMaterial( 'blur' ); diff --git a/packages/three_js_gpu/lib/common/nodes/node_library.dart b/packages/three_js_gpu/lib/common/nodes/node_library.dart index ee317bf7..e75795b4 100644 --- a/packages/three_js_gpu/lib/common/nodes/node_library.dart +++ b/packages/three_js_gpu/lib/common/nodes/node_library.dart @@ -1,13 +1,11 @@ import 'package:three_js_core/three_js_core.dart'; -/** - * The purpose of a node library is to assign node implementations - * to existing library features. In `WebGPURenderer` lights, materials - * which are not based on `NodeMaterial` as well as tone mapping techniques - * are implemented with node-based modules. - * - * @private - */ +/// The purpose of a node library is to assign node implementations +/// to existing library features. In `WebGPURenderer` lights, materials +/// which are not based on `NodeMaterial` as well as tone mapping techniques +/// are implemented with node-based modules. +/// +/// @private class NodeLibrary { WeakMap lightNodes = new WeakMap(); Map materialNodes = new Map(); @@ -15,16 +13,14 @@ class NodeLibrary { NodeLibrary(); - /** - * Returns a matching node material instance for the given material object. - * - * This method also assigns/copies the properties of the given material object - * to the node material. This is done to make sure the current material - * configuration carries over to the node version. - * - * @param {Material} material - A material. - * @return {NodeMaterial} The corresponding node material. - */ + /// Returns a matching node material instance for the given material object. + /// + /// This method also assigns/copies the properties of the given material object + /// to the node material. This is done to make sure the current material + /// configuration carries over to the node version. + /// + /// @param {Material} material - A material. + /// @return {NodeMaterial} The corresponding node material. NodeMaterial fromMaterial(Material material ) { if ( material is NodeMaterial ) return material; @@ -42,12 +38,11 @@ class NodeLibrary { return nodeMaterial; } - /** - * Adds a tone mapping node function for a tone mapping technique (constant). - * - * @param {Function} toneMappingNode - The tone mapping node function. - * @param {number} toneMapping - The tone mapping. - */ + /// Adds a tone mapping node function for a tone mapping technique (constant). + /// + /// @param {Function} toneMappingNode - The tone mapping node function. + /// @param {number} toneMapping - The tone mapping. + /// void addToneMapping(Function toneMappingNode, int toneMapping ) { this.addType( toneMappingNode, toneMapping, this.toneMappingNodes ); } @@ -56,53 +51,47 @@ class NodeLibrary { return this.toneMappingNodes[toneMapping]; } - /** - * Returns a node material class definition for a material type. - * - * @param {string} materialType - The material type. - * @return {?NodeMaterial.constructor} The node material class definition. Returns `null` if no node material is found. - */ + /// Returns a node material class definition for a material type. + /// + /// @param {string} materialType - The material type. + /// @return {?NodeMaterial.constructor} The node material class definition. Returns `null` if no node material is found. Type? getMaterialNodeClass(String materialType ) { return this.materialNodes[materialType]; } - /** - * Adds a node material class definition for a given material type. - * - * @param {NodeMaterial.constructor} materialNodeClass - The node material class definition. - * @param {string} materialClassType - The material type. - */ + /// Adds a node material class definition for a given material type. + /// + /// @param {NodeMaterial.constructor} materialNodeClass - The node material class definition. + /// @param {string} materialClassType - The material type. + /// void addMaterial(Type materialNodeClass,String materialClassType ) { this.addType( materialNodeClass, materialClassType, this.materialNodes ); } - /** - * Returns a light node class definition for a light class definition. - * - * @param {Light.constructor} light - The light class definition. - * @return {?AnalyticLightNode.constructor} The light node class definition. Returns `null` if no light node is found. - */ + /// Returns a light node class definition for a light class definition. + /// + /// @param {Light.constructor} light - The light class definition. + /// @return {?AnalyticLightNode.constructor} The light node class definition. Returns `null` if no light node is found. + /// Type? getLightNodeClass(Type light ) { return this.lightNodes[light]; } - /** - * Adds a light node class definition for a given light class definition. - * - * @param {AnalyticLightNode.constructor} lightNodeClass - The light node class definition. - * @param {Light.constructor} lightClass - The light class definition. - */ + /// Adds a light node class definition for a given light class definition. + /// + /// @param {AnalyticLightNode.constructor} lightNodeClass - The light node class definition. + /// @param {Light.constructor} lightClass - The light class definition. + /// void addLight(Type lightNodeClass, Type lightClass ) { this.addClass( lightNodeClass, lightClass, this.lightNodes ); } - /** - * Adds a node class definition for the given type to the provided type library. - * - * @param {any} nodeClass - The node class definition. - * @param {number|string} type - The object type. - * @param {Map} library - The type library. - */ + /// Adds a node class definition for the given type to the provided type library. + /// + /// @param {any} nodeClass - The node class definition. + /// @param {number|string} type - The object type. + /// @param {Map} library - The type library. + /// void addType(dynamic nodeClass, type, Map library ) { if ( library.containsKey( type ) ) { console.warning( 'Redefinition of node ${ type }' ); @@ -112,16 +101,15 @@ class NodeLibrary { if (nodeClass is! Function ) throw( 'Node class ${ nodeClass.name } is not a class.' ); if (type is Function || typeof type == 'object' ) throw( 'Base class ${ type } is not a class.' ); - library.set( type, nodeClass ); + library[type] = nodeClass; } - /** - * Adds a node class definition for the given class definition to the provided type library. - * - * @param {any} nodeClass - The node class definition. - * @param {any} baseClass - The class definition. - * @param {WeakMap} library - The type library. - */ + /// Adds a node class definition for the given class definition to the provided type library. + /// + /// @param {any} nodeClass - The node class definition. + /// @param {any} baseClass - The class definition. + /// @param {WeakMap} library - The type library. + /// void addClass( nodeClass, baseClass, WeakMap library ) { if ( library.has( baseClass ) ) { console.warning( 'Redefinition of node ${ baseClass.name }' ); diff --git a/packages/three_js_gpu/lib/common/nodes/node_sampled_texture.dart b/packages/three_js_gpu/lib/common/nodes/node_sampled_texture.dart index 063d1d46..a2b10b04 100644 --- a/packages/three_js_gpu/lib/common/nodes/node_sampled_texture.dart +++ b/packages/three_js_gpu/lib/common/nodes/node_sampled_texture.dart @@ -1,24 +1,22 @@ import "package:three_js_gpu/common/sampled_texture.dart"; -/** - * A special form of sampled texture binding type. - * It's texture value is managed by a node object. - * - * @private - * @augments SampledTexture - */ +/// A special form of sampled texture binding type. +/// It's texture value is managed by a node object. +/// +/// @private +/// @augments SampledTexture +/// class NodeSampledTexture extends SampledTexture { TextureNode textureNode; UniformGroupNode groupNode; String? access; - /** - * Constructs a new node-based sampled texture. - * - * @param {string} name - The textures's name. - * @param {TextureNode} textureNode - The texture node. - * @param {UniformGroupNode} groupNode - The uniform group node. - * @param {?string} [access=null] - The access type. - */ + /// Constructs a new node-based sampled texture. + /// + /// @param {string} name - The textures's name. + /// @param {TextureNode} textureNode - The texture node. + /// @param {UniformGroupNode} groupNode - The uniform group node. + /// @param {?string} [access=null] - The access type. + /// NodeSampledTexture(String name, this.textureNode, this.groupNode, [this.access]):super( name, textureNode != null? textureNode.value : null ); bool needsBindingsUpdate(int generation ) { @@ -37,42 +35,38 @@ class NodeSampledTexture extends SampledTexture { } } -/** - * A special form of sampled cube texture binding type. - * It's texture value is managed by a node object. - * - * @private - * @augments NodeSampledTexture - */ +/// A special form of sampled cube texture binding type. +/// It's texture value is managed by a node object. +/// +/// @private +/// @augments NodeSampledTexture +/// class NodeSampledCubeTexture extends NodeSampledTexture { bool isSampledCubeTexture = true; - /** - * Constructs a new node-based sampled cube texture. - * - * @param {string} name - The textures's name. - * @param {TextureNode} textureNode - The texture node. - * @param {UniformGroupNode} groupNode - The uniform group node. - * @param {?string} [access=null] - The access type. - */ + /// Constructs a new node-based sampled cube texture. + /// + /// @param {string} name - The textures's name. + /// @param {TextureNode} textureNode - The texture node. + /// @param {UniformGroupNode} groupNode - The uniform group node. + /// @param {?string} [access=null] - The access type. + /// NodeSampledCubeTexture(super.name, super.textureNode, super.groupNode, [super.access] ); } -/** - * A special form of sampled 3D texture binding type. - * It's texture value is managed by a node object. - * - * @private - * @augments NodeSampledTexture - */ +/// A special form of sampled 3D texture binding type. +/// It's texture value is managed by a node object. +/// +/// @private +/// @augments NodeSampledTexture +/// class NodeSampledTexture3D extends NodeSampledTexture { bool isSampledTexture3D = true; - /** - * Constructs a new node-based sampled 3D texture. - * - * @param {string} name - The textures's name. - * @param {TextureNode} textureNode - The texture node. - * @param {UniformGroupNode} groupNode - The uniform group node. - * @param {?string} [access=null] - The access type. - */ + /// Constructs a new node-based sampled 3D texture. + /// + /// @param {string} name - The textures's name. + /// @param {TextureNode} textureNode - The texture node. + /// @param {UniformGroupNode} groupNode - The uniform group node. + /// @param {?string} [access=null] - The access type. + /// NodeSampledTexture3D(super.name, super.textureNode, super.groupNode, [super.access] ); } \ No newline at end of file diff --git a/packages/three_js_gpu/lib/common/nodes/node_sampler.dart b/packages/three_js_gpu/lib/common/nodes/node_sampler.dart index feb18385..68f5f786 100644 --- a/packages/three_js_gpu/lib/common/nodes/node_sampler.dart +++ b/packages/three_js_gpu/lib/common/nodes/node_sampler.dart @@ -1,26 +1,23 @@ import "package:three_js_gpu/common/sampler.dart"; -/** - * A special form of sampler binding type. - * It's texture value is managed by a node object. - * - * @private - * @augments Sampler - */ +/// A special form of sampler binding type. +/// It's texture value is managed by a node object. +/// +/// @private +/// @augments Sampler +/// class NodeSampler extends Sampler { UniformGroupNode groupNode; - /** - * Constructs a new node-based sampler. - * - * @param {string} name - The samplers's name. - * @param {TextureNode} textureNode - The texture node. - * @param {UniformGroupNode} groupNode - The uniform group node. - */ + /// Constructs a new node-based sampler. + /// + /// @param {string} name - The samplers's name. + /// @param {TextureNode} textureNode - The texture node. + /// @param {UniformGroupNode} groupNode - The uniform group node. + /// NodeSampler(String name, TextureNode? textureNode, this.groupNode ):super( name, textureNode != null? textureNode.value : null ); - /** - * Updates the texture value of this sampler. - */ + /// Updates the texture value of this sampler. + /// void update() { this.texture = this.textureNode.value; } diff --git a/packages/three_js_gpu/lib/common/nodes/node_storage_buffer.dart b/packages/three_js_gpu/lib/common/nodes/node_storage_buffer.dart index 8bcc2c71..0b411de9 100644 --- a/packages/three_js_gpu/lib/common/nodes/node_storage_buffer.dart +++ b/packages/three_js_gpu/lib/common/nodes/node_storage_buffer.dart @@ -3,33 +3,29 @@ import "package:three_js_math/three_js_math.dart"; int _id = 0; -/** - * A special form of storage buffer binding type. - * It's buffer value is managed by a node object. - * - * @private - * @augments StorageBuffer - */ +/// A special form of storage buffer binding type. +/// It's buffer value is managed by a node object. +/// +/// @private +/// @augments StorageBuffer +/// class NodeStorageBuffer extends StorageBuffer { StorageBufferNode nodeUniform; UniformGroupNode groupNode; String access; - /** - * Constructs a new node-based storage buffer. - * - * @param {StorageBufferNode} nodeUniform - The storage buffer node. - * @param {UniformGroupNode} groupNode - The uniform group node. - */ + /// Constructs a new node-based storage buffer. + /// + /// @param {StorageBufferNode} nodeUniform - The storage buffer node. + /// @param {UniformGroupNode} groupNode - The uniform group node. + /// NodeStorageBuffer(this.nodeUniform, groupNode ):super( 'StorageBuffer_${_id ++}', nodeUniform != null? nodeUniform.value : null ){ this.access = nodeUniform != null? nodeUniform.access : NodeAccess.READ_WRITE; } - /** - * The storage buffer. - * - * @type {BufferAttribute} - */ + /// The storage buffer. + /// + /// @type {BufferAttribute} + /// BufferAttribute get buffer => this.nodeUniform.value; - } diff --git a/packages/three_js_gpu/lib/common/nodes/node_uniform.dart b/packages/three_js_gpu/lib/common/nodes/node_uniform.dart index fb0e50f4..5b7895f4 100644 --- a/packages/three_js_gpu/lib/common/nodes/node_uniform.dart +++ b/packages/three_js_gpu/lib/common/nodes/node_uniform.dart @@ -1,13 +1,12 @@ import 'package:three_js_gpu/common/uniform.dart'; import 'package:three_js_math/three_js_math.dart'; -/** - * A special form of Number uniform binding type. - * It's value is managed by a node object. - * - * @private - * @augments NumberUniform - */ +/// A special form of Number uniform binding type. +/// It's value is managed by a node object. +/// +/// @private +/// @augments NumberUniform +/// class NumberNodeUniform extends NumberUniform { NodeUniform nodeUniform; @@ -22,13 +21,12 @@ class NumberNodeUniform extends NumberUniform { } } -/** - * A special form of Vector2 uniform binding type. - * It's value is managed by a node object. - * - * @private - * @augments Vector2Uniform - */ +/// A special form of Vector2 uniform binding type. +/// It's value is managed by a node object. +/// +/// @private +/// @augments Vector2Uniform +/// class Vector2NodeUniform extends Vector2Uniform { NodeUniform nodeUniform; @@ -43,13 +41,12 @@ class Vector2NodeUniform extends Vector2Uniform { } } -/** - * A special form of Vector3 uniform binding type. - * It's value is managed by a node object. - * - * @private - * @augments Vector3Uniform - */ +/// A special form of Vector3 uniform binding type. +/// It's value is managed by a node object. +/// +/// @private +/// @augments Vector3Uniform +/// class Vector3NodeUniform extends Vector3Uniform { NodeUniform nodeUniform; @@ -66,13 +63,12 @@ class Vector3NodeUniform extends Vector3Uniform { } -/** - * A special form of Vector4 uniform binding type. - * It's value is managed by a node object. - * - * @private - * @augments Vector4Uniform - */ +/// A special form of Vector4 uniform binding type. +/// It's value is managed by a node object. +/// +/// @private +/// @augments Vector4Uniform +/// class Vector4NodeUniform extends Vector4Uniform { NodeUniform nodeUniform; @@ -88,13 +84,12 @@ class Vector4NodeUniform extends Vector4Uniform { } -/** - * A special form of Color uniform binding type. - * It's value is managed by a node object. - * - * @private - * @augments ColorUniform - */ +/// A special form of Color uniform binding type. +/// It's value is managed by a node object. +/// +/// @private +/// @augments ColorUniform +/// class ColorNodeUniform extends ColorUniform { NodeUniform nodeUniform; @@ -110,13 +105,12 @@ class ColorNodeUniform extends ColorUniform { } -/** - * A special form of Matrix2 uniform binding type. - * It's value is managed by a node object. - * - * @private - * @augments Matrix2Uniform - */ +/// A special form of Matrix2 uniform binding type. +/// It's value is managed by a node object. +/// +/// @private +/// @augments Matrix2Uniform +/// class Matrix2NodeUniform extends Matrix2Uniform { NodeUniform nodeUniform; @@ -131,13 +125,12 @@ class Matrix2NodeUniform extends Matrix2Uniform { } } -/** - * A special form of Matrix3 uniform binding type. - * It's value is managed by a node object. - * - * @private - * @augments Matrix3Uniform - */ +/// A special form of Matrix3 uniform binding type. +/// It's value is managed by a node object. +/// +/// @private +/// @augments Matrix3Uniform +/// class Matrix3NodeUniform extends Matrix3Uniform { NodeUniform nodeUniform; @@ -152,13 +145,12 @@ class Matrix3NodeUniform extends Matrix3Uniform { } } -/** - * A special form of Matrix4 uniform binding type. - * It's value is managed by a node object. - * - * @private - * @augments Matrix4Uniform - */ +/// A special form of Matrix4 uniform binding type. +/// It's value is managed by a node object. +/// +/// @private +/// @augments Matrix4Uniform +/// class Matrix4NodeUniform extends Matrix4Uniform { NodeUniform nodeUniform; diff --git a/packages/three_js_gpu/lib/common/nodes/node_uniform_buffer.dart b/packages/three_js_gpu/lib/common/nodes/node_uniform_buffer.dart index 63e1ceb4..4f8bd55c 100644 --- a/packages/three_js_gpu/lib/common/nodes/node_uniform_buffer.dart +++ b/packages/three_js_gpu/lib/common/nodes/node_uniform_buffer.dart @@ -3,22 +3,20 @@ import "package:three_js_math/three_js_math.dart"; int _id = 0; -/** - * A special form of uniform buffer binding type. - * It's buffer value is managed by a node object. - * - * @private - * @augments UniformBuffer - */ +/// A special form of uniform buffer binding type. +/// It's buffer value is managed by a node object. +/// +/// @private +/// @augments UniformBuffer +/// class NodeUniformBuffer extends UniformBuffer { BufferNode nodeUniform; UniformGroupNode groupNode; - /** - * Constructs a new node-based uniform buffer. - * - * @param {BufferNode} nodeUniform - The uniform buffer node. - * @param {UniformGroupNode} groupNode - The uniform group node. - */ + /// Constructs a new node-based uniform buffer. + /// + /// @param {BufferNode} nodeUniform - The uniform buffer node. + /// @param {UniformGroupNode} groupNode - The uniform group node. + /// NodeUniformBuffer( this.nodeUniform, this.groupNode ):super( 'UniformBuffer_${_id ++}', nodeUniform != null ? nodeUniform.value : null ); diff --git a/packages/three_js_gpu/lib/gpu_backend.dart b/packages/three_js_gpu/lib/gpu_backend.dart index 0a82189f..6ce15d66 100644 --- a/packages/three_js_gpu/lib/gpu_backend.dart +++ b/packages/three_js_gpu/lib/gpu_backend.dart @@ -1,141 +1,76 @@ import 'package:three_js_gpu/common/backend.dart'; import 'package:three_js_gpu/common/renderer.dart'; -/** - * A backend implementation targeting WebGPU. - * - * @private - * @augments Backend - */ +/// +/// A backend implementation targeting WebGPU. +/// +/// @private +/// @augments Backend +/// class WebGPUBackend extends Backend { bool isWebGPUBackend = true; - - /** - * WebGPUBackend options. - * - * @typedef {Object} WebGPUBackend~Options - * @property {boolean} [logarithmicDepthBuffer=false] - Whether logarithmic depth buffer is enabled or not. - * @property {boolean} [alpha=true] - Whether the default framebuffer (which represents the final contents of the canvas) should be transparent or opaque. - * @property {boolean} [compatibilityMode=false] - Whether the backend should be in compatibility mode or not. - * @property {boolean} [depth=true] - Whether the default framebuffer should have a depth buffer or not. - * @property {boolean} [stencil=false] - Whether the default framebuffer should have a stencil buffer or not. - * @property {boolean} [antialias=false] - Whether MSAA as the default anti-aliasing should be enabled or not. - * @property {number} [samples=0] - When `antialias` is `true`, `4` samples are used by default. Set this parameter to any other integer value than 0 to overwrite the default. - * @property {boolean} [forceWebGL=false] - If set to `true`, the renderer uses a WebGL 2 backend no matter if WebGPU is supported or not. - * @property {boolean} [trackTimestamp=false] - Whether to track timestamps with a Timestamp Query API or not. - * @property {string} [powerPreference=null] - The power preference. - * @property {Object} [requiredLimits=null] - Specifies the limits that are required by the device request. The request will fail if the adapter cannot provide these limits. - * @property {GPUDevice} [device=null] - If there is an existing GPU device on app level, it can be passed to the renderer as a parameter. - * @property {number} [outputType=null] - Texture type for output to canvas. By default, device's preferred format is used; other formats may incur overhead. - */ - - /** - * Constructs a new WebGPU backend. - * - * @param {WebGPUBackend~Options} [parameters] - The configuration parameter. - */ + bool logarithmicDepthBuffer = false; + bool alpha = true; + late bool compatibilityMode = this.parameters['compatibilityMode']; + bool depth = true; + bool stencil = false; + bool antialias = false; + int samples = 0; + bool forceWebGL = false; + bool trackTimestamp = false; + String powerPreference = ''; + Object requiredLimits = {}; + GPUDevice? device; + int outputType = 0; + GPUCanvasContext? context; + Object? defaultRenderPassdescriptor; + GPUTexture? colorBuffer; + GPUTexture? depthBuffer; + GPUTexture? stencilBuffer; + late WebGPUUtils utils = WebGPUUtils(this); + late WebGPUAttributeUtils attributeUtils = WebGPUAttributeUtils(this); + late WebGPUBindingUtils bindingUtils = WebGPUBindingUtils(this); + late WebGPUPipelineUtils pipelineUtils = WebGPUPipelineUtils(this); + late WebGPUTextureUtils textureUtils = WebGPUTextureUtils(this); + Map occludedResolveCache = new Map(); + + /// WebGPUBackend options. + /// + /// @typedef {Object} WebGPUBackend~Options + /// @property {boolean} [logarithmicDepthBuffer=false] - Whether logarithmic depth buffer is enabled or not. + /// @property {boolean} [alpha=true] - Whether the default framebuffer (which represents the final contents of the canvas) should be transparent or opaque. + /// @property {boolean} [compatibilityMode=false] - Whether the backend should be in compatibility mode or not. + /// @property {boolean} [depth=true] - Whether the default framebuffer should have a depth buffer or not. + /// @property {boolean} [stencil=false] - Whether the default framebuffer should have a stencil buffer or not. + /// @property {boolean} [antialias=false] - Whether MSAA as the default anti-aliasing should be enabled or not. + /// @property {number} [samples=0] - When `antialias` is `true`, `4` samples are used by default. Set this parameter to any other integer value than 0 to overwrite the default. + /// @property {boolean} [forceWebGL=false] - If set to `true`, the renderer uses a WebGL 2 backend no matter if WebGPU is supported or not. + /// @property {boolean} [trackTimestamp=false] - Whether to track timestamps with a Timestamp Query API or not. + /// @property {string} [powerPreference=null] - The power preference. + /// @property {Object} [requiredLimits=null] - Specifies the limits that are required by the device request. The request will fail if the adapter cannot provide these limits. + /// @property {GPUDevice} [device=null] - If there is an existing GPU device on app level, it can be passed to the renderer as a parameter. + /// @property {number} [outputType=null] - Texture type for output to canvas. By default, device's preferred format is used; other formats may incur overhead. + + /// Constructs a new WebGPU backend. + /// + /// @param {WebGPUBackend~Options} [parameters] - The configuration parameter. + /// WebGPUBackend(super.parameters) { // some parameters require default values other than "null" - this.parameters.alpha = ( parameters.alpha == null ) ? true : parameters.alpha; - this.parameters.compatibilityMode = ( parameters.compatibilityMode == null ) ? false : parameters.compatibilityMode; - - this.parameters.requiredLimits = ( parameters.requiredLimits == null ) ? {} : parameters.requiredLimits; - - /** - * Indicates whether the backend is in compatibility mode or not. - * @type {boolean} - * @default false - */ - this.compatibilityMode = this.parameters.compatibilityMode; - - /** - * A reference to the device. - * - * @type {?GPUDevice} - * @default null - */ - this.device = null; - - /** - * A reference to the context. - * - * @type {?GPUCanvasContext} - * @default null - */ - this.context = null; - - /** - * A reference to the color attachment of the default framebuffer. - * - * @type {?GPUTexture} - * @default null - */ - this.colorBuffer = null; - - /** - * A reference to the default render pass descriptor. - * - * @type {?Object} - * @default null - */ - this.defaultRenderPassdescriptor = null; - - /** - * A reference to a backend module holding common utility functions. - * - * @type {WebGPUUtils} - */ - this.utils = new WebGPUUtils( this ); - - /** - * A reference to a backend module holding shader attribute-related - * utility functions. - * - * @type {WebGPUAttributeUtils} - */ - this.attributeUtils = new WebGPUAttributeUtils( this ); - - /** - * A reference to a backend module holding shader binding-related - * utility functions. - * - * @type {WebGPUBindingUtils} - */ - this.bindingUtils = new WebGPUBindingUtils( this ); - - /** - * A reference to a backend module holding shader pipeline-related - * utility functions. - * - * @type {WebGPUPipelineUtils} - */ - this.pipelineUtils = new WebGPUPipelineUtils( this ); - - /** - * A reference to a backend module holding shader texture-related - * utility functions. - * - * @type {WebGPUTextureUtils} - */ - this.textureUtils = new WebGPUTextureUtils( this ); - - /** - * A map that manages the resolve buffers for occlusion queries. - * - * @type {Map} - */ - this.occludedResolveCache = new Map(); + this.parameters['alpha'] = ( parameters['alpha'] == null ) ? true : parameters['alpha']; + this.parameters['compatibilityMode'] = ( parameters['compatibilityMode'] == null ) ? false : parameters['compatibilityMode']; + this.parameters['requiredLimits'] = ( parameters['requiredLimits'] == null ) ? {} : parameters['requiredLimits']; } - /** - * Initializes the backend so it is ready for usage. - * - * @async - * @param {Renderer} renderer - The renderer. - * @return {Promise} A Promise that resolves when the backend has been initialized. - */ + /// + /// Initializes the backend so it is ready for usage. + /// + /// @async + /// @param {Renderer} renderer - The renderer. + /// @return {Promise} A Promise that resolves when the backend has been initialized. + /// Future init(Renderer renderer ) async{ await super.init( renderer ); @@ -143,13 +78,13 @@ class WebGPUBackend extends Backend { // create the device if it is not passed with parameters - let device; + GPUDevice? device; if ( parameters.device == null ) { final adapterOptions = { - powerPreference: parameters.powerPreference, - featureLevel: parameters.compatibilityMode ? 'compatibility' : null + 'powerPreference': parameters.powerPreference, + 'featureLevel': parameters.compatibilityMode ? 'compatibility' : null }; final adapter = ( typeof navigator != 'null' ) ? await navigator.gpu.requestAdapter( adapterOptions ) : null; @@ -166,19 +101,19 @@ class WebGPUBackend extends Backend { final supportedFeatures = []; - for ( final name of features ) { + for ( final name in features ) { if ( adapter.features.has( name ) ) { - supportedFeatures.push( name ); + supportedFeatures.add( name ); } } final deviceDescriptor = { - requiredFeatures: supportedFeatures, - requiredLimits: parameters.requiredLimits + 'requiredFeatures': supportedFeatures, + 'requiredLimits': parameters.requiredLimits }; device = await adapter.requestDevice( deviceDescriptor ); @@ -189,13 +124,13 @@ class WebGPUBackend extends Backend { } - device.lost.then( ( info ) => { + device.lost.then( ( info ){ final deviceLossInfo = { - api: 'WebGPU', - message: info.message || 'Unknown reason', - reason: info.reason || null, - originalEvent: info + 'api': 'WebGPU', + 'message': info.message || 'Unknown reason', + 'reason': info.reason || null, + 'originalEvent': info }; renderer.onDeviceLost( deviceLossInfo ); @@ -212,63 +147,59 @@ class WebGPUBackend extends Backend { this.trackTimestamp = this.trackTimestamp && this.hasFeature( GPUFeatureName.TimestampQuery ); this.context.configure( { - device: this.device, - format: this.utils.getPreferredCanvasFormat(), - usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC, - alphaMode: alphaMode + 'device': this.device, + 'format': this.utils.getPreferredCanvasFormat(), + 'usage': GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC, + 'alphaMode': alphaMode } ); this.updateSize(); } - /** - * The coordinate system of the backend. - * - * @type {number} - * @readonly - */ - get coordinateSystem() { - - return WebGPUCoordinateSystem; - - } - - /** - * This method performs a readback operation by moving buffer data from - * a storage buffer attribute from the GPU to the CPU. - * - * @async - * @param {StorageBufferAttribute} attribute - The storage buffer attribute. - * @return {Promise} A promise that resolves with the buffer data when the data are ready. - */ - async getArrayBufferAsync( attribute ) { + /// + /// The coordinate system of the backend. + /// + /// @type {number} + /// @readonly + /// + get coordinateSystem => WebGPUCoordinateSystem; + + /// + /// This method performs a readback operation by moving buffer data from + /// a storage buffer attribute from the GPU to the CPU. + /// + /// @async + /// @param {StorageBufferAttribute} attribute - The storage buffer attribute. + /// @return {Promise} A promise that resolves with the buffer data when the data are ready. + /// + Future getArrayBufferAsync( StorageBufferAttribute attribute ) async{ return await this.attributeUtils.getArrayBufferAsync( attribute ); } - /** - * Returns the backend's rendering context. - * - * @return {GPUCanvasContext} The rendering context. - */ - getContext() { + /// + /// Returns the backend's rendering context. + /// + /// @return {GPUCanvasContext} The rendering context. + /// + GPUCanvasContext getContext() { return this.context; } - /** - * Returns the default render pass descriptor. - * - * In WebGPU, the default framebuffer must be configured - * like custom framebuffers so the backend needs a render - * pass descriptor even when rendering directly to screen. - * - * @private - * @return {Object} The render pass descriptor. - */ + /// + /// Returns the default render pass descriptor. + /// + /// In WebGPU, the default framebuffer must be configured + /// like custom framebuffers so the backend needs a render + /// pass descriptor even when rendering directly to screen. + /// + /// @private + /// @return {Object} The render pass descriptor. + /// _getDefaultRenderPassDescriptor() { let descriptor = this.defaultRenderPassdescriptor; @@ -278,22 +209,22 @@ class WebGPUBackend extends Backend { final renderer = this.renderer; descriptor = { - colorAttachments: [ { - view: null + 'colorAttachments': [ { + 'view': null } ], }; - if ( this.renderer.depth == true || this.renderer.stencil == true ) { + if ( this.renderer?.depth == true || this.renderer?.stencil == true ) { descriptor.depthStencilAttachment = { - view: this.textureUtils.getDepthBuffer( renderer.depth, renderer.stencil ).createView() + 'view': this.textureUtils.getDepthBuffer( renderer.depth, renderer.stencil ).createView() }; } final colorAttachment = descriptor.colorAttachments[ 0 ]; - if ( this.renderer.samples > 0 ) { + if ( (this.renderer?.samples ?? 0) > 0 ) { colorAttachment.view = this.colorBuffer.createView(); @@ -309,7 +240,7 @@ class WebGPUBackend extends Backend { final colorAttachment = descriptor.colorAttachments[ 0 ]; - if ( this.renderer.samples > 0 ) { + if ( (this.renderer?.samples ?? 0) > 0 ) { colorAttachment.resolveTarget = this.context.getCurrentTexture().createView(); @@ -394,17 +325,17 @@ class WebGPUBackend extends Backend { final isRenderCameraDepthArray = this._isRenderCameraDepthArray( renderContext ); - for ( let i = 0; i < textures.length; i ++ ) { + for ( int i = 0; i < textures.length; i ++ ) { final textureData = this.get( textures[ i ] ); final viewDescriptor = { - label: `colorAttachment_${ i }`, - baseMipLevel: renderContext.activeMipmapLevel, - mipLevelCount: 1, - baseArrayLayer: renderContext.activeCubeFace, - arrayLayerCount: 1, - dimension: GPUTextureViewDimension.TwoD + 'label': 'colorAttachment_$i', + 'baseMipLevel': renderContext.activeMipmapLevel, + 'mipLevelCount': 1, + 'baseArrayLayer': renderContext.activeCubeFace, + 'arrayLayerCount': 1, + 'dimension': GPUTextureViewDimension.TwoD }; if ( renderTarget.isRenderTarget3D ) { @@ -420,19 +351,19 @@ class WebGPUBackend extends Backend { if ( isRenderCameraDepthArray == true ) { final cameras = renderContext.camera.cameras; - for ( let layer = 0; layer < cameras.length; layer ++ ) { + for ( int layer = 0; layer < cameras.length; layer ++ ) { final layerViewDescriptor = { ...viewDescriptor, - baseArrayLayer: layer, - arrayLayerCount: 1, - dimension: GPUTextureViewDimension.TwoD + 'baseArrayLayer': layer, + 'arrayLayerCount': 1, + 'dimension': GPUTextureViewDimension.TwoD }; final textureView = textureData.texture.createView( layerViewDescriptor ); - textureViews.push( { - view: textureView, - resolveTarget: null, - depthSlice: null + textureViews.add( { + 'view': textureView, + 'resolveTarget': null, + 'depthSlice': null } ); } @@ -450,7 +381,8 @@ class WebGPUBackend extends Backend { final textureView = textureData.texture.createView( viewDescriptor ); - let view, resolveTarget; + GPUTextureView view; + GPUTextureView? resolveTarget; if ( textureData.msaaTexture != null ) { @@ -464,17 +396,17 @@ class WebGPUBackend extends Backend { } - textureViews.push( { - view, - resolveTarget, - depthSlice: sliceIndex + textureViews.add( { + 'view': view, + 'resolveTarget': resolveTarget, + 'depthSlice': sliceIndex } ); } } - descriptorBase = { textureViews }; + descriptorBase = { 'textureViews': textureViews }; if ( renderContext.depth ) { @@ -482,9 +414,9 @@ class WebGPUBackend extends Backend { final options = {}; if ( renderContext.depthTexture.isArrayTexture ) { - options.dimension = GPUTextureViewDimension.TwoD; - options.arrayLayerCount = 1; - options.baseArrayLayer = renderContext.activeCubeFace; + options['dimension'] = GPUTextureViewDimension.TwoD; + options['arrayLayerCount'] = 1; + options['baseArrayLayer'] = renderContext.activeCubeFace; } @@ -504,28 +436,28 @@ class WebGPUBackend extends Backend { } final descriptor = { - colorAttachments: [] + 'colorAttachments': [] }; // Apply dynamic properties to cached views - for ( let i = 0; i < descriptorBase.textureViews.length; i ++ ) { + for ( int i = 0; i < descriptorBase.textureViews.length; i ++ ) { final viewInfo = descriptorBase.textureViews[ i ]; - let clearValue = { r: 0, g: 0, b: 0, a: 1 }; + let clearValue = { 'r': 0, 'g': 0, 'b': 0, 'a': 1 }; if ( i == 0 && colorAttachmentsConfig.clearValue ) { clearValue = colorAttachmentsConfig.clearValue; } - descriptor.colorAttachments.push( { - view: viewInfo.view, - depthSlice: viewInfo.depthSlice, - resolveTarget: viewInfo.resolveTarget, - loadOp: colorAttachmentsConfig.loadOp || GPULoadOp.Load, - storeOp: colorAttachmentsConfig.storeOp || GPUStoreOp.Store, - clearValue: clearValue + descriptor.colorAttachments.add( { + 'view': viewInfo.view, + 'depthSlice': viewInfo.depthSlice, + 'resolveTarget': viewInfo.resolveTarget, + 'loadOp': colorAttachmentsConfig.loadOp || GPULoadOp.Load, + 'storeOp': colorAttachmentsConfig.storeOp || GPUStoreOp.Store, + 'clearValue': clearValue } ); } @@ -533,7 +465,7 @@ class WebGPUBackend extends Backend { if ( descriptorBase.depthStencilView ) { descriptor.depthStencilAttachment = { - view: descriptorBase.depthStencilView + 'view': descriptorBase.depthStencilView }; } @@ -602,13 +534,13 @@ class WebGPUBackend extends Backend { final colorAttachments = descriptor.colorAttachments; - for ( let i = 0; i < colorAttachments.length; i ++ ) { + for ( int i = 0; i < colorAttachments.length; i ++ ) { final colorAttachment = colorAttachments[ i ]; if ( renderContext.clearColor ) { - colorAttachment.clearValue = i == 0 ? renderContext.clearColorValue : { r: 0, g: 0, b: 0, a: 1 }; + colorAttachment.clearValue = i == 0 ? renderContext.clearColorValue : { 'r': 0, 'g': 0, 'b': 0, 'a': 1 }; colorAttachment.loadOp = GPULoadOp.Clear; } else { diff --git a/packages/three_js_gpu/lib/gpu_renderer.dart b/packages/three_js_gpu/lib/gpu_renderer.dart index 288275c1..14341ffe 100644 --- a/packages/three_js_gpu/lib/gpu_renderer.dart +++ b/packages/three_js_gpu/lib/gpu_renderer.dart @@ -48,7 +48,7 @@ class WebGPURenderer extends Renderer{ BackendClass = WebGPUBackend; parameters.getFallback = (){ console.warning( 'THREE.WebGPURenderer: WebGPU is not available, running under WebGL2 backend.' ); - return new WebGLBackend( parameters ); + return WebGLBackend( parameters ); }; } diff --git a/packages/three_js_gpu/lib/nodes/WGSLNodeBuilder.js b/packages/three_js_gpu/lib/nodes/wgsl_node_builder.dart similarity index 93% rename from packages/three_js_gpu/lib/nodes/WGSLNodeBuilder.js rename to packages/three_js_gpu/lib/nodes/wgsl_node_builder.dart index 9b871de6..6eab6c7d 100644 --- a/packages/three_js_gpu/lib/nodes/WGSLNodeBuilder.js +++ b/packages/three_js_gpu/lib/nodes/wgsl_node_builder.dart @@ -1,22 +1,4 @@ -import NodeUniformsGroup from '../../common/nodes/NodeUniformsGroup.js'; -import NodeSampler from '../../common/nodes/NodeSampler.js'; -import { NodeSampledTexture, NodeSampledCubeTexture, NodeSampledTexture3D } from '../../common/nodes/NodeSampledTexture.js'; - -import NodeUniformBuffer from '../../common/nodes/NodeUniformBuffer.js'; -import NodeStorageBuffer from '../../common/nodes/NodeStorageBuffer.js'; - -import { NodeBuilder, CodeNode } from '../../../nodes/Nodes.js'; - -import { getFormat } from '../utils/WebGPUTextureUtils.js'; - -import WGSLNodeParser from './WGSLNodeParser.js'; -import { NodeAccess } from '../../../nodes/core/constants.js'; - -import VarNode from '../../../nodes/core/VarNode.js'; -import ExpressionNode from '../../../nodes/code/ExpressionNode.js'; - -import { FloatType, RepeatWrapping, ClampToEdgeWrapping, MirroredRepeatWrapping, NearestFilter } from '../../../constants.js'; // GPUShaderStage is not defined in browsers not supporting WebGPU const GPUShaderStage = ( typeof self !== 'undefined' ) ? self.GPUShaderStage : { VERTEX: 1, FRAGMENT: 2, COMPUTE: 4 }; @@ -40,9 +22,9 @@ const gpuShaderStageLib = { }; const supports = { - instance: true, - swizzleAssign: false, - storageBuffer: true + 'instance': true, + 'swizzleAssign': false, + 'storageBuffer': true }; const wgslFnOpLib = { @@ -50,48 +32,48 @@ const wgslFnOpLib = { }; const wgslTypeLib = { - float: 'f32', - int: 'i32', - uint: 'u32', - bool: 'bool', - color: 'vec3', - - vec2: 'vec2', - ivec2: 'vec2', - uvec2: 'vec2', - bvec2: 'vec2', - - vec3: 'vec3', - ivec3: 'vec3', - uvec3: 'vec3', - bvec3: 'vec3', - - vec4: 'vec4', - ivec4: 'vec4', - uvec4: 'vec4', - bvec4: 'vec4', - - mat2: 'mat2x2', - mat3: 'mat3x3', - mat4: 'mat4x4' + 'float': 'f32', + 'int': 'i32', + 'uint': 'u32', + 'bool': 'bool', + 'color': 'vec3', + + 'vec2': 'vec2', + 'ivec2': 'vec2', + 'uvec2': 'vec2', + 'bvec2': 'vec2', + + 'vec3': 'vec3', + 'ivec3': 'vec3', + 'uvec3': 'vec3', + 'bvec3': 'vec3', + + 'vec4': 'vec4', + 'ivec4': 'vec4', + 'uvec4': 'vec4', + 'bvec4': 'vec4', + + 'mat2': 'mat2x2', + 'mat3': 'mat3x3', + 'mat4': 'mat4x4' }; const wgslCodeCache = {}; const wgslPolyfill = { - tsl_xor: new CodeNode( 'fn tsl_xor( a : bool, b : bool ) -> bool { return ( a || b ) && !( a && b ); }' ), - mod_float: new CodeNode( 'fn tsl_mod_float( x : f32, y : f32 ) -> f32 { return x - y * floor( x / y ); }' ), - mod_vec2: new CodeNode( 'fn tsl_mod_vec2( x : vec2f, y : vec2f ) -> vec2f { return x - y * floor( x / y ); }' ), - mod_vec3: new CodeNode( 'fn tsl_mod_vec3( x : vec3f, y : vec3f ) -> vec3f { return x - y * floor( x / y ); }' ), - mod_vec4: new CodeNode( 'fn tsl_mod_vec4( x : vec4f, y : vec4f ) -> vec4f { return x - y * floor( x / y ); }' ), - equals_bool: new CodeNode( 'fn tsl_equals_bool( a : bool, b : bool ) -> bool { return a == b; }' ), - equals_bvec2: new CodeNode( 'fn tsl_equals_bvec2( a : vec2f, b : vec2f ) -> vec2 { return vec2( a.x == b.x, a.y == b.y ); }' ), - equals_bvec3: new CodeNode( 'fn tsl_equals_bvec3( a : vec3f, b : vec3f ) -> vec3 { return vec3( a.x == b.x, a.y == b.y, a.z == b.z ); }' ), - equals_bvec4: new CodeNode( 'fn tsl_equals_bvec4( a : vec4f, b : vec4f ) -> vec4 { return vec4( a.x == b.x, a.y == b.y, a.z == b.z, a.w == b.w ); }' ), - repeatWrapping_float: new CodeNode( 'fn tsl_repeatWrapping_float( coord: f32 ) -> f32 { return fract( coord ); }' ), - mirrorWrapping_float: new CodeNode( 'fn tsl_mirrorWrapping_float( coord: f32 ) -> f32 { let mirrored = fract( coord * 0.5 ) * 2.0; return 1.0 - abs( 1.0 - mirrored ); }' ), - clampWrapping_float: new CodeNode( 'fn tsl_clampWrapping_float( coord: f32 ) -> f32 { return clamp( coord, 0.0, 1.0 ); }' ), - biquadraticTexture: new CodeNode( /* wgsl */` + 'tsl_xor': new CodeNode( 'fn tsl_xor( a : bool, b : bool ) -> bool { return ( a || b ) && !( a && b ); }' ), + 'mod_float': new CodeNode( 'fn tsl_mod_float( x : f32, y : f32 ) -> f32 { return x - y * floor( x / y ); }' ), + 'mod_vec2': new CodeNode( 'fn tsl_mod_vec2( x : vec2f, y : vec2f ) -> vec2f { return x - y * floor( x / y ); }' ), + 'mod_vec3': new CodeNode( 'fn tsl_mod_vec3( x : vec3f, y : vec3f ) -> vec3f { return x - y * floor( x / y ); }' ), + 'mod_vec4': new CodeNode( 'fn tsl_mod_vec4( x : vec4f, y : vec4f ) -> vec4f { return x - y * floor( x / y ); }' ), + 'equals_bool': new CodeNode( 'fn tsl_equals_bool( a : bool, b : bool ) -> bool { return a == b; }' ), + 'equals_bvec2': new CodeNode( 'fn tsl_equals_bvec2( a : vec2f, b : vec2f ) -> vec2 { return vec2( a.x == b.x, a.y == b.y ); }' ), + 'equals_bvec3': new CodeNode( 'fn tsl_equals_bvec3( a : vec3f, b : vec3f ) -> vec3 { return vec3( a.x == b.x, a.y == b.y, a.z == b.z ); }' ), + 'equals_bvec4': new CodeNode( 'fn tsl_equals_bvec4( a : vec4f, b : vec4f ) -> vec4 { return vec4( a.x == b.x, a.y == b.y, a.z == b.z, a.w == b.w ); }' ), + 'repeatWrapping_float': new CodeNode( 'fn tsl_repeatWrapping_float( coord: f32 ) -> f32 { return fract( coord ); }' ), + 'mirrorWrapping_float': new CodeNode( 'fn tsl_mirrorWrapping_float( coord: f32 ) -> f32 { let mirrored = fract( coord * 0.5 ) * 2.0; return 1.0 - abs( 1.0 - mirrored ); }' ), + 'clampWrapping_float': new CodeNode( 'fn tsl_clampWrapping_float( coord: f32 ) -> f32 { return clamp( coord, 0.0, 1.0 ); }' ), + 'biquadraticTexture': new CodeNode( /* wgsl */''' fn tsl_biquadraticTexture( map : texture_2d, coord : vec2f, iRes : vec2u, level : u32 ) -> vec4f { let res = vec2f( iRes ); @@ -113,27 +95,27 @@ fn tsl_biquadraticTexture( map : texture_2d, coord : vec2f, iRes : vec2u, l return mix( mix( rg1, rg2, f.x ), mix( rg3, rg4, f.x ), f.y ); } -` ) +''' ) }; const wgslMethods = { - dFdx: 'dpdx', - dFdy: '- dpdy', - mod_float: 'tsl_mod_float', - mod_vec2: 'tsl_mod_vec2', - mod_vec3: 'tsl_mod_vec3', - mod_vec4: 'tsl_mod_vec4', - equals_bool: 'tsl_equals_bool', - equals_bvec2: 'tsl_equals_bvec2', - equals_bvec3: 'tsl_equals_bvec3', - equals_bvec4: 'tsl_equals_bvec4', - inversesqrt: 'inverseSqrt', - bitcast: 'bitcast' + 'dFdx': 'dpdx', + 'dFdy': '- dpdy', + 'mod_float': 'tsl_mod_float', + 'mod_vec2': 'tsl_mod_vec2', + 'mod_vec3': 'tsl_mod_vec3', + 'mod_vec4': 'tsl_mod_vec4', + 'equals_bool': 'tsl_equals_bool', + 'equals_bvec2': 'tsl_equals_bvec2', + 'equals_bvec3': 'tsl_equals_bvec3', + 'equals_bvec4': 'tsl_equals_bvec4', + 'inversesqrt': 'inverseSqrt', + 'bitcast': 'bitcast' }; // WebGPU issue: does not support pow() with negative base on Windows -if ( typeof navigator !== 'undefined' && /Windows/g.test( navigator.userAgent ) ) { +if ( typeof navigator != null && /Windows/g.test( navigator.userAgent ) ) { wgslPolyfill.pow_float = new CodeNode( 'fn tsl_pow_float( a : f32, b : f32 ) -> f32 { return select( -pow( -a, b ), pow( a, b ), a > 0.0 ); }' ); wgslPolyfill.pow_vec2 = new CodeNode( 'fn tsl_pow_vec2( a : vec2f, b : vec2f ) -> vec2f { return vec2f( tsl_pow_float( a.x, b.x ), tsl_pow_float( a.y, b.y ) ); }', [ wgslPolyfill.pow_float ] ); @@ -1981,7 +1963,7 @@ ${ flowData.code } */ _getWGSLVertexCode( shaderData ) { - return `${ this.getSignature() } + return '''${ this.getSignature() } // directives ${shaderData.directives} @@ -2010,7 +1992,7 @@ fn main( ${shaderData.attributes} ) -> VaryingsStruct { return varyings; } -`; +'''; } @@ -2023,7 +2005,7 @@ fn main( ${shaderData.attributes} ) -> VaryingsStruct { */ _getWGSLFragmentCode( shaderData ) { - return `${ this.getSignature() } + return '''${ this.getSignature() } // global ${ diagnostics } @@ -2046,7 +2028,7 @@ fn main( ${shaderData.varyings} ) -> ${shaderData.returnType} { ${shaderData.flow} } -`; +'''; } @@ -2062,7 +2044,7 @@ fn main( ${shaderData.varyings} ) -> ${shaderData.returnType} { const [ workgroupSizeX, workgroupSizeY, workgroupSizeZ ] = workgroupSize; - return `${ this.getSignature() } + return '''${ this.getSignature() } // directives ${ shaderData.directives } @@ -2096,7 +2078,7 @@ fn main( ${ shaderData.attributes } ) { ${ shaderData.flow } } -`; +'''; } @@ -2110,10 +2092,10 @@ fn main( ${ shaderData.attributes } ) { */ _getWGSLStruct( name, vars ) { - return ` + return ''' struct ${name} { ${vars} -};`; +};'''; } @@ -2133,12 +2115,10 @@ ${vars} const structName = name + 'Struct'; const structSnippet = this._getWGSLStruct( structName, vars ); - return `${structSnippet} + return '''${structSnippet} @binding( ${ binding } ) @group( ${ group } ) -var<${access}> ${ name } : ${ structName };`; +var<${access}> ${ name } : ${ structName };'''; } } - -export default WGSLNodeBuilder; diff --git a/packages/three_js_gpu/lib/src/materialx/lib/mx_hsv.dart b/packages/three_js_gpu/lib/src/materialx/lib/mx_hsv.dart new file mode 100644 index 00000000..3f3ce47a --- /dev/null +++ b/packages/three_js_gpu/lib/src/materialx/lib/mx_hsv.dart @@ -0,0 +1,122 @@ +import 'dart:math'; + +final mx_hsvtorgb = /*@__PURE__*/ Fn( ( [ hsv ] ) { + + final s = hsv.y; + final v = hsv.z; + + final result = vec3().toVar(); + + If( s.lessThan( 0.0001 ), () { + + result.assign( vec3( v, v, v ) ); + + } ).Else( () { + + var h = hsv.x; + h = h.sub( floor( h ) ).mul( 6.0 ).toVar(); // TODO: check what .toVar() is needed in node system cache + final hi = int( trunc( h ) ); + final f = h.sub( float( hi ) ); + final p = v.mul( s.oneMinus() ); + final q = v.mul( s.mul( f ).oneMinus() ); + final t = v.mul( s.mul( f.oneMinus() ).oneMinus() ); + + If( hi.equal( int( 0 ) ), () { + + result.assign( vec3( v, t, p ) ); + + } ).ElseIf( hi.equal( int( 1 ) ), () { + + result.assign( vec3( q, v, p ) ); + + } ).ElseIf( hi.equal( int( 2 ) ), () { + + result.assign( vec3( p, v, t ) ); + + } ).ElseIf( hi.equal( int( 3 ) ), () { + + result.assign( vec3( p, q, v ) ); + + } ).ElseIf( hi.equal( int( 4 ) ), () { + + result.assign( vec3( t, p, v ) ); + + } ).Else( () { + + result.assign( vec3( v, p, q ) ); + + } ); + + } ); + + return result; + +} ).setLayout( { + 'name': 'mx_hsvtorgb', + 'type': 'vec3', + 'inputs': [ + { 'name': 'hsv', 'type': 'vec3' } + ] +} ); + +final mx_rgbtohsv = /*@__PURE__*/ Fn( ( [ c_immutable ] ) { + + final c = vec3( c_immutable ).toVar(); + final r = float( c.x ).toVar(); + final g = float( c.y ).toVar(); + final b = float( c.z ).toVar(); + final mincomp = float( min( r, min( g, b ) ) ).toVar(); + final maxcomp = float( max( r, max( g, b ) ) ).toVar(); + final delta = float( maxcomp.sub( mincomp ) ).toVar(); + final h = float().toVar(), s = float().toVar(), v = float().toVar(); + v.assign( maxcomp ); + + If( maxcomp.greaterThan( 0.0 ), () => { + + s.assign( delta.div( maxcomp ) ); + + } ).Else( () => { + + s.assign( 0.0 ); + + } ); + + If( s.lessThanEqual( 0.0 ), () { + + h.assign( 0.0 ); + + } ).Else( () { + + If( r.greaterThanEqual( maxcomp ), () { + + h.assign( g.sub( b ).div( delta ) ); + + } ).ElseIf( g.greaterThanEqual( maxcomp ), () { + + h.assign( add( 2.0, b.sub( r ).div( delta ) ) ); + + } ).Else( () { + + h.assign( add( 4.0, r.sub( g ).div( delta ) ) ); + + } ); + + h.mulAssign( 1.0 / 6.0 ); + + If( h.lessThan( 0.0 ), () { + + h.addAssign( 1.0 ); + + } ); + + } ); + + return vec3( h, s, v ); + +} ).setLayout( { + 'name': 'mx_rgbtohsv', + 'type': 'vec3', + 'inputs': [ + { 'name': 'c', 'type': 'vec3' } + ] +} ); diff --git a/packages/three_js_gpu/lib/src/materialx/lib/mx_noise.dart b/packages/three_js_gpu/lib/src/materialx/lib/mx_noise.dart new file mode 100644 index 00000000..786fe569 --- /dev/null +++ b/packages/three_js_gpu/lib/src/materialx/lib/mx_noise.dart @@ -0,0 +1,1315 @@ + +export const mx_select = /*@__PURE__*/ Fn( ( [ b_immutable, t_immutable, f_immutable ] ) => { + + const f = float( f_immutable ).toVar(); + const t = float( t_immutable ).toVar(); + const b = bool( b_immutable ).toVar(); + + return select( b, t, f ); + +} ).setLayout( { + name: 'mx_select', + type: 'float', + inputs: [ + { name: 'b', type: 'bool' }, + { name: 't', type: 'float' }, + { name: 'f', type: 'float' } + ] +} ); + +export const mx_negate_if = /*@__PURE__*/ Fn( ( [ val_immutable, b_immutable ] ) => { + + const b = bool( b_immutable ).toVar(); + const val = float( val_immutable ).toVar(); + + return select( b, val.negate(), val ); + +} ).setLayout( { + name: 'mx_negate_if', + type: 'float', + inputs: [ + { name: 'val', type: 'float' }, + { name: 'b', type: 'bool' } + ] +} ); + +export const mx_floor = /*@__PURE__*/ Fn( ( [ x_immutable ] ) => { + + const x = float( x_immutable ).toVar(); + + return int( floor( x ) ); + +} ).setLayout( { + name: 'mx_floor', + type: 'int', + inputs: [ + { name: 'x', type: 'float' } + ] +} ); + +export const mx_floorfrac = /*@__PURE__*/ Fn( ( [ x_immutable, i ] ) => { + + const x = float( x_immutable ).toVar(); + i.assign( mx_floor( x ) ); + + return x.sub( float( i ) ); + +} ); + +export const mx_bilerp_0 = /*@__PURE__*/ Fn( ( [ v0_immutable, v1_immutable, v2_immutable, v3_immutable, s_immutable, t_immutable ] ) => { + + const t = float( t_immutable ).toVar(); + const s = float( s_immutable ).toVar(); + const v3 = float( v3_immutable ).toVar(); + const v2 = float( v2_immutable ).toVar(); + const v1 = float( v1_immutable ).toVar(); + const v0 = float( v0_immutable ).toVar(); + const s1 = float( sub( 1.0, s ) ).toVar(); + + return sub( 1.0, t ).mul( v0.mul( s1 ).add( v1.mul( s ) ) ).add( t.mul( v2.mul( s1 ).add( v3.mul( s ) ) ) ); + +} ).setLayout( { + name: 'mx_bilerp_0', + type: 'float', + inputs: [ + { name: 'v0', type: 'float' }, + { name: 'v1', type: 'float' }, + { name: 'v2', type: 'float' }, + { name: 'v3', type: 'float' }, + { name: 's', type: 'float' }, + { name: 't', type: 'float' } + ] +} ); + +export const mx_bilerp_1 = /*@__PURE__*/ Fn( ( [ v0_immutable, v1_immutable, v2_immutable, v3_immutable, s_immutable, t_immutable ] ) => { + + const t = float( t_immutable ).toVar(); + const s = float( s_immutable ).toVar(); + const v3 = vec3( v3_immutable ).toVar(); + const v2 = vec3( v2_immutable ).toVar(); + const v1 = vec3( v1_immutable ).toVar(); + const v0 = vec3( v0_immutable ).toVar(); + const s1 = float( sub( 1.0, s ) ).toVar(); + + return sub( 1.0, t ).mul( v0.mul( s1 ).add( v1.mul( s ) ) ).add( t.mul( v2.mul( s1 ).add( v3.mul( s ) ) ) ); + +} ).setLayout( { + name: 'mx_bilerp_1', + type: 'vec3', + inputs: [ + { name: 'v0', type: 'vec3' }, + { name: 'v1', type: 'vec3' }, + { name: 'v2', type: 'vec3' }, + { name: 'v3', type: 'vec3' }, + { name: 's', type: 'float' }, + { name: 't', type: 'float' } + ] +} ); + +export const mx_bilerp = /*@__PURE__*/ overloadingFn( [ mx_bilerp_0, mx_bilerp_1 ] ); + +export const mx_trilerp_0 = /*@__PURE__*/ Fn( ( [ v0_immutable, v1_immutable, v2_immutable, v3_immutable, v4_immutable, v5_immutable, v6_immutable, v7_immutable, s_immutable, t_immutable, r_immutable ] ) => { + + const r = float( r_immutable ).toVar(); + const t = float( t_immutable ).toVar(); + const s = float( s_immutable ).toVar(); + const v7 = float( v7_immutable ).toVar(); + const v6 = float( v6_immutable ).toVar(); + const v5 = float( v5_immutable ).toVar(); + const v4 = float( v4_immutable ).toVar(); + const v3 = float( v3_immutable ).toVar(); + const v2 = float( v2_immutable ).toVar(); + const v1 = float( v1_immutable ).toVar(); + const v0 = float( v0_immutable ).toVar(); + const s1 = float( sub( 1.0, s ) ).toVar(); + const t1 = float( sub( 1.0, t ) ).toVar(); + const r1 = float( sub( 1.0, r ) ).toVar(); + + return r1.mul( t1.mul( v0.mul( s1 ).add( v1.mul( s ) ) ).add( t.mul( v2.mul( s1 ).add( v3.mul( s ) ) ) ) ).add( r.mul( t1.mul( v4.mul( s1 ).add( v5.mul( s ) ) ).add( t.mul( v6.mul( s1 ).add( v7.mul( s ) ) ) ) ) ); + +} ).setLayout( { + name: 'mx_trilerp_0', + type: 'float', + inputs: [ + { name: 'v0', type: 'float' }, + { name: 'v1', type: 'float' }, + { name: 'v2', type: 'float' }, + { name: 'v3', type: 'float' }, + { name: 'v4', type: 'float' }, + { name: 'v5', type: 'float' }, + { name: 'v6', type: 'float' }, + { name: 'v7', type: 'float' }, + { name: 's', type: 'float' }, + { name: 't', type: 'float' }, + { name: 'r', type: 'float' } + ] +} ); + +export const mx_trilerp_1 = /*@__PURE__*/ Fn( ( [ v0_immutable, v1_immutable, v2_immutable, v3_immutable, v4_immutable, v5_immutable, v6_immutable, v7_immutable, s_immutable, t_immutable, r_immutable ] ) => { + + const r = float( r_immutable ).toVar(); + const t = float( t_immutable ).toVar(); + const s = float( s_immutable ).toVar(); + const v7 = vec3( v7_immutable ).toVar(); + const v6 = vec3( v6_immutable ).toVar(); + const v5 = vec3( v5_immutable ).toVar(); + const v4 = vec3( v4_immutable ).toVar(); + const v3 = vec3( v3_immutable ).toVar(); + const v2 = vec3( v2_immutable ).toVar(); + const v1 = vec3( v1_immutable ).toVar(); + const v0 = vec3( v0_immutable ).toVar(); + const s1 = float( sub( 1.0, s ) ).toVar(); + const t1 = float( sub( 1.0, t ) ).toVar(); + const r1 = float( sub( 1.0, r ) ).toVar(); + + return r1.mul( t1.mul( v0.mul( s1 ).add( v1.mul( s ) ) ).add( t.mul( v2.mul( s1 ).add( v3.mul( s ) ) ) ) ).add( r.mul( t1.mul( v4.mul( s1 ).add( v5.mul( s ) ) ).add( t.mul( v6.mul( s1 ).add( v7.mul( s ) ) ) ) ) ); + +} ).setLayout( { + name: 'mx_trilerp_1', + type: 'vec3', + inputs: [ + { name: 'v0', type: 'vec3' }, + { name: 'v1', type: 'vec3' }, + { name: 'v2', type: 'vec3' }, + { name: 'v3', type: 'vec3' }, + { name: 'v4', type: 'vec3' }, + { name: 'v5', type: 'vec3' }, + { name: 'v6', type: 'vec3' }, + { name: 'v7', type: 'vec3' }, + { name: 's', type: 'float' }, + { name: 't', type: 'float' }, + { name: 'r', type: 'float' } + ] +} ); + +export const mx_trilerp = /*@__PURE__*/ overloadingFn( [ mx_trilerp_0, mx_trilerp_1 ] ); + +export const mx_gradient_float_0 = /*@__PURE__*/ Fn( ( [ hash_immutable, x_immutable, y_immutable ] ) => { + + const y = float( y_immutable ).toVar(); + const x = float( x_immutable ).toVar(); + const hash = uint( hash_immutable ).toVar(); + const h = uint( hash.bitAnd( uint( 7 ) ) ).toVar(); + const u = float( mx_select( h.lessThan( uint( 4 ) ), x, y ) ).toVar(); + const v = float( mul( 2.0, mx_select( h.lessThan( uint( 4 ) ), y, x ) ) ).toVar(); + + return mx_negate_if( u, bool( h.bitAnd( uint( 1 ) ) ) ).add( mx_negate_if( v, bool( h.bitAnd( uint( 2 ) ) ) ) ); + +} ).setLayout( { + name: 'mx_gradient_float_0', + type: 'float', + inputs: [ + { name: 'hash', type: 'uint' }, + { name: 'x', type: 'float' }, + { name: 'y', type: 'float' } + ] +} ); + +export const mx_gradient_float_1 = /*@__PURE__*/ Fn( ( [ hash_immutable, x_immutable, y_immutable, z_immutable ] ) => { + + const z = float( z_immutable ).toVar(); + const y = float( y_immutable ).toVar(); + const x = float( x_immutable ).toVar(); + const hash = uint( hash_immutable ).toVar(); + const h = uint( hash.bitAnd( uint( 15 ) ) ).toVar(); + const u = float( mx_select( h.lessThan( uint( 8 ) ), x, y ) ).toVar(); + const v = float( mx_select( h.lessThan( uint( 4 ) ), y, mx_select( h.equal( uint( 12 ) ).or( h.equal( uint( 14 ) ) ), x, z ) ) ).toVar(); + + return mx_negate_if( u, bool( h.bitAnd( uint( 1 ) ) ) ).add( mx_negate_if( v, bool( h.bitAnd( uint( 2 ) ) ) ) ); + +} ).setLayout( { + name: 'mx_gradient_float_1', + type: 'float', + inputs: [ + { name: 'hash', type: 'uint' }, + { name: 'x', type: 'float' }, + { name: 'y', type: 'float' }, + { name: 'z', type: 'float' } + ] +} ); + +export const mx_gradient_float = /*@__PURE__*/ overloadingFn( [ mx_gradient_float_0, mx_gradient_float_1 ] ); + +export const mx_gradient_vec3_0 = /*@__PURE__*/ Fn( ( [ hash_immutable, x_immutable, y_immutable ] ) => { + + const y = float( y_immutable ).toVar(); + const x = float( x_immutable ).toVar(); + const hash = uvec3( hash_immutable ).toVar(); + + return vec3( mx_gradient_float( hash.x, x, y ), mx_gradient_float( hash.y, x, y ), mx_gradient_float( hash.z, x, y ) ); + +} ).setLayout( { + name: 'mx_gradient_vec3_0', + type: 'vec3', + inputs: [ + { name: 'hash', type: 'uvec3' }, + { name: 'x', type: 'float' }, + { name: 'y', type: 'float' } + ] +} ); + +export const mx_gradient_vec3_1 = /*@__PURE__*/ Fn( ( [ hash_immutable, x_immutable, y_immutable, z_immutable ] ) => { + + const z = float( z_immutable ).toVar(); + const y = float( y_immutable ).toVar(); + const x = float( x_immutable ).toVar(); + const hash = uvec3( hash_immutable ).toVar(); + + return vec3( mx_gradient_float( hash.x, x, y, z ), mx_gradient_float( hash.y, x, y, z ), mx_gradient_float( hash.z, x, y, z ) ); + +} ).setLayout( { + name: 'mx_gradient_vec3_1', + type: 'vec3', + inputs: [ + { name: 'hash', type: 'uvec3' }, + { name: 'x', type: 'float' }, + { name: 'y', type: 'float' }, + { name: 'z', type: 'float' } + ] +} ); + +export const mx_gradient_vec3 = /*@__PURE__*/ overloadingFn( [ mx_gradient_vec3_0, mx_gradient_vec3_1 ] ); + +export const mx_gradient_scale2d_0 = /*@__PURE__*/ Fn( ( [ v_immutable ] ) => { + + const v = float( v_immutable ).toVar(); + + return mul( 0.6616, v ); + +} ).setLayout( { + name: 'mx_gradient_scale2d_0', + type: 'float', + inputs: [ + { name: 'v', type: 'float' } + ] +} ); + +export const mx_gradient_scale3d_0 = /*@__PURE__*/ Fn( ( [ v_immutable ] ) => { + + const v = float( v_immutable ).toVar(); + + return mul( 0.9820, v ); + +} ).setLayout( { + name: 'mx_gradient_scale3d_0', + type: 'float', + inputs: [ + { name: 'v', type: 'float' } + ] +} ); + +export const mx_gradient_scale2d_1 = /*@__PURE__*/ Fn( ( [ v_immutable ] ) => { + + const v = vec3( v_immutable ).toVar(); + + return mul( 0.6616, v ); + +} ).setLayout( { + name: 'mx_gradient_scale2d_1', + type: 'vec3', + inputs: [ + { name: 'v', type: 'vec3' } + ] +} ); + +export const mx_gradient_scale2d = /*@__PURE__*/ overloadingFn( [ mx_gradient_scale2d_0, mx_gradient_scale2d_1 ] ); + +export const mx_gradient_scale3d_1 = /*@__PURE__*/ Fn( ( [ v_immutable ] ) => { + + const v = vec3( v_immutable ).toVar(); + + return mul( 0.9820, v ); + +} ).setLayout( { + name: 'mx_gradient_scale3d_1', + type: 'vec3', + inputs: [ + { name: 'v', type: 'vec3' } + ] +} ); + +export const mx_gradient_scale3d = /*@__PURE__*/ overloadingFn( [ mx_gradient_scale3d_0, mx_gradient_scale3d_1 ] ); + +export const mx_rotl32 = /*@__PURE__*/ Fn( ( [ x_immutable, k_immutable ] ) => { + + const k = int( k_immutable ).toVar(); + const x = uint( x_immutable ).toVar(); + + return x.shiftLeft( k ).bitOr( x.shiftRight( int( 32 ).sub( k ) ) ); + +} ).setLayout( { + name: 'mx_rotl32', + type: 'uint', + inputs: [ + { name: 'x', type: 'uint' }, + { name: 'k', type: 'int' } + ] +} ); + +export const mx_bjmix = /*@__PURE__*/ Fn( ( [ a, b, c ] ) => { + + a.subAssign( c ); + a.bitXorAssign( mx_rotl32( c, int( 4 ) ) ); + c.addAssign( b ); + b.subAssign( a ); + b.bitXorAssign( mx_rotl32( a, int( 6 ) ) ); + a.addAssign( c ); + c.subAssign( b ); + c.bitXorAssign( mx_rotl32( b, int( 8 ) ) ); + b.addAssign( a ); + a.subAssign( c ); + a.bitXorAssign( mx_rotl32( c, int( 16 ) ) ); + c.addAssign( b ); + b.subAssign( a ); + b.bitXorAssign( mx_rotl32( a, int( 19 ) ) ); + a.addAssign( c ); + c.subAssign( b ); + c.bitXorAssign( mx_rotl32( b, int( 4 ) ) ); + b.addAssign( a ); + +} ); + +export const mx_bjfinal = /*@__PURE__*/ Fn( ( [ a_immutable, b_immutable, c_immutable ] ) => { + + const c = uint( c_immutable ).toVar(); + const b = uint( b_immutable ).toVar(); + const a = uint( a_immutable ).toVar(); + c.bitXorAssign( b ); + c.subAssign( mx_rotl32( b, int( 14 ) ) ); + a.bitXorAssign( c ); + a.subAssign( mx_rotl32( c, int( 11 ) ) ); + b.bitXorAssign( a ); + b.subAssign( mx_rotl32( a, int( 25 ) ) ); + c.bitXorAssign( b ); + c.subAssign( mx_rotl32( b, int( 16 ) ) ); + a.bitXorAssign( c ); + a.subAssign( mx_rotl32( c, int( 4 ) ) ); + b.bitXorAssign( a ); + b.subAssign( mx_rotl32( a, int( 14 ) ) ); + c.bitXorAssign( b ); + c.subAssign( mx_rotl32( b, int( 24 ) ) ); + + return c; + +} ).setLayout( { + name: 'mx_bjfinal', + type: 'uint', + inputs: [ + { name: 'a', type: 'uint' }, + { name: 'b', type: 'uint' }, + { name: 'c', type: 'uint' } + ] +} ); + +export const mx_bits_to_01 = /*@__PURE__*/ Fn( ( [ bits_immutable ] ) => { + + const bits = uint( bits_immutable ).toVar(); + + return float( bits ).div( float( uint( int( 0xffffffff ) ) ) ); + +} ).setLayout( { + name: 'mx_bits_to_01', + type: 'float', + inputs: [ + { name: 'bits', type: 'uint' } + ] +} ); + +export const mx_fade = /*@__PURE__*/ Fn( ( [ t_immutable ] ) => { + + const t = float( t_immutable ).toVar(); + + return t.mul( t ).mul( t ).mul( t.mul( t.mul( 6.0 ).sub( 15.0 ) ).add( 10.0 ) ); + +} ).setLayout( { + name: 'mx_fade', + type: 'float', + inputs: [ + { name: 't', type: 'float' } + ] +} ); + +export const mx_hash_int_0 = /*@__PURE__*/ Fn( ( [ x_immutable ] ) => { + + const x = int( x_immutable ).toVar(); + const len = uint( uint( 1 ) ).toVar(); + const seed = uint( uint( int( 0xdeadbeef ) ).add( len.shiftLeft( uint( 2 ) ) ).add( uint( 13 ) ) ).toVar(); + + return mx_bjfinal( seed.add( uint( x ) ), seed, seed ); + +} ).setLayout( { + name: 'mx_hash_int_0', + type: 'uint', + inputs: [ + { name: 'x', type: 'int' } + ] +} ); + +export const mx_hash_int_1 = /*@__PURE__*/ Fn( ( [ x_immutable, y_immutable ] ) => { + + const y = int( y_immutable ).toVar(); + const x = int( x_immutable ).toVar(); + const len = uint( uint( 2 ) ).toVar(); + const a = uint().toVar(), b = uint().toVar(), c = uint().toVar(); + a.assign( b.assign( c.assign( uint( int( 0xdeadbeef ) ).add( len.shiftLeft( uint( 2 ) ) ).add( uint( 13 ) ) ) ) ); + a.addAssign( uint( x ) ); + b.addAssign( uint( y ) ); + + return mx_bjfinal( a, b, c ); + +} ).setLayout( { + name: 'mx_hash_int_1', + type: 'uint', + inputs: [ + { name: 'x', type: 'int' }, + { name: 'y', type: 'int' } + ] +} ); + +export const mx_hash_int_2 = /*@__PURE__*/ Fn( ( [ x_immutable, y_immutable, z_immutable ] ) => { + + const z = int( z_immutable ).toVar(); + const y = int( y_immutable ).toVar(); + const x = int( x_immutable ).toVar(); + const len = uint( uint( 3 ) ).toVar(); + const a = uint().toVar(), b = uint().toVar(), c = uint().toVar(); + a.assign( b.assign( c.assign( uint( int( 0xdeadbeef ) ).add( len.shiftLeft( uint( 2 ) ) ).add( uint( 13 ) ) ) ) ); + a.addAssign( uint( x ) ); + b.addAssign( uint( y ) ); + c.addAssign( uint( z ) ); + + return mx_bjfinal( a, b, c ); + +} ).setLayout( { + name: 'mx_hash_int_2', + type: 'uint', + inputs: [ + { name: 'x', type: 'int' }, + { name: 'y', type: 'int' }, + { name: 'z', type: 'int' } + ] +} ); + +export const mx_hash_int_3 = /*@__PURE__*/ Fn( ( [ x_immutable, y_immutable, z_immutable, xx_immutable ] ) => { + + const xx = int( xx_immutable ).toVar(); + const z = int( z_immutable ).toVar(); + const y = int( y_immutable ).toVar(); + const x = int( x_immutable ).toVar(); + const len = uint( uint( 4 ) ).toVar(); + const a = uint().toVar(), b = uint().toVar(), c = uint().toVar(); + a.assign( b.assign( c.assign( uint( int( 0xdeadbeef ) ).add( len.shiftLeft( uint( 2 ) ) ).add( uint( 13 ) ) ) ) ); + a.addAssign( uint( x ) ); + b.addAssign( uint( y ) ); + c.addAssign( uint( z ) ); + mx_bjmix( a, b, c ); + a.addAssign( uint( xx ) ); + + return mx_bjfinal( a, b, c ); + +} ).setLayout( { + name: 'mx_hash_int_3', + type: 'uint', + inputs: [ + { name: 'x', type: 'int' }, + { name: 'y', type: 'int' }, + { name: 'z', type: 'int' }, + { name: 'xx', type: 'int' } + ] +} ); + +export const mx_hash_int_4 = /*@__PURE__*/ Fn( ( [ x_immutable, y_immutable, z_immutable, xx_immutable, yy_immutable ] ) => { + + const yy = int( yy_immutable ).toVar(); + const xx = int( xx_immutable ).toVar(); + const z = int( z_immutable ).toVar(); + const y = int( y_immutable ).toVar(); + const x = int( x_immutable ).toVar(); + const len = uint( uint( 5 ) ).toVar(); + const a = uint().toVar(), b = uint().toVar(), c = uint().toVar(); + a.assign( b.assign( c.assign( uint( int( 0xdeadbeef ) ).add( len.shiftLeft( uint( 2 ) ) ).add( uint( 13 ) ) ) ) ); + a.addAssign( uint( x ) ); + b.addAssign( uint( y ) ); + c.addAssign( uint( z ) ); + mx_bjmix( a, b, c ); + a.addAssign( uint( xx ) ); + b.addAssign( uint( yy ) ); + + return mx_bjfinal( a, b, c ); + +} ).setLayout( { + name: 'mx_hash_int_4', + type: 'uint', + inputs: [ + { name: 'x', type: 'int' }, + { name: 'y', type: 'int' }, + { name: 'z', type: 'int' }, + { name: 'xx', type: 'int' }, + { name: 'yy', type: 'int' } + ] +} ); + +export const mx_hash_int = /*@__PURE__*/ overloadingFn( [ mx_hash_int_0, mx_hash_int_1, mx_hash_int_2, mx_hash_int_3, mx_hash_int_4 ] ); + +export const mx_hash_vec3_0 = /*@__PURE__*/ Fn( ( [ x_immutable, y_immutable ] ) => { + + const y = int( y_immutable ).toVar(); + const x = int( x_immutable ).toVar(); + const h = uint( mx_hash_int( x, y ) ).toVar(); + const result = uvec3().toVar(); + result.x.assign( h.bitAnd( int( 0xFF ) ) ); + result.y.assign( h.shiftRight( int( 8 ) ).bitAnd( int( 0xFF ) ) ); + result.z.assign( h.shiftRight( int( 16 ) ).bitAnd( int( 0xFF ) ) ); + + return result; + +} ).setLayout( { + name: 'mx_hash_vec3_0', + type: 'uvec3', + inputs: [ + { name: 'x', type: 'int' }, + { name: 'y', type: 'int' } + ] +} ); + +export const mx_hash_vec3_1 = /*@__PURE__*/ Fn( ( [ x_immutable, y_immutable, z_immutable ] ) => { + + const z = int( z_immutable ).toVar(); + const y = int( y_immutable ).toVar(); + const x = int( x_immutable ).toVar(); + const h = uint( mx_hash_int( x, y, z ) ).toVar(); + const result = uvec3().toVar(); + result.x.assign( h.bitAnd( int( 0xFF ) ) ); + result.y.assign( h.shiftRight( int( 8 ) ).bitAnd( int( 0xFF ) ) ); + result.z.assign( h.shiftRight( int( 16 ) ).bitAnd( int( 0xFF ) ) ); + + return result; + +} ).setLayout( { + name: 'mx_hash_vec3_1', + type: 'uvec3', + inputs: [ + { name: 'x', type: 'int' }, + { name: 'y', type: 'int' }, + { name: 'z', type: 'int' } + ] +} ); + +export const mx_hash_vec3 = /*@__PURE__*/ overloadingFn( [ mx_hash_vec3_0, mx_hash_vec3_1 ] ); + +export const mx_perlin_noise_float_0 = /*@__PURE__*/ Fn( ( [ p_immutable ] ) => { + + const p = vec2( p_immutable ).toVar(); + const X = int().toVar(), Y = int().toVar(); + const fx = float( mx_floorfrac( p.x, X ) ).toVar(); + const fy = float( mx_floorfrac( p.y, Y ) ).toVar(); + const u = float( mx_fade( fx ) ).toVar(); + const v = float( mx_fade( fy ) ).toVar(); + const result = float( mx_bilerp( mx_gradient_float( mx_hash_int( X, Y ), fx, fy ), mx_gradient_float( mx_hash_int( X.add( int( 1 ) ), Y ), fx.sub( 1.0 ), fy ), mx_gradient_float( mx_hash_int( X, Y.add( int( 1 ) ) ), fx, fy.sub( 1.0 ) ), mx_gradient_float( mx_hash_int( X.add( int( 1 ) ), Y.add( int( 1 ) ) ), fx.sub( 1.0 ), fy.sub( 1.0 ) ), u, v ) ).toVar(); + + return mx_gradient_scale2d( result ); + +} ).setLayout( { + name: 'mx_perlin_noise_float_0', + type: 'float', + inputs: [ + { name: 'p', type: 'vec2' } + ] +} ); + +export const mx_perlin_noise_float_1 = /*@__PURE__*/ Fn( ( [ p_immutable ] ) => { + + const p = vec3( p_immutable ).toVar(); + const X = int().toVar(), Y = int().toVar(), Z = int().toVar(); + const fx = float( mx_floorfrac( p.x, X ) ).toVar(); + const fy = float( mx_floorfrac( p.y, Y ) ).toVar(); + const fz = float( mx_floorfrac( p.z, Z ) ).toVar(); + const u = float( mx_fade( fx ) ).toVar(); + const v = float( mx_fade( fy ) ).toVar(); + const w = float( mx_fade( fz ) ).toVar(); + const result = float( mx_trilerp( mx_gradient_float( mx_hash_int( X, Y, Z ), fx, fy, fz ), mx_gradient_float( mx_hash_int( X.add( int( 1 ) ), Y, Z ), fx.sub( 1.0 ), fy, fz ), mx_gradient_float( mx_hash_int( X, Y.add( int( 1 ) ), Z ), fx, fy.sub( 1.0 ), fz ), mx_gradient_float( mx_hash_int( X.add( int( 1 ) ), Y.add( int( 1 ) ), Z ), fx.sub( 1.0 ), fy.sub( 1.0 ), fz ), mx_gradient_float( mx_hash_int( X, Y, Z.add( int( 1 ) ) ), fx, fy, fz.sub( 1.0 ) ), mx_gradient_float( mx_hash_int( X.add( int( 1 ) ), Y, Z.add( int( 1 ) ) ), fx.sub( 1.0 ), fy, fz.sub( 1.0 ) ), mx_gradient_float( mx_hash_int( X, Y.add( int( 1 ) ), Z.add( int( 1 ) ) ), fx, fy.sub( 1.0 ), fz.sub( 1.0 ) ), mx_gradient_float( mx_hash_int( X.add( int( 1 ) ), Y.add( int( 1 ) ), Z.add( int( 1 ) ) ), fx.sub( 1.0 ), fy.sub( 1.0 ), fz.sub( 1.0 ) ), u, v, w ) ).toVar(); + + return mx_gradient_scale3d( result ); + +} ).setLayout( { + name: 'mx_perlin_noise_float_1', + type: 'float', + inputs: [ + { name: 'p', type: 'vec3' } + ] +} ); + +export const mx_perlin_noise_float = /*@__PURE__*/ overloadingFn( [ mx_perlin_noise_float_0, mx_perlin_noise_float_1 ] ); + +export const mx_perlin_noise_vec3_0 = /*@__PURE__*/ Fn( ( [ p_immutable ] ) => { + + const p = vec2( p_immutable ).toVar(); + const X = int().toVar(), Y = int().toVar(); + const fx = float( mx_floorfrac( p.x, X ) ).toVar(); + const fy = float( mx_floorfrac( p.y, Y ) ).toVar(); + const u = float( mx_fade( fx ) ).toVar(); + const v = float( mx_fade( fy ) ).toVar(); + const result = vec3( mx_bilerp( mx_gradient_vec3( mx_hash_vec3( X, Y ), fx, fy ), mx_gradient_vec3( mx_hash_vec3( X.add( int( 1 ) ), Y ), fx.sub( 1.0 ), fy ), mx_gradient_vec3( mx_hash_vec3( X, Y.add( int( 1 ) ) ), fx, fy.sub( 1.0 ) ), mx_gradient_vec3( mx_hash_vec3( X.add( int( 1 ) ), Y.add( int( 1 ) ) ), fx.sub( 1.0 ), fy.sub( 1.0 ) ), u, v ) ).toVar(); + + return mx_gradient_scale2d( result ); + +} ).setLayout( { + name: 'mx_perlin_noise_vec3_0', + type: 'vec3', + inputs: [ + { name: 'p', type: 'vec2' } + ] +} ); + +export const mx_perlin_noise_vec3_1 = /*@__PURE__*/ Fn( ( [ p_immutable ] ) => { + + const p = vec3( p_immutable ).toVar(); + const X = int().toVar(), Y = int().toVar(), Z = int().toVar(); + const fx = float( mx_floorfrac( p.x, X ) ).toVar(); + const fy = float( mx_floorfrac( p.y, Y ) ).toVar(); + const fz = float( mx_floorfrac( p.z, Z ) ).toVar(); + const u = float( mx_fade( fx ) ).toVar(); + const v = float( mx_fade( fy ) ).toVar(); + const w = float( mx_fade( fz ) ).toVar(); + const result = vec3( mx_trilerp( mx_gradient_vec3( mx_hash_vec3( X, Y, Z ), fx, fy, fz ), mx_gradient_vec3( mx_hash_vec3( X.add( int( 1 ) ), Y, Z ), fx.sub( 1.0 ), fy, fz ), mx_gradient_vec3( mx_hash_vec3( X, Y.add( int( 1 ) ), Z ), fx, fy.sub( 1.0 ), fz ), mx_gradient_vec3( mx_hash_vec3( X.add( int( 1 ) ), Y.add( int( 1 ) ), Z ), fx.sub( 1.0 ), fy.sub( 1.0 ), fz ), mx_gradient_vec3( mx_hash_vec3( X, Y, Z.add( int( 1 ) ) ), fx, fy, fz.sub( 1.0 ) ), mx_gradient_vec3( mx_hash_vec3( X.add( int( 1 ) ), Y, Z.add( int( 1 ) ) ), fx.sub( 1.0 ), fy, fz.sub( 1.0 ) ), mx_gradient_vec3( mx_hash_vec3( X, Y.add( int( 1 ) ), Z.add( int( 1 ) ) ), fx, fy.sub( 1.0 ), fz.sub( 1.0 ) ), mx_gradient_vec3( mx_hash_vec3( X.add( int( 1 ) ), Y.add( int( 1 ) ), Z.add( int( 1 ) ) ), fx.sub( 1.0 ), fy.sub( 1.0 ), fz.sub( 1.0 ) ), u, v, w ) ).toVar(); + + return mx_gradient_scale3d( result ); + +} ).setLayout( { + name: 'mx_perlin_noise_vec3_1', + type: 'vec3', + inputs: [ + { name: 'p', type: 'vec3' } + ] +} ); + +export const mx_perlin_noise_vec3 = /*@__PURE__*/ overloadingFn( [ mx_perlin_noise_vec3_0, mx_perlin_noise_vec3_1 ] ); + +export const mx_cell_noise_float_0 = /*@__PURE__*/ Fn( ( [ p_immutable ] ) => { + + const p = float( p_immutable ).toVar(); + const ix = int( mx_floor( p ) ).toVar(); + + return mx_bits_to_01( mx_hash_int( ix ) ); + +} ).setLayout( { + name: 'mx_cell_noise_float_0', + type: 'float', + inputs: [ + { name: 'p', type: 'float' } + ] +} ); + +export const mx_cell_noise_float_1 = /*@__PURE__*/ Fn( ( [ p_immutable ] ) => { + + const p = vec2( p_immutable ).toVar(); + const ix = int( mx_floor( p.x ) ).toVar(); + const iy = int( mx_floor( p.y ) ).toVar(); + + return mx_bits_to_01( mx_hash_int( ix, iy ) ); + +} ).setLayout( { + name: 'mx_cell_noise_float_1', + type: 'float', + inputs: [ + { name: 'p', type: 'vec2' } + ] +} ); + +export const mx_cell_noise_float_2 = /*@__PURE__*/ Fn( ( [ p_immutable ] ) => { + + const p = vec3( p_immutable ).toVar(); + const ix = int( mx_floor( p.x ) ).toVar(); + const iy = int( mx_floor( p.y ) ).toVar(); + const iz = int( mx_floor( p.z ) ).toVar(); + + return mx_bits_to_01( mx_hash_int( ix, iy, iz ) ); + +} ).setLayout( { + name: 'mx_cell_noise_float_2', + type: 'float', + inputs: [ + { name: 'p', type: 'vec3' } + ] +} ); + +export const mx_cell_noise_float_3 = /*@__PURE__*/ Fn( ( [ p_immutable ] ) => { + + const p = vec4( p_immutable ).toVar(); + const ix = int( mx_floor( p.x ) ).toVar(); + const iy = int( mx_floor( p.y ) ).toVar(); + const iz = int( mx_floor( p.z ) ).toVar(); + const iw = int( mx_floor( p.w ) ).toVar(); + + return mx_bits_to_01( mx_hash_int( ix, iy, iz, iw ) ); + +} ).setLayout( { + name: 'mx_cell_noise_float_3', + type: 'float', + inputs: [ + { name: 'p', type: 'vec4' } + ] +} ); + +export const mx_cell_noise_float = /*@__PURE__*/ overloadingFn( [ mx_cell_noise_float_0, mx_cell_noise_float_1, mx_cell_noise_float_2, mx_cell_noise_float_3 ] ); + +export const mx_cell_noise_vec3_0 = /*@__PURE__*/ Fn( ( [ p_immutable ] ) => { + + const p = float( p_immutable ).toVar(); + const ix = int( mx_floor( p ) ).toVar(); + + return vec3( mx_bits_to_01( mx_hash_int( ix, int( 0 ) ) ), mx_bits_to_01( mx_hash_int( ix, int( 1 ) ) ), mx_bits_to_01( mx_hash_int( ix, int( 2 ) ) ) ); + +} ).setLayout( { + name: 'mx_cell_noise_vec3_0', + type: 'vec3', + inputs: [ + { name: 'p', type: 'float' } + ] +} ); + +export const mx_cell_noise_vec3_1 = /*@__PURE__*/ Fn( ( [ p_immutable ] ) => { + + const p = vec2( p_immutable ).toVar(); + const ix = int( mx_floor( p.x ) ).toVar(); + const iy = int( mx_floor( p.y ) ).toVar(); + + return vec3( mx_bits_to_01( mx_hash_int( ix, iy, int( 0 ) ) ), mx_bits_to_01( mx_hash_int( ix, iy, int( 1 ) ) ), mx_bits_to_01( mx_hash_int( ix, iy, int( 2 ) ) ) ); + +} ).setLayout( { + name: 'mx_cell_noise_vec3_1', + type: 'vec3', + inputs: [ + { name: 'p', type: 'vec2' } + ] +} ); + +export const mx_cell_noise_vec3_2 = /*@__PURE__*/ Fn( ( [ p_immutable ] ) => { + + const p = vec3( p_immutable ).toVar(); + const ix = int( mx_floor( p.x ) ).toVar(); + const iy = int( mx_floor( p.y ) ).toVar(); + const iz = int( mx_floor( p.z ) ).toVar(); + + return vec3( mx_bits_to_01( mx_hash_int( ix, iy, iz, int( 0 ) ) ), mx_bits_to_01( mx_hash_int( ix, iy, iz, int( 1 ) ) ), mx_bits_to_01( mx_hash_int( ix, iy, iz, int( 2 ) ) ) ); + +} ).setLayout( { + name: 'mx_cell_noise_vec3_2', + type: 'vec3', + inputs: [ + { name: 'p', type: 'vec3' } + ] +} ); + +export const mx_cell_noise_vec3_3 = /*@__PURE__*/ Fn( ( [ p_immutable ] ) => { + + const p = vec4( p_immutable ).toVar(); + const ix = int( mx_floor( p.x ) ).toVar(); + const iy = int( mx_floor( p.y ) ).toVar(); + const iz = int( mx_floor( p.z ) ).toVar(); + const iw = int( mx_floor( p.w ) ).toVar(); + + return vec3( mx_bits_to_01( mx_hash_int( ix, iy, iz, iw, int( 0 ) ) ), mx_bits_to_01( mx_hash_int( ix, iy, iz, iw, int( 1 ) ) ), mx_bits_to_01( mx_hash_int( ix, iy, iz, iw, int( 2 ) ) ) ); + +} ).setLayout( { + name: 'mx_cell_noise_vec3_3', + type: 'vec3', + inputs: [ + { name: 'p', type: 'vec4' } + ] +} ); + +export const mx_cell_noise_vec3 = /*@__PURE__*/ overloadingFn( [ mx_cell_noise_vec3_0, mx_cell_noise_vec3_1, mx_cell_noise_vec3_2, mx_cell_noise_vec3_3 ] ); + +export const mx_fractal_noise_float = /*@__PURE__*/ Fn( ( [ p_immutable, octaves_immutable, lacunarity_immutable, diminish_immutable ] ) => { + + const diminish = float( diminish_immutable ).toVar(); + const lacunarity = float( lacunarity_immutable ).toVar(); + const octaves = int( octaves_immutable ).toVar(); + const p = vec3( p_immutable ).toVar(); + const result = float( 0.0 ).toVar(); + const amplitude = float( 1.0 ).toVar(); + + Loop( octaves, () => { + + result.addAssign( amplitude.mul( mx_perlin_noise_float( p ) ) ); + amplitude.mulAssign( diminish ); + p.mulAssign( lacunarity ); + + } ); + + return result; + +} ).setLayout( { + name: 'mx_fractal_noise_float', + type: 'float', + inputs: [ + { name: 'p', type: 'vec3' }, + { name: 'octaves', type: 'int' }, + { name: 'lacunarity', type: 'float' }, + { name: 'diminish', type: 'float' } + ] +} ); + +export const mx_fractal_noise_vec3 = /*@__PURE__*/ Fn( ( [ p_immutable, octaves_immutable, lacunarity_immutable, diminish_immutable ] ) => { + + const diminish = float( diminish_immutable ).toVar(); + const lacunarity = float( lacunarity_immutable ).toVar(); + const octaves = int( octaves_immutable ).toVar(); + const p = vec3( p_immutable ).toVar(); + const result = vec3( 0.0 ).toVar(); + const amplitude = float( 1.0 ).toVar(); + + Loop( octaves, () => { + + result.addAssign( amplitude.mul( mx_perlin_noise_vec3( p ) ) ); + amplitude.mulAssign( diminish ); + p.mulAssign( lacunarity ); + + } ); + + return result; + +} ).setLayout( { + name: 'mx_fractal_noise_vec3', + type: 'vec3', + inputs: [ + { name: 'p', type: 'vec3' }, + { name: 'octaves', type: 'int' }, + { name: 'lacunarity', type: 'float' }, + { name: 'diminish', type: 'float' } + ] +} ); + +export const mx_fractal_noise_vec2 = /*@__PURE__*/ Fn( ( [ p_immutable, octaves_immutable, lacunarity_immutable, diminish_immutable ] ) => { + + const diminish = float( diminish_immutable ).toVar(); + const lacunarity = float( lacunarity_immutable ).toVar(); + const octaves = int( octaves_immutable ).toVar(); + const p = vec3( p_immutable ).toVar(); + + return vec2( mx_fractal_noise_float( p, octaves, lacunarity, diminish ), mx_fractal_noise_float( p.add( vec3( int( 19 ), int( 193 ), int( 17 ) ) ), octaves, lacunarity, diminish ) ); + +} ).setLayout( { + name: 'mx_fractal_noise_vec2', + type: 'vec2', + inputs: [ + { name: 'p', type: 'vec3' }, + { name: 'octaves', type: 'int' }, + { name: 'lacunarity', type: 'float' }, + { name: 'diminish', type: 'float' } + ] +} ); + +export const mx_fractal_noise_vec4 = /*@__PURE__*/ Fn( ( [ p_immutable, octaves_immutable, lacunarity_immutable, diminish_immutable ] ) => { + + const diminish = float( diminish_immutable ).toVar(); + const lacunarity = float( lacunarity_immutable ).toVar(); + const octaves = int( octaves_immutable ).toVar(); + const p = vec3( p_immutable ).toVar(); + const c = vec3( mx_fractal_noise_vec3( p, octaves, lacunarity, diminish ) ).toVar(); + const f = float( mx_fractal_noise_float( p.add( vec3( int( 19 ), int( 193 ), int( 17 ) ) ), octaves, lacunarity, diminish ) ).toVar(); + + return vec4( c, f ); + +} ).setLayout( { + name: 'mx_fractal_noise_vec4', + type: 'vec4', + inputs: [ + { name: 'p', type: 'vec3' }, + { name: 'octaves', type: 'int' }, + { name: 'lacunarity', type: 'float' }, + { name: 'diminish', type: 'float' } + ] +} ); + +export const mx_worley_distance_0 = /*@__PURE__*/ Fn( ( [ p_immutable, x_immutable, y_immutable, xoff_immutable, yoff_immutable, jitter_immutable, metric_immutable ] ) => { + + const metric = int( metric_immutable ).toVar(); + const jitter = float( jitter_immutable ).toVar(); + const yoff = int( yoff_immutable ).toVar(); + const xoff = int( xoff_immutable ).toVar(); + const y = int( y_immutable ).toVar(); + const x = int( x_immutable ).toVar(); + const p = vec2( p_immutable ).toVar(); + const tmp = vec3( mx_cell_noise_vec3( vec2( x.add( xoff ), y.add( yoff ) ) ) ).toVar(); + const off = vec2( tmp.x, tmp.y ).toVar(); + off.subAssign( 0.5 ); + off.mulAssign( jitter ); + off.addAssign( 0.5 ); + const cellpos = vec2( vec2( float( x ), float( y ) ).add( off ) ).toVar(); + const diff = vec2( cellpos.sub( p ) ).toVar(); + + If( metric.equal( int( 2 ) ), () => { + + return abs( diff.x ).add( abs( diff.y ) ); + + } ); + + If( metric.equal( int( 3 ) ), () => { + + return max( abs( diff.x ), abs( diff.y ) ); + + } ); + + return dot( diff, diff ); + +} ).setLayout( { + name: 'mx_worley_distance_0', + type: 'float', + inputs: [ + { name: 'p', type: 'vec2' }, + { name: 'x', type: 'int' }, + { name: 'y', type: 'int' }, + { name: 'xoff', type: 'int' }, + { name: 'yoff', type: 'int' }, + { name: 'jitter', type: 'float' }, + { name: 'metric', type: 'int' } + ] +} ); + +export const mx_worley_distance_1 = /*@__PURE__*/ Fn( ( [ p_immutable, x_immutable, y_immutable, z_immutable, xoff_immutable, yoff_immutable, zoff_immutable, jitter_immutable, metric_immutable ] ) => { + + const metric = int( metric_immutable ).toVar(); + const jitter = float( jitter_immutable ).toVar(); + const zoff = int( zoff_immutable ).toVar(); + const yoff = int( yoff_immutable ).toVar(); + const xoff = int( xoff_immutable ).toVar(); + const z = int( z_immutable ).toVar(); + const y = int( y_immutable ).toVar(); + const x = int( x_immutable ).toVar(); + const p = vec3( p_immutable ).toVar(); + const off = vec3( mx_cell_noise_vec3( vec3( x.add( xoff ), y.add( yoff ), z.add( zoff ) ) ) ).toVar(); + off.subAssign( 0.5 ); + off.mulAssign( jitter ); + off.addAssign( 0.5 ); + const cellpos = vec3( vec3( float( x ), float( y ), float( z ) ).add( off ) ).toVar(); + const diff = vec3( cellpos.sub( p ) ).toVar(); + + If( metric.equal( int( 2 ) ), () => { + + return abs( diff.x ).add( abs( diff.y ) ).add( abs( diff.z ) ); + + } ); + + If( metric.equal( int( 3 ) ), () => { + + return max( abs( diff.x ), abs( diff.y ), abs( diff.z ) ); + + } ); + + return dot( diff, diff ); + +} ).setLayout( { + name: 'mx_worley_distance_1', + type: 'float', + inputs: [ + { name: 'p', type: 'vec3' }, + { name: 'x', type: 'int' }, + { name: 'y', type: 'int' }, + { name: 'z', type: 'int' }, + { name: 'xoff', type: 'int' }, + { name: 'yoff', type: 'int' }, + { name: 'zoff', type: 'int' }, + { name: 'jitter', type: 'float' }, + { name: 'metric', type: 'int' } + ] +} ); + +export const mx_worley_distance = /*@__PURE__*/ overloadingFn( [ mx_worley_distance_0, mx_worley_distance_1 ] ); + +export const mx_worley_noise_float_0 = /*@__PURE__*/ Fn( ( [ p_immutable, jitter_immutable, metric_immutable ] ) => { + + const metric = int( metric_immutable ).toVar(); + const jitter = float( jitter_immutable ).toVar(); + const p = vec2( p_immutable ).toVar(); + const X = int().toVar(), Y = int().toVar(); + const localpos = vec2( mx_floorfrac( p.x, X ), mx_floorfrac( p.y, Y ) ).toVar(); + const sqdist = float( 1e6 ).toVar(); + + Loop( { start: - 1, end: int( 1 ), name: 'x', condition: '<=' }, ( { x } ) => { + + Loop( { start: - 1, end: int( 1 ), name: 'y', condition: '<=' }, ( { y } ) => { + + const dist = float( mx_worley_distance( localpos, x, y, X, Y, jitter, metric ) ).toVar(); + sqdist.assign( min( sqdist, dist ) ); + + } ); + + } ); + + If( metric.equal( int( 0 ) ), () => { + + sqdist.assign( sqrt( sqdist ) ); + + } ); + + return sqdist; + +} ).setLayout( { + name: 'mx_worley_noise_float_0', + type: 'float', + inputs: [ + { name: 'p', type: 'vec2' }, + { name: 'jitter', type: 'float' }, + { name: 'metric', type: 'int' } + ] +} ); + +export const mx_worley_noise_vec2_0 = /*@__PURE__*/ Fn( ( [ p_immutable, jitter_immutable, metric_immutable ] ) => { + + const metric = int( metric_immutable ).toVar(); + const jitter = float( jitter_immutable ).toVar(); + const p = vec2( p_immutable ).toVar(); + const X = int().toVar(), Y = int().toVar(); + const localpos = vec2( mx_floorfrac( p.x, X ), mx_floorfrac( p.y, Y ) ).toVar(); + const sqdist = vec2( 1e6, 1e6 ).toVar(); + + Loop( { start: - 1, end: int( 1 ), name: 'x', condition: '<=' }, ( { x } ) => { + + Loop( { start: - 1, end: int( 1 ), name: 'y', condition: '<=' }, ( { y } ) => { + + const dist = float( mx_worley_distance( localpos, x, y, X, Y, jitter, metric ) ).toVar(); + + If( dist.lessThan( sqdist.x ), () => { + + sqdist.y.assign( sqdist.x ); + sqdist.x.assign( dist ); + + } ).ElseIf( dist.lessThan( sqdist.y ), () => { + + sqdist.y.assign( dist ); + + } ); + + } ); + + } ); + + If( metric.equal( int( 0 ) ), () => { + + sqdist.assign( sqrt( sqdist ) ); + + } ); + + return sqdist; + +} ).setLayout( { + name: 'mx_worley_noise_vec2_0', + type: 'vec2', + inputs: [ + { name: 'p', type: 'vec2' }, + { name: 'jitter', type: 'float' }, + { name: 'metric', type: 'int' } + ] +} ); + +export const mx_worley_noise_vec3_0 = /*@__PURE__*/ Fn( ( [ p_immutable, jitter_immutable, metric_immutable ] ) => { + + const metric = int( metric_immutable ).toVar(); + const jitter = float( jitter_immutable ).toVar(); + const p = vec2( p_immutable ).toVar(); + const X = int().toVar(), Y = int().toVar(); + const localpos = vec2( mx_floorfrac( p.x, X ), mx_floorfrac( p.y, Y ) ).toVar(); + const sqdist = vec3( 1e6, 1e6, 1e6 ).toVar(); + + Loop( { start: - 1, end: int( 1 ), name: 'x', condition: '<=' }, ( { x } ) => { + + Loop( { start: - 1, end: int( 1 ), name: 'y', condition: '<=' }, ( { y } ) => { + + const dist = float( mx_worley_distance( localpos, x, y, X, Y, jitter, metric ) ).toVar(); + + If( dist.lessThan( sqdist.x ), () => { + + sqdist.z.assign( sqdist.y ); + sqdist.y.assign( sqdist.x ); + sqdist.x.assign( dist ); + + } ).ElseIf( dist.lessThan( sqdist.y ), () => { + + sqdist.z.assign( sqdist.y ); + sqdist.y.assign( dist ); + + } ).ElseIf( dist.lessThan( sqdist.z ), () => { + + sqdist.z.assign( dist ); + + } ); + + } ); + + } ); + + If( metric.equal( int( 0 ) ), () => { + + sqdist.assign( sqrt( sqdist ) ); + + } ); + + return sqdist; + +} ).setLayout( { + name: 'mx_worley_noise_vec3_0', + type: 'vec3', + inputs: [ + { name: 'p', type: 'vec2' }, + { name: 'jitter', type: 'float' }, + { name: 'metric', type: 'int' } + ] +} ); + +export const mx_worley_noise_float_1 = /*@__PURE__*/ Fn( ( [ p_immutable, jitter_immutable, metric_immutable ] ) => { + + const metric = int( metric_immutable ).toVar(); + const jitter = float( jitter_immutable ).toVar(); + const p = vec3( p_immutable ).toVar(); + const X = int().toVar(), Y = int().toVar(), Z = int().toVar(); + const localpos = vec3( mx_floorfrac( p.x, X ), mx_floorfrac( p.y, Y ), mx_floorfrac( p.z, Z ) ).toVar(); + const sqdist = float( 1e6 ).toVar(); + + Loop( { start: - 1, end: int( 1 ), name: 'x', condition: '<=' }, ( { x } ) => { + + Loop( { start: - 1, end: int( 1 ), name: 'y', condition: '<=' }, ( { y } ) => { + + Loop( { start: - 1, end: int( 1 ), name: 'z', condition: '<=' }, ( { z } ) => { + + const dist = float( mx_worley_distance( localpos, x, y, z, X, Y, Z, jitter, metric ) ).toVar(); + sqdist.assign( min( sqdist, dist ) ); + + } ); + + } ); + + } ); + + If( metric.equal( int( 0 ) ), () => { + + sqdist.assign( sqrt( sqdist ) ); + + } ); + + return sqdist; + +} ).setLayout( { + name: 'mx_worley_noise_float_1', + type: 'float', + inputs: [ + { name: 'p', type: 'vec3' }, + { name: 'jitter', type: 'float' }, + { name: 'metric', type: 'int' } + ] +} ); + +export const mx_worley_noise_float = /*@__PURE__*/ overloadingFn( [ mx_worley_noise_float_0, mx_worley_noise_float_1 ] ); + +export const mx_worley_noise_vec2_1 = /*@__PURE__*/ Fn( ( [ p_immutable, jitter_immutable, metric_immutable ] ) => { + + const metric = int( metric_immutable ).toVar(); + const jitter = float( jitter_immutable ).toVar(); + const p = vec3( p_immutable ).toVar(); + const X = int().toVar(), Y = int().toVar(), Z = int().toVar(); + const localpos = vec3( mx_floorfrac( p.x, X ), mx_floorfrac( p.y, Y ), mx_floorfrac( p.z, Z ) ).toVar(); + const sqdist = vec2( 1e6, 1e6 ).toVar(); + + Loop( { start: - 1, end: int( 1 ), name: 'x', condition: '<=' }, ( { x } ) => { + + Loop( { start: - 1, end: int( 1 ), name: 'y', condition: '<=' }, ( { y } ) => { + + Loop( { start: - 1, end: int( 1 ), name: 'z', condition: '<=' }, ( { z } ) => { + + const dist = float( mx_worley_distance( localpos, x, y, z, X, Y, Z, jitter, metric ) ).toVar(); + + If( dist.lessThan( sqdist.x ), () => { + + sqdist.y.assign( sqdist.x ); + sqdist.x.assign( dist ); + + } ).ElseIf( dist.lessThan( sqdist.y ), () => { + + sqdist.y.assign( dist ); + + } ); + + } ); + + } ); + + } ); + + If( metric.equal( int( 0 ) ), () => { + + sqdist.assign( sqrt( sqdist ) ); + + } ); + + return sqdist; + +} ).setLayout( { + name: 'mx_worley_noise_vec2_1', + type: 'vec2', + inputs: [ + { name: 'p', type: 'vec3' }, + { name: 'jitter', type: 'float' }, + { name: 'metric', type: 'int' } + ] +} ); + +export const mx_worley_noise_vec2 = /*@__PURE__*/ overloadingFn( [ mx_worley_noise_vec2_0, mx_worley_noise_vec2_1 ] ); + +export const mx_worley_noise_vec3_1 = /*@__PURE__*/ Fn( ( [ p_immutable, jitter_immutable, metric_immutable ] ) => { + + const metric = int( metric_immutable ).toVar(); + const jitter = float( jitter_immutable ).toVar(); + const p = vec3( p_immutable ).toVar(); + const X = int().toVar(), Y = int().toVar(), Z = int().toVar(); + const localpos = vec3( mx_floorfrac( p.x, X ), mx_floorfrac( p.y, Y ), mx_floorfrac( p.z, Z ) ).toVar(); + const sqdist = vec3( 1e6, 1e6, 1e6 ).toVar(); + + Loop( { start: - 1, end: int( 1 ), name: 'x', condition: '<=' }, ( { x } ) => { + + Loop( { start: - 1, end: int( 1 ), name: 'y', condition: '<=' }, ( { y } ) => { + + Loop( { start: - 1, end: int( 1 ), name: 'z', condition: '<=' }, ( { z } ) => { + + const dist = float( mx_worley_distance( localpos, x, y, z, X, Y, Z, jitter, metric ) ).toVar(); + + If( dist.lessThan( sqdist.x ), () => { + + sqdist.z.assign( sqdist.y ); + sqdist.y.assign( sqdist.x ); + sqdist.x.assign( dist ); + + } ).ElseIf( dist.lessThan( sqdist.y ), () => { + + sqdist.z.assign( sqdist.y ); + sqdist.y.assign( dist ); + + } ).ElseIf( dist.lessThan( sqdist.z ), () => { + + sqdist.z.assign( dist ); + + } ); + + } ); + + } ); + + } ); + + If( metric.equal( int( 0 ) ), () => { + + sqdist.assign( sqrt( sqdist ) ); + + } ); + + return sqdist; + +} ).setLayout( { + name: 'mx_worley_noise_vec3_1', + type: 'vec3', + inputs: [ + { name: 'p', type: 'vec3' }, + { name: 'jitter', type: 'float' }, + { name: 'metric', type: 'int' } + ] +} ); diff --git a/packages/three_js_gpu/lib/src/materialx/lib/mx_transform_color.dart b/packages/three_js_gpu/lib/src/materialx/lib/mx_transform_color.dart new file mode 100644 index 00000000..a12fca26 --- /dev/null +++ b/packages/three_js_gpu/lib/src/materialx/lib/mx_transform_color.dart @@ -0,0 +1,18 @@ + + +final mx_srgb_texture_to_lin_rec709 = Fn( ( [ color_immutable ] ){ + + final color = vec3( color_immutable ).toVar(); + final isAbove = bvec3( greaterThan( color, vec3( 0.04045 ) ) ).toVar(); + final linSeg = vec3( color.div( 12.92 ) ).toVar(); + final powSeg = vec3( pow( max( color.add( vec3( 0.055 ) ), vec3( 0.0 ) ).div( 1.055 ), vec3( 2.4 ) ) ).toVar(); + + return mix( linSeg, powSeg, isAbove ); + +} ).setLayout( { + 'name': 'mx_srgb_texture_to_lin_rec709', + 'type': 'vec3', + 'inputs': [ + { 'name': 'color', 'type': 'vec3' } + ] +} ); diff --git a/packages/three_js_gpu/lib/src/materialx/materialx_nodes.dart b/packages/three_js_gpu/lib/src/materialx/materialx_nodes.dart new file mode 100644 index 00000000..61dd1faa --- /dev/null +++ b/packages/three_js_gpu/lib/src/materialx/materialx_nodes.dart @@ -0,0 +1,79 @@ + + +mx_aastep( threshold, value ){ + threshold = double.parse( threshold ); + value = double.parse( value ); + const afwidth = vec2( value.dFdx(), value.dFdy() ).length().mul( 0.70710678118654757 ); + return smoothstep( threshold.sub( afwidth ), threshold.add( afwidth ), value ); +} + +mx_ramplr( valuel, valuer, [texcoord = uv() ]){ + return mix( valuel, valuer, texcoord.x.clamp() ); +} +mx_ramptb( valuet, valueb, [texcoord = uv() ]){ + return mix( valuet, valueb, texcoord.y.clamp() ); +} + +mx_splitlr( valuel, valuer, center, [texcoord = uv() ]){ + return mix( valuel, valuer, mx_aastep( center, texcoord.x ) ); +} +mx_splittb( valuet, valueb, center, [texcoord = uv() ]){ + return mix( valuet, valueb, mx_aastep( center, texcoord.y ) ); +} + +mx_transform_uv([ uv_scale = 1, uv_offset = 0, uv_geo = uv() ]){ + return uv_geo.mul( uv_scale ).add( uv_offset ); +} + +mx_safepower( in1, [in2 = 1 ]){ + in1 = double.parse( in1 ); + return in1.abs().pow( in2 ).mul( in1.sign() ); +} +mx_contrast( input, [amount = 1, pivot = .5 ]){ + input = double.parse( input ); + return input.sub( pivot ).mul( amount ).add( pivot ); +} + +mx_noise_float([ texcoord = uv(), amplitude = 1, pivot = 0 ]){ + return mx_perlin_noise_float( texcoord.convert( 'vec2|vec3' ) ).mul( amplitude ).add( pivot ); +} +//export const mx_noise_vec2 = ( texcoord = uv(), amplitude = 1, pivot = 0 ) => mx_perlin_noise_vec3( texcoord.convert( 'vec2|vec3' ) ).mul( amplitude ).add( pivot ); +mx_noise_vec3([ texcoord = uv(), amplitude = 1, pivot = 0 ]){ + return mx_perlin_noise_vec3( texcoord.convert( 'vec2|vec3' ) ).mul( amplitude ).add( pivot ); +} +mx_noise_vec4([ texcoord = uv(), amplitude = 1, pivot = 0 ]){ + + texcoord = texcoord.convert( 'vec2|vec3' ); // overloading type + + const noise_vec4 = vec4( mx_perlin_noise_vec3( texcoord ), mx_perlin_noise_float( texcoord.add( vec2( 19, 73 ) ) ) ); + + return noise_vec4.mul( amplitude ).add( pivot ); + +} + +mx_worley_noise_float([ texcoord = uv(), jitter = 1 ]){ + return worley_noise_float( texcoord.convert( 'vec2|vec3' ), jitter, 1); +} +mx_worley_noise_vec2([ texcoord = uv(), jitter = 1 ]){ + return worley_noise_vec2( texcoord.convert( 'vec2|vec3' ), jitter, 1 ); +} +mx_worley_noise_vec3([ texcoord = uv(), jitter = 1 ]){ + return worley_noise_vec3( texcoord.convert( 'vec2|vec3' ), jitter, 1 ); +} + +mx_cell_noise_float([ texcoord = uv() ]){ + return cell_noise_float( texcoord.convert( 'vec2|vec3' ) ); +} + +mx_fractal_noise_float([ position = uv(), octaves = 3, lacunarity = 2, diminish = .5, amplitude = 1 ]){ + return fractal_noise_float( position, octaves, lacunarity, diminish ).mul( amplitude ); +} +mx_fractal_noise_vec2([ position = uv(), octaves = 3, lacunarity = 2, diminish = .5, amplitude = 1 ]){ + return fractal_noise_vec2( position, octaves, lacunarity, diminish ).mul( amplitude ); +} +mx_fractal_noise_vec3([ position = uv(), octaves = 3, lacunarity = 2, diminish = .5, amplitude = 1 ]){ + return fractal_noise_vec3( position, octaves, lacunarity, diminish ).mul( amplitude ); +} +mx_fractal_noise_vec4([ position = uv(), octaves = 3, lacunarity = 2, diminish = .5, amplitude = 1 ]){ + return fractal_noise_vec4( position, octaves, lacunarity, diminish ).mul( amplitude ); +} diff --git a/packages/three_js_gpu/lib/src/tsl/tsl_base.dart b/packages/three_js_gpu/lib/src/tsl/tsl_base.dart new file mode 100644 index 00000000..b5780ad7 --- /dev/null +++ b/packages/three_js_gpu/lib/src/tsl/tsl_base.dart @@ -0,0 +1,31 @@ +// Non-PURE exports list, side-effects are required here. +// TSL Base Syntax + +export './tsl_core.dart'; // float(), vec2(), vec3(), vec4(), mat3(), mat4(), Fn(), If(), element(), nodeObject(), nodeProxy(), ... +export '../core/array_node.dart'; // array(), .toArray() +export '../core/uniform_node.dart'; // uniform() +export '../core/property_node.dart'; // property() <-> TODO: Separate Material Properties in other file +export '../core/assign_node.dart'; // .assign() +export '../code/function_call_node.dart'; // .call() +export '../math/operator_node.dart'; // .add(), .sub(), ... +export '../math/math_node.dart'; // abs(), floor(), ... +export '../math/conditional_node.dart'; // select(), ... +export '../core/context_node.dart'; // .context() +export '../core/var_node.dart'; // .var() -> TODO: Maybe rename .toVar() -> .var() +export '../core/varying_node.dart'; // varying(), vertexStage() +export '../display/color_space_node.dart'; // .toColorSpace() +export '../display/tone_mapping_node.dart'; // .toToneMapping() +export '../accessors/buffer_attribute_node.dart'; // .toAttribute() +export '../gpgpu/compute_node.dart'; // .compute() +export '../core/cache_node.dart'; // .cache() +export '../core/bypass_node.dart'; // .bypass() +export '../utils/remap_node.dart'; // .remap(), .remapClamp() +export '../code/expression_node.dart'; // expression() +export '../utils/discard.dart'; // Discard(), Return() +export '../display/render_output_node.dart'; // .renderOutput() +export '../utils/debug_node.dart'; // debug() +export '../core/sub_build_node.dart'; // subBuild() + +addNodeElement( name/*, nodeElement*/ ) { + console.warn( 'THREE.TSL: AddNodeElement has been removed in favor of tree-shaking. Trying add', name ); +} diff --git a/packages/three_js_gpu/lib/src/tsl/tsl_core.dart b/packages/three_js_gpu/lib/src/tsl/tsl_core.dart new file mode 100644 index 00000000..fe032b0b --- /dev/null +++ b/packages/three_js_gpu/lib/src/tsl/tsl_core.dart @@ -0,0 +1,862 @@ + + +let currentStack = null; + +final Map NodeElements = new Map(); + +addMethodChaining( name, nodeElement ) { + + if ( NodeElements.has( name ) ) { + + console.warn( 'THREE.TSL: Redefinition of method chaining $name.' ); + return; + + } + + if ( nodeElement != 'function' ) throw new Error( 'THREE.TSL: Node element $name is not a function' ); + + NodeElements.set( name, nodeElement ); + +} + +const parseSwizzle = ( props ) => props.replace( /r|s/g, 'x' ).replace( /g|t/g, 'y' ).replace( /b|p/g, 'z' ).replace( /a|q/g, 'w' ); +const parseSwizzleAndSort = ( props ) => parseSwizzle( props ).split( '' ).sort().join( '' ); + +final shaderNodeHandler = { + + setup( NodeClosure, params ) { + + final inputs = params.shift(); + + return NodeClosure( nodeObjects( inputs ), ...params ); + + }, + + get( node, prop, nodeObj ) { + + if ( prop is String && node[ prop ] == undefined ) { + + if ( node.isStackNode != true && prop == 'assign' ) { + + return ( ...params ) => { + + currentStack.assign( nodeObj, ...params ); + + return nodeObj; + + }; + + } else if ( NodeElements.has( prop ) ) { + + const nodeElement = NodeElements.get( prop ); + + return node.isStackNode ? ( ...params ) => nodeObj.add( nodeElement( ...params ) ) : ( ...params ) => nodeElement( nodeObj, ...params ); + + } else if ( prop == 'self' ) { + + return node; + + } else if ( prop.endsWith( 'Assign' ) && NodeElements.has( prop.slice( 0, prop.length - 'Assign'.length ) ) ) { + + const nodeElement = NodeElements.get( prop.slice( 0, prop.length - 'Assign'.length ) ); + + return node.isStackNode ? ( ...params ) => nodeObj.assign( params[ 0 ], nodeElement( ...params ) ) : ( ...params ) => nodeObj.assign( nodeElement( nodeObj, ...params ) ); + + } else if ( /^[xyzwrgbastpq]{1,4}$/.test( prop ) === true ) { + + // accessing properties ( swizzle ) + + prop = parseSwizzle( prop ); + + return nodeObject( new SplitNode( nodeObj, prop ) ); + + } else if ( /^set[XYZWRGBASTPQ]{1,4}$/.test( prop ) === true ) { + + // set properties ( swizzle ) and sort to xyzw sequence + + prop = parseSwizzleAndSort( prop.slice( 3 ).toLowerCase() ); + + return ( value ) => nodeObject( new SetNode( node, prop, nodeObject( value ) ) ); + + } else if ( /^flip[XYZWRGBASTPQ]{1,4}$/.test( prop ) === true ) { + + // set properties ( swizzle ) and sort to xyzw sequence + + prop = parseSwizzleAndSort( prop.slice( 4 ).toLowerCase() ); + + return () => nodeObject( new FlipNode( nodeObject( node ), prop ) ); + + } else if ( prop === 'width' || prop === 'height' || prop === 'depth' ) { + + // accessing property + + if ( prop === 'width' ) prop = 'x'; + else if ( prop === 'height' ) prop = 'y'; + else if ( prop === 'depth' ) prop = 'z'; + + return nodeObject( new SplitNode( node, prop ) ); + + } else if ( /^\d+$/.test( prop ) === true ) { + + // accessing array + + return nodeObject( new ArrayElementNode( nodeObj, new ConstNode( Number( prop ), 'uint' ) ) ); + + } else if ( /^get$/.test( prop ) === true ) { + + // accessing properties + + return ( value ) => nodeObject( new MemberNode( nodeObj, value ) ); + + } + + } + + return Reflect.get( node, prop, nodeObj ); + + }, + + set( node, prop, value, nodeObj ) { + + if ( typeof prop === 'string' && node[ prop ] === undefined ) { + + // setting properties + + if ( /^[xyzwrgbastpq]{1,4}$/.test( prop ) === true || prop === 'width' || prop === 'height' || prop === 'depth' || /^\d+$/.test( prop ) === true ) { + + nodeObj[ prop ].assign( value ); + + return true; + + } + + } + + return Reflect.set( node, prop, value, nodeObj ); + + } + +}; + +const nodeObjectsCacheMap = new WeakMap(); +const nodeBuilderFunctionsCacheMap = new WeakMap(); + +const ShaderNodeObject = function ( obj, altType = null ) { + + const type = getValueType( obj ); + + if ( type === 'node' ) { + + let nodeObject = nodeObjectsCacheMap.get( obj ); + + if ( nodeObject === undefined ) { + + nodeObject = new Proxy( obj, shaderNodeHandler ); + + nodeObjectsCacheMap.set( obj, nodeObject ); + nodeObjectsCacheMap.set( nodeObject, nodeObject ); + + } + + return nodeObject; + + } else if ( ( altType === null && ( type === 'float' || type === 'boolean' ) ) || ( type && type !== 'shader' && type !== 'string' ) ) { + + return nodeObject( getConstNode( obj, altType ) ); + + } else if ( type === 'shader' ) { + + return obj.isFn ? obj : Fn( obj ); + + } + + return obj; + +}; + +const ShaderNodeObjects = function ( objects, altType = null ) { + + for ( const name in objects ) { + + objects[ name ] = nodeObject( objects[ name ], altType ); + + } + + return objects; + +}; + +const ShaderNodeArray = function ( array, altType = null ) { + + const len = array.length; + + for ( let i = 0; i < len; i ++ ) { + + array[ i ] = nodeObject( array[ i ], altType ); + + } + + return array; + +}; + +const ShaderNodeProxy = function ( NodeClass, scope = null, factor = null, settings = null ) { + + const assignNode = ( node ) => nodeObject( settings !== null ? Object.assign( node, settings ) : node ); + + let fn, name = scope, minParams, maxParams; + + function verifyParamsLimit( params ) { + + let tslName; + + if ( name ) tslName = /[a-z]/i.test( name ) ? name + '()' : name; + else tslName = NodeClass.type; + + if ( minParams !== undefined && params.length < minParams ) { + + console.error( `THREE.TSL: "${ tslName }" parameter length is less than minimum required.` ); + + return params.concat( new Array( minParams - params.length ).fill( 0 ) ); + + } else if ( maxParams !== undefined && params.length > maxParams ) { + + console.error( `THREE.TSL: "${ tslName }" parameter length exceeds limit.` ); + + return params.slice( 0, maxParams ); + + } + + return params; + + } + + if ( scope === null ) { + + fn = ( ...params ) => { + + return assignNode( new NodeClass( ...nodeArray( verifyParamsLimit( params ) ) ) ); + + }; + + } else if ( factor !== null ) { + + factor = nodeObject( factor ); + + fn = ( ...params ) => { + + return assignNode( new NodeClass( scope, ...nodeArray( verifyParamsLimit( params ) ), factor ) ); + + }; + + } else { + + fn = ( ...params ) => { + + return assignNode( new NodeClass( scope, ...nodeArray( verifyParamsLimit( params ) ) ) ); + + }; + + } + + fn.setParameterLength = ( ...params ) => { + + if ( params.length === 1 ) minParams = maxParams = params[ 0 ]; + else if ( params.length === 2 ) [ minParams, maxParams ] = params; + + return fn; + + }; + + fn.setName = ( value ) => { + + name = value; + + return fn; + + }; + + return fn; + +}; + +const ShaderNodeImmutable = function ( NodeClass, ...params ) { + + return nodeObject( new NodeClass( ...nodeArray( params ) ) ); + +}; + +class ShaderCallNodeInternal extends Node { + + constructor( shaderNode, inputNodes ) { + + super(); + + this.shaderNode = shaderNode; + this.inputNodes = inputNodes; + + this.isShaderCallNodeInternal = true; + + } + + getNodeType( builder ) { + + return this.shaderNode.nodeType || this.getOutputNode( builder ).getNodeType( builder ); + + } + + getMemberType( builder, name ) { + + return this.getOutputNode( builder ).getMemberType( builder, name ); + + } + + call( builder ) { + + const { shaderNode, inputNodes } = this; + + const properties = builder.getNodeProperties( shaderNode ); + + const subBuild = builder.getClosestSubBuild( shaderNode.subBuilds ) || ''; + const subBuildProperty = subBuild || 'default'; + + if ( properties[ subBuildProperty ] ) { + + return properties[ subBuildProperty ]; + + } + + // + + const previousSubBuildFn = builder.subBuildFn; + + builder.subBuildFn = subBuild; + + let result = null; + + if ( shaderNode.layout ) { + + let functionNodesCacheMap = nodeBuilderFunctionsCacheMap.get( builder.constructor ); + + if ( functionNodesCacheMap === undefined ) { + + functionNodesCacheMap = new WeakMap(); + + nodeBuilderFunctionsCacheMap.set( builder.constructor, functionNodesCacheMap ); + + } + + let functionNode = functionNodesCacheMap.get( shaderNode ); + + if ( functionNode === undefined ) { + + functionNode = nodeObject( builder.buildFunctionNode( shaderNode ) ); + + functionNodesCacheMap.set( shaderNode, functionNode ); + + } + + builder.addInclude( functionNode ); + + result = nodeObject( functionNode.call( inputNodes ) ); + + } else { + + const jsFunc = shaderNode.jsFunc; + const outputNode = inputNodes !== null || jsFunc.length > 1 ? jsFunc( inputNodes || [], builder ) : jsFunc( builder ); + + result = nodeObject( outputNode ); + + } + + builder.subBuildFn = previousSubBuildFn; + + if ( shaderNode.once ) { + + properties[ subBuildProperty ] = result; + + } + + return result; + + } + + setupOutput( builder ) { + + builder.addStack(); + + builder.stack.outputNode = this.call( builder ); + + return builder.removeStack(); + + } + + getOutputNode( builder ) { + + const properties = builder.getNodeProperties( this ); + const subBuildOutput = builder.getSubBuildOutput( this ); + + properties[ subBuildOutput ] = properties[ subBuildOutput ] || this.setupOutput( builder ); + properties[ subBuildOutput ].subBuild = builder.getClosestSubBuild( this ); + + return properties[ subBuildOutput ]; + + } + + build( builder, output = null ) { + + let result = null; + + const buildStage = builder.getBuildStage(); + const properties = builder.getNodeProperties( this ); + + const subBuildOutput = builder.getSubBuildOutput( this ); + const outputNode = this.getOutputNode( builder ); + + if ( buildStage === 'setup' ) { + + const subBuildInitialized = builder.getSubBuildProperty( 'initialized', this ); + + if ( properties[ subBuildInitialized ] !== true ) { + + properties[ subBuildInitialized ] = true; + + properties[ subBuildOutput ] = this.getOutputNode( builder ); + properties[ subBuildOutput ].build( builder ); + + // If the shaderNode has subBuilds, add them to the chaining nodes + // so they can be built later in the build process. + + if ( this.shaderNode.subBuilds ) { + + for ( const node of builder.chaining ) { + + const nodeData = builder.getDataFromNode( node, 'any' ); + nodeData.subBuilds = nodeData.subBuilds || new Set(); + + for ( const subBuild of this.shaderNode.subBuilds ) { + + nodeData.subBuilds.add( subBuild ); + + } + + //builder.getDataFromNode( node ).subBuilds = nodeData.subBuilds; + + } + + } + + } + + result = properties[ subBuildOutput ]; + + } else if ( buildStage === 'analyze' ) { + + outputNode.build( builder, output ); + + } else if ( buildStage === 'generate' ) { + + result = outputNode.build( builder, output ) || ''; + + } + + return result; + + } + +} + +class ShaderNodeInternal extends Node { + + constructor( jsFunc, nodeType ) { + + super( nodeType ); + + this.jsFunc = jsFunc; + this.layout = null; + + this.global = true; + + this.once = false; + + } + + setLayout( layout ) { + + this.layout = layout; + + return this; + + } + + call( inputs = null ) { + + nodeObjects( inputs ); + + return nodeObject( new ShaderCallNodeInternal( this, inputs ) ); + + } + + setup() { + + return this.call(); + + } + +} + +const bools = [ false, true ]; +const uints = [ 0, 1, 2, 3 ]; +const ints = [ - 1, - 2 ]; +const floats = [ 0.5, 1.5, 1 / 3, 1e-6, 1e6, Math.PI, Math.PI * 2, 1 / Math.PI, 2 / Math.PI, 1 / ( Math.PI * 2 ), Math.PI / 2 ]; + +const boolsCacheMap = new Map(); +for ( const bool of bools ) boolsCacheMap.set( bool, new ConstNode( bool ) ); + +const uintsCacheMap = new Map(); +for ( const uint of uints ) uintsCacheMap.set( uint, new ConstNode( uint, 'uint' ) ); + +const intsCacheMap = new Map( [ ...uintsCacheMap ].map( el => new ConstNode( el.value, 'int' ) ) ); +for ( const int of ints ) intsCacheMap.set( int, new ConstNode( int, 'int' ) ); + +const floatsCacheMap = new Map( [ ...intsCacheMap ].map( el => new ConstNode( el.value ) ) ); +for ( const float of floats ) floatsCacheMap.set( float, new ConstNode( float ) ); +for ( const float of floats ) floatsCacheMap.set( - float, new ConstNode( - float ) ); + +const cacheMaps = { bool: boolsCacheMap, uint: uintsCacheMap, ints: intsCacheMap, float: floatsCacheMap }; + +const constNodesCacheMap = new Map( [ ...boolsCacheMap, ...floatsCacheMap ] ); + +const getConstNode = ( value, type ) => { + + if ( constNodesCacheMap.has( value ) ) { + + return constNodesCacheMap.get( value ); + + } else if ( value.isNode === true ) { + + return value; + + } else { + + return new ConstNode( value, type ); + + } + +}; + +const ConvertType = function ( type, cacheMap = null ) { + + return ( ...params ) => { + + if ( params.length === 0 || ( ! [ 'bool', 'float', 'int', 'uint' ].includes( type ) && params.every( param => typeof param !== 'object' ) ) ) { + + params = [ getValueFromType( type, ...params ) ]; + + } + + if ( params.length === 1 && cacheMap !== null && cacheMap.has( params[ 0 ] ) ) { + + return nodeObject( cacheMap.get( params[ 0 ] ) ); + + } + + if ( params.length === 1 ) { + + const node = getConstNode( params[ 0 ], type ); + if ( node.nodeType === type ) return nodeObject( node ); + return nodeObject( new ConvertNode( node, type ) ); + + } + + const nodes = params.map( param => getConstNode( param ) ); + return nodeObject( new JoinNode( nodes, type ) ); + + }; + +}; + +// exports + +export const defined = ( v ) => typeof v === 'object' && v !== null ? v.value : v; // TODO: remove boolean conversion and defined function + +// utils + +export const getConstNodeType = ( value ) => ( value !== undefined && value !== null ) ? ( value.nodeType || value.convertTo || ( typeof value === 'string' ? value : null ) ) : null; + +// shader node base + +export function ShaderNode( jsFunc, nodeType ) { + + return new Proxy( new ShaderNodeInternal( jsFunc, nodeType ), shaderNodeHandler ); + +} + +export const nodeObject = ( val, altType = null ) => /* new */ ShaderNodeObject( val, altType ); +export const nodeObjects = ( val, altType = null ) => new ShaderNodeObjects( val, altType ); +export const nodeArray = ( val, altType = null ) => new ShaderNodeArray( val, altType ); +export const nodeProxy = ( ...params ) => new ShaderNodeProxy( ...params ); +export const nodeImmutable = ( ...params ) => new ShaderNodeImmutable( ...params ); + +let fnId = 0; + +export const Fn = ( jsFunc, layout = null ) => { + + let nodeType = null; + + if ( layout !== null ) { + + if ( typeof layout === 'object' ) { + + nodeType = layout.return; + + } else { + + if ( typeof layout === 'string' ) { + + nodeType = layout; + + } else { + + console.error( 'THREE.TSL: Invalid layout type.' ); + + } + + layout = null; + + } + + } + + const shaderNode = new ShaderNode( jsFunc, nodeType ); + + const fn = ( ...params ) => { + + let inputs; + + nodeObjects( params ); + + const isArrayAsParameter = params[ 0 ] && ( params[ 0 ].isNode || Object.getPrototypeOf( params[ 0 ] ) !== Object.prototype ); + + if ( isArrayAsParameter ) { + + inputs = [ ...params ]; + + } else { + + inputs = params[ 0 ]; + + } + + const fnCall = shaderNode.call( inputs ); + + if ( nodeType === 'void' ) fnCall.toStack(); + + return fnCall; + + }; + + fn.shaderNode = shaderNode; + fn.id = shaderNode.id; + + fn.isFn = true; + + fn.getNodeType = ( ...params ) => shaderNode.getNodeType( ...params ); + fn.getCacheKey = ( ...params ) => shaderNode.getCacheKey( ...params ); + + fn.setLayout = ( layout ) => { + + shaderNode.setLayout( layout ); + + return fn; + + }; + + fn.once = ( subBuilds = null ) => { + + shaderNode.once = true; + shaderNode.subBuilds = subBuilds; + + return fn; + + }; + + if ( layout !== null ) { + + if ( typeof layout.inputs !== 'object' ) { + + const fullLayout = { + name: 'fn' + fnId ++, + type: nodeType, + inputs: [] + }; + + for ( const name in layout ) { + + if ( name === 'return' ) continue; + + fullLayout.inputs.push( { + name: name, + type: layout[ name ] + } ); + + } + + layout = fullLayout; + + } + + fn.setLayout( layout ); + + } + + return fn; + +}; + +// + +export const setCurrentStack = ( stack ) => { + + if ( currentStack === stack ) { + + //throw new Error( 'Stack already defined.' ); + + } + + currentStack = stack; + +}; + +export const getCurrentStack = () => currentStack; + +/** + * Represent a conditional node using if/else statements. + * + * ```js + * If( condition, function ) + * .ElseIf( condition, function ) + * .Else( function ) + * ``` + * @tsl + * @function + * @param {...any} params - The parameters for the conditional node. + * @returns {StackNode} The conditional node. + */ +export const If = ( ...params ) => currentStack.If( ...params ); + +/** + * Represent a conditional node using switch/case statements. + * + * ```js + * Switch( value ) + * .Case( 1, function ) + * .Case( 2, 3, 4, function ) + * .Default( function ) + * ``` + * @tsl + * @function + * @param {...any} params - The parameters for the conditional node. + * @returns {StackNode} The conditional node. + */ +export const Switch = ( ...params ) => currentStack.Switch( ...params ); + +/** + * Add the given node to the current stack. + * + * @param {Node} node - The node to add. + * @returns {Node} The node that was added to the stack. + */ +export function Stack( node ) { + + if ( currentStack ) currentStack.add( node ); + + return node; + +} + +addMethodChaining( 'toStack', Stack ); + +// types + +final color = new ConvertType( 'color' ); + +final float = new ConvertType( 'float', cacheMaps.float ); +final int = new ConvertType( 'int', cacheMaps.ints ); +final uint = new ConvertType( 'uint', cacheMaps.uint ); +final bool = new ConvertType( 'bool', cacheMaps.bool ); + +final vec2 = new ConvertType( 'vec2' ); +final ivec2 = new ConvertType( 'ivec2' ); +final uvec2 = new ConvertType( 'uvec2' ); +final bvec2 = new ConvertType( 'bvec2' ); + +final vec3 = new ConvertType( 'vec3' ); +final ivec3 = new ConvertType( 'ivec3' ); +final uvec3 = new ConvertType( 'uvec3' ); +final bvec3 = new ConvertType( 'bvec3' ); + +final vec4 = new ConvertType( 'vec4' ); +final ivec4 = new ConvertType( 'ivec4' ); +final uvec4 = new ConvertType( 'uvec4' ); +final bvec4 = new ConvertType( 'bvec4' ); + +final mat2 = new ConvertType( 'mat2' ); +final mat3 = new ConvertType( 'mat3' ); +final mat4 = new ConvertType( 'mat4' ); + +final string = ( value = '' ) => nodeObject( new ConstNode( value, 'string' ) ); +final arrayBuffer = ( value ) => nodeObject( new ConstNode( value, 'ArrayBuffer' ) ); + +addMethodChaining( 'toColor', color ); +addMethodChaining( 'toFloat', float ); +addMethodChaining( 'toInt', int ); +addMethodChaining( 'toUint', uint ); +addMethodChaining( 'toBool', bool ); +addMethodChaining( 'toVec2', vec2 ); +addMethodChaining( 'toIVec2', ivec2 ); +addMethodChaining( 'toUVec2', uvec2 ); +addMethodChaining( 'toBVec2', bvec2 ); +addMethodChaining( 'toVec3', vec3 ); +addMethodChaining( 'toIVec3', ivec3 ); +addMethodChaining( 'toUVec3', uvec3 ); +addMethodChaining( 'toBVec3', bvec3 ); +addMethodChaining( 'toVec4', vec4 ); +addMethodChaining( 'toIVec4', ivec4 ); +addMethodChaining( 'toUVec4', uvec4 ); +addMethodChaining( 'toBVec4', bvec4 ); +addMethodChaining( 'toMat2', mat2 ); +addMethodChaining( 'toMat3', mat3 ); +addMethodChaining( 'toMat4', mat4 ); + +// basic nodes + +export const element = /*@__PURE__*/ nodeProxy( ArrayElementNode ).setParameterLength( 2 ); +export const convert = ( node, types ) => nodeObject( new ConvertNode( nodeObject( node ), types ) ); +export const split = ( node, channels ) => nodeObject( new SplitNode( nodeObject( node ), channels ) ); + +addMethodChaining( 'element', element ); +addMethodChaining( 'convert', convert ); + +// deprecated + +/** + * @tsl + * @function + * @deprecated since r176. Use {@link Stack} instead. + * + * @param {Node} node - The node to add. + * @returns {Function} + */ +append( node ){ // @deprecated, r176 + + console.warn( 'THREE.TSL: append() has been renamed to Stack().' ); + return Stack( node ); + +} + +addMethodChaining( 'append', ( node ){ // @deprecated, r176 + console.warn( 'THREE.TSL: .append() has been renamed to .toStack().' ); + return Stack( node ); +} ); + diff --git a/packages/three_js_gpu/lib/utils/WebGPUPipelineUtils.js b/packages/three_js_gpu/lib/utils/WebGPUPipelineUtils.js deleted file mode 100644 index 741589c1..00000000 --- a/packages/three_js_gpu/lib/utils/WebGPUPipelineUtils.js +++ /dev/null @@ -1,789 +0,0 @@ -import { BlendColorFactor, OneMinusBlendColorFactor, } from '../../common/Constants.js'; - -import { - GPUFrontFace, GPUCullMode, GPUColorWriteFlags, GPUCompareFunction, GPUBlendFactor, GPUBlendOperation, GPUIndexFormat, GPUStencilOperation -} from './WebGPUConstants.js'; - -import { - FrontSide, BackSide, DoubleSide, - NeverDepth, AlwaysDepth, LessDepth, LessEqualDepth, EqualDepth, GreaterEqualDepth, GreaterDepth, NotEqualDepth, - NoBlending, NormalBlending, AdditiveBlending, SubtractiveBlending, MultiplyBlending, CustomBlending, - ZeroFactor, OneFactor, SrcColorFactor, OneMinusSrcColorFactor, SrcAlphaFactor, OneMinusSrcAlphaFactor, DstColorFactor, - OneMinusDstColorFactor, DstAlphaFactor, OneMinusDstAlphaFactor, SrcAlphaSaturateFactor, - AddEquation, SubtractEquation, ReverseSubtractEquation, MinEquation, MaxEquation, - KeepStencilOp, ZeroStencilOp, ReplaceStencilOp, InvertStencilOp, IncrementStencilOp, DecrementStencilOp, IncrementWrapStencilOp, DecrementWrapStencilOp, - NeverStencilFunc, AlwaysStencilFunc, LessStencilFunc, LessEqualStencilFunc, EqualStencilFunc, GreaterEqualStencilFunc, GreaterStencilFunc, NotEqualStencilFunc -} from '../../../constants.js'; - -/** - * A WebGPU backend utility module for managing pipelines. - * - * @private - */ -class WebGPUPipelineUtils { - - /** - * Constructs a new utility object. - * - * @param {WebGPUBackend} backend - The WebGPU backend. - */ - constructor( backend ) { - - /** - * A reference to the WebGPU backend. - * - * @type {WebGPUBackend} - */ - this.backend = backend; - - /** - * A Weak Map that tracks the active pipeline for render or compute passes. - * - * @private - * @type {WeakMap<(GPURenderPassEncoder|GPUComputePassEncoder),(GPURenderPipeline|GPUComputePipeline)>} - */ - this._activePipelines = new WeakMap(); - - } - - /** - * Sets the given pipeline for the given pass. The method makes sure to only set the - * pipeline when necessary. - * - * @param {(GPURenderPassEncoder|GPUComputePassEncoder)} pass - The pass encoder. - * @param {(GPURenderPipeline|GPUComputePipeline)} pipeline - The pipeline. - */ - setPipeline( pass, pipeline ) { - - const currentPipeline = this._activePipelines.get( pass ); - - if ( currentPipeline !== pipeline ) { - - pass.setPipeline( pipeline ); - - this._activePipelines.set( pass, pipeline ); - - } - - } - - /** - * Returns the sample count derived from the given render context. - * - * @private - * @param {RenderContext} renderContext - The render context. - * @return {number} The sample count. - */ - _getSampleCount( renderContext ) { - - return this.backend.utils.getSampleCountRenderContext( renderContext ); - - } - - /** - * Creates a render pipeline for the given render object. - * - * @param {RenderObject} renderObject - The render object. - * @param {Array} promises - An array of compilation promises which are used in `compileAsync()`. - */ - createRenderPipeline( renderObject, promises ) { - - const { object, material, geometry, pipeline } = renderObject; - const { vertexProgram, fragmentProgram } = pipeline; - - const backend = this.backend; - const device = backend.device; - const utils = backend.utils; - - const pipelineData = backend.get( pipeline ); - - // bind group layouts - - const bindGroupLayouts = []; - - for ( const bindGroup of renderObject.getBindings() ) { - - const bindingsData = backend.get( bindGroup ); - - bindGroupLayouts.push( bindingsData.layout ); - - } - - // vertex buffers - - const vertexBuffers = backend.attributeUtils.createShaderVertexBuffers( renderObject ); - - // blending - - let blending; - - if ( material.blending !== NoBlending && ( material.blending !== NormalBlending || material.transparent !== false ) ) { - - blending = this._getBlending( material ); - - } - - // stencil - - let stencilFront = {}; - - if ( material.stencilWrite === true ) { - - stencilFront = { - compare: this._getStencilCompare( material ), - failOp: this._getStencilOperation( material.stencilFail ), - depthFailOp: this._getStencilOperation( material.stencilZFail ), - passOp: this._getStencilOperation( material.stencilZPass ) - }; - - } - - const colorWriteMask = this._getColorWriteMask( material ); - - const targets = []; - - if ( renderObject.context.textures !== null ) { - - const textures = renderObject.context.textures; - - for ( let i = 0; i < textures.length; i ++ ) { - - const colorFormat = utils.getTextureFormatGPU( textures[ i ] ); - - targets.push( { - format: colorFormat, - blend: blending, - writeMask: colorWriteMask - } ); - - } - - } else { - - const colorFormat = utils.getCurrentColorFormat( renderObject.context ); - - targets.push( { - format: colorFormat, - blend: blending, - writeMask: colorWriteMask - } ); - - } - - const vertexModule = backend.get( vertexProgram ).module; - const fragmentModule = backend.get( fragmentProgram ).module; - - const primitiveState = this._getPrimitiveState( object, geometry, material ); - const depthCompare = this._getDepthCompare( material ); - const depthStencilFormat = utils.getCurrentDepthStencilFormat( renderObject.context ); - - const sampleCount = this._getSampleCount( renderObject.context ); - - const pipelineDescriptor = { - label: `renderPipeline_${ material.name || material.type }_${ material.id }`, - vertex: Object.assign( {}, vertexModule, { buffers: vertexBuffers } ), - fragment: Object.assign( {}, fragmentModule, { targets } ), - primitive: primitiveState, - multisample: { - count: sampleCount, - alphaToCoverageEnabled: material.alphaToCoverage && sampleCount > 1 - }, - layout: device.createPipelineLayout( { - bindGroupLayouts - } ) - }; - - - const depthStencil = {}; - const renderDepth = renderObject.context.depth; - const renderStencil = renderObject.context.stencil; - - if ( renderDepth === true || renderStencil === true ) { - - if ( renderDepth === true ) { - - depthStencil.format = depthStencilFormat; - depthStencil.depthWriteEnabled = material.depthWrite; - depthStencil.depthCompare = depthCompare; - - } - - if ( renderStencil === true ) { - - depthStencil.stencilFront = stencilFront; - depthStencil.stencilBack = {}; // three.js does not provide an API to configure the back function (gl.stencilFuncSeparate() was never used) - depthStencil.stencilReadMask = material.stencilFuncMask; - depthStencil.stencilWriteMask = material.stencilWriteMask; - - } - - if ( material.polygonOffset === true ) { - - depthStencil.depthBias = material.polygonOffsetUnits; - depthStencil.depthBiasSlopeScale = material.polygonOffsetFactor; - depthStencil.depthBiasClamp = 0; // three.js does not provide an API to configure this value - - } - - pipelineDescriptor.depthStencil = depthStencil; - - } - - - if ( promises === null ) { - - pipelineData.pipeline = device.createRenderPipeline( pipelineDescriptor ); - - } else { - - const p = new Promise( ( resolve /*, reject*/ ) => { - - device.createRenderPipelineAsync( pipelineDescriptor ).then( pipeline => { - - pipelineData.pipeline = pipeline; - resolve(); - - } ); - - } ); - - promises.push( p ); - - } - - } - - /** - * Creates GPU render bundle encoder for the given render context. - * - * @param {RenderContext} renderContext - The render context. - * @param {?string} [label='renderBundleEncoder'] - The label. - * @return {GPURenderBundleEncoder} The GPU render bundle encoder. - */ - createBundleEncoder( renderContext, label = 'renderBundleEncoder' ) { - - const backend = this.backend; - const { utils, device } = backend; - - const depthStencilFormat = utils.getCurrentDepthStencilFormat( renderContext ); - const colorFormat = utils.getCurrentColorFormat( renderContext ); - const sampleCount = this._getSampleCount( renderContext ); - - const descriptor = { - label: label, - colorFormats: [ colorFormat ], - depthStencilFormat, - sampleCount - }; - - return device.createRenderBundleEncoder( descriptor ); - - } - - /** - * Creates a compute pipeline for the given compute node. - * - * @param {ComputePipeline} pipeline - The compute pipeline. - * @param {Array} bindings - The bindings. - */ - createComputePipeline( pipeline, bindings ) { - - const backend = this.backend; - const device = backend.device; - - const computeProgram = backend.get( pipeline.computeProgram ).module; - - const pipelineGPU = backend.get( pipeline ); - - // bind group layouts - - const bindGroupLayouts = []; - - for ( const bindingsGroup of bindings ) { - - const bindingsData = backend.get( bindingsGroup ); - - bindGroupLayouts.push( bindingsData.layout ); - - } - - pipelineGPU.pipeline = device.createComputePipeline( { - compute: computeProgram, - layout: device.createPipelineLayout( { - bindGroupLayouts - } ) - } ); - - } - - /** - * Returns the blending state as a descriptor object required - * for the pipeline creation. - * - * @private - * @param {Material} material - The material. - * @return {Object} The blending state. - */ - _getBlending( material ) { - - let color, alpha; - - const blending = material.blending; - const blendSrc = material.blendSrc; - const blendDst = material.blendDst; - const blendEquation = material.blendEquation; - - - if ( blending === CustomBlending ) { - - const blendSrcAlpha = material.blendSrcAlpha !== null ? material.blendSrcAlpha : blendSrc; - const blendDstAlpha = material.blendDstAlpha !== null ? material.blendDstAlpha : blendDst; - const blendEquationAlpha = material.blendEquationAlpha !== null ? material.blendEquationAlpha : blendEquation; - - color = { - srcFactor: this._getBlendFactor( blendSrc ), - dstFactor: this._getBlendFactor( blendDst ), - operation: this._getBlendOperation( blendEquation ) - }; - - alpha = { - srcFactor: this._getBlendFactor( blendSrcAlpha ), - dstFactor: this._getBlendFactor( blendDstAlpha ), - operation: this._getBlendOperation( blendEquationAlpha ) - }; - - } else { - - const premultipliedAlpha = material.premultipliedAlpha; - - const setBlend = ( srcRGB, dstRGB, srcAlpha, dstAlpha ) => { - - color = { - srcFactor: srcRGB, - dstFactor: dstRGB, - operation: GPUBlendOperation.Add - }; - - alpha = { - srcFactor: srcAlpha, - dstFactor: dstAlpha, - operation: GPUBlendOperation.Add - }; - - }; - - if ( premultipliedAlpha ) { - - switch ( blending ) { - - case NormalBlending: - setBlend( GPUBlendFactor.One, GPUBlendFactor.OneMinusSrcAlpha, GPUBlendFactor.One, GPUBlendFactor.OneMinusSrcAlpha ); - break; - - case AdditiveBlending: - setBlend( GPUBlendFactor.One, GPUBlendFactor.One, GPUBlendFactor.One, GPUBlendFactor.One ); - break; - - case SubtractiveBlending: - setBlend( GPUBlendFactor.Zero, GPUBlendFactor.OneMinusSrc, GPUBlendFactor.Zero, GPUBlendFactor.One ); - break; - - case MultiplyBlending: - setBlend( GPUBlendFactor.Dst, GPUBlendFactor.OneMinusSrcAlpha, GPUBlendFactor.Zero, GPUBlendFactor.One ); - break; - - } - - } else { - - switch ( blending ) { - - case NormalBlending: - setBlend( GPUBlendFactor.SrcAlpha, GPUBlendFactor.OneMinusSrcAlpha, GPUBlendFactor.One, GPUBlendFactor.OneMinusSrcAlpha ); - break; - - case AdditiveBlending: - setBlend( GPUBlendFactor.SrcAlpha, GPUBlendFactor.One, GPUBlendFactor.One, GPUBlendFactor.One ); - break; - - case SubtractiveBlending: - console.error( 'THREE.WebGPURenderer: SubtractiveBlending requires material.premultipliedAlpha = true' ); - break; - - case MultiplyBlending: - console.error( 'THREE.WebGPURenderer: MultiplyBlending requires material.premultipliedAlpha = true' ); - break; - - } - - } - - } - - if ( color !== undefined && alpha !== undefined ) { - - return { color, alpha }; - - } else { - - console.error( 'THREE.WebGPURenderer: Invalid blending: ', blending ); - - } - - } - /** - * Returns the GPU blend factor which is required for the pipeline creation. - * - * @private - * @param {number} blend - The blend factor as a three.js constant. - * @return {string} The GPU blend factor. - */ - _getBlendFactor( blend ) { - - let blendFactor; - - switch ( blend ) { - - case ZeroFactor: - blendFactor = GPUBlendFactor.Zero; - break; - - case OneFactor: - blendFactor = GPUBlendFactor.One; - break; - - case SrcColorFactor: - blendFactor = GPUBlendFactor.Src; - break; - - case OneMinusSrcColorFactor: - blendFactor = GPUBlendFactor.OneMinusSrc; - break; - - case SrcAlphaFactor: - blendFactor = GPUBlendFactor.SrcAlpha; - break; - - case OneMinusSrcAlphaFactor: - blendFactor = GPUBlendFactor.OneMinusSrcAlpha; - break; - - case DstColorFactor: - blendFactor = GPUBlendFactor.Dst; - break; - - case OneMinusDstColorFactor: - blendFactor = GPUBlendFactor.OneMinusDst; - break; - - case DstAlphaFactor: - blendFactor = GPUBlendFactor.DstAlpha; - break; - - case OneMinusDstAlphaFactor: - blendFactor = GPUBlendFactor.OneMinusDstAlpha; - break; - - case SrcAlphaSaturateFactor: - blendFactor = GPUBlendFactor.SrcAlphaSaturated; - break; - - case BlendColorFactor: - blendFactor = GPUBlendFactor.Constant; - break; - - case OneMinusBlendColorFactor: - blendFactor = GPUBlendFactor.OneMinusConstant; - break; - - default: - console.error( 'THREE.WebGPURenderer: Blend factor not supported.', blend ); - - } - - return blendFactor; - - } - - /** - * Returns the GPU stencil compare function which is required for the pipeline creation. - * - * @private - * @param {Material} material - The material. - * @return {string} The GPU stencil compare function. - */ - _getStencilCompare( material ) { - - let stencilCompare; - - const stencilFunc = material.stencilFunc; - - switch ( stencilFunc ) { - - case NeverStencilFunc: - stencilCompare = GPUCompareFunction.Never; - break; - - case AlwaysStencilFunc: - stencilCompare = GPUCompareFunction.Always; - break; - - case LessStencilFunc: - stencilCompare = GPUCompareFunction.Less; - break; - - case LessEqualStencilFunc: - stencilCompare = GPUCompareFunction.LessEqual; - break; - - case EqualStencilFunc: - stencilCompare = GPUCompareFunction.Equal; - break; - - case GreaterEqualStencilFunc: - stencilCompare = GPUCompareFunction.GreaterEqual; - break; - - case GreaterStencilFunc: - stencilCompare = GPUCompareFunction.Greater; - break; - - case NotEqualStencilFunc: - stencilCompare = GPUCompareFunction.NotEqual; - break; - - default: - console.error( 'THREE.WebGPURenderer: Invalid stencil function.', stencilFunc ); - - } - - return stencilCompare; - - } - - /** - * Returns the GPU stencil operation which is required for the pipeline creation. - * - * @private - * @param {number} op - A three.js constant defining the stencil operation. - * @return {string} The GPU stencil operation. - */ - _getStencilOperation( op ) { - - let stencilOperation; - - switch ( op ) { - - case KeepStencilOp: - stencilOperation = GPUStencilOperation.Keep; - break; - - case ZeroStencilOp: - stencilOperation = GPUStencilOperation.Zero; - break; - - case ReplaceStencilOp: - stencilOperation = GPUStencilOperation.Replace; - break; - - case InvertStencilOp: - stencilOperation = GPUStencilOperation.Invert; - break; - - case IncrementStencilOp: - stencilOperation = GPUStencilOperation.IncrementClamp; - break; - - case DecrementStencilOp: - stencilOperation = GPUStencilOperation.DecrementClamp; - break; - - case IncrementWrapStencilOp: - stencilOperation = GPUStencilOperation.IncrementWrap; - break; - - case DecrementWrapStencilOp: - stencilOperation = GPUStencilOperation.DecrementWrap; - break; - - default: - console.error( 'THREE.WebGPURenderer: Invalid stencil operation.', stencilOperation ); - - } - - return stencilOperation; - - } - - /** - * Returns the GPU blend operation which is required for the pipeline creation. - * - * @private - * @param {number} blendEquation - A three.js constant defining the blend equation. - * @return {string} The GPU blend operation. - */ - _getBlendOperation( blendEquation ) { - - let blendOperation; - - switch ( blendEquation ) { - - case AddEquation: - blendOperation = GPUBlendOperation.Add; - break; - - case SubtractEquation: - blendOperation = GPUBlendOperation.Subtract; - break; - - case ReverseSubtractEquation: - blendOperation = GPUBlendOperation.ReverseSubtract; - break; - - case MinEquation: - blendOperation = GPUBlendOperation.Min; - break; - - case MaxEquation: - blendOperation = GPUBlendOperation.Max; - break; - - default: - console.error( 'THREE.WebGPUPipelineUtils: Blend equation not supported.', blendEquation ); - - } - - return blendOperation; - - } - - /** - * Returns the primitive state as a descriptor object required - * for the pipeline creation. - * - * @private - * @param {Object3D} object - The 3D object. - * @param {BufferGeometry} geometry - The geometry. - * @param {Material} material - The material. - * @return {Object} The primitive state. - */ - _getPrimitiveState( object, geometry, material ) { - - const descriptor = {}; - const utils = this.backend.utils; - - descriptor.topology = utils.getPrimitiveTopology( object, material ); - - if ( geometry.index !== null && object.isLine === true && object.isLineSegments !== true ) { - - descriptor.stripIndexFormat = ( geometry.index.array instanceof Uint16Array ) ? GPUIndexFormat.Uint16 : GPUIndexFormat.Uint32; - - } - - switch ( material.side ) { - - case FrontSide: - descriptor.frontFace = GPUFrontFace.CCW; - descriptor.cullMode = GPUCullMode.Back; - break; - - case BackSide: - descriptor.frontFace = GPUFrontFace.CCW; - descriptor.cullMode = GPUCullMode.Front; - break; - - case DoubleSide: - descriptor.frontFace = GPUFrontFace.CCW; - descriptor.cullMode = GPUCullMode.None; - break; - - default: - console.error( 'THREE.WebGPUPipelineUtils: Unknown material.side value.', material.side ); - break; - - } - - return descriptor; - - } - - /** - * Returns the GPU color write mask which is required for the pipeline creation. - * - * @private - * @param {Material} material - The material. - * @return {string} The GPU color write mask. - */ - _getColorWriteMask( material ) { - - return ( material.colorWrite === true ) ? GPUColorWriteFlags.All : GPUColorWriteFlags.None; - - } - - /** - * Returns the GPU depth compare function which is required for the pipeline creation. - * - * @private - * @param {Material} material - The material. - * @return {string} The GPU depth compare function. - */ - _getDepthCompare( material ) { - - let depthCompare; - - if ( material.depthTest === false ) { - - depthCompare = GPUCompareFunction.Always; - - } else { - - const depthFunc = material.depthFunc; - - switch ( depthFunc ) { - - case NeverDepth: - depthCompare = GPUCompareFunction.Never; - break; - - case AlwaysDepth: - depthCompare = GPUCompareFunction.Always; - break; - - case LessDepth: - depthCompare = GPUCompareFunction.Less; - break; - - case LessEqualDepth: - depthCompare = GPUCompareFunction.LessEqual; - break; - - case EqualDepth: - depthCompare = GPUCompareFunction.Equal; - break; - - case GreaterEqualDepth: - depthCompare = GPUCompareFunction.GreaterEqual; - break; - - case GreaterDepth: - depthCompare = GPUCompareFunction.Greater; - break; - - case NotEqualDepth: - depthCompare = GPUCompareFunction.NotEqual; - break; - - default: - console.error( 'THREE.WebGPUPipelineUtils: Invalid depth function.', depthFunc ); - - } - - } - - return depthCompare; - - } - -} - -export default WebGPUPipelineUtils; diff --git a/packages/three_js_gpu/lib/utils/WebGPUTexturePassUtils.js b/packages/three_js_gpu/lib/utils/WebGPUTexturePassUtils.js deleted file mode 100644 index 36965f7d..00000000 --- a/packages/three_js_gpu/lib/utils/WebGPUTexturePassUtils.js +++ /dev/null @@ -1,439 +0,0 @@ -import DataMap from '../../common/DataMap.js'; -import { GPUTextureViewDimension, GPUIndexFormat, GPUFilterMode, GPUPrimitiveTopology, GPULoadOp, GPUStoreOp } from './WebGPUConstants.js'; - -/** - * A WebGPU backend utility module used by {@link WebGPUTextureUtils}. - * - * @private - */ -class WebGPUTexturePassUtils extends DataMap { - - /** - * Constructs a new utility object. - * - * @param {GPUDevice} device - The WebGPU device. - */ - constructor( device ) { - - super(); - - /** - * The WebGPU device. - * - * @type {GPUDevice} - */ - this.device = device; - - const mipmapVertexSource = ` -struct VarysStruct { - @builtin( position ) Position: vec4, - @location( 0 ) vTex : vec2 -}; - -@vertex -fn main( @builtin( vertex_index ) vertexIndex : u32 ) -> VarysStruct { - - var Varys : VarysStruct; - - var pos = array< vec2, 4 >( - vec2( -1.0, 1.0 ), - vec2( 1.0, 1.0 ), - vec2( -1.0, -1.0 ), - vec2( 1.0, -1.0 ) - ); - - var tex = array< vec2, 4 >( - vec2( 0.0, 0.0 ), - vec2( 1.0, 0.0 ), - vec2( 0.0, 1.0 ), - vec2( 1.0, 1.0 ) - ); - - Varys.vTex = tex[ vertexIndex ]; - Varys.Position = vec4( pos[ vertexIndex ], 0.0, 1.0 ); - - return Varys; - -} -`; - - const mipmapFragmentSource = ` -@group( 0 ) @binding( 0 ) -var imgSampler : sampler; - -@group( 0 ) @binding( 1 ) -var img : texture_2d; - -@fragment -fn main( @location( 0 ) vTex : vec2 ) -> @location( 0 ) vec4 { - - return textureSample( img, imgSampler, vTex ); - -} -`; - - const flipYFragmentSource = ` -@group( 0 ) @binding( 0 ) -var imgSampler : sampler; - -@group( 0 ) @binding( 1 ) -var img : texture_2d; - -@fragment -fn main( @location( 0 ) vTex : vec2 ) -> @location( 0 ) vec4 { - - return textureSample( img, imgSampler, vec2( vTex.x, 1.0 - vTex.y ) ); - -} -`; - - /** - * The mipmap GPU sampler. - * - * @type {GPUSampler} - */ - this.mipmapSampler = device.createSampler( { minFilter: GPUFilterMode.Linear } ); - - /** - * The flipY GPU sampler. - * - * @type {GPUSampler} - */ - this.flipYSampler = device.createSampler( { minFilter: GPUFilterMode.Nearest } ); //@TODO?: Consider using textureLoad() - - /** - * A cache for GPU render pipelines used for copy/transfer passes. - * Every texture format requires a unique pipeline. - * - * @type {Object} - */ - this.transferPipelines = {}; - - /** - * A cache for GPU render pipelines used for flipY passes. - * Every texture format requires a unique pipeline. - * - * @type {Object} - */ - this.flipYPipelines = {}; - - /** - * The mipmap vertex shader module. - * - * @type {GPUShaderModule} - */ - this.mipmapVertexShaderModule = device.createShaderModule( { - label: 'mipmapVertex', - code: mipmapVertexSource - } ); - - /** - * The mipmap fragment shader module. - * - * @type {GPUShaderModule} - */ - this.mipmapFragmentShaderModule = device.createShaderModule( { - label: 'mipmapFragment', - code: mipmapFragmentSource - } ); - - /** - * The flipY fragment shader module. - * - * @type {GPUShaderModule} - */ - this.flipYFragmentShaderModule = device.createShaderModule( { - label: 'flipYFragment', - code: flipYFragmentSource - } ); - - } - - /** - * Returns a render pipeline for the internal copy render pass. The pass - * requires a unique render pipeline for each texture format. - * - * @param {string} format - The GPU texture format - * @return {GPURenderPipeline} The GPU render pipeline. - */ - getTransferPipeline( format ) { - - let pipeline = this.transferPipelines[ format ]; - - if ( pipeline === undefined ) { - - pipeline = this.device.createRenderPipeline( { - label: `mipmap-${ format }`, - vertex: { - module: this.mipmapVertexShaderModule, - entryPoint: 'main' - }, - fragment: { - module: this.mipmapFragmentShaderModule, - entryPoint: 'main', - targets: [ { format } ] - }, - primitive: { - topology: GPUPrimitiveTopology.TriangleStrip, - stripIndexFormat: GPUIndexFormat.Uint32 - }, - layout: 'auto' - } ); - - this.transferPipelines[ format ] = pipeline; - - } - - return pipeline; - - } - - /** - * Returns a render pipeline for the flipY render pass. The pass - * requires a unique render pipeline for each texture format. - * - * @param {string} format - The GPU texture format - * @return {GPURenderPipeline} The GPU render pipeline. - */ - getFlipYPipeline( format ) { - - let pipeline = this.flipYPipelines[ format ]; - - if ( pipeline === undefined ) { - - pipeline = this.device.createRenderPipeline( { - label: `flipY-${ format }`, - vertex: { - module: this.mipmapVertexShaderModule, - entryPoint: 'main' - }, - fragment: { - module: this.flipYFragmentShaderModule, - entryPoint: 'main', - targets: [ { format } ] - }, - primitive: { - topology: GPUPrimitiveTopology.TriangleStrip, - stripIndexFormat: GPUIndexFormat.Uint32 - }, - layout: 'auto' - } ); - - this.flipYPipelines[ format ] = pipeline; - - } - - return pipeline; - - } - - /** - * Flip the contents of the given GPU texture along its vertical axis. - * - * @param {GPUTexture} textureGPU - The GPU texture object. - * @param {Object} textureGPUDescriptor - The texture descriptor. - * @param {number} [baseArrayLayer=0] - The index of the first array layer accessible to the texture view. - */ - flipY( textureGPU, textureGPUDescriptor, baseArrayLayer = 0 ) { - - const format = textureGPUDescriptor.format; - const { width, height } = textureGPUDescriptor.size; - - const transferPipeline = this.getTransferPipeline( format ); - const flipYPipeline = this.getFlipYPipeline( format ); - - const tempTexture = this.device.createTexture( { - size: { width, height, depthOrArrayLayers: 1 }, - format, - usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING - } ); - - const srcView = textureGPU.createView( { - baseMipLevel: 0, - mipLevelCount: 1, - dimension: GPUTextureViewDimension.TwoD, - baseArrayLayer - } ); - - const dstView = tempTexture.createView( { - baseMipLevel: 0, - mipLevelCount: 1, - dimension: GPUTextureViewDimension.TwoD, - baseArrayLayer: 0 - } ); - - const commandEncoder = this.device.createCommandEncoder( {} ); - - const pass = ( pipeline, sourceView, destinationView ) => { - - const bindGroupLayout = pipeline.getBindGroupLayout( 0 ); // @TODO: Consider making this static. - - const bindGroup = this.device.createBindGroup( { - layout: bindGroupLayout, - entries: [ { - binding: 0, - resource: this.flipYSampler - }, { - binding: 1, - resource: sourceView - } ] - } ); - - const passEncoder = commandEncoder.beginRenderPass( { - colorAttachments: [ { - view: destinationView, - loadOp: GPULoadOp.Clear, - storeOp: GPUStoreOp.Store, - clearValue: [ 0, 0, 0, 0 ] - } ] - } ); - - passEncoder.setPipeline( pipeline ); - passEncoder.setBindGroup( 0, bindGroup ); - passEncoder.draw( 4, 1, 0, 0 ); - passEncoder.end(); - - }; - - pass( transferPipeline, srcView, dstView ); - pass( flipYPipeline, dstView, srcView ); - - this.device.queue.submit( [ commandEncoder.finish() ] ); - - tempTexture.destroy(); - - } - - /** - * Generates mipmaps for the given GPU texture. - * - * @param {GPUTexture} textureGPU - The GPU texture object. - * @param {Object} textureGPUDescriptor - The texture descriptor. - * @param {number} [baseArrayLayer=0] - The index of the first array layer accessible to the texture view. - */ - generateMipmaps( textureGPU, textureGPUDescriptor, baseArrayLayer = 0 ) { - - const textureData = this.get( textureGPU ); - - if ( textureData.useCount === undefined ) { - - textureData.useCount = 0; - textureData.layers = []; - - } - - const passes = textureData.layers[ baseArrayLayer ] || this._mipmapCreateBundles( textureGPU, textureGPUDescriptor, baseArrayLayer ); - - const commandEncoder = this.device.createCommandEncoder( {} ); - - this._mipmapRunBundles( commandEncoder, passes ); - - this.device.queue.submit( [ commandEncoder.finish() ] ); - - if ( textureData.useCount !== 0 ) textureData.layers[ baseArrayLayer ] = passes; - - textureData.useCount ++; - - } - - /** - * Since multiple copy render passes are required to generate mipmaps, the passes - * are managed as render bundles to improve performance. - * - * @param {GPUTexture} textureGPU - The GPU texture object. - * @param {Object} textureGPUDescriptor - The texture descriptor. - * @param {number} baseArrayLayer - The index of the first array layer accessible to the texture view. - * @return {Array} An array of render bundles. - */ - _mipmapCreateBundles( textureGPU, textureGPUDescriptor, baseArrayLayer ) { - - const pipeline = this.getTransferPipeline( textureGPUDescriptor.format ); - - const bindGroupLayout = pipeline.getBindGroupLayout( 0 ); // @TODO: Consider making this static. - - let srcView = textureGPU.createView( { - baseMipLevel: 0, - mipLevelCount: 1, - dimension: GPUTextureViewDimension.TwoD, - baseArrayLayer - } ); - - const passes = []; - - for ( let i = 1; i < textureGPUDescriptor.mipLevelCount; i ++ ) { - - const bindGroup = this.device.createBindGroup( { - layout: bindGroupLayout, - entries: [ { - binding: 0, - resource: this.mipmapSampler - }, { - binding: 1, - resource: srcView - } ] - } ); - - const dstView = textureGPU.createView( { - baseMipLevel: i, - mipLevelCount: 1, - dimension: GPUTextureViewDimension.TwoD, - baseArrayLayer - } ); - - const passDescriptor = { - colorAttachments: [ { - view: dstView, - loadOp: GPULoadOp.Clear, - storeOp: GPUStoreOp.Store, - clearValue: [ 0, 0, 0, 0 ] - } ] - }; - - const passEncoder = this.device.createRenderBundleEncoder( { - colorFormats: [ textureGPUDescriptor.format ] - } ); - - passEncoder.setPipeline( pipeline ); - passEncoder.setBindGroup( 0, bindGroup ); - passEncoder.draw( 4, 1, 0, 0 ); - - passes.push( { - renderBundles: [ passEncoder.finish() ], - passDescriptor - } ); - - srcView = dstView; - - } - - return passes; - - } - - /** - * Executes the render bundles. - * - * @param {GPUCommandEncoder} commandEncoder - The GPU command encoder. - * @param {Array} passes - An array of render bundles. - */ - _mipmapRunBundles( commandEncoder, passes ) { - - const levels = passes.length; - - for ( let i = 0; i < levels; i ++ ) { - - const pass = passes[ i ]; - - const passEncoder = commandEncoder.beginRenderPass( pass.passDescriptor ); - - passEncoder.executeBundles( pass.renderBundles ); - - passEncoder.end(); - - } - - } - -} - -export default WebGPUTexturePassUtils; diff --git a/packages/three_js_gpu/lib/utils/WebGPUTextureUtils.js b/packages/three_js_gpu/lib/utils/WebGPUTextureUtils.js deleted file mode 100644 index 7a00c95c..00000000 --- a/packages/three_js_gpu/lib/utils/WebGPUTextureUtils.js +++ /dev/null @@ -1,1415 +0,0 @@ -import { - GPUTextureFormat, GPUAddressMode, GPUFilterMode, GPUTextureDimension, GPUFeatureName, GPUTextureViewDimension -} from './WebGPUConstants.js'; -import { ColorManagement } from '../../../math/ColorManagement.js'; - -import WebGPUTexturePassUtils from './WebGPUTexturePassUtils.js'; - -import { - ByteType, ShortType, - NearestFilter, NearestMipmapNearestFilter, NearestMipmapLinearFilter, - RepeatWrapping, MirroredRepeatWrapping, - RGB_ETC2_Format, RGBA_ETC2_EAC_Format, - RGBAFormat, RGBFormat, RedFormat, RGFormat, RGBA_S3TC_DXT1_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT5_Format, UnsignedByteType, FloatType, HalfFloatType, SRGBTransfer, DepthFormat, DepthStencilFormat, - 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, UnsignedIntType, UnsignedShortType, UnsignedInt248Type, UnsignedInt5999Type, - NeverCompare, AlwaysCompare, LessCompare, LessEqualCompare, EqualCompare, GreaterEqualCompare, GreaterCompare, NotEqualCompare, IntType, RedIntegerFormat, RGIntegerFormat, RGBAIntegerFormat -} from '../../../constants.js'; -import { CubeTexture } from '../../../textures/CubeTexture.js'; -import { DepthTexture } from '../../../textures/DepthTexture.js'; -import { Texture } from '../../../textures/Texture.js'; - -const _compareToWebGPU = { - [ NeverCompare ]: 'never', - [ LessCompare ]: 'less', - [ EqualCompare ]: 'equal', - [ LessEqualCompare ]: 'less-equal', - [ GreaterCompare ]: 'greater', - [ GreaterEqualCompare ]: 'greater-equal', - [ AlwaysCompare ]: 'always', - [ NotEqualCompare ]: 'not-equal' -}; - -const _flipMap = [ 0, 1, 3, 2, 4, 5 ]; - -/** - * A WebGPU backend utility module for managing textures. - * - * @private - */ -class WebGPUTextureUtils { - - /** - * Constructs a new utility object. - * - * @param {WebGPUBackend} backend - The WebGPU backend. - */ - constructor( backend ) { - - /** - * A reference to the WebGPU backend. - * - * @type {WebGPUBackend} - */ - this.backend = backend; - - /** - * A reference to the pass utils. - * - * @type {?WebGPUTexturePassUtils} - * @default null - */ - this._passUtils = null; - - /** - * A dictionary for managing default textures. The key - * is the texture format, the value the texture object. - * - * @type {Object} - */ - this.defaultTexture = {}; - - /** - * A dictionary for managing default cube textures. The key - * is the texture format, the value the texture object. - * - * @type {Object} - */ - this.defaultCubeTexture = {}; - - /** - * A default video frame. - * - * @type {?VideoFrame} - * @default null - */ - this.defaultVideoFrame = null; - - /** - * Represents the color attachment of the default framebuffer. - * - * @type {?GPUTexture} - * @default null - */ - this.colorBuffer = null; - - /** - * Represents the depth attachment of the default framebuffer. - * - * @type {DepthTexture} - */ - this.depthTexture = new DepthTexture(); - this.depthTexture.name = 'depthBuffer'; - - } - - /** - * Creates a GPU sampler for the given texture. - * - * @param {Texture} texture - The texture to create the sampler for. - */ - createSampler( texture ) { - - const backend = this.backend; - const device = backend.device; - - const textureGPU = backend.get( texture ); - - const samplerDescriptorGPU = { - addressModeU: this._convertAddressMode( texture.wrapS ), - addressModeV: this._convertAddressMode( texture.wrapT ), - addressModeW: this._convertAddressMode( texture.wrapR ), - magFilter: this._convertFilterMode( texture.magFilter ), - minFilter: this._convertFilterMode( texture.minFilter ), - mipmapFilter: this._convertFilterMode( texture.minFilter ), - maxAnisotropy: 1 - }; - - // anisotropy can only be used when all filter modes are set to linear. - - if ( samplerDescriptorGPU.magFilter === GPUFilterMode.Linear && samplerDescriptorGPU.minFilter === GPUFilterMode.Linear && samplerDescriptorGPU.mipmapFilter === GPUFilterMode.Linear ) { - - samplerDescriptorGPU.maxAnisotropy = texture.anisotropy; - - } - - if ( texture.isDepthTexture && texture.compareFunction !== null ) { - - samplerDescriptorGPU.compare = _compareToWebGPU[ texture.compareFunction ]; - - } - - textureGPU.sampler = device.createSampler( samplerDescriptorGPU ); - - } - - /** - * Creates a default texture for the given texture that can be used - * as a placeholder until the actual texture is ready for usage. - * - * @param {Texture} texture - The texture to create a default texture for. - */ - createDefaultTexture( texture ) { - - let textureGPU; - - const format = getFormat( texture ); - - if ( texture.isCubeTexture ) { - - textureGPU = this._getDefaultCubeTextureGPU( format ); - - } else { - - textureGPU = this._getDefaultTextureGPU( format ); - - } - - this.backend.get( texture ).texture = textureGPU; - - } - - /** - * Defines a texture on the GPU for the given texture object. - * - * @param {Texture} texture - The texture. - * @param {Object} [options={}] - Optional configuration parameter. - */ - createTexture( texture, options = {} ) { - - const backend = this.backend; - const textureData = backend.get( texture ); - - if ( textureData.initialized ) { - - throw new Error( 'WebGPUTextureUtils: Texture already initialized.' ); - - } - - if ( options.needsMipmaps === undefined ) options.needsMipmaps = false; - if ( options.levels === undefined ) options.levels = 1; - if ( options.depth === undefined ) options.depth = 1; - - const { width, height, depth, levels } = options; - - if ( texture.isFramebufferTexture ) { - - if ( options.renderTarget ) { - - options.format = this.backend.utils.getCurrentColorFormat( options.renderTarget ); - - } else { - - options.format = this.backend.utils.getPreferredCanvasFormat(); - - } - - } - - const dimension = this._getDimension( texture ); - const format = texture.internalFormat || options.format || getFormat( texture, backend.device ); - - textureData.format = format; - - const { samples, primarySamples, isMSAA } = backend.utils.getTextureSampleData( texture ); - - let usage = GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.COPY_SRC; - - if ( texture.isStorageTexture === true ) { - - usage |= GPUTextureUsage.STORAGE_BINDING; - - } - - if ( texture.isCompressedTexture !== true && texture.isCompressedArrayTexture !== true ) { - - usage |= GPUTextureUsage.RENDER_ATTACHMENT; - - } - - const textureDescriptorGPU = { - label: texture.name, - size: { - width: width, - height: height, - depthOrArrayLayers: depth, - }, - mipLevelCount: levels, - sampleCount: primarySamples, - dimension: dimension, - format: format, - usage: usage - }; - - // texture creation - - if ( format === undefined ) { - - console.warn( 'WebGPURenderer: Texture format not supported.' ); - - this.createDefaultTexture( texture ); - return; - - } - - if ( texture.isCubeTexture ) { - - textureDescriptorGPU.textureBindingViewDimension = GPUTextureViewDimension.Cube; - - } - - textureData.texture = backend.device.createTexture( textureDescriptorGPU ); - - if ( isMSAA ) { - - const msaaTextureDescriptorGPU = Object.assign( {}, textureDescriptorGPU ); - - msaaTextureDescriptorGPU.label = msaaTextureDescriptorGPU.label + '-msaa'; - msaaTextureDescriptorGPU.sampleCount = samples; - - textureData.msaaTexture = backend.device.createTexture( msaaTextureDescriptorGPU ); - - } - - textureData.initialized = true; - - textureData.textureDescriptorGPU = textureDescriptorGPU; - - } - - /** - * Destroys the GPU data for the given texture object. - * - * @param {Texture} texture - The texture. - */ - destroyTexture( texture ) { - - const backend = this.backend; - const textureData = backend.get( texture ); - - if ( textureData.texture !== undefined ) textureData.texture.destroy(); - - if ( textureData.msaaTexture !== undefined ) textureData.msaaTexture.destroy(); - - backend.delete( texture ); - - } - - /** - * Destroys the GPU sampler for the given texture. - * - * @param {Texture} texture - The texture to destroy the sampler for. - */ - destroySampler( texture ) { - - const backend = this.backend; - const textureData = backend.get( texture ); - - delete textureData.sampler; - - } - - /** - * Generates mipmaps for the given texture. - * - * @param {Texture} texture - The texture. - */ - generateMipmaps( texture ) { - - const textureData = this.backend.get( texture ); - - if ( texture.isCubeTexture ) { - - for ( let i = 0; i < 6; i ++ ) { - - this._generateMipmaps( textureData.texture, textureData.textureDescriptorGPU, i ); - - } - - } else { - - const depth = texture.image.depth || 1; - - for ( let i = 0; i < depth; i ++ ) { - - this._generateMipmaps( textureData.texture, textureData.textureDescriptorGPU, i ); - - } - - } - - } - - /** - * Returns the color buffer representing the color - * attachment of the default framebuffer. - * - * @return {GPUTexture} The color buffer. - */ - getColorBuffer() { - - if ( this.colorBuffer ) this.colorBuffer.destroy(); - - const backend = this.backend; - const { width, height } = backend.getDrawingBufferSize(); - - this.colorBuffer = backend.device.createTexture( { - label: 'colorBuffer', - size: { - width: width, - height: height, - depthOrArrayLayers: 1 - }, - sampleCount: backend.utils.getSampleCount( backend.renderer.samples ), - format: backend.utils.getPreferredCanvasFormat(), - usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC - } ); - - return this.colorBuffer; - - } - - /** - * Returns the depth buffer representing the depth - * attachment of the default framebuffer. - * - * @param {boolean} [depth=true] - Whether depth is enabled or not. - * @param {boolean} [stencil=false] - Whether stencil is enabled or not. - * @return {GPUTexture} The depth buffer. - */ - getDepthBuffer( depth = true, stencil = false ) { - - const backend = this.backend; - const { width, height } = backend.getDrawingBufferSize(); - - const depthTexture = this.depthTexture; - const depthTextureGPU = backend.get( depthTexture ).texture; - - let format, type; - - if ( stencil ) { - - format = DepthStencilFormat; - type = UnsignedInt248Type; - - } else if ( depth ) { - - format = DepthFormat; - type = UnsignedIntType; - - } - - if ( depthTextureGPU !== undefined ) { - - if ( depthTexture.image.width === width && depthTexture.image.height === height && depthTexture.format === format && depthTexture.type === type ) { - - return depthTextureGPU; - - } - - this.destroyTexture( depthTexture ); - - } - - depthTexture.name = 'depthBuffer'; - depthTexture.format = format; - depthTexture.type = type; - depthTexture.image.width = width; - depthTexture.image.height = height; - - this.createTexture( depthTexture, { width, height } ); - - return backend.get( depthTexture ).texture; - - } - - /** - * Uploads the updated texture data to the GPU. - * - * @param {Texture} texture - The texture. - * @param {Object} [options={}] - Optional configuration parameter. - */ - updateTexture( texture, options ) { - - const textureData = this.backend.get( texture ); - - const { textureDescriptorGPU } = textureData; - - if ( texture.isRenderTargetTexture || ( textureDescriptorGPU === undefined /* unsupported texture format */ ) ) - return; - - // transfer texture data - - if ( texture.isDataTexture ) { - - this._copyBufferToTexture( options.image, textureData.texture, textureDescriptorGPU, 0, texture.flipY ); - - } else if ( texture.isArrayTexture || texture.isDataArrayTexture || texture.isData3DTexture ) { - - for ( let i = 0; i < options.image.depth; i ++ ) { - - this._copyBufferToTexture( options.image, textureData.texture, textureDescriptorGPU, i, texture.flipY, i ); - - } - - } else if ( texture.isCompressedTexture || texture.isCompressedArrayTexture ) { - - this._copyCompressedBufferToTexture( texture.mipmaps, textureData.texture, textureDescriptorGPU ); - - } else if ( texture.isCubeTexture ) { - - this._copyCubeMapToTexture( options.images, textureData.texture, textureDescriptorGPU, texture.flipY, texture.premultiplyAlpha ); - - } else { - - this._copyImageToTexture( options.image, textureData.texture, textureDescriptorGPU, 0, texture.flipY, texture.premultiplyAlpha ); - - } - - // - - textureData.version = texture.version; - - if ( texture.onUpdate ) texture.onUpdate( texture ); - - } - - /** - * Returns texture data as a typed array. - * - * @async - * @param {Texture} texture - The texture to copy. - * @param {number} x - The x coordinate of the copy origin. - * @param {number} y - The y coordinate of the copy origin. - * @param {number} width - The width of the copy. - * @param {number} height - The height of the copy. - * @param {number} faceIndex - The face index. - * @return {Promise} A Promise that resolves with a typed array when the copy operation has finished. - */ - async copyTextureToBuffer( texture, x, y, width, height, faceIndex ) { - - const device = this.backend.device; - - const textureData = this.backend.get( texture ); - const textureGPU = textureData.texture; - const format = textureData.textureDescriptorGPU.format; - const bytesPerTexel = this._getBytesPerTexel( format ); - - let bytesPerRow = width * bytesPerTexel; - bytesPerRow = Math.ceil( bytesPerRow / 256 ) * 256; // Align to 256 bytes - - const readBuffer = device.createBuffer( - { - size: width * height * bytesPerTexel, - usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ - } - ); - - const encoder = device.createCommandEncoder(); - - encoder.copyTextureToBuffer( - { - texture: textureGPU, - origin: { x, y, z: faceIndex }, - }, - { - buffer: readBuffer, - bytesPerRow: bytesPerRow - }, - { - width: width, - height: height - } - - ); - - const typedArrayType = this._getTypedArrayType( format ); - - device.queue.submit( [ encoder.finish() ] ); - - await readBuffer.mapAsync( GPUMapMode.READ ); - - const buffer = readBuffer.getMappedRange(); - - return new typedArrayType( buffer ); - - } - - /** - * Returns the default GPU texture for the given format. - * - * @private - * @param {string} format - The GPU format. - * @return {GPUTexture} The GPU texture. - */ - _getDefaultTextureGPU( format ) { - - let defaultTexture = this.defaultTexture[ format ]; - - if ( defaultTexture === undefined ) { - - const texture = new Texture(); - texture.minFilter = NearestFilter; - texture.magFilter = NearestFilter; - - this.createTexture( texture, { width: 1, height: 1, format } ); - - this.defaultTexture[ format ] = defaultTexture = texture; - - } - - return this.backend.get( defaultTexture ).texture; - - } - - /** - * Returns the default GPU cube texture for the given format. - * - * @private - * @param {string} format - The GPU format. - * @return {GPUTexture} The GPU texture. - */ - _getDefaultCubeTextureGPU( format ) { - - let defaultCubeTexture = this.defaultTexture[ format ]; - - if ( defaultCubeTexture === undefined ) { - - const texture = new CubeTexture(); - texture.minFilter = NearestFilter; - texture.magFilter = NearestFilter; - - this.createTexture( texture, { width: 1, height: 1, depth: 6 } ); - - this.defaultCubeTexture[ format ] = defaultCubeTexture = texture; - - } - - return this.backend.get( defaultCubeTexture ).texture; - - } - - /** - * Uploads cube texture image data to the GPU memory. - * - * @private - * @param {Array} images - The cube image data. - * @param {GPUTexture} textureGPU - The GPU texture. - * @param {Object} textureDescriptorGPU - The GPU texture descriptor. - * @param {boolean} flipY - Whether to flip texture data along their vertical axis or not. - * @param {boolean} premultiplyAlpha - Whether the texture should have its RGB channels premultiplied by the alpha channel or not. - */ - _copyCubeMapToTexture( images, textureGPU, textureDescriptorGPU, flipY, premultiplyAlpha ) { - - for ( let i = 0; i < 6; i ++ ) { - - const image = images[ i ]; - - const flipIndex = flipY === true ? _flipMap[ i ] : i; - - if ( image.isDataTexture ) { - - this._copyBufferToTexture( image.image, textureGPU, textureDescriptorGPU, flipIndex, flipY ); - - } else { - - this._copyImageToTexture( image, textureGPU, textureDescriptorGPU, flipIndex, flipY, premultiplyAlpha ); - - } - - } - - } - - /** - * Uploads texture image data to the GPU memory. - * - * @private - * @param {HTMLImageElement|ImageBitmap|HTMLCanvasElement} image - The image data. - * @param {GPUTexture} textureGPU - The GPU texture. - * @param {Object} textureDescriptorGPU - The GPU texture descriptor. - * @param {number} originDepth - The origin depth. - * @param {boolean} flipY - Whether to flip texture data along their vertical axis or not. - * @param {boolean} premultiplyAlpha - Whether the texture should have its RGB channels premultiplied by the alpha channel or not. - */ - _copyImageToTexture( image, textureGPU, textureDescriptorGPU, originDepth, flipY, premultiplyAlpha ) { - - const device = this.backend.device; - - device.queue.copyExternalImageToTexture( - { - source: image, - flipY: flipY - }, { - texture: textureGPU, - mipLevel: 0, - origin: { x: 0, y: 0, z: originDepth }, - premultipliedAlpha: premultiplyAlpha - }, { - width: textureDescriptorGPU.size.width, - height: textureDescriptorGPU.size.height, - depthOrArrayLayers: 1 - } - ); - - } - - /** - * Returns the pass utils singleton. - * - * @private - * @return {WebGPUTexturePassUtils} The utils instance. - */ - _getPassUtils() { - - let passUtils = this._passUtils; - - if ( passUtils === null ) { - - this._passUtils = passUtils = new WebGPUTexturePassUtils( this.backend.device ); - - } - - return passUtils; - - } - - /** - * Generates mipmaps for the given GPU texture. - * - * @private - * @param {GPUTexture} textureGPU - The GPU texture object. - * @param {Object} textureDescriptorGPU - The texture descriptor. - * @param {number} [baseArrayLayer=0] - The index of the first array layer accessible to the texture view. - */ - _generateMipmaps( textureGPU, textureDescriptorGPU, baseArrayLayer = 0 ) { - - this._getPassUtils().generateMipmaps( textureGPU, textureDescriptorGPU, baseArrayLayer ); - - } - - /** - * Flip the contents of the given GPU texture along its vertical axis. - * - * @private - * @param {GPUTexture} textureGPU - The GPU texture object. - * @param {Object} textureDescriptorGPU - The texture descriptor. - * @param {number} [originDepth=0] - The origin depth. - */ - _flipY( textureGPU, textureDescriptorGPU, originDepth = 0 ) { - - this._getPassUtils().flipY( textureGPU, textureDescriptorGPU, originDepth ); - - } - - /** - * Uploads texture buffer data to the GPU memory. - * - * @private - * @param {Object} image - An object defining the image buffer data. - * @param {GPUTexture} textureGPU - The GPU texture. - * @param {Object} textureDescriptorGPU - The GPU texture descriptor. - * @param {number} originDepth - The origin depth. - * @param {boolean} flipY - Whether to flip texture data along their vertical axis or not. - * @param {number} [depth=0] - TODO. - */ - _copyBufferToTexture( image, textureGPU, textureDescriptorGPU, originDepth, flipY, depth = 0 ) { - - // @TODO: Consider to use GPUCommandEncoder.copyBufferToTexture() - // @TODO: Consider to support valid buffer layouts with other formats like RGB - - const device = this.backend.device; - - const data = image.data; - - const bytesPerTexel = this._getBytesPerTexel( textureDescriptorGPU.format ); - const bytesPerRow = image.width * bytesPerTexel; - - device.queue.writeTexture( - { - texture: textureGPU, - mipLevel: 0, - origin: { x: 0, y: 0, z: originDepth } - }, - data, - { - offset: image.width * image.height * bytesPerTexel * depth, - bytesPerRow - }, - { - width: image.width, - height: image.height, - depthOrArrayLayers: 1 - } ); - - if ( flipY === true ) { - - this._flipY( textureGPU, textureDescriptorGPU, originDepth ); - - } - - } - - /** - * Uploads compressed texture data to the GPU memory. - * - * @private - * @param {Array} mipmaps - An array with mipmap data. - * @param {GPUTexture} textureGPU - The GPU texture. - * @param {Object} textureDescriptorGPU - The GPU texture descriptor. - */ - _copyCompressedBufferToTexture( mipmaps, textureGPU, textureDescriptorGPU ) { - - // @TODO: Consider to use GPUCommandEncoder.copyBufferToTexture() - - const device = this.backend.device; - - const blockData = this._getBlockData( textureDescriptorGPU.format ); - const isArrayTexture = textureDescriptorGPU.size.depthOrArrayLayers > 1; - - for ( let i = 0; i < mipmaps.length; i ++ ) { - - const mipmap = mipmaps[ i ]; - - const width = mipmap.width; - const height = mipmap.height; - const depth = isArrayTexture ? textureDescriptorGPU.size.depthOrArrayLayers : 1; - - const bytesPerRow = Math.ceil( width / blockData.width ) * blockData.byteLength; - const bytesPerImage = bytesPerRow * Math.ceil( height / blockData.height ); - - for ( let j = 0; j < depth; j ++ ) { - - device.queue.writeTexture( - { - texture: textureGPU, - mipLevel: i, - origin: { x: 0, y: 0, z: j } - }, - mipmap.data, - { - offset: j * bytesPerImage, - bytesPerRow, - rowsPerImage: Math.ceil( height / blockData.height ) - }, - { - width: Math.ceil( width / blockData.width ) * blockData.width, - height: Math.ceil( height / blockData.height ) * blockData.height, - depthOrArrayLayers: 1 - } - ); - - } - - } - - } - - /** - * This method is only relevant for compressed texture formats. It returns a block - * data descriptor for the given GPU compressed texture format. - * - * @private - * @param {string} format - The GPU compressed texture format. - * @return {Object} The block data descriptor. - */ - _getBlockData( format ) { - - if ( format === GPUTextureFormat.BC1RGBAUnorm || format === GPUTextureFormat.BC1RGBAUnormSRGB ) return { byteLength: 8, width: 4, height: 4 }; // DXT1 - if ( format === GPUTextureFormat.BC2RGBAUnorm || format === GPUTextureFormat.BC2RGBAUnormSRGB ) return { byteLength: 16, width: 4, height: 4 }; // DXT3 - if ( format === GPUTextureFormat.BC3RGBAUnorm || format === GPUTextureFormat.BC3RGBAUnormSRGB ) return { byteLength: 16, width: 4, height: 4 }; // DXT5 - if ( format === GPUTextureFormat.BC4RUnorm || format === GPUTextureFormat.BC4RSnorm ) return { byteLength: 8, width: 4, height: 4 }; // RGTC1 - if ( format === GPUTextureFormat.BC5RGUnorm || format === GPUTextureFormat.BC5RGSnorm ) return { byteLength: 16, width: 4, height: 4 }; // RGTC2 - if ( format === GPUTextureFormat.BC6HRGBUFloat || format === GPUTextureFormat.BC6HRGBFloat ) return { byteLength: 16, width: 4, height: 4 }; // BPTC (float) - if ( format === GPUTextureFormat.BC7RGBAUnorm || format === GPUTextureFormat.BC7RGBAUnormSRGB ) return { byteLength: 16, width: 4, height: 4 }; // BPTC (unorm) - - if ( format === GPUTextureFormat.ETC2RGB8Unorm || format === GPUTextureFormat.ETC2RGB8UnormSRGB ) return { byteLength: 8, width: 4, height: 4 }; - if ( format === GPUTextureFormat.ETC2RGB8A1Unorm || format === GPUTextureFormat.ETC2RGB8A1UnormSRGB ) return { byteLength: 8, width: 4, height: 4 }; - if ( format === GPUTextureFormat.ETC2RGBA8Unorm || format === GPUTextureFormat.ETC2RGBA8UnormSRGB ) return { byteLength: 16, width: 4, height: 4 }; - if ( format === GPUTextureFormat.EACR11Unorm ) return { byteLength: 8, width: 4, height: 4 }; - if ( format === GPUTextureFormat.EACR11Snorm ) return { byteLength: 8, width: 4, height: 4 }; - if ( format === GPUTextureFormat.EACRG11Unorm ) return { byteLength: 16, width: 4, height: 4 }; - if ( format === GPUTextureFormat.EACRG11Snorm ) return { byteLength: 16, width: 4, height: 4 }; - - if ( format === GPUTextureFormat.ASTC4x4Unorm || format === GPUTextureFormat.ASTC4x4UnormSRGB ) return { byteLength: 16, width: 4, height: 4 }; - if ( format === GPUTextureFormat.ASTC5x4Unorm || format === GPUTextureFormat.ASTC5x4UnormSRGB ) return { byteLength: 16, width: 5, height: 4 }; - if ( format === GPUTextureFormat.ASTC5x5Unorm || format === GPUTextureFormat.ASTC5x5UnormSRGB ) return { byteLength: 16, width: 5, height: 5 }; - if ( format === GPUTextureFormat.ASTC6x5Unorm || format === GPUTextureFormat.ASTC6x5UnormSRGB ) return { byteLength: 16, width: 6, height: 5 }; - if ( format === GPUTextureFormat.ASTC6x6Unorm || format === GPUTextureFormat.ASTC6x6UnormSRGB ) return { byteLength: 16, width: 6, height: 6 }; - if ( format === GPUTextureFormat.ASTC8x5Unorm || format === GPUTextureFormat.ASTC8x5UnormSRGB ) return { byteLength: 16, width: 8, height: 5 }; - if ( format === GPUTextureFormat.ASTC8x6Unorm || format === GPUTextureFormat.ASTC8x6UnormSRGB ) return { byteLength: 16, width: 8, height: 6 }; - if ( format === GPUTextureFormat.ASTC8x8Unorm || format === GPUTextureFormat.ASTC8x8UnormSRGB ) return { byteLength: 16, width: 8, height: 8 }; - if ( format === GPUTextureFormat.ASTC10x5Unorm || format === GPUTextureFormat.ASTC10x5UnormSRGB ) return { byteLength: 16, width: 10, height: 5 }; - if ( format === GPUTextureFormat.ASTC10x6Unorm || format === GPUTextureFormat.ASTC10x6UnormSRGB ) return { byteLength: 16, width: 10, height: 6 }; - if ( format === GPUTextureFormat.ASTC10x8Unorm || format === GPUTextureFormat.ASTC10x8UnormSRGB ) return { byteLength: 16, width: 10, height: 8 }; - if ( format === GPUTextureFormat.ASTC10x10Unorm || format === GPUTextureFormat.ASTC10x10UnormSRGB ) return { byteLength: 16, width: 10, height: 10 }; - if ( format === GPUTextureFormat.ASTC12x10Unorm || format === GPUTextureFormat.ASTC12x10UnormSRGB ) return { byteLength: 16, width: 12, height: 10 }; - if ( format === GPUTextureFormat.ASTC12x12Unorm || format === GPUTextureFormat.ASTC12x12UnormSRGB ) return { byteLength: 16, width: 12, height: 12 }; - - } - - /** - * Converts the three.js uv wrapping constants to GPU address mode constants. - * - * @private - * @param {number} value - The three.js constant defining a uv wrapping mode. - * @return {string} The GPU address mode. - */ - _convertAddressMode( value ) { - - let addressMode = GPUAddressMode.ClampToEdge; - - if ( value === RepeatWrapping ) { - - addressMode = GPUAddressMode.Repeat; - - } else if ( value === MirroredRepeatWrapping ) { - - addressMode = GPUAddressMode.MirrorRepeat; - - } - - return addressMode; - - } - - /** - * Converts the three.js filter constants to GPU filter constants. - * - * @private - * @param {number} value - The three.js constant defining a filter mode. - * @return {string} The GPU filter mode. - */ - _convertFilterMode( value ) { - - let filterMode = GPUFilterMode.Linear; - - if ( value === NearestFilter || value === NearestMipmapNearestFilter || value === NearestMipmapLinearFilter ) { - - filterMode = GPUFilterMode.Nearest; - - } - - return filterMode; - - } - - /** - * Returns the bytes-per-texel value for the given GPU texture format. - * - * @private - * @param {string} format - The GPU texture format. - * @return {number} The bytes-per-texel. - */ - _getBytesPerTexel( format ) { - - // 8-bit formats - if ( format === GPUTextureFormat.R8Unorm || - format === GPUTextureFormat.R8Snorm || - format === GPUTextureFormat.R8Uint || - format === GPUTextureFormat.R8Sint ) return 1; - - // 16-bit formats - if ( format === GPUTextureFormat.R16Uint || - format === GPUTextureFormat.R16Sint || - format === GPUTextureFormat.R16Float || - format === GPUTextureFormat.RG8Unorm || - format === GPUTextureFormat.RG8Snorm || - format === GPUTextureFormat.RG8Uint || - format === GPUTextureFormat.RG8Sint ) return 2; - - // 32-bit formats - if ( format === GPUTextureFormat.R32Uint || - format === GPUTextureFormat.R32Sint || - format === GPUTextureFormat.R32Float || - format === GPUTextureFormat.RG16Uint || - format === GPUTextureFormat.RG16Sint || - format === GPUTextureFormat.RG16Float || - format === GPUTextureFormat.RGBA8Unorm || - format === GPUTextureFormat.RGBA8UnormSRGB || - format === GPUTextureFormat.RGBA8Snorm || - format === GPUTextureFormat.RGBA8Uint || - format === GPUTextureFormat.RGBA8Sint || - format === GPUTextureFormat.BGRA8Unorm || - format === GPUTextureFormat.BGRA8UnormSRGB || - // Packed 32-bit formats - format === GPUTextureFormat.RGB9E5UFloat || - format === GPUTextureFormat.RGB10A2Unorm || - format === GPUTextureFormat.RG11B10UFloat || - format === GPUTextureFormat.Depth32Float || - format === GPUTextureFormat.Depth24Plus || - format === GPUTextureFormat.Depth24PlusStencil8 || - format === GPUTextureFormat.Depth32FloatStencil8 ) return 4; - - // 64-bit formats - if ( format === GPUTextureFormat.RG32Uint || - format === GPUTextureFormat.RG32Sint || - format === GPUTextureFormat.RG32Float || - format === GPUTextureFormat.RGBA16Uint || - format === GPUTextureFormat.RGBA16Sint || - format === GPUTextureFormat.RGBA16Float ) return 8; - - // 128-bit formats - if ( format === GPUTextureFormat.RGBA32Uint || - format === GPUTextureFormat.RGBA32Sint || - format === GPUTextureFormat.RGBA32Float ) return 16; - - - } - - /** - * Returns the corresponding typed array type for the given GPU texture format. - * - * @private - * @param {string} format - The GPU texture format. - * @return {TypedArray.constructor} The typed array type. - */ - _getTypedArrayType( format ) { - - if ( format === GPUTextureFormat.R8Uint ) return Uint8Array; - if ( format === GPUTextureFormat.R8Sint ) return Int8Array; - if ( format === GPUTextureFormat.R8Unorm ) return Uint8Array; - if ( format === GPUTextureFormat.R8Snorm ) return Int8Array; - if ( format === GPUTextureFormat.RG8Uint ) return Uint8Array; - if ( format === GPUTextureFormat.RG8Sint ) return Int8Array; - if ( format === GPUTextureFormat.RG8Unorm ) return Uint8Array; - if ( format === GPUTextureFormat.RG8Snorm ) return Int8Array; - if ( format === GPUTextureFormat.RGBA8Uint ) return Uint8Array; - if ( format === GPUTextureFormat.RGBA8Sint ) return Int8Array; - if ( format === GPUTextureFormat.RGBA8Unorm ) return Uint8Array; - if ( format === GPUTextureFormat.RGBA8Snorm ) return Int8Array; - - - if ( format === GPUTextureFormat.R16Uint ) return Uint16Array; - if ( format === GPUTextureFormat.R16Sint ) return Int16Array; - if ( format === GPUTextureFormat.RG16Uint ) return Uint16Array; - if ( format === GPUTextureFormat.RG16Sint ) return Int16Array; - if ( format === GPUTextureFormat.RGBA16Uint ) return Uint16Array; - if ( format === GPUTextureFormat.RGBA16Sint ) return Int16Array; - if ( format === GPUTextureFormat.R16Float ) return Uint16Array; - if ( format === GPUTextureFormat.RG16Float ) return Uint16Array; - if ( format === GPUTextureFormat.RGBA16Float ) return Uint16Array; - - - if ( format === GPUTextureFormat.R32Uint ) return Uint32Array; - if ( format === GPUTextureFormat.R32Sint ) return Int32Array; - if ( format === GPUTextureFormat.R32Float ) return Float32Array; - if ( format === GPUTextureFormat.RG32Uint ) return Uint32Array; - if ( format === GPUTextureFormat.RG32Sint ) return Int32Array; - if ( format === GPUTextureFormat.RG32Float ) return Float32Array; - if ( format === GPUTextureFormat.RGBA32Uint ) return Uint32Array; - if ( format === GPUTextureFormat.RGBA32Sint ) return Int32Array; - if ( format === GPUTextureFormat.RGBA32Float ) return Float32Array; - - if ( format === GPUTextureFormat.BGRA8Unorm ) return Uint8Array; - if ( format === GPUTextureFormat.BGRA8UnormSRGB ) return Uint8Array; - if ( format === GPUTextureFormat.RGB10A2Unorm ) return Uint32Array; - if ( format === GPUTextureFormat.RGB9E5UFloat ) return Uint32Array; - if ( format === GPUTextureFormat.RG11B10UFloat ) return Uint32Array; - - if ( format === GPUTextureFormat.Depth32Float ) return Float32Array; - if ( format === GPUTextureFormat.Depth24Plus ) return Uint32Array; - if ( format === GPUTextureFormat.Depth24PlusStencil8 ) return Uint32Array; - if ( format === GPUTextureFormat.Depth32FloatStencil8 ) return Float32Array; - - } - - /** - * Returns the GPU dimensions for the given texture. - * - * @private - * @param {Texture} texture - The texture. - * @return {string} The GPU dimension. - */ - _getDimension( texture ) { - - let dimension; - - if ( texture.is3DTexture || texture.isData3DTexture ) { - - dimension = GPUTextureDimension.ThreeD; - - } else { - - dimension = GPUTextureDimension.TwoD; - - } - - return dimension; - - } - -} - -/** - * Returns the GPU format for the given texture. - * - * @param {Texture} texture - The texture. - * @param {?GPUDevice} [device=null] - The GPU device which is used for feature detection. - * It is not necessary to apply the device for most formats. - * @return {string} The GPU format. - */ -export function getFormat( texture, device = null ) { - - const format = texture.format; - const type = texture.type; - const colorSpace = texture.colorSpace; - const transfer = ColorManagement.getTransfer( colorSpace ); - - let formatGPU; - - if ( texture.isCompressedTexture === true || texture.isCompressedArrayTexture === true ) { - - switch ( format ) { - - case RGBA_S3TC_DXT1_Format: - formatGPU = ( transfer === SRGBTransfer ) ? GPUTextureFormat.BC1RGBAUnormSRGB : GPUTextureFormat.BC1RGBAUnorm; - break; - - case RGBA_S3TC_DXT3_Format: - formatGPU = ( transfer === SRGBTransfer ) ? GPUTextureFormat.BC2RGBAUnormSRGB : GPUTextureFormat.BC2RGBAUnorm; - break; - - case RGBA_S3TC_DXT5_Format: - formatGPU = ( transfer === SRGBTransfer ) ? GPUTextureFormat.BC3RGBAUnormSRGB : GPUTextureFormat.BC3RGBAUnorm; - break; - - case RGB_ETC2_Format: - formatGPU = ( transfer === SRGBTransfer ) ? GPUTextureFormat.ETC2RGB8UnormSRGB : GPUTextureFormat.ETC2RGB8Unorm; - break; - - case RGBA_ETC2_EAC_Format: - formatGPU = ( transfer === SRGBTransfer ) ? GPUTextureFormat.ETC2RGBA8UnormSRGB : GPUTextureFormat.ETC2RGBA8Unorm; - break; - - case RGBA_ASTC_4x4_Format: - formatGPU = ( transfer === SRGBTransfer ) ? GPUTextureFormat.ASTC4x4UnormSRGB : GPUTextureFormat.ASTC4x4Unorm; - break; - - case RGBA_ASTC_5x4_Format: - formatGPU = ( transfer === SRGBTransfer ) ? GPUTextureFormat.ASTC5x4UnormSRGB : GPUTextureFormat.ASTC5x4Unorm; - break; - - case RGBA_ASTC_5x5_Format: - formatGPU = ( transfer === SRGBTransfer ) ? GPUTextureFormat.ASTC5x5UnormSRGB : GPUTextureFormat.ASTC5x5Unorm; - break; - - case RGBA_ASTC_6x5_Format: - formatGPU = ( transfer === SRGBTransfer ) ? GPUTextureFormat.ASTC6x5UnormSRGB : GPUTextureFormat.ASTC6x5Unorm; - break; - - case RGBA_ASTC_6x6_Format: - formatGPU = ( transfer === SRGBTransfer ) ? GPUTextureFormat.ASTC6x6UnormSRGB : GPUTextureFormat.ASTC6x6Unorm; - break; - - case RGBA_ASTC_8x5_Format: - formatGPU = ( transfer === SRGBTransfer ) ? GPUTextureFormat.ASTC8x5UnormSRGB : GPUTextureFormat.ASTC8x5Unorm; - break; - - case RGBA_ASTC_8x6_Format: - formatGPU = ( transfer === SRGBTransfer ) ? GPUTextureFormat.ASTC8x6UnormSRGB : GPUTextureFormat.ASTC8x6Unorm; - break; - - case RGBA_ASTC_8x8_Format: - formatGPU = ( transfer === SRGBTransfer ) ? GPUTextureFormat.ASTC8x8UnormSRGB : GPUTextureFormat.ASTC8x8Unorm; - break; - - case RGBA_ASTC_10x5_Format: - formatGPU = ( transfer === SRGBTransfer ) ? GPUTextureFormat.ASTC10x5UnormSRGB : GPUTextureFormat.ASTC10x5Unorm; - break; - - case RGBA_ASTC_10x6_Format: - formatGPU = ( transfer === SRGBTransfer ) ? GPUTextureFormat.ASTC10x6UnormSRGB : GPUTextureFormat.ASTC10x6Unorm; - break; - - case RGBA_ASTC_10x8_Format: - formatGPU = ( transfer === SRGBTransfer ) ? GPUTextureFormat.ASTC10x8UnormSRGB : GPUTextureFormat.ASTC10x8Unorm; - break; - - case RGBA_ASTC_10x10_Format: - formatGPU = ( transfer === SRGBTransfer ) ? GPUTextureFormat.ASTC10x10UnormSRGB : GPUTextureFormat.ASTC10x10Unorm; - break; - - case RGBA_ASTC_12x10_Format: - formatGPU = ( transfer === SRGBTransfer ) ? GPUTextureFormat.ASTC12x10UnormSRGB : GPUTextureFormat.ASTC12x10Unorm; - break; - - case RGBA_ASTC_12x12_Format: - formatGPU = ( transfer === SRGBTransfer ) ? GPUTextureFormat.ASTC12x12UnormSRGB : GPUTextureFormat.ASTC12x12Unorm; - break; - - case RGBAFormat: - formatGPU = ( transfer === SRGBTransfer ) ? GPUTextureFormat.RGBA8UnormSRGB : GPUTextureFormat.RGBA8Unorm; - break; - - default: - console.error( 'WebGPURenderer: Unsupported texture format.', format ); - - } - - } else { - - switch ( format ) { - - case RGBAFormat: - - switch ( type ) { - - case ByteType: - formatGPU = GPUTextureFormat.RGBA8Snorm; - break; - - case ShortType: - formatGPU = GPUTextureFormat.RGBA16Sint; - break; - - case UnsignedShortType: - formatGPU = GPUTextureFormat.RGBA16Uint; - break; - case UnsignedIntType: - formatGPU = GPUTextureFormat.RGBA32Uint; - break; - - case IntType: - formatGPU = GPUTextureFormat.RGBA32Sint; - break; - - case UnsignedByteType: - formatGPU = ( transfer === SRGBTransfer ) ? GPUTextureFormat.RGBA8UnormSRGB : GPUTextureFormat.RGBA8Unorm; - break; - - case HalfFloatType: - formatGPU = GPUTextureFormat.RGBA16Float; - break; - - case FloatType: - formatGPU = GPUTextureFormat.RGBA32Float; - break; - - default: - console.error( 'WebGPURenderer: Unsupported texture type with RGBAFormat.', type ); - - } - - break; - - case RGBFormat: - - switch ( type ) { - - case UnsignedInt5999Type: - formatGPU = GPUTextureFormat.RGB9E5UFloat; - break; - - default: - console.error( 'WebGPURenderer: Unsupported texture type with RGBFormat.', type ); - - } - - break; - - case RedFormat: - - switch ( type ) { - - case ByteType: - formatGPU = GPUTextureFormat.R8Snorm; - break; - - case ShortType: - formatGPU = GPUTextureFormat.R16Sint; - break; - - case UnsignedShortType: - formatGPU = GPUTextureFormat.R16Uint; - break; - - case UnsignedIntType: - formatGPU = GPUTextureFormat.R32Uint; - break; - - case IntType: - formatGPU = GPUTextureFormat.R32Sint; - break; - - case UnsignedByteType: - formatGPU = GPUTextureFormat.R8Unorm; - break; - - case HalfFloatType: - formatGPU = GPUTextureFormat.R16Float; - break; - - case FloatType: - formatGPU = GPUTextureFormat.R32Float; - break; - - default: - console.error( 'WebGPURenderer: Unsupported texture type with RedFormat.', type ); - - } - - break; - - case RGFormat: - - switch ( type ) { - - case ByteType: - formatGPU = GPUTextureFormat.RG8Snorm; - break; - - case ShortType: - formatGPU = GPUTextureFormat.RG16Sint; - break; - - case UnsignedShortType: - formatGPU = GPUTextureFormat.RG16Uint; - break; - - case UnsignedIntType: - formatGPU = GPUTextureFormat.RG32Uint; - break; - - case IntType: - formatGPU = GPUTextureFormat.RG32Sint; - break; - - case UnsignedByteType: - formatGPU = GPUTextureFormat.RG8Unorm; - break; - - case HalfFloatType: - formatGPU = GPUTextureFormat.RG16Float; - break; - - case FloatType: - formatGPU = GPUTextureFormat.RG32Float; - break; - - default: - console.error( 'WebGPURenderer: Unsupported texture type with RGFormat.', type ); - - } - - break; - - case DepthFormat: - - switch ( type ) { - - case UnsignedShortType: - formatGPU = GPUTextureFormat.Depth16Unorm; - break; - - case UnsignedIntType: - formatGPU = GPUTextureFormat.Depth24Plus; - break; - - case FloatType: - formatGPU = GPUTextureFormat.Depth32Float; - break; - - default: - console.error( 'WebGPURenderer: Unsupported texture type with DepthFormat.', type ); - - } - - break; - - case DepthStencilFormat: - - switch ( type ) { - - case UnsignedInt248Type: - formatGPU = GPUTextureFormat.Depth24PlusStencil8; - break; - - case FloatType: - - if ( device && device.features.has( GPUFeatureName.Depth32FloatStencil8 ) === false ) { - - console.error( 'WebGPURenderer: Depth textures with DepthStencilFormat + FloatType can only be used with the "depth32float-stencil8" GPU feature.' ); - - } - - formatGPU = GPUTextureFormat.Depth32FloatStencil8; - - break; - - default: - console.error( 'WebGPURenderer: Unsupported texture type with DepthStencilFormat.', type ); - - } - - break; - - case RedIntegerFormat: - - switch ( type ) { - - case IntType: - formatGPU = GPUTextureFormat.R32Sint; - break; - - case UnsignedIntType: - formatGPU = GPUTextureFormat.R32Uint; - break; - - default: - console.error( 'WebGPURenderer: Unsupported texture type with RedIntegerFormat.', type ); - - } - - break; - - case RGIntegerFormat: - - switch ( type ) { - - case IntType: - formatGPU = GPUTextureFormat.RG32Sint; - break; - - case UnsignedIntType: - formatGPU = GPUTextureFormat.RG32Uint; - break; - - default: - console.error( 'WebGPURenderer: Unsupported texture type with RGIntegerFormat.', type ); - - } - - break; - - case RGBAIntegerFormat: - - switch ( type ) { - - case IntType: - formatGPU = GPUTextureFormat.RGBA32Sint; - break; - - case UnsignedIntType: - formatGPU = GPUTextureFormat.RGBA32Uint; - break; - - default: - console.error( 'WebGPURenderer: Unsupported texture type with RGBAIntegerFormat.', type ); - - } - - break; - - default: - console.error( 'WebGPURenderer: Unsupported texture format.', format ); - - } - - } - - return formatGPU; - -} - -export default WebGPUTextureUtils; diff --git a/packages/three_js_gpu/lib/utils/web_gpu_pipeline_utils.dart b/packages/three_js_gpu/lib/utils/web_gpu_pipeline_utils.dart new file mode 100644 index 00000000..30993f20 --- /dev/null +++ b/packages/three_js_gpu/lib/utils/web_gpu_pipeline_utils.dart @@ -0,0 +1,759 @@ +import 'package:three_js_core/three_js_core.dart'; +import 'package:three_js_gpu/gpu_backend.dart'; +import 'package:three_js_math/three_js_math.dart'; + + +/// +/// A WebGPU backend utility module for managing pipelines. +/// +/// @private +/// +class WebGPUPipelineUtils { + WebGPUBackend backend; + WeakMap _activePipelines = WeakMap(); + + /// + /// Constructs a new utility object. + /// + /// @param {WebGPUBackend} backend - The WebGPU backend. + /// + WebGPUPipelineUtils( this.backend ); + + /// + /// Sets the given pipeline for the given pass. The method makes sure to only set the + /// pipeline when necessary. + /// + /// @param {(GPURenderPassEncoder|GPUComputePassEncoder)} pass - The pass encoder. + /// @param {(GPURenderPipeline|GPUComputePipeline)} pipeline - The pipeline. + /// + setPipeline( pass, pipeline ) { + + final currentPipeline = this._activePipelines.get( pass ); + + if ( currentPipeline != pipeline ) { + + pass.setPipeline( pipeline ); + + this._activePipelines.set( pass, pipeline ); + + } + + } + + /// + /// Returns the sample count derived from the given render context. + /// + /// @private + /// @param {RenderContext} renderContext - The render context. + /// @return {number} The sample count. + /// + _getSampleCount( renderContext ) { + + return this.backend.utils.getSampleCountRenderContext( renderContext ); + + } + + /// + /// Creates a render pipeline for the given render object. + /// + /// @param {RenderObject} renderObject - The render object. + /// @param {Array} promises - An array of compilation promises which are used in `compileAsync()`. + /// + createRenderPipeline( renderObject, promises ) { + + final object = renderObject.object; + final material = renderObject.material; + final geometry = renderObject.geometry; + final pipeline = renderObject.pipeline; + + final vertexProgram = pipeline.vertexProgram; + final fragmentProgram = pipeline.fragmentProgram; + + final backend = this.backend; + final device = backend.device; + final utils = backend.utils; + + final pipelineData = backend.get( pipeline ); + + // bind group layouts + + final bindGroupLayouts = []; + + for ( final bindGroup in renderObject.getBindings() ) { + + final bindingsData = backend.get( bindGroup ); + + bindGroupLayouts.add( bindingsData.layout ); + + } + + // vertex buffers + + final vertexBuffers = backend.attributeUtils.createShaderVertexBuffers( renderObject ); + + // blending + + var blending; + + if ( material.blending != NoBlending && ( material.blending != NormalBlending || material.transparent != false ) ) { + + blending = this._getBlending( material ); + + } + + // stencil + + Map stencilFront = {}; + + if ( material.stencilWrite == true ) { + + stencilFront = { + 'compare': this._getStencilCompare( material ), + 'failOp': this._getStencilOperation( material.stencilFail ), + 'depthFailOp': this._getStencilOperation( material.stencilZFail ), + 'passOp': this._getStencilOperation( material.stencilZPass ) + }; + + } + + final colorWriteMask = this._getColorWriteMask( material ); + + final targets = []; + + if ( renderObject.context.textures != null ) { + + final textures = renderObject.context.textures; + + for ( int i = 0; i < textures.length; i ++ ) { + + final colorFormat = utils.getTextureFormatGPU( textures[ i ] ); + + targets.add( { + 'format': colorFormat, + 'blend': blending, + 'writeMask': colorWriteMask + } ); + + } + + } else { + + final colorFormat = utils.getCurrentColorFormat( renderObject.context ); + + targets.add( { + 'format': colorFormat, + 'blend': blending, + 'writeMask': colorWriteMask + } ); + + } + + final vertexModule = backend.get( vertexProgram ).module; + final fragmentModule = backend.get( fragmentProgram ).module; + + final primitiveState = this._getPrimitiveState( object, geometry, material ); + final depthCompare = this._getDepthCompare( material ); + final depthStencilFormat = utils.getCurrentDepthStencilFormat( renderObject.context ); + + final sampleCount = this._getSampleCount( renderObject.context ); + + final pipelineDescriptor = { + 'label': 'renderPipeline_${ material.name || material.type }_${ material.id }', + 'vertex': Object.assign( {}, vertexModule, { 'buffers': vertexBuffers } ), + 'fragment': Object.assign( {}, fragmentModule, { 'targets': targets } ), + 'primitive': primitiveState, + 'multisample': { + 'count': sampleCount, + 'alphaToCoverageEnabled': material.alphaToCoverage && sampleCount > 1 + }, + 'layout': device.createPipelineLayout( { + 'bindGroupLayouts': bindGroupLayouts + } ) + }; + + + final Map depthStencil = {}; + final renderDepth = renderObject.context.depth; + final renderStencil = renderObject.context.stencil; + + if ( renderDepth == true || renderStencil == true ) { + + if ( renderDepth == true ) { + + depthStencil['format'] = depthStencilFormat; + depthStencil['depthWriteEnabled'] = material.depthWrite; + depthStencil['depthCompare'] = depthCompare; + + } + + if ( renderStencil == true ) { + + depthStencil['stencilFront'] = stencilFront; + depthStencil['stencilBack'] = {}; // three.js does not provide an API to configure the back function (gl.stencilFuncSeparate() was never used) + depthStencil['stencilReadMask'] = material.stencilFuncMask; + depthStencil['stencilWriteMask'] = material.stencilWriteMask; + + } + + if ( material.polygonOffset == true ) { + + depthStencil['depthBias'] = material.polygonOffsetUnits; + depthStencil['depthBiasSlopeScale'] = material.polygonOffsetFactor; + depthStencil['depthBiasClamp'] = 0; // three.js does not provide an API to configure this value + + } + + pipelineDescriptor['depthStencil'] = depthStencil; + + } + + + if ( promises == null ) { + pipelineData.pipeline = device.createRenderPipeline( pipelineDescriptor ); + } + else { + final p = new Future( () { + + device.createRenderPipelineAsync( pipelineDescriptor ).then( (pipeline){ + pipelineData.pipeline = pipeline; + //resolve(); + } ); + } ); + + promises.add( p ); + } + } + + /// + /// Creates GPU render bundle encoder for the given render context. + /// + /// @param {RenderContext} renderContext - The render context. + /// @param {?string} [label='renderBundleEncoder'] - The label. + /// @return {GPURenderBundleEncoder} The GPU render bundle encoder. + GPURenderBundleEncoder createBundleEncoder(RenderContext renderContext, [String label = 'renderBundleEncoder'] ) { + + final backend = this.backend; + final utils = backend.utils; + final device = backend.device; + + final depthStencilFormat = utils.getCurrentDepthStencilFormat( renderContext ); + final colorFormat = utils.getCurrentColorFormat( renderContext ); + final sampleCount = this._getSampleCount( renderContext ); + + final descriptor = { + 'label': label, + 'colorFormats': [ colorFormat ], + 'depthStencilFormat': depthStencilFormat, + 'sampleCount': sampleCount + }; + + return device.createRenderBundleEncoder( descriptor ); + + } + + /// + /// Creates a compute pipeline for the given compute node. + /// + /// @param {ComputePipeline} pipeline - The compute pipeline. + /// @param {Array} bindings - The bindings. + /// + createComputePipeline( ComputePipeline pipeline, List bindings ) { + + final backend = this.backend; + final device = backend.device; + + final computeProgram = backend.get( pipeline.computeProgram ).module; + + final pipelineGPU = backend.get( pipeline ); + + // bind group layouts + + final bindGroupLayouts = []; + + for ( final bindingsGroup in bindings ) { + + final bindingsData = backend.get( bindingsGroup ); + + bindGroupLayouts.add( bindingsData.layout ); + + } + + pipelineGPU.pipeline = device.createComputePipeline( { + 'compute': computeProgram, + 'layout': device.createPipelineLayout( { + 'bindGroupLayouts': bindGroupLayouts + } ) + } ); + + } + + /// + /// Returns the blending state as a descriptor object required + /// for the pipeline creation. + /// + /// @private + /// @param {Material} material - The material. + /// @return {Object} The blending state. + /// + _getBlending( Material material ) { + + Map color, alpha; + + final blending = material.blending; + final blendSrc = material.blendSrc; + final blendDst = material.blendDst; + final blendEquation = material.blendEquation; + + + if ( blending == CustomBlending ) { + + final blendSrcAlpha = material.blendSrcAlpha ?? blendSrc; + final blendDstAlpha = material.blendDstAlpha ?? blendDst; + final blendEquationAlpha = material.blendEquationAlpha ?? blendEquation; + + color = { + 'srcFactor': this._getBlendFactor( blendSrc ), + 'dstFactor': this._getBlendFactor( blendDst ), + 'operation': this._getBlendOperation( blendEquation ) + }; + + alpha = { + 'srcFactor': this._getBlendFactor( blendSrcAlpha ), + 'dstFactor': this._getBlendFactor( blendDstAlpha ), + 'operation': this._getBlendOperation( blendEquationAlpha ) + }; + + } else { + + final premultipliedAlpha = material.premultipliedAlpha; + + final setBlend = ( srcRGB, dstRGB, srcAlpha, dstAlpha ){ + + color = { + 'srcFactor': srcRGB, + 'dstFactor': dstRGB, + 'operation': GPUBlendOperation.Add + }; + + alpha = { + 'srcFactor': srcAlpha, + 'dstFactor': dstAlpha, + 'operation': GPUBlendOperation.Add + }; + + }; + + if ( premultipliedAlpha ) { + + switch ( blending ) { + + case NormalBlending: + setBlend( GPUBlendFactor.One, GPUBlendFactor.OneMinusSrcAlpha, GPUBlendFactor.One, GPUBlendFactor.OneMinusSrcAlpha ); + break; + + case AdditiveBlending: + setBlend( GPUBlendFactor.One, GPUBlendFactor.One, GPUBlendFactor.One, GPUBlendFactor.One ); + break; + + case SubtractiveBlending: + setBlend( GPUBlendFactor.Zero, GPUBlendFactor.OneMinusSrc, GPUBlendFactor.Zero, GPUBlendFactor.One ); + break; + + case MultiplyBlending: + setBlend( GPUBlendFactor.Dst, GPUBlendFactor.OneMinusSrcAlpha, GPUBlendFactor.Zero, GPUBlendFactor.One ); + break; + + } + + } else { + + switch ( blending ) { + + case NormalBlending: + setBlend( GPUBlendFactor.SrcAlpha, GPUBlendFactor.OneMinusSrcAlpha, GPUBlendFactor.One, GPUBlendFactor.OneMinusSrcAlpha ); + break; + + case AdditiveBlending: + setBlend( GPUBlendFactor.SrcAlpha, GPUBlendFactor.One, GPUBlendFactor.One, GPUBlendFactor.One ); + break; + + case SubtractiveBlending: + console.error( 'THREE.WebGPURenderer: SubtractiveBlending requires material.premultipliedAlpha = true' ); + break; + + case MultiplyBlending: + console.error( 'THREE.WebGPURenderer: MultiplyBlending requires material.premultipliedAlpha = true' ); + break; + + } + + } + + } + + if ( color != null && alpha != null ) { + + return { 'color': color, 'alpha': alpha }; + + } else { + + console.error( 'THREE.WebGPURenderer: Invalid blending: ', blending ); + + } + + } + + /// + /// Returns the GPU blend factor which is required for the pipeline creation. + /// + /// @private + /// @param {number} blend - The blend factor as a three.js constant. + /// @return {string} The GPU blend factor. + /// + _getBlendFactor( int blend ) { + + String blendFactor; + + switch ( blend ) { + + case ZeroFactor: + blendFactor = GPUBlendFactor.Zero; + break; + + case OneFactor: + blendFactor = GPUBlendFactor.One; + break; + + case SrcColorFactor: + blendFactor = GPUBlendFactor.Src; + break; + + case OneMinusSrcColorFactor: + blendFactor = GPUBlendFactor.OneMinusSrc; + break; + + case SrcAlphaFactor: + blendFactor = GPUBlendFactor.SrcAlpha; + break; + + case OneMinusSrcAlphaFactor: + blendFactor = GPUBlendFactor.OneMinusSrcAlpha; + break; + + case DstColorFactor: + blendFactor = GPUBlendFactor.Dst; + break; + + case OneMinusDstColorFactor: + blendFactor = GPUBlendFactor.OneMinusDst; + break; + + case DstAlphaFactor: + blendFactor = GPUBlendFactor.DstAlpha; + break; + + case OneMinusDstAlphaFactor: + blendFactor = GPUBlendFactor.OneMinusDstAlpha; + break; + + case SrcAlphaSaturateFactor: + blendFactor = GPUBlendFactor.SrcAlphaSaturated; + break; + + case BlendColorFactor: + blendFactor = GPUBlendFactor.Constant; + break; + + case OneMinusBlendColorFactor: + blendFactor = GPUBlendFactor.OneMinusConstant; + break; + + default: + console.error( 'THREE.WebGPURenderer: Blend factor not supported.', blend ); + + } + + return blendFactor; + + } + + /// + /// Returns the GPU stencil compare function which is required for the pipeline creation. + /// + /// @private + /// @param {Material} material - The material. + /// @return {string} The GPU stencil compare function. + /// + _getStencilCompare( Material material ) { + + String stencilCompare; + + final stencilFunc = material.stencilFunc; + + switch ( stencilFunc ) { + + case NeverStencilFunc: + stencilCompare = GPUCompareFunction.Never; + break; + + case AlwaysStencilFunc: + stencilCompare = GPUCompareFunction.Always; + break; + + case LessStencilFunc: + stencilCompare = GPUCompareFunction.Less; + break; + + case LessEqualStencilFunc: + stencilCompare = GPUCompareFunction.LessEqual; + break; + + case EqualStencilFunc: + stencilCompare = GPUCompareFunction.Equal; + break; + + case GreaterEqualStencilFunc: + stencilCompare = GPUCompareFunction.GreaterEqual; + break; + + case GreaterStencilFunc: + stencilCompare = GPUCompareFunction.Greater; + break; + + case NotEqualStencilFunc: + stencilCompare = GPUCompareFunction.NotEqual; + break; + + default: + console.error( 'THREE.WebGPURenderer: Invalid stencil function.', stencilFunc ); + + } + + return stencilCompare; + + } + + /// + /// Returns the GPU stencil operation which is required for the pipeline creation. + /// + /// @private + /// @param {number} op - A three.js constant defining the stencil operation. + /// @return {string} The GPU stencil operation. + /// + _getStencilOperation( int op ) { + + String stencilOperation; + + switch ( op ) { + + case KeepStencilOp: + stencilOperation = GPUStencilOperation.Keep; + break; + + case ZeroStencilOp: + stencilOperation = GPUStencilOperation.Zero; + break; + + case ReplaceStencilOp: + stencilOperation = GPUStencilOperation.Replace; + break; + + case InvertStencilOp: + stencilOperation = GPUStencilOperation.Invert; + break; + + case IncrementStencilOp: + stencilOperation = GPUStencilOperation.IncrementClamp; + break; + + case DecrementStencilOp: + stencilOperation = GPUStencilOperation.DecrementClamp; + break; + + case IncrementWrapStencilOp: + stencilOperation = GPUStencilOperation.IncrementWrap; + break; + + case DecrementWrapStencilOp: + stencilOperation = GPUStencilOperation.DecrementWrap; + break; + + default: + console.error( 'THREE.WebGPURenderer: Invalid stencil operation.', stencilOperation ); + + } + + return stencilOperation; + + } + + /// + /// Returns the GPU blend operation which is required for the pipeline creation. + /// + /// @private + /// @param {number} blendEquation - A three.js constant defining the blend equation. + /// @return {string} The GPU blend operation. + /// + _getBlendOperation( int blendEquation ) { + + String blendOperation; + + switch ( blendEquation ) { + + case AddEquation: + blendOperation = GPUBlendOperation.Add; + break; + + case SubtractEquation: + blendOperation = GPUBlendOperation.Subtract; + break; + + case ReverseSubtractEquation: + blendOperation = GPUBlendOperation.ReverseSubtract; + break; + + case MinEquation: + blendOperation = GPUBlendOperation.Min; + break; + + case MaxEquation: + blendOperation = GPUBlendOperation.Max; + break; + + default: + console.error( 'THREE.WebGPUPipelineUtils: Blend equation not supported.', blendEquation ); + + } + + return blendOperation; + + } + + /** + * Returns the primitive state as a descriptor object required + * for the pipeline creation. + * + * @private + * @param {Object3D} object - The 3D object. + * @param {BufferGeometry} geometry - The geometry. + * @param {Material} material - The material. + * @return {Object} The primitive state. + */ + _getPrimitiveState( object, geometry, material ) { + + const descriptor = {}; + const utils = this.backend.utils; + + descriptor.topology = utils.getPrimitiveTopology( object, material ); + + if ( geometry.index !== null && object.isLine === true && object.isLineSegments !== true ) { + + descriptor.stripIndexFormat = ( geometry.index.array instanceof Uint16Array ) ? GPUIndexFormat.Uint16 : GPUIndexFormat.Uint32; + + } + + switch ( material.side ) { + + case FrontSide: + descriptor.frontFace = GPUFrontFace.CCW; + descriptor.cullMode = GPUCullMode.Back; + break; + + case BackSide: + descriptor.frontFace = GPUFrontFace.CCW; + descriptor.cullMode = GPUCullMode.Front; + break; + + case DoubleSide: + descriptor.frontFace = GPUFrontFace.CCW; + descriptor.cullMode = GPUCullMode.None; + break; + + default: + console.error( 'THREE.WebGPUPipelineUtils: Unknown material.side value.', material.side ); + break; + + } + + return descriptor; + + } + + /// + /// Returns the GPU color write mask which is required for the pipeline creation. + /// + /// @private + /// @param {Material} material - The material. + /// @return {string} The GPU color write mask. + /// + _getColorWriteMask( Material material ) { + + return ( material.colorWrite ) ? GPUColorWriteFlags.All : GPUColorWriteFlags.None; + + } + + /// + /// Returns the GPU depth compare function which is required for the pipeline creation. + /// + /// @private + /// @param {Material} material - The material. + /// @return {string} The GPU depth compare function. + /// + _getDepthCompare( Material material ) { + + String depthCompare; + + if ( material.depthTest === false ) { + + depthCompare = GPUCompareFunction.Always; + + } else { + + const depthFunc = material.depthFunc; + + switch ( depthFunc ) { + + case NeverDepth: + depthCompare = GPUCompareFunction.Never; + break; + + case AlwaysDepth: + depthCompare = GPUCompareFunction.Always; + break; + + case LessDepth: + depthCompare = GPUCompareFunction.Less; + break; + + case LessEqualDepth: + depthCompare = GPUCompareFunction.LessEqual; + break; + + case EqualDepth: + depthCompare = GPUCompareFunction.Equal; + break; + + case GreaterEqualDepth: + depthCompare = GPUCompareFunction.GreaterEqual; + break; + + case GreaterDepth: + depthCompare = GPUCompareFunction.Greater; + break; + + case NotEqualDepth: + depthCompare = GPUCompareFunction.NotEqual; + break; + + default: + console.error( 'THREE.WebGPUPipelineUtils: Invalid depth function.', depthFunc ); + + } + + } + + return depthCompare; + + } + +} diff --git a/packages/three_js_gpu/lib/utils/web_gpu_texture_pass_utils.dart b/packages/three_js_gpu/lib/utils/web_gpu_texture_pass_utils.dart new file mode 100644 index 00000000..dc209cad --- /dev/null +++ b/packages/three_js_gpu/lib/utils/web_gpu_texture_pass_utils.dart @@ -0,0 +1,436 @@ +import 'package:three_js_gpu/gpu_backend.dart'; +import 'package:three_js_gpu/utils/web_gpu_constants.dart'; + +/// +/// A WebGPU backend utility module used by {@link WebGPUTextureUtils}. +/// +/// @private +/// +class WebGPUTexturePassUtils extends DataMap { + + /// + /// Constructs a new utility object. + /// + /// @param {GPUDevice} device - The WebGPU device. + /// + WebGPUTexturePassUtils( GPUDevice device ) : super() { + + /// + /// The WebGPU device. + /// + /// @type {GPUDevice} + /// + final this.device = device; + + const mipmapVertexSource = ''' +struct VarysStruct { + @builtin( position ) Position: vec4, + @location( 0 ) vTex : vec2 +}; + +@vertex +fn main( @builtin( vertex_index ) vertexIndex : u32 ) -> VarysStruct { + + var Varys : VarysStruct; + + var pos = array< vec2, 4 >( + vec2( -1.0, 1.0 ), + vec2( 1.0, 1.0 ), + vec2( -1.0, -1.0 ), + vec2( 1.0, -1.0 ) + ); + + var tex = array< vec2, 4 >( + vec2( 0.0, 0.0 ), + vec2( 1.0, 0.0 ), + vec2( 0.0, 1.0 ), + vec2( 1.0, 1.0 ) + ); + + Varys.vTex = tex[ vertexIndex ]; + Varys.Position = vec4( pos[ vertexIndex ], 0.0, 1.0 ); + + return Varys; + +} +'''; + + const mipmapFragmentSource = ''' +@group( 0 ) @binding( 0 ) +var imgSampler : sampler; + +@group( 0 ) @binding( 1 ) +var img : texture_2d; + +@fragment +fn main( @location( 0 ) vTex : vec2 ) -> @location( 0 ) vec4 { + + return textureSample( img, imgSampler, vTex ); + +} +'''; + + const flipYFragmentSource = ''' +@group( 0 ) @binding( 0 ) +var imgSampler : sampler; + +@group( 0 ) @binding( 1 ) +var img : texture_2d; + +@fragment +fn main( @location( 0 ) vTex : vec2 ) -> @location( 0 ) vec4 { + + return textureSample( img, imgSampler, vec2( vTex.x, 1.0 - vTex.y ) ); + +} +'''; + + /// + /// The mipmap GPU sampler. + /// + /// @type {GPUSampler} + /// + this.mipmapSampler = device.createSampler( { minFilter: GPUFilterMode.Linear } ); + + /// + /// The flipY GPU sampler. + /// + /// @type {GPUSampler} + /// + this.flipYSampler = device.createSampler( { minFilter: GPUFilterMode.Nearest } ); //@TODO?: Consider using textureLoad() + + /// + /// A cache for GPU render pipelines used for copy/transfer passes. + /// Every texture format requires a unique pipeline. + /// + /// @type {Object} + /// + this.transferPipelines = {}; + + /// + /// A cache for GPU render pipelines used for flipY passes. + /// Every texture format requires a unique pipeline. + /// + /// @type {Object} + /// + this.flipYPipelines = {}; + + /// + /// The mipmap vertex shader module. + /// + /// @type {GPUShaderModule} + /// + this.mipmapVertexShaderModule = device.createShaderModule( { + label: 'mipmapVertex', + code: mipmapVertexSource + } ); + + /// + /// The mipmap fragment shader module. + /// + /// @type {GPUShaderModule} + /// + this.mipmapFragmentShaderModule = device.createShaderModule( { + label: 'mipmapFragment', + code: mipmapFragmentSource + } ); + + /// + /// The flipY fragment shader module. + /// + /// @type {GPUShaderModule} + /// + this.flipYFragmentShaderModule = device.createShaderModule( { + label: 'flipYFragment', + code: flipYFragmentSource + } ); + + } + + /// + /// Returns a render pipeline for the internal copy render pass. The pass + /// requires a unique render pipeline for each texture format. + /// + /// @param {string} format - The GPU texture format + /// @return {GPURenderPipeline} The GPU render pipeline. + /// + getTransferPipeline( format ) { + + let pipeline = this.transferPipelines[ format ]; + + if ( pipeline == null ) { + + pipeline = this.device.createRenderPipeline( { + 'label': 'mipmap-$format', + 'vertex': { + 'module': this.mipmapVertexShaderModule, + 'entryPoint': 'main' + }, + 'fragment': { + 'module': this.mipmapFragmentShaderModule, + 'entryPoint': 'main', + 'targets': [ { 'format': format } ] + }, + 'primitive': { + 'topology': GPUPrimitiveTopology.TriangleStrip, + 'stripIndexFormat': GPUIndexFormat.Uint32 + }, + 'layout': 'auto' + } ); + + this.transferPipelines[ format ] = pipeline; + + } + + return pipeline; + + } + + /// + /// Returns a render pipeline for the flipY render pass. The pass + /// requires a unique render pipeline for each texture format. + /// + /// @param {string} format - The GPU texture format + /// @return {GPURenderPipeline} The GPU render pipeline. + /// + getFlipYPipeline( format ) { + + let pipeline = this.flipYPipelines[ format ]; + + if ( pipeline == null ) { + + pipeline = this.device.createRenderPipeline( { + 'label': 'flipY-$format', + 'vertex': { + 'module': this.mipmapVertexShaderModule, + 'entryPoint': 'main' + }, + 'fragment': { + 'module': this.flipYFragmentShaderModule, + 'entryPoint': 'main', + 'targets': [ { 'format': format } ] + }, + 'primitive': { + 'topology': GPUPrimitiveTopology.TriangleStrip, + 'stripIndexFormat': GPUIndexFormat.Uint32 + }, + 'layout': 'auto' + } ); + + this.flipYPipelines[ format ] = pipeline; + + } + + return pipeline; + + } + + /// + /// Flip the contents of the given GPU texture along its vertical axis. + /// + /// @param {GPUTexture} textureGPU - The GPU texture object. + /// @param {Object} textureGPUDescriptor - The texture descriptor. + /// @param {number} [baseArrayLayer=0] - The index of the first array layer accessible to the texture view. + /// + flipY( textureGPU, textureGPUDescriptor, baseArrayLayer = 0 ) { + + final format = textureGPUDescriptor.format; + final width = textureGPUDescriptor.size.width; + final height = textureGPUDescriptor.size.height; + + final transferPipeline = this.getTransferPipeline( format ); + final flipYPipeline = this.getFlipYPipeline( format ); + + final tempTexture = this.device.createTexture( { + 'size': { 'width': width, 'height': height, 'depthOrArrayLayers': 1 }, + 'format': format, + 'usage': GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.TEXTURE_BINDING + } ); + + final srcView = textureGPU.createView( { + 'baseMipLevel': 0, + 'mipLevelCount': 1, + 'dimension': GPUTextureViewDimension.TwoD, + 'baseArrayLayer': baseArrayLayer + } ); + + final dstView = tempTexture.createView( { + 'baseMipLevel': 0, + 'mipLevelCount': 1, + 'dimension': GPUTextureViewDimension.TwoD, + 'baseArrayLayer': 0 + } ); + + final commandEncoder = this.device.createCommandEncoder( {} ); + + final pass = ( pipeline, sourceView, destinationView ) => { + + final bindGroupLayout = pipeline.getBindGroupLayout( 0 ); // @TODO: Consider making this static. + + final bindGroup = this.device.createBindGroup( { + 'layout': bindGroupLayout, + 'entries': [ { + 'binding': 0, + 'resource': this.flipYSampler + }, { + 'binding': 1, + 'resource': sourceView + } ] + } ); + + final passEncoder = commandEncoder.beginRenderPass( { + 'colorAttachments': [ { + 'view': destinationView, + 'loadOp': GPULoadOp.Clear, + 'storeOp': GPUStoreOp.Store, + 'clearValue': [ 0, 0, 0, 0 ] + } ] + } ); + + passEncoder.setPipeline( pipeline ); + passEncoder.setBindGroup( 0, bindGroup ); + passEncoder.draw( 4, 1, 0, 0 ); + passEncoder.end(); + + }; + + pass( transferPipeline, srcView, dstView ); + pass( flipYPipeline, dstView, srcView ); + + this.device.queue.submit( [ commandEncoder.finish() ] ); + + tempTexture.destroy(); + + } + + /// + /// Generates mipmaps for the given GPU texture. + /// + /// @param {GPUTexture} textureGPU - The GPU texture object. + /// @param {Object} textureGPUDescriptor - The texture descriptor. + /// @param {number} [baseArrayLayer=0] - The index of the first array layer accessible to the texture view. + /// + generateMipmaps( textureGPU, textureGPUDescriptor, baseArrayLayer = 0 ) { + + final textureData = this.get( textureGPU ); + + if ( textureData.useCount == null ) { + + textureData.useCount = 0; + textureData.layers = []; + + } + + final passes = textureData.layers[ baseArrayLayer ] ?? this._mipmapCreateBundles( textureGPU, textureGPUDescriptor, baseArrayLayer ); + + final commandEncoder = this.device.createCommandEncoder( {} ); + + this._mipmapRunBundles( commandEncoder, passes ); + + this.device.queue.submit( [ commandEncoder.finish() ] ); + + if ( textureData.useCount != 0 ) textureData.layers[ baseArrayLayer ] = passes; + + textureData.useCount ++; + + } + + /// + /// Since multiple copy render passes are required to generate mipmaps, the passes + /// are managed as render bundles to improve performance. + /// + /// @param {GPUTexture} textureGPU - The GPU texture object. + /// @param {Object} textureGPUDescriptor - The texture descriptor. + /// @param {number} baseArrayLayer - The index of the first array layer accessible to the texture view. + /// @return {Array} An array of render bundles. + /// + _mipmapCreateBundles( textureGPU, textureGPUDescriptor, baseArrayLayer ) { + + final pipeline = this.getTransferPipeline( textureGPUDescriptor.format ); + + final bindGroupLayout = pipeline.getBindGroupLayout( 0 ); // @TODO: Consider making this static. + + var srcView = textureGPU.createView( { + 'baseMipLevel': 0, + 'mipLevelCount': 1, + 'dimension': GPUTextureViewDimension.TwoD, + 'baseArrayLayer': baseArrayLayer + } ); + + final passes = []; + + for ( int i = 1; i < textureGPUDescriptor.mipLevelCount; i ++ ) { + + final bindGroup = this.device.createBindGroup( { + 'layout': bindGroupLayout, + 'entries': [ { + 'binding': 0, + 'resource': this.mipmapSampler + }, { + 'binding': 1, + 'resource': srcView + } ] + } ); + + final dstView = textureGPU.createView( { + 'baseMipLevel': i, + 'mipLevelCount': 1, + 'dimension': GPUTextureViewDimension.TwoD, + 'baseArrayLayer': baseArrayLayer + } ); + + final passDescriptor = { + 'colorAttachments': [ { + 'view': dstView, + 'loadOp': GPULoadOp.Clear, + 'storeOp': GPUStoreOp.Store, + 'clearValue': [ 0, 0, 0, 0 ] + } ] + }; + + final passEncoder = this.device.createRenderBundleEncoder( { + 'colorFormats': [ textureGPUDescriptor.format ] + } ); + + passEncoder.setPipeline( pipeline ); + passEncoder.setBindGroup( 0, bindGroup ); + passEncoder.draw( 4, 1, 0, 0 ); + + passes.add( { + 'renderBundles': [ passEncoder.finish() ], + 'passDescriptor': passDescriptor + } ); + + srcView = dstView; + + } + + return passes; + + } + + /// + /// Executes the render bundles. + /// + /// @param {GPUCommandEncoder} commandEncoder - The GPU command encoder. + /// @param {Array} passes - An array of render bundles. + /// + _mipmapRunBundles( commandEncoder, passes ) { + + final levels = passes.length; + + for ( int i = 0; i < levels; i ++ ) { + + final pass = passes[ i ]; + + final passEncoder = commandEncoder.beginRenderPass( pass['passDescriptor'] ); + + passEncoder.executeBundles( pass['renderBundles'] ); + + passEncoder.end(); + + } + + } + +} diff --git a/packages/three_js_gpu/lib/utils/web_gpu_texture_utils.dart b/packages/three_js_gpu/lib/utils/web_gpu_texture_utils.dart new file mode 100644 index 00000000..2b786115 --- /dev/null +++ b/packages/three_js_gpu/lib/utils/web_gpu_texture_utils.dart @@ -0,0 +1,1383 @@ +import 'dart:typed_data'; +import 'package:three_js_gpu/gpu_backend.dart'; + +const _compareToWebGPU = { + [ NeverCompare ]: 'never', + [ LessCompare ]: 'less', + [ EqualCompare ]: 'equal', + [ LessEqualCompare ]: 'less-equal', + [ GreaterCompare ]: 'greater', + [ GreaterEqualCompare ]: 'greater-equal', + [ AlwaysCompare ]: 'always', + [ NotEqualCompare ]: 'not-equal' +}; + +const _flipMap = [ 0, 1, 3, 2, 4, 5 ]; + +/// A WebGPU backend utility module for managing textures. +/// +/// @private +class WebGPUTextureUtils { + WebGPUBackend backend; + WebGPUTexturePassUtils? _passUtils; + Map defaultTexture = {}; + Map defaultCubeTexture = {}; + VideoFrame? defaultVideoFrame; + GPUTexture? colorBuffer; + DepthTexture depthTexture = DepthTexture(); + + /// Constructs a new utility object. + /// + /// @param {WebGPUBackend} backend - The WebGPU backend. + WebGPUTextureUtils( this.backend ) { + + /// A reference to the WebGPU backend. + /// + /// @type {WebGPUBackend} + this.backend = backend; + + /// A reference to the pass utils. + /// + /// @type {?WebGPUTexturePassUtils} + /// @default null + this._passUtils = null; + + /// A dictionary for managing default textures. The key + /// is the texture format, the value the texture object. + /// + /// @type {Object} + this.defaultTexture = {}; + + /// A dictionary for managing default cube textures. The key + /// is the texture format, the value the texture object. + /// + /// @type {Object} + this.defaultCubeTexture = {}; + + /// A default video frame. + /// + /// @type {?VideoFrame} + /// @default null + this.defaultVideoFrame = null; + + /// Represents the color attachment of the default framebuffer. + /// + /// @type {?GPUTexture} + /// @default null + this.colorBuffer = null; + + /// Represents the depth attachment of the default framebuffer. + /// + /// @type {DepthTexture} + this.depthTexture = new DepthTexture(); + this.depthTexture.name = 'depthBuffer'; + + } + + /// Creates a GPU sampler for the given texture. + /// + /// @param {Texture} texture - The texture to create the sampler for. + createSampler( texture ) { + + const backend = this.backend; + const device = backend.device; + + const textureGPU = backend.get( texture ); + + const samplerDescriptorGPU = { + addressModeU: this._convertAddressMode( texture.wrapS ), + addressModeV: this._convertAddressMode( texture.wrapT ), + addressModeW: this._convertAddressMode( texture.wrapR ), + magFilter: this._convertFilterMode( texture.magFilter ), + minFilter: this._convertFilterMode( texture.minFilter ), + mipmapFilter: this._convertFilterMode( texture.minFilter ), + maxAnisotropy: 1 + }; + + // anisotropy can only be used when all filter modes are set to linear. + + if ( samplerDescriptorGPU.magFilter == GPUFilterMode.Linear && samplerDescriptorGPU.minFilter == GPUFilterMode.Linear && samplerDescriptorGPU.mipmapFilter == GPUFilterMode.Linear ) { + + samplerDescriptorGPU.maxAnisotropy = texture.anisotropy; + + } + + if ( texture.isDepthTexture && texture.compareFunction !== null ) { + + samplerDescriptorGPU.compare = _compareToWebGPU[ texture.compareFunction ]; + + } + + textureGPU.sampler = device.createSampler( samplerDescriptorGPU ); + + } + + /** + * Creates a default texture for the given texture that can be used + * as a placeholder until the actual texture is ready for usage. + * + * @param {Texture} texture - The texture to create a default texture for. + */ + createDefaultTexture( texture ) { + + let textureGPU; + + const format = getFormat( texture ); + + if ( texture.isCubeTexture ) { + + textureGPU = this._getDefaultCubeTextureGPU( format ); + + } else { + + textureGPU = this._getDefaultTextureGPU( format ); + + } + + this.backend.get( texture ).texture = textureGPU; + + } + + /** + * Defines a texture on the GPU for the given texture object. + * + * @param {Texture} texture - The texture. + * @param {Object} [options={}] - Optional configuration parameter. + */ + createTexture( texture, options = {} ) { + + const backend = this.backend; + const textureData = backend.get( texture ); + + if ( textureData.initialized ) { + + throw new Error( 'WebGPUTextureUtils: Texture already initialized.' ); + + } + + if ( options.needsMipmaps == undefined ) options.needsMipmaps = false; + if ( options.levels == undefined ) options.levels = 1; + if ( options.depth == undefined ) options.depth = 1; + + const { width, height, depth, levels } = options; + + if ( texture.isFramebufferTexture ) { + + if ( options.renderTarget ) { + + options.format = this.backend.utils.getCurrentColorFormat( options.renderTarget ); + + } else { + + options.format = this.backend.utils.getPreferredCanvasFormat(); + + } + + } + + const dimension = this._getDimension( texture ); + const format = texture.internalFormat || options.format || getFormat( texture, backend.device ); + + textureData.format = format; + + const { samples, primarySamples, isMSAA } = backend.utils.getTextureSampleData( texture ); + + let usage = GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.COPY_SRC; + + if ( texture.isStorageTexture == true ) { + + usage |= GPUTextureUsage.STORAGE_BINDING; + + } + + if ( texture.isCompressedTexture !== true && texture.isCompressedArrayTexture !== true ) { + + usage |= GPUTextureUsage.RENDER_ATTACHMENT; + + } + + const textureDescriptorGPU = { + label: texture.name, + size: { + width: width, + height: height, + depthOrArrayLayers: depth, + }, + mipLevelCount: levels, + sampleCount: primarySamples, + dimension: dimension, + format: format, + usage: usage + }; + + // texture creation + + if ( format == undefined ) { + + console.warn( 'WebGPURenderer: Texture format not supported.' ); + + this.createDefaultTexture( texture ); + return; + + } + + if ( texture.isCubeTexture ) { + + textureDescriptorGPU.textureBindingViewDimension = GPUTextureViewDimension.Cube; + + } + + textureData.texture = backend.device.createTexture( textureDescriptorGPU ); + + if ( isMSAA ) { + + const msaaTextureDescriptorGPU = Object.assign( {}, textureDescriptorGPU ); + + msaaTextureDescriptorGPU.label = msaaTextureDescriptorGPU.label + '-msaa'; + msaaTextureDescriptorGPU.sampleCount = samples; + + textureData.msaaTexture = backend.device.createTexture( msaaTextureDescriptorGPU ); + + } + + textureData.initialized = true; + + textureData.textureDescriptorGPU = textureDescriptorGPU; + + } + + /** + * Destroys the GPU data for the given texture object. + * + * @param {Texture} texture - The texture. + */ + destroyTexture( texture ) { + + const backend = this.backend; + const textureData = backend.get( texture ); + + if ( textureData.texture !== undefined ) textureData.texture.destroy(); + + if ( textureData.msaaTexture !== undefined ) textureData.msaaTexture.destroy(); + + backend.delete( texture ); + + } + + /** + * Destroys the GPU sampler for the given texture. + * + * @param {Texture} texture - The texture to destroy the sampler for. + */ + destroySampler( texture ) { + + const backend = this.backend; + const textureData = backend.get( texture ); + + delete textureData.sampler; + + } + + /** + * Generates mipmaps for the given texture. + * + * @param {Texture} texture - The texture. + */ + generateMipmaps( texture ) { + + const textureData = this.backend.get( texture ); + + if ( texture.isCubeTexture ) { + + for ( let i = 0; i < 6; i ++ ) { + + this._generateMipmaps( textureData.texture, textureData.textureDescriptorGPU, i ); + + } + + } else { + + const depth = texture.image.depth || 1; + + for ( let i = 0; i < depth; i ++ ) { + + this._generateMipmaps( textureData.texture, textureData.textureDescriptorGPU, i ); + + } + + } + + } + + /** + * Returns the color buffer representing the color + * attachment of the default framebuffer. + * + * @return {GPUTexture} The color buffer. + */ + getColorBuffer() { + + if ( this.colorBuffer ) this.colorBuffer.destroy(); + + const backend = this.backend; + const { width, height } = backend.getDrawingBufferSize(); + + this.colorBuffer = backend.device.createTexture( { + label: 'colorBuffer', + size: { + width: width, + height: height, + depthOrArrayLayers: 1 + }, + sampleCount: backend.utils.getSampleCount( backend.renderer.samples ), + format: backend.utils.getPreferredCanvasFormat(), + usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC + } ); + + return this.colorBuffer; + + } + + /** + * Returns the depth buffer representing the depth + * attachment of the default framebuffer. + * + * @param {boolean} [depth=true] - Whether depth is enabled or not. + * @param {boolean} [stencil=false] - Whether stencil is enabled or not. + * @return {GPUTexture} The depth buffer. + */ + getDepthBuffer( depth = true, stencil = false ) { + + const backend = this.backend; + const { width, height } = backend.getDrawingBufferSize(); + + const depthTexture = this.depthTexture; + const depthTextureGPU = backend.get( depthTexture ).texture; + + let format, type; + + if ( stencil ) { + + format = DepthStencilFormat; + type = UnsignedInt248Type; + + } else if ( depth ) { + + format = DepthFormat; + type = UnsignedIntType; + + } + + if ( depthTextureGPU !== undefined ) { + + if ( depthTexture.image.width == width && depthTexture.image.height == height && depthTexture.format == format && depthTexture.type == type ) { + + return depthTextureGPU; + + } + + this.destroyTexture( depthTexture ); + + } + + depthTexture.name = 'depthBuffer'; + depthTexture.format = format; + depthTexture.type = type; + depthTexture.image.width = width; + depthTexture.image.height = height; + + this.createTexture( depthTexture, { width, height } ); + + return backend.get( depthTexture ).texture; + + } + + /** + * Uploads the updated texture data to the GPU. + * + * @param {Texture} texture - The texture. + * @param {Object} [options={}] - Optional configuration parameter. + */ + updateTexture( texture, options ) { + + const textureData = this.backend.get( texture ); + + const { textureDescriptorGPU } = textureData; + + if ( texture.isRenderTargetTexture || ( textureDescriptorGPU == undefined /* unsupported texture format */ ) ) + return; + + // transfer texture data + + if ( texture.isDataTexture ) { + + this._copyBufferToTexture( options.image, textureData.texture, textureDescriptorGPU, 0, texture.flipY ); + + } else if ( texture.isArrayTexture || texture.isDataArrayTexture || texture.isData3DTexture ) { + + for ( let i = 0; i < options.image.depth; i ++ ) { + + this._copyBufferToTexture( options.image, textureData.texture, textureDescriptorGPU, i, texture.flipY, i ); + + } + + } else if ( texture.isCompressedTexture || texture.isCompressedArrayTexture ) { + + this._copyCompressedBufferToTexture( texture.mipmaps, textureData.texture, textureDescriptorGPU ); + + } else if ( texture.isCubeTexture ) { + + this._copyCubeMapToTexture( options.images, textureData.texture, textureDescriptorGPU, texture.flipY, texture.premultiplyAlpha ); + + } else { + + this._copyImageToTexture( options.image, textureData.texture, textureDescriptorGPU, 0, texture.flipY, texture.premultiplyAlpha ); + + } + + // + + textureData.version = texture.version; + + if ( texture.onUpdate ) texture.onUpdate( texture ); + + } + + /// + /// Returns texture data as a typed array. + /// + /// @async + /// @param {Texture} texture - The texture to copy. + /// @param {number} x - The x coordinate of the copy origin. + /// @param {number} y - The y coordinate of the copy origin. + /// @param {number} width - The width of the copy. + /// @param {number} height - The height of the copy. + /// @param {number} faceIndex - The face index. + /// @return {Promise} A Promise that resolves with a typed array when the copy operation has finished. + /// + Future copyTextureToBuffer( Texture texture, double x, double y, double width, double height, int faceIndex ) async { + + final device = this.backend.device; + + final textureData = this.backend.get( texture ); + final textureGPU = textureData.texture; + final format = textureData.textureDescriptorGPU.format; + final bytesPerTexel = this._getBytesPerTexel( format ); + + double bytesPerRow = width * bytesPerTexel; + bytesPerRow = ( bytesPerRow / 256 ).ceil() * 256; // Align to 256 bytes + + final readBuffer = device.createBuffer( + { + size: width * height * bytesPerTexel, + usage: GPUBufferUsage.COPY_DST | GPUBufferUsage.MAP_READ + } + ); + + final encoder = device.createCommandEncoder(); + + encoder.copyTextureToBuffer( + { + 'texture': textureGPU, + 'origin': { 'x': x, 'y': y, 'z': faceIndex }, + }, + { + 'buffer': readBuffer, + 'bytesPerRow': bytesPerRow + }, + { + 'width': width, + 'height': height + } + + ); + + final typedArrayType = this._getTypedArrayType( format ); + + device.queue.submit( [ encoder.finish() ] ); + + await readBuffer.mapAsync( GPUMapMode.READ ); + + final buffer = readBuffer.getMappedRange(); + + return new typedArrayType( buffer ); + + } + + /// + /// Returns the default GPU texture for the given format. + /// + /// @private + /// @param {string} format - The GPU format. + /// @return {GPUTexture} The GPU texture. + /// + GPUTexture _getDefaultTextureGPU( String format ) { + + Texture? defaultTexture = this.defaultTexture[ format ]; + + if ( defaultTexture == null ) { + + final texture = Texture(); + texture.minFilter = NearestFilter; + texture.magFilter = NearestFilter; + + this.createTexture( texture, { width: 1, height: 1, format } ); + + this.defaultTexture[ format ] = defaultTexture = texture; + + } + + return this.backend.get( defaultTexture ).texture; + + } + + /// + /// Returns the default GPU cube texture for the given format. + /// + /// @private + /// @param {string} format - The GPU format. + /// @return {GPUTexture} The GPU texture. + /// + GPUTexture _getDefaultCubeTextureGPU( String format ) { + + Texture? defaultCubeTexture = this.defaultTexture[ format ]; + + if ( defaultCubeTexture == null ) { + + final texture = CubeTexture(); + texture.minFilter = NearestFilter; + texture.magFilter = NearestFilter; + + this.createTexture( texture, { width: 1, height: 1, depth: 6 } ); + + this.defaultCubeTexture[ format ] = defaultCubeTexture = texture; + + } + + return this.backend.get( defaultCubeTexture ).texture; + + } + + /// + /// Uploads cube texture image data to the GPU memory. + /// + /// @private + /// @param {Array} images - The cube image data. + /// @param {GPUTexture} textureGPU - The GPU texture. + /// @param {Object} textureDescriptorGPU - The GPU texture descriptor. + /// @param {boolean} flipY - Whether to flip texture data along their vertical axis or not. + /// @param {boolean} premultiplyAlpha - Whether the texture should have its RGB channels premultiplied by the alpha channel or not. + /// + void _copyCubeMapToTexture( List images, GPUTexture textureGPU, Object textureDescriptorGPU, bool flipY, bool premultiplyAlpha ) { + + for ( int i = 0; i < 6; i ++ ) { + + final image = images[ i ]; + + final flipIndex = flipY == true ? _flipMap[ i ] : i; + + if ( image.isDataTexture ) { + + this._copyBufferToTexture( image.image, textureGPU, textureDescriptorGPU, flipIndex, flipY ); + + } else { + + this._copyImageToTexture( image, textureGPU, textureDescriptorGPU, flipIndex, flipY, premultiplyAlpha ); + + } + + } + + } + + /// + /// Uploads texture image data to the GPU memory. + /// + /// @private + /// @param {HTMLImageElement|ImageBitmap|HTMLCanvasElement} image - The image data. + /// @param {GPUTexture} textureGPU - The GPU texture. + /// @param {Object} textureDescriptorGPU - The GPU texture descriptor. + /// @param {number} originDepth - The origin depth. + /// @param {boolean} flipY - Whether to flip texture data along their vertical axis or not. + /// @param {boolean} premultiplyAlpha - Whether the texture should have its RGB channels premultiplied by the alpha channel or not. + /// + void _copyImageToTexture( image, GPUTexture textureGPU, Object textureDescriptorGPU, int originDepth, bool flipY, bool premultiplyAlpha ) { + + const device = this.backend.device; + + device.queue.copyExternalImageToTexture( + { + 'source': image, + 'flipY': flipY + }, { + 'texture': textureGPU, + 'mipLevel': 0, + 'origin': { 'x': 0, 'y': 0, 'z': originDepth }, + 'premultipliedAlpha': premultiplyAlpha + }, { + 'width': textureDescriptorGPU.size.width, + 'height': textureDescriptorGPU.size.height, + 'depthOrArrayLayers': 1 + } + ); + + } + + /// + /// Returns the pass utils singleton. + /// + /// @private + /// @return {WebGPUTexturePassUtils} The utils instance. + /// + WebGPUTexturePassUtils _getPassUtils() { + + WebGPUTexturePassUtils? passUtils = this._passUtils; + + if ( passUtils == null ) { + + this._passUtils = passUtils = WebGPUTexturePassUtils( this.backend.device ); + + } + + return passUtils; + + } + + /// + /// Generates mipmaps for the given GPU texture. + /// + /// @private + /// @param {GPUTexture} textureGPU - The GPU texture object. + /// @param {Object} textureDescriptorGPU - The texture descriptor. + /// @param {number} [baseArrayLayer=0] - The index of the first array layer accessible to the texture view. + /// + void _generateMipmaps( GPUTexture textureGPU, Object textureDescriptorGPU, { int baseArrayLayer = 0 } ) { + + this._getPassUtils().generateMipmaps( textureGPU, textureDescriptorGPU, baseArrayLayer ); + + } + + /// + /// Flip the contents of the given GPU texture along its vertical axis. + /// + /// @private + /// @param {GPUTexture} textureGPU - The GPU texture object. + /// @param {Object} textureDescriptorGPU - The texture descriptor. + /// @param {number} [originDepth=0] - The origin depth. + /// + void _flipY( GPUTexture textureGPU, Object textureDescriptorGPU, { int originDepth = 0 } ) { + + this._getPassUtils().flipY( textureGPU, textureDescriptorGPU, originDepth ); + + } + + /// + /// Uploads texture buffer data to the GPU memory. + /// + /// @private + /// @param {Object} image - An object defining the image buffer data. + /// @param {GPUTexture} textureGPU - The GPU texture. + /// @param {Object} textureDescriptorGPU - The GPU texture descriptor. + /// @param {number} originDepth - The origin depth. + /// @param {boolean} flipY - Whether to flip texture data along their vertical axis or not. + /// @param {number} [depth=0] - TODO. + /// + void _copyBufferToTexture(Map image, GPUTexture textureGPU, Object textureDescriptorGPU, int originDepth, bool flipY, { int depth = 0 } ) { + + // @TODO: Consider to use GPUCommandEncoder.copyBufferToTexture() + // @TODO: Consider to support valid buffer layouts with other formats like RGB + + final device = this.backend.device; + + final data = image.data; + + final bytesPerTexel = this._getBytesPerTexel( textureDescriptorGPU.format ); + final bytesPerRow = image.width * bytesPerTexel; + + device.queue.writeTexture( + { + 'texture': textureGPU, + 'mipLevel': 0, + 'origin': { 'x': 0, 'y': 0, 'z': originDepth } + }, + data, + { + 'offset': image.width * image.height * bytesPerTexel * depth, + 'bytesPerRow': bytesPerRow + }, + { + 'width': image.width, + 'height': image.height, + 'depthOrArrayLayers': 1 + } ); + + if ( flipY == true ) { + + this._flipY( textureGPU, textureDescriptorGPU, originDepth ); + + } + + } + + /// + /// Uploads compressed texture data to the GPU memory. + /// + /// @private + /// @param {Array} mipmaps - An array with mipmap data. + /// @param {GPUTexture} textureGPU - The GPU texture. + /// @param {Object} textureDescriptorGPU - The GPU texture descriptor. + /// + void _copyCompressedBufferToTexture( List mipmaps, GPUTexture textureGPU, Object textureDescriptorGPU ) { + + // @TODO: Consider to use GPUCommandEncoder.copyBufferToTexture() + + final device = this.backend.device; + + final blockData = this._getBlockData( textureDescriptorGPU.format ); + final isArrayTexture = textureDescriptorGPU.size.depthOrArrayLayers > 1; + + for ( int i = 0; i < mipmaps.length; i ++ ) { + + final mipmap = mipmaps[ i ]; + + final width = mipmap.width; + final height = mipmap.height; + final depth = isArrayTexture ? textureDescriptorGPU.size.depthOrArrayLayers : 1; + + final bytesPerRow = ( width / blockData.width ).ceil() * blockData.byteLength; + final bytesPerImage = bytesPerRow * ( height / blockData.height ).ceil(); + + for ( int j = 0; j < depth; j ++ ) { + + device.queue.writeTexture( + { + 'texture': textureGPU, + 'mipLevel': i, + 'origin': { 'x': 0, 'y': 0, 'z': j } + }, + mipmap.data, + { + 'offset': j * bytesPerImage, + 'bytesPerRow': bytesPerRow, + 'rowsPerImage': ( height / blockData.height ).ceil() + }, + { + 'width': ( width / blockData.width ).ceil() * blockData.width, + 'height': ( height / blockData.height ).ceil() * blockData.height, + 'depthOrArrayLayers': 1 + } + ); + + } + + } + + } + + /// + /// This method is only relevant for compressed texture formats. It returns a block + /// data descriptor for the given GPU compressed texture format. + /// + /// @private + /// @param {string} format - The GPU compressed texture format. + /// @return {Object} The block data descriptor. + /// + Map _getBlockData( String format ) { + + if ( format == GPUTextureFormat.bc1RgbaUnorm || format == GPUTextureFormat.bc1RgbaUnormSrgb ) return { 'byteLength': 8, 'width': 4, 'height': 4 }; // DXT1 + if ( format == GPUTextureFormat.bc2RgbaUnorm || format == GPUTextureFormat.bc2RgbaUnormSrgb ) return { 'byteLength': 16, 'width': 4, 'height': 4 }; // DXT3 + if ( format == GPUTextureFormat.bc3RgbaUnorm || format == GPUTextureFormat.bc3RgbaUnormSrgb ) return { 'byteLength': 16, 'width': 4, 'height': 4 }; // DXT5 + if ( format == GPUTextureFormat.bc4RUnorm || format == GPUTextureFormat.bc4RSnorm ) return { 'byteLength': 8, 'width': 4, 'height': 4 }; // RGTC1 + if ( format == GPUTextureFormat.BC5RGUnorm || format == GPUTextureFormat.BC5RGSnorm ) return { byteLength: 16, width: 4, height: 4 }; // RGTC2 + if ( format == GPUTextureFormat.BC6HRGBUFloat || format == GPUTextureFormat.BC6HRGBFloat ) return { byteLength: 16, width: 4, height: 4 }; // BPTC (float) + if ( format == GPUTextureFormat.BC7RGBAUnorm || format == GPUTextureFormat.BC7RGBAUnormSRGB ) return { byteLength: 16, width: 4, height: 4 }; // BPTC (unorm) + + if ( format == GPUTextureFormat.ETC2RGB8Unorm || format == GPUTextureFormat.ETC2RGB8UnormSRGB ) return { byteLength: 8, width: 4, height: 4 }; + if ( format == GPUTextureFormat.ETC2RGB8A1Unorm || format == GPUTextureFormat.ETC2RGB8A1UnormSRGB ) return { byteLength: 8, width: 4, height: 4 }; + if ( format == GPUTextureFormat.ETC2RGBA8Unorm || format == GPUTextureFormat.ETC2RGBA8UnormSRGB ) return { byteLength: 16, width: 4, height: 4 }; + if ( format == GPUTextureFormat.EACR11Unorm ) return { byteLength: 8, width: 4, height: 4 }; + if ( format == GPUTextureFormat.EACR11Snorm ) return { byteLength: 8, width: 4, height: 4 }; + if ( format == GPUTextureFormat.EACRG11Unorm ) return { byteLength: 16, width: 4, height: 4 }; + if ( format == GPUTextureFormat.EACRG11Snorm ) return { byteLength: 16, width: 4, height: 4 }; + + if ( format == GPUTextureFormat.ASTC4x4Unorm || format == GPUTextureFormat.ASTC4x4UnormSRGB ) return { byteLength: 16, width: 4, height: 4 }; + if ( format == GPUTextureFormat.ASTC5x4Unorm || format == GPUTextureFormat.ASTC5x4UnormSRGB ) return { byteLength: 16, width: 5, height: 4 }; + if ( format == GPUTextureFormat.ASTC5x5Unorm || format == GPUTextureFormat.ASTC5x5UnormSRGB ) return { byteLength: 16, width: 5, height: 5 }; + if ( format == GPUTextureFormat.ASTC6x5Unorm || format == GPUTextureFormat.ASTC6x5UnormSRGB ) return { byteLength: 16, width: 6, height: 5 }; + if ( format == GPUTextureFormat.ASTC6x6Unorm || format == GPUTextureFormat.ASTC6x6UnormSRGB ) return { byteLength: 16, width: 6, height: 6 }; + if ( format == GPUTextureFormat.ASTC8x5Unorm || format == GPUTextureFormat.ASTC8x5UnormSRGB ) return { byteLength: 16, width: 8, height: 5 }; + if ( format == GPUTextureFormat.ASTC8x6Unorm || format == GPUTextureFormat.ASTC8x6UnormSRGB ) return { byteLength: 16, width: 8, height: 6 }; + if ( format == GPUTextureFormat.ASTC8x8Unorm || format == GPUTextureFormat.ASTC8x8UnormSRGB ) return { byteLength: 16, width: 8, height: 8 }; + if ( format == GPUTextureFormat.ASTC10x5Unorm || format == GPUTextureFormat.ASTC10x5UnormSRGB ) return { byteLength: 16, width: 10, height: 5 }; + if ( format == GPUTextureFormat.ASTC10x6Unorm || format == GPUTextureFormat.ASTC10x6UnormSRGB ) return { byteLength: 16, width: 10, height: 6 }; + if ( format == GPUTextureFormat.ASTC10x8Unorm || format == GPUTextureFormat.ASTC10x8UnormSRGB ) return { byteLength: 16, width: 10, height: 8 }; + if ( format == GPUTextureFormat.ASTC10x10Unorm || format == GPUTextureFormat.ASTC10x10UnormSRGB ) return { byteLength: 16, width: 10, height: 10 }; + if ( format == GPUTextureFormat.ASTC12x10Unorm || format == GPUTextureFormat.ASTC12x10UnormSRGB ) return { byteLength: 16, width: 12, height: 10 }; + if ( format == GPUTextureFormat.ASTC12x12Unorm || format == GPUTextureFormat.ASTC12x12UnormSRGB ) return { byteLength: 16, width: 12, height: 12 }; + + } + + /// + /// Converts the three.js uv wrapping constants to GPU address mode constants. + /// + /// @private + /// @param {number} value - The three.js constant defining a uv wrapping mode. + /// @return {string} The GPU address mode. + /// + String _convertAddressMode( int value ) { + + String addressMode = GPUAddressMode.clampToEdge; + + if ( value == RepeatWrapping ) { + + addressMode = GPUAddressMode.Repeat; + + } else if ( value == MirroredRepeatWrapping ) { + + addressMode = GPUAddressMode.MirrorRepeat; + + } + + return addressMode; + + } + + /// + /// Converts the three.js filter constants to GPU filter constants. + /// + /// @private + /// @param {number} value - The three.js constant defining a filter mode. + /// @return {string} The GPU filter mode. + /// + String _convertFilterMode( int value ) { + + String filterMode = GPUFilterMode.linear; + + if ( value == NearestFilter || value == NearestMipmapNearestFilter || value == NearestMipmapLinearFilter ) { + + filterMode = GPUFilterMode.Nearest; + + } + + return filterMode; + + } + + /// + /// Returns the bytes-per-texel value for the given GPU texture format. + /// + /// @private + /// @param {string} format - The GPU texture format. + /// @return {number} The bytes-per-texel. + /// + int _getBytesPerTexel( String format ) { + + // 8-bit formats + if ( format == GPUTextureFormat.r8Unorm || + format == GPUTextureFormat.r8Snorm || + format == GPUTextureFormat.R8Uint || + format == GPUTextureFormat.R8Sint ) return 1; + + // 16-bit formats + if ( format == GPUTextureFormat.R16Uint || + format == GPUTextureFormat.R16Sint || + format == GPUTextureFormat.R16Float || + format == GPUTextureFormat.RG8Unorm || + format == GPUTextureFormat.RG8Snorm || + format == GPUTextureFormat.RG8Uint || + format == GPUTextureFormat.RG8Sint ) return 2; + + // 32-bit formats + if ( format == GPUTextureFormat.R32Uint || + format == GPUTextureFormat.R32Sint || + format == GPUTextureFormat.R32Float || + format == GPUTextureFormat.RG16Uint || + format == GPUTextureFormat.RG16Sint || + format == GPUTextureFormat.RG16Float || + format == GPUTextureFormat.RGBA8Unorm || + format == GPUTextureFormat.RGBA8UnormSRGB || + format == GPUTextureFormat.RGBA8Snorm || + format == GPUTextureFormat.RGBA8Uint || + format == GPUTextureFormat.RGBA8Sint || + format == GPUTextureFormat.BGRA8Unorm || + format == GPUTextureFormat.BGRA8UnormSRGB || + // Packed 32-bit formats + format == GPUTextureFormat.RGB9E5UFloat || + format == GPUTextureFormat.RGB10A2Unorm || + format == GPUTextureFormat.RG11B10UFloat || + format == GPUTextureFormat.Depth32Float || + format == GPUTextureFormat.Depth24Plus || + format == GPUTextureFormat.Depth24PlusStencil8 || + format == GPUTextureFormat.Depth32FloatStencil8 ) return 4; + + // 64-bit formats + if ( format == GPUTextureFormat.RG32Uint || + format == GPUTextureFormat.RG32Sint || + format == GPUTextureFormat.RG32Float || + format == GPUTextureFormat.RGBA16Uint || + format == GPUTextureFormat.RGBA16Sint || + format == GPUTextureFormat.RGBA16Float ) return 8; + + // 128-bit formats + if ( format == GPUTextureFormat.RGBA32Uint || + format == GPUTextureFormat.RGBA32Sint || + format == GPUTextureFormat.RGBA32Float ) return 16; + + + } + + /// + /// Returns the corresponding typed array type for the given GPU texture format. + /// + /// @private + /// @param {string} format - The GPU texture format. + /// @return {TypedArray.constructor} The typed array type. + /// + Type _getTypedArrayType( String format ) { + + if ( format == GPUTextureFormat.r8Uint ) return Uint8List; + if ( format == GPUTextureFormat.r8Sint ) return Int8List; + if ( format == GPUTextureFormat.r8Unorm ) return Uint8List; + if ( format == GPUTextureFormat.R8Snorm ) return Int8List; + if ( format == GPUTextureFormat.RG8Uint ) return Uint8List; + if ( format == GPUTextureFormat.RG8Sint ) return Int8List; + if ( format == GPUTextureFormat.RG8Unorm ) return Uint8List; + if ( format == GPUTextureFormat.RG8Snorm ) return Int8List; + if ( format == GPUTextureFormat.RGBA8Uint ) return Uint8List; + if ( format == GPUTextureFormat.RGBA8Sint ) return Int8List; + if ( format == GPUTextureFormat.RGBA8Unorm ) return Uint8List; + if ( format == GPUTextureFormat.RGBA8Snorm ) return Int8List; + + + if ( format == GPUTextureFormat.R16Uint ) return Uint16Array; + if ( format == GPUTextureFormat.R16Sint ) return Int16Array; + if ( format == GPUTextureFormat.RG16Uint ) return Uint16Array; + if ( format == GPUTextureFormat.RG16Sint ) return Int16Array; + if ( format == GPUTextureFormat.RGBA16Uint ) return Uint16Array; + if ( format == GPUTextureFormat.RGBA16Sint ) return Int16Array; + if ( format == GPUTextureFormat.R16Float ) return Uint16Array; + if ( format == GPUTextureFormat.RG16Float ) return Uint16Array; + if ( format == GPUTextureFormat.RGBA16Float ) return Uint16Array; + + + if ( format == GPUTextureFormat.R32Uint ) return Uint32Array; + if ( format == GPUTextureFormat.R32Sint ) return Int32Array; + if ( format == GPUTextureFormat.R32Float ) return Float32Array; + if ( format == GPUTextureFormat.RG32Uint ) return Uint32Array; + if ( format == GPUTextureFormat.RG32Sint ) return Int32Array; + if ( format == GPUTextureFormat.RG32Float ) return Float32Array; + if ( format == GPUTextureFormat.RGBA32Uint ) return Uint32Array; + if ( format == GPUTextureFormat.RGBA32Sint ) return Int32Array; + if ( format == GPUTextureFormat.RGBA32Float ) return Float32Array; + + if ( format == GPUTextureFormat.BGRA8Unorm ) return Uint8List; + if ( format == GPUTextureFormat.BGRA8UnormSRGB ) return Uint8List; + if ( format == GPUTextureFormat.RGB10A2Unorm ) return Uint32Array; + if ( format == GPUTextureFormat.RGB9E5UFloat ) return Uint32Array; + if ( format == GPUTextureFormat.RG11B10UFloat ) return Uint32Array; + + if ( format == GPUTextureFormat.Depth32Float ) return Float32Array; + if ( format == GPUTextureFormat.Depth24Plus ) return Uint32Array; + if ( format == GPUTextureFormat.Depth24PlusStencil8 ) return Uint32Array; + if ( format == GPUTextureFormat.Depth32FloatStencil8 ) return Float32Array; + + } + + /** + * Returns the GPU dimensions for the given texture. + * + * @private + * @param {Texture} texture - The texture. + * @return {string} The GPU dimension. + */ + _getDimension( texture ) { + + let dimension; + + if ( texture.is3DTexture || texture.isData3DTexture ) { + + dimension = GPUTextureDimension.ThreeD; + + } else { + + dimension = GPUTextureDimension.TwoD; + + } + + return dimension; + + } + +} + + + +/// +/// Returns the GPU format for the given texture. +/// +/// @param {Texture} texture - The texture. +/// @param {?GPUDevice} [device=null] - The GPU device which is used for feature detection. +/// It is not necessary to apply the device for most formats. +/// @return {string} The GPU format. +/// +String getFormat(Texture texture, { GPUDevice? device } ) { + + final format = texture.format; + final type = texture.type; + final colorSpace = texture.colorSpace; + final transfer = ColorManagement.getTransfer( colorSpace ); + + String formatGPU; + + if ( texture.isCompressedTexture == true || texture.isCompressedArrayTexture == true ) { + + switch ( format ) { + + case RGBA_S3TC_DXT1_Format: + formatGPU = ( transfer == SRGBTransfer ) ? GPUTextureFormat.BC1RGBAUnormSRGB : GPUTextureFormat.BC1RGBAUnorm; + break; + + case RGBA_S3TC_DXT3_Format: + formatGPU = ( transfer == SRGBTransfer ) ? GPUTextureFormat.BC2RGBAUnormSRGB : GPUTextureFormat.BC2RGBAUnorm; + break; + + case RGBA_S3TC_DXT5_Format: + formatGPU = ( transfer == SRGBTransfer ) ? GPUTextureFormat.BC3RGBAUnormSRGB : GPUTextureFormat.BC3RGBAUnorm; + break; + + case RGB_ETC2_Format: + formatGPU = ( transfer == SRGBTransfer ) ? GPUTextureFormat.ETC2RGB8UnormSRGB : GPUTextureFormat.ETC2RGB8Unorm; + break; + + case RGBA_ETC2_EAC_Format: + formatGPU = ( transfer == SRGBTransfer ) ? GPUTextureFormat.ETC2RGBA8UnormSRGB : GPUTextureFormat.ETC2RGBA8Unorm; + break; + + case RGBA_ASTC_4x4_Format: + formatGPU = ( transfer == SRGBTransfer ) ? GPUTextureFormat.ASTC4x4UnormSRGB : GPUTextureFormat.ASTC4x4Unorm; + break; + + case RGBA_ASTC_5x4_Format: + formatGPU = ( transfer == SRGBTransfer ) ? GPUTextureFormat.ASTC5x4UnormSRGB : GPUTextureFormat.ASTC5x4Unorm; + break; + + case RGBA_ASTC_5x5_Format: + formatGPU = ( transfer == SRGBTransfer ) ? GPUTextureFormat.ASTC5x5UnormSRGB : GPUTextureFormat.ASTC5x5Unorm; + break; + + case RGBA_ASTC_6x5_Format: + formatGPU = ( transfer == SRGBTransfer ) ? GPUTextureFormat.ASTC6x5UnormSRGB : GPUTextureFormat.ASTC6x5Unorm; + break; + + case RGBA_ASTC_6x6_Format: + formatGPU = ( transfer == SRGBTransfer ) ? GPUTextureFormat.ASTC6x6UnormSRGB : GPUTextureFormat.ASTC6x6Unorm; + break; + + case RGBA_ASTC_8x5_Format: + formatGPU = ( transfer == SRGBTransfer ) ? GPUTextureFormat.ASTC8x5UnormSRGB : GPUTextureFormat.ASTC8x5Unorm; + break; + + case RGBA_ASTC_8x6_Format: + formatGPU = ( transfer == SRGBTransfer ) ? GPUTextureFormat.ASTC8x6UnormSRGB : GPUTextureFormat.ASTC8x6Unorm; + break; + + case RGBA_ASTC_8x8_Format: + formatGPU = ( transfer == SRGBTransfer ) ? GPUTextureFormat.ASTC8x8UnormSRGB : GPUTextureFormat.ASTC8x8Unorm; + break; + + case RGBA_ASTC_10x5_Format: + formatGPU = ( transfer == SRGBTransfer ) ? GPUTextureFormat.ASTC10x5UnormSRGB : GPUTextureFormat.ASTC10x5Unorm; + break; + + case RGBA_ASTC_10x6_Format: + formatGPU = ( transfer == SRGBTransfer ) ? GPUTextureFormat.ASTC10x6UnormSRGB : GPUTextureFormat.ASTC10x6Unorm; + break; + + case RGBA_ASTC_10x8_Format: + formatGPU = ( transfer == SRGBTransfer ) ? GPUTextureFormat.ASTC10x8UnormSRGB : GPUTextureFormat.ASTC10x8Unorm; + break; + + case RGBA_ASTC_10x10_Format: + formatGPU = ( transfer == SRGBTransfer ) ? GPUTextureFormat.ASTC10x10UnormSRGB : GPUTextureFormat.ASTC10x10Unorm; + break; + + case RGBA_ASTC_12x10_Format: + formatGPU = ( transfer == SRGBTransfer ) ? GPUTextureFormat.ASTC12x10UnormSRGB : GPUTextureFormat.ASTC12x10Unorm; + break; + + case RGBA_ASTC_12x12_Format: + formatGPU = ( transfer == SRGBTransfer ) ? GPUTextureFormat.ASTC12x12UnormSRGB : GPUTextureFormat.ASTC12x12Unorm; + break; + + case RGBAFormat: + formatGPU = ( transfer == SRGBTransfer ) ? GPUTextureFormat.RGBA8UnormSRGB : GPUTextureFormat.RGBA8Unorm; + break; + + default: + console.error( 'WebGPURenderer: Unsupported texture format.', format ); + + } + + } else { + + switch ( format ) { + + case RGBAFormat: + + switch ( type ) { + + case ByteType: + formatGPU = GPUTextureFormat.RGBA8Snorm; + break; + + case ShortType: + formatGPU = GPUTextureFormat.RGBA16Sint; + break; + + case UnsignedShortType: + formatGPU = GPUTextureFormat.RGBA16Uint; + break; + case UnsignedIntType: + formatGPU = GPUTextureFormat.RGBA32Uint; + break; + + case IntType: + formatGPU = GPUTextureFormat.RGBA32Sint; + break; + + case UnsignedByteType: + formatGPU = ( transfer == SRGBTransfer ) ? GPUTextureFormat.RGBA8UnormSRGB : GPUTextureFormat.RGBA8Unorm; + break; + + case HalfFloatType: + formatGPU = GPUTextureFormat.RGBA16Float; + break; + + case FloatType: + formatGPU = GPUTextureFormat.RGBA32Float; + break; + + default: + console.error( 'WebGPURenderer: Unsupported texture type with RGBAFormat.', type ); + + } + + break; + + case RGBFormat: + + switch ( type ) { + + case UnsignedInt5999Type: + formatGPU = GPUTextureFormat.RGB9E5UFloat; + break; + + default: + console.error( 'WebGPURenderer: Unsupported texture type with RGBFormat.', type ); + + } + + break; + + case RedFormat: + + switch ( type ) { + + case ByteType: + formatGPU = GPUTextureFormat.R8Snorm; + break; + + case ShortType: + formatGPU = GPUTextureFormat.R16Sint; + break; + + case UnsignedShortType: + formatGPU = GPUTextureFormat.R16Uint; + break; + + case UnsignedIntType: + formatGPU = GPUTextureFormat.R32Uint; + break; + + case IntType: + formatGPU = GPUTextureFormat.R32Sint; + break; + + case UnsignedByteType: + formatGPU = GPUTextureFormat.R8Unorm; + break; + + case HalfFloatType: + formatGPU = GPUTextureFormat.R16Float; + break; + + case FloatType: + formatGPU = GPUTextureFormat.R32Float; + break; + + default: + console.error( 'WebGPURenderer: Unsupported texture type with RedFormat.', type ); + + } + + break; + + case RGFormat: + + switch ( type ) { + + case ByteType: + formatGPU = GPUTextureFormat.RG8Snorm; + break; + + case ShortType: + formatGPU = GPUTextureFormat.RG16Sint; + break; + + case UnsignedShortType: + formatGPU = GPUTextureFormat.RG16Uint; + break; + + case UnsignedIntType: + formatGPU = GPUTextureFormat.RG32Uint; + break; + + case IntType: + formatGPU = GPUTextureFormat.RG32Sint; + break; + + case UnsignedByteType: + formatGPU = GPUTextureFormat.RG8Unorm; + break; + + case HalfFloatType: + formatGPU = GPUTextureFormat.RG16Float; + break; + + case FloatType: + formatGPU = GPUTextureFormat.RG32Float; + break; + + default: + console.error( 'WebGPURenderer: Unsupported texture type with RGFormat.', type ); + + } + + break; + + case DepthFormat: + + switch ( type ) { + + case UnsignedShortType: + formatGPU = GPUTextureFormat.Depth16Unorm; + break; + + case UnsignedIntType: + formatGPU = GPUTextureFormat.Depth24Plus; + break; + + case FloatType: + formatGPU = GPUTextureFormat.Depth32Float; + break; + + default: + console.error( 'WebGPURenderer: Unsupported texture type with DepthFormat.', type ); + + } + + break; + + case DepthStencilFormat: + + switch ( type ) { + + case UnsignedInt248Type: + formatGPU = GPUTextureFormat.Depth24PlusStencil8; + break; + + case FloatType: + + if ( device && device.features.has( GPUFeatureName.Depth32FloatStencil8 ) == false ) { + + console.error( 'WebGPURenderer: Depth textures with DepthStencilFormat + FloatType can only be used with the "depth32float-stencil8" GPU feature.' ); + + } + + formatGPU = GPUTextureFormat.Depth32FloatStencil8; + + break; + + default: + console.error( 'WebGPURenderer: Unsupported texture type with DepthStencilFormat.', type ); + + } + + break; + + case RedIntegerFormat: + + switch ( type ) { + + case IntType: + formatGPU = GPUTextureFormat.R32Sint; + break; + + case UnsignedIntType: + formatGPU = GPUTextureFormat.R32Uint; + break; + + default: + console.error( 'WebGPURenderer: Unsupported texture type with RedIntegerFormat.', type ); + + } + + break; + + case RGIntegerFormat: + + switch ( type ) { + + case IntType: + formatGPU = GPUTextureFormat.RG32Sint; + break; + + case UnsignedIntType: + formatGPU = GPUTextureFormat.RG32Uint; + break; + + default: + console.error( 'WebGPURenderer: Unsupported texture type with RGIntegerFormat.', type ); + + } + + break; + + case RGBAIntegerFormat: + + switch ( type ) { + + case IntType: + formatGPU = GPUTextureFormat.RGBA32Sint; + break; + + case UnsignedIntType: + formatGPU = GPUTextureFormat.RGBA32Uint; + break; + + default: + console.error( 'WebGPURenderer: Unsupported texture type with RGBAIntegerFormat.', type ); + + } + + break; + + default: + console.error( 'WebGPURenderer: Unsupported texture format.', format ); + + } + + } + + return formatGPU; +} diff --git a/packages/three_js_impeller_renderer/.gitignore b/packages/three_js_impeller_renderer/.gitignore new file mode 100755 index 00000000..fbf43d48 --- /dev/null +++ b/packages/three_js_impeller_renderer/.gitignore @@ -0,0 +1,143 @@ +# Miscellaneous +*.class +*.lock +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +renderers_old/ +renderers_new/ +# Visual Studio Code related +.classpath +.project +.settings/ +.vscode/* +.metadata + +*/macos +*/web +*/ios +*/android +*/linux +*/windows + +# Flutter repo-specific +/bin/cache/ +/bin/internal/bootstrap.bat +/bin/internal/bootstrap.sh +/bin/mingit/ +/dev/benchmarks/mega_gallery/ +/dev/bots/.recipe_deps +/dev/bots/android_tools/ +/dev/devicelab/ABresults*.json +/dev/docs/doc/ +/dev/docs/flutter.docs.zip +/dev/docs/lib/ +/dev/docs/pubspec.yaml +/dev/integration_tests/**/xcuserdata +/dev/integration_tests/**/Pods +/packages/flutter/coverage/ +version +analysis_benchmark.json + +# packages file containing multi-root paths +.packages.generated + +# Flutter/Dart/Pub related +**/doc/api/ +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +**/generated_plugin_registrant.dart +.packages +.pub-preload-cache/ +.pub/ +build/ +flutter_*.png +linked_*.ds +unlinked.ds +unlinked_spec.ds + +# Android related +**/android/**/gradle-wrapper.jar +.gradle/ +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java +**/android/key.properties +*.jks + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/.last_build_id +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Flutter.podspec +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/ephemeral +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/Flutter/flutter_export_environment.sh +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# macOS +**/Flutter/ephemeral/ +**/Pods/ +**/macos/Flutter/GeneratedPluginRegistrant.swift +**/macos/Flutter/ephemeral +**/xcuserdata/ + +# Windows +**/windows/flutter/generated_plugin_registrant.cc +**/windows/flutter/generated_plugin_registrant.h +**/windows/flutter/generated_plugins.cmake + +# Linux +**/linux/flutter/generated_plugin_registrant.cc +**/linux/flutter/generated_plugin_registrant.h +**/linux/flutter/generated_plugins.cmake + +# Coverage +coverage/ + +# Symbols +app.*.symbols + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +!/dev/ci/**/Gemfile.lock +!.vscode/settings.json \ No newline at end of file diff --git a/packages/three_js_impeller_renderer/CHANGELOG.md b/packages/three_js_impeller_renderer/CHANGELOG.md new file mode 100755 index 00000000..9b7b03ba --- /dev/null +++ b/packages/three_js_impeller_renderer/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.0.1 + +* Initial release. \ No newline at end of file diff --git a/packages/three_js_impeller_renderer/LICENSE b/packages/three_js_impeller_renderer/LICENSE new file mode 100755 index 00000000..383b4da5 --- /dev/null +++ b/packages/three_js_impeller_renderer/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright © 2010-2024 three.js authors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/packages/three_js_impeller_renderer/README.md b/packages/three_js_impeller_renderer/README.md new file mode 100755 index 00000000..a918e082 --- /dev/null +++ b/packages/three_js_impeller_renderer/README.md @@ -0,0 +1,21 @@ +# three_js_angle_renderer + +[![Pub Version](https://img.shields.io/pub/v/three_js_angle_renderer)](https://pub.dev/packages/three_js_angle_renderer) +[![License: MIT](https://img.shields.io/badge/license-MIT-purple.svg)](https://opensource.org/licenses/MIT) + +This is one of the renderers for three_js to allow users to view their 3D objects in their projects. + +## Usage + +This is a renderer for three_js using google's ANGLE. + +## Example + +Find the example for this API [here](https://github.com/Knightro63/three_js/tree/main/packages/three_js_angle_renderer/example/lib/main.dart). + +## Contributing + +Contributions are welcome. +In case of any problems look at [existing issues](https://github.com/Knightro63/three_js/issues), if you cannot find anything related to your problem then open an issue. +Create an issue before opening a [pull request](https://github.com/Knightro63/three_js/pulls) for non trivial fixes. +In case of trivial fixes open a [pull request](https://github.com/Knightro63/three_js/pulls) directly. diff --git a/packages/three_js_impeller_renderer/example/.gitignore b/packages/three_js_impeller_renderer/example/.gitignore new file mode 100755 index 00000000..79c113f9 --- /dev/null +++ b/packages/three_js_impeller_renderer/example/.gitignore @@ -0,0 +1,45 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.build/ +.buildlog/ +.history +.svn/ +.swiftpm/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.pub-cache/ +.pub/ +/build/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/packages/three_js_impeller_renderer/example/README.md b/packages/three_js_impeller_renderer/example/README.md new file mode 100755 index 00000000..2b3fce4c --- /dev/null +++ b/packages/three_js_impeller_renderer/example/README.md @@ -0,0 +1,16 @@ +# example + +A new Flutter project. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) + +For help getting started with Flutter development, view the +[online documentation](https://docs.flutter.dev/), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/packages/three_js_impeller_renderer/example/lib/main.dart b/packages/three_js_impeller_renderer/example/lib/main.dart new file mode 100755 index 00000000..6b8099d1 --- /dev/null +++ b/packages/three_js_impeller_renderer/example/lib/main.dart @@ -0,0 +1,114 @@ +import 'dart:async'; +import 'package:flutter/material.dart'; +import 'package:three_js_core/three_js_core.dart' as three; +import 'package:three_js_math/three_js_math.dart' as tmath; +import 'package:three_js_angle_renderer/three_js_angle_renderer.dart'; +import 'dart:math' as math; + +void main() { + runApp(const MyApp()); +} + +class MyApp extends StatelessWidget { + const MyApp({super.key}); + + // This widget is the root of your application. + @override + Widget build(BuildContext context) { + return MaterialApp( + theme: ThemeData( + colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), + useMaterial3: true, + ), + home: const WebglGeometries(), + ); + } +} + +class WebglGeometries extends StatefulWidget { + const WebglGeometries({super.key}); + + @override + createState() => _State(); +} + +class _State extends State { + late ThreeJS threeJs; + + @override + void initState() { + threeJs = ThreeJS( + onSetupComplete: (){setState(() {});}, + setup: setup, + settings: Settings( + localClippingEnabled: true, + ) + ); + super.initState(); + } + @override + void dispose() { + threeJs.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return threeJs.build(); + } + + int startTime = 0; + + Future setup() async { + threeJs.camera = three.PerspectiveCamera(45, threeJs.width / threeJs.height, 1, 2000); + threeJs.camera.position.y = 400; + + threeJs.scene = three.Scene(); + + three.Mesh object; + + final ambientLight = three.AmbientLight(0xffffff, 0.8); + threeJs.scene.add(ambientLight); + + final pointLight = three.PointLight(0xffffff, 0.8); + threeJs.camera.add(pointLight); + threeJs.scene.add(threeJs.camera); + + final material = three.MeshPhongMaterial.fromMap({ + "color": 0xffffff, + "side": tmath.DoubleSide, + "clipShadows": true + }); + object = three.Mesh(three.SphereGeometry(75, 20, 10), material); + object.position.setValues(-300, 0, 200); + threeJs.scene.add(object); + + object = three.Mesh(three.PlaneGeometry(100, 100, 4, 4), material); + object.position.setValues(-300, 0, 0); + threeJs.scene.add(object); + + object = three.Mesh(three.BoxGeometry(100, 100, 100, 4, 4, 4), material); + object.position.setValues(-100, 0, 0); + threeJs.scene.add(object); + + + startTime = DateTime.now().millisecondsSinceEpoch; + + threeJs.addAnimationEvent((dt){ + final timer = DateTime.now().millisecondsSinceEpoch * 0.0001; + + threeJs.camera.position.x = math.cos(timer) * 800; + threeJs.camera.position.z = math.sin(timer) * 800; + threeJs.camera.lookAt(threeJs.scene.position); + + threeJs.scene.traverse((object) { + if (object is three.Mesh) { + object.rotation.x = timer * 5; + object.rotation.y = timer * 2.5; + } + }); + }); + } +} + + diff --git a/packages/three_js_impeller_renderer/example/pubspec.yaml b/packages/three_js_impeller_renderer/example/pubspec.yaml new file mode 100755 index 00000000..475e1bd2 --- /dev/null +++ b/packages/three_js_impeller_renderer/example/pubspec.yaml @@ -0,0 +1,33 @@ +name: example +description: "A new Flutter project." +publish_to: 'none' # Remove this line if you wish to publish to pub.dev +version: 1.0.0+1 + +environment: + sdk: '>=3.3.2 <4.0.0' + +dependencies: + flutter: + sdk: flutter + cupertino_icons: ^1.0.6 + three_js_angle_renderer: + path: ../ + three_js_math: ^0.2.0 + three_js_core: ^0.2.0 + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^3.0.0 + +dependency_overrides: + flutter_angle: + path: ../../../../flutter_angle/flutter_angle + three_js_math: + path: ../../three_js_math + three_js_core: + path: ../../three_js_core + +# The following section is specific to Flutter packages. +flutter: + uses-material-design: true \ No newline at end of file diff --git a/packages/three_js_impeller_renderer/lib/renderers/index.dart b/packages/three_js_impeller_renderer/lib/renderers/index.dart new file mode 100644 index 00000000..793f0fd5 --- /dev/null +++ b/packages/three_js_impeller_renderer/lib/renderers/index.dart @@ -0,0 +1,9 @@ +library three_renderers; + +import 'package:flutter/foundation.dart'; +import 'package:three_js_core/three_js_core.dart'; +import 'package:three_js_math/three_js_math.dart'; +import 'dart:ui' as ui; +import 'package:flutter_gpu/gpu.dart' as gpu; + +part 'renderer.dart'; \ No newline at end of file diff --git a/packages/three_js_impeller_renderer/lib/renderers/renderer.dart b/packages/three_js_impeller_renderer/lib/renderers/renderer.dart new file mode 100755 index 00000000..80c2825c --- /dev/null +++ b/packages/three_js_impeller_renderer/lib/renderers/renderer.dart @@ -0,0 +1,164 @@ +part of three_renderers; + +class ImpellerRendererParameters{ + double width; + double height; + bool stencil; + bool antialias; + bool alpha; + int clearColor; + double clearAlpha; + bool logarithmicDepthBuffer; + bool premultipliedAlpha; + bool preserveDrawingBuffer; + PowerPreference powerPreference; + bool reverseDepthBuffer; + bool failIfMajorPerformanceCaveat; + bool depth = true; + Precision precision; + ui.Canvas canvas; + XRManager Function(ImpellerRenderer renderer, dynamic gl)? xr; + + ImpellerRendererParameters({ + required this.width, + required this.height, + this.stencil = true, + this.antialias = false, + this.alpha = false, + this.clearAlpha = 1.0, + this.clearColor = 0x000000, + this.logarithmicDepthBuffer = false, + this.depth = true, + this.premultipliedAlpha = true, + this.preserveDrawingBuffer = false, + this.powerPreference = PowerPreference.defaultp, + this.failIfMajorPerformanceCaveat = false, + this.reverseDepthBuffer = false, + this.precision = Precision.highp, + required this.canvas, + this.xr, + }); + + factory ImpellerRendererParameters.fromMap(Map map){ + return ImpellerRendererParameters( + width: map["width"].toDouble(), + height: map["height"].toDouble(), + depth: map["depth"] ?? true, + stencil: map["stencil"] ?? true, + antialias: map["antialias"] ?? false, + premultipliedAlpha: map["premultipliedAlpha"] ?? true, + preserveDrawingBuffer: map["preserveDrawingBuffer"] ?? false, + powerPreference: map["powerPreference"] ?? "default", + failIfMajorPerformanceCaveat: map["failIfMajorPerformanceCaveat"] ?? false, + alpha: map["alpha"] ?? false, + canvas: map["canvas"], + xr: map["xr"], + precision: map['precision'], + reverseDepthBuffer: map['reverseDepthBuffer'] + ); + } +} + +class ImpellerRenderer extends Renderer{ + late final ImpellerRendererParameters parameters; + + late final ui.Canvas _canvas; + + bool antialias = false; + + // clearing + + bool autoClear = true; + bool autoClearColor = true; + bool autoClearDepth = true; + bool autoClearStencil = true; + + late double _width; + late double _height; + + double get width => _width; + double get height => _height; + + late final ui.Rect _viewport; + late final ui.Rect _scissor; + + bool _isContextLost = false; + + ImpellerRenderer(this.parameters){ + _width = this.parameters.width; + _height = this.parameters.height; + + antialias = this.parameters.antialias; + + _viewport = ui.Rect.fromLTWH(0, 0, width, height); + _scissor = ui.Rect.fromLTWH(0, 0, width, height); + + _canvas = this.parameters.canvas; + } + + @override + void dispose() { + // TODO: implement dispose + } + + @override + void render(Object3D scene, Camera camera) { + if (_isContextLost) return; + + if (scene.matrixWorldAutoUpdate) scene.updateMatrixWorld(); + + if (camera.parent == null && camera.matrixWorldAutoUpdate) camera.updateMatrixWorld(); + + if ( xr.enabled && xr.isPresenting ) { + if (xr.cameraAutoUpdate) xr.updateCamera( camera ); + if(kIsWeb) camera = xr.getCamera(); + } + + if (scene is Scene) { + scene.onBeforeRender?.call(renderer: this, scene: scene, camera: camera, renderTarget: _currentRenderTarget); + } + + final drawArea = _canvas.getLocalClipBounds(); + if (drawArea.isEmpty) { + return; + } + final enableMsaa = antialias; + final gpu.RenderTarget renderTarget = surface.getNextRenderTarget( + drawArea.size, + enableMsaa, + ); + + final env = + environment.environmentMap.isEmpty() + ? environment.withNewEnvironmentMap( + Material.getDefaultEnvironmentMap(), + ) + : environment; + + final encoder = SceneEncoder(renderTarget, camera, drawArea.size, env); + root.render(encoder, Matrix4.identity()); + encoder.finish(); + + final gpu.Texture texture = + enableMsaa + ? renderTarget.colorAttachments[0].resolveTexture! + : renderTarget.colorAttachments[0].texture; + final image = texture.asImage(); + _canvas.drawImage(image, drawArea.topLeft, ui.Paint()); + } + + @override + void clear([bool color = true, bool depth = true, bool stencil = true]){ + + } + + @override + void setRenderTarget(RenderTarget? renderTarget, [int activeCubeFace = 0, int activeMipmapLevel = 0]){ + + } + + @override + RenderTarget? getRenderTarget(){ + return null; + } +} diff --git a/packages/three_js_impeller_renderer/lib/three_js_impeller_renderer.dart b/packages/three_js_impeller_renderer/lib/three_js_impeller_renderer.dart new file mode 100755 index 00000000..e27c3955 --- /dev/null +++ b/packages/three_js_impeller_renderer/lib/three_js_impeller_renderer.dart @@ -0,0 +1,3 @@ +library three_js_impeller_renderer; + +export 'three_viewer.dart'; \ No newline at end of file diff --git a/packages/three_js_impeller_renderer/lib/three_viewer.dart b/packages/three_js_impeller_renderer/lib/three_viewer.dart new file mode 100644 index 00000000..3155cf41 --- /dev/null +++ b/packages/three_js_impeller_renderer/lib/three_viewer.dart @@ -0,0 +1,425 @@ +import 'dart:async'; +import 'dart:io'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/scheduler.dart'; +import 'package:three_js_angle/renderers/index.dart'; +import 'package:three_js_core/others/index.dart'; +import 'package:three_js_core/renderers/index.dart'; +import 'package:three_js_core/three_js_core.dart' as core; +import 'package:three_js_math/three_js_math.dart'; +import 'package:flutter_angle/flutter_angle.dart'; + +class Settings{ + Settings({ + this.useSourceTexture = false, + this.enableShadowMap = true, + this.autoClear = true, + Map? renderOptions, + this.animate = true, + this.alpha = false, + this.autoClearDepth = true, + this.autoClearStencil = true, + this.clearAlpha = 1.0, + this.clearColor = 0x000000, + this.localClippingEnabled = false, + this.clippingPlanes = const [], + this.colorSpace = ColorSpace.srgb, + this.outputEncoding = sRGBEncoding, + this.toneMapping = NoToneMapping, + this.shadowMapType = PCFShadowMap, + this.toneMappingExposure = 1.0, + this.logarithmicDepthBuffer = false, + this.stencil = true, + this.xr, + this.antialias = false, + + this.depth = true, + this.premultipliedAlpha = true, + this.preserveDrawingBuffer = false, + this.powerPreference = core.PowerPreference.defaultp, + this.failIfMajorPerformanceCaveat = false, + this.reverseDepthBuffer = false, + this.precision = core.Precision.highp, + this.screenResolution + }){ + this.renderOptions = renderOptions ?? { + "format": RGBAFormat, + "samples": 4 + }; + } + + bool premultipliedAlpha; + bool preserveDrawingBuffer; + PowerPreference powerPreference; + bool reverseDepthBuffer; + bool failIfMajorPerformanceCaveat; + bool depth = true; + Precision precision; + bool alpha; + bool stencil; + bool logarithmicDepthBuffer; + int clearColor; + double clearAlpha; + bool antialias; + XRManager Function(ImpellerRenderer renderer, dynamic gl)? xr; + double? screenResolution; + + bool animate; + bool useSourceTexture; + bool enableShadowMap; + bool autoClear; + bool autoClearDepth; + bool autoClearStencil; + bool localClippingEnabled; + late Map renderOptions; + List clippingPlanes; + int outputEncoding; + ColorSpace colorSpace; + int toneMapping; + int shadowMapType; + double toneMappingExposure; +} + +/// threeJs utility class. If you want to learn how to connect cannon.js with js, please look at the examples/threejs_* instead. +class ThreeJS with WidgetsBindingObserver{ + void Function() onSetupComplete; + ThreeJS({ + Settings? settings, + required this.onSetupComplete, + required this.setup, + this.rendererUpdate, + this.postProcessor, + this.windowResizeUpdate, + Size? size, + ImpellerRenderer? renderer, + this.renderNumber = 0, + this.loadingWidget + }){ + this.settings = settings ?? Settings(); + _resolution = this.settings.screenResolution; + _fixedSize = size; + } + + int renderNumber; + + BuildContext? _context; + Timer? _debounceTimer; + + Widget? loadingWidget; + Size? _fixedSize; + late final Settings settings; + final GlobalKey globalKey = GlobalKey(); + core.PeripheralsState get domElement => globalKey.currentState!; + + bool visible = true; + + FlutterAngleTexture? texture; + RenderingContext? gl; + + ImpellerRenderTarget? renderTarget; + ImpellerRenderer? renderer; + final core.Clock clock = core.Clock(); + + late final core.Scene scene; + late final core.Camera camera; + Ticker? ticker; + + double get width => screenSize!.width; + double get height => screenSize!.height; + + Size? screenSize; + double? _resolution; + double get dpr => _resolution ?? 1.0; + void setResolution(double newResolution){ + _resolution = newResolution; + } + + WebGLTexture? sourceTexture; + + bool pause = false; + bool _disposed = false; + bool isVisibleOnScreen = true; + bool _mounted = false; + bool get mounted => _mounted; + bool _updating = false; + bool get updating => _updating; + + void Function()? rendererUpdate; + void Function(Size newSize)? windowResizeUpdate; + void Function([double? dt])? postProcessor; + Future Function(core.Scene,core.Camera,FlutterAngleTexture,[double? dt])? customRenderer; + Future Function(BuildContext) onWindowResize = (context) async{}; + FutureOr Function()? setup; + List events = []; + List disposeEvents = []; + + FlutterAngle? angle = FlutterAngle(); + + void addAnimationEvent(Function(double dt) event){ + events.add(event); + } + void toDispose(Function() event){ + disposeEvents.add(event); + } + + @override + void didChangeMetrics() { + if (_disposed) return; + _debounceTimer?.cancel(); // Clear existing timer + _debounceTimer = Timer(Duration(milliseconds: 300+renderNumber*100), () { // Set a new timer + if (_context != null && _context!.mounted) { + _onWindowResize(_context!); + } + }); + } + + void dispose(){ + if(_disposed) return; + _disposed = true; + _debounceTimer?.cancel(); // Cancel timer if active + _debounceTimer = null; + WidgetsBinding.instance.removeObserver(this); + ticker?.dispose(); + ticker = null; + renderer?.dispose(); + renderer = null; + renderTarget?.dispose(); + renderTarget = null; + scene.dispose(); + for(final event in disposeEvents){ + event.call(); + } + + camera.dispose(); + events.clear(); + disposeEvents.clear(); + + //allNativeData.dispose(); + + angle?.dispose([texture]); + loadingWidget = null; + _fixedSize = null; + screenSize = null; + + rendererUpdate = null; + windowResizeUpdate = null; + postProcessor = null; + setup = null; + } + + void initSize(BuildContext context){ + if (screenSize != null) { + return; + } + _context = context; + WidgetsBinding.instance.addObserver(this); + final mqd = MediaQuery.of(context); + + screenSize = _fixedSize ?? mqd.size; + _resolution ??= mqd.devicePixelRatio; + + Future.delayed(Duration(milliseconds: renderNumber*100), () async{ + await initPlatformState(); + }); + } + + Future animate(Duration duration) async { + if (!mounted || _disposed || updating || !isVisibleOnScreen || !visible) { + return; + } + _updating = true; + double dt = clock.getDelta(); + + if(settings.animate){ + await (customRenderer?.call(scene,camera,texture!,dt) ?? render(scene,camera,texture!,dt)); + if(!pause){ + for(int i = 0; i < events.length;i++){ + events[i].call(dt); + } + } + } + _updating = false; + } + + Future render([core.Scene? scene, core.Camera? camera, FlutterAngleTexture? texture, double? dt]) async{ + scene ??= this.scene; + camera ??= this.camera; + texture ??= this.texture!; + + if(sourceTexture == null){ + angle?.activateTexture(texture); + } + rendererUpdate?.call(); + if(postProcessor == null){ + renderer!.clear(); + renderer!.setViewport(0,0,width,height); + renderer!.render(scene, camera); + } + else{ + postProcessor?.call(dt); + } + + if(sourceTexture != null){ + angle?.activateTexture(texture); + } + await angle?.updateTexture(texture,sourceTexture); + } + + void initRenderer() { + ImpellerRendererParameters options = ImpellerRendererParameters( + width: width, + height: height, + stencil: settings.stencil, + antialias: settings.antialias, + alpha: settings.alpha, + clearColor: settings.clearColor, + clearAlpha: settings.clearAlpha, + logarithmicDepthBuffer: settings.logarithmicDepthBuffer, + xr: settings.xr, + depth: settings.depth, + premultipliedAlpha: settings.premultipliedAlpha, + preserveDrawingBuffer: settings.preserveDrawingBuffer, + powerPreference: settings.powerPreference, + failIfMajorPerformanceCaveat: settings.failIfMajorPerformanceCaveat, + reverseDepthBuffer: settings.reverseDepthBuffer, + precision: settings.precision, + ); + + renderer = ImpellerRenderer(options); + renderer!.setPixelRatio(_resolution!); + renderer!.setSize(width, height, false); + renderer!.alpha = settings.alpha; + renderer!.shadowMap.enabled = settings.enableShadowMap; + renderer!.shadowMap.type = settings.shadowMapType; + renderer!.autoClear = settings.autoClear; + renderer!.setClearColor( + Color.fromHex32(settings.clearColor), + settings.clearAlpha + ); + renderer!.autoClearDepth = settings.autoClearDepth; + renderer!.autoClearStencil = settings.autoClearStencil; + renderer!.outputEncoding = settings.outputEncoding; + renderer!.outputColorSpace = settings.colorSpace.toString(); + renderer!.localClippingEnabled = settings.localClippingEnabled; + renderer!.clippingPlanes = settings.clippingPlanes; + renderer!.toneMapping = settings.toneMapping; + renderer!.toneMappingExposure = settings.toneMappingExposure; + + if(settings.useSourceTexture){ + final RenderTargetOptions pars = RenderTargetOptions(settings.renderOptions); + renderTarget = ImpellerRenderTarget((width * _resolution!).toInt(), (height * _resolution!).toInt(), pars); + renderer!.setRenderTarget(renderTarget); + sourceTexture = renderer!.getRenderTargetGLTexture(renderTarget!); + } + } + + Future _onWindowResize(BuildContext context) async{ + if (_disposed) return; + double dt = clock.getDelta(); + final mqd = MediaQuery.maybeOf(context); + if (mqd == null) return; + if(_fixedSize == null && screenSize != mqd.size && texture != null){ + screenSize = mqd.size; + + if(settings.screenResolution == null){ + _resolution = mqd.devicePixelRatio; + } + + final options = AngleOptions( + width: width.toInt(), + height: height.toInt(), + dpr: _resolution!, + ); + + await angle?.resize(texture!, options); + + camera.aspect = width/height; + camera.updateProjectionMatrix(); + + windowResizeUpdate?.call(screenSize!); + renderer!.setSize(width, height); + + if(postProcessor != null){ + postProcessor?.call(dt); + } + render(scene,camera,texture!,dt); + } + } + + Future initScene() async{ + if (renderer == null) { + initRenderer(); + } + await setup?.call(); + _mounted = true; + ticker = Ticker(animate); + ticker?.start(); + onSetupComplete(); + } + + Future initPlatformState() async { + if(texture == null){ + await angle?.init(); + + texture = await angle?.createTexture( + AngleOptions( + width: width.toInt(), + height: height.toInt(), + dpr: _resolution!, + alpha: settings.alpha, + antialias: settings.antialias, + customRenderer: !settings.useSourceTexture, + useSurfaceProducer: true + ) + ); + } + + console.info(texture?.toMap()); + if (gl == null) { + gl = texture!.getContext(); + } + await initScene(); + } + + Widget build() { + return Builder(builder: (BuildContext context) { + initSize(context); + return core.Peripherals( + key: globalKey, + builder: (BuildContext context) { + return Container( + width: !visible?0:width, + height: !visible?0:height, + child: SizeChangedLayoutNotifier( + child: Builder(builder: (BuildContext context) { + if (kIsWeb) { + return texture != null && mounted? HtmlElementView(viewType:texture!.textureId.toString()):loadingWidget ?? Container( + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height, + color: Theme.of(context).canvasColor, + alignment: Alignment.center, + child: const CircularProgressIndicator() + ); + } + else { + return texture != null && mounted? + Transform.scale( + scaleY: sourceTexture != null || Platform.isAndroid?1:-1, + child:Texture(textureId: texture!.textureId) + ):loadingWidget ?? Container( + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height, + color: Theme.of(context).canvasColor, + alignment: Alignment.center, + child: const CircularProgressIndicator() + ); + } + }) + ) + ); + } + ); + }); + } +} \ No newline at end of file diff --git a/packages/three_js_impeller_renderer/pubspec.yaml b/packages/three_js_impeller_renderer/pubspec.yaml new file mode 100755 index 00000000..95660e1f --- /dev/null +++ b/packages/three_js_impeller_renderer/pubspec.yaml @@ -0,0 +1,32 @@ +name: three_js_angle_renderer +description: "This is a renderer for three_js using angle." +version: 0.0.1 +homepage: https://github.com/Knightro63/three_js/tree/main/packages/three_js_angle_renderer + +environment: + sdk: '>=3.5.0 <4.0.0' + flutter: ">=1.17.0" + +dependencies: + flutter: + sdk: flutter + flutter_gpu: + sdk: flutter + logger: ^2.5.0 + web: ^1.1.1 + three_js_core: ^0.3.0 + three_js_math: ^0.3.0 + flutter_angle: ^0.4.0 + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^5.0.0 + +dependency_overrides: + three_js_math: + path: ../three_js_math + three_js_core: + path: ../three_js_core + flutter_angle: + path: ../../../flutter_angle/flutter_angle \ No newline at end of file diff --git a/packages/three_js_webgl/.gitignore b/packages/three_js_webgl/.gitignore new file mode 100755 index 00000000..2e198e1d --- /dev/null +++ b/packages/three_js_webgl/.gitignore @@ -0,0 +1,141 @@ +# Miscellaneous +*.class +*.lock +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ +.metadata + +# Visual Studio Code related +.classpath +.project +.settings/ +.vscode/* + +*/macos +*/web +*/ios +*/android +*/linux +*/windows + +# Flutter repo-specific +/bin/cache/ +/bin/internal/bootstrap.bat +/bin/internal/bootstrap.sh +/bin/mingit/ +/dev/benchmarks/mega_gallery/ +/dev/bots/.recipe_deps +/dev/bots/android_tools/ +/dev/devicelab/ABresults*.json +/dev/docs/doc/ +/dev/docs/flutter.docs.zip +/dev/docs/lib/ +/dev/docs/pubspec.yaml +/dev/integration_tests/**/xcuserdata +/dev/integration_tests/**/Pods +/packages/flutter/coverage/ +version +analysis_benchmark.json + +# packages file containing multi-root paths +.packages.generated + +# Flutter/Dart/Pub related +**/doc/api/ +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +**/generated_plugin_registrant.dart +.packages +.pub-preload-cache/ +.pub/ +build/ +flutter_*.png +linked_*.ds +unlinked.ds +unlinked_spec.ds + +# Android related +**/android/**/gradle-wrapper.jar +.gradle/ +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java +**/android/key.properties +*.jks + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/.last_build_id +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Flutter.podspec +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/ephemeral +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/Flutter/flutter_export_environment.sh +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# macOS +**/Flutter/ephemeral/ +**/Pods/ +**/macos/Flutter/GeneratedPluginRegistrant.swift +**/macos/Flutter/ephemeral +**/xcuserdata/ + +# Windows +**/windows/flutter/generated_plugin_registrant.cc +**/windows/flutter/generated_plugin_registrant.h +**/windows/flutter/generated_plugins.cmake + +# Linux +**/linux/flutter/generated_plugin_registrant.cc +**/linux/flutter/generated_plugin_registrant.h +**/linux/flutter/generated_plugins.cmake + +# Coverage +coverage/ + +# Symbols +app.*.symbols + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +!/dev/ci/**/Gemfile.lock +!.vscode/settings.json \ No newline at end of file diff --git a/packages/three_js_webgl/CHANGELOG.md b/packages/three_js_webgl/CHANGELOG.md new file mode 100755 index 00000000..9b7b03ba --- /dev/null +++ b/packages/three_js_webgl/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.0.1 + +* Initial release. \ No newline at end of file diff --git a/packages/three_js_webgl/LICENSE b/packages/three_js_webgl/LICENSE new file mode 100755 index 00000000..383b4da5 --- /dev/null +++ b/packages/three_js_webgl/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright © 2010-2024 three.js authors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/packages/three_js_webgl/README.md b/packages/three_js_webgl/README.md new file mode 100755 index 00000000..75d7a565 --- /dev/null +++ b/packages/three_js_webgl/README.md @@ -0,0 +1,469 @@ +# three_js_webgl + +[![Pub Version](https://img.shields.io/pub/v/three_js_webgl)](https://pub.dev/packages/three_js_webgl) +[![License: MIT](https://img.shields.io/badge/license-MIT-purple.svg)](https://opensource.org/licenses/MIT) + +A 3D rendering engine for dart (based on [three.js](https://github.com/mrdoob/three.js) and [three_dart](https://github.com/wasabia/three_dart)) that allows users to view, edit and manipulate their 3D objects. The current builds uses [angle](https://github.com/google/angle) for desktop and mobile, and WebGL2 for web applications. This version of three_js uses an older version of three.js renderer, which is similar to three_dart renderer. + +## Features + +![Gif of dash playing a game.](https://raw.githubusercontent.com/Knightro63/three_js/master/assets/flutter_game.gif) + +This is a dart conversion of three.js and three_dart, originally created by [@mrdoob](https://github.com/mrdoob) and has a coverted dart fork by [@wasabia](https://github.com/wasabia). + +## Requirements + +**MacOS** + - Minimum os Deployment Target: 10.15 + - Xcode 13 or newer + - Swift 5 + - Metal supported + +**iOS** + - Minimum os Deployment Target: 13.0 + - Xcode 13 or newer + - Swift 5 + - Metal supported + +**iOS-Simulator** + - Minimum os Deployment Target: 13.0 + - Xcode 13 or newer + - Swift 5 + - Metal supported + +**Android** + - compileSdkVersion: 34 + - minSdk: 21 + - OpenGL supported + - Vulkan supported + +**Android Emulator** + - compileSdkVersion: 34 + - minSdk: 21 + - OpenGL supported + +**Windows** + - Intel supported + - AMD supported + - Qualcom supported + - Direct3D 11 supported + - OpenGL supported + +**Web** + - WebGL2 supported. please add `` to your index.html to load the js_interop file. + +**WASM** + - WebGL2 supported. please add `` to your index.html to load the js_interop file. + +**Linux** + - Currenlty only works for flutter < 3.27 + - Ubuntu supported (Tested on Linux Mint) + - OpenGL supported + +## Getting started + +To get started add three_js to your pubspec.yaml file. Adding permissions for audio and video is required if using either item. +Please use [Permission Handler](https://pub.dev/packages/permission_handler) package to help with this. + +## Usage + +This project is a simple 3D rendering engine for flutter to view, edit, or manipulate 3D models. + +## Example + +Find the example for this API [here](https://github.com/Knightro63/three_js/tree/main/packages/three_js/example/), for more examples you can click [here](https://github.com/Knightro63/three_js/tree/main/examples/), and for a preview go [here](https://knightro63.github.io/three_js/). + +## Know Issues + +**All** + - MD2 annimations do not work + - Collada animations do not work + - Collada kinnametics does not work + - PMREM gives weird artifacts or is completely black + +**MacOS** + - N/A + +**iOS** + - Protoplanets does not function correctly + +**Android** + - Morphtargets does not work on some devices + - Some RGBELoaders cause app to crash + +**Windows** + - Tonemapping turns screen black + - Some RGBELoaders cause app to crash + +**Web** + - Lens Flare not working correctly + - Simplify modifer has weird artifacts + + **WASM** + - Simple GI does not work + - Simplify modifer has weird artifacts + +**Linux** + - Tonemapping turns screen black + - Postprocessing does not work + - Track pad does not zoom out + - Some RGBELoaders cause app to crash + +## Libraries and Plugins + +**Other Libs** + - [Advanced Exporters](https://pub.dev/packages/three_js_advanced_exporters) a USDZ exporter to your three_js project. + - [Audio](https://pub.dev/packages/three_js_audio) an audio api using flutters audioplayer from pub.dev do not use with any other audio package.. + - [Audio Latency](https://pub.dev/packages/three_js_audio_latency) an audio api using SoLoud from pub.dev do not use with any other audio package.. + - [BVH CSG](https://pub.dev/packages/three_js_bvh_csg) a bvh csg api for three_js. + - [Exporters](https://pub.dev/packages/three_js_exporters) an api to add STL, OBJ or PLY exporter for three_js. + - [Geometry](https://pub.dev/packages/three_js_geometry) an api to add complex geometries to three_js. + - [Line](https://pub.dev/packages/three_js_line) an api to add more line types to three_js. + - [Helpers](https://pub.dev/packages/three_js_helpers) an api to add helpers to three_js. + - [Modifers](https://pub.dev/packages/three_js_modifers) an api to add simplify or subdivision to three_js. + - [Post Processing](https://pub.dev/packages/three_js_postprocessing) a post processor to three_js. + - [SVG](https://pub.dev/packages/three_js_svg) an api to add a svg importer and exporter to three_js. + - [Three JS Loader](https://pub.dev/packages/three_js_tjs_loader) a loader to add three js json files to three_js. + - [Transfrom Controls](https://pub.dev/packages/three_js_transform_controls) a transfor controller for 3d objects for three_js. + - [Video Texture](https://pub.dev/packages/three_js_video_texture) an api to add videos and audio to three_js do not use with any other audio package. + +**ADD-ONS** + - [Omio](https://pub.dev/packages/oimo_physics) a physics engine for three_js. + - [Cannon](https://pub.dev/packages/cannon_physics) a physics engine for three_js. + - [Terrain](https://pub.dev/packages/three_js_terrain) a map generator for three_js. + - [XR](https://pub.dev/packages/three_js_xr) a VR/AR/MR sdk for three_js. (web only) + - [Yuka](https://pub.dev/packages/yuka) a game ai sdk for three_js. + +## Contributing + +Contributions are welcome. +In case of any problems look at [existing issues](https://github.com/Knightro63/three_js/issues), if you cannot find anything related to your problem then open an issue. +Create an issue before opening a [pull request](https://github.com/Knightro63/three_js/pulls) for non trivial fixes. +In case of trivial fixes open a [pull request](https://github.com/Knightro63/three_js/pulls) directly. + +## Supported Features + +All of the current webgl2 core features are supported at this time.
+GPU is currently under development, so it is currently not supported.
+Please review the following table for all the supported Modules. + + - ✅ Currently Supported + - ⚠️ Upon request + - ❗ Waiting on GPU update + - ❌ Not intended + +| Module | Plugin | Web | Mobile | Desktop | +|-----------------------------------------------------------------------------------------------|--------|------------|---------|-----| +| | **Animation** | | | | +| AnimationClipCreator | | ⚠️ | ⚠️ | ⚠️ | +| CCDIKSolver | | ❌ | ❌ | ❌ | +| | **Controls** | | | | +| [ArcballControls](https://github.com/Knightro63/three_js/blob/main/packages/three_js_transform_controls/lib/arcball_controls.dart) | [three_js_transform_controls](https://pub.dev/packages/three_js_transform_controls) | ✅ | ✅ | ✅ | +| [DragControls](https://github.com/Knightro63/three_js/blob/main/packages/three_js_controls/lib/drag_controls.dart) | [three_js_controls](https://pub.dev/packages/three_js_controls) | ✅ | ✅ | ✅ | +| [FirstPersonControls](https://github.com/Knightro63/three_js/blob/main/packages/three_js_controls/lib/first_person_controls.dart) | [three_js_controls](https://pub.dev/packages/three_js_controls) | ✅ | ✅ | ✅ | +| [FlyControls](https://github.com/Knightro63/three_js/blob/main/packages/three_js_controls/lib/fly_controls.dart) | [three_js_controls](https://pub.dev/packages/three_js_controls) | ✅ | ✅ | ✅ | +| [MapControls](https://github.com/Knightro63/three_js/blob/main/packages/three_js_controls/lib/orbit_controls.dart) | [three_js_controls](https://pub.dev/packages/three_js_controls) | ✅ | ✅ | ✅ | +| [OrbitControls](https://github.com/Knightro63/three_js/blob/main/packages/three_js_controls/lib/orbit_controls.dart) | [three_js_controls](https://pub.dev/packages/three_js_controls) | ✅ | ✅ | ✅ | +| [PointerLockControls](https://github.com/Knightro63/three_js/blob/main/packages/three_js_controls/lib/pointer_lock_controls.dart) | [three_js_controls](https://pub.dev/packages/three_js_controls) | ✅ | ✅ | ✅ | +| [TrackballControls](https://github.com/Knightro63/three_js/blob/main/packages/three_js_controls/lib/trackball_controls.dart) | [three_js_controls](https://pub.dev/packages/three_js_controls) | ✅ | ✅ | ✅ | +| [TransformControls](https://github.com/Knightro63/three_js/blob/main/packages/three_js_transform_controls/lib/transform_controls.dart) | [three_js_transform_controls](https://pub.dev/packages/three_js_transform_controls) | ✅ | ✅ | ✅ | +| | **CSM** | | | | +| [CSM](https://github.com/Knightro63/three_js/blob/main/packages/three_js_objects/lib/csm/csm.dart) | [three_js_objects](https://pub.dev/packages/three_js_objects) | ✅ | ✅ | ✅ | +| [CSMFrustum](https://github.com/Knightro63/three_js/blob/main/packages/three_js_objects/lib/csm/csm_frustum.dart) | [three_js_objects](https://pub.dev/packages/three_js_objects) | ✅ | ✅ | ✅ | +| [CSMHelper](https://github.com/Knightro63/three_js/blob/main/packages/three_js_objects/lib/csm/csm_helper.dart) | [three_js_objects](https://pub.dev/packages/three_js_objects) | ✅ | ✅ | ✅ | +| [CSMShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_objects/lib/csm/csm_shader.dart) | [three_js_objects](https://pub.dev/packages/three_js_objects) | ✅ | ✅ | ✅ | +| CSMShadowNode | | ❗ | ❗ | ❗ | +| | **Curves** | | | | +| [EXTRAS](https://github.com/Knightro63/three_js/blob/main/packages/three_js_curves/lib/curves/extra.dart) | [three_js_curves](https://pub.dev/packages/three_js_curves) | ✅ | ✅ | ✅ | +| [NURBSCurve](https://github.com/Knightro63/three_js/blob/main/packages/three_js_curves/lib/nurbs/nurbs_curve.dart) | [three_js_curves](https://pub.dev/packages/three_js_curves) | ✅ | ✅ | ✅ | +| [NURBSSurface](https://github.com/Knightro63/three_js/blob/main/packages/three_js_curves/lib/nurbs/nurbs_surface.dart) | [three_js_curves](https://pub.dev/packages/three_js_curves) | ✅ | ✅ | ✅ | +| [NURBSUtils](https://github.com/Knightro63/three_js/blob/main/packages/three_js_curves/lib/nurbs/nurbs_utils.dart) | [three_js_curves](https://pub.dev/packages/three_js_curves) | ✅ | ✅ | ✅ | +| NURBSVolume | | ⚠️ | ⚠️ | ⚠️ | +| | **Effects** | | | | +| AnaglyphEffect | | ⚠️ | ⚠️ | ⚠️ | +| AsciiEffect | | ⚠️ | ⚠️ | ⚠️ | +| OutlineEffect | | ⚠️ | ⚠️ | ⚠️ | +| ParallaxBarrierEffect | | ⚠️ | ⚠️ | ⚠️ | +| [StereoEffect](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/stero_effect.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| | **Enviroments** | | | | +| [DebugEnvironment](https://github.com/Knightro63/three_js/blob/main/packages/three_js_helpers/lib/enviroments/debug_environment.dart) | [three_js_helpers](https://pub.dev/packages/three_js_helpers) | ✅ | ✅ | ✅ | +| [RoomEnvironment](https://github.com/Knightro63/three_js/blob/main/packages/three_js_helpers/lib/enviroments/room_environment.dart) | [three_js_helpers](https://pub.dev/packages/three_js_helpers) | ✅ | ✅ | ✅ | +| | **Exporters** | | | | +| DRACOExporter | | ❌ | ❌ | ❌ | +| EXRExporter | | ❌ | ❌ | ❌ | +| GLTFExporter | | ⚠️ | ⚠️ | ⚠️ | +| KTX2Exporter | | ❌ | ❌ | ❌ | +| [OBJExporter](https://github.com/Knightro63/three_js/blob/main/packages/three_js_exporters/lib/obj_exporter.dart) | [three_js_simple_exporters](https://pub.dev/packages/three_js_exporters) | ✅ | ✅ | ✅ | +| [PLYExporter](https://github.com/Knightro63/three_js/blob/main/packages/three_js_exporters/lib/ply_exporter.dart) | [three_js_simple_exporters](https://pub.dev/packages/three_js_exporters) | ✅ | ✅ | ✅ | +| [STLExporter](https://github.com/Knightro63/three_js/blob/main/packages/three_js_exporters/lib/stl_exporter.dart) | [three_js_simple_exporters](https://pub.dev/packages/three_js_exporters) | ✅ | ✅ | ✅ | +| [USDZExporter](https://github.com/Knightro63/three_js/blob/main/packages/three_js_advanced_exporters/lib/usdz_exporter.dart) | [three_js_advanced_exporters](https://pub.dev/packages/three_js_advanced_exporters) | ✅ | ✅ | ✅ | +| | **Geometry** | | | | +| [BoxLineGeometry](https://github.com/Knightro63/three_js/blob/main/packages/three_js_geometry/lib/box_line_geometry.dart) | [three_js_geometry](https://pub.dev/packages/three_js_geometry) | ✅ | ✅ | ✅ | +| [ConvexGeometry](https://github.com/Knightro63/three_js/blob/main/packages/three_js_geometry/lib/convex.dart) | [three_js_geometry](https://pub.dev/packages/three_js_geometry) | ✅ | ✅ | ✅ | +| [DecalGeometry](https://github.com/Knightro63/three_js/blob/main/packages/three_js_geometry/lib/decal_geometry.dart) | [three_js_geometry](https://pub.dev/packages/three_js_geometry) | ✅ | ✅ | ✅ | +| [ParametricFunctions](https://github.com/Knightro63/three_js/blob/main/packages/three_js_geometry/lib/parametric_gemoetries.dart) | [three_js_geometry](https://pub.dev/packages/three_js_geometry) | ✅ | ✅ | ✅ | +| [ParametricGeometry](https://github.com/Knightro63/three_js/blob/main/packages/three_js_geometry/lib/parametric.dart) | [three_js_geometry](https://pub.dev/packages/three_js_geometry) | ✅ | ✅ | ✅ | +| RoundedBoxGeometry | | ⚠️ | ⚠️ | ⚠️ | +| TeapotGeometry | | ⚠️ | ⚠️ | ⚠️ | +| [TextGeometry](https://github.com/Knightro63/three_js/blob/main/packages/three_js_text/lib/text/text.dart) | [three_js_text](https://pub.dev/packages/three_js_text) | ✅ | ✅ | ✅ | +| | **Helpers** | | | | +| [LightProbeHelper](https://github.com/Knightro63/three_js/blob/main/packages/three_js_helpers/lib/light_probe_helper.dart) | [three_js_helpers](https://pub.dev/packages/three_js_helpers) | ✅ | ✅ | ✅ | +| LightProbeHelperGPU | | ❗ | ❗ | ❗ | +| [OctreeHelper](https://github.com/Knightro63/three_js/blob/main/packages/three_js_objects/lib/octree_helper.dart) | [three_js_objects](https://pub.dev/packages/three_js_objects) | ✅ | ✅ | ✅ | +| [PositionalAudioHelper](https://github.com/Knightro63/three_js/blob/main/packages/three_js_core/lib/audio/positional_audio_helper.dart) | [three_js_core](https://pub.dev/packages/three_js_core) | ✅ | ✅ | ✅ | +| RapierHelper | | ❌ | ❌ | ❌ | +| [RectAreaLightHelper](https://github.com/Knightro63/three_js/blob/main/packages/three_js_helpers/lib/rect_area_light_helper.dart) | [three_js_helpers](https://pub.dev/packages/three_js_helpers) | ✅ | ✅ | ✅ | +| TextureHelper | | ⚠️ | ⚠️ | ⚠️ | +| [VertexNormalsHelper](https://github.com/Knightro63/three_js/blob/main/packages/three_js_helpers/lib/vertex_normals_helper.dart) | [three_js_helpers](https://pub.dev/packages/three_js_helpers) | ✅ | ✅ | ✅ | +| [VertexTangentsHelper](https://github.com/Knightro63/three_js/blob/main/packages/three_js_helpers/lib/vertex_tangents_helper.dart) | [three_js_helpers](https://pub.dev/packages/three_js_helpers) | ✅ | ✅ | ✅ | +| [ViewHelper](https://github.com/Knightro63/three_js/blob/main/packages/three_js_helpers/lib/view_helper.dart) | [three_js_helpers](https://pub.dev/packages/three_js_helpers) | ✅ | ✅ | ✅ | +| | **Interactive** | | | | +| HTMLMesh | | ❌ | ❌ | ❌ | +| [InteractiveGroup](https://github.com/Knightro63/three_js/blob/main/packages/three_js_xr/lib/other/interactive_group.dart) | [three_js_xr](https://pub.dev/packages/three_js_xr) | ✅ | ❌ | ❌ | +| [SelectionBox](https://github.com/Knightro63/three_js/blob/main/packages/three_js_helpers/lib/selection/selection_box.dart) | [three_js_helpers](https://pub.dev/packages/three_js_helpers) | ✅ | ✅ | ✅ | +| [SelectionHelper](https://github.com/Knightro63/three_js/blob/main/packages/three_js_helpers/lib/selection/selection_helper.dart) | [three_js_helpers](https://pub.dev/packages/three_js_helpers) | ✅ | ✅ | ✅ | +| | **Lighting** | | | | +| TiledLighting | | ❗ | ❗ | ❗ | +| | **Lights** | | | | +| [LightProbeGenerator](https://github.com/Knightro63/three_js/blob/main/packages/three_js_objects/lib/lights/light_probe_generator.dart) | [three_js_objects](https://pub.dev/packages/three_js_objects) | ✅ | ✅ | ✅ | +| RectAreaLightTexturesLib | | ⚠️ | ⚠️ | ⚠️ | +| RectAreaLightUniformsLib | | ⚠️ | ⚠️ | ⚠️ | +| | **Lines** | | | | +| [Line2](https://github.com/Knightro63/three_js/blob/main/packages/three_js_line/lib/line2.dart) | [three_js_line](https://pub.dev/packages/three_js_line) | ✅ | ✅ | ✅ | +| [LineGeometry](https://github.com/Knightro63/three_js/blob/main/packages/three_js_line/lib/line_geometry.dart) | [three_js_line](https://pub.dev/packages/three_js_line) | ✅ | ✅ | ✅ | +| [LineMaterial](https://github.com/Knightro63/three_js/blob/main/packages/three_js_line/lib/line_material.dart) | [three_js_line](https://pub.dev/packages/three_js_line) | ✅ | ✅ | ✅ | +| [LineSegments2](https://github.com/Knightro63/three_js/blob/main/packages/three_js_line/lib/line_segments2.dart) | [three_js_line](https://pub.dev/packages/three_js_line) | ✅ | ✅ | ✅ | +| [LineSegmentsGeometry](https://github.com/Knightro63/three_js/blob/main/packages/three_js_line/lib/line_segments_geometry.dart) | [three_js_line](https://pub.dev/packages/three_js_line) | ✅ | ✅ | ✅ | +| [Wireframe](https://github.com/Knightro63/three_js/blob/main/packages/three_js_line/lib/wireframe.dart) | [three_js_line](https://pub.dev/packages/three_js_line) | ✅ | ✅ | ✅ | +| [WireframeGeometry2](https://github.com/Knightro63/three_js/blob/main/packages/three_js_line/lib/wireframe_geometry2.dart) | [three_js_line](https://pub.dev/packages/three_js_line) | ✅ | ✅ | ✅ | +| | **Loaders** | | | | +| Rhino3dmLoader | | ❌ | ❌ | ❌ | +| ThreeMFLoader | | ❌ | ❌ | ❌ | +| AMFLoader | | ❌ | ❌ | ❌ | +| [BVHLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_advanced_loaders/lib/bvh_loader.dart) | [three_js_advanced_loaders](https://pub.dev/packages/three_js_advanced_loaders) | ✅ | ✅ | ✅ | +| [ColladaLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_advanced_loaders/lib/collada/collada_loader.dart) | [three_js_advanced_loaders](https://pub.dev/packages/three_js_advanced_loaders) | ✅ | ✅ | ✅ | +| [DDSLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_advanced_loaders/lib/dds_loader.dart) | [three_js_advanced_loaders](https://pub.dev/packages/three_js_advanced_loaders) | ✅ | ✅ | ✅ | +| DRACOLoader | | ❌ | ❌ | ❌ | +| EXRLoader | | ⚠️ | ⚠️ | ⚠️ | +| [FBXLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_advanced_loaders/lib/fbx_loader.dart) | [three_js_advanced_loaders](https://pub.dev/packages/three_js_advanced_loaders) | ✅ | ✅ | ✅ | +| [FontLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_text/lib/loaders/font_loader.dart) | [three_js_text](https://pub.dev/packages/three_js_text) | ✅ | ✅ | ✅ | +| [GCodeLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_simple_loaders/lib/gcode_loder.dart) | [three_js_simple_loaders](https://pub.dev/packages/three_js_simple_loaders) | ✅ | ✅ | ✅ | +| [GLTFLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_advanced_loaders/lib/gltf/gltf_loader.dart) | [three_js_advanced_loaders](https://pub.dev/packages/three_js_advanced_loaders) | ✅ | ✅ | ✅ | +| HDRCubeTextureLoader | | ⚠️ | ⚠️ | ⚠️ | +| IESLoader | | ⚠️ | ⚠️ | ⚠️ | +| KMZLoader | | ❌ | ❌ | ❌ | +| KTX2Loader | | ❌ | ❌ | ❌ | +| [KTXLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_advanced_loaders/lib/ktx_loader.dart) | [three_js_advanced_loaders](https://pub.dev/packages/three_js_advanced_loaders) | ✅ | ✅ | ✅ | +| LDrawLoader | | ⚠️ | ⚠️ | ⚠️ | +| LottieLoader | | ❌ | ❌ | ❌ | +| LUT3dlLoader | | ⚠️ | ⚠️ | ⚠️ | +| [LUTCubeLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_simple_loaders/lib/lut_cube_loder.dart) | [three_js_simple_loaders](https://pub.dev/packages/three_js_simple_loaders) | ✅ | ✅ | ✅ | +| LUTImageLoader | | ⚠️ | ⚠️ | ⚠️ | +| LWOLoader | | ❌ | ❌ | ❌ | +| MaterialXLoader | | ❌ | ❌ | ❌ | +| [MD2Loader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_advanced_loaders/lib/md2/md2_loader.dart) | [three_js_advanced_loaders](https://pub.dev/packages/three_js_advanced_loaders) | ✅ | ✅ | ✅ | +| MDDLoader | | ⚠️ | ⚠️ | ⚠️ | +| [MTLLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_simple_loaders/lib/obj/mtl_loder.dart) | [three_js_simple_loaders](https://pub.dev/packages/three_js_simple_loaders) | ✅ | ✅ | ✅ | +| NRRDLoader | | ⚠️ | ⚠️ | ⚠️ | +| [OBJLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_simple_loaders/lib/obj/obj_loder.dart) | [three_js_simple_loaders](https://pub.dev/packages/three_js_simple_loaders) | ✅ | ✅ | ✅ | +| [PCDLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_advanced_loaders/lib/pcd_loader.dart) | [three_js_advanced_loaders](https://pub.dev/packages/three_js_advanced_loaders) | ✅ | ✅ | ✅ | +| PBDLoader | | ⚠️ | ⚠️ | ⚠️ | +| [PLYLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_simple_loaders/lib/ply_loder.dart) | [three_js_simple_loaders](https://pub.dev/packages/three_js_simple_loaders) | ✅ | ✅ | ✅ | +| PVRLoader | | ⚠️ | ⚠️ | ⚠️ | +| [RGBELoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_advanced_loaders/lib/rgbe_loader.dart) | [three_js_advanced_loaders](https://pub.dev/packages/three_js_advanced_loaders) | ✅ | ✅ | ✅ | +| RGBMLoader | | ⚠️ | ⚠️ | ⚠️ | +| [STLLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_simple_loaders/lib/stl_loder.dart) | [three_js_simple_loaders](https://pub.dev/packages/three_js_simple_loaders) | ✅ | ✅ | ✅ | +| [SVGLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_svg/lib/import/svg_loder.dart) | [three_js_svg](https://pub.dev/packages/three_js_svg) | ✅ | ✅ | ✅ | +| TDSLoader | | ⚠️ | ⚠️ | ⚠️ | +| [TGALoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_advanced_loaders/lib/tga_loader.dart) | [three_js_advanced_loaders](https://pub.dev/packages/three_js_advanced_loaders) | ✅ | ✅ | ✅ | +| TIFFLoader | | ❌ | ❌ | ❌ | +| [TTFLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_text/lib/loaders/ttf_loader.dart) | [three_js_text](https://pub.dev/packages/three_js_text) | ✅ | ✅ | ✅ | +| UltraHDRLoader | | ⚠️ | ⚠️ | ⚠️ | +| [USDLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_advanced_loaders/lib/usdz/usdz_loader.dart) | [three_js_advanced_loaders](https://pub.dev/packages/three_js_advanced_loaders) | ✅ | ✅ | ✅ | +| [USDZLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_advanced_loaders/lib/usdz/usdz_loader.dart) | [three_js_advanced_loaders](https://pub.dev/packages/three_js_advanced_loaders) | ✅ | ✅ | ✅ | +| [VOXLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_simple_loaders/lib/vox_loder.dart) | [three_js_simple_loaders](https://pub.dev/packages/three_js_simple_loaders) | ✅ | ✅ | ✅ | +| VRMLoader | | ❌ | ❌ | ❌ | +| VTKLoader | | ⚠️ | ⚠️ | ⚠️ | +| [XYZLoader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_simple_loaders/lib/xyz_loder.dart) | [three_js_simple_loaders](https://pub.dev/packages/three_js_simple_loaders) | ✅ | ✅ | ✅ | +| | **Materials** | | | | +| LDrawConditionalLineMaterial | | ❌ | ❌ | ❌ | +| LDrawConditionalLineNodeMaterial | | ❌ | ❌ | ❌ | +| [MeshGouraudMaterial](https://github.com/Knightro63/three_js/blob/main/packages/three_js_core/lib/materials/mesh_gouraud_loader.dart) | [three_js_core](https://pub.dev/packages/three_js_core) | ✅ | ✅ | ✅ | +| MeshPostProcessingMaterial | | ⚠️ | ⚠️ | ⚠️ | +| | **Math** | | | | +| [Capsule](https://github.com/Knightro63/three_js/blob/main/packages/three_js_objects/lib/octree/capsule.dart) | [three_js_objects](https://pub.dev/packages/three_js_objects) | ✅ | ✅ | ✅ | +| ColorConverter | | ⚠️ | ⚠️ | ⚠️ | +| ColorSpaces | | ⚠️ | ⚠️ | ⚠️ | +| [ConvexHull](https://github.com/Knightro63/three_js/blob/main/packages/three_js_geometry/lib/convex_hull.dart) | [three_js_geometry](https://pub.dev/packages/three_js_geometry) | ✅ | ✅ | ✅ | +| [ImprovedNoise](https://github.com/Knightro63/three_js/blob/main/packages/three_js_objects/lib/noise/improved_noise.dart) | [three_js_objects](https://pub.dev/packages/three_js_objects) | ✅ | ✅ | ✅ | +| Lut | | ⚠️ | ⚠️ | ⚠️ | +| [MeshSurfaceSampler](https://github.com/Knightro63/three_js/blob/main/packages/three_js_helpers/lib/utils/mesh_surface_sampler.dart) | [three_js_helpers](https://pub.dev/packages/three_js_helpers) | ✅ | ✅ | ✅ | +| OBB | | ⚠️ | ⚠️ | ⚠️ | +| [Octree](https://github.com/Knightro63/three_js/blob/main/packages/three_js_objects/lib/octree/octree.dart) | [three_js_objects](https://pub.dev/packages/three_js_objects) | ✅ | ✅ | ✅ | +| SimplexNoise | | ⚠️ | ⚠️ | ⚠️ | +| | **Misc** | | | | +| ConvexObjectBreaker | | ⚠️ | ⚠️ | ⚠️ | +| GPUComputationRenderer | | ❗ | ❗ | ❗ | +| [Gyroscope](https://github.com/Knightro63/three_js/blob/main/packages/three_js_particles/lib/gyroscope.dart) | [three_js_particles](https://pub.dev/packages/three_js_particles) | ✅ | ✅ | ✅ | +| [MD2Character](https://github.com/Knightro63/three_js/blob/main/packages/three_js_advanced_loaders/lib/md2/md2_charcter.dart) | [three_js_advanced_loaders](https://pub.dev/packages/three_js_advanced_loaders) | ✅ | ✅ | ✅ | +| [MD2Loader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_advanced_loaders/lib/md2/md2_loader.dart) | [three_js_advanced_loaders](https://pub.dev/packages/three_js_advanced_loaders) | ✅ | ✅ | ✅ | +| MD2CharacterComplex | | ❌ | ❌ | ❌ | +| [MorphAnimMesh](https://github.com/Knightro63/three_js/blob/main/packages/three_js_advanced_loaders/lib/md2/morph_anim_mesh.dart) | [three_js_advanced_loaders](https://pub.dev/packages/three_js_advanced_loaders) | ✅ | ✅ | ✅ | +| MorphBlendMesh | | ⚠️ | ⚠️ | ⚠️ | +| ProgressiveLightMap | | ⚠️ | ⚠️ | ⚠️ | +| ProgressiveLightMapGPU | | ❗ | ❗ | ❌❗ | +| [RollerCoasterGeometry](https://github.com/Knightro63/three_js/blob/main/examples/lib/rollercoster/rollercoaster.dart) | | ✅ | ✅ | ✅ | +| [TubePainter](https://github.com/Knightro63/three_js/blob/main/packages/three_js_objects/lib/tube_painter.dart) | [three_js_objects](https://pub.dev/packages/three_js_objects) | ✅ | ✅ | ✅ | +| Volume | | ⚠️ | ⚠️ | ⚠️ | +| VolumeSlice | | ❌ | ❌ | ❌ | +| | **Modifers** | | | | +| CurveModifier | | ❌ | ❌ | ❌ | +| CurveModifierGPU | | ❌ | ❌ | ❌ | +| [EdgeSplitModifier](https://github.com/Knightro63/three_js/blob/main/packages/three_js_modifers/lib/edge_split_modifier.dart) | [three_js_modifers](https://pub.dev/packages/three_js_modifers) | ✅ | ✅ | ✅ | +| [SimplifyModifier](https://github.com/Knightro63/three_js/blob/main/packages/three_js_modifers/lib/simplify_modifer.dart) | [three_js_modifers](https://pub.dev/packages/three_js_modifers) | ✅ | ✅ | ✅ | +| [TessellateModifier](https://github.com/Knightro63/three_js/blob/main/packages/three_js_modifers/lib/tesselate_modifer.dart) | [three_js_modifers](https://pub.dev/packages/three_js_modifers) | ✅ | ✅ | ✅ | +| | **Objects** | | | | +| GroundedSkybox | | ⚠️ | ⚠️ | ⚠️ | +| [Lensflare](https://github.com/Knightro63/three_js/blob/main/packages/three_js_objects/lib/lens_flare.dart) | [three_js_objects](https://pub.dev/packages/three_js_objects) | ✅ | ✅ | ✅ | +| LensflareMesh | | ❗ | ❗ | ❗ | +| [MarchingCubes](https://github.com/Knightro63/three_js/blob/main/packages/three_js_objects/lib/marching_cubes.dart) | [three_js_objects](https://pub.dev/packages/three_js_objects) | ✅ | ✅ | ✅ | +| [Reflector](https://github.com/Knightro63/three_js/blob/main/packages/three_js_objects/lib/water/reflector.dart) | [three_js_objects](https://pub.dev/packages/three_js_objects) | ✅ | ✅ | ✅ | +| ReflectorForSSRPass | | ⚠️ | ⚠️ | ⚠️ | +| [Refractor](https://github.com/Knightro63/three_js/blob/main/packages/three_js_objects/lib/water/refractor.dart) | [three_js_objects](https://pub.dev/packages/three_js_objects) | ✅ | ✅ | ✅ | +| ShadowMesh | | ⚠️ | ⚠️ | ⚠️ | +| [Sky](https://github.com/Knightro63/three_js/blob/main/packages/three_js_objects/lib/sky/sky.dart) | [three_js_objects](https://pub.dev/packages/three_js_objects) | ✅ | ✅ | ✅ | +| SkyMesh | | ❗ | ❗ | ❗ | +| Water | | ⚠️ | ⚠️ | ⚠️ | +| [Water2](https://github.com/Knightro63/three_js/blob/main/packages/three_js_objects/lib/water/water2.dart) | [three_js_objects](https://pub.dev/packages/three_js_objects) | ✅ | ✅ | ✅ | +| Water2Mesh | | ❗ | ❗ | ❗ | +| WaterMesh | | ❗ | ❗ | ❗ | +| | **Off Screen** | | | | +| Jank | | ⚠️ | ⚠️ | ⚠️ | +| OffScreen | | ❌ | ❌ | ❌ | +| Scene | | ❌ | ❌ | ❌ | +| | **Physics** | | | | +| AmmoPhysics | | ❌ | ❌ | ❌ | +| JoltPhysics | | ❌ | ❌ | ❌ | +| RapierPhysics | | ❌ | ❌ | ❌ | +| | **Post Porcessing** | | | | +| [AfterimagePass](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/afterimage_pass.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| [BloomPass](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/bloom_pass.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| BokehPass | | ⚠️ | ⚠️ | ⚠️ | +| ClearPass | | ⚠️ | ⚠️ | ⚠️ | +| CubeTexturePass | | ⚠️ | ⚠️ | ⚠️ | +| [DotScreenPass](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/dot_screen_pass.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| [EffectComposer](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/effect_composer.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| [FilmPass](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/film_pass.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| [FXAAPass](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/fxaa_pass.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| [GlitchPass](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/glitch_pass.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| GTAOPass | | ⚠️ | ⚠️ | ⚠️ | +| HalftonePass | | ⚠️ | ⚠️ | ⚠️ | +| [LUTPass](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/lut_pass.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| [MaskPass](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/mask_pass.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| OutlinePass | | ⚠️ | ⚠️ | ⚠️ | +| [OutputPass](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/output_pass.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| [Pass](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/pass.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| [RenderPass](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/render_pass.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| RenderPixelatedPass | | ⚠️ | ⚠️ | ⚠️ | +| RenderTransitionPass | | ⚠️ | ⚠️ | ⚠️ | +| SAOPass | | ⚠️ | ⚠️ | ⚠️ | +| SavePass | | ⚠️ | ⚠️ | ⚠️ | +| [ShaderPass](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/shader_pass.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| [SMAAPass](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/smaa_pass.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| [SSAARenderPass](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/ssaa_render_pass.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| SSAOPass | | ⚠️ | ⚠️ | ⚠️ | +| SSRPass | | ⚠️ | ⚠️ | ⚠️ | +| [TAARenderPass](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/taa_render_pass.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| [TexturePass](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/texture_pass.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| [UnrealBloomPass](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/post/unreal_bloom_pass.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| | **Renderers** | | | | +| CSS2DRenderer | | ❌ | ❌ | ❌ | +| CSS3DRenderer | | ❌ | ❌ | ❌ | +| [Projector](https://github.com/Knightro63/three_js/blob/main/packages/three_js_svg/lib/export/projector.dart) | [three_js_svg](https://pub.dev/packages/three_js_svg) | ✅ | ✅ | ✅ | +| [SVGRenderer](https://github.com/Knightro63/three_js/blob/main/packages/three_js_svg/lib/export/svg_renderer.dart) | [three_js_svg](https://pub.dev/packages/three_js_svg) | ✅ | ✅ | ✅ | +| | **Shaders** | | | | +| ACESFilmicToneMappingShader | | ⚠️ | ⚠️ | ⚠️ | +| [AfterimageShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/afterimage_shader.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| BasicShader | | ⚠️ | ⚠️ | ⚠️ | +| [BleachBypassShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/bleach_bypass_shader.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| BlendShader | | ⚠️ | ⚠️ | ⚠️ | +| BokehShader | | ⚠️ | ⚠️ | ⚠️ | +| BokehShader2 | | ⚠️ | ⚠️ | ⚠️ | +| BrightnessContrastShader | | ⚠️ | ⚠️ | ⚠️ | +| ColorCorrectionShader | | ⚠️ | ⚠️ | ⚠️ | +| ColorifyShader | | ⚠️ | ⚠️ | ⚠️ | +| [ConvolutionShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/convolution_shader.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| [CopyShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/copy_shader.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| DepthLimitedBlurShader | | ⚠️ | ⚠️ | ⚠️ | +| [DigitalGlitch](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/digital_glitch.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| DOFMipMapShader | | ⚠️ | ⚠️ | ⚠️ | +| [DotScreenShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/dot_screen_shader.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| ExposureShader | | ⚠️ | ⚠️ | ⚠️ | +| [FilmShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/film_shader.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| FocusShader | | ⚠️ | ⚠️ | ⚠️ | +| FreiChenShader | | ⚠️ | ⚠️ | ⚠️ | +| [FXAAShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/fxaa_shader.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| [GammaCorrectionShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/gamma_correction_shader.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| GodRaysDepthMaskShader | | ⚠️ | ⚠️ | ⚠️ | +| GTAOShader | | ⚠️ | ⚠️ | ⚠️ | +| HalftoneShader | | ⚠️ | ⚠️ | ⚠️ | +| [HorizontalBlurShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/horizontal_blur_shader.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| HorizontalTiltShiftShader | | ⚠️ | ⚠️ | ⚠️ | +| HueSaturationShader | | ⚠️ | ⚠️ | ⚠️ | +| KaleidoShader | | ⚠️ | ⚠️ | ⚠️ | +| [LuminosityHighPassShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/luminosity_high_pass_shader.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| [LuminosityShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/luminosity_shader.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| MirrorShader | | ⚠️ | ⚠️ | ⚠️ | +| NormalMapShader | | ⚠️ | ⚠️ | ⚠️ | +| [OutputShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/outpass_shader.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| PoissonDenoiseShader | | ⚠️ | ⚠️ | ⚠️ | +| RGBShiftShader | | ⚠️ | ⚠️ | ⚠️ | +| SAOShader | | ⚠️ | ⚠️ | ⚠️ | +| SepiaShader | | ⚠️ | ⚠️ | ⚠️ | +| [SMAAShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/smaa_shader.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| [SobelOperatorShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/sobel_operator_shader.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| SSAOShader | | ⚠️ | ⚠️ | ⚠️ | +| SSRShader | | ⚠️ | ⚠️ | ⚠️ | +| SubsurfaceScatteringShader | | ⚠️ | ⚠️ | ⚠️ | +| TechnicolorShader | | ⚠️ | ⚠️ | ⚠️ | +| ToonShader | | ⚠️ | ⚠️ | ⚠️ | +| TriangleBlurShader | | ⚠️ | ⚠️ | ⚠️ | +| [UnpackDepthRGBAShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/unpack_depth_rgba_shader.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| VelocityShader | | ⚠️ | ⚠️ | ⚠️ | +| [VerticalBlurShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/vertical_blur_shader.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| VerticalTiltShiftShader | | ⚠️ | ⚠️ | ⚠️ | +| [VignetteShader](https://github.com/Knightro63/three_js/blob/main/packages/three_js_postprocessing/lib/shaders/vignette_shader.dart) | [three_js_postprocessing](https://pub.dev/packages/three_js_postprocessing) | ✅ | ✅ | ✅ | +| VolumeShader | | ⚠️ | ⚠️ | ⚠️ | +| WaterRefractionShader | | ⚠️ | ⚠️ | ⚠️ | +| | **Textures** | | | | +| FlakesTexture | | ⚠️ | ⚠️ | ⚠️ | +| | **Transpiler** | ❗ | ❗ | ❗ | +| | **TSL** | ❗ | ❗ | ❗ | +| | **Utils** | | | | +| [BufferGeometryUtils](https://github.com/Knightro63/three_js/blob/main/packages/three_js_modifers/lib/buffergeometry_utils.dart) | [three_js_modifers](https://pub.dev/packages/three_js_modifers) | ✅ | ✅ | ✅ | +| [CameraUtils](https://github.com/Knightro63/three_js/blob/main/packages/three_js_helpers/lib/utils/camera_utils.dart) | [three_js_helpers](https://pub.dev/packages/three_js_helpers) | ✅ | ✅ | ✅ | +| GeometryCompressionUtils | | ⚠️ | ⚠️ | ⚠️ | +| GeometryUtils | | ⚠️ | ⚠️ | ⚠️ | +| LDrawUtils | | ⚠️ | ⚠️ | ⚠️ | +| SceneOptimizer | | ⚠️ | ⚠️ | ⚠️ | +| SceneUtils | | ⚠️ | ⚠️ | ⚠️ | +| ShadowMapViewer | | ⚠️ | ⚠️ | ⚠️ | +| ShadowMapViewerGPU | | ❗ | ❗ | ❗ | +| [SkeletonUtils](https://github.com/Knightro63/three_js/blob/main/packages/three_js_helpers/lib/utils/skeleton_utils.dart) | [three_js_helpers](https://pub.dev/packages/three_js_helpers) | ✅ | ✅ | ✅ | +| SortUtils | | ⚠️ | ⚠️ | ⚠️ | +| UVsDebug | | ⚠️ | ⚠️ | ⚠️ | +| WebGLTextureUtils | | ⚠️ | ⚠️ | ⚠️ | +| WebGPUTextureUtils | | ❗ | ❗ | ❗ | +| | **WebXR** | | | | +| [ARButton](https://github.com/Knightro63/three_js/blob/main/packages/three_js_xr/lib/buttons/ar_button.dart) | [three_js_xr](https://pub.dev/packages/three_js_xr) | ✅ | ❌ | ❌ | +| OculusHandModel | | ❌ | ❌ | ❌ | +| OculusHandPointerModel | | ❌ | ❌ | ❌ | +| Text2D | | ❌ | ❌ | ❌ | +| [VRButton](https://github.com/Knightro63/three_js/blob/main/packages/three_js_xr/lib/buttons/vr_button.dart) | [three_js_xr](https://pub.dev/packages/three_js_xr) | ✅ | ❌ | ❌ | +| [XRButton](https://github.com/Knightro63/three_js/blob/main/packages/three_js_xr/lib/buttons/xr_button.dart) | [three_js_xr](https://pub.dev/packages/three_js_xr) | ✅ | ❌ | ❌ | +| [XRControllerModelFactory](https://github.com/Knightro63/three_js/blob/main/packages/three_js_xr/lib/models/hand/xr_controller_model_factory.dart) | [three_js_xr](https://pub.dev/packages/three_js_xr) | ✅ | ❌ | ❌ | +| XREstimatedLight | | ❌ | ❌ | ❌ | +| [XRHandMeshModel](https://github.com/Knightro63/three_js/blob/main/packages/three_js_xr/lib/models/hand/xr_hand_mesh_modle.dart) | [three_js_xr](https://pub.dev/packages/three_js_xr) | ✅ | ❌ | ❌ | +| [XRHandModelFactory](https://github.com/Knightro63/three_js/blob/main/packages/three_js_xr/lib/models/hand/xr_hand_modle_factory.dart) | [three_js_xr](https://pub.dev/packages/three_js_xr) | ✅ | ❌ | ❌ | +| [XRHandPrimitiveModel](https://github.com/Knightro63/three_js/blob/main/packages/three_js_xr/lib/models/hand/xr_hand_primitive_modle.dart) | [three_js_xr](https://pub.dev/packages/three_js_xr) | ✅ | ❌ | ❌ | +| [XRPlanes](https://github.com/Knightro63/three_js/blob/main/packages/three_js_xr/lib/models/xr_planes.dart) | [three_js_xr](https://pub.dev/packages/three_js_xr) | ✅ | ❌ | ❌ | diff --git a/packages/three_js_webgl/lib/three_js.dart b/packages/three_js_webgl/lib/three_js.dart new file mode 100755 index 00000000..668c6b88 --- /dev/null +++ b/packages/three_js_webgl/lib/three_js.dart @@ -0,0 +1,14 @@ +library three_js; + +/// Export all the packages that relies on Three_JS to work +export 'package:three_js_math/three_js_math.dart'; +export 'package:three_js_advanced_loaders/three_js_advanced_loaders.dart'; +export 'package:three_js_animations/three_js_animations.dart'; +export 'package:three_js_controls/three_js_controls.dart'; +export 'package:three_js_core/three_js_core.dart'; +export 'package:three_js_core_loaders/three_js_core_loaders.dart'; +export 'package:three_js_curves/three_js_curves.dart'; +export 'package:three_js_simple_loaders/three_js_simple_loaders.dart'; +export 'package:three_js_text/three_js_text.dart'; +export 'package:three_js_geometry/three_js_geometry.dart'; +export 'package:three_js_webgl_renderer/three_js_webgl_renderer.dart'; diff --git a/packages/three_js_webgl/pubspec.yaml b/packages/three_js_webgl/pubspec.yaml new file mode 100755 index 00000000..95994d74 --- /dev/null +++ b/packages/three_js_webgl/pubspec.yaml @@ -0,0 +1,43 @@ +name: three_js_webgl +description: "Flutter package converted from threejs and three_dart to allow users to view, edit, and control 3D models with the three_dart renderer." +version: 0.0.1 +homepage: https://github.com/Knightro63/three_js/tree/main/packages/three_js_webgl + +topics: + - threejs + - games + - animations + - flutter3d + - model3d + +environment: + sdk: '>=3.3.2 <4.0.0' + flutter: ">=1.17.0" + +dependencies: + flutter: + sdk: flutter + three_js_math: ^0.3.0 + three_js_advanced_loaders: ^0.3.0 + three_js_animations: ^0.3.0 + three_js_controls: ^0.3.0 + three_js_core: ^0.3.0 + three_js_core_loaders: ^0.3.0 + three_js_curves: ^0.3.0 + three_js_simple_loaders: ^0.3.0 + three_js_text: ^0.3.0 + three_js_geometry: ^0.3.0 + three_js_webgl_renderer: ^0.0.1 + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^5.0.0 + +platforms: + android: + ios: + macos: + web: + windows: + linux: \ No newline at end of file diff --git a/packages/three_js_webgl_renderer/.gitignore b/packages/three_js_webgl_renderer/.gitignore new file mode 100755 index 00000000..fbf43d48 --- /dev/null +++ b/packages/three_js_webgl_renderer/.gitignore @@ -0,0 +1,143 @@ +# Miscellaneous +*.class +*.lock +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.buildlog/ +.history +.svn/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +renderers_old/ +renderers_new/ +# Visual Studio Code related +.classpath +.project +.settings/ +.vscode/* +.metadata + +*/macos +*/web +*/ios +*/android +*/linux +*/windows + +# Flutter repo-specific +/bin/cache/ +/bin/internal/bootstrap.bat +/bin/internal/bootstrap.sh +/bin/mingit/ +/dev/benchmarks/mega_gallery/ +/dev/bots/.recipe_deps +/dev/bots/android_tools/ +/dev/devicelab/ABresults*.json +/dev/docs/doc/ +/dev/docs/flutter.docs.zip +/dev/docs/lib/ +/dev/docs/pubspec.yaml +/dev/integration_tests/**/xcuserdata +/dev/integration_tests/**/Pods +/packages/flutter/coverage/ +version +analysis_benchmark.json + +# packages file containing multi-root paths +.packages.generated + +# Flutter/Dart/Pub related +**/doc/api/ +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +**/generated_plugin_registrant.dart +.packages +.pub-preload-cache/ +.pub/ +build/ +flutter_*.png +linked_*.ds +unlinked.ds +unlinked_spec.ds + +# Android related +**/android/**/gradle-wrapper.jar +.gradle/ +**/android/captures/ +**/android/gradlew +**/android/gradlew.bat +**/android/local.properties +**/android/**/GeneratedPluginRegistrant.java +**/android/key.properties +*.jks + +# iOS/XCode related +**/ios/**/*.mode1v3 +**/ios/**/*.mode2v3 +**/ios/**/*.moved-aside +**/ios/**/*.pbxuser +**/ios/**/*.perspectivev3 +**/ios/**/*sync/ +**/ios/**/.sconsign.dblite +**/ios/**/.tags* +**/ios/**/.vagrant/ +**/ios/**/DerivedData/ +**/ios/**/Icon? +**/ios/**/Pods/ +**/ios/**/.symlinks/ +**/ios/**/profile +**/ios/**/xcuserdata +**/ios/.generated/ +**/ios/Flutter/.last_build_id +**/ios/Flutter/App.framework +**/ios/Flutter/Flutter.framework +**/ios/Flutter/Flutter.podspec +**/ios/Flutter/Generated.xcconfig +**/ios/Flutter/ephemeral +**/ios/Flutter/app.flx +**/ios/Flutter/app.zip +**/ios/Flutter/flutter_assets/ +**/ios/Flutter/flutter_export_environment.sh +**/ios/ServiceDefinitions.json +**/ios/Runner/GeneratedPluginRegistrant.* + +# macOS +**/Flutter/ephemeral/ +**/Pods/ +**/macos/Flutter/GeneratedPluginRegistrant.swift +**/macos/Flutter/ephemeral +**/xcuserdata/ + +# Windows +**/windows/flutter/generated_plugin_registrant.cc +**/windows/flutter/generated_plugin_registrant.h +**/windows/flutter/generated_plugins.cmake + +# Linux +**/linux/flutter/generated_plugin_registrant.cc +**/linux/flutter/generated_plugin_registrant.h +**/linux/flutter/generated_plugins.cmake + +# Coverage +coverage/ + +# Symbols +app.*.symbols + +# Exceptions to above rules. +!**/ios/**/default.mode1v3 +!**/ios/**/default.mode2v3 +!**/ios/**/default.pbxuser +!**/ios/**/default.perspectivev3 +!/packages/flutter_tools/test/data/dart_dependencies_test/**/.packages +!/dev/ci/**/Gemfile.lock +!.vscode/settings.json \ No newline at end of file diff --git a/packages/three_js_webgl_renderer/CHANGELOG.md b/packages/three_js_webgl_renderer/CHANGELOG.md new file mode 100755 index 00000000..9b7b03ba --- /dev/null +++ b/packages/three_js_webgl_renderer/CHANGELOG.md @@ -0,0 +1,3 @@ +## 0.0.1 + +* Initial release. \ No newline at end of file diff --git a/packages/three_js_webgl_renderer/LICENSE b/packages/three_js_webgl_renderer/LICENSE new file mode 100755 index 00000000..383b4da5 --- /dev/null +++ b/packages/three_js_webgl_renderer/LICENSE @@ -0,0 +1,21 @@ +The MIT License + +Copyright © 2010-2024 three.js authors + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. \ No newline at end of file diff --git a/packages/three_js_webgl_renderer/README.md b/packages/three_js_webgl_renderer/README.md new file mode 100755 index 00000000..9e3033e4 --- /dev/null +++ b/packages/three_js_webgl_renderer/README.md @@ -0,0 +1,21 @@ +# three_js_webgl_renderer + +[![Pub Version](https://img.shields.io/pub/v/three_js_webgl_renderer)](https://pub.dev/packages/three_js_webgl_renderer) +[![License: MIT](https://img.shields.io/badge/license-MIT-purple.svg)](https://opensource.org/licenses/MIT) + +This is one of the renderers for three_js to allow users to view their 3D objects in their projects. + +## Usage + +This is an older version of the renderer for three_js using google's ANGLE. + +## Example + +Find the example for this API [here](https://github.com/Knightro63/three_js/tree/main/packages/three_js_webgl_renderer/example/lib/main.dart). + +## Contributing + +Contributions are welcome. +In case of any problems look at [existing issues](https://github.com/Knightro63/three_js/issues), if you cannot find anything related to your problem then open an issue. +Create an issue before opening a [pull request](https://github.com/Knightro63/three_js/pulls) for non trivial fixes. +In case of trivial fixes open a [pull request](https://github.com/Knightro63/three_js/pulls) directly. diff --git a/packages/three_js_webgl_renderer/example/.gitignore b/packages/three_js_webgl_renderer/example/.gitignore new file mode 100755 index 00000000..79c113f9 --- /dev/null +++ b/packages/three_js_webgl_renderer/example/.gitignore @@ -0,0 +1,45 @@ +# Miscellaneous +*.class +*.log +*.pyc +*.swp +.DS_Store +.atom/ +.build/ +.buildlog/ +.history +.svn/ +.swiftpm/ +migrate_working_dir/ + +# IntelliJ related +*.iml +*.ipr +*.iws +.idea/ + +# The .vscode folder contains launch configuration and tasks you configure in +# VS Code which you may wish to be included in version control, so this line +# is commented out by default. +#.vscode/ + +# Flutter/Dart/Pub related +**/doc/api/ +**/ios/Flutter/.last_build_id +.dart_tool/ +.flutter-plugins +.flutter-plugins-dependencies +.pub-cache/ +.pub/ +/build/ + +# Symbolication related +app.*.symbols + +# Obfuscation related +app.*.map.json + +# Android Studio will place build artifacts here +/android/app/debug +/android/app/profile +/android/app/release diff --git a/packages/three_js_webgl_renderer/example/README.md b/packages/three_js_webgl_renderer/example/README.md new file mode 100755 index 00000000..2b3fce4c --- /dev/null +++ b/packages/three_js_webgl_renderer/example/README.md @@ -0,0 +1,16 @@ +# example + +A new Flutter project. + +## Getting Started + +This project is a starting point for a Flutter application. + +A few resources to get you started if this is your first Flutter project: + +- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab) +- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook) + +For help getting started with Flutter development, view the +[online documentation](https://docs.flutter.dev/), which offers tutorials, +samples, guidance on mobile development, and a full API reference. diff --git a/packages/three_js_webgl_renderer/example/lib/main.dart b/packages/three_js_webgl_renderer/example/lib/main.dart new file mode 100755 index 00000000..6fc56b25 --- /dev/null +++ b/packages/three_js_webgl_renderer/example/lib/main.dart @@ -0,0 +1,114 @@ +import 'dart:async'; +import 'package:flutter/material.dart'; +import 'package:three_js_core/three_js_core.dart' as three; +import 'package:three_js_math/three_js_math.dart' as tmath; +import 'package:three_js_webgl_renderer/three_js_webgl_renderer.dart'; +import 'dart:math' as math; + +void main() { + runApp(const MyApp()); +} + +class MyApp extends StatelessWidget { + const MyApp({super.key}); + + // This widget is the root of your application. + @override + Widget build(BuildContext context) { + return MaterialApp( + theme: ThemeData( + colorScheme: ColorScheme.fromSeed(seedColor: Colors.deepPurple), + useMaterial3: true, + ), + home: const WebglGeometries(), + ); + } +} + +class WebglGeometries extends StatefulWidget { + const WebglGeometries({super.key}); + + @override + createState() => _State(); +} + +class _State extends State { + late ThreeJS threeJs; + + @override + void initState() { + threeJs = ThreeJS( + onSetupComplete: (){setState(() {});}, + setup: setup, + settings: Settings( + localClippingEnabled: true, + ) + ); + super.initState(); + } + @override + void dispose() { + threeJs.dispose(); + super.dispose(); + } + + @override + Widget build(BuildContext context) { + return threeJs.build(); + } + + int startTime = 0; + + Future setup() async { + threeJs.camera = three.PerspectiveCamera(45, threeJs.width / threeJs.height, 1, 2000); + threeJs.camera.position.y = 400; + + threeJs.scene = three.Scene(); + + three.Mesh object; + + final ambientLight = three.AmbientLight(0xffffff, 0.8); + threeJs.scene.add(ambientLight); + + final pointLight = three.PointLight(0xffffff, 0.8); + threeJs.camera.add(pointLight); + threeJs.scene.add(threeJs.camera); + + final material = three.MeshPhongMaterial.fromMap({ + "color": 0xffffff, + "side": tmath.DoubleSide, + "clipShadows": true + }); + object = three.Mesh(three.SphereGeometry(75, 20, 10), material); + object.position.setValues(-300, 0, 200); + threeJs.scene.add(object); + + object = three.Mesh(three.PlaneGeometry(100, 100, 4, 4), material); + object.position.setValues(-300, 0, 0); + threeJs.scene.add(object); + + object = three.Mesh(three.BoxGeometry(100, 100, 100, 4, 4, 4), material); + object.position.setValues(-100, 0, 0); + threeJs.scene.add(object); + + + startTime = DateTime.now().millisecondsSinceEpoch; + + threeJs.addAnimationEvent((dt){ + final timer = DateTime.now().millisecondsSinceEpoch * 0.0001; + + threeJs.camera.position.x = math.cos(timer) * 800; + threeJs.camera.position.z = math.sin(timer) * 800; + threeJs.camera.lookAt(threeJs.scene.position); + + threeJs.scene.traverse((object) { + if (object is three.Mesh) { + object.rotation.x = timer * 5; + object.rotation.y = timer * 2.5; + } + }); + }); + } +} + + diff --git a/packages/three_js_webgl_renderer/example/pubspec.yaml b/packages/three_js_webgl_renderer/example/pubspec.yaml new file mode 100755 index 00000000..62542195 --- /dev/null +++ b/packages/three_js_webgl_renderer/example/pubspec.yaml @@ -0,0 +1,33 @@ +name: example +description: "A new Flutter project." +publish_to: 'none' # Remove this line if you wish to publish to pub.dev +version: 1.0.0+1 + +environment: + sdk: '>=3.3.2 <4.0.0' + +dependencies: + flutter: + sdk: flutter + cupertino_icons: ^1.0.6 + three_js_webgl_renderer: + path: ../ + three_js_math: ^0.2.0 + three_js_core: ^0.2.0 + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^3.0.0 + +dependency_overrides: + flutter_angle: + path: ../../../../flutter_angle/flutter_angle + three_js_math: + path: ../../three_js_math + three_js_core: + path: ../../three_js_core + +# The following section is specific to Flutter packages. +flutter: + uses-material-design: true \ No newline at end of file diff --git a/packages/three_js_webgl_renderer/lib/renderers/index.dart b/packages/three_js_webgl_renderer/lib/renderers/index.dart new file mode 100755 index 00000000..c083ebad --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/renderers/index.dart @@ -0,0 +1,17 @@ +library three_renderers; + +import 'dart:math' as math; +import 'dart:typed_data'; + +import 'package:flutter/foundation.dart'; + +import 'package:three_js_core/three_js_core.dart'; +import 'package:three_js_math/three_js_math.dart'; +import 'package:flutter_angle/flutter_angle.dart'; +import '../webgl/index.dart'; + +part 'web_gl_cube_render_target.dart'; +part 'web_gl_renderer.dart'; +part 'web_gl_render_target.dart'; +part 'web_gl_3d_render_target.dart'; +part 'web_gl_array_render_target.dart'; diff --git a/packages/three_js_webgl_renderer/lib/renderers/pmrem_generator.dart b/packages/three_js_webgl_renderer/lib/renderers/pmrem_generator.dart new file mode 100755 index 00000000..306ed985 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/renderers/pmrem_generator.dart @@ -0,0 +1,780 @@ +import 'package:flutter/foundation.dart'; +import 'package:three_js_core/three_js_core.dart'; +import 'package:three_js_math/three_js_math.dart'; +import 'index.dart'; +import 'dart:math' as math; + +final _origin = Vector3(); + +class PMREMGeneratorOptions{ + int size; + late final Vector3 position; + PMREMGeneratorOptions({ + Vector3? position, + this.size = 256, + }){ + this.position = position ?? _origin; + } +} + +/// This class generates a Prefiltered, Mipmapped Radiance Environment Map +/// (PMREM) from a cubeMap environment texture. This allows different levels of +/// blur to be quickly accessed based on material roughness. It is packed into a +/// special CubeUV format that allows us to perform custom interpolation so that +/// we can support nonlinear formats such as RGBE. Unlike a traditional mipmap +/// chain, it only goes down to the lodMin level (above), and then creates extra +/// even more filtered 'mips' at the same lodMin resolution, associated with +/// higher roughness levels. In this way we maintain resolution to smoothly +/// interpolate diffuse lighting while limiting sampling computation. +int lodMin = 4; + +// The standard deviations (radians) associated with the extra mips. These are +// chosen to approximate a Trowbridge-Reitz distribution function times the +// geometric shadowing function. These sigma values squared must match the +// variance #defines in cube_uv_reflection_fragment.glsl.js. +final extraLodSigma = [0.125, 0.215, 0.35, 0.446, 0.526, 0.582]; + +class PMREMGenerator { + bool _didDispose = false; + late int totalLods; + + // The maximum length of the blur for loop. Smaller sigmas will use fewer + // samples and exit early, but not recompile the shader. + final maxSamples = 20; + + dynamic _lodPlanes; + dynamic _sizeLods; + dynamic _sigmas; + + final _flatCamera = OrthographicCamera(); + final _clearColor = Color(1, 1, 1); + RenderTarget? _oldTarget; + int _oldActiveCubeFace = 0; + int _oldActiveMipmapLevel = 0; + bool _oldXrEnabled = false; + + late final double phi; + late final double invPhi; + late final List _axisDirections; + + late WebGLRenderer _renderer; + dynamic _pingPongRenderTarget; + dynamic _blurMaterial; + dynamic _equirectMaterial; + dynamic _cubemapMaterial; + + late int _lodMax; + late int _cubeSize; + + PMREMGenerator(WebGLRenderer renderer) { + // Golden Ratio + phi = (1 + math.sqrt(5)) / 2; + invPhi = 1 / phi; + + // Vertices of a dodecahedron (except the opposites, which represent the + // same axis), used as axis directions evenly spread on a sphere. + _axisDirections = [ + Vector3(-phi, invPhi, 0), + Vector3(phi, invPhi, 0), + Vector3(-invPhi, 0, phi), + Vector3(invPhi, 0, phi), + Vector3(0, phi, -invPhi), + Vector3(0, phi, invPhi), + Vector3(-1, 1, -1), + Vector3(1, 1, -1), + Vector3(-1, 1, 1), + Vector3(1, 1, 1), + ]; + + _renderer = renderer; + _pingPongRenderTarget = null; + + _lodMax = 0; + _cubeSize = 0; + _lodPlanes = []; + _sizeLods = []; + _sigmas = []; + + _compileMaterial(_blurMaterial); + } + + + /// * + /// * Generates a PMREM from a supplied Scene, which can be faster than using an + /// * image if networking bandwidth is low. Optional sigma specifies a blur radius + /// * in radians to be applied to the scene before PMREM generation. Optional near + /// * and far planes ensure the scene is rendered in its entirety (the cubeCamera + /// * is placed at the origin). + /// * + WebGLRenderTarget fromScene(Scene scene, {double sigma = 0, double near = 0.1, double far = 100, PMREMGeneratorOptions? options}) { + options ??= PMREMGeneratorOptions(); + + _oldTarget = _renderer.getRenderTarget(); + _oldActiveCubeFace = _renderer.getActiveCubeFace(); + _oldActiveMipmapLevel = _renderer.getActiveMipmapLevel(); + _oldXrEnabled = _renderer.xr.enabled; + _renderer.xr.enabled = false; + _setSize(options.size); + + final cubeUVRenderTarget = this._allocateTargets(); + cubeUVRenderTarget.depthBuffer = true; + + _sceneToCubeUV(scene, near, far, cubeUVRenderTarget, options.position); + if (sigma > 0) { + _blur(cubeUVRenderTarget, 0, 0, sigma); + } + + _applyPMREM(cubeUVRenderTarget); + _cleanup(cubeUVRenderTarget); + + return cubeUVRenderTarget; + } + + /// * + /// * Generates a PMREM from an equirectangular texture, which can be either LDR + /// * or HDR. The ideal input image size is 1k (1024 x 512), + /// * as this matches best with the 256 x 256 cubemap output. + /// * + RenderTarget fromEquirectangular(equirectangular, [RenderTarget? renderTarget]) { + return _fromTexture(equirectangular, renderTarget); + } + + /// * + /// * Generates a PMREM from an cubemap texture, which can be either LDR + /// * or HDR. The ideal input cube size is 256 x 256, + /// * as this matches best with the 256 x 256 cubemap output. + /// * + RenderTarget fromCubemap(cubemap, [RenderTarget? renderTarget]) { + return _fromTexture(cubemap, renderTarget); + } + + /// * + /// * Pre-compiles the cubemap shader. You can get faster start-up by invoking this method during + /// * your texture's network fetch for increased concurrency. + /// * + void compileCubemapShader() { + if (_cubemapMaterial == null) { + _cubemapMaterial = _getCubemapShader(); + _compileMaterial(_cubemapMaterial); + } + } + + /// * + /// * Pre-compiles the equirectangular shader. You can get faster start-up by invoking this method during + /// * your texture's network fetch for increased concurrency. + /// * + void compileEquirectangularShader() { + if (_equirectMaterial == null) { + _equirectMaterial = _getEquirectMaterial(); + _compileMaterial(_equirectMaterial); + } + } + + /// * + /// * Disposes of the PMREMGenerator's internal memory. Note that PMREMGenerator is a static class, + /// * so you should not need more than one PMREMGenerator object. If you do, calling dispose() on + /// * one of them will cause any others to also become unusable. + /// * + void dispose() { + if(_didDispose) return; + _didDispose = true; + _dispose(); + _cubemapMaterial?.dispose(); + _equirectMaterial?.dispose(); + _blurMaterial?.dispose(); + _pingPongRenderTarget?.dispose(); + + _flatCamera.dispose(); + _oldTarget?.dispose(); + _axisDirections.clear(); + _renderer.dispose(); } + + // private interface + + void _setSize(int cubeSize) { + _lodMax = (MathUtils.log2(cubeSize.toDouble())).floor(); + _cubeSize = math.pow(2, _lodMax).toInt(); + } + + void _dispose() { + _blurMaterial?.dispose(); + _pingPongRenderTarget?.dispose(); + + for (int i = 0; i < _lodPlanes.length; i++) { + _lodPlanes[i].dispose(); + } + } + + void _cleanup(RenderTarget outputTarget) { + _renderer.setRenderTarget(_oldTarget,_oldActiveCubeFace, _oldActiveMipmapLevel); + _renderer.xr.enabled = _oldXrEnabled; + outputTarget.scissorTest = false; + _setViewport(outputTarget, 0, 0, outputTarget.width.toDouble(), outputTarget.height.toDouble()); + } + + RenderTarget _fromTexture(texture, [RenderTarget? renderTarget]) { + if (texture.mapping == CubeReflectionMapping || + texture.mapping == CubeRefractionMapping) { + _setSize(texture.image.length == 0 + ? 16 + : (texture.image[0].width ?? texture.image[0].image.width)); + } else { + // Equirectangular + + _setSize(texture.image.width ~/ 4); + } + + _oldTarget = _renderer.getRenderTarget(); + _oldActiveCubeFace = _renderer.getActiveCubeFace(); + _oldActiveMipmapLevel = _renderer.getActiveMipmapLevel(); + _oldXrEnabled = _renderer.xr.enabled; + + _renderer.xr.enabled = false; + + final cubeUVRenderTarget = renderTarget ?? _allocateTargets(); + _textureToCubeUV(texture, cubeUVRenderTarget); + _applyPMREM(cubeUVRenderTarget); + _cleanup(cubeUVRenderTarget); + + return cubeUVRenderTarget; + } + + WebGLRenderTarget _allocateTargets() { + int width = 3 * math.max(_cubeSize, 16 * 7); + int height = 4 * _cubeSize; + + final params = { + "magFilter": LinearFilter, + "minFilter": LinearFilter, + "generateMipmaps": false, + "type": HalfFloatType, + "format": RGBAFormat, + 'colorSpace': LinearSRGBColorSpace, + "depthBuffer": false + }; + + final cubeUVRenderTarget = _createRenderTarget(width, height, params); + + if (_pingPongRenderTarget == null || _pingPongRenderTarget.width != width) { + if (_pingPongRenderTarget != null) { + _dispose(); + } + + _pingPongRenderTarget = _createRenderTarget(width, height, params); + + final result = _createPlanes(_lodMax); + + _sizeLods = result["sizeLods"]; + _lodPlanes = result["lodPlanes"]; + _sigmas = result["sigmas"]; + + _blurMaterial = _getBlurShader(_lodMax, width, height); + } + + return cubeUVRenderTarget; + } + + void _compileMaterial(Material? material) { + BufferGeometry? geometry; + if (_lodPlanes.length >= 1) { + geometry = _lodPlanes[0]; + } + + final tmpMesh = Mesh(geometry, material); + _renderer.compile(tmpMesh, _flatCamera); + } + + void _sceneToCubeUV(Scene scene, double near, double far, RenderTarget cubeUVRenderTarget, Vector3 position) { + const double fov = 90; + const double aspect = 1; + final cubeCamera = PerspectiveCamera(fov, aspect, near, far); + List upSign = [1, -1, 1, 1, 1, 1]; + List forwardSign = [1, 1, 1, -1, -1, -1]; + final renderer = _renderer; + + final originalAutoClear = renderer.autoClear; + final toneMapping = renderer.toneMapping; + renderer.getClearColor(_clearColor); + + renderer.toneMapping = NoToneMapping; + renderer.autoClear = false; + final backgroundMaterial = MeshBasicMaterial.fromMap({ + "name": 'PMREM.Background', + "side": BackSide, + "depthWrite": false, + "depthTest": false, + }); + final backgroundBox = Mesh(BoxGeometry(), backgroundMaterial); + bool useSolidColor = false; + final background = scene.background; + if (background != null) { + if (background is Color) { + backgroundMaterial.color.setFrom(background); + scene.background = null; + useSolidColor = true; + } + } + else { + backgroundMaterial.color.setFrom(_clearColor); + useSolidColor = true; + } + + for (int i = 0; i < 6; i++) { + final col = i % 3; + if (col == 0) { + cubeCamera.up.setValues(0, upSign[i], 0); + cubeCamera.position.setValues( position.x, position.y, position.z ); + cubeCamera.lookAt(Vector3(forwardSign[i], 0, 0)); + } + else if (col == 1) { + cubeCamera.up.setValues(0, 0, upSign[i]); + cubeCamera.position.setValues( position.x, position.y, position.z ); + cubeCamera.lookAt(Vector3(0, forwardSign[i], 0)); + } + else { + cubeCamera.up.setValues(0, upSign[i], 0); + cubeCamera.position.setValues( position.x, position.y, position.z ); + cubeCamera.lookAt(Vector3(0, 0, forwardSign[i])); + } + final size = _cubeSize.toDouble(); + _setViewport(cubeUVRenderTarget, col * size, i > 2 ? size : 0, size, size); + renderer.setRenderTarget(cubeUVRenderTarget); + if (useSolidColor) { + renderer.render(backgroundBox, cubeCamera); + } + renderer.render(scene, cubeCamera); + } + backgroundBox.geometry?.dispose(); + backgroundBox.material?.dispose(); + + renderer.toneMapping = toneMapping; + renderer.autoClear = originalAutoClear; + scene.background = background; + } + + void _textureToCubeUV(Texture texture, RenderTarget cubeUVRenderTarget) { + final renderer = _renderer; + + bool isCubeTexture = (texture.mapping == CubeReflectionMapping || + texture.mapping == CubeRefractionMapping); + + if (isCubeTexture) { + _cubemapMaterial ??= _getCubemapShader(); + + _cubemapMaterial.uniforms["flipEnvMap"]["value"] = + (texture.isRenderTargetTexture == false) ? -1 : 1; + } else { + _equirectMaterial ??= _getEquirectMaterial(); + } + + final material = isCubeTexture ? _cubemapMaterial : _equirectMaterial; + + BufferGeometry? geometry; + if (_lodPlanes.length >= 1) { + geometry = _lodPlanes[0]; + } + final mesh = Mesh(geometry, material); + + final uniforms = material.uniforms; + + uniforms['envMap']["value"] = texture; + + final size = _cubeSize.toDouble(); + _setViewport(cubeUVRenderTarget, 0, 0, 3 * size, 2 * size); + + renderer.setRenderTarget(cubeUVRenderTarget); + renderer.render(mesh, _flatCamera); + } + + void _applyPMREM(RenderTarget cubeUVRenderTarget) { + final renderer = _renderer; + final autoClear = renderer.autoClear; + renderer.autoClear = false; + + for (int i = 1; i < _lodPlanes.length; i++) { + final sigma = math.sqrt(_sigmas[i] * _sigmas[i] - _sigmas[i - 1] * _sigmas[i - 1]); + final poleAxis = _axisDirections[(i - 1) % _axisDirections.length]; + _blur(cubeUVRenderTarget, i - 1, i, sigma, poleAxis); + } + + renderer.autoClear = autoClear; + } + + /// * + /// * This is a two-pass Gaussian blur for a cubemap. Normally this is done + /// * vertically and horizontally, but this breaks down on a cube. Here we apply + /// * the blur latitudinally (around the poles), and then longitudinally (towards + /// * the poles) to approximate the orthogonally-separable blur. It is least + /// * accurate at the poles, but still does a decent job. + /// * + void _blur(RenderTarget cubeUVRenderTarget, int lodIn, int lodOut, double sigma, [Vector3? poleAxis]) { + final RenderTarget? pingPongRenderTarget = _pingPongRenderTarget; + _halfBlur(cubeUVRenderTarget, pingPongRenderTarget, lodIn, lodOut, sigma, 'latitudinal', poleAxis); + _halfBlur(pingPongRenderTarget, cubeUVRenderTarget, lodOut, lodOut, sigma,'longitudinal', poleAxis); + } + + void _halfBlur(RenderTarget? targetIn, RenderTarget? targetOut, int lodIn, int lodOut, double sigmaRadians, String direction, Vector3? poleAxis) { + final renderer = _renderer; + final blurMaterial = _blurMaterial; + + if (direction != 'latitudinal' && direction != 'longitudinal') { + console.warning('blur direction must be either latitudinal or longitudinal!'); + } + + // Number of standard deviations at which to cut off the discrete approximation. + const standardDeviations = 3; + + BufferGeometry? geometry; + + if (lodOut < _lodPlanes.length) { + geometry = _lodPlanes[lodOut]; + } + + final blurMesh = Mesh(geometry, blurMaterial); + final blurUniforms = blurMaterial?.uniforms; + + final pixels = _sizeLods[lodIn] - 1; + final radiansPerPixel = isFinite(sigmaRadians)? math.pi / (2 * pixels): 2 * math.pi / (2 * maxSamples - 1); + final sigmaPixels = sigmaRadians / radiansPerPixel; + final samples = isFinite(sigmaRadians)? 1 + (standardDeviations * sigmaPixels).floor(): maxSamples; + + if (samples > maxSamples) { + console.warning("sigmaRadians, $sigmaRadians, is too large and will clip, as it requested $samples samples when the maximum is set to $maxSamples"); + } + + List weights = []; + double sum = 0; + + for (int i = 0; i < maxSamples; ++i) { + final x = i / sigmaPixels; + final weight = math.exp(-x * x / 2); + weights.add(weight); + + if (i == 0) { + sum += weight; + } else if (i < samples) { + sum += 2 * weight; + } + } + + for (int i = 0; i < weights.length; i++) { + weights[i] = weights[i] / sum; + } + + blurUniforms['envMap']["value"] = targetIn?.texture; + blurUniforms['samples']["value"] = samples; + blurUniforms['weights']["value"] = Float32List.fromList(weights); + blurUniforms['latitudinal']["value"] = direction == 'latitudinal'; + + if (poleAxis != null) { + blurUniforms['poleAxis']["value"] = poleAxis; + } + + blurUniforms['dTheta']["value"] = radiansPerPixel; + blurUniforms['mipInt']["value"] = this._lodMax - lodIn; + + final double outputSize = _sizeLods[lodOut].toDouble(); + final x = 3 * outputSize *(lodOut > this._lodMax - lodMin ? lodOut - this._lodMax + lodMin : 0); + final y = 4 * (this._cubeSize - outputSize); + + _setViewport(targetOut, x, y, 3 * outputSize, 2 * outputSize); + renderer.setRenderTarget(targetOut); + renderer.render(blurMesh, _flatCamera); + } + + bool isFinite(double value) { + return value == double.maxFinite; + } + + Map _createPlanes(int lodMax) { + final lodPlanes = []; + final sizeLods = []; + final sigmas = []; + + int lod = lodMax; + + final totalLods = lodMax - lodMin + 1 + extraLodSigma.length; + + for (int i = 0; i < totalLods; i++) { + final sizeLod = math.pow(2, lod); + sizeLods.add(sizeLod); + double sigma = 1.0 / sizeLod; + + if (i > lodMax - lodMin) { + sigma = extraLodSigma[i - lodMax + lodMin - 1]; + } else if (i == 0) { + sigma = 0; + } + + sigmas.add(sigma); + + final texelSize = 1.0 / (sizeLod - 2); + final min = -texelSize; + final max = 1 + texelSize; + final uv1 = [min, min, max, min, max, max, min, min, max, max, min, max]; + + const cubeFaces = 6; + const vertices = 6; + const positionSize = 3; + const uvSize = 2; + const faceIndexSize = 1; + + final position = Float32List(positionSize * vertices * cubeFaces); + final uv = Float32List(uvSize * vertices * cubeFaces); + final faceIndex = Int32List(faceIndexSize * vertices * cubeFaces); + + for (int face = 0; face < cubeFaces; face++) { + double x = (face % 3) * 2 / 3 - 1; + double y = face > 2 ? 0 : -1; + List coordinates = [ + x, y, 0, + x + 2 / 3, y, 0, + x + 2 / 3, y + 1, 0, + x, y, 0, + x + 2 / 3, y + 1, 0, + x, y + 1, 0 + ]; + position.set(coordinates, positionSize * vertices * face); + uv.set(uv1, uvSize * vertices * face); + final faces = [face, face, face, face, face, face]; + faceIndex.set(faces, faceIndexSize * vertices * face); + } + + final planes = BufferGeometry(); + planes.setAttributeFromString('position', Float32BufferAttribute.fromList(position, positionSize)); + planes.setAttributeFromString('uv', Float32BufferAttribute.fromList(uv, uvSize)); + planes.setAttributeFromString('faceIndex', Int32BufferAttribute.fromList(faceIndex, faceIndexSize)); + lodPlanes.add(planes); + + if (lod > lodMin) { + lod--; + } + } + + return {"lodPlanes": lodPlanes, "sizeLods": sizeLods, "sigmas": sigmas}; + } + + WebGLRenderTarget _createRenderTarget(int width, int height, Map params) { + final cubeUVRenderTarget = WebGLRenderTarget(width, height, RenderTargetOptions(params)); + cubeUVRenderTarget.texture.mapping = CubeUVReflectionMapping; + cubeUVRenderTarget.texture.name = 'PMREM.cubeUv'; + cubeUVRenderTarget.scissorTest = true; + return cubeUVRenderTarget; + } + + void _setViewport(RenderTarget? target, double x, double y, double width, double height) { + target?.viewport.setValues(x, y, width, height); + target?.scissor.setValues(x, y, width, height); + } + + ShaderMaterial _getBlurShader(int lodMax, int width, int height) { + final weights = Float32List(maxSamples); + final poleAxis = Vector3(0, 1, 0); + final shaderMaterial = ShaderMaterial.fromMap({ + "name": 'SphericalGaussianBlur', + "defines": { + 'n': maxSamples, + 'CUBEUV_TEXEL_WIDTH': 1.0 / width, + 'CUBEUV_TEXEL_HEIGHT': 1.0 / height, + 'CUBEUV_MAX_MIP': "$lodMax.0", + }, + "uniforms": { + 'envMap': {"value": null}, + 'samples': {"value": 1}, + 'weights': {"value": weights}, + 'latitudinal': {"value": false}, + 'dTheta': {"value": 0.0}, + 'mipInt': {"value": 0}, + 'poleAxis': {"value": poleAxis} + }, + "vertexShader": _getCommonVertexShader(), + "fragmentShader": """ + + precision mediump float; + precision mediump int; + + varying vec3 vOutputDirection; + + uniform sampler2D envMap; + uniform int samples; + uniform float weights[ n ]; + uniform bool latitudinal; + uniform float dTheta; + uniform float mipInt; + uniform vec3 poleAxis; + + #define ENVMAP_TYPE_CUBE_UV + #include + + vec3 getSample( float theta, vec3 axis ) { + + float cosTheta = cos( theta ); + // Rodrigues' axis-angle rotation + vec3 sampleDirection = vOutputDirection * cosTheta + + cross( axis, vOutputDirection ) * sin( theta ) + + axis * dot( axis, vOutputDirection ) * ( 1.0 - cosTheta ); + + return bilinearCubeUV( envMap, sampleDirection, mipInt ); + + } + + void main() { + + vec3 axis = latitudinal ? poleAxis : cross( poleAxis, vOutputDirection ); + + if ( all( equal( axis, vec3( 0.0 ) ) ) ) { + + axis = vec3( vOutputDirection.z, 0.0, - vOutputDirection.x ); + + } + + axis = normalize( axis ); + + gl_FragColor = vec4( 0.0, 0.0, 0.0, 1.0 ); + gl_FragColor.rgb += weights[ 0 ] * getSample( 0.0, axis ); + + for ( int i = 1; i < n; i++ ) { + + if ( i >= samples ) { + + break; + + } + + float theta = dTheta * float( i ); + gl_FragColor.rgb += weights[ i ] * getSample( -1.0 * theta, axis ); + gl_FragColor.rgb += weights[ i ] * getSample( theta, axis ); + + } + + } + """, + "blending": NoBlending, + "depthTest": false, + "depthWrite": false + }); + + return shaderMaterial; + } + + ShaderMaterial _getEquirectMaterial() { + final shaderMaterial = ShaderMaterial.fromMap({ + "name": 'EquirectangularToCubeUV', + "uniforms": {'envMap': {'value': null}}, + "vertexShader": _getCommonVertexShader(), + "fragmentShader": """ + + precision mediump float; + precision mediump int; + + varying vec3 vOutputDirection; + + uniform sampler2D envMap; + + #include + + void main() { + vec3 outputDirection = normalize( vOutputDirection ); + vec2 uv = equirectUv( outputDirection ); + gl_FragColor = vec4( texture2D ( envMap, uv ).rgb, 1.0 ); + } + """, + "blending": NoBlending, + "depthTest": false, + "depthWrite": false + }); + + return shaderMaterial; + } + + ShaderMaterial _getCubemapShader() { + final shaderMaterial = ShaderMaterial.fromMap({ + "name": 'CubemapToCubeUV', + "uniforms": { + 'envMap': {"value":null}, + 'flipEnvMap': {"value": -1} + }, + "vertexShader": _getCommonVertexShader(), + "fragmentShader": """ + + precision mediump float; + precision mediump int; + + uniform float flipEnvMap; + + varying vec3 vOutputDirection; + + uniform samplerCube envMap; + + void main() { + + gl_FragColor = textureCube( envMap, vec3( flipEnvMap * vOutputDirection.x, vOutputDirection.yz ) ); + + } + """, + "blending": NoBlending, + "depthTest": false, + "depthWrite": false + }); + + return shaderMaterial; + } + + String _getCommonVertexShader() { + return """ + precision mediump float; + precision mediump int; + + attribute float faceIndex; + + varying vec3 vOutputDirection; + + // RH coordinate system; PMREM face-indexing convention + vec3 getDirection( vec2 uv, float face ) { + + uv = 2.0 * uv - 1.0; + + vec3 direction = vec3( uv, 1.0 ); + + if ( face == 0.0 ) { + + direction = direction.zyx; // ( 1, v, u ) pos x + + } else if ( face == 1.0 ) { + + direction = direction.xzy; + direction.xz *= -1.0; // ( -u, 1, -v ) pos y + + } else if ( face == 2.0 ) { + + direction.x *= -1.0; // ( -u, v, 1 ) pos z + + } else if ( face == 3.0 ) { + + direction = direction.zyx; + direction.xz *= -1.0; // ( -1, v, -u ) neg x + + } else if ( face == 4.0 ) { + + direction = direction.xzy; + direction.xy *= -1.0; // ( -u, -1, v ) neg y + + } else if ( face == 5.0 ) { + + direction.z *= -1.0; // ( u, v, -1 ) neg z + + } + + return direction; + + } + + void main() { + + vOutputDirection = getDirection( uv, faceIndex ); + gl_Position = vec4( position, 1.0 ); + + } + """; + } +} diff --git a/packages/three_js_core/lib/renderers/web_gl_3d_render_target.dart b/packages/three_js_webgl_renderer/lib/renderers/web_gl_3d_render_target.dart similarity index 78% rename from packages/three_js_core/lib/renderers/web_gl_3d_render_target.dart rename to packages/three_js_webgl_renderer/lib/renderers/web_gl_3d_render_target.dart index ab8ae4f0..2658ae24 100755 --- a/packages/three_js_core/lib/renderers/web_gl_3d_render_target.dart +++ b/packages/three_js_webgl_renderer/lib/renderers/web_gl_3d_render_target.dart @@ -1,7 +1,7 @@ part of three_renderers; class WebGL3DRenderTarget extends WebGLRenderTarget { - WebGL3DRenderTarget([int width = 1, int height = 1, int depth = 1, WebGLRenderTargetOptions? options]) : super(width, height, options) { + WebGL3DRenderTarget([int width = 1, int height = 1, int depth = 1, RenderTargetOptions? options]) : super(width, height, options) { this.depth = depth; texture = Data3DTexture(null, width, height, depth); texture.isRenderTargetTexture = true; diff --git a/packages/three_js_core/lib/renderers/web_gl_array_render_target.dart b/packages/three_js_webgl_renderer/lib/renderers/web_gl_array_render_target.dart similarity index 78% rename from packages/three_js_core/lib/renderers/web_gl_array_render_target.dart rename to packages/three_js_webgl_renderer/lib/renderers/web_gl_array_render_target.dart index 8e80410b..91c77127 100755 --- a/packages/three_js_core/lib/renderers/web_gl_array_render_target.dart +++ b/packages/three_js_webgl_renderer/lib/renderers/web_gl_array_render_target.dart @@ -1,7 +1,7 @@ part of three_renderers; class WebGLArrayRenderTarget extends WebGLRenderTarget { - WebGLArrayRenderTarget([int width = 1, int height = 1, int depth = 1, WebGLRenderTargetOptions? options]) : super(width, height, options) { + WebGLArrayRenderTarget([int width = 1, int height = 1, int depth = 1, RenderTargetOptions? options]) : super(width, height, options) { this.depth = depth; texture = DataArrayTexture(null, width, height, depth); texture.isRenderTargetTexture = true; diff --git a/packages/three_js_core/lib/renderers/web_gl_cube_render_target.dart b/packages/three_js_webgl_renderer/lib/renderers/web_gl_cube_render_target.dart similarity index 90% rename from packages/three_js_core/lib/renderers/web_gl_cube_render_target.dart rename to packages/three_js_webgl_renderer/lib/renderers/web_gl_cube_render_target.dart index 348fd59d..c941117a 100755 --- a/packages/three_js_core/lib/renderers/web_gl_cube_render_target.dart +++ b/packages/three_js_webgl_renderer/lib/renderers/web_gl_cube_render_target.dart @@ -1,7 +1,7 @@ part of three_renderers; -class WebGLCubeRenderTarget extends WebGLRenderTarget { - WebGLCubeRenderTarget([int size = 1, WebGLRenderTargetOptions? options]) : super(size, size, options) { +class WebGLCubeRenderTarget extends CubeRenderTarget { + WebGLCubeRenderTarget([int size = 1, RenderTargetOptions? options]) : super(size, options) { // By convention -- likely based on the RenderMan spec from the 1990's -- cube maps are specified by WebGL (and three.js) // in a coordinate system in which positive-x is to the right when looking up the positive-z axis -- in other words, // in a left-handed coordinate system. By continuing this convention, preexisting cube maps continued to render correctly. @@ -30,7 +30,8 @@ class WebGLCubeRenderTarget extends WebGLRenderTarget { texture.minFilter = this.options.minFilter ?? LinearFilter; } - WebGLCubeRenderTarget fromEquirectangularTexture(WebGLRenderer renderer, Texture texture) { + @override + WebGLCubeRenderTarget fromEquirectangularTexture(Renderer renderer, Texture texture) { this.texture.type = texture.type; this.texture.colorSpace = texture.colorSpace; @@ -113,7 +114,8 @@ class WebGLCubeRenderTarget extends WebGLRenderTarget { return this; } - void clear(WebGLRenderer renderer, [bool color = true, bool depth = true, bool stencil = true]) { + @override + void clear(Renderer renderer, [bool color = true, bool depth = true, bool stencil = true]) { final currentRenderTarget = renderer.getRenderTarget(); for (int i = 0; i < 6; i++) { renderer.setRenderTarget(this, i); diff --git a/packages/three_js_webgl_renderer/lib/renderers/web_gl_render_target.dart b/packages/three_js_webgl_renderer/lib/renderers/web_gl_render_target.dart new file mode 100755 index 00000000..7ee78ab7 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/renderers/web_gl_render_target.dart @@ -0,0 +1,167 @@ +/* + In options, we can specify: + * Texture parameters for an auto-generated target texture + * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers +*/ +// import "package:universal_html/html.dart"; + +part of three_renderers; + +class WebGLRenderTarget extends RenderTarget { + bool isWebGLRenderTarget = true; + bool _didDispose = false; + WebGLRenderTarget(super.width, super.height, [super.options]); + + @override + WebGLRenderTarget clone() { + return WebGLRenderTarget(width, height, options).copy(this); + } + + @override + WebGLRenderTarget copy(RenderTarget source) { + super.copy(source); + return this; + } + + @override + bool is3D() { + return texture is Data3DTexture || texture is DataArrayTexture; + } + + @override + void dispose() { + if(_didDispose) return; + _didDispose = true; + dispatchEvent(Event(type: "dispose")); + depthTexture?.dispose(); + texture.dispose(); + options.dispose(); + } +} + +// class WebGLRenderTargetOptions { +// int? wrapS; +// int? wrapT; +// int? wrapR; +// int? magFilter; +// int? minFilter; +// int? format; +// int? type; +// int? anisotropy; +// bool? depthBuffer; +// int? mapping; + +// bool stencilBuffer = false; +// bool generateMipmaps = false; +// DepthTexture? depthTexture; +// int? encoding; + +// bool useMultisampleRenderToTexture = false; +// bool ignoreDepth = false; +// bool useRenderToTexture = false; + +// int? samples; +// int? internalFormat; +// int count = 1; + +// bool resolveDepthBuffer = false; +// bool resolveStencilBuffer = false; + +// void dispose(){ +// depthTexture?.dispose(); +// depthTexture = null; +// } + +// WebGLRenderTargetOptions([Map? json]) { +// json ??= {}; +// if (json["wrapS"] != null) { +// wrapS = json["wrapS"]; +// } +// if(json['count'] != null){ +// count = json['count']; +// } +// if(json['resolveDepthBuffer'] != null){ +// resolveDepthBuffer = json['resolveDepthBuffer']; +// } +// if(json['resolveStencilBuffer'] != null){ +// resolveStencilBuffer = json['resolveStencilBuffer']; +// } +// if(json['internalFormat'] != null){ +// internalFormat = json['internalFormat']; +// } +// if (json["wrapT"] != null) { +// wrapT = json["wrapT"]; +// } +// if (json["wrapR"] != null) { +// wrapR = json["wrapR"]; +// } +// if (json["magFilter"] != null) { +// magFilter = json["magFilter"]; +// } +// if (json["minFilter"] != null) { +// minFilter = json["minFilter"]; +// } +// if (json["format"] != null) { +// format = json["format"]; +// } +// if (json["type"] != null) { +// type = json["type"]; +// } +// if (json["anisotropy"] != null) { +// anisotropy = json["anisotropy"]; +// } +// if (json["depthBuffer"] != null) { +// depthBuffer = json["depthBuffer"]; +// } +// if (json["mapping"] != null) { +// mapping = json["mapping"]; +// } +// if (json["generateMipmaps"] != null) { +// generateMipmaps = json["generateMipmaps"]; +// } +// if (json["depthTexture"] != null) { +// depthTexture = json["depthTexture"]; +// } +// if (json["encoding"] != null) { +// encoding = json["encoding"]; +// } +// if (json["useMultisampleRenderToTexture"] != null) { +// useMultisampleRenderToTexture = json["useMultisampleRenderToTexture"]; +// } +// if (json["ignoreDepth"] != null) { +// ignoreDepth = json["ignoreDepth"]; +// } +// if (json["useRenderToTexture"] != null) { +// useRenderToTexture = json["useRenderToTexture"]; +// } + +// samples = json["samples"]; +// } + +// Map toJson() { +// return { +// "wrapS": wrapS, +// "wrapT": wrapT, +// "wrapR": wrapR, +// "magFilter": magFilter, +// "minFilter": minFilter, +// 'internalFormat': internalFormat, +// "format": format, +// 'count': count, +// "type": type, +// 'resolveStencilBuffer': resolveStencilBuffer, +// 'resolveDepthBuffer': resolveDepthBuffer, +// "anisotropy": anisotropy, +// "depthBuffer": depthBuffer, +// "mapping": mapping, +// "stencilBuffer": stencilBuffer, +// "generateMipmaps": generateMipmaps, +// "depthTexture": depthTexture, +// "encoding": encoding, +// "useMultisampleRenderToTexture": useMultisampleRenderToTexture, +// "ignoreDepth": ignoreDepth, +// "useRenderToTexture": useRenderToTexture, +// "samples": samples +// }; +// } +// } diff --git a/packages/three_js_core/lib/renderers/web_gl_renderer.dart b/packages/three_js_webgl_renderer/lib/renderers/web_gl_renderer.dart similarity index 94% rename from packages/three_js_core/lib/renderers/web_gl_renderer.dart rename to packages/three_js_webgl_renderer/lib/renderers/web_gl_renderer.dart index 2dd63506..a6200c16 100755 --- a/packages/three_js_core/lib/renderers/web_gl_renderer.dart +++ b/packages/three_js_webgl_renderer/lib/renderers/web_gl_renderer.dart @@ -1,23 +1,6 @@ part of three_renderers; enum RenderType{after,before,custom} -enum PowerPreference{high,defaultp,low; - - String get name => _name(); - String _name(){ - if(index == 0){ - return 'high-performance'; - } - else if(index == 2){ - return 'low-power'; - } - else{ - return 'default'; - } - } -} - -enum Precision{highp,mediump,lowp} class WebGLRendererParameters{ double width; @@ -36,7 +19,7 @@ class WebGLRendererParameters{ bool failIfMajorPerformanceCaveat; bool depth = true; Precision precision; - WebXRManager Function(WebGLRenderer renderer, dynamic gl)? xr; + XRManager Function(WebGLRenderer renderer, dynamic gl)? xr; WebGLRendererParameters({ required this.width, @@ -78,7 +61,7 @@ class WebGLRendererParameters{ } } -class WebGLRenderer { +class WebGLRenderer extends Renderer{ late WebGLRendererParameters parameters; bool _didDispose = false; @@ -97,8 +80,8 @@ class WebGLRenderer { bool reverseDepthBuffer = false; bool renderBackground = false; - WebGLRenderList? currentRenderList; - WebGLRenderState? currentRenderState; + late WebGLRenderList? currentRenderList; + late WebGLRenderState? currentRenderState; // render() can be called from within a callback triggered by another render. @@ -187,13 +170,13 @@ class WebGLRenderer { // transmission double transmissionResolutionScale = 1.0; + RenderTarget? _transmissionRenderTarget; // camera matrices cache final projScreenMatrix = Matrix4.identity(); final _vector3 = Vector3(); - final _vector4 = Vector4(); final _emptyScene = Scene(); @@ -232,14 +215,14 @@ class WebGLRenderer { late WebGLBindingStates bindingStates; - late WebXRManager xr; - late WebXRManager Function(WebGLRenderer renderer, dynamic gl)? _setXR; + late XRManager xr; late WebGLUniformsGroups uniformsGroups; late WebGLShadowMap shadowMap; late final Framebuffer _scratchFrameBuffer; late final Framebuffer _srcFramebuffer; late final Framebuffer _dstFramebuffer; + WebGLRenderer(this.parameters) { _width = this.parameters.width; _height = this.parameters.height; @@ -259,13 +242,9 @@ class WebGLRenderer { _scissor = Vector4(0, 0, width, height); _gl = this.parameters.gl; - _setXR = this.parameters.xr; initGLContext(); } - factory WebGLRenderer.fromMap([Map? parameters]) { - return WebGLRenderer(WebGLRendererParameters.fromMap(parameters ?? {})); - } void initGLContext() { _scratchFrameBuffer = _gl.createFramebuffer(); @@ -306,11 +285,10 @@ class WebGLRenderer { indexedBufferRenderer = WebGLIndexedBufferRenderer(_gl, extensions, info); info.programs = programCache.programs; - - xr = _setXR?.call(this,gl) ?? WebXRManager(this, _gl); - xr.init(); - xr.addEventListener( 'sessionstart', onXRSessionStart ); - xr.addEventListener( 'sessionend', onXRSessionEnd ); + + xr = XRManager(this, _gl); + // xr.addEventListener( 'sessionstart', onXRSessionStart ); + // xr.addEventListener( 'sessionend', onXRSessionEnd ); } // API @@ -519,6 +497,9 @@ class WebGLRenderer { cubeuvmaps.dispose(); bindingStates.dispose(); programCache.dispose(); + + _transmissionRenderTarget?.dispose(); + _transmissionRenderTarget = null; currentRenderList?.dispose(); for(final stack in renderListStack){ @@ -552,10 +533,6 @@ class WebGLRenderer { shadowMap.dispose(); properties.dispose(); - - _gl.deleteFramebuffer(_scratchFrameBuffer); - _gl.deleteFramebuffer(_srcFramebuffer); - _gl.deleteFramebuffer(_dstFramebuffer); } // Events @@ -639,7 +616,7 @@ class WebGLRenderer { if (material.wireframe) { index = geometries.getWireframeAttribute(geometry); if (index == null) return; - if(kIsWeb && !kIsWasm){ + if(kIsWeb){ rangeFactor = 2; } } @@ -650,8 +627,8 @@ class WebGLRenderer { final drawRange = geometry.drawRange; BufferAttribute? position = geometry.attributes["position"]; - int drawStart = (drawRange['start'] ?? 0) * rangeFactor; - int drawEnd = ( (drawRange['start'] ?? 0) + (drawRange['count'] ?? 0) ) * rangeFactor; + int drawStart = drawRange['start']! * rangeFactor; + int drawEnd = ( drawRange['start']! + drawRange['count']! ) * rangeFactor; if ( group != null ) { drawStart = math.max( drawStart, group['start'] * rangeFactor ); @@ -833,11 +810,11 @@ class WebGLRenderer { if (onAnimationFrameCallback != null) onAnimationFrameCallback!(time); } - void onXRSessionStart(event) { + void onXRSessionStart() { animation.stop(); } - void onXRSessionEnd(event) { + void onXRSessionEnd() { animation.start(); } @@ -849,7 +826,6 @@ class WebGLRenderer { // Rendering void render(Object3D scene, Camera camera) { - if (_isContextLost) return; // update scene graph @@ -861,7 +837,7 @@ class WebGLRenderer { if ( xr.enabled && xr.isPresenting ) { if (xr.cameraAutoUpdate) xr.updateCamera( camera ); - if(kIsWeb) camera = xr.getCamera(); + camera = xr.getCamera(); } if (scene is Scene) { @@ -923,7 +899,6 @@ class WebGLRenderer { currentRenderState!.setupLights(physicallyCorrectLights); if (camera is ArrayCamera) { - final cameras = camera.cameras; if (transmissiveObjects != null && transmissiveObjects.isNotEmpty) { for (int i = 0, l = cameras.length; i < l; i ++ ) { @@ -958,7 +933,7 @@ class WebGLRenderer { scene.onAfterRender?.call(renderer: this, scene: scene, camera: camera); } - _gl.flush(); + _gl.finish(); bindingStates.resetDefaultState(); _currentMaterialId = -1; @@ -1005,14 +980,14 @@ class WebGLRenderer { else if (object is Sprite) { if (!object.frustumCulled || _frustum.intersectsSprite(object)) { if (sortObjects) { - _vector4.setFromMatrixPosition(object.matrixWorld).applyMatrix4(projScreenMatrix); + _vector3.setFromMatrixPosition(object.matrixWorld).applyMatrix4(projScreenMatrix); } BufferGeometry geometry = objects.update(object); final material = object.material; if (material != null && material.visible) { - currentRenderList!.push(object, geometry, material, groupOrder, _vector4.z, null); + currentRenderList!.push(object, geometry, material, groupOrder, _vector3.z, null); } } } @@ -1034,13 +1009,13 @@ class WebGLRenderer { if (sortObjects) { if (object.boundingSphere != null ) { if (object.boundingSphere == null ) object.computeBoundingSphere(); - _vector4.setFrom(object.boundingSphere!.center ); + _vector3.setFrom(object.boundingSphere!.center ); } else { if ( geometry.boundingSphere == null ) geometry.computeBoundingSphere(); - _vector4.setFrom( geometry.boundingSphere!.center ); + _vector3.setFrom( geometry.boundingSphere!.center ); } - _vector4..applyMatrix4(object.matrixWorld)..applyMatrix4(projScreenMatrix); + _vector3..applyMatrix4(object.matrixWorld)..applyMatrix4(projScreenMatrix); } if (material is GroupMaterial) { @@ -1049,21 +1024,23 @@ class WebGLRenderer { if (groups.isNotEmpty) { for (int i = 0, l = groups.length; i < l; i++) { Map group = groups[i]; - final groupMaterial = material.children[group["materialIndex"]]; + if(group["materialIndex"] < material.children.length){ + final groupMaterial = material.children[group["materialIndex"]]; - if (groupMaterial.visible) { - currentRenderList!.push(object, geometry, groupMaterial, groupOrder, _vector4.z, group); + if (groupMaterial.visible) { + currentRenderList!.push(object, geometry, groupMaterial, groupOrder, _vector3.z, group); + } } } } else { - if (material.visible && material.children.isNotEmpty) { - currentRenderList!.push(object, geometry, material.children[0], groupOrder, _vector4.z, null); + if (material.visible) { + currentRenderList!.push(object, geometry, material, groupOrder, _vector3.z, null); } } } else if (material != null && material.visible) { - currentRenderList!.push(object, geometry, material, groupOrder, _vector4.z, null); + currentRenderList!.push(object, geometry, material, groupOrder, _vector3.z, null); } } } @@ -1110,28 +1087,26 @@ class WebGLRenderer { return; } - RenderTarget? transmissionRenderTarget = currentRenderState?.state.transmissionRenderTarget[ camera.id ]; - final activeViewport = camera.viewport ?? _currentViewport; - - if ( currentRenderState?.state.transmissionRenderTarget[ camera.id ] == null || - (activeViewport.w.toInt() != transmissionRenderTarget?.height || activeViewport.z.toInt() != transmissionRenderTarget?.width) - ) { - transmissionRenderTarget?.dispose(); - currentRenderState?.state.transmissionRenderTarget[ camera.id ] = WebGLRenderTarget( 1, 1, WebGLRenderTargetOptions({ - 'generateMipmaps': true, - 'type': ( extensions.has( 'EXT_color_buffer_half_float' ) || extensions.has( 'EXT_color_buffer_float' ) ) ? HalfFloatType : UnsignedByteType, - 'minFilter': LinearMipmapLinearFilter, - 'samples': 4, - 'stencilBuffer': stencil, - 'resolveDepthBuffer': false, - 'resolveStencilBuffer': false, - 'colorSpace': ColorManagement.workingColorSpace.toString(), + if ( currentRenderState?.state.transmissionRenderTarget[ camera.id ] == null ) { + + currentRenderState?.state.transmissionRenderTarget[ camera.id ] = WebGLRenderTarget( 1, 1, RenderTargetOptions({ + 'generateMipmaps': true, + 'type': ( extensions.has( 'EXT_color_buffer_half_float' ) || extensions.has( 'EXT_color_buffer_float' ) ) ? HalfFloatType : UnsignedByteType, + 'minFilter': LinearMipmapLinearFilter, + 'samples': 4, + 'stencilBuffer': stencil, + 'resolveDepthBuffer': false, + 'resolveStencilBuffer': false, + 'colorSpace': ColorManagement.workingColorSpace, })); - - transmissionRenderTarget = currentRenderState?.state.transmissionRenderTarget[ camera.id ]; } - transmissionRenderTarget!.setSize( (activeViewport.z * transmissionResolutionScale).toInt(), (activeViewport.w * transmissionResolutionScale).toInt()); + final RenderTarget transmissionRenderTarget = currentRenderState?.state.transmissionRenderTarget[ camera.id ]; + + final activeViewport = camera.viewport ?? _currentViewport; + transmissionRenderTarget.setSize( (activeViewport.z * transmissionResolutionScale).toInt(), (activeViewport.w * transmissionResolutionScale).toInt()); + + // final currentRenderTarget = getRenderTarget(); setRenderTarget( transmissionRenderTarget ); @@ -1709,7 +1684,7 @@ class WebGLRenderer { //} } - void setRenderTargetFramebuffer(RenderTarget renderTarget, Framebuffer? defaultFramebuffer) { + void setRenderTargetFramebuffer(RenderTarget renderTarget, defaultFramebuffer) { final renderTargetProperties = properties.get(renderTarget); renderTargetProperties["__webglFramebuffer"] = defaultFramebuffer; renderTargetProperties["__useDefaultFramebuffer"] = defaultFramebuffer == null; @@ -1831,7 +1806,7 @@ class WebGLRenderer { _currentMaterialId = -1; // reset current material to ensure correct uniform bindings } - void readRenderTargetPixels(WebGLRenderTarget renderTarget, int x, int y, int width, int height, TypedData buffer, [int? activeCubeFaceIndex]) { + void readRenderTargetPixels(WebGLRenderTarget renderTarget, int x, int y, int width, int height, TypedDataList buffer, [activeCubeFaceIndex]) { dynamic framebuffer = properties.get(renderTarget)["__webglFramebuffer"]; //can be Map or int if (renderTarget is WebGLCubeRenderTarget && activeCubeFaceIndex != null) { @@ -1853,11 +1828,12 @@ class WebGLRenderer { } final halfFloatSupportedByExt = textureType == HalfFloatType && - (extensions.has('EXT_color_buffer_half_float') || - (capabilities.isWebGL2 && extensions.has('EXT_color_buffer_float'))); + (extensions.get('EXT_color_buffer_half_float') || + (capabilities.isWebGL2 && extensions.get('EXT_color_buffer_float'))); if (textureType != UnsignedByteType && - (kIsWeb && utils.convert(textureType) != _gl.getParameter(WebGL.IMPLEMENTATION_COLOR_READ_TYPE)) && // IE11, Edge and Chrome Mac < 52 (#9513) + utils.convert(textureType) != + _gl.getParameter(WebGL.IMPLEMENTATION_COLOR_READ_TYPE) && // IE11, Edge and Chrome Mac < 52 (#9513) !(textureType == FloatType && (capabilities.isWebGL2 || extensions.get('OES_texture_float') || @@ -1889,8 +1865,8 @@ class WebGLRenderer { final width = (texture.image.width * levelScale).floor(); final height = (texture.image.height * levelScale).floor(); - final x = position != null && !position.x.isNaN ? position.x.toInt() : 0; - final y = position != null && !position.y.isNaN ? position.y.toInt() : 0; + final x = position != null ? position.x.toInt() : 0; + final y = position != null ? position.y.toInt() : 0; textures.setTexture2D(texture, 0); _gl.copyTexSubImage2D(WebGL.TEXTURE_2D, level, 0, 0, x, y, width, height); @@ -1967,11 +1943,11 @@ class WebGLRenderer { textures.setTexture2D( dstTexture, 0 ); glTarget = WebGL.TEXTURE_2D; } - // if(kIsWeb){ - // _gl.pixelStorei( WebGL.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY?1:0 ); - // _gl.pixelStorei( WebGL.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha?1:0 ); - // _gl.pixelStorei( WebGL.UNPACK_ALIGNMENT, dstTexture.unpackAlignment ); - // } + if(kIsWeb){ + _gl.pixelStorei( WebGL.UNPACK_FLIP_Y_WEBGL, dstTexture.flipY?1:0 ); + _gl.pixelStorei( WebGL.UNPACK_PREMULTIPLY_ALPHA_WEBGL, dstTexture.premultiplyAlpha?1:0 ); + _gl.pixelStorei( WebGL.UNPACK_ALIGNMENT, dstTexture.unpackAlignment ); + } // used for copying data from cpu final currentUnpackRowLen = _gl.getParameter( WebGL.UNPACK_ROW_LENGTH ); diff --git a/packages/three_js_core/lib/renderers/shaders/index.dart b/packages/three_js_webgl_renderer/lib/shaders/index.dart similarity index 91% rename from packages/three_js_core/lib/renderers/shaders/index.dart rename to packages/three_js_webgl_renderer/lib/shaders/index.dart index 33b3df49..6dec99a8 100755 --- a/packages/three_js_core/lib/renderers/shaders/index.dart +++ b/packages/three_js_webgl_renderer/lib/shaders/index.dart @@ -3,11 +3,11 @@ library three_shaders; import 'package:three_js_core/three_js_core.dart'; import 'package:three_js_math/three_js_math.dart'; import 'shader_chunk/index.dart'; +import 'shader_lib/index.dart'; export './shader_lib/vsm_vert.glsl.dart'; export './shader_lib/vsm_frag.glsl.dart'; part './shader_lib.dart'; part 'uniforms_lib.dart'; -part 'uniforms_utils.dart'; part './shader_chunk.dart'; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk.dart new file mode 100755 index 00000000..03c9815a --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk.dart @@ -0,0 +1,154 @@ +part of three_shaders; + +Map shaderChunk = { + 'alphahash_fragment': alphahashFragment, + 'alphahash_pars_fragment': alphahashParsFragment, + "alphamap_fragment": alphamapFragment, + "alphamap_pars_fragment": alphamapParsFragment, + "alphatest_fragment": alphatestFragment, + "aomap_fragment": aomapFragment, + "alphatest_pars_fragment": alphatestParsFragment, + "aomap_pars_fragment": aomapParsFragment, + 'batching_pars_vertex': batchingParsVertex, + 'batching_vertex': batchingVertex, + "begin_vertex": beginVertex, + "beginnormal_vertex": beginnormalVertex, + "bsdfs": bsdfs, + "bumpmap_pars_fragment": bumpmapParsFragment, + "clearcoat_normal_fragment_begin": clearcoatNormalFragmentBegin, + "clearcoat_normal_fragment_maps": clearcoatNormalFragmentMaps, + "clearcoat_pars_fragment": clearcoatParsFragment, + "clipping_planes_fragment": clippingPlanesFragment, + "clipping_planes_pars_fragment": clippingPlanesParsFragment, + "clipping_planes_pars_vertex": clippingPlanesParsVertex, + "clipping_planes_vertex": clippingPlanesVertex, + "color_fragment": colorFragment, + "color_pars_fragment": colorParsFragment, + "color_pars_vertex": colorParsVertex, + "colorspace_fragment": colorspaceFragment, + 'colorspace_pars_fragment': colorspaceParsFragment, + "color_vertex": colorVertex, + "common": commonGlsl, + "cube_uv_reflection_fragment": cubeUvReflectionFragment, + "defaultnormal_vertex": defaultnormalVertex, + "dithering_fragment": ditheringFragment, + "dithering_pars_fragment": ditheringParsFragment, + "displacementmap_pars_vertex": displacementmapParsVertex, + "displacementmap_vertex": displacementmapVertex, + "emissivemap_fragment": emissivemapFragment, + "emissivemap_pars_fragment": emissivemapParsFragment, + "encodings_fragment": encodingsFragment, + "encodings_pars_fragment": encodingsParsFragment, + "envmap_fragment": envmapFragment, + "envmap_common_pars_fragment": envmapCommonParsFragment, + "envmap_pars_fragment": envmapParsFragment, + "envmap_pars_vertex": envmapParsVertex, + "envmap_physical_pars_fragment": envmapPhysicalParsFragment, + "envmap_vertex": envmapVertex, + "fog_vertex": fogVertex, + "fog_pars_vertex": fogParsVertex, + "fog_fragment": fogFragment, + "fog_pars_fragment": fogParsFragment, + "gradientmap_pars_fragment": gradientmapParsFragment, + 'iridescence_fragment': iridescenceFragment, + 'iridescence_pars_fragment': iridescenceParsFragment, + "lightmap_fragment": lightmapFragment, + "lightmap_pars_fragment": lightmapParsFragment, + "lights_lambert_vertex": lightsLambertVertex, + 'lights_lambert_fragment': lightsLambertFragment, + 'lights_lambert_pars_fragment': lightsLambertParsFragment, + "lights_pars_begin": lightsParsBegin, + "lights_toon_fragment": lightsToonFragment, + "lights_toon_pars_fragment": lightsToonParsFragment, + "lights_phong_fragment": lightsPhongFragment, + "lights_phong_pars_fragment": lightsPhongParsFragment, + "lights_physical_fragment": lightsPhysicalFragment, + "lights_physical_pars_fragment": lightsPhysicalParsFragment, + "lights_fragment_begin": lightsFragmentBegin, + "lights_fragment_maps": lightsFragmentMaps, + "lights_fragment_end": lightsFragmentEnd, + "logdepthbuf_fragment": logdepthbufFragment, + "logdepthbuf_pars_fragment": logdepthbufParsFragment, + "logdepthbuf_pars_vertex": logdepthbufParsVertex, + "logdepthbuf_vertex": logdepthbufVertex, + "map_fragment": mapFragment, + "map_pars_fragment": mapParsFragment, + "map_particle_fragment": mapParticleFragment, + "map_particle_pars_fragment": mapParticleParsFragment, + "metalnessmap_fragment": metalnessmapFragment, + "metalnessmap_pars_fragment": metalnessmapParsFragment, + 'morphinstance_vertex': morphinstanceVertex, + "morphcolor_vertex": morphcolorVertex, + "morphnormal_vertex": morphnormalVertex, + "morphtarget_pars_vertex": morphtargetParsVertex, + "morphtarget_vertex": morphtargetVertex, + "normal_fragment_begin": normalFragmentBegin, + "normal_fragment_maps": normalFragmentMaps, + "normal_pars_fragment": normalParsFragment, + "normal_pars_vertex": normalParsVertex, + "normal_vertex": normalVertex, + "normalmap_pars_fragment": normalmapParsFragment, + "opaque_fragment": opaqueFragment, + // "output_fragment": outputFragment, + "packing": packingGlsl, + "premultiplied_alpha_fragment": premultipliedAlphaFragment, + "project_vertex": projectVertex, + "roughnessmap_fragment": roughnessmapFragment, + "roughnessmap_pars_fragment": roughnessmapParsFragment, + "shadowmap_pars_fragment": shadowmapParsFragment, + "shadowmap_pars_vertex": shadowmapParsVertex, + "shadowmap_vertex": shadowmapVertex, + "shadowmask_pars_fragment": shadowmaskParsFragment, + "skinbase_vertex": skinbaseVertex, + "skinning_pars_vertex": skinningParsVertex, + "skinning_vertex": skinningVertex, + "skinnormal_vertex": skinnormalVertex, + "specularmap_fragment": specularmapFragment, + "specularmap_pars_fragment": specularmapParsFragment, + "tonemapping_fragment": tonemappingFragment, + "tonemapping_pars_fragment": tonemappingParsFragment, + "transmission_fragment": transmissionFragment, + "transmission_pars_fragment": transmissionParsFragment, + "uv_pars_fragment": uvParsFragment, + "uv_pars_vertex": uvParsVertex, + "uv_vertex": uvVertex, + // "uv2_pars_fragment": uv2ParsFragment, + // "uv2_pars_vertex": uv2ParsVertex, + "uv2_vertex": uv2Vertex, + "worldpos_vertex": worldposVertex, + + "background_frag": backgroundFrag, + "background_vert": backgroundVert, + 'backgroundCube_vert': backgroundCubeVert, + 'backgroundCube_frag': backgroundCubeFrag, + "cube_frag": cubeFrag, + "cube_vert": cubeVert, + "depth_frag": depthFrag, + "depth_vert": depthVert, + "distanceRGBA_frag": distanceRgbeFrag, + "distanceRGBA_vert": distanceRgbaVert, + "equirect_frag": equirectFrag, + "equirect_vert": equirectVert, + "linedashed_frag": linedashedFrag, + "linedashed_vert": linedashedVert, + "meshbasic_frag": meshbasicFrag, + "meshbasic_vert": meshbasicVert, + "meshlambert_frag": meshlambertFrag, + "meshlambert_vert": meshlambertVert, + "meshmatcap_frag": meshmatcapFrag, + "meshmatcap_vert": meshmatcapVert, + "meshtoon_frag": meshtoonFrag, + "meshtoon_vert": meshtoonVert, + "meshphong_frag": meshphongFrag, + "meshphong_vert": meshphongVert, + "meshphysical_frag": meshphysicalFrag, + "meshphysical_vert": meshphysicalVert, + "meshnormal_frag": meshnormalFrag, + "meshnormal_vert": meshnormalVert, + "points_frag": pointsFrag, + "points_vert": pointsVert, + "shadow_frag": shadowFrag, + "shadow_vert": shadowVert, + "sprite_frag": spriteFrag, + "sprite_vert": spriteVert +}; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/alphahash_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/alphahash_fragment.glsl.dart new file mode 100644 index 00000000..b85c9cad --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/alphahash_fragment.glsl.dart @@ -0,0 +1,7 @@ +const String alphahashFragment = /* glsl */''' +#ifdef USE_ALPHAHASH + + if ( diffuseColor.a < getAlphaHashThreshold( vPosition ) ) discard; + +#endif +'''; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/alphahash_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/alphahash_pars_fragment.glsl.dart new file mode 100644 index 00000000..5f1a85fe --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/alphahash_pars_fragment.glsl.dart @@ -0,0 +1,68 @@ +const String alphahashParsFragment = /* glsl */''' +#ifdef USE_ALPHAHASH + + /** + * See: https://casual-effects.com/research/Wyman2017Hashed/index.html + */ + + const float ALPHA_HASH_SCALE = 0.05; // Derived from trials only, and may be changed. + + float hash2D( vec2 value ) { + + return fract( 1.0e4 * sin( 17.0 * value.x + 0.1 * value.y ) * ( 0.1 + abs( sin( 13.0 * value.y + value.x ) ) ) ); + + } + + float hash3D( vec3 value ) { + + return hash2D( vec2( hash2D( value.xy ), value.z ) ); + + } + + float getAlphaHashThreshold( vec3 position ) { + + // Find the discretized derivatives of our coordinates + float maxDeriv = max( + length( dFdx( position.xyz ) ), + length( dFdy( position.xyz ) ) + ); + float pixScale = 1.0 / ( ALPHA_HASH_SCALE * maxDeriv ); + + // Find two nearest log-discretized noise scales + vec2 pixScales = vec2( + exp2( floor( log2( pixScale ) ) ), + exp2( ceil( log2( pixScale ) ) ) + ); + + // Compute alpha thresholds at our two noise scales + vec2 alpha = vec2( + hash3D( floor( pixScales.x * position.xyz ) ), + hash3D( floor( pixScales.y * position.xyz ) ) + ); + + // Factor to interpolate lerp with + float lerpFactor = fract( log2( pixScale ) ); + + // Interpolate alpha threshold from noise at two scales + float x = ( 1.0 - lerpFactor ) * alpha.x + lerpFactor * alpha.y; + + // Pass into CDF to compute uniformly distrib threshold + float a = min( lerpFactor, 1.0 - lerpFactor ); + vec3 cases = vec3( + x * x / ( 2.0 * a * ( 1.0 - a ) ), + ( x - 0.5 * a ) / ( 1.0 - a ), + 1.0 - ( ( 1.0 - x ) * ( 1.0 - x ) / ( 2.0 * a * ( 1.0 - a ) ) ) + ); + + // Find our final, uniformly distributed alpha threshold (ατ) + float threshold = ( x < ( 1.0 - a ) ) + ? ( ( x < a ) ? cases.x : cases.y ) + : cases.z; + + // Avoids ατ == 0. Could also do ατ =1-ατ + return clamp( threshold , 1.0e-6, 1.0 ); + + } + +#endif +'''; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/alphamap_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/alphamap_fragment.glsl.dart new file mode 100755 index 00000000..6a6cc166 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/alphamap_fragment.glsl.dart @@ -0,0 +1,7 @@ +const String alphamapFragment = """ +#ifdef USE_ALPHAMAP + + diffuseColor.a *= texture2D( alphaMap, vAlphaMapUv ).g; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/alphamap_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/alphamap_pars_fragment.glsl.dart new file mode 100755 index 00000000..6b1eec88 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/alphamap_pars_fragment.glsl.dart @@ -0,0 +1,7 @@ +const String alphamapParsFragment = """ +#ifdef USE_ALPHAMAP + + uniform sampler2D alphaMap; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/alphatest_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/alphatest_fragment.glsl.dart new file mode 100755 index 00000000..d517b7c6 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/alphatest_fragment.glsl.dart @@ -0,0 +1,16 @@ +const String alphatestFragment = """ +#ifdef USE_ALPHATEST + + #ifdef ALPHA_TO_COVERAGE + + diffuseColor.a = smoothstep( alphaTest, alphaTest + fwidth( diffuseColor.a ), diffuseColor.a ); + if ( diffuseColor.a == 0.0 ) discard; + + #else + + if ( diffuseColor.a < alphaTest ) discard; + + #endif + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/alphatest_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/alphatest_pars_fragment.glsl.dart new file mode 100755 index 00000000..11ff85f7 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/alphatest_pars_fragment.glsl.dart @@ -0,0 +1,5 @@ +const String alphatestParsFragment = """ +#ifdef USE_ALPHATEST + uniform float alphaTest; +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/aomap_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/aomap_fragment.glsl.dart new file mode 100755 index 00000000..0cf9aa3e --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/aomap_fragment.glsl.dart @@ -0,0 +1,26 @@ +const String aomapFragment = """ +#ifdef USE_AOMAP + + // reads channel R, compatible with a combined OcclusionRoughnessMetallic (RGB) texture + float ambientOcclusion = ( texture2D( aoMap, vAoMapUv ).r - 1.0 ) * aoMapIntensity + 1.0; + + reflectedLight.indirectDiffuse *= ambientOcclusion; + + #if defined( USE_CLEARCOAT ) + clearcoatSpecularIndirect *= ambientOcclusion; + #endif + + #if defined( USE_SHEEN ) + sheenSpecularIndirect *= ambientOcclusion; + #endif + + #if defined( USE_ENVMAP ) && defined( STANDARD ) + + float dotNV = saturate( dot( geometryNormal, geometryViewDir ) ); + + reflectedLight.indirectSpecular *= computeSpecularOcclusion( dotNV, ambientOcclusion, material.roughness ); + + #endif + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/aomap_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/aomap_pars_fragment.glsl.dart new file mode 100755 index 00000000..340b75c3 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/aomap_pars_fragment.glsl.dart @@ -0,0 +1,8 @@ +const String aomapParsFragment = """ +#ifdef USE_AOMAP + + uniform sampler2D aoMap; + uniform float aoMapIntensity; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/batching_pars_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/batching_pars_vertex.glsl.dart new file mode 100644 index 00000000..decb4f67 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/batching_pars_vertex.glsl.dart @@ -0,0 +1,19 @@ +const String batchingParsVertex = /* glsl */''' +#ifdef USE_BATCHING + attribute float batchId; + uniform highp sampler2D batchingTexture; + mat4 getBatchingMatrix( const in float i ) { + + int size = textureSize( batchingTexture, 0 ).x; + int j = int( i ) * 4; + int x = j % size; + int y = j / size; + vec4 v1 = texelFetch( batchingTexture, ivec2( x, y ), 0 ); + vec4 v2 = texelFetch( batchingTexture, ivec2( x + 1, y ), 0 ); + vec4 v3 = texelFetch( batchingTexture, ivec2( x + 2, y ), 0 ); + vec4 v4 = texelFetch( batchingTexture, ivec2( x + 3, y ), 0 ); + return mat4( v1, v2, v3, v4 ); + + } +#endif +'''; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/batching_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/batching_vertex.glsl.dart new file mode 100644 index 00000000..50ee8f95 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/batching_vertex.glsl.dart @@ -0,0 +1,5 @@ +const String batchingVertex = /* glsl */''' +#ifdef USE_BATCHING + mat4 batchingMatrix = getBatchingMatrix( batchId ); +#endif +'''; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/begin_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/begin_vertex.glsl.dart new file mode 100755 index 00000000..e3c765bb --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/begin_vertex.glsl.dart @@ -0,0 +1,9 @@ +const String beginVertex = """ +vec3 transformed = vec3( position ); + +#ifdef USE_ALPHAHASH + + vPosition = vec3( position ); + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/beginnormal_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/beginnormal_vertex.glsl.dart new file mode 100755 index 00000000..81b98e56 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/beginnormal_vertex.glsl.dart @@ -0,0 +1,9 @@ +const String beginnormalVertex = """ +vec3 objectNormal = vec3( normal ); + +#ifdef USE_TANGENT + + vec3 objectTangent = vec3( tangent.xyz ); + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/bsdfs.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/bsdfs.glsl.dart new file mode 100755 index 00000000..f6d91b4c --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/bsdfs.glsl.dart @@ -0,0 +1,31 @@ +const String bsdfs = """ +float G_BlinnPhong_Implicit( /* const in float dotNL, const in float dotNV */ ) { + + // geometry term is (n dot l)(n dot v) / 4(n dot l)(n dot v) + return 0.25; + +} + +float D_BlinnPhong( const in float shininess, const in float dotNH ) { + + return RECIPROCAL_PI * ( shininess * 0.5 + 1.0 ) * pow( dotNH, shininess ); + +} + +vec3 BRDF_BlinnPhong( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in vec3 specularColor, const in float shininess ) { + + vec3 halfDir = normalize( lightDir + viewDir ); + + float dotNH = saturate( dot( normal, halfDir ) ); + float dotVH = saturate( dot( viewDir, halfDir ) ); + + vec3 F = F_Schlick( specularColor, 1.0, dotVH ); + + float G = G_BlinnPhong_Implicit( /* dotNL, dotNV */ ); + + float D = D_BlinnPhong( shininess, dotNH ); + + return F * ( G * D ); + +} // validated +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/bumpmap_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/bumpmap_pars_fragment.glsl.dart new file mode 100755 index 00000000..94c3ea22 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/bumpmap_pars_fragment.glsl.dart @@ -0,0 +1,43 @@ +const String bumpmapParsFragment = """ +#ifdef USE_BUMPMAP + + uniform sampler2D bumpMap; + uniform float bumpScale; + + // Bump Mapping Unparametrized Surfaces on the GPU by Morten S. Mikkelsen + // https://mmikk.github.io/papers3d/mm_sfgrad_bump.pdf + + // Evaluate the derivative of the height w.r.t. screen-space using forward differencing (listing 2) + + vec2 dHdxy_fwd() { + + vec2 dSTdx = dFdx( vBumpMapUv ); + vec2 dSTdy = dFdy( vBumpMapUv ); + + float Hll = bumpScale * texture2D( bumpMap, vBumpMapUv ).x; + float dBx = bumpScale * texture2D( bumpMap, vBumpMapUv + dSTdx ).x - Hll; + float dBy = bumpScale * texture2D( bumpMap, vBumpMapUv + dSTdy ).x - Hll; + + return vec2( dBx, dBy ); + + } + + vec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy, float faceDirection ) { + + // normalize is done to ensure that the bump map looks the same regardless of the texture's scale + vec3 vSigmaX = normalize( dFdx( surf_pos.xyz ) ); + vec3 vSigmaY = normalize( dFdy( surf_pos.xyz ) ); + vec3 vN = surf_norm; // normalized + + vec3 R1 = cross( vSigmaY, vN ); + vec3 R2 = cross( vN, vSigmaX ); + + float fDet = dot( vSigmaX, R1 ) * faceDirection; + + vec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 ); + return normalize( abs( fDet ) * surf_norm - vGrad ); + + } + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/clearcoat_normal_fragment_begin.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/clearcoat_normal_fragment_begin.glsl.dart new file mode 100755 index 00000000..5811673d --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/clearcoat_normal_fragment_begin.glsl.dart @@ -0,0 +1,7 @@ +const String clearcoatNormalFragmentBegin = """ +#ifdef USE_CLEARCOAT + + vec3 clearcoatNormal = nonPerturbedNormal; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/clearcoat_normal_fragment_maps.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/clearcoat_normal_fragment_maps.glsl.dart new file mode 100755 index 00000000..0220e3a6 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/clearcoat_normal_fragment_maps.glsl.dart @@ -0,0 +1,10 @@ +const String clearcoatNormalFragmentMaps = """ +#ifdef USE_CLEARCOAT_NORMALMAP + + vec3 clearcoatMapN = texture2D( clearcoatNormalMap, vClearcoatNormalMapUv ).xyz * 2.0 - 1.0; + clearcoatMapN.xy *= clearcoatNormalScale; + + clearcoatNormal = normalize( tbn2 * clearcoatMapN ); + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/clearcoat_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/clearcoat_pars_fragment.glsl.dart new file mode 100755 index 00000000..eecaa78f --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/clearcoat_pars_fragment.glsl.dart @@ -0,0 +1,20 @@ +const String clearcoatParsFragment = """ +#ifdef USE_CLEARCOATMAP + + uniform sampler2D clearcoatMap; + +#endif + +#ifdef USE_CLEARCOAT_NORMALMAP + + uniform sampler2D clearcoatNormalMap; + uniform vec2 clearcoatNormalScale; + +#endif + +#ifdef USE_CLEARCOAT_ROUGHNESSMAP + + uniform sampler2D clearcoatRoughnessMap; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/clipping_planes_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/clipping_planes_fragment.glsl.dart new file mode 100755 index 00000000..6ca24a28 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/clipping_planes_fragment.glsl.dart @@ -0,0 +1,78 @@ +const String clippingPlanesFragment = """ +#if NUM_CLIPPING_PLANES > 0 + + vec4 plane; + + #ifdef ALPHA_TO_COVERAGE + + float distanceToPlane, distanceGradient; + float clipOpacity = 1.0; + + #pragma unroll_loop_start + for ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) { + + plane = clippingPlanes[ i ]; + distanceToPlane = - dot( vClipPosition, plane.xyz ) + plane.w; + distanceGradient = fwidth( distanceToPlane ) / 2.0; + clipOpacity *= smoothstep( - distanceGradient, distanceGradient, distanceToPlane ); + + if ( clipOpacity == 0.0 ) discard; + + } + #pragma unroll_loop_end + + #if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES + + float unionClipOpacity = 1.0; + + #pragma unroll_loop_start + for ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) { + + plane = clippingPlanes[ i ]; + distanceToPlane = - dot( vClipPosition, plane.xyz ) + plane.w; + distanceGradient = fwidth( distanceToPlane ) / 2.0; + unionClipOpacity *= 1.0 - smoothstep( - distanceGradient, distanceGradient, distanceToPlane ); + + } + #pragma unroll_loop_end + + clipOpacity *= 1.0 - unionClipOpacity; + + #endif + + diffuseColor.a *= clipOpacity; + + if ( diffuseColor.a == 0.0 ) discard; + + #else + + #pragma unroll_loop_start + for ( int i = 0; i < UNION_CLIPPING_PLANES; i ++ ) { + + plane = clippingPlanes[ i ]; + if ( dot( vClipPosition, plane.xyz ) > plane.w ) discard; + + } + #pragma unroll_loop_end + + #if UNION_CLIPPING_PLANES < NUM_CLIPPING_PLANES + + bool clipped = true; + + #pragma unroll_loop_start + for ( int i = UNION_CLIPPING_PLANES; i < NUM_CLIPPING_PLANES; i ++ ) { + + plane = clippingPlanes[ i ]; + clipped = ( dot( vClipPosition, plane.xyz ) > plane.w ) && clipped; + + } + #pragma unroll_loop_end + + if ( clipped ) discard; + + #endif + + #endif + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/clipping_planes_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/clipping_planes_pars_fragment.glsl.dart new file mode 100755 index 00000000..4126a03b --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/clipping_planes_pars_fragment.glsl.dart @@ -0,0 +1,9 @@ +const String clippingPlanesParsFragment = """ +#if NUM_CLIPPING_PLANES > 0 + + varying vec3 vClipPosition; + + uniform vec4 clippingPlanes[ NUM_CLIPPING_PLANES ]; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/clipping_planes_pars_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/clipping_planes_pars_vertex.glsl.dart new file mode 100755 index 00000000..f553229f --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/clipping_planes_pars_vertex.glsl.dart @@ -0,0 +1,7 @@ +const String clippingPlanesParsVertex = """ +#if NUM_CLIPPING_PLANES > 0 + + varying vec3 vClipPosition; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/clipping_planes_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/clipping_planes_vertex.glsl.dart new file mode 100755 index 00000000..f5dfee4e --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/clipping_planes_vertex.glsl.dart @@ -0,0 +1,7 @@ +const String clippingPlanesVertex = """ +#if NUM_CLIPPING_PLANES > 0 + + vClipPosition = - mvPosition.xyz; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/color_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/color_fragment.glsl.dart new file mode 100755 index 00000000..fc02b4ca --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/color_fragment.glsl.dart @@ -0,0 +1,11 @@ +const String colorFragment = """ +#if defined( USE_COLOR_ALPHA ) + + diffuseColor *= vColor; + +#elif defined( USE_COLOR ) + + diffuseColor.rgb *= vColor; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/color_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/color_pars_fragment.glsl.dart new file mode 100755 index 00000000..1adae8fe --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/color_pars_fragment.glsl.dart @@ -0,0 +1,11 @@ +const String colorParsFragment = """ +#if defined( USE_COLOR_ALPHA ) + + varying vec4 vColor; + +#elif defined( USE_COLOR ) + + varying vec3 vColor; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/color_pars_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/color_pars_vertex.glsl.dart new file mode 100755 index 00000000..293b94b9 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/color_pars_vertex.glsl.dart @@ -0,0 +1,11 @@ +const String colorParsVertex = """ +#if defined( USE_COLOR_ALPHA ) + + varying vec4 vColor; + +#elif defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR ) + + varying vec3 vColor; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/color_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/color_vertex.glsl.dart new file mode 100755 index 00000000..301d1827 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/color_vertex.glsl.dart @@ -0,0 +1,23 @@ +const String colorVertex = """ +#if defined( USE_COLOR_ALPHA ) + + vColor = vec4( 1.0 ); + +#elif defined( USE_COLOR ) || defined( USE_INSTANCING_COLOR ) + + vColor = vec3( 1.0 ); + +#endif + +#ifdef USE_COLOR + + vColor *= color; + +#endif + +#ifdef USE_INSTANCING_COLOR + + vColor.xyz *= instanceColor.xyz; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/colorspace_fragment.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/colorspace_fragment.dart new file mode 100644 index 00000000..3a2aee5d --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/colorspace_fragment.dart @@ -0,0 +1,3 @@ +const String colorspaceFragment = """ +gl_FragColor = linearToOutputTexel( gl_FragColor ); +"""; \ No newline at end of file diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/colorspace_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/colorspace_pars_fragment.glsl.dart new file mode 100644 index 00000000..ef115a0a --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/colorspace_pars_fragment.glsl.dart @@ -0,0 +1,43 @@ +const String colorspaceParsFragment = ''' +// http://www.russellcottrell.com/photo/matrixCalculator.htm + +// Linear sRGB => XYZ => Linear Display P3 +const mat3 LINEAR_SRGB_TO_LINEAR_DISPLAY_P3 = mat3( + vec3( 0.8224621, 0.177538, 0.0 ), + vec3( 0.0331941, 0.9668058, 0.0 ), + vec3( 0.0170827, 0.0723974, 0.9105199 ) +); + +// Linear Display P3 => XYZ => Linear sRGB +const mat3 LINEAR_DISPLAY_P3_TO_LINEAR_SRGB = mat3( + vec3( 1.2249401, - 0.2249404, 0.0 ), + vec3( - 0.0420569, 1.0420571, 0.0 ), + vec3( - 0.0196376, - 0.0786361, 1.0982735 ) +); + +vec4 LinearSRGBToLinearDisplayP3( in vec4 value ) { + return vec4( value.rgb * LINEAR_SRGB_TO_LINEAR_DISPLAY_P3, value.a ); +} + +vec4 LinearDisplayP3ToLinearSRGB( in vec4 value ) { + return vec4( value.rgb * LINEAR_DISPLAY_P3_TO_LINEAR_SRGB, value.a ); +} + +vec4 LinearTransferOETF( in vec4 value ) { + return value; +} + +vec4 sRGBTransferOETF( in vec4 value ) { + return vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a ); +} + +// @deprecated, r156 +vec4 LinearToLinear( in vec4 value ) { + return value; +} + +// @deprecated, r156 +vec4 LinearTosRGB( in vec4 value ) { + return sRGBTransferOETF( value ); +} +'''; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/common.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/common.glsl.dart new file mode 100755 index 00000000..2ae80f57 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/common.glsl.dart @@ -0,0 +1,147 @@ +const String commonGlsl = """ +#define PI 3.141592653589793 +#define PI2 6.283185307179586 +#define PI_HALF 1.5707963267948966 +#define RECIPROCAL_PI 0.3183098861837907 +#define RECIPROCAL_PI2 0.15915494309189535 +#define EPSILON 1e-6 + +#ifndef saturate +// may have defined saturate() already +#define saturate( a ) clamp( a, 0.0, 1.0 ) +#endif +#define whiteComplement( a ) ( 1.0 - saturate( a ) ) + +float pow2( const in float x ) { return x*x; } +vec3 pow2( const in vec3 x ) { return x*x; } +float pow3( const in float x ) { return x*x*x; } +float pow4( const in float x ) { float x2 = x*x; return x2*x2; } +float max3( const in vec3 v ) { return max( max( v.x, v.y ), v.z ); } +float average( const in vec3 v ) { return dot( v, vec3( 0.3333333 ) ); } + +// expects values in the range of [0,1]x[0,1], returns values in the [0,1] range. +// do not collapse into a single function per: http://byteblacksmith.com/improvements-to-the-canonical-one-liner-glsl-rand-for-opengl-es-2-0/ +highp float rand( const in vec2 uv ) { + + const highp float a = 12.9898, b = 78.233, c = 43758.5453; + highp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI ); + + return fract( sin( sn ) * c ); + +} + +#ifdef HIGH_PRECISION + float precisionSafeLength( vec3 v ) { return length( v ); } +#else + float precisionSafeLength( vec3 v ) { + float maxComponent = max3( abs( v ) ); + return length( v / maxComponent ) * maxComponent; + } +#endif + +struct IncidentLight { + vec3 color; + vec3 direction; + bool visible; +}; + +struct ReflectedLight { + vec3 directDiffuse; + vec3 directSpecular; + vec3 indirectDiffuse; + vec3 indirectSpecular; +}; + +#ifdef USE_ALPHAHASH + + varying vec3 vPosition; + +#endif + +vec3 transformDirection( in vec3 dir, in mat4 matrix ) { + + return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz ); + +} + +vec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) { + + // dir can be either a direction vector or a normal vector + // upper-left 3x3 of matrix is assumed to be orthogonal + + return normalize( ( vec4( dir, 0.0 ) * matrix ).xyz ); + +} + +mat3 transposeMat3( const in mat3 m ) { + + mat3 tmp; + + tmp[ 0 ] = vec3( m[ 0 ].x, m[ 1 ].x, m[ 2 ].x ); + tmp[ 1 ] = vec3( m[ 0 ].y, m[ 1 ].y, m[ 2 ].y ); + tmp[ 2 ] = vec3( m[ 0 ].z, m[ 1 ].z, m[ 2 ].z ); + + return tmp; + +} + +float luminance( const in vec3 rgb ) { + + // assumes rgb is in linear color space with sRGB primaries and D65 white point + + const vec3 weights = vec3( 0.2126729, 0.7151522, 0.0721750 ); + + return dot( weights, rgb ); + +} + +bool isPerspectiveMatrix( mat4 m ) { + + return m[ 2 ][ 3 ] == - 1.0; + +} + +vec2 equirectUv( in vec3 dir ) { + + // dir is assumed to be unit length + + float u = atan( dir.z, dir.x ) * RECIPROCAL_PI2 + 0.5; + + float v = asin( clamp( dir.y, - 1.0, 1.0 ) ) * RECIPROCAL_PI + 0.5; + + return vec2( u, v ); + +} + +vec3 BRDF_Lambert( const in vec3 diffuseColor ) { + + return RECIPROCAL_PI * diffuseColor; + +} // validated + +vec3 F_Schlick( const in vec3 f0, const in float f90, const in float dotVH ) { + + // Original approximation by Christophe Schlick '94 + // float fresnel = pow( 1.0 - dotVH, 5.0 ); + + // Optimized variant (presented by Epic at SIGGRAPH '13) + // https://cdn2.unrealengine.com/Resources/files/2013SiggraphPresentationsNotes-26915738.pdf + float fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH ); + + return f0 * ( 1.0 - fresnel ) + ( f90 * fresnel ); + +} // validated + +float F_Schlick( const in float f0, const in float f90, const in float dotVH ) { + + // Original approximation by Christophe Schlick '94 + // float fresnel = pow( 1.0 - dotVH, 5.0 ); + + // Optimized variant (presented by Epic at SIGGRAPH '13) + // https://cdn2.unrealengine.com/Resources/files/2013SiggraphPresentationsNotes-26915738.pdf + float fresnel = exp2( ( - 5.55473 * dotVH - 6.98316 ) * dotVH ); + + return f0 * ( 1.0 - fresnel ) + ( f90 * fresnel ); + +} // validated +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/cube_uv_reflection_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/cube_uv_reflection_fragment.glsl.dart new file mode 100755 index 00000000..a94436ba --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/cube_uv_reflection_fragment.glsl.dart @@ -0,0 +1,186 @@ +const String cubeUvReflectionFragment = """ +#ifdef ENVMAP_TYPE_CUBE_UV + + #define cubeUV_minMipLevel 4.0 + #define cubeUV_minTileSize 16.0 + + // These shader functions convert between the UV coordinates of a single face of + // a cubemap, the 0-5 integer index of a cube face, and the direction vector for + // sampling a textureCube (not generally normalized ). + + float getFace( vec3 direction ) { + + vec3 absDirection = abs( direction ); + + float face = - 1.0; + + if ( absDirection.x > absDirection.z ) { + + if ( absDirection.x > absDirection.y ) + + face = direction.x > 0.0 ? 0.0 : 3.0; + + else + + face = direction.y > 0.0 ? 1.0 : 4.0; + + } else { + + if ( absDirection.z > absDirection.y ) + + face = direction.z > 0.0 ? 2.0 : 5.0; + + else + + face = direction.y > 0.0 ? 1.0 : 4.0; + + } + + return face; + + } + + // RH coordinate system; PMREM face-indexing convention + vec2 getUV( vec3 direction, float face ) { + + vec2 uv; + + if ( face == 0.0 ) { + + uv = vec2( direction.z, direction.y ) / abs( direction.x ); // pos x + + } else if ( face == 1.0 ) { + + uv = vec2( - direction.x, - direction.z ) / abs( direction.y ); // pos y + + } else if ( face == 2.0 ) { + + uv = vec2( - direction.x, direction.y ) / abs( direction.z ); // pos z + + } else if ( face == 3.0 ) { + + uv = vec2( - direction.z, direction.y ) / abs( direction.x ); // neg x + + } else if ( face == 4.0 ) { + + uv = vec2( - direction.x, direction.z ) / abs( direction.y ); // neg y + + } else { + + uv = vec2( direction.x, direction.y ) / abs( direction.z ); // neg z + + } + + return 0.5 * ( uv + 1.0 ); + + } + + vec3 bilinearCubeUV( sampler2D envMap, vec3 direction, float mipInt ) { + + float face = getFace( direction ); + + float filterInt = max( cubeUV_minMipLevel - mipInt, 0.0 ); + + mipInt = max( mipInt, cubeUV_minMipLevel ); + + float faceSize = exp2( mipInt ); + + highp vec2 uv = getUV( direction, face ) * ( faceSize - 2.0 ) + 1.0; // #25071 + + if ( face > 2.0 ) { + + uv.y += faceSize; + + face -= 3.0; + + } + + uv.x += face * faceSize; + + uv.x += filterInt * 3.0 * cubeUV_minTileSize; + + uv.y += 4.0 * ( exp2( CUBEUV_MAX_MIP ) - faceSize ); + + uv.x *= CUBEUV_TEXEL_WIDTH; + uv.y *= CUBEUV_TEXEL_HEIGHT; + + #ifdef texture2DGradEXT + + return texture2DGradEXT( envMap, uv, vec2( 0.0 ), vec2( 0.0 ) ).rgb; // disable anisotropic filtering + + #else + + return texture2D( envMap, uv ).rgb; + + #endif + + } + + // These defines must match with PMREMGenerator + + #define cubeUV_r0 1.0 + #define cubeUV_m0 - 2.0 + #define cubeUV_r1 0.8 + #define cubeUV_m1 - 1.0 + #define cubeUV_r4 0.4 + #define cubeUV_m4 2.0 + #define cubeUV_r5 0.305 + #define cubeUV_m5 3.0 + #define cubeUV_r6 0.21 + #define cubeUV_m6 4.0 + + float roughnessToMip( float roughness ) { + + float mip = 0.0; + + if ( roughness >= cubeUV_r1 ) { + + mip = ( cubeUV_r0 - roughness ) * ( cubeUV_m1 - cubeUV_m0 ) / ( cubeUV_r0 - cubeUV_r1 ) + cubeUV_m0; + + } else if ( roughness >= cubeUV_r4 ) { + + mip = ( cubeUV_r1 - roughness ) * ( cubeUV_m4 - cubeUV_m1 ) / ( cubeUV_r1 - cubeUV_r4 ) + cubeUV_m1; + + } else if ( roughness >= cubeUV_r5 ) { + + mip = ( cubeUV_r4 - roughness ) * ( cubeUV_m5 - cubeUV_m4 ) / ( cubeUV_r4 - cubeUV_r5 ) + cubeUV_m4; + + } else if ( roughness >= cubeUV_r6 ) { + + mip = ( cubeUV_r5 - roughness ) * ( cubeUV_m6 - cubeUV_m5 ) / ( cubeUV_r5 - cubeUV_r6 ) + cubeUV_m5; + + } else { + + mip = - 2.0 * log2( 1.16 * roughness ); // 1.16 = 1.79^0.25 + } + + return mip; + + } + + vec4 textureCubeUV( sampler2D envMap, vec3 sampleDir, float roughness ) { + + float mip = clamp( roughnessToMip( roughness ), cubeUV_m0, CUBEUV_MAX_MIP ); + + float mipF = fract( mip ); + + float mipInt = floor( mip ); + + vec3 color0 = bilinearCubeUV( envMap, sampleDir, mipInt ); + + if ( mipF == 0.0 ) { + + return vec4( color0, 1.0 ); + + } else { + + vec3 color1 = bilinearCubeUV( envMap, sampleDir, mipInt + 1.0 ); + + return vec4( mix( color0, color1, mipF ), 1.0 ); + + } + + } + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/default_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/default_fragment.glsl.dart new file mode 100755 index 00000000..de0fa051 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/default_fragment.glsl.dart @@ -0,0 +1,5 @@ +const String defaultFragment = /* glsl */ """ +void main() { + gl_FragColor = vec4( 1.0, 0.0, 0.0, 1.0 ); +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/default_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/default_vertex.glsl.dart new file mode 100755 index 00000000..00d0acdd --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/default_vertex.glsl.dart @@ -0,0 +1,5 @@ +const String defaultVertex = /* glsl */ """ +void main() { + gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 ); +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/defaultnormal_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/defaultnormal_vertex.glsl.dart new file mode 100755 index 00000000..29197db6 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/defaultnormal_vertex.glsl.dart @@ -0,0 +1,62 @@ +const String defaultnormalVertex = """ +vec3 transformedNormal = objectNormal; +#ifdef USE_TANGENT + + vec3 transformedTangent = objectTangent; + +#endif + +#ifdef USE_BATCHING + + // this is in lieu of a per-instance normal-matrix + // shear transforms in the instance matrix are not supported + + mat3 bm = mat3( batchingMatrix ); + transformedNormal /= vec3( dot( bm[ 0 ], bm[ 0 ] ), dot( bm[ 1 ], bm[ 1 ] ), dot( bm[ 2 ], bm[ 2 ] ) ); + transformedNormal = bm * transformedNormal; + + #ifdef USE_TANGENT + + transformedTangent = bm * transformedTangent; + + #endif + +#endif + +#ifdef USE_INSTANCING + + // this is in lieu of a per-instance normal-matrix + // shear transforms in the instance matrix are not supported + + mat3 im = mat3( instanceMatrix ); + transformedNormal /= vec3( dot( im[ 0 ], im[ 0 ] ), dot( im[ 1 ], im[ 1 ] ), dot( im[ 2 ], im[ 2 ] ) ); + transformedNormal = im * transformedNormal; + + #ifdef USE_TANGENT + + transformedTangent = im * transformedTangent; + + #endif + +#endif + +transformedNormal = normalMatrix * transformedNormal; + +#ifdef FLIP_SIDED + + transformedNormal = - transformedNormal; + +#endif + +#ifdef USE_TANGENT + + transformedTangent = ( modelViewMatrix * vec4( transformedTangent, 0.0 ) ).xyz; + + #ifdef FLIP_SIDED + + transformedTangent = - transformedTangent; + + #endif + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/displacementmap_pars_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/displacementmap_pars_vertex.glsl.dart new file mode 100755 index 00000000..55f8bed6 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/displacementmap_pars_vertex.glsl.dart @@ -0,0 +1,9 @@ +const String displacementmapParsVertex = """ +#ifdef USE_DISPLACEMENTMAP + + uniform sampler2D displacementMap; + uniform float displacementScale; + uniform float displacementBias; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/displacementmap_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/displacementmap_vertex.glsl.dart new file mode 100755 index 00000000..db093928 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/displacementmap_vertex.glsl.dart @@ -0,0 +1,7 @@ +const String displacementmapVertex = """ +#ifdef USE_DISPLACEMENTMAP + + transformed += normalize( objectNormal ) * ( texture2D( displacementMap, vDisplacementMapUv ).x * displacementScale + displacementBias ); + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/dithering_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/dithering_fragment.glsl.dart new file mode 100755 index 00000000..6b7129de --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/dithering_fragment.glsl.dart @@ -0,0 +1,7 @@ +const String ditheringFragment = """ +#ifdef DITHERING + + gl_FragColor.rgb = dithering( gl_FragColor.rgb ); + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/dithering_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/dithering_pars_fragment.glsl.dart new file mode 100755 index 00000000..b0d2a839 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/dithering_pars_fragment.glsl.dart @@ -0,0 +1,20 @@ +const String ditheringParsFragment = """ +#ifdef DITHERING + + // based on https://www.shadertoy.com/view/MslGR8 + vec3 dithering( vec3 color ) { + //Calculate grid position + float grid_position = rand( gl_FragCoord.xy ); + + //Shift the individual colors differently, thus making it even harder to see the dithering pattern + vec3 dither_shift_RGB = vec3( 0.25 / 255.0, -0.25 / 255.0, 0.25 / 255.0 ); + + //modify shift according to grid position. + dither_shift_RGB = mix( 2.0 * dither_shift_RGB, -2.0 * dither_shift_RGB, grid_position ); + + //shift the color by dither_shift + return color + dither_shift_RGB; + } + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/emissivemap_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/emissivemap_fragment.glsl.dart new file mode 100755 index 00000000..df701d17 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/emissivemap_fragment.glsl.dart @@ -0,0 +1,9 @@ +const String emissivemapFragment = """ +#ifdef USE_EMISSIVEMAP + + vec4 emissiveColor = texture2D( emissiveMap, vEmissiveMapUv ); + + totalEmissiveRadiance *= emissiveColor.rgb; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/emissivemap_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/emissivemap_pars_fragment.glsl.dart new file mode 100755 index 00000000..895a6609 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/emissivemap_pars_fragment.glsl.dart @@ -0,0 +1,7 @@ +const String emissivemapParsFragment = """ +#ifdef USE_EMISSIVEMAP + + uniform sampler2D emissiveMap; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/encodings_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/encodings_fragment.glsl.dart new file mode 100755 index 00000000..7205b7fa --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/encodings_fragment.glsl.dart @@ -0,0 +1,3 @@ +const String encodingsFragment = """ +gl_FragColor = linearToOutputTexel( gl_FragColor ); +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/encodings_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/encodings_pars_fragment.glsl.dart new file mode 100755 index 00000000..db19bc0e --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/encodings_pars_fragment.glsl.dart @@ -0,0 +1,10 @@ +const String encodingsParsFragment = /* glsl */ """ + +vec4 LinearToLinear( in vec4 value ) { + return value; +} + +vec4 LinearTosRGB( in vec4 value ) { + return vec4( mix( pow( value.rgb, vec3( 0.41666 ) ) * 1.055 - vec3( 0.055 ), value.rgb * 12.92, vec3( lessThanEqual( value.rgb, vec3( 0.0031308 ) ) ) ), value.a ); +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/envmap_common_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/envmap_common_pars_fragment.glsl.dart new file mode 100755 index 00000000..ef1ca578 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/envmap_common_pars_fragment.glsl.dart @@ -0,0 +1,15 @@ +const String envmapCommonParsFragment = """ +#ifdef USE_ENVMAP + + uniform float envMapIntensity; + uniform float flipEnvMap; + uniform mat3 envMapRotation; + + #ifdef ENVMAP_TYPE_CUBE + uniform samplerCube envMap; + #else + uniform sampler2D envMap; + #endif + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/envmap_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/envmap_fragment.glsl.dart new file mode 100755 index 00000000..b844a6e2 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/envmap_fragment.glsl.dart @@ -0,0 +1,62 @@ +const String envmapFragment = """ +#ifdef USE_ENVMAP + + #ifdef ENV_WORLDPOS + + vec3 cameraToFrag; + + if ( isOrthographic ) { + + cameraToFrag = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) ); + + } else { + + cameraToFrag = normalize( vWorldPosition - cameraPosition ); + + } + + // Transforming Normal Vectors with the Inverse Transformation + vec3 worldNormal = inverseTransformDirection( normal, viewMatrix ); + + #ifdef ENVMAP_MODE_REFLECTION + + vec3 reflectVec = reflect( cameraToFrag, worldNormal ); + + #else + + vec3 reflectVec = refract( cameraToFrag, worldNormal, refractionRatio ); + + #endif + + #else + + vec3 reflectVec = vReflect; + + #endif + + #ifdef ENVMAP_TYPE_CUBE + + vec4 envColor = textureCube( envMap, envMapRotation * vec3( flipEnvMap * reflectVec.x, reflectVec.yz ) ); + + #else + + vec4 envColor = vec4( 0.0 ); + + #endif + + #ifdef ENVMAP_BLENDING_MULTIPLY + + outgoingLight = mix( outgoingLight, outgoingLight * envColor.xyz, specularStrength * reflectivity ); + + #elif defined( ENVMAP_BLENDING_MIX ) + + outgoingLight = mix( outgoingLight, envColor.xyz, specularStrength * reflectivity ); + + #elif defined( ENVMAP_BLENDING_ADD ) + + outgoingLight += envColor.xyz * specularStrength * reflectivity; + + #endif + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/envmap_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/envmap_pars_fragment.glsl.dart new file mode 100755 index 00000000..d8957be9 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/envmap_pars_fragment.glsl.dart @@ -0,0 +1,21 @@ +const String envmapParsFragment = """ +#ifdef USE_ENVMAP + + uniform float reflectivity; + + #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( LAMBERT ) + + #define ENV_WORLDPOS + + #endif + + #ifdef ENV_WORLDPOS + + varying vec3 vWorldPosition; + uniform float refractionRatio; + #else + varying vec3 vReflect; + #endif + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/envmap_pars_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/envmap_pars_vertex.glsl.dart new file mode 100755 index 00000000..1649a91d --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/envmap_pars_vertex.glsl.dart @@ -0,0 +1,22 @@ +const String envmapParsVertex = """ +#ifdef USE_ENVMAP + + #if defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( PHONG ) || defined( LAMBERT ) + + #define ENV_WORLDPOS + + #endif + + #ifdef ENV_WORLDPOS + + varying vec3 vWorldPosition; + + #else + + varying vec3 vReflect; + uniform float refractionRatio; + + #endif + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/envmap_physical_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/envmap_physical_pars_fragment.glsl.dart new file mode 100755 index 00000000..fe8af53a --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/envmap_physical_pars_fragment.glsl.dart @@ -0,0 +1,69 @@ +const String envmapPhysicalParsFragment = """ +#ifdef USE_ENVMAP + + vec3 getIBLIrradiance( const in vec3 normal ) { + + #ifdef ENVMAP_TYPE_CUBE_UV + + vec3 worldNormal = inverseTransformDirection( normal, viewMatrix ); + + vec4 envMapColor = textureCubeUV( envMap, envMapRotation * worldNormal, 1.0 ); + + return PI * envMapColor.rgb * envMapIntensity; + + #else + + return vec3( 0.0 ); + + #endif + + } + + vec3 getIBLRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness ) { + + #ifdef ENVMAP_TYPE_CUBE_UV + + vec3 reflectVec = reflect( - viewDir, normal ); + + // Mixing the reflection with the normal is more accurate and keeps rough objects from gathering light from behind their tangent plane. + reflectVec = normalize( mix( reflectVec, normal, roughness * roughness) ); + + reflectVec = inverseTransformDirection( reflectVec, viewMatrix ); + + vec4 envMapColor = textureCubeUV( envMap, envMapRotation * reflectVec, roughness ); + + return envMapColor.rgb * envMapIntensity; + + #else + + return vec3( 0.0 ); + + #endif + + } + + #ifdef USE_ANISOTROPY + + vec3 getIBLAnisotropyRadiance( const in vec3 viewDir, const in vec3 normal, const in float roughness, const in vec3 bitangent, const in float anisotropy ) { + + #ifdef ENVMAP_TYPE_CUBE_UV + + // https://google.github.io/filament/Filament.md.html#lighting/imagebasedlights/anisotropy + vec3 bentNormal = cross( bitangent, viewDir ); + bentNormal = normalize( cross( bentNormal, bitangent ) ); + bentNormal = normalize( mix( bentNormal, normal, pow2( pow2( 1.0 - anisotropy * ( 1.0 - roughness ) ) ) ) ); + + return getIBLRadiance( viewDir, bentNormal, roughness ); + + #else + + return vec3( 0.0 ); + + #endif + + } + + #endif + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/envmap_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/envmap_vertex.glsl.dart new file mode 100755 index 00000000..071b32e0 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/envmap_vertex.glsl.dart @@ -0,0 +1,37 @@ +const String envmapVertex = """ +#ifdef USE_ENVMAP + + #ifdef ENV_WORLDPOS + + vWorldPosition = worldPosition.xyz; + + #else + + vec3 cameraToVertex; + + if ( isOrthographic ) { + + cameraToVertex = normalize( vec3( - viewMatrix[ 0 ][ 2 ], - viewMatrix[ 1 ][ 2 ], - viewMatrix[ 2 ][ 2 ] ) ); + + } else { + + cameraToVertex = normalize( worldPosition.xyz - cameraPosition ); + + } + + vec3 worldNormal = inverseTransformDirection( transformedNormal, viewMatrix ); + + #ifdef ENVMAP_MODE_REFLECTION + + vReflect = reflect( cameraToVertex, worldNormal ); + + #else + + vReflect = refract( cameraToVertex, worldNormal, refractionRatio ); + + #endif + + #endif + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/fog_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/fog_fragment.glsl.dart new file mode 100755 index 00000000..92b91170 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/fog_fragment.glsl.dart @@ -0,0 +1,17 @@ +const String fogFragment = """ +#ifdef USE_FOG + + #ifdef FOG_EXP2 + + float fogFactor = 1.0 - exp( - fogDensity * fogDensity * vFogDepth * vFogDepth ); + + #else + + float fogFactor = smoothstep( fogNear, fogFar, vFogDepth ); + + #endif + + gl_FragColor.rgb = mix( gl_FragColor.rgb, fogColor, fogFactor ); + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/fog_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/fog_pars_fragment.glsl.dart new file mode 100755 index 00000000..f3808efe --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/fog_pars_fragment.glsl.dart @@ -0,0 +1,19 @@ +const String fogParsFragment = """ +#ifdef USE_FOG + + uniform vec3 fogColor; + varying float vFogDepth; + + #ifdef FOG_EXP2 + + uniform float fogDensity; + + #else + + uniform float fogNear; + uniform float fogFar; + + #endif + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/fog_pars_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/fog_pars_vertex.glsl.dart new file mode 100755 index 00000000..df7ea656 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/fog_pars_vertex.glsl.dart @@ -0,0 +1,7 @@ +const String fogParsVertex = """ +#ifdef USE_FOG + + varying float vFogDepth; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/fog_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/fog_vertex.glsl.dart new file mode 100755 index 00000000..dc9ddba7 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/fog_vertex.glsl.dart @@ -0,0 +1,7 @@ +const String fogVertex = """ +#ifdef USE_FOG + + vFogDepth = - mvPosition.z; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/gradientmap_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/gradientmap_pars_fragment.glsl.dart new file mode 100755 index 00000000..1d8064c9 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/gradientmap_pars_fragment.glsl.dart @@ -0,0 +1,27 @@ +const String gradientmapParsFragment = """ + +#ifdef USE_GRADIENTMAP + + uniform sampler2D gradientMap; + +#endif + +vec3 getGradientIrradiance( vec3 normal, vec3 lightDirection ) { + + // dotNL will be from -1.0 to 1.0 + float dotNL = dot( normal, lightDirection ); + vec2 coord = vec2( dotNL * 0.5 + 0.5, 0.0 ); + + #ifdef USE_GRADIENTMAP + + return vec3( texture2D( gradientMap, coord ).r ); + + #else + + vec2 fw = fwidth( coord ) * 0.5; + return mix( vec3( 0.7 ), vec3( 1.0 ), smoothstep( 0.7 - fw.x, 0.7 + fw.x, coord.x ) ); + + #endif + +} +"""; diff --git a/packages/three_js_core/lib/renderers/shaders/shader_chunk/index.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/index.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_chunk/index.dart rename to packages/three_js_webgl_renderer/lib/shaders/shader_chunk/index.dart diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/iridescence_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/iridescence_fragment.glsl.dart new file mode 100644 index 00000000..bbe117ff --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/iridescence_fragment.glsl.dart @@ -0,0 +1,119 @@ +const String iridescenceFragment = /* glsl */'''\ +#ifdef USE_IRIDESCENCE + + // XYZ to linear-sRGB color space + const mat3 XYZ_TO_REC709 = mat3( + 3.2404542, -0.9692660, 0.0556434, + -1.5371385, 1.8760108, -0.2040259, + -0.4985314, 0.0415560, 1.0572252 + ); + + // Assume air interface for top + // Note: We don't handle the case fresnel0 == 1 + vec3 Fresnel0ToIor( vec3 fresnel0 ) { + + vec3 sqrtF0 = sqrt( fresnel0 ); + return ( vec3( 1.0 ) + sqrtF0 ) / ( vec3( 1.0 ) - sqrtF0 ); + + } + + // Conversion FO/IOR + vec3 IorToFresnel0( vec3 transmittedIor, float incidentIor ) { + + return pow2( ( transmittedIor - vec3( incidentIor ) ) / ( transmittedIor + vec3( incidentIor ) ) ); + + } + + // ior is a value between 1.0 and 3.0. 1.0 is air interface + float IorToFresnel0( float transmittedIor, float incidentIor ) { + + return pow2( ( transmittedIor - incidentIor ) / ( transmittedIor + incidentIor )); + + } + + // Fresnel equations for dielectric/dielectric interfaces. + // Ref: https://belcour.github.io/blog/research/2017/05/01/brdf-thin-film.html + // Evaluation XYZ sensitivity curves in Fourier space + vec3 evalSensitivity( float OPD, vec3 shift ) { + + float phase = 2.0 * PI * OPD * 1.0e-9; + vec3 val = vec3( 5.4856e-13, 4.4201e-13, 5.2481e-13 ); + vec3 pos = vec3( 1.6810e+06, 1.7953e+06, 2.2084e+06 ); + vec3 var = vec3( 4.3278e+09, 9.3046e+09, 6.6121e+09 ); + + vec3 xyz = val * sqrt( 2.0 * PI * var ) * cos( pos * phase + shift ) * exp( - pow2( phase ) * var ); + 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 ) ); + xyz /= 1.0685e-7; + + vec3 rgb = XYZ_TO_REC709 * xyz; + return rgb; + + } + + vec3 evalIridescence( float outsideIOR, float eta2, float cosTheta1, float thinFilmThickness, vec3 baseF0 ) { + + vec3 I; + + // Force iridescenceIOR -> outsideIOR when thinFilmThickness -> 0.0 + float iridescenceIOR = mix( outsideIOR, eta2, smoothstep( 0.0, 0.03, thinFilmThickness ) ); + // Evaluate the cosTheta on the base layer (Snell law) + float sinTheta2Sq = pow2( outsideIOR / iridescenceIOR ) * ( 1.0 - pow2( cosTheta1 ) ); + + // Handle TIR: + float cosTheta2Sq = 1.0 - sinTheta2Sq; + if ( cosTheta2Sq < 0.0 ) { + + return vec3( 1.0 ); + + } + + float cosTheta2 = sqrt( cosTheta2Sq ); + + // First interface + float R0 = IorToFresnel0( iridescenceIOR, outsideIOR ); + float R12 = F_Schlick( R0, 1.0, cosTheta1 ); + float T121 = 1.0 - R12; + float phi12 = 0.0; + if ( iridescenceIOR < outsideIOR ) phi12 = PI; + float phi21 = PI - phi12; + + // Second interface + vec3 baseIOR = Fresnel0ToIor( clamp( baseF0, 0.0, 0.9999 ) ); // guard against 1.0 + vec3 R1 = IorToFresnel0( baseIOR, iridescenceIOR ); + vec3 R23 = F_Schlick( R1, 1.0, cosTheta2 ); + vec3 phi23 = vec3( 0.0 ); + if ( baseIOR[ 0 ] < iridescenceIOR ) phi23[ 0 ] = PI; + if ( baseIOR[ 1 ] < iridescenceIOR ) phi23[ 1 ] = PI; + if ( baseIOR[ 2 ] < iridescenceIOR ) phi23[ 2 ] = PI; + + // Phase shift + float OPD = 2.0 * iridescenceIOR * thinFilmThickness * cosTheta2; + vec3 phi = vec3( phi21 ) + phi23; + + // Compound terms + vec3 R123 = clamp( R12 * R23, 1e-5, 0.9999 ); + vec3 r123 = sqrt( R123 ); + vec3 Rs = pow2( T121 ) * R23 / ( vec3( 1.0 ) - R123 ); + + // Reflectance term for m = 0 (DC term amplitude) + vec3 C0 = R12 + Rs; + I = C0; + + // Reflectance term for m > 0 (pairs of diracs) + vec3 Cm = Rs - T121; + for ( int m = 1; m <= 2; ++ m ) { + + Cm *= r123; + vec3 Sm = 2.0 * evalSensitivity( float( m ) * OPD, float( m ) * phi ); + I += Cm * Sm; + + } + + // Since out of gamut colors might be produced, negative color values are clamped to 0. + return max( I, vec3( 0.0 ) ); + + } + +#endif + +'''; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/iridescence_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/iridescence_pars_fragment.glsl.dart new file mode 100644 index 00000000..6d15bf20 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/iridescence_pars_fragment.glsl.dart @@ -0,0 +1,13 @@ +const String iridescenceParsFragment = /* glsl */''' +#ifdef USE_IRIDESCENCEMAP + + uniform sampler2D iridescenceMap; + +#endif + +#ifdef USE_IRIDESCENCE_THICKNESSMAP + + uniform sampler2D iridescenceThicknessMap; + +#endif +'''; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lightmap_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lightmap_fragment.glsl.dart new file mode 100755 index 00000000..5ca088f3 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lightmap_fragment.glsl.dart @@ -0,0 +1,10 @@ +const String lightmapFragment = """ +#ifdef USE_LIGHTMAP + + vec4 lightMapTexel = texture2D( lightMap, vUv2 ); + vec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity; + + reflectedLight.indirectDiffuse += lightMapIrradiance; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lightmap_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lightmap_pars_fragment.glsl.dart new file mode 100755 index 00000000..d79072c3 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lightmap_pars_fragment.glsl.dart @@ -0,0 +1,8 @@ +const String lightmapParsFragment = """ +#ifdef USE_LIGHTMAP + + uniform sampler2D lightMap; + uniform float lightMapIntensity; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_fragment_begin.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_fragment_begin.glsl.dart new file mode 100755 index 00000000..a57085a9 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_fragment_begin.glsl.dart @@ -0,0 +1,202 @@ +String lightsFragmentBegin = """ +/** + * This is a template that can be used to light a material, it uses pluggable + * RenderEquations (RE)for specific lighting scenarios. + * + * Instructions for use: + * - Ensure that both RE_Direct, RE_IndirectDiffuse and RE_IndirectSpecular are defined + * - Create a material parameter that is to be passed as the third parameter to your lighting functions. + * + * TODO: + * - Add area light support. + * - Add sphere light support. + * - Add diffuse light probe (irradiance cubemap) support. + */ + +vec3 geometryPosition = - vViewPosition; +vec3 geometryNormal = normal; +vec3 geometryViewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( vViewPosition ); + +vec3 geometryClearcoatNormal = vec3( 0.0 ); + +#ifdef USE_CLEARCOAT + + geometryClearcoatNormal = clearcoatNormal; + +#endif + +#ifdef USE_IRIDESCENCE + + float dotNVi = saturate( dot( normal, geometryViewDir ) ); + + if ( material.iridescenceThickness == 0.0 ) { + + material.iridescence = 0.0; + + } else { + + material.iridescence = saturate( material.iridescence ); + + } + + if ( material.iridescence > 0.0 ) { + + material.iridescenceFresnel = evalIridescence( 1.0, material.iridescenceIOR, dotNVi, material.iridescenceThickness, material.specularColor ); + + // Iridescence F0 approximation + material.iridescenceF0 = Schlick_to_F0( material.iridescenceFresnel, 1.0, dotNVi ); + + } + +#endif + +IncidentLight directLight; + +#if ( NUM_POINT_LIGHTS > 0 ) && defined( RE_Direct ) + + PointLight pointLight; + #if defined( USE_SHADOWMAP ) && NUM_POINT_LIGHT_SHADOWS > 0 + PointLightShadow pointLightShadow; + #endif + + #pragma unroll_loop_start + for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) { + + pointLight = pointLights[ i ]; + + getPointLightInfo( pointLight, geometryPosition, directLight ); + + #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_POINT_LIGHT_SHADOWS ) + pointLightShadow = pointLightShadows[ i ]; + directLight.color *= ( directLight.visible && receiveShadow ) ? getPointShadow( pointShadowMap[ i ], pointLightShadow.shadowMapSize, pointLightShadow.shadowBias, pointLightShadow.shadowRadius, vPointShadowCoord[ i ], pointLightShadow.shadowCameraNear, pointLightShadow.shadowCameraFar ) : 1.0; + #endif + + RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight ); + + } + #pragma unroll_loop_end + +#endif + +#if ( NUM_SPOT_LIGHTS > 0 ) && defined( RE_Direct ) + + SpotLight spotLight; + vec4 spotColor; + vec3 spotLightCoord; + bool inSpotLightMap; + + #if defined( USE_SHADOWMAP ) && NUM_SPOT_LIGHT_SHADOWS > 0 + SpotLightShadow spotLightShadow; + #endif + + #pragma unroll_loop_start + for ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) { + + spotLight = spotLights[ i ]; + + getSpotLightInfo( spotLight, geometryPosition, directLight ); + + // spot lights are ordered [shadows with maps, shadows without maps, maps without shadows, none] + #if ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS ) + #define SPOT_LIGHT_MAP_INDEX UNROLLED_LOOP_INDEX + #elif ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS ) + #define SPOT_LIGHT_MAP_INDEX NUM_SPOT_LIGHT_MAPS + #else + #define SPOT_LIGHT_MAP_INDEX ( UNROLLED_LOOP_INDEX - NUM_SPOT_LIGHT_SHADOWS + NUM_SPOT_LIGHT_SHADOWS_WITH_MAPS ) + #endif + + #if ( SPOT_LIGHT_MAP_INDEX < NUM_SPOT_LIGHT_MAPS ) + spotLightCoord = vSpotLightCoord[ i ].xyz / vSpotLightCoord[ i ].w; + inSpotLightMap = all( lessThan( abs( spotLightCoord * 2. - 1. ), vec3( 1.0 ) ) ); + spotColor = texture2D( spotLightMap[ SPOT_LIGHT_MAP_INDEX ], spotLightCoord.xy ); + directLight.color = inSpotLightMap ? directLight.color * spotColor.rgb : directLight.color; + #endif + + #undef SPOT_LIGHT_MAP_INDEX + + #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS ) + spotLightShadow = spotLightShadows[ i ]; + directLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( spotShadowMap[ i ], spotLightShadow.shadowMapSize, spotLightShadow.shadowBias, spotLightShadow.shadowRadius, vSpotLightCoord[ i ] ) : 1.0; + #endif + + RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight ); + + } + #pragma unroll_loop_end + +#endif + +#if ( NUM_DIR_LIGHTS > 0 ) && defined( RE_Direct ) + + DirectionalLight directionalLight; + #if defined( USE_SHADOWMAP ) && NUM_DIR_LIGHT_SHADOWS > 0 + DirectionalLightShadow directionalLightShadow; + #endif + + #pragma unroll_loop_start + for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) { + + directionalLight = directionalLights[ i ]; + + getDirectionalLightInfo( directionalLight, directLight ); + + #if defined( USE_SHADOWMAP ) && ( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS ) + directionalLightShadow = directionalLightShadows[ i ]; + directLight.color *= ( directLight.visible && receiveShadow ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0; + #endif + + RE_Direct( directLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight ); + + } + #pragma unroll_loop_end + +#endif + +#if ( NUM_RECT_AREA_LIGHTS > 0 ) && defined( RE_Direct_RectArea ) + + RectAreaLight rectAreaLight; + + #pragma unroll_loop_start + for ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) { + + rectAreaLight = rectAreaLights[ i ]; + RE_Direct_RectArea( rectAreaLight, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight ); + + } + #pragma unroll_loop_end + +#endif + +#if defined( RE_IndirectDiffuse ) + + vec3 iblIrradiance = vec3( 0.0 ); + + vec3 irradiance = getAmbientLightIrradiance( ambientLightColor ); + + #if defined( USE_LIGHT_PROBES ) + + irradiance += getLightProbeIrradiance( lightProbe, geometryNormal ); + + #endif + + #if ( NUM_HEMI_LIGHTS > 0 ) + + #pragma unroll_loop_start + for ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) { + + irradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometryNormal ); + + } + #pragma unroll_loop_end + + #endif + +#endif + +#if defined( RE_IndirectSpecular ) + + vec3 radiance = vec3( 0.0 ); + vec3 clearcoatRadiance = vec3( 0.0 ); + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_fragment_end.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_fragment_end.glsl.dart new file mode 100755 index 00000000..ccbff3ae --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_fragment_end.glsl.dart @@ -0,0 +1,13 @@ +const String lightsFragmentEnd = """ +#if defined( RE_IndirectDiffuse ) + + RE_IndirectDiffuse( irradiance, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight ); + +#endif + +#if defined( RE_IndirectSpecular ) + + RE_IndirectSpecular( radiance, iblIrradiance, clearcoatRadiance, geometryPosition, geometryNormal, geometryViewDir, geometryClearcoatNormal, material, reflectedLight ); + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_fragment_maps.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_fragment_maps.glsl.dart new file mode 100755 index 00000000..7189a1c7 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_fragment_maps.glsl.dart @@ -0,0 +1,40 @@ +const String lightsFragmentMaps = """ +#if defined( RE_IndirectDiffuse ) + + #ifdef USE_LIGHTMAP + + vec4 lightMapTexel = texture2D( lightMap, vLightMapUv ); + vec3 lightMapIrradiance = lightMapTexel.rgb * lightMapIntensity; + + irradiance += lightMapIrradiance; + + #endif + + #if defined( USE_ENVMAP ) && defined( STANDARD ) && defined( ENVMAP_TYPE_CUBE_UV ) + + iblIrradiance += getIBLIrradiance( geometryNormal ); + + #endif + +#endif + +#if defined( USE_ENVMAP ) && defined( RE_IndirectSpecular ) + + #ifdef USE_ANISOTROPY + + radiance += getIBLAnisotropyRadiance( geometryViewDir, geometryNormal, material.roughness, material.anisotropyB, material.anisotropy ); + + #else + + radiance += getIBLRadiance( geometryViewDir, geometryNormal, material.roughness ); + + #endif + + #ifdef USE_CLEARCOAT + + clearcoatRadiance += getIBLRadiance( geometryViewDir, geometryClearcoatNormal, material.clearcoatRoughness ); + + #endif + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_lambert_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_lambert_fragment.glsl.dart new file mode 100644 index 00000000..5e193c52 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_lambert_fragment.glsl.dart @@ -0,0 +1,5 @@ +const String lightsLambertFragment = /* glsl */''' +LambertMaterial material; +material.diffuseColor = diffuseColor.rgb; +material.specularStrength = specularStrength; +'''; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_lambert_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_lambert_pars_fragment.glsl.dart new file mode 100644 index 00000000..65baa219 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_lambert_pars_fragment.glsl.dart @@ -0,0 +1,28 @@ +const String lightsLambertParsFragment = /* glsl */''' +varying vec3 vViewPosition; + +struct LambertMaterial { + + vec3 diffuseColor; + float specularStrength; + +}; + +void RE_Direct_Lambert( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in LambertMaterial material, inout ReflectedLight reflectedLight ) { + + float dotNL = saturate( dot( geometryNormal, directLight.direction ) ); + vec3 irradiance = dotNL * directLight.color; + + reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor ); + +} + +void RE_IndirectDiffuse_Lambert( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in LambertMaterial material, inout ReflectedLight reflectedLight ) { + + reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor ); + +} + +#define RE_Direct RE_Direct_Lambert +#define RE_IndirectDiffuse RE_IndirectDiffuse_Lambert +'''; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_lambert_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_lambert_vertex.glsl.dart new file mode 100755 index 00000000..419a9dde --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_lambert_vertex.glsl.dart @@ -0,0 +1,125 @@ +const String lightsLambertVertex = """ +vec3 diffuse = vec3( 1.0 ); + +GeometricContext geometry; +geometry.position = mvPosition.xyz; +geometry.normal = normalize( transformedNormal ); +geometry.viewDir = ( isOrthographic ) ? vec3( 0, 0, 1 ) : normalize( -mvPosition.xyz ); + +GeometricContext backGeometry; +backGeometry.position = geometry.position; +backGeometry.normal = -geometry.normal; +backGeometry.viewDir = geometry.viewDir; + +vLightFront = vec3( 0.0 ); +vIndirectFront = vec3( 0.0 ); +#ifdef DOUBLE_SIDED + vLightBack = vec3( 0.0 ); + vIndirectBack = vec3( 0.0 ); +#endif + +IncidentLight directLight; +float dotNL; +vec3 directLightColor_Diffuse; + +vIndirectFront += getAmbientLightIrradiance( ambientLightColor ); + +#if defined( USE_LIGHT_PROBES ) + vIndirectFront += getLightProbeIrradiance( lightProbe, geometry.normal ); +#endif + +#ifdef DOUBLE_SIDED + + vIndirectBack += getAmbientLightIrradiance( ambientLightColor ); + + #if defined( USE_LIGHT_PROBES ) + vIndirectBack += getLightProbeIrradiance( lightProbe, backGeometry.normal ); + #endif +#endif + +#if NUM_POINT_LIGHTS > 0 + + #pragma unroll_loop_start + for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) { + + getPointLightInfo( pointLights[ i ], geometry, directLight ); + + dotNL = dot( geometry.normal, directLight.direction ); + directLightColor_Diffuse = directLight.color; + + vLightFront += saturate( dotNL ) * directLightColor_Diffuse; + + #ifdef DOUBLE_SIDED + + vLightBack += saturate( - dotNL ) * directLightColor_Diffuse; + + #endif + + } + #pragma unroll_loop_end + +#endif + +#if NUM_SPOT_LIGHTS > 0 + + #pragma unroll_loop_start + for ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) { + + getSpotLightInfo( spotLights[ i ], geometry, directLight ); + + dotNL = dot( geometry.normal, directLight.direction ); + directLightColor_Diffuse = directLight.color; + + vLightFront += saturate( dotNL ) * directLightColor_Diffuse; + + #ifdef DOUBLE_SIDED + + vLightBack += saturate( - dotNL ) * directLightColor_Diffuse; + + #endif + } + #pragma unroll_loop_end + +#endif + +#if NUM_DIR_LIGHTS > 0 + + #pragma unroll_loop_start + for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) { + + getDirectionalLightInfo( directionalLights[ i ], geometry, directLight ); + + dotNL = dot( geometry.normal, directLight.direction ); + directLightColor_Diffuse = directLight.color; + + vLightFront += saturate( dotNL ) * directLightColor_Diffuse; + + #ifdef DOUBLE_SIDED + + vLightBack += saturate( - dotNL ) * directLightColor_Diffuse; + + #endif + + } + #pragma unroll_loop_end + +#endif + +#if NUM_HEMI_LIGHTS > 0 + + #pragma unroll_loop_start + for ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) { + + vIndirectFront += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry.normal ); + + #ifdef DOUBLE_SIDED + + vIndirectBack += getHemisphereLightIrradiance( hemisphereLights[ i ], backGeometry.normal ); + + #endif + + } + #pragma unroll_loop_end + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_pars_begin.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_pars_begin.glsl.dart new file mode 100755 index 00000000..f4887867 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_pars_begin.glsl.dart @@ -0,0 +1,228 @@ +String lightsParsBegin = """ +uniform bool receiveShadow; +uniform vec3 ambientLightColor; + +#if defined( USE_LIGHT_PROBES ) + + uniform vec3 lightProbe[ 9 ]; + +#endif + +// get the irradiance (radiance convolved with cosine lobe) at the point 'normal' on the unit sphere +// source: https://graphics.stanford.edu/papers/envmap/envmap.pdf +vec3 shGetIrradianceAt( in vec3 normal, in vec3 shCoefficients[ 9 ] ) { + + // normal is assumed to have unit length + + float x = normal.x, y = normal.y, z = normal.z; + + // band 0 + vec3 result = shCoefficients[ 0 ] * 0.886227; + + // band 1 + result += shCoefficients[ 1 ] * 2.0 * 0.511664 * y; + result += shCoefficients[ 2 ] * 2.0 * 0.511664 * z; + result += shCoefficients[ 3 ] * 2.0 * 0.511664 * x; + + // band 2 + result += shCoefficients[ 4 ] * 2.0 * 0.429043 * x * y; + result += shCoefficients[ 5 ] * 2.0 * 0.429043 * y * z; + result += shCoefficients[ 6 ] * ( 0.743125 * z * z - 0.247708 ); + result += shCoefficients[ 7 ] * 2.0 * 0.429043 * x * z; + result += shCoefficients[ 8 ] * 0.429043 * ( x * x - y * y ); + + return result; + +} + +vec3 getLightProbeIrradiance( const in vec3 lightProbe[ 9 ], const in vec3 normal ) { + + vec3 worldNormal = inverseTransformDirection( normal, viewMatrix ); + + vec3 irradiance = shGetIrradianceAt( worldNormal, lightProbe ); + + return irradiance; + +} + +vec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) { + + vec3 irradiance = ambientLightColor; + + return irradiance; + +} + +float getDistanceAttenuation( const in float lightDistance, const in float cutoffDistance, const in float decayExponent ) { + + #if defined ( LEGACY_LIGHTS ) + + if ( cutoffDistance > 0.0 && decayExponent > 0.0 ) { + + return pow( saturate( - lightDistance / cutoffDistance + 1.0 ), decayExponent ); + + } + + return 1.0; + + #else + + // based upon Frostbite 3 Moving to Physically-based Rendering + // page 32, equation 26: E[window1] + // https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf + float distanceFalloff = 1.0 / max( pow( lightDistance, decayExponent ), 0.01 ); + + if ( cutoffDistance > 0.0 ) { + + distanceFalloff *= pow2( saturate( 1.0 - pow4( lightDistance / cutoffDistance ) ) ); + + } + + return distanceFalloff; + + #endif + +} + +float getSpotAttenuation( const in float coneCosine, const in float penumbraCosine, const in float angleCosine ) { + + return smoothstep( coneCosine, penumbraCosine, angleCosine ); + +} + +#if NUM_DIR_LIGHTS > 0 + + struct DirectionalLight { + vec3 direction; + vec3 color; + }; + + uniform DirectionalLight directionalLights[ NUM_DIR_LIGHTS ]; + + void getDirectionalLightInfo( const in DirectionalLight directionalLight, out IncidentLight light ) { + + light.color = directionalLight.color; + light.direction = directionalLight.direction; + light.visible = true; + + } + +#endif + + +#if NUM_POINT_LIGHTS > 0 + + struct PointLight { + vec3 position; + vec3 color; + float distance; + float decay; + }; + + uniform PointLight pointLights[ NUM_POINT_LIGHTS ]; + + // light is an out parameter as having it as a return value caused compiler errors on some devices + void getPointLightInfo( const in PointLight pointLight, const in vec3 geometryPosition, out IncidentLight light ) { + + vec3 lVector = pointLight.position - geometryPosition; + + light.direction = normalize( lVector ); + + float lightDistance = length( lVector ); + + light.color = pointLight.color; + light.color *= getDistanceAttenuation( lightDistance, pointLight.distance, pointLight.decay ); + light.visible = ( light.color != vec3( 0.0 ) ); + + } + +#endif + + +#if NUM_SPOT_LIGHTS > 0 + + struct SpotLight { + vec3 position; + vec3 direction; + vec3 color; + float distance; + float decay; + float coneCos; + float penumbraCos; + }; + + uniform SpotLight spotLights[ NUM_SPOT_LIGHTS ]; + + // light is an out parameter as having it as a return value caused compiler errors on some devices + void getSpotLightInfo( const in SpotLight spotLight, const in vec3 geometryPosition, out IncidentLight light ) { + + vec3 lVector = spotLight.position - geometryPosition; + + light.direction = normalize( lVector ); + + float angleCos = dot( light.direction, spotLight.direction ); + + float spotAttenuation = getSpotAttenuation( spotLight.coneCos, spotLight.penumbraCos, angleCos ); + + if ( spotAttenuation > 0.0 ) { + + float lightDistance = length( lVector ); + + light.color = spotLight.color * spotAttenuation; + light.color *= getDistanceAttenuation( lightDistance, spotLight.distance, spotLight.decay ); + light.visible = ( light.color != vec3( 0.0 ) ); + + } else { + + light.color = vec3( 0.0 ); + light.visible = false; + + } + + } + +#endif + + +#if NUM_RECT_AREA_LIGHTS > 0 + + struct RectAreaLight { + vec3 color; + vec3 position; + vec3 halfWidth; + vec3 halfHeight; + }; + + // Pre-computed values of LinearTransformedCosine approximation of BRDF + // BRDF approximation Texture is 64x64 + uniform sampler2D ltc_1; // RGBA Float + uniform sampler2D ltc_2; // RGBA Float + + uniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ]; + +#endif + + +#if NUM_HEMI_LIGHTS > 0 + + struct HemisphereLight { + vec3 direction; + vec3 skyColor; + vec3 groundColor; + }; + + uniform HemisphereLight hemisphereLights[ NUM_HEMI_LIGHTS ]; + + vec3 getHemisphereLightIrradiance( const in HemisphereLight hemiLight, const in vec3 normal ) { + + float dotNL = dot( normal, hemiLight.direction ); + float hemiDiffuseWeight = 0.5 * dotNL + 0.5; + + vec3 irradiance = mix( hemiLight.groundColor, hemiLight.skyColor, hemiDiffuseWeight ); + + return irradiance; + + } + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_phong_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_phong_fragment.glsl.dart new file mode 100755 index 00000000..90fb6df5 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_phong_fragment.glsl.dart @@ -0,0 +1,7 @@ +const String lightsPhongFragment = """ +BlinnPhongMaterial material; +material.diffuseColor = diffuseColor.rgb; +material.specularColor = specular; +material.specularShininess = shininess; +material.specularStrength = specularStrength; +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_phong_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_phong_pars_fragment.glsl.dart new file mode 100755 index 00000000..fd8e2714 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_phong_pars_fragment.glsl.dart @@ -0,0 +1,32 @@ +const String lightsPhongParsFragment = """ +varying vec3 vViewPosition; + +struct BlinnPhongMaterial { + + vec3 diffuseColor; + vec3 specularColor; + float specularShininess; + float specularStrength; + +}; + +void RE_Direct_BlinnPhong( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) { + + float dotNL = saturate( dot( geometryNormal, directLight.direction ) ); + vec3 irradiance = dotNL * directLight.color; + + reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor ); + + reflectedLight.directSpecular += irradiance * BRDF_BlinnPhong( directLight.direction, geometryViewDir, geometryNormal, material.specularColor, material.specularShininess ) * material.specularStrength; + +} + +void RE_IndirectDiffuse_BlinnPhong( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in BlinnPhongMaterial material, inout ReflectedLight reflectedLight ) { + + reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor ); + +} + +#define RE_Direct RE_Direct_BlinnPhong +#define RE_IndirectDiffuse RE_IndirectDiffuse_BlinnPhong +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_physical_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_physical_fragment.glsl.dart new file mode 100755 index 00000000..57374154 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_physical_fragment.glsl.dart @@ -0,0 +1,157 @@ +const String lightsPhysicalFragment = """ +PhysicalMaterial material; +material.diffuseColor = diffuseColor.rgb * ( 1.0 - metalnessFactor ); + +vec3 dxy = max( abs( dFdx( nonPerturbedNormal ) ), abs( dFdy( nonPerturbedNormal ) ) ); +float geometryRoughness = max( max( dxy.x, dxy.y ), dxy.z ); + +material.roughness = max( roughnessFactor, 0.0525 );// 0.0525 corresponds to the base mip of a 256 cubemap. +material.roughness += geometryRoughness; +material.roughness = min( material.roughness, 1.0 ); + +#ifdef IOR + + material.ior = ior; + + #ifdef USE_SPECULAR + + float specularIntensityFactor = specularIntensity; + vec3 specularColorFactor = specularColor; + + #ifdef USE_SPECULAR_COLORMAP + + specularColorFactor *= texture2D( specularColorMap, vSpecularColorMapUv ).rgb; + + #endif + + #ifdef USE_SPECULAR_INTENSITYMAP + + specularIntensityFactor *= texture2D( specularIntensityMap, vSpecularIntensityMapUv ).a; + + #endif + + material.specularF90 = mix( specularIntensityFactor, 1.0, metalnessFactor ); + + #else + + float specularIntensityFactor = 1.0; + vec3 specularColorFactor = vec3( 1.0 ); + material.specularF90 = 1.0; + + #endif + + material.specularColor = mix( min( pow2( ( material.ior - 1.0 ) / ( material.ior + 1.0 ) ) * specularColorFactor, vec3( 1.0 ) ) * specularIntensityFactor, diffuseColor.rgb, metalnessFactor ); + +#else + + material.specularColor = mix( vec3( 0.04 ), diffuseColor.rgb, metalnessFactor ); + material.specularF90 = 1.0; + +#endif + +#ifdef USE_CLEARCOAT + + material.clearcoat = clearcoat; + material.clearcoatRoughness = clearcoatRoughness; + material.clearcoatF0 = vec3( 0.04 ); + material.clearcoatF90 = 1.0; + + #ifdef USE_CLEARCOATMAP + + material.clearcoat *= texture2D( clearcoatMap, vClearcoatMapUv ).x; + + #endif + + #ifdef USE_CLEARCOAT_ROUGHNESSMAP + + material.clearcoatRoughness *= texture2D( clearcoatRoughnessMap, vClearcoatRoughnessMapUv ).y; + + #endif + + material.clearcoat = saturate( material.clearcoat ); // Burley clearcoat model + material.clearcoatRoughness = max( material.clearcoatRoughness, 0.0525 ); + material.clearcoatRoughness += geometryRoughness; + material.clearcoatRoughness = min( material.clearcoatRoughness, 1.0 ); + +#endif + +#ifdef USE_DISPERSION + + material.dispersion = dispersion; + +#endif + +#ifdef USE_IRIDESCENCE + + material.iridescence = iridescence; + material.iridescenceIOR = iridescenceIOR; + + #ifdef USE_IRIDESCENCEMAP + + material.iridescence *= texture2D( iridescenceMap, vIridescenceMapUv ).r; + + #endif + + #ifdef USE_IRIDESCENCE_THICKNESSMAP + + material.iridescenceThickness = (iridescenceThicknessMaximum - iridescenceThicknessMinimum) * texture2D( iridescenceThicknessMap, vIridescenceThicknessMapUv ).g + iridescenceThicknessMinimum; + + #else + + material.iridescenceThickness = iridescenceThicknessMaximum; + + #endif + +#endif + +#ifdef USE_SHEEN + + material.sheenColor = sheenColor; + + #ifdef USE_SHEEN_COLORMAP + + material.sheenColor *= texture2D( sheenColorMap, vSheenColorMapUv ).rgb; + + #endif + + material.sheenRoughness = clamp( sheenRoughness, 0.07, 1.0 ); + + #ifdef USE_SHEEN_ROUGHNESSMAP + + material.sheenRoughness *= texture2D( sheenRoughnessMap, vSheenRoughnessMapUv ).a; + + #endif + +#endif + +#ifdef USE_ANISOTROPY + + #ifdef USE_ANISOTROPYMAP + + mat2 anisotropyMat = mat2( anisotropyVector.x, anisotropyVector.y, - anisotropyVector.y, anisotropyVector.x ); + vec3 anisotropyPolar = texture2D( anisotropyMap, vAnisotropyMapUv ).rgb; + vec2 anisotropyV = anisotropyMat * normalize( 2.0 * anisotropyPolar.rg - vec2( 1.0 ) ) * anisotropyPolar.b; + + #else + + vec2 anisotropyV = anisotropyVector; + + #endif + + material.anisotropy = length( anisotropyV ); + + if( material.anisotropy == 0.0 ) { + anisotropyV = vec2( 1.0, 0.0 ); + } else { + anisotropyV /= material.anisotropy; + material.anisotropy = saturate( material.anisotropy ); + } + + // Roughness along the anisotropy bitangent is the material roughness, while the tangent roughness increases with anisotropy. + material.alphaT = mix( pow2( material.roughness ), 1.0, pow2( material.anisotropy ) ); + + material.anisotropyT = tbn[ 0 ] * anisotropyV.x + tbn[ 1 ] * anisotropyV.y; + material.anisotropyB = tbn[ 1 ] * anisotropyV.x - tbn[ 0 ] * anisotropyV.y; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_physical_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_physical_pars_fragment.glsl.dart new file mode 100755 index 00000000..b4785c4d --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_physical_pars_fragment.glsl.dart @@ -0,0 +1,562 @@ +const String lightsPhysicalParsFragment = """ +struct PhysicalMaterial { + + vec3 diffuseColor; + float roughness; + vec3 specularColor; + float specularF90; + float dispersion; + + #ifdef USE_CLEARCOAT + float clearcoat; + float clearcoatRoughness; + vec3 clearcoatF0; + float clearcoatF90; + #endif + + #ifdef USE_IRIDESCENCE + float iridescence; + float iridescenceIOR; + float iridescenceThickness; + vec3 iridescenceFresnel; + vec3 iridescenceF0; + #endif + + #ifdef USE_SHEEN + vec3 sheenColor; + float sheenRoughness; + #endif + + #ifdef IOR + float ior; + #endif + + #ifdef USE_TRANSMISSION + float transmission; + float transmissionAlpha; + float thickness; + float attenuationDistance; + vec3 attenuationColor; + #endif + + #ifdef USE_ANISOTROPY + float anisotropy; + float alphaT; + vec3 anisotropyT; + vec3 anisotropyB; + #endif + +}; + +// temporary +vec3 clearcoatSpecularDirect = vec3( 0.0 ); +vec3 clearcoatSpecularIndirect = vec3( 0.0 ); +vec3 sheenSpecularDirect = vec3( 0.0 ); +vec3 sheenSpecularIndirect = vec3(0.0 ); + +vec3 Schlick_to_F0( const in vec3 f, const in float f90, const in float dotVH ) { + float x = clamp( 1.0 - dotVH, 0.0, 1.0 ); + float x2 = x * x; + float x5 = clamp( x * x2 * x2, 0.0, 0.9999 ); + + return ( f - vec3( f90 ) * x5 ) / ( 1.0 - x5 ); +} + +// Moving Frostbite to Physically Based Rendering 3.0 - page 12, listing 2 +// https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf +float V_GGX_SmithCorrelated( const in float alpha, const in float dotNL, const in float dotNV ) { + + float a2 = pow2( alpha ); + + float gv = dotNL * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNV ) ); + float gl = dotNV * sqrt( a2 + ( 1.0 - a2 ) * pow2( dotNL ) ); + + return 0.5 / max( gv + gl, EPSILON ); + +} + +// Microfacet Models for Refraction through Rough Surfaces - equation (33) +// http://graphicrants.blogspot.com/2013/08/specular-brdf-reference.html +// alpha is "roughness squared" in Disney’s reparameterization +float D_GGX( const in float alpha, const in float dotNH ) { + + float a2 = pow2( alpha ); + + float denom = pow2( dotNH ) * ( a2 - 1.0 ) + 1.0; // avoid alpha = 0 with dotNH = 1 + + return RECIPROCAL_PI * a2 / pow2( denom ); + +} + +// https://google.github.io/filament/Filament.md.html#materialsystem/anisotropicmodel/anisotropicspecularbrdf +#ifdef USE_ANISOTROPY + + float V_GGX_SmithCorrelated_Anisotropic( const in float alphaT, const in float alphaB, const in float dotTV, const in float dotBV, const in float dotTL, const in float dotBL, const in float dotNV, const in float dotNL ) { + + float gv = dotNL * length( vec3( alphaT * dotTV, alphaB * dotBV, dotNV ) ); + float gl = dotNV * length( vec3( alphaT * dotTL, alphaB * dotBL, dotNL ) ); + float v = 0.5 / ( gv + gl ); + + return saturate(v); + + } + + float D_GGX_Anisotropic( const in float alphaT, const in float alphaB, const in float dotNH, const in float dotTH, const in float dotBH ) { + + float a2 = alphaT * alphaB; + highp vec3 v = vec3( alphaB * dotTH, alphaT * dotBH, a2 * dotNH ); + highp float v2 = dot( v, v ); + float w2 = a2 / v2; + + return RECIPROCAL_PI * a2 * pow2 ( w2 ); + + } + +#endif + +#ifdef USE_CLEARCOAT + + // GGX Distribution, Schlick Fresnel, GGX_SmithCorrelated Visibility + vec3 BRDF_GGX_Clearcoat( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material) { + + vec3 f0 = material.clearcoatF0; + float f90 = material.clearcoatF90; + float roughness = material.clearcoatRoughness; + + float alpha = pow2( roughness ); // UE4's roughness + + vec3 halfDir = normalize( lightDir + viewDir ); + + float dotNL = saturate( dot( normal, lightDir ) ); + float dotNV = saturate( dot( normal, viewDir ) ); + float dotNH = saturate( dot( normal, halfDir ) ); + float dotVH = saturate( dot( viewDir, halfDir ) ); + + vec3 F = F_Schlick( f0, f90, dotVH ); + + float V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV ); + + float D = D_GGX( alpha, dotNH ); + + return F * ( V * D ); + + } + +#endif + +vec3 BRDF_GGX( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, const in PhysicalMaterial material ) { + + vec3 f0 = material.specularColor; + float f90 = material.specularF90; + float roughness = material.roughness; + + float alpha = pow2( roughness ); // UE4's roughness + + vec3 halfDir = normalize( lightDir + viewDir ); + + float dotNL = saturate( dot( normal, lightDir ) ); + float dotNV = saturate( dot( normal, viewDir ) ); + float dotNH = saturate( dot( normal, halfDir ) ); + float dotVH = saturate( dot( viewDir, halfDir ) ); + + vec3 F = F_Schlick( f0, f90, dotVH ); + + #ifdef USE_IRIDESCENCE + + F = mix( F, material.iridescenceFresnel, material.iridescence ); + + #endif + + #ifdef USE_ANISOTROPY + + float dotTL = dot( material.anisotropyT, lightDir ); + float dotTV = dot( material.anisotropyT, viewDir ); + float dotTH = dot( material.anisotropyT, halfDir ); + float dotBL = dot( material.anisotropyB, lightDir ); + float dotBV = dot( material.anisotropyB, viewDir ); + float dotBH = dot( material.anisotropyB, halfDir ); + + float V = V_GGX_SmithCorrelated_Anisotropic( material.alphaT, alpha, dotTV, dotBV, dotTL, dotBL, dotNV, dotNL ); + + float D = D_GGX_Anisotropic( material.alphaT, alpha, dotNH, dotTH, dotBH ); + + #else + + float V = V_GGX_SmithCorrelated( alpha, dotNL, dotNV ); + + float D = D_GGX( alpha, dotNH ); + + #endif + + return F * ( V * D ); + +} + +// Rect Area Light + +// Real-Time Polygonal-Light Shading with Linearly Transformed Cosines +// by Eric Heitz, Jonathan Dupuy, Stephen Hill and David Neubelt +// code: https://github.com/selfshadow/ltc_code/ + +vec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) { + + const float LUT_SIZE = 64.0; + const float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE; + const float LUT_BIAS = 0.5 / LUT_SIZE; + + float dotNV = saturate( dot( N, V ) ); + + // texture parameterized by sqrt( GGX alpha ) and sqrt( 1 - cos( theta ) ) + vec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) ); + + uv = uv * LUT_SCALE + LUT_BIAS; + + return uv; + +} + +float LTC_ClippedSphereFormFactor( const in vec3 f ) { + + // Real-Time Area Lighting: a Journey from Research to Production (p.102) + // An approximation of the form factor of a horizon-clipped rectangle. + + float l = length( f ); + + return max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 ); + +} + +vec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) { + + float x = dot( v1, v2 ); + + float y = abs( x ); + + // rational polynomial approximation to theta / sin( theta ) / 2PI + float a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y; + float b = 3.4175940 + ( 4.1616724 + y ) * y; + float v = a / b; + + float theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v; + + return cross( v1, v2 ) * theta_sintheta; + +} + +vec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in mat3 mInv, const in vec3 rectCoords[ 4 ] ) { + + // bail if point is on back side of plane of light + // assumes ccw winding order of light vertices + vec3 v1 = rectCoords[ 1 ] - rectCoords[ 0 ]; + vec3 v2 = rectCoords[ 3 ] - rectCoords[ 0 ]; + vec3 lightNormal = cross( v1, v2 ); + + if( dot( lightNormal, P - rectCoords[ 0 ] ) < 0.0 ) return vec3( 0.0 ); + + // construct orthonormal basis around N + vec3 T1, T2; + T1 = normalize( V - N * dot( V, N ) ); + T2 = - cross( N, T1 ); // negated from paper; possibly due to a different handedness of world coordinate system + + // compute transform + mat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) ); + + // transform rect + vec3 coords[ 4 ]; + coords[ 0 ] = mat * ( rectCoords[ 0 ] - P ); + coords[ 1 ] = mat * ( rectCoords[ 1 ] - P ); + coords[ 2 ] = mat * ( rectCoords[ 2 ] - P ); + coords[ 3 ] = mat * ( rectCoords[ 3 ] - P ); + + // project rect onto sphere + coords[ 0 ] = normalize( coords[ 0 ] ); + coords[ 1 ] = normalize( coords[ 1 ] ); + coords[ 2 ] = normalize( coords[ 2 ] ); + coords[ 3 ] = normalize( coords[ 3 ] ); + + // calculate vector form factor + vec3 vectorFormFactor = vec3( 0.0 ); + vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 0 ], coords[ 1 ] ); + vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 1 ], coords[ 2 ] ); + vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 2 ], coords[ 3 ] ); + vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] ); + + // adjust for horizon clipping + float result = LTC_ClippedSphereFormFactor( vectorFormFactor ); + +/* + // alternate method of adjusting for horizon clipping (see referece) + // refactoring required + float len = length( vectorFormFactor ); + float z = vectorFormFactor.z / len; + + const float LUT_SIZE = 64.0; + const float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE; + const float LUT_BIAS = 0.5 / LUT_SIZE; + + // tabulated horizon-clipped sphere, apparently... + vec2 uv = vec2( z * 0.5 + 0.5, len ); + uv = uv * LUT_SCALE + LUT_BIAS; + + float scale = texture2D( ltc_2, uv ).w; + + float result = len * scale; +*/ + + return vec3( result ); + +} + +// End Rect Area Light + +#if defined( USE_SHEEN ) + +// https://github.com/google/filament/blob/master/shaders/src/brdf.fs +float D_Charlie( float roughness, float dotNH ) { + + float alpha = pow2( roughness ); + + // Estevez and Kulla 2017, "Production Friendly Microfacet Sheen BRDF" + float invAlpha = 1.0 / alpha; + float cos2h = dotNH * dotNH; + float sin2h = max( 1.0 - cos2h, 0.0078125 ); // 2^(-14/2), so sin2h^2 > 0 in fp16 + + return ( 2.0 + invAlpha ) * pow( sin2h, invAlpha * 0.5 ) / ( 2.0 * PI ); + +} + +// https://github.com/google/filament/blob/master/shaders/src/brdf.fs +float V_Neubelt( float dotNV, float dotNL ) { + + // Neubelt and Pettineo 2013, "Crafting a Next-gen Material Pipeline for The Order: 1886" + return saturate( 1.0 / ( 4.0 * ( dotNL + dotNV - dotNL * dotNV ) ) ); + +} + +vec3 BRDF_Sheen( const in vec3 lightDir, const in vec3 viewDir, const in vec3 normal, vec3 sheenColor, const in float sheenRoughness ) { + + vec3 halfDir = normalize( lightDir + viewDir ); + + float dotNL = saturate( dot( normal, lightDir ) ); + float dotNV = saturate( dot( normal, viewDir ) ); + float dotNH = saturate( dot( normal, halfDir ) ); + + float D = D_Charlie( sheenRoughness, dotNH ); + float V = V_Neubelt( dotNV, dotNL ); + + return sheenColor * ( D * V ); + +} + +#endif + +// This is a curve-fit approxmation to the "Charlie sheen" BRDF integrated over the hemisphere from +// Estevez and Kulla 2017, "Production Friendly Microfacet Sheen BRDF". The analysis can be found +// in the Sheen section of https://drive.google.com/file/d/1T0D1VSyR4AllqIJTQAraEIzjlb5h4FKH/view?usp=sharing +float IBLSheenBRDF( const in vec3 normal, const in vec3 viewDir, const in float roughness ) { + + float dotNV = saturate( dot( normal, viewDir ) ); + + float r2 = roughness * roughness; + + float a = roughness < 0.25 ? -339.2 * r2 + 161.4 * roughness - 25.9 : -8.48 * r2 + 14.3 * roughness - 9.95; + + float b = roughness < 0.25 ? 44.0 * r2 - 23.7 * roughness + 3.26 : 1.97 * r2 - 3.27 * roughness + 0.72; + + float DG = exp( a * dotNV + b ) + ( roughness < 0.25 ? 0.0 : 0.1 * ( roughness - 0.25 ) ); + + return saturate( DG * RECIPROCAL_PI ); + +} + +// Analytical approximation of the DFG LUT, one half of the +// split-sum approximation used in indirect specular lighting. +// via 'environmentBRDF' from "Physically Based Shading on Mobile" +// https://www.unrealengine.com/blog/physically-based-shading-on-mobile +vec2 DFGApprox( const in vec3 normal, const in vec3 viewDir, const in float roughness ) { + + float dotNV = saturate( dot( normal, viewDir ) ); + + const vec4 c0 = vec4( - 1, - 0.0275, - 0.572, 0.022 ); + + const vec4 c1 = vec4( 1, 0.0425, 1.04, - 0.04 ); + + vec4 r = roughness * c0 + c1; + + float a004 = min( r.x * r.x, exp2( - 9.28 * dotNV ) ) * r.x + r.y; + + vec2 fab = vec2( - 1.04, 1.04 ) * a004 + r.zw; + + return fab; + +} + +vec3 EnvironmentBRDF( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness ) { + + vec2 fab = DFGApprox( normal, viewDir, roughness ); + + return specularColor * fab.x + specularF90 * fab.y; + +} + +// Fdez-Agüera's "Multiple-Scattering Microfacet Model for Real-Time Image Based Lighting" +// Approximates multiscattering in order to preserve energy. +// http://www.jcgt.org/published/0008/01/03/ +#ifdef USE_IRIDESCENCE +void computeMultiscatteringIridescence( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float iridescence, const in vec3 iridescenceF0, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) { +#else +void computeMultiscattering( const in vec3 normal, const in vec3 viewDir, const in vec3 specularColor, const in float specularF90, const in float roughness, inout vec3 singleScatter, inout vec3 multiScatter ) { +#endif + + vec2 fab = DFGApprox( normal, viewDir, roughness ); + + #ifdef USE_IRIDESCENCE + + vec3 Fr = mix( specularColor, iridescenceF0, iridescence ); + + #else + + vec3 Fr = specularColor; + + #endif + + vec3 FssEss = Fr * fab.x + specularF90 * fab.y; + + float Ess = fab.x + fab.y; + float Ems = 1.0 - Ess; + + vec3 Favg = Fr + ( 1.0 - Fr ) * 0.047619; // 1/21 + vec3 Fms = FssEss * Favg / ( 1.0 - Ems * Favg ); + + singleScatter += FssEss; + multiScatter += Fms * Ems; + +} + +#if NUM_RECT_AREA_LIGHTS > 0 + + void RE_Direct_RectArea_Physical( const in RectAreaLight rectAreaLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) { + + vec3 normal = geometryNormal; + vec3 viewDir = geometryViewDir; + vec3 position = geometryPosition; + vec3 lightPos = rectAreaLight.position; + vec3 halfWidth = rectAreaLight.halfWidth; + vec3 halfHeight = rectAreaLight.halfHeight; + vec3 lightColor = rectAreaLight.color; + float roughness = material.roughness; + + vec3 rectCoords[ 4 ]; + rectCoords[ 0 ] = lightPos + halfWidth - halfHeight; // counterclockwise; light shines in local neg z direction + rectCoords[ 1 ] = lightPos - halfWidth - halfHeight; + rectCoords[ 2 ] = lightPos - halfWidth + halfHeight; + rectCoords[ 3 ] = lightPos + halfWidth + halfHeight; + + vec2 uv = LTC_Uv( normal, viewDir, roughness ); + + vec4 t1 = texture2D( ltc_1, uv ); + vec4 t2 = texture2D( ltc_2, uv ); + + mat3 mInv = mat3( + vec3( t1.x, 0, t1.y ), + vec3( 0, 1, 0 ), + vec3( t1.z, 0, t1.w ) + ); + + // LTC Fresnel Approximation by Stephen Hill + // http://blog.selfshadow.com/publications/s2016-advances/s2016_ltc_fresnel.pdf + vec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y ); + + reflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords ); + + reflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords ); + + } + +#endif + +void RE_Direct_Physical( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) { + + float dotNL = saturate( dot( geometryNormal, directLight.direction ) ); + + vec3 irradiance = dotNL * directLight.color; + + #ifdef USE_CLEARCOAT + + float dotNLcc = saturate( dot( geometryClearcoatNormal, directLight.direction ) ); + + vec3 ccIrradiance = dotNLcc * directLight.color; + + clearcoatSpecularDirect += ccIrradiance * BRDF_GGX_Clearcoat( directLight.direction, geometryViewDir, geometryClearcoatNormal, material ); + + #endif + + #ifdef USE_SHEEN + + sheenSpecularDirect += irradiance * BRDF_Sheen( directLight.direction, geometryViewDir, geometryNormal, material.sheenColor, material.sheenRoughness ); + + #endif + + reflectedLight.directSpecular += irradiance * BRDF_GGX( directLight.direction, geometryViewDir, geometryNormal, material ); + + reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor ); +} + +void RE_IndirectDiffuse_Physical( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight ) { + + reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor ); + +} + +void RE_IndirectSpecular_Physical( const in vec3 radiance, const in vec3 irradiance, const in vec3 clearcoatRadiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in PhysicalMaterial material, inout ReflectedLight reflectedLight) { + + #ifdef USE_CLEARCOAT + + clearcoatSpecularIndirect += clearcoatRadiance * EnvironmentBRDF( geometryClearcoatNormal, geometryViewDir, material.clearcoatF0, material.clearcoatF90, material.clearcoatRoughness ); + + #endif + + #ifdef USE_SHEEN + + sheenSpecularIndirect += irradiance * material.sheenColor * IBLSheenBRDF( geometryNormal, geometryViewDir, material.sheenRoughness ); + + #endif + + // Both indirect specular and indirect diffuse light accumulate here + + vec3 singleScattering = vec3( 0.0 ); + vec3 multiScattering = vec3( 0.0 ); + vec3 cosineWeightedIrradiance = irradiance * RECIPROCAL_PI; + + #ifdef USE_IRIDESCENCE + + computeMultiscatteringIridescence( geometryNormal, geometryViewDir, material.specularColor, material.specularF90, material.iridescence, material.iridescenceFresnel, material.roughness, singleScattering, multiScattering ); + + #else + + computeMultiscattering( geometryNormal, geometryViewDir, material.specularColor, material.specularF90, material.roughness, singleScattering, multiScattering ); + + #endif + + vec3 totalScattering = singleScattering + multiScattering; + vec3 diffuse = material.diffuseColor * ( 1.0 - max( max( totalScattering.r, totalScattering.g ), totalScattering.b ) ); + + reflectedLight.indirectSpecular += radiance * singleScattering; + reflectedLight.indirectSpecular += multiScattering * cosineWeightedIrradiance; + + reflectedLight.indirectDiffuse += diffuse * cosineWeightedIrradiance; + +} + +#define RE_Direct RE_Direct_Physical +#define RE_Direct_RectArea RE_Direct_RectArea_Physical +#define RE_IndirectDiffuse RE_IndirectDiffuse_Physical +#define RE_IndirectSpecular RE_IndirectSpecular_Physical + +// ref: https://seblagarde.files.wordpress.com/2015/07/course_notes_moving_frostbite_to_pbr_v32.pdf +float computeSpecularOcclusion( const in float dotNV, const in float ambientOcclusion, const in float roughness ) { + + return saturate( pow( dotNV + ambientOcclusion, exp2( - 16.0 * roughness - 1.0 ) ) - 1.0 + ambientOcclusion ); + +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_toon_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_toon_fragment.glsl.dart new file mode 100755 index 00000000..e1a2a157 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_toon_fragment.glsl.dart @@ -0,0 +1,4 @@ +const String lightsToonFragment = """ +ToonMaterial material; +material.diffuseColor = diffuseColor.rgb; +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_toon_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_toon_pars_fragment.glsl.dart new file mode 100755 index 00000000..4563351f --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_toon_pars_fragment.glsl.dart @@ -0,0 +1,26 @@ +const String lightsToonParsFragment = """ +varying vec3 vViewPosition; + +struct ToonMaterial { + + vec3 diffuseColor; + +}; + +void RE_Direct_Toon( const in IncidentLight directLight, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in ToonMaterial material, inout ReflectedLight reflectedLight ) { + + vec3 irradiance = getGradientIrradiance( geometryNormal, directLight.direction ) * directLight.color; + + reflectedLight.directDiffuse += irradiance * BRDF_Lambert( material.diffuseColor ); + +} + +void RE_IndirectDiffuse_Toon( const in vec3 irradiance, const in vec3 geometryPosition, const in vec3 geometryNormal, const in vec3 geometryViewDir, const in vec3 geometryClearcoatNormal, const in ToonMaterial material, inout ReflectedLight reflectedLight ) { + + reflectedLight.indirectDiffuse += irradiance * BRDF_Lambert( material.diffuseColor ); + +} + +#define RE_Direct RE_Direct_Toon +#define RE_IndirectDiffuse RE_IndirectDiffuse_Toon +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/logdepthbuf_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/logdepthbuf_fragment.glsl.dart new file mode 100755 index 00000000..6546f363 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/logdepthbuf_fragment.glsl.dart @@ -0,0 +1,9 @@ +const String logdepthbufFragment = """ +#if defined( USE_LOGDEPTHBUF ) + + // Doing a strict comparison with == 1.0 can cause noise artifacts + // on some platforms. See issue #17623. + gl_FragDepth = vIsPerspective == 0.0 ? gl_FragCoord.z : log2( vFragDepth ) * logDepthBufFC * 0.5; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/logdepthbuf_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/logdepthbuf_pars_fragment.glsl.dart new file mode 100755 index 00000000..93866dc5 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/logdepthbuf_pars_fragment.glsl.dart @@ -0,0 +1,9 @@ +const String logdepthbufParsFragment = """ +#if defined( USE_LOGDEPTHBUF ) + + uniform float logDepthBufFC; + varying float vFragDepth; + varying float vIsPerspective; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/logdepthbuf_pars_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/logdepthbuf_pars_vertex.glsl.dart new file mode 100755 index 00000000..2107eaea --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/logdepthbuf_pars_vertex.glsl.dart @@ -0,0 +1,8 @@ +const String logdepthbufParsVertex = """ +#ifdef USE_LOGDEPTHBUF + + varying float vFragDepth; + varying float vIsPerspective; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/logdepthbuf_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/logdepthbuf_vertex.glsl.dart new file mode 100755 index 00000000..e4484355 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/logdepthbuf_vertex.glsl.dart @@ -0,0 +1,8 @@ +const String logdepthbufVertex = """ +#ifdef USE_LOGDEPTHBUF + + vFragDepth = 1.0 + gl_Position.w; + vIsPerspective = float( isPerspectiveMatrix( projectionMatrix ) ); + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/map_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/map_fragment.glsl.dart new file mode 100755 index 00000000..a48f6cd6 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/map_fragment.glsl.dart @@ -0,0 +1,17 @@ +const String mapFragment = """ +#ifdef USE_MAP + + vec4 sampledDiffuseColor = texture2D( map, vMapUv ); + + #ifdef DECODE_VIDEO_TEXTURE + + // use inline sRGB decode until browsers properly support SRGB8_ALPHA8 with video textures (#26516) + + sampledDiffuseColor = vec4( mix( pow( sampledDiffuseColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), sampledDiffuseColor.rgb * 0.0773993808, vec3( lessThanEqual( sampledDiffuseColor.rgb, vec3( 0.04045 ) ) ) ), sampledDiffuseColor.w ); + + #endif + + diffuseColor *= sampledDiffuseColor; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/map_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/map_pars_fragment.glsl.dart new file mode 100755 index 00000000..7a647bff --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/map_pars_fragment.glsl.dart @@ -0,0 +1,7 @@ +const String mapParsFragment = """ +#ifdef USE_MAP + + uniform sampler2D map; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/map_particle_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/map_particle_fragment.glsl.dart new file mode 100755 index 00000000..6cbf3e56 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/map_particle_fragment.glsl.dart @@ -0,0 +1,27 @@ +const String mapParticleFragment = """ +#if defined( USE_MAP ) || defined( USE_ALPHAMAP ) + + #if defined( USE_POINTS_UV ) + + vec2 uv = vUv; + + #else + + vec2 uv = ( uvTransform * vec3( gl_PointCoord.x, 1.0 - gl_PointCoord.y, 1 ) ).xy; + + #endif + +#endif + +#ifdef USE_MAP + + diffuseColor *= texture2D( map, uv ); + +#endif + +#ifdef USE_ALPHAMAP + + diffuseColor.a *= texture2D( alphaMap, uv ).g; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/map_particle_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/map_particle_pars_fragment.glsl.dart new file mode 100755 index 00000000..a1740929 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/map_particle_pars_fragment.glsl.dart @@ -0,0 +1,27 @@ +const String mapParticleParsFragment = """ +#if defined( USE_POINTS_UV ) + + varying vec2 vUv; + +#else + + #if defined( USE_MAP ) || defined( USE_ALPHAMAP ) + + uniform mat3 uvTransform; + + #endif + +#endif + +#ifdef USE_MAP + + uniform sampler2D map; + +#endif + +#ifdef USE_ALPHAMAP + + uniform sampler2D alphaMap; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/metalnessmap_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/metalnessmap_fragment.glsl.dart new file mode 100755 index 00000000..86ed1546 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/metalnessmap_fragment.glsl.dart @@ -0,0 +1,12 @@ +const String metalnessmapFragment = """ +float metalnessFactor = metalness; + +#ifdef USE_METALNESSMAP + + vec4 texelMetalness = texture2D( metalnessMap, vMetalnessMapUv ); + + // reads channel B, compatible with a combined OcclusionRoughnessMetallic (RGB) texture + metalnessFactor *= texelMetalness.b; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/metalnessmap_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/metalnessmap_pars_fragment.glsl.dart new file mode 100755 index 00000000..8feca2bb --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/metalnessmap_pars_fragment.glsl.dart @@ -0,0 +1,7 @@ +const String metalnessmapParsFragment = """ +#ifdef USE_METALNESSMAP + + uniform sampler2D metalnessMap; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/morphcolor_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/morphcolor_vertex.glsl.dart new file mode 100755 index 00000000..bc1f1165 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/morphcolor_vertex.glsl.dart @@ -0,0 +1,24 @@ +const String morphcolorVertex = """ +#if defined( USE_MORPHCOLORS ) && defined( MORPHTARGETS_TEXTURE ) + + // morphTargetBaseInfluence is set based on BufferGeometry.morphTargetsRelative value: + // When morphTargetsRelative is false, this is set to 1 - sum(influences); this results in normal = sum((target - base) * influence) + // When morphTargetsRelative is true, this is set to 1; as a result, all morph targets are simply added to the base after weighting + vColor *= morphTargetBaseInfluence; + + for ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) { + + #if defined( USE_COLOR_ALPHA ) + + if ( morphTargetInfluences[ i ] != 0.0 ) vColor += getMorph( gl_VertexID, i, 2 ) * morphTargetInfluences[ i ]; + + #elif defined( USE_COLOR ) + + if ( morphTargetInfluences[ i ] != 0.0 ) vColor += getMorph( gl_VertexID, i, 2 ).rgb * morphTargetInfluences[ i ]; + + #endif + + } + +#endif +"""; \ No newline at end of file diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/morphinstance_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/morphinstance_vertex.glsl.dart new file mode 100644 index 00000000..4c04a330 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/morphinstance_vertex.glsl.dart @@ -0,0 +1,14 @@ +const String morphinstanceVertex = /* glsl */''' +#ifdef USE_INSTANCING_MORPH + + float morphTargetInfluences[MORPHTARGETS_COUNT]; + + float morphTargetBaseInfluence = texelFetch( morphTexture, ivec2( 0, gl_InstanceID ), 0 ).r; + + for ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) { + + morphTargetInfluences[i] = texelFetch( morphTexture, ivec2( i + 1, gl_InstanceID ), 0 ).r; + + } +#endif +'''; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/morphnormal_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/morphnormal_vertex.glsl.dart new file mode 100755 index 00000000..4ad3fc3f --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/morphnormal_vertex.glsl.dart @@ -0,0 +1,27 @@ +const String morphnormalVertex = """ +#ifdef USE_MORPHNORMALS + + // morphTargetBaseInfluence is set based on BufferGeometry.morphTargetsRelative value: + // When morphTargetsRelative is false, this is set to 1 - sum(influences); this results in normal = sum((target - base) * influence) + // When morphTargetsRelative is true, this is set to 1; as a result, all morph targets are simply added to the base after weighting + objectNormal *= morphTargetBaseInfluence; + + #ifdef MORPHTARGETS_TEXTURE + + for ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) { + + if ( morphTargetInfluences[ i ] != 0.0 ) objectNormal += getMorph( gl_VertexID, i, 1 ).xyz * morphTargetInfluences[ i ]; + + } + + #else + + objectNormal += morphNormal0 * morphTargetInfluences[ 0 ]; + objectNormal += morphNormal1 * morphTargetInfluences[ 1 ]; + objectNormal += morphNormal2 * morphTargetInfluences[ 2 ]; + objectNormal += morphNormal3 * morphTargetInfluences[ 3 ]; + + #endif + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/morphtarget_pars_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/morphtarget_pars_vertex.glsl.dart new file mode 100755 index 00000000..f77b6c5e --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/morphtarget_pars_vertex.glsl.dart @@ -0,0 +1,47 @@ +const String morphtargetParsVertex = """ +#ifdef USE_MORPHTARGETS + + #ifndef USE_INSTANCING_MORPH + + uniform float morphTargetBaseInfluence; + + #endif + + #ifdef MORPHTARGETS_TEXTURE + + #ifndef USE_INSTANCING_MORPH + + uniform float morphTargetInfluences[ MORPHTARGETS_COUNT ]; + + #endif + + uniform sampler2DArray morphTargetsTexture; + uniform ivec2 morphTargetsTextureSize; + + vec4 getMorph( const in int vertexIndex, const in int morphTargetIndex, const in int offset ) { + + int texelIndex = vertexIndex * MORPHTARGETS_TEXTURE_STRIDE + offset; + int y = texelIndex / morphTargetsTextureSize.x; + int x = texelIndex - y * morphTargetsTextureSize.x; + + ivec3 morphUV = ivec3( x, y, morphTargetIndex ); + return texelFetch( morphTargetsTexture, morphUV, 0 ); + + } + + #else + + #ifndef USE_MORPHNORMALS + + uniform float morphTargetInfluences[ 8 ]; + + #else + + uniform float morphTargetInfluences[ 4 ]; + + #endif + + #endif + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/morphtarget_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/morphtarget_vertex.glsl.dart new file mode 100755 index 00000000..0c7a9298 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/morphtarget_vertex.glsl.dart @@ -0,0 +1,36 @@ +const String morphtargetVertex = """ +#ifdef USE_MORPHTARGETS + + // morphTargetBaseInfluence is set based on BufferGeometry.morphTargetsRelative value: + // When morphTargetsRelative is false, this is set to 1 - sum(influences); this results in position = sum((target - base) * influence) + // When morphTargetsRelative is true, this is set to 1; as a result, all morph targets are simply added to the base after weighting + transformed *= morphTargetBaseInfluence; + + #ifdef MORPHTARGETS_TEXTURE + + for ( int i = 0; i < MORPHTARGETS_COUNT; i ++ ) { + + if ( morphTargetInfluences[ i ] != 0.0 ) transformed += getMorph( gl_VertexID, i, 0 ).xyz * morphTargetInfluences[ i ]; + + } + + #else + + transformed += morphTarget0 * morphTargetInfluences[ 0 ]; + transformed += morphTarget1 * morphTargetInfluences[ 1 ]; + transformed += morphTarget2 * morphTargetInfluences[ 2 ]; + transformed += morphTarget3 * morphTargetInfluences[ 3 ]; + + #ifndef USE_MORPHNORMALS + + transformed += morphTarget4 * morphTargetInfluences[ 4 ]; + transformed += morphTarget5 * morphTargetInfluences[ 5 ]; + transformed += morphTarget6 * morphTargetInfluences[ 6 ]; + transformed += morphTarget7 * morphTargetInfluences[ 7 ]; + + #endif + + #endif + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/normal_fragment_begin.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/normal_fragment_begin.glsl.dart new file mode 100755 index 00000000..5449dc7f --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/normal_fragment_begin.glsl.dart @@ -0,0 +1,76 @@ +const String normalFragmentBegin = """ +float faceDirection = gl_FrontFacing ? 1.0 : - 1.0; + +#ifdef FLAT_SHADED + + vec3 fdx = dFdx( vViewPosition ); + vec3 fdy = dFdy( vViewPosition ); + vec3 normal = normalize( cross( fdx, fdy ) ); + +#else + + vec3 normal = normalize( vNormal ); + + #ifdef DOUBLE_SIDED + + normal *= faceDirection; + + #endif + +#endif + +#if defined( USE_NORMALMAP_TANGENTSPACE ) || defined( USE_CLEARCOAT_NORMALMAP ) || defined( USE_ANISOTROPY ) + + #ifdef USE_TANGENT + + mat3 tbn = mat3( normalize( vTangent ), normalize( vBitangent ), normal ); + + #else + + mat3 tbn = getTangentFrame( - vViewPosition, normal, + #if defined( USE_NORMALMAP ) + vNormalMapUv + #elif defined( USE_CLEARCOAT_NORMALMAP ) + vClearcoatNormalMapUv + #else + vUv + #endif + ); + + #endif + + #if defined( DOUBLE_SIDED ) && ! defined( FLAT_SHADED ) + + tbn[0] *= faceDirection; + tbn[1] *= faceDirection; + + #endif + +#endif + +#ifdef USE_CLEARCOAT_NORMALMAP + + #ifdef USE_TANGENT + + mat3 tbn2 = mat3( normalize( vTangent ), normalize( vBitangent ), normal ); + + #else + + mat3 tbn2 = getTangentFrame( - vViewPosition, normal, vClearcoatNormalMapUv ); + + #endif + + #if defined( DOUBLE_SIDED ) && ! defined( FLAT_SHADED ) + + tbn2[0] *= faceDirection; + tbn2[1] *= faceDirection; + + #endif + +#endif + +// non perturbed normal for clearcoat among others + +vec3 nonPerturbedNormal = normal; + +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/normal_fragment_maps.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/normal_fragment_maps.glsl.dart new file mode 100755 index 00000000..40aa4ad9 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/normal_fragment_maps.glsl.dart @@ -0,0 +1,32 @@ +const String normalFragmentMaps = """ +#ifdef USE_NORMALMAP_OBJECTSPACE + + normal = texture2D( normalMap, vNormalMapUv ).xyz * 2.0 - 1.0; // overrides both flatShading and attribute normals + + #ifdef FLIP_SIDED + + normal = - normal; + + #endif + + #ifdef DOUBLE_SIDED + + normal = normal * faceDirection; + + #endif + + normal = normalize( normalMatrix * normal ); + +#elif defined( USE_NORMALMAP_TANGENTSPACE ) + + vec3 mapN = texture2D( normalMap, vNormalMapUv ).xyz * 2.0 - 1.0; + mapN.xy *= normalScale; + + normal = normalize( tbn * mapN ); + +#elif defined( USE_BUMPMAP ) + + normal = perturbNormalArb( - vViewPosition, normal, dHdxy_fwd(), faceDirection ); + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/normal_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/normal_pars_fragment.glsl.dart new file mode 100755 index 00000000..56251571 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/normal_pars_fragment.glsl.dart @@ -0,0 +1,14 @@ +const String normalParsFragment = """ +#ifndef FLAT_SHADED + + varying vec3 vNormal; + + #ifdef USE_TANGENT + + varying vec3 vTangent; + varying vec3 vBitangent; + + #endif + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/normal_pars_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/normal_pars_vertex.glsl.dart new file mode 100755 index 00000000..89626aa9 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/normal_pars_vertex.glsl.dart @@ -0,0 +1,14 @@ +const String normalParsVertex = """ +#ifndef FLAT_SHADED + + varying vec3 vNormal; + + #ifdef USE_TANGENT + + varying vec3 vTangent; + varying vec3 vBitangent; + + #endif + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/normal_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/normal_vertex.glsl.dart new file mode 100755 index 00000000..b6437efb --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/normal_vertex.glsl.dart @@ -0,0 +1,14 @@ +const String normalVertex = """ +#ifndef FLAT_SHADED // normal is computed with derivatives when FLAT_SHADED + + vNormal = normalize( transformedNormal ); + + #ifdef USE_TANGENT + + vTangent = normalize( transformedTangent ); + vBitangent = normalize( cross( vNormal, vTangent ) * tangent.w ); + + #endif + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/normalmap_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/normalmap_pars_fragment.glsl.dart new file mode 100755 index 00000000..16acbadb --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/normalmap_pars_fragment.glsl.dart @@ -0,0 +1,43 @@ +const String normalmapParsFragment = """ +#ifdef USE_NORMALMAP + + uniform sampler2D normalMap; + uniform vec2 normalScale; + +#endif + +#ifdef USE_NORMALMAP_OBJECTSPACE + + uniform mat3 normalMatrix; + +#endif + +#if ! defined ( USE_TANGENT ) && ( defined ( USE_NORMALMAP_TANGENTSPACE ) || defined ( USE_CLEARCOAT_NORMALMAP ) || defined( USE_ANISOTROPY ) ) + + // Normal Mapping Without Precomputed Tangents + // http://www.thetenthplanet.de/archives/1180 + + mat3 getTangentFrame( vec3 eye_pos, vec3 surf_norm, vec2 uv ) { + + vec3 q0 = dFdx( eye_pos.xyz ); + vec3 q1 = dFdy( eye_pos.xyz ); + vec2 st0 = dFdx( uv.st ); + vec2 st1 = dFdy( uv.st ); + + vec3 N = surf_norm; // normalized + + vec3 q1perp = cross( q1, N ); + vec3 q0perp = cross( N, q0 ); + + vec3 T = q1perp * st0.x + q0perp * st1.x; + vec3 B = q1perp * st0.y + q0perp * st1.y; + + float det = max( dot( T, T ), dot( B, B ) ); + float scale = ( det == 0.0 ) ? 0.0 : inversesqrt( det ); + + return mat3( T * scale, B * scale, N ); + + } + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/opaque_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/opaque_fragment.glsl.dart new file mode 100755 index 00000000..d082fcac --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/opaque_fragment.glsl.dart @@ -0,0 +1,11 @@ +const String opaqueFragment = """ +#ifdef OPAQUE +diffuseColor.a = 1.0; +#endif + +#ifdef USE_TRANSMISSION +diffuseColor.a *= material.transmissionAlpha; +#endif + +gl_FragColor = vec4( outgoingLight, diffuseColor.a ); +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/output_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/output_fragment.glsl.dart new file mode 100644 index 00000000..8ede12b8 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/output_fragment.glsl.dart @@ -0,0 +1,12 @@ +const String outputFragment = """ +#ifdef OPAQUE +diffuseColor.a = 1.0; +#endif + +// https://github.com/mrdoob/three.js/pull/22425 +#ifdef USE_TRANSMISSION +diffuseColor.a *= transmissionAlpha + 0.1; +#endif + +gl_FragColor = vec4( outgoingLight, diffuseColor.a ); +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/packing.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/packing.glsl.dart new file mode 100755 index 00000000..5b9754f4 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/packing.glsl.dart @@ -0,0 +1,68 @@ +const String packingGlsl = """ +vec3 packNormalToRGB( const in vec3 normal ) { + return normalize( normal ) * 0.5 + 0.5; +} + +vec3 unpackRGBToNormal( const in vec3 rgb ) { + return 2.0 * rgb.xyz - 1.0; +} + +const float PackUpscale = 256. / 255.; // fraction -> 0..1 (including 1) +const float UnpackDownscale = 255. / 256.; // 0..1 -> fraction (excluding 1) + +const vec3 PackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. ); +const vec4 UnpackFactors = UnpackDownscale / vec4( PackFactors, 1. ); + +const float ShiftRight8 = 1. / 256.; + +vec4 packDepthToRGBA( const in float v ) { + vec4 r = vec4( fract( v * PackFactors ), v ); + r.yzw -= r.xyz * ShiftRight8; // tidy overflow + return r * PackUpscale; +} + +float unpackRGBAToDepth( const in vec4 v ) { + return dot( v, UnpackFactors ); +} + +vec2 packDepthToRG( in highp float v ) { + return packDepthToRGBA( v ).yx; +} + +float unpackRGToDepth( const in highp vec2 v ) { + return unpackRGBAToDepth( vec4( v.xy, 0.0, 0.0 ) ); +} + +vec4 pack2HalfToRGBA( vec2 v ) { + vec4 r = vec4( v.x, fract( v.x * 255.0 ), v.y, fract( v.y * 255.0 ) ); + return vec4( r.x - r.y / 255.0, r.y, r.z - r.w / 255.0, r.w ); +} + +vec2 unpackRGBATo2Half( vec4 v ) { + return vec2( v.x + ( v.y / 255.0 ), v.z + ( v.w / 255.0 ) ); +} + +// NOTE: viewZ, the z-coordinate in camera space, is negative for points in front of the camera + +float viewZToOrthographicDepth( const in float viewZ, const in float near, const in float far ) { + // -near maps to 0; -far maps to 1 + return ( viewZ + near ) / ( near - far ); +} + +float orthographicDepthToViewZ( const in float depth, const in float near, const in float far ) { + // maps orthographic depth in [ 0, 1 ] to viewZ + return depth * ( near - far ) - near; +} + +// NOTE: https://twitter.com/gonnavis/status/1377183786949959682 + +float viewZToPerspectiveDepth( const in float viewZ, const in float near, const in float far ) { + // -near maps to 0; -far maps to 1 + return ( ( near + viewZ ) * far ) / ( ( far - near ) * viewZ ); +} + +float perspectiveDepthToViewZ( const in float depth, const in float near, const in float far ) { + // maps perspective depth in [ 0, 1 ] to viewZ + return ( near * far ) / ( ( far - near ) * depth - far ); +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/premultiplied_alpha_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/premultiplied_alpha_fragment.glsl.dart new file mode 100755 index 00000000..c64a39e9 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/premultiplied_alpha_fragment.glsl.dart @@ -0,0 +1,8 @@ +const String premultipliedAlphaFragment = """ +#ifdef PREMULTIPLIED_ALPHA + + // Get get normal blending with premultipled, use with CustomBlending, OneFactor, OneMinusSrcAlphaFactor, AddEquation. + gl_FragColor.rgb *= gl_FragColor.a; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/project_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/project_vertex.glsl.dart new file mode 100755 index 00000000..b4a1c6ef --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/project_vertex.glsl.dart @@ -0,0 +1,19 @@ +const String projectVertex = """ +vec4 mvPosition = vec4( transformed, 1.0 ); + +#ifdef USE_BATCHING + + mvPosition = batchingMatrix * mvPosition; + +#endif + +#ifdef USE_INSTANCING + + mvPosition = instanceMatrix * mvPosition; + +#endif + +mvPosition = modelViewMatrix * mvPosition; + +gl_Position = projectionMatrix * mvPosition; +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/roughnessmap_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/roughnessmap_fragment.glsl.dart new file mode 100755 index 00000000..104ef457 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/roughnessmap_fragment.glsl.dart @@ -0,0 +1,12 @@ +const String roughnessmapFragment = """ +float roughnessFactor = roughness; + +#ifdef USE_ROUGHNESSMAP + + vec4 texelRoughness = texture2D( roughnessMap, vRoughnessMapUv ); + + // reads channel G, compatible with a combined OcclusionRoughnessMetallic (RGB) texture + roughnessFactor *= texelRoughness.g; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/roughnessmap_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/roughnessmap_pars_fragment.glsl.dart new file mode 100755 index 00000000..87a244b7 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/roughnessmap_pars_fragment.glsl.dart @@ -0,0 +1,7 @@ +const String roughnessmapParsFragment = """ +#ifdef USE_ROUGHNESSMAP + + uniform sampler2D roughnessMap; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/shadowmap_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/shadowmap_pars_fragment.glsl.dart new file mode 100755 index 00000000..c01932c3 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/shadowmap_pars_fragment.glsl.dart @@ -0,0 +1,324 @@ +const String shadowmapParsFragment = """ +#if NUM_SPOT_LIGHT_COORDS > 0 + + varying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ]; + +#endif + +#if NUM_SPOT_LIGHT_MAPS > 0 + + uniform sampler2D spotLightMap[ NUM_SPOT_LIGHT_MAPS ]; + +#endif + +#ifdef USE_SHADOWMAP + + #if NUM_DIR_LIGHT_SHADOWS > 0 + + uniform sampler2D directionalShadowMap[ NUM_DIR_LIGHT_SHADOWS ]; + varying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ]; + + struct DirectionalLightShadow { + float shadowBias; + float shadowNormalBias; + float shadowRadius; + vec2 shadowMapSize; + }; + + uniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ]; + + #endif + + #if NUM_SPOT_LIGHT_SHADOWS > 0 + + uniform sampler2D spotShadowMap[ NUM_SPOT_LIGHT_SHADOWS ]; + + struct SpotLightShadow { + float shadowBias; + float shadowNormalBias; + float shadowRadius; + vec2 shadowMapSize; + }; + + uniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ]; + + #endif + + #if NUM_POINT_LIGHT_SHADOWS > 0 + + uniform sampler2D pointShadowMap[ NUM_POINT_LIGHT_SHADOWS ]; + varying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ]; + + struct PointLightShadow { + float shadowBias; + float shadowNormalBias; + float shadowRadius; + vec2 shadowMapSize; + float shadowCameraNear; + float shadowCameraFar; + }; + + uniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ]; + + #endif + + /* + #if NUM_RECT_AREA_LIGHTS > 0 + + // TODO (abelnation): create uniforms for area light shadows + + #endif + */ + + float texture2DCompare( sampler2D depths, vec2 uv, float compare ) { + + return step( compare, unpackRGBAToDepth( texture2D( depths, uv ) ) ); + + } + + vec2 texture2DDistribution( sampler2D shadow, vec2 uv ) { + + return unpackRGBATo2Half( texture2D( shadow, uv ) ); + + } + + float VSMShadow (sampler2D shadow, vec2 uv, float compare ){ + + float occlusion = 1.0; + + vec2 distribution = texture2DDistribution( shadow, uv ); + + float hard_shadow = step( compare , distribution.x ); // Hard Shadow + + if (hard_shadow != 1.0 ) { + + float distance = compare - distribution.x ; + float variance = max( 0.00000, distribution.y * distribution.y ); + float softness_probability = variance / (variance + distance * distance ); // Chebeyshevs inequality + softness_probability = clamp( ( softness_probability - 0.3 ) / ( 0.95 - 0.3 ), 0.0, 1.0 ); // 0.3 reduces light bleed + occlusion = clamp( max( hard_shadow, softness_probability ), 0.0, 1.0 ); + + } + return occlusion; + + } + + float getShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord ) { + + float shadow = 1.0; + + shadowCoord.xyz /= shadowCoord.w; + shadowCoord.z += shadowBias; + + bool inFrustum = shadowCoord.x >= 0.0 && shadowCoord.x <= 1.0 && shadowCoord.y >= 0.0 && shadowCoord.y <= 1.0; + bool frustumTest = inFrustum && shadowCoord.z <= 1.0; + + if ( frustumTest ) { + + #if defined( SHADOWMAP_TYPE_PCF ) + + vec2 texelSize = vec2( 1.0 ) / shadowMapSize; + + float dx0 = - texelSize.x * shadowRadius; + float dy0 = - texelSize.y * shadowRadius; + float dx1 = + texelSize.x * shadowRadius; + float dy1 = + texelSize.y * shadowRadius; + float dx2 = dx0 / 2.0; + float dy2 = dy0 / 2.0; + float dx3 = dx1 / 2.0; + float dy3 = dy1 / 2.0; + + shadow = ( + texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy0 ), shadowCoord.z ) + + texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy0 ), shadowCoord.z ) + + texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy0 ), shadowCoord.z ) + + texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy2 ), shadowCoord.z ) + + texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy2 ), shadowCoord.z ) + + texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy2 ), shadowCoord.z ) + + texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, 0.0 ), shadowCoord.z ) + + texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, 0.0 ), shadowCoord.z ) + + texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ) + + texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, 0.0 ), shadowCoord.z ) + + texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, 0.0 ), shadowCoord.z ) + + texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx2, dy3 ), shadowCoord.z ) + + texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy3 ), shadowCoord.z ) + + texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx3, dy3 ), shadowCoord.z ) + + texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx0, dy1 ), shadowCoord.z ) + + texture2DCompare( shadowMap, shadowCoord.xy + vec2( 0.0, dy1 ), shadowCoord.z ) + + texture2DCompare( shadowMap, shadowCoord.xy + vec2( dx1, dy1 ), shadowCoord.z ) + ) * ( 1.0 / 17.0 ); + + #elif defined( SHADOWMAP_TYPE_PCF_SOFT ) + + vec2 texelSize = vec2( 1.0 ) / shadowMapSize; + float dx = texelSize.x; + float dy = texelSize.y; + + vec2 uv = shadowCoord.xy; + vec2 f = fract( uv * shadowMapSize + 0.5 ); + uv -= f * texelSize; + + shadow = ( + texture2DCompare( shadowMap, uv, shadowCoord.z ) + + texture2DCompare( shadowMap, uv + vec2( dx, 0.0 ), shadowCoord.z ) + + texture2DCompare( shadowMap, uv + vec2( 0.0, dy ), shadowCoord.z ) + + texture2DCompare( shadowMap, uv + texelSize, shadowCoord.z ) + + mix( texture2DCompare( shadowMap, uv + vec2( -dx, 0.0 ), shadowCoord.z ), + texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 0.0 ), shadowCoord.z ), + f.x ) + + mix( texture2DCompare( shadowMap, uv + vec2( -dx, dy ), shadowCoord.z ), + texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, dy ), shadowCoord.z ), + f.x ) + + mix( texture2DCompare( shadowMap, uv + vec2( 0.0, -dy ), shadowCoord.z ), + texture2DCompare( shadowMap, uv + vec2( 0.0, 2.0 * dy ), shadowCoord.z ), + f.y ) + + mix( texture2DCompare( shadowMap, uv + vec2( dx, -dy ), shadowCoord.z ), + texture2DCompare( shadowMap, uv + vec2( dx, 2.0 * dy ), shadowCoord.z ), + f.y ) + + mix( mix( texture2DCompare( shadowMap, uv + vec2( -dx, -dy ), shadowCoord.z ), + texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, -dy ), shadowCoord.z ), + f.x ), + mix( texture2DCompare( shadowMap, uv + vec2( -dx, 2.0 * dy ), shadowCoord.z ), + texture2DCompare( shadowMap, uv + vec2( 2.0 * dx, 2.0 * dy ), shadowCoord.z ), + f.x ), + f.y ) + ) * ( 1.0 / 9.0 ); + + #elif defined( SHADOWMAP_TYPE_VSM ) + + shadow = VSMShadow( shadowMap, shadowCoord.xy, shadowCoord.z ); + + #else // no percentage-closer filtering: + + shadow = texture2DCompare( shadowMap, shadowCoord.xy, shadowCoord.z ); + + #endif + + } + + return shadow; + + } + + // cubeToUV() maps a 3D direction vector suitable for cube texture mapping to a 2D + // vector suitable for 2D texture mapping. This code uses the following layout for the + // 2D texture: + // + // xzXZ + // y Y + // + // Y - Positive y direction + // y - Negative y direction + // X - Positive x direction + // x - Negative x direction + // Z - Positive z direction + // z - Negative z direction + // + // Source and test bed: + // https://gist.github.com/tschw/da10c43c467ce8afd0c4 + + vec2 cubeToUV( vec3 v, float texelSizeY ) { + + // Number of texels to avoid at the edge of each square + + vec3 absV = abs( v ); + + // Intersect unit cube + + float scaleToCube = 1.0 / max( absV.x, max( absV.y, absV.z ) ); + absV *= scaleToCube; + + // Apply scale to avoid seams + + // two texels less per square (one texel will do for NEAREST) + v *= scaleToCube * ( 1.0 - 2.0 * texelSizeY ); + + // Unwrap + + // space: -1 ... 1 range for each square + // + // #X## dim := ( 4 , 2 ) + // # # center := ( 1 , 1 ) + + vec2 planar = v.xy; + + float almostATexel = 1.5 * texelSizeY; + float almostOne = 1.0 - almostATexel; + + if ( absV.z >= almostOne ) { + + if ( v.z > 0.0 ) + planar.x = 4.0 - v.x; + + } else if ( absV.x >= almostOne ) { + + float signX = sign( v.x ); + planar.x = v.z * signX + 2.0 * signX; + + } else if ( absV.y >= almostOne ) { + + float signY = sign( v.y ); + planar.x = v.x + 2.0 * signY + 2.0; + planar.y = v.z * signY - 2.0; + + } + + // Transform to UV space + + // scale := 0.5 / dim + // translate := ( center + 0.5 ) / dim + return vec2( 0.125, 0.25 ) * planar + vec2( 0.375, 0.75 ); + + } + + float getPointShadow( sampler2D shadowMap, vec2 shadowMapSize, float shadowBias, float shadowRadius, vec4 shadowCoord, float shadowCameraNear, float shadowCameraFar ) { + + float shadow = 1.0; + + // for point lights, the uniform @vShadowCoord is re-purposed to hold + // the vector from the light to the world-space position of the fragment. + vec3 lightToPosition = shadowCoord.xyz; + + float lightToPositionLength = length( lightToPosition ); + + if ( lightToPositionLength - shadowCameraFar <= 0.0 && lightToPositionLength - shadowCameraNear >= 0.0 ) { + + // dp = normalized distance from light to fragment position + float dp = ( lightToPositionLength - shadowCameraNear ) / ( shadowCameraFar - shadowCameraNear ); // need to clamp? + dp += shadowBias; + + // bd3D = base direction 3D + vec3 bd3D = normalize( lightToPosition ); + + vec2 texelSize = vec2( 1.0 ) / ( shadowMapSize * vec2( 4.0, 2.0 ) ); + + #if defined( SHADOWMAP_TYPE_PCF ) || defined( SHADOWMAP_TYPE_PCF_SOFT ) || defined( SHADOWMAP_TYPE_VSM ) + + vec2 offset = vec2( - 1, 1 ) * shadowRadius * texelSize.y; + + shadow = ( + texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyy, texelSize.y ), dp ) + + texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyy, texelSize.y ), dp ) + + texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xyx, texelSize.y ), dp ) + + texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yyx, texelSize.y ), dp ) + + texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ) + + texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxy, texelSize.y ), dp ) + + texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxy, texelSize.y ), dp ) + + texture2DCompare( shadowMap, cubeToUV( bd3D + offset.xxx, texelSize.y ), dp ) + + texture2DCompare( shadowMap, cubeToUV( bd3D + offset.yxx, texelSize.y ), dp ) + ) * ( 1.0 / 9.0 ); + + #else // no percentage-closer filtering + + shadow = texture2DCompare( shadowMap, cubeToUV( bd3D, texelSize.y ), dp ); + + #endif + + } + + return shadow; + + } + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/shadowmap_pars_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/shadowmap_pars_vertex.glsl.dart new file mode 100755 index 00000000..748ee2a8 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/shadowmap_pars_vertex.glsl.dart @@ -0,0 +1,67 @@ +const String shadowmapParsVertex = """ +#if NUM_SPOT_LIGHT_COORDS > 0 + + uniform mat4 spotLightMatrix[ NUM_SPOT_LIGHT_COORDS ]; + varying vec4 vSpotLightCoord[ NUM_SPOT_LIGHT_COORDS ]; + +#endif + +#ifdef USE_SHADOWMAP + + #if NUM_DIR_LIGHT_SHADOWS > 0 + + uniform mat4 directionalShadowMatrix[ NUM_DIR_LIGHT_SHADOWS ]; + varying vec4 vDirectionalShadowCoord[ NUM_DIR_LIGHT_SHADOWS ]; + + struct DirectionalLightShadow { + float shadowBias; + float shadowNormalBias; + float shadowRadius; + vec2 shadowMapSize; + }; + + uniform DirectionalLightShadow directionalLightShadows[ NUM_DIR_LIGHT_SHADOWS ]; + + #endif + + #if NUM_SPOT_LIGHT_SHADOWS > 0 + + struct SpotLightShadow { + float shadowBias; + float shadowNormalBias; + float shadowRadius; + vec2 shadowMapSize; + }; + + uniform SpotLightShadow spotLightShadows[ NUM_SPOT_LIGHT_SHADOWS ]; + + #endif + + #if NUM_POINT_LIGHT_SHADOWS > 0 + + uniform mat4 pointShadowMatrix[ NUM_POINT_LIGHT_SHADOWS ]; + varying vec4 vPointShadowCoord[ NUM_POINT_LIGHT_SHADOWS ]; + + struct PointLightShadow { + float shadowBias; + float shadowNormalBias; + float shadowRadius; + vec2 shadowMapSize; + float shadowCameraNear; + float shadowCameraFar; + }; + + uniform PointLightShadow pointLightShadows[ NUM_POINT_LIGHT_SHADOWS ]; + + #endif + + /* + #if NUM_RECT_AREA_LIGHTS > 0 + + // TODO (abelnation): uniforms for area light shadows + + #endif + */ + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/shadowmap_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/shadowmap_vertex.glsl.dart new file mode 100755 index 00000000..340e8207 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/shadowmap_vertex.glsl.dart @@ -0,0 +1,65 @@ +const String shadowmapVertex = """ +#if ( defined( USE_SHADOWMAP ) && ( NUM_DIR_LIGHT_SHADOWS > 0 || NUM_POINT_LIGHT_SHADOWS > 0 ) ) || ( NUM_SPOT_LIGHT_COORDS > 0 ) + + // Offsetting the position used for querying occlusion along the world normal can be used to reduce shadow acne. + vec3 shadowWorldNormal = inverseTransformDirection( transformedNormal, viewMatrix ); + vec4 shadowWorldPosition; + +#endif + +#if defined( USE_SHADOWMAP ) + + #if NUM_DIR_LIGHT_SHADOWS > 0 + + #pragma unroll_loop_start + for ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) { + + shadowWorldPosition = worldPosition + vec4( shadowWorldNormal * directionalLightShadows[ i ].shadowNormalBias, 0 ); + vDirectionalShadowCoord[ i ] = directionalShadowMatrix[ i ] * shadowWorldPosition; + + } + #pragma unroll_loop_end + + #endif + + #if NUM_POINT_LIGHT_SHADOWS > 0 + + #pragma unroll_loop_start + for ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) { + + shadowWorldPosition = worldPosition + vec4( shadowWorldNormal * pointLightShadows[ i ].shadowNormalBias, 0 ); + vPointShadowCoord[ i ] = pointShadowMatrix[ i ] * shadowWorldPosition; + + } + #pragma unroll_loop_end + + #endif + + /* + #if NUM_RECT_AREA_LIGHTS > 0 + + // TODO (abelnation): update vAreaShadowCoord with area light info + + #endif + */ + +#endif + +// spot lights can be evaluated without active shadow mapping (when SpotLight.map is used) + +#if NUM_SPOT_LIGHT_COORDS > 0 + + #pragma unroll_loop_start + for ( int i = 0; i < NUM_SPOT_LIGHT_COORDS; i ++ ) { + + shadowWorldPosition = worldPosition; + #if ( defined( USE_SHADOWMAP ) && UNROLLED_LOOP_INDEX < NUM_SPOT_LIGHT_SHADOWS ) + shadowWorldPosition.xyz += shadowWorldNormal * spotLightShadows[ i ].shadowNormalBias; + #endif + vSpotLightCoord[ i ] = spotLightMatrix[ i ] * shadowWorldPosition; + + } + #pragma unroll_loop_end + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/shadowmask_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/shadowmask_pars_fragment.glsl.dart new file mode 100755 index 00000000..a084792f --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/shadowmask_pars_fragment.glsl.dart @@ -0,0 +1,66 @@ +const String shadowmaskParsFragment = """ +float getShadowMask() { + + float shadow = 1.0; + + #ifdef USE_SHADOWMAP + + #if NUM_DIR_LIGHT_SHADOWS > 0 + + DirectionalLightShadow directionalLight; + + #pragma unroll_loop_start + for ( int i = 0; i < NUM_DIR_LIGHT_SHADOWS; i ++ ) { + + directionalLight = directionalLightShadows[ i ]; + shadow *= receiveShadow ? getShadow( directionalShadowMap[ i ], directionalLight.shadowMapSize, directionalLight.shadowBias, directionalLight.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0; + + } + #pragma unroll_loop_end + + #endif + + #if NUM_SPOT_LIGHT_SHADOWS > 0 + + SpotLightShadow spotLight; + + #pragma unroll_loop_start + for ( int i = 0; i < NUM_SPOT_LIGHT_SHADOWS; i ++ ) { + + spotLight = spotLightShadows[ i ]; + shadow *= receiveShadow ? getShadow( spotShadowMap[ i ], spotLight.shadowMapSize, spotLight.shadowBias, spotLight.shadowRadius, vSpotLightCoord[ i ] ) : 1.0; + + } + #pragma unroll_loop_end + + #endif + + #if NUM_POINT_LIGHT_SHADOWS > 0 + + PointLightShadow pointLight; + + #pragma unroll_loop_start + for ( int i = 0; i < NUM_POINT_LIGHT_SHADOWS; i ++ ) { + + pointLight = pointLightShadows[ i ]; + shadow *= receiveShadow ? getPointShadow( pointShadowMap[ i ], pointLight.shadowMapSize, pointLight.shadowBias, pointLight.shadowRadius, vPointShadowCoord[ i ], pointLight.shadowCameraNear, pointLight.shadowCameraFar ) : 1.0; + + } + #pragma unroll_loop_end + + #endif + + /* + #if NUM_RECT_AREA_LIGHTS > 0 + + // TODO (abelnation): update shadow for Area light + + #endif + */ + + #endif + + return shadow; + +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/skinbase_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/skinbase_vertex.glsl.dart new file mode 100755 index 00000000..b81c7024 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/skinbase_vertex.glsl.dart @@ -0,0 +1,10 @@ +const String skinbaseVertex = """ +#ifdef USE_SKINNING + + mat4 boneMatX = getBoneMatrix( skinIndex.x ); + mat4 boneMatY = getBoneMatrix( skinIndex.y ); + mat4 boneMatZ = getBoneMatrix( skinIndex.z ); + mat4 boneMatW = getBoneMatrix( skinIndex.w ); + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/skinning_pars_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/skinning_pars_vertex.glsl.dart new file mode 100755 index 00000000..0a1df450 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/skinning_pars_vertex.glsl.dart @@ -0,0 +1,25 @@ +const String skinningParsVertex = """ +#ifdef USE_SKINNING + + uniform mat4 bindMatrix; + uniform mat4 bindMatrixInverse; + + uniform highp sampler2D boneTexture; + + mat4 getBoneMatrix( const in float i ) { + + int size = textureSize( boneTexture, 0 ).x; + int j = int( i ) * 4; + int x = j % size; + int y = j / size; + vec4 v1 = texelFetch( boneTexture, ivec2( x, y ), 0 ); + vec4 v2 = texelFetch( boneTexture, ivec2( x + 1, y ), 0 ); + vec4 v3 = texelFetch( boneTexture, ivec2( x + 2, y ), 0 ); + vec4 v4 = texelFetch( boneTexture, ivec2( x + 3, y ), 0 ); + + return mat4( v1, v2, v3, v4 ); + + } + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/skinning_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/skinning_vertex.glsl.dart new file mode 100755 index 00000000..42cf7a96 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/skinning_vertex.glsl.dart @@ -0,0 +1,15 @@ +const String skinningVertex = """ +#ifdef USE_SKINNING + + vec4 skinVertex = bindMatrix * vec4( transformed, 1.0 ); + + vec4 skinned = vec4( 0.0 ); + skinned += boneMatX * skinVertex * skinWeight.x; + skinned += boneMatY * skinVertex * skinWeight.y; + skinned += boneMatZ * skinVertex * skinWeight.z; + skinned += boneMatW * skinVertex * skinWeight.w; + + transformed = ( bindMatrixInverse * skinned ).xyz; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/skinnormal_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/skinnormal_vertex.glsl.dart new file mode 100755 index 00000000..3f72e489 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/skinnormal_vertex.glsl.dart @@ -0,0 +1,20 @@ +const String skinnormalVertex = """ +#ifdef USE_SKINNING + + mat4 skinMatrix = mat4( 0.0 ); + skinMatrix += skinWeight.x * boneMatX; + skinMatrix += skinWeight.y * boneMatY; + skinMatrix += skinWeight.z * boneMatZ; + skinMatrix += skinWeight.w * boneMatW; + skinMatrix = bindMatrixInverse * skinMatrix * bindMatrix; + + objectNormal = vec4( skinMatrix * vec4( objectNormal, 0.0 ) ).xyz; + + #ifdef USE_TANGENT + + objectTangent = vec4( skinMatrix * vec4( objectTangent, 0.0 ) ).xyz; + + #endif + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/specularmap_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/specularmap_fragment.glsl.dart new file mode 100755 index 00000000..fa66d0c3 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/specularmap_fragment.glsl.dart @@ -0,0 +1,14 @@ +const String specularmapFragment = """ +float specularStrength; + +#ifdef USE_SPECULARMAP + + vec4 texelSpecular = texture2D( specularMap, vSpecularMapUv ); + specularStrength = texelSpecular.r; + +#else + + specularStrength = 1.0; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/specularmap_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/specularmap_pars_fragment.glsl.dart new file mode 100755 index 00000000..6ef93d08 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/specularmap_pars_fragment.glsl.dart @@ -0,0 +1,7 @@ +const String specularmapParsFragment = """ +#ifdef USE_SPECULARMAP + + uniform sampler2D specularMap; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/tonemapping_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/tonemapping_fragment.glsl.dart new file mode 100755 index 00000000..3b16b013 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/tonemapping_fragment.glsl.dart @@ -0,0 +1,7 @@ +const String tonemappingFragment = """ +#if defined( TONE_MAPPING ) + + gl_FragColor.rgb = toneMapping( gl_FragColor.rgb ); + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/tonemapping_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/tonemapping_pars_fragment.glsl.dart new file mode 100755 index 00000000..cccf6ff7 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/tonemapping_pars_fragment.glsl.dart @@ -0,0 +1,200 @@ +const String tonemappingParsFragment = """ +#ifndef saturate +// may have defined saturate() already +#define saturate( a ) clamp( a, 0.0, 1.0 ) +#endif + +uniform float toneMappingExposure; + +// exposure only +vec3 LinearToneMapping( vec3 color ) { + + return saturate( toneMappingExposure * color ); + +} + +// source: https://www.cs.utah.edu/docs/techreports/2002/pdf/UUCS-02-001.pdf +vec3 ReinhardToneMapping( vec3 color ) { + + color *= toneMappingExposure; + return saturate( color / ( vec3( 1.0 ) + color ) ); + +} + +// source: http://filmicworlds.com/blog/filmic-tonemapping-operators/ +vec3 OptimizedCineonToneMapping( vec3 color ) { + + // optimized filmic operator by Jim Hejl and Richard Burgess-Dawson + color *= toneMappingExposure; + color = max( vec3( 0.0 ), color - 0.004 ); + return pow( ( color * ( 6.2 * color + 0.5 ) ) / ( color * ( 6.2 * color + 1.7 ) + 0.06 ), vec3( 2.2 ) ); + +} + +// source: https://github.com/selfshadow/ltc_code/blob/master/webgl/shaders/ltc/ltc_blit.fs +vec3 RRTAndODTFit( vec3 v ) { + + vec3 a = v * ( v + 0.0245786 ) - 0.000090537; + vec3 b = v * ( 0.983729 * v + 0.4329510 ) + 0.238081; + return a / b; + +} + +// this implementation of ACES is modified to accommodate a brighter viewing environment. +// the scale factor of 1/0.6 is subjective. see discussion in #19621. + +vec3 ACESFilmicToneMapping( vec3 color ) { + + // sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT + const mat3 ACESInputMat = mat3( + vec3( 0.59719, 0.07600, 0.02840 ), // transposed from source + vec3( 0.35458, 0.90834, 0.13383 ), + vec3( 0.04823, 0.01566, 0.83777 ) + ); + + // ODT_SAT => XYZ => D60_2_D65 => sRGB + const mat3 ACESOutputMat = mat3( + vec3( 1.60475, -0.10208, -0.00327 ), // transposed from source + vec3( -0.53108, 1.10813, -0.07276 ), + vec3( -0.07367, -0.00605, 1.07602 ) + ); + + color *= toneMappingExposure / 0.6; + + color = ACESInputMat * color; + + // Apply RRT and ODT + color = RRTAndODTFit( color ); + + color = ACESOutputMat * color; + + // Clamp to [0, 1] + return saturate( color ); + +} + +// Matrices for rec 2020 <> rec 709 color space conversion +// matrix provided in row-major order so it has been transposed +// https://www.itu.int/pub/R-REP-BT.2407-2017 +const mat3 LINEAR_REC2020_TO_LINEAR_SRGB = mat3( + vec3( 1.6605, - 0.1246, - 0.0182 ), + vec3( - 0.5876, 1.1329, - 0.1006 ), + vec3( - 0.0728, - 0.0083, 1.1187 ) +); + +const mat3 LINEAR_SRGB_TO_LINEAR_REC2020 = mat3( + vec3( 0.6274, 0.0691, 0.0164 ), + vec3( 0.3293, 0.9195, 0.0880 ), + vec3( 0.0433, 0.0113, 0.8956 ) +); + +// https://iolite-engine.com/blog_posts/minimal_agx_implementation +// Mean error^2: 3.6705141e-06 +vec3 agxDefaultContrastApprox( vec3 x ) { + + vec3 x2 = x * x; + vec3 x4 = x2 * x2; + + return + 15.5 * x4 * x2 + - 40.14 * x4 * x + + 31.96 * x4 + - 6.868 * x2 * x + + 0.4298 * x2 + + 0.1191 * x + - 0.00232; + +} + +// AgX Tone Mapping implementation based on Filament, which in turn is based +// on Blender's implementation using rec 2020 primaries +// https://github.com/google/filament/pull/7236 +// Inputs and outputs are encoded as Linear-sRGB. + +vec3 AgXToneMapping( vec3 color ) { + + // AgX constants + const mat3 AgXInsetMatrix = mat3( + vec3( 0.856627153315983, 0.137318972929847, 0.11189821299995 ), + vec3( 0.0951212405381588, 0.761241990602591, 0.0767994186031903 ), + vec3( 0.0482516061458583, 0.101439036467562, 0.811302368396859 ) + ); + + // explicit AgXOutsetMatrix generated from Filaments AgXOutsetMatrixInv + const mat3 AgXOutsetMatrix = mat3( + vec3( 1.1271005818144368, - 0.1413297634984383, - 0.14132976349843826 ), + vec3( - 0.11060664309660323, 1.157823702216272, - 0.11060664309660294 ), + vec3( - 0.016493938717834573, - 0.016493938717834257, 1.2519364065950405 ) + ); + + // LOG2_MIN = -10.0 + // LOG2_MAX = +6.5 + // MIDDLE_GRAY = 0.18 + const float AgxMinEv = - 12.47393; // log2( pow( 2, LOG2_MIN ) * MIDDLE_GRAY ) + const float AgxMaxEv = 4.026069; // log2( pow( 2, LOG2_MAX ) * MIDDLE_GRAY ) + + color *= toneMappingExposure; + + color = LINEAR_SRGB_TO_LINEAR_REC2020 * color; + + color = AgXInsetMatrix * color; + + // Log2 encoding + color = max( color, 1e-10 ); // avoid 0 or negative numbers for log2 + color = log2( color ); + color = ( color - AgxMinEv ) / ( AgxMaxEv - AgxMinEv ); + + color = clamp( color, 0.0, 1.0 ); + + // Apply sigmoid + color = agxDefaultContrastApprox( color ); + + // Apply AgX look + // v = agxLook(v, look); + + color = AgXOutsetMatrix * color; + + // Linearize + color = pow( max( vec3( 0.0 ), color ), vec3( 2.2 ) ); + + color = LINEAR_REC2020_TO_LINEAR_SRGB * color; + + // Gamut mapping. Simple clamp for now. + color = clamp( color, 0.0, 1.0 ); + + return color; + +} + +// https://modelviewer.dev/examples/tone-mapping + +vec3 NeutralToneMapping( vec3 color ) { + + const float StartCompression = 0.8 - 0.04; + const float Desaturation = 0.15; + + color *= toneMappingExposure; + + float x = min( color.r, min( color.g, color.b ) ); + + float offset = x < 0.08 ? x - 6.25 * x * x : 0.04; + + color -= offset; + + float peak = max( color.r, max( color.g, color.b ) ); + + if ( peak < StartCompression ) return color; + + float d = 1. - StartCompression; + + float newPeak = 1. - d * d / ( peak + d - StartCompression ); + + color *= newPeak / peak; + + float g = 1. - 1. / ( Desaturation * ( peak - newPeak ) + 1. ); + + return mix( color, vec3( newPeak ), g ); + +} + +vec3 CustomToneMapping( vec3 color ) { return color; } +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/transmission_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/transmission_fragment.glsl.dart new file mode 100755 index 00000000..4f7872e4 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/transmission_fragment.glsl.dart @@ -0,0 +1,36 @@ +const String transmissionFragment = """ +#ifdef USE_TRANSMISSION + + material.transmission = transmission; + material.transmissionAlpha = 1.0; + material.thickness = thickness; + material.attenuationDistance = attenuationDistance; + material.attenuationColor = attenuationColor; + + #ifdef USE_TRANSMISSIONMAP + + material.transmission *= texture2D( transmissionMap, vTransmissionMapUv ).r; + + #endif + + #ifdef USE_THICKNESSMAP + + material.thickness *= texture2D( thicknessMap, vThicknessMapUv ).g; + + #endif + + vec3 pos = vWorldPosition; + vec3 v = normalize( cameraPosition - pos ); + vec3 n = inverseTransformDirection( normal, viewMatrix ); + + vec4 transmitted = getIBLVolumeRefraction( + n, v, material.roughness, material.diffuseColor, material.specularColor, material.specularF90, + pos, modelMatrix, viewMatrix, projectionMatrix, material.dispersion, material.ior, material.thickness, + material.attenuationColor, material.attenuationDistance ); + + material.transmissionAlpha = mix( material.transmissionAlpha, transmitted.a, material.transmission ); + + totalDiffuse = mix( totalDiffuse, transmitted.rgb, material.transmission ); + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/transmission_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/transmission_pars_fragment.glsl.dart new file mode 100755 index 00000000..01faa46c --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/transmission_pars_fragment.glsl.dart @@ -0,0 +1,235 @@ +const String transmissionParsFragment = """ +#ifdef USE_TRANSMISSION + + // Transmission code is based on glTF-Sampler-Viewer + // https://github.com/KhronosGroup/glTF-Sample-Viewer + + uniform float transmission; + uniform float thickness; + uniform float attenuationDistance; + uniform vec3 attenuationColor; + + #ifdef USE_TRANSMISSIONMAP + + uniform sampler2D transmissionMap; + + #endif + + #ifdef USE_THICKNESSMAP + + uniform sampler2D thicknessMap; + + #endif + + uniform vec2 transmissionSamplerSize; + uniform sampler2D transmissionSamplerMap; + + uniform mat4 modelMatrix; + uniform mat4 projectionMatrix; + + varying vec3 vWorldPosition; + + // Mipped Bicubic Texture Filtering by N8 + // https://www.shadertoy.com/view/Dl2SDW + + float w0( float a ) { + + return ( 1.0 / 6.0 ) * ( a * ( a * ( - a + 3.0 ) - 3.0 ) + 1.0 ); + + } + + float w1( float a ) { + + return ( 1.0 / 6.0 ) * ( a * a * ( 3.0 * a - 6.0 ) + 4.0 ); + + } + + float w2( float a ){ + + return ( 1.0 / 6.0 ) * ( a * ( a * ( - 3.0 * a + 3.0 ) + 3.0 ) + 1.0 ); + + } + + float w3( float a ) { + + return ( 1.0 / 6.0 ) * ( a * a * a ); + + } + + // g0 and g1 are the two amplitude functions + float g0( float a ) { + + return w0( a ) + w1( a ); + + } + + float g1( float a ) { + + return w2( a ) + w3( a ); + + } + + // h0 and h1 are the two offset functions + float h0( float a ) { + + return - 1.0 + w1( a ) / ( w0( a ) + w1( a ) ); + + } + + float h1( float a ) { + + return 1.0 + w3( a ) / ( w2( a ) + w3( a ) ); + + } + + vec4 bicubic( sampler2D tex, vec2 uv, vec4 texelSize, float lod ) { + + uv = uv * texelSize.zw + 0.5; + + vec2 iuv = floor( uv ); + vec2 fuv = fract( uv ); + + float g0x = g0( fuv.x ); + float g1x = g1( fuv.x ); + float h0x = h0( fuv.x ); + float h1x = h1( fuv.x ); + float h0y = h0( fuv.y ); + float h1y = h1( fuv.y ); + + vec2 p0 = ( vec2( iuv.x + h0x, iuv.y + h0y ) - 0.5 ) * texelSize.xy; + vec2 p1 = ( vec2( iuv.x + h1x, iuv.y + h0y ) - 0.5 ) * texelSize.xy; + vec2 p2 = ( vec2( iuv.x + h0x, iuv.y + h1y ) - 0.5 ) * texelSize.xy; + vec2 p3 = ( vec2( iuv.x + h1x, iuv.y + h1y ) - 0.5 ) * texelSize.xy; + + return g0( fuv.y ) * ( g0x * textureLod( tex, p0, lod ) + g1x * textureLod( tex, p1, lod ) ) + + g1( fuv.y ) * ( g0x * textureLod( tex, p2, lod ) + g1x * textureLod( tex, p3, lod ) ); + + } + + vec4 textureBicubic( sampler2D sampler, vec2 uv, float lod ) { + + vec2 fLodSize = vec2( textureSize( sampler, int( lod ) ) ); + vec2 cLodSize = vec2( textureSize( sampler, int( lod + 1.0 ) ) ); + vec2 fLodSizeInv = 1.0 / fLodSize; + vec2 cLodSizeInv = 1.0 / cLodSize; + vec4 fSample = bicubic( sampler, uv, vec4( fLodSizeInv, fLodSize ), floor( lod ) ); + vec4 cSample = bicubic( sampler, uv, vec4( cLodSizeInv, cLodSize ), ceil( lod ) ); + return mix( fSample, cSample, fract( lod ) ); + + } + + vec3 getVolumeTransmissionRay( const in vec3 n, const in vec3 v, const in float thickness, const in float ior, const in mat4 modelMatrix ) { + + // Direction of refracted light. + vec3 refractionVector = refract( - v, normalize( n ), 1.0 / ior ); + + // Compute rotation-independant scaling of the model matrix. + vec3 modelScale; + modelScale.x = length( vec3( modelMatrix[ 0 ].xyz ) ); + modelScale.y = length( vec3( modelMatrix[ 1 ].xyz ) ); + modelScale.z = length( vec3( modelMatrix[ 2 ].xyz ) ); + + // The thickness is specified in local space. + return normalize( refractionVector ) * thickness * modelScale; + + } + + float applyIorToRoughness( const in float roughness, const in float ior ) { + + // Scale roughness with IOR so that an IOR of 1.0 results in no microfacet refraction and + // an IOR of 1.5 results in the default amount of microfacet refraction. + return roughness * clamp( ior * 2.0 - 2.0, 0.0, 1.0 ); + + } + + vec4 getTransmissionSample( const in vec2 fragCoord, const in float roughness, const in float ior ) { + + float lod = log2( transmissionSamplerSize.x ) * applyIorToRoughness( roughness, ior ); + return textureBicubic( transmissionSamplerMap, fragCoord.xy, lod ); + + } + + vec3 volumeAttenuation( const in float transmissionDistance, const in vec3 attenuationColor, const in float attenuationDistance ) { + + if ( isinf( attenuationDistance ) ) { + + // Attenuation distance is +∞, i.e. the transmitted color is not attenuated at all. + return vec3( 1.0 ); + + } else { + + // Compute light attenuation using Beer's law. + vec3 attenuationCoefficient = -log( attenuationColor ) / attenuationDistance; + vec3 transmittance = exp( - attenuationCoefficient * transmissionDistance ); // Beer's law + return transmittance; + + } + + } + + vec4 getIBLVolumeRefraction( const in vec3 n, const in vec3 v, const in float roughness, const in vec3 diffuseColor, + const in vec3 specularColor, const in float specularF90, const in vec3 position, const in mat4 modelMatrix, + const in mat4 viewMatrix, const in mat4 projMatrix, const in float dispersion, const in float ior, const in float thickness, + const in vec3 attenuationColor, const in float attenuationDistance ) { + + vec4 transmittedLight; + vec3 transmittance; + + #ifdef USE_DISPERSION + + float halfSpread = ( ior - 1.0 ) * 0.025 * dispersion; + vec3 iors = vec3( ior - halfSpread, ior, ior + halfSpread ); + + for ( int i = 0; i < 3; i ++ ) { + + vec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, iors[ i ], modelMatrix ); + vec3 refractedRayExit = position + transmissionRay; + + // Project refracted vector on the framebuffer, while mapping to normalized device coordinates. + vec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 ); + vec2 refractionCoords = ndcPos.xy / ndcPos.w; + refractionCoords += 1.0; + refractionCoords /= 2.0; + + // Sample framebuffer to get pixel the refracted ray hits. + vec4 transmissionSample = getTransmissionSample( refractionCoords, roughness, iors[ i ] ); + transmittedLight[ i ] = transmissionSample[ i ]; + transmittedLight.a += transmissionSample.a; + + transmittance[ i ] = diffuseColor[ i ] * volumeAttenuation( length( transmissionRay ), attenuationColor, attenuationDistance )[ i ]; + + } + + transmittedLight.a /= 3.0; + + #else + + vec3 transmissionRay = getVolumeTransmissionRay( n, v, thickness, ior, modelMatrix ); + vec3 refractedRayExit = position + transmissionRay; + + // Project refracted vector on the framebuffer, while mapping to normalized device coordinates. + vec4 ndcPos = projMatrix * viewMatrix * vec4( refractedRayExit, 1.0 ); + vec2 refractionCoords = ndcPos.xy / ndcPos.w; + refractionCoords += 1.0; + refractionCoords /= 2.0; + + // Sample framebuffer to get pixel the refracted ray hits. + transmittedLight = getTransmissionSample( refractionCoords, roughness, ior ); + transmittance = diffuseColor * volumeAttenuation( length( transmissionRay ), attenuationColor, attenuationDistance ); + + #endif + + vec3 attenuatedColor = transmittance * transmittedLight.rgb; + + // Get the specular component. + vec3 F = EnvironmentBRDF( n, v, specularColor, specularF90, roughness ); + + // As less light is transmitted, the opacity should be increased. This simple approximation does a decent job + // of modulating a CSS background, and has no effect when the buffer is opaque, due to a solid object or clear color. + float transmittanceFactor = ( transmittance.r + transmittance.g + transmittance.b ) / 3.0; + + return vec4( ( 1.0 - F ) * attenuatedColor, 1.0 - ( 1.0 - transmittedLight.a ) * transmittanceFactor ); + + } +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/uv2_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/uv2_pars_fragment.glsl.dart new file mode 100644 index 00000000..d108e4e8 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/uv2_pars_fragment.glsl.dart @@ -0,0 +1,7 @@ +const String uv2ParsFragment = """ +#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP ) + + varying vec2 vUv2; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/uv2_pars_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/uv2_pars_vertex.glsl.dart new file mode 100644 index 00000000..a5f41ed5 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/uv2_pars_vertex.glsl.dart @@ -0,0 +1,10 @@ +const String uv2ParsVertex = """ +#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP ) + + attribute vec2 uv2; + varying vec2 vUv2; + + uniform mat3 uv2Transform; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/uv2_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/uv2_vertex.glsl.dart new file mode 100644 index 00000000..f18f8165 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/uv2_vertex.glsl.dart @@ -0,0 +1,7 @@ +const String uv2Vertex = """ +#if defined( USE_LIGHTMAP ) || defined( USE_AOMAP ) + + vUv2 = ( uv2Transform * vec3( uv2, 1 ) ).xy; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/uv_pars_fragment.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/uv_pars_fragment.glsl.dart new file mode 100755 index 00000000..72e7d72f --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/uv_pars_fragment.glsl.dart @@ -0,0 +1,119 @@ +const String uvParsFragment = """ +#if defined( USE_UV ) || defined( USE_ANISOTROPY ) + + varying vec2 vUv; + +#endif +#ifdef USE_MAP + + varying vec2 vMapUv; + +#endif +#ifdef USE_ALPHAMAP + + varying vec2 vAlphaMapUv; + +#endif +#ifdef USE_LIGHTMAP + + varying vec2 vLightMapUv; + +#endif +#ifdef USE_AOMAP + + varying vec2 vAoMapUv; + +#endif +#ifdef USE_BUMPMAP + + varying vec2 vBumpMapUv; + +#endif +#ifdef USE_NORMALMAP + + varying vec2 vNormalMapUv; + +#endif +#ifdef USE_EMISSIVEMAP + + varying vec2 vEmissiveMapUv; + +#endif +#ifdef USE_METALNESSMAP + + varying vec2 vMetalnessMapUv; + +#endif +#ifdef USE_ROUGHNESSMAP + + varying vec2 vRoughnessMapUv; + +#endif +#ifdef USE_ANISOTROPYMAP + + varying vec2 vAnisotropyMapUv; + +#endif +#ifdef USE_CLEARCOATMAP + + varying vec2 vClearcoatMapUv; + +#endif +#ifdef USE_CLEARCOAT_NORMALMAP + + varying vec2 vClearcoatNormalMapUv; + +#endif +#ifdef USE_CLEARCOAT_ROUGHNESSMAP + + varying vec2 vClearcoatRoughnessMapUv; + +#endif +#ifdef USE_IRIDESCENCEMAP + + varying vec2 vIridescenceMapUv; + +#endif +#ifdef USE_IRIDESCENCE_THICKNESSMAP + + varying vec2 vIridescenceThicknessMapUv; + +#endif +#ifdef USE_SHEEN_COLORMAP + + varying vec2 vSheenColorMapUv; + +#endif +#ifdef USE_SHEEN_ROUGHNESSMAP + + varying vec2 vSheenRoughnessMapUv; + +#endif +#ifdef USE_SPECULARMAP + + varying vec2 vSpecularMapUv; + +#endif +#ifdef USE_SPECULAR_COLORMAP + + varying vec2 vSpecularColorMapUv; + +#endif +#ifdef USE_SPECULAR_INTENSITYMAP + + varying vec2 vSpecularIntensityMapUv; + +#endif +#ifdef USE_TRANSMISSIONMAP + + uniform mat3 transmissionMapTransform; + varying vec2 vTransmissionMapUv; + +#endif +#ifdef USE_THICKNESSMAP + + uniform mat3 thicknessMapTransform; + varying vec2 vThicknessMapUv; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/uv_pars_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/uv_pars_vertex.glsl.dart new file mode 100755 index 00000000..cbefef18 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/uv_pars_vertex.glsl.dart @@ -0,0 +1,145 @@ +const String uvParsVertex = """ +#if defined( USE_UV ) || defined( USE_ANISOTROPY ) + + varying vec2 vUv; + +#endif +#ifdef USE_MAP + + uniform mat3 mapTransform; + varying vec2 vMapUv; + +#endif +#ifdef USE_ALPHAMAP + + uniform mat3 alphaMapTransform; + varying vec2 vAlphaMapUv; + +#endif +#ifdef USE_LIGHTMAP + + uniform mat3 lightMapTransform; + varying vec2 vLightMapUv; + +#endif +#ifdef USE_AOMAP + + uniform mat3 aoMapTransform; + varying vec2 vAoMapUv; + +#endif +#ifdef USE_BUMPMAP + + uniform mat3 bumpMapTransform; + varying vec2 vBumpMapUv; + +#endif +#ifdef USE_NORMALMAP + + uniform mat3 normalMapTransform; + varying vec2 vNormalMapUv; + +#endif +#ifdef USE_DISPLACEMENTMAP + + uniform mat3 displacementMapTransform; + varying vec2 vDisplacementMapUv; + +#endif +#ifdef USE_EMISSIVEMAP + + uniform mat3 emissiveMapTransform; + varying vec2 vEmissiveMapUv; + +#endif +#ifdef USE_METALNESSMAP + + uniform mat3 metalnessMapTransform; + varying vec2 vMetalnessMapUv; + +#endif +#ifdef USE_ROUGHNESSMAP + + uniform mat3 roughnessMapTransform; + varying vec2 vRoughnessMapUv; + +#endif +#ifdef USE_ANISOTROPYMAP + + uniform mat3 anisotropyMapTransform; + varying vec2 vAnisotropyMapUv; + +#endif +#ifdef USE_CLEARCOATMAP + + uniform mat3 clearcoatMapTransform; + varying vec2 vClearcoatMapUv; + +#endif +#ifdef USE_CLEARCOAT_NORMALMAP + + uniform mat3 clearcoatNormalMapTransform; + varying vec2 vClearcoatNormalMapUv; + +#endif +#ifdef USE_CLEARCOAT_ROUGHNESSMAP + + uniform mat3 clearcoatRoughnessMapTransform; + varying vec2 vClearcoatRoughnessMapUv; + +#endif +#ifdef USE_SHEEN_COLORMAP + + uniform mat3 sheenColorMapTransform; + varying vec2 vSheenColorMapUv; + +#endif +#ifdef USE_SHEEN_ROUGHNESSMAP + + uniform mat3 sheenRoughnessMapTransform; + varying vec2 vSheenRoughnessMapUv; + +#endif +#ifdef USE_IRIDESCENCEMAP + + uniform mat3 iridescenceMapTransform; + varying vec2 vIridescenceMapUv; + +#endif +#ifdef USE_IRIDESCENCE_THICKNESSMAP + + uniform mat3 iridescenceThicknessMapTransform; + varying vec2 vIridescenceThicknessMapUv; + +#endif +#ifdef USE_SPECULARMAP + + uniform mat3 specularMapTransform; + varying vec2 vSpecularMapUv; + +#endif +#ifdef USE_SPECULAR_COLORMAP + + uniform mat3 specularColorMapTransform; + varying vec2 vSpecularColorMapUv; + +#endif +#ifdef USE_SPECULAR_INTENSITYMAP + + uniform mat3 specularIntensityMapTransform; + varying vec2 vSpecularIntensityMapUv; + +#endif +#ifdef USE_TRANSMISSIONMAP + + uniform mat3 transmissionMapTransform; + varying vec2 vTransmissionMapUv; + +#endif +#ifdef USE_THICKNESSMAP + + uniform mat3 thicknessMapTransform; + varying vec2 vThicknessMapUv; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/uv_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/uv_vertex.glsl.dart new file mode 100755 index 00000000..4a1da6d8 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/uv_vertex.glsl.dart @@ -0,0 +1,122 @@ +const String uvVertex = """ +#if defined( USE_UV ) || defined( USE_ANISOTROPY ) + + vUv = vec3( uv, 1 ).xy; + +#endif +#ifdef USE_MAP + + vMapUv = ( mapTransform * vec3( MAP_UV, 1 ) ).xy; + +#endif +#ifdef USE_ALPHAMAP + + vAlphaMapUv = ( alphaMapTransform * vec3( ALPHAMAP_UV, 1 ) ).xy; + +#endif +#ifdef USE_LIGHTMAP + + vLightMapUv = ( lightMapTransform * vec3( LIGHTMAP_UV, 1 ) ).xy; + +#endif +#ifdef USE_AOMAP + + vAoMapUv = ( aoMapTransform * vec3( AOMAP_UV, 1 ) ).xy; + +#endif +#ifdef USE_BUMPMAP + + vBumpMapUv = ( bumpMapTransform * vec3( BUMPMAP_UV, 1 ) ).xy; + +#endif +#ifdef USE_NORMALMAP + + vNormalMapUv = ( normalMapTransform * vec3( NORMALMAP_UV, 1 ) ).xy; + +#endif +#ifdef USE_DISPLACEMENTMAP + + vDisplacementMapUv = ( displacementMapTransform * vec3( DISPLACEMENTMAP_UV, 1 ) ).xy; + +#endif +#ifdef USE_EMISSIVEMAP + + vEmissiveMapUv = ( emissiveMapTransform * vec3( EMISSIVEMAP_UV, 1 ) ).xy; + +#endif +#ifdef USE_METALNESSMAP + + vMetalnessMapUv = ( metalnessMapTransform * vec3( METALNESSMAP_UV, 1 ) ).xy; + +#endif +#ifdef USE_ROUGHNESSMAP + + vRoughnessMapUv = ( roughnessMapTransform * vec3( ROUGHNESSMAP_UV, 1 ) ).xy; + +#endif +#ifdef USE_ANISOTROPYMAP + + vAnisotropyMapUv = ( anisotropyMapTransform * vec3( ANISOTROPYMAP_UV, 1 ) ).xy; + +#endif +#ifdef USE_CLEARCOATMAP + + vClearcoatMapUv = ( clearcoatMapTransform * vec3( CLEARCOATMAP_UV, 1 ) ).xy; + +#endif +#ifdef USE_CLEARCOAT_NORMALMAP + + vClearcoatNormalMapUv = ( clearcoatNormalMapTransform * vec3( CLEARCOAT_NORMALMAP_UV, 1 ) ).xy; + +#endif +#ifdef USE_CLEARCOAT_ROUGHNESSMAP + + vClearcoatRoughnessMapUv = ( clearcoatRoughnessMapTransform * vec3( CLEARCOAT_ROUGHNESSMAP_UV, 1 ) ).xy; + +#endif +#ifdef USE_IRIDESCENCEMAP + + vIridescenceMapUv = ( iridescenceMapTransform * vec3( IRIDESCENCEMAP_UV, 1 ) ).xy; + +#endif +#ifdef USE_IRIDESCENCE_THICKNESSMAP + + vIridescenceThicknessMapUv = ( iridescenceThicknessMapTransform * vec3( IRIDESCENCE_THICKNESSMAP_UV, 1 ) ).xy; + +#endif +#ifdef USE_SHEEN_COLORMAP + + vSheenColorMapUv = ( sheenColorMapTransform * vec3( SHEEN_COLORMAP_UV, 1 ) ).xy; + +#endif +#ifdef USE_SHEEN_ROUGHNESSMAP + + vSheenRoughnessMapUv = ( sheenRoughnessMapTransform * vec3( SHEEN_ROUGHNESSMAP_UV, 1 ) ).xy; + +#endif +#ifdef USE_SPECULARMAP + + vSpecularMapUv = ( specularMapTransform * vec3( SPECULARMAP_UV, 1 ) ).xy; + +#endif +#ifdef USE_SPECULAR_COLORMAP + + vSpecularColorMapUv = ( specularColorMapTransform * vec3( SPECULAR_COLORMAP_UV, 1 ) ).xy; + +#endif +#ifdef USE_SPECULAR_INTENSITYMAP + + vSpecularIntensityMapUv = ( specularIntensityMapTransform * vec3( SPECULAR_INTENSITYMAP_UV, 1 ) ).xy; + +#endif +#ifdef USE_TRANSMISSIONMAP + + vTransmissionMapUv = ( transmissionMapTransform * vec3( TRANSMISSIONMAP_UV, 1 ) ).xy; + +#endif +#ifdef USE_THICKNESSMAP + + vThicknessMapUv = ( thicknessMapTransform * vec3( THICKNESSMAP_UV, 1 ) ).xy; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/worldpos_vertex.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/worldpos_vertex.glsl.dart new file mode 100755 index 00000000..b30c95fb --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/worldpos_vertex.glsl.dart @@ -0,0 +1,21 @@ +const String worldposVertex = """ +#if defined( USE_ENVMAP ) || defined( DISTANCE ) || defined ( USE_SHADOWMAP ) || defined ( USE_TRANSMISSION ) || NUM_SPOT_LIGHT_COORDS > 0 + + vec4 worldPosition = vec4( transformed, 1.0 ); + + #ifdef USE_BATCHING + + worldPosition = batchingMatrix * worldPosition; + + #endif + + #ifdef USE_INSTANCING + + worldPosition = instanceMatrix * worldPosition; + + #endif + + worldPosition = modelMatrix * worldPosition; + +#endif +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib.dart new file mode 100755 index 00000000..7cd3362b --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib.dart @@ -0,0 +1,279 @@ +part of three_shaders; + +Map shaderLibStandard = { + "uniforms": mergeUniforms([ + uniformsLib["common"], + uniformsLib["envmap"], + uniformsLib["aomap"], + uniformsLib["lightmap"], + uniformsLib["emissivemap"], + uniformsLib["bumpmap"], + uniformsLib["normalmap"], + uniformsLib["displacementmap"], + uniformsLib["roughnessmap"], + uniformsLib["metalnessmap"], + uniformsLib["fog"], + uniformsLib["lights"], + { + "emissive": {"value": Color(0, 0, 0)}, + "roughness": {"value": 1.0}, + "metalness": {"value": 0.0}, + "envMapIntensity": {"value": 1} // temporary + } + ]), + "vertexShader": shaderChunk["meshphysical_vert"], + "fragmentShader": shaderChunk["meshphysical_frag"] +}; + +Map shaderLib = { + "basic": { + "uniforms": mergeUniforms([ + uniformsLib["common"], + uniformsLib["specularmap"], + uniformsLib["envmap"], + uniformsLib["aomap"], + uniformsLib["lightmap"], + uniformsLib["fog"] + ]), + "vertexShader": shaderChunk["meshbasic_vert"], + "fragmentShader": shaderChunk["meshbasic_frag"] + }, + "lambert": { + "uniforms": mergeUniforms([ + uniformsLib["common"], + uniformsLib["specularmap"], + uniformsLib["envmap"], + uniformsLib["aomap"], + uniformsLib["lightmap"], + uniformsLib["emissivemap"], + uniformsLib["bumpmap"], + uniformsLib["normalmap"], + uniformsLib["displacementmap"], + uniformsLib["fog"], + uniformsLib["lights"], + { + "emissive": {"value": Color.fromHex32(0x000000)} + } + ]), + "vertexShader": shaderChunk["meshlambert_vert"], + "fragmentShader": shaderChunk["meshlambert_frag"] + }, + "phong": { + "uniforms": mergeUniforms([ + uniformsLib["common"], + uniformsLib["specularmap"], + uniformsLib["envmap"], + uniformsLib["aomap"], + uniformsLib["lightmap"], + uniformsLib["emissivemap"], + uniformsLib["bumpmap"], + uniformsLib["normalmap"], + uniformsLib["displacementmap"], + uniformsLib["fog"], + uniformsLib["lights"], + { + "emissive": {"value": Color.fromHex32(0x000000)}, + "specular": {"value": Color.fromHex32(0x111111)}, + "shininess": {"value": 30} + } + ]), + "vertexShader": shaderChunk["meshphong_vert"], + "fragmentShader": shaderChunk["meshphong_frag"] + }, + "standard": shaderLibStandard, + "toon": { + "uniforms": mergeUniforms([ + uniformsLib["common"], + uniformsLib["aomap"], + uniformsLib["lightmap"], + uniformsLib["emissivemap"], + uniformsLib["bumpmap"], + uniformsLib["normalmap"], + uniformsLib["displacementmap"], + uniformsLib["gradientmap"], + uniformsLib["fog"], + uniformsLib["lights"], + { + "emissive": {"value": Color.fromHex32(0x000000)} + } + ]), + "vertexShader": shaderChunk["meshtoon_vert"], + "fragmentShader": shaderChunk["meshtoon_frag"] + }, + "matcap": { + "uniforms": mergeUniforms([ + uniformsLib["common"], + uniformsLib["bumpmap"], + uniformsLib["normalmap"], + uniformsLib["displacementmap"], + uniformsLib["fog"], + { + "matcap": {"value": null} + } + ]), + "vertexShader": shaderChunk["meshmatcap_vert"], + "fragmentShader": shaderChunk["meshmatcap_frag"] + }, + "points": { + "uniforms": mergeUniforms([uniformsLib["points"], uniformsLib["fog"]]), + "vertexShader": shaderChunk["points_vert"], + "fragmentShader": shaderChunk["points_frag"] + }, + "dashed": { + "uniforms": mergeUniforms([ + uniformsLib["common"], + uniformsLib["fog"], + { + "scale": {"value": 1}, + "dashSize": {"value": 1}, + "totalSize": {"value": 2} + } + ]), + "vertexShader": shaderChunk["linedashed_vert"], + "fragmentShader": shaderChunk["linedashed_frag"] + }, + "depth": { + "uniforms": + mergeUniforms([uniformsLib["common"], uniformsLib["displacementmap"]]), + "vertexShader": shaderChunk["depth_vert"], + "fragmentShader": shaderChunk["depth_frag"] + }, + "normal": { + "uniforms": mergeUniforms([ + uniformsLib["common"], + uniformsLib["bumpmap"], + uniformsLib["normalmap"], + uniformsLib["displacementmap"], + { + "opacity": {"value": 1.0} + } + ]), + "vertexShader": shaderChunk["meshnormal_vert"], + "fragmentShader": shaderChunk["meshnormal_frag"] + }, + "sprite": { + "uniforms": mergeUniforms([uniformsLib["sprite"], uniformsLib["fog"]]), + "vertexShader": shaderChunk["sprite_vert"], + "fragmentShader": shaderChunk["sprite_frag"] + }, + "background": { + "uniforms": { + "uvTransform": {"value": Matrix3.identity()}, + "t2D": {"value": null}, + 'backgroundIntensity': { 'value': 1 } + }, + "vertexShader": shaderChunk["background_vert"], + "fragmentShader": shaderChunk["background_frag"] + }, + 'backgroundCube': { + + 'uniforms': { + 'envMap': { 'value': null }, + 'flipEnvMap': { 'value': - 1 }, + 'backgroundBlurriness': { 'value': 0 }, + 'backgroundIntensity': { 'value': 1 }, + 'backgroundRotation': { 'value': Matrix3.identity() } + }, + + 'vertexShader': shaderChunk['backgroundCube_vert'], + 'fragmentShader': shaderChunk['backgroundCube_frag'] + }, + /* ------------------------------------------------------------------------- + // Cube map shader + ------------------------------------------------------------------------- */ + + "cube": { + 'uniforms': { + 'tCube': { 'value': null }, + 'tFlip': { 'value': - 1 }, + 'opacity': { 'value': 1.0 }, + }, + "vertexShader": shaderChunk["cube_vert"], + "fragmentShader": shaderChunk["cube_frag"] + }, + "equirect": { + "uniforms": { + "tEquirect": {"value": null}, + }, + "vertexShader": shaderChunk["equirect_vert"], + "fragmentShader": shaderChunk["equirect_frag"] + }, + "distanceRGBA": { + "uniforms": mergeUniforms([ + uniformsLib["common"], + uniformsLib["displacementmap"], + { + "referencePosition": {"value": Vector3.zero()}, + "nearDistance": {"value": 1}, + "farDistance": {"value": 1000} + } + ]), + "vertexShader": shaderChunk["distanceRGBA_vert"], + "fragmentShader": shaderChunk["distanceRGBA_frag"] + }, + "shadow": { + "uniforms": mergeUniforms([ + uniformsLib["lights"], + uniformsLib["fog"], + { + "color": {"value": Color.fromHex32(0x000000)}, + "opacity": {"value": 1.0} + }, + ]), + "vertexShader": shaderChunk["shadow_vert"], + "fragmentShader": shaderChunk["shadow_frag"] + }, + "physical": { + "uniforms": mergeUniforms([ + shaderLibStandard["uniforms"], + { + 'clearcoat': { 'value': 0 }, + 'clearcoatMap': { 'value': null }, + 'clearcoatMapTransform': { 'value': Matrix3.identity() }, + 'clearcoatNormalMap': { 'value': null }, + 'clearcoatNormalMapTransform': { 'value': Matrix3.identity() }, + 'clearcoatNormalScale': { 'value': Vector2( 1, 1 ) }, + 'clearcoatRoughness': { 'value': 0 }, + 'clearcoatRoughnessMap': { 'value': null }, + 'clearcoatRoughnessMapTransform': { 'value': Matrix3.identity() }, + 'dispersion': { 'value': 0 }, + 'iridescence': { 'value': 0 }, + 'iridescenceMap': { 'value': null }, + 'iridescenceMapTransform': { 'value': Matrix3.identity() }, + 'iridescenceIOR': { 'value': 1.3 }, + 'iridescenceThicknessMinimum': { 'value': 100 }, + 'iridescenceThicknessMaximum': { 'value': 400 }, + 'iridescenceThicknessMap': { 'value': null }, + 'iridescenceThicknessMapTransform': { 'value': Matrix3.identity() }, + 'sheen': { 'value': 0 }, + 'sheenColor': { 'value': Color( 0x000000 ) }, + 'sheenColorMap': { 'value': null }, + 'sheenColorMapTransform': { 'value': Matrix3.identity() }, + 'sheenRoughness': { 'value': 1 }, + 'sheenRoughnessMap': { 'value': null }, + 'sheenRoughnessMapTransform': { 'value': Matrix3.identity() }, + 'transmission': { 'value': 0 }, + 'transmissionMap': { 'value': null }, + 'transmissionMapTransform': { 'value': Matrix3.identity() }, + 'transmissionSamplerSize': { 'value': Vector2() }, + 'transmissionSamplerMap': { 'value': null }, + 'thickness': { 'value': 0 }, + 'thicknessMap': { 'value': null }, + 'thicknessMapTransform': { 'value': Matrix3.identity() }, + 'attenuationDistance': { 'value': 0 }, + 'attenuationColor': { 'value': Color( 0x000000 ) }, + 'specularColor': { 'value': Color( 1, 1, 1 ) }, + 'specularColorMap': { 'value': null }, + 'specularColorMapTransform': { 'value': Matrix3.identity() }, + 'specularIntensity': { 'value': 1 }, + 'specularIntensityMap': { 'value': null }, + 'specularIntensityMapTransform': { 'value': Matrix3.identity() }, + 'anisotropyVector': { 'value': Vector2() }, + 'anisotropyMap': { 'value': null }, + 'anisotropyMapTransform': { 'value': Matrix3.identity() }, + } + ]), + "vertexShader": shaderChunk["meshphysical_vert"], + "fragmentShader": shaderChunk["meshphysical_frag"] + } +}; \ No newline at end of file diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/background_cube_frag.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/background_cube_frag.glsl.dart new file mode 100644 index 00000000..4d4fd17d --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/background_cube_frag.glsl.dart @@ -0,0 +1,45 @@ +const String backgroundCubeFrag = /* glsl */''' +#ifdef ENVMAP_TYPE_CUBE + + uniform samplerCube envMap; + +#elif defined( ENVMAP_TYPE_CUBE_UV ) + + uniform sampler2D envMap; + +#endif + +uniform float flipEnvMap; +uniform float backgroundBlurriness; +uniform float backgroundIntensity; +uniform mat3 backgroundRotation; + +varying vec3 vWorldDirection; + +#include + +void main() { + + #ifdef ENVMAP_TYPE_CUBE + + vec4 texColor = textureCube( envMap, backgroundRotation * vec3( flipEnvMap * vWorldDirection.x, vWorldDirection.yz ) ); + + #elif defined( ENVMAP_TYPE_CUBE_UV ) + + vec4 texColor = textureCubeUV( envMap, backgroundRotation * vWorldDirection, backgroundBlurriness ); + + #else + + vec4 texColor = vec4( 0.0, 0.0, 0.0, 1.0 ); + + #endif + + texColor.rgb *= backgroundIntensity; + + gl_FragColor = texColor; + + #include + #include + +} +'''; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/background_cube_vert.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/background_cube_vert.glsl.dart new file mode 100644 index 00000000..aa9b759f --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/background_cube_vert.glsl.dart @@ -0,0 +1,16 @@ +const String backgroundCubeVert = /* glsl */''' +varying vec3 vWorldDirection; + +#include + +void main() { + + vWorldDirection = transformDirection( position, modelMatrix ); + + #include + #include + + gl_Position.z = gl_Position.w; // set z to camera.far + +} +'''; \ No newline at end of file diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/background_frag.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/background_frag.glsl.dart new file mode 100755 index 00000000..caac9b48 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/background_frag.glsl.dart @@ -0,0 +1,27 @@ +const String backgroundFrag = """ +uniform sampler2D t2D; +uniform float backgroundIntensity; + +varying vec2 vUv; + +void main() { + + vec4 texColor = texture2D( t2D, vUv ); + + #ifdef DECODE_VIDEO_TEXTURE + + // use inline sRGB decode until browsers properly support SRGB8_APLHA8 with video textures + + texColor = vec4( mix( pow( texColor.rgb * 0.9478672986 + vec3( 0.0521327014 ), vec3( 2.4 ) ), texColor.rgb * 0.0773993808, vec3( lessThanEqual( texColor.rgb, vec3( 0.04045 ) ) ) ), texColor.w ); + + #endif + + texColor.rgb *= backgroundIntensity; + + gl_FragColor = texColor; + + #include + #include + +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/background_vert.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/background_vert.glsl.dart new file mode 100755 index 00000000..a11c6de5 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/background_vert.glsl.dart @@ -0,0 +1,12 @@ +const String backgroundVert = """ +varying vec2 vUv; +uniform mat3 uvTransform; + +void main() { + + vUv = ( uvTransform * vec3( uv, 1 ) ).xy; + + gl_Position = vec4( position.xy, 1.0, 1.0 ); + +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/cube_frag.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/cube_frag.glsl.dart new file mode 100755 index 00000000..cc6f8468 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/cube_frag.glsl.dart @@ -0,0 +1,19 @@ +const String cubeFrag = """ +uniform samplerCube tCube; +uniform float tFlip; +uniform float opacity; + +varying vec3 vWorldDirection; + +void main() { + + vec4 texColor = textureCube( tCube, vec3( tFlip * vWorldDirection.x, vWorldDirection.yz ) ); + + gl_FragColor = texColor; + gl_FragColor.a *= opacity; + + #include + #include + +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/cube_vert.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/cube_vert.glsl.dart new file mode 100755 index 00000000..5c3fa93a --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/cube_vert.glsl.dart @@ -0,0 +1,16 @@ +const String cubeVert = """ +varying vec3 vWorldDirection; + +#include + +void main() { + + vWorldDirection = transformDirection( position, modelMatrix ); + + #include + #include + + gl_Position.z = gl_Position.w; // set z to camera.far + +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/depth_frag.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/depth_frag.glsl.dart new file mode 100755 index 00000000..0ea5ab06 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/depth_frag.glsl.dart @@ -0,0 +1,52 @@ +const String depthFrag = """ +#if DEPTH_PACKING == 3200 + + uniform float opacity; + +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +varying vec2 vHighPrecisionZW; + +void main() { + + vec4 diffuseColor = vec4( 1.0 ); + #include + + #if DEPTH_PACKING == 3200 + + diffuseColor.a = opacity; + + #endif + + #include + #include + #include + #include + + #include + + // Higher precision equivalent of gl_FragCoord.z. This assumes depthRange has been left to its default values. + float fragCoordZ = 0.5 * vHighPrecisionZW[0] / vHighPrecisionZW[1] + 0.5; + + #if DEPTH_PACKING == 3200 + + gl_FragColor = vec4( vec3( 1.0 - fragCoordZ ), opacity ); + + #elif DEPTH_PACKING == 3201 + + gl_FragColor = packDepthToRGBA( fragCoordZ ); + + #endif + +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/depth_vert.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/depth_vert.glsl.dart new file mode 100755 index 00000000..24e701c4 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/depth_vert.glsl.dart @@ -0,0 +1,44 @@ +const String depthVert = """ +#include +#include +#include +#include +#include +#include +#include +#include + +// This is used for computing an equivalent of gl_FragCoord.z that is as high precision as possible. +// Some platforms compute gl_FragCoord at a lower precision which makes the manually computed value better for +// depth-based postprocessing effects. Reproduced on iPad with A10 processor / iPadOS 13.3.1. +varying vec2 vHighPrecisionZW; + +void main() { + + #include + + #include + #include + + #include + + #ifdef USE_DISPLACEMENTMAP + + #include + #include + #include + + #endif + + #include + #include + #include + #include + #include + #include + #include + + vHighPrecisionZW = gl_Position.zw; + +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/distanceRGBA_frag.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/distanceRGBA_frag.glsl.dart new file mode 100755 index 00000000..308f95c8 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/distanceRGBA_frag.glsl.dart @@ -0,0 +1,35 @@ +const String distanceRgbeFrag = """ +#define DISTANCE + +uniform vec3 referencePosition; +uniform float nearDistance; +uniform float farDistance; +varying vec3 vWorldPosition; + +#include +#include +#include +#include +#include +#include +#include +#include + +void main () { + + vec4 diffuseColor = vec4( 1.0 ); + #include + + #include + #include + #include + #include + + float dist = length( vWorldPosition - referencePosition ); + dist = ( dist - nearDistance ) / ( farDistance - nearDistance ); + dist = saturate( dist ); // clamp to [ 0, 1 ] + + gl_FragColor = packDepthToRGBA( dist ); + +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/distanceRGBA_vert.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/distanceRGBA_vert.glsl.dart new file mode 100755 index 00000000..8ff13db0 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/distanceRGBA_vert.glsl.dart @@ -0,0 +1,42 @@ +const String distanceRgbaVert = """ +#define DISTANCE + +varying vec3 vWorldPosition; + +#include +#include +#include +#include +#include +#include +#include + +void main() { + + #include + + #include + #include + + #include + + #ifdef USE_DISPLACEMENTMAP + + #include + #include + #include + + #endif + + #include + #include + #include + #include + #include + #include + #include + + vWorldPosition = worldPosition.xyz; + +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/equirect_frag.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/equirect_frag.glsl.dart new file mode 100755 index 00000000..119b0961 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/equirect_frag.glsl.dart @@ -0,0 +1,20 @@ +const String equirectFrag = """ +uniform sampler2D tEquirect; + +varying vec3 vWorldDirection; + +#include + +void main() { + + vec3 direction = normalize( vWorldDirection ); + + vec2 sampleUV = equirectUv( direction ); + + gl_FragColor = texture2D( tEquirect, sampleUV ); + + #include + #include + +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/equirect_vert.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/equirect_vert.glsl.dart new file mode 100755 index 00000000..e2daa15a --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/equirect_vert.glsl.dart @@ -0,0 +1,14 @@ +const String equirectVert = """ +varying vec3 vWorldDirection; + +#include + +void main() { + + vWorldDirection = transformDirection( position, modelMatrix ); + + #include + #include + +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/horizontal_blur_shader.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/horizontal_blur_shader.dart new file mode 100644 index 00000000..a036003e --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/horizontal_blur_shader.dart @@ -0,0 +1,41 @@ +/** + * Two pass Gaussian blur filter (horizontal and vertical blur shaders) + * - described in http://www.gamerendering.com/2008/10/11/gaussian-blur-filter-shader/ + * and used in http://www.cake23.de/traveling-wavefronts-lit-up.html + * + * - 9 samples per pass + * - standard deviation 2.7 + * - "h" and "v" parameters should be set to "1 / width" and "1 / height" + */ + +Map horizontalBlurShader = { + "uniforms": { + 'tDiffuse': {}, + 'h': {"value": 1.0 / 512.0} + }, + "vertexShader": [ + 'varying vec2 vUv;', + 'void main() {', + ' vUv = uv;', + ' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', + '}' + ].join('\n'), + "fragmentShader": [ + 'uniform sampler2D tDiffuse;', + 'uniform float h;', + 'varying vec2 vUv;', + 'void main() {', + ' vec4 sum = vec4( 0.0 );', + ' sum += texture2D( tDiffuse, vec2( vUv.x - 4.0 * h, vUv.y ) ) * 0.051;', + ' sum += texture2D( tDiffuse, vec2( vUv.x - 3.0 * h, vUv.y ) ) * 0.0918;', + ' sum += texture2D( tDiffuse, vec2( vUv.x - 2.0 * h, vUv.y ) ) * 0.12245;', + ' sum += texture2D( tDiffuse, vec2( vUv.x - 1.0 * h, vUv.y ) ) * 0.1531;', + ' sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;', + ' sum += texture2D( tDiffuse, vec2( vUv.x + 1.0 * h, vUv.y ) ) * 0.1531;', + ' sum += texture2D( tDiffuse, vec2( vUv.x + 2.0 * h, vUv.y ) ) * 0.12245;', + ' sum += texture2D( tDiffuse, vec2( vUv.x + 3.0 * h, vUv.y ) ) * 0.0918;', + ' sum += texture2D( tDiffuse, vec2( vUv.x + 4.0 * h, vUv.y ) ) * 0.051;', + ' gl_FragColor = sum;', + '}' + ].join('\n') +}; diff --git a/packages/three_js_core/lib/renderers/shaders/shader_lib/index.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/index.dart similarity index 100% rename from packages/three_js_core/lib/renderers/shaders/shader_lib/index.dart rename to packages/three_js_webgl_renderer/lib/shaders/shader_lib/index.dart diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/linedashed_frag.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/linedashed_frag.glsl.dart new file mode 100755 index 00000000..a2480f64 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/linedashed_frag.glsl.dart @@ -0,0 +1,44 @@ +const String linedashedFrag = """ +uniform vec3 diffuse; +uniform float opacity; + +uniform float dashSize; +uniform float totalSize; + +varying float vLineDistance; + +#include +#include +#include +#include +#include +#include +#include + +void main() { + + vec4 diffuseColor = vec4( diffuse, opacity ); + #include + + if ( mod( vLineDistance, totalSize ) > dashSize ) { + + discard; + + } + + vec3 outgoingLight = vec3( 0.0 ); + + #include + #include + #include + + outgoingLight = diffuseColor.rgb; // simple shader + + #include + #include + #include + #include + #include + +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/linedashed_vert.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/linedashed_vert.glsl.dart new file mode 100755 index 00000000..b44843e5 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/linedashed_vert.glsl.dart @@ -0,0 +1,31 @@ +const String linedashedVert = """ +uniform float scale; +attribute float lineDistance; + +varying float vLineDistance; + +#include +#include +#include +#include +#include +#include +#include + +void main() { + + vLineDistance = scale * lineDistance; + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshbasic_frag.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshbasic_frag.glsl.dart new file mode 100755 index 00000000..d6e3dbc1 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshbasic_frag.glsl.dart @@ -0,0 +1,72 @@ +const String meshbasicFrag = """ +uniform vec3 diffuse; +uniform float opacity; + +#ifndef FLAT_SHADED + + varying vec3 vNormal; + +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void main() { + + vec4 diffuseColor = vec4( diffuse, opacity ); + #include + + #include + #include + #include + #include + #include + #include + #include + + ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) ); + + // accumulation (baked indirect lighting only) + #ifdef USE_LIGHTMAP + + vec4 lightMapTexel = texture2D( lightMap, vLightMapUv ); + reflectedLight.indirectDiffuse += lightMapTexel.rgb * lightMapIntensity * RECIPROCAL_PI; + + #else + + reflectedLight.indirectDiffuse += vec3( 1.0 ); + + #endif + + // modulation + #include + + reflectedLight.indirectDiffuse *= diffuseColor.rgb; + + vec3 outgoingLight = reflectedLight.indirectDiffuse; + + #include + + #include + #include + #include + #include + #include + #include + +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshbasic_vert.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshbasic_vert.glsl.dart new file mode 100755 index 00000000..ba021a58 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshbasic_vert.glsl.dart @@ -0,0 +1,43 @@ +const String meshbasicVert = /* glsl */ """ +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void main() { + + #include + #include + #include + #include + #include + + #if defined ( USE_ENVMAP ) || defined ( USE_SKINNING ) + + #include + #include + #include + #include + #include + + #endif + + #include + #include + #include + #include + #include + #include + + #include + #include + #include + +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshlambert_frag.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshlambert_frag.glsl.dart new file mode 100755 index 00000000..e59de838 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshlambert_frag.glsl.dart @@ -0,0 +1,73 @@ +const String meshlambertFrag = """ +#define LAMBERT + +uniform vec3 diffuse; +uniform vec3 emissive; +uniform float opacity; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void main() { + + vec4 diffuseColor = vec4( diffuse, opacity ); + #include + + ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) ); + vec3 totalEmissiveRadiance = emissive; + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + // accumulation + #include + #include + #include + #include + + // modulation + #include + + vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance; + + #include + #include + #include + #include + #include + #include + #include + +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshlambert_vert.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshlambert_vert.glsl.dart new file mode 100755 index 00000000..6cc51edc --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshlambert_vert.glsl.dart @@ -0,0 +1,51 @@ +const String meshlambertVert = """ +#define LAMBERT + +varying vec3 vViewPosition; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void main() { + + #include + #include + #include + #include + #include + + #include + #include + #include + #include + #include + #include + + #include + #include + #include + #include + #include + #include + #include + + vViewPosition = - mvPosition.xyz; + + #include + #include + #include + #include + +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshmatcap_frag.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshmatcap_frag.glsl.dart new file mode 100755 index 00000000..329f0cdc --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshmatcap_frag.glsl.dart @@ -0,0 +1,64 @@ +const String meshmatcapFrag = """ +#define MATCAP + +uniform vec3 diffuse; +uniform float opacity; +uniform sampler2D matcap; + +varying vec3 vViewPosition; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void main() { + + vec4 diffuseColor = vec4( diffuse, opacity ); + #include + + #include + #include + #include + #include + #include + #include + #include + #include + + vec3 viewDir = normalize( vViewPosition ); + vec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) ); + vec3 y = cross( viewDir, x ); + vec2 uv = vec2( dot( x, normal ), dot( y, normal ) ) * 0.495 + 0.5; // 0.495 to remove artifacts caused by undersized matcap disks + + #ifdef USE_MATCAP + + vec4 matcapColor = texture2D( matcap, uv ); + + #else + + vec4 matcapColor = vec4( vec3( mix( 0.2, 0.8, uv.y ) ), 1.0 ); // default if matcap is missing + + #endif + + vec3 outgoingLight = diffuseColor.rgb * matcapColor.rgb; + + #include + #include + #include + #include + #include + #include + +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshmatcap_vert.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshmatcap_vert.glsl.dart new file mode 100755 index 00000000..af2de944 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshmatcap_vert.glsl.dart @@ -0,0 +1,47 @@ +const String meshmatcapVert = """ +#define MATCAP + +varying vec3 vViewPosition; + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include + +void main() { + + #include + #include + #include + #include + #include + + #include + #include + #include + #include + #include + #include + + #include + #include + #include + #include + #include + + #include + #include + #include + + vViewPosition = - mvPosition.xyz; + +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshnormal_frag.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshnormal_frag.glsl.dart new file mode 100755 index 00000000..7ec384d9 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshnormal_frag.glsl.dart @@ -0,0 +1,38 @@ +const String meshnormalFrag = """ +#define NORMAL + +uniform float opacity; + +#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE ) + + varying vec3 vViewPosition; + +#endif + +#include +#include +#include +#include +#include +#include +#include + +void main() { + + vec4 diffuseColor = vec4( 0.0, 0.0, 0.0, opacity ); + + #include + #include + #include + #include + + gl_FragColor = vec4( packNormalToRGB( normal ), diffuseColor.a ); + + #ifdef OPAQUE + + gl_FragColor.a = 1.0; + + #endif + +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshnormal_vert.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshnormal_vert.glsl.dart new file mode 100755 index 00000000..69e43b9a --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshnormal_vert.glsl.dart @@ -0,0 +1,48 @@ +const String meshnormalVert = """ +#define NORMAL + +#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE ) + + varying vec3 vViewPosition; + +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void main() { + + #include + #include + + #include + #include + #include + #include + #include + #include + #include + + #include + #include + #include + #include + #include + #include + #include + +#if defined( FLAT_SHADED ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP_TANGENTSPACE ) + + vViewPosition = - mvPosition.xyz; + +#endif + +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshphong_frag.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshphong_frag.glsl.dart new file mode 100755 index 00000000..8340b0e9 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshphong_frag.glsl.dart @@ -0,0 +1,75 @@ +const String meshphongFrag = """ +#define PHONG + +uniform vec3 diffuse; +uniform vec3 emissive; +uniform vec3 specular; +uniform float shininess; +uniform float opacity; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void main() { + + vec4 diffuseColor = vec4( diffuse, opacity ); + #include + + ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) ); + vec3 totalEmissiveRadiance = emissive; + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + // accumulation + #include + #include + #include + #include + + // modulation + #include + + vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance; + + #include + #include + #include + #include + #include + #include + #include + +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshphong_vert.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshphong_vert.glsl.dart new file mode 100755 index 00000000..7a4efd76 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshphong_vert.glsl.dart @@ -0,0 +1,51 @@ +const String meshphongVert = """ +#define PHONG + +varying vec3 vViewPosition; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void main() { + + #include + #include + #include + #include + + #include + #include + #include + #include + #include + #include + #include + + #include + #include + #include + #include + #include + #include + #include + + vViewPosition = - mvPosition.xyz; + + #include + #include + #include + #include + +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshphysical_frag.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshphysical_frag.glsl.dart new file mode 100755 index 00000000..eae6611c --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshphysical_frag.glsl.dart @@ -0,0 +1,168 @@ +const String meshphysicalFrag = """ +#define STANDARD + +#ifdef PHYSICAL + #define IOR + #define USE_SPECULAR +#endif + +uniform vec3 diffuse; +uniform vec3 emissive; +uniform float roughness; +uniform float metalness; +uniform float opacity; + +#ifdef IOR + uniform float ior; +#endif + +#ifdef USE_SPECULAR + uniform float specularIntensity; + uniform vec3 specularColor; + + #ifdef USE_SPECULAR_COLORMAP + uniform sampler2D specularColorMap; + #endif + + #ifdef USE_SPECULAR_INTENSITYMAP + uniform sampler2D specularIntensityMap; + #endif +#endif + +#ifdef USE_CLEARCOAT + uniform float clearcoat; + uniform float clearcoatRoughness; +#endif + +#ifdef USE_DISPERSION + uniform float dispersion; +#endif + +#ifdef USE_IRIDESCENCE + uniform float iridescence; + uniform float iridescenceIOR; + uniform float iridescenceThicknessMinimum; + uniform float iridescenceThicknessMaximum; +#endif + +#ifdef USE_SHEEN + uniform vec3 sheenColor; + uniform float sheenRoughness; + + #ifdef USE_SHEEN_COLORMAP + uniform sampler2D sheenColorMap; + #endif + + #ifdef USE_SHEEN_ROUGHNESSMAP + uniform sampler2D sheenRoughnessMap; + #endif +#endif + +#ifdef USE_ANISOTROPY + uniform vec2 anisotropyVector; + + #ifdef USE_ANISOTROPYMAP + uniform sampler2D anisotropyMap; + #endif +#endif + +varying vec3 vViewPosition; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void main() { + + vec4 diffuseColor = vec4( diffuse, opacity ); + #include + + ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) ); + vec3 totalEmissiveRadiance = emissive; + + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + #include + + // accumulation + #include + #include + #include + #include + + // modulation + #include + + vec3 totalDiffuse = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse; + vec3 totalSpecular = reflectedLight.directSpecular + reflectedLight.indirectSpecular; + + #include + + vec3 outgoingLight = totalDiffuse + totalSpecular + totalEmissiveRadiance; + + #ifdef USE_SHEEN + + // Sheen energy compensation approximation calculation can be found at the end of + // https://drive.google.com/file/d/1T0D1VSyR4AllqIJTQAraEIzjlb5h4FKH/view?usp=sharing + float sheenEnergyComp = 1.0 - 0.157 * max3( material.sheenColor ); + + outgoingLight = outgoingLight * sheenEnergyComp + sheenSpecularDirect + sheenSpecularIndirect; + + #endif + + #ifdef USE_CLEARCOAT + + float dotNVcc = saturate( dot( geometryClearcoatNormal, geometryViewDir ) ); + + vec3 Fcc = F_Schlick( material.clearcoatF0, material.clearcoatF90, dotNVcc ); + + outgoingLight = outgoingLight * ( 1.0 - material.clearcoat * Fcc ) + ( clearcoatSpecularDirect + clearcoatSpecularIndirect ) * material.clearcoat; + + #endif + + #include + #include + #include + #include + #include + #include + +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshphysical_vert.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshphysical_vert.glsl.dart new file mode 100755 index 00000000..508f43b9 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshphysical_vert.glsl.dart @@ -0,0 +1,60 @@ +const String meshphysicalVert = """ +#define STANDARD + +varying vec3 vViewPosition; + +#ifdef USE_TRANSMISSION + + varying vec3 vWorldPosition; + +#endif + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void main() { + + #include + #include + #include + #include + #include + + #include + #include + #include + #include + #include + #include + + #include + #include + #include + #include + #include + #include + #include + + vViewPosition = - mvPosition.xyz; + + #include + #include + #include + +#ifdef USE_TRANSMISSION + + vWorldPosition = worldPosition.xyz; + +#endif +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshtoon_frag.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshtoon_frag.glsl.dart new file mode 100755 index 00000000..83210808 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshtoon_frag.glsl.dart @@ -0,0 +1,69 @@ +const String meshtoonFrag = """ +#define TOON + +uniform vec3 diffuse; +uniform vec3 emissive; +uniform float opacity; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void main() { + + vec4 diffuseColor = vec4( diffuse, opacity ); + #include + + ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) ); + vec3 totalEmissiveRadiance = emissive; + + #include + #include + #include + #include + #include + #include + #include + #include + #include + + // accumulation + #include + #include + #include + #include + + // modulation + #include + + vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + totalEmissiveRadiance; + + #include + #include + #include + #include + #include + #include + +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshtoon_vert.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshtoon_vert.glsl.dart new file mode 100755 index 00000000..b0803b9e --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/meshtoon_vert.glsl.dart @@ -0,0 +1,49 @@ +const String meshtoonVert = """ +#define TOON + +varying vec3 vViewPosition; + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void main() { + + #include + #include + #include + #include + #include + + #include + #include + #include + #include + #include + #include + + #include + #include + #include + #include + #include + #include + #include + + vViewPosition = - mvPosition.xyz; + + #include + #include + #include + +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/points_frag.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/points_frag.glsl.dart new file mode 100755 index 00000000..df1d943d --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/points_frag.glsl.dart @@ -0,0 +1,36 @@ +const String pointsFrag = """ +uniform vec3 diffuse; +uniform float opacity; + +#include +#include +#include +#include +#include +#include +#include +#include + +void main() { + + vec4 diffuseColor = vec4( diffuse, opacity ); + #include + + vec3 outgoingLight = vec3( 0.0 ); + + #include + #include + #include + #include + #include + + outgoingLight = diffuseColor.rgb; + + #include + #include + #include + #include + #include + +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/points_vert.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/points_vert.glsl.dart new file mode 100755 index 00000000..bbc0ffb6 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/points_vert.glsl.dart @@ -0,0 +1,50 @@ +const String pointsVert = """ +uniform float size; +uniform float scale; + +#include +#include +#include +#include +#include +#include + +#ifdef USE_POINTS_UV + + varying vec2 vUv; + uniform mat3 uvTransform; + +#endif + +void main() { + + #ifdef USE_POINTS_UV + + vUv = ( uvTransform * vec3( uv, 1 ) ).xy; + + #endif + + #include + #include + #include + #include + #include + #include + + gl_PointSize = size; + + #ifdef USE_SIZEATTENUATION + + bool isPerspective = isPerspectiveMatrix( projectionMatrix ); + + if ( isPerspective ) gl_PointSize *= ( scale / - mvPosition.z ); + + #endif + + #include + #include + #include + #include + +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/shadow_frag.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/shadow_frag.glsl.dart new file mode 100755 index 00000000..87522035 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/shadow_frag.glsl.dart @@ -0,0 +1,25 @@ +const String shadowFrag = """ +uniform vec3 color; +uniform float opacity; + +#include +#include +#include +#include +#include +#include +#include +#include + +void main() { + + #include + + gl_FragColor = vec4( color, opacity * ( 1.0 - getShadowMask() ) ); + + #include + #include + #include + +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/shadow_vert.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/shadow_vert.glsl.dart new file mode 100755 index 00000000..bcdba4f5 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/shadow_vert.glsl.dart @@ -0,0 +1,32 @@ +const String shadowVert = """ +#include +#include +#include +#include +#include +#include +#include + +void main() { + + #include + + #include + #include + #include + #include + #include + #include + + #include + #include + #include + #include + #include + + #include + #include + #include + +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/sprite_frag.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/sprite_frag.glsl.dart new file mode 100755 index 00000000..a9327bce --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/sprite_frag.glsl.dart @@ -0,0 +1,36 @@ +const String spriteFrag = """ +uniform vec3 diffuse; +uniform float opacity; + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +void main() { + + vec4 diffuseColor = vec4( diffuse, opacity ); + #include + + vec3 outgoingLight = vec3( 0.0 ); + + #include + #include + #include + #include + #include + + outgoingLight = diffuseColor.rgb; + + #include + #include + #include + #include + +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/sprite_vert.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/sprite_vert.glsl.dart new file mode 100755 index 00000000..e15e59f0 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/sprite_vert.glsl.dart @@ -0,0 +1,44 @@ +const String spriteVert = """ +uniform float rotation; +uniform vec2 center; + +#include +#include +#include +#include +#include + +void main() { + + #include + + vec4 mvPosition = modelViewMatrix * vec4( 0.0, 0.0, 0.0, 1.0 ); + + vec2 scale; + scale.x = length( vec3( modelMatrix[ 0 ].x, modelMatrix[ 0 ].y, modelMatrix[ 0 ].z ) ); + scale.y = length( vec3( modelMatrix[ 1 ].x, modelMatrix[ 1 ].y, modelMatrix[ 1 ].z ) ); + + #ifndef USE_SIZEATTENUATION + + bool isPerspective = isPerspectiveMatrix( projectionMatrix ); + + if ( isPerspective ) scale *= - mvPosition.z; + + #endif + + vec2 alignedPosition = ( position.xy - ( center - vec2( 0.5 ) ) ) * scale; + + vec2 rotatedPosition; + rotatedPosition.x = cos( rotation ) * alignedPosition.x - sin( rotation ) * alignedPosition.y; + rotatedPosition.y = sin( rotation ) * alignedPosition.x + cos( rotation ) * alignedPosition.y; + + mvPosition.xy += rotatedPosition; + + gl_Position = projectionMatrix * mvPosition; + + #include + #include + #include + +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/vertical_blur_shader.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/vertical_blur_shader.dart new file mode 100644 index 00000000..77cdc475 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/vertical_blur_shader.dart @@ -0,0 +1,41 @@ +/** + * Two pass Gaussian blur filter (horizontal and vertical blur shaders) + * - described in http://www.gamerendering.com/2008/10/11/gaussian-blur-filter-shader/ + * and used in http://www.cake23.de/traveling-wavefronts-lit-up.html + * + * - 9 samples per pass + * - standard deviation 2.7 + * - "h" and "v" parameters should be set to "1 / width" and "1 / height" + */ + +Map verticalBlurShader = { + "uniforms": { + 'tDiffuse': {}, + 'v': {"value": 1.0 / 512.0} + }, + "vertexShader": [ + 'varying vec2 vUv;', + 'void main() {', + ' vUv = uv;', + ' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', + '}' + ].join('\n'), + "fragmentShader": [ + 'uniform sampler2D tDiffuse;', + 'uniform float v;', + 'varying vec2 vUv;', + 'void main() {', + ' vec4 sum = vec4( 0.0 );', + ' sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 4.0 * v ) ) * 0.051;', + ' sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 3.0 * v ) ) * 0.0918;', + ' sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 2.0 * v ) ) * 0.12245;', + ' sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 1.0 * v ) ) * 0.1531;', + ' sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;', + ' sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 1.0 * v ) ) * 0.1531;', + ' sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 2.0 * v ) ) * 0.12245;', + ' sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 3.0 * v ) ) * 0.0918;', + ' sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 4.0 * v ) ) * 0.051;', + ' gl_FragColor = sum;', + '}' + ].join('\n') +}; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/vsm_frag.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/vsm_frag.glsl.dart new file mode 100755 index 00000000..09d4fc70 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/vsm_frag.glsl.dart @@ -0,0 +1,45 @@ +const String vsmFrag = /* glsl */ """ +uniform sampler2D shadow_pass; +uniform vec2 resolution; +uniform float radius; + +#include + +void main() { + + const float samples = float( VSM_SAMPLES ); + + float mean = 0.0; + float squared_mean = 0.0; + + float uvStride = samples <= 1.0 ? 0.0 : 2.0 / ( samples - 1.0 ); + float uvStart = samples <= 1.0 ? 0.0 : - 1.0; + for ( float i = 0.0; i < samples; i ++ ) { + + float uvOffset = uvStart + i * uvStride; + + #ifdef HORIZONTAL_PASS + + vec2 distribution = unpackRGBATo2Half( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( uvOffset, 0.0 ) * radius ) / resolution ) ); + mean += distribution.x; + squared_mean += distribution.y * distribution.y + distribution.x * distribution.x; + + #else + + float depth = unpackRGBAToDepth( texture2D( shadow_pass, ( gl_FragCoord.xy + vec2( 0.0, uvOffset ) * radius ) / resolution ) ); + mean += depth; + squared_mean += depth * depth; + + #endif + + } + + mean = mean / samples; + squared_mean = squared_mean / samples; + + float std_dev = sqrt( squared_mean - mean * mean ); + + gl_FragColor = pack2HalfToRGBA( vec2( mean, std_dev ) ); + +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib/vsm_vert.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/vsm_vert.glsl.dart new file mode 100755 index 00000000..d202bedf --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_lib/vsm_vert.glsl.dart @@ -0,0 +1,7 @@ +const String vsmVert = /* glsl */ """ +void main() { + + gl_Position = vec4( position, 1.0 ); + +} +"""; diff --git a/packages/three_js_webgl_renderer/lib/shaders/uniforms_lib.dart b/packages/three_js_webgl_renderer/lib/shaders/uniforms_lib.dart new file mode 100755 index 00000000..de5b8bf3 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/shaders/uniforms_lib.dart @@ -0,0 +1,175 @@ +part of three_shaders; + +Map uniformsLib = { + "common": { + "diffuse": {"value": Color.fromHex32(0xffffff)}, + "opacity": {"value": 1.0}, + "map": {'value': null}, + "mapTransform": {"value": Matrix3.identity()}, + "alphaMap": {'value': null}, + "alphaMapTransform": {"value": Matrix3.identity()}, + "alphaTest": {"value": 0.0}, + "uvTransform": {"value": Matrix3.identity()}, + "uv2Transform": {"value": Matrix3.identity()}, + }, + "specularmap": { + "specularMap": {'value': null}, + 'specularMapTransform': { 'value': Matrix3.identity() } + }, + "envmap": { + "envMap": {}, + "flipEnvMapX": {"value": -1}, + "flipEnvMapY": {"value": 1}, + + 'envMapRotation': { 'value': Matrix3.identity() }, + "flipEnvMap": {"value": -1}, + "reflectivity": {"value": 1.0}, // basic, lambert, phong + "ior": {"value": 1.5}, // physical + "refractionRatio": {"value": 0.98}, // basic, lambert, phong + }, + "aomap": { + "aoMap": {'value': null}, + "aoMapIntensity": {"value": 1}, + 'aoMapTransform': { 'value': Matrix3.identity() } + }, + "lightmap": { + "lightMap": {'value': null}, + "lightMapIntensity": {"value": 1}, + 'lightMapTransform': { 'value': Matrix3.identity() } + }, + "emissivemap": { + "emissiveMap": {'value': null}, + 'emissiveMapTransform': { 'value': Matrix3.identity() } + }, + "bumpmap": { + "bumpMap": {'value': null}, + 'bumpMapTransform': { 'value': Matrix3.identity() }, + "bumpScale": {"value": 1} + }, + "normalmap": { + "normalMap": {'value': null}, + 'normalMapTransform': { 'value': Matrix3.identity() }, + "normalScale": {"value": Vector2(1, 1)} + }, + "displacementmap": { + "displacementMap": {'value': null}, + 'displacementMapTransform': { 'value': Matrix3.identity() }, + "displacementScale": {"value": 1}, + "displacementBias": {"value": 0} + }, + "roughnessmap": { + "roughnessMap": {'value': null}, + 'roughnessMapTransform': { 'value': Matrix3.identity() } + }, + "metalnessmap": { + "metalnessMap": {'value': null}, + 'metalnessMapTransform': { 'value': Matrix3.identity() } + }, + "gradientmap": { + "gradientMap": {'value': null} + }, + "fog": { + "fogDensity": {"value": 0.00025}, + "fogNear": {"value": 1}, + "fogFar": {"value": 2000}, + "fogColor": {"value": Color(0, 0, 0)} + }, + "lights": { + "ambientLightColor": {"value": []}, + + "lightProbe": {"value": []}, + + "directionalLights": { + "value": [], + "properties": {"direction": {}, "color": {}} + }, + + "directionalLightShadows": { + "value": [], + "properties": {"shadowBias": {}, "shadowNormalBias": {}, "shadowRadius": {}, "shadowMapSize": {}} + }, + + "directionalShadowMap": {"value": []}, + "directionalShadowMatrix": {"value": []}, + + "spotLights": { + "value": [], + "properties": { + "color": {}, + "position": {}, + "direction": {}, + "distance": {}, + "coneCos": {}, + "penumbraCos": {}, + "decay": {} + } + }, + + "spotLightShadows": { + "value": [], + "properties": {"shadowBias": {}, "shadowNormalBias": {}, "shadowRadius": {}, "shadowMapSize": {}} + }, + + 'spotLightMap': { 'value': [] }, + "spotShadowMap": {"value": []}, + "spotShadowMatrix": {"value": []}, + 'spotLightMatrix': { 'value': [] }, + + "pointLights": { + "value": [], + "properties": {"color": {}, "position": {}, "decay": {}, "distance": {}} + }, + + "pointLightShadows": { + "value": [], + "properties": { + "shadowBias": {}, + "shadowNormalBias": {}, + "shadowRadius": {}, + "shadowMapSize": {}, + "shadowCameraNear": {}, + "shadowCameraFar": {} + } + }, + + "pointShadowMap": {"value": []}, + "pointShadowMatrix": {"value": []}, + + "hemisphereLights": { + "value": [], + "properties": {"direction": {}, "skyColor": {}, "groundColor": {}} + }, + + // TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src + "rectAreaLights": { + "value": [], + "properties": {"color": {}, "position": {}, "width": {}, "height": {}} + }, + + "ltc_1": {'value': null}, + "ltc_2": {'value': null} + }, + "points": { + "diffuse": {"value": Color.fromHex32(0xffffff)}, + "opacity": {"value": 1.0}, + "size": {"value": 1.0}, + "scale": {"value": 1.0}, + "map": {'value': null}, + "alphaMap": {'value': null}, + 'alphaMapTransform': { 'value': Matrix3.identity() }, + "alphaTest": {"value": 0.0}, + "uvTransform": {"value": Matrix3.identity()} + }, + "sprite": { + "diffuse": {"value": Color.fromHex32(0xffffff)}, + "opacity": {"value": 1.0}, + "center": {"value": Vector2(0.5, 0.5)}, + "rotation": {"value": 0.0}, + "map": {'value': null}, + 'mapTransform': { 'value': Matrix3.identity() }, + "alphaMap": {'value': null}, + 'alphaMapTransform': { 'value': Matrix3.identity() }, + "alphaTest": {"value": 0.0}, + "uvTransform": {"value": Matrix3.identity()} + } +}; diff --git a/packages/three_js_webgl_renderer/lib/three_js_webgl_renderer.dart b/packages/three_js_webgl_renderer/lib/three_js_webgl_renderer.dart new file mode 100755 index 00000000..16bb7a47 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/three_js_webgl_renderer.dart @@ -0,0 +1,7 @@ +library three_js_webgl_renderer; + +export 'shaders/index.dart'; +export 'renderers/index.dart'; +export 'shaders/shader_lib/index.dart'; +export 'renderers/pmrem_generator.dart'; +export 'three_viewer.dart'; \ No newline at end of file diff --git a/packages/three_js_webgl_renderer/lib/three_viewer.dart b/packages/three_js_webgl_renderer/lib/three_viewer.dart new file mode 100644 index 00000000..596eed48 --- /dev/null +++ b/packages/three_js_webgl_renderer/lib/three_viewer.dart @@ -0,0 +1,426 @@ +import 'dart:async'; +import 'dart:io'; +import 'package:flutter/foundation.dart'; +import 'package:flutter/material.dart'; +import 'package:flutter/scheduler.dart'; +import './renderers/index.dart'; +import 'package:three_js_core/others/index.dart'; +import 'package:three_js_core/renderers/index.dart'; +import 'package:three_js_core/three_js_core.dart' as core; +import 'package:three_js_math/three_js_math.dart'; +import 'package:flutter_angle/flutter_angle.dart'; + +class Settings{ + Settings({ + this.useSourceTexture = false, + this.enableShadowMap = true, + this.autoClear = true, + Map? renderOptions, + this.animate = true, + this.alpha = false, + this.autoClearDepth = true, + this.autoClearStencil = true, + this.clearAlpha = 1.0, + this.clearColor = 0x000000, + this.localClippingEnabled = false, + this.clippingPlanes = const [], + this.colorSpace = ColorSpace.srgb, + this.outputEncoding = sRGBEncoding, + this.toneMapping = NoToneMapping, + this.shadowMapType = PCFShadowMap, + this.toneMappingExposure = 1.0, + this.logarithmicDepthBuffer = false, + this.stencil = true, + this.xr, + this.antialias = false, + + this.depth = true, + this.premultipliedAlpha = true, + this.preserveDrawingBuffer = false, + this.powerPreference = PowerPreference.defaultp, + this.failIfMajorPerformanceCaveat = false, + this.reverseDepthBuffer = false, + this.precision = Precision.highp, + this.screenResolution + }){ + this.renderOptions = renderOptions ?? { + "format": RGBAFormat, + "samples": 4 + }; + } + + bool premultipliedAlpha; + bool preserveDrawingBuffer; + PowerPreference powerPreference; + bool reverseDepthBuffer; + bool failIfMajorPerformanceCaveat; + bool depth = true; + Precision precision; + bool alpha; + bool stencil; + bool logarithmicDepthBuffer; + int clearColor; + double clearAlpha; + bool antialias; + XRManager Function(WebGLRenderer renderer, dynamic gl)? xr; + double? screenResolution; + + bool animate; + bool useSourceTexture; + bool enableShadowMap; + bool autoClear; + bool autoClearDepth; + bool autoClearStencil; + bool localClippingEnabled; + late Map renderOptions; + List clippingPlanes; + int outputEncoding; + ColorSpace colorSpace; + int toneMapping; + int shadowMapType; + double toneMappingExposure; +} + +/// threeJs utility class. If you want to learn how to connect cannon.js with js, please look at the examples/threejs_* instead. +class ThreeJS with WidgetsBindingObserver{ + void Function() onSetupComplete; + ThreeJS({ + Settings? settings, + required this.onSetupComplete, + required this.setup, + this.rendererUpdate, + this.postProcessor, + this.windowResizeUpdate, + Size? size, + WebGLRenderer? renderer, + this.renderNumber = 0, + this.loadingWidget + }){ + this.settings = settings ?? Settings(); + _resolution = this.settings.screenResolution; + _fixedSize = size; + } + + int renderNumber; + + BuildContext? _context; + Timer? _debounceTimer; + + Widget? loadingWidget; + Size? _fixedSize; + late final Settings settings; + final GlobalKey globalKey = GlobalKey(); + core.PeripheralsState get domElement => globalKey.currentState!; + + bool visible = true; + + FlutterAngleTexture? texture; + RenderingContext? gl; + + WebGLRenderTarget? renderTarget; + WebGLRenderer? renderer; + final core.Clock clock = core.Clock(); + + late final core.Scene scene; + late final core.Camera camera; + Ticker? ticker; + + double get width => screenSize!.width; + double get height => screenSize!.height; + + Size? screenSize; + double? _resolution; + double get dpr => _resolution ?? 1.0; + void setResolution(double newResolution){ + _resolution = newResolution; + } + + WebGLTexture? sourceTexture; + + bool pause = false; + bool _disposed = false; + bool isVisibleOnScreen = true; + bool _mounted = false; + bool get mounted => _mounted; + bool _updating = false; + bool get updating => _updating; + + void Function()? rendererUpdate; + void Function(Size newSize)? windowResizeUpdate; + void Function([double? dt])? postProcessor; + Future Function(core.Scene,core.Camera,FlutterAngleTexture,[double? dt])? customRenderer; + Future Function(BuildContext) onWindowResize = (context) async{}; + FutureOr Function()? setup; + List events = []; + List disposeEvents = []; + + FlutterAngle? angle = FlutterAngle(); + + void addAnimationEvent(Function(double dt) event){ + events.add(event); + } + void toDispose(Function() event){ + disposeEvents.add(event); + } + + @override + void didChangeMetrics() { + if (_disposed) return; + _debounceTimer?.cancel(); // Clear existing timer + _debounceTimer = Timer(Duration(milliseconds: 300+renderNumber*100), () { // Set a new timer + if (_context != null && _context!.mounted) { + _onWindowResize(_context!); + } + }); + } + + void dispose(){ + if(_disposed) return; + _disposed = true; + _debounceTimer?.cancel(); // Cancel timer if active + _debounceTimer = null; + WidgetsBinding.instance.removeObserver(this); + ticker?.dispose(); + ticker = null; + renderer?.dispose(); + renderer = null; + renderTarget?.dispose(); + renderTarget = null; + scene.dispose(); + for(final event in disposeEvents){ + event.call(); + } + + camera.dispose(); + events.clear(); + disposeEvents.clear(); + + //allNativeData.dispose(); + + angle?.dispose([texture]); + loadingWidget = null; + _fixedSize = null; + screenSize = null; + + rendererUpdate = null; + windowResizeUpdate = null; + postProcessor = null; + setup = null; + } + + void initSize(BuildContext context){ + if (screenSize != null) { + return; + } + _context = context; + WidgetsBinding.instance.addObserver(this); + final mqd = MediaQuery.of(context); + + screenSize = _fixedSize ?? mqd.size; + _resolution ??= mqd.devicePixelRatio; + + Future.delayed(Duration(milliseconds: renderNumber*100), () async{ + await initPlatformState(); + }); + } + + Future animate(Duration duration) async { + if (!mounted || _disposed || updating || !isVisibleOnScreen || !visible) { + return; + } + _updating = true; + double dt = clock.getDelta(); + + if(settings.animate){ + await (customRenderer?.call(scene,camera,texture!,dt) ?? render(scene,camera,texture!,dt)); + if(!pause){ + for(int i = 0; i < events.length;i++){ + events[i].call(dt); + } + } + } + _updating = false; + } + + Future render([core.Scene? scene, core.Camera? camera, FlutterAngleTexture? texture, double? dt]) async{ + scene ??= this.scene; + camera ??= this.camera; + texture ??= this.texture!; + + if(sourceTexture == null){ + angle?.activateTexture(texture); + } + rendererUpdate?.call(); + if(postProcessor == null){ + renderer!.clear(); + renderer!.setViewport(0,0,width,height); + renderer!.render(scene, camera); + } + else{ + postProcessor?.call(dt); + } + + if(sourceTexture != null){ + angle?.activateTexture(texture); + } + await angle?.updateTexture(texture,sourceTexture); + } + + void initRenderer() { + WebGLRendererParameters options = WebGLRendererParameters( + width: width, + height: height, + gl: gl!, + stencil: settings.stencil, + antialias: settings.antialias, + alpha: settings.alpha, + clearColor: settings.clearColor, + clearAlpha: settings.clearAlpha, + logarithmicDepthBuffer: settings.logarithmicDepthBuffer, + xr: settings.xr, + depth: settings.depth, + premultipliedAlpha: settings.premultipliedAlpha, + preserveDrawingBuffer: settings.preserveDrawingBuffer, + powerPreference: settings.powerPreference, + failIfMajorPerformanceCaveat: settings.failIfMajorPerformanceCaveat, + reverseDepthBuffer: settings.reverseDepthBuffer, + precision: settings.precision, + ); + + renderer = WebGLRenderer(options); + renderer!.setPixelRatio(_resolution!); + renderer!.setSize(width, height, false); + renderer!.alpha = settings.alpha; + renderer!.shadowMap.enabled = settings.enableShadowMap; + renderer!.shadowMap.type = settings.shadowMapType; + renderer!.autoClear = settings.autoClear; + renderer!.setClearColor( + Color.fromHex32(settings.clearColor), + settings.clearAlpha + ); + renderer!.autoClearDepth = settings.autoClearDepth; + renderer!.autoClearStencil = settings.autoClearStencil; + renderer!.outputEncoding = settings.outputEncoding; + renderer!.outputColorSpace = settings.colorSpace.toString(); + renderer!.localClippingEnabled = settings.localClippingEnabled; + renderer!.clippingPlanes = settings.clippingPlanes; + renderer!.toneMapping = settings.toneMapping; + renderer!.toneMappingExposure = settings.toneMappingExposure; + + if(settings.useSourceTexture){ + final RenderTargetOptions pars = RenderTargetOptions(settings.renderOptions); + renderTarget = WebGLRenderTarget((width * _resolution!).toInt(), (height * _resolution!).toInt(), pars); + renderer!.setRenderTarget(renderTarget); + sourceTexture = renderer!.getRenderTargetGLTexture(renderTarget!); + } + } + + Future _onWindowResize(BuildContext context) async{ + if (_disposed) return; + double dt = clock.getDelta(); + final mqd = MediaQuery.maybeOf(context); + if (mqd == null) return; + if(_fixedSize == null && screenSize != mqd.size && texture != null){ + screenSize = mqd.size; + + if(settings.screenResolution == null){ + _resolution = mqd.devicePixelRatio; + } + + final options = AngleOptions( + width: width.toInt(), + height: height.toInt(), + dpr: _resolution!, + ); + + await angle?.resize(texture!, options); + + camera.aspect = width/height; + camera.updateProjectionMatrix(); + + windowResizeUpdate?.call(screenSize!); + renderer!.setSize(width, height); + + if(postProcessor != null){ + postProcessor?.call(dt); + } + render(scene,camera,texture!,dt); + } + } + + Future initScene() async{ + if (renderer == null) { + initRenderer(); + } + await setup?.call(); + _mounted = true; + ticker = Ticker(animate); + ticker?.start(); + onSetupComplete(); + } + + Future initPlatformState() async { + if(texture == null){ + await angle?.init(); + + texture = await angle?.createTexture( + AngleOptions( + width: width.toInt(), + height: height.toInt(), + dpr: _resolution!, + alpha: settings.alpha, + antialias: settings.antialias, + customRenderer: !settings.useSourceTexture, + useSurfaceProducer: true + ) + ); + } + + console.info(texture?.toMap()); + if (gl == null) { + gl = texture!.getContext(); + } + await initScene(); + } + + Widget build() { + return Builder(builder: (BuildContext context) { + initSize(context); + return core.Peripherals( + key: globalKey, + builder: (BuildContext context) { + return Container( + width: !visible?0:width, + height: !visible?0:height, + child: SizeChangedLayoutNotifier( + child: Builder(builder: (BuildContext context) { + if (kIsWeb) { + return texture != null && mounted? HtmlElementView(viewType:texture!.textureId.toString()):loadingWidget ?? Container( + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height, + color: Theme.of(context).canvasColor, + alignment: Alignment.center, + child: const CircularProgressIndicator() + ); + } + else { + return texture != null && mounted? + Transform.scale( + scaleY: sourceTexture != null || Platform.isAndroid?1:-1, + child:Texture(textureId: texture!.textureId) + ):loadingWidget ?? Container( + width: MediaQuery.of(context).size.width, + height: MediaQuery.of(context).size.height, + color: Theme.of(context).canvasColor, + alignment: Alignment.center, + child: const CircularProgressIndicator() + ); + } + }) + ) + ); + } + ); + }); + } +} \ No newline at end of file diff --git a/packages/three_js_core/lib/renderers/webgl/index.dart b/packages/three_js_webgl_renderer/lib/webgl/index.dart similarity index 76% rename from packages/three_js_core/lib/renderers/webgl/index.dart rename to packages/three_js_webgl_renderer/lib/webgl/index.dart index 1b51907d..39ff278a 100755 --- a/packages/three_js_core/lib/renderers/webgl/index.dart +++ b/packages/three_js_webgl_renderer/lib/webgl/index.dart @@ -4,21 +4,12 @@ import 'dart:typed_data'; import 'dart:math' as math; import 'package:flutter/foundation.dart'; +import 'package:three_js_core/three_js_core.dart'; import 'package:three_js_math/three_js_math.dart'; -import '../../objects/index.dart'; -import '../../core/index.dart'; -import '../../others/index.dart'; -import '../index.dart'; -import '../../materials/index.dart'; -import '../../geometries/index.dart'; -import '../../textures/index.dart'; -import '../../cameras/index.dart'; -import '../../scenes/index.dart'; -import '../../lights/index.dart'; -import '../shaders/index.dart'; -import '../../math/frustum.dart'; -import '../pmrem_generator.dart'; import 'package:flutter_angle/flutter_angle.dart'; +import '../shaders/index.dart'; +import '../renderers/index.dart'; +import '../renderers/pmrem_generator.dart'; part 'web_gl_animation.dart'; part 'web_gl_attributes.dart'; diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_animation.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_animation.dart similarity index 100% rename from packages/three_js_core/lib/renderers/webgl/web_gl_animation.dart rename to packages/three_js_webgl_renderer/lib/webgl/web_gl_animation.dart diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_attributes.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_attributes.dart similarity index 97% rename from packages/three_js_core/lib/renderers/webgl/web_gl_attributes.dart rename to packages/three_js_webgl_renderer/lib/webgl/web_gl_attributes.dart index 11c38c5d..a15e5adc 100755 --- a/packages/three_js_core/lib/renderers/webgl/web_gl_attributes.dart +++ b/packages/three_js_webgl_renderer/lib/webgl/web_gl_attributes.dart @@ -8,7 +8,7 @@ class WebGLAttributes { WebGLAttributes(this.gl); - Map createBuffer(dynamic attribute, int bufferType, {String? name}) {//BufferAttribute + Map createBuffer(dynamic attribute, int bufferType, {String? name}) {//BufferAttribute> final array = attribute.array; final usage = attribute.usage; @@ -85,11 +85,12 @@ class WebGLAttributes { void updateBufferNew(Buffer buffer, attribute, int bufferType) { final array = attribute.array; + final updateRange = attribute.updateRange; final updateRanges = attribute.updateRanges; gl.bindBuffer(bufferType, buffer); - if (updateRanges!["length"] == 0) { + if (updateRange!["count"] == -1) { // Not using update ranges gl.bufferSubData(bufferType, 0, attribute.array); } @@ -123,7 +124,7 @@ class WebGLAttributes { updateRanges[ mergeIndex ] = range; } } - updateRanges.length = mergeIndex + 1; + for (int i = 0, l = updateRanges.length; i < l; i ++ ) { final range = updateRanges[i]; Float32List f = Float32List.fromList(attribute.array.sublist(range.start,range.count) as List); @@ -133,7 +134,7 @@ class WebGLAttributes { f, ); - //f.dispose(); + f.dispose(); } attribute.clearUpdateRanges(); diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_background.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_background.dart similarity index 100% rename from packages/three_js_core/lib/renderers/webgl/web_gl_background.dart rename to packages/three_js_webgl_renderer/lib/webgl/web_gl_background.dart diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_binding_states.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_binding_states.dart similarity index 92% rename from packages/three_js_core/lib/renderers/webgl/web_gl_binding_states.dart rename to packages/three_js_webgl_renderer/lib/webgl/web_gl_binding_states.dart index 1f593a31..ba7c227e 100755 --- a/packages/three_js_core/lib/renderers/webgl/web_gl_binding_states.dart +++ b/packages/three_js_webgl_renderer/lib/webgl/web_gl_binding_states.dart @@ -42,6 +42,7 @@ class WebGLBindingStates { } updateBuffers = needsUpdate(object, geometry, program, index); + // print("WebGLBindingStates.dart setup object: ${object} updateBuffers: ${updateBuffers} "); if (updateBuffers) saveCache(object, geometry, program, index); @@ -116,11 +117,11 @@ class WebGLBindingStates { final enabledAttributes = List.filled(maxVertexAttributes, 0); final attributeDivisors = List.filled(maxVertexAttributes, 0); - // for (int i = 0; i < maxVertexAttributes; i++) { - // newAttributes[i] = 0; - // enabledAttributes[i] = 0; - // attributeDivisors[i] = 0; - // } + for (int i = 0; i < maxVertexAttributes; i++) { + newAttributes[i] = 0; + enabledAttributes[i] = 0; + attributeDivisors[i] = 0; + } return { // for backward compatibility on non-VAO support browser @@ -214,11 +215,11 @@ class WebGLBindingStates { } } - void enableAttribute(int attribute) { + void enableAttribute(attribute) { enableAttributeAndDivisor(attribute, 0); } - void enableAttributeAndDivisor(int attribute, int meshPerAttribute) { + void enableAttributeAndDivisor(attribute, meshPerAttribute) { final newAttributes = currentState["newAttributes"]; final enabledAttributes = currentState["enabledAttributes"]; final attributeDivisors = currentState["attributeDivisors"]; @@ -249,7 +250,7 @@ class WebGLBindingStates { } void vertexAttribPointer(int index, int size, int type, bool normalized, int stride, int offset, bool integer) { - if (integer){ + if (integer){//(type == WebGL.INT || type == WebGL.UNSIGNED_INT) && !kIsWeb) { gl.vertexAttribIPointer(index, size, type, stride, offset); } else { gl.vertexAttribPointer(index, size, type, normalized, stride, offset); @@ -274,6 +275,7 @@ class WebGLBindingStates { final programAttribute = programAttributes[name]; if (programAttribute!.location.id >= 0) { + // final geometryAttribute = geometryAttributes[ name ]; BufferAttribute? geometryAttribute = geometryAttributes[name]; if (geometryAttribute == null) { @@ -303,12 +305,14 @@ class WebGLBindingStates { final bytesPerElement = attribute["bytesPerElement"]; final integer = ( type == WebGL.INT || type == WebGL.UNSIGNED_INT) && geometryAttribute.gpuType == IntType; + if (geometryAttribute is InterleavedBufferAttribute) { final data = geometryAttribute.data; final stride = data?.stride; final offset = geometryAttribute.offset; if (data != null && data is InstancedInterleavedBuffer) { + // enableAttributeAndDivisor( programAttribute, data.meshPerAttribute ); for (int i = 0; i < programAttribute.locationSize; i++) { enableAttributeAndDivisor(programAttribute.location.id + i, data.meshPerAttribute); } @@ -316,8 +320,8 @@ class WebGLBindingStates { if (object is! InstancedMesh && geometry.maxInstanceCount == null) { geometry.maxInstanceCount = data.meshPerAttribute * data.count; } - } - else { + } else { + // enableAttribute( programAttribute ); for (int i = 0; i < programAttribute.locationSize; i++) { enableAttribute(programAttribute.location.id + i); } @@ -325,6 +329,7 @@ class WebGLBindingStates { gl.bindBuffer(WebGL.ARRAY_BUFFER, buffer); + // vertexAttribPointer( programAttribute, size, type, normalized, stride * bytesPerElement, offset * bytesPerElement ); for (int i = 0; i < programAttribute.locationSize; i++) { vertexAttribPointer( programAttribute.location.id + i, @@ -339,18 +344,21 @@ class WebGLBindingStates { } else { if (geometryAttribute is InstancedBufferAttribute) { + // enableAttributeAndDivisor( programAttribute, geometryAttribute.meshPerAttribute ); for (int i = 0; i < programAttribute.locationSize; i++) { enableAttributeAndDivisor(programAttribute.location.id + i, geometryAttribute.meshPerAttribute); } geometry.maxInstanceCount ??= geometryAttribute.meshPerAttribute * geometryAttribute.count; } else { + // enableAttribute( programAttribute ); for (int i = 0; i < programAttribute.locationSize; i++) { enableAttribute(programAttribute.location.id + i); } } gl.bindBuffer(WebGL.ARRAY_BUFFER, buffer); + //vertexAttribPointer( programAttribute, size, type, normalized, 0, 0 ); for (int i = 0; i < programAttribute.locationSize; i++) { vertexAttribPointer( programAttribute.location.id + i, @@ -372,12 +380,15 @@ class WebGLBindingStates { case 2: gl.vertexAttrib2fv(programAttribute.location.id, value); break; + case 3: gl.vertexAttrib3fv(programAttribute.location.id, value); break; + case 4: gl.vertexAttrib4fv(programAttribute.location.id, value); break; + default: gl.vertexAttrib1fv(programAttribute.location.id, value); } @@ -442,7 +453,7 @@ class WebGLBindingStates { deleteVertexArrayObject( stateMap[ wireframe ]['object'] ); } (stateMap as Map).clear(); - (programMap as Map).remove(program.id); + (programMap as Map).remove(program.id);//delete programMap[ program.id ]; } } diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_buffer_renderer.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_buffer_renderer.dart similarity index 100% rename from packages/three_js_core/lib/renderers/webgl/web_gl_buffer_renderer.dart rename to packages/three_js_webgl_renderer/lib/webgl/web_gl_buffer_renderer.dart diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_capabilities.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_capabilities.dart similarity index 95% rename from packages/three_js_core/lib/renderers/webgl/web_gl_capabilities.dart rename to packages/three_js_webgl_renderer/lib/webgl/web_gl_capabilities.dart index 09c80251..fe252b3d 100755 --- a/packages/three_js_core/lib/renderers/webgl/web_gl_capabilities.dart +++ b/packages/three_js_webgl_renderer/lib/webgl/web_gl_capabilities.dart @@ -39,8 +39,8 @@ class WebGLCapabilities { precision = maxPrecision; } - logarithmicDepthBuffer = parameters.logarithmicDepthBuffer == true; - reverseDepthBuffer = parameters.reverseDepthBuffer == true && extensions.has( 'EXT_clip_control' ); + logarithmicDepthBuffer = parameters.logarithmicDepthBuffer; + reverseDepthBuffer = parameters.reverseDepthBuffer && extensions.has( 'EXT_clip_control' ); maxTextures = gl.getParameter(WebGL.MAX_TEXTURE_IMAGE_UNITS); maxVertexTextures = gl.getParameter(WebGL.MAX_VERTEX_TEXTURE_IMAGE_UNITS); diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_clipping.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_clipping.dart similarity index 100% rename from packages/three_js_core/lib/renderers/webgl/web_gl_clipping.dart rename to packages/three_js_webgl_renderer/lib/webgl/web_gl_clipping.dart diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_cube_maps.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_cube_maps.dart similarity index 100% rename from packages/three_js_core/lib/renderers/webgl/web_gl_cube_maps.dart rename to packages/three_js_webgl_renderer/lib/webgl/web_gl_cube_maps.dart diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_cube_uv_maps.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_cube_uv_maps.dart similarity index 98% rename from packages/three_js_core/lib/renderers/webgl/web_gl_cube_uv_maps.dart rename to packages/three_js_webgl_renderer/lib/webgl/web_gl_cube_uv_maps.dart index 84093fa9..091fe275 100755 --- a/packages/three_js_core/lib/renderers/webgl/web_gl_cube_uv_maps.dart +++ b/packages/three_js_webgl_renderer/lib/webgl/web_gl_cube_uv_maps.dart @@ -79,7 +79,7 @@ class WebGLCubeUVMaps { final cubemapUV = cubeUVmaps.get(texture); if (cubemapUV != null) { - cubeUVmaps.delete(texture); + cubemapUV.delete(texture); cubemapUV.dispose(); } } diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_extensions.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_extensions.dart similarity index 78% rename from packages/three_js_core/lib/renderers/webgl/web_gl_extensions.dart rename to packages/three_js_webgl_renderer/lib/webgl/web_gl_extensions.dart index b171e3eb..291e88f6 100755 --- a/packages/three_js_core/lib/renderers/webgl/web_gl_extensions.dart +++ b/packages/three_js_webgl_renderer/lib/webgl/web_gl_extensions.dart @@ -14,13 +14,28 @@ class WebGLExtensions { return _has(name); } - void init() { - getExtension( 'EXT_color_buffer_float' ); - getExtension( 'WEBGL_clip_cull_distance' ); - getExtension( 'OES_texture_float_linear' ); - getExtension( 'EXT_color_buffer_half_float' ); - getExtension( 'WEBGL_multisampled_render_to_texture' ); - getExtension( 'WEBGL_render_shared_exponent' ); + void init() {//capabilities + // if (capabilities.isWebGL2) { + getExtension( 'EXT_color_buffer_float' ); + getExtension( 'WEBGL_clip_cull_distance' ); + getExtension( 'OES_texture_float_linear' ); + getExtension( 'EXT_color_buffer_half_float' ); + getExtension( 'WEBGL_multisampled_render_to_texture' ); + getExtension( 'WEBGL_render_shared_exponent' ); + // } + // else { + // getExtension('WEBGL_depth_texture'); + // getExtension('OES_texture_float'); + // getExtension('OES_texture_half_float'); + // getExtension('OES_texture_half_float_linear'); + // getExtension('OES_standard_derivatives'); + // getExtension('OES_element_index_uint'); + // getExtension('OES_vertex_array_object'); + // getExtension('ANGLE_instanced_arrays'); + // } + + // getExtension('OES_texture_float_linear'); + // getExtension('EXT_color_buffer_half_float'); } dynamic _has(String name) { diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_geometries.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_geometries.dart similarity index 99% rename from packages/three_js_core/lib/renderers/webgl/web_gl_geometries.dart rename to packages/three_js_webgl_renderer/lib/webgl/web_gl_geometries.dart index a602e36a..082fe817 100755 --- a/packages/three_js_core/lib/renderers/webgl/web_gl_geometries.dart +++ b/packages/three_js_webgl_renderer/lib/webgl/web_gl_geometries.dart @@ -75,7 +75,7 @@ class WebGLGeometries { } void updateWireframeAttribute(BufferGeometry geometry) { - Uint32List indices = Uint32List(0); + List indices = []; final geometryIndex = geometry.index; final geometryPosition = geometry.attributes["position"]; diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_indexed_buffer_renderer.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_indexed_buffer_renderer.dart similarity index 100% rename from packages/three_js_core/lib/renderers/webgl/web_gl_indexed_buffer_renderer.dart rename to packages/three_js_webgl_renderer/lib/webgl/web_gl_indexed_buffer_renderer.dart diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_info.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_info.dart similarity index 100% rename from packages/three_js_core/lib/renderers/webgl/web_gl_info.dart rename to packages/three_js_webgl_renderer/lib/webgl/web_gl_info.dart diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_lights.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_lights.dart similarity index 100% rename from packages/three_js_core/lib/renderers/webgl/web_gl_lights.dart rename to packages/three_js_webgl_renderer/lib/webgl/web_gl_lights.dart diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_materials.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_materials.dart similarity index 99% rename from packages/three_js_core/lib/renderers/webgl/web_gl_materials.dart rename to packages/three_js_webgl_renderer/lib/webgl/web_gl_materials.dart index f386fa7d..f848b3cf 100755 --- a/packages/three_js_core/lib/renderers/webgl/web_gl_materials.dart +++ b/packages/three_js_webgl_renderer/lib/webgl/web_gl_materials.dart @@ -44,17 +44,17 @@ class WebGLMaterials { } else if (material is MeshPhongMaterial) { refreshUniformsCommon(uniforms, material); refreshUniformsPhong(uniforms, material); - } else if (material is MeshPhysicalMaterial) { - refreshUniformsCommon(uniforms, material); - refreshUniformsStandard(uniforms, material); - refreshUniformsPhysical(uniforms, material, transmissionRenderTarget); } else if (material is MeshStandardMaterial) { refreshUniformsCommon(uniforms, material); refreshUniformsStandard(uniforms, material); if ( material is MeshPhysicalMaterial ) { refreshUniformsPhysical( uniforms, material, transmissionRenderTarget ); } - } else if (material is MeshMatcapMaterial) { + } else if (material is MeshPhysicalMaterial) { + refreshUniformsCommon(uniforms, material); + refreshUniformsStandard(uniforms, material); + refreshUniformsPhysical(uniforms, material, transmissionRenderTarget); + }else if (material is MeshMatcapMaterial) { refreshUniformsCommon(uniforms, material); refreshUniformsMatcap(uniforms, material); } else if (material is MeshDepthMaterial) { diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_morphtargets.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_morphtargets.dart similarity index 98% rename from packages/three_js_core/lib/renderers/webgl/web_gl_morphtargets.dart rename to packages/three_js_webgl_renderer/lib/webgl/web_gl_morphtargets.dart index 00380f0a..582caf5e 100755 --- a/packages/three_js_core/lib/renderers/webgl/web_gl_morphtargets.dart +++ b/packages/three_js_webgl_renderer/lib/webgl/web_gl_morphtargets.dart @@ -58,7 +58,7 @@ class WebGLMorphtargets { } void update(Object3D object, BufferGeometry geometry, WebGLProgram program) { - Float32List? objectInfluences = Float32List.fromList(object.morphTargetInfluences); + List? objectInfluences = object.morphTargetInfluences; final morphAttribute = geometry.morphAttributes["position"] ?? geometry.morphAttributes["normal"] ?? geometry.morphAttributes["color"]; final morphTargetsCount = (morphAttribute != null) ? morphAttribute.length : 0; diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_objects.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_objects.dart similarity index 100% rename from packages/three_js_core/lib/renderers/webgl/web_gl_objects.dart rename to packages/three_js_webgl_renderer/lib/webgl/web_gl_objects.dart diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_parameters.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_parameters.dart similarity index 100% rename from packages/three_js_core/lib/renderers/webgl/web_gl_parameters.dart rename to packages/three_js_webgl_renderer/lib/webgl/web_gl_parameters.dart diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_program.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_program.dart similarity index 100% rename from packages/three_js_core/lib/renderers/webgl/web_gl_program.dart rename to packages/three_js_webgl_renderer/lib/webgl/web_gl_program.dart diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_program_extra.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_program_extra.dart similarity index 100% rename from packages/three_js_core/lib/renderers/webgl/web_gl_program_extra.dart rename to packages/three_js_webgl_renderer/lib/webgl/web_gl_program_extra.dart diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_programs.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_programs.dart similarity index 100% rename from packages/three_js_core/lib/renderers/webgl/web_gl_programs.dart rename to packages/three_js_webgl_renderer/lib/webgl/web_gl_programs.dart diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_properties.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_properties.dart similarity index 97% rename from packages/three_js_core/lib/renderers/webgl/web_gl_properties.dart rename to packages/three_js_webgl_renderer/lib/webgl/web_gl_properties.dart index 78104abf..6dc26403 100755 --- a/packages/three_js_core/lib/renderers/webgl/web_gl_properties.dart +++ b/packages/three_js_webgl_renderer/lib/webgl/web_gl_properties.dart @@ -13,8 +13,7 @@ class WebGLProperties { if (!properties.contains(object)) { map = {}; properties[object] = map; - } - else { + } else { map = properties[object]!; } diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_render_list.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_render_list.dart similarity index 100% rename from packages/three_js_core/lib/renderers/webgl/web_gl_render_list.dart rename to packages/three_js_webgl_renderer/lib/webgl/web_gl_render_list.dart diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_render_lists.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_render_lists.dart similarity index 100% rename from packages/three_js_core/lib/renderers/webgl/web_gl_render_lists.dart rename to packages/three_js_webgl_renderer/lib/webgl/web_gl_render_lists.dart diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_render_states.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_render_states.dart similarity index 100% rename from packages/three_js_core/lib/renderers/webgl/web_gl_render_states.dart rename to packages/three_js_webgl_renderer/lib/webgl/web_gl_render_states.dart diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_shader.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_shader.dart similarity index 100% rename from packages/three_js_core/lib/renderers/webgl/web_gl_shader.dart rename to packages/three_js_webgl_renderer/lib/webgl/web_gl_shader.dart diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_shader_cache.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_shader_cache.dart similarity index 100% rename from packages/three_js_core/lib/renderers/webgl/web_gl_shader_cache.dart rename to packages/three_js_webgl_renderer/lib/webgl/web_gl_shader_cache.dart diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_shadow_map.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_shadow_map.dart similarity index 99% rename from packages/three_js_core/lib/renderers/webgl/web_gl_shadow_map.dart rename to packages/three_js_webgl_renderer/lib/webgl/web_gl_shadow_map.dart index f9335764..b573575d 100755 --- a/packages/three_js_core/lib/renderers/webgl/web_gl_shadow_map.dart +++ b/packages/three_js_webgl_renderer/lib/webgl/web_gl_shadow_map.dart @@ -151,7 +151,7 @@ class WebGLShadowMap { shadow.map?.dispose(); } - shadow.map = WebGLRenderTarget(_shadowMapSize.x.toInt(), _shadowMapSize.y.toInt(), WebGLRenderTargetOptions(pars)); + shadow.map = WebGLRenderTarget(_shadowMapSize.x.toInt(), _shadowMapSize.y.toInt(), RenderTargetOptions(pars)); shadow.map!.texture.name = '${light.name}.shadowMap'; shadow.camera!.updateProjectionMatrix(); diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_state.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_state.dart similarity index 98% rename from packages/three_js_core/lib/renderers/webgl/web_gl_state.dart rename to packages/three_js_webgl_renderer/lib/webgl/web_gl_state.dart index 170f1f05..3478cf31 100755 --- a/packages/three_js_core/lib/renderers/webgl/web_gl_state.dart +++ b/packages/three_js_webgl_renderer/lib/webgl/web_gl_state.dart @@ -17,7 +17,7 @@ class WebGLState { Map get buffers => {"color": colorBuffer, "depth": depthBuffer, "stencil": stencilBuffer}; Map enabledCapabilities = {}; - Framebuffer? xrFramebuffer; + dynamic xrFramebuffer; Map currentBoundFramebuffers = {}; final uboBindings = WeakMap(); final uboProgramMap = WeakMap(); @@ -77,6 +77,8 @@ class WebGLState { emptyTextures[WebGL.TEXTURE_2D] = createTexture(WebGL.TEXTURE_2D, WebGL.TEXTURE_2D, 1); emptyTextures[WebGL.TEXTURE_CUBE_MAP] = createTexture(WebGL.TEXTURE_CUBE_MAP, WebGL.TEXTURE_CUBE_MAP_POSITIVE_X, 6); + // init + colorBuffer.setClear(0, 0, 0, 1, false); depthBuffer.setClear(1); stencilBuffer.setClear(0); @@ -123,9 +125,8 @@ class WebGLState { currentViewport = Vector4.identity(); } - final data = Uint8List(4); - WebGLTexture createTexture(int type, int target, int count) { + final data = Uint8List(4); // 4 is required to match default unpack alignment of 4. // final texture = gl.createTexture(); @@ -138,7 +139,7 @@ class WebGLState { gl.texImage2D(target + i, 0, WebGL.RGBA, 1, 1, 0, WebGL.RGBA, WebGL.UNSIGNED_BYTE, data); } - //data.dispose(); + data.dispose(); return texture; } @@ -160,6 +161,7 @@ class WebGLState { void bindXRFramebuffer(Framebuffer? framebuffer) { if (framebuffer != xrFramebuffer) { gl.bindFramebuffer(WebGL.FRAMEBUFFER, framebuffer); + xrFramebuffer = framebuffer; } } @@ -175,6 +177,7 @@ class WebGLState { currentBoundFramebuffers[target] = framebuffer; // gl.DRAW_FRAMEBUFFER is equivalent to gl.FRAMEBUFFER + if (target == WebGL.DRAW_FRAMEBUFFER) { currentBoundFramebuffers[WebGL.FRAMEBUFFER] = framebuffer; } @@ -527,7 +530,7 @@ class WebGLState { int height, int depth, int format, - TypedData? data, + TypedDataList? data, ) { gl.compressedTexSubImage3D(target,level,xoffset,yoffset,zoffset,width,height,depth,format,data); } @@ -539,21 +542,21 @@ class WebGLState { int height, int depth, int border, - TypedData? data, + TypedDataList? data, ) { gl.compressedTexImage3D(target,level,internalformat,width,height,depth,border,data); } - void compressedTexImage2D(int target, int level, int internalformat, int width, int height, int border, TypedData? pixels) { + void compressedTexImage2D(int target, int level, int internalformat, int width, int height, int border, TypedDataList? pixels) { gl.compressedTexImage2D(target, level, internalformat, width, height, border, pixels); } - void texSubImage2D(int target, int level, int x, int y, num width, num height, int glFormat, int glType, TypedData data) { + void texSubImage2D(int target, int level, int x, int y, num width, num height, int glFormat, int glType, TypedDataList data) { gl.texSubImage2D(target, level, x, y, width.toInt(), height.toInt(), glFormat, glType, data); } void texSubImage2DIf(int target, int level, int x, int y, int glFormat, int glType, ImageElement image) { - if (kIsWeb && image.data is! TypedData) { + if (kIsWeb && image.data is! TypedDataList) { texSubImage2DNoSize(WebGL.TEXTURE_2D, 0, 0, 0, glFormat, glType, image.data); } else { @@ -570,7 +573,7 @@ class WebGLState { } } - void texSubImage3D(int target, int level, int xoffset, int yoffset, int zoffset, int width, int height, int depth, int format, int type, TypedData? pixels) { + void texSubImage3D(int target, int level, int xoffset, int yoffset, int zoffset, int width, int height, int depth, int format, int type, TypedDataList? pixels) { gl.texSubImage3D(target, level, xoffset, yoffset, zoffset, width, height, depth, format, type, pixels); } @@ -582,7 +585,7 @@ class WebGLState { int width, int height, int format, - TypedData? pixels, + TypedDataList? pixels, ) { gl.compressedTexSubImage2D(target, level, xoffset, yoffset, width, height, format, pixels); } diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_textures.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_textures.dart similarity index 88% rename from packages/three_js_core/lib/renderers/webgl/web_gl_textures.dart rename to packages/three_js_webgl_renderer/lib/webgl/web_gl_textures.dart index 52d35bf5..0f580d66 100755 --- a/packages/three_js_core/lib/renderers/webgl/web_gl_textures.dart +++ b/packages/three_js_webgl_renderer/lib/webgl/web_gl_textures.dart @@ -33,6 +33,7 @@ class WebGLTextures { dynamic multisampledRTTExt; final bool supportsInvalidateFramebuffer = false;//typeof navigator === 'undefined' ? false : /OculusBrowser/g.test( navigator.userAgent ); + WebGLTextures(this.gl, this.extensions, this.state, this.properties, this.capabilities, this.utils, this.info) { maxTextures = capabilities.maxTextures; maxCubemapSize = capabilities.maxCubemapSize; @@ -40,7 +41,9 @@ class WebGLTextures { maxSamples = capabilities.maxSamples; multisampledRTTExt = extensions.has( 'WEBGL_multisampled_render_to_texture' )? extensions.get( 'WEBGL_multisampled_render_to_texture' ) : null; - multisampledRenderToTextureExtension = extensions.has('WEBGL_multisampled_render_to_texture')? extensions.get('WEBGL_multisampled_render_to_texture'): null; + multisampledRenderToTextureExtension = extensions.has('WEBGL_multisampled_render_to_texture') + ? extensions.get('WEBGL_multisampled_render_to_texture') + : null; wrappingToGL[RepeatWrapping] = WebGL.REPEAT; wrappingToGL[ClampToEdgeWrapping] = WebGL.CLAMP_TO_EDGE; @@ -237,6 +240,8 @@ class WebGLTextures { if (textureProperties["__webglInit"] == null) return; + // check if it's necessary to remove the WebGLTexture object + final source = texture.source; final webglTextures = _sources.get(source); @@ -244,10 +249,14 @@ class WebGLTextures { Map webglTexture = webglTextures[textureProperties["__cacheKey"]]; webglTexture["usedTimes"]--; + // the WebGLTexture object is not used anymore, remove it + if (webglTexture["usedTimes"] == 0) { deleteTexture(texture); } + // remove the weak map entry if no WebGLTexture uses the source anymore + if (webglTextures.keys.length == 0) { _sources.delete(source); } @@ -303,7 +312,7 @@ class WebGLTextures { } if (renderTargetProperties["__webglColorRenderbuffer"] != null) { for (int i = 0; i < renderTargetProperties['__webglColorRenderbuffer'].length; i ++ ) { - if ( renderTargetProperties['__webglColorRenderbuffer'][ i ] != null) _gl.deleteRenderbuffer( renderTargetProperties['__webglColorRenderbuffer'][ i ] ); + if ( renderTargetProperties['__webglColorRenderbuffer'][ i ] ) _gl.deleteRenderbuffer( renderTargetProperties['__webglColorRenderbuffer'][ i ] ); } } if (renderTargetProperties["__webglDepthRenderbuffer"] != null) { @@ -384,8 +393,13 @@ class WebGLTextures { return; } } - state.activeTexture(WebGL.TEXTURE0 + slot); - state.bindTexture(WebGL.TEXTURE_2D, textureProperties["__webglTexture"]); + if(kIsWeb){ + state.bindTexture(WebGL.TEXTURE_2D, textureProperties["__webglTexture"], WebGL.TEXTURE0 + slot); + } + else{ + state.activeTexture(WebGL.TEXTURE0 + slot); + state.bindTexture(WebGL.TEXTURE_2D, textureProperties["__webglTexture"]); + } } void setTexture2DArray(Texture texture, int slot) { @@ -395,8 +409,13 @@ class WebGLTextures { uploadTexture(textureProperties, texture, slot); return; } - state.activeTexture(WebGL.TEXTURE0 + slot); - state.bindTexture(WebGL.TEXTURE_2D_ARRAY, textureProperties["__webglTexture"]); + if(kIsWeb){ + state.bindTexture(WebGL.TEXTURE_2D_ARRAY, textureProperties["__webglTexture"],WebGL.TEXTURE0 + slot); + } + else{ + state.activeTexture(WebGL.TEXTURE0 + slot); + state.bindTexture(WebGL.TEXTURE_2D_ARRAY, textureProperties["__webglTexture"]); + } } void setTexture3D(Texture texture, int slot) { @@ -406,8 +425,12 @@ class WebGLTextures { uploadTexture(textureProperties, texture, slot); return; } - state.activeTexture(WebGL.TEXTURE0 + slot); - state.bindTexture(WebGL.TEXTURE_3D, textureProperties["__webglTexture"]); + if(kIsWeb){ + state.bindTexture(WebGL.TEXTURE_3D, textureProperties["__webglTexture"], WebGL.TEXTURE0 + slot); + }else{ + state.activeTexture(WebGL.TEXTURE0 + slot); + state.bindTexture(WebGL.TEXTURE_3D, textureProperties["__webglTexture"]); + } } void setTextureCube(Texture texture, int slot) { @@ -417,9 +440,13 @@ class WebGLTextures { uploadCubeTexture(textureProperties, texture, slot); return; } - - state.activeTexture(WebGL.TEXTURE0 + slot); - state.bindTexture(WebGL.TEXTURE_CUBE_MAP, textureProperties["__webglTexture"]); + if(kIsWeb){ + state.bindTexture(WebGL.TEXTURE_CUBE_MAP, textureProperties["__webglTexture"], WebGL.TEXTURE0 + slot); + } + else{ + state.activeTexture(WebGL.TEXTURE0 + slot); + state.bindTexture(WebGL.TEXTURE_CUBE_MAP, textureProperties["__webglTexture"]); + } } void setTextureParameters(textureType, Texture texture, [supportsMips]) { @@ -433,7 +460,9 @@ class WebGLTextures { _gl.texParameteri( textureType, WebGL.TEXTURE_WRAP_T, wrappingToGL[ texture.wrapT ]! ); if ( textureType == WebGL.TEXTURE_3D || textureType == WebGL.TEXTURE_2D_ARRAY ) { + _gl.texParameteri( textureType, WebGL.TEXTURE_WRAP_R, wrappingToGL[ texture.wrapR ]! ); + } _gl.texParameteri( textureType, WebGL.TEXTURE_MAG_FILTER, filterToGL[ texture.magFilter ]! ); @@ -450,13 +479,13 @@ class WebGLTextures { if ( texture.type == FloatType && !extensions.has( 'OES_texture_float_linear' )) return; // verify extension if ( texture.anisotropy > 1 || properties.get( texture )['__currentAnisotropy'] != null) { - // final extension = extensions.get( 'EXT_texture_filter_anisotropic' ); - // if (kIsWeb && !kIsWasm) { - // gl.texParameterf(textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT,math.min(texture.anisotropy, capabilities.getMaxAnisotropy()).toDouble()); - // } - // else { + final extension = extensions.get( 'EXT_texture_filter_anisotropic' ); + if (kIsWeb) { + gl.texParameterf(textureType, extension.TEXTURE_MAX_ANISOTROPY_EXT,math.min(texture.anisotropy, capabilities.getMaxAnisotropy()).toDouble()); + } + else { gl.texParameterf(textureType, WebGL.TEXTURE_MAX_ANISOTROPY_EXT,math.min(texture.anisotropy, capabilities.getMaxAnisotropy()).toDouble()); - //} + } properties.get( texture )['__currentAnisotropy'] = texture.anisotropy; } } @@ -523,101 +552,6 @@ class WebGLTextures { return forceUpload; } - int getRow(int index, num rowLength, int componentStride ) { - return ( ( index / componentStride ).floor() / rowLength ).floor(); - } - - void updateTexture(Texture texture, ImageElement image, int glFormat, int glType ) { - int componentStride = 4; // only RGBA supported - final updateRanges = texture.updateRanges; - - if ( updateRanges.length == 0 ) { - state.texSubImage2D( WebGL.TEXTURE_2D, 0, 0, 0, image.width, image.height, glFormat, glType, image.data ); - } - else { - - // Before applying update ranges, we merge any adjacent / overlapping - // ranges to reduce load on `gl.texSubImage2D`. Empirically, this has led - // to performance improvements for applications which make heavy use of - // update ranges. Likely due to GPU command overhead. - // - // Note that to reduce garbage collection between frames, we merge the - // update ranges in-place. This is safe because this method will clear the - // update ranges once updated. - - updateRanges.sort( ( a, b ) => a.start - b.start ); - - // To merge the update ranges in-place, we work from left to right in the - // existing updateRanges array, merging ranges. This may result in a final - // array which is smaller than the original. This index tracks the last - // index representing a merged range, any data after this index can be - // trimmed once the merge algorithm is completed. - int mergeIndex = 0; - - for (int i = 1; i < updateRanges.length; i ++ ) { - final previousRange = updateRanges[ mergeIndex ]; - final range = updateRanges[ i ]; - - // Only merge if in the same row and overlapping/adjacent - final previousEnd = previousRange.start + previousRange.count; - final currentRow = getRow( range.start, image.width, componentStride ); - final previousRow = getRow( previousRange.start, image.width, componentStride ); - - // We add one here to merge adjacent ranges. This is safe because ranges - // operate over positive integers. - if ( - range.start <= previousEnd + 1 && - currentRow == previousRow && - getRow( range.start + range.count - 1, image.width, componentStride ) == currentRow // ensure range doesn't spill - ) { - - previousRange.count = math.max( - previousRange.count, - range.start + range.count - previousRange.start - ); - - } else { - ++ mergeIndex; - updateRanges[ mergeIndex ] = range; - } - } - - // Trim the array to only contain the merged ranges. - updateRanges.length = mergeIndex + 1; - - final currentUnpackRowLen = _gl.getParameter( WebGL.UNPACK_ROW_LENGTH ); - final currentUnpackSkipPixels = _gl.getParameter( WebGL.UNPACK_SKIP_PIXELS ); - final currentUnpackSkipRows = _gl.getParameter( WebGL.UNPACK_SKIP_ROWS ); - - _gl.pixelStorei( WebGL.UNPACK_ROW_LENGTH, image.width.toInt() ); - - for (int i = 0, l = updateRanges.length; i < l; i ++ ) { - final range = updateRanges[ i ]; - - final pixelStart = ( range.start / componentStride ).floor(); - final pixelCount = ( range.count / componentStride ).ceil(); - - final x = (pixelStart % image.width).toInt(); - final y = ( pixelStart / image.width ).floor(); - - // Assumes update ranges refer to contiguous memory - final width = pixelCount; - final height = 1; - - _gl.pixelStorei( WebGL.UNPACK_SKIP_PIXELS, x ); - _gl.pixelStorei( WebGL.UNPACK_SKIP_ROWS, y ); - - state.texSubImage2D( WebGL.TEXTURE_2D, 0, x, y, width, height, glFormat, glType, image.data ); - } - - texture.clearUpdateRanges(); - - _gl.pixelStorei( WebGL.UNPACK_ROW_LENGTH, currentUnpackRowLen ); - _gl.pixelStorei( WebGL.UNPACK_SKIP_PIXELS, currentUnpackSkipPixels ); - _gl.pixelStorei( WebGL.UNPACK_SKIP_ROWS, currentUnpackSkipRows ); - } - } - void uploadTexture(Map textureProperties, Texture texture, int slot) { dynamic textureType = WebGL.TEXTURE_2D; @@ -653,7 +587,6 @@ class WebGLTextures { final useTexStorage = (isWebGL2 && texture is! VideoTexture); final allocateMemory = (textureProperties["__version"] == null) || (forceUpload == true); - final dataReady = source.dataReady; final levels = getMipLevels(texture, image); if (texture is DepthTexture) { @@ -678,10 +611,9 @@ class WebGLTextures { for (int i = 0, il = mipmaps.length; i < il; i++) { mipmap = mipmaps[i]; - if (useTexStorage && dataReady) { + if (useTexStorage) { state.texSubImage2D(WebGL.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data); - } - else { + } else { state.texImage2D(WebGL.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data); } } @@ -694,9 +626,7 @@ class WebGLTextures { if (allocateMemory) { state.texStorage2D(WebGL.TEXTURE_2D, levels, glInternalFormat, image.width.toInt(), image.height.toInt()); } - if ( dataReady ) { - updateTexture( texture, image, glFormat, glType ); - } + state.texSubImage2D(WebGL.TEXTURE_2D, 0, 0, 0, image.width, image.height, glFormat, glType, image.data); } else { state.texImage2D(WebGL.TEXTURE_2D, 0, glInternalFormat, image.width, image.height, 0, glFormat, glType, image.data); @@ -713,7 +643,7 @@ class WebGLTextures { mipmap = mipmaps[ i ]; if ( texture.format != RGBAFormat ) { if ( glFormat > 0 ) { - if ( useTexStorage && dataReady) { + if ( useTexStorage ) { if ( texture.layerUpdates.isNotEmpty ) { final layerByteLength = TextureUtils.getByteLength( mipmap.width, mipmap.height, texture.format, texture.type ); for ( final layerIndex in texture.layerUpdates ) { @@ -734,7 +664,7 @@ class WebGLTextures { console.warning( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()' ); } } else { - if ( useTexStorage && dataReady) { + if ( useTexStorage ) { state.texSubImage3D( WebGL.TEXTURE_2D_ARRAY, i, 0, 0, 0, mipmap.width, mipmap.height, image.depth, glFormat, glType, mipmap.data ); } else { state.texImage3D( WebGL.TEXTURE_2D_ARRAY, i, glInternalFormat, mipmap.width, mipmap.height, image.depth, 0, glFormat, glType, mipmap.data ); @@ -751,7 +681,7 @@ class WebGLTextures { if ( texture.format != RGBAFormat ) { if ( glFormat > 0 ) { - if ( useTexStorage && dataReady) { + if ( useTexStorage ) { state.compressedTexSubImage2D( WebGL.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data ); } else { state.compressedTexImage2D( WebGL.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data ); @@ -760,7 +690,7 @@ class WebGLTextures { console.warning( 'THREE.WebGLRenderer: Attempt to load unsupported compressed texture format in .uploadTexture()' ); } } else { - if ( useTexStorage && dataReady) { + if ( useTexStorage ) { state.texSubImage2D( WebGL.TEXTURE_2D, i, 0, 0, mipmap.width, mipmap.height, glFormat, glType, mipmap.data ); } else { state.texImage2D( WebGL.TEXTURE_2D, i, glInternalFormat, mipmap.width, mipmap.height, 0, glFormat, glType, mipmap.data ); @@ -774,23 +704,21 @@ class WebGLTextures { if (allocateMemory) { state.texStorage3D(WebGL.TEXTURE_2D_ARRAY, levels, glInternalFormat, image.width, image.height, image.depth); } - if(dataReady){ - if ( texture.layerUpdates.isNotEmpty ) { - final layerByteLength = TextureUtils.getByteLength( image.width, image.height, texture.format, texture.type ); - for ( final layerIndex in texture.layerUpdates ) { - final layerData = image.data.subarray( - layerIndex * layerByteLength / image.data.BYTES_PER_ELEMENT, - ( layerIndex + 1 ) * layerByteLength / image.data.BYTES_PER_ELEMENT - ); - state.texSubImage3D( WebGL.TEXTURE_2D_ARRAY, 0, 0, 0, layerIndex, image.width, image.height, 1, glFormat, glType, layerData ); - } - - texture.clearLayerUpdates(); - } - else { - state.texSubImage3D( WebGL.TEXTURE_2D_ARRAY, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data ); + if ( texture.layerUpdates.isNotEmpty) { + final layerByteLength = TextureUtils.getByteLength( image.width, image.height, texture.format, texture.type ); + for ( final layerIndex in texture.layerUpdates ) { + final layerData = image.data.subarray( + layerIndex * layerByteLength / image.data.BYTES_PER_ELEMENT, + ( layerIndex + 1 ) * layerByteLength / image.data.BYTES_PER_ELEMENT + ); + state.texSubImage3D( WebGL.TEXTURE_2D_ARRAY, 0, 0, 0, layerIndex, image.width, image.height, 1, glFormat, glType, layerData ); } - } + + texture.clearLayerUpdates(); + } + else { + state.texSubImage3D( WebGL.TEXTURE_2D_ARRAY, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data ); + } } else { state.texImage3D(WebGL.TEXTURE_2D_ARRAY, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat, glType, image.data); @@ -801,9 +729,7 @@ class WebGLTextures { if (allocateMemory) { state.texStorage3D(WebGL.TEXTURE_3D, levels, glInternalFormat, image.width, image.height, image.depth); } - if(dataReady){ - state.texSubImage3D(WebGL.TEXTURE_3D, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data); - } + state.texSubImage3D(WebGL.TEXTURE_3D, 0, 0, 0, 0, image.width, image.height, image.depth, glFormat, glType, image.data); } else { state.texImage3D(WebGL.TEXTURE_3D, 0, glInternalFormat, image.width, image.height, image.depth, 0, glFormat,glType, image.data); } @@ -838,7 +764,7 @@ class WebGLTextures { for (int i = 0, il = mipmaps.length; i < il; i++) { mipmap = mipmaps[i]; - if (useTexStorage && dataReady) { + if (useTexStorage) { state.texSubImage2DIf(WebGL.TEXTURE_2D, i, 0, 0, glFormat, glType, mipmap); } else { @@ -853,9 +779,7 @@ class WebGLTextures { if (allocateMemory) { state.texStorage2D(WebGL.TEXTURE_2D, levels, glInternalFormat, image.width.toInt(), image.height.toInt()); } - if(dataReady){ - state.texSubImage2DIf(WebGL.TEXTURE_2D, 0, 0, 0, glFormat, glType, image); - } + state.texSubImage2DIf(WebGL.TEXTURE_2D, 0, 0, 0, glFormat, glType, image); } else { state.texImage2DIf(WebGL.TEXTURE_2D, 0, glInternalFormat, glFormat, glType, image); @@ -902,7 +826,7 @@ class WebGLTextures { final isCompressed = (texture.isCompressedTexture || texture is CompressedTexture); final isDataTexture = (texture.image[0] != null && texture is DataTexture); final isCubeTexture = (texture.image[0] != null && texture is CubeTexture); - print('here1'); + final cubeImage = []; for (int i = 0; i < 6; i++) { @@ -910,7 +834,6 @@ class WebGLTextures { cubeImage.add(texture.image[i]); } else { - print('here2'); cubeImage.add(isDataTexture ? texture.image[i].image : texture.image[i]); } @@ -924,7 +847,6 @@ class WebGLTextures { final useTexStorage = (isWebGL2 && texture is! VideoTexture); final allocateMemory = (textureProperties['__version'] == null); - final dataReady = source.dataReady; int levels = getMipLevels(texture, image); setTextureParameters(WebGL.TEXTURE_CUBE_MAP, texture); @@ -944,23 +866,21 @@ class WebGLTextures { if (texture.format != RGBAFormat) { if (glFormat != null) { - if (useTexStorage && dataReady) { + if (useTexStorage ) { state.compressedTexSubImage2D(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, 0, 0, mipmap.width, mipmap.height, glFormat, mipmap.data); - } - else { + } else { state.compressedTexImage2D(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height, 0, mipmap.data); } - } - else { + } else { console.warning('WebGLRenderer: Attempt to load unsupported compressed texture format in .setTextureCube()'); } - } - else { - if (useTexStorage && dataReady) { - state.texSubImage2D(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, 0, 0, mipmap.width, mipmap.height, glFormat,glType, mipmap.data); - } - else { - state.texImage2D(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height,0, glFormat, glType, mipmap.data); + } else { + if (useTexStorage) { + state.texSubImage2D(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, 0, 0, mipmap.width, mipmap.height, glFormat, + glType, mipmap.data); + } else { + state.texImage2D(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, j, glInternalFormat, mipmap.width, mipmap.height, + 0, glFormat, glType, mipmap.data); } } } @@ -981,8 +901,8 @@ class WebGLTextures { for (int i = 0; i < 6; i++) { if (isDataTexture || isCubeTexture) { - if (useTexStorage && dataReady) { - if( kIsWeb ){ + if (useTexStorage) { + if(kIsWeb){ state.texSubImage2DNoSize(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, glFormat, glType, cubeImage[i].data); } else{ @@ -990,7 +910,7 @@ class WebGLTextures { } } else { - if( kIsWeb ){ + if(kIsWeb){ state.texImage2DNoSize(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, glFormat, glType, cubeImage[i].data); } else{ @@ -1002,30 +922,32 @@ class WebGLTextures { final mipmap = mipmaps[j]; final mipmapImage = mipmap.image[i].image; - if (useTexStorage && dataReady) { - state.texSubImage2D(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, mipmapImage.width,mipmapImage.height, glFormat, glType, mipmapImage.data); - } - else { - state.texImage2D(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, glInternalFormat, mipmapImage.width,mipmapImage.height, 0, glFormat, glType, mipmapImage.data); + if (useTexStorage) { + state.texSubImage2D(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, mipmapImage.width, + mipmapImage.height, glFormat, glType, mipmapImage.data); + } else { + state.texImage2D(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, glInternalFormat, mipmapImage.width, + mipmapImage.height, 0, glFormat, glType, mipmapImage.data); } } } else { - if (useTexStorage && dataReady) { + if (useTexStorage) { state.texSubImage2DIf(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, 0, 0, glFormat, glType, cubeImage[i]); - } - else { - state.texImage2DIf(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, glFormat, glType, cubeImage[i]); + } else { + state.texImage2DIf( + WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, 0, glInternalFormat, glFormat, glType, cubeImage[i]); } for (int j = 0; j < mipmaps.length; j++) { final mipmap = mipmaps[j]; - if (useTexStorage && dataReady) { - state.texSubImage2DIf(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, glFormat, glType, mipmap.image[i]); - } - else { - state.texImage2DIf(WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, glInternalFormat, glFormat, glType, mipmap.image[i]); + if (useTexStorage) { + state.texSubImage2DIf( + WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, 0, 0, glFormat, glType, mipmap.image[i]); + } else { + state.texImage2DIf( + WebGL.TEXTURE_CUBE_MAP_POSITIVE_X + i, j + 1, glInternalFormat, glFormat, glType, mipmap.image[i]); } } } @@ -1335,12 +1257,14 @@ class WebGLTextures { } if ( ( renderTarget.samples > 0 ) && useMultisampledRTT( renderTarget ) == false ) { + renderTargetProperties['__webglMultisampledFramebuffer'] = _gl.createFramebuffer(); renderTargetProperties['__webglColorRenderbuffer'] = []; state.bindFramebuffer( WebGL.FRAMEBUFFER, renderTargetProperties['__webglMultisampledFramebuffer'] ); for ( int i = 0; i < textures.length; i ++ ) { + final texture = textures[ i ]; (renderTargetProperties['__webglColorRenderbuffer'] as List).listSetter(i, _gl.createRenderbuffer()); @@ -1350,20 +1274,25 @@ class WebGLTextures { final glType = utils.convert( texture.type ); final glInternalFormat = getInternalFormat( texture.internalFormat, glFormat, glType, texture.colorSpace, renderTarget.isXRRenderTarget == true ); final samples = getRenderTargetSamples( renderTarget ); - _gl.renderbufferStorageMultisample( WebGL.RENDERBUFFER, samples, glInternalFormat, renderTarget.width, renderTarget.height ); + _gl.framebufferRenderbuffer( WebGL.FRAMEBUFFER, WebGL.COLOR_ATTACHMENT0 + i, WebGL.RENDERBUFFER, renderTargetProperties['__webglColorRenderbuffer'][ i ] ); + } _gl.bindRenderbuffer( WebGL.RENDERBUFFER, null ); if ( renderTarget.depthBuffer ) { + renderTargetProperties['__webglDepthRenderbuffer'] = _gl.createRenderbuffer(); setupRenderBufferStorage( renderTargetProperties['__webglDepthRenderbuffer'], renderTarget, true ); + } state.bindFramebuffer( WebGL.FRAMEBUFFER, null ); + } + } // Setup color buffer @@ -1449,9 +1378,8 @@ class WebGLTextures { } } + final Uint32List invalidationArrayRead = Uint32List(1); final Uint32List invalidationArrayDraw = Uint32List(1); - final Uint32List invalidationArrayRead = Uint32List(1); - void updateMultisampleRenderTarget(RenderTarget renderTarget) { if ( renderTarget.samples > 0 ) { if ( !useMultisampledRTT( renderTarget )) { @@ -1536,7 +1464,7 @@ class WebGLTextures { } Uint32List depthStyle = Uint32List.fromList([WebGL.DEPTH_ATTACHMENT]); - + bool useMultisampledRenderToTexture(RenderTarget renderTarget) { final renderTargetProperties = properties.get(renderTarget); @@ -1582,7 +1510,7 @@ class WebGLTextures { state.activeTexture(WebGL.TEXTURE0 + slot); state.bindTexture(textureType, textureProperties["__webglTexture"]); - if( kIsWeb ){ + if(kIsWeb){ gl.pixelStorei(WebGL.UNPACK_FLIP_Y_WEBGL, texture.flipY ? 1 : 0); gl.pixelStorei(WebGL.UNPACK_PREMULTIPLY_ALPHA_WEBGL, texture.premultiplyAlpha ? 1 : 0); } @@ -1594,7 +1522,7 @@ class WebGLTextures { final format = texture.format; final type = texture.type; - if ( texture.isCompressedTexture || texture is VideoTexture ) return image; + if ( texture.isCompressedTexture || texture.isVideoTexture ) return image; if ( colorSpace != LinearSRGBColorSpace && colorSpace != NoColorSpace ) { diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_uniforms.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_uniforms.dart similarity index 100% rename from packages/three_js_core/lib/renderers/webgl/web_gl_uniforms.dart rename to packages/three_js_webgl_renderer/lib/webgl/web_gl_uniforms.dart diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_uniforms_groups.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_uniforms_groups.dart similarity index 97% rename from packages/three_js_core/lib/renderers/webgl/web_gl_uniforms_groups.dart rename to packages/three_js_webgl_renderer/lib/webgl/web_gl_uniforms_groups.dart index 353c61be..523d5c12 100644 --- a/packages/three_js_core/lib/renderers/webgl/web_gl_uniforms_groups.dart +++ b/packages/three_js_webgl_renderer/lib/webgl/web_gl_uniforms_groups.dart @@ -7,7 +7,7 @@ class WebGLUniformsGroups{ Map buffers = {}; Map updateList = {}; - late final Uint32List allocatedBindingPoints = Uint32List(maxBindingPoints); + List allocatedBindingPoints = []; RenderingContext gl; late final int maxBindingPoints; // binding points are global whereas block indices are per shader program @@ -64,8 +64,8 @@ class WebGLUniformsGroups{ int allocateBindingPointIndex() { for (int i = 0; i < maxBindingPoints; i ++ ) { - if (allocatedBindingPoints[i] == 0) { - allocatedBindingPoints[i] = 1; + if (!allocatedBindingPoints.contains( i )) { + allocatedBindingPoints.add( i ); return i; } } @@ -271,7 +271,7 @@ class WebGLUniformsGroups{ gl.deleteBuffer( buffers[ id ] ); } - allocatedBindingPoints.clear(); + allocatedBindingPoints = []; buffers = {}; updateList = {}; } diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_uniforms_helper.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_uniforms_helper.dart similarity index 98% rename from packages/three_js_core/lib/renderers/webgl/web_gl_uniforms_helper.dart rename to packages/three_js_webgl_renderer/lib/webgl/web_gl_uniforms_helper.dart index 844063fd..b411bad3 100755 --- a/packages/three_js_core/lib/renderers/webgl/web_gl_uniforms_helper.dart +++ b/packages/three_js_webgl_renderer/lib/webgl/web_gl_uniforms_helper.dart @@ -149,8 +149,6 @@ mixin WebGLUniformsHelper { cache.clear(); } - Float32List flat = Float32List(0); - Float32List flatten(List? array, int nBlocks, int blockSize) { if(array == null || array.isEmpty) return Float32List(0); final firstElem = array[0]; @@ -352,6 +350,7 @@ mixin WebGLUniformsHelper { //mat2array.set(List.from(elements.map((e) => e.toDouble())), 0); gl.uniformMatrix2fv(addr, false, mat2array); + copyArray(cache, elements); } } @@ -367,6 +366,15 @@ mixin WebGLUniformsHelper { copyArray(cache, v); } + else if(kIsWeb){ + final element = elements.sublist(0); + if (arraysEqual(cache, element)) { + return; + } + + gl.uniformMatrix3fv(addr, false, element); + copyArray(cache, elements); + } else { if (arraysEqual(cache, elements)) { return; @@ -384,6 +392,7 @@ mixin WebGLUniformsHelper { if (arraysEqual(cache, elements)) { return; } + gl.uniformMatrix4fv(addr, false, elements); copyArray(cache, elements); } @@ -457,13 +466,11 @@ mixin WebGLUniformsHelper { cache[0] = v; } - Int32List iv = Int32List(2); void setValueV2i(RenderingContext gl, Vector v, [WebGLTextures? textures]) { final cache = this.cache; if (arraysEqual(cache, v)) return; - iv[0] = v.x.toInt(); - iv[1] = v.y.toInt(); + Int32List iv = Int32List.fromList([v.x.toInt(),v.y.toInt()]); gl.uniform2iv(addr, iv); copyArray(cache, v.copyIntoArray()); } @@ -624,6 +631,7 @@ mixin WebGLUniformsHelper { void setValueM4Array(RenderingContext gl, v, [WebGLTextures? textures]) { final data = flatten(v, size, 16); + gl.uniformMatrix4fv(addr, false, data); } diff --git a/packages/three_js_core/lib/renderers/webgl/web_gl_utils.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_utils.dart similarity index 100% rename from packages/three_js_core/lib/renderers/webgl/web_gl_utils.dart rename to packages/three_js_webgl_renderer/lib/webgl/web_gl_utils.dart diff --git a/packages/three_js_webgl_renderer/pubspec.yaml b/packages/three_js_webgl_renderer/pubspec.yaml new file mode 100755 index 00000000..730e4674 --- /dev/null +++ b/packages/three_js_webgl_renderer/pubspec.yaml @@ -0,0 +1,30 @@ +name: three_js_webgl_renderer +description: "This is an older version of the renderer for three_js using angle." +version: 0.0.1 +homepage: https://github.com/Knightro63/three_js/tree/main/packages/three_js_webgl_renderer + +environment: + sdk: '>=3.5.0 <4.0.0' + flutter: ">=1.17.0" + +dependencies: + flutter: + sdk: flutter + logger: ^2.5.0 + web: ^1.1.1 + three_js_core: ^0.3.0 + three_js_math: ^0.3.0 + flutter_angle: ^0.4.0 + +dev_dependencies: + flutter_test: + sdk: flutter + flutter_lints: ^5.0.0 + +dependency_overrides: + three_js_math: + path: ../three_js_math + three_js_core: + path: ../three_js_core + flutter_angle: + path: ../../../flutter_angle/flutter_angle \ No newline at end of file From 08234520d5f9836107b61dc26af2d475f8ab0e64 Mon Sep 17 00:00:00 2001 From: Knightro <50028636+Knightro63@users.noreply.github.com> Date: Wed, 28 Jan 2026 18:18:36 -0500 Subject: [PATCH 05/17] bug fixes --- examples/lib/camera/webgl_camera.dart | 2 +- .../lib/clipping/webgl_clipping_stencil.dart | 2 +- .../lights/webgl_lightprobe_cube_camera.dart | 2 +- examples/lib/mirror/webgl_portal.dart | 6 +- .../webgl2_multiple_rendertargets.dart | 4 +- .../lib/projected/webgl_projected_basic.dart | 9 +- .../lib/screenshot/opengl_screenshot.dart | 4 +- examples/lib/shadow/webgl_shadow_contact.dart | 10 +- examples/lib/shadow/webgl_simple_gi.dart | 4 +- .../lib/terrain/webgl_planet_generator.dart | 31 +- .../lib/volume/webgl_volume_instancing.dart | 2 +- examples/pubspec.yaml | 8 +- packages/three_js/lib/three_js.dart | 4 +- packages/three_js/pubspec.yaml | 1 + .../lib/angle/angle_capabilities.dart | 24 +- .../lib/angle/angle_cube_maps.dart | 2 +- .../lib/angle/angle_geometries.dart | 2 +- .../lib/angle/angle_program.dart | 2 +- .../lib/angle/angle_program_extra.dart | 18 +- .../lib/angle/angle_programs.dart | 12 +- .../lib/angle/angle_shadow_map.dart | 27 +- .../lib/angle/angle_state.dart | 11 +- .../lib/angle/angle_textures.dart | 22 +- .../lib/angle/index.dart | 1 - .../lib/renderers/3d_render_target.dart | 2 +- .../lib/renderers/array_render_target.dart | 2 +- .../lib/renderers/cube_render_target.dart | 186 ++--- .../lib/renderers/index.dart | 5 +- .../lib/renderers/pmrem_generator.dart | 8 +- .../lib/renderers/render_target.dart | 72 +- .../lib/renderers/renderer.dart | 128 ++-- .../lib/shaders/index.dart | 14 +- .../lib/shaders/mesh_gouraund_material.dart | 3 +- .../lib/shaders/shader_chunk.dart | 9 +- .../lights_fragment_begin.glsl.dart | 2 +- .../shader_chunk/lights_pars_begin.glsl.dart | 2 +- .../lib/shaders/uniforms_lib.dart | 175 ----- .../lib/three_js_angle_renderer.dart | 3 +- .../lib/three_viewer.dart | 6 +- .../lib/materials/hex_tiling_material.dart | 9 +- .../three_js_core/lib/materials/index.dart | 3 +- .../lib/materials/projected_material.dart | 2 +- .../lib/renderers/capabilities.dart | 34 + .../lib/renderers/cube_render_target.dart | 126 +++- .../three_js_core/lib/renderers/index.dart | 8 +- .../lib/renderers/parameters.dart} | 10 +- .../lib/renderers/render_target.dart | 48 +- .../three_js_core/lib/renderers/renderer.dart | 42 +- .../lib/renderers}/shaders/shader_lib.dart | 8 +- .../lib/renderers}/shaders/uniforms_lib.dart | 2 +- .../{ => shaders}/uniforms_utils.dart | 4 +- .../lib/renderers/shadow_map.dart | 29 + .../three_js_core/lib/renderers/state.dart | 17 + .../three_js_core/lib/textures/texture.dart | 2 +- .../lib/light_probe_helper.dart | 2 +- .../three_js_helpers/lib/view_helper.dart | 2 +- .../three_js_helpers/lib/view_helper2.dart | 2 +- packages/three_js_line/lib/line_material.dart | 1 - packages/three_js_objects/lib/csm/csm.dart | 5 - .../three_js_objects/lib/csm/csm_shaders.dart | 2 +- .../lib/gpu_computation_renderer.dart | 10 +- packages/three_js_objects/lib/lens_flare.dart | 2 +- .../light_probe_generator_platform.dart | 2 +- .../lib/lights/light_probe_generator_web.dart | 2 +- .../lib/planet_generator/atmosphere.dart | 27 +- .../planet_generator/planet_generator.dart | 8 +- .../three_js_objects/lib/water/reflector.dart | 14 +- .../three_js_objects/lib/water/refractor.dart | 16 +- .../three_js_objects/lib/water/water2.dart | 2 +- .../lib/post/afterimage_pass.dart | 14 +- .../lib/post/bloom_pass.dart | 10 +- .../lib/post/dot_screen_pass.dart | 2 +- .../lib/post/effect_composer.dart | 18 +- .../lib/post/film_pass.dart | 2 +- .../lib/post/glitch_pass.dart | 2 +- .../lib/post/mask_pass.dart | 4 +- .../lib/post/outpass.dart | 2 +- .../lib/post/pass.dart | 4 +- .../lib/post/render_pass.dart | 2 +- .../lib/post/shader_pass.dart | 2 +- .../lib/post/shader_passes.dart | 12 +- .../lib/post/smaa_pass.dart | 14 +- .../lib/post/ssaa_render_pass.dart | 8 +- .../lib/post/taa_render_pass.dart | 10 +- .../lib/post/texture_pass.dart | 2 +- .../lib/post/unreal_bloom_pass.dart | 16 +- packages/three_js_terrain/lib/core.dart | 7 +- .../lib/material_loader.dart | 3 +- .../lib/renderers/index.dart | 5 +- .../lib/renderers/pmrem_generator.dart | 8 +- .../renderers/web_gl_3d_render_target.dart | 2 +- .../renderers/web_gl_array_render_target.dart | 2 +- .../renderers/web_gl_cube_render_target.dart | 186 ++--- .../lib/renderers/web_gl_render_target.dart | 304 ++++---- .../lib/renderers/web_gl_renderer.dart | 127 ++-- .../lib/shaders/index.dart | 19 +- .../lib/shaders/shader_chunk.dart | 9 +- .../lights_fragment_begin.glsl.dart | 2 +- .../shader_chunk/lights_pars_begin.glsl.dart | 2 +- .../lib/shaders/shader_lib.dart | 279 -------- .../lib/three_viewer.dart | 4 +- .../lib/webgl/index.dart | 1 - .../lib/webgl/web_gl_capabilities.dart | 24 +- .../lib/webgl/web_gl_cube_maps.dart | 2 +- .../lib/webgl/web_gl_parameters.dart | 670 ------------------ .../lib/webgl/web_gl_program.dart | 2 +- .../lib/webgl/web_gl_program_extra.dart | 18 +- .../lib/webgl/web_gl_programs.dart | 12 +- .../lib/webgl/web_gl_shadow_map.dart | 29 +- .../lib/webgl/web_gl_state.dart | 9 +- .../lib/webgl/web_gl_textures.dart | 10 +- three_js_editor/lib/ui/line_material.dart | 532 -------------- 112 files changed, 1105 insertions(+), 2555 deletions(-) delete mode 100755 packages/three_js_angle_renderer/lib/shaders/uniforms_lib.dart rename packages/{three_js_angle_renderer => three_js_core}/lib/materials/hex_tiling_material.dart (98%) create mode 100644 packages/three_js_core/lib/renderers/capabilities.dart rename packages/{three_js_angle_renderer/lib/angle/angle_parameters.dart => three_js_core/lib/renderers/parameters.dart} (99%) mode change 100755 => 100644 rename packages/{three_js_angle_renderer/lib => three_js_core/lib/renderers}/shaders/shader_lib.dart (97%) rename packages/{three_js_webgl_renderer/lib => three_js_core/lib/renderers}/shaders/uniforms_lib.dart (99%) rename packages/three_js_core/lib/renderers/{ => shaders}/uniforms_utils.dart (95%) create mode 100644 packages/three_js_core/lib/renderers/shadow_map.dart create mode 100644 packages/three_js_core/lib/renderers/state.dart mode change 100755 => 100644 packages/three_js_webgl_renderer/lib/shaders/index.dart delete mode 100755 packages/three_js_webgl_renderer/lib/shaders/shader_lib.dart delete mode 100755 packages/three_js_webgl_renderer/lib/webgl/web_gl_parameters.dart delete mode 100644 three_js_editor/lib/ui/line_material.dart diff --git a/examples/lib/camera/webgl_camera.dart b/examples/lib/camera/webgl_camera.dart index 7b6c89f8..251506cb 100644 --- a/examples/lib/camera/webgl_camera.dart +++ b/examples/lib/camera/webgl_camera.dart @@ -44,7 +44,7 @@ class _MyAppState extends State { void dispose() { timer.cancel(); threeJs.dispose(); - threeJs.renderer!.setScissor( 0, 0, threeJs.width , threeJs.height); + threeJs.renderer?.setScissor( 0, 0, threeJs.width , threeJs.height); super.dispose(); cameraPerspective.dispose(); diff --git a/examples/lib/clipping/webgl_clipping_stencil.dart b/examples/lib/clipping/webgl_clipping_stencil.dart index 81f33465..669657d3 100644 --- a/examples/lib/clipping/webgl_clipping_stencil.dart +++ b/examples/lib/clipping/webgl_clipping_stencil.dart @@ -170,7 +170,7 @@ class _State extends State { final po = three.Mesh(planeGeom, planeMat); po.onAfterRender = ({ - three.WebGLRenderer? renderer, + three.Renderer? renderer, three.RenderTarget? renderTarget, three.Object3D? mesh, three.Scene? scene, diff --git a/examples/lib/lights/webgl_lightprobe_cube_camera.dart b/examples/lib/lights/webgl_lightprobe_cube_camera.dart index ad0132c2..827c1999 100644 --- a/examples/lib/lights/webgl_lightprobe_cube_camera.dart +++ b/examples/lib/lights/webgl_lightprobe_cube_camera.dart @@ -60,7 +60,7 @@ class _State extends State { threeJs.camera = three.PerspectiveCamera( 40, threeJs.width / threeJs.height, 1, 1000 ); threeJs.camera.position.setValues( 0, 0, 30 ); - final cubeRenderTarget = three.WebGLCubeRenderTarget( 256 ); + final cubeRenderTarget = three.CubeRenderTarget( 256 ); final cubeCamera = three.CubeCamera( 1, 1000, cubeRenderTarget ); // controls diff --git a/examples/lib/mirror/webgl_portal.dart b/examples/lib/mirror/webgl_portal.dart index 9061ea45..d1857456 100644 --- a/examples/lib/mirror/webgl_portal.dart +++ b/examples/lib/mirror/webgl_portal.dart @@ -97,14 +97,14 @@ class _State extends State { final topLeftCorner = three.Vector3(); final reflectedPosition = three.Vector3(); - final leftPortalTexture = three.WebGLRenderTarget( 256, 256 ); + final leftPortalTexture = three.RenderTarget( 256, 256 ); final leftPortal = three.Mesh( planeGeo, three.MeshBasicMaterial.fromMap( { 'map': leftPortalTexture.texture } ) ); leftPortal.position.x = - 30; leftPortal.position.y = 20; leftPortal.scale.setValues( 0.35, 0.35, 0.35 ); threeJs.scene.add( leftPortal ); - final rightPortalTexture = three.WebGLRenderTarget( 256, 256 ); + final rightPortalTexture = three.RenderTarget( 256, 256 ); final rightPortal = three.Mesh( planeGeo, three.MeshBasicMaterial.fromMap( { 'map': rightPortalTexture.texture } ) ); rightPortal.position.x = 30; rightPortal.position.y = 20; @@ -162,7 +162,7 @@ class _State extends State { blueLight.position.setValues( 0, 50, 550 ); threeJs.scene.add( blueLight ); - void renderPortal(three.Mesh thisPortalMesh,three.Mesh otherPortalMesh,three.WebGLRenderTarget thisPortalTexture ) { + void renderPortal(three.Mesh thisPortalMesh,three.Mesh otherPortalMesh,three.RenderTarget thisPortalTexture ) { thisPortalMesh.worldToLocal( reflectedPosition.setFrom( threeJs.camera.position ) ); reflectedPosition.x *= - 1.0; reflectedPosition.z *= - 1.0; otherPortalMesh.localToWorld( reflectedPosition ); diff --git a/examples/lib/multi_views/webgl2_multiple_rendertargets.dart b/examples/lib/multi_views/webgl2_multiple_rendertargets.dart index 34f2fccb..dac17a27 100644 --- a/examples/lib/multi_views/webgl2_multiple_rendertargets.dart +++ b/examples/lib/multi_views/webgl2_multiple_rendertargets.dart @@ -169,10 +169,10 @@ class _State extends State { Future setup() async { // Create a multi render target with Float buffers - final renderTarget = three.WebGLRenderTarget( + final renderTarget = three.RenderTarget( (threeJs.width * threeJs.dpr).toInt(), (threeJs.height * threeJs.dpr).toInt(), - three.WebGLRenderTargetOptions({ + three.RenderTargetOptions({ 'count': 2, 'minFilter': three.NearestFilter, 'magFilter': three.NearestFilter diff --git a/examples/lib/projected/webgl_projected_basic.dart b/examples/lib/projected/webgl_projected_basic.dart index 3c0f028b..52f80fe6 100644 --- a/examples/lib/projected/webgl_projected_basic.dart +++ b/examples/lib/projected/webgl_projected_basic.dart @@ -1,5 +1,6 @@ import 'dart:async'; import 'dart:math' as math; +import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:example/src/statistics.dart'; import 'package:three_js/three_js.dart' as three; @@ -64,7 +65,7 @@ class _State extends State { threeJs.camera.lookAt(three.Vector3(0, 0, 0)); // load the example texture - final texture = await three.TextureLoader().fromAsset('assets/textures/uv_grid_directx.jpg'); + final texture = await three.TextureLoader(flipY: !kIsWeb).fromAsset('assets/textures/uv_grid_directx.jpg'); final camera = three.PerspectiveCamera(45, 1, 0.01, 3); camera.position.setValues(-1, 1.2, 2); camera.lookAt(three.Vector3(0, 0, 0)); @@ -82,6 +83,7 @@ class _State extends State { ); final box = three.Mesh(geometry, material); threeJs.scene.add(box); + material.needsUpdate = true; // move the mesh any way you want! box.rotation.y = -math.pi / 4; @@ -93,6 +95,11 @@ class _State extends State { final ambientLight = three.AmbientLight(0xffffff, 0.8); threeJs.scene.add(ambientLight); + final dirLight = three.DirectionalLight( 0xFFFFFF, 3 ); + dirLight.position.setValues( - 0.5, 1, 0.8 ); + dirLight.castShadow = true; + threeJs.scene.add( dirLight ); + controls = three.OrbitControls(threeJs.camera, threeJs.globalKey); } } diff --git a/examples/lib/screenshot/opengl_screenshot.dart b/examples/lib/screenshot/opengl_screenshot.dart index 1897699f..5f250d5a 100644 --- a/examples/lib/screenshot/opengl_screenshot.dart +++ b/examples/lib/screenshot/opengl_screenshot.dart @@ -17,7 +17,7 @@ class _State extends State { late Timer timer; late three.ThreeJS threeJs; late final Uint8List buffer; - late final three.WebGLRenderTarget rt; + late final three.RenderTarget rt; @override void initState() { @@ -90,7 +90,7 @@ class _State extends State { Future setup() async { buffer = Uint8List( desiredWidth * desiredHeight * 4 ); - rt = three.WebGLRenderTarget( desiredWidth, desiredHeight, three.WebGLRenderTargetOptions({ + rt = three.RenderTarget( desiredWidth, desiredHeight, three.RenderTargetOptions({ 'colorSpace': three.SRGBColorSpace, 'samples': 4, }) ); diff --git a/examples/lib/shadow/webgl_shadow_contact.dart b/examples/lib/shadow/webgl_shadow_contact.dart index cfddd2f8..a24e8558 100644 --- a/examples/lib/shadow/webgl_shadow_contact.dart +++ b/examples/lib/shadow/webgl_shadow_contact.dart @@ -52,8 +52,8 @@ class _MyAppState extends State { } late three.Mesh blurPlane; - late three.WebGLRenderTarget renderTarget; - late three.WebGLRenderTarget renderTargetBlur; + late three.RenderTarget renderTarget; + late three.RenderTarget renderTargetBlur; final meshes = []; @@ -210,13 +210,13 @@ class _MyAppState extends State { shadowGroup.position.y = -0.3; threeJs.scene.add(shadowGroup); - final pars = three.WebGLRenderTargetOptions({"format": three.RGBAFormat}); + final pars = three.RenderTargetOptions({"format": three.RGBAFormat}); // the render target that will show the shadows in the plane texture - renderTarget = three.WebGLRenderTarget(512, 512, pars); + renderTarget = three.RenderTarget(512, 512, pars); renderTarget.texture.generateMipmaps = false; // the render target that we will use to blur the first render target - renderTargetBlur = three.WebGLRenderTarget(512, 512, pars); + renderTargetBlur = three.RenderTarget(512, 512, pars); renderTargetBlur.texture.generateMipmaps = false; // make a plane and make it face up diff --git a/examples/lib/shadow/webgl_simple_gi.dart b/examples/lib/shadow/webgl_simple_gi.dart index 88cdd4fb..a37505d6 100644 --- a/examples/lib/shadow/webgl_simple_gi.dart +++ b/examples/lib/shadow/webgl_simple_gi.dart @@ -98,7 +98,7 @@ class _State extends State { void Function([double?])? compute; - void simpleGI(three.WebGLRenderer renderer, three.Scene scene) { + void simpleGI(three.Renderer renderer, three.Scene scene) { final SIZE = 32, SIZE2 = SIZE * SIZE; @@ -109,7 +109,7 @@ class _State extends State { three.Object3D clone = scene.clone(); clone.matrixAutoUpdate = false; - final rt = three.WebGLRenderTarget( SIZE, SIZE ); + final rt = three.RenderTarget( SIZE, SIZE ); final normalMatrix = three.Matrix3.identity(); final position = three.Vector3(); diff --git a/examples/lib/terrain/webgl_planet_generator.dart b/examples/lib/terrain/webgl_planet_generator.dart index cc0a07af..5792d130 100644 --- a/examples/lib/terrain/webgl_planet_generator.dart +++ b/examples/lib/terrain/webgl_planet_generator.dart @@ -80,14 +80,31 @@ class _State extends State { final controls = three.OrbitControls(threeJs.camera, threeJs.globalKey); threeJs.camera.position.z = 50; - final composer = EffectComposer(threeJs.renderer!); + final double dpr = 0.5; // Half resolution for processing + final int width = (threeJs.width * dpr).toInt(); + final int height = (threeJs.height * dpr).toInt(); + + final renderTarget = three.RenderTarget(width, height, three.RenderTargetOptions({ + 'minFilter': three.LinearFilter, + 'magFilter': three.LinearFilter, + 'format': three.RGBAFormat, + 'type': three.HalfFloatType, + 'stencilBuffer': false, // Turn off for speed + 'depthBuffer': true, + })); + + final composer = EffectComposer(threeJs.renderer!, renderTarget); + final renderPass = RenderPass(threeJs.scene, threeJs.camera); + // Explicitly clear to fix those "weird drawing" artifacts + renderPass.clear = true; composer.addPass(renderPass); - final bloomPass = UnrealBloomPass(null,0.0,0.2,0.5); + // Only keep this if you actually want the glow effect + final bloomPass = UnrealBloomPass(three.Vector2(width.toDouble(), height.toDouble()), 0.0, 0.2, 0.5); composer.addPass(bloomPass); - final outputPass = new OutputPass(); + final outputPass = OutputPass(); composer.addPass(outputPass); final texLoader = three.TextureLoader(); @@ -96,17 +113,19 @@ class _State extends State { PlanetGenerator planet = PlanetGenerator(cloudTexture: cloudTex); threeJs.scene.add(planet); + threeJs.renderer!.setPixelRatio(1.0); + threeJs.addAnimationEvent((dt) { - planet.atmosphere.material?.uniforms['time']['value'] = threeJs.clock.getElapsedTime(); + planet.atmosphere.material?.uniforms['time']['value'] += dt; planet.atmosphere.rotation.y += 0.0002; controls.update(); composer.render(); }); - createUI(planet, bloomPass); + createUI(planet); } - void createUI(PlanetGenerator planet,UnrealBloomPass bloomPass) { + void createUI(PlanetGenerator planet) { final planetParams = planet.planetParams.json; final atmosphereParams = planet.atmosphereParams.json; Atmosphere atmosphere = planet.atmosphere; diff --git a/examples/lib/volume/webgl_volume_instancing.dart b/examples/lib/volume/webgl_volume_instancing.dart index 2686eca6..6292d0ae 100644 --- a/examples/lib/volume/webgl_volume_instancing.dart +++ b/examples/lib/volume/webgl_volume_instancing.dart @@ -203,7 +203,7 @@ class _State extends State { three.Material? material, three.Object3D? mesh, three.RenderTarget? renderTarget, - three.WebGLRenderer? renderer, + three.Renderer? renderer, three. Scene? scene }) { material?.uniforms['cameraPos']['value'].setFrom( threeJs.camera.position ); diff --git a/examples/pubspec.yaml b/examples/pubspec.yaml index ad6f32b2..71d6e7f0 100644 --- a/examples/pubspec.yaml +++ b/examples/pubspec.yaml @@ -17,8 +17,8 @@ dependencies: css: git: url: https://github.com/Knightro63/css.git - three_js: ^0.2.7 - #path: ../packages/three_js + three_js: + path: ../packages/three_js three_js_helpers: ^0.2.3 three_js_transform_controls: ^0.2.1 three_js_svg: ^0.2.1 @@ -106,6 +106,10 @@ dependency_overrides: path: ../packages/three_js_geometry three_js_sensors: path: ../packages/three_js_sensors + three_js_angle_renderer: + path: ../packages/three_js_angle_renderer + # three_js_webgl_renderer: + # path: ../packages/three_js_webgl_renderer flutter: uses-material-design: true diff --git a/packages/three_js/lib/three_js.dart b/packages/three_js/lib/three_js.dart index b59b7fe0..9bd5db91 100755 --- a/packages/three_js/lib/three_js.dart +++ b/packages/three_js/lib/three_js.dart @@ -10,4 +10,6 @@ export 'package:three_js_core_loaders/three_js_core_loaders.dart'; export 'package:three_js_curves/three_js_curves.dart'; export 'package:three_js_simple_loaders/three_js_simple_loaders.dart'; export 'package:three_js_text/three_js_text.dart'; -export 'package:three_js_geometry/three_js_geometry.dart'; \ No newline at end of file +export 'package:three_js_geometry/three_js_geometry.dart'; +export 'package:three_js_angle_renderer/three_js_angle_renderer.dart'; +//export 'package:three_js_webgl_renderer/three_js_webgl_renderer.dart'; \ No newline at end of file diff --git a/packages/three_js/pubspec.yaml b/packages/three_js/pubspec.yaml index 506206d9..b3f4baeb 100755 --- a/packages/three_js/pubspec.yaml +++ b/packages/three_js/pubspec.yaml @@ -18,6 +18,7 @@ dependencies: flutter: sdk: flutter three_js_angle_renderer: ^0.0.1 + #three_js_webgl_renderer: ^0.0.1 three_js_math: ^0.3.0 three_js_advanced_loaders: ^0.3.0 three_js_animations: ^0.3.0 diff --git a/packages/three_js_angle_renderer/lib/angle/angle_capabilities.dart b/packages/three_js_angle_renderer/lib/angle/angle_capabilities.dart index a1e916d6..6375c40f 100755 --- a/packages/three_js_angle_renderer/lib/angle/angle_capabilities.dart +++ b/packages/three_js_angle_renderer/lib/angle/angle_capabilities.dart @@ -1,35 +1,13 @@ part of three_webgl; -class AngleCapabilities { +class AngleCapabilities extends Capabilities { bool _didDispose = false; - bool isWebGL2 = true; AngleRendererParameters parameters; RenderingContext gl; AngleExtensions extensions; AngleUtils utils; - String precision = 'highp'; - String maxPrecision = "highp"; - - bool logarithmicDepthBuffer = false; - late int maxTextures; - late int maxVertexTextures; - late int maxTextureSize; - late int maxCubemapSize; - late int maxAttributes; - late int maxVertexUniforms; - late int maxVaryings; - late int maxFragmentUniforms; - late bool reverseDepthBuffer; - - num? maxAnisotropy; - - late bool vertexTextures; - late int maxSamples; - - bool drawBuffers = true; - AngleCapabilities(this.gl, this.extensions, this.parameters, this.utils) { precision = parameters.precision.name; diff --git a/packages/three_js_angle_renderer/lib/angle/angle_cube_maps.dart b/packages/three_js_angle_renderer/lib/angle/angle_cube_maps.dart index ab46b62e..f0d3374f 100755 --- a/packages/three_js_angle_renderer/lib/angle/angle_cube_maps.dart +++ b/packages/three_js_angle_renderer/lib/angle/angle_cube_maps.dart @@ -30,7 +30,7 @@ class AngleCubeMaps { final image = texture.image; if (image != null && image.height > 0) { - final renderTarget = AngleCubeRenderTarget(image.height ~/ 2); + final renderTarget = CubeRenderTarget(image.height ~/ 2); renderTarget.fromEquirectangularTexture(renderer, texture); cubemaps.add(key: texture, value: renderTarget); diff --git a/packages/three_js_angle_renderer/lib/angle/angle_geometries.dart b/packages/three_js_angle_renderer/lib/angle/angle_geometries.dart index b71265c5..eadaaaf5 100755 --- a/packages/three_js_angle_renderer/lib/angle/angle_geometries.dart +++ b/packages/three_js_angle_renderer/lib/angle/angle_geometries.dart @@ -75,7 +75,7 @@ class AngleGeometries { } void updateWireframeAttribute(BufferGeometry geometry) { - Uint32List indices = Uint32List(0); + List indices = []; final geometryIndex = geometry.index; final geometryPosition = geometry.attributes["position"]; diff --git a/packages/three_js_angle_renderer/lib/angle/angle_program.dart b/packages/three_js_angle_renderer/lib/angle/angle_program.dart index 5684b1fe..72a631ce 100755 --- a/packages/three_js_angle_renderer/lib/angle/angle_program.dart +++ b/packages/three_js_angle_renderer/lib/angle/angle_program.dart @@ -15,7 +15,7 @@ class AngleProgram extends DefaultProgram with AngleProgramExtra { AngleBindingStates bindingStates; int usedTimes = 1; late RenderingContext gl; - AngleParameters parameters; + Parameters parameters; late Program? program; late String vertexShader; diff --git a/packages/three_js_angle_renderer/lib/angle/angle_program_extra.dart b/packages/three_js_angle_renderer/lib/angle/angle_program_extra.dart index 014fe0ef..9f9502d3 100755 --- a/packages/three_js_angle_renderer/lib/angle/angle_program_extra.dart +++ b/packages/three_js_angle_renderer/lib/angle/angle_program_extra.dart @@ -123,7 +123,7 @@ mixin AngleProgramExtra { return 'vec3 $functionName( vec3 color ) { return ${toneMappingName}ToneMapping( color ); }'; } - String generateVertexExtensions(AngleParameters parameters) { + String generateVertexExtensions(Parameters parameters) { final chunks = [ parameters.extensionClipCullDistance ? '#extension GL_ANGLE_clip_cull_distance : require' : '', parameters.extensionMultiDraw ? '#extension GL_ANGLE_multi_draw : require' : '', @@ -183,7 +183,7 @@ mixin AngleProgramExtra { return string != ''; } - String replaceLightNums(String string, AngleParameters parameters) { + String replaceLightNums(String string, Parameters parameters) { final numSpotLightCoords = parameters.numSpotLightShadows + parameters.numSpotLightMaps - parameters.numSpotLightShadowsWithMaps; string = string.replaceAll("NUM_DIR_LIGHTS", parameters.numDirLights.toString() ); @@ -201,7 +201,7 @@ mixin AngleProgramExtra { return string; } - String replaceClippingPlaneNums(String string, AngleParameters parameters) { + String replaceClippingPlaneNums(String string, Parameters parameters) { string = string.replaceAll("NUM_CLIPPING_PLANES", parameters.numClippingPlanes.toString()); string = string.replaceAll("UNION_CLIPPING_PLANES", (parameters.numClippingPlanes - parameters.numClipIntersection).toString()); @@ -309,7 +309,7 @@ mixin AngleProgramExtra { // - String generatePrecision(AngleParameters parameters) { + String generatePrecision(Parameters parameters) { String precisionstring = '''precision ${parameters.precision} float; precision ${parameters.precision} int; precision ${parameters.precision} sampler2D; @@ -340,7 +340,7 @@ mixin AngleProgramExtra { return precisionstring; } - String generateShadowMapTypeDefine(AngleParameters parameters) { + String generateShadowMapTypeDefine(Parameters parameters) { String shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC'; if (parameters.shadowMapType == PCFShadowMap) { @@ -354,7 +354,7 @@ mixin AngleProgramExtra { return shadowMapTypeDefine; } - String generateEnvMapTypeDefine(AngleParameters parameters) { + String generateEnvMapTypeDefine(Parameters parameters) { String envMapTypeDefine = 'ENVMAP_TYPE_CUBE'; if (parameters.envMap) { @@ -373,7 +373,7 @@ mixin AngleProgramExtra { return envMapTypeDefine; } - String generateEnvMapModeDefine (AngleParameters parameters) { + String generateEnvMapModeDefine (Parameters parameters) { String envMapModeDefine = 'ENVMAP_MODE_REFLECTION'; if (parameters.envMap) { @@ -387,7 +387,7 @@ mixin AngleProgramExtra { return envMapModeDefine; } - String generateEnvMapBlendingDefine(AngleParameters parameters) { + String generateEnvMapBlendingDefine(Parameters parameters) { String envMapBlendingDefine = 'ENVMAP_BLENDING_NONE'; if (parameters.envMap) { @@ -409,7 +409,7 @@ mixin AngleProgramExtra { return envMapBlendingDefine; } - Map? generateCubeUVSize(AngleParameters parameters) { + Map? generateCubeUVSize(Parameters parameters) { final imageHeight = parameters.envMapCubeUVHeight; if (imageHeight == null) return null; diff --git a/packages/three_js_angle_renderer/lib/angle/angle_programs.dart b/packages/three_js_angle_renderer/lib/angle/angle_programs.dart index c007fb66..a2f48d9a 100755 --- a/packages/three_js_angle_renderer/lib/angle/angle_programs.dart +++ b/packages/three_js_angle_renderer/lib/angle/angle_programs.dart @@ -63,7 +63,7 @@ class AnglePrograms { return 'uv$value'; } - AngleParameters getParameters(Material material, LightState lights, List shadows, Scene scene, Object3D object) { + Parameters getParameters(Material material, LightState lights, List shadows, Scene scene, Object3D object) { final fog = scene.fog; final geometry = object.geometry; final environment = material is MeshStandardMaterial ? scene.environment : null; @@ -121,7 +121,7 @@ class AnglePrograms { final useAlphaTest = material.alphaTest > 0; final useClearcoat = material.clearcoat > 0; - final parameters = AngleParameters( + final parameters = Parameters( shaderID: shaderID, shaderType: material.type, shaderName: "${material.type} - ${material.name}", @@ -319,7 +319,7 @@ class AnglePrograms { return parameters; } - String getProgramCacheKey(AngleParameters parameters) { + String getProgramCacheKey(Parameters parameters) { List array = []; if (parameters.shaderID != null) { @@ -347,7 +347,7 @@ class AnglePrograms { return array.join(); } - void getProgramCacheKeyParameters(List array, AngleParameters parameters) { + void getProgramCacheKeyParameters(List array, Parameters parameters) { array.add( parameters.precision ); array.add( parameters.outputColorSpace ); array.add( parameters.envMapMode ); @@ -398,7 +398,7 @@ class AnglePrograms { array.add( parameters.depthPacking ); } - void getProgramCacheKeyBooleans(List array, AngleParameters parameters) { + void getProgramCacheKeyBooleans(List array, Parameters parameters) { _programLayers.disableAll(); @@ -468,7 +468,7 @@ class AnglePrograms { return uniforms; } - AngleProgram? acquireProgram(AngleParameters parameters, String cacheKey) { + AngleProgram? acquireProgram(Parameters parameters, String cacheKey) { AngleProgram? program; // Check if code has been already compiled diff --git a/packages/three_js_angle_renderer/lib/angle/angle_shadow_map.dart b/packages/three_js_angle_renderer/lib/angle/angle_shadow_map.dart index c559b4f0..3887576e 100755 --- a/packages/three_js_angle_renderer/lib/angle/angle_shadow_map.dart +++ b/packages/three_js_angle_renderer/lib/angle/angle_shadow_map.dart @@ -1,38 +1,17 @@ part of three_webgl; -class AngleShadowMap { +class AngleShadowMap extends ShadowMap { bool _didDispose = false; Frustum _frustum = Frustum(); final _shadowMapSize = Vector2.zero(); final _viewportSize = Vector2.zero(); final _viewport = Vector4.identity(); - final shadowSide = {0: BackSide, 1: FrontSide, 2: DoubleSide}; - - // HashMap _depthMaterials = HashMap(); - // HashMap _distanceMaterials = HashMap(); - late MeshDepthMaterial _depthMaterial; late MeshDistanceMaterial _distanceMaterial; final _materialCache = {}; - late ShaderMaterial shadowMaterialVertical; - late ShaderMaterial shadowMaterialHorizontal; - - BufferGeometry fullScreenTri = BufferGeometry(); - - late Mesh fullScreenMesh; - - bool enabled = false; - - bool autoUpdate = true; - bool needsUpdate = false; - - int type = PCFShadowMap; - - late AngleShadowMap scope; - final AngleRenderer _renderer; final AngleObjects _objects; final AngleCapabilities _capabilities; @@ -151,7 +130,7 @@ class AngleShadowMap { shadow.map?.dispose(); } - shadow.map = AngleRenderTarget(_shadowMapSize.x.toInt(), _shadowMapSize.y.toInt(), RenderTargetOptions(pars)); + shadow.map = RenderTarget(_shadowMapSize.x.toInt(), _shadowMapSize.y.toInt(), RenderTargetOptions(pars)); shadow.map!.texture.name = '${light.name}.shadowMap'; shadow.camera!.updateProjectionMatrix(); @@ -196,7 +175,7 @@ class AngleShadowMap { shadowMaterialHorizontal.needsUpdate = true; } - shadow.mapPass ??= AngleRenderTarget( _shadowMapSize.x.toInt(), _shadowMapSize.y.toInt() ); + shadow.mapPass ??= RenderTarget( _shadowMapSize.x.toInt(), _shadowMapSize.y.toInt() ); // vertical pass diff --git a/packages/three_js_angle_renderer/lib/angle/angle_state.dart b/packages/three_js_angle_renderer/lib/angle/angle_state.dart index e4eb1a98..936fa1f4 100755 --- a/packages/three_js_angle_renderer/lib/angle/angle_state.dart +++ b/packages/three_js_angle_renderer/lib/angle/angle_state.dart @@ -1,6 +1,6 @@ part of three_webgl; -class AngleState { +class AngleState extends State { bool _didDispose = false; RenderingContext gl; @@ -14,6 +14,7 @@ class AngleState { late Map equationToGL; late Map factorToGL; + @override Map get buffers => {"color": colorBuffer, "depth": depthBuffer, "stencil": stencilBuffer}; Map enabledCapabilities = {}; @@ -143,6 +144,7 @@ class AngleState { return texture; } + @override void enable(id) { if (enabledCapabilities[id] != true) { gl.enable(id); @@ -150,6 +152,7 @@ class AngleState { } } + @override void disable(id) { if (enabledCapabilities[id] != false) { gl.disable(id); @@ -616,6 +619,7 @@ class AngleState { gl.texImage3D(target, level, internalformat, width, height, depth, border, format, type, offset); } + @override void scissor(Vector4 scissor) { if (!currentScissor.equals(scissor)) { gl.scissor(scissor.x.toInt(), scissor.y.toInt(), scissor.z.toInt(), scissor.w.toInt()); @@ -623,6 +627,7 @@ class AngleState { } } + @override void viewport(Vector4 viewport) { if (!currentViewport.equals(viewport)) { gl.viewport(viewport.x.toInt(), viewport.y.toInt(), viewport.z.toInt(), viewport.w.toInt()); @@ -656,6 +661,7 @@ class AngleState { } } + @override void reset() { gl.disable(WebGL.BLEND); gl.disable(WebGL.CULL_FACE); @@ -735,6 +741,7 @@ class AngleState { stencilBuffer.reset(); } + @override void dispose(){ if(_didDispose) return; _didDispose = true; @@ -792,7 +799,7 @@ class ColorBuffer { currentColorClear.setFrom(color); } } - + void reset() { locked = false; diff --git a/packages/three_js_angle_renderer/lib/angle/angle_textures.dart b/packages/three_js_angle_renderer/lib/angle/angle_textures.dart index 311f4b72..88300d94 100755 --- a/packages/three_js_angle_renderer/lib/angle/angle_textures.dart +++ b/packages/three_js_angle_renderer/lib/angle/angle_textures.dart @@ -275,7 +275,7 @@ class AngleTextures { properties.remove( renderTarget.depthTexture ); } - if (renderTarget is AngleCubeRenderTarget) { + if (renderTarget is CubeRenderTarget) { for (int i = 0; i < 6; i++) { gl.deleteFramebuffer(renderTargetProperties["__webglFramebuffer"][i]); if (renderTargetProperties['__webglFramebuffer'][ i ] is List) { @@ -1131,9 +1131,9 @@ class AngleTextures { // Setup resources for a Depth Texture for a FBO (needs an extension) - void setupDepthTexture(framebuffer, AngleRenderTarget renderTarget) { + void setupDepthTexture(framebuffer, RenderTarget renderTarget) { final renderTargetProperties = properties.get( renderTarget ); - final isCube = renderTarget is AngleCubeRenderTarget; + final isCube = renderTarget is CubeRenderTarget; // if the bound depth texture has changed if ( renderTargetProperties['__boundDepthTexture'] != renderTarget.depthTexture ) { @@ -1198,9 +1198,9 @@ class AngleTextures { } // Setup GL resources for a non-texture depth buffer - void setupDepthRenderbuffer(AngleRenderTarget renderTarget) { + void setupDepthRenderbuffer(RenderTarget renderTarget) { final renderTargetProperties = properties.get( renderTarget ); - final isCube = ( renderTarget is AngleCubeRenderTarget == true ); + final isCube = ( renderTarget is CubeRenderTarget == true ); // if the bound depth texture has changed if ( renderTargetProperties['__boundDepthTexture'] != renderTarget.depthTexture ) { @@ -1264,7 +1264,7 @@ class AngleTextures { } // rebind framebuffer with external textures - void rebindTextures(AngleRenderTarget renderTarget, dynamic colorTexture, dynamic depthTexture) { + void rebindTextures(RenderTarget renderTarget, dynamic colorTexture, dynamic depthTexture) { final renderTargetProperties = properties.get(renderTarget); if (colorTexture != null) { @@ -1278,7 +1278,7 @@ class AngleTextures { } // Set up GL resources for the render target - void setupRenderTarget(AngleRenderTarget renderTarget) { + void setupRenderTarget(RenderTarget renderTarget) { final texture = renderTarget.texture; final renderTargetProperties = properties.get( renderTarget ); @@ -1288,7 +1288,7 @@ class AngleTextures { final textures = renderTarget.textures; - final isCube = renderTarget is AngleCubeRenderTarget; + final isCube = renderTarget is CubeRenderTarget; final isMultipleRenderTargets = ( textures.length > 1 ); if ( ! isMultipleRenderTargets ) { @@ -1433,13 +1433,13 @@ class AngleTextures { } } - void updateRenderTargetMipmap(AngleRenderTarget renderTarget) { + void updateRenderTargetMipmap(RenderTarget renderTarget) { final textures = renderTarget.textures; for (int i = 0, il = textures.length; i < il; i++) { final texture = textures[i]; if (textureNeedsGenerateMipmaps(texture)) { - final target = renderTarget is AngleCubeRenderTarget ? WebGL.TEXTURE_CUBE_MAP : WebGL.TEXTURE_2D; + final target = renderTarget is CubeRenderTarget ? WebGL.TEXTURE_CUBE_MAP : WebGL.TEXTURE_2D; final webglTexture = properties.get(texture)["__webglTexture"]; state.bindTexture(target, webglTexture); @@ -1452,7 +1452,7 @@ class AngleTextures { final Uint32List invalidationArrayDraw = Uint32List(1); final Uint32List invalidationArrayRead = Uint32List(1); - void updateMultisampleRenderTarget(AngleRenderTarget renderTarget) { + void updateMultisampleRenderTarget(RenderTarget renderTarget) { if ( renderTarget.samples > 0 ) { if ( !useMultisampledRTT( renderTarget )) { final textures = renderTarget.textures; diff --git a/packages/three_js_angle_renderer/lib/angle/index.dart b/packages/three_js_angle_renderer/lib/angle/index.dart index 2b743863..09d9207e 100755 --- a/packages/three_js_angle_renderer/lib/angle/index.dart +++ b/packages/three_js_angle_renderer/lib/angle/index.dart @@ -27,7 +27,6 @@ part 'angle_lights.dart'; part 'angle_materials.dart'; part 'angle_morphtargets.dart'; part 'angle_objects.dart'; -part 'angle_parameters.dart'; part 'angle_program.dart'; part 'angle_program_extra.dart'; part 'angle_programs.dart'; diff --git a/packages/three_js_angle_renderer/lib/renderers/3d_render_target.dart b/packages/three_js_angle_renderer/lib/renderers/3d_render_target.dart index ab3ba6e7..4a96a6ce 100755 --- a/packages/three_js_angle_renderer/lib/renderers/3d_render_target.dart +++ b/packages/three_js_angle_renderer/lib/renderers/3d_render_target.dart @@ -1,6 +1,6 @@ part of three_renderers; -class Angle3DRenderTarget extends AngleRenderTarget { +class Angle3DRenderTarget extends RenderTarget { Angle3DRenderTarget([int width = 1, int height = 1, int depth = 1, RenderTargetOptions? options]) : super(width, height, options) { this.depth = depth; texture = Data3DTexture(null, width, height, depth); diff --git a/packages/three_js_angle_renderer/lib/renderers/array_render_target.dart b/packages/three_js_angle_renderer/lib/renderers/array_render_target.dart index 160edf59..0d9553af 100755 --- a/packages/three_js_angle_renderer/lib/renderers/array_render_target.dart +++ b/packages/three_js_angle_renderer/lib/renderers/array_render_target.dart @@ -1,6 +1,6 @@ part of three_renderers; -class AngleArrayRenderTarget extends AngleRenderTarget { +class AngleArrayRenderTarget extends RenderTarget { AngleArrayRenderTarget([int width = 1, int height = 1, int depth = 1, RenderTargetOptions? options]) : super(width, height, options) { this.depth = depth; texture = DataArrayTexture(null, width, height, depth); diff --git a/packages/three_js_angle_renderer/lib/renderers/cube_render_target.dart b/packages/three_js_angle_renderer/lib/renderers/cube_render_target.dart index 0f247e86..b129bc83 100755 --- a/packages/three_js_angle_renderer/lib/renderers/cube_render_target.dart +++ b/packages/three_js_angle_renderer/lib/renderers/cube_render_target.dart @@ -1,126 +1,126 @@ -part of three_renderers; +// part of three_renderers; -class AngleCubeRenderTarget extends CubeRenderTarget { - AngleCubeRenderTarget([int size = 1, RenderTargetOptions? options]) : super(size, options) { - // By convention -- likely based on the RenderMan spec from the 1990's -- cube maps are specified by WebGL (and three.js) - // in a coordinate system in which positive-x is to the right when looking up the positive-z axis -- in other words, - // in a left-handed coordinate system. By continuing this convention, preexisting cube maps continued to render correctly. +// class AngleCubeRenderTarget extends CubeRenderTarget { +// AngleCubeRenderTarget([int size = 1, RenderTargetOptions? options]) : super(size, options) { +// // By convention -- likely based on the RenderMan spec from the 1990's -- cube maps are specified by WebGL (and three.js) +// // in a coordinate system in which positive-x is to the right when looking up the positive-z axis -- in other words, +// // in a left-handed coordinate system. By continuing this convention, preexisting cube maps continued to render correctly. - // three.js uses a right-handed coordinate system. So environment maps used in three.js appear to have px and nx swapped - // and the flag isRenderTargetTexture controls this conversion. The flip is not required when using WebGLCubeRenderTarget.texture - // as a cube texture (this is detected when isRenderTargetTexture is set to true for cube textures). - final image = ImageElement(width: size, height: size, depth: 1); - final images = [image, image, image, image, image, image]; +// // three.js uses a right-handed coordinate system. So environment maps used in three.js appear to have px and nx swapped +// // and the flag isRenderTargetTexture controls this conversion. The flip is not required when using WebGLCubeRenderTarget.texture +// // as a cube texture (this is detected when isRenderTargetTexture is set to true for cube textures). +// final image = ImageElement(width: size, height: size, depth: 1); +// final images = [image, image, image, image, image, image]; - texture = CubeTexture( - images, - this.options.mapping, - this.options.wrapS, - this.options.wrapT, - this.options.magFilter, - this.options.minFilter, - this.options.format, - this.options.type, - this.options.anisotropy, - this.options.colorSpace - ); - texture.isRenderTargetTexture = true; +// texture = CubeTexture( +// images, +// this.options.mapping, +// this.options.wrapS, +// this.options.wrapT, +// this.options.magFilter, +// this.options.minFilter, +// this.options.format, +// this.options.type, +// this.options.anisotropy, +// this.options.colorSpace +// ); +// texture.isRenderTargetTexture = true; - texture.generateMipmaps = this.options.generateMipmaps; - texture.minFilter = this.options.minFilter ?? LinearFilter; - } +// texture.generateMipmaps = this.options.generateMipmaps; +// texture.minFilter = this.options.minFilter ?? LinearFilter; +// } - @override - AngleCubeRenderTarget fromEquirectangularTexture(Renderer renderer, Texture texture) { - this.texture.type = texture.type; - this.texture.colorSpace = texture.colorSpace; +// @override +// AngleCubeRenderTarget fromEquirectangularTexture(Renderer renderer, Texture texture) { +// this.texture.type = texture.type; +// this.texture.colorSpace = texture.colorSpace; - this.texture.generateMipmaps = texture.generateMipmaps; - this.texture.minFilter = texture.minFilter; - this.texture.magFilter = texture.magFilter; +// this.texture.generateMipmaps = texture.generateMipmaps; +// this.texture.minFilter = texture.minFilter; +// this.texture.magFilter = texture.magFilter; - final shader = { - "uniforms": { - "tEquirect": {'value': null}, - }, - "vertexShader": """ +// final shader = { +// "uniforms": { +// "tEquirect": {'value': null}, +// }, +// "vertexShader": """ - varying vec3 vWorldDirection; +// varying vec3 vWorldDirection; - vec3 transformDirection( in vec3 dir, in mat4 matrix ) { +// vec3 transformDirection( in vec3 dir, in mat4 matrix ) { - return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz ); +// return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz ); - } +// } - void main() { +// void main() { - vWorldDirection = transformDirection( position, modelMatrix ); +// vWorldDirection = transformDirection( position, modelMatrix ); - #include - #include +// #include +// #include - } - """, - "fragmentShader": """ +// } +// """, +// "fragmentShader": """ - uniform sampler2D tEquirect; +// uniform sampler2D tEquirect; - varying vec3 vWorldDirection; +// varying vec3 vWorldDirection; - #include +// #include - void main() { +// void main() { - vec3 direction = normalize( vWorldDirection ); +// vec3 direction = normalize( vWorldDirection ); - vec2 sampleUV = equirectUv( direction ); +// vec2 sampleUV = equirectUv( direction ); - gl_FragColor = texture2D( tEquirect, sampleUV ); +// gl_FragColor = texture2D( tEquirect, sampleUV ); - } - """ - }; +// } +// """ +// }; - final geometry = BoxGeometry(5, 5, 5); - final material = ShaderMaterial.fromMap({ - "name": 'CubemapFromEquirect', - "uniforms": cloneUniforms(shader["uniforms"] as Map), - "vertexShader": shader["vertexShader"], - "fragmentShader": shader["fragmentShader"], - "side": BackSide, - "blending": NoBlending - }); +// final geometry = BoxGeometry(5, 5, 5); +// final material = ShaderMaterial.fromMap({ +// "name": 'CubemapFromEquirect', +// "uniforms": cloneUniforms(shader["uniforms"] as Map), +// "vertexShader": shader["vertexShader"], +// "fragmentShader": shader["fragmentShader"], +// "side": BackSide, +// "blending": NoBlending +// }); - material.uniforms["tEquirect"]["value"] = texture; +// material.uniforms["tEquirect"]["value"] = texture; - final mesh = Mesh(geometry, material); +// final mesh = Mesh(geometry, material); - final currentMinFilter = texture.minFilter; +// final currentMinFilter = texture.minFilter; - // Avoid blurred poles - if (texture.minFilter == LinearMipmapLinearFilter) { - texture.minFilter = LinearFilter; - } +// // Avoid blurred poles +// if (texture.minFilter == LinearMipmapLinearFilter) { +// texture.minFilter = LinearFilter; +// } - final camera = CubeCamera(1, 10, this); - camera.update(renderer, mesh); +// final camera = CubeCamera(1, 10, this); +// camera.update(renderer, mesh); - texture.minFilter = currentMinFilter; +// texture.minFilter = currentMinFilter; - mesh.geometry!.dispose(); - mesh.material?.dispose(); +// mesh.geometry!.dispose(); +// mesh.material?.dispose(); - return this; - } +// return this; +// } - @override - void clear(Renderer renderer, [bool color = true, bool depth = true, bool stencil = true]) { - final currentRenderTarget = renderer.getRenderTarget(); - for (int i = 0; i < 6; i++) { - renderer.setRenderTarget(this, i); - renderer.clear(color, depth, stencil); - } - renderer.setRenderTarget(currentRenderTarget); - } -} \ No newline at end of file +// @override +// void clear(Renderer renderer, [bool color = true, bool depth = true, bool stencil = true]) { +// final currentRenderTarget = renderer.getRenderTarget(); +// for (int i = 0; i < 6; i++) { +// renderer.setRenderTarget(this, i); +// renderer.clear(color, depth, stencil); +// } +// renderer.setRenderTarget(currentRenderTarget); +// } +// } \ No newline at end of file diff --git a/packages/three_js_angle_renderer/lib/renderers/index.dart b/packages/three_js_angle_renderer/lib/renderers/index.dart index 9409772f..92e79a3b 100755 --- a/packages/three_js_angle_renderer/lib/renderers/index.dart +++ b/packages/three_js_angle_renderer/lib/renderers/index.dart @@ -2,6 +2,7 @@ library three_renderers; import 'dart:math' as math; import 'dart:typed_data'; +import '../shaders/index.dart'; import 'package:three_js_core/three_js_core.dart'; import 'package:flutter/foundation.dart'; @@ -10,7 +11,7 @@ import 'package:three_js_math/three_js_math.dart'; import '../angle/index.dart'; part 'renderer.dart'; -part 'render_target.dart'; +//part 'render_target.dart'; part '3d_render_target.dart'; part 'array_render_target.dart'; -part 'cube_render_target.dart'; +//part 'cube_render_target.dart'; diff --git a/packages/three_js_angle_renderer/lib/renderers/pmrem_generator.dart b/packages/three_js_angle_renderer/lib/renderers/pmrem_generator.dart index f07d2909..aa49c6f3 100755 --- a/packages/three_js_angle_renderer/lib/renderers/pmrem_generator.dart +++ b/packages/three_js_angle_renderer/lib/renderers/pmrem_generator.dart @@ -106,7 +106,7 @@ class PMREMGenerator { /// * and far planes ensure the scene is rendered in its entirety (the cubeCamera /// * is placed at the origin). /// * - AngleRenderTarget fromScene(Scene scene, {double sigma = 0, double near = 0.1, double far = 100, PMREMGeneratorOptions? options}) { + RenderTarget fromScene(Scene scene, {double sigma = 0, double near = 0.1, double far = 100, PMREMGeneratorOptions? options}) { options ??= PMREMGeneratorOptions(); _oldTarget = _renderer.getRenderTarget(); @@ -237,7 +237,7 @@ class PMREMGenerator { return cubeUVRenderTarget; } - AngleRenderTarget _allocateTargets() { + RenderTarget _allocateTargets() { int width = 3 * math.max(_cubeSize, 16 * 7); int height = 4 * _cubeSize; @@ -552,8 +552,8 @@ class PMREMGenerator { return {"lodPlanes": lodPlanes, "sizeLods": sizeLods, "sigmas": sigmas}; } - AngleRenderTarget _createRenderTarget(int width, int height, Map params) { - final cubeUVRenderTarget = AngleRenderTarget(width, height, RenderTargetOptions(params)); + RenderTarget _createRenderTarget(int width, int height, Map params) { + final cubeUVRenderTarget = RenderTarget(width, height, RenderTargetOptions(params)); cubeUVRenderTarget.texture.mapping = CubeUVReflectionMapping; cubeUVRenderTarget.texture.name = 'PMREM.cubeUv'; cubeUVRenderTarget.scissorTest = true; diff --git a/packages/three_js_angle_renderer/lib/renderers/render_target.dart b/packages/three_js_angle_renderer/lib/renderers/render_target.dart index 6d27d043..564e2cc3 100755 --- a/packages/three_js_angle_renderer/lib/renderers/render_target.dart +++ b/packages/three_js_angle_renderer/lib/renderers/render_target.dart @@ -1,44 +1,44 @@ -/* - In options, we can specify: - * Texture parameters for an auto-generated target texture - * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers -*/ +// /* +// In options, we can specify: +// * Texture parameters for an auto-generated target texture +// * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers +// */ -part of three_renderers; +// part of three_renderers; -class AngleRenderTarget extends RenderTarget { - bool _didDispose = false; +// class AngleRenderTarget extends RenderTarget { +// bool _didDispose = false; - AngleRenderTarget(super.width, super.height, [super.options]); +// AngleRenderTarget(super.width, super.height, [super.options]); - @override - AngleRenderTarget clone() { - return AngleRenderTarget(width, height, options)..copy(this); - } +// @override +// AngleRenderTarget clone() { +// return AngleRenderTarget(width, height, options)..copy(this); +// } - @override - AngleRenderTarget copy(RenderTarget source) { - super.copy(source); - return this; - } +// @override +// AngleRenderTarget copy(RenderTarget source) { +// super.copy(source); +// return this; +// } - @override - bool is3D() { - return texture is Data3DTexture || texture is DataArrayTexture; - } +// @override +// bool is3D() { +// return texture is Data3DTexture || texture is DataArrayTexture; +// } - @override - void dispose() { - if(_didDispose) return; - _didDispose = true; - dispatchEvent(Event(type: "dispose")); - depthTexture?.dispose(); - texture.dispose(); - options.dispose(); +// @override +// void dispose() { +// if(_didDispose) return; +// _didDispose = true; +// dispatchEvent(Event(type: "dispose")); +// depthTexture?.dispose(); +// texture.dispose(); +// options.dispose(); - // textures.forEach((t){ - // t.dispose(); - // }); - // textures.clear(); - } -} \ No newline at end of file +// // textures.forEach((t){ +// // t.dispose(); +// // }); +// // textures.clear(); +// } +// } \ No newline at end of file diff --git a/packages/three_js_angle_renderer/lib/renderers/renderer.dart b/packages/three_js_angle_renderer/lib/renderers/renderer.dart index 36d7808e..85b38c97 100755 --- a/packages/three_js_angle_renderer/lib/renderers/renderer.dart +++ b/packages/three_js_angle_renderer/lib/renderers/renderer.dart @@ -96,30 +96,19 @@ class AngleRenderer extends Renderer{ }; // clearing - - bool autoClear = true; - bool autoClearColor = true; - bool autoClearDepth = true; - bool autoClearStencil = true; bool useLegacyLights = false; - // scene graph - bool sortObjects = true; - // user-defined clipping - List clippingPlanes = []; bool localClippingEnabled = false; - // physically based shading + // physically based shading int outputEncoding = LinearEncoding; // physical lights - bool physicallyCorrectLights = false; // tone mapping - late double _width; late double _height; @@ -137,7 +126,7 @@ class AngleRenderer extends Renderer{ int _currentActiveCubeFace = 0; int _currentActiveMipmapLevel = 0; - AngleRenderTarget? _currentRenderTarget; + RenderTarget? _currentRenderTarget; int _currentMaterialId = -1; Camera? _currentCamera; @@ -174,6 +163,7 @@ class AngleRenderer extends Renderer{ final _emptyScene = Scene(); + @override double getTargetPixelRatio() => _currentRenderTarget == null ? _pixelRatio : 1.0; // initialize @@ -184,8 +174,7 @@ class AngleRenderer extends Renderer{ final animation = AngleAnimation(); late AngleExtensions extensions; - late AngleCapabilities capabilities; - late AngleState state; + late Capabilities capabilities; late AngleInfo info; late AngleProperties properties; late AngleTextures textures; @@ -211,12 +200,15 @@ class AngleRenderer extends Renderer{ late XRManager Function(AngleRenderer renderer, dynamic gl)? _setXR; late AngleUniformsGroups uniformsGroups; - late AngleShadowMap shadowMap; late final Framebuffer _scratchFrameBuffer; late final Framebuffer _srcFramebuffer; late final Framebuffer _dstFramebuffer; AngleRenderer(this.parameters) { + shaderChunk = angleShaderChunk; + lightsFragmentBegin = angleLightsFragmentBegin; + lightsParsBegin = angleLightsParsBegin; + _width = this.parameters.width; _height = this.parameters.height; @@ -255,28 +247,28 @@ class AngleRenderer extends Renderer{ capabilities = AngleCapabilities(_gl, extensions, parameters, utils); state = AngleState(_gl,extensions); - if ( capabilities.reverseDepthBuffer && reverseDepthBuffer ) { + if ( (capabilities as AngleCapabilities).reverseDepthBuffer && reverseDepthBuffer ) { state.buffers['depth'].setReversed( true ); } info = AngleInfo(_gl); properties = AngleProperties(); - textures = AngleTextures(_gl, extensions, state, properties, capabilities, utils, info); + textures = AngleTextures(_gl, extensions, state as AngleState, properties, capabilities as AngleCapabilities, utils, info); cubemaps = AngleCubeMaps(this); cubeuvmaps = AngleCubeUVMaps(this); attributes = AngleAttributes(_gl); bindingStates = AngleBindingStates(_gl, attributes); geometries = AngleGeometries(_gl, attributes, info, bindingStates); objects = AngleObjects(_gl, geometries, attributes, info); - morphtargets = AngleMorphtargets(_gl, capabilities, textures); + morphtargets = AngleMorphtargets(_gl, capabilities as AngleCapabilities, textures); clipping = AngleClipping(properties); - programCache = AnglePrograms(this, cubemaps, cubeuvmaps, extensions, capabilities, bindingStates, clipping); + programCache = AnglePrograms(this, cubemaps, cubeuvmaps, extensions, capabilities as AngleCapabilities, bindingStates, clipping); materials = AngleMaterials(this, properties); renderLists = AngleRenderLists(); renderStates = AngleRenderStates(extensions); - background = AngleBackground(this, cubemaps, cubeuvmaps, state, objects, alpha, premultipliedAlpha); - shadowMap = AngleShadowMap(this, objects, capabilities); - uniformsGroups = AngleUniformsGroups( _gl, info, capabilities, state ); + background = AngleBackground(this, cubemaps, cubeuvmaps, state as AngleState, objects, alpha, premultipliedAlpha); + shadowMap = AngleShadowMap(this, objects, capabilities as AngleCapabilities); + uniformsGroups = AngleUniformsGroups( _gl, info, capabilities as AngleCapabilities, state as AngleState ); bufferRenderer = AngleBufferRenderer(_gl, extensions, info); indexedBufferRenderer = AngleIndexedBufferRenderer(_gl, extensions, info); @@ -290,7 +282,7 @@ class AngleRenderer extends Renderer{ } // API - + @override RenderingContext getContext() { return _gl; } @@ -309,6 +301,7 @@ class AngleRenderer extends Renderer{ if (extension) extension.restoreContext(); } + @override double getPixelRatio() { return _pixelRatio; } @@ -318,6 +311,7 @@ class AngleRenderer extends Renderer{ setSize(width, height, false); } + @override Vector2 getSize(Vector2 target) { return target.setValues(width.toDouble(), height.toDouble()); } @@ -344,14 +338,17 @@ class AngleRenderer extends Renderer{ setViewport(0, 0, width, height); } + @override Vector4 getCurrentViewport(Vector4 target) { return target.setFrom(_currentViewport); } + @override Vector4 getViewport(Vector4 target) { return target.setFrom(_viewport); } + @override void setViewport(double x, double y, double width, double height) { _viewport.setValues(x, y, width, height); _currentViewport.setFrom(_viewport); @@ -377,7 +374,7 @@ class AngleRenderer extends Renderer{ } void setScissorTest(bool boolean) { - state.setScissorTest(_scissorTest = boolean); + (state as AngleState).setScissorTest(_scissorTest = boolean); } void setOpaqueSort(Function? method) { @@ -389,21 +386,24 @@ class AngleRenderer extends Renderer{ } // Clearing - + @override Color getClearColor(Color target) { target.setFrom(background.getClearColor()); return target; } // color same as Color.set + @override void setClearColor(Color color, [double alpha = 1.0]) { background.setClearColor(color, alpha); } + @override double getClearAlpha() { return background.getClearAlpha(); } + @override void setClearAlpha(double alpha) { background.setClearAlpha(alpha); } @@ -472,18 +472,6 @@ class AngleRenderer extends Renderer{ _gl.clear( bits ); } - void clearColor() { - clear(true, false, false); - } - - void clearDepth() { - clear(false, true, false); - } - - void clearStencil() { - clear(false, false, true); - } - // @override void dispose() { @@ -594,6 +582,7 @@ class AngleRenderer extends Renderer{ } } + @override void renderBufferDirect( Camera camera, Object3D? scene, @@ -609,7 +598,7 @@ class AngleRenderer extends Renderer{ AngleProgram program = setProgram(camera, scene, geometry, material, object); - state.setMaterial(material, frontFaceCW); + (state as AngleState).setMaterial(material, frontFaceCW); BufferAttribute? index = geometry.index; int rangeFactor = 1; @@ -660,7 +649,7 @@ class AngleRenderer extends Renderer{ if (object is Mesh) { if (material.wireframe) { - state.setLineWidth(material.wireframeLinewidth! * getTargetPixelRatio()); + (state as AngleState).setLineWidth(material.wireframeLinewidth! * getTargetPixelRatio()); renderer.setMode(WebGL.LINES); } else { @@ -672,7 +661,7 @@ class AngleRenderer extends Renderer{ lineWidth ??= 1; // Not using Line*Material - state.setLineWidth(lineWidth * getTargetPixelRatio()); + (state as AngleState).setLineWidth(lineWidth * getTargetPixelRatio()); if (object is LineSegments) { renderer.setMode(WebGL.LINES); @@ -1079,7 +1068,7 @@ class AngleRenderer extends Renderer{ state.buffers["depth"].setMask(true); state.buffers["color"].setMask(true); - state.setPolygonOffset(false); + (state as AngleState).setPolygonOffset(false); } void renderTransmissionPass(List opaqueObjects, List transmissiveObjects, Object3D scene, Camera camera) { @@ -1089,14 +1078,14 @@ class AngleRenderer extends Renderer{ return; } - AngleRenderTarget? transmissionRenderTarget = currentRenderState?.state.transmissionRenderTarget[ camera.id ]; + RenderTarget? transmissionRenderTarget = currentRenderState?.state.transmissionRenderTarget[ camera.id ]; final activeViewport = camera.viewport ?? _currentViewport; if ( currentRenderState?.state.transmissionRenderTarget[ camera.id ] == null || (activeViewport.w.toInt() != transmissionRenderTarget?.height || activeViewport.z.toInt() != transmissionRenderTarget?.width) ) { transmissionRenderTarget?.dispose(); - currentRenderState?.state.transmissionRenderTarget[ camera.id ] = AngleRenderTarget( 1, 1, RenderTargetOptions({ + currentRenderState?.state.transmissionRenderTarget[ camera.id ] = RenderTarget( 1, 1, RenderTargetOptions({ 'generateMipmaps': true, 'type': ( extensions.has( 'EXT_color_buffer_half_float' ) || extensions.has( 'EXT_color_buffer_float' ) ) ? HalfFloatType : UnsignedByteType, 'minFilter': LinearMipmapLinearFilter, @@ -1338,7 +1327,7 @@ class AngleRenderer extends Renderer{ return materialProperties['uniformsList']; } - void updateCommonMaterialProperties(Material material, AngleParameters parameters) { + void updateCommonMaterialProperties(Material material, Parameters parameters) { final materialProperties = properties.get(material); materialProperties['outputColorSpace'] = parameters.outputColorSpace; @@ -1472,7 +1461,7 @@ class AngleRenderer extends Renderer{ final AngleUniforms? pUniformS = program?.getUniforms(); final Map mUniformS = materialProperties['uniforms']; - if (state.useProgram( program?.program ) ) { + if ((state as AngleState).useProgram( program?.program ) ) { refreshProgram = true; refreshMaterial = true; refreshLights = true; @@ -1689,7 +1678,7 @@ class AngleRenderer extends Renderer{ //} } - void setRenderTargetFramebuffer(AngleRenderTarget renderTarget, Framebuffer? defaultFramebuffer) { + void setRenderTargetFramebuffer(RenderTarget renderTarget, Framebuffer? defaultFramebuffer) { final renderTargetProperties = properties.get(renderTarget); renderTargetProperties["__webglFramebuffer"] = defaultFramebuffer; renderTargetProperties["__useDefaultFramebuffer"] = defaultFramebuffer == null; @@ -1697,7 +1686,6 @@ class AngleRenderer extends Renderer{ @override void setRenderTarget(RenderTarget? renderTarget, [int activeCubeFace = 0, int activeMipmapLevel = 0]) { - renderTarget as AngleRenderTarget?; _currentRenderTarget = renderTarget; _currentActiveCubeFace = activeCubeFace; _currentActiveMipmapLevel = activeMipmapLevel; @@ -1712,7 +1700,7 @@ class AngleRenderer extends Renderer{ if (renderTargetProperties["__useDefaultFramebuffer"] != null) { // We need to make sure to rebind the framebuffer. - state.bindFramebuffer(WebGL.FRAMEBUFFER, null); + (state as AngleState).bindFramebuffer(WebGL.FRAMEBUFFER, null); useDefaultFramebuffer = false; } else if (renderTargetProperties["__webglFramebuffer"] == null) { @@ -1783,16 +1771,16 @@ class AngleRenderer extends Renderer{ if ( activeMipmapLevel != 0 ) { framebuffer = _scratchFrameBuffer; } - - final framebufferBound = state.bindFramebuffer(WebGL.FRAMEBUFFER, framebuffer); + final angleState = state as AngleState; + final framebufferBound = angleState.bindFramebuffer(WebGL.FRAMEBUFFER, framebuffer); if (framebufferBound && capabilities.drawBuffers && useDefaultFramebuffer) { - state.drawBuffers(renderTarget, framebuffer); + angleState.drawBuffers(renderTarget, framebuffer); } - state.viewport(_currentViewport); - state.scissor(_currentScissor); - state.setScissorTest(_currentScissorTest!); + angleState.viewport(_currentViewport); + angleState.scissor(_currentScissor); + angleState.setScissorTest(_currentScissorTest!); if (isCube) { final textureProperties = properties.get(renderTarget!.texture); @@ -1813,7 +1801,7 @@ class AngleRenderer extends Renderer{ _currentMaterialId = -1; // reset current material to ensure correct uniform bindings } - void readRenderTargetPixels(AngleRenderTarget renderTarget, int x, int y, int width, int height, TypedData buffer, [int? activeCubeFaceIndex]) { + void readRenderTargetPixels(RenderTarget renderTarget, int x, int y, int width, int height, TypedData buffer, [int? activeCubeFaceIndex]) { dynamic framebuffer = properties.get(renderTarget)["__webglFramebuffer"]; //can be Map or int if (renderTarget is CubeRenderTarget && activeCubeFaceIndex != null) { @@ -1821,7 +1809,7 @@ class AngleRenderer extends Renderer{ } if (framebuffer != null) { - state.bindFramebuffer(WebGL.FRAMEBUFFER, framebuffer); + (state as AngleState).bindFramebuffer(WebGL.FRAMEBUFFER, framebuffer); try { final texture = renderTarget.texture; @@ -1855,11 +1843,12 @@ class AngleRenderer extends Renderer{ } } finally { final framebuffer = (_currentRenderTarget != null) ? properties.get(_currentRenderTarget)["__webglFramebuffer"] : null; - state.bindFramebuffer(WebGL.FRAMEBUFFER, framebuffer); + (state as AngleState).bindFramebuffer(WebGL.FRAMEBUFFER, framebuffer); } } } + @override void copyFramebufferToTexture(Vector? position, Texture? texture, {int level = 0}) { //console.warning('copyFramebufferToTexture not supported'); if (texture is! FramebufferTexture) { @@ -1876,7 +1865,7 @@ class AngleRenderer extends Renderer{ textures.setTexture2D(texture, 0); _gl.copyTexSubImage2D(WebGL.TEXTURE_2D, level, 0, 0, x, y, width, height); - state.unbindTexture(WebGLTexture(WebGL.TEXTURE_2D)); + (state as AngleState).unbindTexture(WebGLTexture(WebGL.TEXTURE_2D)); } void copyTextureToTexture(Texture srcTexture, Texture dstTexture, {srcRegion, dstPosition, int srcLevel = 0, dstLevel}) { @@ -1971,14 +1960,15 @@ class AngleRenderer extends Renderer{ // set up the src texture final isSrc3D = srcTexture is DataArrayTexture || srcTexture is Data3DTexture; final isDst3D = dstTexture is DataArrayTexture || dstTexture is Data3DTexture; + final angleState = state as AngleState; if ( srcTexture.isDepthTexture ) { final srcTextureProperties = properties.get( srcTexture ); final dstTextureProperties = properties.get( dstTexture ); final srcRenderTargetProperties = properties.get( srcTextureProperties['__renderTarget'] ); final dstRenderTargetProperties = properties.get( dstTextureProperties['__renderTarget'] ); - state.bindFramebuffer( WebGL.READ_FRAMEBUFFER, srcRenderTargetProperties['__webglFramebuffer'] ); - state.bindFramebuffer( WebGL.DRAW_FRAMEBUFFER, dstRenderTargetProperties['__webglFramebuffer'] ); + angleState.bindFramebuffer( WebGL.READ_FRAMEBUFFER, srcRenderTargetProperties['__webglFramebuffer'] ); + angleState.bindFramebuffer( WebGL.DRAW_FRAMEBUFFER, dstRenderTargetProperties['__webglFramebuffer'] ); for (int i = 0; i < depth; i ++ ) { // if the source or destination are a 3d target then a layer needs to be bound @@ -1990,8 +1980,8 @@ class AngleRenderer extends Renderer{ _gl.blitFramebuffer( minX, minY, width, height, dstX, dstY, width, height, WebGL.DEPTH_BUFFER_BIT, WebGL.NEAREST ); } - state.bindFramebuffer( WebGL.READ_FRAMEBUFFER, null ); - state.bindFramebuffer( WebGL.DRAW_FRAMEBUFFER, null ); + angleState.bindFramebuffer( WebGL.READ_FRAMEBUFFER, null ); + angleState.bindFramebuffer( WebGL.DRAW_FRAMEBUFFER, null ); } else if ( srcLevel != 0 || srcTexture.isRenderTargetTexture || properties.has( srcTexture ) ) { @@ -2000,8 +1990,8 @@ class AngleRenderer extends Renderer{ final dstTextureProperties = properties.get( dstTexture ); // bind the frame buffer targets - state.bindFramebuffer( WebGL.READ_FRAMEBUFFER, _srcFramebuffer ); - state.bindFramebuffer( WebGL.DRAW_FRAMEBUFFER, _dstFramebuffer ); + angleState.bindFramebuffer( WebGL.READ_FRAMEBUFFER, _srcFramebuffer ); + angleState.bindFramebuffer( WebGL.DRAW_FRAMEBUFFER, _dstFramebuffer ); for (int i = 0; i < depth; i ++ ) { @@ -2031,8 +2021,8 @@ class AngleRenderer extends Renderer{ } // unbind read, draw buffers - state.bindFramebuffer( WebGL.READ_FRAMEBUFFER, null ); - state.bindFramebuffer( WebGL.DRAW_FRAMEBUFFER, null ); + angleState.bindFramebuffer( WebGL.READ_FRAMEBUFFER, null ); + angleState.bindFramebuffer( WebGL.DRAW_FRAMEBUFFER, null ); } else { @@ -2074,7 +2064,7 @@ class AngleRenderer extends Renderer{ _gl.generateMipmap( glTarget ); } - state.unbindTexture(); + angleState.unbindTexture(); } void copyTextureToTexture3D( @@ -2107,7 +2097,7 @@ class AngleRenderer extends Renderer{ textures.setTexture2D(texture, 0); } - state.unbindTexture(); + (state as AngleState).unbindTexture(); } WebGLTexture getRenderTargetGLTexture(RenderTarget renderTarget) { diff --git a/packages/three_js_angle_renderer/lib/shaders/index.dart b/packages/three_js_angle_renderer/lib/shaders/index.dart index 89d75dd8..d609c506 100755 --- a/packages/three_js_angle_renderer/lib/shaders/index.dart +++ b/packages/three_js_angle_renderer/lib/shaders/index.dart @@ -1,13 +1,5 @@ -library three_shaders; - -import 'package:three_js_core/three_js_core.dart'; -import 'package:three_js_math/three_js_math.dart'; -import 'shader_chunk/index.dart'; -import 'shader_lib/index.dart'; - export 'shader_lib/vsm_vert.glsl.dart'; export 'shader_lib/vsm_frag.glsl.dart'; - -part 'shader_lib.dart'; -part 'uniforms_lib.dart'; -part 'shader_chunk.dart'; +export 'shader_chunk.dart'; +export 'shader_chunk/lights_fragment_begin.glsl.dart'; +export 'shader_chunk/lights_pars_begin.glsl.dart'; \ No newline at end of file diff --git a/packages/three_js_angle_renderer/lib/shaders/mesh_gouraund_material.dart b/packages/three_js_angle_renderer/lib/shaders/mesh_gouraund_material.dart index a1eb4c84..ac0e4781 100644 --- a/packages/three_js_angle_renderer/lib/shaders/mesh_gouraund_material.dart +++ b/packages/three_js_angle_renderer/lib/shaders/mesh_gouraund_material.dart @@ -1,6 +1,5 @@ -import "package:three_js_angle/shaders/index.dart"; import "package:three_js_math/three_js_math.dart"; -import "package:three_js_core/renderers/uniforms_utils.dart"; +import "package:three_js_core/three_js_core.dart"; final Map gouraudShader = { 'name': 'GouraudShader', diff --git a/packages/three_js_angle_renderer/lib/shaders/shader_chunk.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk.dart index 03c9815a..61c87560 100755 --- a/packages/three_js_angle_renderer/lib/shaders/shader_chunk.dart +++ b/packages/three_js_angle_renderer/lib/shaders/shader_chunk.dart @@ -1,6 +1,7 @@ -part of three_shaders; +import 'shader_chunk/index.dart'; +import 'shader_lib/index.dart'; -Map shaderChunk = { +Map angleShaderChunk = { 'alphahash_fragment': alphahashFragment, 'alphahash_pars_fragment': alphahashParsFragment, "alphamap_fragment": alphamapFragment, @@ -57,14 +58,14 @@ Map shaderChunk = { "lights_lambert_vertex": lightsLambertVertex, 'lights_lambert_fragment': lightsLambertFragment, 'lights_lambert_pars_fragment': lightsLambertParsFragment, - "lights_pars_begin": lightsParsBegin, + "lights_pars_begin": angleLightsParsBegin, "lights_toon_fragment": lightsToonFragment, "lights_toon_pars_fragment": lightsToonParsFragment, "lights_phong_fragment": lightsPhongFragment, "lights_phong_pars_fragment": lightsPhongParsFragment, "lights_physical_fragment": lightsPhysicalFragment, "lights_physical_pars_fragment": lightsPhysicalParsFragment, - "lights_fragment_begin": lightsFragmentBegin, + "lights_fragment_begin": angleLightsFragmentBegin, "lights_fragment_maps": lightsFragmentMaps, "lights_fragment_end": lightsFragmentEnd, "logdepthbuf_fragment": logdepthbufFragment, diff --git a/packages/three_js_angle_renderer/lib/shaders/shader_chunk/lights_fragment_begin.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/lights_fragment_begin.glsl.dart index a57085a9..e86de392 100755 --- a/packages/three_js_angle_renderer/lib/shaders/shader_chunk/lights_fragment_begin.glsl.dart +++ b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/lights_fragment_begin.glsl.dart @@ -1,4 +1,4 @@ -String lightsFragmentBegin = """ +String angleLightsFragmentBegin = """ /** * This is a template that can be used to light a material, it uses pluggable * RenderEquations (RE)for specific lighting scenarios. diff --git a/packages/three_js_angle_renderer/lib/shaders/shader_chunk/lights_pars_begin.glsl.dart b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/lights_pars_begin.glsl.dart index f4887867..5b7bafad 100755 --- a/packages/three_js_angle_renderer/lib/shaders/shader_chunk/lights_pars_begin.glsl.dart +++ b/packages/three_js_angle_renderer/lib/shaders/shader_chunk/lights_pars_begin.glsl.dart @@ -1,4 +1,4 @@ -String lightsParsBegin = """ +String angleLightsParsBegin = """ uniform bool receiveShadow; uniform vec3 ambientLightColor; diff --git a/packages/three_js_angle_renderer/lib/shaders/uniforms_lib.dart b/packages/three_js_angle_renderer/lib/shaders/uniforms_lib.dart deleted file mode 100755 index de5b8bf3..00000000 --- a/packages/three_js_angle_renderer/lib/shaders/uniforms_lib.dart +++ /dev/null @@ -1,175 +0,0 @@ -part of three_shaders; - -Map uniformsLib = { - "common": { - "diffuse": {"value": Color.fromHex32(0xffffff)}, - "opacity": {"value": 1.0}, - "map": {'value': null}, - "mapTransform": {"value": Matrix3.identity()}, - "alphaMap": {'value': null}, - "alphaMapTransform": {"value": Matrix3.identity()}, - "alphaTest": {"value": 0.0}, - "uvTransform": {"value": Matrix3.identity()}, - "uv2Transform": {"value": Matrix3.identity()}, - }, - "specularmap": { - "specularMap": {'value': null}, - 'specularMapTransform': { 'value': Matrix3.identity() } - }, - "envmap": { - "envMap": {}, - "flipEnvMapX": {"value": -1}, - "flipEnvMapY": {"value": 1}, - - 'envMapRotation': { 'value': Matrix3.identity() }, - "flipEnvMap": {"value": -1}, - "reflectivity": {"value": 1.0}, // basic, lambert, phong - "ior": {"value": 1.5}, // physical - "refractionRatio": {"value": 0.98}, // basic, lambert, phong - }, - "aomap": { - "aoMap": {'value': null}, - "aoMapIntensity": {"value": 1}, - 'aoMapTransform': { 'value': Matrix3.identity() } - }, - "lightmap": { - "lightMap": {'value': null}, - "lightMapIntensity": {"value": 1}, - 'lightMapTransform': { 'value': Matrix3.identity() } - }, - "emissivemap": { - "emissiveMap": {'value': null}, - 'emissiveMapTransform': { 'value': Matrix3.identity() } - }, - "bumpmap": { - "bumpMap": {'value': null}, - 'bumpMapTransform': { 'value': Matrix3.identity() }, - "bumpScale": {"value": 1} - }, - "normalmap": { - "normalMap": {'value': null}, - 'normalMapTransform': { 'value': Matrix3.identity() }, - "normalScale": {"value": Vector2(1, 1)} - }, - "displacementmap": { - "displacementMap": {'value': null}, - 'displacementMapTransform': { 'value': Matrix3.identity() }, - "displacementScale": {"value": 1}, - "displacementBias": {"value": 0} - }, - "roughnessmap": { - "roughnessMap": {'value': null}, - 'roughnessMapTransform': { 'value': Matrix3.identity() } - }, - "metalnessmap": { - "metalnessMap": {'value': null}, - 'metalnessMapTransform': { 'value': Matrix3.identity() } - }, - "gradientmap": { - "gradientMap": {'value': null} - }, - "fog": { - "fogDensity": {"value": 0.00025}, - "fogNear": {"value": 1}, - "fogFar": {"value": 2000}, - "fogColor": {"value": Color(0, 0, 0)} - }, - "lights": { - "ambientLightColor": {"value": []}, - - "lightProbe": {"value": []}, - - "directionalLights": { - "value": [], - "properties": {"direction": {}, "color": {}} - }, - - "directionalLightShadows": { - "value": [], - "properties": {"shadowBias": {}, "shadowNormalBias": {}, "shadowRadius": {}, "shadowMapSize": {}} - }, - - "directionalShadowMap": {"value": []}, - "directionalShadowMatrix": {"value": []}, - - "spotLights": { - "value": [], - "properties": { - "color": {}, - "position": {}, - "direction": {}, - "distance": {}, - "coneCos": {}, - "penumbraCos": {}, - "decay": {} - } - }, - - "spotLightShadows": { - "value": [], - "properties": {"shadowBias": {}, "shadowNormalBias": {}, "shadowRadius": {}, "shadowMapSize": {}} - }, - - 'spotLightMap': { 'value': [] }, - "spotShadowMap": {"value": []}, - "spotShadowMatrix": {"value": []}, - 'spotLightMatrix': { 'value': [] }, - - "pointLights": { - "value": [], - "properties": {"color": {}, "position": {}, "decay": {}, "distance": {}} - }, - - "pointLightShadows": { - "value": [], - "properties": { - "shadowBias": {}, - "shadowNormalBias": {}, - "shadowRadius": {}, - "shadowMapSize": {}, - "shadowCameraNear": {}, - "shadowCameraFar": {} - } - }, - - "pointShadowMap": {"value": []}, - "pointShadowMatrix": {"value": []}, - - "hemisphereLights": { - "value": [], - "properties": {"direction": {}, "skyColor": {}, "groundColor": {}} - }, - - // TODO (abelnation): RectAreaLight BRDF data needs to be moved from example to main src - "rectAreaLights": { - "value": [], - "properties": {"color": {}, "position": {}, "width": {}, "height": {}} - }, - - "ltc_1": {'value': null}, - "ltc_2": {'value': null} - }, - "points": { - "diffuse": {"value": Color.fromHex32(0xffffff)}, - "opacity": {"value": 1.0}, - "size": {"value": 1.0}, - "scale": {"value": 1.0}, - "map": {'value': null}, - "alphaMap": {'value': null}, - 'alphaMapTransform': { 'value': Matrix3.identity() }, - "alphaTest": {"value": 0.0}, - "uvTransform": {"value": Matrix3.identity()} - }, - "sprite": { - "diffuse": {"value": Color.fromHex32(0xffffff)}, - "opacity": {"value": 1.0}, - "center": {"value": Vector2(0.5, 0.5)}, - "rotation": {"value": 0.0}, - "map": {'value': null}, - 'mapTransform': { 'value': Matrix3.identity() }, - "alphaMap": {'value': null}, - 'alphaMapTransform': { 'value': Matrix3.identity() }, - "alphaTest": {"value": 0.0}, - "uvTransform": {"value": Matrix3.identity()} - } -}; diff --git a/packages/three_js_angle_renderer/lib/three_js_angle_renderer.dart b/packages/three_js_angle_renderer/lib/three_js_angle_renderer.dart index df4891be..3a80ba10 100755 --- a/packages/three_js_angle_renderer/lib/three_js_angle_renderer.dart +++ b/packages/three_js_angle_renderer/lib/three_js_angle_renderer.dart @@ -4,5 +4,4 @@ export 'shaders/index.dart'; export 'renderers/index.dart'; export 'shaders/shader_lib/index.dart'; export 'renderers/pmrem_generator.dart'; -export 'three_viewer.dart'; -export 'materials/hex_tiling_material.dart'; \ No newline at end of file +export 'three_viewer.dart'; \ No newline at end of file diff --git a/packages/three_js_angle_renderer/lib/three_viewer.dart b/packages/three_js_angle_renderer/lib/three_viewer.dart index 48b4518f..fc02aad8 100644 --- a/packages/three_js_angle_renderer/lib/three_viewer.dart +++ b/packages/three_js_angle_renderer/lib/three_viewer.dart @@ -3,7 +3,7 @@ import 'dart:io'; import 'package:flutter/foundation.dart'; import 'package:flutter/material.dart'; import 'package:flutter/scheduler.dart'; -import 'package:three_js_angle/renderers/index.dart'; +import '../renderers/index.dart'; import 'package:three_js_core/others/index.dart'; import 'package:three_js_core/renderers/index.dart'; import 'package:three_js_core/three_js_core.dart' as core; @@ -117,7 +117,7 @@ class ThreeJS with WidgetsBindingObserver{ FlutterAngleTexture? texture; RenderingContext? gl; - AngleRenderTarget? renderTarget; + RenderTarget? renderTarget; AngleRenderer? renderer; final core.Clock clock = core.Clock(); @@ -309,7 +309,7 @@ class ThreeJS with WidgetsBindingObserver{ if(settings.useSourceTexture){ final RenderTargetOptions pars = RenderTargetOptions(settings.renderOptions); - renderTarget = AngleRenderTarget((width * _resolution!).toInt(), (height * _resolution!).toInt(), pars); + renderTarget = RenderTarget((width * _resolution!).toInt(), (height * _resolution!).toInt(), pars); renderer!.setRenderTarget(renderTarget); sourceTexture = renderer!.getRenderTargetGLTexture(renderTarget!); } diff --git a/packages/three_js_angle_renderer/lib/materials/hex_tiling_material.dart b/packages/three_js_core/lib/materials/hex_tiling_material.dart similarity index 98% rename from packages/three_js_angle_renderer/lib/materials/hex_tiling_material.dart rename to packages/three_js_core/lib/materials/hex_tiling_material.dart index 045b488a..3a5438d8 100644 --- a/packages/three_js_angle_renderer/lib/materials/hex_tiling_material.dart +++ b/packages/three_js_core/lib/materials/hex_tiling_material.dart @@ -1,6 +1,3 @@ -import 'package:three_js_angle/shaders/index.dart'; - -import '../angle/index.dart'; import 'package:three_js_core/three_js_core.dart'; import 'dart:math' as math; @@ -145,7 +142,7 @@ class HexTilingMaterial extends MeshPhysicalMaterial { String get genRandomStringID => generateId()+generateId(); HexTilingMaterial(this.hexTiling,[ Map? options]):super.fromMap(options){ - type = "HexTilingMaterial"; + //type = "HexTilingMaterial"; if(hexTiling != null){ patchMeshPhysicalMaterial(); patchMaterial(); @@ -169,9 +166,9 @@ class HexTilingMaterial extends MeshPhysicalMaterial { } void patchMaterial(){ - final shaderMap = new Map(); + final shaderMap = new Map(); - this.onBeforeCompile = (shader, Renderer renderer) { + this.onBeforeCompile = (Parameters shader, Renderer renderer) { final hexTilingID = genRandomStringID; this.hexTilingID = hexTilingID; shaderMap[hexTilingID] = shader; diff --git a/packages/three_js_core/lib/materials/index.dart b/packages/three_js_core/lib/materials/index.dart index eede8a83..9551bb37 100755 --- a/packages/three_js_core/lib/materials/index.dart +++ b/packages/three_js_core/lib/materials/index.dart @@ -20,4 +20,5 @@ export 'mesh_toon_material.dart'; export 'mesh_matcap_material.dart'; export 'shadow_material.dart'; export 'mesh_gouraund_material.dart'; -export 'projected_material.dart'; \ No newline at end of file +export 'projected_material.dart'; +export 'hex_tiling_material.dart'; \ No newline at end of file diff --git a/packages/three_js_core/lib/materials/projected_material.dart b/packages/three_js_core/lib/materials/projected_material.dart index 3899ac83..bdd5bf79 100644 --- a/packages/three_js_core/lib/materials/projected_material.dart +++ b/packages/three_js_core/lib/materials/projected_material.dart @@ -128,7 +128,7 @@ class ProjectedMaterial extends MeshPhysicalMaterial { console.warning('You have to pass "transparent: true" to the ProjectedMaterial for the backgroundOpacity option to work'); } - type = "ProjectedMaterial"; + //type = "ProjectedMaterial"; //Object.defineProperty(this, 'isProjectedMaterial', { 'value': true }); diff --git a/packages/three_js_core/lib/renderers/capabilities.dart b/packages/three_js_core/lib/renderers/capabilities.dart new file mode 100644 index 00000000..1e5b555c --- /dev/null +++ b/packages/three_js_core/lib/renderers/capabilities.dart @@ -0,0 +1,34 @@ + + +abstract class Capabilities { + bool isWebGL2 = true; + + String precision = 'highp'; + String maxPrecision = "highp"; + + bool logarithmicDepthBuffer = false; + num? maxAnisotropy; + bool drawBuffers = true; + + late int maxTextures; + late int maxVertexTextures; + late int maxTextureSize; + late int maxCubemapSize; + late int maxAttributes; + late int maxVertexUniforms; + late int maxVaryings; + late int maxFragmentUniforms; + late bool reverseDepthBuffer; + + late bool vertexTextures; + late int maxSamples; + + num getMaxAnisotropy(); + + bool textureFormatReadable(int textureFormat ); + + bool textureTypeReadable(int textureType ); + String getMaxPrecision([String? precision]); + + void dispose(); +} diff --git a/packages/three_js_core/lib/renderers/cube_render_target.dart b/packages/three_js_core/lib/renderers/cube_render_target.dart index 4037c14b..55811e5f 100755 --- a/packages/three_js_core/lib/renderers/cube_render_target.dart +++ b/packages/three_js_core/lib/renderers/cube_render_target.dart @@ -1,7 +1,125 @@ import 'package:three_js_core/three_js_core.dart'; +import 'package:three_js_math/three_js_math.dart'; -abstract class CubeRenderTarget extends RenderTarget { - CubeRenderTarget([int size = 1, RenderTargetOptions? options]) : super(size, size, options); - CubeRenderTarget fromEquirectangularTexture(Renderer renderer, Texture texture); - void clear(Renderer renderer, [bool color = true, bool depth = true, bool stencil = true]); +class CubeRenderTarget extends RenderTarget { + CubeRenderTarget([int size = 1, RenderTargetOptions? options]) : super(size, size , options) { + // By convention -- likely based on the RenderMan spec from the 1990's -- cube maps are specified by WebGL (and three.js) + // in a coordinate system in which positive-x is to the right when looking up the positive-z axis -- in other words, + // in a left-handed coordinate system. By continuing this convention, preexisting cube maps continued to render correctly. + + // three.js uses a right-handed coordinate system. So environment maps used in three.js appear to have px and nx swapped + // and the flag isRenderTargetTexture controls this conversion. The flip is not required when using WebGLCubeRenderTarget.texture + // as a cube texture (this is detected when isRenderTargetTexture is set to true for cube textures). + final image = ImageElement(width: size, height: size, depth: 1); + final images = [image, image, image, image, image, image]; + + texture = CubeTexture( + images, + this.options.mapping, + this.options.wrapS, + this.options.wrapT, + this.options.magFilter, + this.options.minFilter, + this.options.format, + this.options.type, + this.options.anisotropy, + this.options.colorSpace + ); + texture.isRenderTargetTexture = true; + + texture.generateMipmaps = this.options.generateMipmaps; + texture.minFilter = this.options.minFilter ?? LinearFilter; + } + + CubeRenderTarget fromEquirectangularTexture(Renderer renderer, Texture texture) { + this.texture.type = texture.type; + this.texture.colorSpace = texture.colorSpace; + + this.texture.generateMipmaps = texture.generateMipmaps; + this.texture.minFilter = texture.minFilter; + this.texture.magFilter = texture.magFilter; + + final shader = { + "uniforms": { + "tEquirect": {'value': null}, + }, + "vertexShader": """ + + varying vec3 vWorldDirection; + + vec3 transformDirection( in vec3 dir, in mat4 matrix ) { + + return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz ); + + } + + void main() { + + vWorldDirection = transformDirection( position, modelMatrix ); + + #include + #include + + } + """, + "fragmentShader": """ + + uniform sampler2D tEquirect; + + varying vec3 vWorldDirection; + + #include + + void main() { + + vec3 direction = normalize( vWorldDirection ); + + vec2 sampleUV = equirectUv( direction ); + + gl_FragColor = texture2D( tEquirect, sampleUV ); + + } + """ + }; + + final geometry = BoxGeometry(5, 5, 5); + final material = ShaderMaterial.fromMap({ + "name": 'CubemapFromEquirect', + "uniforms": cloneUniforms(shader["uniforms"] as Map), + "vertexShader": shader["vertexShader"], + "fragmentShader": shader["fragmentShader"], + "side": BackSide, + "blending": NoBlending + }); + + material.uniforms["tEquirect"]["value"] = texture; + + final mesh = Mesh(geometry, material); + + final currentMinFilter = texture.minFilter; + + // Avoid blurred poles + if (texture.minFilter == LinearMipmapLinearFilter) { + texture.minFilter = LinearFilter; + } + + final camera = CubeCamera(1, 10, this); + camera.update(renderer, mesh); + + texture.minFilter = currentMinFilter; + + mesh.geometry!.dispose(); + mesh.material?.dispose(); + + return this; + } + + void clear(Renderer renderer, [bool color = true, bool depth = true, bool stencil = true]) { + final currentRenderTarget = renderer.getRenderTarget(); + for (int i = 0; i < 6; i++) { + renderer.setRenderTarget(this, i); + renderer.clear(color, depth, stencil); + } + renderer.setRenderTarget(currentRenderTarget); + } } \ No newline at end of file diff --git a/packages/three_js_core/lib/renderers/index.dart b/packages/three_js_core/lib/renderers/index.dart index d746515d..81f6a884 100644 --- a/packages/three_js_core/lib/renderers/index.dart +++ b/packages/three_js_core/lib/renderers/index.dart @@ -2,5 +2,11 @@ export 'renderer.dart'; export 'xr_manager.dart'; export 'render_target.dart'; export 'cube_render_target.dart'; -export 'uniforms_utils.dart'; +export 'shaders/uniforms_utils.dart'; +export 'shadow_map.dart'; +export 'state.dart'; +export 'capabilities.dart'; +export 'shaders/shader_lib.dart'; +export 'shaders/uniforms_lib.dart'; +export 'parameters.dart'; diff --git a/packages/three_js_angle_renderer/lib/angle/angle_parameters.dart b/packages/three_js_core/lib/renderers/parameters.dart old mode 100755 new mode 100644 similarity index 99% rename from packages/three_js_angle_renderer/lib/angle/angle_parameters.dart rename to packages/three_js_core/lib/renderers/parameters.dart index 50ce877a..7fb5cf6d --- a/packages/three_js_angle_renderer/lib/angle/angle_parameters.dart +++ b/packages/three_js_core/lib/renderers/parameters.dart @@ -1,6 +1,6 @@ -part of three_webgl; +import 'package:three_js_math/three_js_math.dart'; -class AngleParameters { +class Parameters{ int? customVertexShaderID; int? customFragmentShaderID; @@ -190,13 +190,13 @@ class AngleParameters { bool uvsVertexOnly = false; int outputEncoding = 0; - AngleParameters.create(); + Parameters.create(); void dispose(){ uniforms?.clear(); } - AngleParameters({ + Parameters({ this.shaderID, this.shaderType, this.shaderName = '', @@ -367,7 +367,7 @@ class AngleParameters { this.customProgramCacheKey, }); - AngleParameters.fromJson(Map json) { + Parameters.fromJson(Map json) { shaderID = json['shaderID']; shaderType = json['shaderType']; shaderName = json['shaderName'] ?? ''; diff --git a/packages/three_js_core/lib/renderers/render_target.dart b/packages/three_js_core/lib/renderers/render_target.dart index 9a9fae91..acc7cb26 100644 --- a/packages/three_js_core/lib/renderers/render_target.dart +++ b/packages/three_js_core/lib/renderers/render_target.dart @@ -1,9 +1,9 @@ import 'package:three_js_core/three_js_core.dart'; import 'package:three_js_math/three_js_math.dart'; -class RenderTarget with EventDispatcher { +class BaseRenderTarget with EventDispatcher { String? name; - + bool _didDispose = false; late int width; late int height; int depth = 1; @@ -52,7 +52,7 @@ class RenderTarget with EventDispatcher { DepthTexture? get depthTexture => _depthTexture; - RenderTarget([this.width = 1, this.height = 1, RenderTargetOptions? options]):super(){ + BaseRenderTarget([this.width = 1, this.height = 1, RenderTargetOptions? options]):super(){ scissor = Vector4(0, 0, width.toDouble(), height.toDouble()); scissorTest = false; @@ -102,11 +102,11 @@ class RenderTarget with EventDispatcher { multiview = this.options.multiview; } - RenderTarget clone() { - return RenderTarget()..copy( this ); + BaseRenderTarget clone() { + return BaseRenderTarget()..copy( this ); } - RenderTarget copy(RenderTarget source){ + BaseRenderTarget copy(BaseRenderTarget source){ height = source.height; width = source.width; depth = source.depth; @@ -173,6 +173,42 @@ class RenderTarget with EventDispatcher { } } +class RenderTarget extends BaseRenderTarget { + + RenderTarget(super.width, super.height, [super.options]); + + @override + RenderTarget clone() { + return RenderTarget(width, height, options)..copy(this); + } + + @override + RenderTarget copy(BaseRenderTarget source) { + super.copy(source); + return this; + } + + @override + bool is3D() { + return texture is Data3DTexture || texture is DataArrayTexture; + } + + @override + void dispose() { + if(_didDispose) return; + _didDispose = true; + dispatchEvent(Event(type: "dispose")); + depthTexture?.dispose(); + texture.dispose(); + options.dispose(); + + // textures.forEach((t){ + // t.dispose(); + // }); + // textures.clear(); + } +} + class RenderTargetOptions { int? wrapS; int? wrapT; diff --git a/packages/three_js_core/lib/renderers/renderer.dart b/packages/three_js_core/lib/renderers/renderer.dart index f10c33e7..79ec43d7 100644 --- a/packages/three_js_core/lib/renderers/renderer.dart +++ b/packages/three_js_core/lib/renderers/renderer.dart @@ -1,8 +1,6 @@ +import 'dart:typed_data'; +import 'package:three_js_core/three_js_core.dart'; import 'package:three_js_math/three_js_math.dart'; -import 'xr_manager.dart'; -import '../cameras/camera.dart'; -import '../core/object_3d.dart'; -import 'render_target.dart'; enum RenderType{after,before,custom} enum PowerPreference{high,defaultp,low; @@ -24,7 +22,17 @@ enum PowerPreference{high,defaultp,low; enum Precision{highp,mediump,lowp} abstract class Renderer { + bool autoClear = true; + bool autoClearColor = true; + bool autoClearDepth = true; + bool autoClearStencil = true; + bool sortObjects = true; + late XRManager xr; + late ShadowMap shadowMap; + late Capabilities capabilities; + late State state; + int toneMapping = NoToneMapping; double toneMappingExposure = 1.0; int get coordinateSystem => WebGLCoordinateSystem; @@ -32,13 +40,39 @@ abstract class Renderer { String _outputColorSpace = SRGBColorSpace; String get outputColorSpace => _outputColorSpace; set outputColorSpace(String colorSpace )=>setOutputColorSpace(colorSpace); + + double getTargetPixelRatio(); + Vector2 getSize(Vector2 target); + dynamic getContext(); + double getPixelRatio(); + + double getClearAlpha(); + void setClearAlpha(double alpha); + + void setViewport(double x, double y, double width, double height); + Vector4 getViewport(Vector4 target); + Vector4 getCurrentViewport(Vector4 target); void setOutputColorSpace(String colorSpace ) { _outputColorSpace = colorSpace; } void dispose(); void clear([bool color = true, bool depth = true, bool stencil = true]); + void clearColor() { + clear(true, false, false); + } + void clearDepth() { + clear(false, true, false); + } + void clearStencil() { + clear(false, false, true); + } + void setClearColor(Color color, [double alpha = 1.0]); + Color getClearColor(Color target); void render(Object3D scene, Camera camera); void setRenderTarget(RenderTarget? renderTarget, [int activeCubeFace = 0, int activeMipmapLevel = 0]); + void readRenderTargetPixels(RenderTarget renderTarget, int x, int y, int width, int height, TypedData buffer, [int? activeCubeFaceIndex]) ; + void copyFramebufferToTexture(Vector? position, Texture? texture, {int level = 0}); + void renderBufferDirect(Camera camera,Object3D? scene,BufferGeometry geometry,Material material,Object3D object,Map? group); RenderTarget? getRenderTarget(); } diff --git a/packages/three_js_angle_renderer/lib/shaders/shader_lib.dart b/packages/three_js_core/lib/renderers/shaders/shader_lib.dart similarity index 97% rename from packages/three_js_angle_renderer/lib/shaders/shader_lib.dart rename to packages/three_js_core/lib/renderers/shaders/shader_lib.dart index b773d79f..797d3445 100755 --- a/packages/three_js_angle_renderer/lib/shaders/shader_lib.dart +++ b/packages/three_js_core/lib/renderers/shaders/shader_lib.dart @@ -1,4 +1,10 @@ -part of three_shaders; +import 'uniforms_lib.dart'; +import 'uniforms_utils.dart'; +import 'package:three_js_math/three_js_math.dart'; + +Map shaderChunk = {}; +String lightsFragmentBegin = ''; +String lightsParsBegin = ''; Map shaderLibStandard = { "uniforms": mergeUniforms([ diff --git a/packages/three_js_webgl_renderer/lib/shaders/uniforms_lib.dart b/packages/three_js_core/lib/renderers/shaders/uniforms_lib.dart similarity index 99% rename from packages/three_js_webgl_renderer/lib/shaders/uniforms_lib.dart rename to packages/three_js_core/lib/renderers/shaders/uniforms_lib.dart index de5b8bf3..d1914d4d 100755 --- a/packages/three_js_webgl_renderer/lib/shaders/uniforms_lib.dart +++ b/packages/three_js_core/lib/renderers/shaders/uniforms_lib.dart @@ -1,4 +1,4 @@ -part of three_shaders; +import 'package:three_js_math/three_js_math.dart'; Map uniformsLib = { "common": { diff --git a/packages/three_js_core/lib/renderers/uniforms_utils.dart b/packages/three_js_core/lib/renderers/shaders/uniforms_utils.dart similarity index 95% rename from packages/three_js_core/lib/renderers/uniforms_utils.dart rename to packages/three_js_core/lib/renderers/shaders/uniforms_utils.dart index cc89d7c1..162c2694 100755 --- a/packages/three_js_core/lib/renderers/uniforms_utils.dart +++ b/packages/three_js_core/lib/renderers/shaders/uniforms_utils.dart @@ -43,8 +43,8 @@ Map cloneUniforms(Map src) { Map mergeUniforms(uniforms) { Map merged = {}; - for (int u = 0; u < uniforms.length; u++) { - final tmp = cloneUniforms(uniforms[u]); + for (final u in uniforms) { + final tmp = cloneUniforms(u); for (final p in tmp.keys) { merged[p] = tmp[p]; diff --git a/packages/three_js_core/lib/renderers/shadow_map.dart b/packages/three_js_core/lib/renderers/shadow_map.dart new file mode 100644 index 00000000..f86ff5fd --- /dev/null +++ b/packages/three_js_core/lib/renderers/shadow_map.dart @@ -0,0 +1,29 @@ +import 'package:three_js_core/three_js_core.dart'; +import 'package:three_js_math/three_js_math.dart'; + +abstract class ShadowMap { + final shadowSide = {0: BackSide, 1: FrontSide, 2: DoubleSide}; + + late ShaderMaterial shadowMaterialVertical; + late ShaderMaterial shadowMaterialHorizontal; + + BufferGeometry fullScreenTri = BufferGeometry(); + + late Mesh fullScreenMesh; + + bool enabled = false; + + bool autoUpdate = true; + bool needsUpdate = false; + + int type = PCFShadowMap; + late ShadowMap scope; + + void dispose(); + + void render(List lights, Object3D scene, Camera camera); + void vSMPass(LightShadow shadow, Camera camera); + + Material getDepthMaterial(Object3D object, Material material, Light light, double shadowCameraNear, double shadowCameraFar, int type); + void renderObject(Object3D object, Camera camera, Camera shadowCamera, Light light, int type); +} diff --git a/packages/three_js_core/lib/renderers/state.dart b/packages/three_js_core/lib/renderers/state.dart new file mode 100644 index 00000000..5b9e7961 --- /dev/null +++ b/packages/three_js_core/lib/renderers/state.dart @@ -0,0 +1,17 @@ +import 'package:three_js_math/three_js_math.dart'; + +abstract class State { + Map get buffers; + + void enable(id); + void disable(id); + + void scissor(Vector4 scissor) ; + void viewport(Vector4 viewport); + + void setBlending(int blending); + void setScissorTest(bool scissorTest); + + void reset(); + void dispose(); +} diff --git a/packages/three_js_core/lib/textures/texture.dart b/packages/three_js_core/lib/textures/texture.dart index fa1cba7d..52a86510 100755 --- a/packages/three_js_core/lib/textures/texture.dart +++ b/packages/three_js_core/lib/textures/texture.dart @@ -33,7 +33,7 @@ class Texture with EventDispatcher { bool isOpenGLTexture = false; bool isRenderTargetTexture = false; // indicates whether a texture belongs to a render target or not // bool needsPMREMUpdate = false; // indicates whether this texture should be processed by PMREMGenerator or not (only relevant for render target textures) - RenderTarget? renderTarget; + BaseRenderTarget? renderTarget; int pmremVersion = 0; diff --git a/packages/three_js_helpers/lib/light_probe_helper.dart b/packages/three_js_helpers/lib/light_probe_helper.dart index 9707ed37..e30b4113 100644 --- a/packages/three_js_helpers/lib/light_probe_helper.dart +++ b/packages/three_js_helpers/lib/light_probe_helper.dart @@ -90,7 +90,7 @@ class LightProbeHelper extends Mesh { @override OnRender get onBeforeRender => ({ - WebGLRenderer? renderer, + Renderer? renderer, RenderTarget? renderTarget, Object3D? mesh, Scene? scene, diff --git a/packages/three_js_helpers/lib/view_helper.dart b/packages/three_js_helpers/lib/view_helper.dart index f1be8153..b22aa399 100644 --- a/packages/three_js_helpers/lib/view_helper.dart +++ b/packages/three_js_helpers/lib/view_helper.dart @@ -159,7 +159,7 @@ class ViewHelper extends Object3D { _scissorPos.y = _viewport.w/2-screenSize.height+oy; } } - void render(WebGLRenderer renderer) { + void render(Renderer renderer) { quaternion.setFrom( camera.quaternion ).invert(); updateMatrixWorld(); diff --git a/packages/three_js_helpers/lib/view_helper2.dart b/packages/three_js_helpers/lib/view_helper2.dart index 10d061f8..68a85e6f 100644 --- a/packages/three_js_helpers/lib/view_helper2.dart +++ b/packages/three_js_helpers/lib/view_helper2.dart @@ -253,7 +253,7 @@ class ViewHelper2 extends Object3D{ //_pointerPos!.x += -4*(_pointerPos!.x/(size.width-(_offset.x+screenSize.width)))+2; _pointerPos!.y += 4*(_pointerPos!.y/(size.height-screenSize.height-_offset.y))+3; } - void render(WebGLRenderer renderer){ + void render(Renderer renderer){ quaternion.setFrom( camera.quaternion ).invert(); updateMatrixWorld(); diff --git a/packages/three_js_line/lib/line_material.dart b/packages/three_js_line/lib/line_material.dart index dde684d3..73064b1e 100644 --- a/packages/three_js_line/lib/line_material.dart +++ b/packages/three_js_line/lib/line_material.dart @@ -1,5 +1,4 @@ import 'dart:typed_data'; - import 'package:three_js_core/three_js_core.dart'; import 'package:three_js_math/three_js_math.dart'; diff --git a/packages/three_js_objects/lib/csm/csm.dart b/packages/three_js_objects/lib/csm/csm.dart index b691c3df..c0f0656e 100644 --- a/packages/three_js_objects/lib/csm/csm.dart +++ b/packages/three_js_objects/lib/csm/csm.dart @@ -1,5 +1,3 @@ -import 'package:three_js_core/renderers/shaders/shader_chunk/index.dart'; -import 'package:three_js_core/renderers/webgl/index.dart'; import 'package:three_js_core/three_js_core.dart'; import 'package:three_js_math/three_js_math.dart'; import 'package:three_js_objects/csm/csm_shaders.dart'; @@ -246,7 +244,6 @@ class CSM{ final shaders = this.shaders; material.onBeforeCompile = ( shader,target ) { - shader as WebGLParameters; final far = math.min( scope.camera.far, scope.maxFar ); getExtendedBreaks( breaksVec2 ); @@ -265,7 +262,6 @@ class CSM{ final shaders = this.shaders; shaders.forEach((material,shader ) { - shader as WebGLParameters?; material as Material; if ( shader != null ) { final uniforms = shader.uniforms; @@ -318,7 +314,6 @@ class CSM{ void dispose() { final shaders = this.shaders; shaders.forEach((material,shader ) { - shader as WebGLParameters?; material as Material; //material.onBeforeCompile; material.defines?.remove('USE_CSM'); diff --git a/packages/three_js_objects/lib/csm/csm_shaders.dart b/packages/three_js_objects/lib/csm/csm_shaders.dart index da487cd5..7888f564 100644 --- a/packages/three_js_objects/lib/csm/csm_shaders.dart +++ b/packages/three_js_objects/lib/csm/csm_shaders.dart @@ -1,4 +1,4 @@ -import 'package:three_js_core/renderers/shaders/shader_chunk/index.dart'; +import 'package:three_js_core/renderers/shaders/shader_lib.dart'; final csmShader = { 'lights_fragment_begin': /* glsl */''' diff --git a/packages/three_js_objects/lib/gpu_computation_renderer.dart b/packages/three_js_objects/lib/gpu_computation_renderer.dart index 23a17cd9..35a858f4 100644 --- a/packages/three_js_objects/lib/gpu_computation_renderer.dart +++ b/packages/three_js_objects/lib/gpu_computation_renderer.dart @@ -114,13 +114,13 @@ class GPUComputationRenderer { late void Function(Material,RenderTarget) doRenderTarget; late void Function(Texture,RenderTarget) renderTexture; late DataTexture Function() createTexture; - late WebGLRenderTarget Function(dynamic,dynamic,dynamic,dynamic,dynamic,dynamic) createRenderTarget; + late RenderTarget Function(dynamic,dynamic,dynamic,dynamic,dynamic,dynamic) createRenderTarget; late void Function(Map,dynamic) setVariableDependencies; - late WebGLRenderTarget Function(Map) getCurrentRenderTarget; - late WebGLRenderTarget Function(Map) getAlternateRenderTarget; + late RenderTarget Function(Map) getCurrentRenderTarget; + late RenderTarget Function(Map) getAlternateRenderTarget; late void Function(dynamic) addResolutionDefine; - GPUComputationRenderer(int sizeX, int sizeY, WebGLRenderer renderer ) { + GPUComputationRenderer(int sizeX, int sizeY, Renderer renderer ) { int dataType = FloatType; camera.position.z = 1; @@ -314,7 +314,7 @@ class GPUComputationRenderer { minFilter = minFilter ?? NearestFilter; magFilter = magFilter ?? NearestFilter; - final renderTarget = WebGLRenderTarget( sizeXTexture, sizeYTexture, WebGLRenderTargetOptions({ + final renderTarget = RenderTarget( sizeXTexture, sizeYTexture, RenderTargetOptions({ 'wrapS': wrapS, 'wrapT': wrapT, 'minFilter': minFilter, diff --git a/packages/three_js_objects/lib/lens_flare.dart b/packages/three_js_objects/lib/lens_flare.dart index 1797d11e..8ffb1668 100644 --- a/packages/three_js_objects/lib/lens_flare.dart +++ b/packages/three_js_objects/lib/lens_flare.dart @@ -146,7 +146,7 @@ class Lensflare extends Mesh { final viewport = Vector4(); onBeforeRender = ({ - WebGLRenderer? renderer, + Renderer? renderer, RenderTarget? renderTarget, Object3D? mesh, Scene? scene, diff --git a/packages/three_js_objects/lib/lights/light_probe_generator_platform.dart b/packages/three_js_objects/lib/lights/light_probe_generator_platform.dart index 2133f323..26b19fdd 100644 --- a/packages/three_js_objects/lib/lights/light_probe_generator_platform.dart +++ b/packages/three_js_objects/lib/lights/light_probe_generator_platform.dart @@ -79,7 +79,7 @@ class LightProbeGenerator { return LightProbe( sh ); } - static LightProbe fromCubeRenderTarget(WebGLRenderer renderer,WebGLCubeRenderTarget cubeRenderTarget ) { + static LightProbe fromCubeRenderTarget(Renderer renderer, CubeRenderTarget cubeRenderTarget ) { // The renderTarget must be set to RGBA in order to make readRenderTargetPixels works double totalWeight = 0; final coord = Vector3(); diff --git a/packages/three_js_objects/lib/lights/light_probe_generator_web.dart b/packages/three_js_objects/lib/lights/light_probe_generator_web.dart index ee15403f..947e38cc 100644 --- a/packages/three_js_objects/lib/lights/light_probe_generator_web.dart +++ b/packages/three_js_objects/lib/lights/light_probe_generator_web.dart @@ -94,7 +94,7 @@ class LightProbeGenerator { return LightProbe( sh ); } - static LightProbe fromCubeRenderTarget(WebGLRenderer renderer,WebGLCubeRenderTarget cubeRenderTarget ) { + static LightProbe fromCubeRenderTarget(Renderer renderer, CubeRenderTarget cubeRenderTarget ) { // The renderTarget must be set to RGBA in order to make readRenderTargetPixels works double totalWeight = 0; final coord = Vector3(); diff --git a/packages/three_js_objects/lib/planet_generator/atmosphere.dart b/packages/three_js_objects/lib/planet_generator/atmosphere.dart index f3e78685..dc948468 100644 --- a/packages/three_js_objects/lib/planet_generator/atmosphere.dart +++ b/packages/three_js_objects/lib/planet_generator/atmosphere.dart @@ -1,3 +1,5 @@ +import 'dart:typed_data'; + import 'package:three_js_core/three_js_core.dart'; import 'package:three_js_math/three_js_math.dart'; import './shaders/index.dart'; @@ -104,7 +106,7 @@ class AtmosphereParameters{ class Atmosphere extends Points { final AtmosphereParameters atmosphereParams; - Atmosphere(this.atmosphereParams, [Texture? cloudTexture]):super(null,null){ + Atmosphere(this.atmosphereParams, [Texture? cloudTexture]):super(){ this.material = ShaderMaterial.fromMap({ 'uniforms': { 'time': { 'value': 0.0 }, @@ -121,7 +123,9 @@ class Atmosphere extends Points { 'depthWrite': false, 'transparent': true }); - + material?.polygonOffset = true; + material?.polygonOffsetFactor = -1.0; + material?.polygonOffsetUnits = -4.0; update(); } @@ -133,9 +137,7 @@ class Atmosphere extends Points { final geometry = BufferGeometry(); - final verts = []; - final uvs = []; - final sizes = []; + final Float32List combinedData = Float32List(atmosphereParams.particles * 6); // Sample points within the atmosphere for(int i = 0; i < atmosphereParams.particles; i++) { @@ -158,15 +160,18 @@ class Atmosphere extends Points { final maxSize = atmosphereParams.maxParticleSize; final size = math.Random().nextDouble() * (maxSize - minSize) + minSize; - verts.addAll([p.x, p.y, p.z]); - uvs.addAll([0.5, 0.5]); - sizes.add(size); + combinedData.setAll(i * 6, [p.x, p.y, p.z, 0.5, 0.5, size]); } - geometry.setAttributeFromString('position', Float32BufferAttribute.fromList(verts, 3)); - geometry.setAttributeFromString('uv', Float32BufferAttribute.fromList(uvs, 2)); - geometry.setAttributeFromString('size', Float32BufferAttribute.fromList(sizes, 1)); + final interleavedBuffer = InterleavedBuffer(combinedData, 6); + + geometry.setAttributeFromString('position', InterleavedBufferAttribute(interleavedBuffer, 3, 0)); + geometry.setAttributeFromString('uv', InterleavedBufferAttribute(interleavedBuffer, 2, 3)); + geometry.setAttributeFromString('size', InterleavedBufferAttribute(interleavedBuffer, 1, 5)); this.geometry = geometry; + + geometry.computeBoundingSphere(); + geometry.computeBoundingBox(); } } \ No newline at end of file diff --git a/packages/three_js_objects/lib/planet_generator/planet_generator.dart b/packages/three_js_objects/lib/planet_generator/planet_generator.dart index 3603ee68..b620e3dc 100644 --- a/packages/three_js_objects/lib/planet_generator/planet_generator.dart +++ b/packages/three_js_objects/lib/planet_generator/planet_generator.dart @@ -69,7 +69,7 @@ class PlanetGeneratorParameters{ this.period = 0.6, this.persistence = 0.484, this.lacunarity = 1.8, - this.octaves = 10, + this.octaves = 8, this.undulation = 0, this.ambientIntensity = 0.02, this.diffuseIntensity = 1, @@ -321,9 +321,15 @@ class PlanetGenerator extends Mesh{ this.geometry?.computeTangents(); atmosphere = Atmosphere(atmosphereParams, cloudTexture); + atmosphere.renderOrder = 1; this.add(atmosphere); type = "Mesh"; updateMorphTargets(); + + geometry?.computeBoundingSphere(); + geometry?.computeBoundingBox(); + + this.renderOrder = 0; } } \ No newline at end of file diff --git a/packages/three_js_objects/lib/water/reflector.dart b/packages/three_js_objects/lib/water/reflector.dart index bb8f2cf0..bfd13b18 100644 --- a/packages/three_js_objects/lib/water/reflector.dart +++ b/packages/three_js_objects/lib/water/reflector.dart @@ -5,7 +5,7 @@ class Reflector extends Mesh { final bool isReflector = true; bool forceUpdate = false; RenderType renderType = RenderType.after; - late WebGLRenderTarget renderTarget; + late RenderTarget renderTarget; PerspectiveCamera camera = PerspectiveCamera(); Reflector(super.geometry, [Map? options] ) { @@ -36,7 +36,7 @@ class Reflector extends Mesh { final textureMatrix = Matrix4.identity(); final PerspectiveCamera virtualCamera = camera; - renderTarget = WebGLRenderTarget( textureWidth, textureHeight, WebGLRenderTargetOptions({'samples': multisample, 'type': HalfFloatType })); + renderTarget = RenderTarget(textureWidth, textureHeight, RenderTargetOptions({'samples': multisample, 'type': HalfFloatType })); final material = ShaderMaterial.fromMap( { 'name': shader['name'] ?? 'unspecified', @@ -51,7 +51,7 @@ class Reflector extends Mesh { this.material = material; - void render(WebGLRenderer? renderer, Object3D? scene, Camera camera){ + void render(Renderer? renderer, Object3D? scene, Camera camera){ reflectorWorldPosition.setFromMatrixPosition( scope.matrixWorld ); cameraWorldPosition.setFromMatrixPosition( camera.matrixWorld ); @@ -158,24 +158,24 @@ class Reflector extends Mesh { forceUpdate = false; }; - onAfterRender = ({Camera? camera, BufferGeometry? geometry, Map? group, Material? material, Object3D? mesh, RenderTarget? renderTarget, WebGLRenderer? renderer, Scene? scene}){ + onAfterRender = ({Camera? camera, BufferGeometry? geometry, Map? group, Material? material, Object3D? mesh, RenderTarget? renderTarget, Renderer? renderer, Scene? scene}){ if(renderType == RenderType.after){ render(renderer,scene,camera!); } }; - onBeforeRender = ({Camera? camera, BufferGeometry? geometry, Map? group, Material? material, Object3D? mesh, RenderTarget? renderTarget, WebGLRenderer? renderer, Scene? scene}){ + onBeforeRender = ({Camera? camera, BufferGeometry? geometry, Map? group, Material? material, Object3D? mesh, RenderTarget? renderTarget, Renderer? renderer, Scene? scene}){ if(renderType == RenderType.before){ render(renderer,scene,camera!); } }; - customRender = ({Camera? camera, BufferGeometry? geometry, Map? group, Material? material, Object3D? mesh, RenderTarget? renderTarget, WebGLRenderer? renderer, Scene? scene}){ + customRender = ({Camera? camera, BufferGeometry? geometry, Map? group, Material? material, Object3D? mesh, RenderTarget? renderTarget, Renderer? renderer, Scene? scene}){ if(renderType == RenderType.custom){ render(renderer,scene,camera!); } }; } - WebGLRenderTarget getRenderTarget() { + RenderTarget getRenderTarget() { return renderTarget; } diff --git a/packages/three_js_objects/lib/water/refractor.dart b/packages/three_js_objects/lib/water/refractor.dart index 1f0b4b17..1fdf1919 100644 --- a/packages/three_js_objects/lib/water/refractor.dart +++ b/packages/three_js_objects/lib/water/refractor.dart @@ -5,7 +5,7 @@ import 'reflector.dart'; class Refractor extends Mesh { final bool isRefractor = true; RenderType renderType = RenderType.after; - late WebGLRenderTarget renderTarget; + late RenderTarget renderTarget; PerspectiveCamera camera = PerspectiveCamera(); Refractor(super.geometry, [Map? options] ) { @@ -31,7 +31,7 @@ class Refractor extends Mesh { // render target - renderTarget = WebGLRenderTarget( textureWidth, textureHeight, WebGLRenderTargetOptions({'samples': multisample, 'type': HalfFloatType})); + renderTarget = RenderTarget( textureWidth, textureHeight, RenderTargetOptions({'samples': multisample, 'type': HalfFloatType})); // material @@ -153,7 +153,7 @@ class Refractor extends Mesh { // - void _render(WebGLRenderer renderer, Object3D scene, Camera camera ) { + void _render(Renderer renderer, Object3D scene, Camera camera ) { scope.visible = false; final currentRenderTarget = renderer.getRenderTarget(); @@ -182,7 +182,7 @@ class Refractor extends Mesh { scope.visible = true; } - void render(WebGLRenderer? renderer, Object3D? scene, Camera camera){ + void render(Renderer? renderer, Object3D? scene, Camera camera){ if ( camera.userData['refractor'] == true ) return; // avoid rendering when the refractor is viewed from behind if ( !visible( camera ) == true ) return; @@ -193,24 +193,24 @@ class Refractor extends Mesh { _render( renderer!, scene!, camera ); }; - onAfterRender = ({Camera? camera, BufferGeometry? geometry, Map? group, Material? material, Object3D? mesh, RenderTarget? renderTarget, WebGLRenderer? renderer, Scene? scene}){ + onAfterRender = ({Camera? camera, BufferGeometry? geometry, Map? group, Material? material, Object3D? mesh, RenderTarget? renderTarget, Renderer? renderer, Scene? scene}){ if(renderType == RenderType.after){ render(renderer,scene,camera!); } }; - onBeforeRender = ({Camera? camera, BufferGeometry? geometry, Map? group, Material? material, Object3D? mesh, RenderTarget? renderTarget, WebGLRenderer? renderer, Scene? scene}){ + onBeforeRender = ({Camera? camera, BufferGeometry? geometry, Map? group, Material? material, Object3D? mesh, RenderTarget? renderTarget, Renderer? renderer, Scene? scene}){ if(renderType == RenderType.before){ render(renderer,scene,camera!); } }; - customRender = ({Camera? camera, BufferGeometry? geometry, Map? group, Material? material, Object3D? mesh, RenderTarget? renderTarget, WebGLRenderer? renderer, Scene? scene}){ + customRender = ({Camera? camera, BufferGeometry? geometry, Map? group, Material? material, Object3D? mesh, RenderTarget? renderTarget, Renderer? renderer, Scene? scene}){ if(renderType == RenderType.custom){ render(renderer,scene,camera!); } }; } - WebGLRenderTarget getRenderTarget() { + RenderTarget getRenderTarget() { return renderTarget; } diff --git a/packages/three_js_objects/lib/water/water2.dart b/packages/three_js_objects/lib/water/water2.dart index 846e1ef7..199c5397 100644 --- a/packages/three_js_objects/lib/water/water2.dart +++ b/packages/three_js_objects/lib/water/water2.dart @@ -182,7 +182,7 @@ class Water extends Mesh { material?.uniforms[ 'config' ]['value'].z = halfCycle; // halfCycle material?.uniforms[ 'config' ]['value'].w = scale*1.0; // scale - onAfterRender = ({Camera? camera, BufferGeometry? geometry, Map? group, Material? material, Object3D? mesh, RenderTarget? renderTarget, WebGLRenderer? renderer, Scene? scene}){ + onAfterRender = ({Camera? camera, BufferGeometry? geometry, Map? group, Material? material, Object3D? mesh, RenderTarget? renderTarget, Renderer? renderer, Scene? scene}){ updateTextureMatrix( camera! ); updateFlow(); diff --git a/packages/three_js_postprocessing/lib/post/afterimage_pass.dart b/packages/three_js_postprocessing/lib/post/afterimage_pass.dart index c708cc83..f9f37c6c 100644 --- a/packages/three_js_postprocessing/lib/post/afterimage_pass.dart +++ b/packages/three_js_postprocessing/lib/post/afterimage_pass.dart @@ -6,8 +6,8 @@ import "pass.dart"; class AfterimagePass extends Pass { late Map shader; late ShaderMaterial shaderMaterial; - late WebGLRenderTarget textureComp; - late WebGLRenderTarget textureOld; + late RenderTarget textureComp; + late RenderTarget textureOld; late FullScreenQuad compFsQuad; late FullScreenQuad copyFsQuad; @@ -18,19 +18,19 @@ class AfterimagePass extends Pass { uniforms['damp']["value"] = damp != null ? damp : 0.96; - textureComp = WebGLRenderTarget( + textureComp = RenderTarget( bufferSizeMap["width"], bufferSizeMap["height"], - WebGLRenderTargetOptions({ + RenderTargetOptions({ "minFilter": LinearFilter, "magFilter": NearestFilter, "format": RGBAFormat })); - textureOld = WebGLRenderTarget( + textureOld = RenderTarget( bufferSizeMap["width"], bufferSizeMap["height"], - WebGLRenderTargetOptions({ + RenderTargetOptions({ "minFilter": LinearFilter, "magFilter": NearestFilter, "format": RGBAFormat @@ -48,7 +48,7 @@ class AfterimagePass extends Pass { copyFsQuad = FullScreenQuad(material); } - void render(WebGLRenderer renderer, WebGLRenderTarget writeBuffer, WebGLRenderTarget readBuffer,{double? deltaTime, bool? maskActive}) { + void render(Renderer renderer, RenderTarget writeBuffer, RenderTarget readBuffer,{double? deltaTime, bool? maskActive}) { uniforms['tOld']["value"] = textureOld.texture; uniforms['tNew']["value"] = readBuffer.texture; diff --git a/packages/three_js_postprocessing/lib/post/bloom_pass.dart b/packages/three_js_postprocessing/lib/post/bloom_pass.dart index efceff7e..457e7629 100644 --- a/packages/three_js_postprocessing/lib/post/bloom_pass.dart +++ b/packages/three_js_postprocessing/lib/post/bloom_pass.dart @@ -4,8 +4,8 @@ import 'package:three_js_postprocessing/shaders/convolution_shader.dart'; import "pass.dart"; class BloomPass extends Pass { - late WebGLRenderTarget renderTargetX; - late WebGLRenderTarget renderTargetY; + late RenderTarget renderTargetX; + late RenderTarget renderTargetY; late ShaderMaterial materialCopy; late Map convolutionUniforms; late ShaderMaterial materialConvolution; @@ -25,9 +25,9 @@ class BloomPass extends Pass { 'type': HalfFloatType }; - renderTargetX = WebGLRenderTarget(resolution, resolution, WebGLRenderTargetOptions(pars)); + renderTargetX = RenderTarget(resolution, resolution, RenderTargetOptions(pars)); renderTargetX.texture.name = 'BloomPass.x'; - renderTargetY = WebGLRenderTarget(resolution, resolution, WebGLRenderTargetOptions(pars)); + renderTargetY = RenderTarget(resolution, resolution, RenderTargetOptions(pars)); renderTargetY.texture.name = 'BloomPass.y'; uniforms = UniformsUtils.clone(CombineShader["uniforms"]); @@ -65,7 +65,7 @@ class BloomPass extends Pass { } @override - void render(WebGLRenderer renderer, WebGLRenderTarget writeBuffer, WebGLRenderTarget readBuffer,{double? deltaTime, bool? maskActive}) { + void render(Renderer renderer, RenderTarget writeBuffer, RenderTarget readBuffer,{double? deltaTime, bool? maskActive}) { if (maskActive == true) renderer.state.buffers['stencil'].setTest(false); // Render quad with blured scene into texture (convolution pass 1) diff --git a/packages/three_js_postprocessing/lib/post/dot_screen_pass.dart b/packages/three_js_postprocessing/lib/post/dot_screen_pass.dart index 5f71d6bf..ce5636ed 100644 --- a/packages/three_js_postprocessing/lib/post/dot_screen_pass.dart +++ b/packages/three_js_postprocessing/lib/post/dot_screen_pass.dart @@ -23,7 +23,7 @@ class DotScreenPass extends Pass { } @override - void render(WebGLRenderer renderer, WebGLRenderTarget writeBuffer, WebGLRenderTarget readBuffer,{double? deltaTime, bool? maskActive}) { + void render(Renderer renderer, RenderTarget writeBuffer, RenderTarget readBuffer,{double? deltaTime, bool? maskActive}) { uniforms['tDiffuse']["value"] = readBuffer.texture; uniforms['tSize']["value"].set(readBuffer.width, readBuffer.height); diff --git a/packages/three_js_postprocessing/lib/post/effect_composer.dart b/packages/three_js_postprocessing/lib/post/effect_composer.dart index fc65931a..93598d06 100644 --- a/packages/three_js_postprocessing/lib/post/effect_composer.dart +++ b/packages/three_js_postprocessing/lib/post/effect_composer.dart @@ -5,12 +5,12 @@ import 'package:three_js_postprocessing/post/index.dart'; import 'package:three_js_postprocessing/shaders/copy_shader.dart'; class EffectComposer { - late WebGLRenderer renderer; - late WebGLRenderTarget renderTarget1; - late WebGLRenderTarget renderTarget2; + late Renderer renderer; + late RenderTarget renderTarget1; + late RenderTarget renderTarget2; - late WebGLRenderTarget writeBuffer; - late WebGLRenderTarget readBuffer; + late RenderTarget writeBuffer; + late RenderTarget readBuffer; final dynamic texture; bool renderToScreen = true; @@ -25,7 +25,7 @@ class EffectComposer { late Pass copyPass; - EffectComposer(this.renderer, [WebGLRenderTarget? renderTarget, this.texture]) { + EffectComposer(this.renderer, [RenderTarget? renderTarget, this.texture]) { _pixelRatio = renderer.getPixelRatio(); if (renderTarget == null) { @@ -38,10 +38,10 @@ class EffectComposer { _width = size.width; _height = size.height; - renderTarget = WebGLRenderTarget( + renderTarget = RenderTarget( (_width * _pixelRatio).toInt(), (_height * _pixelRatio).toInt(), - WebGLRenderTargetOptions(parameters) + RenderTargetOptions(parameters) ); renderTarget.texture.name = 'EffectComposer.rt1'; @@ -156,7 +156,7 @@ class EffectComposer { renderer.setRenderTarget(currentRenderTarget); } - void reset([WebGLRenderTarget? renderTarget]) { + void reset([RenderTarget? renderTarget]) { if (renderTarget == null) { final size = renderer.getSize(Vector2()); _pixelRatio = renderer.getPixelRatio(); diff --git a/packages/three_js_postprocessing/lib/post/film_pass.dart b/packages/three_js_postprocessing/lib/post/film_pass.dart index ae3d13ea..8224b3bb 100644 --- a/packages/three_js_postprocessing/lib/post/film_pass.dart +++ b/packages/three_js_postprocessing/lib/post/film_pass.dart @@ -30,7 +30,7 @@ class FilmPass extends Pass { } @override - void render(WebGLRenderer renderer, WebGLRenderTarget writeBuffer, WebGLRenderTarget readBuffer,{double? deltaTime, bool? maskActive}) { + void render(Renderer renderer, RenderTarget writeBuffer, RenderTarget readBuffer,{double? deltaTime, bool? maskActive}) { uniforms['tDiffuse']["value"] = readBuffer.texture; uniforms['time']["value"] += deltaTime; diff --git a/packages/three_js_postprocessing/lib/post/glitch_pass.dart b/packages/three_js_postprocessing/lib/post/glitch_pass.dart index 3e9d4714..44d8590c 100644 --- a/packages/three_js_postprocessing/lib/post/glitch_pass.dart +++ b/packages/three_js_postprocessing/lib/post/glitch_pass.dart @@ -36,7 +36,7 @@ class GlitchPass extends Pass { return low + (math.Random().nextDouble() * (high - low + 1)).floor(); } @override - void render(renderer, writeBuffer, readBuffer,{double? deltaTime, bool? maskActive}) { + void render(Renderer renderer, RenderTarget writeBuffer, RenderTarget readBuffer,{double? deltaTime, bool? maskActive}) { uniforms['tDiffuse']["value"] = readBuffer.texture; uniforms['seed']["value"] = math.Random().nextDouble(); //default seeding uniforms['byp']["value"] = 0; diff --git a/packages/three_js_postprocessing/lib/post/mask_pass.dart b/packages/three_js_postprocessing/lib/post/mask_pass.dart index f6f5ad58..4d473009 100644 --- a/packages/three_js_postprocessing/lib/post/mask_pass.dart +++ b/packages/three_js_postprocessing/lib/post/mask_pass.dart @@ -13,7 +13,7 @@ class MaskPass extends Pass { } @override - void render(WebGLRenderer renderer, WebGLRenderTarget writeBuffer, WebGLRenderTarget readBuffer,{double? deltaTime, bool? maskActive}) { + void render(Renderer renderer, RenderTarget writeBuffer, RenderTarget readBuffer,{double? deltaTime, bool? maskActive}) { final context = renderer.getContext(); final state = renderer.state; @@ -75,7 +75,7 @@ class ClearMaskPass extends Pass { needsSwap = false; } @override - void render(WebGLRenderer renderer, writeBuffer, readBuffer,{double? deltaTime, bool? maskActive}) { + void render(Renderer renderer, RenderTarget writeBuffer, RenderTarget readBuffer,{double? deltaTime, bool? maskActive}) { renderer.state.buffers["stencil"].setLocked(false); renderer.state.buffers["stencil"].setTest(false); } diff --git a/packages/three_js_postprocessing/lib/post/outpass.dart b/packages/three_js_postprocessing/lib/post/outpass.dart index fd075320..cfb1e275 100644 --- a/packages/three_js_postprocessing/lib/post/outpass.dart +++ b/packages/three_js_postprocessing/lib/post/outpass.dart @@ -68,7 +68,7 @@ class OutputPass extends Pass { } @override - void render(WebGLRenderer renderer, WebGLRenderTarget writeBuffer, WebGLRenderTarget readBuffer, {double? deltaTime, bool? maskActive}) { + void render(Renderer renderer, RenderTarget writeBuffer, RenderTarget readBuffer, {double? deltaTime, bool? maskActive}) { uniforms['tDiffuse']['value'] = readBuffer.texture; uniforms['toneMappingExposure']['value'] = renderer.toneMappingExposure; diff --git a/packages/three_js_postprocessing/lib/post/pass.dart b/packages/three_js_postprocessing/lib/post/pass.dart index 424a172b..98b630ce 100644 --- a/packages/three_js_postprocessing/lib/post/pass.dart +++ b/packages/three_js_postprocessing/lib/post/pass.dart @@ -23,7 +23,7 @@ class Pass { void setSize(int width, int height){} - void render(WebGLRenderer renderer, WebGLRenderTarget writeBuffer, WebGLRenderTarget readBuffer,{double? deltaTime, bool? maskActive}) { + void render(Renderer renderer, RenderTarget writeBuffer, RenderTarget readBuffer,{double? deltaTime, bool? maskActive}) { throw ('Pass: .render() must be implemented in derived pass.'); } @@ -49,7 +49,7 @@ class FullScreenQuad { _mesh.material = value; } - void render(WebGLRenderer renderer) { + void render(Renderer renderer) { renderer.render(_mesh, camera); } diff --git a/packages/three_js_postprocessing/lib/post/render_pass.dart b/packages/three_js_postprocessing/lib/post/render_pass.dart index 62f466a1..bcc21a3e 100644 --- a/packages/three_js_postprocessing/lib/post/render_pass.dart +++ b/packages/three_js_postprocessing/lib/post/render_pass.dart @@ -20,7 +20,7 @@ class RenderPass extends Pass { } @override - void render(WebGLRenderer renderer, WebGLRenderTarget writeBuffer, WebGLRenderTarget readBuffer, {double? deltaTime, bool? maskActive}) { + void render(Renderer renderer, RenderTarget writeBuffer, RenderTarget readBuffer, {double? deltaTime, bool? maskActive}) { final oldAutoClear = renderer.autoClear; renderer.autoClear = false; diff --git a/packages/three_js_postprocessing/lib/post/shader_pass.dart b/packages/three_js_postprocessing/lib/post/shader_pass.dart index 287f68f6..d3168f5c 100644 --- a/packages/three_js_postprocessing/lib/post/shader_pass.dart +++ b/packages/three_js_postprocessing/lib/post/shader_pass.dart @@ -46,7 +46,7 @@ class ShaderPass extends Pass { } @override - void render(WebGLRenderer renderer, WebGLRenderTarget writeBuffer, WebGLRenderTarget readBuffer, {double? deltaTime, bool? maskActive}) { + void render(Renderer renderer, RenderTarget writeBuffer, RenderTarget readBuffer, {double? deltaTime, bool? maskActive}) { if (uniforms[textureID] != null) { uniforms[textureID]["value"] = readBuffer.texture; } diff --git a/packages/three_js_postprocessing/lib/post/shader_passes.dart b/packages/three_js_postprocessing/lib/post/shader_passes.dart index 2a8a49fa..439cf7e4 100644 --- a/packages/three_js_postprocessing/lib/post/shader_passes.dart +++ b/packages/three_js_postprocessing/lib/post/shader_passes.dart @@ -10,7 +10,7 @@ class ShaderPasses extends Pass { late bool oldAutoClear; late Color clearColor; List? passes; - late Map renderTargetsPass; + late Map renderTargetsPass; late int resx; late int resy; @@ -38,7 +38,7 @@ class ShaderPasses extends Pass { } @override - void render(WebGLRenderer renderer, WebGLRenderTarget writeBuffer, WebGLRenderTarget readBuffer,{double? deltaTime, bool? maskActive}) { + void render(Renderer renderer, RenderTarget writeBuffer, RenderTarget readBuffer,{double? deltaTime, bool? maskActive}) { renderer.getClearColor(oldClearColor); oldClearAlpha = renderer.getClearAlpha(); oldAutoClear = renderer.autoClear; @@ -54,7 +54,7 @@ class ShaderPasses extends Pass { if (passes != null) { int lastPass = passes!.length - 1; - WebGLRenderTarget? lastRenderTarget; + RenderTarget? lastRenderTarget; for (int i = 0; i < passes!.length; i++) { material.uniforms["acPass"] = {"value": i}; if (lastRenderTarget != null) { @@ -66,13 +66,13 @@ class ShaderPasses extends Pass { material.needsUpdate = true; if (renderTargetsPass[i] == null) { - final pars = WebGLRenderTargetOptions({ + final pars = RenderTargetOptions({ "minFilter": LinearFilter, "magFilter": LinearFilter, "format": RGBAFormat }); final renderTargetPass = - WebGLRenderTarget(readBuffer.width, readBuffer.height, pars); + RenderTarget(readBuffer.width, readBuffer.height, pars); renderTargetPass.texture.name = 'renderTargetPass $i'; renderTargetPass.texture.generateMipmaps = false; renderTargetsPass[i] = renderTargetPass; @@ -102,7 +102,7 @@ class ShaderPasses extends Pass { } } - void renderPass(WebGLRenderer renderer, Material passMaterial, [WebGLRenderTarget? renderTarget, Color? clearColor, double? clearAlpha, bool clear = false]) { + void renderPass(Renderer renderer, Material passMaterial, [RenderTarget? renderTarget, Color? clearColor, double? clearAlpha, bool clear = false]) { // setup pass state renderer.autoClear = false; diff --git a/packages/three_js_postprocessing/lib/post/smaa_pass.dart b/packages/three_js_postprocessing/lib/post/smaa_pass.dart index 9eec2b83..d3574a07 100644 --- a/packages/three_js_postprocessing/lib/post/smaa_pass.dart +++ b/packages/three_js_postprocessing/lib/post/smaa_pass.dart @@ -8,8 +8,8 @@ import 'package:three_js_postprocessing/shaders/smaa_shader.dart'; import 'pass.dart'; class SMAAPass extends Pass { - late WebGLRenderTarget edgesRT; - late WebGLRenderTarget weightsRT; + late RenderTarget edgesRT; + late RenderTarget weightsRT; late Texture searchTexture; late Texture areaTexture; late Map uniformsEdges; @@ -21,16 +21,16 @@ class SMAAPass extends Pass { SMAAPass() : super() { // render targets - this.edgesRT = new WebGLRenderTarget( 1, 1, - WebGLRenderTargetOptions({ + this.edgesRT = new RenderTarget( 1, 1, + RenderTargetOptions({ "depthBuffer": false, 'type': HalfFloatType }) ); this.edgesRT.texture.name = 'SMAAPass.edges'; - this.weightsRT = new WebGLRenderTarget( 1, 1, - WebGLRenderTargetOptions({ + this.weightsRT = new RenderTarget( 1, 1, + RenderTargetOptions({ "depthBuffer": false, 'type': HalfFloatType }) @@ -106,7 +106,7 @@ class SMAAPass extends Pass { this.fsQuad = new FullScreenQuad(); } - void render(WebGLRenderer renderer, WebGLRenderTarget writeBuffer, WebGLRenderTarget readBuffer, {num? deltaTime, bool? maskActive}) { + void render(Renderer renderer, RenderTarget writeBuffer, RenderTarget readBuffer, {num? deltaTime, bool? maskActive}) { // pass 1 diff --git a/packages/three_js_postprocessing/lib/post/ssaa_render_pass.dart b/packages/three_js_postprocessing/lib/post/ssaa_render_pass.dart index 12e9fa5a..358c1379 100644 --- a/packages/three_js_postprocessing/lib/post/ssaa_render_pass.dart +++ b/packages/three_js_postprocessing/lib/post/ssaa_render_pass.dart @@ -24,7 +24,7 @@ class SSAARenderPass extends Pass { late Map copyUniforms; late ShaderMaterial copyMaterial; - WebGLRenderTarget? sampleRenderTarget; + RenderTarget? sampleRenderTarget; SSAARenderPass(Scene scene, Camera camera, [Color? clearColor, this.clearAlpha = 0]) : super() { this.scene = scene; @@ -69,12 +69,12 @@ class SSAARenderPass extends Pass { } @override - void render(WebGLRenderer renderer, WebGLRenderTarget writeBuffer, WebGLRenderTarget readBuffer, {num? deltaTime, bool? maskActive}) { + void render(Renderer renderer, RenderTarget writeBuffer, RenderTarget readBuffer, {num? deltaTime, bool? maskActive}) { if (sampleRenderTarget == null) { - sampleRenderTarget = WebGLRenderTarget( + sampleRenderTarget = RenderTarget( readBuffer.width, readBuffer.height, - WebGLRenderTargetOptions({ + RenderTargetOptions({ "minFilter": LinearFilter, "magFilter": LinearFilter, "format": RGBAFormat diff --git a/packages/three_js_postprocessing/lib/post/taa_render_pass.dart b/packages/three_js_postprocessing/lib/post/taa_render_pass.dart index b8e7823c..8ceb6dad 100644 --- a/packages/three_js_postprocessing/lib/post/taa_render_pass.dart +++ b/packages/three_js_postprocessing/lib/post/taa_render_pass.dart @@ -7,15 +7,15 @@ class TAARenderPass extends SSAARenderPass { int sampleLevel = 0; bool accumulate = false; int accumulateIndex = - 1; - WebGLRenderTarget? _sampleRenderTarget; - WebGLRenderTarget? _holdRenderTarget; + RenderTarget? _sampleRenderTarget; + RenderTarget? _holdRenderTarget; late Map copyUniforms; Color _oldClearColor = Color(0, 0, 0); TAARenderPass(super.scene, super.camera, [super.clearColor, super.clearAlpha ]); @override - void render(WebGLRenderer renderer, WebGLRenderTarget writeBuffer, WebGLRenderTarget readBuffer, {num? deltaTime, bool? maskActive}) { + void render(Renderer renderer, RenderTarget writeBuffer, RenderTarget readBuffer, {num? deltaTime, bool? maskActive}) { if ( this.accumulate == false ) { super.render( renderer, writeBuffer, readBuffer, deltaTime: deltaTime ); @@ -26,12 +26,12 @@ class TAARenderPass extends SSAARenderPass { final jitterOffsets = _JitterVectors[ 5 ]; if ( this._sampleRenderTarget == null ) { - this._sampleRenderTarget = new WebGLRenderTarget( readBuffer.width, readBuffer.height, WebGLRenderTargetOptions({'type': HalfFloatType})); + this._sampleRenderTarget = new RenderTarget( readBuffer.width, readBuffer.height, RenderTargetOptions({'type': HalfFloatType})); this._sampleRenderTarget?.texture.name = 'TAARenderPass.sample'; } if ( this._holdRenderTarget == null ) { - this._holdRenderTarget = new WebGLRenderTarget( readBuffer.width, readBuffer.height, WebGLRenderTargetOptions({'type': HalfFloatType})); + this._holdRenderTarget = new RenderTarget( readBuffer.width, readBuffer.height, RenderTargetOptions({'type': HalfFloatType})); this._holdRenderTarget?.texture.name = 'TAARenderPass.hold'; } diff --git a/packages/three_js_postprocessing/lib/post/texture_pass.dart b/packages/three_js_postprocessing/lib/post/texture_pass.dart index 7bf269c7..7a960c6b 100644 --- a/packages/three_js_postprocessing/lib/post/texture_pass.dart +++ b/packages/three_js_postprocessing/lib/post/texture_pass.dart @@ -29,7 +29,7 @@ class TexturePass extends Pass { } @override - void render(WebGLRenderer renderer, WebGLRenderTarget writeBuffer, WebGLRenderTarget readBuffer,{double? deltaTime, bool? maskActive}) { + void render(Renderer renderer, RenderTarget writeBuffer, RenderTarget readBuffer,{double? deltaTime, bool? maskActive}) { final oldAutoClear = renderer.autoClear; renderer.autoClear = false; diff --git a/packages/three_js_postprocessing/lib/post/unreal_bloom_pass.dart b/packages/three_js_postprocessing/lib/post/unreal_bloom_pass.dart index eca110fe..b9e8851e 100644 --- a/packages/three_js_postprocessing/lib/post/unreal_bloom_pass.dart +++ b/packages/three_js_postprocessing/lib/post/unreal_bloom_pass.dart @@ -24,10 +24,10 @@ class UnrealBloomPass extends Pass { late double radius; late double threshold; late Color clearColor; - late List renderTargetsHorizontal; - late List renderTargetsVertical; + late List renderTargetsHorizontal; + late List renderTargetsVertical; late num nMips; - late WebGLRenderTarget renderTargetBright; + late RenderTarget renderTargetBright; late Map highPassUniforms; late ShaderMaterial materialHighPassFilter; late List separableBlurMaterials; @@ -53,7 +53,7 @@ class UnrealBloomPass extends Pass { clearColor = Color(0, 0, 0); // render targets - final pars = WebGLRenderTargetOptions({ + final pars = RenderTargetOptions({ "minFilter": LinearFilter, "magFilter": LinearFilter, "format": RGBAFormat, @@ -65,19 +65,19 @@ class UnrealBloomPass extends Pass { int resx = (this.resolution.x ~/ 2); int resy = (this.resolution.y ~/ 2); - renderTargetBright = WebGLRenderTarget(resx, resy, pars); + renderTargetBright = RenderTarget(resx, resy, pars); renderTargetBright.texture.name = 'UnrealBloomPass.bright'; renderTargetBright.texture.generateMipmaps = false; for (int i = 0; i < nMips; i++) { - final renderTargetHorizonal = WebGLRenderTarget(resx, resy, pars); + final renderTargetHorizonal = RenderTarget(resx, resy, pars); renderTargetHorizonal.texture.name = 'UnrealBloomPass.h $i'; renderTargetHorizonal.texture.generateMipmaps = false; renderTargetsHorizontal.add(renderTargetHorizonal); - final renderTargetVertical = WebGLRenderTarget(resx, resy, pars); + final renderTargetVertical = RenderTarget(resx, resy, pars); renderTargetVertical.texture.name = 'UnrealBloomPass.v $i'; renderTargetVertical.texture.generateMipmaps = false; @@ -205,7 +205,7 @@ class UnrealBloomPass extends Pass { } @override - void render(WebGLRenderer renderer, WebGLRenderTarget writeBuffer, WebGLRenderTarget readBuffer,{double? deltaTime, bool? maskActive}) { + void render(Renderer renderer, RenderTarget writeBuffer, RenderTarget readBuffer,{double? deltaTime, bool? maskActive}) { renderer.getClearColor(oldClearColor); oldClearAlpha = renderer.getClearAlpha(); final oldAutoClear = renderer.autoClear; diff --git a/packages/three_js_terrain/lib/core.dart b/packages/three_js_terrain/lib/core.dart index efa5c354..011ccc0d 100644 --- a/packages/three_js_terrain/lib/core.dart +++ b/packages/three_js_terrain/lib/core.dart @@ -1,5 +1,4 @@ import 'package:flutter/foundation.dart'; -import 'package:three_js_core/renderers/webgl/index.dart'; import 'package:three_js_core/three_js_core.dart'; import 'package:three_js_math/three_js_math.dart'; import 'dart:math' as math; @@ -1573,11 +1572,11 @@ class Terrain{ final mat = material ?? MeshLambertMaterial(); Function? hexOnBeforeCompile; - if(mat is HexTilingMaterial){ + if(mat.runtimeType.toString() == 'HexTilingMaterial'){ hexOnBeforeCompile = mat.onBeforeCompile; } - mat.onBeforeCompile = (WebGLParameters shader, WebGLRenderer renderer) { + mat.onBeforeCompile = (shader, renderer) { hexOnBeforeCompile?.call(shader, renderer); // Patch vertexShader to setup MyUv, vPosition, and myNormal shader.vertexShader = shader.vertexShader.replaceAll('#include ', @@ -1596,7 +1595,7 @@ class Terrain{ }; } - if(mat is HexTilingMaterial){ + if(mat.runtimeType.toString() == 'HexTilingMaterial'){ shader.fragmentShader = shader.fragmentShader.replaceAll( 'texture2D', 'textureNoTileNeyret' diff --git a/packages/three_js_tjs_loader/lib/material_loader.dart b/packages/three_js_tjs_loader/lib/material_loader.dart index 078a3243..6d3b2f6d 100644 --- a/packages/three_js_tjs_loader/lib/material_loader.dart +++ b/packages/three_js_tjs_loader/lib/material_loader.dart @@ -133,7 +133,8 @@ class MaterialLoader extends Loader { material = HexTilingMaterial( HexTilingParams.fromJson(json['hexTiling'] ?? {}), ); - } else if (json["type"] == "ProjectedMaterial") { + } + else if (json["type"] == "ProjectedMaterial") { material = ProjectedMaterial.fromJson(json['projected']); } else { throw (" MaterialLoader ${json["type"]} is not support "); diff --git a/packages/three_js_webgl_renderer/lib/renderers/index.dart b/packages/three_js_webgl_renderer/lib/renderers/index.dart index c083ebad..3d94debe 100755 --- a/packages/three_js_webgl_renderer/lib/renderers/index.dart +++ b/packages/three_js_webgl_renderer/lib/renderers/index.dart @@ -9,9 +9,10 @@ import 'package:three_js_core/three_js_core.dart'; import 'package:three_js_math/three_js_math.dart'; import 'package:flutter_angle/flutter_angle.dart'; import '../webgl/index.dart'; +import '../shaders/index.dart'; -part 'web_gl_cube_render_target.dart'; +//part 'web_gl_cube_render_target.dart'; part 'web_gl_renderer.dart'; -part 'web_gl_render_target.dart'; +//part 'web_gl_render_target.dart'; part 'web_gl_3d_render_target.dart'; part 'web_gl_array_render_target.dart'; diff --git a/packages/three_js_webgl_renderer/lib/renderers/pmrem_generator.dart b/packages/three_js_webgl_renderer/lib/renderers/pmrem_generator.dart index 306ed985..60f9aae0 100755 --- a/packages/three_js_webgl_renderer/lib/renderers/pmrem_generator.dart +++ b/packages/three_js_webgl_renderer/lib/renderers/pmrem_generator.dart @@ -106,7 +106,7 @@ class PMREMGenerator { /// * and far planes ensure the scene is rendered in its entirety (the cubeCamera /// * is placed at the origin). /// * - WebGLRenderTarget fromScene(Scene scene, {double sigma = 0, double near = 0.1, double far = 100, PMREMGeneratorOptions? options}) { + RenderTarget fromScene(Scene scene, {double sigma = 0, double near = 0.1, double far = 100, PMREMGeneratorOptions? options}) { options ??= PMREMGeneratorOptions(); _oldTarget = _renderer.getRenderTarget(); @@ -239,7 +239,7 @@ class PMREMGenerator { return cubeUVRenderTarget; } - WebGLRenderTarget _allocateTargets() { + RenderTarget _allocateTargets() { int width = 3 * math.max(_cubeSize, 16 * 7); int height = 4 * _cubeSize; @@ -554,8 +554,8 @@ class PMREMGenerator { return {"lodPlanes": lodPlanes, "sizeLods": sizeLods, "sigmas": sigmas}; } - WebGLRenderTarget _createRenderTarget(int width, int height, Map params) { - final cubeUVRenderTarget = WebGLRenderTarget(width, height, RenderTargetOptions(params)); + RenderTarget _createRenderTarget(int width, int height, Map params) { + final cubeUVRenderTarget = RenderTarget(width, height, RenderTargetOptions(params)); cubeUVRenderTarget.texture.mapping = CubeUVReflectionMapping; cubeUVRenderTarget.texture.name = 'PMREM.cubeUv'; cubeUVRenderTarget.scissorTest = true; diff --git a/packages/three_js_webgl_renderer/lib/renderers/web_gl_3d_render_target.dart b/packages/three_js_webgl_renderer/lib/renderers/web_gl_3d_render_target.dart index 2658ae24..85c3d49d 100755 --- a/packages/three_js_webgl_renderer/lib/renderers/web_gl_3d_render_target.dart +++ b/packages/three_js_webgl_renderer/lib/renderers/web_gl_3d_render_target.dart @@ -1,6 +1,6 @@ part of three_renderers; -class WebGL3DRenderTarget extends WebGLRenderTarget { +class WebGL3DRenderTarget extends RenderTarget { WebGL3DRenderTarget([int width = 1, int height = 1, int depth = 1, RenderTargetOptions? options]) : super(width, height, options) { this.depth = depth; texture = Data3DTexture(null, width, height, depth); diff --git a/packages/three_js_webgl_renderer/lib/renderers/web_gl_array_render_target.dart b/packages/three_js_webgl_renderer/lib/renderers/web_gl_array_render_target.dart index 91c77127..13b50b6c 100755 --- a/packages/three_js_webgl_renderer/lib/renderers/web_gl_array_render_target.dart +++ b/packages/three_js_webgl_renderer/lib/renderers/web_gl_array_render_target.dart @@ -1,6 +1,6 @@ part of three_renderers; -class WebGLArrayRenderTarget extends WebGLRenderTarget { +class WebGLArrayRenderTarget extends RenderTarget { WebGLArrayRenderTarget([int width = 1, int height = 1, int depth = 1, RenderTargetOptions? options]) : super(width, height, options) { this.depth = depth; texture = DataArrayTexture(null, width, height, depth); diff --git a/packages/three_js_webgl_renderer/lib/renderers/web_gl_cube_render_target.dart b/packages/three_js_webgl_renderer/lib/renderers/web_gl_cube_render_target.dart index c941117a..14a17975 100755 --- a/packages/three_js_webgl_renderer/lib/renderers/web_gl_cube_render_target.dart +++ b/packages/three_js_webgl_renderer/lib/renderers/web_gl_cube_render_target.dart @@ -1,126 +1,126 @@ -part of three_renderers; +// part of three_renderers; -class WebGLCubeRenderTarget extends CubeRenderTarget { - WebGLCubeRenderTarget([int size = 1, RenderTargetOptions? options]) : super(size, options) { - // By convention -- likely based on the RenderMan spec from the 1990's -- cube maps are specified by WebGL (and three.js) - // in a coordinate system in which positive-x is to the right when looking up the positive-z axis -- in other words, - // in a left-handed coordinate system. By continuing this convention, preexisting cube maps continued to render correctly. +// class WebGLCubeRenderTarget extends CubeRenderTarget { +// WebGLCubeRenderTarget([int size = 1, RenderTargetOptions? options]) : super(size, options) { +// // By convention -- likely based on the RenderMan spec from the 1990's -- cube maps are specified by WebGL (and three.js) +// // in a coordinate system in which positive-x is to the right when looking up the positive-z axis -- in other words, +// // in a left-handed coordinate system. By continuing this convention, preexisting cube maps continued to render correctly. - // three.js uses a right-handed coordinate system. So environment maps used in three.js appear to have px and nx swapped - // and the flag isRenderTargetTexture controls this conversion. The flip is not required when using WebGLCubeRenderTarget.texture - // as a cube texture (this is detected when isRenderTargetTexture is set to true for cube textures). - final image = ImageElement(width: size, height: size, depth: 1); - final images = [image, image, image, image, image, image]; +// // three.js uses a right-handed coordinate system. So environment maps used in three.js appear to have px and nx swapped +// // and the flag isRenderTargetTexture controls this conversion. The flip is not required when using WebGLCubeRenderTarget.texture +// // as a cube texture (this is detected when isRenderTargetTexture is set to true for cube textures). +// final image = ImageElement(width: size, height: size, depth: 1); +// final images = [image, image, image, image, image, image]; - texture = CubeTexture( - images, - this.options.mapping, - this.options.wrapS, - this.options.wrapT, - this.options.magFilter, - this.options.minFilter, - this.options.format, - this.options.type, - this.options.anisotropy, - this.options.colorSpace - ); - texture.isRenderTargetTexture = true; +// texture = CubeTexture( +// images, +// this.options.mapping, +// this.options.wrapS, +// this.options.wrapT, +// this.options.magFilter, +// this.options.minFilter, +// this.options.format, +// this.options.type, +// this.options.anisotropy, +// this.options.colorSpace +// ); +// texture.isRenderTargetTexture = true; - texture.generateMipmaps = this.options.generateMipmaps; - texture.minFilter = this.options.minFilter ?? LinearFilter; - } +// texture.generateMipmaps = this.options.generateMipmaps; +// texture.minFilter = this.options.minFilter ?? LinearFilter; +// } - @override - WebGLCubeRenderTarget fromEquirectangularTexture(Renderer renderer, Texture texture) { - this.texture.type = texture.type; - this.texture.colorSpace = texture.colorSpace; +// @override +// WebGLCubeRenderTarget fromEquirectangularTexture(Renderer renderer, Texture texture) { +// this.texture.type = texture.type; +// this.texture.colorSpace = texture.colorSpace; - this.texture.generateMipmaps = texture.generateMipmaps; - this.texture.minFilter = texture.minFilter; - this.texture.magFilter = texture.magFilter; +// this.texture.generateMipmaps = texture.generateMipmaps; +// this.texture.minFilter = texture.minFilter; +// this.texture.magFilter = texture.magFilter; - final shader = { - "uniforms": { - "tEquirect": {'value': null}, - }, - "vertexShader": """ +// final shader = { +// "uniforms": { +// "tEquirect": {'value': null}, +// }, +// "vertexShader": """ - varying vec3 vWorldDirection; +// varying vec3 vWorldDirection; - vec3 transformDirection( in vec3 dir, in mat4 matrix ) { +// vec3 transformDirection( in vec3 dir, in mat4 matrix ) { - return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz ); +// return normalize( ( matrix * vec4( dir, 0.0 ) ).xyz ); - } +// } - void main() { +// void main() { - vWorldDirection = transformDirection( position, modelMatrix ); +// vWorldDirection = transformDirection( position, modelMatrix ); - #include - #include +// #include +// #include - } - """, - "fragmentShader": """ +// } +// """, +// "fragmentShader": """ - uniform sampler2D tEquirect; +// uniform sampler2D tEquirect; - varying vec3 vWorldDirection; +// varying vec3 vWorldDirection; - #include +// #include - void main() { +// void main() { - vec3 direction = normalize( vWorldDirection ); +// vec3 direction = normalize( vWorldDirection ); - vec2 sampleUV = equirectUv( direction ); +// vec2 sampleUV = equirectUv( direction ); - gl_FragColor = texture2D( tEquirect, sampleUV ); +// gl_FragColor = texture2D( tEquirect, sampleUV ); - } - """ - }; +// } +// """ +// }; - final geometry = BoxGeometry(5, 5, 5); - final material = ShaderMaterial.fromMap({ - "name": 'CubemapFromEquirect', - "uniforms": cloneUniforms(shader["uniforms"] as Map), - "vertexShader": shader["vertexShader"], - "fragmentShader": shader["fragmentShader"], - "side": BackSide, - "blending": NoBlending - }); +// final geometry = BoxGeometry(5, 5, 5); +// final material = ShaderMaterial.fromMap({ +// "name": 'CubemapFromEquirect', +// "uniforms": cloneUniforms(shader["uniforms"] as Map), +// "vertexShader": shader["vertexShader"], +// "fragmentShader": shader["fragmentShader"], +// "side": BackSide, +// "blending": NoBlending +// }); - material.uniforms["tEquirect"]["value"] = texture; +// material.uniforms["tEquirect"]["value"] = texture; - final mesh = Mesh(geometry, material); +// final mesh = Mesh(geometry, material); - final currentMinFilter = texture.minFilter; +// final currentMinFilter = texture.minFilter; - // Avoid blurred poles - if (texture.minFilter == LinearMipmapLinearFilter) { - texture.minFilter = LinearFilter; - } +// // Avoid blurred poles +// if (texture.minFilter == LinearMipmapLinearFilter) { +// texture.minFilter = LinearFilter; +// } - final camera = CubeCamera(1, 10, this); - camera.update(renderer, mesh); +// final camera = CubeCamera(1, 10, this); +// camera.update(renderer, mesh); - texture.minFilter = currentMinFilter; +// texture.minFilter = currentMinFilter; - mesh.geometry!.dispose(); - mesh.material?.dispose(); +// mesh.geometry!.dispose(); +// mesh.material?.dispose(); - return this; - } +// return this; +// } - @override - void clear(Renderer renderer, [bool color = true, bool depth = true, bool stencil = true]) { - final currentRenderTarget = renderer.getRenderTarget(); - for (int i = 0; i < 6; i++) { - renderer.setRenderTarget(this, i); - renderer.clear(color, depth, stencil); - } - renderer.setRenderTarget(currentRenderTarget); - } -} \ No newline at end of file +// @override +// void clear(Renderer renderer, [bool color = true, bool depth = true, bool stencil = true]) { +// final currentRenderTarget = renderer.getRenderTarget(); +// for (int i = 0; i < 6; i++) { +// renderer.setRenderTarget(this, i); +// renderer.clear(color, depth, stencil); +// } +// renderer.setRenderTarget(currentRenderTarget); +// } +// } \ No newline at end of file diff --git a/packages/three_js_webgl_renderer/lib/renderers/web_gl_render_target.dart b/packages/three_js_webgl_renderer/lib/renderers/web_gl_render_target.dart index 7ee78ab7..4d8cd3b7 100755 --- a/packages/three_js_webgl_renderer/lib/renderers/web_gl_render_target.dart +++ b/packages/three_js_webgl_renderer/lib/renderers/web_gl_render_target.dart @@ -1,167 +1,167 @@ -/* - In options, we can specify: - * Texture parameters for an auto-generated target texture - * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers -*/ -// import "package:universal_html/html.dart"; +// /* +// In options, we can specify: +// * Texture parameters for an auto-generated target texture +// * depthBuffer/stencilBuffer: Booleans to indicate if we should generate these buffers +// */ +// // import "package:universal_html/html.dart"; -part of three_renderers; +// part of three_renderers; -class WebGLRenderTarget extends RenderTarget { - bool isWebGLRenderTarget = true; - bool _didDispose = false; - WebGLRenderTarget(super.width, super.height, [super.options]); +// class WebGLRenderTarget extends RenderTarget { +// bool isWebGLRenderTarget = true; +// bool _didDispose = false; +// WebGLRenderTarget(super.width, super.height, [super.options]); - @override - WebGLRenderTarget clone() { - return WebGLRenderTarget(width, height, options).copy(this); - } +// @override +// WebGLRenderTarget clone() { +// return WebGLRenderTarget(width, height, options).copy(this); +// } - @override - WebGLRenderTarget copy(RenderTarget source) { - super.copy(source); - return this; - } +// @override +// WebGLRenderTarget copy(RenderTarget source) { +// super.copy(source); +// return this; +// } - @override - bool is3D() { - return texture is Data3DTexture || texture is DataArrayTexture; - } +// @override +// bool is3D() { +// return texture is Data3DTexture || texture is DataArrayTexture; +// } - @override - void dispose() { - if(_didDispose) return; - _didDispose = true; - dispatchEvent(Event(type: "dispose")); - depthTexture?.dispose(); - texture.dispose(); - options.dispose(); - } -} +// @override +// void dispose() { +// if(_didDispose) return; +// _didDispose = true; +// dispatchEvent(Event(type: "dispose")); +// depthTexture?.dispose(); +// texture.dispose(); +// options.dispose(); +// } +// } -// class WebGLRenderTargetOptions { -// int? wrapS; -// int? wrapT; -// int? wrapR; -// int? magFilter; -// int? minFilter; -// int? format; -// int? type; -// int? anisotropy; -// bool? depthBuffer; -// int? mapping; +// // class WebGLRenderTargetOptions { +// // int? wrapS; +// // int? wrapT; +// // int? wrapR; +// // int? magFilter; +// // int? minFilter; +// // int? format; +// // int? type; +// // int? anisotropy; +// // bool? depthBuffer; +// // int? mapping; -// bool stencilBuffer = false; -// bool generateMipmaps = false; -// DepthTexture? depthTexture; -// int? encoding; +// // bool stencilBuffer = false; +// // bool generateMipmaps = false; +// // DepthTexture? depthTexture; +// // int? encoding; -// bool useMultisampleRenderToTexture = false; -// bool ignoreDepth = false; -// bool useRenderToTexture = false; +// // bool useMultisampleRenderToTexture = false; +// // bool ignoreDepth = false; +// // bool useRenderToTexture = false; -// int? samples; -// int? internalFormat; -// int count = 1; +// // int? samples; +// // int? internalFormat; +// // int count = 1; -// bool resolveDepthBuffer = false; -// bool resolveStencilBuffer = false; +// // bool resolveDepthBuffer = false; +// // bool resolveStencilBuffer = false; -// void dispose(){ -// depthTexture?.dispose(); -// depthTexture = null; -// } +// // void dispose(){ +// // depthTexture?.dispose(); +// // depthTexture = null; +// // } -// WebGLRenderTargetOptions([Map? json]) { -// json ??= {}; -// if (json["wrapS"] != null) { -// wrapS = json["wrapS"]; -// } -// if(json['count'] != null){ -// count = json['count']; -// } -// if(json['resolveDepthBuffer'] != null){ -// resolveDepthBuffer = json['resolveDepthBuffer']; -// } -// if(json['resolveStencilBuffer'] != null){ -// resolveStencilBuffer = json['resolveStencilBuffer']; -// } -// if(json['internalFormat'] != null){ -// internalFormat = json['internalFormat']; -// } -// if (json["wrapT"] != null) { -// wrapT = json["wrapT"]; -// } -// if (json["wrapR"] != null) { -// wrapR = json["wrapR"]; -// } -// if (json["magFilter"] != null) { -// magFilter = json["magFilter"]; -// } -// if (json["minFilter"] != null) { -// minFilter = json["minFilter"]; -// } -// if (json["format"] != null) { -// format = json["format"]; -// } -// if (json["type"] != null) { -// type = json["type"]; -// } -// if (json["anisotropy"] != null) { -// anisotropy = json["anisotropy"]; -// } -// if (json["depthBuffer"] != null) { -// depthBuffer = json["depthBuffer"]; -// } -// if (json["mapping"] != null) { -// mapping = json["mapping"]; -// } -// if (json["generateMipmaps"] != null) { -// generateMipmaps = json["generateMipmaps"]; -// } -// if (json["depthTexture"] != null) { -// depthTexture = json["depthTexture"]; -// } -// if (json["encoding"] != null) { -// encoding = json["encoding"]; -// } -// if (json["useMultisampleRenderToTexture"] != null) { -// useMultisampleRenderToTexture = json["useMultisampleRenderToTexture"]; -// } -// if (json["ignoreDepth"] != null) { -// ignoreDepth = json["ignoreDepth"]; -// } -// if (json["useRenderToTexture"] != null) { -// useRenderToTexture = json["useRenderToTexture"]; -// } +// // WebGLRenderTargetOptions([Map? json]) { +// // json ??= {}; +// // if (json["wrapS"] != null) { +// // wrapS = json["wrapS"]; +// // } +// // if(json['count'] != null){ +// // count = json['count']; +// // } +// // if(json['resolveDepthBuffer'] != null){ +// // resolveDepthBuffer = json['resolveDepthBuffer']; +// // } +// // if(json['resolveStencilBuffer'] != null){ +// // resolveStencilBuffer = json['resolveStencilBuffer']; +// // } +// // if(json['internalFormat'] != null){ +// // internalFormat = json['internalFormat']; +// // } +// // if (json["wrapT"] != null) { +// // wrapT = json["wrapT"]; +// // } +// // if (json["wrapR"] != null) { +// // wrapR = json["wrapR"]; +// // } +// // if (json["magFilter"] != null) { +// // magFilter = json["magFilter"]; +// // } +// // if (json["minFilter"] != null) { +// // minFilter = json["minFilter"]; +// // } +// // if (json["format"] != null) { +// // format = json["format"]; +// // } +// // if (json["type"] != null) { +// // type = json["type"]; +// // } +// // if (json["anisotropy"] != null) { +// // anisotropy = json["anisotropy"]; +// // } +// // if (json["depthBuffer"] != null) { +// // depthBuffer = json["depthBuffer"]; +// // } +// // if (json["mapping"] != null) { +// // mapping = json["mapping"]; +// // } +// // if (json["generateMipmaps"] != null) { +// // generateMipmaps = json["generateMipmaps"]; +// // } +// // if (json["depthTexture"] != null) { +// // depthTexture = json["depthTexture"]; +// // } +// // if (json["encoding"] != null) { +// // encoding = json["encoding"]; +// // } +// // if (json["useMultisampleRenderToTexture"] != null) { +// // useMultisampleRenderToTexture = json["useMultisampleRenderToTexture"]; +// // } +// // if (json["ignoreDepth"] != null) { +// // ignoreDepth = json["ignoreDepth"]; +// // } +// // if (json["useRenderToTexture"] != null) { +// // useRenderToTexture = json["useRenderToTexture"]; +// // } -// samples = json["samples"]; -// } +// // samples = json["samples"]; +// // } -// Map toJson() { -// return { -// "wrapS": wrapS, -// "wrapT": wrapT, -// "wrapR": wrapR, -// "magFilter": magFilter, -// "minFilter": minFilter, -// 'internalFormat': internalFormat, -// "format": format, -// 'count': count, -// "type": type, -// 'resolveStencilBuffer': resolveStencilBuffer, -// 'resolveDepthBuffer': resolveDepthBuffer, -// "anisotropy": anisotropy, -// "depthBuffer": depthBuffer, -// "mapping": mapping, -// "stencilBuffer": stencilBuffer, -// "generateMipmaps": generateMipmaps, -// "depthTexture": depthTexture, -// "encoding": encoding, -// "useMultisampleRenderToTexture": useMultisampleRenderToTexture, -// "ignoreDepth": ignoreDepth, -// "useRenderToTexture": useRenderToTexture, -// "samples": samples -// }; -// } -// } +// // Map toJson() { +// // return { +// // "wrapS": wrapS, +// // "wrapT": wrapT, +// // "wrapR": wrapR, +// // "magFilter": magFilter, +// // "minFilter": minFilter, +// // 'internalFormat': internalFormat, +// // "format": format, +// // 'count': count, +// // "type": type, +// // 'resolveStencilBuffer': resolveStencilBuffer, +// // 'resolveDepthBuffer': resolveDepthBuffer, +// // "anisotropy": anisotropy, +// // "depthBuffer": depthBuffer, +// // "mapping": mapping, +// // "stencilBuffer": stencilBuffer, +// // "generateMipmaps": generateMipmaps, +// // "depthTexture": depthTexture, +// // "encoding": encoding, +// // "useMultisampleRenderToTexture": useMultisampleRenderToTexture, +// // "ignoreDepth": ignoreDepth, +// // "useRenderToTexture": useRenderToTexture, +// // "samples": samples +// // }; +// // } +// // } diff --git a/packages/three_js_webgl_renderer/lib/renderers/web_gl_renderer.dart b/packages/three_js_webgl_renderer/lib/renderers/web_gl_renderer.dart index a6200c16..d728a73d 100755 --- a/packages/three_js_webgl_renderer/lib/renderers/web_gl_renderer.dart +++ b/packages/three_js_webgl_renderer/lib/renderers/web_gl_renderer.dart @@ -1,7 +1,5 @@ part of three_renderers; -enum RenderType{after,before,custom} - class WebGLRendererParameters{ double width; double height; @@ -98,31 +96,20 @@ class WebGLRenderer extends Renderer{ }; // clearing - - bool autoClear = true; - bool autoClearColor = true; - bool autoClearDepth = true; - bool autoClearStencil = true; bool useLegacyLights = false; - // scene graph - bool sortObjects = true; - // user-defined clipping - List clippingPlanes = []; bool localClippingEnabled = false; String _outputColorSpace = SRGBColorSpace; - // physically based shading + // physically based shading int outputEncoding = LinearEncoding; // physical lights - bool physicallyCorrectLights = false; // tone mapping - int toneMapping = NoToneMapping; double toneMappingExposure = 1.0; @@ -180,6 +167,7 @@ class WebGLRenderer extends Renderer{ final _emptyScene = Scene(); + @override double getTargetPixelRatio() => _currentRenderTarget == null ? _pixelRatio : 1.0; // initialize @@ -190,8 +178,7 @@ class WebGLRenderer extends Renderer{ final animation = WebGLAnimation(); late WebGLExtensions extensions; - late WebGLCapabilities capabilities; - late WebGLState state; + late Capabilities capabilities; late WebGLInfo info; late WebGLProperties properties; late WebGLTextures textures; @@ -217,13 +204,15 @@ class WebGLRenderer extends Renderer{ late XRManager xr; late WebGLUniformsGroups uniformsGroups; - late WebGLShadowMap shadowMap; late final Framebuffer _scratchFrameBuffer; late final Framebuffer _srcFramebuffer; late final Framebuffer _dstFramebuffer; WebGLRenderer(this.parameters) { + shaderChunk = webglShaderChunk; + lightsFragmentBegin = webGlLightsFragmentBegin; + lightsParsBegin = webGlLightsParsBegin; _width = this.parameters.width; _height = this.parameters.height; @@ -258,28 +247,28 @@ class WebGLRenderer extends Renderer{ capabilities = WebGLCapabilities(_gl, extensions, parameters, utils); state = WebGLState(_gl,extensions); - if ( capabilities.reverseDepthBuffer && reverseDepthBuffer ) { + if ( (capabilities as WebGLCapabilities).reverseDepthBuffer && reverseDepthBuffer ) { state.buffers['depth'].setReversed( true ); } info = WebGLInfo(_gl); properties = WebGLProperties(); - textures = WebGLTextures(_gl, extensions, state, properties, capabilities, utils, info); + textures = WebGLTextures(_gl, extensions, state as WebGLState, properties, capabilities as WebGLCapabilities, utils, info); cubemaps = WebGLCubeMaps(this); cubeuvmaps = WebGLCubeUVMaps(this); attributes = WebGLAttributes(_gl); bindingStates = WebGLBindingStates(_gl, attributes); geometries = WebGLGeometries(_gl, attributes, info, bindingStates); objects = WebGLObjects(_gl, geometries, attributes, info); - morphtargets = WebGLMorphtargets(_gl, capabilities, textures); + morphtargets = WebGLMorphtargets(_gl, capabilities as WebGLCapabilities, textures); clipping = WebGLClipping(properties); - programCache = WebGLPrograms(this, cubemaps, cubeuvmaps, extensions, capabilities, bindingStates, clipping); + programCache = WebGLPrograms(this, cubemaps, cubeuvmaps, extensions, capabilities as WebGLCapabilities, bindingStates, clipping); materials = WebGLMaterials(this, properties); renderLists = WebGLRenderLists(); renderStates = WebGLRenderStates(extensions); - background = WebGLBackground(this, cubemaps, cubeuvmaps, state, objects, alpha, premultipliedAlpha); - shadowMap = WebGLShadowMap(this, objects, capabilities); - uniformsGroups = WebGLUniformsGroups( _gl, info, capabilities, state ); + background = WebGLBackground(this, cubemaps, cubeuvmaps, state as WebGLState, objects, alpha, premultipliedAlpha); + shadowMap = WebGLShadowMap(this, objects, capabilities as WebGLCapabilities); + uniformsGroups = WebGLUniformsGroups( _gl, info, capabilities as WebGLCapabilities, state as WebGLState ); bufferRenderer = WebGLBufferRenderer(_gl, extensions, info); indexedBufferRenderer = WebGLIndexedBufferRenderer(_gl, extensions, info); @@ -292,8 +281,8 @@ class WebGLRenderer extends Renderer{ } // API - - dynamic getContext() { + @override + RenderingContext getContext() { return _gl; } @@ -311,6 +300,7 @@ class WebGLRenderer extends Renderer{ if (extension) extension.restoreContext(); } + @override double getPixelRatio() { return _pixelRatio; } @@ -320,6 +310,7 @@ class WebGLRenderer extends Renderer{ setSize(width, height, false); } + @override Vector2 getSize(Vector2 target) { return target.setValues(width.toDouble(), height.toDouble()); } @@ -346,14 +337,16 @@ class WebGLRenderer extends Renderer{ setViewport(0, 0, width, height); } + @override Vector4 getCurrentViewport(Vector4 target) { return target.setFrom(_currentViewport); } + @override Vector4 getViewport(Vector4 target) { return target.setFrom(_viewport); } - + @override void setViewport(double x, double y, double width, double height) { _viewport.setValues(x, y, width, height); _currentViewport.setFrom(_viewport); @@ -379,7 +372,7 @@ class WebGLRenderer extends Renderer{ } void setScissorTest(bool boolean) { - state.setScissorTest(_scissorTest = boolean); + (state as WebGLState).setScissorTest(_scissorTest = boolean); } void setOpaqueSort(Function? method) { @@ -391,21 +384,24 @@ class WebGLRenderer extends Renderer{ } // Clearing - + @override Color getClearColor(Color target) { target.setFrom(background.getClearColor()); return target; } // color same as Color.set + @override void setClearColor(Color color, [double alpha = 1.0]) { background.setClearColor(color, alpha); } + @override double getClearAlpha() { return background.getClearAlpha(); } + @override void setClearAlpha(double alpha) { background.setClearAlpha(alpha); } @@ -473,18 +469,6 @@ class WebGLRenderer extends Renderer{ _gl.clear( bits ); } - void clearColor() { - clear(true, false, false); - } - - void clearDepth() { - clear(false, true, false); - } - - void clearStencil() { - clear(false, false, true); - } - // void dispose() { if(_didDispose) return; @@ -593,6 +577,7 @@ class WebGLRenderer extends Renderer{ } } + @override void renderBufferDirect( Camera camera, Object3D? scene, @@ -608,7 +593,7 @@ class WebGLRenderer extends Renderer{ WebGLProgram program = setProgram(camera, scene, geometry, material, object); - state.setMaterial(material, frontFaceCW); + (state as WebGLState).setMaterial(material, frontFaceCW); BufferAttribute? index = geometry.index; int rangeFactor = 1; @@ -659,7 +644,7 @@ class WebGLRenderer extends Renderer{ if (object is Mesh) { if (material.wireframe) { - state.setLineWidth(material.wireframeLinewidth! * getTargetPixelRatio()); + (state as WebGLState).setLineWidth(material.wireframeLinewidth! * getTargetPixelRatio()); renderer.setMode(WebGL.LINES); } else { @@ -671,7 +656,7 @@ class WebGLRenderer extends Renderer{ lineWidth ??= 1; // Not using Line*Material - state.setLineWidth(lineWidth * getTargetPixelRatio()); + (state as WebGLState).setLineWidth(lineWidth * getTargetPixelRatio()); if (object is LineSegments) { renderer.setMode(WebGL.LINES); @@ -1077,7 +1062,7 @@ class WebGLRenderer extends Renderer{ state.buffers["depth"].setMask(true); state.buffers["color"].setMask(true); - state.setPolygonOffset(false); + (state as WebGLState).setPolygonOffset(false); } void renderTransmissionPass(List opaqueObjects, List transmissiveObjects, Object3D scene, Camera camera) { @@ -1089,7 +1074,7 @@ class WebGLRenderer extends Renderer{ if ( currentRenderState?.state.transmissionRenderTarget[ camera.id ] == null ) { - currentRenderState?.state.transmissionRenderTarget[ camera.id ] = WebGLRenderTarget( 1, 1, RenderTargetOptions({ + currentRenderState?.state.transmissionRenderTarget[ camera.id ] = RenderTarget( 1, 1, RenderTargetOptions({ 'generateMipmaps': true, 'type': ( extensions.has( 'EXT_color_buffer_half_float' ) || extensions.has( 'EXT_color_buffer_float' ) ) ? HalfFloatType : UnsignedByteType, 'minFilter': LinearMipmapLinearFilter, @@ -1334,7 +1319,7 @@ class WebGLRenderer extends Renderer{ return materialProperties['uniformsList']; } - void updateCommonMaterialProperties(Material material, WebGLParameters parameters) { + void updateCommonMaterialProperties(Material material, Parameters parameters) { final materialProperties = properties.get(material); materialProperties['outputColorSpace'] = parameters.outputColorSpace; @@ -1468,7 +1453,7 @@ class WebGLRenderer extends Renderer{ final WebGLUniforms? pUniformS = program?.getUniforms(); final Map mUniformS = materialProperties['uniforms']; - if (state.useProgram( program?.program ) ) { + if ((state as WebGLState).useProgram( program?.program ) ) { refreshProgram = true; refreshMaterial = true; refreshLights = true; @@ -1705,7 +1690,7 @@ class WebGLRenderer extends Renderer{ if (renderTargetProperties["__useDefaultFramebuffer"] != null) { // We need to make sure to rebind the framebuffer. - state.bindFramebuffer(WebGL.FRAMEBUFFER, null); + (state as WebGLState).bindFramebuffer(WebGL.FRAMEBUFFER, null); useDefaultFramebuffer = false; } else if (renderTargetProperties["__webglFramebuffer"] == null) { @@ -1741,7 +1726,7 @@ class WebGLRenderer extends Renderer{ final webglFramebuffer = properties.get(renderTarget)["__webglFramebuffer"]; - if (renderTarget is WebGLCubeRenderTarget) { + if (renderTarget is CubeRenderTarget) { if (webglFramebuffer[ activeCubeFace ] is List) { framebuffer = webglFramebuffer[ activeCubeFace ][ activeMipmapLevel ]; } @@ -1777,15 +1762,15 @@ class WebGLRenderer extends Renderer{ framebuffer = _scratchFrameBuffer; } - final framebufferBound = state.bindFramebuffer(WebGL.FRAMEBUFFER, framebuffer); + final framebufferBound = (state as WebGLState).bindFramebuffer(WebGL.FRAMEBUFFER, framebuffer); if (framebufferBound && capabilities.drawBuffers && useDefaultFramebuffer) { - state.drawBuffers(renderTarget, framebuffer); + (state as WebGLState).drawBuffers(renderTarget, framebuffer); } - state.viewport(_currentViewport); - state.scissor(_currentScissor); - state.setScissorTest(_currentScissorTest!); + (state as WebGLState).viewport(_currentViewport); + (state as WebGLState).scissor(_currentScissor); + (state as WebGLState).setScissorTest(_currentScissorTest!); if (isCube) { final textureProperties = properties.get(renderTarget!.texture); @@ -1806,15 +1791,16 @@ class WebGLRenderer extends Renderer{ _currentMaterialId = -1; // reset current material to ensure correct uniform bindings } - void readRenderTargetPixels(WebGLRenderTarget renderTarget, int x, int y, int width, int height, TypedDataList buffer, [activeCubeFaceIndex]) { + @override + void readRenderTargetPixels(RenderTarget renderTarget, int x, int y, int width, int height, TypedData buffer, [int? activeCubeFaceIndex]) { dynamic framebuffer = properties.get(renderTarget)["__webglFramebuffer"]; //can be Map or int - if (renderTarget is WebGLCubeRenderTarget && activeCubeFaceIndex != null) { + if (renderTarget is CubeRenderTarget && activeCubeFaceIndex != null) { framebuffer = framebuffer?[activeCubeFaceIndex]; } if (framebuffer != null) { - state.bindFramebuffer(WebGL.FRAMEBUFFER, framebuffer); + (state as WebGLState).bindFramebuffer(WebGL.FRAMEBUFFER, framebuffer); try { final texture = renderTarget.texture; @@ -1849,11 +1835,12 @@ class WebGLRenderer extends Renderer{ } } finally { final framebuffer = (_currentRenderTarget != null) ? properties.get(_currentRenderTarget)["__webglFramebuffer"] : null; - state.bindFramebuffer(WebGL.FRAMEBUFFER, framebuffer); + (state as WebGLState).bindFramebuffer(WebGL.FRAMEBUFFER, framebuffer); } } } + @override void copyFramebufferToTexture(Vector? position, Texture? texture, {int level = 0}) { //console.warning('copyFramebufferToTexture not supported'); if (texture is! FramebufferTexture) { @@ -1870,7 +1857,7 @@ class WebGLRenderer extends Renderer{ textures.setTexture2D(texture, 0); _gl.copyTexSubImage2D(WebGL.TEXTURE_2D, level, 0, 0, x, y, width, height); - state.unbindTexture(WebGLTexture(WebGL.TEXTURE_2D)); + (state as WebGLState).unbindTexture(WebGLTexture(WebGL.TEXTURE_2D)); } void copyTextureToTexture(Texture srcTexture, Texture dstTexture, {srcRegion, dstPosition, int srcLevel = 0, dstLevel}) { @@ -1971,8 +1958,8 @@ class WebGLRenderer extends Renderer{ final dstTextureProperties = properties.get( dstTexture ); final srcRenderTargetProperties = properties.get( srcTextureProperties['__renderTarget'] ); final dstRenderTargetProperties = properties.get( dstTextureProperties['__renderTarget'] ); - state.bindFramebuffer( WebGL.READ_FRAMEBUFFER, srcRenderTargetProperties['__webglFramebuffer'] ); - state.bindFramebuffer( WebGL.DRAW_FRAMEBUFFER, dstRenderTargetProperties['__webglFramebuffer'] ); + (state as WebGLState).bindFramebuffer( WebGL.READ_FRAMEBUFFER, srcRenderTargetProperties['__webglFramebuffer'] ); + (state as WebGLState).bindFramebuffer( WebGL.DRAW_FRAMEBUFFER, dstRenderTargetProperties['__webglFramebuffer'] ); for (int i = 0; i < depth; i ++ ) { // if the source or destination are a 3d target then a layer needs to be bound @@ -1984,8 +1971,8 @@ class WebGLRenderer extends Renderer{ _gl.blitFramebuffer( minX, minY, width, height, dstX, dstY, width, height, WebGL.DEPTH_BUFFER_BIT, WebGL.NEAREST ); } - state.bindFramebuffer( WebGL.READ_FRAMEBUFFER, null ); - state.bindFramebuffer( WebGL.DRAW_FRAMEBUFFER, null ); + (state as WebGLState).bindFramebuffer( WebGL.READ_FRAMEBUFFER, null ); + (state as WebGLState).bindFramebuffer( WebGL.DRAW_FRAMEBUFFER, null ); } else if ( srcLevel != 0 || srcTexture.isRenderTargetTexture || properties.has( srcTexture ) ) { @@ -1994,8 +1981,8 @@ class WebGLRenderer extends Renderer{ final dstTextureProperties = properties.get( dstTexture ); // bind the frame buffer targets - state.bindFramebuffer( WebGL.READ_FRAMEBUFFER, _srcFramebuffer ); - state.bindFramebuffer( WebGL.DRAW_FRAMEBUFFER, _dstFramebuffer ); + (state as WebGLState).bindFramebuffer( WebGL.READ_FRAMEBUFFER, _srcFramebuffer ); + (state as WebGLState).bindFramebuffer( WebGL.DRAW_FRAMEBUFFER, _dstFramebuffer ); for (int i = 0; i < depth; i ++ ) { @@ -2025,8 +2012,8 @@ class WebGLRenderer extends Renderer{ } // unbind read, draw buffers - state.bindFramebuffer( WebGL.READ_FRAMEBUFFER, null ); - state.bindFramebuffer( WebGL.DRAW_FRAMEBUFFER, null ); + (state as WebGLState).bindFramebuffer( WebGL.READ_FRAMEBUFFER, null ); + (state as WebGLState).bindFramebuffer( WebGL.DRAW_FRAMEBUFFER, null ); } else { @@ -2068,7 +2055,7 @@ class WebGLRenderer extends Renderer{ _gl.generateMipmap( glTarget ); } - state.unbindTexture(); + (state as WebGLState).unbindTexture(); } void copyTextureToTexture3D( @@ -2101,7 +2088,7 @@ class WebGLRenderer extends Renderer{ textures.setTexture2D(texture, 0); } - state.unbindTexture(); + (state as WebGLState).unbindTexture(); } WebGLTexture getRenderTargetGLTexture(RenderTarget renderTarget) { diff --git a/packages/three_js_webgl_renderer/lib/shaders/index.dart b/packages/three_js_webgl_renderer/lib/shaders/index.dart old mode 100755 new mode 100644 index 6dec99a8..2a51fb2a --- a/packages/three_js_webgl_renderer/lib/shaders/index.dart +++ b/packages/three_js_webgl_renderer/lib/shaders/index.dart @@ -1,13 +1,6 @@ -library three_shaders; - -import 'package:three_js_core/three_js_core.dart'; -import 'package:three_js_math/three_js_math.dart'; -import 'shader_chunk/index.dart'; -import 'shader_lib/index.dart'; - -export './shader_lib/vsm_vert.glsl.dart'; -export './shader_lib/vsm_frag.glsl.dart'; - -part './shader_lib.dart'; -part 'uniforms_lib.dart'; -part './shader_chunk.dart'; +export 'shader_chunk.dart'; +export 'shader_lib/index.dart'; +export 'shader_lib/vsm_vert.glsl.dart'; +export 'shader_lib/vsm_frag.glsl.dart'; +export 'shader_chunk/lights_fragment_begin.glsl.dart'; +export 'shader_chunk/lights_pars_begin.glsl.dart'; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk.dart index 03c9815a..99666090 100755 --- a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk.dart +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk.dart @@ -1,6 +1,7 @@ -part of three_shaders; +import 'shader_chunk/index.dart'; +import 'shader_lib/index.dart'; -Map shaderChunk = { +Map webglShaderChunk = { 'alphahash_fragment': alphahashFragment, 'alphahash_pars_fragment': alphahashParsFragment, "alphamap_fragment": alphamapFragment, @@ -57,14 +58,14 @@ Map shaderChunk = { "lights_lambert_vertex": lightsLambertVertex, 'lights_lambert_fragment': lightsLambertFragment, 'lights_lambert_pars_fragment': lightsLambertParsFragment, - "lights_pars_begin": lightsParsBegin, + "lights_pars_begin": webGlLightsParsBegin, "lights_toon_fragment": lightsToonFragment, "lights_toon_pars_fragment": lightsToonParsFragment, "lights_phong_fragment": lightsPhongFragment, "lights_phong_pars_fragment": lightsPhongParsFragment, "lights_physical_fragment": lightsPhysicalFragment, "lights_physical_pars_fragment": lightsPhysicalParsFragment, - "lights_fragment_begin": lightsFragmentBegin, + "lights_fragment_begin": webGlLightsFragmentBegin, "lights_fragment_maps": lightsFragmentMaps, "lights_fragment_end": lightsFragmentEnd, "logdepthbuf_fragment": logdepthbufFragment, diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_fragment_begin.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_fragment_begin.glsl.dart index a57085a9..a8ea7178 100755 --- a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_fragment_begin.glsl.dart +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_fragment_begin.glsl.dart @@ -1,4 +1,4 @@ -String lightsFragmentBegin = """ +String webGlLightsFragmentBegin = """ /** * This is a template that can be used to light a material, it uses pluggable * RenderEquations (RE)for specific lighting scenarios. diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_pars_begin.glsl.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_pars_begin.glsl.dart index f4887867..eb749a30 100755 --- a/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_pars_begin.glsl.dart +++ b/packages/three_js_webgl_renderer/lib/shaders/shader_chunk/lights_pars_begin.glsl.dart @@ -1,4 +1,4 @@ -String lightsParsBegin = """ +String webGlLightsParsBegin = """ uniform bool receiveShadow; uniform vec3 ambientLightColor; diff --git a/packages/three_js_webgl_renderer/lib/shaders/shader_lib.dart b/packages/three_js_webgl_renderer/lib/shaders/shader_lib.dart deleted file mode 100755 index 7cd3362b..00000000 --- a/packages/three_js_webgl_renderer/lib/shaders/shader_lib.dart +++ /dev/null @@ -1,279 +0,0 @@ -part of three_shaders; - -Map shaderLibStandard = { - "uniforms": mergeUniforms([ - uniformsLib["common"], - uniformsLib["envmap"], - uniformsLib["aomap"], - uniformsLib["lightmap"], - uniformsLib["emissivemap"], - uniformsLib["bumpmap"], - uniformsLib["normalmap"], - uniformsLib["displacementmap"], - uniformsLib["roughnessmap"], - uniformsLib["metalnessmap"], - uniformsLib["fog"], - uniformsLib["lights"], - { - "emissive": {"value": Color(0, 0, 0)}, - "roughness": {"value": 1.0}, - "metalness": {"value": 0.0}, - "envMapIntensity": {"value": 1} // temporary - } - ]), - "vertexShader": shaderChunk["meshphysical_vert"], - "fragmentShader": shaderChunk["meshphysical_frag"] -}; - -Map shaderLib = { - "basic": { - "uniforms": mergeUniforms([ - uniformsLib["common"], - uniformsLib["specularmap"], - uniformsLib["envmap"], - uniformsLib["aomap"], - uniformsLib["lightmap"], - uniformsLib["fog"] - ]), - "vertexShader": shaderChunk["meshbasic_vert"], - "fragmentShader": shaderChunk["meshbasic_frag"] - }, - "lambert": { - "uniforms": mergeUniforms([ - uniformsLib["common"], - uniformsLib["specularmap"], - uniformsLib["envmap"], - uniformsLib["aomap"], - uniformsLib["lightmap"], - uniformsLib["emissivemap"], - uniformsLib["bumpmap"], - uniformsLib["normalmap"], - uniformsLib["displacementmap"], - uniformsLib["fog"], - uniformsLib["lights"], - { - "emissive": {"value": Color.fromHex32(0x000000)} - } - ]), - "vertexShader": shaderChunk["meshlambert_vert"], - "fragmentShader": shaderChunk["meshlambert_frag"] - }, - "phong": { - "uniforms": mergeUniforms([ - uniformsLib["common"], - uniformsLib["specularmap"], - uniformsLib["envmap"], - uniformsLib["aomap"], - uniformsLib["lightmap"], - uniformsLib["emissivemap"], - uniformsLib["bumpmap"], - uniformsLib["normalmap"], - uniformsLib["displacementmap"], - uniformsLib["fog"], - uniformsLib["lights"], - { - "emissive": {"value": Color.fromHex32(0x000000)}, - "specular": {"value": Color.fromHex32(0x111111)}, - "shininess": {"value": 30} - } - ]), - "vertexShader": shaderChunk["meshphong_vert"], - "fragmentShader": shaderChunk["meshphong_frag"] - }, - "standard": shaderLibStandard, - "toon": { - "uniforms": mergeUniforms([ - uniformsLib["common"], - uniformsLib["aomap"], - uniformsLib["lightmap"], - uniformsLib["emissivemap"], - uniformsLib["bumpmap"], - uniformsLib["normalmap"], - uniformsLib["displacementmap"], - uniformsLib["gradientmap"], - uniformsLib["fog"], - uniformsLib["lights"], - { - "emissive": {"value": Color.fromHex32(0x000000)} - } - ]), - "vertexShader": shaderChunk["meshtoon_vert"], - "fragmentShader": shaderChunk["meshtoon_frag"] - }, - "matcap": { - "uniforms": mergeUniforms([ - uniformsLib["common"], - uniformsLib["bumpmap"], - uniformsLib["normalmap"], - uniformsLib["displacementmap"], - uniformsLib["fog"], - { - "matcap": {"value": null} - } - ]), - "vertexShader": shaderChunk["meshmatcap_vert"], - "fragmentShader": shaderChunk["meshmatcap_frag"] - }, - "points": { - "uniforms": mergeUniforms([uniformsLib["points"], uniformsLib["fog"]]), - "vertexShader": shaderChunk["points_vert"], - "fragmentShader": shaderChunk["points_frag"] - }, - "dashed": { - "uniforms": mergeUniforms([ - uniformsLib["common"], - uniformsLib["fog"], - { - "scale": {"value": 1}, - "dashSize": {"value": 1}, - "totalSize": {"value": 2} - } - ]), - "vertexShader": shaderChunk["linedashed_vert"], - "fragmentShader": shaderChunk["linedashed_frag"] - }, - "depth": { - "uniforms": - mergeUniforms([uniformsLib["common"], uniformsLib["displacementmap"]]), - "vertexShader": shaderChunk["depth_vert"], - "fragmentShader": shaderChunk["depth_frag"] - }, - "normal": { - "uniforms": mergeUniforms([ - uniformsLib["common"], - uniformsLib["bumpmap"], - uniformsLib["normalmap"], - uniformsLib["displacementmap"], - { - "opacity": {"value": 1.0} - } - ]), - "vertexShader": shaderChunk["meshnormal_vert"], - "fragmentShader": shaderChunk["meshnormal_frag"] - }, - "sprite": { - "uniforms": mergeUniforms([uniformsLib["sprite"], uniformsLib["fog"]]), - "vertexShader": shaderChunk["sprite_vert"], - "fragmentShader": shaderChunk["sprite_frag"] - }, - "background": { - "uniforms": { - "uvTransform": {"value": Matrix3.identity()}, - "t2D": {"value": null}, - 'backgroundIntensity': { 'value': 1 } - }, - "vertexShader": shaderChunk["background_vert"], - "fragmentShader": shaderChunk["background_frag"] - }, - 'backgroundCube': { - - 'uniforms': { - 'envMap': { 'value': null }, - 'flipEnvMap': { 'value': - 1 }, - 'backgroundBlurriness': { 'value': 0 }, - 'backgroundIntensity': { 'value': 1 }, - 'backgroundRotation': { 'value': Matrix3.identity() } - }, - - 'vertexShader': shaderChunk['backgroundCube_vert'], - 'fragmentShader': shaderChunk['backgroundCube_frag'] - }, - /* ------------------------------------------------------------------------- - // Cube map shader - ------------------------------------------------------------------------- */ - - "cube": { - 'uniforms': { - 'tCube': { 'value': null }, - 'tFlip': { 'value': - 1 }, - 'opacity': { 'value': 1.0 }, - }, - "vertexShader": shaderChunk["cube_vert"], - "fragmentShader": shaderChunk["cube_frag"] - }, - "equirect": { - "uniforms": { - "tEquirect": {"value": null}, - }, - "vertexShader": shaderChunk["equirect_vert"], - "fragmentShader": shaderChunk["equirect_frag"] - }, - "distanceRGBA": { - "uniforms": mergeUniforms([ - uniformsLib["common"], - uniformsLib["displacementmap"], - { - "referencePosition": {"value": Vector3.zero()}, - "nearDistance": {"value": 1}, - "farDistance": {"value": 1000} - } - ]), - "vertexShader": shaderChunk["distanceRGBA_vert"], - "fragmentShader": shaderChunk["distanceRGBA_frag"] - }, - "shadow": { - "uniforms": mergeUniforms([ - uniformsLib["lights"], - uniformsLib["fog"], - { - "color": {"value": Color.fromHex32(0x000000)}, - "opacity": {"value": 1.0} - }, - ]), - "vertexShader": shaderChunk["shadow_vert"], - "fragmentShader": shaderChunk["shadow_frag"] - }, - "physical": { - "uniforms": mergeUniforms([ - shaderLibStandard["uniforms"], - { - 'clearcoat': { 'value': 0 }, - 'clearcoatMap': { 'value': null }, - 'clearcoatMapTransform': { 'value': Matrix3.identity() }, - 'clearcoatNormalMap': { 'value': null }, - 'clearcoatNormalMapTransform': { 'value': Matrix3.identity() }, - 'clearcoatNormalScale': { 'value': Vector2( 1, 1 ) }, - 'clearcoatRoughness': { 'value': 0 }, - 'clearcoatRoughnessMap': { 'value': null }, - 'clearcoatRoughnessMapTransform': { 'value': Matrix3.identity() }, - 'dispersion': { 'value': 0 }, - 'iridescence': { 'value': 0 }, - 'iridescenceMap': { 'value': null }, - 'iridescenceMapTransform': { 'value': Matrix3.identity() }, - 'iridescenceIOR': { 'value': 1.3 }, - 'iridescenceThicknessMinimum': { 'value': 100 }, - 'iridescenceThicknessMaximum': { 'value': 400 }, - 'iridescenceThicknessMap': { 'value': null }, - 'iridescenceThicknessMapTransform': { 'value': Matrix3.identity() }, - 'sheen': { 'value': 0 }, - 'sheenColor': { 'value': Color( 0x000000 ) }, - 'sheenColorMap': { 'value': null }, - 'sheenColorMapTransform': { 'value': Matrix3.identity() }, - 'sheenRoughness': { 'value': 1 }, - 'sheenRoughnessMap': { 'value': null }, - 'sheenRoughnessMapTransform': { 'value': Matrix3.identity() }, - 'transmission': { 'value': 0 }, - 'transmissionMap': { 'value': null }, - 'transmissionMapTransform': { 'value': Matrix3.identity() }, - 'transmissionSamplerSize': { 'value': Vector2() }, - 'transmissionSamplerMap': { 'value': null }, - 'thickness': { 'value': 0 }, - 'thicknessMap': { 'value': null }, - 'thicknessMapTransform': { 'value': Matrix3.identity() }, - 'attenuationDistance': { 'value': 0 }, - 'attenuationColor': { 'value': Color( 0x000000 ) }, - 'specularColor': { 'value': Color( 1, 1, 1 ) }, - 'specularColorMap': { 'value': null }, - 'specularColorMapTransform': { 'value': Matrix3.identity() }, - 'specularIntensity': { 'value': 1 }, - 'specularIntensityMap': { 'value': null }, - 'specularIntensityMapTransform': { 'value': Matrix3.identity() }, - 'anisotropyVector': { 'value': Vector2() }, - 'anisotropyMap': { 'value': null }, - 'anisotropyMapTransform': { 'value': Matrix3.identity() }, - } - ]), - "vertexShader": shaderChunk["meshphysical_vert"], - "fragmentShader": shaderChunk["meshphysical_frag"] - } -}; \ No newline at end of file diff --git a/packages/three_js_webgl_renderer/lib/three_viewer.dart b/packages/three_js_webgl_renderer/lib/three_viewer.dart index 596eed48..d85076e7 100644 --- a/packages/three_js_webgl_renderer/lib/three_viewer.dart +++ b/packages/three_js_webgl_renderer/lib/three_viewer.dart @@ -117,7 +117,7 @@ class ThreeJS with WidgetsBindingObserver{ FlutterAngleTexture? texture; RenderingContext? gl; - WebGLRenderTarget? renderTarget; + RenderTarget? renderTarget; WebGLRenderer? renderer; final core.Clock clock = core.Clock(); @@ -309,7 +309,7 @@ class ThreeJS with WidgetsBindingObserver{ if(settings.useSourceTexture){ final RenderTargetOptions pars = RenderTargetOptions(settings.renderOptions); - renderTarget = WebGLRenderTarget((width * _resolution!).toInt(), (height * _resolution!).toInt(), pars); + renderTarget = RenderTarget((width * _resolution!).toInt(), (height * _resolution!).toInt(), pars); renderer!.setRenderTarget(renderTarget); sourceTexture = renderer!.getRenderTargetGLTexture(renderTarget!); } diff --git a/packages/three_js_webgl_renderer/lib/webgl/index.dart b/packages/three_js_webgl_renderer/lib/webgl/index.dart index 39ff278a..dc3ab44d 100755 --- a/packages/three_js_webgl_renderer/lib/webgl/index.dart +++ b/packages/three_js_webgl_renderer/lib/webgl/index.dart @@ -27,7 +27,6 @@ part 'web_gl_lights.dart'; part 'web_gl_materials.dart'; part 'web_gl_morphtargets.dart'; part 'web_gl_objects.dart'; -part 'web_gl_parameters.dart'; part 'web_gl_program.dart'; part 'web_gl_program_extra.dart'; part 'web_gl_programs.dart'; diff --git a/packages/three_js_webgl_renderer/lib/webgl/web_gl_capabilities.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_capabilities.dart index fe252b3d..ef6b510f 100755 --- a/packages/three_js_webgl_renderer/lib/webgl/web_gl_capabilities.dart +++ b/packages/three_js_webgl_renderer/lib/webgl/web_gl_capabilities.dart @@ -1,35 +1,13 @@ part of three_webgl; -class WebGLCapabilities { +class WebGLCapabilities extends Capabilities { bool _didDispose = false; - bool isWebGL2 = true; WebGLRendererParameters parameters; RenderingContext gl; WebGLExtensions extensions; WebGLUtils utils; - String precision = 'highp'; - String maxPrecision = "highp"; - - bool logarithmicDepthBuffer = false; - late int maxTextures; - late int maxVertexTextures; - late int maxTextureSize; - late int maxCubemapSize; - late int maxAttributes; - late int maxVertexUniforms; - late int maxVaryings; - late int maxFragmentUniforms; - late bool reverseDepthBuffer; - - num? maxAnisotropy; - - late bool vertexTextures; - late int maxSamples; - - bool drawBuffers = true; - WebGLCapabilities(this.gl, this.extensions, this.parameters, this.utils) { precision = parameters.precision.name; diff --git a/packages/three_js_webgl_renderer/lib/webgl/web_gl_cube_maps.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_cube_maps.dart index c93fefe2..248091cd 100755 --- a/packages/three_js_webgl_renderer/lib/webgl/web_gl_cube_maps.dart +++ b/packages/three_js_webgl_renderer/lib/webgl/web_gl_cube_maps.dart @@ -30,7 +30,7 @@ class WebGLCubeMaps { final image = texture.image; if (image != null && image.height > 0) { - final renderTarget = WebGLCubeRenderTarget(image.height ~/ 2); + final renderTarget = CubeRenderTarget(image.height ~/ 2); renderTarget.fromEquirectangularTexture(renderer, texture); cubemaps.add(key: texture, value: renderTarget); diff --git a/packages/three_js_webgl_renderer/lib/webgl/web_gl_parameters.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_parameters.dart deleted file mode 100755 index e2703902..00000000 --- a/packages/three_js_webgl_renderer/lib/webgl/web_gl_parameters.dart +++ /dev/null @@ -1,670 +0,0 @@ -part of three_webgl; - -class WebGLParameters { - int? customVertexShaderID; - int? customFragmentShaderID; - - bool rendererExtensionParallelShaderCompile = false; - - String? shaderID; - String? shaderType; - String outputColorSpace = NoColorSpace; - String shaderName = ''; - - String vertexShader = ''; - String fragmentShader = ''; - - Map? defines; - - bool isRawShaderMaterial = false; - String? glslVersion; - - late String precision; - - bool instancing = false; - bool instancingColor = false; - - bool supportsVertexTextures = false; - bool map = false; - bool matcap = false; - bool envMap = false; - int? envMapMode; - bool lightMap = false; - bool aoMap = false; - bool emissiveMap = false; - bool bumpMap = false; - bool normalMap = false; - bool normalMapObjectSpace = false; - bool normalMapTangentSpace = false; - - bool clearcoat = false; - bool clearcoatMap = false; - bool clearcoatRoughnessMap = false; - bool clearcoatNormalMap = false; - - bool displacementMap = false; - bool roughnessMap = false; - bool metalnessMap = false; - bool specularMap = false; - bool specularIntensityMap = false; - bool specularColorMap = false; - bool alphaMap = false; - bool sheenColorMap = false; - - bool gradientMap = false; - bool sheenRoughnessMap = false; - bool sheen = false; - bool transmission = false; - bool transmissionMap = false; - bool thicknessMap = false; - int? combine; - bool vertexTangents = false; - bool vertexColors = false; - bool vertexUvs = false; - bool pointsUvs = false; - bool fog = false; - bool useFog = false; - bool fogExp2 = false; - bool flatShading = false; - bool sizeAttenuation = false; - bool logarithmicDepthBuffer = false; - - bool skinning = false; - - bool morphTargets = false; - bool morphNormals = false; - bool morphColors = false; - - int numDirLights = 0; - int numPointLights = 0; - int numSpotLights = 0; - int numRectAreaLights = 0; - int numHemiLights = 0; - int numSpotLightMaps = 0; - - int numDirLightShadows = 0; - int numPointLightShadows = 0; - int numSpotLightShadows = 0; - int numLightProbes = 0; - int numSpotLightShadowsWithMaps = 0; - - int numClippingPlanes = 0; - int numClipIntersection = 0; - bool dithering = false; - bool shadowMapEnabled = false; - int? shadowMapType; - int? toneMapping; - bool useLegacyLights = false; - bool physicallyCorrectLights = false; - bool premultipliedAlpha = false; - bool alphaTest = false; - - bool doubleSided = false; - bool flipSided = false; - - bool useDepthPacking = false; - int? depthPacking; - - String? index0AttributeName; - - late bool extensionDerivatives; - late bool extensionFragDepth; - late bool extensionDrawBuffers; - late bool extensionShaderTextureLOD; - - late bool rendererExtensionFragDepth; - late bool rendererExtensionDrawBuffers; - late bool rendererExtensionShaderTextureLod; - String? customProgramCacheKey; - - bool decodeVideoTexture = false; - bool decodeVideoTextureEmissive = false; - - Map? uniforms; - - bool vertexAlphas = false; - bool opaque = false; - bool batching = false; - - bool anisotropy = false; - bool anisotropyMap = false; - - bool iridescence = false; - bool iridescenceMap = false; - bool iridescenceThicknessMap = false; - bool alphaHash = false; - bool dispersion = false; - bool batchingColor = false; - - int morphTargetsCount = 0; - num? cubeUVHeight; - - num? envMapCubeUVHeight; - bool instancingMorph = false; - bool alphaToCoverage = false; - int? morphTextureStride; - - bool extensionClipCullDistance = false; - bool extensionMultiDraw = false; - - String? mapUv; - String? aoMapUv; - String? lightMapUv; - String? bumpMapUv; - String? normalMapUv; - String? displacementMapUv; - String? emissiveMapUv; - - String? metalnessMapUv; - String? roughnessMapUv; - - String? anisotropyMapUv; - - String? clearcoatMapUv; - String? clearcoatNormalMapUv; - String? clearcoatRoughnessMapUv; - - String? iridescenceMapUv; - String? iridescenceThicknessMapUv; - - String? sheenColorMapUv; - String? sheenRoughnessMapUv; - - String? specularMapUv; - String? specularColorMapUv; - String? specularIntensityMapUv; - - String? transmissionMapUv; - String? thicknessMapUv; - - String? alphaMapUv; - - bool vertexUv1s = false; - bool vertexUv2s = false; - bool vertexUv3s = false; - - int morphAttributeCount = 0; - - bool tangentSpaceNormalMap = false; - bool objectSpaceNormalMap = false; - bool uvsVertexOnly = false; - int outputEncoding = 0; - - WebGLParameters.create(); - - void dispose(){ - uniforms?.clear(); - } - - WebGLParameters({ - this.shaderID, - this.shaderType, - this.shaderName = '', - this.vertexShader = '', - this.fragmentShader = '', - this.defines, - this.customVertexShaderID, - this.customFragmentShaderID, - this.isRawShaderMaterial = false, - this.glslVersion, - required this.precision, - this.batching = false, - this.instancing = false, - this.instancingColor = false, - this.instancingMorph = false, - this.supportsVertexTextures = false, - this.outputColorSpace = NoColorSpace, - this.alphaToCoverage = false, - this.map = false, - this.displacementMap = false, - this.matcap = false, - this.envMap = false, - this.envMapMode, - this.envMapCubeUVHeight, - this.lightMap = false, - this.aoMap = false, - this.emissiveMap = false, - this.bumpMap = false, - this.normalMap = false, - - this.morphAttributeCount = 0, - - this.normalMapObjectSpace = false, - this.normalMapTangentSpace = false, - this.roughnessMap = false, - this.metalnessMap = false, - - this.anisotropy = false, - this.anisotropyMap = false, - - this.clearcoat = false, - this.clearcoatMap = false, - this.clearcoatRoughnessMap = false, - this.clearcoatNormalMap = false, - - this.dispersion = false, - this.batchingColor = false, - - this.iridescence = false, - this.iridescenceMap = false, - this.iridescenceThicknessMap = false, - - this.sheen = false, - this.sheenColorMap = false, - this.sheenRoughnessMap = false, - - this.specularMap = false, - this.specularIntensityMap = false, - this.specularColorMap = false, - - this.transmission = false, - this.transmissionMap = false, - this.thicknessMap = false, - - this.gradientMap = false, - - this.opaque = false, - - this.alphaMap = false, - this.alphaTest = false, - this.alphaHash = false, - - this.combine, - - this.mapUv, - this.aoMapUv, - this.lightMapUv, - this.bumpMapUv, - this.normalMapUv, - this.displacementMapUv, - this.emissiveMapUv, - - this.metalnessMapUv, - this.roughnessMapUv, - - this.anisotropyMapUv, - - this.clearcoatMapUv, - this.clearcoatNormalMapUv, - this.clearcoatRoughnessMapUv, - - this.iridescenceMapUv, - this.iridescenceThicknessMapUv, - - this.sheenColorMapUv, - this.sheenRoughnessMapUv, - - this.specularMapUv, - this.specularColorMapUv, - this.specularIntensityMapUv, - - this.transmissionMapUv, - this.thicknessMapUv, - - this.alphaMapUv, - - this.vertexTangents = false, - this.vertexColors = false, - this.vertexAlphas = false, - - this.pointsUvs = false, - this.fog = false, - this.useFog = false, - this.fogExp2 = false, - - this.flatShading = false, - - this.sizeAttenuation = false, - this.logarithmicDepthBuffer = false, - - this.skinning = false, - - this.morphTargets = false, - this.morphNormals = false, - this.morphColors = false, - this.morphTargetsCount = 0, - this.morphTextureStride, - - this.numDirLights = 0, - this.numPointLights = 0, - this.numSpotLights = 0, - this.numSpotLightMaps = 0, - this.numRectAreaLights = 0, - this.numHemiLights = 0, - - this.numDirLightShadows = 0, - this.numPointLightShadows = 0, - this.numSpotLightShadows = 0, - this.numSpotLightShadowsWithMaps = 0, - this.numLightProbes = 0, - this.numClippingPlanes = 0, - this.numClipIntersection = 0, - - this.dithering = false, - - this.shadowMapEnabled = false, - this.shadowMapType, - - this.toneMapping, - this.useLegacyLights = false, - - this.decodeVideoTexture = false, - this.decodeVideoTextureEmissive = false, - - this.premultipliedAlpha = false, - - this.doubleSided = false, - this.flipSided = false, - - this.useDepthPacking = false, - this.depthPacking, - - this.index0AttributeName, - - this.extensionClipCullDistance = false, - this.extensionMultiDraw = false, - this.rendererExtensionParallelShaderCompile = false, - this.customProgramCacheKey, - }); - - WebGLParameters.fromJson(Map json) { - shaderID = json['shaderID']; - shaderType = json['shaderType']; - shaderName = json['shaderName'] ?? ''; - - vertexShader = json['vertexShader'] ?? ''; - fragmentShader = json['fragmentShader'] ?? ''; - defines = json['defines']; - - customVertexShaderID = json['customVertexShaderID']; - customFragmentShaderID = json['customFragmentShaderID']; - - isRawShaderMaterial = json['isRawShaderMaterial'] ?? false; - glslVersion = json['glslVersion']; - - precision = json['precision'] ?? ''; - batching = json['batching'] ?? false; - instancing = json['instancing'] ?? false; - instancingColor = json['instancingColor'] ?? false; - instancingMorph = json['instancingMorph'] ?? false; - - supportsVertexTextures = json['supportsVertexTextures'] ?? false; - outputColorSpace = json['outputColorSpace'] ?? NoColorSpace; - alphaToCoverage = json['alphaToCoverage'] ?? false; - - map = json['map'] ?? false; - matcap = json['matcap'] ?? false; - envMap = json['envMap'] ?? false; - envMapMode = json['envMapMode'] ?? false; - envMapCubeUVHeight = json['envMapCubeUVHeight']; - lightMap = json['lightMap'] ?? false; - aoMap = json['aoMap'] ?? false; - emissiveMap = json['emissiveMap'] ?? false; - bumpMap = json['bumpMap'] ?? false; - normalMap = json['normalMap'] ?? false; - - normalMapObjectSpace = json['normalMapObjectSpace'] ?? false; - normalMapTangentSpace = json['normalMapTangentSpace'] ?? false; - roughnessMap = json['roughnessMap'] ?? false; - metalnessMap = json['metalnessMap'] ?? false; - - anisotropy = json['anisotropy'] ?? false; - anisotropyMap = json['anisotropyMap'] ?? false; - - clearcoat = json['clearcoat'] ?? false; - clearcoatMap = json['clearcoatMap'] ?? false; - clearcoatRoughnessMap = json['clearcoatRoughnessMap'] ?? false; - clearcoatNormalMap = json['clearcoatNormalMap'] ?? false; - - displacementMap = json['displacementMap'] ?? false; - - iridescence = json['iridescence'] ?? false; - iridescenceMap = json['iridescenceMap'] ?? false; - iridescenceThicknessMap = json['iridescenceThicknessMap'] ?? false; - - sheen = json['sheen'] ?? false; - sheenColorMap = json['sheenColorMap'] ?? false; - sheenRoughnessMap = json['sheenRoughnessMap'] ?? false; - - specularMap = json['specularMap'] ?? false; - specularIntensityMap = json['specularIntensityMap'] ?? false; - specularColorMap = json['specularColorMap'] ?? false; - - transmission = json['transmission'] ?? false; - transmissionMap = json['transmissionMap'] ?? false; - thicknessMap = json['thicknessMap'] ?? false; - - gradientMap = json['gradientMap'] ?? false; - - opaque = json['opaque'] ?? false; - dispersion = json['dispersion'] ?? false; - batchingColor = json['batchingColor'] ?? false; - - alphaMap = json['alphaMap'] ?? false; - alphaTest = json['alphaTest'] ?? false; - alphaHash = json['alphaHash'] ?? false; - - combine = json['combine']; - - mapUv = json['mapUv']; - aoMapUv = json['aoMapUv']; - lightMapUv = json['lightMapUv']; - bumpMapUv = json['bumpMapUv']; - normalMapUv = json['normalMapUv']; - displacementMapUv = json['displacementMapUv']; - emissiveMapUv = json['emissiveMapUv']; - - metalnessMapUv = json['metalnessMapUv']; - roughnessMapUv = json['roughnessMapUv']; - - anisotropyMapUv = json['anisotropyMapUv']; - - clearcoatMapUv = json['clearcoatMapUv']; - clearcoatNormalMapUv = json['clearcoatNormalMapUv']; - clearcoatRoughnessMapUv = json['clearcoatRoughnessMapUv']; - - iridescenceMapUv = json['iridescenceMapUv']; - iridescenceThicknessMapUv = json['iridescenceThicknessMapUv']; - - sheenColorMapUv = json['sheenColorMapUv']; - sheenRoughnessMapUv = json['sheenRoughnessMapUv']; - - specularMapUv = json['specularMapUv']; - specularColorMapUv = json['specularColorMapUv']; - specularIntensityMapUv = json['specularIntensityMapUv']; - - transmissionMapUv = json['transmissionMapUv']; - thicknessMapUv = json['thicknessMapUv']; - - alphaMapUv = json['alphaMapUv']; - - vertexTangents = json['vertexTangents'] ?? false; - vertexColors = json['vertexColors'] ?? false; - vertexAlphas = json['vertexAlphas'] ?? false; - - vertexUvs = json['vertexUvs'] ?? false; - - fog = json['fog'] ?? false; - useFog = json['useFog'] ?? false; - fogExp2 = json['fogExp2'] ?? false; - - flatShading = json['flatShading'] ?? false; - - sizeAttenuation = json['sizeAttenuation'] ?? false; - logarithmicDepthBuffer = json['logarithmicDepthBuffer'] ?? false; - - skinning = json['skinning'] ?? false; - - morphTargets = json['morphTargets'] ?? false; - morphNormals = json['morphNormals'] ?? false; - morphColors = json['morphColors'] ?? false; - morphTargetsCount = json['morphTargetsCount'] ?? 0; - morphTextureStride = json['morphTextureStride']; - - numDirLights = json['numDirLights'] ?? 0; - numPointLights = json['numPointLights'] ?? 0; - numSpotLights = json['numSpotLights'] ?? 0; - numSpotLightMaps = json['numSpotLightMaps'] ?? 0; - numRectAreaLights = json['numRectAreaLights'] ?? 0; - numHemiLights = json['numHemiLights'] ?? 0; - - numDirLightShadows = json['numDirLightShadows'] ?? 0; - numPointLightShadows = json['numPointLightShadows'] ?? 0; - numSpotLightShadows = json['numSpotLightShadows'] ?? 0; - numSpotLightShadowsWithMaps = json['numSpotLightShadowsWithMaps'] ?? 0; - - numLightProbes = json['numLightProbes'] ?? 0; - - numClippingPlanes = json['numClippingPlanes'] ?? 0; - numClipIntersection = json['numClipIntersection'] ?? 0; - - dithering = json['dithering'] ?? false; - - shadowMapEnabled = json['shadowMapEnabled'] ?? false; - shadowMapType = json['shadowMapType']; - - toneMapping = json['toneMapping']; - useLegacyLights = json['useLegacyLights'] ?? false; - - decodeVideoTexture = json['decodeVideoTexture'] ?? false; - decodeVideoTextureEmissive = json['decodeVideoTextureEmissive'] ?? false; - - premultipliedAlpha = json['premultipliedAlpha'] ?? false; - - doubleSided = json['doubleSided'] ?? false; - flipSided = json['flipSided'] ?? false; - - useDepthPacking = json['useDepthPacking'] ?? false; - depthPacking = json['depthPacking']; - - index0AttributeName = json['index0AttributeName']; - - pointsUvs = json['pointsUvs'] ?? false; - - extensionClipCullDistance = json['extensionClipCullDistance'] ?? false; - extensionMultiDraw = json['extensionMultiDraw'] ?? false; - - customProgramCacheKey = json['customProgramCacheKey']; - - tangentSpaceNormalMap = json["tangentSpaceNormalMap"]; - objectSpaceNormalMap = json["objectSpaceNormalMap"]; - uvsVertexOnly = json["uvsVertexOnly"]; - outputEncoding = json["outputEncoding"]; - } - - getValue(String name) { - Map json = toJson(); - - return json[name]; - } - - toJson() { - Map json = { - "shaderID": shaderID, - "customVertexShaderID": customVertexShaderID, - "customFragmentShaderID": customFragmentShaderID, - "shaderName": shaderName, - "vertexShader": vertexShader, - "fragmentShader": fragmentShader, - "defines": defines, - "isRawShaderMaterial": isRawShaderMaterial, - "glslVersion": glslVersion, - "precision": precision, - "instancing": instancing, - "instancingColor": instancingColor, - "supportsVertexTextures": supportsVertexTextures, - "outputColorSpace": outputColorSpace, - "outputEncoding": outputEncoding, - 'opaque': opaque, - 'dispersion': dispersion, - 'batchingColor': batchingColor, - "map": map, - "matcap": matcap, - "envMap": envMap, - "envMapMode": envMapMode, - "lightMap": lightMap, - "aoMap": aoMap, - "emissiveMap": emissiveMap, - "bumpMap": bumpMap, - "normalMap": normalMap, - "normalMapObjectSpace": normalMapObjectSpace, - "normalMapTangentSpace": normalMapTangentSpace, - "clearcoat": clearcoat, - "clearcoatMap": clearcoatMap, - "clearcoatRoughnessMap": clearcoatRoughnessMap, - "clearcoatNormalMap": clearcoatNormalMap, - "displacementMap": displacementMap, - "roughnessMap": roughnessMap, - "metalnessMap": metalnessMap, - "specularMap": specularMap, - "specularIntensityMap": specularIntensityMap, - "specularColorMap": specularColorMap, - "alphaMap": alphaMap, - "gradientMap": gradientMap, - "sheenColorMap": sheenColorMap, - "sheenRoughnessMap": sheenRoughnessMap, - "sheen": sheen, - "transmission": transmission, - "transmissionMap": transmissionMap, - "transmissionMapUv": transmissionMapUv, - "thicknessMap": thicknessMap, - "combine": combine, - "vertexTangents": vertexTangents, - "vertexColors": vertexColors, - "vertexUvs": vertexUvs, - "uvsVertexOnly": uvsVertexOnly, - "pointsUvs": pointsUvs, - "fog": fog, - "useFog": useFog, - "fogExp2": fogExp2, - "flatShading": flatShading, - "sizeAttenuation": sizeAttenuation, - "logarithmicDepthBuffer": logarithmicDepthBuffer, - "skinning": skinning, - "morphTargets": morphTargets, - "morphNormals": morphNormals, - "morphColors": morphColors, - "numDirLights": numDirLights, - "numPointLights": numPointLights, - "numSpotLights": numSpotLights, - "numRectAreaLights": numRectAreaLights, - "numHemiLights": numHemiLights, - "numDirLightShadows": numDirLightShadows, - "numPointLightShadows": numPointLightShadows, - "numSpotLightShadows": numSpotLightShadows, - "numClippingPlanes": numClippingPlanes, - "numClipIntersection": numClipIntersection, - "dithering": dithering, - "shadowMapEnabled": shadowMapEnabled, - "shadowMapType": shadowMapType, - "toneMapping": toneMapping, - "physicallyCorrectLights": physicallyCorrectLights, - "useLegacyLights": useLegacyLights, - "premultipliedAlpha": premultipliedAlpha, - "alphaTest": alphaTest, - "doubleSided": doubleSided, - "flipSided": flipSided, - "useDepthPacking": useDepthPacking, - "depthPacking": depthPacking, - "index0AttributeName": index0AttributeName, - "extensionDerivatives": extensionDerivatives, - "extensionFragDepth": extensionFragDepth, - "extensionDrawBuffers": extensionDrawBuffers, - "extensionShaderTextureLOD": extensionShaderTextureLOD, - "rendererExtensionFragDepth": rendererExtensionFragDepth, - "rendererExtensionDrawBuffers": rendererExtensionDrawBuffers, - "rendererExtensionShaderTextureLod": rendererExtensionShaderTextureLod, - "customProgramCacheKey": customProgramCacheKey, - "uniforms": uniforms, - "vertexAlphas": vertexAlphas, - "decodeVideoTexture": decodeVideoTexture, - 'decodeVideoTextureEmissive': decodeVideoTextureEmissive, - "morphTargetsCount": morphTargetsCount, - "cubeUVHeight": cubeUVHeight, - "envMapCubeUVHeight": envMapCubeUVHeight, - "morphTextureStride": morphTextureStride - }; - - return json; - } -} diff --git a/packages/three_js_webgl_renderer/lib/webgl/web_gl_program.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_program.dart index c14f7aa4..0deac3bc 100755 --- a/packages/three_js_webgl_renderer/lib/webgl/web_gl_program.dart +++ b/packages/three_js_webgl_renderer/lib/webgl/web_gl_program.dart @@ -15,7 +15,7 @@ class WebGLProgram extends DefaultProgram with WebGLProgramExtra { WebGLBindingStates bindingStates; int usedTimes = 1; late RenderingContext gl; - WebGLParameters parameters; + Parameters parameters; late Program? program; late String vertexShader; diff --git a/packages/three_js_webgl_renderer/lib/webgl/web_gl_program_extra.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_program_extra.dart index a60ed547..3fec8a64 100755 --- a/packages/three_js_webgl_renderer/lib/webgl/web_gl_program_extra.dart +++ b/packages/three_js_webgl_renderer/lib/webgl/web_gl_program_extra.dart @@ -123,7 +123,7 @@ mixin WebGLProgramExtra { return 'vec3 $functionName( vec3 color ) { return ${toneMappingName}ToneMapping( color ); }'; } - String generateVertexExtensions(WebGLParameters parameters) { + String generateVertexExtensions(Parameters parameters) { final chunks = [ parameters.extensionClipCullDistance ? '#extension GL_ANGLE_clip_cull_distance : require' : '', parameters.extensionMultiDraw ? '#extension GL_ANGLE_multi_draw : require' : '', @@ -183,7 +183,7 @@ mixin WebGLProgramExtra { return string != ''; } - String replaceLightNums(String string, WebGLParameters parameters) { + String replaceLightNums(String string, Parameters parameters) { final numSpotLightCoords = parameters.numSpotLightShadows + parameters.numSpotLightMaps - parameters.numSpotLightShadowsWithMaps; string = string.replaceAll("NUM_DIR_LIGHTS", parameters.numDirLights.toString() ); @@ -201,7 +201,7 @@ mixin WebGLProgramExtra { return string; } - String replaceClippingPlaneNums(String string, WebGLParameters parameters) { + String replaceClippingPlaneNums(String string, Parameters parameters) { string = string.replaceAll("NUM_CLIPPING_PLANES", parameters.numClippingPlanes.toString()); string = string.replaceAll("UNION_CLIPPING_PLANES", (parameters.numClippingPlanes - parameters.numClipIntersection).toString()); @@ -309,7 +309,7 @@ mixin WebGLProgramExtra { // - String generatePrecision(WebGLParameters parameters) { + String generatePrecision(Parameters parameters) { String precisionstring = '''precision ${parameters.precision} float; precision ${parameters.precision} int; precision ${parameters.precision} sampler2D; @@ -340,7 +340,7 @@ mixin WebGLProgramExtra { return precisionstring; } - String generateShadowMapTypeDefine(WebGLParameters parameters) { + String generateShadowMapTypeDefine(Parameters parameters) { String shadowMapTypeDefine = 'SHADOWMAP_TYPE_BASIC'; if (parameters.shadowMapType == PCFShadowMap) { @@ -354,7 +354,7 @@ mixin WebGLProgramExtra { return shadowMapTypeDefine; } - String generateEnvMapTypeDefine(WebGLParameters parameters) { + String generateEnvMapTypeDefine(Parameters parameters) { String envMapTypeDefine = 'ENVMAP_TYPE_CUBE'; if (parameters.envMap) { @@ -373,7 +373,7 @@ mixin WebGLProgramExtra { return envMapTypeDefine; } - String generateEnvMapModeDefine (WebGLParameters parameters) { + String generateEnvMapModeDefine (Parameters parameters) { String envMapModeDefine = 'ENVMAP_MODE_REFLECTION'; if (parameters.envMap) { @@ -387,7 +387,7 @@ mixin WebGLProgramExtra { return envMapModeDefine; } - String generateEnvMapBlendingDefine(WebGLParameters parameters) { + String generateEnvMapBlendingDefine(Parameters parameters) { String envMapBlendingDefine = 'ENVMAP_BLENDING_NONE'; if (parameters.envMap) { @@ -409,7 +409,7 @@ mixin WebGLProgramExtra { return envMapBlendingDefine; } - Map? generateCubeUVSize(WebGLParameters parameters) { + Map? generateCubeUVSize(Parameters parameters) { final imageHeight = parameters.envMapCubeUVHeight; if (imageHeight == null) return null; diff --git a/packages/three_js_webgl_renderer/lib/webgl/web_gl_programs.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_programs.dart index edc06e6f..407e7e32 100755 --- a/packages/three_js_webgl_renderer/lib/webgl/web_gl_programs.dart +++ b/packages/three_js_webgl_renderer/lib/webgl/web_gl_programs.dart @@ -63,7 +63,7 @@ class WebGLPrograms { return 'uv$value'; } - WebGLParameters getParameters(Material material, LightState lights, List shadows, Scene scene, Object3D object) { + Parameters getParameters(Material material, LightState lights, List shadows, Scene scene, Object3D object) { final fog = scene.fog; final geometry = object.geometry; final environment = material is MeshStandardMaterial ? scene.environment : null; @@ -121,7 +121,7 @@ class WebGLPrograms { final useAlphaTest = material.alphaTest > 0; final useClearcoat = material.clearcoat > 0; - final parameters = WebGLParameters( + final parameters = Parameters( shaderID: shaderID, shaderType: material.type, shaderName: "${material.type} - ${material.name}", @@ -319,7 +319,7 @@ class WebGLPrograms { return parameters; } - String getProgramCacheKey(WebGLParameters parameters) { + String getProgramCacheKey(Parameters parameters) { List array = []; if (parameters.shaderID != null) { @@ -347,7 +347,7 @@ class WebGLPrograms { return array.join(); } - void getProgramCacheKeyParameters(List array, WebGLParameters parameters) { + void getProgramCacheKeyParameters(List array, Parameters parameters) { array.add( parameters.precision ); array.add( parameters.outputColorSpace ); array.add( parameters.envMapMode ); @@ -398,7 +398,7 @@ class WebGLPrograms { array.add( parameters.depthPacking ); } - void getProgramCacheKeyBooleans(List array, WebGLParameters parameters) { + void getProgramCacheKeyBooleans(List array, Parameters parameters) { _programLayers.disableAll(); @@ -468,7 +468,7 @@ class WebGLPrograms { return uniforms; } - WebGLProgram? acquireProgram(WebGLParameters parameters, String cacheKey) { + WebGLProgram? acquireProgram(Parameters parameters, String cacheKey) { WebGLProgram? program; // Check if code has been already compiled diff --git a/packages/three_js_webgl_renderer/lib/webgl/web_gl_shadow_map.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_shadow_map.dart index b573575d..3cf25ef3 100755 --- a/packages/three_js_webgl_renderer/lib/webgl/web_gl_shadow_map.dart +++ b/packages/three_js_webgl_renderer/lib/webgl/web_gl_shadow_map.dart @@ -1,38 +1,17 @@ part of three_webgl; -class WebGLShadowMap { +class WebGLShadowMap extends ShadowMap { bool _didDispose = false; Frustum _frustum = Frustum(); final _shadowMapSize = Vector2.zero(); final _viewportSize = Vector2.zero(); final _viewport = Vector4.identity(); - final shadowSide = {0: BackSide, 1: FrontSide, 2: DoubleSide}; - - // HashMap _depthMaterials = HashMap(); - // HashMap _distanceMaterials = HashMap(); - late MeshDepthMaterial _depthMaterial; late MeshDistanceMaterial _distanceMaterial; final _materialCache = {}; - late ShaderMaterial shadowMaterialVertical; - late ShaderMaterial shadowMaterialHorizontal; - - BufferGeometry fullScreenTri = BufferGeometry(); - - late Mesh fullScreenMesh; - - bool enabled = false; - - bool autoUpdate = true; - bool needsUpdate = false; - - int type = PCFShadowMap; - - late WebGLShadowMap scope; - final WebGLRenderer _renderer; final WebGLObjects _objects; final WebGLCapabilities _capabilities; @@ -101,7 +80,7 @@ class WebGLShadowMap { final activeCubeFace = _renderer.getActiveCubeFace(); final activeMipmapLevel = _renderer.getActiveMipmapLevel(); - final state = _renderer.state; + final state = _renderer.state as WebGLState; // Set GL state for depth map. state.setBlending(NoBlending); @@ -151,7 +130,7 @@ class WebGLShadowMap { shadow.map?.dispose(); } - shadow.map = WebGLRenderTarget(_shadowMapSize.x.toInt(), _shadowMapSize.y.toInt(), RenderTargetOptions(pars)); + shadow.map = RenderTarget(_shadowMapSize.x.toInt(), _shadowMapSize.y.toInt(), RenderTargetOptions(pars)); shadow.map!.texture.name = '${light.name}.shadowMap'; shadow.camera!.updateProjectionMatrix(); @@ -196,7 +175,7 @@ class WebGLShadowMap { shadowMaterialHorizontal.needsUpdate = true; } - shadow.mapPass ??= WebGLRenderTarget( _shadowMapSize.x.toInt(), _shadowMapSize.y.toInt() ); + shadow.mapPass ??= RenderTarget( _shadowMapSize.x.toInt(), _shadowMapSize.y.toInt() ); // vertical pass diff --git a/packages/three_js_webgl_renderer/lib/webgl/web_gl_state.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_state.dart index 3478cf31..db4d8629 100755 --- a/packages/three_js_webgl_renderer/lib/webgl/web_gl_state.dart +++ b/packages/three_js_webgl_renderer/lib/webgl/web_gl_state.dart @@ -1,6 +1,6 @@ part of three_webgl; -class WebGLState { +class WebGLState extends State{ bool _didDispose = false; RenderingContext gl; @@ -14,6 +14,7 @@ class WebGLState { late Map equationToGL; late Map factorToGL; + @override Map get buffers => {"color": colorBuffer, "depth": depthBuffer, "stencil": stencilBuffer}; Map enabledCapabilities = {}; @@ -144,6 +145,7 @@ class WebGLState { return texture; } + @override void enable(id) { if (enabledCapabilities[id] != true) { gl.enable(id); @@ -151,6 +153,7 @@ class WebGLState { } } + @override void disable(id) { if (enabledCapabilities[id] != false) { gl.disable(id); @@ -619,6 +622,7 @@ class WebGLState { gl.texImage3D(target, level, internalformat, width, height, depth, border, format, type, offset); } + @override void scissor(Vector4 scissor) { if (!currentScissor.equals(scissor)) { gl.scissor(scissor.x.toInt(), scissor.y.toInt(), scissor.z.toInt(), scissor.w.toInt()); @@ -626,6 +630,7 @@ class WebGLState { } } + @override void viewport(Vector4 viewport) { if (!currentViewport.equals(viewport)) { gl.viewport(viewport.x.toInt(), viewport.y.toInt(), viewport.z.toInt(), viewport.w.toInt()); @@ -659,6 +664,7 @@ class WebGLState { } } + @override void reset() { gl.disable(WebGL.BLEND); gl.disable(WebGL.CULL_FACE); @@ -738,6 +744,7 @@ class WebGLState { stencilBuffer.reset(); } + @override void dispose(){ if(_didDispose) return; _didDispose = true; diff --git a/packages/three_js_webgl_renderer/lib/webgl/web_gl_textures.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_textures.dart index 0f580d66..f4b13643 100755 --- a/packages/three_js_webgl_renderer/lib/webgl/web_gl_textures.dart +++ b/packages/three_js_webgl_renderer/lib/webgl/web_gl_textures.dart @@ -284,7 +284,7 @@ class WebGLTextures { properties.remove( renderTarget.depthTexture ); } - if (renderTarget is WebGLCubeRenderTarget) { + if (renderTarget is CubeRenderTarget) { for (int i = 0; i < 6; i++) { gl.deleteFramebuffer(renderTargetProperties["__webglFramebuffer"][i]); if (renderTargetProperties['__webglFramebuffer'][ i ] is List) { @@ -1055,7 +1055,7 @@ class WebGLTextures { // Setup resources for a Depth Texture for a FBO (needs an extension) void setupDepthTexture(framebuffer, RenderTarget renderTarget) { final renderTargetProperties = properties.get( renderTarget ); - final isCube = renderTarget is WebGLCubeRenderTarget; + final isCube = renderTarget is CubeRenderTarget; // if the bound depth texture has changed if ( renderTargetProperties['__boundDepthTexture'] != renderTarget.depthTexture ) { @@ -1122,7 +1122,7 @@ class WebGLTextures { // Setup GL resources for a non-texture depth buffer void setupDepthRenderbuffer(RenderTarget renderTarget) { final renderTargetProperties = properties.get( renderTarget ); - final isCube = ( renderTarget is WebGLCubeRenderTarget == true ); + final isCube = ( renderTarget is CubeRenderTarget == true ); // if the bound depth texture has changed if ( renderTargetProperties['__boundDepthTexture'] != renderTarget.depthTexture ) { @@ -1210,7 +1210,7 @@ class WebGLTextures { final textures = renderTarget.textures; - final isCube = renderTarget is WebGLCubeRenderTarget; + final isCube = renderTarget is CubeRenderTarget; final isMultipleRenderTargets = ( textures.length > 1 ); if ( ! isMultipleRenderTargets ) { @@ -1368,7 +1368,7 @@ class WebGLTextures { final texture = textures[i]; if (textureNeedsGenerateMipmaps(texture)) { - final target = renderTarget is WebGLCubeRenderTarget ? WebGL.TEXTURE_CUBE_MAP : WebGL.TEXTURE_2D; + final target = renderTarget is CubeRenderTarget ? WebGL.TEXTURE_CUBE_MAP : WebGL.TEXTURE_2D; final webglTexture = properties.get(texture)["__webglTexture"]; state.bindTexture(target, webglTexture); diff --git a/three_js_editor/lib/ui/line_material.dart b/three_js_editor/lib/ui/line_material.dart deleted file mode 100644 index 92449a23..00000000 --- a/three_js_editor/lib/ui/line_material.dart +++ /dev/null @@ -1,532 +0,0 @@ -import 'dart:typed_data'; - -import 'package:three_js/three_js.dart'; - - -class LineMaterial extends ShaderMaterial { - - LineMaterial([Map? parameters]):super(parameters) { - _init(); - if (parameters != null) { - if (parameters[MaterialProperty.attributes] != null) { - console.warning('ShaderMaterial: attributes should now be defined in BufferGeometry instead.'); - } - - setValues(parameters); - } - } - - LineMaterial.fromMap([Map? parameters]) : super.fromMap(parameters) { - _init(); - if (parameters != null) { - if (parameters['attributes'] != null) { - console.warning('ShaderMaterial: attributes should now be defined in BufferGeometry instead.'); - } - - setValuesFromString(parameters); - } - } - - void _init(){ - uniformsLib['line'] = { - 'worldUnits': { 'value': 1.0 }, - 'linewidth': { 'value': 1.0 }, - 'resolution': { 'value': Vector2( 1.0, 1.0 ) }, - 'dashOffset': { 'value': 0.0 }, - 'dashScale': { 'value': 1.0 }, - 'dashSize': { 'value': 1.0 }, - 'gapSize': { 'value': 1.0 } // todo FIX - maybe change to totalSize - }; - - shaderLib[ 'line' ] = { - 'uniforms': UniformsUtils.merge( [ - uniformsLib['common'], - uniformsLib['fog'], - uniformsLib['line'] - ] ), - - 'vertexShader': - /* glsl */''' - #include - #include - #include - #include - #include - - uniform float linewidth; - uniform vec2 resolution; - - attribute vec3 instanceStart; - attribute vec3 instanceEnd; - - attribute vec3 instanceColorStart; - attribute vec3 instanceColorEnd; - - #ifdef WORLD_UNITS - - varying vec4 worldPos; - varying vec3 worldStart; - varying vec3 worldEnd; - - #ifdef USE_DASH - - varying vec2 vUv; - - #endif - - #else - - varying vec2 vUv; - - #endif - - #ifdef USE_DASH - - uniform float dashScale; - attribute float instanceDistanceStart; - attribute float instanceDistanceEnd; - varying float vLineDistance; - - #endif - - void trimSegment( const in vec4 start, inout vec4 end ) { - - // trim end segment so it terminates between the camera plane and the near plane - - // conservative estimate of the near plane - float a = projectionMatrix[ 2 ][ 2 ]; // 3nd entry in 3th column - float b = projectionMatrix[ 3 ][ 2 ]; // 3nd entry in 4th column - float nearEstimate = - 0.5 * b / a; - - float alpha = ( nearEstimate - start.z ) / ( end.z - start.z ); - - end.xyz = mix( start.xyz, end.xyz, alpha ); - - } - - void main() { - - #ifdef USE_COLOR - - vColor.xyz = ( position.y < 0.5 ) ? instanceColorStart : instanceColorEnd; - - #endif - - #ifdef USE_DASH - - vLineDistance = ( position.y < 0.5 ) ? dashScale * instanceDistanceStart : dashScale * instanceDistanceEnd; - vUv = uv; - - #endif - - float aspect = resolution.x / resolution.y; - - // camera space - vec4 start = modelViewMatrix * vec4( instanceStart, 1.0 ); - vec4 end = modelViewMatrix * vec4( instanceEnd, 1.0 ); - - #ifdef WORLD_UNITS - - worldStart = start.xyz; - worldEnd = end.xyz; - - #else - - vUv = uv; - - #endif - - // special case for perspective projection, and segments that terminate either in, or behind, the camera plane - // clearly the gpu firmware has a way of addressing this issue when projecting into ndc space - // but we need to perform ndc-space calculations in the shader, so we must address this issue directly - // perhaps there is a more elegant solution -- WestLangley - - bool perspective = ( projectionMatrix[ 2 ][ 3 ] == - 1.0 ); // 4th entry in the 3rd column - - if ( perspective ) { - - if ( start.z < 0.0 && end.z >= 0.0 ) { - - trimSegment( start, end ); - - } else if ( end.z < 0.0 && start.z >= 0.0 ) { - - trimSegment( end, start ); - - } - - } - - // clip space - vec4 clipStart = projectionMatrix * start; - vec4 clipEnd = projectionMatrix * end; - - // ndc space - vec3 ndcStart = clipStart.xyz / clipStart.w; - vec3 ndcEnd = clipEnd.xyz / clipEnd.w; - - // direction - vec2 dir = ndcEnd.xy - ndcStart.xy; - - // account for clip-space aspect ratio - dir.x *= aspect; - dir = normalize( dir ); - - #ifdef WORLD_UNITS - - vec3 worldDir = normalize( end.xyz - start.xyz ); - vec3 tmpFwd = normalize( mix( start.xyz, end.xyz, 0.5 ) ); - vec3 worldUp = normalize( cross( worldDir, tmpFwd ) ); - vec3 worldFwd = cross( worldDir, worldUp ); - worldPos = position.y < 0.5 ? start: end; - - // height offset - float hw = linewidth * 0.5; - worldPos.xyz += position.x < 0.0 ? hw * worldUp : - hw * worldUp; - - // don't extend the line if we're rendering dashes because we - // won't be rendering the endcaps - #ifndef USE_DASH - - // cap extension - worldPos.xyz += position.y < 0.5 ? - hw * worldDir : hw * worldDir; - - // add width to the box - worldPos.xyz += worldFwd * hw; - - // endcaps - if ( position.y > 1.0 || position.y < 0.0 ) { - - worldPos.xyz -= worldFwd * 2.0 * hw; - - } - - #endif - - // project the worldpos - vec4 clip = projectionMatrix * worldPos; - - // shift the depth of the projected points so the line - // segments overlap neatly - vec3 clipPose = ( position.y < 0.5 ) ? ndcStart : ndcEnd; - clip.z = clipPose.z * clip.w; - - #else - - vec2 offset = vec2( dir.y, - dir.x ); - // undo aspect ratio adjustment - dir.x /= aspect; - offset.x /= aspect; - - // sign flip - if ( position.x < 0.0 ) offset *= - 1.0; - - // endcaps - if ( position.y < 0.0 ) { - - offset += - dir; - - } else if ( position.y > 1.0 ) { - - offset += dir; - - } - - // adjust for linewidth - offset *= linewidth; - - // adjust for clip-space to screen-space conversion // maybe resolution should be based on viewport ... - offset /= resolution.y; - - // select end - vec4 clip = ( position.y < 0.5 ) ? clipStart : clipEnd; - - // back to clip space - offset *= clip.w; - - clip.xy += offset; - - #endif - - gl_Position = clip; - - vec4 mvPosition = ( position.y < 0.5 ) ? start : end; // this is an approximation - - #include - #include - #include - - } - ''', - - 'fragmentShader': - /* glsl */''' - uniform vec3 diffuse; - uniform float opacity; - uniform float linewidth; - - #ifdef USE_DASH - - uniform float dashOffset; - uniform float dashSize; - uniform float gapSize; - - #endif - - varying float vLineDistance; - - #ifdef WORLD_UNITS - - varying vec4 worldPos; - varying vec3 worldStart; - varying vec3 worldEnd; - - #ifdef USE_DASH - - varying vec2 vUv; - - #endif - - #else - - varying vec2 vUv; - - #endif - - #include - #include - #include - #include - #include - - vec2 closestLineToLine(vec3 p1, vec3 p2, vec3 p3, vec3 p4) { - - float mua; - float mub; - - vec3 p13 = p1 - p3; - vec3 p43 = p4 - p3; - - vec3 p21 = p2 - p1; - - float d1343 = dot( p13, p43 ); - float d4321 = dot( p43, p21 ); - float d1321 = dot( p13, p21 ); - float d4343 = dot( p43, p43 ); - float d2121 = dot( p21, p21 ); - - float denom = d2121 * d4343 - d4321 * d4321; - - float numer = d1343 * d4321 - d1321 * d4343; - - mua = numer / denom; - mua = clamp( mua, 0.0, 1.0 ); - mub = ( d1343 + d4321 * ( mua ) ) / d4343; - mub = clamp( mub, 0.0, 1.0 ); - - return vec2( mua, mub ); - - } - - void main() { - - #include - - #ifdef USE_DASH - - if ( vUv.y < - 1.0 || vUv.y > 1.0 ) discard; // discard endcaps - - if ( mod( vLineDistance + dashOffset, dashSize + gapSize ) > dashSize ) discard; // todo - FIX - - #endif - - float alpha = opacity; - - #ifdef WORLD_UNITS - - // Find the closest points on the view ray and the line segment - vec3 rayEnd = normalize( worldPos.xyz ) * 1e5; - vec3 lineDir = worldEnd - worldStart; - vec2 params = closestLineToLine( worldStart, worldEnd, vec3( 0.0, 0.0, 0.0 ), rayEnd ); - - vec3 p1 = worldStart + lineDir * params.x; - vec3 p2 = rayEnd * params.y; - vec3 delta = p1 - p2; - float len = length( delta ); - float norm = len / linewidth; - - #ifndef USE_DASH - - #ifdef USE_ALPHA_TO_COVERAGE - - float dnorm = fwidth( norm ); - alpha = 1.0 - smoothstep( 0.5 - dnorm, 0.5 + dnorm, norm ); - - #else - - if ( norm > 0.5 ) { - - discard; - - } - - #endif - - #endif - - #else - - #ifdef USE_ALPHA_TO_COVERAGE - - // artifacts appear on some hardware if a derivative is taken within a conditional - float a = vUv.x; - float b = ( vUv.y > 0.0 ) ? vUv.y - 1.0 : vUv.y + 1.0; - float len2 = a * a + b * b; - float dlen = fwidth( len2 ); - - if ( abs( vUv.y ) > 1.0 ) { - - alpha = 1.0 - smoothstep( 1.0 - dlen, 1.0 + dlen, len2 ); - - } - - #else - - if ( abs( vUv.y ) > 1.0 ) { - - float a = vUv.x; - float b = ( vUv.y > 0.0 ) ? vUv.y - 1.0 : vUv.y + 1.0; - float len2 = a * a + b * b; - - if ( len2 > 1.0 ) discard; - - } - - #endif - - #endif - - vec4 diffuseColor = vec4( diffuse, alpha ); - - #include - #include - - gl_FragColor = vec4( diffuseColor.rgb, alpha ); - - #include - #include - #include - #include - - } - ''' - }; - type = 'LineMaterial'; - uniforms = UniformsUtils.clone( shaderLib[ 'line' ]['uniforms'] ); - vertexShader = shaderLib[ 'line' ]['vertexShader']; - fragmentShader = shaderLib[ 'line' ]['fragmentShader']; - clipping = true; // required for clipping support - - defaultAttributeValues = { - 'color': Float32List.fromList([1.0, 1.0, 1.0]), - 'uv': Float32List.fromList([0.0, 0.0]), - 'uv2': Float32List.fromList([0.0, 0.0]) - }; - } - - // @override - // get color => uniforms['diffuse']['value']; - // @override - // set color( value ) { - // uniforms['diffuse']['value'] = value; - // } - - get worldUnits => defines?.containsKey('WORLD_UNITS'); - - set worldUnits( value ) { - - if ( value == true ) { - defines?['WORLD_UNITS'] = ''; - } - else { - defines?.remove('WORLD_UNITS'); - } - } - @override - get linewidth => uniforms['linewidth']['value']; - @override - set linewidth( value ) { - if (uniforms['linewidth'] == null) return; - uniforms['linewidth']['value'] = value; - } - - get dashed => defines?.containsKey('USE_DASH'); - - set dashed( value ) { - - if ((value == true ) != dashed ) { - needsUpdate = true; - } - - if ( value == true ) { - defines?['USE_DASH'] = ''; - } - else { - defines?.remove('USE_DASH'); - } - } - - get dashScale => uniforms['dashScale']['value']; - - set dashScale( value ) { - uniforms['dashScale']['value'] = value; - } - @override - get dashSize =>uniforms['dashSize']['value']; - @override - set dashSize( value ) { - uniforms['dashSize']['value'] = value; - } - - get dashOffset => uniforms['dashOffset']['value']; - - set dashOffset( value ) { - uniforms['dashOffset']['value'] = value; - } - @override - get gapSize => uniforms['gapSize']['value']; - @override - set gapSize( value ) { - uniforms['gapSize']['value'] = value; - } - @override - get opacity => uniforms['opacity']['value']; - @override - set opacity( value ) { - uniforms['opacity']['value'] = value; - } - - get resolution => uniforms['resolution']['value']; - - set resolution( value ) { - uniforms['resolution']['value'].copy( value ); - } - - @override - get alphaToCoverage => defines?.containsKey('USE_ALPHA_TO_COVERAGE') ?? false; - @override - set alphaToCoverage( value ) { - if (defines == null) return; - - if (( value == true ) != alphaToCoverage ) { - needsUpdate = true; - } - - if ( value == true ) { - defines?['USE_ALPHA_TO_COVERAGE'] = ''; - } - else { - defines?.remove('USE_ALPHA_TO_COVERAGE'); - } - } -} From 465b0898d4188d98793dc994951a00a2048f3f7d Mon Sep 17 00:00:00 2001 From: Knightro <50028636+Knightro63@users.noreply.github.com> Date: Wed, 28 Jan 2026 19:03:21 -0500 Subject: [PATCH 06/17] updated examples --- .../lib/terrain/webgl_planet_generator.dart | 36 ------------------- .../lib/texture/webgl_opengl_texture.dart | 1 - .../planet_generator/planet_generator.dart | 2 +- 3 files changed, 1 insertion(+), 38 deletions(-) diff --git a/examples/lib/terrain/webgl_planet_generator.dart b/examples/lib/terrain/webgl_planet_generator.dart index 5792d130..46d67f48 100644 --- a/examples/lib/terrain/webgl_planet_generator.dart +++ b/examples/lib/terrain/webgl_planet_generator.dart @@ -3,7 +3,6 @@ import 'package:example/src/gui.dart'; import 'package:flutter/material.dart'; import 'package:example/src/statistics.dart'; import 'package:three_js/three_js.dart' as three; -import 'package:three_js_postprocessing/three_js_postprocessing.dart'; import 'package:three_js_objects/three_js_objects.dart'; class WebglPlanetGenerator extends StatefulWidget { @@ -80,46 +79,16 @@ class _State extends State { final controls = three.OrbitControls(threeJs.camera, threeJs.globalKey); threeJs.camera.position.z = 50; - final double dpr = 0.5; // Half resolution for processing - final int width = (threeJs.width * dpr).toInt(); - final int height = (threeJs.height * dpr).toInt(); - - final renderTarget = three.RenderTarget(width, height, three.RenderTargetOptions({ - 'minFilter': three.LinearFilter, - 'magFilter': three.LinearFilter, - 'format': three.RGBAFormat, - 'type': three.HalfFloatType, - 'stencilBuffer': false, // Turn off for speed - 'depthBuffer': true, - })); - - final composer = EffectComposer(threeJs.renderer!, renderTarget); - - final renderPass = RenderPass(threeJs.scene, threeJs.camera); - // Explicitly clear to fix those "weird drawing" artifacts - renderPass.clear = true; - composer.addPass(renderPass); - - // Only keep this if you actually want the glow effect - final bloomPass = UnrealBloomPass(three.Vector2(width.toDouble(), height.toDouble()), 0.0, 0.2, 0.5); - composer.addPass(bloomPass); - - final outputPass = OutputPass(); - composer.addPass(outputPass); - final texLoader = three.TextureLoader(); final cloudTex = await texLoader.fromAsset('assets/textures/planet_generator/cloud.png'); PlanetGenerator planet = PlanetGenerator(cloudTexture: cloudTex); threeJs.scene.add(planet); - threeJs.renderer!.setPixelRatio(1.0); - threeJs.addAnimationEvent((dt) { planet.atmosphere.material?.uniforms['time']['value'] += dt; planet.atmosphere.rotation.y += 0.0002; controls.update(); - composer.render(); }); createUI(planet); @@ -277,10 +246,5 @@ class _State extends State { }); bumpMapFolder.addSlider(planetParams, 'bumpStrength', 0, 1,0.1)..name = 'Bump Strength'; bumpMapFolder.addSlider(planetParams, 'bumpOffset', 0.0001, 0.1,0.0001)..name = 'Bump Offset'; - - // final bloomFolder = gui.addFolder('Bloom'); - // bloomFolder.addSlider(bloomPass, 'threshold', 0, 1,0.1); - // bloomFolder.addSlider(bloomPass, 'strength', 0, 1,0.1); - // bloomFolder.addSlider(bloomPass, 'radius', 0, 2,0.1); } } diff --git a/examples/lib/texture/webgl_opengl_texture.dart b/examples/lib/texture/webgl_opengl_texture.dart index 4a23a02d..5cdc38fa 100644 --- a/examples/lib/texture/webgl_opengl_texture.dart +++ b/examples/lib/texture/webgl_opengl_texture.dart @@ -4,7 +4,6 @@ import 'package:flutter/material.dart'; import 'package:example/src/statistics.dart'; import 'package:three_js/three_js.dart' as three; import 'package:flutter_angle/flutter_angle.dart'; -import 'package:flutter_angle/flutter_angle.dart'; class WebglOpenglTexture extends StatefulWidget { const WebglOpenglTexture({super.key}); diff --git a/packages/three_js_objects/lib/planet_generator/planet_generator.dart b/packages/three_js_objects/lib/planet_generator/planet_generator.dart index b620e3dc..88cb4cd6 100644 --- a/packages/three_js_objects/lib/planet_generator/planet_generator.dart +++ b/packages/three_js_objects/lib/planet_generator/planet_generator.dart @@ -74,7 +74,7 @@ class PlanetGeneratorParameters{ this.ambientIntensity = 0.02, this.diffuseIntensity = 1, this.specularIntensity = 2, - this.shininess = 10, + this.shininess = 6, Vector3? lightDirection, Color? lightColor, this.bumpStrength = 1, From 6c752a07e3a0c2696e9cf55194a33bf76d82aaac Mon Sep 17 00:00:00 2001 From: Knightro <50028636+Knightro63@users.noreply.github.com> Date: Thu, 29 Jan 2026 06:33:33 -0500 Subject: [PATCH 07/17] changed atmoshpere parms --- .../lib/terrain/webgl_planet_generator.dart | 294 +++++++++++++++--- .../lib/planet_generator/atmosphere.dart | 41 ++- .../planet_generator/planet_generator.dart | 106 +++++-- 3 files changed, 361 insertions(+), 80 deletions(-) diff --git a/examples/lib/terrain/webgl_planet_generator.dart b/examples/lib/terrain/webgl_planet_generator.dart index 46d67f48..e64e6579 100644 --- a/examples/lib/terrain/webgl_planet_generator.dart +++ b/examples/lib/terrain/webgl_planet_generator.dart @@ -61,6 +61,225 @@ class _State extends State { ); } + Map mercury = { + "type": 1, + "radius": 2.44 * 3, + "amplitude": 0.8, + "sharpness": 3.5, + "offset": 0.1, + "period": 0.4, + "persistence": 0.6, + "lacunarity": 2.2, + "octaves": 6, + "undulation": 0.05, + "ambientIntensity": 0.02, + "diffuseIntensity": 0.8, + "specularIntensity": 0.1, + "shininess": 2.0, + "lightDirection": [1.0, 1.0, 1.0], + "lightColor": 0xffffff, + "bumpStrength": 1.5, + "bumpOffset": 0.002, + "color1": 0x1a1a1a, + "color2": 0x333333, + "color3": 0x4d4d4d, + "color4": 0x666666, + "color5": 0x999999, + "transition2": 0.1, + "transition3": 0.3, + "transition4": 0.6, + "transition5": 1.0, + "blend12": 0.1, + "blend23": 0.1, + "blend34": 0.1, + "blend45": 0.1 +}; + +Map venus = { + "type": 1, + "radius": 6.05 * 3, + "amplitude": 0.5, + "sharpness": 1.2, + "offset": 0.05, + "period": 0.8, + "persistence": 0.4, + "lacunarity": 2.0, + "octaves": 4, + "undulation": 0.2, + "ambientIntensity": 0.05, + "diffuseIntensity": 1.0, + "specularIntensity": 0.1, + "shininess": 1.0, + "lightDirection": [1.0, 1.0, 1.0], + "lightColor": 0xffedbc, + "bumpStrength": 0.4, + "bumpOffset": 0.001, + "color1": 0x4b3621, + "color2": 0x8b4513, + "color3": 0xd2b48c, + "color4": 0xe2bc5a, + "color5": 0xfffacd, + "transition2": 0.2, + "transition3": 0.4, + "transition4": 0.7, + "transition5": 1.1, + "blend12": 0.2, + "blend23": 0.2, + "blend34": 0.2, + "blend45": 0.2 +}; + +Map earth = { + "type": 2,//"terrestrial", + "radius": 6.37*3, + "amplitude": 1.19, + "sharpness": 2.6, + "offset": -0.016, + "period": 0.6, + "persistence": 0.484, + "lacunarity": 1.8, + "octaves": 6, + "undulation": 0.0, + "ambientIntensity": 0.02, + "diffuseIntensity": 1.0, + "specularIntensity": 2.0, + "shininess": 6.0, + "lightDirection": [1.0, 1.0, 1.0], + "lightColor": 0xffffff, + "bumpStrength": 1.0, + "bumpOffset": 0.001, + "color1": 0x001050, + "color2": 0xc2b280, + "color3": 0x228b22, + "color4": 0x1b5e20, + "color5": 0xffffff, + "transition2": 0.071, + "transition3": 0.215, + "transition4": 0.373, + "transition5": 1.2, + "blend12": 0.152, + "blend23": 0.152, + "blend34": 0.104, + "blend45": 0.168 +}; + +Map gas = { + "type": 3, + "radius": 12.0 * 3, + "amplitude": 0.15, + "sharpness": 0.5, + "offset": 0.0, + "period": 3.0, + "persistence": 0.3, + "lacunarity": 2.0, + "octaves": 3, + "undulation": 0.01, + "ambientIntensity": 0.1, + "diffuseIntensity": 0.8, + "specularIntensity": 0.0, + "shininess": 1.0, + "lightDirection": [1.0, 1.0, 1.0], + "lightColor": 0xffffff, + "bumpStrength": 0.1, + "bumpOffset": 0.0, + "color1": 0x5c4033, + "color2": 0x966f33, + "color3": 0xd2b48c, + "color4": 0xffe4c4, + "color5": 0x8b4513, + "transition2": 0.2, + "transition3": 0.4, + "transition4": 0.6, + "transition5": 0.8, + "blend12": 0.4, + "blend23": 0.4, + "blend34": 0.4, + "blend45": 0.4 +}; + +Map mars = { + "type": 1, + "radius": 3.39 * 3, + "amplitude": 1.3, + "sharpness": 2.8, + "offset": -0.05, + "period": 0.5, + "persistence": 0.55, + "lacunarity": 2.1, + "octaves": 7, + "undulation": 0.0, + "ambientIntensity": 0.02, + "diffuseIntensity": 0.9, + "specularIntensity": 0.05, + "shininess": 4.0, + "lightDirection": [1.0, 1.0, 1.0], + "lightColor": 0xffdbac, + "bumpStrength": 1.2, + "bumpOffset": 0.002, + "color1": 0x4a0e0e, + "color2": 0x8b0000, + "color3": 0xb22222, + "color4": 0xcd5c5c, + "color5": 0xf4a460, + "transition2": 0.15, + "transition3": 0.35, + "transition4": 0.55, + "transition5": 1.0, + "blend12": 0.1, + "blend23": 0.1, + "blend34": 0.1, + "blend45": 0.1, + "atmosphere": { + "particles": 2000, + "minParticleSize": 30, + "maxParticleSize": 80, + "radius": 10.17, + "thickness": 1.2, + "density": 0.0, + "opacity": 0.2, + "scale": 5.0, + "color": 0xe27b58, + "speed": 0.05, + "lightDirection": [1, 1, 1] + } +}; + +Map sun = { + "type": 4, + "radius": 25.0 * 3, + "amplitude": 3.5, + "sharpness": 1.2, + "offset": 0.0, + "period": 4.5, + "persistence": 0.4, + "lacunarity": 2.0, + "octaves": 4, + "undulation": 0.8, + "ambientIntensity": 2.0, // Glows even without external light + "diffuseIntensity": 0.0, + "specularIntensity": 0.0, + "shininess": 0.0, + "lightDirection": [0.0, 0.0, 0.0], + "lightColor": 0xffffff, + "bumpStrength": 0.0, + "bumpOffset": 0.0, + "color1": 0xff4500, // Deep orange + "color2": 0xff8c00, // Darker gold + "color3": 0xffd700, // Pure gold + "color4": 0xffff00, // Bright yellow + "color5": 0xffffff, // White hot spots + "transition2": 0.1, + "transition3": 0.3, + "transition4": 0.6, + "transition5": 0.9, + "blend12": 0.5, + "blend23": 0.5, + "blend34": 0.5, + "blend45": 0.5 +}; + + + Future setup() async { threeJs.scene = three.Scene(); @@ -82,12 +301,15 @@ class _State extends State { final texLoader = three.TextureLoader(); final cloudTex = await texLoader.fromAsset('assets/textures/planet_generator/cloud.png'); - PlanetGenerator planet = PlanetGenerator(cloudTexture: cloudTex); + PlanetGenerator planet = PlanetGenerator( + planetParams: PlanetGeneratorParameters.fromMap(mars), + atmosphere: Atmosphere(cloudTexture: cloudTex, atmosphereParams: AtmosphereParameters.fromMap(mars['atmosphere'])) + ); threeJs.scene.add(planet); threeJs.addAnimationEvent((dt) { - planet.atmosphere.material?.uniforms['time']['value'] += dt; - planet.atmosphere.rotation.y += 0.0002; + planet.atmosphere?.material?.uniforms['time']['value'] += dt; + planet.atmosphere?.rotation.y += 0.0002; controls.update(); }); @@ -96,8 +318,8 @@ class _State extends State { void createUI(PlanetGenerator planet) { final planetParams = planet.planetParams.json; - final atmosphereParams = planet.atmosphereParams.json; - Atmosphere atmosphere = planet.atmosphere; + final atmosphereParams = planet.atmosphereParams?.json; + Atmosphere? atmosphere = planet.atmosphere; final terrainFolder = gui.addFolder('Terrain')..open(); terrainFolder.onChange((name,value){ @@ -110,13 +332,13 @@ class _State extends State { else{ planet.material?.uniforms[name]['value'] = value; } - atmosphere.update(); + atmosphere?.update(); }); terrainFolder.addDropDown(planetParams, 'type', ['1', '2', '3'])..name = 'Type'; - terrainFolder.addSlider(planetParams, 'amplitude', 0.1, 1.5,0.1)..name ='Amplitude'; + terrainFolder.addSlider(planetParams, 'amplitude', 0.01, 1.5,0.01)..name ='Amplitude'; terrainFolder.addSlider(planetParams, 'sharpness', 0, 5,0.1)..name = 'Sharpness'; terrainFolder.addSlider(planetParams, 'offset', -2, 2,0.1)..name = 'Offset'; - terrainFolder.addSlider(planetParams, 'period', 0.1, 2,0.1)..name = 'Period'; + terrainFolder.addSlider(planetParams, 'period', 0.1, 3,0.1)..name = 'Period'; terrainFolder.addSlider(planetParams, 'persistence', 0, 1,0.1)..name = 'Persistence'; terrainFolder.addSlider(planetParams, 'lacunarity', 1, 3,0.1)..name = 'Lacunarity'; terrainFolder.addSlider(planetParams, 'octaves', 1, 10, 1)..name = 'Octaves'; @@ -180,34 +402,36 @@ class _State extends State { layer5Folder.addSlider(planetParams, 'blend45', 0, 1, 0.1)..name = 'Blend Factor (4->5)'; layer5Folder.addColor(planetParams, 'color5')..name = 'Color'; - final atmosphereFolder = gui.addFolder('Atmosphere')..open()..onChange((name,value){ - if(name == 'Atmosphere'){ - planet.atmosphere.material?.uniforms['speed']['value'] = value; - } - else{ - if(name == 'particles'||name == 'minParticleSize'||name == 'maxParticleSize'){ - planet.atmosphere.material?.uniforms[name]['value'] = value.toInt(); + if(planet.atmosphere != null){ + final atmosphereFolder = gui.addFolder('Atmosphere')..open()..onChange((name,value){ + if(name == 'Atmosphere'){ + planet.atmosphere?.material?.uniforms['speed']['value'] = value; } else{ - planet.atmosphere.material?.uniforms[name]['value'] = value; + if(name == 'particles'||name == 'minParticleSize'||name == 'maxParticleSize'){ + planet.atmosphere?.material?.uniforms[name]['value'] = value.toInt(); + } + else{ + planet.atmosphere?.material?.uniforms[name]['value'] = value; + } } - } - atmosphere.update(); - }); - atmosphereFolder.addSlider(atmosphereParams, 'thickness', 0.1, 5, 0.1)..name = 'Thickness'; - atmosphereFolder.addSlider(atmosphereParams, 'particles', 1, 50000, 1)..name = 'Particle Count'; - atmosphereFolder.addSlider(atmosphereParams, 'minParticleSize', 0, 200)..name = 'Min Particle Size'; - atmosphereFolder.addSlider(atmosphereParams, 'maxParticleSize', 0, 200)..name = 'Max Particle Size'; - atmosphereFolder.addSlider(atmosphereParams, 'density', -2, 2, 0.1)..name = 'Density'; - atmosphereFolder.addSlider(atmosphereParams, 'opacity', 0, 1, 0.1)..name = 'Opacity'; - atmosphereFolder.addSlider(atmosphereParams, 'scale', 1, 30)..name = 'Scale'; - atmosphereFolder.addSlider(atmosphereParams, 'speed', 0, 0.1, 0.001)..name = 'Speed'; - - final atmosphereColorFolder = gui.addFolder('Color')..open(); - atmosphereColorFolder.addColor(atmosphereParams, 'color')..name = 'Color'..onChange((value){ - planet.atmosphere.material?.uniforms['color']['value'] = three.Color.fromHex32(value); - atmosphere.update(); - }); + atmosphere?.update(); + }); + atmosphereFolder.addSlider(atmosphereParams!, 'thickness', 0.1, 5, 0.1)..name = 'Thickness'; + atmosphereFolder.addSlider(atmosphereParams, 'particles', 1, 50000, 1)..name = 'Particle Count'; + atmosphereFolder.addSlider(atmosphereParams, 'minParticleSize', 0, 200)..name = 'Min Particle Size'; + atmosphereFolder.addSlider(atmosphereParams, 'maxParticleSize', 0, 200)..name = 'Max Particle Size'; + atmosphereFolder.addSlider(atmosphereParams, 'density', -2, 2, 0.1)..name = 'Density'; + atmosphereFolder.addSlider(atmosphereParams, 'opacity', 0, 1, 0.1)..name = 'Opacity'; + atmosphereFolder.addSlider(atmosphereParams, 'scale', 1, 30)..name = 'Scale'; + atmosphereFolder.addSlider(atmosphereParams, 'speed', 0, 0.1, 0.001)..name = 'Speed'; + + final atmosphereColorFolder = gui.addFolder('Color')..open(); + atmosphereColorFolder.addColor(atmosphereParams, 'color')..name = 'Color'..onChange((value){ + planet.atmosphere?.material?.uniforms['color']['value'] = three.Color.fromHex32(value); + atmosphere?.update(); + }); + } final lightingFolder = gui.addFolder('Lighting')..open(); lightingFolder.onChange((name,value){ @@ -244,7 +468,7 @@ class _State extends State { planet.material?.uniforms[name]['value'] = value; } }); - bumpMapFolder.addSlider(planetParams, 'bumpStrength', 0, 1,0.1)..name = 'Bump Strength'; - bumpMapFolder.addSlider(planetParams, 'bumpOffset', 0.0001, 0.1,0.0001)..name = 'Bump Offset'; + bumpMapFolder.addSlider(planetParams, 'bumpStrength', 0, 2,0.1)..name = 'Bump Strength'; + bumpMapFolder.addSlider(planetParams, 'bumpOffset', 0.0, 0.1,0.0001)..name = 'Bump Offset'; } } diff --git a/packages/three_js_objects/lib/planet_generator/atmosphere.dart b/packages/three_js_objects/lib/planet_generator/atmosphere.dart index dc948468..795f4c00 100644 --- a/packages/three_js_objects/lib/planet_generator/atmosphere.dart +++ b/packages/three_js_objects/lib/planet_generator/atmosphere.dart @@ -6,23 +6,38 @@ import './shaders/index.dart'; import 'dart:math' as math; class AtmosphereParameters{ - int particles; - int minParticleSize; - int maxParticleSize; - double radius; - double thickness; - double density; - double opacity; - double scale; + late int particles; + late int minParticleSize; + late int maxParticleSize; + late double radius; + late double thickness; + late double density; + late double opacity; + late double scale; late Color color; - double speed; + late double speed; late Vector3 lightDirection; + AtmosphereParameters.fromMap([Map? map]){ + map = map ?? {}; + particles = map['particles'] ?? 4000; + minParticleSize = map['minParticleSize'] ?? 50; + maxParticleSize = map['maxParticleSize'] ?? 100; + radius = map['radius'] ?? 0.0; + thickness = map['thickness'] ?? 1.5; + density = map['density'] ?? 0.0; + opacity = map['opacity'] ?? 0.35; + scale = map['scale'] ?? 8.0; + color = map['color'] != null ? Color.fromHex32(map['color']) : Color.fromHex32(0xffffff); + speed = map['speed'] ?? 0.03; + lightDirection = map['lightDirection'] != null ? Vector3(map['lightDirection'][0], map['lightDirection'][1], map['lightDirection'][2]) : Vector3(1,1,1); + } + AtmosphereParameters({ this.particles = 4000, this.minParticleSize = 50, this.maxParticleSize = 100, - this.radius = 21.0, + this.radius = 0.0, this.thickness = 1.5, this.density = 0, this.opacity = 0.35, @@ -104,9 +119,11 @@ class AtmosphereParameters{ } class Atmosphere extends Points { - final AtmosphereParameters atmosphereParams; + late final AtmosphereParameters atmosphereParams; - Atmosphere(this.atmosphereParams, [Texture? cloudTexture]):super(){ + Atmosphere({AtmosphereParameters? atmosphereParams, Texture? cloudTexture}):super(){ + this.atmosphereParams = atmosphereParams ?? AtmosphereParameters(); + this.material = ShaderMaterial.fromMap({ 'uniforms': { 'time': { 'value': 0.0 }, diff --git a/packages/three_js_objects/lib/planet_generator/planet_generator.dart b/packages/three_js_objects/lib/planet_generator/planet_generator.dart index 88cb4cd6..895cd54b 100644 --- a/packages/three_js_objects/lib/planet_generator/planet_generator.dart +++ b/packages/three_js_objects/lib/planet_generator/planet_generator.dart @@ -28,37 +28,72 @@ SOFTWARE. */ class PlanetGeneratorParameters{ - int type; - double radius; - double amplitude; - double sharpness; - double offset; - double period; - double persistence; - double lacunarity; - int octaves; - double undulation; - double ambientIntensity; - double diffuseIntensity; - double specularIntensity; - double shininess; + late int type; + late double radius; + late double amplitude; + late double sharpness; + late double offset; + late double period; + late double persistence; + late double lacunarity; + late int octaves; + late double undulation; + late double ambientIntensity; + late double diffuseIntensity; + late double specularIntensity; + late double shininess; late final Vector3 lightDirection; late final Color lightColor; - double bumpStrength; - double bumpOffset; + late double bumpStrength; + late double bumpOffset; late final Color color1; late final Color color2; late final Color color3; late final Color color4; late final Color color5; - double transition2; - double transition3; - double transition4; - double transition5; - double blend12; - double blend23; - double blend34; - double blend45; + late double transition2; + late double transition3; + late double transition4; + late double transition5; + late double blend12; + late double blend23; + late double blend34; + late double blend45; + + PlanetGeneratorParameters.fromMap([Map? map]){ + map = map ?? {}; + type = map['type'] ?? 2; + radius = map['radius'] ?? 20.1; + amplitude = map['amplitude'] ?? 1.19; + sharpness = map['sharpness'] ?? 2.6; + offset = map['offset'] ?? -0.016; + period = map['period'] ?? 0.6; + persistence = map['persistence'] ?? 0.484; + lacunarity = map['lacunarity'] ?? 1.8; + octaves = map['octaves'] ?? 8; + undulation = map['undulation'] ?? 0; + ambientIntensity = map['ambientIntensity'] ?? 0.02; + diffuseIntensity = map['diffuseIntensity'] ?? 1; + specularIntensity = map['specularIntensity'] ?? 2; + shininess = map['shininess'] ?? 6; + lightDirection = map['lightDirection'] != null ? Vector3(map['lightDirection'][0], map['lightDirection'][1], map['lightDirection'][2]) : Vector3(1,1,1); + lightColor = map['lightColor'] != null ? Color.fromHex32(map['lightColor']) : Color.fromHex32(0xffffff); + bumpStrength = map['bumpStrength'] ?? 1; + bumpOffset = map['bumpOffset'] ?? 0.001; + color1 = map['color1'] != null ? Color.fromHex32(map['color1']) : Color(0.014, 0.117, 0.279); + color2 = map['color2'] != null ? Color.fromHex32(map['color2']) : Color(0.080, 0.527, 0.351); + color3 = map['color3'] != null ? Color.fromHex32(map['color3']) : Color(0.620, 0.516, 0.372); + color4 = map['color4'] != null ? Color.fromHex32(map['color4']) : Color(0.149, 0.254, 0.084); + color5 = map['color5'] != null ? Color.fromHex32(map['color5']) : Color(0.150, 0.150, 0.150); + transition2 = map['transition2'] ?? 0.071; + transition3 = map['transition3'] ?? 0.215; + transition4 = map['transition4'] ?? 0.372; + transition5 = map['transition5'] ?? 1.2; + blend12 = map['blend12'] ?? 0.152; + blend23 = map['blend23'] ?? 0.152; + blend34 = map['blend34'] ?? 0.104; + blend45 = map['blend45'] ?? 0.168; + } PlanetGeneratorParameters({ this.type = 2, @@ -102,6 +137,8 @@ class PlanetGeneratorParameters{ this.color5 = color5 ?? Color(0.150, 0.150, 0.150); } + + dynamic operator [] (key) => uniforms[key]['value']; void operator []=(String key, dynamic value) => setProperty(key, value); @@ -292,16 +329,13 @@ class PlanetGeneratorParameters{ } class PlanetGenerator extends Mesh{ - AtmosphereParameters get atmosphereParams => atmosphere.atmosphereParams; + AtmosphereParameters? get atmosphereParams => atmosphere?.atmosphereParams; late final PlanetGeneratorParameters planetParams; - late final Atmosphere atmosphere; + Atmosphere? atmosphere; - PlanetGenerator({PlanetGeneratorParameters? planetParams,AtmosphereParameters? atmosphereParams, Texture? cloudTexture}):super(){ + PlanetGenerator({PlanetGeneratorParameters? planetParams, this.atmosphere}):super(){ this.planetParams = planetParams ?? PlanetGeneratorParameters(); - atmosphereParams ??= AtmosphereParameters(); - atmosphereParams.radius = this.planetParams.radius+1; - atmosphereParams.lightDirection = this.planetParams.lightDirection; this.material = ShaderMaterial.fromMap({ 'uniforms': this.planetParams.uniforms, @@ -320,9 +354,15 @@ class PlanetGenerator extends Mesh{ this.geometry = SphereGeometry(1, 128, 128); this.geometry?.computeTangents(); - atmosphere = Atmosphere(atmosphereParams, cloudTexture); - atmosphere.renderOrder = 1; - this.add(atmosphere); + if(atmosphere != null){ + // if(atmosphere!.atmosphereParams.radius <= this.planetParams.radius) { + // atmosphere!.atmosphereParams.radius = this.planetParams.radius+1; + // } + atmosphere!.atmosphereParams.lightDirection = this.planetParams.lightDirection; + atmosphere!.renderOrder = 1; + atmosphere!.update(); + this.add(atmosphere); + } type = "Mesh"; updateMorphTargets(); From b5a55d5013807e074f6cfb4205a239b344e6cf30 Mon Sep 17 00:00:00 2001 From: Knightro <50028636+Knightro63@users.noreply.github.com> Date: Thu, 29 Jan 2026 17:47:09 -0500 Subject: [PATCH 08/17] minor planet fixes --- .../lib/terrain/webgl_planet_generator.dart | 222 +----------------- .../lib/planet_generator/atmosphere.dart | 10 +- .../planet_generator/planet_generator.dart | 3 +- .../shaders/atmosphere_vertex_shader.dart | 3 +- 4 files changed, 12 insertions(+), 226 deletions(-) diff --git a/examples/lib/terrain/webgl_planet_generator.dart b/examples/lib/terrain/webgl_planet_generator.dart index e64e6579..2ca59cf9 100644 --- a/examples/lib/terrain/webgl_planet_generator.dart +++ b/examples/lib/terrain/webgl_planet_generator.dart @@ -61,225 +61,6 @@ class _State extends State { ); } - Map mercury = { - "type": 1, - "radius": 2.44 * 3, - "amplitude": 0.8, - "sharpness": 3.5, - "offset": 0.1, - "period": 0.4, - "persistence": 0.6, - "lacunarity": 2.2, - "octaves": 6, - "undulation": 0.05, - "ambientIntensity": 0.02, - "diffuseIntensity": 0.8, - "specularIntensity": 0.1, - "shininess": 2.0, - "lightDirection": [1.0, 1.0, 1.0], - "lightColor": 0xffffff, - "bumpStrength": 1.5, - "bumpOffset": 0.002, - "color1": 0x1a1a1a, - "color2": 0x333333, - "color3": 0x4d4d4d, - "color4": 0x666666, - "color5": 0x999999, - "transition2": 0.1, - "transition3": 0.3, - "transition4": 0.6, - "transition5": 1.0, - "blend12": 0.1, - "blend23": 0.1, - "blend34": 0.1, - "blend45": 0.1 -}; - -Map venus = { - "type": 1, - "radius": 6.05 * 3, - "amplitude": 0.5, - "sharpness": 1.2, - "offset": 0.05, - "period": 0.8, - "persistence": 0.4, - "lacunarity": 2.0, - "octaves": 4, - "undulation": 0.2, - "ambientIntensity": 0.05, - "diffuseIntensity": 1.0, - "specularIntensity": 0.1, - "shininess": 1.0, - "lightDirection": [1.0, 1.0, 1.0], - "lightColor": 0xffedbc, - "bumpStrength": 0.4, - "bumpOffset": 0.001, - "color1": 0x4b3621, - "color2": 0x8b4513, - "color3": 0xd2b48c, - "color4": 0xe2bc5a, - "color5": 0xfffacd, - "transition2": 0.2, - "transition3": 0.4, - "transition4": 0.7, - "transition5": 1.1, - "blend12": 0.2, - "blend23": 0.2, - "blend34": 0.2, - "blend45": 0.2 -}; - -Map earth = { - "type": 2,//"terrestrial", - "radius": 6.37*3, - "amplitude": 1.19, - "sharpness": 2.6, - "offset": -0.016, - "period": 0.6, - "persistence": 0.484, - "lacunarity": 1.8, - "octaves": 6, - "undulation": 0.0, - "ambientIntensity": 0.02, - "diffuseIntensity": 1.0, - "specularIntensity": 2.0, - "shininess": 6.0, - "lightDirection": [1.0, 1.0, 1.0], - "lightColor": 0xffffff, - "bumpStrength": 1.0, - "bumpOffset": 0.001, - "color1": 0x001050, - "color2": 0xc2b280, - "color3": 0x228b22, - "color4": 0x1b5e20, - "color5": 0xffffff, - "transition2": 0.071, - "transition3": 0.215, - "transition4": 0.373, - "transition5": 1.2, - "blend12": 0.152, - "blend23": 0.152, - "blend34": 0.104, - "blend45": 0.168 -}; - -Map gas = { - "type": 3, - "radius": 12.0 * 3, - "amplitude": 0.15, - "sharpness": 0.5, - "offset": 0.0, - "period": 3.0, - "persistence": 0.3, - "lacunarity": 2.0, - "octaves": 3, - "undulation": 0.01, - "ambientIntensity": 0.1, - "diffuseIntensity": 0.8, - "specularIntensity": 0.0, - "shininess": 1.0, - "lightDirection": [1.0, 1.0, 1.0], - "lightColor": 0xffffff, - "bumpStrength": 0.1, - "bumpOffset": 0.0, - "color1": 0x5c4033, - "color2": 0x966f33, - "color3": 0xd2b48c, - "color4": 0xffe4c4, - "color5": 0x8b4513, - "transition2": 0.2, - "transition3": 0.4, - "transition4": 0.6, - "transition5": 0.8, - "blend12": 0.4, - "blend23": 0.4, - "blend34": 0.4, - "blend45": 0.4 -}; - -Map mars = { - "type": 1, - "radius": 3.39 * 3, - "amplitude": 1.3, - "sharpness": 2.8, - "offset": -0.05, - "period": 0.5, - "persistence": 0.55, - "lacunarity": 2.1, - "octaves": 7, - "undulation": 0.0, - "ambientIntensity": 0.02, - "diffuseIntensity": 0.9, - "specularIntensity": 0.05, - "shininess": 4.0, - "lightDirection": [1.0, 1.0, 1.0], - "lightColor": 0xffdbac, - "bumpStrength": 1.2, - "bumpOffset": 0.002, - "color1": 0x4a0e0e, - "color2": 0x8b0000, - "color3": 0xb22222, - "color4": 0xcd5c5c, - "color5": 0xf4a460, - "transition2": 0.15, - "transition3": 0.35, - "transition4": 0.55, - "transition5": 1.0, - "blend12": 0.1, - "blend23": 0.1, - "blend34": 0.1, - "blend45": 0.1, - "atmosphere": { - "particles": 2000, - "minParticleSize": 30, - "maxParticleSize": 80, - "radius": 10.17, - "thickness": 1.2, - "density": 0.0, - "opacity": 0.2, - "scale": 5.0, - "color": 0xe27b58, - "speed": 0.05, - "lightDirection": [1, 1, 1] - } -}; - -Map sun = { - "type": 4, - "radius": 25.0 * 3, - "amplitude": 3.5, - "sharpness": 1.2, - "offset": 0.0, - "period": 4.5, - "persistence": 0.4, - "lacunarity": 2.0, - "octaves": 4, - "undulation": 0.8, - "ambientIntensity": 2.0, // Glows even without external light - "diffuseIntensity": 0.0, - "specularIntensity": 0.0, - "shininess": 0.0, - "lightDirection": [0.0, 0.0, 0.0], - "lightColor": 0xffffff, - "bumpStrength": 0.0, - "bumpOffset": 0.0, - "color1": 0xff4500, // Deep orange - "color2": 0xff8c00, // Darker gold - "color3": 0xffd700, // Pure gold - "color4": 0xffff00, // Bright yellow - "color5": 0xffffff, // White hot spots - "transition2": 0.1, - "transition3": 0.3, - "transition4": 0.6, - "transition5": 0.9, - "blend12": 0.5, - "blend23": 0.5, - "blend34": 0.5, - "blend45": 0.5 -}; - - - Future setup() async { threeJs.scene = three.Scene(); @@ -302,8 +83,7 @@ Map sun = { final cloudTex = await texLoader.fromAsset('assets/textures/planet_generator/cloud.png'); PlanetGenerator planet = PlanetGenerator( - planetParams: PlanetGeneratorParameters.fromMap(mars), - atmosphere: Atmosphere(cloudTexture: cloudTex, atmosphereParams: AtmosphereParameters.fromMap(mars['atmosphere'])) + atmosphere: Atmosphere(cloudTexture: cloudTex) ); threeJs.scene.add(planet); diff --git a/packages/three_js_objects/lib/planet_generator/atmosphere.dart b/packages/three_js_objects/lib/planet_generator/atmosphere.dart index 795f4c00..2ab61a84 100644 --- a/packages/three_js_objects/lib/planet_generator/atmosphere.dart +++ b/packages/three_js_objects/lib/planet_generator/atmosphere.dart @@ -136,13 +136,19 @@ class Atmosphere extends Points { '''${noiseFunctions} void main() {''' ), - 'blending': NormalBlending, + //'size': atmosphereParams?.maxParticleSize ?? 1, + //'blending': NormalBlending, 'depthWrite': false, - 'transparent': true + //'depthTest': true, + 'transparent': true, + 'blending': AdditiveBlending, + //'sizeAttenuation': true }); material?.polygonOffset = true; material?.polygonOffsetFactor = -1.0; material?.polygonOffsetUnits = -4.0; + this.renderOrder = 1; + // material?.sizeAttenuation = true; update(); } diff --git a/packages/three_js_objects/lib/planet_generator/planet_generator.dart b/packages/three_js_objects/lib/planet_generator/planet_generator.dart index 895cd54b..dc9e9fcd 100644 --- a/packages/three_js_objects/lib/planet_generator/planet_generator.dart +++ b/packages/three_js_objects/lib/planet_generator/planet_generator.dart @@ -336,7 +336,6 @@ class PlanetGenerator extends Mesh{ PlanetGenerator({PlanetGeneratorParameters? planetParams, this.atmosphere}):super(){ this.planetParams = planetParams ?? PlanetGeneratorParameters(); - this.material = ShaderMaterial.fromMap({ 'uniforms': this.planetParams.uniforms, 'vertexShader': vertexShader.replaceAll( @@ -358,7 +357,7 @@ class PlanetGenerator extends Mesh{ // if(atmosphere!.atmosphereParams.radius <= this.planetParams.radius) { // atmosphere!.atmosphereParams.radius = this.planetParams.radius+1; // } - atmosphere!.atmosphereParams.lightDirection = this.planetParams.lightDirection; + //atmosphere!.atmosphereParams.lightDirection = this.planetParams.lightDirection; atmosphere!.renderOrder = 1; atmosphere!.update(); this.add(atmosphere); diff --git a/packages/three_js_objects/lib/planet_generator/shaders/atmosphere_vertex_shader.dart b/packages/three_js_objects/lib/planet_generator/shaders/atmosphere_vertex_shader.dart index 96cf5bec..0611edbf 100644 --- a/packages/three_js_objects/lib/planet_generator/shaders/atmosphere_vertex_shader.dart +++ b/packages/three_js_objects/lib/planet_generator/shaders/atmosphere_vertex_shader.dart @@ -4,7 +4,8 @@ final String atosphereVertexShader = ''' varying vec3 fragPosition; void main() { - gl_PointSize = size; + vec4 mvPosition = modelViewMatrix * vec4(position, 1.0); + gl_PointSize = size*(300.0/length(mvPosition.z)); gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); fragPosition = (modelMatrix * vec4(position, 1.0)).xyz; } From ed271ce0d451331696fbaac9b42287ad03a5febb Mon Sep 17 00:00:00 2001 From: Knightro <50028636+Knightro63@users.noreply.github.com> Date: Mon, 16 Feb 2026 07:33:57 -0500 Subject: [PATCH 09/17] added lod to planet generator --- .../lib/cameras/cube_camera.dart | 4 +- packages/three_js_core/lib/objects/lod.dart | 2 +- .../lib/planet_generator/atmosphere.dart | 69 ++++++------- .../planet_generator/planet_generator.dart | 12 ++- .../shaders/atmosphere_vertex_shader.dart | 41 ++++++-- .../shaders/fragment_shader.dart | 99 ++++++++++++++++++- .../shaders/noise_functions.dart | 95 +++++++++++++----- .../shaders/vertex_shader.dart | 51 +++++++++- 8 files changed, 295 insertions(+), 78 deletions(-) diff --git a/packages/three_js_core/lib/cameras/cube_camera.dart b/packages/three_js_core/lib/cameras/cube_camera.dart index ac4764ee..f2e8c79c 100755 --- a/packages/three_js_core/lib/cameras/cube_camera.dart +++ b/packages/three_js_core/lib/cameras/cube_camera.dart @@ -1,9 +1,9 @@ import 'package:flutter/foundation.dart'; +import 'package:three_js_core/cameras/index.dart'; import '../core/index.dart'; import 'package:three_js_math/three_js_math.dart'; import '../renderers/index.dart'; -import 'perspective_camera.dart'; /// Creates 6 cameras that render to a [page:WebGLCubeRenderTarget]. /// @@ -29,7 +29,7 @@ import 'perspective_camera.dart'; /// car.visible = true; /// renderer.render( scene, camera ); /// ``` -class CubeCamera extends Object3D { +class CubeCamera extends Camera { /// The destination cube render target. late CubeRenderTarget renderTarget; diff --git a/packages/three_js_core/lib/objects/lod.dart b/packages/three_js_core/lib/objects/lod.dart index c3e4c334..5bd223e5 100755 --- a/packages/three_js_core/lib/objects/lod.dart +++ b/packages/three_js_core/lib/objects/lod.dart @@ -23,7 +23,7 @@ final _v2 = Vector3.zero(); /// lod.addLevel( mesh, i * 75 ); /// } //// -/// ∂scene.add( lod ); +/// scene.add( lod ); /// ``` /// class LOD extends Object3D{ diff --git a/packages/three_js_objects/lib/planet_generator/atmosphere.dart b/packages/three_js_objects/lib/planet_generator/atmosphere.dart index 2ab61a84..f3f12b62 100644 --- a/packages/three_js_objects/lib/planet_generator/atmosphere.dart +++ b/packages/three_js_objects/lib/planet_generator/atmosphere.dart @@ -121,14 +121,20 @@ class AtmosphereParameters{ class Atmosphere extends Points { late final AtmosphereParameters atmosphereParams; - Atmosphere({AtmosphereParameters? atmosphereParams, Texture? cloudTexture}):super(){ - this.atmosphereParams = atmosphereParams ?? AtmosphereParameters(); + Atmosphere._(super.geometry, super.material, this.atmosphereParams, int renderOrder){ + this.renderOrder = renderOrder; + } + + factory Atmosphere({AtmosphereParameters? atmosphereParams, Texture? cloudTexture, int renderOrder = 2}){ + atmosphereParams ??= AtmosphereParameters(); - this.material = ShaderMaterial.fromMap({ + final material = ShaderMaterial.fromMap({ 'uniforms': { 'time': { 'value': 0.0 }, 'pointTexture': { 'value': cloudTexture }, - ...this.atmosphereParams.uniforms + 'radius': { 'value': atmosphereParams.radius }, + 'thickness': { 'value': atmosphereParams.thickness }, + ...atmosphereParams.uniforms }, 'vertexShader': atosphereVertexShader, 'fragmentShader': atmosphereFragmentShader.replaceAll( @@ -136,43 +142,28 @@ class Atmosphere extends Points { '''${noiseFunctions} void main() {''' ), - //'size': atmosphereParams?.maxParticleSize ?? 1, - //'blending': NormalBlending, 'depthWrite': false, - //'depthTest': true, 'transparent': true, 'blending': AdditiveBlending, - //'sizeAttenuation': true }); - material?.polygonOffset = true; - material?.polygonOffsetFactor = -1.0; - material?.polygonOffsetUnits = -4.0; - this.renderOrder = 1; - // material?.sizeAttenuation = true; - update(); - } + material.polygonOffset = true; + material.polygonOffsetFactor = -1.0; + material.polygonOffsetUnits = -4.0; - void update(){ - if (this.geometry != null) { - this.geometry?.dispose(); - this.geometry = null; - } - - final geometry = BufferGeometry(); - final Float32List combinedData = Float32List(atmosphereParams.particles * 6); - - // Sample points within the atmosphere - for(int i = 0; i < atmosphereParams.particles; i++) { - double r = math.Random().nextDouble() * atmosphereParams.thickness + atmosphereParams.radius; + final int count = atmosphereParams.particles; + final Float32List combinedData = Float32List(count * 6); + final random = math.Random(); + for(int i = 0; i < count; i++) { + double r = random.nextDouble() * atmosphereParams.thickness + atmosphereParams.radius; // Pick a random point within a cube of size [-1, 1] // This approach works better than parameterizing the spherical coordinates // since it doesn't have the issue of particles being bunched at the poles final p = Vector3( - 2 * math.Random().nextDouble() - 1, - 2 * math.Random().nextDouble() - 1, - 2 * math.Random().nextDouble() - 1 + 2 * random.nextDouble() - 1, + 2 * random.nextDouble() - 1, + 2 * random.nextDouble() - 1 ); // Project onto the surface of a sphere @@ -181,20 +172,24 @@ class Atmosphere extends Points { final minSize = atmosphereParams.minParticleSize; final maxSize = atmosphereParams.maxParticleSize; - final size = math.Random().nextDouble() * (maxSize - minSize) + minSize; + final size = random.nextDouble() * (maxSize - minSize) + minSize; - combinedData.setAll(i * 6, [p.x, p.y, p.z, 0.5, 0.5, size]); + combinedData.setAll(i * 4, [p.x, p.y, p.z, size]); } - final interleavedBuffer = InterleavedBuffer(combinedData, 6); + final geometry = BufferGeometry(); + final interleavedBuffer = InterleavedBuffer(combinedData, 4); geometry.setAttributeFromString('position', InterleavedBufferAttribute(interleavedBuffer, 3, 0)); - geometry.setAttributeFromString('uv', InterleavedBufferAttribute(interleavedBuffer, 2, 3)); - geometry.setAttributeFromString('size', InterleavedBufferAttribute(interleavedBuffer, 1, 5)); - - this.geometry = geometry; + geometry.setAttributeFromString('size', InterleavedBufferAttribute(interleavedBuffer, 1, 3)); geometry.computeBoundingSphere(); geometry.computeBoundingBox(); + + return Atmosphere._(geometry, material, atmosphereParams, renderOrder); + } + + void update(double dt){ + material?.uniforms['time']['value'] += dt; } } \ No newline at end of file diff --git a/packages/three_js_objects/lib/planet_generator/planet_generator.dart b/packages/three_js_objects/lib/planet_generator/planet_generator.dart index dc9e9fcd..34bda936 100644 --- a/packages/three_js_objects/lib/planet_generator/planet_generator.dart +++ b/packages/three_js_objects/lib/planet_generator/planet_generator.dart @@ -59,6 +59,7 @@ class PlanetGeneratorParameters{ late double blend23; late double blend34; late double blend45; + int segments = 128; PlanetGeneratorParameters.fromMap([Map? map]){ map = map ?? {}; @@ -93,6 +94,7 @@ class PlanetGeneratorParameters{ blend23 = map['blend23'] ?? 0.152; blend34 = map['blend34'] ?? 0.104; blend45 = map['blend45'] ?? 0.168; + segments = map['segments'] ?? 128; } PlanetGeneratorParameters({ @@ -127,6 +129,7 @@ class PlanetGeneratorParameters{ this.blend23 = 0.152, this.blend34 = 0.104, this.blend45 = 0.168, + this.segments = 128, }){ this.lightDirection = lightDirection ?? Vector3(1,1,1); this.lightColor = lightColor ?? Color.fromHex32(0xffffff); @@ -257,6 +260,9 @@ class PlanetGeneratorParameters{ else if(key == 'blend45'){ blend45 = value; } + else if(key == 'segments'){ + segments = value; + } } Map get json => { @@ -290,7 +296,8 @@ class PlanetGeneratorParameters{ 'blend12': blend12, 'blend23': blend23, 'blend34': blend34, - 'blend45': blend45 + 'blend45': blend45, + 'segments': segments }; Map get uniforms => { @@ -350,7 +357,7 @@ class PlanetGenerator extends Mesh{ ), }); - this.geometry = SphereGeometry(1, 128, 128); + this.geometry = SphereGeometry(1, this.planetParams.segments, this.planetParams.segments); this.geometry?.computeTangents(); if(atmosphere != null){ @@ -359,7 +366,6 @@ class PlanetGenerator extends Mesh{ // } //atmosphere!.atmosphereParams.lightDirection = this.planetParams.lightDirection; atmosphere!.renderOrder = 1; - atmosphere!.update(); this.add(atmosphere); } diff --git a/packages/three_js_objects/lib/planet_generator/shaders/atmosphere_vertex_shader.dart b/packages/three_js_objects/lib/planet_generator/shaders/atmosphere_vertex_shader.dart index 0611edbf..53277f15 100644 --- a/packages/three_js_objects/lib/planet_generator/shaders/atmosphere_vertex_shader.dart +++ b/packages/three_js_objects/lib/planet_generator/shaders/atmosphere_vertex_shader.dart @@ -1,12 +1,37 @@ +// final String atosphereVertexShader_old = ''' +// attribute float size; + +// varying vec3 fragPosition; + +// void main() { +// vec4 mvPosition = modelViewMatrix * vec4(position, 1.0); +// gl_PointSize = size*(300.0/length(mvPosition.z)); +// gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); +// fragPosition = (modelMatrix * vec4(position, 1.0)).xyz; +// } +// '''; + final String atosphereVertexShader = ''' - attribute float size; +attribute float size; +varying vec3 fragPosition; + +uniform float radius; +uniform float thickness; + +void main() { + // Project seed to sphere + vec3 dir = normalize(position); + + // Quick pseudo-random for radius jitter + float hash = fract(sin(dot(position, vec3(12.9, 78.2, 45.1))) * 43758.5); + float r = radius + (hash * thickness); + vec3 finalPos = dir * r; - varying vec3 fragPosition; + vec4 mvPosition = modelViewMatrix * vec4(finalPos, 1.0); + gl_PointSize = size * (300.0 / length(mvPosition.z)); + gl_Position = projectionMatrix * mvPosition; - void main() { - vec4 mvPosition = modelViewMatrix * vec4(position, 1.0); - gl_PointSize = size*(300.0/length(mvPosition.z)); - gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0); - fragPosition = (modelMatrix * vec4(position, 1.0)).xyz; - } + // Pass world position for noise + fragPosition = (modelMatrix * vec4(finalPos, 1.0)).xyz; +} '''; \ No newline at end of file diff --git a/packages/three_js_objects/lib/planet_generator/shaders/fragment_shader.dart b/packages/three_js_objects/lib/planet_generator/shaders/fragment_shader.dart index 40e043f9..b4d2f0fe 100644 --- a/packages/three_js_objects/lib/planet_generator/shaders/fragment_shader.dart +++ b/packages/three_js_objects/lib/planet_generator/shaders/fragment_shader.dart @@ -1,4 +1,4 @@ -final String fragmentShader = ''' +final String fragmentShader_old = ''' // Terrain generation parameters uniform int type; uniform float radius; @@ -130,4 +130,101 @@ final String fragmentShader = ''' gl_FragColor = vec4(light * finalColor * lightColor, 1.0); } +'''; + +final String fragmentShader = ''' + // Terrain generation parameters + varying vec3 vWorldPosition; // Receive from Vertex + uniform int type; + uniform float radius; + uniform float amplitude; + uniform float sharpness; + uniform float offset; + uniform float period; + uniform float persistence; + uniform float lacunarity; + uniform int octaves; + + // Layer colors + uniform vec3 color1; + uniform vec3 color2; + uniform vec3 color3; + uniform vec3 color4; + uniform vec3 color5; + + // Transition points for each layer + uniform float transition2; + uniform float transition3; + uniform float transition4; + uniform float transition5; + + // Amount of blending between each layer + uniform float blend12; + uniform float blend23; + uniform float blend34; + uniform float blend45; + + // Bump mapping parameters + uniform float bumpStrength; + uniform float bumpOffset; + + // Lighting parameters + uniform float ambientIntensity; + uniform float diffuseIntensity; + uniform float specularIntensity; + uniform float shininess; + uniform vec3 lightDirection; + uniform vec3 lightColor; + + varying vec3 fragPosition; + varying vec3 fragNormal; + varying vec3 fragTangent; + varying vec3 fragBitangent; + + varying float vHeight; // Receiving from Vertex + + void main() { + float dist = distance(cameraPosition, vWorldPosition); + float smoothLod = float(octaves); + if (dist > 1000.0) { + // Linear interpolation of the octave count + float t = clamp((dist - 1000.0) / 300.0, 0.0, 1.0); + smoothLod = mix(float(octaves), 2.0, t); + } + + float h = terrainHeight(type, fragPosition, amplitude, sharpness, offset, period, persistence, lacunarity, smoothLod); + + vec3 dx = bumpOffset * fragTangent; + float h_dx = terrainHeight(type, fragPosition + dx, amplitude, sharpness, offset, period, persistence, lacunarity, smoothLod); + + vec3 dy = bumpOffset * fragBitangent; + float h_dy = terrainHeight(type, fragPosition + dy, amplitude, sharpness, offset, period, persistence, lacunarity, smoothLod); + + vec3 pos = fragPosition * (radius + h); + vec3 pos_dx = (fragPosition + dx) * (radius + h_dx); + vec3 pos_dy = (fragPosition + dy) * (radius + h_dy); + vec3 N = normalize(mix(fragNormal, normalize(cross(pos_dx - pos, pos_dy - pos)), bumpStrength)); + + vec3 L = normalize(-lightDirection); + vec3 V = normalize(cameraPosition - pos); + vec3 R = normalize(reflect(L, N)); + + float diffuse = diffuseIntensity * max(0.0, dot(N, -L)); + float specularFalloff = clamp((transition3 - h) / transition3, 0.0, 1.0); + float specular = max(0.0, specularFalloff * specularIntensity * pow(dot(V, R), shininess)); + float light = ambientIntensity + diffuse + specular; + + vec3 finalColor; + if (h < transition2 + blend12) { + finalColor = mix(color1, color2, smoothstep(transition2 - blend12, transition2 + blend12, h)); + } else if (h < transition3 + blend23) { + finalColor = mix(color2, color3, smoothstep(transition3 - blend23, transition3 + blend23, h)); + } else if (h < transition4 + blend34) { + finalColor = mix(color3, color4, smoothstep(transition4 - blend34, transition4 + blend34, h)); + } else { + finalColor = mix(color4, color5, smoothstep(transition5 - blend45, transition5 + blend45, h)); + } + + gl_FragColor = vec4(light * finalColor * lightColor, 1.0); +} '''; \ No newline at end of file diff --git a/packages/three_js_objects/lib/planet_generator/shaders/noise_functions.dart b/packages/three_js_objects/lib/planet_generator/shaders/noise_functions.dart index 9d6e2922..c9460d5a 100644 --- a/packages/three_js_objects/lib/planet_generator/shaders/noise_functions.dart +++ b/packages/three_js_objects/lib/planet_generator/shaders/noise_functions.dart @@ -77,28 +77,71 @@ final String noiseFunctions = ''' dot(p2,x2), dot(p3,x3) ) ); } - float fractal3( - vec3 v, - float sharpness, - float period, - float persistence, - float lacunarity, - int octaves - ) { - float n = 0.0; - float a = 1.0; // Amplitude for current octave - float max_amp = 0.0; // Accumulate max amplitude so we can normalize after - float P = period; // Period for current octave - - for(int i = 0; i < octaves; i++) { - n += a * simplex3(v / P); - a *= persistence; - max_amp += a; - P /= lacunarity; - } - - // Normalize noise between [0.0, amplitude] - return n / max_amp; + // float fractal3( + // vec3 v, + // float sharpness, + // float period, + // float persistence, + // float lacunarity, + // int octaves + // ) { + // float n = 0.0; + // float a = 1.0; // Amplitude for current octave + // float max_amp = 0.0; // Accumulate max amplitude so we can normalize after + // float P = period; // Period for current octave + + // for(int i = 0; i < octaves; i++) { + // n += a * simplex3(v / P); + // a *= persistence; + // max_amp += a; + // P /= lacunarity; + // } + + // // Normalize noise between [0.0, amplitude] + // return n / max_amp; + // } + + // float fractal3(vec3 p, float sharp, float per, float pers, float lac, int lodLimit) { + // float total = 0.0; + // float frequency = 1.0 / per; + // float amplitude = 1.0; + + // // Use a constant max (e.g., 12) so the shader compiles everywhere + // for (int i = 0; i < 12; i++) { + // if (i >= lodLimit) break; // This is the performance "Magic" + + // total += simplex3(p * frequency) * amplitude; + + // frequency *= lac; + // amplitude *= pers; + // } + // return total; + // } + + float fractal3(vec3 p, float sharp, float per, float pers, float lac, float lodLimit) { + float total = 0.0; + float frequency = 1.0 / per; + float amplitude = 1.0; + + // We still loop to a constant max + for (int i = 0; i < 12; i++) { + float fi = float(i); + + // SMOOTH TRANSITION LOGIC + // If we are below the floor of the limit, add full noise. + // If we are at the limit, add a fraction of the noise. + // If we are above, stop. + float multiplier = clamp(lodLimit - fi, 0.0, 1.0); + + if (multiplier > 0.0) { + total += simplex3(p * frequency) * amplitude * multiplier; + frequency *= lac; + amplitude *= pers; + } else { + break; + } + } + return total; } float terrainHeight( @@ -110,13 +153,14 @@ final String noiseFunctions = ''' float period, float persistence, float lacunarity, - int octaves + float octaves ) { float h = 0.0; if (type == 1) { h = amplitude * simplex3(v / period); - } else if (type == 2) { + } + else if (type == 2) { h = amplitude * fractal3( v, sharpness, @@ -125,7 +169,8 @@ final String noiseFunctions = ''' lacunarity, octaves); h = amplitude * pow(max(0.0, (h + 1.0) / 2.0), sharpness); - } else if (type == 3) { + } + else if (type == 3) { h = fractal3( v, sharpness, diff --git a/packages/three_js_objects/lib/planet_generator/shaders/vertex_shader.dart b/packages/three_js_objects/lib/planet_generator/shaders/vertex_shader.dart index 079412d9..8aafafb1 100644 --- a/packages/three_js_objects/lib/planet_generator/shaders/vertex_shader.dart +++ b/packages/three_js_objects/lib/planet_generator/shaders/vertex_shader.dart @@ -1,4 +1,4 @@ -final String vertexShader = ''' +final String vertexShader_old = ''' attribute vec3 tangent; // Terrain generation parameters @@ -37,6 +37,55 @@ final String vertexShader = ''' vec3 pos = position * (radius + h); gl_Position = projectionMatrix * modelViewMatrix * vec4(pos, 1.0); + fragPosition = position; + fragNormal = normal; + fragTangent = tangent; + fragBitangent = cross(normal, tangent); + } +'''; + +final String vertexShader = ''' + attribute vec3 tangent; + + // Terrain generation parameters + varying vec3 vWorldPosition; // Add this varying + uniform int type; + uniform float radius; + uniform float amplitude; + uniform float sharpness; + uniform float offset; + uniform float period; + uniform float persistence; + uniform float lacunarity; + uniform int octaves; + + varying vec3 fragPosition; + varying vec3 fragNormal; + varying vec3 fragTangent; + varying vec3 fragBitangent; + varying float vHeight; // New: Pass height to fragment to save CPU/GPU cycles + + void main() { + float worldDist = distance(cameraPosition, modelMatrix[3].xyz); + float smoothLod = float(octaves); + if (worldDist > 1000.0) { + // Linear interpolation of the octave count + float t = clamp((worldDist - 1000.0) / 300.0, 0.0, 1.0); + smoothLod = mix(float(octaves), 2.0, t); + } + + vHeight = terrainHeight( + type, position, amplitude, sharpness, offset, + period, persistence, lacunarity, smoothLod + ); + + vec3 displacedPos = position * (radius + vHeight); + + vec4 worldPos = modelMatrix * vec4(displacedPos, 1.0); + vWorldPosition = worldPos.xyz; + + gl_Position = projectionMatrix * modelViewMatrix * vec4(displacedPos, 1.0); + fragPosition = position; fragNormal = normal; fragTangent = tangent; From f2c26c370d0f4deb89cd97edee717989ccb96b41 Mon Sep 17 00:00:00 2001 From: Knightro <50028636+Knightro63@users.noreply.github.com> Date: Mon, 16 Feb 2026 08:14:46 -0500 Subject: [PATCH 10/17] removed runtimeType.toString() --- .../lib/terrain/webgl_planet_generator.dart | 6 ++--- .../lib/gltf/gltf_helper.dart | 2 +- .../lib/gltf/gltf_parser.dart | 16 ++++++------ .../lib/renderers/renderer.dart | 2 +- .../lib/animations/animation_mixer.dart | 2 +- .../lib/animations/animation_utils.dart | 8 +++--- .../lib/animations/property_binding.dart | 5 ++-- .../future/core/utils/geometry_utils.dart | 2 +- .../three_js_core/lib/materials/material.dart | 2 +- packages/three_js_curves/lib/core/curve.dart | 2 +- .../lib/utils/skeleton_utils.dart | 6 ++--- packages/three_js_terrain/lib/core.dart | 6 ++--- .../lib/buffer_geometry_loader.dart | 2 +- .../lib/renderers/web_gl_renderer.dart | 2 +- three_js_editor/lib/ui.dart | 25 +++++++++---------- 15 files changed, 44 insertions(+), 44 deletions(-) diff --git a/examples/lib/terrain/webgl_planet_generator.dart b/examples/lib/terrain/webgl_planet_generator.dart index 2ca59cf9..dc290e8b 100644 --- a/examples/lib/terrain/webgl_planet_generator.dart +++ b/examples/lib/terrain/webgl_planet_generator.dart @@ -112,7 +112,7 @@ class _State extends State { else{ planet.material?.uniforms[name]['value'] = value; } - atmosphere?.update(); + atmosphere?.update(0.0); }); terrainFolder.addDropDown(planetParams, 'type', ['1', '2', '3'])..name = 'Type'; terrainFolder.addSlider(planetParams, 'amplitude', 0.01, 1.5,0.01)..name ='Amplitude'; @@ -195,7 +195,7 @@ class _State extends State { planet.atmosphere?.material?.uniforms[name]['value'] = value; } } - atmosphere?.update(); + atmosphere?.update(0.0); }); atmosphereFolder.addSlider(atmosphereParams!, 'thickness', 0.1, 5, 0.1)..name = 'Thickness'; atmosphereFolder.addSlider(atmosphereParams, 'particles', 1, 50000, 1)..name = 'Particle Count'; @@ -209,7 +209,7 @@ class _State extends State { final atmosphereColorFolder = gui.addFolder('Color')..open(); atmosphereColorFolder.addColor(atmosphereParams, 'color')..name = 'Color'..onChange((value){ planet.atmosphere?.material?.uniforms['color']['value'] = three.Color.fromHex32(value); - atmosphere?.update(); + atmosphere?.update(0.0); }); } diff --git a/packages/three_js_advanced_loaders/lib/gltf/gltf_helper.dart b/packages/three_js_advanced_loaders/lib/gltf/gltf_helper.dart index 299a1e66..8a349ad5 100755 --- a/packages/three_js_advanced_loaders/lib/gltf/gltf_helper.dart +++ b/packages/three_js_advanced_loaders/lib/gltf/gltf_helper.dart @@ -101,7 +101,7 @@ class GLTypeData { } else if (array is Float32List) { return Float32BufferAttribute.fromList(array, itemSize, normalized); } else { - throw ("GLTFHelper createBufferAttribute array.runtimeType : ${array.runtimeType} is not support yet"); + throw ("GLTFHelper createBufferAttribute array: ${array} is not support yet"); } } } diff --git a/packages/three_js_advanced_loaders/lib/gltf/gltf_parser.dart b/packages/three_js_advanced_loaders/lib/gltf/gltf_parser.dart index b7e1b860..5cb4fcec 100755 --- a/packages/three_js_advanced_loaders/lib/gltf/gltf_parser.dart +++ b/packages/three_js_advanced_loaders/lib/gltf/gltf_parser.dart @@ -467,25 +467,25 @@ class GLTFParser { final int stride = byteStride ~/ elementBytes; int totalLen = array.length; if(array is Uint8List){ - ib = InterleavedBuffer(Uint8List(totalLen).set(array.buffer.asUint8List()), 1); + ib = InterleavedBuffer(Uint8List(totalLen)..set(array.buffer.asUint8List()), 1); } else if(array is Int8List){ - ib = InterleavedBuffer(Int8List(totalLen).set(array.buffer.asInt8List()), 1); + ib = InterleavedBuffer(Int8List(totalLen)..set(array.buffer.asInt8List()), 1); } else if(array is Int16List){ - ib = InterleavedBuffer(Int16List(totalLen).set(array.buffer.asInt16List()), 1); + ib = InterleavedBuffer(Int16List(totalLen)..set(array.buffer.asInt16List()), 1); } else if(array is Int32List){ - ib = InterleavedBuffer(Int32List(totalLen).set(array.buffer.asInt32List()), 1); + ib = InterleavedBuffer(Int32List(totalLen)..set(array.buffer.asInt32List()), 1); } else if(array is Uint16List){ - ib = InterleavedBuffer(Uint16List(totalLen).set(array.buffer.asUint16List()), 1); + ib = InterleavedBuffer(Uint16List(totalLen)..set(array.buffer.asUint16List()), 1); } else if(array is Uint32List){ - ib = InterleavedBuffer(Uint32List(totalLen).set(array.buffer.asUint32List()), 1); + ib = InterleavedBuffer(Uint32List(totalLen)..set(array.buffer.asUint32List()), 1); } else{ - ib = InterleavedBuffer(Float32List(totalLen).set(array.buffer.asFloat32List()), stride); + ib = InterleavedBuffer(Float32List(totalLen)..set(array.buffer.asFloat32List()), stride); } parser.cache.add(ibCacheKey, ib); @@ -941,7 +941,7 @@ class GLTFParser { } else if (materialType == MeshStandardMaterial) { return MeshStandardMaterial.fromMap(materialParams); } else { - throw ("GLTFParser createMaterialType materialType: ${materialType.runtimeType.toString()} is not support "); + throw ("GLTFParser createMaterialType materialType: $materialType is not support "); } } diff --git a/packages/three_js_angle_renderer/lib/renderers/renderer.dart b/packages/three_js_angle_renderer/lib/renderers/renderer.dart index 85b38c97..5267183d 100755 --- a/packages/three_js_angle_renderer/lib/renderers/renderer.dart +++ b/packages/three_js_angle_renderer/lib/renderers/renderer.dart @@ -591,7 +591,7 @@ class AngleRenderer extends Renderer{ Object3D object, Map? group, ) { - // print("renderBufferDirect .............material: ${material.runtimeType} "); + // print("renderBufferDirect .............material: $material "); // renderBufferDirect second parameter used to be fog (could be null) scene ??= _emptyScene; final frontFaceCW = (object is Mesh && object.matrixWorld.determinant() < 0); diff --git a/packages/three_js_animations/lib/animations/animation_mixer.dart b/packages/three_js_animations/lib/animations/animation_mixer.dart index e0df77a3..ec24287c 100755 --- a/packages/three_js_animations/lib/animations/animation_mixer.dart +++ b/packages/three_js_animations/lib/animations/animation_mixer.dart @@ -482,7 +482,7 @@ class AnimationMixer with EventDispatcher { final root = optionalRoot ?? this.root; final rootUuid = root.uuid; - final clipObject = clip;//clip.runtimeType.toString() == 'String'? AnimationClip.findByName(root, clip):clip, + final clipObject = clip;//clip is String? AnimationClip.findByName(root, clip):clip, final clipUuid = clipObject.uuid;//clipObject ? clipObject.uuid : clip; final actionsForClip = actionsByClip[clipUuid]; diff --git a/packages/three_js_animations/lib/animations/animation_utils.dart b/packages/three_js_animations/lib/animations/animation_utils.dart index 4001225e..e9cae7ea 100755 --- a/packages/three_js_animations/lib/animations/animation_utils.dart +++ b/packages/three_js_animations/lib/animations/animation_utils.dart @@ -8,8 +8,8 @@ class AnimationUtils { // same as Array.prototype.slice, but also works on typed arrays static List arraySlice(List array, [int from = 0, int? to]) { // if ( AnimationUtils.isTypedArray( array ) ) { - if (array.runtimeType.toString() != "List") { - console.info(" AnimationUtils.arraySlice array: ${array.runtimeType} "); + if (array.runtimeType != List) { + console.info(" AnimationUtils.arraySlice array: $array"); // // in ios9 array.subarray(from, null) will return empty array // // but array.subarray(from) or array.subarray(from, len) is correct // return new array.constructor( array.subarray( from, to != null ? to : array.length ) ); @@ -158,8 +158,8 @@ class AnimationUtils { if (times.isEmpty) continue; - track.times = times;//AnimationUtils.convertArray(times, track.times.runtimeType.toString()); - track.values = values;//AnimationUtils.convertArray(values, track.values.runtimeType.toString()); + track.times = times;//AnimationUtils.convertArray(times, track.times); + track.values = values;//AnimationUtils.convertArray(values, track.values); tracks.add(track); } diff --git a/packages/three_js_animations/lib/animations/property_binding.dart b/packages/three_js_animations/lib/animations/property_binding.dart index 525d727e..9ff932d7 100755 --- a/packages/three_js_animations/lib/animations/property_binding.dart +++ b/packages/three_js_animations/lib/animations/property_binding.dart @@ -1,4 +1,5 @@ import 'package:three_js_core/three_js_core.dart'; +import 'package:three_js_math/three_js_math.dart'; import 'animation_object_group.dart'; // Characters [].:/ are reserved for track binding syntax. @@ -491,7 +492,7 @@ class PropertyBinding extends AnimationBinding{ this.targetObject = targetObject; // if ( targetObject.needsUpdate != null ) { // material - if (targetObject.runtimeType.toString().endsWith("Material")) { + if (targetObject is Material) { versioning = Versioning.needsUpdate; } else if (targetObject?.matrixWorldNeedsUpdate != null) { @@ -536,7 +537,7 @@ class PropertyBinding extends AnimationBinding{ this.propertyIndex = propertyIndex; // } else if ( nodeProperty.fromArray != null && nodeProperty.toArray != null ) { } - else if (["Color", "Vector3", "Quaternion"].contains(nodeProperty.runtimeType.toString())) { + else if (nodeProperty is Color || nodeProperty is Vector3 || nodeProperty is Quaternion) { // must use copy for Object3D.Euler/Quaternion bindingType = BindingType.hasFromToArray; resolvedProperty = nodeProperty; diff --git a/packages/three_js_bvh_csg/future/core/utils/geometry_utils.dart b/packages/three_js_bvh_csg/future/core/utils/geometry_utils.dart index cf3a9af4..bf3480b8 100644 --- a/packages/three_js_bvh_csg/future/core/utils/geometry_utils.dart +++ b/packages/three_js_bvh_csg/future/core/utils/geometry_utils.dart @@ -16,7 +16,7 @@ TypedData convertToSharedArrayBuffer(TypedData array) { return array; } - //final cons = array.runtimeType; + //final cons = array; final buffer = array.buffer; final sharedBuffer = SharedArrayBuffer(buffer.lengthInBytes); diff --git a/packages/three_js_core/lib/materials/material.dart b/packages/three_js_core/lib/materials/material.dart index f040274b..0c806e36 100755 --- a/packages/three_js_core/lib/materials/material.dart +++ b/packages/three_js_core/lib/materials/material.dart @@ -472,7 +472,7 @@ class Material with EventDispatcher { } else if (key == "dithering") { dithering = newValue; } else if (key == "emissive") { - if (newValue.runtimeType == Color) { + if (newValue is Color) { emissive = newValue; } else { emissive = Color.fromHex32(newValue); diff --git a/packages/three_js_curves/lib/core/curve.dart b/packages/three_js_curves/lib/core/curve.dart index ed534a5f..28f64c15 100644 --- a/packages/three_js_curves/lib/core/curve.dart +++ b/packages/three_js_curves/lib/core/curve.dart @@ -269,7 +269,7 @@ class Curve { final pt2 = getPoint(t2); final tangent = optionalTarget ?? - ((pt1.runtimeType == Vector2)?Vector2(): Vector3()); + ((pt1 is Vector2)?Vector2(): Vector3()); if(pt2 != null && pt1 != null){ tangent.setFrom(pt2).sub(pt1).normalize(); diff --git a/packages/three_js_helpers/lib/utils/skeleton_utils.dart b/packages/three_js_helpers/lib/utils/skeleton_utils.dart index b0f92d49..ea08bcbd 100644 --- a/packages/three_js_helpers/lib/utils/skeleton_utils.dart +++ b/packages/three_js_helpers/lib/utils/skeleton_utils.dart @@ -487,7 +487,7 @@ class SkeletonUtils { }); clone.traverse((node) { - if (!node.runtimeType.toString().contains("SkinnedMesh")) return; + if (node is!SkinnedMesh) return; final clonedMesh = node; final Object3D sourceMesh = sourceLookup[node]; @@ -500,9 +500,9 @@ class SkeletonUtils { return cloneLookup[bone]; }).toList()); - if(clonedMesh is SkinnedMesh){ + //if(clonedMesh is SkinnedMesh){ clonedMesh.bind(clonedMesh.skeleton!, clonedMesh.bindMatrix); - } + //} }); return clone; diff --git a/packages/three_js_terrain/lib/core.dart b/packages/three_js_terrain/lib/core.dart index 011ccc0d..6bfb386e 100644 --- a/packages/three_js_terrain/lib/core.dart +++ b/packages/three_js_terrain/lib/core.dart @@ -549,7 +549,7 @@ class Terrain{ options.heightmap(zs, options); } else { - console.warning('An invalid value was passed for `options.heightmap`: ${options.heightmap.runtimeType}'); + console.warning('An invalid value was passed for `options.heightmap`: ${options.heightmap}'); } fromArray1D(mesh.geometry!.attributes['position'].array, zs); @@ -1572,7 +1572,7 @@ class Terrain{ final mat = material ?? MeshLambertMaterial(); Function? hexOnBeforeCompile; - if(mat.runtimeType.toString() == 'HexTilingMaterial'){ + if(mat is HexTilingMaterial){ hexOnBeforeCompile = mat.onBeforeCompile; } @@ -1595,7 +1595,7 @@ class Terrain{ }; } - if(mat.runtimeType.toString() == 'HexTilingMaterial'){ + if(mat is HexTilingMaterial){ shader.fragmentShader = shader.fragmentShader.replaceAll( 'texture2D', 'textureNoTileNeyret' diff --git a/packages/three_js_tjs_loader/lib/buffer_geometry_loader.dart b/packages/three_js_tjs_loader/lib/buffer_geometry_loader.dart index 9c032f3a..59baa97b 100644 --- a/packages/three_js_tjs_loader/lib/buffer_geometry_loader.dart +++ b/packages/three_js_tjs_loader/lib/buffer_geometry_loader.dart @@ -251,6 +251,6 @@ BufferAttribute getTypedAttribute(TypedData array, int itemSize, } else if (array is Float32List) { return Float32BufferAttribute(array, itemSize, normalized); } else { - throw (" Util.dart getTypedArray type: ${array.runtimeType} is not support "); + throw (" Util.dart getTypedArray type: $array is not support "); } } diff --git a/packages/three_js_webgl_renderer/lib/renderers/web_gl_renderer.dart b/packages/three_js_webgl_renderer/lib/renderers/web_gl_renderer.dart index d728a73d..7e8c642e 100755 --- a/packages/three_js_webgl_renderer/lib/renderers/web_gl_renderer.dart +++ b/packages/three_js_webgl_renderer/lib/renderers/web_gl_renderer.dart @@ -586,7 +586,7 @@ class WebGLRenderer extends Renderer{ Object3D object, Map? group, ) { - // print("renderBufferDirect .............material: ${material.runtimeType} "); + // print("renderBufferDirect .............material: ${material} "); // renderBufferDirect second parameter used to be fog (could be null) scene ??= _emptyScene; final frontFaceCW = (object is Mesh && object.matrixWorld.determinant() < 0); diff --git a/three_js_editor/lib/ui.dart b/three_js_editor/lib/ui.dart index cd95d6ad..abd246be 100644 --- a/three_js_editor/lib/ui.dart +++ b/three_js_editor/lib/ui.dart @@ -1,6 +1,5 @@ import 'dart:async'; import 'dart:math' as math; -import 'dart:io'; import 'package:css/css.dart'; import 'package:flutter/foundation.dart'; @@ -167,16 +166,16 @@ class _UIPageState extends State { setState(() {}); } - static Future? _writeToFile(String path, {String? spark, Uint8List? image}){ - final file = File(path); - if(spark != null){ - return file.writeAsString(spark); - } - else if(image != null){ - return file.writeAsBytes(image); - } - return null; - } + // static Future? _writeToFile(String path, {String? spark, Uint8List? image}){ + // final file = File(path); + // if(spark != null){ + // return file.writeAsString(spark); + // } + // else if(image != null){ + // return file.writeAsBytes(image); + // } + // return null; + // } Future setup() async{ const frustumSize = 5.0; @@ -972,11 +971,11 @@ class _UIPageState extends State { onChanged:(value){ setState(() { selectedValue = value; - three.Mesh mesh; + //three.Mesh mesh; int n = int.parse(selectedValue.split('|').last); for(final m in threeJs.scene.children){ if(m.id == n){ - mesh = m as three.Mesh; + //mesh = m as three.Mesh; break; } } From afbf7259e4c831e7f7022bbaf0edcffe48725474 Mon Sep 17 00:00:00 2001 From: Knightro <50028636+Knightro63@users.noreply.github.com> Date: Mon, 16 Feb 2026 08:40:14 -0500 Subject: [PATCH 11/17] added key to material --- packages/three_js_core/lib/materials/material.dart | 3 +++ packages/three_js_simple_loaders/lib/obj/mtl_loader.dart | 2 +- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/packages/three_js_core/lib/materials/material.dart b/packages/three_js_core/lib/materials/material.dart index 0c806e36..0330f32b 100755 --- a/packages/three_js_core/lib/materials/material.dart +++ b/packages/three_js_core/lib/materials/material.dart @@ -646,6 +646,9 @@ class Material with EventDispatcher { else if (key == 'emissiveIntensity') { emissiveIntensity = newValue.toDouble(); } + else if (key == 'specularIntensityMap') { + specularIntensityMap = newValue; + } else { console.error("Material.setValues key: $key newValue: $newValue is not support"); } diff --git a/packages/three_js_simple_loaders/lib/obj/mtl_loader.dart b/packages/three_js_simple_loaders/lib/obj/mtl_loader.dart index 2e5faca7..d6af5ab4 100644 --- a/packages/three_js_simple_loaders/lib/obj/mtl_loader.dart +++ b/packages/three_js_simple_loaders/lib/obj/mtl_loader.dart @@ -431,7 +431,7 @@ class MaterialCreator { pos = items.indexOf('-bm'); if (pos >= 0) { - matParams.bumpScale = double.parse(items[pos + 1]); + matParams['bumpScale'] = double.parse(items[pos + 1]); items.removeRange(pos, pos+2); } From c57f07c2cb030611f01f978f65829a599b4e0961 Mon Sep 17 00:00:00 2001 From: Knightro <50028636+Knightro63@users.noreply.github.com> Date: Mon, 16 Feb 2026 11:45:15 -0500 Subject: [PATCH 12/17] Update positional_audio.dart --- packages/three_js_core/lib/audio/positional_audio.dart | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/three_js_core/lib/audio/positional_audio.dart b/packages/three_js_core/lib/audio/positional_audio.dart index ff9b99d0..06cdc24d 100644 --- a/packages/three_js_core/lib/audio/positional_audio.dart +++ b/packages/three_js_core/lib/audio/positional_audio.dart @@ -179,7 +179,6 @@ class PositionalAudio extends Object3D { } void setVolume(double volume) { - print(volume); audioSource.setVolume(volume); } From 219864c1110996a4819dd1220cccf5d43904041b Mon Sep 17 00:00:00 2001 From: Knightro <50028636+Knightro63@users.noreply.github.com> Date: Fri, 27 Feb 2026 07:20:36 -0500 Subject: [PATCH 13/17] updated web_gl_materials --- .../lib/webgl/web_gl_materials.dart | 63 ++++++++++++++++--- 1 file changed, 56 insertions(+), 7 deletions(-) diff --git a/packages/three_js_webgl_renderer/lib/webgl/web_gl_materials.dart b/packages/three_js_webgl_renderer/lib/webgl/web_gl_materials.dart index f848b3cf..12c3ef4e 100755 --- a/packages/three_js_webgl_renderer/lib/webgl/web_gl_materials.dart +++ b/packages/three_js_webgl_renderer/lib/webgl/web_gl_materials.dart @@ -91,43 +91,92 @@ class WebGLMaterials { } if (material.map != null) { - uniforms["map"]["value"] = material.map; + if(uniforms['map'] == null){ + uniforms["map"] = { + "value": material.map + }; + } + else { + uniforms["map"]["value"] = material.map; + } refreshTransformUniform( material.map, uniforms['mapTransform'] ); } if (material.alphaMap != null) { - uniforms["alphaMap"]["value"] = material.alphaMap; + if(uniforms['alphaMap'] == null){ + uniforms["alphaMap"] = { + "value": material.alphaMap + }; + } + else { + uniforms["alphaMap"]["value"] = material.alphaMap; + } refreshTransformUniform( material.alphaMap!, uniforms['alphaMapTransform'] ); } if (material.bumpMap != null) { - uniforms["bumpMap"]["value"] = material.bumpMap; + if(uniforms['bumpMap'] == null){ + uniforms["bumpMap"] = { + "value": material.bumpMap + }; + } + else { + uniforms["bumpMap"]["value"] = material.bumpMap; + } refreshTransformUniform( material.bumpMap!, uniforms['bumpMapTransform'] ); uniforms["bumpScale"]["value"] = material.bumpScale; if (material.side == BackSide) uniforms["bumpScale"]["value"] *= -1; } if (material.displacementMap != null) { - uniforms["displacementMap"]["value"] = material.displacementMap; + if(uniforms['displacementMap'] == null){ + uniforms["displacementMap"] = { + "value": material.displacementMap + }; + } + else { + uniforms["displacementMap"]["value"] = material.displacementMap; + } refreshTransformUniform( material.displacementMap!, uniforms['displacementMapTransform'] ); uniforms["displacementScale"]["value"] = material.displacementScale; uniforms["displacementBias"]["value"] = material.displacementBias; } if (material.emissiveMap != null) { - uniforms["emissiveMap"]["value"] = material.emissiveMap; + if(uniforms['emissiveMap'] == null){ + uniforms["emissiveMap"] = { + "value": material.emissiveMap + }; + } + else { + uniforms["emissiveMap"]["value"] = material.emissiveMap; + } refreshTransformUniform( material.emissiveMap!, uniforms['emissiveMapTransform'] ); } if (material.normalMap != null) { - uniforms["normalMap"]["value"] = material.normalMap; + if(uniforms["normalMap"] == null){ + uniforms["normalMap"] = { + "value": material.normalMap + }; + } + else{ + uniforms["normalMap"]["value"] = material.normalMap; + } refreshTransformUniform( material.normalMap!, uniforms['normalMapTransform'] ); uniforms["normalScale"]["value"].setFrom(material.normalScale); if (material.side == BackSide) uniforms["normalScale"]["value"].negate(); } if (material.specularMap != null) { - uniforms["specularMap"]["value"] = material.specularMap; + if(uniforms["specularMap"] == null){ + uniforms["specularMap"] = { + "value": material.specularMap + }; + } + else{ + uniforms["specularMap"]["value"] = material.specularMap; + } refreshTransformUniform( material.specularMap!, uniforms['specularMapTransform'] ); } From c44cc5619c6235691889012fb76d2a316ab1433c Mon Sep 17 00:00:00 2001 From: Knightro <50028636+Knightro63@users.noreply.github.com> Date: Fri, 27 Feb 2026 07:24:38 -0500 Subject: [PATCH 14/17] minor updates --- packages/three_js_core/lib/materials/material.dart | 3 +++ packages/three_js_core/lib/textures/source.dart | 2 +- .../three_js_webgl_renderer/lib/renderers/web_gl_renderer.dart | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/packages/three_js_core/lib/materials/material.dart b/packages/three_js_core/lib/materials/material.dart index 0330f32b..c535c93f 100755 --- a/packages/three_js_core/lib/materials/material.dart +++ b/packages/three_js_core/lib/materials/material.dart @@ -649,6 +649,9 @@ class Material with EventDispatcher { else if (key == 'specularIntensityMap') { specularIntensityMap = newValue; } + else if (key == 'clearcoatMap') { + clearcoatMap = newValue; + } else { console.error("Material.setValues key: $key newValue: $newValue is not support"); } diff --git a/packages/three_js_core/lib/textures/source.dart b/packages/three_js_core/lib/textures/source.dart index 94591e78..e0594ea7 100755 --- a/packages/three_js_core/lib/textures/source.dart +++ b/packages/three_js_core/lib/textures/source.dart @@ -53,7 +53,7 @@ class Source { return meta.images[uuid]; } - final output = { + final output = { "uuid": uuid, "url": '' }; diff --git a/packages/three_js_webgl_renderer/lib/renderers/web_gl_renderer.dart b/packages/three_js_webgl_renderer/lib/renderers/web_gl_renderer.dart index 7e8c642e..744d0a7b 100755 --- a/packages/three_js_webgl_renderer/lib/renderers/web_gl_renderer.dart +++ b/packages/three_js_webgl_renderer/lib/renderers/web_gl_renderer.dart @@ -591,7 +591,7 @@ class WebGLRenderer extends Renderer{ scene ??= _emptyScene; final frontFaceCW = (object is Mesh && object.matrixWorld.determinant() < 0); - WebGLProgram program = setProgram(camera, scene, geometry, material, object); + final program = setProgram(camera, scene, geometry, material, object); (state as WebGLState).setMaterial(material, frontFaceCW); From 76ac4ce94873e027fbdb6711731bf3423218a93a Mon Sep 17 00:00:00 2001 From: Rodion Stashinsky Date: Fri, 27 Mar 2026 17:10:56 +0300 Subject: [PATCH 15/17] line_segments.dart, line.dart -> fix clone incorrect, geometry and material. --- packages/three_js_core/lib/objects/line.dart | 4 ++-- packages/three_js_core/lib/objects/line_segments.dart | 5 +++++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/packages/three_js_core/lib/objects/line.dart b/packages/three_js_core/lib/objects/line.dart index e1f80bc3..607014e5 100755 --- a/packages/three_js_core/lib/objects/line.dart +++ b/packages/three_js_core/lib/objects/line.dart @@ -55,8 +55,8 @@ class Line extends Object3D { Line copy(Object3D source, [bool? recursive]) { super.copy(source); - material = source.material; - geometry = source.geometry; + material = source.material?.clone(); + geometry = source.geometry?.clone(); return this; } diff --git a/packages/three_js_core/lib/objects/line_segments.dart b/packages/three_js_core/lib/objects/line_segments.dart index d4c12b27..cba6cd7a 100755 --- a/packages/three_js_core/lib/objects/line_segments.dart +++ b/packages/three_js_core/lib/objects/line_segments.dart @@ -56,4 +56,9 @@ class LineSegments extends Line { return this; } + + @override + LineSegments clone([bool? recursive = true]) { + return LineSegments(this.geometry)..copy(this, recursive); + } } From 76b7afc8300f2a8ebfebe08a640ec9146eb48125 Mon Sep 17 00:00:00 2001 From: Rodion Stashinsky Date: Fri, 27 Mar 2026 17:12:00 +0300 Subject: [PATCH 16/17] group.dart-> fix clone incorrect return type (now return Group instead of Object3D) --- packages/three_js_core/lib/objects/group.dart | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/packages/three_js_core/lib/objects/group.dart b/packages/three_js_core/lib/objects/group.dart index 4ef9a5d2..3cb11d29 100755 --- a/packages/three_js_core/lib/objects/group.dart +++ b/packages/three_js_core/lib/objects/group.dart @@ -30,4 +30,18 @@ class Group extends Object3D { Group.fromJson(Map json, Map rootJson):super.fromJson(json, rootJson) { type = 'Group'; } + + @override + Group clone ([bool? recursive = true]) { + return Group()..copy(this, recursive); + } + + @override + Group copy(Object3D source, [bool? recursive]) { + super.copy(source, recursive); + if(source is Group) { + this.userData = Map.from(source.userData); + } + return this; + } } From 7c5a5cafc9f536afb4adf30815df3a4f7c7cb039 Mon Sep 17 00:00:00 2001 From: Knightro <50028636+Knightro63@users.noreply.github.com> Date: Sat, 2 May 2026 16:29:19 -0400 Subject: [PATCH 17/17] added ability to change surface producer --- packages/three_js_angle_renderer/lib/three_viewer.dart | 6 ++++-- packages/three_js_webgl_renderer/lib/three_viewer.dart | 6 ++++-- 2 files changed, 8 insertions(+), 4 deletions(-) diff --git a/packages/three_js_angle_renderer/lib/three_viewer.dart b/packages/three_js_angle_renderer/lib/three_viewer.dart index fc02aad8..fd3fed70 100644 --- a/packages/three_js_angle_renderer/lib/three_viewer.dart +++ b/packages/three_js_angle_renderer/lib/three_viewer.dart @@ -41,7 +41,8 @@ class Settings{ this.failIfMajorPerformanceCaveat = false, this.reverseDepthBuffer = false, this.precision = core.Precision.highp, - this.screenResolution + this.screenResolution, + this.useSurfaceProducer = true }){ this.renderOptions = renderOptions ?? { "format": RGBAFormat, @@ -55,6 +56,7 @@ class Settings{ bool reverseDepthBuffer; bool failIfMajorPerformanceCaveat; bool depth = true; + bool useSurfaceProducer; Precision precision; bool alpha; bool stencil; @@ -371,7 +373,7 @@ class ThreeJS with WidgetsBindingObserver{ alpha: settings.alpha, antialias: settings.antialias, customRenderer: !settings.useSourceTexture, - useSurfaceProducer: true + useSurfaceProducer: settings.useSurfaceProducer ) ); } diff --git a/packages/three_js_webgl_renderer/lib/three_viewer.dart b/packages/three_js_webgl_renderer/lib/three_viewer.dart index d85076e7..35c2141c 100644 --- a/packages/three_js_webgl_renderer/lib/three_viewer.dart +++ b/packages/three_js_webgl_renderer/lib/three_viewer.dart @@ -41,7 +41,8 @@ class Settings{ this.failIfMajorPerformanceCaveat = false, this.reverseDepthBuffer = false, this.precision = Precision.highp, - this.screenResolution + this.screenResolution, + this.useSurfaceProducer = true }){ this.renderOptions = renderOptions ?? { "format": RGBAFormat, @@ -55,6 +56,7 @@ class Settings{ bool reverseDepthBuffer; bool failIfMajorPerformanceCaveat; bool depth = true; + bool useSurfaceProducer; Precision precision; bool alpha; bool stencil; @@ -371,7 +373,7 @@ class ThreeJS with WidgetsBindingObserver{ alpha: settings.alpha, antialias: settings.antialias, customRenderer: !settings.useSourceTexture, - useSurfaceProducer: true + useSurfaceProducer: settings.useSurfaceProducer ) ); }