@@ -10,8 +10,7 @@ import {
1010 createCamera ,
1111 createControls ,
1212 createBackground ,
13- createLightsAsync ,
14- createGlowEffect
13+ createLightsAsync
1514} from "./game/scene-elements" ;
1615import {
1716 Clock ,
@@ -35,6 +34,8 @@ import { localPlayer } from "./game/player";
3534import GUI from 'lil-gui' ;
3635import { World } from "./game/world" ;
3736import { create8x8BoardAsync } from "./game/board" ;
37+ import { EffectComposer , OutputPass , RenderPass , ShaderPass , UnrealBloomPass } from "three/examples/jsm/Addons.js" ;
38+ import { BloomManager } from "./game/bloom-manager" ;
3839
3940// Required for Github Pages deployment
4041DefaultLoadingManager . setURLModifier ( ( url ) => {
@@ -106,17 +107,56 @@ async function init() {
106107 const scene = new Scene ( ) ;
107108 const camera = createCamera ( w , h ) ;
108109 const controls = createControls ( camera , renderer ) ;
109- let composer = isMobile ( ) ?
110- undefined :
111- createGlowEffect ( scene , camera , renderer )
110+
111+ const bloomStrength = 0.6 ;
112+ const bloomTarget = new WebGLRenderTarget ( w , h , {
113+ samples : Math . min ( 4 , renderer . capabilities . maxSamples ) ,
114+ type : HalfFloatType
115+ } ) ;
116+ const bloomComposer = new EffectComposer ( renderer , bloomTarget ) ;
117+ bloomComposer . renderToScreen = false ;
118+ bloomComposer . addPass ( new RenderPass ( scene , camera ) ) ;
119+ bloomComposer . addPass ( new UnrealBloomPass ( new Vector2 ( w , h ) , bloomStrength , 0.4 , 0.85 ) ) ;
120+
121+ const renderTarget = new WebGLRenderTarget ( w , h , {
122+ samples : Math . min ( 4 , renderer . capabilities . maxSamples ) ,
123+ type : HalfFloatType
124+ } ) ;
125+ const finalComposer = new EffectComposer ( renderer , renderTarget ) ;
126+ const addBloomPass = new ShaderPass ( new ShaderMaterial ( {
127+ uniforms : {
128+ baseTexture : { value : null } , // set by ShaderPass
129+ bloomTexture : { value : bloomComposer . renderTarget2 . texture } ,
130+ bloomStrength : { value : bloomStrength }
131+ } ,
132+ vertexShader : `
133+ varying vec2 vUv;
134+ void main() { vUv = uv; gl_Position = vec4(position,1.0); }
135+ ` ,
136+ fragmentShader : `
137+ uniform sampler2D baseTexture, bloomTexture;
138+ uniform float bloomStrength;
139+ varying vec2 vUv;
140+ void main() {
141+ vec4 base = texture2D(baseTexture, vUv);
142+ vec4 bloom = texture2D(bloomTexture, vUv);
143+ gl_FragColor = base + bloom * bloomStrength;
144+ }
145+ `
146+ } ) , 'baseTexture' ) ;
147+
148+ finalComposer . addPass ( new RenderPass ( scene , camera ) ) ;
149+ finalComposer . addPass ( addBloomPass ) ;
150+ finalComposer . addPass ( new OutputPass ( ) ) ;
112151
113152 window . addEventListener ( "resize" , ( ) => {
114153 let w = canvas . clientWidth ;
115154 let h = canvas . clientHeight ;
116155 camera . aspect = w / h ;
117156 camera . updateProjectionMatrix ( ) ;
118157 renderer . setSize ( w , h ) ;
119- composer ?. setSize ( w , h ) ;
158+ bloomComposer ?. setSize ( w , h ) ;
159+ finalComposer ?. setSize ( w , h ) ;
120160 } ) ;
121161
122162 await createBackground ( scene , renderer ) ;
@@ -138,17 +178,18 @@ async function init() {
138178 }
139179
140180 const clock = new Clock ( ) ;
141-
181+ const bloomManager = new BloomManager ( scene ) ;
142182 function Update ( ) {
143183 const delta = clock . getDelta ( ) ;
144184 world . update ( delta )
145185 controls . update ( ) ;
146- if ( composer ) {
147- composer . render ( ) ;
148- }
149- else {
150- renderer . render ( scene , camera ) ;
151- }
186+
187+ bloomManager . overrideMaterialsToBlack ( ) ;
188+ bloomComposer . render ( ) ;
189+ bloomManager . restoreMaterials ( ) ;
190+
191+ finalComposer . render ( ) ;
192+
152193 renderFps ( delta ) ;
153194
154195 requestAnimationFrame ( Update ) ;
0 commit comments