From 552ad1ae27f7e4f3d7ac19c10476c53636965976 Mon Sep 17 00:00:00 2001 From: Mugen87 Date: Fri, 21 Jun 2024 10:53:11 +0200 Subject: [PATCH 1/4] TextureUtils: Add `contain()`, `cover()` and `fill()`. --- docs/api/en/extras/TextureUtils.html | 15 ++++++ docs/list.json | 3 +- examples/webgl_test_wide_gamut.html | 35 +++---------- src/extras/TextureUtils.js | 73 +++++++++++++++++++++++++++- 4 files changed, 95 insertions(+), 31 deletions(-) diff --git a/docs/api/en/extras/TextureUtils.html b/docs/api/en/extras/TextureUtils.html index 5836e5b98949b3..d655c6e5ab1412 100644 --- a/docs/api/en/extras/TextureUtils.html +++ b/docs/api/en/extras/TextureUtils.html @@ -13,6 +13,21 @@

[name]

Methods

+

[method:Texture contain]( [param:Texture texture], [param:Number aspect] )

+

+ Scales the texture as large as possible within its surface without cropping or stretching the texture. The method preserves the original aspect ratio of the texture. Akin to CSS `object-fit: contain`. +

+ +

[method:Texture cover]( [param:Texture texture], [param:Number aspect] )

+

+ Scales the texture to the smallest possible size to fill the surface, leaving no empty space. The method preserves the original aspect ratio of the texture. Akin to CSS `object-fit: cover`. +

+ +

[method:Texture fill]( [param:Texture texture] )

+

+ Configures the texture to the default transformation. Akin to CSS `object-fit: fill`. +

+

[method:Number getByteLength]( [param:Number width], [param:Number height], [param:Number format], [param:Number type] )

Given the width, height, format, and type of a texture. Determines how diff --git a/docs/list.json b/docs/list.json index 15ecfdac9ef6f8..c3fb7f43edccb0 100644 --- a/docs/list.json +++ b/docs/list.json @@ -103,7 +103,8 @@ "Earcut": "api/en/extras/Earcut", "ImageUtils": "api/en/extras/ImageUtils", "PMREMGenerator": "api/en/extras/PMREMGenerator", - "ShapeUtils": "api/en/extras/ShapeUtils" + "ShapeUtils": "api/en/extras/ShapeUtils", + "TextureUtils": "api/en/extras/TextureUtils" }, "Extras / Core": { diff --git a/examples/webgl_test_wide_gamut.html b/examples/webgl_test_wide_gamut.html index 63357bb43c76ae..eda8d0625890cc 100644 --- a/examples/webgl_test_wide_gamut.html +++ b/examples/webgl_test_wide_gamut.html @@ -128,8 +128,11 @@ textureL.colorSpace = THREE.SRGBColorSpace; textureR.colorSpace = THREE.DisplayP3ColorSpace; - sceneL.background = containTexture( window.innerWidth / window.innerHeight, textureL ); - sceneR.background = containTexture( window.innerWidth / window.innerHeight, textureR ); + THREE.TextureUtils.contain( textureL, window.innerWidth / window.innerHeight ); + THREE.TextureUtils.contain( textureR, window.innerWidth / window.innerHeight ); + + sceneL.background = textureL; + sceneR.background = textureR; } @@ -175,8 +178,8 @@ renderer.setSize( window.innerWidth, window.innerHeight ); - containTexture( window.innerWidth / window.innerHeight, sceneL.background ); - containTexture( window.innerWidth / window.innerHeight, sceneR.background ); + THREE.TextureUtils.contain( sceneL.background, window.innerWidth / window.innerHeight ); + THREE.TextureUtils.contain( sceneR.background, window.innerWidth / window.innerHeight ); } @@ -189,30 +192,6 @@ } - function containTexture( aspect, target ) { - - // Sets the matrix uv transform so the texture image is contained in a region having the specified aspect ratio, - // and does so without distortion. Akin to CSS object-fit: contain. - // Source: https://github.com/mrdoob/three.js/pull/17199 - - var imageAspect = ( target.image && target.image.width ) ? target.image.width / target.image.height : 1; - - if ( aspect > imageAspect ) { - - target.matrix.setUvTransform( 0, 0, aspect / imageAspect, 1, 0, 0.5, 0.5 ); - - } else { - - target.matrix.setUvTransform( 0, 0, 1, imageAspect / aspect, 0, 0.5, 0.5 ); - - } - - target.matrixAutoUpdate = false; - - return target; - - } - function animate() { renderer.setScissor( 0, 0, sliderPos, window.innerHeight ); diff --git a/src/extras/TextureUtils.js b/src/extras/TextureUtils.js index 69f7b73ca5ffb1..40397d9ed42c2f 100644 --- a/src/extras/TextureUtils.js +++ b/src/extras/TextureUtils.js @@ -1,5 +1,71 @@ import { AlphaFormat, LuminanceFormat, LuminanceAlphaFormat, RedFormat, RedIntegerFormat, RGFormat, RGIntegerFormat, RGBFormat, RGBAFormat, RGBAIntegerFormat, RGB_S3TC_DXT1_Format, RGBA_S3TC_DXT1_Format, RGBA_S3TC_DXT3_Format, RGBA_S3TC_DXT5_Format, RGB_PVRTC_2BPPV1_Format, RGBA_PVRTC_2BPPV1_Format, RGB_PVRTC_4BPPV1_Format, RGBA_PVRTC_4BPPV1_Format, RGB_ETC1_Format, RGB_ETC2_Format, RGBA_ETC2_EAC_Format, RGBA_ASTC_4x4_Format, RGBA_ASTC_5x4_Format, RGBA_ASTC_5x5_Format, RGBA_ASTC_6x5_Format, RGBA_ASTC_6x6_Format, RGBA_ASTC_8x5_Format, RGBA_ASTC_8x6_Format, RGBA_ASTC_8x8_Format, RGBA_ASTC_10x5_Format, RGBA_ASTC_10x6_Format, RGBA_ASTC_10x8_Format, RGBA_ASTC_10x10_Format, RGBA_ASTC_12x10_Format, RGBA_ASTC_12x12_Format, RGBA_BPTC_Format, RGB_BPTC_SIGNED_Format, RGB_BPTC_UNSIGNED_Format, RED_RGTC1_Format, SIGNED_RED_RGTC1_Format, RED_GREEN_RGTC2_Format, SIGNED_RED_GREEN_RGTC2_Format, UnsignedByteType, ByteType, UnsignedShortType, ShortType, HalfFloatType, UnsignedShort4444Type, UnsignedShort5551Type, UnsignedIntType, IntType, FloatType, UnsignedInt5999Type } from '../constants.js'; +function contain( texture, aspect ) { + + const imageAspect = ( texture.image && texture.image.width ) ? texture.image.width / texture.image.height : 1; + + if ( imageAspect > aspect ) { + + texture.repeat.x = 1; + texture.repeat.y = imageAspect / aspect; + + texture.offset.x = 0; + texture.offset.y = ( 1 - texture.repeat.y ) / 2; + + } else { + + texture.repeat.x = aspect / imageAspect; + texture.repeat.y = 1; + + texture.offset.x = ( 1 - texture.repeat.x ) / 2; + texture.offset.y = 0; + + } + + return texture; + +} + +function cover( texture, aspect ) { + + const imageAspect = ( texture.image && texture.image.width ) ? texture.image.width / texture.image.height : 1; + + if ( imageAspect > aspect ) { + + texture.repeat.x = aspect / imageAspect; + texture.repeat.y = 1; + + texture.offset.x = ( 1 - texture.repeat.x ) / 2; + texture.offset.y = 0; + + } else { + + texture.repeat.x = 1; + texture.repeat.y = imageAspect / aspect; + + texture.offset.x = 0; + texture.offset.y = ( 1 - texture.repeat.y ) / 2; + + } + + return texture; + +} + +function fill( texture ) { + + texture.repeat.x = 1; + texture.repeat.y = 1; + + texture.offset.x = 0; + texture.offset.y = 0; + + return texture; + +} + + + /** * Given the width, height, format, and type of a texture. Determines how many * bytes must be used to represent the texture. @@ -135,7 +201,10 @@ function getTextureTypeByteLength( type ) { } const TextureUtils = { - getByteLength, + contain, + cover, + fill, + getByteLength }; -export { getByteLength, TextureUtils }; +export { cover, contain, fill, getByteLength, TextureUtils }; From b7ab7d7558632de30f97ea5e8c0d272ad2b2d88c Mon Sep 17 00:00:00 2001 From: Mugen87 Date: Fri, 21 Jun 2024 11:07:34 +0200 Subject: [PATCH 2/4] WebGLTextures: Improve tree shaking. --- src/renderers/webgl/WebGLTextures.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/renderers/webgl/WebGLTextures.js b/src/renderers/webgl/WebGLTextures.js index 225b6d3f1a5132..ea924232005404 100644 --- a/src/renderers/webgl/WebGLTextures.js +++ b/src/renderers/webgl/WebGLTextures.js @@ -2,7 +2,7 @@ import { LinearFilter, LinearMipmapLinearFilter, LinearMipmapNearestFilter, Near import { createElementNS } from '../../utils.js'; import { ColorManagement } from '../../math/ColorManagement.js'; import { Vector2 } from '../../math/Vector2.js'; -import { TextureUtils } from '../../extras/TextureUtils.js'; +import { getByteLength } from '../../extras/TextureUtils.js'; function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, info ) { @@ -855,7 +855,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, if ( texture.layerUpdates.size > 0 ) { - const layerByteLength = TextureUtils.getByteLength( mipmap.width, mipmap.height, texture.format, texture.type ); + const layerByteLength = getByteLength( mipmap.width, mipmap.height, texture.format, texture.type ); for ( const layerIndex of texture.layerUpdates ) { @@ -981,7 +981,7 @@ function WebGLTextures( _gl, extensions, state, properties, capabilities, utils, if ( texture.layerUpdates.size > 0 ) { - const layerByteLength = TextureUtils.getByteLength( image.width, image.height, texture.format, texture.type ); + const layerByteLength = getByteLength( image.width, image.height, texture.format, texture.type ); for ( const layerIndex of texture.layerUpdates ) { From b77bd39aaf0af7a1b95a1bbd2508c61ecc4978e1 Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Fri, 21 Jun 2024 11:16:02 +0200 Subject: [PATCH 3/4] Update TextureUtils.js Clean up. --- src/extras/TextureUtils.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/extras/TextureUtils.js b/src/extras/TextureUtils.js index 40397d9ed42c2f..c98bd1eb2ffbd8 100644 --- a/src/extras/TextureUtils.js +++ b/src/extras/TextureUtils.js @@ -207,4 +207,4 @@ const TextureUtils = { getByteLength }; -export { cover, contain, fill, getByteLength, TextureUtils }; +export { contain, cover, fill, getByteLength, TextureUtils }; From 8dc735091a1a8c95d8979ec8d37250dae5007efc Mon Sep 17 00:00:00 2001 From: Michael Herzog Date: Fri, 21 Jun 2024 11:18:40 +0200 Subject: [PATCH 4/4] Update webgl_test_wide_gamut.html Simplify example. --- examples/webgl_test_wide_gamut.html | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/examples/webgl_test_wide_gamut.html b/examples/webgl_test_wide_gamut.html index eda8d0625890cc..3ef6e33fabb433 100644 --- a/examples/webgl_test_wide_gamut.html +++ b/examples/webgl_test_wide_gamut.html @@ -128,11 +128,8 @@ textureL.colorSpace = THREE.SRGBColorSpace; textureR.colorSpace = THREE.DisplayP3ColorSpace; - THREE.TextureUtils.contain( textureL, window.innerWidth / window.innerHeight ); - THREE.TextureUtils.contain( textureR, window.innerWidth / window.innerHeight ); - - sceneL.background = textureL; - sceneR.background = textureR; + sceneL.background = THREE.TextureUtils.contain( textureL, window.innerWidth / window.innerHeight ); + sceneR.background = THREE.TextureUtils.contain( textureR, window.innerWidth / window.innerHeight ); }