Need to know what to read up to achieve this effect - javascript

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

Related

Display text with WebGL

I want to display text with WebGL, and I know that there is not a built in way to do this. However, I know it can be done, with textures. I am new to OpenGL, so I don't really have much experience with shaders, so if someone could add how to set up the shaders for this. I would like to draw the entire string on the same object, instead of a bunch of seperate letters, and the strings are NOT preset, they will not always be the same. How can I get the text to appear? Also, how do I know how to space each letter?
I read post #7 at this page, and that sounds like it's what I want to do, but I don't understand exactly what It all means. (It's mostly the shader stuff I don't understand).
By the way, I am using sylvester.js
There are many ways to render text but one of the simplest is called bitmap font rendering.
All you need to get started is a sprite sheet with all of the letters you might want to render. Then you simply render a quad with the texture coordinates set to the location of the character you want to draw. To render a full sentence, just draw a bunch of quads, each representing a single letter.
Your sprite sheet will look something like the following texture.
Once you have that, you'll need the texture coordinates, essentially (x, y) coordinates in the range 0 to 1, for each character in the sprite texture. Use these when generating quad meshes. You'll end up drawing something like this to the screen:
Now that you have text on the screen, you can get fancy and take into account the glyph kerning between the letters. This allows you to render more natural text.
Unfortunately, I can't find a tutorial to point you to. And its not really something that I can whip together for you here. There are many pieces to the puzzle and its no small task (matrix math, camera's, orthographic projection, texture coords, textures, sprites, generating meshes, etc...).
If you'd like you can look through one of my projects where I have done this with WebGL. I even generate the initial sprite sheet using javascript + 2d canvas.
Sprite Sheet generated here:
https://github.com/zfedoran/prefab.js/blob/master/app/graphics/spriteFont.js
Quad Mesh generated in this file:
https://github.com/zfedoran/prefab.js/blob/master/app/controllers/labelController.js
Wrapper around WebGL:
https://github.com/zfedoran/prefab.js/blob/master/app/graphics/device.js
Or You Could
Watch Notch (the guy who made Minecraft) do this, in only about 30 minutes, in Java (fast forward to 2:21 hours in):
http://www.twitch.tv/notch/b/487451713
http://www.twitch.tv/notch/b/487621698
Good luck, and have fun :)
Three.js has actual text glyph support. In addition, dimensionthree.net uses textures on shapes. if you need source let me know.
There also is my http://taccGL.org library that can draw HTML text on a 2D canvas and then use it as textures on 3D objects drawn on a 3D/WebGL canvas.

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.

three.js outer glow for sphere object?

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.

Storing shapes in JavaScript array to redraw after some operation

I am developing an editor in html5. I have buttons for creating shapes when clicked, including triangle, rectangle, hexa, penta, heptagons, lines, and so on. Now I also want to perform operations on these shapes such as rotate, flip, undo, redo, ...etc. I want to save these drawn objects in a JavaScript array or something so I can create them after performing operations on the canvas, since individual shapes cannot be rotated or flipped in canvas, we have to redraw it. How can I achieve this? Thanks in advance.
I have a project where if you click on an image of a rectangle you can then draw a rectangle, click on an ellipse then you can draw an ellipse. My shapes are stored as objects which are then drawn using Canvas and can be flipped, rotated etc I have not implemented undo redo.
My project is at http://canvimation.github.com/
The source code for my project is at https://github.com/canvimation/canvimation.github.com
The master branch is the current working code. You are welcome to use any of the code or fork the project.
as you said, you have to clear your context and redraw your shapes any time you change them.
It's not mandatory to clear and redraw all the context, you can just redraw the region in which a shape is modified.
So you have to think your shapes as objects (in a OOP way) with their own properties and render method.
What I'd do is to create another class to apply transformations to a shape (a flip is just a -1 scale).
If you go this way, it could become a huge work (the more features you add, the more complexe your code becomes and the first design of your application may be re-think during the work).
What I can suggest to you is to use a framework that already does the job.
For example, cgSceneGraph is designed to let developers add their own rendering method and provides a lot of methods to manipulate them. I'm the designer of the framework, feel free to ask more on about how to apply transformations or create your own nodes (tutorials and examples are already on the website, but I'll please to help you).

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