diff --git a/examples/jsm/shaders/HalftoneShader.js b/examples/jsm/shaders/HalftoneShader.js index 78b3f57ff84071..afafea3ac785aa 100644 --- a/examples/jsm/shaders/HalftoneShader.js +++ b/examples/jsm/shaders/HalftoneShader.js @@ -8,7 +8,7 @@ * * Used by {@link HalftonePass}. * - * Shape (1 = Dot, 2 = Ellipse, 3 = Line, 4 = Square) + * Shape (1 = Dot, 2 = Ellipse, 3 = Line, 4 = Square, 5 = Diamond) * Blending Mode (1 = Linear, 2 = Multiply, 3 = Add, 4 = Lighter, 5 = Darker) * * @constant @@ -49,11 +49,13 @@ const HalftoneShader = { #define SQRT2_MINUS_ONE 0.41421356 #define SQRT2_HALF_MINUS_ONE 0.20710678 + #define PI 3.14159265 #define PI2 6.28318531 #define SHAPE_DOT 1 #define SHAPE_ELLIPSE 2 #define SHAPE_LINE 3 #define SHAPE_SQUARE 4 + #define SHAPE_DIAMOND 5 #define BLENDING_LINEAR 1 #define BLENDING_MULTIPLY 2 #define BLENDING_ADD 3 @@ -129,6 +131,15 @@ const HalftoneShader = { rad = pow( abs( rad ), 1.4 ); rad = rad_max * ( rad + ( ( sin_t > cos_t ) ? rad - sin_t * rad : rad - cos_t * rad ) ); + } else if ( shape == SHAPE_DIAMOND ) { + + float angle45 = PI / 4.0; + float theta = atan( p.y - coord.y, p.x - coord.x ) - angle - angle45; + float sin_t = abs( sin( theta ) ); + float cos_t = abs( cos( theta ) ); + rad = pow( abs( rad ), 1.4 ); + rad = rad_max * ( rad + ( ( sin_t > cos_t ) ? rad - sin_t * rad : rad - cos_t * rad ) ); + } return rad - dist; diff --git a/examples/webgl_postprocessing_rgb_halftone.html b/examples/webgl_postprocessing_rgb_halftone.html index 36b08e561b99c5..0a08a175f3b1b8 100644 --- a/examples/webgl_postprocessing_rgb_halftone.html +++ b/examples/webgl_postprocessing_rgb_halftone.html @@ -179,7 +179,7 @@ } const gui = new GUI(); - gui.add( controller, 'shape', { 'Dot': 1, 'Ellipse': 2, 'Line': 3, 'Square': 4 } ).onChange( onGUIChange ); + gui.add( controller, 'shape', { 'Dot': 1, 'Ellipse': 2, 'Line': 3, 'Square': 4, 'Diamond': 5 } ).onChange( onGUIChange ); gui.add( controller, 'radius', 1, 25 ).onChange( onGUIChange ); gui.add( controller, 'rotateR', 0, 90 ).onChange( onGUIChange ); gui.add( controller, 'rotateG', 0, 90 ).onChange( onGUIChange ); diff --git a/src/nodes/lighting/EnvironmentNode.js b/src/nodes/lighting/EnvironmentNode.js index 6e0c6bab0aa407..afed15d0f793ec 100644 --- a/src/nodes/lighting/EnvironmentNode.js +++ b/src/nodes/lighting/EnvironmentNode.js @@ -9,7 +9,7 @@ import { bentNormalView } from '../accessors/AccessorsUtils.js'; import { pmremTexture } from '../pmrem/PMREMNode.js'; import { materialEnvIntensity } from '../accessors/MaterialProperties.js'; -const _envNodeCache = new WeakMap(); +const _rendererCache = new WeakMap(); /** * Represents a physical model for Image-based lighting (IBL). The environment @@ -55,13 +55,15 @@ class EnvironmentNode extends LightingNode { const value = ( envNode.isTextureNode ) ? envNode.value : material[ envNode.property ]; - let cacheEnvNode = _envNodeCache.get( value ); + const cache = this._getPMREMNodeCache( builder.renderer ); + + let cacheEnvNode = cache.get( value ); if ( cacheEnvNode === undefined ) { cacheEnvNode = pmremTexture( value ); - _envNodeCache.set( value, cacheEnvNode ); + cache.set( value, cacheEnvNode ); } @@ -101,6 +103,29 @@ class EnvironmentNode extends LightingNode { } + /** + * Returns the PMREM node cache of the current renderer. + * + * @private + * @param {Renderer} renderer - The current renderer. + * @return {WeakMap} The node cache. + */ + _getPMREMNodeCache( renderer ) { + + let pmremCache = _rendererCache.get( renderer ); + + if ( pmremCache === undefined ) { + + pmremCache = new WeakMap(); + + _rendererCache.set( renderer, pmremCache ); + + } + + return pmremCache; + + } + } export default EnvironmentNode;