@@ -33,10 +33,41 @@ var Reflector = function ( geometry, options ) {
33
33
var clipBias = options . clipBias || 0 ;
34
34
var shader = options . shader || Reflector . ReflectorShader ;
35
35
var useDepthTexture = options . useDepthTexture
36
+ var yAxis = new Vector3 ( 0 , 1 , 0 ) ;
37
+ var vecTemp0 = new Vector3 ( ) ;
38
+ var vecTemp1 = new Vector3 ( ) ;
36
39
37
40
//
38
41
39
42
scope . needsUpdate = false ;
43
+ scope . maxDistance = Reflector . ReflectorShader . uniforms . maxDistance . value
44
+ scope . opacity = Reflector . ReflectorShader . uniforms . opacity . value
45
+
46
+ scope . _isDistanceAttenuation = Reflector . ReflectorShader . defines . isDistanceAttenuation
47
+ Object . defineProperty ( scope , 'isDistanceAttenuation' , {
48
+ get ( ) {
49
+ return scope . _isDistanceAttenuation
50
+ } ,
51
+ set ( val ) {
52
+ if ( scope . _isDistanceAttenuation === val ) return
53
+ scope . _isDistanceAttenuation = val
54
+ scope . material . defines . isDistanceAttenuation = val
55
+ scope . material . needsUpdate = true
56
+ }
57
+ } )
58
+
59
+ scope . _isFresnel = Reflector . ReflectorShader . defines . isFresnel
60
+ Object . defineProperty ( scope , 'isFresnel' , {
61
+ get ( ) {
62
+ return scope . _isFresnel
63
+ } ,
64
+ set ( val ) {
65
+ if ( scope . _isFresnel === val ) return
66
+ scope . _isFresnel = val
67
+ scope . material . defines . isFresnel = val
68
+ scope . material . needsUpdate = true
69
+ }
70
+ } )
40
71
41
72
var reflectorPlane = new Plane ( ) ;
42
73
var normal = new Vector3 ( ) ;
@@ -77,7 +108,9 @@ var Reflector = function ( geometry, options ) {
77
108
78
109
var material = new ShaderMaterial ( {
79
110
transparent : useDepthTexture ,
80
- defines : { useDepthTexture : useDepthTexture } ,
111
+ defines : Object . assign ( {
112
+ useDepthTexture : useDepthTexture
113
+ } , Reflector . ReflectorShader . defines ) ,
81
114
uniforms : UniformsUtils . clone ( shader . uniforms ) ,
82
115
fragmentShader : shader . fragmentShader ,
83
116
vertexShader : shader . vertexShader
@@ -97,6 +130,18 @@ var Reflector = function ( geometry, options ) {
97
130
scope . needsUpdate = false ;
98
131
// console.log('onBeforeRender')
99
132
133
+ material . uniforms [ 'maxDistance' ] . value = scope . maxDistance * ( camera . position . length ( ) / camera . position . y ) ;
134
+ // Temporary hack,
135
+ // need precise calculation like this https://github.com/mrdoob/three.js/pull/20156/commits/8181946068e386d14a283cbd4f8877bc7ae066d3 ,
136
+ // after fully understand http://www.terathon.com/lengyel/Lengyel-Oblique.pdf .
137
+
138
+ material . uniforms [ 'opacity' ] . value = scope . opacity ;
139
+
140
+ vecTemp0 . copy ( camera . position ) . normalize ( ) ;
141
+ vecTemp1 . copy ( vecTemp0 ) . reflect ( yAxis ) ;
142
+ material . uniforms [ 'fresnel' ] . value = ( vecTemp0 . dot ( vecTemp1 ) + 1. ) / 2. ;
143
+ // console.log(material.uniforms['fresnel'].value)
144
+
100
145
reflectorWorldPosition . setFromMatrixPosition ( scope . matrixWorld ) ;
101
146
cameraWorldPosition . setFromMatrixPosition ( camera . matrixWorld ) ;
102
147
@@ -220,25 +265,22 @@ var Reflector = function ( geometry, options ) {
220
265
Reflector . prototype = Object . create ( Mesh . prototype ) ;
221
266
Reflector . prototype . constructor = Reflector ;
222
267
223
- Reflector . ReflectorShader = {
224
-
225
- uniforms : {
226
-
227
- 'color' : {
228
- value : null
229
- } ,
268
+ Reflector . ReflectorShader = { ///todo: Will conflict with Reflector.js?
230
269
231
- 'tDiffuse' : {
232
- value : null
233
- } ,
270
+ defines : {
271
+ isDistanceAttenuation : true ,
272
+ isFresnel : true ,
273
+ } ,
234
274
235
- 'tDepth' : {
236
- value : null
237
- } ,
275
+ uniforms : {
238
276
239
- 'textureMatrix' : {
240
- value : null
241
- }
277
+ color : { value : null } ,
278
+ tDiffuse : { value : null } ,
279
+ tDepth : { value : null } ,
280
+ textureMatrix : { value : null } ,
281
+ maxDistance : { value : 180 } ,
282
+ opacity : { value : .5 } ,
283
+ fresnel : { value : null } ,
242
284
243
285
} ,
244
286
@@ -255,36 +297,40 @@ Reflector.ReflectorShader = {
255
297
'}'
256
298
] . join ( '\n' ) ,
257
299
258
- fragmentShader : [
259
- 'uniform vec3 color;' ,
260
- 'uniform sampler2D tDiffuse;' ,
261
- 'uniform sampler2D tDepth;' ,
262
- 'varying vec4 vUv;' ,
263
-
264
- 'float blendOverlay( float base, float blend ) {' ,
265
-
266
- ' return( base < 0.5 ? ( 2.0 * base * blend ) : ( 1.0 - 2.0 * ( 1.0 - base ) * ( 1.0 - blend ) ) );' ,
267
-
268
- '}' ,
269
-
270
- 'vec3 blendOverlay( vec3 base, vec3 blend ) {' ,
271
-
272
- ' return vec3( blendOverlay( base.r, blend.r ), blendOverlay( base.g, blend.g ), blendOverlay( base.b, blend.b ) );' ,
273
-
274
- '}' ,
275
-
276
- 'void main() {' ,
277
-
278
- ' vec4 base = texture2DProj( tDiffuse, vUv );' ,
279
- ' #ifdef useDepthTexture' ,
280
- ' vec4 depth = texture2DProj( tDepth, vUv );' ,
281
- ' gl_FragColor = vec4( blendOverlay( base.rgb, color ), pow(1.-depth.r,10./*temp*/) );' ,
282
- ' #else' ,
283
- ' gl_FragColor = vec4( blendOverlay( base.rgb, color ), 1.0 );' ,
284
- ' #endif' ,
285
-
286
- '}'
287
- ] . join ( '\n' )
300
+ fragmentShader : `
301
+ uniform vec3 color;
302
+ uniform sampler2D tDiffuse;
303
+ uniform sampler2D tDepth;
304
+ uniform float maxDistance;
305
+ uniform float opacity;
306
+ uniform float fresnel;
307
+ varying vec4 vUv;
308
+ float blendOverlay( float base, float blend ) {
309
+ return( base < 0.5 ? ( 2.0 * base * blend ) : ( 1.0 - 2.0 * ( 1.0 - base ) * ( 1.0 - blend ) ) );
310
+ }
311
+ vec3 blendOverlay( vec3 base, vec3 blend ) {
312
+ return vec3( blendOverlay( base.r, blend.r ), blendOverlay( base.g, blend.g ), blendOverlay( base.b, blend.b ) );
313
+ }
314
+ void main() {
315
+ vec4 base = texture2DProj( tDiffuse, vUv );
316
+ #ifdef useDepthTexture
317
+ float op=opacity;
318
+ float depth = texture2DProj( tDepth, vUv ).r;
319
+ if(depth>maxDistance) discard;
320
+ #ifdef isDistanceAttenuation
321
+ float ratio=1.-(depth/maxDistance);
322
+ float attenuation=ratio*ratio;
323
+ op=opacity*attenuation;
324
+ #endif
325
+ #ifdef isFresnel
326
+ op*=fresnel;
327
+ #endif
328
+ gl_FragColor = vec4( blendOverlay( base.rgb, color ), op );
329
+ #else
330
+ gl_FragColor = vec4( blendOverlay( base.rgb, color ), 1.0 );
331
+ #endif
332
+ }
333
+ ` ,
288
334
} ;
289
335
290
336
export { Reflector } ;
0 commit comments