Showing posts with label animation technique. Show all posts
Showing posts with label animation technique. Show all posts

Saturday, January 18, 2014

You Could Upload an Image from WEBGL or You Could Just Go Shoot Yourself


Lets say that you embrace the WebGL world and write some nifty graphics application in it.   Now lets suppose you want to save an image or two from your interactive application and doing a screengrab is not appropriate. Perhaps this is because you wish to save many images, such as an animation.   Maybe you are debugging a complicated problem and wish to save snapshots in various parts of a process.

Maybe you are iterating through a space and need to make a record of each step.  I do this all the time in animation production to do what is called a "wedge", which is a way of making choices among many parameters.  

But this is WEBGL and the bold new Internet paradigm, so things are not so easy.

In fact, its a really annoying process to save an image under program control and the reason for this has less to do with WebGL than it does to do with Internet architecture and the awful state of documentation in our bold new Internet based reality.

I present here one solution to the "save an image" problem.  Here are choices that had to be made to get to this solution:

1. In order to save an image, you must upload it to a server.
2. In order to upload anything you must use "Ajax", which really means XMHHttpRequest.
3. The server side is written in node.js
4. We are going to use POST.
5. We are going to use base64.
6. We are not going to use FORMS or BLOBS.
7. Our server is going to do nothing but receive an image and save it out.
8. You may save as many images as you like, the filename will be incremented by 1 each time.
9. All images are saved in PNG format.
10. We are going to use getDataURL() directly from the canvas and not use gl.readPixels at all.
11. Therefore we do not have to set any special flags when we acquire the 3D canvas.
12. If a file already exists of the same name, it will be written over without comment.
13. The images are put in the directory that you run the node server out of.

If you are new to this, these choices made above eliminate a billion or so other possible solutions and therefore makes the problem solvable (instead of iterating through an infinite search space getting half baked quasi solutions on the internet).

When it is all said and done, the result is about 1/2 page of code on the browser/client side and about 1 page or a little more on the server side.  Everything is written in Javascript, with the server side making use of node.js.

Here is the code that works for me.  If you try it and it does not work for you, please let me know.   

Uploading An Image (Client/Browser Side)

When the 3D canvas has an image you wish to save, do the following: 

// generate "dataURL" for the image on the screen
// "canvas" is what is returned from document.getElementById on your webgl canvas

   var newimg_dataurl = canvas.toDataURL("image/png"); 

// NB  The server is going to be looking on socket 8080 and a path of  /imagehandler.  
// But these are arbitrary and can be whatever you like 

   s_postimage(newimg_dataurl, "image/png", "http://localhost:8080/imagehandler"); 

// the function that actually posts the image 

var s_postimage = function(dataurl, imagetype, dest_url) {

    var xr = XMLHttpRequest(); 
    xr.addEventListener("error", xfer_error, false); 
    xr.addEventListener("load", xfer_complete, false); 

    xr.open("POST", dest_url); 
    xr.send(dataurl);

    return;
}; 

var xfer_complete = function(e) {
    // document.write("<br>xfer complete");
}; 

var xfer_error = function(e) {
    if (e) throw e; 
}; 


Uploading an Image (Server Side)

This is run with the command "node imageup.js" where the file imageup.js contains:

var http = require('http');
var url = require('url'); 
var querystring = require('querystring');
var util = require('util'); 
var fs = require('fs'); 

var img_seqno = 0; 

http.createServer(function (req, res) {

    switch(req.url) {

     // This is where you would put in handlers for situations/requests other than 
      // the request to upload an image

    case '/imagehandler':

if (req.method == 'POST') {
           console.log("[200] " + req.method + " to " + req.url);
           var fullBody = "'';
           var fname = "upimage_" + img_seqno.toString() + ".png"; 
           console.log(fname); 

           req.on('data', function(chunk) {
          // append the current chunk of data to the fullBody variable
              fullBody += chunk;
             console.log("data received"); 
});

        req.on('end', function() {
           // request ended -> do something with the data
           res.writeHead(200, "OK", {'Content-Type': 'text/html'});
           console.log("end received"); 

           var base64Data = fullBody.replace(/^data:image\/png;base64,/,"");
           fs.writeFile(fname, base64Data, 'base64', function(err) { 
              if (err) throw err; 
             console.log("image saved " + fname); 
             img_seqno ++; 
}); 
        res.end();
});
} else if (req.method == 'OPTIONS') {

            var headers = {};
            headers["Access-Control-Allow-Origin"] = "*"; 
            headers["Access-Control-Allow-Methods"] = "PUT, POST, GET, DELETE, OPTIONS"; 
             headers["Access-Control-Allow-Credentials"] = false;
             headers["Access-Control-Max-Age"] = '86400'; // 24 hours
             headers["Access-Control-Allow-Headers"] = 
                 "X-Requested-With, X-HTTP-Method-Override, Content-Type, Accept";
            res.writeHead(200, headers); 
            res.end(); 
            console.log("OPTIONS received"); 

        } else {
            console.log("[405] " + req.method + " to " + req.url);
            res.writeHead(405, "Method not supported", {'Content-Type': 'text/html'});
            res.end('<html><body>Method not supported</body></html>');
}
break;


    default:
        res.writeHead(404, "Not found", {'Content-Type': 'text/html'});
      res.end('<html><body>Not found</body></html>');
console.log("[404] " + req.method + " to " + req.url);
    };
}).listen(8080, "127.0.0.1"); // listen on tcp port 8080 on the localhost

// end of server code




Tuesday, February 19, 2013

Totoro and the Absence of Traditional Story Structure


As anyone who has tried to finance a film knows, Hollywood has very clear ideas about what sort of film is marketable in this country. And very, very clear ideas of what sort of ANIMATED film makes money in this country. And since they are very specifically in that business to make money, they attach a lot of importance to these rules.

Among the rules are these: (a) an animated film will have frequent breaks with music for the small children in the audience, (b) an animated film will not be over a certain length, and (c) an animated film will rarely if ever have a female protagonist, and if it does, she shares center stage with a male protagonist. From there, Hollywood goes on and applies a number of other rules and requirements about story structure, most of these ae applicable to other types of films as well, and includes certain things about the types of conflict in the film, the pacing, the reversals, the climax, etc. Hollywood has a strong opinion on these matters. It is one reason so many Hollywood films seem the same, one giant robot or alien invasion after another. That is because they are the same at one level of abstraction.

My favorite animated film however follows none of those rules. It has no happy songs, it is much longer than average, and the protagonists are two little girls, one about three years old. It goes on from there in its eccentricity. It is not clear that there is a villain in the film, except perhaps whatever it is that is making their mother sick such that she must stay in a hospital. There is one homage to standard story structure: the climax of the film involves the youngest girl running away to see her mother, and the effort to find her.  This could be seen as a classic 3rd act rescue mission.


What's up in the scary attic?

The film did not do well at first in the Far East, where it was made. But eventually the toys got marketed and that fed back to the film until it became successful there. The film found no distribution in this country (1) until, unusually, a firm with no experience in this genre picked it up, added English subtitles and tried a theatrical release in N. America. I believe it did not do well, and the film disappeared, except to the few who knew of it and loved it, until Disney, at John Lasseter's urging, picked up all the films of this director and started marketing them in this country.

The director of course is Hayao Miyizaki and the film is My Neighbor Totoro (1988).


This is my corn and you are not going to take it from me

The company that attempted the distribution was Troma, a firm better known for making and distributing films such as "Surf Nazis Must Die" and "The Toxic Avenger". But in this case, they spent their own money bringing Totoro to the notice of Americans and, I think, lost their money. I happened to see it because my friend Chris Casady, owner of Roto Efx of America, had worked for Troma in the past and was invited to the screening at the DGA and invited me along.

I have excerpted my favorite scene from this film and put it at Youtube.  Well, I had put it on Youtube but it seems that someone is blocking it.  So you will have to review the pictures below, or of course, rent the video, which is what they want you to do which is fine with me.



Its an umbrella

On another occassion we will discuss the issues of trying to make a 3D character from one designed for 2D and review all the reasons that is hard, using two characters from this movie: the dust spirits and Totoro himself. Here are some images of these characters which I hope will set you thinking about why doing them in some sense in 3D (as in modelled in geometry) would be very difficult if you wanted to keep the essence and charm of the characters. And if you would not want to keep their charm, then why oh why would you even bother?




My Neighbor Totoro on IMDB

Miyazaki on Wikipedia

____________________________________________________

1. Most animated films, indeed most films, made in the Far East never see formal distribution in this country or North America. There have been a few exceptions and some of them are quite notable, e.g. many Kurosawa films would find some independent distribution here. This is especially true for animation made in the Far East, where many of their best and most successful films traditionally never made it over here, except in a very limited form marketed directly to fans of the various genres.

By way of counterexample, Bruno Bozzetto's Allegro Non Troppo did get distribution of some sort in this country.  I am not sure how that happened, but that does show that it is possible.

Friday, November 23, 2012

How To Make Someone's Head Explode


[This will be one of the many posts that include details about famous effects shots that I have picked up over the years.   It is all anecdotal information, believed to be true, but I wasn't there.  When this film was shot, I was in a dark room at Robert Abel & Associates writing their raster graphics system.]

As an exercise, I want you to think for a moment about how you would make someone's head explode.

As it turns out there are many ways to do this (in visual effects, of course, not in real life) and they all work with varying degrees of realism and at various costs.

Many of the films that might want to cause someone's head to explode are also low-budget horror films, those with the least amount of money to execute their vision. So I think we can say that one attribute of a method to make someone's head explode is that it should have a modest price and hopefully contribute a lot of value to the film.

Generally speaking, these are the things we are looking for.

1. That the head that explodes looks as much as possible as the real person's head. 
2. The audience should not notice the switch from the real to the standin.
3. The explosion itself should have character and not be a generic explosion.
4. The exploding head should interact with the set in some suitable way, e.g. brains, skull parts, etc. 

Although there are many ways of doing this kind of shot which could use any number of different techniques (miniatures, prosthetics, all digital, etc), best of all would be that it was "practical" in some way. "Practical" is a visual effects term of art that refers to an effect that you can use on the stage and when it is shot in live action it is in some sense done. There is no more to do. A radio controlled squib that spurts blood in simulation of someone being hit by a bullet is an example of a practical effect.

Arguably the best solution of this cinematic problem was realized by the movie Scanners (1981) as directed by David Cronenberg. The script describes a war between a small number of telepaths who are trying to take over the world and who have the power to read minds and also, with some effort, to cause someone's head to explode. Near the beginning of the film, a security organization gives a demonstration of telepathy to an audience of security professionals and, not realizing that they have been penetrated by a "bad telepath", played by actor Michael Ironside, the "good telepath" and the "bad telepath" struggle.   Evil wins in this case, and our victim telepath explodes.   Or rather, his head explodes.



As you can see, the telepath on the right seems to be reaching for a certain, climactic head position.

The solution was completely practical. A life mask of the good telepath in an expression of great pain was made, as well as a dummy of the rest of the body, dressed in the same suit. The live action of the scene was shot with the good telepath emoting his great unhappiness and reaching the same position and expression of the mask. A second sequence is shot with the camera in the same (or a similar) position, but instead of our actor we have a dummy, whose hands are gripped in an indication of great stress.  The mask on top of the dummy is given appropriate makeup and appliances, such as the eyeglasses, and filled with fresh chicken skin and Technicolor Blood #2. Then a shotgun is placed behind the dummy and pointed to the back of the head, out of sight of the camera, bolted into position, and rigged to be fired remotely. They then start the camera, set off the shotgun, and record the results for a few seconds. I am guessing that they use a high speed camera.

Then the two different takes are edited together such that the cut to the dummy happens a frame or so before the shotgun goes off. Of course they had to find a place to cut where the real actor had reached the head position and facial expression to match the dummy and mask.

The shotgun blows away both the mask and the contents, which then fall heavily, showing both excellent gravity and a sense of "follow through", onto the chest of the dummy. The effect itself makes good use of the animation principles of replacement animation, gravity, anticipation, follow-through and appropriate sound effects to enhance the visuals.

Its a beautiful effect which truly accomplishes what it needed to accomplish, which was to blow someones head off in a way that was dramatic and memorable and yet be very economical.   You could use the same technique today and it would work very well. 

Here is the trailer on Youtube, unfortunately in poor quality. It captures the essence of the scene in context however, if you want to see the blood more clearly there are other examples on Youtube that show that, but this shows the context, which is so important.   Please ignore the stupid music and graphics at the beginning and end of the trailer.  This was 1981 after all, a more primitive time.

I have found a much better trailer, this one for British audiences.  Unfortunately, it does not show the head explosion as well, but it is superior in all other ways.   On review, I have decided that this is probably a completely different head explosion from that found in the movie.  I wonder if it wasn't made especially for this trailer.   Some other post will discuss the context of how trailers are made, it is probably different than you expect.
http://www.youtube.com/watch?v=d6GNs6MthtU&NR=1&feature=fvwp

I have left out a picture of the exploding head, because it is too disgusting, and I am very sensitive to images of former people who have been turned into a bloody mess.   

The IMDB page for Scanners: