Skip to content

Commit

Permalink
TextureUtils: Add contain(), cover() and fill(). (#28713)
Browse files Browse the repository at this point in the history
* TextureUtils: Add `contain()`, `cover()` and `fill()`.

* WebGLTextures: Improve tree shaking.

* Update TextureUtils.js

Clean up.

* Update webgl_test_wide_gamut.html

Simplify example.
  • Loading branch information
Mugen87 authored Jun 21, 2024
1 parent 96ba72e commit 3ea97b9
Show file tree
Hide file tree
Showing 5 changed files with 95 additions and 34 deletions.
15 changes: 15 additions & 0 deletions docs/api/en/extras/TextureUtils.html
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,21 @@ <h1>[name]</h1>

<h2>Methods</h2>

<h3>[method:Texture contain]( [param:Texture texture], [param:Number aspect] )</h3>
<p>
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`.
</p>

<h3>[method:Texture cover]( [param:Texture texture], [param:Number aspect] )</h3>
<p>
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`.
</p>

<h3>[method:Texture fill]( [param:Texture texture] )</h3>
<p>
Configures the texture to the default transformation. Akin to CSS `object-fit: fill`.
</p>

<h3>[method:Number getByteLength]( [param:Number width], [param:Number height], [param:Number format], [param:Number type] )</h3>
<p>
Given the width, height, format, and type of a texture. Determines how
Expand Down
3 changes: 2 additions & 1 deletion docs/list.json
Original file line number Diff line number Diff line change
Expand Up @@ -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": {
Expand Down
32 changes: 4 additions & 28 deletions examples/webgl_test_wide_gamut.html
Original file line number Diff line number Diff line change
Expand Up @@ -128,8 +128,8 @@
textureL.colorSpace = THREE.SRGBColorSpace;
textureR.colorSpace = THREE.DisplayP3ColorSpace;

sceneL.background = containTexture( window.innerWidth / window.innerHeight, textureL );
sceneR.background = containTexture( window.innerWidth / window.innerHeight, textureR );
sceneL.background = THREE.TextureUtils.contain( textureL, window.innerWidth / window.innerHeight );
sceneR.background = THREE.TextureUtils.contain( textureR, window.innerWidth / window.innerHeight );

}

Expand Down Expand Up @@ -175,8 +175,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 );

}

Expand All @@ -189,30 +189,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 );
Expand Down
73 changes: 71 additions & 2 deletions src/extras/TextureUtils.js
Original file line number Diff line number Diff line change
@@ -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.
Expand Down Expand Up @@ -135,7 +201,10 @@ function getTextureTypeByteLength( type ) {
}

const TextureUtils = {
getByteLength,
contain,
cover,
fill,
getByteLength
};

export { getByteLength, TextureUtils };
export { contain, cover, fill, getByteLength, TextureUtils };
6 changes: 3 additions & 3 deletions src/renderers/webgl/WebGLTextures.js
Original file line number Diff line number Diff line change
Expand Up @@ -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 ) {

Expand Down Expand Up @@ -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 ) {

Expand Down Expand Up @@ -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 ) {

Expand Down

0 comments on commit 3ea97b9

Please sign in to comment.