November 11, 2014

Engraved Shotgun - Reverse Engineering

0 comments
So here we go, I'd like to share one of my projects that might be interesting for you to look at. This project, for me personally, is kind of 'expansion' of what my knowledge and skill in 3D can do. So far, I've been doing 3D only for visualization and animation. But this one is for manufacturing industry, which is new to me.

I'm really grateful to meet some friends at Rannova Indonesia that gave me a chance to work with them in this project. The project is what we call a reverse engineering, a process of recreating something based on the existed thing which in this case is a wooden engraved shotgun body.

So this guy has a wooden shotgun with some engraving on it and he wanted this shotgun to be available for mass production. For a time being, it took a lot of time to produce the shotgun because it needs craftsmen, a human resources to do the job. Furthermore, since every craftsmen has different skill, it's hard to standardize the quality of the engraving. There comes an idea of how to make this product available to be created by machine.

This is the rendered image of final 3D file that I created based on the original product:
render 3D engraved shotgun - reverse engineering
Final 3D File for Prototyping

Then my friends at Rannova Indonesia did the rest, the process of milling and so on which I actually don't really understand. :p

Then after the long process, this is what we got:
First look of the Final Product
First look of the Final Product


It reminds me of Gunpla kits btw. LOL

Cheers!

November 07, 2014

[Freebies] MAXScript: Rendering AO Pass Made Easy

0 comments
As you all know, there are many ways to create an Ambient Occlusion Pass. We can use the default Ambient Occlusion Pass in Render Element, use the mr_shader_element with AO shader set on it, or use the Material Override and do the render. The first two is much faster to do, but resulting in solid black background image that might be quite annoying when in compositing process. The last one needs some steps to do before doing the render, but we can set the background to solid white.

MaxScript Render AO Pass
MAXScript: Rendering AO Pass made easy
So I took some time learning MAXScript and decided to create this simple one that might help me do the task. So, what does this script do? This script is actually doing the third method mentioned above, in automatic way:

  • switch the renderer to mental ray
  • remove all lights
  • turning off FG (to speed up render a little bit)
  • create an AO material and apply it on ALL objects (you might want to hidden the objects you don't want to render)
  • set the background environment to white
  • set the gamma to 1.0 (so you won't get a washed-out AO)
  • do the render
  • saving the file (only if you set the Save File on your Render Setting)
  • then set everything back as if nothing happened

One nice thing about this script is you don't need to worry about what render engine you use for your main renderer. As long as mental ray is (by default) come as one package with your 3ds Max, then this will work. When you run this script, it will render the AO pass and leave your scene back as it was before the rendering process.

INSTALLATION
The installation is very easy. First you need to download the .ms file (link available below). Run your max, click on MaxScript - Run Script, then browse the downloaded file. Nothing happened but don't be panic, click on Customize - Customize User Interface. Then click on Toolbars tab, choose Main UI on the Group dropdown menu, and find ariespranata on the Category.


You should find the renderAO in the Action as shown in image above. Just drag it to your toolbar on top and the button will be created automatically there. Just click on that render AO button, and new window will appear.

Render AO Pass parameter dialog
There are some parameters that you might want to set to define the quality of your AO pass. The parameter setting is actually the same as the mental ray AO shader and I guess they are pretty much self-explained.

The "-suffix Name" is the text that will be used as a -suffix in your filename. This will only apply when you check the Save File on your Render Setting. No worries, if this script find the same file name, it will ask your permission first whether to replace it or not. Say that you have a file named "Interior.jpg", then the AO will be saved as "Interior_AO.jpg" at the same directory.

DOWNLOAD: MAXScript: Render AO Pass
NOTE: you might need to temporarily turn off your ad blocker. If you find this script useful, I'd be very grateful if you share this blog post instead of the direct link. :)

MAXScript: Render AO Pass version release
ver 1.0
- Initial Release, tested and developed on Max 2011. Update: tested also on Max 2013 and 2015.

If you have some idea to improve this script, please comment below. I'd love to hear that and I'll try to improve this script in my free time.

Cheers!

August 30, 2014

[Flash] Action Script 3.0 Basic Part I

0 comments
Today, I will explain about the basic programming in ActionScript 3.0 (AS3) using Adobe Flash Professional. This is a very basic principle and it's actually the fundamentals of any programming language. You can use this principle to any programming language. The only difference is just the syntax (the way the code is written), but the concept remains the same.


So in this part 1, I will cover some basics about:
- Declaring Variable
- Conditional Statement
- Loop Statement

You can use this in any version of Flash Professional that supports ActionScript 3.0 (Macromedia Flash 8, CS, and CC version). Let's get started! :D

Creating New File

When we open Flash, there will be a Welcome Screen. With that many options, choose Create New File - ActionScript 3.0. Then we're ready to code, as simple as that. Note that if you use AS3 code in AS2 project, you will get error message when you compile the movie.

A few things to keep in mind before we begin to code in AS3:

- AS3 is case-sensitive language, meaning the uppercase and lowercase letter is recognized differently. For example, if we type a text data 'string' instead of 'String', then we'll get error. Because Flash recognizes 'String' (with capital S letter) instead of 'string' as a data type for text data. The easiest way to avoid that mistake, you can notice that the term will always change to blue color if Flash recognizes it as its default scripting term.
- Always use semicolon (;) to end a statement. It's recommended to use semicolon (;) to end each statement so you'll not find really hard when you learn other programming language that force you to use it. In Flash, it's actually not really necessary to use, you can simply use a line break (Enter), but still, I recommend you to use semicolon.
- You can access the ActionScript window by pressing F9, and compile the script by using Test Movie (Ctrl+Enter).
- Like any other programming language, AS3 will be executed in order from top to bottom lines. So in some cases, if the order is not right, then it will throw some errors. For example, we set a value to a variable before declaring that variable first will throw error because it's unable to find the variable. It's illogical to set a value to a non-existed variable.

Declaring Variable

So, what is variable? Variable is like a container to hold something, and this container have specific type to match with the content. For example, if we have a water container, then it should be used to contain water. So if we have a text variable, then we can use it to contain text data. Variables value can also be changed dynamically as long as the value is the same type as the variable type.

The syntax:
var var_name:var_type = value;
var_name is the variable name, you can name it everything you like with some conditions: variable name cannot contain only number or started by number, but combination of text+number is fine. Also it's recommended to avoid the same name as Flash default scripting term (when the text turns to blue). For example:
  • var 123:int; is incorrect
  • var 1ove:int; is incorrect
  • var a:int; is correct
  • var number01:int; is correct
  • var var:int; is incorrect since var is Flash default scripting term

var_type is the type of the variable. Normally, when we type var a:, then the autocomplete window will appear, showing the list of all available data type to help us get the right term. You can see it in the image below (the color might be different from yours because I have my actionscript color preferences set to my custom colors). :p
AutoComplete Feature in Flash Professional
AutoComplete Feature in Flash Professional
Now, let's try creating a variable. You can type this into your Actions window:
var a:int;
trace(a);
int is a data type for round number, it's derived from the word 'integer'.
trace() is a function to show a value of a variable. The value will be shown in the Output window when we compile the movie.

Now, hit Ctrl+Enter to execute the script. You will get 0 in the Output window. Why? because we didn't set any value to the variable a yet. Now set the value to 2.
var a:int = 2;
trace(a);
Hit Ctrl+Enter again and now it will show 2. That means that our variable 'a' now has a value, which is 2.

Now let's try a simple math:
var a:int = 2;
var b:int = 3;
var c:int;

c = a+b;
trace(c);
Hit Ctrl+Enter again and now you will see 5 in the output window. What exactly happened here? First, we create a variable a with value 2, variable b with value 3, and variable c with empty value. Then, we set the value of variable c by adding 'a' value (2) with 'b' value (3). Thus we get 5.

Conditional Statement

Conditional Statement is used when we need to check whether a condition is met or not.

The syntax:
if (condition){
    //Do something
}
condition is where we put something to check; I'll explain next with an example. Note that in this syntax, we use brackets {}. This is what we call a 'code block', a place where we can put some code to be executed when certain condition is met. Also, you can see the //, this is called a 'comment'. Anything that we put after the // will not be executed by the compiler (try yourself and see what you type turns to grey color), so it is good to use when we want to give notes.

Now, let's try a little example:
var a:int = 1;
if (a==1){
    trace("a is one");
}
What this code means? It means that we want to check whether the value of 'a' is equal to 1. Notice that I use == instead of =. When we want to check the value of a variable, we use ==is used when we want to set a value.

Then, what happened when the condition is met? Hit Ctrl+Enter and you can see 'a is one' text in your output window. Since the value of 'a' is equals to 1, it means the condition is met, so the code within the code block is executed, which is trace("a is one"). Wait, why use double quotes ("")? Whenever it's a text data (called String data type), we have to use " before and after the text. If we don't, Flash will throw errors. We can also use single quotes (') interchangeably if our text data contain double quotes, e.g. 'a is "one" ' . In Flash, every String data will turns to green color by default.

Now, what if the condition is not met? Let's modify our code a little:
var a:int = 2;
if (a==1){
    trace("a is one");
} else {
    trace("a is not one");
}
I change the value of 'a' to 2, and add an else clause. What does this else clause do? Whenever a condition is not met, the code within the else clause will be executed. If you don't give any else clause, then nothing will be executed. Now hit Ctrl+Enter, you should now see 'a is not one' text in your output window because the value of 'a' is 2 and not 1.

Let's make things a little bit more complicated. What if the condition to check is more than 1? If so, we can use the else if clause:
var a:int = 2;
if (a==1){
    trace("a is one");
} else if (a==2){
    trace("a is two");
} else {
    trace("a is not one nor two");
}
Now hit Ctrl+Enter again, you will see 'a is two' text in your output window. What happened here is Flash will first check, whether the value of 'a' is equals to 1, which is not. So, Flash will skip the first code block and jump to the second check: is value of 'a' equals to 2? It's true, so Flash runs the following code block, thus we get 'a is two' text in our output window. Note that once a condition is met, then Flash won't run the following else and else if clause (if there is any). In our case, the else clause won't be run because the condition (a==2) has been met.

Loop Statement

Loop Statement is used to execute some codes repeatedly for a specific number of times when a certain condition is met.

The syntax:
for (counter; condition; action){
    //Do Something
}
counter is any number variable, it's used as an iterator or starting number. The second parameter is condition, this is where we set a condition for our counter to meet. The last parameter is action, where we define how the counter will increase, decrease, or multiply. This action will be executed for every loop cycle.

Let's say we want to trace "Hello World!" for 5 times, in ancient-fashioned way, we can use:
trace("Hello World!");
trace("Hello World!");
trace("Hello World!");
trace("Hello World!");
trace("Hello World!");
Imagine when we need to trace that for a hundred times.. @.@
Instead, we can use this:
var i:int;
for (i=0; i<5; i++ {
    trace("Hello World!");
}
When you hit the magic button, Ctrl+Enter, you will find exactly the same result as the first one.
First, we start by declaring a variable 'i' with integer type, then followed by the for-loop statement.
- i=0 is how we set the starting number of our counter; we set it to 0.
- i<5 is the condition we set for our counter to meet.
- i++ has the same meaning as i=i+1, which will add 1 to our counter for each loop cycle. You can use any math operation of course to accommodate your need, increasing our counter by 1 for each loop cycle is what we most generally used.

To explain better how this for-loop statement works, we will modify our code a little:
var i:int;
for (i=0; i<5; i++ {
    //trace("Hello World!");
    trace("Hello World!, i="+i); //will trace the value of i
}
This will result:
How the For-Loop Statement Works
How the For-Loop Statement Works

You can see that our counter starts with 0, as we stated before i=0. Then after executing the trace() code, it increases by 1 for every loop cycle. The cycle stops when the counter reached 5, because it's no longer meet our i<5 or i is less than 5 condition. That's why the last trace() executed is when the counter value is 4.


--
So, this is the end of part 1. I hope this will be a useful tutorial, especially for those who wants to start learning AS3. Any positive comments are welcomed to make this tutorial better. :)

Cheers!

February 15, 2014

[3ds Max] Quick Tips: X-Ray Shader

0 comments
Hi, guys. Today I'm gonna show you how to create an x-ray shader in 3ds Max. Nice thing is, this shader is using only procedural map, so we don't need to create any texture map our own.

X-Ray Shader in Autodesk 3ds Max
X-Ray Shader in Autodesk 3ds Max

So first thing first, we need a reference of how an x-ray image looks like in real world. It's always been a good habit for us, as an artist, to look for real-world reference before we start making anything. So, I googled a little and found this image:

x-ray crab | source: nationalgeographic.com

It's an x-ray crab. :D ....now, let's start a brief research of the image.
  • First, notice that x-ray makes the object looks hollow. The intensity of the outer part of the objects is high and gradually decrease when it comes to the inner part.
  • Second, the overlap parts have even brighter intensity. This effect is similar to when we use 'Add' in Photoshop layer mode.
  • Third, we have some noise when it comes to the inner part.
So, that's our quick examination. Let's get into 3ds max and we'll start the shader creation.

Open 3ds max, create an empty scene. Now hit M to show our Material Editor window. Grab an empty material slot and switch it to a Standard Material if it isn't.

Set to Standard Material
Click on the little square beside the Opacity and select Falloff map in the Material/Map Browser window. The Falloff map generates a value from white to black, based on the angular falloff of the face normals on the surface of the geometry. Well, that words might be too difficult to understand, so when you see the result once the map is applied, you will understand.

Use Falloff for Opacity map

The Falloff map will make our material have 100% intensity on the outer side and gradually decrease to 0% in the inner part. Thus, our shader looks like it's hollow in the inside. We can also adjust the intensity by playing with the black and white color in the parameters.

Now, drag our Opacity map to our Self Illumination map, make an Instance copy. X-ray creates no shadow, so it's a good idea to use the Falloff map also in the Self Illumination map so that our shader will 'glow' and pop out. Don't forget to check on the 2-Sided too.

Make an Instance Copy of Falloff map to Self Illumination

Remember the 'additive' part in our brief research? We can do that by checking on Additive in the Extended Parameters rollout. Now we are a little bit closer to our x-ray.

Use Additive Type

Click on the M square button to adjust our Falloff map parameter. Since we use our Falloff map in the Opacity slot, then we can play the opacity of our material by adjusting the black and white color. White means 100% opacity, black means 0% opacity, and grey means between them. Adjust the black color to a dark grey so that our material won't be 100% transparent in the inside.

Now you might want to test the material. Create an object, I used Torus Knot, in the scene and hit render. You should get something similar to this image:

Torus Knot with X-Ray Shader
Nice one, eh? :D
So this is our basic shader for x-ray. We can adjust and playing with the maps to create more detailed effect. For example, we can use Noise map in our Falloff map to make some noise in the shader too.

Use Noise Map to Give Detailed Look

Some Parameter Tweaking of the Noise Map
I also adjust the diffuse color to a bluish one and got something like this:


Well of course you can still play more with the shader to achieve better result. You might need to adjust some of the size parameters in the maps to fit your model. By the way, the more detail your model is, the better you will get the effect.


If you're interested, I want to share my x-ray shader that I used for the T-Rex above. Basically it's the same shader I used from above tutorial, but with a little tweaking and some more maps for the detail. You might learn something from this.

DOWNLOAD: X-Ray Shader
This is a .max file created using 3ds Max 2011 (you can't open this in older max version). Open the file then open the Material Editor and you'll get the shader there.

I hope you find this tutorial helpful and have a nice day. :D

Cheers!

February 13, 2014

[Flash] Load a Web Page using Adobe AIR

0 comments
Hi, guys. I've been testing about using Flash and Adobe AIR recently to create an app for mobile devices. One tips that I'd like to share with you today is how we can easily load a web page in Flash. Wait, why would we want that? By doing so, we are actually creating a web app specifically for our website without having to code again from zero. Isn't that cool to have an app with your brand name on it? :D

So what do we need to have? First we need to build our website (of course), preferably a responsive one so that it should match wide variety of device resolution.. especially for Android phones, they have a very wide range of device resolution since they're created by many manufacturers.

Then we need Flash to build our Air application, or other Flash IDE such as Flash Builder or flashdevelop. In this tutorial, I will use Flash CS6. Fyi, Flash CS6 supports Adobe AIR for Android and iOS, and it allows you to manage the AIR SDK, so we can always replace it with the latest SDK. If you don't know where to download the latest Adobe Air SDK, you can download it from Adobe AIR Developer Center. Flash CS6 has ver. 3.5 included by the way.

So we're all set up, then let's code ;)

Preparing the Project File

Every time we open Flash, we'll be asked about what project we're going to create. This time, instead of choosing ActionScript 3.0, we'll use the AIR project.

Flash Professional CS6 Welcome Screen
Flash Professional Welcome Screen
Notice that there're 3 options for AIR projects, AIR, AIR for Android, and AIR for iOS. Actually they're all the same. The only differences is the targeted device: AIR for desktop PC, Air for Android for Android device, and AIR for iOS for iOS device. So, in this tutorial, I will use the Air for Android option.

Click on that, and we'll now have a 480x800 px blank new file with the Publish Settings already set for Android device.

Using StageWebView Class for Loading Web Page

StageWebView class is the class that we'll be using to load our awesome website. If you want to dig depper about this class, you can see the documentation here.

Now, I'll explain you the code. First, we need to calculate the width and height of the screen, since we don't know where this app will be installed considering that wide-variety of resolution.

//This will return the actual width value of our stage
var wView:int = stage.stageWidth;
//This will return the actual height value of our stage
var hView:int = stage.stageHeight;

After we get the size, then we need to create our StageWebView object and assign the screen size to it using viewPort property. The viewPort property uses Rectangle value, so we need to set the screen size using Rectangle object (it uses 4 values: x position, y position, width, and height).

//Create a new StageWebView object
var swv:StageWebView = new StageWebView();
//Set the size of StageWebView object created to match the screen size
swv.viewPort = new Rectangle(0,0,wView,hView);

When you're done, now we will load the webpage using loadURL property, and show it using the stage property. NOTE: StageWebView is not a DisplayObject, so we cannot call it using addChild method like we've used to do when calling a MovieClip or Sprite. Thus, StageWebView object will always be put on top of everything and make us unable to place another object on top of that. Suppose you want to place a button or movie clip on top of that, you need to hide the real StageWebView object and convert it to BitmapData using drawViewPortToBitmapData() method. Then show the bitmap instead of the real StageWebView object. Read the full explanation in the documentation.

//Load the Google Page
swv.loadURL("http://www.google.com");
//Show the StageWebView Object
//If you want to hide it, set the stage property to null
swv.stage = this.stage;

Now hit the magic shortcut (Ctrl+Enter) and you should see the Google page shown on your screen.

StageWebView Object showing Google Web Page
StageWebView Object showing Google Web Page

The nice thing about StageWebView is when the page is longer than the screen, then it will actually show the scrollbar. So we don't need to mess with the scrolling page code. ;)

Now, try to load a heavier website. You'll notice that the StageWebView will show a white blank page before it completes loading the webpage. We can avoid that white blank page being shown by setting the stage property only after the webpage is fully loaded. So what to show, while it's loading? Well, a movie clip with loading animation would be a good idea. :D

//Add an event listener when the webpage is fully loaded
swv.addEventListener(Event.COMPLETE,onCompleteHandler);
function onCompleteHandler(e:Event):void {
    swv.removeEventListener(Event.COMPLETE,onCompleteHandler);
    swv.stage = this.stage;
}

So our full code would be something like this. *Do not forget to import the required class also*

import flash.display.Stage;
import flash.geom.Rectangle;
import flash.media.StageWebView;
import flash.events.Event;

var wView:int = stage.stageWidth;
var hView:int = stage.stageHeight;

var swv:StageWebView = new StageWebView();
swv.viewPort = new Rectangle(0,0,wView,hView);
swv.loadURL("http://www.google.com");

swv.addEventListener(Event.COMPLETE,onCompleteHandler);
function onCompleteHandler(e:Event):void {
    swv.removeEventListener(Event.COMPLETE,onCompleteHandler);
    swv.stage = this.stage;
}

Publishing the Application

Well, I'm not going to explain the detail step to do this because that will make this post much much longer. But you can get the documentation in the Adobe official website:
- Publishing for Android device
- Publishing for iOS device

Btw, it's better for you to have a real device to test when developing a mobile device app, because if you have your code work in Test Movie doesn't guarantee that it will work on the device.

Okay, I think this is the end of the tutorial. I hope you find something useful here.
Cheers!

January 24, 2014

In Christ Alone

0 comments
Okay, so I am not an illustrator. I know for sure that my drawing skill is not quite great but I just want to share this. :p One day, my friend made me to draw for her, an illustration that tells the story about her struggling when she worked on her final project. I think that would be fun, and since we both love the illustration style of HJ-Story, I tried to make one with that style.

This illustration tells all: about how she learned to rely on God's strength instead of hers to do her final project. The texts, it was taken from a song by Brian Littrel, In Christ Alone (you should hear the song, it's very nice). It was the song that gave her strength in her struggling.
In Christ Alone
In Christ Alone
..and for her graduation surprise. :D
Grace is
Grace is

To remind us that it's all by HIS grace. Cheers! :)