Home / Archive by category "Uncategorized"

Simple environment map

Just want to share a simple technique I used in my christmas experiment this year. I was trying to create some image based lighting. I found myself often in a situation that I just need a background. However I don’t have enough photoshop skill to make a custom background. I’ve always want to put more colours into my project and like to have some beautiful gradient background instead of just a plain colour. So I discover this trick : I want the colour to look nature in my work, so why don’t I just grab the colour from the nature itself ?

It’s simple : search images for ‘sky gradient’ and you’ll get tons of beautiful gradients colour for you :

gradients

some of them have some clouds but you can just apply a massive blur on it and it’ll look smooth.

 

After get this in there’s a really easy way to make an image based lighting that doesn’t require a cube map. I found an amazing article here :

http://marcinignac.com/blog/pragmatic-pbr-hdr/
and this super useful shader  :

vec2 envMapEquirect(vec3 wcNormal, float flipEnvMap) {
  //I assume envMap texture has been flipped the WebGL way (pixel 0,0 is a the bottom)
  //therefore we flip wcNorma.y as acos(1) = 0
  float phi = acos(-wcNormal.y);
  float theta = atan(flipEnvMap * wcNormal.x, wcNormal.z) + PI;
  return vec2(theta / TwoPI, phi / PI);
}

vec2 envMapEquirect(vec3 wcNormal) {
    //-1.0 for left handed coordinate system oriented texture (usual case)
    return envMapEquirect(wcNormal, -1.0);
}

With this you only need the normal to get the reflect colour from an image, combine this with the gradient colour image we got, you can produce a very nature look environment lighting.

Ultimately you’ll probably want to go for cube map + PBR but I think this could be useful for some smaller projects.

And lastly here is the link to my christmas experiment this year :

http://christmasexperiments.com/xps/13/lanterns

and the source code is here :

https://github.com/yiwenl/Christmas_Experiment_2015

the sound cloud loader I was using is from here :
https://github.com/hughsk/soundcloud-badge
Really glad to be part of it again and merry christmas everyone !

Bubble

My latest project finally gone live. I spend some efforts working on the liquid/fluid looks of the bubble and found some interesting techniques. Really thankful for the people who create these techniques and willing to share with everyone.

Here is a demo link to the bubble, you can click on the bubble to launch a wave as well.

http://www.bongiovi.tw/projects/bubble/

 

 

Animate bubble in shader and normal

The first task is to animate the bubble and getting the right normal. The way we’ve done it is to put everything to the vertex shader and then calculate the normals based on the vertices positions. This approach makes it really easy for us when we decide to add the ripples in the bubble. We only need to calculate the position offset caused by the ripple and added to the vertex position, then the normal map is updated.
In order to do so, in the positions buffer instead of putting in the position of the vertex, I put the rotation of x , rotation of y and the size of the bubble. And to get the position of vertex you can use this function :

vec3 getPosition(vec3 values) {
  float rx = values.y / numSeg * PI - PI;
  float ry = values.x / numSeg * PI * 2.0;

  vec3 pos = vec3(0.0);
  pos.y = cos(rx) * values.z;
  float r = sin(rx) * values.z;
  pos.x = cos(ry) * r;
  pos.z = sin(ry) * r;
  return pos;
}

Then using the position to get the 3D noise ( I’m using this noise function) and the ripple height.
At the end, the final position of the vertex is the original position (sphere) + noise + ripple.

Because we are using the rotation X and rotation Y to get the vertex position so we can get the neighbor position just by offset this rotation X and rotation Y. And with the position of the neighbors, we can calculate a simple normal by using cross product. The shader code looks like this:

vec3 currPos = getFinalPosition(position); // getPosition() + noise + ripple
vec3 rightPos = getFinalPosition(position+vec3(1.0, 0.0, 0.0);
vec3 bottomPos = getFinalPosition(position+vec3(0.0, 1.0, 0.0);
vec3 vRight = rightPos - currPos;
vec3 vBottom = bottomPos - currPos;
vec3 normal = normalize(cross(vBottom, vRight));

This way you could get a animate bubble and a normal with it.

02_normal

 

Distortion with background image

The second task is to distort the background behind the bubble. I started with the refract function but that requires a cube map, we’ve only got an image. So i start look around to see if there’s a simpler way to create the refraction effect, then I found this article :
http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter19.html
In short you can create a refraction effect by just using the normal.xy as a displacement map.

vec2 newUV =uv + normal * distortionRate;
gl_FragColor = texture2D(texture, newUV);

with this you can achieve a good simulate refraction effect with just a background image instead of a cube map.

04_distortion

 

Lights

At the beginning of the project we started with the traditional diffuse and specular lighting. It works however the bubble lacks one important feature : reflection. I went back to search for possible solutions and then found this amazing article :
https://www.clicktorelease.com/blog/creating-spherical-environment-mapping-shader
using this effect add a lots to the bubble and gives it a very strong glassy/fluid look, which is exactly what the client after.

03_light

 

Small Details

We also add 2 small detail to the bubble :

  1. Distorted a bit more toward the edge of the bubble.
  2. Darker on the edge of the bubble.

These 2 works in the same way and I need a value that changes from the center of the bubble to the edge. A quick way to do it is to get the dot product of the normal and the vector(0.0, 0.0, 1.0). Once you got this you can add this to the distrotionRate and get the different distortion between the center and the edge.

 

Summary

It is really fun and good learning process to go through all these steps in order to create the final look of it. I believe there are more ways to achieve this look but we really happy with this one. I’m also trying and learning cubemap now. For the next time I might try with the cubemap to recreate this fresnel effect. And even more a dynamic cubemap could be an interesting effect to add on this.

One of my codevember experiment is based on this technique. I only remove the noise animation also replace the lighting map with a much simpler one ( just a glow on the edge )

05_waves
http://yiwenl.github.io/Codevember/labs/wen/24_bubble/dist/index.html

 

and also the case study of the whole project on stink digital’s site :
http://www.stinkdigital.com/work/sky-q/

Dark Forest – part 1

Hi, here is the part one of this project, which is going to be part of my speech at Reasons to be Creative this year as well.

Inspiration

I get this idea with this beautiful photo :

darkForset02

I fell in love with it right away and want to do something about it. The first idea I had was the flocking experiments, I’ve always enjoy it and wanted to do it myself for a long time. The picture gives me the feeling that the fireflies are swarming in the forest. So I decide to create a flocking system of fireflies flying among the trees.

 

I started building my first experiment with the particle stream i made a while ago. And adding some cylinders as the placeholder for trees and the particles will fly around them. Here’s what I’ve got :

darkForset04

And then I start wondering how it would look like if I project it on my chalkboard wall ? Also I think it will be interesting if the tree is actually drawn on the wall instead of being rendered in 3D, just give it a bit different feelings. I render the trees with the background colour so when the particles run behind them they will be blocked but shows the colour of the background. I wasn’t 100% sure this will create the surrounding feeling I want but just give it a shot. Surprisingly it works quite well.

I was really happy with the result and decide to take it to the next step.

Entrainment

Couple months later I came across a video talking about the synchronising behaviour of fireflies. I was really shocked and also excited about it. I think it will be very fun to try to reproduce this behaviour in my project. I start searching for videos but there’s not too many until I found this one:

The way they synchronized together is just unbelievable. I went back online and try to search for the ways of recreate this synchronisation. They are not too hard to find. I tried several, they work but not very satisfying :

darkForset03Sync

First one doesn’t really sync completely, they kind of form into groups. The second one synchronised too perfect, which is obviously not the case in the real world. So I read more articles about firefly synchronisation and finally find this approach : Image the firefly keep a circular period. Each firefly will check with its neighbours within a distance. If it senses his flashing circle is fall behind from his neighbour, it will speed up, otherwise slow down. Just 2 simple rules, this video demonstrates how it works :

 

This time I was really satisfied with the result, of course there’s some tricks to make it less uniform such as if the period difference between it and its neighbor is smaller than certain value, stop adjust its speed. This will make sure they won’t end up in a perfect synchronisation. And the other reason I love this solution is that this is very similar to how flocking works. You don’t need to know the overall speed is, you just need focus on your neighbors and adjust yourself. And it’s perfect for putting in my system as well because it’s the same way to implement the flocking behaviour. Here is the result :

 

With this I am ready to do the next step : Projection testing in my backyard. I want to bring it out from the screen and see if it will work better to project on the grass.

Maps, portrait and Chalkboard

Just playing with map and portraits, inspired by the amazing works of Ed Fairburn

Not too much on the code side. I just create a flood fill function, so the program will pick up a random pixel and the fill the region around it. Although it feels more like photoshopping : Combine map image and the portrait using mask and blend modes. The code it self doesn’t alter the image at all. But I really enjoy watching the image being generated. Then I start to draw the map on my chalkboard wall, and the project these result on it, which looks really good.

map1

 

 

And one of my colleague said that it will be interesting if the program could generate the city shape automatically, it reminds me the old substrate thing right away. I took a quick test and the result is very interesting as well. These are more like generate art to me, it still uses these portraits but could generate quite different result each time. There’s some more picture here.

map3

 

DIY Steampunk Keyboard

It is such a stupid idea but in the same time it is so much fun to build it.

Few month ago I saw this ( Qwerkywriter ) on the internet, it caught my eyes right away, it looks amazing and beautiful. However there’s one problem with it : It’s too expensive. Don’t get me wrong, I believe the quality of the final product will be amazing, and I believe he spend a lot of time and effort to build this and it looks great. But for me it’s just hard to spend 300 dollars on a keyboard. So I looked around and found actually there’s a lot of people doing their own customize vintage or steampunk style keyboard. At the end I found this one, it looks great and seems to be possible for me to build a similar one. So I decided to build one on my own.

 

Getting the parts

The first thing to do is to get the parts. I choose to buy a mechanical keyboard because it has a better type feeling and also the sound of hitting the key is closer to vintage typewriters. This is not too hard to find. And then it comes the challenge : the keys. It took me some time to finally settle with the metal buttons. I was searching for typewriter keys which already comes with the letters but they are quite expensive too, and also for a modern keyboard you have about 105 keys in total, for the vintage typewriter you only get 35-50 keys i think. Which means you need to buy 2 or 3 full sets of them and also need some customize jobs too. Therefore I switch to search for metal buttons, which you can find a lot on amazon or ebay. There are couple things you need to be careful : the first one is the size of the button, you don’t want it to be small but you don’t want it to be too big either, from my point of view i think between 14 ~ 16mm is the best. The second thing is that you want it to be flat, some buttons comes with a small ring in the back. I don’t have proper tool to remove it and bear in mind we are looking at over 100 keys. To remove it for everyone of them is going to be a huge amount of work. At the end I found these :

SteamPunk_02

These buttons are perfect to me, they do have that small thing on the back but it’s really flat so it doesn’t matter. And I really like edge in the front, make it look like one of those vintage typewriter keys.

 

Building it

So finally we get all the things we need and can start building it. What I did is really simple : I remove the key from the keyboard, then cut the 4 sides of it and leave only the top. And then just use super glue to glue these buttons on to the key. There are things you can do to improve this such as minimum the surface the key and also make it thinner as well. As for me this is already good enough.

SteamPunk_03

But these are only the small keys. For the bigger keys such as space bar, shift, backspace and enter, I don’t want to put just a button on it. It will looks empty and hard to type. So I decide just to remove the 4 sides and leave it like that, which looks quite ok to me to be honest. However there some extra work needs to be done for these big keys : I need to polish the edges. Because when I cut them it leaves a very ugly and uneven edge, I want to polish it and make it smoother.

Again I don’t have the right tool to do it, but I don’t want to spend some money on a tool that I won’t be using that often. So I asked myself : why not just build it myself, and I can have some fun with my LegoNxt ! And here it is, my DIY lego nxt polisher 😀

SteamPunk_04

The button on the left is for turning on and off, the ultrasonic sensor is for detecting the distance from my hand to the wheels. The original idea is that the wheel will start itself automatically when my hands is close to the machine, and stop itself when I move away. It does work however I get some noise from the ultrasonic sensor ( return a lot of zeros ) and also I find actually easier just let it run. So at the end I just disable it but it’s still very fun to play with these sensors. It’s a simple thing which I spent about 2 hours to build it and make it work, but it’s perfect for polish my keys. Here is a short video of how it works  :

 

So that’s it, that’s my DIY steampunk keyboard, I’ve never feel so nerdy in my life 😀 There are still things can be done to make it better. But I kind of enjoy the look of it now so i’ll just leave it like this for now. To be honest it’s not very difficult to make one, I spend the most time on cutting the keys, but if you have proper tools it could save you a lot of time. Also I really enjoy building this mini robot. I’ve always been working with codes and haven’t explored hardwares that much. My next goal will be learning Arduino and build some awesome robot !

 

 

Photoshop curve and gradient map in shader and texture

Recently I’ve been working on a project which I need to recreate some photoshop effects in code. Most of them are quite easy to do or to find sample shader codes, such as hue/saturation/brightness and contrast. However there are still 2 effects need a bit more work : Curve and Gradient map.

Screen Shot 2014-08-15 at 11.25.02  Screen Shot 2014-08-15 at 11.31.43

The way curve and gradient map works is to map your current color value to another one, so the question for us is how to save this mapping information and then pass it into our code. It seems quite complicated at first glance, we need to save a lot data such as all 3 RGB channels plus an overall one for curve. However there is an easy way to do it : using texture. What we need is to create a base gradient texture from black to white like this :

baseTextureand apply your curve or gradient map on this texture to get the mapping texture you need.

export02

The next step is to do the mapping in the fragment shader, for the curve :

uniform sampler2D   texture;
uniform sampler2D   textureCurve;

void main(void) {
    
    vec2 texCoord   = gl_TexCoord[0].st;
    vec4 color      = texture2D(texture, texCoord);
    
    color.r         = texture2D(textureCurve, vec2(gl_FragColor.r, 0)).r;
    color.g         = texture2D(textureCurve, vec2(gl_FragColor.g, 0)).g;
    color.b         = texture2D(textureCurve, vec2(gl_FragColor.b, 0)).b;
    
    gl_FragColor    = color;
}

and for the gradient map :

uniform sampler2D   texture;
uniform sampler2D   textureMap;

#define sq3         1.73205080757

void main(void) {
    
    vec2 texCoord   = gl_TexCoord[0].st;
    vec4 color      = texture2D(texture, texCoord);
    float lenColor  = length(color.rgb) / sq3;
    color.rgb       = texture2D(textureMap, vec2(lenColor, 0)).rgb;
    
    gl_FragColor    = color;
}

This is really nice and easy, we don’t need to find a way to save mapping data with lots of numbers, a simple texture will do the job , and it’s much easier to export the texture too.

Chalkboard wall

About a month ago, my wife have this idea of turning one of our walls into a chalkboard wall, so the kids can draw on that ( instead of on our furnitures …. ) We did it and it looks amazing,  now we even spend more time ourselves to draw than the kids. We use projector to help us to draw as we are not good enough yet to draw without any help, it’s cheating I know but it looks way better 😀  Now more and more idea come to our head after we build this chalkboard wall, all kinds of different style we want to try, also we want to try projection mapping too with our drawings, lots of fun stuff to do.

Now I really recommend to all the people who want to decorate their house, it’s really easy to make a chalkboard wall, you just need to clean the wall and put the paint on, that’s it, and you have your own creative corner starting up. And also because it’s black ( or dark ) it actually makes your space feel larger. Search for chalkboard wall on the internet, you will find a lot of interesting stuff, and it’s a easy thing to do to make your space look different and fun !