The Escher Boxes


The Escher Boxes


Insight


As my first project ever in SCAD, I was assigned to create a Jack in the Box, with the concept of What Goes Around Comes Around. In fact, we have a similar expression in our home country which says: If You Give Something Away With Your Hand, You Gain Something With That One In Return.



Suddenly something caught my attention. I have always been a fan of M. C. Escher; the Dutch graphic artist. So I remembered one of his concepts, in which two hands are drawing each other; another interesting example of Escher's impossible loops. Therefore I decided to adapt that marvelous concept to my project and started to work on The Escher Boxes.



Process




The boxes on an infinite checkerboard

I made an infinite checkerboard that gives the idea of an infinite world in which its details, the boxes, are there to interact with each other. But the boxes actually can't have interaction with each other, unless they get opened by a hand rotating their cranks. But the hands are actually inside the boxes. So we confront an impossible loop.
I designed the crank of each box to be in the middle of a ring, so together they form something similar to the face of a clock. Therefore it gives the feeling of a freezed time and needs to be triggered.


The Escher Boxes - DOP1

Hands Modeling

I came up with the idea of creating a robotic hand, but definitely not too fancy and futuristic. So I found a model, which was a robot hand with not much of a detail and modified it so it would appear simpler. Then I changed the pose of fingers so it feels like they are grasping something. And for the arm, again I tried it to be minimal. So I extended the parts of the wrist and added some wires, represending blood veins.
After modeling the arm, I used a curve to put the arm in a flow, inducing the motion of the hand coming out of the box. Then I put them with their origin boxes against each other so they can reach the crank of the other one's box. I added a couple of other hands in the scene as well, which are struggling to get out of their own boxes. But their efforts are in vain.

Hand Model


Shading and Lighting

I used a metalic texture for the boxes and blend it with a pattern. For the ground, apart from a procedural checkboard texture, I used a displacement map connected to the same checkboard node as well in the Hypershade.

Hypershade

To add a mood to the scene, I used my key light and concentrated it on the spot where action is happening. The environment is almost dark, because I wanted to show an infinite space full of boxes. I used two other lights as well to add a bit of depth in the bright area.

The Escher Boxes - DOP2

Camera and Composite

For the camera, I used a low f-stop for most shots to have a shallow depth-of-field. Because I wanted my audience to have more focus on my subjects.
I rendered out two passes for each shot, a master and an ambient occlusion and composited them in The Foundry Nuke.





Obstacles

During the process of making The Escher Boxes, I have encountered a couple of problems: like having a high poly mesh which caused more render time or creating z-depth for shots. But one of the issues was so interesting and unique that needs to be mentioned here.
It started when I tried to render out my other cameras after the master shot. When I attempted to render, as the computer started to render, it just simply got stuck. The only way out was to kill renderman process.
I tried troubleshooting it, and after messing around with a lot of attributes, I found out that actually when I change the attribute DisplacementSpace from Shader to World, the problem get solved. It seems that from other views than the master shot, RenderMan cannot calculate the displacement applied to the checkerboard and I have to set its point of view to the world, instead of that specific camera.

Displacement Space Issue


Conclusion

As my first project in RenderMan, I just concentrated on shading, lighting and rendering my scene. I didn't spend much time on modeling and saved it for my models compositing in the scene; actually I'm referring to mise en scene.
I had to work with just Maya and a compositor of choice, which in my case was The Foundry Nuke. But I am pretty sure if I had more time to spend in Adobe Photoshop and add more touches to the renders, the results would be more interesting.
Overall I must say that I always used MetalRay as the renderer of my choice, but during this course I really enjoyed accompanying RenderMan and I'm pretty sure that I will meet him in the not too distant future.

The Escher Boxes - DOP3


RIB Scene





Introduction


As my second project, the challenge was to create a 3D scene, just by coding, and no help of any graphical user interface (GUI) from a 3D applications. The language for this assignment was Renderman Shading Language (RSL).
I must say that I had some experience in JavaScript and ActionScript. Even I've tried to write a plugin for Adobe After Effects in C++, though it is still in progress. But generally, I am okay with coding, especially when it comes to a language in which its vocabulary is limited to less than a hundred words.



We were told to create a teapot from scratch. I found an interesting design, in which the teapot is fit in a cup. In fact, from the beginning when I started to code, I was thinking about how I can clarify this concept for the audience if I can't show the movement of the teapot; there an animation of the objects in my scene was vital. That's where I began to model objects seperately, so that later, when I'm done modeling, I can animate them easily apart from each other.



Process




I started with a simple sphere. Then I made other parts basically out of torus, cylinders and cone. For lighting, I used just two lights in opposite angles, for the main subjects to stand out. I used the Disney shader from Renderman and tweak it a little bit to mimic the surface of a teapot or cup. For the surface, I didn't spend much time on shading it with a texture or displacement map. Because I've already done that in previous project, so I stopped at this point so I can go to the next stage where I need to animate the parts. Though before getting to the animation part, I used a famous Turntable movement for the camera as well, so all the scene objects can be viewed by the viewer.


The Escher Boxes - DOP1

Animation

The animation part was a bit tricky. I used a quarter torus, in which its top and bottom are covered with semi spheres, to be acting the role of the pouring tea. I used a disc as well to give the illusion of the cup getting full. In addition, I animated the teapot being picked up and its cap being opened. I add all the keyframes in key file so I can have the entire animation in one render. Here's the header part and one of the keyframes code:


The Escher Boxes

Animation "Header" Code

Option "searchpath" "shader"  "@:../shaders"
Option "searchpath" "texture" "@:../textures"
Option "searchpath" "archive" "../archives:Cutter_Help/templates/Rib:custom_templates/Rib"
  
Display "untitled" "it" "rgba"
Hider "raytrace" "string integrationmode" ["path"] "int incremental" [1]
        "int minsamples" [0] "int maxsamples" [128]
Integrator "PxrPathTracer" "PxrPathTracer" "int maxPathLength" [10] "int allowCaustics" [0]
PixelVariance 0.01
Format 640 360 1
  
        Tween "from" 1 "to" 2 "frames" 30 "easeout" 1.0 "easein" 1.0 #Picking Up
        Tween "from" 2 "to" 3 "frames" 30 "easeout" 1.0 "easein" 1.0 #Finishing Pouring
        Tween "from" 4 "to" 5 "frames" 30 "easeout" 1.0 "easein" 1.0 #Putting Back
        Tween "from" 5 "to" 6 "frames" 90 "easeout" 1.0 #Turntable
        Tween "output" "all"


A Sample Code of a Keyframe

#Tween "output" 1
#------------------------------------------
        KeyFrameBegin 1
Projection "perspective" "fov" [20]
DepthOfField 54 64 65
Translate  0 -3 65
Rotate -10 1 0 0
Rotate 70  0 1 0
Scale 1 1 -1
WorldBegin
  
    #SceneSetup
    ReadArchive "objects/basicSceneSetup.rib"
  
  
  
    #TeaPot
    AttributeBegin
        Bxdf "PxrDisney" "PxrDisney1"
                "color baseColor" [1.0 0.8 0.2]
                "float metallic" [.4]
                "float specular" [1]
                "float specularTint" [0]
                "float roughness" [0.5]
                "float anisotropic" [-1]
                "float sheen" [1]
                "float sheenTint" [0.5]
        TransformBegin
            #Keyframing 0 1.6 0 to 0 4 -7
            Translate 0 1.6 0
            #Keyframing 0 to 30
            Rotate 0 1 0 0
            TransformBegin
                #Keyframing 0 0 0 to 0 1.7 2.3
                Translate 0 0 0
                #Keyframing 0 to -30
                Rotate 0 1 0 0
                ReadArchive "objects/teaPotCap.rib"
            TransformEnd
            ReadArchive "objects/teaPotBody.rib"
  
            #Pouring
            AttributeBegin
                Bxdf "PxrDisney" "PxrDisney1"
                        "color baseColor" [0.75 0.15 0.05]
                        "float metallic" [3]
                        "float specular" [2]
                        "float specularTint" [1]
                        "float roughness" [.4]
                        "float anisotropic" [-.5]
                        "float sheen" [2]
                        "float sheenTint" [1]
                TransformBegin
                    Translate 0 2.9 5
                    #Keyframing -20 to 90
                    #[2]Keyframing 90 to 180
                    Rotate -20 1 0 0
                    TransformBegin
                        Translate 0 2.7 0
                        Rotate 90 1 0 0
                        Sphere 0.3 -0.3 0.3 180
                    TransformEnd
                TransformEnd
                TransformBegin
                    Translate 0 2.9 5
                    #[2]Keyframing 70 to 180
                    Rotate 70 1 0 0
                    Rotate 90 0 1 0
                    #Keyframing 0 to 110
                    Torus 2.7 0.3 0 360 0
                    TransformBegin
                        Translate 2.7 0 0
                        Rotate 170 0 0 1
                        Sphere 0.3 -0.3 0.3 180
                    TransformEnd
                TransformEnd
            AttributeEnd
        TransformEnd
    AttributeEnd
  
  
    #Cups
    AttributeBegin
        TransformBegin
            Bxdf "PxrDisney" "PxrDisney1"
                    "color baseColor" [0.2 0.4 0.6]
                    "float metallic" [.4]
                    "float specular" [1]
                    "float specularTint" [0]
                    "float roughness" [0.4]
                    "float anisotropic" [-1]
                    "float sheen" [1]
                    "float sheenTint" [0.5]
            Translate 0 0.4 0
            ReadArchive "objects/cup.rib"
        TransformEnd
        AttributeBegin
            Bxdf "PxrDisney" "PxrDisney1"
                    "color baseColor" [0.75 0.15 0.05]
                    "float metallic" [3]
                    "float specular" [2]
                    "float specularTint" [1]
                    "float roughness" [.4]
                    "float anisotropic" [-.5]
                    "float sheen" [2]
                    "float sheenTint" [1]
            TransformBegin
                #[2]Keyframing 2 to 3
                Translate 0 2 0
                Rotate 90 1 0 0
                #[2]Keyframing 3 to 3.8
                Disk 0 3 360
            TransformEnd
        AttributeEnd
    AttributeEnd
  
    #StaticCups
    ReadArchive "objects/staticCups.rib"
  
WorldEnd
        KeyFrameEnd
#------------------------------------------


Obstacles

I wanted to use booleans, to make the process of my modeling smoother. The first problem occuring was the normals of the shapes. For I created the polygons and shapes in script, at first it was hard to understand which direction the normal of each shape is pointing. After overcoming this issue, another problem poped out. When I made a boolean out of two shapes, some dots showed up when rendering. I did everything I could to avoid such a problem in rendering, but my efforts were in vain. In the end, I gave up using boolean and went on with the just plain modeling.




Conclusion

It was not my first time coding, but it was definitely my first time coding for the purpose of creating any kinds of graphic. It was an interesting challenge and I really enjoyed analyzing the modeling and animation part of a 3d scene in codes.




Batman Shader


The Batman Shader

Now we get to the third assignment, the Custom Shaders. To be honest, I'm so excited because it's getting more challenging with each assignment ahead. In fact, what I need to do is to create a shader in Renderman Reyes, completely from scratch, by using math functions. Of course, initially we need to create some basic shapes, and after that we must create our own custom shape.
As Batman was one of my childhood's favorite superheroes, I decided to make him my shader. I found the Batman equation, created and distributed by a math teacher in internet, so I didn't have to make that on my own. But the conversion of the mathmatical equation into RSL codes was a bit tricky.

/* Crescent */


surface
diffuse_test(    float    Kd = 1;    /* basic brightness */
                color     FrontColor = (0.513,0.517,0.768);
)
{
color    surfcolor = 1;
float    x = s-0.5;
float    y = t-0.5;
if(pow(x,2)+pow(y,2)<=0.15 && pow(x-0.1,2)+pow(y,2)>=0.12) surfcolor = FrontColor;
  
/* STEP 1 - make a copy of the surface normal one unit in length */
normal    n = normalize(N);
normal    nf = faceforward(n, I);
  
/* STEP 2 - set the apparent surface opacity */
Oi = Os;
  
/* STEP 3 - calculate the diffuse lighting component */
color    diffusecolor = Kd * diffuse(nf);
  
/* STEP 4 - calculate the apparent surface color */
Ci = Oi * Cs * surfcolor * diffusecolor;
}

Crescent Shader



/* Cross */


surface
diffuse_test(    float    Kd = 1;    /* basic brightness */
                color     FrontColor = (0.513,0.517,0.768);
)
{
color    surfcolor = 1;
float    x = s;
float    y = t;
if(x>=0.2 && x<=0.8 || y>=0.2 && y<=0.8) surfcolor = FrontColor;
  
/* STEP 1 - make a copy of the surface normal one unit in length */
normal    n = normalize(N);
normal    nf = faceforward(n, I);
  
/* STEP 2 - set the apparent surface opacity */
Oi = Os;
  
/* STEP 3 - calculate the diffuse lighting component */
color    diffusecolor = Kd * diffuse(nf);
  
/* STEP 4 - calculate the apparent surface color */
Ci = Oi * Cs * surfcolor * diffusecolor;
}

Cross Shader



/* Sinusoids */


surface
diffuse_test(    float    Kd = 1;    /* basic brightness */
                color     FrontColor = (0.513,0.517,0.768);
)
{
color    surfcolor = 1;
float    x = s-0.5;
float    y = t-0.5;
if(y>=sin(x*6)) surfcolor = FrontColor;
  
/* STEP 1 - make a copy of the surface normal one unit in length */
normal    n = normalize(N);
normal    nf = faceforward(n, I);
  
/* STEP 2 - set the apparent surface opacity */
Oi = Os;
  
/* STEP 3 - calculate the diffuse lighting component */
color    diffusecolor = Kd * diffuse(nf);
  
/* STEP 4 - calculate the apparent surface color */
Ci = Oi * Cs * surfcolor * diffusecolor;
}

Sinus Shader



/* CheckerBoard */


surface
diffuse_test(    float    Kd = 1;    /* basic brightness */
                color     FrontColor = (0.513,0.517,0.768);
                float    HorizontalSpread = 50;
                float    VerticalSpread = 50;
)
{
color    surfcolor = 1;
float    x = s;
float    y = t;
if(sin(s*HorizontalSpread)*sin(t*VerticalSpread)<=0) surfcolor = FrontColor;
  
/* STEP 1 - make a copy of the surface normal one unit in length */
normal    n = normalize(N);
normal    nf = faceforward(n, I);
  
/* STEP 2 - set the apparent surface opacity */
Oi = Os;
  
/* STEP 3 - calculate the diffuse lighting component */
color    diffusecolor = Kd * diffuse(nf);
  
/* STEP 4 - calculate the apparent surface color */
Ci = Oi * Cs * surfcolor * diffusecolor;
}

CheckBoard Shader



/* BatmanShader */


surface
BatmanShader(    float    Kfb = 1;    /* fake brightness */
               	color    BackColor = 1;
                color    BatmanColor = 0.05;
                float    Scale = 1;
                float    OffsetX = 0;
                float    OffsetY = 0;
                float    Rotation = 0;        
)
{
color    surfcolor = BackColor;
float    a = 0.06*Scale;
float    x = (s-0.5-OffsetX)*cos(Rotation/58.8)-(t-0.5-OffsetY)*sin(Rotation/58.8);
float    y = (t-0.5-OffsetY)*cos(Rotation/58.8)+(s-0.5-OffsetX)*sin(Rotation/58.8);
  
if(
//BatmanEquationBegin
(x*x/(49*a*a)+y*y/(9*a*a)<=1)
&&
(abs(x/a)>=3)||((-(3*sqrt(33))/7<=y/a)
&&
(y/a<=0))
&&
(y>0)||((-3<=y/a)&&(y/a<=0))
&&
((-4<=x/a)&&(x/a<=4))
&&
(-((3*sqrt(33)-7)*x*x)/(112*a*a)+(abs(x/a))/2+sqrt(1-(abs(abs(x/a)-2)-1)*(abs(abs(x/a)-2)-1))-y/a-3<=0)||(y>=0)
&&
(3/4<=abs(x/a))&&(abs(x/a)<=1)
&&
(-8*abs(x/a)-y/a+9>=0)||((1/2<=abs(x/a))&&(abs(x/a)<=3/4))
&&
(3*abs(x/a)-y/a+3/4>=0)
&&
(y>=0)||(abs(x/a)<=1/2)
&&
(y>=0)
&&
(9/4-y/a>=0)||((1<=abs(x/a))&&(abs(x/a)<=3))
&&
(y>=0)
&&
(-(abs(x/a))/2-3/7*sqrt(10)*sqrt(4-(abs(x/a)-1)*(abs(x/a)-1))-y/a+(6*sqrt(10))/7+3/2>=0)
)
//BatmanEquationEnd
surfcolor = BatmanColor;
  
/* STEP 1 - set the apparent surface opacity */
Oi = Os;
  
/* STEP 2 - calculate the apparent surface color */
Ci = Oi * Cs * surfcolor * Kfb;
}

The Batman Shader
The Batman Shader



Conclusion

It was not my first time coding, but it was definitely my first time coding for the purpose of creating any kinds of graphic. It was an interesting challenge and I really enjoyed analyzing the modeling and animation part of a 3d scene in codes.




Shader Animation




For the final project, we were assigned to create an animation based on shader created in the previous assignment. So I used a volumetric, so it kind of gives the concept of Batman Logo being projected in the sky.



I used a noise on the scale of the logo, so it has a shimmering effect in the light rays as well.

BatmanHypershade VolumetricAndBatman


Conclusion

For the final animation, I didn't use any kind of abstract motion-graphics and I tried my best to have an applicable animaiton for the design I used, the batman logo. I think it was a great challenge and I really enjoyed tweaking my own shader's parameters in hypershade and using a volumetric lighting to light my scene.




Shader Animation


BatmanEquationOSLTest

Process

To use our shader created by RSL (Renderman Shading Language) in RIS Renderer, it needs to be converted into OSL (Open Shading Language). For this procedure, we have to create a RibBox in the Shading Group and change its interpretation into TCL. Then we should load the RIB File in that RibBox by using a TCL file. The TCL file can be gerenarted by Cutter with a bunch of edits. The last thing that we need to generate, is a Graphical User Interface (GUI), which in our case will be produced by a mel script.

Obstacle

The obstacle I encountered during the process of converting RSL to OSL was the conversion of the equation. In fact, the same equation were fine in RSL and Renderman Reyes, but when it was converted to OSL, Renderman RIS mode had some problem rendering the right shape. I tried to change the equation in any way I can, but my efforts were in vain.
After a long period of time troubleshooting, finally Malcolm helped me to figure out what was wrong. The problem was that OSL does not understand the integer format like "3/4" and instead, I need to use "0.75". After the chnage, the Batman logo was a match to RSL one."




Conclusion

The process done here might not happen again, because it seems that Pixar is working on an update to make it easier to create OSL shaders. But it was an interesting attempt converting an RSL code into OSL and creating a GUI with controllers for RIS Rendering in Renderman.




Contact Me