source: other-projects/playing-in-the-street/summer-2013/trunk/Playing-in-the-Street-WPF/Content/Web/mrdoob-three.js-4862f5f/src/extras/renderers/plugins/LensFlarePlugin.js@ 28897

Last change on this file since 28897 was 28897, checked in by davidb, 10 years ago

GUI front-end to server base plus web page content

File size: 9.7 KB
Line 
1/**
2 * @author mikael emtinger / http://gomo.se/
3 * @author alteredq / http://alteredqualia.com/
4 */
5
6THREE.LensFlarePlugin = function () {
7
8 var _gl, _renderer, _precision, _lensFlare = {};
9
10 this.init = function ( renderer ) {
11
12 _gl = renderer.context;
13 _renderer = renderer;
14
15 _precision = renderer.getPrecision();
16
17 _lensFlare.vertices = new Float32Array( 8 + 8 );
18 _lensFlare.faces = new Uint16Array( 6 );
19
20 var i = 0;
21 _lensFlare.vertices[ i++ ] = -1; _lensFlare.vertices[ i++ ] = -1; // vertex
22 _lensFlare.vertices[ i++ ] = 0; _lensFlare.vertices[ i++ ] = 0; // uv... etc.
23
24 _lensFlare.vertices[ i++ ] = 1; _lensFlare.vertices[ i++ ] = -1;
25 _lensFlare.vertices[ i++ ] = 1; _lensFlare.vertices[ i++ ] = 0;
26
27 _lensFlare.vertices[ i++ ] = 1; _lensFlare.vertices[ i++ ] = 1;
28 _lensFlare.vertices[ i++ ] = 1; _lensFlare.vertices[ i++ ] = 1;
29
30 _lensFlare.vertices[ i++ ] = -1; _lensFlare.vertices[ i++ ] = 1;
31 _lensFlare.vertices[ i++ ] = 0; _lensFlare.vertices[ i++ ] = 1;
32
33 i = 0;
34 _lensFlare.faces[ i++ ] = 0; _lensFlare.faces[ i++ ] = 1; _lensFlare.faces[ i++ ] = 2;
35 _lensFlare.faces[ i++ ] = 0; _lensFlare.faces[ i++ ] = 2; _lensFlare.faces[ i++ ] = 3;
36
37 // buffers
38
39 _lensFlare.vertexBuffer = _gl.createBuffer();
40 _lensFlare.elementBuffer = _gl.createBuffer();
41
42 _gl.bindBuffer( _gl.ARRAY_BUFFER, _lensFlare.vertexBuffer );
43 _gl.bufferData( _gl.ARRAY_BUFFER, _lensFlare.vertices, _gl.STATIC_DRAW );
44
45 _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _lensFlare.elementBuffer );
46 _gl.bufferData( _gl.ELEMENT_ARRAY_BUFFER, _lensFlare.faces, _gl.STATIC_DRAW );
47
48 // textures
49
50 _lensFlare.tempTexture = _gl.createTexture();
51 _lensFlare.occlusionTexture = _gl.createTexture();
52
53 _gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.tempTexture );
54 _gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGB, 16, 16, 0, _gl.RGB, _gl.UNSIGNED_BYTE, null );
55 _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
56 _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
57 _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MAG_FILTER, _gl.NEAREST );
58 _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, _gl.NEAREST );
59
60 _gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.occlusionTexture );
61 _gl.texImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, 16, 16, 0, _gl.RGBA, _gl.UNSIGNED_BYTE, null );
62 _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_S, _gl.CLAMP_TO_EDGE );
63 _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_WRAP_T, _gl.CLAMP_TO_EDGE );
64 _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MAG_FILTER, _gl.NEAREST );
65 _gl.texParameteri( _gl.TEXTURE_2D, _gl.TEXTURE_MIN_FILTER, _gl.NEAREST );
66
67 if ( _gl.getParameter( _gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS ) <= 0 ) {
68
69 _lensFlare.hasVertexTexture = false;
70 _lensFlare.program = createProgram( THREE.ShaderFlares[ "lensFlare" ], _precision );
71
72 } else {
73
74 _lensFlare.hasVertexTexture = true;
75 _lensFlare.program = createProgram( THREE.ShaderFlares[ "lensFlareVertexTexture" ], _precision );
76
77 }
78
79 _lensFlare.attributes = {};
80 _lensFlare.uniforms = {};
81
82 _lensFlare.attributes.vertex = _gl.getAttribLocation ( _lensFlare.program, "position" );
83 _lensFlare.attributes.uv = _gl.getAttribLocation ( _lensFlare.program, "uv" );
84
85 _lensFlare.uniforms.renderType = _gl.getUniformLocation( _lensFlare.program, "renderType" );
86 _lensFlare.uniforms.map = _gl.getUniformLocation( _lensFlare.program, "map" );
87 _lensFlare.uniforms.occlusionMap = _gl.getUniformLocation( _lensFlare.program, "occlusionMap" );
88 _lensFlare.uniforms.opacity = _gl.getUniformLocation( _lensFlare.program, "opacity" );
89 _lensFlare.uniforms.color = _gl.getUniformLocation( _lensFlare.program, "color" );
90 _lensFlare.uniforms.scale = _gl.getUniformLocation( _lensFlare.program, "scale" );
91 _lensFlare.uniforms.rotation = _gl.getUniformLocation( _lensFlare.program, "rotation" );
92 _lensFlare.uniforms.screenPosition = _gl.getUniformLocation( _lensFlare.program, "screenPosition" );
93
94 };
95
96
97 /*
98 * Render lens flares
99 * Method: renders 16x16 0xff00ff-colored points scattered over the light source area,
100 * reads these back and calculates occlusion.
101 * Then _lensFlare.update_lensFlares() is called to re-position and
102 * update transparency of flares. Then they are rendered.
103 *
104 */
105
106 this.render = function ( scene, camera, viewportWidth, viewportHeight ) {
107
108 var flares = scene.__webglFlares,
109 nFlares = flares.length;
110
111 if ( ! nFlares ) return;
112
113 var tempPosition = new THREE.Vector3();
114
115 var invAspect = viewportHeight / viewportWidth,
116 halfViewportWidth = viewportWidth * 0.5,
117 halfViewportHeight = viewportHeight * 0.5;
118
119 var size = 16 / viewportHeight,
120 scale = new THREE.Vector2( size * invAspect, size );
121
122 var screenPosition = new THREE.Vector3( 1, 1, 0 ),
123 screenPositionPixels = new THREE.Vector2( 1, 1 );
124
125 var uniforms = _lensFlare.uniforms,
126 attributes = _lensFlare.attributes;
127
128 // set _lensFlare program and reset blending
129
130 _gl.useProgram( _lensFlare.program );
131
132 _gl.enableVertexAttribArray( _lensFlare.attributes.vertex );
133 _gl.enableVertexAttribArray( _lensFlare.attributes.uv );
134
135 // loop through all lens flares to update their occlusion and positions
136 // setup gl and common used attribs/unforms
137
138 _gl.uniform1i( uniforms.occlusionMap, 0 );
139 _gl.uniform1i( uniforms.map, 1 );
140
141 _gl.bindBuffer( _gl.ARRAY_BUFFER, _lensFlare.vertexBuffer );
142 _gl.vertexAttribPointer( attributes.vertex, 2, _gl.FLOAT, false, 2 * 8, 0 );
143 _gl.vertexAttribPointer( attributes.uv, 2, _gl.FLOAT, false, 2 * 8, 8 );
144
145 _gl.bindBuffer( _gl.ELEMENT_ARRAY_BUFFER, _lensFlare.elementBuffer );
146
147 _gl.disable( _gl.CULL_FACE );
148 _gl.depthMask( false );
149
150 var i, j, jl, flare, sprite;
151
152 for ( i = 0; i < nFlares; i ++ ) {
153
154 size = 16 / viewportHeight;
155 scale.set( size * invAspect, size );
156
157 // calc object screen position
158
159 flare = flares[ i ];
160
161 tempPosition.set( flare.matrixWorld.elements[12], flare.matrixWorld.elements[13], flare.matrixWorld.elements[14] );
162
163 tempPosition.applyMatrix4( camera.matrixWorldInverse );
164 tempPosition.applyProjection( camera.projectionMatrix );
165
166 // setup arrays for gl programs
167
168 screenPosition.copy( tempPosition )
169
170 screenPositionPixels.x = screenPosition.x * halfViewportWidth + halfViewportWidth;
171 screenPositionPixels.y = screenPosition.y * halfViewportHeight + halfViewportHeight;
172
173 // screen cull
174
175 if ( _lensFlare.hasVertexTexture || (
176 screenPositionPixels.x > 0 &&
177 screenPositionPixels.x < viewportWidth &&
178 screenPositionPixels.y > 0 &&
179 screenPositionPixels.y < viewportHeight ) ) {
180
181 // save current RGB to temp texture
182
183 _gl.activeTexture( _gl.TEXTURE1 );
184 _gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.tempTexture );
185 _gl.copyTexImage2D( _gl.TEXTURE_2D, 0, _gl.RGB, screenPositionPixels.x - 8, screenPositionPixels.y - 8, 16, 16, 0 );
186
187
188 // render pink quad
189
190 _gl.uniform1i( uniforms.renderType, 0 );
191 _gl.uniform2f( uniforms.scale, scale.x, scale.y );
192 _gl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );
193
194 _gl.disable( _gl.BLEND );
195 _gl.enable( _gl.DEPTH_TEST );
196
197 _gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
198
199
200 // copy result to occlusionMap
201
202 _gl.activeTexture( _gl.TEXTURE0 );
203 _gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.occlusionTexture );
204 _gl.copyTexImage2D( _gl.TEXTURE_2D, 0, _gl.RGBA, screenPositionPixels.x - 8, screenPositionPixels.y - 8, 16, 16, 0 );
205
206
207 // restore graphics
208
209 _gl.uniform1i( uniforms.renderType, 1 );
210 _gl.disable( _gl.DEPTH_TEST );
211
212 _gl.activeTexture( _gl.TEXTURE1 );
213 _gl.bindTexture( _gl.TEXTURE_2D, _lensFlare.tempTexture );
214 _gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
215
216
217 // update object positions
218
219 flare.positionScreen.copy( screenPosition )
220
221 if ( flare.customUpdateCallback ) {
222
223 flare.customUpdateCallback( flare );
224
225 } else {
226
227 flare.updateLensFlares();
228
229 }
230
231 // render flares
232
233 _gl.uniform1i( uniforms.renderType, 2 );
234 _gl.enable( _gl.BLEND );
235
236 for ( j = 0, jl = flare.lensFlares.length; j < jl; j ++ ) {
237
238 sprite = flare.lensFlares[ j ];
239
240 if ( sprite.opacity > 0.001 && sprite.scale > 0.001 ) {
241
242 screenPosition.x = sprite.x;
243 screenPosition.y = sprite.y;
244 screenPosition.z = sprite.z;
245
246 size = sprite.size * sprite.scale / viewportHeight;
247
248 scale.x = size * invAspect;
249 scale.y = size;
250
251 _gl.uniform3f( uniforms.screenPosition, screenPosition.x, screenPosition.y, screenPosition.z );
252 _gl.uniform2f( uniforms.scale, scale.x, scale.y );
253 _gl.uniform1f( uniforms.rotation, sprite.rotation );
254
255 _gl.uniform1f( uniforms.opacity, sprite.opacity );
256 _gl.uniform3f( uniforms.color, sprite.color.r, sprite.color.g, sprite.color.b );
257
258 _renderer.setBlending( sprite.blending, sprite.blendEquation, sprite.blendSrc, sprite.blendDst );
259 _renderer.setTexture( sprite.texture, 1 );
260
261 _gl.drawElements( _gl.TRIANGLES, 6, _gl.UNSIGNED_SHORT, 0 );
262
263 }
264
265 }
266
267 }
268
269 }
270
271 // restore gl
272
273 _gl.enable( _gl.CULL_FACE );
274 _gl.enable( _gl.DEPTH_TEST );
275 _gl.depthMask( true );
276
277 };
278
279 function createProgram ( shader, precision ) {
280
281 var program = _gl.createProgram();
282
283 var fragmentShader = _gl.createShader( _gl.FRAGMENT_SHADER );
284 var vertexShader = _gl.createShader( _gl.VERTEX_SHADER );
285
286 var prefix = "precision " + precision + " float;\n";
287
288 _gl.shaderSource( fragmentShader, prefix + shader.fragmentShader );
289 _gl.shaderSource( vertexShader, prefix + shader.vertexShader );
290
291 _gl.compileShader( fragmentShader );
292 _gl.compileShader( vertexShader );
293
294 _gl.attachShader( program, fragmentShader );
295 _gl.attachShader( program, vertexShader );
296
297 _gl.linkProgram( program );
298
299 return program;
300
301 };
302
303};
Note: See TracBrowser for help on using the repository browser.