Archive

Author Archive

Toon Shading

December 6, 2015 1 comment

Introduction

Toon shading is 3D technique based on a specific shading method, which consist in recreate the look of traditional 2D animation cels with the use of flat colours for shading 3D objects in a unrealistic way.

Flat

This shading technique has been used in several games. There are several games that use this tehcnique, such as: Ni No Kuni, Legend of Zelda, Ōkami, Naruto Shippuden, etc.

games.png

There are two main topics in Toon shading, First is shading it self and the second one is Outline.

Shading

Toon shading used the enhancement of Diffuse/Lambertian Reflection, called Half Lambert.

What is Diffuse reflection?

When incoming light touch the surface it will be reflected off the surface in all direction equally. The light intensity of a point in the surface can be computed using the surface normal vector N and the light vector L

diffuse

 

Half Lambert is Technique first developed in the original Half-Life. Way of getting the lighting to show the surface of an object in low-light areas

half_lambert

Example of Half lambert equation in CG Language:

toon_shading_cg

Outline

For the outline we can use Silhouette. A silhouette is an edge shared by one front and one back-facing polygon.

silhouette

To get the outline more appeared we can enlarge back-facing polygon.

backface_poligon

If you look into unity toon shading package, you will see following code in ToonBasicOutline shader to produce the outline.

silhouette_cg

Try out with 3D Model

This is the result when i tried out a 3d model with diffuse shading and toon shading.

unity_result

Categories: Game and CG, Uncategorized

Nintendo 3DS Region Unlock

November 29, 2015 Leave a comment

I have bought old Nintendo 3DS from Japan, but sadly there’s a region lock that not permit us to play 3ds games that have different region with the console it self.

3DS games Sellers in my country rarely sell japanese regional games. To buy game, i had my friend in japan to buy the game for me. that’s suck. I did once anyway.

So, I google how to ‘jailbreak’ it, and found out that we can use Gateway 3DS to do that.

Requirements:

  1. Gateway 3ds Catridges:
    • Blue Catridge
    • Red Catridge
  2. Micro SD cards:
    • 2 GB or less for Gateway3ds Firmware
    • 8 GB or more to store your 3DS games
  3. SD Card to store saved game data
  4. Latest Gateway 3DS firmware
  5. Nintendo 3DS (firmware up to version 9)
  6. Original Game catridge (optional)

Steps needed:

  1. Format 2 GB micro SD card with Fat partition
  2. Copy all Files inside “Blue Card (R4i)” folder (from downloaded gateway 3ds firmware)  to root directory of 2 GB micro SD card
  3. Copy Launcher.dat to SD card
  4. Insert 2 GB micro SD card to Gateway 3DS Blue catridge.
  5. Insert Blue catridge to Nintendo 3DS catridge slot
  6. Boot into Gateway Menu. If it not working, then try to open nintendo 3ds browser, go to

    http://go.gateway-3ds.com – when the bottom screen changes to white, Press and hold the Left Shoulder button and your 3DS/2DS will boot to the Gateway Menu.

  7. Backup current 3ds firmware to SD card by selecting “Backup System Nand” menu. cut and paste backup file to a folder in your computer
  8. Downgrade 3ds firmware to version 4.4-4.5
  9. Reboot 3DS, check current 3ds firmware version
  10. Boot into Gateway Menu again
  11. Create EmuNand
  12. Insert original game catridge and save the game file into sd card. cut and paste the file (with extension .3DS) to 8GB micro SD card (exFat formatted). Insert it into Gateway Red catridge
  13. Boot into Emunand from Gateway Menu and update to the latest 3ds firmware.
  14. Insert Gateway Red catridge into 3ds catridge slot
  15. Press “select” button and select available game, your saved game in step 12 should appear
  16. Play the game!!

 

Categories: Game and CG, Nintendo 3DS

Simple Example using Unit Testing in Python

March 13, 2015 Leave a comment

This is simple example how to use unit testing in python. For example, you want to create module that generate fibonacci numbers and want to test whether the module is working properly or not.

Below is simple fibonacci.py script for module to generate fibonacci numbers :

# Fibonacci numbers module
def fib2(n): # return Fibonacci series up to n
    result = []
    a, b = 0, 1
    while b < n:
        result.append(b)
        a, b = b, a+b
    return result

def main():
    print fib2(100)

if __name__ == '__main__' : main()

And here simple testfibo.py script to test that module:

import fibonacci
import unittest

class TestFibonacciFunctions(unittest.TestCase):

    def test_series_100(self):
        print('\nTest Series 100')
        wanted_result = [1,1,2,3,5,8,13,21,34,55,89]
        test_result = fibonacci.fib2(100)
        self.assertEqual(wanted_result,test_result)

    def test_series_50(self):
        print('\nTest Series 50')
        wanted_result = [1,1,2,3,5,8,13,21,34]
        test_result = fibonacci.fib2(50)
        self.assertEqual(wanted_result,test_result)

if __name__ == '__main__' : unittest.main()

Run testfibo.py script with command

python testfibo.py

You will get following output if the wanted_result and test_result are equal

Test Series 100
.
Test Series 50
.
---------------------------------
Ran 2 tests in 0.000s

OK
Categories: Programming, Python

CodeIgniter & TokuMX

February 4, 2015 Leave a comment

CodeIgniter is a lightweight PHP framework that can help you to develop Web Application. TokuMX is a drop-in replacement for MongoDB, that support transaction.

You can download codeigniter from here, and TokuMX from here . For more information about how to install TokuMX, you can read TokuMX documentation from GitHub here.

To Make Web Application can connect to Mongo Instance, you need to install PHP extension for mongo. To Install in Centos or Redhat environment, run command :

pecl install mongo

and add to /etc/php.ini

extension=mongo.so

Restart Web Service

service httpd restart

Download codeigniter-mongo-library from here .

Here’s simple code example how to use codeigniter-mongo-library to perform CRUD operation.

<?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');

class Welcome extends CI_Controller
{
  // Insert Operation
  public function mongo_insert_test()      
  {
     $this->load->library("cimongo/cimongo");
     for($i=0;$i<25;$i++) {
        $this->cimongo
            ->insert("testData", array("x" => $i, "y" => 25-$i ));
     }
  }

  // Select Operation 
  public function mongo_select_test()
  {
     $this->load->library("cimongo/cimongo");
     $mongo_data = $this->cimongo->get("testData");
     foreach($mongo_data->result_array() as $row) {
        echo sprintf('x:%d,y:%d <br>',$row['x'],$row['y']);
     }
  }
  
  // Update Operation
  public function mongo_update_test()
  {
     $this->load->library("cimongo/cimongo");
     $result = $this->cimongo->where(array("x" => 24 ))
                    ->set(array("x" => 25 ))->update("testData");
     echo $result
  }

  // Delete Operation
  public function mongo_delete_test()
  {
     $this->load->library("cimongo/cimongo");
     $result = $this->cimongo->where(array("x" => 25 ))
                    ->delete("testData");
     echo $result;
  } 

}

?>

 

Categories: Database, Mongo, PHP, Programming

Facebook Login with Code Igniter

January 7, 2015 Leave a comment

Requirement:

  • Code Igniter 2
  • Facebook SDK 3.2.3 (consist of facebook.php & base_facebook.php, put them in libraries folder)

Controllers Code

  • application/controllers/user_auth.php (Handle login process)
    <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
    
    class User_auth extends MY_Controller
    {
        public function __construct()
        {
            parent::__construct();
        }
        
        private function load_fb()
        {
            $fb_config = array(
                'appId'  => $this->config->item('apps_facebook_id'),
                'secret' => $this->config->item('apps_facebook_secret'),
            );
            
            $this->load->library('facebook',$fb_config);
        }
        
        public function login()
        {
            $this->load->helper('url');
            $this->load_fb();
            $user = $this->facebook->getUser();
    
            if($user)
            {
                try 
                {
                    $profile_data = $this->facebook->api('/v2.1/me?fields=id');
                    $this->session->set_userdata(
                      'blablabla',intval($profile_data['id'],10)
                    );
                } 
                catch (FacebookApiException $e) 
                {
                    $user = null;
                }            
            }
            else
            {
                $this->facebook->destroySession();
            }   
            redirect(site_url('welcome/index'));
        }
        
        public function logout()
        {
            
            $this->session->unset_userdata('blablabla');
            redirect(site_url('welcome/index'));    
        }
    }
    
    ?>
  • application/controllers/welcome.php (User access /welcome/index page)
    <?php if ( ! defined('BASEPATH')) exit('No direct script access allowed');
    
    class Welcome extends MY_Controller
    {    
        public function __construct()
        {
            parent::__construct();
        }
        private function load_fb()
        {
            $fb_config = array(
                'appId'  => $this->config->item('apps_facebook_id'),
                'secret' => $this->config->item('apps_facebook_secret'),
            );
            
            $this->load->library('facebook',$fb_config);        
        }
        
        public function index()
        {   
            $this->load->helper('url');
            $fb_id = intval($this->session->userdata('blablabla'),10);
            $page_data = array();
            if(!empty($fb_id) && ($fb_id>0) )
            {
                $page_data['facebook_data']['logged_in'] = true;
                $page_data['facebook_data']['logout_url'] = 
                               site_url('user_auth/logout.php');
            }
            else
            {
                $page_data['facebook_data']['logged_in'] = false;
                $this->load_fb();
                $page_data['facebook_data']['login_url'] = 
                  $this->facebook->getLoginUrl(array(
                    'display' => 'popup',
                    'redirect_uri' => site_url('user_auth/login.php'), 
                    'scope' => array("email,public_profile,user_friends")
                ));
                
            }
            
            $this->load->view('welcome_view', $page_data);
        }
        
    }
    
    ?>

View Code

  • application/views/welcome_view.php (Put login/logout button  here)
    <html>
    <head>
      <title>Hello</title>
    </head>
    <body>
    <div id="fb-root"></div>
    <script>
        window.fbAsyncInit = function () {
          FB.init({
            appId: '<?php echo $facebook_data['apps_id'] ?>',
            version : 'v2.1',
            status: true,
            cookie: true,
            xfbml: true
          });          
        };
    
        (function (doc) {
          var js;
          var id = 'facebook-jssdk';
          var ref = doc.getElementsByTagName('script')[0];
          if (doc.getElementById(id)) {
            return;
          }
          js = doc.createElement('script');
          js.id = id;
          js.async = true;
          js.src = "//connect.facebook.com/en_US/sdk.js";
          ref.parentNode.insertBefore(js, ref);
        }(document));
        
        function Login() {
          FB.login(function (response) {
            if (response.authResponse) {
              location.replace(<?php echo site_url("user_auth/login.php");?>);
            } else {
              alert("Login attempt failed!");
            }
          }, { scope: 'email,public_profile,user_friends' });
        }
    </script>
    <div id="top_menu">
        <?php if(isset($facebook_data['logged_in']) && 
                 ($facebook_data['logged_in'] != false)  ) : ?>
            <div id="logout">
              <a href="<?php echo $facebook_data['logout_url'];?>" >Logout</a>
            </div>
        <?php else : ?>
            <div id="login">
              <a onclick="Login();" href="javascript:void(0);" >Login</a>
            </div>
        <?php endif; ?>
    </div>
    </body>
    </html>

Simple NGinX Config

January 7, 2015 Leave a comment

Simple configuration to host static file like images and act as proxy to pass php resquest to apache httpd.

NGinX Configuration:

#
# The default server
#
server {
    listen       80 default_server;
    server_name  _;

    #charset koi8-r;

    #access_log  logs/host.access.log  main;

    location / {
        root   /var/www/html/some_site/images_folder;
        index  index.html index.htm;
    }

    error_page  404              /404.html;
    location = /404.html {
        root   /usr/share/nginx/html;
    }

    # redirect server error pages to the static page /50x.html
    #
    error_page   500 502 503 504  /50x.html;
    location = /50x.html {
        root   /usr/share/nginx/html;
    }

    # proxy the PHP scripts to Apache listening on http://some.site.com:8080
    #
    location ~ \.php$ {
        proxy_pass   http://some.site.com:8080;
    }

    # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
    #
    #location ~ \.php$ {
    #    root           html;
    #    fastcgi_pass   127.0.0.1:9000;
    #    fastcgi_index  index.php;
    #    fastcgi_param  SCRIPT_FILENAME  /scripts$fastcgi_script_name;
    #    include        fastcgi_params;
    #}

    # deny access to .htaccess files, if Apache's document root
    # concurs with nginx's one
    #
    #location ~ /\.ht {
    #    deny  all;
    #}
}
Categories: Linux

Simple Callback

January 7, 2015 Leave a comment

Callback is a function that is executed when some other function is done with its work.

Example Code:

using UnityEngine;
using System.Collections;

public class SimpleCallback : MonoBehaviour 
{
    delegate void delegateCaller();

    void DoACall()
    {
        Debug.Log("Do A Call");
    }

    void DoAnotherCall()
    {
        Debug.Log("Do Another Call");
    }

    IEnumerator StartATask(delegateCaller callThis)
    {
        Debug.Log("Starting...");
        yield return new WaitForSeconds(1);
        Debug.Log("Done.");
        callThis();
    }

    // Use this for initialization
    void Start () 
    {
        StartCoroutine(StartATask(DoACall));
        StartCoroutine(StartATask(DoAnotherCall));
    }
    

}

Output

Starting...
Starting...
Done.
Do A Call
Done.
Do Another Call
Categories: C#, Programming, Unity