Photo Blog 112

26 09 2010

While it is a subject that has been done to death the Golden Gate bridge is pretty spectacular and I don’t think anyone goes there without taking a photo. We arrived in the early afternoon and there was already the stereotypical fog rolling in off the sea which made it all quite dramatic, if a little cold.

The Bridge (f14 45mm 1/100s)
All I’ve done is convert to Black and White using a blue filter (which makes the bridge’s red closer to black) and I really like the almost antique feel. Maybe I should add some grain or something…





Photo Blog 111

12 09 2010

As mentioned in the last photo blog I’ve been working on some more product photography. The new setup is a bit simpler than before using just one light and the box set up in a way that is a bit easier to manipulate. I also have the props / background that was needed by my Aunt for her shots which meant that the white backdrop wasn’t necessary. This made it heaps easier to set up each individual item and cut the time required down substantially.

The setup:

The Setup

The only real issue was making sure that I was using a custom white balance that matched the lighting as otherwise it would have been a pain in post-processing. In the end the only changes needed in post where a bit of cropping and use of the ‘heal’ brush in Photoshop to remove some artifacts near the edges.

A couple example images:

Example Shot 1 (f16 2.5s 105mm)

Example Shot 2 (f16 2.5s 105mm)





Graphics – MGP – Glass

8 09 2010

With this installment we will finally make our object look like it is made of glass. Luckily we have already been introduced to shaders in a previous post so all that remains to be done is to describe how we can incorporate our new environment/cube map into our shader and use it to fake reflection and refraction.

The first thing we are going to need for our calculations is the normal and position associated for each pixel. These can be calculated in the Vertex shader, as can the usual set of calculations needed for basic operations. As such our Vertex shader is quite simple as shown in Figure 1.

varying vec3 normal;
varying vec3 view;

void main()
{
    // the basics that have to be done
    gl_FrontColor = gl_Color;
    gl_TexCoord[0] = gl_MultiTexCoord0;
    gl_Position = ftransform();
	
    // calculate the view vector in eye-space using the ModelView and Projection matrix
    view = (gl_ModelViewProjectionMatrix * gl_Vertex).xyz;
    // calculate the normal vector in eye-space using the ModelView and Projection matrix
    normal = normalize(gl_NormalMatrix * gl_Normal);
}
// Figure 1

Using the same code as in the previous post the cube map texture should automatically be available to us in the GLSL shader as a texture. The only difference is that the type of the texture is samplerCube instead of sampler2D. Thus we begin our fragment shader like this:

// our cube map texture
uniform samplerCube tex;
//variables passed in from our vertex shader
varying vec3 view;
varying vec3 normal;

void main()
{	

When we want to access our cube map we do so through the use of a vector which expresses the direction we wish to sample the ‘cube’ that surrounds our object. For example, by calculating the reflection vector of the view around the normal and sampling this we can see what would be ‘reflected’ if our object was a perfect mirror.

    // create the reflection vector 
    vec3 reflect_v = normalize(reflect(view,-normal));
    // sample the cube map to find the reflected color
    vec3 colReflect = textureCube(tex,reflect_v).rgb;

GLSL provides a very useful function which we use here for performing the reflection of ‘view’ around ‘-normal’ so we don’t even have to think about it.

We can do exactly the same thing to find the colour that would come from refracting through the surface. This refraction would of course depend on the refractive indices of the two materials. Because we are trying to model glass this means that we are going from a refractive index of 1.0 (air) to 1.2 (glass).

    const float eta = 1.00 / 1.20;
    // create the reflection vector 
    vec3 refract_v = normalize(refract(view,-normal,eta));
    // sample the cube map to find the reflected color
    vec3 colReflect = textureCube(tex,refract_v).rgb;

There is one major limitation to this of course. A real simulation would model the effect of coming out the other side of the glass, and perhaps even entering another material if there are other objects in the scene / concave objects. This is pretty serious but for our purposes it works ok because we limit ourselves to only one object and it kind of looks ‘good enough’.

Finally we composite the reflected and refracted components together, along with a bit of specular lighting from the phong model discussed previously.

    // calculate the specular lighting
    float light = pow(max(dot(normal, gl_LightSource[0].halfVector.xyz),0.0),1000.0);
    // coefficients for each of the calculated components (reflection, refraction, lighting). These DON'T have to add to 1.0
    const vec3 coeff = vec3( 0.3, 0.6, 0.5 );
    gl_FragColor = vec4(coeff.x * colReflect + coeff.y * colRefract + coeff.z * vec3(light,light,light) + gl_Color.rgb,1.0);
}

This gives us a final result that looks something like this:

Glass





Photo Blog 110

7 09 2010

Recently I got to do a bit of road trippen’ between Las Vegas and San Fransisco and we took the route through Death Valley and Yosemite National Park. There is some stunning scenery through there as well as some rather interesting extremes. In 12 hours we went from -200feet to 10000feet and from 46ºC to 3ºC. Luckily I was traveling with a couple of other photographers so there were plenty of opportunities for stopping and taking photos.

Obviously there are lots of photos from there that I’m proud of but one in particular would have to be a panorama I took while leaving Death Valley. So here it is:

Death Valley Panorama

I really do suggest you click on it to view it at a higher resolution as seeing it in a small frame like above doesn’t do it justice.





Graphics – MGP – Environment Mapping

6 09 2010

From the previous step we have a well illuminated cup that looks like it is made of clay, but hardly like a glass. To make this a little more realistic we are going to use environment mapping. How this works is that we define a set of textures representing the six sides of a cube surrounding our scene. This is stored in a cube map which can be accessed like any other texture and so at any point we can ask what colour is in a particular direction and so create pseudo reflection and refraction by asking what from the scene would be reflected or refracted.

Creating the Cube Map
The first step to do this is to acquire a Cube Map. The one I have to use is one I found quite a while ago of the Swedish Royal Palace at night. It has a lot of interesting colours and lighting and while it isn’t the natural habitat for a wine glass it suits well enough for our purposes. You can often find textures appropriate for this sort of thing around the internet and one good collection in particular is Emil Persson’s over here.

These images then need to be loaded into graphics memory so they can be used This is done by using the same glTexImage2D calls as usual but with the targets in Figure 1 instead.

GL_TEXTURE_CUBE_MAP_NEGATIVE_Z
GL_TEXTURE_CUBE_MAP_POSITIVE_Z
GL_TEXTURE_CUBE_MAP_NEGATIVE_X
GL_TEXTURE_CUBE_MAP_POSITIVE_X
GL_TEXTURE_CUBE_MAP_NEGATIVE_Y
GL_TEXTURE_CUBE_MAP_POSITIVE_Y
// Figure 1

Once all 6 textures are loaded we can generate the environment map needed for reflections by calling the functions outlined in Figure 2.

glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
	
glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_REFLECTION_MAP);
// Figure 2

And finally, every time we want to employ our new Environment Map all we have to do is turn it on like we would any other texture.

// Enable
	glEnable(GL_TEXTURE_CUBE_MAP);
	glEnable(GL_TEXTURE_GEN_S);
	glEnable(GL_TEXTURE_GEN_T);
	glEnable(GL_TEXTURE_GEN_R);

// Draw
DrawObject();

// Disable
	glDisable(GL_TEXTURE_CUBE_MAP);
	glDisable(GL_TEXTURE_GEN_S);
	glDisable(GL_TEXTURE_GEN_T);
	glDisable(GL_TEXTURE_GEN_R);
// Figure 3

The result we now get hardly looks like a lot more like pewter than glass but we can already see the basic effect of environment mapping and how it might allow us to preform refraction as well as reflection.

Environment Mapping

This cube/environment map will now be available for us in the shader so we can make more customized requests of it.





Photo Blog 109

5 09 2010

While I was playing around with some more product photography (perhaps the next update will explain) Alyona decided to do some painting. I spun the camera around on the tripod and managed to catch this without her seeing. I like her pose and look of utter concentration. That and our random assortment of stuff around the apartment!

Painting (f8.0 1/10s 47mm)