8

How to detect collision in webgl, without using any library like three.js?

3
  • 1
    This might be hard to do. Anyway, why don't you want a library for his? Commented Dec 11, 2011 at 21:06
  • 1
    @ajax333221 Libraries make our life much more easier. :) Commented Dec 11, 2011 at 21:25
  • 2
    @Derek not when we are first learning to code (they make us library-dependent) Commented Dec 11, 2011 at 21:28

4 Answers 4

13

How to detect collision in webgl

You don't. WebGL, like OpenGL is only for drawing stuff. It doesn't manage a scene, it has no notion of "objects" or such high level things like collisions. It's all about points, lines, triangles and shaders.

Anything related to scene management or collisions lies outside the scope of WebGL (and OpenGL).

Sign up to request clarification or add additional context in comments.

5 Comments

then how can I calculate it in js?
@DannyFox: The same way you'd calculate it in any other language: By solving the various geometric intersection tests equations, and extracting the collisions from the result. There's an excellent book about the topic: realtimecollisiondetection.net
You can definitely solve collision with OpenGL (and probably WebGL) by using shaders. Give the objects different colors and then combine the two using blending. If there is one or more pixels on the resulting image that is a different color from the two objects (e.g. some pixels from the object were blended with the other objects pixels), there is a collision.
@Willem: That method doesn't work in 3D. What about two non intersecting spheres, where one merely occludes the other? And in 2D it's also a rather slow method, since you've to compare all the pixels' colors against all the objects' colors. The complexits of this is O(n×m), which is usually written as O(n²). Using a proper collision detection method that operates on a spatial subdivision structure one can usually achieve O(n log(n)), but often it's effectively close to O(n).
It's definitely meant for 2D usage (although 3D might work, I haven't thought about it). Performance compared to other solutions such as ray tracing, geometrical models etc. varies depending on the context. You'd render the solid objects as gray on individual images with black backgrounds and additively blend the images together. Then run a quick check in the resulting image to see if there is one or more white pixels. If there is, check their positions and run calculations. On a platform such as JS where physics is slow, the hardware acceleration from WebGL shaders could help performance.
3

A simple approach it to do ray collision detection on the GPU. Checkout the following blogpost about the topic.

http://blog.xeolabs.com/ray-picking-in-scenejs

The main idea is to render the scene to a texture (using a FBO) using a shader that saves object ids instead of color. Then you can very fast do a lookup in this texture to see what a ray collides with.

4 Comments

This only works for testing either rays coming from the point of view or with non occluded geometry.
Yes, the solution only works with ray collision, but the question didn't state what kind of collision detection was needed. My point was that a few collision test can run perfectly fine on the GPU (but it's not a general solution)
thanks, but it's in scene.js. I want to do it without any library
Yes - but it is fairly easy to port to any WebGL application (I ported it to KickJS myself).
1

Since sunday I'm trying to solve the same problem. Although there is much information in the www, I wasn't able to get it working on my example-program. As soon as I solve it, I'll post my example in here.

My last try was to use the glu-unProject port for webGL. This one needs the following parameters:

function(winX, winY, winZ, model, proj, view, objPos)

I've tried to call this function directly from my scene-drawing function for testing purposes.

var pMatrix  = new mat4.ortho(iL, iR, iB, iT, fNearZ, farZ);
var mvMatrix = new mat4.create();

mat4.identity(mvMatrix);
mat4.translate(mvMatrix,[0,0,-40]);

var oMouseMatrix = mat4.create();
mat4.identity(oMouseMatrix);

//Rotate eye :-S
mat4.rotate(oMouseMatrix,((this.fAnimationXAngle/10) * Math.PI) / 360.0,[0,1,0]);
mat4.rotate(oMouseMatrix,((this.fAnimationYAngle/10) * Math.PI) / 360.0,[1,0,0]);

mat4.multiply(oMouseMatrix, mvMatrix, mvMatrix);

//Rotate model
mat4.rotateX(mvMatrix,this.fRotX * Math.PI / 180.0);
mat4.rotateY(mvMatrix,this.fRotY * Math.PI / 180.0);
mat4.rotateZ(mvMatrix,this.fRotZ * Math.PI / 180.0);



var aTest = this.unProject(
    this.pLastMouse.x,
    this.pLastMouse.y,
    0,
    mvMatrix,
    pMatrix,
    [0,0,this.iWidth,this.iHeight]
);

this.iWidth & this.iHeight are the canvas and viewport width/height - this.pLastMouse.x & .y are the mouse-coordinates inside the canvas

zI.debug(aTest);

But the result is totally crap. I guess there are several errors in my code. I've started playing around with WebGL just last friday. I didn't want to give up that early, but I've solved many problems since then, but this one is making me crazy.

In openGL it was much easier to me.

Comments

1

I would recommend the following webpage (unfortunately only available in German) http://www.peter-strohm.de/webgl/webgltutorial8.php

We were able to implement collision detection and could even perform API calls on a server using id mapping (e.g. show tooltips with additional information for a certain object in the scene).

I hope this helps a bit.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.