I'm experimenting with three.js. Based on several tutorials I've created a small script that loads an object from obj file, puts a texture on it and provides some interactive features like camera control and collision detection when the cursor moves over the object on screen.
I know how i can change the transparency of the whole object, but now I'm looking for a way to make the loaded object partially transparent depending on the cursors position. If the ray of the cursor intersects the object, all triangles nearby the collision point should get a higher transparency so that i can see other objects inside or behind this object. Is there a way to do this? Anybody knows a tutorial which shows a solution for the implementation with three.js?
For any help or approach I would be grateful.
Its possible to write a custom vertex shader for that, where each vertex has a transparent attribute, and with mouse movements, find the intersection face, and modify face's vertex transparent value.
http://jsfiddle.net/meirm/58w9cfb0/
in this example i wrote very simple shader with attribute opacity per pixel, then in the intersection testing i change the opacity for intersected face's vertices
attribute float opacity;
...
attributes.opacity.value[intersects[0].face.a] = 0.5;
attributes.opacity.value[intersects[0].face.a] = 0.5;
attributes.opacity.value[intersects[0].face.a] = 0.5;
Related
Say I have a nice spaceship rendered in my scene. I then zoom out and the ship becomes smaller. This is all quite simple to achieve. Now at some point I want to replace the spaceship object with a simple triangle representing the ship. At this stage the icon for the ship should be rendered instead of the ship. Obviously the triangle should move based on the ship's movement and my camera movements. The triangle should not change orientation, so even if I rotate the camera or have the ship roll the triangle should stay the same orientation. So on a canvas this would be very simple to do. I would just take the x and y components of the 3d object and draw my triangle at the coordinates. My problem is that I do not know how to draw on the WebGL canvas directly? Is it possible? If not do anybody have any pointers to strategies to get this done? I would be happy if I could get nudged in the right direction :) Thanks in advance.
Update : What I eventually decided to do was to use the orthographic camera overlay approach suggested below and in a couple of other places.
Use Sprite object for icon. Then place icon right between spaceship and camera in a specific distance from the camera (using Raycaster or just calculation).
Use of orthographic overlay as mentioned by #WestLangley is also possible. Since you would have to calculate ship's position relative to your canvas in this case, maybe you could even create pure HTML overlay using DIV and place your icon in it as IMG object.
I was wondering if there's a way to project a shadow without have a "ground" plane where project it.
I'd like to do that because the camera can be moved around the object and would be ugly see it pass through the ground.
I'm using Three.js latest-version with the WebGl renderer.
Yes this is possible by applying ShadowMaterial to the plane geometry. This material can receive shadows and is completely transparent. so you just position the plane geometry at the desired location in the scene and you are good to go. check out this. https://threejs.org/docs/#api/en/materials/ShadowMaterial
This is technically impossible, you could write a shader that renders the shadow on a transparent plane, that way you would not notice it when the "camera" goes through the plane, only when it goes through the shadow itself.
To do so you can lerp between the shadowratio and a transparent black or white in the pixel shader and then set the corresponding blending states on the rendering context.
I am attempting to use an html canvas element to draw each character available in a font file to a canvas. To make this question as simple as possible, pretend only one character is drawn to a canvas. From there, I want to use Javascript to analyze the canvas and create triangle regions of the canvas that make up the entire character. The reason I need it in triangles is so that the data can later be sent to WebGL so text can be rendered and data will not be lost be scaling the text size up or down.
I am looking for some sort of algorithm to accomplish this or at least some knowledge to get me going in the right direction. If you believe I should use a different approach please tell me why, but I figured this would be the best to provide a way to modify text in many ways as well as make it possible to create 3d block text.
Here's an article on how to draw resolution independent curves with shaders
http://research.microsoft.com/en-us/um/people/cloop/loopblinn05.pdf
My understanding is instead of breaking the shapes into triangles you break them into quads with enough info sorted in the vertices to draw a portion of the curve inside each quad. In other words, as the shader draws each quad there's a formula that for each pixel can compute if that pixel is inside the curve or outside the curve.
I suggest you to start with the keyword Polygon Triangulation.
Using this methods, you can split n-Polygons into triangles like this:
These methods may only apply to figures with real (and not rounded) edges.
So, you are trying to convert a raster image into vector data?
When zoomed in, that will result in very jagged looking geometry.
Since each pixel is being treated as a square edged part of the geometry.
Couldn't you get your hands on the original vector (bezier curve) geometry for each glyph you are drawing?
Transforming that into triangle strips and fans would look smoother.
I've been working on a WebGL project that runs on top of the Three.js library. I am rendering several semi-transparent meshes, and I notice that depending on the angle you tilt the camera, a different object is on top.
To illustrate the problem, I made a quick demo using three semi-transparent cubes. When you rotate the image past perpendicular to the screen, the second half of the smallest cube "jumps" and is no longer visible. However, shouldn't it still be visible? I tried adjusting some of the blending equations, but that didn't seem to make a difference.
What I'm wondering is whether or not this is a bug in WebGL/Three, or something I can fix. Any insight would be much appreciated :)
Well, that's something they weren't able to solve when they invented all this hardware accelerated graphics business and sounds like we'll have to deal with this for a long while.
The issue here is that graphic cards do not sort the polygons, nor objects. The graphics card is "dumb", you tell it to draw an object and it will draw the pixels that represent it and also, in another non-visible "image" called zbuffer (or depthbuffer), will draw the pixels that represent the object but instead of color it will draw the distance to the camera for each pixels. Any other objects that you draw afterwards, the graphics card will check if the distance to the camera for each pixel, and if it's farther, it won't draw it (unless you disable the check, that is).
This speeds up things a lot and gives you nice intersections between solid objects. But it doesn't play well with transparency. Say that you have 2 transparent objects and you want A to be drawn behind B. You'll need to tell the graphics card to draw A first and then B. This works fine as long as they're not intersecting. In order to draw 2 transparent objects intersecting then the graphics would have to sort all the polygons, and as the graphics card doesn't do that, then you'll have to do it.
It's one of these things that you need to understand and specifically tweak for your case.
In three.js, if you set material.transparent = true we'll sort that object so it's drawn before (earlier) other objects that are in front. But we can't really help you if you want to intersect them.
Can anybody help me with three.js?
I need to draw background, something, like a THREE.Sprite, but it neet to be UNDER any 3d object, that will draw later. I have a camera, that can be move only on Z axis.
I tryed to use:
cube mapping shader - PROBLEM: artefacts with shadow planes, it's unstable draw
THREE.Sprite that dublicate camera moving - PROBLEM: artefacts with shadow plane - it have a edge highlighting OR drawing only other spirtes without objects.
HTML DOM Background - PROBLEM: big and ugly aliasing in models.
What can I try more? Thanks!
You could maybe try drawing in several passes, i.e. making a first render of the background scene to a buffer, and then a second one over the first "buffer". Maybe using the buffer as background (painting it in 2D with an orthographic projection, and disabling depth buffer writes in that pass).
I haven't tried it myself with three.js, but that's how I'd do that with "traditional" OpenGL.
If you want a "3d" background i.e. something that will follow the rotation of your camera, but not react to the movement (be infinitely far), then the only way to do it is with a cubemap.
The other solution is a environment dome - a fully 3d object.
If you want a static background, then you should be able todo just a html background, i'm not sure why this would fail and what 'aliasing in models' you are talking about.