@@ -13,14 +13,12 @@ import {
13
13
Color ,
14
14
ColorRepresentation ,
15
15
Group ,
16
- Material ,
17
16
Mesh ,
18
17
MeshBasicMaterial ,
19
18
MeshDepthMaterial ,
20
19
OrthographicCamera ,
21
20
PlaneGeometry ,
22
21
ShaderMaterial ,
23
- Texture ,
24
22
WebGLRenderTarget ,
25
23
} from 'three' ;
26
24
import { HorizontalBlurShader , VerticalBlurShader } from 'three-stdlib' ;
@@ -119,24 +117,20 @@ export class NgtsContactShadows {
119
117
private color = pick ( this . options , 'color' ) ;
120
118
private near = pick ( this . options , 'near' ) ;
121
119
private far = pick ( this . options , 'far' ) ;
122
-
123
- private shadowsOptions = computed ( ( ) => {
124
- const [ width , height , resolution , color ] = [
125
- this . scaledWidth ( ) ,
126
- this . scaledHeight ( ) ,
127
- this . resolution ( ) ,
128
- this . color ( ) ,
129
- ] ;
130
- const renderTarget = new WebGLRenderTarget ( resolution , resolution ) ;
131
- const renderTargetBlur = new WebGLRenderTarget ( resolution , resolution ) ;
132
- renderTargetBlur . texture . generateMipmaps = renderTarget . texture . generateMipmaps = false ;
133
-
134
- const planeGeometry = new PlaneGeometry ( width , height ) . rotateX ( Math . PI / 2 ) ;
135
- const blurPlane = new Mesh ( planeGeometry ) ;
136
- const depthMaterial = new MeshDepthMaterial ( ) ;
137
- depthMaterial . depthTest = depthMaterial . depthWrite = false ;
138
- depthMaterial . onBeforeCompile = ( shader ) => {
139
- shader . uniforms = { ...shader . uniforms , ucolor : { value : new Color ( color ) } } ;
120
+ private smooth = pick ( this . options , 'smooth' ) ;
121
+ private frames = pick ( this . options , 'frames' ) ;
122
+ private blur = pick ( this . options , 'blur' ) ;
123
+
124
+ private renderTarget = computed ( ( ) => this . createRenderTarget ( this . resolution ( ) ) ) ;
125
+ private renderTargetBlur = computed ( ( ) => this . createRenderTarget ( this . resolution ( ) ) ) ;
126
+ planeGeometry = computed ( ( ) => new PlaneGeometry ( this . scaledWidth ( ) , this . scaledHeight ( ) ) . rotateX ( Math . PI / 2 ) ) ;
127
+ private blurPlane = computed ( ( ) => new Mesh ( this . planeGeometry ( ) ) ) ;
128
+ private depthMaterial = computed ( ( ) => {
129
+ const color = new Color ( this . color ( ) ) ;
130
+ const material = new MeshDepthMaterial ( ) ;
131
+ material . depthTest = material . depthWrite = false ;
132
+ material . onBeforeCompile = ( shader ) => {
133
+ shader . uniforms = { ...shader . uniforms , ucolor : { value : color } } ;
140
134
shader . fragmentShader = shader . fragmentShader . replace (
141
135
`void main() {` , //
142
136
`uniform vec3 ucolor;
@@ -149,86 +143,107 @@ export class NgtsContactShadows {
149
143
'vec4( ucolor * fragCoordZ * 2.0, ( 1.0 - fragCoordZ ) * 1.0 );' ,
150
144
) ;
151
145
} ;
152
-
153
- const horizontalBlurMaterial = new ShaderMaterial ( HorizontalBlurShader ) ;
154
- const verticalBlurMaterial = new ShaderMaterial ( VerticalBlurShader ) ;
155
- verticalBlurMaterial . depthTest = horizontalBlurMaterial . depthTest = false ;
156
-
157
- return {
158
- renderTarget,
159
- planeGeometry,
160
- depthMaterial,
161
- blurPlane,
162
- horizontalBlurMaterial,
163
- verticalBlurMaterial,
164
- renderTargetBlur,
165
- } ;
146
+ return material ;
166
147
} ) ;
167
148
149
+ private horizontalBlurMaterial = new ShaderMaterial ( { ...HorizontalBlurShader , depthTest : false } ) ;
150
+ private verticalBlurMaterial = new ShaderMaterial ( { ...VerticalBlurShader , depthTest : false } ) ;
151
+
168
152
renderOrder = pick ( this . options , 'renderOrder' ) ;
169
153
opacity = pick ( this . options , 'opacity' ) ;
170
154
depthWrite = pick ( this . options , 'depthWrite' ) ;
171
- planeGeometry = computed ( ( ) => this . shadowsOptions ( ) . planeGeometry ) ;
172
- texture = computed ( ( ) => this . shadowsOptions ( ) . renderTarget . texture ) ;
155
+ texture = pick ( this . renderTarget , 'texture' ) ;
173
156
cameraArgs = computed ( ( ) => {
174
157
const [ width , height , near , far ] = [ this . scaledWidth ( ) , this . scaledHeight ( ) , this . near ( ) , this . far ( ) ] ;
175
158
return [ - width / 2 , width / 2 , height / 2 , - height / 2 , near , far ] ;
176
159
} ) ;
177
160
161
+ constructor ( ) {
162
+ extend ( { Group, Mesh, MeshBasicMaterial, OrthographicCamera } ) ;
163
+
164
+ let count = 0 ;
165
+ injectBeforeRender ( ( ) => {
166
+ const shadowsCamera = this . shadowsCameraRef ( ) ?. nativeElement ;
167
+ if ( ! shadowsCamera ) return ;
168
+
169
+ const frames = this . frames ( ) ;
170
+ if ( frames === Infinity || count < frames ) {
171
+ this . renderShadows ( ) ;
172
+ count ++ ;
173
+ }
174
+ } ) ;
175
+ }
176
+
177
+ private renderShadows ( ) {
178
+ const shadowsCamera = this . shadowsCameraRef ( ) ?. nativeElement ;
179
+ if ( ! shadowsCamera ) return ;
180
+
181
+ const [ blur , smooth , gl , scene , contactShadows , depthMaterial , renderTarget ] = [
182
+ this . blur ( ) ,
183
+ this . smooth ( ) ,
184
+ this . gl ( ) ,
185
+ this . scene ( ) ,
186
+ this . contactShadowsRef ( ) . nativeElement ,
187
+ this . depthMaterial ( ) ,
188
+ this . renderTarget ( ) ,
189
+ ] ;
190
+
191
+ const initialBackground = scene . background ;
192
+ const initialOverrideMaterial = scene . overrideMaterial ;
193
+ const initialClearAlpha = gl . getClearAlpha ( ) ;
194
+
195
+ contactShadows . visible = false ;
196
+ scene . background = null ;
197
+ scene . overrideMaterial = depthMaterial ;
198
+ gl . setClearAlpha ( 0 ) ;
199
+
200
+ // render to the render target to get the depths
201
+ gl . setRenderTarget ( renderTarget ) ;
202
+ gl . render ( scene , shadowsCamera ) ;
203
+
204
+ this . blurShadows ( blur ) ;
205
+ if ( smooth ) this . blurShadows ( blur * 0.4 ) ;
206
+
207
+ // reset
208
+ gl . setRenderTarget ( null ) ;
209
+
210
+ contactShadows . visible = true ;
211
+ scene . overrideMaterial = initialOverrideMaterial ;
212
+ scene . background = initialBackground ;
213
+ gl . setClearAlpha ( initialClearAlpha ) ;
214
+ }
215
+
178
216
private blurShadows ( blur : number ) {
179
- const { renderTarget, renderTargetBlur, blurPlane, horizontalBlurMaterial, verticalBlurMaterial } =
180
- this . shadowsOptions ( ) ;
181
217
const shadowsCamera = this . shadowsCameraRef ( ) ?. nativeElement ;
182
218
if ( ! shadowsCamera ) return ;
183
219
220
+ const [ blurPlane , horizontalBlurMaterial , verticalBlurMaterial , renderTargetBlur , renderTarget , gl ] = [
221
+ this . blurPlane ( ) ,
222
+ this . horizontalBlurMaterial ,
223
+ this . verticalBlurMaterial ,
224
+ this . renderTargetBlur ( ) ,
225
+ this . renderTarget ( ) ,
226
+ this . gl ( ) ,
227
+ ] ;
228
+
184
229
blurPlane . visible = true ;
185
230
blurPlane . material = horizontalBlurMaterial ;
186
231
horizontalBlurMaterial . uniforms [ 'tDiffuse' ] . value = renderTarget . texture ;
187
232
horizontalBlurMaterial . uniforms [ 'h' ] . value = blur / 256 ;
188
- this . gl ( ) . setRenderTarget ( renderTargetBlur ) ;
189
- this . gl ( ) . render ( blurPlane , shadowsCamera ) ;
233
+ gl . setRenderTarget ( renderTargetBlur ) ;
234
+ gl . render ( blurPlane , shadowsCamera ) ;
190
235
191
236
blurPlane . material = verticalBlurMaterial ;
192
237
verticalBlurMaterial . uniforms [ 'tDiffuse' ] . value = renderTargetBlur . texture ;
193
238
verticalBlurMaterial . uniforms [ 'v' ] . value = blur / 256 ;
194
- this . gl ( ) . setRenderTarget ( renderTarget ) ;
195
- this . gl ( ) . render ( blurPlane , shadowsCamera ) ;
239
+ gl . setRenderTarget ( renderTarget ) ;
240
+ gl . render ( blurPlane , shadowsCamera ) ;
196
241
blurPlane . visible = false ;
197
242
}
198
243
199
- constructor ( ) {
200
- extend ( { Group, Mesh, MeshBasicMaterial, OrthographicCamera } ) ;
201
-
202
- let count = 0 ;
203
- let initialBackground : Color | Texture | null ;
204
- let initialOverrideMaterial : Material | null ;
205
-
206
- injectBeforeRender ( ( ) => {
207
- const shadowsCamera = this . shadowsCameraRef ( ) ?. nativeElement ;
208
- if ( ! shadowsCamera ) return ;
209
- const [ { frames, blur, smooth } , gl , scene , contactShadows , { depthMaterial, renderTarget } ] = [
210
- this . options ( ) ,
211
- this . gl ( ) ,
212
- this . scene ( ) ,
213
- this . contactShadowsRef ( ) . nativeElement ,
214
- this . shadowsOptions ( ) ,
215
- ] ;
216
- if ( frames === Infinity || count < frames * frames ) {
217
- count ++ ;
218
- initialBackground = scene . background ;
219
- initialOverrideMaterial = scene . overrideMaterial ;
220
- contactShadows . visible = false ;
221
- scene . background = null ;
222
- scene . overrideMaterial = depthMaterial ;
223
- gl . setRenderTarget ( renderTarget ) ;
224
- gl . render ( scene , shadowsCamera ) ;
225
- this . blurShadows ( blur ) ;
226
- if ( smooth ) this . blurShadows ( blur * 0.4 ) ;
227
- gl . setRenderTarget ( null ) ;
228
- contactShadows . visible = true ;
229
- scene . overrideMaterial = initialOverrideMaterial ;
230
- scene . background = initialBackground ;
231
- }
232
- } ) ;
244
+ private createRenderTarget ( resolution : number ) {
245
+ const renderTarget = new WebGLRenderTarget ( resolution , resolution ) ;
246
+ renderTarget . texture . generateMipmaps = false ;
247
+ return renderTarget ;
233
248
}
234
249
}
0 commit comments