From 84d625d97a62205cf917f7d1b442be83c118bb3a Mon Sep 17 00:00:00 2001
From: Michael Herzog
Date: Wed, 7 Jun 2023 10:19:43 +0200
Subject: [PATCH 1/7] TAARenderPass: Fix color shift. (#26199)
---
examples/jsm/postprocessing/TAARenderPass.js | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/examples/jsm/postprocessing/TAARenderPass.js b/examples/jsm/postprocessing/TAARenderPass.js
index 57eeb80c559989..cbbea08b6601b2 100644
--- a/examples/jsm/postprocessing/TAARenderPass.js
+++ b/examples/jsm/postprocessing/TAARenderPass.js
@@ -69,7 +69,6 @@ class TAARenderPass extends SSAARenderPass {
const oldClearAlpha = renderer.getClearAlpha();
const sampleWeight = 1.0 / ( jitterOffsets.length );
- const accumulationWeight = this.accumulateIndex * sampleWeight;
if ( this.accumulateIndex >= 0 && this.accumulateIndex < jitterOffsets.length ) {
@@ -117,6 +116,7 @@ class TAARenderPass extends SSAARenderPass {
}
renderer.setClearColor( this.clearColor, this.clearAlpha );
+ const accumulationWeight = this.accumulateIndex * sampleWeight;
if ( accumulationWeight > 0 ) {
@@ -133,7 +133,6 @@ class TAARenderPass extends SSAARenderPass {
this.copyUniforms[ 'opacity' ].value = 1.0 - accumulationWeight;
this.copyUniforms[ 'tDiffuse' ].value = this.holdRenderTarget.texture;
renderer.setRenderTarget( writeBuffer );
- if ( accumulationWeight === 0 ) renderer.clear();
this.fsQuad.render( renderer );
}
From cdaaca3cafb7804d4a08955ad0d462a262abd094 Mon Sep 17 00:00:00 2001
From: Omar Khalifa
Date: Wed, 7 Jun 2023 11:31:06 +0300
Subject: [PATCH 2/7] Docs: Translating Loaders/managers section into Arabic
(ar). (#26202)
* update list.json to include the Loaders/managers section of arabic docs
* add arabic translation for DefaultLoadingManager page
* add arabic translation for LoadingManager page
---
.../managers/DefaultLoadingManager.html | 68 +++++
.../ar/loaders/managers/LoadingManager.html | 236 ++++++++++++++++++
docs/list.json | 5 +
3 files changed, 309 insertions(+)
create mode 100644 docs/api/ar/loaders/managers/DefaultLoadingManager.html
create mode 100644 docs/api/ar/loaders/managers/LoadingManager.html
diff --git a/docs/api/ar/loaders/managers/DefaultLoadingManager.html b/docs/api/ar/loaders/managers/DefaultLoadingManager.html
new file mode 100644
index 00000000000000..7fa15480bc662f
--- /dev/null
+++ b/docs/api/ar/loaders/managers/DefaultLoadingManager.html
@@ -0,0 +1,68 @@
+
+
+
+
+
+
+
+
+
+ [name]
+
+
+ نسخة عالمية من [page:LoadingManager LoadingManager]، يستخدمها
+ معظم المحملات عندما لم يتم تحديد مدير مخصص.
+
+ هذا سيكون كافيًا لمعظم الأغراض، ولكن قد يكون هناك أوقات عندما
+ ترغب في مديري تحميل منفصلين للقول، القوام والنماذج.
+
+
+ مثال للكود
+
+
+ يمكنك تعيين [page:LoadingManager.onStart onStart]،
+ [page:LoadingManager.onLoad onLoad]، [page:LoadingManager.onProgress onProgress]،
+ [page:LoadingManager.onStart onError] وظائف لل
+ مدير. ستطبق هذه على أي محملات تستخدم
+ DefaultLoadingManager.
+
+ يجب عدم الخلط بين هذه الوظائف المسماة بشكل مشابه
+ من المحملات الفردية، لأنها مخصصة لعرض المعلومات
+ حول الحالة العامة للتحميل، بدلاً من التعامل مع البيانات
+ التي تم تحميلها.
+
+
+THREE.DefaultLoadingManager.onStart = function ( url, itemsLoaded, itemsTotal ) {
+ console.log( 'Started loading file: ' + url + '.\nLoaded ' + itemsLoaded + ' of ' + itemsTotal + ' files.' );
+};
+
+THREE.DefaultLoadingManager.onLoad = function ( ) {
+ console.log( 'Loading Complete!');
+};
+
+THREE.DefaultLoadingManager.onProgress = function ( url, itemsLoaded, itemsTotal ) {
+ console.log( 'Loading file: ' + url + '.\nLoaded ' + itemsLoaded + ' of ' + itemsTotal + ' files.' );
+};
+
+THREE.DefaultLoadingManager.onError = function ( url ) {
+ console.log( 'There was an error loading ' + url );
+};
+
+
+ الخصائص (Properties)
+
+ انظر صفحة [page:LoadingManager LoadingManager] لتفاصيل
+ الخصائص.
+
+
+ الطرق (Methods)
+
+ انظر صفحة [page:LoadingManager LoadingManager] لتفاصيل الطرق.
+
+
+ المصدر (Source)
+
+ [link:https://github.com/mrdoob/three.js/blob/master/src/loaders/LoadingManager.js src/loaders/LoadingManager.js]
+
+
+
diff --git a/docs/api/ar/loaders/managers/LoadingManager.html b/docs/api/ar/loaders/managers/LoadingManager.html
new file mode 100644
index 00000000000000..bfe70192ed9d59
--- /dev/null
+++ b/docs/api/ar/loaders/managers/LoadingManager.html
@@ -0,0 +1,236 @@
+
+
+
+
+
+
+
+
+
+ [name]
+
+
+ يتعامل ويتتبع البيانات المحملة والمعلقة. يتم إنشاء نسخة عالمية افتراضية
+ من هذه الفئة واستخدامها من قبل المحملات إذا لم يتم توفيرها
+ يدويًا - انظر [page:DefaultLoadingManager].
+
+ بشكل عام يجب أن يكون ذلك كافيًا، ولكن هناك أوقات يمكن أن تكون فيها
+ مفيدًا لديك محملات منفصلة - على سبيل المثال إذا كنت ترغب في عرض
+ شرائط تحميل منفصلة للأشياء والقوام.
+
+
+ مثال للكود
+
+
+ يوضح هذا المثال كيفية استخدام LoadingManager لتتبع التقدم
+ [page:OBJLoader].
+
+
+
+ const manager = new THREE.LoadingManager();
+ manager.onStart = function ( url, itemsLoaded, itemsTotal ) {
+ console.log( 'Started loading file: ' + url + '.\nLoaded ' + itemsLoaded + ' of ' + itemsTotal + ' files.' );
+ };
+
+ manager.onLoad = function ( ) {
+ console.log( 'Loading complete!');
+ };
+
+ manager.onProgress = function ( url, itemsLoaded, itemsTotal ) {
+ console.log( 'Loading file: ' + url + '.\nLoaded ' + itemsLoaded + ' of ' + itemsTotal + ' files.' );
+ };
+
+ manager.onError = function ( url ) {
+ console.log( 'There was an error loading ' + url );
+ };
+
+ const loader = new THREE.OBJLoader( manager );
+ loader.load( 'file.obj', function ( object ) {
+ //
+ } );
+
+
+
+ بالإضافة إلى مراقبة التقدم، يمكن استخدام LoadingManager ل
+ تجاوز عناوين URL للموارد أثناء التحميل. قد يكون ذلك مفيدًا للأصول
+ القادمة من أحداث السحب والإفلات، WebSockets، WebRTC، أو غيرها من واجهات برمجة التطبيقات. A
+ مثال يظهر كيفية تحميل نموذج في الذاكرة باستخدام عناوين URL لـ Blob أدناه.
+
+
+
+ // Blob or File objects created when dragging files into the webpage.
+ const blobs = {'fish.gltf': blob1, 'diffuse.png': blob2, 'normal.png': blob3};
+
+ const manager = new THREE.LoadingManager();
+
+ // Initialize loading manager with URL callback.
+ const objectURLs = [];
+ manager.setURLModifier( ( url ) => {
+
+ url = URL.createObjectURL( blobs[ url ] );
+ objectURLs.push( url );
+ return url;
+
+ } );
+
+ // Load as usual, then revoke the blob URLs.
+ const loader = new THREE.GLTFLoader( manager );
+ loader.load( 'fish.gltf', (gltf) => {
+
+ scene.add( gltf.scene );
+ objectURLs.forEach( ( url ) => URL.revokeObjectURL( url ) );
+
+ });
+
+
+ أمثلة (Examples)
+
+
+ [example:webgl_loader_obj WebGL / loader / obj]
+ [example:webgl_postprocessing_outline WebGL / postprocesing / outline]
+
+
+ المنشئ (Constructor)
+
+ [name]( [param:Function onLoad], [param:Function onProgress],
+ [param:Function onError] )
+
+
+ [page:Function onLoad] — (اختياري) سيتم استدعاء هذه الدالة عندما يتم
+ جميع المحملات.
+ [page:Function onProgress] — (اختياري) سيتم استدعاء هذه الدالة عند
+ اكتمال عنصر.
+ [page:Function onError] — (اختياري) سيتم استدعاء هذه الدالة عندما يواجه المحمل
+ أخطاء.
+
+ ينشئ جديدًا [name].
+
+
+ الخصائص (Properties)
+
+ [property:Function onStart]
+
+ سيتم استدعاء هذه الدالة عند بدء التحميل. المعاملات هي:
+ [page:String url] — عنوان url للعنصر المحمل للتو.
+ [page:Integer itemsLoaded] — عدد العناصر المحملة حتى الآن.
+ [page:Integer itemsTotal] — إجمالي عدد العناصر التي يجب تحميلها.
+
+ بشكل افتراضي هذا غير محدد.
+
+
+ [property:Function onLoad]
+
+ سيتم استدعاء هذه الدالة عند اكتمال جميع التحميلات. بشكل افتراضي
+ هذا غير محدد، ما لم يتم تمريره في المنشئ.
+
+
+ [property:Function onProgress]
+
+ سيتم استدعاء هذه الدالة عند اكتمال عنصر. المعاملات
+ هي:
+ [page:String url] — عنوان url للعنصر المحمل للتو.
+ [page:Integer itemsLoaded] — عدد العناصر المحملة حتى الآن.
+ [page:Integer itemsTotal] — إجمالي عدد العناصر التي يجب تحميلها.
+
+ بشكل افتراضي هذا غير محدد، ما لم يتم تمريره في المنشئ.
+
+
+ [property:Function onError]
+
+ سيتم استدعاء هذه الدالة عند حدوث خطأ في أي عنصر، مع الحجة:
+ [page:String url] — عنوان url للعنصر الذي حدث فيه خطأ.
+
+ بشكل افتراضي هذا غير محدد، ما لم يتم تمريره في المنشئ.
+
+
+ الطرق (Methods)
+
+
+ [method:this addHandler]( [param:Object regex], [param:Loader loader] )
+
+
+ [page:Object regex] — تعبير منتظم.
+ [page:Loader loader] — المحمل.
+
+
+
+ يسجل محملًا مع التعبير المنتظم المعطى. يمكن استخدامه ل
+ تحديد أي محمل يجب استخدامه لتحميل ملفات معينة. A
+ حالة استخدام نموذجية هي الكتابة فوق المحمل الافتراضي للقوام.
+
+
+// add handler for TGA textures
+manager.addHandler( /\.tga$/i, new TGALoader() );
+
+
+ [method:Loader getHandler]( [param:String file] )
+ [page:String file] — مسار الملف.
+
+
+ يمكن استخدامه لاسترجاع المحمل المسجل لمسار الملف المعطى.
+
+
+ [method:this removeHandler]( [param:Object regex] )
+ [page:Object regex] — تعبير منتظم.
+
+ يزيل المحمل للتعبير المنتظم المعطى.
+
+ [method:String resolveURL]( [param:String url] )
+
+ [page:String url] — عنوان url للتحميل
+
+ بالنظر إلى عنوان URL، يستخدم رد الاتصال بتعديل URL (إن وجد) ويعيد
+ عنوان URL المحلول. إذا لم يتم تعيين تعديل URL، فسيتم إرجاع العنوان الأصلي.
+
+
+ [method:this setURLModifier]( [param:Function callback] )
+
+ [page:Function callback] — رد اتصال تعديل URL. يتم استدعاؤه مع [page:String url] الحجة،
+ ويجب أن يعود [page:String resolvedURL].
+
+ إذا تم توفيره، سيتم تمرير رد الاتصال لكل عنوان URL للمورد قبل
+ يتم إرسال طلب. قد يعود الرد الاتصال بالعنوان الأصلي، أو عنوان URL جديد ل
+ تجاوز سلوك التحميل. يمكن استخدام هذا السلوك لتحميل الأصول من
+ ملفات .ZIP، واجهات برمجة التطبيقات السحب والإفلات، وعناوين URI البيانات.
+
+
+
+
+
+
+ ملاحظة: تم تصميم الطرق التالية ليتم استدعاؤها داخليًا من قبل
+ المحملات. يجب ألا تستدعيها مباشرة.
+
+
+
+ [method:undefined itemStart]( [param:String url] )
+
+ [page:String url] — عنوان url للتحميل
+
+ يجب استدعاء هذا من قبل أي محمل يستخدم المدير عندما يبدأ المحمل
+ تحميل عنوان url.
+
+
+ [method:undefined itemEnd]( [param:String url] )
+
+ [page:String url] — عنوان url المحمَّل
+
+ يجب استدعاء هذا من قبل أي محمل يستخدم المدير عند انتهاء المحمل
+ تحميل عنوان url.
+
+
+ [method:undefined itemError]( [param:String url] )
+
+ [page:String url] — عنوان url المحمَّل
+
+ يجب استدعاء هذا من قبل أي محمل يستخدم المدير عند حدوث خطأ في المحمل
+ تحميل عنوان url.
+
+
+ المصدر (Source)
+
+
+ [link:https://github.com/mrdoob/three.js/blob/master/src/loaders/LoadingManager.js src/loaders/LoadingManager.js]
+
+
+
diff --git a/docs/list.json b/docs/list.json
index dd00962d8158d8..1b4d82772d474f 100644
--- a/docs/list.json
+++ b/docs/list.json
@@ -637,6 +637,11 @@
"MaterialLoader": "api/ar/loaders/MaterialLoader",
"ObjectLoader": "api/ar/loaders/ObjectLoader",
"TextureLoader": "api/ar/loaders/TextureLoader"
+ },
+
+ "Loaders / Managers": {
+ "DefaultLoadingManager": "api/ar/loaders/managers/DefaultLoadingManager",
+ "LoadingManager": "api/ar/loaders/managers/LoadingManager"
}
}
From 74b9e7ef8edd6baf9bc97f19825c3a361280cc7d Mon Sep 17 00:00:00 2001
From: WestLangley
Date: Wed, 7 Jun 2023 04:32:57 -0400
Subject: [PATCH 3/7] Ignore tangents when flat shading (#26197)
---
src/renderers/webgl/WebGLProgram.js | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/src/renderers/webgl/WebGLProgram.js b/src/renderers/webgl/WebGLProgram.js
index c90064186f0a75..4039753d6cefc8 100644
--- a/src/renderers/webgl/WebGLProgram.js
+++ b/src/renderers/webgl/WebGLProgram.js
@@ -536,7 +536,7 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
//
- parameters.vertexTangents ? '#define USE_TANGENT' : '',
+ parameters.vertexTangents && parameters.flatShading === false ? '#define USE_TANGENT' : '',
parameters.vertexColors ? '#define USE_COLOR' : '',
parameters.vertexAlphas ? '#define USE_COLOR_ALPHA' : '',
parameters.vertexUv1s ? '#define USE_UV1' : '',
@@ -723,7 +723,7 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
parameters.transmissionMap ? '#define USE_TRANSMISSIONMAP' : '',
parameters.thicknessMap ? '#define USE_THICKNESSMAP' : '',
- parameters.vertexTangents ? '#define USE_TANGENT' : '',
+ parameters.vertexTangents && parameters.flatShading === false ? '#define USE_TANGENT' : '',
parameters.vertexColors || parameters.instancingColor ? '#define USE_COLOR' : '',
parameters.vertexAlphas ? '#define USE_COLOR_ALPHA' : '',
parameters.vertexUv1s ? '#define USE_UV1' : '',
From 07bbe50b51122a4336355363e90970dc6c94c2c3 Mon Sep 17 00:00:00 2001
From: ycw
Date: Wed, 7 Jun 2023 16:34:23 +0800
Subject: [PATCH 4/7] Docs: Dedent code node content correctly. (#26115)
* dedent
* for loop
* use dedent()
---
docs/page.js | 24 ++++++++++++++++++++----
1 file changed, 20 insertions(+), 4 deletions(-)
diff --git a/docs/page.js b/docs/page.js
index a8ee9c3d0714e4..7c888613faeb51 100644
--- a/docs/page.js
+++ b/docs/page.js
@@ -106,16 +106,32 @@ function onDocumentLoad() {
// handle code snippets formatting
+ function dedent( text ) {
+
+ // ignores singleline text
+ const lines = text.split( '\n' );
+ if ( lines.length <= 1 ) return text;
+
+ // ignores blank text
+ const nonBlankLine = lines.filter( l => l.trim() )[ 0 ];
+ if ( nonBlankLine === undefined ) return text;
+
+ // strips indents if any
+ const m = nonBlankLine.match( /^([\t ]+)/ );
+ if ( m ) text = lines.map( l => l.startsWith( m[ 1 ] ) ? l.substring( m[ 1 ].length ) : l ).join( '\n' );
+
+ // strips leading and trailing whitespaces finally
+ return text.trim();
+
+ }
+
const elements = document.getElementsByTagName( 'code' );
for ( let i = 0; i < elements.length; i ++ ) {
const element = elements[ i ];
- text = element.textContent.trim();
- text = text.replace( /^\t\t/gm, '' );
-
- element.textContent = text;
+ element.textContent = dedent( element.textContent );
}
From 14ba68981194a8d1e0a16d9e0af00fa3dabd5146 Mon Sep 17 00:00:00 2001
From: Michael Herzog
Date: Wed, 7 Jun 2023 11:47:31 +0200
Subject: [PATCH 5/7] Update webgl_geometry_csg.html
Update `three-bvh-csg` one more time.
---
examples/webgl_geometry_csg.html | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/examples/webgl_geometry_csg.html b/examples/webgl_geometry_csg.html
index a801738163f778..fee4003c3b6d01 100644
--- a/examples/webgl_geometry_csg.html
+++ b/examples/webgl_geometry_csg.html
@@ -34,7 +34,7 @@
"three": "../build/three.module.js",
"three/addons/": "./jsm/",
"three-mesh-bvh": "https://unpkg.com/three-mesh-bvh@0.6.0/build/index.module.js",
- "three-bvh-csg": "https://unpkg.com/three-bvh-csg@0.0.6/build/index.module.js"
+ "three-bvh-csg": "https://unpkg.com/three-bvh-csg@0.0.7/build/index.module.js"
}
}
From df27d3be030a644883d233e0892f0e6792c615a1 Mon Sep 17 00:00:00 2001
From: sunag
Date: Wed, 7 Jun 2023 13:34:31 -0300
Subject: [PATCH 6/7] WebGPURenderer: Backdrop Node - Part 2/3 (#26196)
* WebGPURenderer: Depth buffer improvements
* CameraNode: Added cameraNear, cameraFar
* Object3DNode: Added modelScale, objectScale()
* Added TextureBicubicNode, textureBicubic
* TextureNode: Added .size(), level() and uv()
* Added ViewportDepthTextureNode: viewportDepthTexture()
* Added ViewportDepthNode: depth, depthTexture()
* Added viewportMipTexture()
* Update imports
* Add webgpu_backdrop_area example
* update title
* CameraNode: Fix VIEW_MATRIX
---
examples/files.json | 1 +
examples/jsm/nodes/Nodes.js | 13 +-
examples/jsm/nodes/accessors/CameraNode.js | 26 ++-
examples/jsm/nodes/accessors/ModelNode.js | 1 +
examples/jsm/nodes/accessors/Object3DNode.js | 12 +-
.../jsm/nodes/accessors/TextureBicubicNode.js | 94 +++++++++
examples/jsm/nodes/accessors/TextureNode.js | 37 ++++
.../jsm/nodes/accessors/TextureSizeNode.js | 35 ++++
.../jsm/nodes/display/ViewportDepthNode.js | 69 +++++++
.../nodes/display/ViewportDepthTextureNode.js | 34 ++++
.../display/ViewportSharedTextureNode.js | 11 +-
.../jsm/nodes/display/ViewportTextureNode.js | 38 ++--
examples/jsm/renderers/common/Renderer.js | 6 +
.../jsm/renderers/webgpu/WebGPUBackend.js | 117 +++++++----
.../webgpu/utils/WebGPUTextureUtils.js | 6 +-
.../jsm/renderers/webgpu/utils/WebGPUUtils.js | 6 +-
examples/screenshots/webgpu_backdrop_area.jpg | Bin 0 -> 3413 bytes
examples/webgpu_backdrop_area.html | 181 ++++++++++++++++++
test/e2e/puppeteer.js | 1 +
19 files changed, 622 insertions(+), 66 deletions(-)
create mode 100644 examples/jsm/nodes/accessors/TextureBicubicNode.js
create mode 100644 examples/jsm/nodes/accessors/TextureSizeNode.js
create mode 100644 examples/jsm/nodes/display/ViewportDepthNode.js
create mode 100644 examples/jsm/nodes/display/ViewportDepthTextureNode.js
create mode 100644 examples/screenshots/webgpu_backdrop_area.jpg
create mode 100644 examples/webgpu_backdrop_area.html
diff --git a/examples/files.json b/examples/files.json
index fda127ff56df75..8a231b23885987 100644
--- a/examples/files.json
+++ b/examples/files.json
@@ -307,6 +307,7 @@
"webgpu": [
"webgpu_audio_processing",
"webgpu_backdrop",
+ "webgpu_backdrop_area",
"webgpu_compute",
"webgpu_cubemap_adjustments",
"webgpu_cubemap_dynamic",
diff --git a/examples/jsm/nodes/Nodes.js b/examples/jsm/nodes/Nodes.js
index 9eaed9ad339f83..90a19fbbab3585 100644
--- a/examples/jsm/nodes/Nodes.js
+++ b/examples/jsm/nodes/Nodes.js
@@ -65,16 +65,17 @@ export * from './shadernode/ShaderNode.js';
export { default as BitangentNode, bitangentGeometry, bitangentLocal, bitangentView, bitangentWorld, transformedBitangentView, transformedBitangentWorld } from './accessors/BitangentNode.js';
export { default as BufferAttributeNode, bufferAttribute, dynamicBufferAttribute } from './accessors/BufferAttributeNode.js';
export { default as BufferNode, buffer } from './accessors/BufferNode.js';
-export { default as CameraNode, cameraProjectionMatrix, cameraViewMatrix, cameraNormalMatrix, cameraWorldMatrix, cameraPosition } from './accessors/CameraNode.js';
+export { default as CameraNode, cameraProjectionMatrix, cameraViewMatrix, cameraNormalMatrix, cameraWorldMatrix, cameraPosition, cameraNear, cameraFar } from './accessors/CameraNode.js';
export { default as CubeTextureNode, cubeTexture } from './accessors/CubeTextureNode.js';
export { default as ExtendedMaterialNode, materialNormal } from './accessors/ExtendedMaterialNode.js';
export { default as InstanceNode, instance } from './accessors/InstanceNode.js';
export { default as MaterialNode, materialUV, materialAlphaTest, materialColor, materialShininess, materialEmissive, materialOpacity, materialSpecularColor, materialReflectivity, materialRoughness, materialMetalness, materialRotation } from './accessors/MaterialNode.js';
export { default as MaterialReferenceNode, materialReference } from './accessors/MaterialReferenceNode.js';
-export { default as ModelNode, modelDirection, modelViewMatrix, modelNormalMatrix, modelWorldMatrix, modelPosition, modelViewPosition } from './accessors/ModelNode.js';
+export { default as TextureBicubicNode, textureBicubic } from './accessors/TextureBicubicNode.js';
+export { default as ModelNode, modelDirection, modelViewMatrix, modelNormalMatrix, modelWorldMatrix, modelPosition, modelViewPosition, modelScale } from './accessors/ModelNode.js';
export { default as ModelViewProjectionNode, modelViewProjection } from './accessors/ModelViewProjectionNode.js';
export { default as NormalNode, normalGeometry, normalLocal, normalView, normalWorld, transformedNormalView, transformedNormalWorld } from './accessors/NormalNode.js';
-export { default as Object3DNode, objectDirection, objectViewMatrix, objectNormalMatrix, objectWorldMatrix, objectPosition, objectViewPosition } from './accessors/Object3DNode.js';
+export { default as Object3DNode, objectDirection, objectViewMatrix, objectNormalMatrix, objectWorldMatrix, objectPosition, objectScale, objectViewPosition } from './accessors/Object3DNode.js';
export { default as PointUVNode, pointUV } from './accessors/PointUVNode.js';
export { default as PositionNode, positionGeometry, positionLocal, positionWorld, positionWorldDirection, positionView, positionViewDirection } from './accessors/PositionNode.js';
export { default as ReferenceNode, reference } from './accessors/ReferenceNode.js';
@@ -82,7 +83,7 @@ export { default as ReflectVectorNode, reflectVector } from './accessors/Reflect
export { default as SkinningNode, skinning } from './accessors/SkinningNode.js';
export { default as StorageBufferNode, storage } from './accessors/StorageBufferNode.js';
export { default as TangentNode, tangentGeometry, tangentLocal, tangentView, tangentWorld, transformedTangentView, transformedTangentWorld } from './accessors/TangentNode.js';
-export { default as TextureNode, texture, sampler } from './accessors/TextureNode.js';
+export { default as TextureNode, texture, /*textureLevel,*/ sampler } from './accessors/TextureNode.js';
export { default as UVNode, uv } from './accessors/UVNode.js';
export { default as UserDataNode, userData } from './accessors/UserDataNode.js';
@@ -95,8 +96,10 @@ export { default as NormalMapNode, normalMap, TBNViewMatrix } from './display/No
export { default as PosterizeNode, posterize } from './display/PosterizeNode.js';
export { default as ToneMappingNode, toneMapping } from './display/ToneMappingNode.js';
export { default as ViewportNode, viewportCoordinate, viewportResolution, viewportTopLeft, viewportBottomLeft, viewportTopRight, viewportBottomRight } from './display/ViewportNode.js';
-export { default as ViewportTextureNode, viewportTexture } from './display/ViewportTextureNode.js';
+export { default as ViewportTextureNode, viewportTexture, viewportMipTexture } from './display/ViewportTextureNode.js';
export { default as ViewportSharedTextureNode, viewportSharedTexture } from './display/ViewportSharedTextureNode.js';
+export { default as ViewportDepthTextureNode, viewportDepthTexture } from './display/ViewportDepthTextureNode.js';
+export { default as ViewportDepthNode, viewZToOrthographicDepth, orthographicDepthToViewZ, viewZToPerspectiveDepth, perspectiveDepthToViewZ, depth, depthTexture } from './display/ViewportDepthNode.js';
// code
export { default as ExpressionNode, expression } from './code/ExpressionNode.js';
diff --git a/examples/jsm/nodes/accessors/CameraNode.js b/examples/jsm/nodes/accessors/CameraNode.js
index 7e41af5a01f62b..df37f6150be612 100644
--- a/examples/jsm/nodes/accessors/CameraNode.js
+++ b/examples/jsm/nodes/accessors/CameraNode.js
@@ -18,6 +18,10 @@ class CameraNode extends Object3DNode {
return 'mat4';
+ } else if ( scope === CameraNode.NEAR || scope === CameraNode.FAR ) {
+
+ return 'float';
+
}
return super.getNodeType( builder );
@@ -30,13 +34,21 @@ class CameraNode extends Object3DNode {
const uniformNode = this._uniformNode;
const scope = this.scope;
- if ( scope === CameraNode.PROJECTION_MATRIX ) {
+ if ( scope === CameraNode.VIEW_MATRIX ) {
+
+ uniformNode.value = camera.matrixWorldInverse;
+
+ } else if ( scope === CameraNode.PROJECTION_MATRIX ) {
uniformNode.value = camera.projectionMatrix;
- } else if ( scope === CameraNode.VIEW_MATRIX ) {
+ } else if ( scope === CameraNode.NEAR ) {
- uniformNode.value = camera.matrixWorldInverse;
+ uniformNode.value = camera.near;
+
+ } else if ( scope === CameraNode.FAR ) {
+
+ uniformNode.value = camera.far;
} else {
@@ -56,6 +68,10 @@ class CameraNode extends Object3DNode {
this._uniformNode.nodeType = 'mat4';
+ } else if ( scope === CameraNode.NEAR || scope === CameraNode.FAR ) {
+
+ this._uniformNode.nodeType = 'float';
+
}
return super.generate( builder );
@@ -65,10 +81,14 @@ class CameraNode extends Object3DNode {
}
CameraNode.PROJECTION_MATRIX = 'projectionMatrix';
+CameraNode.NEAR = 'near';
+CameraNode.FAR = 'far';
export default CameraNode;
export const cameraProjectionMatrix = nodeImmutable( CameraNode, CameraNode.PROJECTION_MATRIX );
+export const cameraNear = nodeImmutable( CameraNode, CameraNode.NEAR );
+export const cameraFar = nodeImmutable( CameraNode, CameraNode.FAR );
export const cameraViewMatrix = nodeImmutable( CameraNode, CameraNode.VIEW_MATRIX );
export const cameraNormalMatrix = nodeImmutable( CameraNode, CameraNode.NORMAL_MATRIX );
export const cameraWorldMatrix = nodeImmutable( CameraNode, CameraNode.WORLD_MATRIX );
diff --git a/examples/jsm/nodes/accessors/ModelNode.js b/examples/jsm/nodes/accessors/ModelNode.js
index d63adbd57b1242..831369a2fac17a 100644
--- a/examples/jsm/nodes/accessors/ModelNode.js
+++ b/examples/jsm/nodes/accessors/ModelNode.js
@@ -27,6 +27,7 @@ export const modelViewMatrix = nodeImmutable( ModelNode, ModelNode.VIEW_MATRIX )
export const modelNormalMatrix = nodeImmutable( ModelNode, ModelNode.NORMAL_MATRIX );
export const modelWorldMatrix = nodeImmutable( ModelNode, ModelNode.WORLD_MATRIX );
export const modelPosition = nodeImmutable( ModelNode, ModelNode.POSITION );
+export const modelScale = nodeImmutable( ModelNode, ModelNode.SCALE );
export const modelViewPosition = nodeImmutable( ModelNode, ModelNode.VIEW_POSITION );
addNodeClass( ModelNode );
diff --git a/examples/jsm/nodes/accessors/Object3DNode.js b/examples/jsm/nodes/accessors/Object3DNode.js
index 516fc32a8d82bb..9cfa4505b08664 100644
--- a/examples/jsm/nodes/accessors/Object3DNode.js
+++ b/examples/jsm/nodes/accessors/Object3DNode.js
@@ -32,7 +32,7 @@ class Object3DNode extends Node {
return 'mat3';
- } else if ( scope === Object3DNode.POSITION || scope === Object3DNode.VIEW_POSITION || scope === Object3DNode.DIRECTION ) {
+ } else if ( scope === Object3DNode.POSITION || scope === Object3DNode.VIEW_POSITION || scope === Object3DNode.DIRECTION || scope === Object3DNode.SCALE ) {
return 'vec3';
@@ -64,6 +64,12 @@ class Object3DNode extends Node {
uniformNode.value.setFromMatrixPosition( object.matrixWorld );
+ } else if ( scope === Object3DNode.SCALE ) {
+
+ uniformNode.value = uniformNode.value || new Vector3();
+
+ uniformNode.value.setFromMatrixScale( object.matrixWorld );
+
} else if ( scope === Object3DNode.DIRECTION ) {
uniformNode.value = uniformNode.value || new Vector3();
@@ -95,7 +101,7 @@ class Object3DNode extends Node {
this._uniformNode.nodeType = 'mat3';
- } else if ( scope === Object3DNode.POSITION || scope === Object3DNode.VIEW_POSITION || scope === Object3DNode.DIRECTION ) {
+ } else if ( scope === Object3DNode.POSITION || scope === Object3DNode.VIEW_POSITION || scope === Object3DNode.DIRECTION || scope === Object3DNode.SCALE ) {
this._uniformNode.nodeType = 'vec3';
@@ -127,6 +133,7 @@ Object3DNode.VIEW_MATRIX = 'viewMatrix';
Object3DNode.NORMAL_MATRIX = 'normalMatrix';
Object3DNode.WORLD_MATRIX = 'worldMatrix';
Object3DNode.POSITION = 'position';
+Object3DNode.SCALE = 'scale';
Object3DNode.VIEW_POSITION = 'viewPosition';
Object3DNode.DIRECTION = 'direction';
@@ -137,6 +144,7 @@ export const objectViewMatrix = nodeProxy( Object3DNode, Object3DNode.VIEW_MATRI
export const objectNormalMatrix = nodeProxy( Object3DNode, Object3DNode.NORMAL_MATRIX );
export const objectWorldMatrix = nodeProxy( Object3DNode, Object3DNode.WORLD_MATRIX );
export const objectPosition = nodeProxy( Object3DNode, Object3DNode.POSITION );
+export const objectScale = nodeProxy( Object3DNode, Object3DNode.SCALE );
export const objectViewPosition = nodeProxy( Object3DNode, Object3DNode.VIEW_POSITION );
addNodeClass( Object3DNode );
diff --git a/examples/jsm/nodes/accessors/TextureBicubicNode.js b/examples/jsm/nodes/accessors/TextureBicubicNode.js
new file mode 100644
index 00000000000000..846450d8f12aca
--- /dev/null
+++ b/examples/jsm/nodes/accessors/TextureBicubicNode.js
@@ -0,0 +1,94 @@
+import TempNode from '../core/TempNode.js';
+import { addNodeClass } from '../core/Node.js';
+import { add, mul, div } from '../math/OperatorNode.js';
+import { floor, ceil, fract, pow } from '../math/MathNode.js';
+import { nodeProxy, addNodeElement, float, vec2, vec4, int } from '../shadernode/ShaderNode.js';
+
+// Mipped Bicubic Texture Filtering by N8
+// https://www.shadertoy.com/view/Dl2SDW
+
+const bC = 1.0 / 6.0;
+
+const w0 = ( a ) => mul( bC, mul( a, mul( a, a.negate().add( 3.0 ) ).sub( 3.0 ) ).add( 1.0 ) );
+
+const w1 = ( a ) => mul( bC, mul( a, mul( a, mul( 3.0, a ).sub( 6.0 ) ) ).add( 4.0 ) );
+
+const w2 = ( a ) => mul( bC, mul( a, mul( a, mul( - 3.0, a ).add( 3.0 ) ).add( 3.0 ) ).add( 1.0 ) );
+
+const w3 = ( a ) => mul( bC, pow( a, 3 ) );
+
+const g0 = ( a ) => w0( a ).add( w1( a ) );
+
+const g1 = ( a ) => w2( a ).add( w3( a ) );
+
+// h0 and h1 are the two offset functions
+const h0 = ( a ) => add( - 1.0, w1( a ).div( w0( a ).add( w1( a ) ) ) );
+
+const h1 = ( a ) => add( 1.0, w3( a ).div( w2( a ).add( w3( a ) ) ) );
+
+const bicubic = ( textureNode, texelSize, lod ) => {
+
+ const uv = textureNode.uvNode;
+ const uvScaled = mul( uv, texelSize.zw ).add( 0.5 );
+
+ const iuv = floor( uvScaled );
+ const fuv = fract( uvScaled );
+
+ const g0x = g0( fuv.x );
+ const g1x = g1( fuv.x );
+ const h0x = h0( fuv.x );
+ const h1x = h1( fuv.x );
+ const h0y = h0( fuv.y );
+ const h1y = h1( fuv.y );
+
+ const p0 = vec2( iuv.x.add( h0x ), iuv.y.add( h0y ) ).sub( 0.5 ).mul( texelSize.xy );
+ const p1 = vec2( iuv.x.add( h1x ), iuv.y.add( h0y ) ).sub( 0.5 ).mul( texelSize.xy );
+ const p2 = vec2( iuv.x.add( h0x ), iuv.y.add( h1y ) ).sub( 0.5 ).mul( texelSize.xy );
+ const p3 = vec2( iuv.x.add( h1x ), iuv.y.add( h1y ) ).sub( 0.5 ).mul( texelSize.xy );
+
+ const a = g0( fuv.y ).mul( add( g0x.mul( textureNode.uv( p0 ).level( lod ) ), g1x.mul( textureNode.uv( p1 ).level( lod ) ) ) );
+ const b = g1( fuv.y ).mul( add( g0x.mul( textureNode.uv( p2 ).level( lod ) ), g1x.mul( textureNode.uv( p3 ).level( lod ) ) ) );
+
+ return a.add( b );
+
+};
+
+const textureBicubicMethod = ( textureNode, lodNode ) => {
+
+ const fLodSize = vec2( textureNode.size( int( lodNode ) ) );
+ const cLodSize = vec2( textureNode.size( int( lodNode.add( 1.0 ) ) ) );
+ const fLodSizeInv = div( 1.0, fLodSize );
+ const cLodSizeInv = div( 1.0, cLodSize );
+ const fSample = bicubic( textureNode, vec4( fLodSizeInv, fLodSize ), floor( lodNode ) );
+ const cSample = bicubic( textureNode, vec4( cLodSizeInv, cLodSize ), ceil( lodNode ) );
+
+ return fract( lodNode ).mix( fSample, cSample );
+
+};
+
+class TextureBicubicNode extends TempNode {
+
+ constructor( textureNode, blurNode = float( 3 ) ) {
+
+ super( 'vec4' );
+
+ this.textureNode = textureNode;
+ this.blurNode = blurNode;
+
+ }
+
+ construct() {
+
+ return textureBicubicMethod( this.textureNode, this.blurNode );
+
+ }
+
+}
+
+export default TextureBicubicNode;
+
+export const textureBicubic = nodeProxy( TextureBicubicNode );
+
+addNodeElement( 'bicubic', textureBicubic );
+
+addNodeClass( TextureBicubicNode );
diff --git a/examples/jsm/nodes/accessors/TextureNode.js b/examples/jsm/nodes/accessors/TextureNode.js
index fce9e2f6fcfcdb..a2c33d40ec1c1c 100644
--- a/examples/jsm/nodes/accessors/TextureNode.js
+++ b/examples/jsm/nodes/accessors/TextureNode.js
@@ -1,5 +1,7 @@
import UniformNode from '../core/UniformNode.js';
import { uv } from './UVNode.js';
+import { textureSize } from './TextureSizeNode.js';
+import { context } from '../core/ContextNode.js';
import { addNodeClass } from '../core/Node.js';
import { addNodeElement, nodeProxy } from '../shadernode/ShaderNode.js';
@@ -140,6 +142,32 @@ class TextureNode extends UniformNode {
}
+ uv( uvNode ) {
+
+ const textureNode = this.clone();
+ textureNode.uvNode = uvNode;
+
+ return textureNode;
+
+ }
+
+ level( levelNode ) {
+
+ const textureNode = this.clone();
+ textureNode.levelNode = levelNode;
+
+ return context( textureNode, {
+ getMIPLevelAlgorithmNode: ( textureNode, levelNode ) => levelNode
+ } );
+
+ }
+
+ size( levelNode ) {
+
+ return textureSize( this, levelNode );
+
+ }
+
serialize( data ) {
super.serialize( data );
@@ -156,13 +184,22 @@ class TextureNode extends UniformNode {
}
+ clone() {
+
+ return new this.constructor( this.value, this.uvNode, this.levelNode );
+
+ }
+
}
export default TextureNode;
export const texture = nodeProxy( TextureNode );
+//export const textureLevel = ( value, uv, level ) => texture( value, uv ).level( level );
+
export const sampler = ( aTexture ) => ( aTexture.isNode === true ? aTexture : texture( aTexture ) ).convert( 'sampler' );
addNodeElement( 'texture', texture );
+//addNodeElement( 'textureLevel', textureLevel );
addNodeClass( TextureNode );
diff --git a/examples/jsm/nodes/accessors/TextureSizeNode.js b/examples/jsm/nodes/accessors/TextureSizeNode.js
new file mode 100644
index 00000000000000..04501f1a16fdd1
--- /dev/null
+++ b/examples/jsm/nodes/accessors/TextureSizeNode.js
@@ -0,0 +1,35 @@
+import Node from '../core/Node.js';
+import { addNodeClass } from '../core/Node.js';
+import { addNodeElement, nodeProxy } from '../shadernode/ShaderNode.js';
+
+class TextureSizeNode extends Node {
+
+ constructor( textureNode, levelNode = null ) {
+
+ super( 'uvec2' );
+
+ this.isTextureSizeNode = true;
+
+ this.textureNode = textureNode;
+ this.levelNode = levelNode;
+
+ }
+
+ generate( builder, output ) {
+
+ const textureProperty = this.textureNode.build( builder, 'property' );
+ const levelNode = this.levelNode.build( builder, 'int' );
+
+ return builder.format( `textureDimensions( ${textureProperty}, ${levelNode} )`, this.getNodeType( builder ), output );
+
+ }
+
+}
+
+export default TextureSizeNode;
+
+export const textureSize = nodeProxy( TextureSizeNode );
+
+addNodeElement( 'textureSize', textureSize );
+
+addNodeClass( TextureSizeNode );
diff --git a/examples/jsm/nodes/display/ViewportDepthNode.js b/examples/jsm/nodes/display/ViewportDepthNode.js
new file mode 100644
index 00000000000000..7c31c7f4d6349e
--- /dev/null
+++ b/examples/jsm/nodes/display/ViewportDepthNode.js
@@ -0,0 +1,69 @@
+import Node, { addNodeClass } from '../core/Node.js';
+import { nodeImmutable, nodeProxy } from '../shadernode/ShaderNode.js';
+import { cameraNear, cameraFar } from '../accessors/CameraNode.js';
+import { positionView } from '../accessors/PositionNode.js';
+import { viewportDepthTexture } from './ViewportDepthTextureNode.js';
+
+class ViewportDepthNode extends Node {
+
+ constructor( scope, textureNode = null ) {
+
+ super( 'float' );
+
+ this.scope = scope;
+ this.textureNode = textureNode;
+
+ this.isViewportDepthNode = true;
+
+ }
+
+ construct( /*builder*/ ) {
+
+ const { scope } = this;
+
+ let node = null;
+
+ if ( scope === ViewportDepthNode.DEPTH ) {
+
+ node = viewZToOrthographicDepth( positionView.z, cameraNear, cameraFar );
+
+ } else if ( scope === ViewportDepthNode.DEPTH_TEXTURE ) {
+
+ const texture = this.textureNode || viewportDepthTexture();
+
+ const viewZ = perspectiveDepthToViewZ( texture, cameraNear, cameraFar );
+ node = viewZToOrthographicDepth( viewZ, cameraNear, cameraFar );
+
+ }
+
+ return node;
+
+ }
+
+}
+
+// NOTE: viewZ, the z-coordinate in camera space, is negative for points in front of the camera
+
+// -near maps to 0; -far maps to 1
+export const viewZToOrthographicDepth = ( viewZ, near, far ) => viewZ.add( near ).div( near.sub( far ) );
+
+// maps orthographic depth in [ 0, 1 ] to viewZ
+export const orthographicDepthToViewZ = ( depth, near, far ) => near.sub( far ).mul( depth ).sub( near );
+
+// NOTE: https://twitter.com/gonnavis/status/1377183786949959682
+
+// -near maps to 0; -far maps to 1
+export const viewZToPerspectiveDepth = ( viewZ, near, far ) => near.add( viewZ ).mul( far ).div( near.sub( far ).mul( viewZ ) );
+
+// maps perspective depth in [ 0, 1 ] to viewZ
+export const perspectiveDepthToViewZ = ( depth, near, far ) => near.mul( far ).div( far.sub( near ).mul( depth ).sub( far ) );
+
+ViewportDepthNode.DEPTH = 'depth';
+ViewportDepthNode.DEPTH_TEXTURE = 'depthTexture';
+
+export default ViewportDepthNode;
+
+export const depth = nodeImmutable( ViewportDepthNode, ViewportDepthNode.DEPTH );
+export const depthTexture = nodeProxy( ViewportDepthNode, ViewportDepthNode.DEPTH_TEXTURE );
+
+addNodeClass( ViewportDepthNode );
diff --git a/examples/jsm/nodes/display/ViewportDepthTextureNode.js b/examples/jsm/nodes/display/ViewportDepthTextureNode.js
new file mode 100644
index 00000000000000..d090ad2b020b64
--- /dev/null
+++ b/examples/jsm/nodes/display/ViewportDepthTextureNode.js
@@ -0,0 +1,34 @@
+import ViewportTextureNode from './ViewportTextureNode.js';
+import { addNodeClass } from '../core/Node.js';
+import { addNodeElement, nodeProxy } from '../shadernode/ShaderNode.js';
+import { viewportTopLeft } from './ViewportNode.js';
+import { DepthTexture, LinearMipmapLinearFilter, DepthFormat, UnsignedIntType } from 'three';
+
+let sharedDepthbuffer = null;
+
+class ViewportDepthTextureNode extends ViewportTextureNode {
+
+ constructor( uvNode = viewportTopLeft, levelNode = null ) {
+
+ if ( sharedDepthbuffer === null ) {
+
+ sharedDepthbuffer = new DepthTexture();
+ sharedDepthbuffer.minFilter = LinearMipmapLinearFilter;
+ sharedDepthbuffer.type = UnsignedIntType;
+ sharedDepthbuffer.format = DepthFormat;
+
+ }
+
+ super( uvNode, levelNode, sharedDepthbuffer );
+
+ }
+
+}
+
+export default ViewportDepthTextureNode;
+
+export const viewportDepthTexture = nodeProxy( ViewportDepthTextureNode );
+
+addNodeElement( 'viewportDepthTexture', viewportDepthTexture );
+
+addNodeClass( ViewportDepthTextureNode );
diff --git a/examples/jsm/nodes/display/ViewportSharedTextureNode.js b/examples/jsm/nodes/display/ViewportSharedTextureNode.js
index 108631ceb77921..853f26feeda7e6 100644
--- a/examples/jsm/nodes/display/ViewportSharedTextureNode.js
+++ b/examples/jsm/nodes/display/ViewportSharedTextureNode.js
@@ -2,20 +2,21 @@ import ViewportTextureNode from './ViewportTextureNode.js';
import { addNodeClass } from '../core/Node.js';
import { addNodeElement, nodeProxy } from '../shadernode/ShaderNode.js';
import { viewportTopLeft } from './ViewportNode.js';
+import { FramebufferTexture } from 'three';
let sharedFramebuffer = null;
class ViewportSharedTextureNode extends ViewportTextureNode {
- constructor( uv = viewportTopLeft ) {
+ constructor( uvNode = viewportTopLeft, levelNode = null ) {
- super( uv );
+ if ( sharedFramebuffer === null ) {
- }
+ sharedFramebuffer = new FramebufferTexture();
- constructFramebuffer( builder ) {
+ }
- return sharedFramebuffer || ( sharedFramebuffer = super.constructFramebuffer( builder ) );
+ super( uvNode, levelNode, sharedFramebuffer );
}
diff --git a/examples/jsm/nodes/display/ViewportTextureNode.js b/examples/jsm/nodes/display/ViewportTextureNode.js
index e1af41eb04ea1d..356f5c28b4681d 100644
--- a/examples/jsm/nodes/display/ViewportTextureNode.js
+++ b/examples/jsm/nodes/display/ViewportTextureNode.js
@@ -3,33 +3,28 @@ import { NodeUpdateType } from '../core/constants.js';
import { addNodeClass } from '../core/Node.js';
import { addNodeElement, nodeProxy } from '../shadernode/ShaderNode.js';
import { viewportTopLeft } from './ViewportNode.js';
-import { Vector2, FramebufferTexture } from 'three';
+import { Vector2, FramebufferTexture, LinearMipmapLinearFilter } from 'three';
const _size = new Vector2();
class ViewportTextureNode extends TextureNode {
- constructor( uv = viewportTopLeft, level = null ) {
+ constructor( uvNode = viewportTopLeft, levelNode = null, framebufferTexture = null ) {
- super( null, uv, level );
+ if ( framebufferTexture === null ) {
- this.isOutputTextureNode = true;
-
- this.updateBeforeType = NodeUpdateType.FRAME;
-
- }
-
- constructFramebuffer( /*builder*/ ) {
+ framebufferTexture = new FramebufferTexture();
+ framebufferTexture.minFilter = LinearMipmapLinearFilter;
- return new FramebufferTexture();
+ }
- }
+ super( framebufferTexture, uvNode, levelNode );
- construct( builder ) {
+ this.generateMipmaps = false;
- if ( this.value === null ) this.value = this.constructFramebuffer( builder );
+ this.isOutputTextureNode = true;
- return super.construct( builder );
+ this.updateBeforeType = NodeUpdateType.FRAME;
}
@@ -52,8 +47,19 @@ class ViewportTextureNode extends TextureNode {
//
+ const currentGenerateMipmaps = framebufferTexture.generateMipmaps;
+ framebufferTexture.generateMipmaps = this.generateMipmaps;
+
renderer.copyFramebufferToTexture( framebufferTexture );
+ framebufferTexture.generateMipmaps = currentGenerateMipmaps;
+
+ }
+
+ clone() {
+
+ return new this.constructor( this.uvNode, this.levelNode, this.value );
+
}
}
@@ -61,7 +67,9 @@ class ViewportTextureNode extends TextureNode {
export default ViewportTextureNode;
export const viewportTexture = nodeProxy( ViewportTextureNode );
+export const viewportMipTexture = nodeProxy( ViewportTextureNode, null, null, { generateMipmaps: true } );
addNodeElement( 'viewportTexture', viewportTexture );
+addNodeElement( 'viewportMipTexture', viewportMipTexture );
addNodeClass( ViewportTextureNode );
diff --git a/examples/jsm/renderers/common/Renderer.js b/examples/jsm/renderers/common/Renderer.js
index 77fb724074a53a..848b7f091b930b 100644
--- a/examples/jsm/renderers/common/Renderer.js
+++ b/examples/jsm/renderers/common/Renderer.js
@@ -42,6 +42,9 @@ class Renderer {
this.sortObjects = true;
+ this.depth = true;
+ this.stencil = true;
+
// internals
this._pixelRatio = 1;
@@ -239,6 +242,9 @@ class Renderer {
renderContext.scissorValue.copy( scissor ).multiplyScalar( pixelRatio ).floor();
renderContext.scissor = this._scissorTest && renderContext.scissorValue.equals( _screen ) === false;
+ renderContext.depth = this.depth;
+ renderContext.stencil = this.stencil;
+
//
_projScreenMatrix.multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse );
diff --git a/examples/jsm/renderers/webgpu/WebGPUBackend.js b/examples/jsm/renderers/webgpu/WebGPUBackend.js
index 203ed87903f58e..4b41c2372297c6 100644
--- a/examples/jsm/renderers/webgpu/WebGPUBackend.js
+++ b/examples/jsm/renderers/webgpu/WebGPUBackend.js
@@ -7,7 +7,7 @@ import { GPUFeatureName, GPUTextureFormat, GPULoadOp, GPUStoreOp, GPUIndexFormat
import WebGPUNodeBuilder from './nodes/WGSLNodeBuilder.js';
import Backend from '../common/Backend.js';
-import { DepthFormat, WebGPUCoordinateSystem } from 'three';
+import { DepthTexture, DepthFormat, DepthStencilFormat, UnsignedInt248Type, UnsignedIntType, WebGPUCoordinateSystem } from 'three';
import WebGPUUtils from './utils/WebGPUUtils.js';
import WebGPUAttributeUtils from './utils/WebGPUAttributeUtils.js';
@@ -53,7 +53,8 @@ class WebGPUBackend extends Backend {
this.device = null;
this.context = null;
this.colorBuffer = null;
- this.depthBuffer = null;
+
+ this.depthBuffers = new WeakMap();
this.utils = new WebGPUUtils( this );
this.attributeUtils = new WebGPUAttributeUtils( this );
@@ -184,7 +185,7 @@ class WebGPUBackend extends Backend {
}
- depthStencilAttachment.view = this.depthBuffer.createView();
+ depthStencilAttachment.view = this._getDepthBufferGPU( renderContext ).createView();
}
@@ -321,7 +322,7 @@ class WebGPUBackend extends Backend {
}
- descriptor.depthStencilAttachment.view = this.depthBuffer.createView();
+ descriptor.depthStencilAttachment.view = this._getDepthBufferGPU( renderContext ).createView();
if ( color ) {
@@ -670,7 +671,6 @@ class WebGPUBackend extends Backend {
this._configureContext();
this._setupColorBuffer();
- this._setupDepthBuffer();
}
@@ -696,30 +696,44 @@ class WebGPUBackend extends Backend {
}
- copyFramebufferToTexture( framebufferTexture, renderContext ) {
+ copyFramebufferToTexture( texture, renderContext ) {
const renderContextData = this.get( renderContext );
const { encoder, descriptor } = renderContextData;
- const sourceGPU = this.context.getCurrentTexture();
- const destinationGPU = this.get( framebufferTexture ).texture;
+ let sourceGPU = null;
+
+ if ( texture.isFramebufferTexture ) {
+
+ sourceGPU = this.context.getCurrentTexture();
+
+ } else if ( texture.isDepthTexture ) {
+
+ sourceGPU = this._getDepthBufferGPU( renderContext );
+
+ }
+
+ const destinationGPU = this.get( texture ).texture;
renderContextData.currentPass.end();
encoder.copyTextureToTexture(
{
- texture: sourceGPU
+ texture: sourceGPU,
+ origin: { x: 0, y: 0, z: 0 }
},
{
- texture: destinationGPU
+ texture: destinationGPU
},
[
- framebufferTexture.image.width,
- framebufferTexture.image.height
+ texture.image.width,
+ texture.image.height
]
);
+ if ( texture.generateMipmaps ) this.textureUtils.generateMipmaps( texture );
+
descriptor.colorAttachments[ 0 ].loadOp = GPULoadOp.Load;
if ( renderContext.depth ) descriptor.depthStencilAttachment.depthLoadOp = GPULoadOp.Load;
if ( renderContext.stencil ) descriptor.depthStencilAttachment.stencilLoadOp = GPULoadOp.Load;
@@ -731,6 +745,65 @@ class WebGPUBackend extends Backend {
// utils
+ _getDepthBufferGPU( renderContext ) {
+
+ const { depthBuffers } = this;
+ const { width, height } = this.getDrawingBufferSize();
+
+ let depthTexture = depthBuffers.get( renderContext );
+
+ if ( depthTexture !== undefined && depthTexture.image.width === width && depthTexture.image.height === height ) {
+
+ return this.get( depthTexture ).texture;
+
+ }
+
+ this._destroyDepthBufferGPU( renderContext );
+
+ depthTexture = new DepthTexture();
+ depthTexture.name = 'depthBuffer';
+
+ if ( renderContext.stencil ) {
+
+ depthTexture = new DepthTexture();
+ depthTexture.format = DepthStencilFormat;
+ depthTexture.type = UnsignedInt248Type;
+
+ } else if ( renderContext.depth ) {
+
+ depthTexture = new DepthTexture();
+ depthTexture.format = DepthFormat;
+ depthTexture.type = UnsignedIntType;
+
+ }
+
+ depthTexture.image.width = width;
+ depthTexture.image.height = height;
+
+ this.textureUtils.createTexture( depthTexture, { sampleCount: this.parameters.sampleCount } );
+
+ depthBuffers.set( renderContext, depthTexture );
+
+ return this.get( depthTexture ).texture;
+
+ }
+
+ _destroyDepthBufferGPU( renderContext ) {
+
+ const { depthBuffers } = this;
+
+ const depthTexture = depthBuffers.get( renderContext );
+
+ if ( depthTexture !== undefined ) {
+
+ this.textureUtils.destroyTexture( depthTexture );
+
+ depthBuffers.delete( renderContext );
+
+ }
+
+ }
+
_configureContext() {
this.context.configure( {
@@ -763,26 +836,6 @@ class WebGPUBackend extends Backend {
}
- _setupDepthBuffer() {
-
- if ( this.depthBuffer ) this.depthBuffer.destroy();
-
- const { width, height } = this.getDrawingBufferSize();
-
- this.depthBuffer = this.device.createTexture( {
- label: 'depthBuffer',
- size: {
- width: width,
- height: height,
- depthOrArrayLayers: 1
- },
- sampleCount: this.parameters.sampleCount,
- format: GPUTextureFormat.Depth24PlusStencil8,
- usage: GPUTextureUsage.RENDER_ATTACHMENT | GPUTextureUsage.COPY_SRC
- } );
-
- }
-
}
export default WebGPUBackend;
diff --git a/examples/jsm/renderers/webgpu/utils/WebGPUTextureUtils.js b/examples/jsm/renderers/webgpu/utils/WebGPUTextureUtils.js
index cf8c8033a7d9d1..b85aeffd353b16 100644
--- a/examples/jsm/renderers/webgpu/utils/WebGPUTextureUtils.js
+++ b/examples/jsm/renderers/webgpu/utils/WebGPUTextureUtils.js
@@ -86,7 +86,7 @@ class WebGPUTextureUtils {
}
- createTexture( texture ) {
+ createTexture( texture, options = {} ) {
const backend = this.backend;
const textureData = backend.get( texture );
@@ -104,9 +104,9 @@ class WebGPUTextureUtils {
const mipLevelCount = this._getMipLevelCount( texture, width, height, needsMipmaps );
const format = texture.internalFormat || this._getFormat( texture );
//const sampleCount = texture.isRenderTargetTexture || texture.isDepthTexture ? backend.utils.getSampleCount( renderContext ) : 1;
- const sampleCount = 1;
+ const sampleCount = options.sampleCount !== undefined ? options.sampleCount : 1;
- let usage = GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST;
+ let usage = GPUTextureUsage.TEXTURE_BINDING | GPUTextureUsage.COPY_DST | GPUTextureUsage.COPY_SRC;
if ( texture.isCompressedTexture !== true ) {
diff --git a/examples/jsm/renderers/webgpu/utils/WebGPUUtils.js b/examples/jsm/renderers/webgpu/utils/WebGPUUtils.js
index f99ed6eb88ee28..39d8d85d5b2990 100644
--- a/examples/jsm/renderers/webgpu/utils/WebGPUUtils.js
+++ b/examples/jsm/renderers/webgpu/utils/WebGPUUtils.js
@@ -16,10 +16,14 @@ class WebGPUUtils {
format = this.getTextureFormatGPU( renderContext.depthTexture );
- } else {
+ } else if ( renderContext.depth && renderContext.stencil ) {
format = GPUTextureFormat.Depth24PlusStencil8;
+ } else if ( renderContext.depth ) {
+
+ format = GPUTextureFormat.Depth24Plus;
+
}
return format;
diff --git a/examples/screenshots/webgpu_backdrop_area.jpg b/examples/screenshots/webgpu_backdrop_area.jpg
new file mode 100644
index 0000000000000000000000000000000000000000..001fe203e0b94e476d12e5c1c76aa979a0fbc77f
GIT binary patch
literal 3413
zcmex=iF;N$`UAd82aiwDGkXk%h!W@hDLXJZFTlSKSKz#z!M@QZN*Gov5_lOQ9r
zAmjfdjEjJ7WCc47=uik?WMXDvWn%|Afm;CRY-VPlV_AVN1*)tC$}zAAvI;30I#U-U>$dGXcJ4ZK_{h;?$4{I*b?NeztJkjIxOwa0qsLF4K70P+<*SdMK7aZ8?fZ|P
zzZe;qA>IL!82$lzoRJ9>=IkK_0Zp(e6?1osf!KmTtr@Gvt1BaB&)!Jgq?{R@T#ObuKN
n8l%)`5R9gR(Tp%!7K|2$qcy^4Z8%yRj@E|5u{QkA@c$+N?bpn5
literal 0
HcmV?d00001
diff --git a/examples/webgpu_backdrop_area.html b/examples/webgpu_backdrop_area.html
new file mode 100644
index 00000000000000..5d5cd1a7f00d8a
--- /dev/null
+++ b/examples/webgpu_backdrop_area.html
@@ -0,0 +1,181 @@
+
+
+
+ three.js - WebGPU - Backdrop Area
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/test/e2e/puppeteer.js b/test/e2e/puppeteer.js
index 7e76a9a93825ac..43c3e5af4284e6 100644
--- a/test/e2e/puppeteer.js
+++ b/test/e2e/puppeteer.js
@@ -94,6 +94,7 @@ const exceptionList = [
// Awaiting for WebGPU support
'webgpu_audio_processing',
'webgpu_backdrop',
+ 'webgpu_backdrop_area',
'webgpu_compute',
'webgpu_cubemap_adjustments',
'webgpu_cubemap_dynamic',
From 2b8f3608a4c645ba8f329958dcbe258c10ff480e Mon Sep 17 00:00:00 2001
From: Don McCurdy
Date: Wed, 7 Jun 2023 13:00:42 -0400
Subject: [PATCH 7/7] Docs: Fix mistake in Color#getRGB signature. (#26210)
---
docs/api/en/math/Color.html | 2 +-
docs/api/it/math/Color.html | 2 +-
docs/api/zh/math/Color.html | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/docs/api/en/math/Color.html b/docs/api/en/math/Color.html
index 010630b063127f..408ced10806d74 100644
--- a/docs/api/en/math/Color.html
+++ b/docs/api/en/math/Color.html
@@ -217,7 +217,7 @@
- [method:Color getRGB]( [param:Color target], [param:string colorSpace] = SRGBColorSpace )
+ [method:Color getRGB]( [param:Color target], [param:string colorSpace] = LinearSRGBColorSpace )
[page:Color target] — the result will be copied into this object.
diff --git a/docs/api/it/math/Color.html b/docs/api/it/math/Color.html
index 8460c5d8679e61..c4879fb67ead94 100644
--- a/docs/api/it/math/Color.html
+++ b/docs/api/it/math/Color.html
@@ -181,7 +181,7 @@
[method:Object getHSL]( [param:Object target], [param:string colorSpace] = L
- [method:Color getRGB]( [param:Color target], [param:string colorSpace] = SRGBColorSpace )
+ [method:Color getRGB]( [param:Color target], [param:string colorSpace] = LinearSRGBColorSpace )
[page:Color target] - questo risultato sarà copiato in questo oggetto.
diff --git a/docs/api/zh/math/Color.html b/docs/api/zh/math/Color.html
index 2e77617fb21007..8d31093444856b 100644
--- a/docs/api/zh/math/Color.html
+++ b/docs/api/zh/math/Color.html
@@ -182,7 +182,7 @@
[method:Object getHSL]( [param:Object target], [param:string colorSpace] = L
- [method:Color getRGB]( [param:Color target], [param:string colorSpace] = SRGBColorSpace )
+ [method:Color getRGB]( [param:Color target], [param:string colorSpace] = LinearSRGBColorSpace )
[page:Color target] - 结果将复制到这个对象中.