diff --git a/packages/room/src/object/visualization/furniture/FurnitureVisualization.ts b/packages/room/src/object/visualization/furniture/FurnitureVisualization.ts index 9ce7c18..0df68cb 100644 --- a/packages/room/src/object/visualization/furniture/FurnitureVisualization.ts +++ b/packages/room/src/object/visualization/furniture/FurnitureVisualization.ts @@ -1,4 +1,5 @@ import { AlphaTolerance, IGraphicAsset, IObjectVisualizationData, IRoomGeometry, IRoomObjectSprite, RoomObjectVariable, RoomObjectVisualizationType } from '@nitrots/api'; +import { BlackToAlphaFilter } from '@nitrots/utils'; import { BLEND_MODES, Filter, Texture } from 'pixi.js'; import { RoomObjectSpriteVisualization } from '../RoomObjectSpriteVisualization'; import { ColorData, LayerData } from '../data'; @@ -7,6 +8,7 @@ import { FurnitureVisualizationData } from './FurnitureVisualizationData'; export class FurnitureVisualization extends RoomObjectSpriteVisualization { protected static DEPTH_MULTIPLIER: number = Math.sqrt(0.5); + private static _blackToAlphaFilter: BlackToAlphaFilter = null; public static TYPE: string = RoomObjectVisualizationType.FURNITURE_STATIC; @@ -333,7 +335,16 @@ export class FurnitureVisualization extends RoomObjectSpriteVisualization sprite.posture = this.getPostureForAsset(scale, assetData.source); sprite.clickHandling = this._clickHandling; - if(sprite.blendMode !== 'add') sprite.filters = this._filters; + if(sprite.blendMode === 'add') + { + if(!FurnitureVisualization._blackToAlphaFilter) FurnitureVisualization._blackToAlphaFilter = new BlackToAlphaFilter(); + + sprite.filters = [FurnitureVisualization._blackToAlphaFilter]; + } + else + { + sprite.filters = this._filters; + } } else { @@ -485,7 +496,9 @@ export class FurnitureVisualization extends RoomObjectSpriteVisualization if(!this.getLayerIgnoreMouse(scale, direction, layerId)) return false; - if(this.getLayerBlendMode(scale, direction, layerId) === 'normal') return false; + const blendMode = this.getLayerBlendMode(scale, direction, layerId); + + if(blendMode === 'normal' || blendMode === 'add') return false; if(layerId !== (totalLayers - 1)) return false; diff --git a/packages/utils/src/filters/BlackToAlphaFilter.ts b/packages/utils/src/filters/BlackToAlphaFilter.ts new file mode 100644 index 0000000..226d2f1 --- /dev/null +++ b/packages/utils/src/filters/BlackToAlphaFilter.ts @@ -0,0 +1,66 @@ +import { Filter, FilterSystem, GlProgram, RenderSurface, Texture } from 'pixi.js'; + +export class BlackToAlphaFilter extends Filter +{ + constructor() + { + const glProgram = GlProgram.from({ + vertex: `in vec2 aPosition; + out vec2 vTextureCoord; + + uniform vec4 uInputSize; + uniform vec4 uOutputFrame; + uniform vec4 uOutputTexture; + + vec4 filterVertexPosition( void ) + { + vec2 position = aPosition * uOutputFrame.zw + uOutputFrame.xy; + + position.x = position.x * (2.0 / uOutputTexture.x) - 1.0; + position.y = position.y * (2.0*uOutputTexture.z / uOutputTexture.y) - uOutputTexture.z; + + return vec4(position, 0.0, 1.0); + } + + vec2 filterTextureCoord( void ) + { + return aPosition * (uOutputFrame.zw * uInputSize.zw); + } + + void main(void) + { + gl_Position = filterVertexPosition(); + vTextureCoord = filterTextureCoord(); + }`, + fragment: ` + in vec2 vTextureCoord; + out vec4 finalColor; + + uniform sampler2D uTexture; + + void main(void) { + vec4 color = texture(uTexture, vTextureCoord); + float brightness = max(max(color.r, color.g), color.b); + finalColor = vec4(color.rgb, color.a * brightness); + } + `, + name: 'black-to-alpha-filter', + }); + + super({ + gpuProgram: null, + glProgram, + resources: {}, + }); + } + + public apply( + filterManager: FilterSystem, + input: Texture, + output: RenderSurface, + clearMode: boolean, + ): void + { + filterManager.applyFilter(this, input, output, clearMode); + } +} diff --git a/packages/utils/src/filters/index.ts b/packages/utils/src/filters/index.ts index 910b9e9..a2b018d 100644 --- a/packages/utils/src/filters/index.ts +++ b/packages/utils/src/filters/index.ts @@ -1,3 +1,4 @@ +export * from './BlackToAlphaFilter'; export * from './PaletteMapFilter'; export * from './PlaneMaskFilter'; export * from './WiredFilter';