Comments (4)
This is not a bad idea. Unfortunately POINTS in OpenGL/OpenGL ES/WebGL have incompatibilities across GPUs.
See the bottom of this article
If you're curious, here's an example of how to emulate POINTS using instancing. This emulation doesn't have the issues that POINTS has.
There's no article for WebGL1 on instanced drawing but there is for WebGL2 since it's not an extension there.
from webgl-fundamentals.
TL;DR: You can also use a transformfeedback with gl.INTERLEAVED_ATTRIBS to emit multiple vertices at a time, which is good for drawing small particles like quads.
Hi Greg, Thanks for the reply.
These past few weeks I've taken a look at the various methods of drawing quads to the screen with WebGL2/OpenGLES3. I've also run into those same issues with point sprites- namely the size limit.
I've also become quite familiar with the instanced rendering method (thanks in large part to webgl2fundamentals.org). However, there are a couple problems with instanced rendering I'd like to discuss in further detail, but I'll skip to my main point:
Yesterday I came up with a (new?) method of drawing small groups of primatives like quads and whatnot faster using transform feedbacks with gl.INTERLEAVED_ATTRIBS. Well, I have not benchmarked it yet, but it should be faster and more versatile than an equivalent instanced render, assuming you are already using transform feedbacks to write to per-instance (per-quad) data like to interpolate the quad's position or texture-coordinates.
I can send you some of the code I've been working on if you are interested, but it goes something like this:
-
You have a particle shader program that uses a vertex shader with transform feedbacks, it takes in stuff like the position and outputs one vertex for each vertex the shape needs (for example a quad drawn with GL_TRIANGLES would need 6). you use transformfeedbackvaryings with gl.INTERLEAVED_ATTRIBS so they're packed back-to-back in the same output buffer after you do the transform feedback on a draw call like gl.drawArrays(gl.POINTS,0,<num_quads>);
-
You configure the transformFeedbackVaryings of the particle shader program and the vertexAttribPointers (using stride and offset) of the quad-drawing shader program such that the inputs line up with the outputs properly.
-
What you end up with is a single buffer with all 6*<num_quads> verticies lined up nicely, so you can draw them with another shader program in one fell gl.drawArrays(gl.TRIANGLES,0, 6*<num_quads>)
It gets more complicated than that if you want the particle shader to output multiple per-vertex attributes, like position and color at the same time, because you need to interleave them, but that is the basic gist of it.
It might be a bit better than instanced rendering. I've heard that instanced rendering adds an additional CPU overhead in terms of draw calls or something, and that it's really for larger models as opposed to quads. The other problem with instanced rendering is that you have to do a little more per-vertex processing (to draw a 2D quad at least). This was my motivation for using this method in the first place (for example, instead of transforming texture co-ordinates by a per-instance matrix or something, you can just put those in a static draw buffer). You can just generally make it faster by optimizing stuff that should only be calculated once per quad.
I guess the only downside is that you can't use GL_TRIANGLE_STRIP to draw a single quad like you could with instanced rendering.
Point Sprites have their advantages too, because you can run the vertex shader once per-quad without doing all the transform feedbacks calls. But they really don't outweigh the limitiations. Also, I'm told that many OpenGL implementations just process GL_POINTS as two triangles in their backend.
Sorry if this is was too wordy.
from webgl-fundamentals.
Oh, I should mention that the GL_TRIANGLE_STRIP with instanced rendering trick is just to prevent you from running the vertex shader an extra two more times per quad instance.
But using this method you still only run those same per-vertex calculatons four times in the particle shader, and then copy two of them to get a total of 6 output verts.
from webgl-fundamentals.
Yea, you can do particles without instancing. An example is covered in this article though it may or may not be faster than instancing.
TRIANGLE_STRIP is generally slower than TRIANGLES because on several implementations it has to be emulated.
Also, you can easily do the particle calculations in the shaders for more speed though of course likely without any collisions and other limitations. That's often fine depending on your needs. The same article above shows a simple example of moving particles based on time. This article shows moving particles in the GPU.
This example shows a single shader that does time based particles where every particle has these inputs
'attribute vec4 uvLifeTimeFrameStart; // uv, lifeTime, frameStart\n' +
'attribute vec4 positionStartTime; // position.xyz, startTime\n' +
'attribute vec4 velocityStartSize; // velocity.xyz, startSize\n' +
'attribute vec4 accelerationEndSize; // acceleration.xyz, endSize\n' +
'attribute vec4 spinStartSpinSpeed; // spinStart.x, spinSpeed.y\n' +
'attribute vec4 orientation; // orientation quaternion\n' +
'attribute vec4 colorMult; // multiplies color and ramp textures\n' +
And things are computed based on time as in
// pp = per particle
localTime = currentTime - pp.startTime;
lerp = localTime / pp.lifeTime;
position = pp.startPosition + (pp.velocity + pp.acceleration * localTime) * localTime;
color = mix(pp.startColor, pp.endColor, lerp)
etc.....
from webgl-fundamentals.
Related Issues (20)
- Duplicate gl.bindBuffer in webgl-fundamentals.html? HOT 1
- Suggestion: How about to use unit square instead of unit quad? HOT 4
- Is the example lost? HOT 3
- Is it modulo or module? HOT 1
- WebGL Using 2 or More Textures (wrong order of calls) HOT 6
- Explanation error HOT 1
- Skinning inverse world matrix HOT 1
- possible bug in m3.js HOT 1
- another bug in m3.js HOT 3
- error in textures example code HOT 2
- data-textures: Mention (data in texture)=(data supplied)/255?
- webgl-state-diagram use-2-programs does not work HOT 6
- Broken links HOT 1
- webgl state diagram : draw on cube
- webgl-state-diagram: extraneous column heading in vertex array HOT 2
- Broken link in Load Obj HOT 1
- webgl-how-it-works.html: some poor rounding, one wrong number
- webgl-image-processing: images don't actually have to be same-origin
- Camera tutorial requirements
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from webgl-fundamentals.