three.js outer glow for sphere object? - javascript

I'm building some sort of planetary system in three.js and I spent couple of hours looking for a decent solution to get an outer glow on one planet - a sphere object with a texture.
I came across this example http://stemkoski.github.io/Three.js/Selective-Glow.html which kind of does the trick, but the thing is - this form of glow also affects the main 3D object resulting in color change (as seen there).
Another nice glow example can be found here http://bkcore.com/blog/3d/webgl-three-js-animated-selective-glow.html but again it glows the entire region, not only "outer" thing.
I've been reading some discussion thread about "overrideMaterial" property on GitHub but this seems experimental, unused and undocumented... not even sure if this could solve my problem.
Please share your ideas, thanks!

I've worked a bit on separating out the part of the WebGL Globe code (linked to above) that produces the atmospheric effect. A preliminary working version is here:
http://stemkoski.github.io/Three.js/Atmosphere.html
To the best of my understanding, there are a few interesting things going on in the original code to create the atmospheric effect. First, the glowing texture is placed on another sphere -- let's call it the Atmo Sphere :) -- that surrounds the sphere with the image of earth on it. The Atmosphere material is flipped so that the front side does not render, only the back side, thus it does not obscure the earth sphere even though it surrounds it. Second, the gradient lighting effect is achieved by using a fragment shader rather than a texture. However, the atmosphere will change its appearance if you zoom in and out; this was not evident in the WebGL Globe experiment because zooming was disabled.
[updated April 30th]
Next, similar to the source code from
http://stemkoski.github.io/Three.js/Selective-Glow.html
the sphere with the gradient lighting texture (and another black-textured sphere) are placed in a second scene, and then the results from that scene are composed with the original scene using an additive blender. And just so you can experiment with the parameters used to create the glow effect, I have included a couple of sliders so that you can change the values and see the different glow effects that result.
I hope this helps you get started. Good luck!
[updated June 11]
I have a new example which achieves the same effect in a much simpler way, rather than using post-processing and additively blending two scenes, I just changed some of the parameters in the customized material. (It seems obvious in retrospect.) For an updated example, check out:
http://stemkoski.github.io/Three.js/Shader-Halo.html
Still haven't figured out the pan/zoom issues though.
[Updated July 24]
I figured out the pan/zoom issues. It requires using a shader; for details about the complexities, see the related question Three.js - shader code for halo effect, normals need transformation and for the final working example, see:
http://stemkoski.github.io/Three.js/Shader-Glow.html.
I'm pretty happy with the final result, so I will not be updating this answer any more :)

In the example you are referring to, I used a blue glow with additive blending -- if you used a white color instead maybe that would produce the effect you want.

Related

Using ThreeJS StereoEffect and Raycaster

Has anybody used ThreeJS StereoEffect and Raycaster together for collision detection (in stereo view). In standard full screen view I can easily check if a Vector2 in the middle of the screen colides with an object in my scene. When I switch on the stereo effect I in effect get 2 scenes, and the collision detection stops working, but I am not really sure how to proceed. Should I create two new vector2d objects, one for each view - help :) ...
It's a bit late, but ...
I encountered a similar problem, I eventually found the reason. Actually in StereoEffect THREE.js displays the meshes on the two eyes, but in reality is actually adds only one mesh to the scene, exactly in the middle of the line left-eye-mesh <-> right-eye-mesh, hidden to the viewer.
So when you use the raycaster, you need to use it on the real mesh on the middle, not the illusion displayed on each eye !
I detailled here how to do it
Three.js StereoEffect displays meshes across 2 eyes
Hopes it solves your problem !
You can use my StereoEffect.js file in your project for resolving problem. See example of using.

Need to know what to read up to achieve this effect

I'm trying to do some data visualization and I want to make spheres light up (glow, pulsate) when I click on them. I'm new to webGL. There's a chrome experiment here that does it. Basically all those flashy lines (not the normal lines. The thicker lines actually light up and pulsate) that appear when you click united states, I want to know how to achieve them. Are they done using shaders? I've no idea what to read up on this. Can you give me some links and examples?
EDIT: Another webGL demo that uses similar effects
Cool effects like glow are created by customizing your shaders. Click here to see details
Here is a glow example covered in that post https://stemkoski.github.io/Three.js/Shader-Glow.html
Its source code is at https://github.com/stemkoski/ blah blah blah Three.js/Shader-Glow.html
WebGL uses two stages of shaders : 1st the vertex shader which calculates the mapping from your object's (points,lines,triangles...) vertices in world coordinate space onto your screen space, and the other is the fragment shader which is often called the pixel shader for good reason. It controls final pixel level positions and colors and is largely where the magic happens for glow

Three.js what does computeCentroids do?

I was making my own custom geometry with three.js (using typescript). Something was wrong with it, the object appeared all dark with Lambert material. I checked the three.js source code to see if I forgot to do something when creating the geometry. I saw these two lines appear at the end of the constructor of nearly every geometry class:
this.computeCentroids();
this.computeFaceNormals();
Adding the computeFaceNormals solved my problem. I remember something about normals having to do with lighting (so that makes sense).
But I don't know what the computeCentroids does, and where/why those centroids are needed. Can someone explain? Also do I need to call that function? What can happen if I don't?
computeCentroids calculates the centroid of each triangle in a mesh, not the center of the mesh itself.
Probably the easiest way to see their purpose is to search for .centroid in the three.js source code. AFAICS, they are not used for much apart from lighting, but then only if you're using CanvasRenderer.

Rounded Plane In THREE JS

THREE JS, can often seem angular and straight edged. I haven't used it for very long and thus am struggling to understand how to curve the world so to speak. I would imagine a renderer or something must be changed, but the idea is to take a 2d map and turn it into a simple three lane running game. However, if you look at the picture below from another similar game, how can i achieve the fish eye effect?
I would do that kind of effect on per-vertex base depending on the distance from the camera.
Also, maybe a bit tweaked perspective camera with bigger vertical fov would boost up the effect of the "curviness".
It's just a simple distortion effect that has been simulated in some way, it probably isn't really curved. Hope this helps.
I'm sure there are many possible different approaches... Here's one that creates nice barrel distortion effect.
You can do something like that by rendering normal wide angle camera to a texture, then project it to a lens-shaped plane (a sphere even), then the actual on-screen render is from a camera pointing to that.
I don't have the code available ATM, but I should be able to dig it up in few days if interested. Or you can just adapt from the three.js examples. Three.js includes some postprocessing examples where the scene is first rendered into a texture, that texture is applied to a a quad then photographed with ortographic camera. You can modify such an example by changing the ortographic camera to a perspective one, then distorting/changing the quad to something more appropriately shaped.
Taken to extremes, this approach can produce some pixelization / blocky artifacts.

HTML5 Canvas: How to fake globalCompositeOperation="darker"

I've googled and googled about this, and all I can find, including on StackOverflow, is "support was and is broken in most major browsers." Not an actual solution to my problem.
This month's Playboy came with a pair of 3D glasses (red/cyan) to view the eye-popping centerfold. Naturally, I hit the Internets to find every single red/cyan anaglyph I could and look at how awesome they are. Eventually I found some animated GIFs, which led to the idea that maybe I should make some cool HTML5 Canvas thing that lets you put shapes on a scene in 3D.
This is how far I got. Only works well in Google Chrome. In Firefox, the "Elevated Text" should look correct, but not the rectangles.
The way I'm generating the scene is thus: There are layers that each contain a Z-index, and you can place a rectangle or some text on whichever layer you want. The concept is simple. When drawing the object, it draws one [Z-index] pixels to the left in pure red, then it draws one [Z-index] pixels to the right in pure cyan.
In theory, the overlapping parts should subtract to become pure black. In Chrome, this happens for filling rectangles, stroking text, but not for filling text. In Firefox, this only happens for stroking text.
Although the intended effect of globalCompositeOperation="darker" should do exactly what I want, it's obvious that going down this road is going to bring nothing but pain.
Does anyone here have an idea as to how I can get the effect I want without using globalCompositeOperation? I tried messing with the alpha channel on the colors but didn't really like how that came together (they never add up to pure black). I could draw a third black rectangle between the red and cyan ones, but that doesn't solve the problem for text or arbitrary shapes.
I could do the pixel-for-pixel rendering myself in the Javascript, but that just seems like overkill. Any thoughts?
If you still need this, I have written a free context-blender library that lets you perform Photoshop-style blend modes between two canvases. I have not yet added 'darker', but you could either:
Fork the project on GitHub, add your own support for darker (it's pretty easy to see how to add a mode) and then send me a pull request, or
Ply me with promises of upvotes to get it added for you. :) The only hard part (as with many of the blending modes) will be attempting to determine what is correct when blending one or two areas which are <100% opacity.
It seems that the correct mode in Firefox is globalCompositeOperation="difference". Haven't tested in Chrome or IE.
Because "difference" is a mathematical operation, there is no ambiguity in the implementation, unlike the subjective term "darker".
Maybe you would like to use darken instead of darker. darker has been removed from the specification in 2007
It's a bit of a hacky way but it worked for me.
You can invert the entire canvas by doing
ctx.globalCompositeOperation = "difference";
ctx.fillStyle = "white";
ctx.fillRect(0,0,canvas.width,canvas.height);
Then render whatever you want to render using globalCompositeOperation = "lighter". Then invert the entire canvas again and it should give the same results as a "darker" blend mode would.

Categories

Resources