Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BatchedMesh: add per-instance setOpacity #28151

Closed
wants to merge 2 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions examples/jsm/renderers/common/RenderObject.js
Expand Up @@ -189,6 +189,7 @@ export default class RenderObject {
if ( object.isBatchedMesh ) {

cacheKey += object._matricesTexture.uuid + ',';
cacheKey += object._opacitiesTexture.uuid + ',';

}

Expand Down
1 change: 1 addition & 0 deletions src/core/Object3D.js
Expand Up @@ -760,6 +760,7 @@ class Object3D extends EventDispatcher {
object.geometryCount = this._geometryCount;

object.matricesTexture = this._matricesTexture.toJSON( meta );
object.opacitiesTexture = this._opacitiesTexture.toJSON( meta );

if ( this.boundingSphere !== null ) {

Expand Down
1 change: 1 addition & 0 deletions src/loaders/ObjectLoader.js
Expand Up @@ -946,6 +946,7 @@ class ObjectLoader extends Loader {
object._geometryCount = data.geometryCount;

object._matricesTexture = getTexture( data.matricesTexture.uuid );
object._opacitiesTexture = getTexture( data.opacitiesTexture.uuid );

break;

Expand Down
59 changes: 58 additions & 1 deletion src/objects/BatchedMesh.js
Expand Up @@ -4,7 +4,7 @@ import { DataTexture } from '../textures/DataTexture.js';
import { FloatType } from '../constants.js';
import { Matrix4 } from '../math/Matrix4.js';
import { Mesh } from './Mesh.js';
import { RGBAFormat } from '../constants.js';
import { RGBAFormat, RedFormat } from '../constants.js';
import { Box3 } from '../math/Box3.js';
import { Sphere } from '../math/Sphere.js';
import { Frustum } from '../math/Frustum.js';
Expand Down Expand Up @@ -160,6 +160,11 @@ class BatchedMesh extends Mesh {

this._initMatricesTexture();

// Local opacity per geometry by using data texture
this._opacitiesTexture = null;

this._initOpacitiesTexture();

}

_initMatricesTexture() {
Expand All @@ -182,6 +187,14 @@ class BatchedMesh extends Mesh {

}

_initOpacitiesTexture() {

const opacitiesTexture = new DataTexture( new Float32Array( this._maxGeometryCount ).fill( 1.0 ), 1, this._maxGeometryCount, RedFormat, FloatType );

this._opacitiesTexture = opacitiesTexture;

}

_initializeGeometry( reference ) {

const geometry = this.geometry;
Expand Down Expand Up @@ -746,6 +759,43 @@ class BatchedMesh extends Mesh {

}

setOpacityAt( geometryId, opacity ) {

// @TODO: Map geometryId to index of the arrays because
// optimize() can make geometryId mismatch the index

const active = this._active;
const opacitiesTexture = this._opacitiesTexture;
const opacitiesArray = this._opacitiesTexture.image.data;
const geometryCount = this._geometryCount;
if ( geometryId >= geometryCount || active[ geometryId ] === false ) {

return this;

}

opacitiesArray[ geometryId ] = opacity;
opacitiesTexture.needsUpdate = true;

return this;

}

getOpacityAt( geometryId ) {

const active = this._active;
const opacitiesArray = this._opacitiesTexture.image.data;
const geometryCount = this._geometryCount;
if ( geometryId >= geometryCount || active[ geometryId ] === false ) {

return null;

}

return opacitiesArray[ geometryId ];

}

setVisibleAt( geometryId, value ) {

const visibility = this._visibility;
Expand Down Expand Up @@ -886,6 +936,9 @@ class BatchedMesh extends Mesh {
this._matricesTexture = source._matricesTexture.clone();
this._matricesTexture.image.data = this._matricesTexture.image.slice();

this._opacitiesTexture = source._opacitiesTexture.clone();
this._opacitiesTexture.image.data = this._opacitiesTexture.image.slice();

return this;

}
Expand All @@ -897,6 +950,10 @@ class BatchedMesh extends Mesh {

this._matricesTexture.dispose();
this._matricesTexture = null;

this._opacitiesTexture.dispose();
this._opacitiesTexture = null;

return this;

}
Expand Down
1 change: 1 addition & 0 deletions src/renderers/WebGLRenderer.js
Expand Up @@ -1997,6 +1997,7 @@ class WebGLRenderer {

p_uniforms.setOptional( _gl, object, 'batchingTexture' );
p_uniforms.setValue( _gl, 'batchingTexture', object._matricesTexture, textures );
p_uniforms.setValue( _gl, 'batchingOpacityTexture', object._opacitiesTexture, textures );

}

Expand Down
Expand Up @@ -2,6 +2,10 @@ export default /* glsl */`
#ifdef USE_BATCHING
attribute float batchId;
uniform highp sampler2D batchingTexture;

uniform highp sampler2D batchingOpacityTexture;
varying float vBatchingOpacity;

mat4 getBatchingMatrix( const in float i ) {

int size = textureSize( batchingTexture, 0 ).x;
Expand Down
2 changes: 2 additions & 0 deletions src/renderers/shaders/ShaderChunk/batching_vertex.glsl.js
@@ -1,5 +1,7 @@
export default /* glsl */`
#ifdef USE_BATCHING
mat4 batchingMatrix = getBatchingMatrix( batchId );

vBatchingOpacity = texelFetch( batchingOpacityTexture, ivec2( 0, batchId ), 0 ).r;
#endif
`;
6 changes: 6 additions & 0 deletions src/renderers/shaders/ShaderChunk/color_fragment.glsl.js
Expand Up @@ -7,5 +7,11 @@ export default /* glsl */`

diffuseColor.rgb *= vColor;

#endif

#if defined( USE_BATCHING )

diffuseColor.a *= vBatchingOpacity;

#endif
`;
6 changes: 6 additions & 0 deletions src/renderers/shaders/ShaderChunk/color_pars_fragment.glsl.js
Expand Up @@ -7,5 +7,11 @@ export default /* glsl */`

varying vec3 vColor;

#endif

#if defined( USE_BATCHING )

varying float vBatchingOpacity;

#endif
`;
1 change: 1 addition & 0 deletions src/renderers/webgl/WebGLProgram.js
Expand Up @@ -800,6 +800,7 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {

parameters.vertexTangents && parameters.flatShading === false ? '#define USE_TANGENT' : '',
parameters.vertexColors || parameters.instancingColor ? '#define USE_COLOR' : '',
parameters.batching ? '#define USE_BATCHING' : '',
parameters.vertexAlphas ? '#define USE_COLOR_ALPHA' : '',
parameters.vertexUv1s ? '#define USE_UV1' : '',
parameters.vertexUv2s ? '#define USE_UV2' : '',
Expand Down