Playing around with Three.JS -- Part Two of a not quite a tutorial series

23. July 2014

 

In Part One we looked at the basics of working with the Three.js graphics library.  We got as far as creating a camera and a textured 3D object.  Now is the true test of ease of use… getting a 3D model exported from Blender and displayed in our browser.  HTML libraries face an even bigger burden, as their access to the local file system isn’t as seamless as most other games.  Simply opening up an FBX or DAE file isn’t an option.  Let’s take a look at how ThreeJS works around this issues.

 

 

First’s thing first, I needed a Blender Blend file to work with.  This actually lead me down this road, resulting in a post about taking a Blend file from the web and making it game ready.  Anyways, I did.  I started with this file, merged the geometry, UV mapped it, and baked the Blender materials to a single texture map.  I am not entirely sure if I can share the resulting file or not, so you may have to provide your own Blender file or follow the linked tutorial to generate one of your own.

 

Anyways, this is what we are starting with…

image 

 

Let’s see how close we can get with Three.js.

 

The first obvious question is… how the hell do we get this model in to Three.JS from Blender?

Well, the answer is a plugin.  Follow the installation direction, however in my case the path was wrong.  For Blender 2.71, my actual plugin directory is C:\Program Files\Blender Foundation\Blender\2.71\scripts\addons\io_mesh_threejs.

 

There is one very critical thing to be aware of here… when downloading the files from Github, be certain to download the RAW format:

image

 

This particular mistake caused me a bit of pain, don’t make the same mistake!

 

Once you’ve copied each of these three files, configure the plugin in Blender.  If Blender is running, restart it.

Now select File->User Preferences:

image

 

In the resulting dialog select Addons, then in the search box type “three”.  If it installed correctly it will show on the right.  Click the checkbox to enable the plugin.

image

 

Now if you check the File->Export menu, you should see Three.js as an option.

image

 

When exporting you can clearly see there are a ton of options:

image

 

The options I selected above is for just exporting the mesh and materials.  No animation data, lights, cameras, etc… Scaling and Flip YZ all depend on the orientation of your game engine.

 

This exporter creates a JSON js like this one:

 

{"metadata" :{"formatVersion" : 3.1,"generatedBy": "Blender 2.7 Exporter","vertices": 8,"faces": 6,"normals": 2,"colors": 0,"uvs": [24],"materials": 1,"morphTargets": 0,"bones": 0},"scale" : 1.000000,"materials" : [	{"DbgColor" : 15658734,"DbgIndex" : 0,"DbgName" : "Material","blending" : "NormalBlending","colorAmbient" : [0.6400000190734865, 0.6400000190734865, 0.6400000190734865],"colorDiffuse" : [0.6400000190734865, 0.6400000190734865, 0.6400000190734865],"colorEmissive" : [0.0, 0.0, 0.0],"colorSpecular" : [0.5, 0.5, 0.5],"depthTest" : true,"depthWrite" : true,"mapDiffuse" : "crate.jpg","mapDiffuseWrap" : ["repeat", "repeat"],"shading" : "Lambert","specularCoef" : 50,"transparency" : 1.0,"transparent" : false,"vertexColors" : false}],"vertices" : [1,-1,0,1,0,1,-1,0,0,0,-1,0,1,0,0,0,1,1,-1,1,0,0,0,0],"morphTargets" : [],"normals" : [0.577349,0.577349,0.577349,0.577349,0.577349,-0.577349],"colors" : [],"uvs" : [[0.988679,0.99767,0.988677,0.016243,0.007251,0.016244,0.007252,0.997671,0.989755,0.017099,0.989755,0.998526,0.008328,0.998526,0.008328,0.017099,0.990714,0.989755,0.009287,0.989755,0.009286,0.008328,0.990713,0.008328,0.000516,0.993662,0.981943,0.993661,0.981942,0.012235,0.000516,0.012235,0.987766,0.997568,0.987766,0.016141,0.006339,0.016141,0.006339,0.997568,0.986807,0.986807,0.986807,0.005381,0.00538,0.00538,0.00538,0.986807]],"faces" : [43,0,3,2,1,0,0,1,2,3,0,0,1,1,43,4,7,6,5,0,4,5,6,7,0,0,1,1,43,0,4,5,1,0,8,9,10,11,0,0,1,1,43,1,2,6,5,0,12,13,14,15,1,1,1,1,43,2,3,7,6,0,16,17,18,19,1,0,0,1,43,3,0,4,7,0,20,21,22,23,0,0,0,0],"bones" : [],"skinIndices" : [],"skinWeights" : [],"animations" : []}

 

In theory things should just work, but since when did gamedev give a damn about theory?  Suffice to say I ran into a bit of a problem fully documented here.  The bug actually had nothing to do with Three.js, it was actually caused by my IDE WebStorm.

 

Anyways… once I figured out the problem, the code to load a model was extremely straightforward:

 

///<reference path="./three.d.ts"/>class ThreeJSTest {
renderer:THREE.WebGLRenderer;
scene:THREE.Scene;
camera:THREE.Camera;constructor() {this.renderer = new THREE.WebGLRenderer({ alpha: true });
this.renderer.setSize(500, 500);this.renderer.setClearColor(0xFFFFFF, 1);
document.getElementById('content').appendChild(this.renderer.domElement);
this.scene = new THREE.Scene();
this.camera = new THREE.PerspectiveCamera(75
, 1
, 0.1, 1000);
this.camera.position = new THREE.Vector3(10, 0, 10);this.camera.lookAt(new THREE.Vector3(0, 0, 0));
// New code begins below// Create a loader to load in the JSON filevar modelLoader = new THREE.JSONLoader();
// Call the load method, passing in the name of our generated JSON file// and a callback for when loadign is complete.// Not fat arrow typescript call for proper thisification.  AKA, we want         this to be this, not that// or something else completely
modelLoader.load("robot.jsm", (geometry,materials) => {
// create a mesh using the passed in geometry and textures
var mesh = new THREE.SkinnedMesh(geometry,new THREE.MeshFaceMaterial(
materials));
mesh.position.x = 0; mesh.position.y = mesh.position.z = 0;
// add it to the scene
this.scene.add(mesh);});
this.scene.add(new THREE.AmbientLight(new THREE.Color(0.9,0.9,0.9).
getHex()));this.renderer.render(this.scene, this.camera);}render() {requestAnimationFrame(() => this.render());this.renderer.render(this.scene, this.camera);}start() {this.render();}}
window.onload = () => {var three = new ThreeJSTest();
three.start();};

 

And when you run it:

image

 

Mission accomplished!  The astute reader may notice the file was renamed robot.jsm.  That was to work around the problem I mentioned earlier.

 

 

 

This isn’t actually the only option for loading 3D models into Three.js, there are actually a series of loaders available as a separate download from the Github site.  It is however certainly the easiest one!  The next few steps took me two full days to fight my way through!  Some of the blame is on TypeScript, some is on me and of course, CORS reared it ugly head as well.  Oh, and to add to the fun, a recent change in Three.js introduced an error in the version of ColladaLoader.js I downloaded. This was one of those trials that Google was no help with, so hopefully this guide will help others in the future.  Anyways… on with the adventure!

 

We are actually about to run smack into two different problems with using a Three.js plugin.  The first one is TypeScript related.  You see, the ColladaLoader plugin is not a core part of Three.js.  In JavaScript, this is no big deal.  In TypeScript however, big deal.  You see, until now we have been relying on the generated .d.ts file from StrictlyTyped for defining all of the types in Three.js from JavaScript in their corresponding TypeScript form.  However, since this is a plugin and not a core part of Three.js, this means the d.ts file has no idea how ColladaLoader works.

 

Ultimately this means you have to had roll your own Typescript definition file. I had to struggle a bit to find the exact TypeScript syntax to map ColladaLoader so it will run in TypeScript within the THREE namespace with proper callback syntax.  First off, create a file called ColladaLoader.d.ts   Now enter the following code:

 

///<reference path="./three.d.ts"/>declare module THREE {export class ColladaLoader{
options:any;load(
name:string,
readyCallback:(result:any)=> void,
progressCallback:( total:number,loaded:number)=> void);}}

 

 

I should probably point out, I only implemented the barest minimum of what I required.  In your case you may have to implement more of the interface.  Also note I also took the lazy approach to defining options.  By returning any, my code will compile in TypeScript, but I do lose some of the type checking.  The alternative would have been to define the Options type and I am way too lazy for that.  The above definition enable me to call the load() method and set options, which is all I actually needed.  I don’t even want to talk about how long it took me to puzzle out those 10 lines of code so that the generated code actually matched THREE.js!

 

OK, we now have ColladaLoader.d.ts defined let’s look at code to use ColladaLoader to load a DAE (COLLADA) file:

 

///<reference path="./three.d.ts"/>///<reference path="./ColladaLoader.d.ts"/>class ThreeJSTest {
renderer:THREE.WebGLRenderer;
scene:THREE.Scene;
camera:THREE.Camera;
loader:THREE.ColladaLoader;
light:THREE.PointLight;constructor() {this.renderer = new THREE.WebGLRenderer({ alpha: true });
this.renderer.setSize(500, 500);this.renderer.setClearColor(0xFFFFFF, 1);
document.getElementById('content').appendChild(this.renderer.domElement);
this.scene = new THREE.Scene();;
this.camera = new THREE.PerspectiveCamera(75
, 1
, 0.1, 1000);
this.camera.position = new THREE.Vector3(5, 0, 5);this.camera.lookAt(new THREE.Vector3(0, 0, 0));
// Create a loaderthis.loader = new THREE.ColladaLoader();
// Add a point light to the scene to light up our modelthis.light = new THREE.PointLight();this.light.position.set(100,100,100);this.light.intensity = 0.8;this.scene.add(this.light);
this.renderer.render(this.scene, this.camera);
// Blender COLLADA models have a different up vector than Three.js, set         this option to flip themthis.loader.options.convertUpAxis = true;
// Now load the model, passing the callback finishedLoading() when done.this.loader.load("robot.dae",
(result) => this.finishedLoading(result),
(length,curLength)=>{
// called as file is loading, if you want a progress bar
});}finishedLoading(result){// Model file is loaded, add it to the scenethis.scene.add(result.scene);}render() {requestAnimationFrame(() => this.render());this.renderer.render(this.scene, this.camera);}start() {this.render();}}
window.onload = () => {var three = new ThreeJSTest();
three.start();};

 

 

Finally of course we need to export our COLLADA model.  Using Blender, you can export using File->Export->Collada menu option.  These are the settings I used:

image

 

And when you run it:

image

 

That said, there is a really good chance this isn’t what is going to happen to you when you run your project.  Instead you are going to probably receive a 404 error that your dae file is not found.  This is because, unlike before with the JSON file being added directly to your project, this time you are loading the model using an XML HTTP Request.  This causes a number of problems.  The first and most likely problem you are going to encounter is if you are running your application locally from your file system instead of a server.  By default XHR requests do not work this way ( no idea why, seems kinda stupid to me ).  There is a switch that allows chrome to run XHR local requests ( link here ) using --allow-file-access-from-files.

 

In my case the problem was a little bit different.  I use WebStorm, which includes a built in web server to make this kind of stuff easier.  This however raises a completely different set of problems…  CORS  Cross Origin Resource Sharing.  In a very simple description, CORS is a security method for making XML HTTP Requests across different servers.  That said, how the heck do you set it when you are working with a built in stripped down development server?  Fortunately WebStorm have thought about that.

 

Assuming you are using Chrome and have the Webstorm plugin install, in the Chrome address bar, go to chrome://extensions.

image

 

Click the Options button.

image

Now simply add 127.0.0.1 to the allow list and press Apply. 

 

Now if you run from Webstorm, no more 404 errors.

 

A moment about TypeScript

 

I’ve been using TypeScript a fair bit lately and this is the first time I’ve run into major problems with it.  But the experience is enough that I can safely say…

 

TypeScript is not appropriate for new developers to use!

 

Simply put, unless you have a decent amount of experience with JavaScript, you really shouldn’t use TypeScript.  You will have to read the generated code at some point in time, and if you don’t full understand the code it generates, you are doomed.  The minute definition files arent available to you the experience becomes a hell of a lot less fun.  The process of mapping TypeScript types to existing JavaScript libraries is not trivial and requires you to have a pretty good understanding of both languages.  Especially when the library you are trying to define uses a number of clever JavaScript tricks, which basically… is all of them.  The fact there isnt a reliable tool out there for generating at least boilerplate .d.ts files from .js files is a bit of a puzzle to me.

 

Next, I also have to say TypeScript’s handling of this is just as mind bogglingly stupid as JavaScript’s.  That fat arrow ( => ) functions are used to capture local context, until used as an anonymous method, at which point they capture global (window) context, forcing you to resort to function() is downright perplexing.  I simply couldn’t get anonymous callback functions to have the proper this context no matter what syntax combination I tried.  Infuriatingly, the _this value Typescript automatically contains was set to the right value.

 

One other major downside I noticed about the language with my recent struggles is the newness of the language is very much an annoyance.  When researching bugs or workarounds you quite often find things that are reported as bugs, reported as changed,  or reported and never responded to.  This isn’t a bash on the language as it’s really only a problem that time can solve.  However, for a new developer, dealing with a language where a great deal of the material out there is potentially wrong because of language changes, that is certainly a challenge.  All languages change over time of course, but young languages change more and more dramatically.

 

Don’t get me wrong, I am not off Typescript, even though it spent a good part of the last two days pissing me off.  At least until ECMAScript 6 is the norm I can see a great deal of value in using TypeScript for large projects.

 

For beginners though, with little JavaScript experience… forget about it.  It’s going to cause more headaches than it’s worth.

Programming, ,





Unreal Engine 4.3 released

18. July 2014

I just received the following email from Unreal:

 

TranslusentFogDemo

Unreal Engine 4.3 Released!

 

More than 500 updates ship in this release! Unreal Engine 4.3 includes greatly improved mobile support, awesome new rendering features, improved Blueprint workflows, and strides toward an excellent experience on Mac and laptops.

 

Check out the new World Composition tools, spline features, and the preview of Paper2D, our 2D toolset! You also get SpeedTree 7 support, our work on Metal API for iOS 8 to date, and new Oculus Rift features such as time warping.

 

There’s no limit to what you can do with Unreal Engine 4 for only $19 per month.

 

Paper2D Side Scroller Template

Have fun with the new side-scroller template game as you become acquainted with Paper2D.

Read More

 

VR Couch Knights

We love VR, and Unreal Engine 4.3 supports the new Oculus DK2 out of the box! Dive into Epic’s popular “Couch Knights” demo which has been making the rounds at GDC and other shows.

Read More

SpeedTree 7

SpeedTree 7 support is here, and UE4 trees are 33% off in the SpeedTree store throughJuly 26!

Read More

Rendering Goodies

Rendering goodies include distance field ambient occlusion, skylight global illumination and shadowed translucency.

Read More

Behavior Trees

Better AI tools! Switch to the new Blackboard mode inside the Behavior Tree Editor to edit and debug Blackboard entries.

Read More

Large World Support!

Large world support! Check out the new World Composition tools. Create sub-levels and position them anywhere.

Read More

Customize Your Static Mesh Collision!

Customize your static mesh collision!

Read More

Spline Editing

Edit splines directly within your levels!

Read More

 

Build games and apps for Windows, Mac, iOS, Android, PlayStation 4, Xbox One, Linux, SteamOS, HTML5 and VR platforms.

Get Unreal for $19/Month

Mobile Developers!

Zen Gardens

Google recently demonstrated the graphics power of L, the upcoming release of Android, using Epic's Rivalry demo running on Tegra K1 at Google I/O. Mobile is a huge focus for UE4, and we hope you’ll enjoy all the latest improvements!

Read More

 

 

The UE4 Roadmap continues to evolve, and we encourage you to vote for features that want to use.

 

To ask questions and share feedback, please visit the forums or join our live broadcasts at Twitch.tv every Thursday at 2pm ET, which you can always go back and view atYouTube.com.

 

Hats off to the developers who contributed to this great release! These who helped are forever immortalized in the Credits section under the editor’s Help menu.

 

Thank you for being a part of this adventure. We can’t wait to see what you build next.

 

We are one step closer to Paper2D support, which is their support for 2D engines. Occulus Rift support is no doubt cool for those developing for the Rift. Not quite as impressive as the last release, but still a good amount of progress from Unreal.

News,





WebStorm, Three.JS, Source Maps and ARRRRRGHHHHHHHH

18. July 2014

 

So, as you may be able to tell from the title, I’ve run into a bit of a bug moment.  I am in the process of getting Blender exported models to work with the Three.JS library, as a follow up to this post.  As with all things programming related you are going to run into your share of problems.  This post actually walks through the process of identifying and fixing a bug.

 

The first lesson of bug hunting is always simplify.  Try to replicate the problem in as little code as possible.  What follows below is a blow by blow of  the debugging process.

 

First off, it’s a Three.JS project using TypeScript authored in WebStorm.  All of these points are important to this story.  Not to ruin an upcoming post with too much code, I’ll just give the applicable code.  The problem is in this code… if it’s in code at all that is.  Yeah, that’s a bit of a hint.

 

var modelLoader = new THREE.JSONLoader();
modelLoader.load("dice.jsm", function(geometry,materials){
var mesh = new THREE.SkinnedMesh(geometry,new THREE.MeshFaceMaterial(
materials));
mesh.position. x = mesh.position.y = mesh.position.z = 0;
this.scene.add(mesh);});

 

Anyways, I started off by trying to load this model:

image

Exported from Blender to Three.JS JSON format.

 

When I run the code however I get the following in WebStorm:

image

 

Unexpected token /?

 

Hmmm, looks like something went wrong in the export process.  This is never a fun thing to debug, as the output of the above model is a JSON file 1.5MB in size.

 

So, it’s time to simplify.  I need a model with a texture, nothing more.  Let’s make something about as basic as possible.  So I hack together a quick textured model in Blender and export it.  This is the new model:

image

 

Ok, that is definitely simpler.  Now when I run it I get the exact same error.  Ok, this file should be a hell of a lot easier to debug.  Let’s take a look at the generated JSON file.  Oh, top type… right click the js file and tell Webstorm to treat it as plain text, otherwise it will clobber your CPU trying to parse the javascript!

 

 

{"metadata" :{"formatVersion" : 3.1,"generatedBy": "Blender 2.7 Exporter","vertices": 8,"faces": 6,"normals": 2,"colors": 0,"uvs": [24],"materials": 1,"morphTargets": 0,"bones": 0},"scale" : 1.000000,"materials" : [	{"DbgColor" : 15658734,"DbgIndex" : 0,"DbgName" : "Material","blending" : "NormalBlending","colorAmbient" : [0.6400000190734865, 0.6400000190734865, 0.6400000190734865],"colorDiffuse" : [0.6400000190734865, 0.6400000190734865, 0.6400000190734865],"colorEmissive" : [0.0, 0.0, 0.0],"colorSpecular" : [0.5, 0.5, 0.5],"depthTest" : true,"depthWrite" : true,"mapDiffuse" : "crate.jpg","mapDiffuseWrap" : ["repeat", "repeat"],"shading" : "Lambert","specularCoef" : 50,"transparency" : 1.0,"transparent" : false,"vertexColors" : false}],"vertices" : [1,-1,0,1,0,1,-1,0,0,0,-1,0,1,0,0,0,1,1,-1,1,0,0,0,0],"morphTargets" : [],"normals" : [0.577349,0.577349,0.577349,0.577349,0.577349,-0.577349],"colors" : [],"uvs" : [[0.988679,0.99767,0.988677,0.016243,0.007251,0.016244,0.007252,0.997671,0.989755,0.017099,0.989755,0.998526,0.008328,0.998526,0.008328,0.017099,0.990714,0.989755,0.009287,0.989755,0.009286,0.008328,0.990713,0.008328,0.000516,0.993662,0.981943,0.993661,0.981942,0.012235,0.000516,0.012235,0.987766,0.997568,0.987766,0.016141,0.006339,0.016141,0.006339,0.997568,0.986807,0.986807,0.986807,0.005381,0.00538,0.00538,0.00538,0.986807]],"faces" : [43,0,3,2,1,0,0,1,2,3,0,0,1,1,43,4,7,6,5,0,4,5,6,7,0,0,1,1,43,0,4,5,1,0,8,9,10,11,0,0,1,1,43,1,2,6,5,0,12,13,14,15,1,1,1,1,43,2,3,7,6,0,16,17,18,19,1,0,0,1,43,3,0,4,7,0,20,21,22,23,0,0,0,0],"bones" : [],"skinIndices" : [],"skinWeights" : [],"animations" : []}

 

Well, first obvious thing is to look for an offending / in this code.

Hmmm… there is none.  Well we wouldn’t make the big bucks if this was easy now would we?

 

Let’s go back to our error for a second:

image

 

Well, other than the fact we know we have a / where we shouldn’t, we also have the line of code that is going all explodey.  Let’s start there.  This is one of those things that makes WebStorm so freaking cool.  Just click the link “three.js:11960” and it will automatically download that script file and go to that position.  Let’s take a look at the resulting code:

image

 

Ok, that’s some pretty straight forward code.  Basically it’s a XML response function handler.  As we can tell from the above code, the callback executed all nice and dandy.  As you can see on line 11960 I’ve set a breakpoint to pause execution before our exception, let’s see if that gives us any insight.  If you don’t know about breakpoints and debugging, drop everything and learn.  You will literally become a better programmer overnight.

 

So… to the debugger!  Let’s see what the value of responseText is:

 

By hovering over it, everything looks fine, seems to match the file we are expecting:

image

 

That said, let’s take a look at the whole thing.  Now we are going to use a feature called “Evaluate Expression”.  Again, if you don’t know what this is, drop everything and go learn.  I really need to write a debugging tutorial…. 

 

image

 

Copy the value and paste it into your editor of choice.  Then scroll to the very bottom:

image

 

Oh son of a bi….

 

That my friend, is our bug.  See, Webstorm has the ability to generate something called a SourceMap, which helps the debugger translate your running code to the code you created, especially useful if you, like me, are working in a JavaScript generating language like TypeScript.  As you can see, sometimes this is not ideal however.  Basically when run, Webstorm was appending a source map to the bottom of our js file, rendering into invalid JSON and causing the parser to puke.

 

There are two immediate solutions to this problem.  First, we can disable source map generation.  This unfortunately is a project wide setting as far as I can tell, and I rather like the ability to debug.  The easier solution is to change it from a .js file to something different.  However, once deployed to a server this can have unintended side effects.  For example, IIS will not, by default, serve files without a registered mime type.

 

Oh, and for the astute, once I got past the problem be renaming the file extension, I did in fact discover two errors in my code.  The proper TypeScript code is;

 

var modelLoader = new THREE.JSONLoader();
modelLoader.load("dice.jsm", (geometry,materials) => {
var mesh = new THREE.SkinnedMesh(geometry,new THREE.MeshFaceMaterial(
materials));
mesh.position.x = 0; mesh.position.y = mesh.position.z = 0;
this.scene.add(mesh);});

 

Why is an exercise for the reader. :)

Programming, , ,





Baking Blender materials to texture to make them usable in a game engine

16. July 2014

 

Or…

How to take a Blender model you downloaded from the web and make it actually usable in your game in 28 easy steps!

 

… granted, the second title doesn’t have the same flow to it, does it?

 

I just had to run through this process and I figured I would share it as it is something that occurs fairly often.  When working with Blender, there are dozens of behavioral textures available that can make for some very nice results quickly.  The only problem is, when you get your asset out of Blender and into your game engine, things suddenly go horribly wrong.  The problem is, those textures only make sense inside of Blender.  Fortunately through the magic of baking, you can easily convert them into a texture map usable in any game engine.

 

Let’s take a look how.

 

First we need a model.  I am using a beautiful new model that was recently added to Blend-Swap.  It’s a free download but you need to register.  Don’t worry, you can use a real email address, they don’t spam, or at least haven't so far.  The model in question looks like this:

 

image

 

Unfortunately when we load it in Blender we quickly learn this model is in no way game ready.  Let’s take a look:

image

 

Ick.  So instead of a single Mesh, we have a dozen individual meshes.  Problem is, we need to unwrap them as a single object, so let’s join them all together.  First let’s get the camera out of the default layer.

 

If you look at the way this particular Blend is setup, there are currently two layers, the second contains the armature, the first contains everything else.

image

 

Lets get the camera out of there.  Select the camera object then hit the M key.  Then select the layer you want to move the camera to, like so:

image

 

Now click the first layer ( bottom left box ) and it should now only contain geometry.

 

We want to join everything together.  Press ‘A’ to select everything in the layer, then hit “Ctrl + J” to join everything into a single set of geometry.  Now it should look something like this:

image

 

Perfect, now we can unwrap our model.  Switch in to EDIT mode

image

 

Press ‘A’ again, until all faces are selected, like so:

image

 

Now we unwrap our model.  Select Mesh->UV Unwrap-> Unwrap ( or Smart UV Project ).

 

Switch your view to UV/Image Editor

image

 

It should look something like this:

image

 

Now create a New Image:

image

 

This image is where we are going to render our texture to.  Here are the settings I used.  Remember, games like Power of 2 textures.

image

 

Ok, now let’s look at the actual render to texture part.  Take a quick look at how the model is currently shaded:

image

 

Frankly none of those are really game engine friendly.  So let’s render all of those materials out to a single texture.  Go to the render tab

image

 

Scroll down and locate Bake.

In the UV Editor window, make sure everything is selected ( using ‘A’.  They should be highlighted in yellow ).  At this point, with your generated image and all the UV’s selected, it should look like:

image

 

 

Now under bake, set the following settings:

image

The key values being Bake Mode = Full Render and Selected to Active checked.  Now click the Bake button.

 

Up in your top part of Blender, you should see a progress bar like so:

image

 

 

Now if you go back to the UV/Image viewer, and select your image RenderedTexture, you should see:

image

 

Cool!

 

Let’s save the result to an external ( game engine friendly ) texture.  Select Image->Save as Image.  Save the image somewhere.  Remember where.

image

 

 

Now lets modify the textures on our model to use only our newly generated texture map.  First in 3D View, switch back to Object Mode from Edit mode.

Then, open the materials tab:

image

 

Select each material and hit the – ( or killswitch engage! ) button.  So it should ultimately look like this:

image

 

Now hit the + button and create a new Material.  Then click the New button.

image

 

The default values for the material should be OK, but depending on your game engine, you may have to enable Face Textures:

image

 

Now click over to the Texture tab.  Click New.

image

 

Drop down the Type box and select Image or Movie.

image

 

Scroll down to the Image section and select Open.  Pick the image you saved earlier.

image

 

Now scroll down to Mapping, drop down Coordinates and select UV.

image

 

Under Map select UVMap.

image

 

Now if you go to the 3D View and set the view mode to Texture:

image

 

TADA!  A game ready model.

 

One word of caution though, if you render this scene in Blender you will get the following result:

image

 

Don’t worry.  That’s just a biproduct of going from Blender materials to texture mapping.  If you want the texture to be seen, you need to add some lights to the scene.  Or change the material so it has an Emit value > 0, so it will provide it’s own light source.

 

With Emit set to .92, here is the result if you render it:

 

image

 

Now, what about it game?

 

Let’s create a simple LibGDX project that loads and displays our exported model:

 

package com.gamefromscratch;import com.badlogic.gdx.ApplicationListener;import com.badlogic.gdx.Files.FileType;import com.badlogic.gdx.Gdx;import com.badlogic.gdx.graphics.GL20;import com.badlogic.gdx.graphics.PerspectiveCamera;import com.badlogic.gdx.graphics.g3d.Environment;import com.badlogic.gdx.graphics.g3d.Model;import com.badlogic.gdx.graphics.g3d.ModelBatch;import com.badlogic.gdx.graphics.g3d.ModelInstance;import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute;import com.badlogic.gdx.graphics.g3d.loader.G3dModelLoader;import com.badlogic.gdx.utils.UBJsonReader;public class ModelTest implements ApplicationListener {private PerspectiveCamera camera;private ModelBatch modelBatch;private Model model;private ModelInstance modelInstance;private Environment environment;@Overridepublic void create() {
camera = new PerspectiveCamera(
75,
Gdx.graphics.getWidth(),
Gdx.graphics.getHeight());
camera.position.set(3f,0f,6f);
camera.lookAt(0f,1f,0f);
// Near and Far (plane) represent the minimum and maximum ranges of the camera in, um, units
camera.near = 0.1f;
camera.far = 300.0f;
modelBatch = new ModelBatch();
UBJsonReader jsonReader = new UBJsonReader();
G3dModelLoader modelLoader = new G3dModelLoader(jsonReader);
model = modelLoader.loadModel(Gdx.files.getFileHandle("robot.g3db", FileType.Internal));
modelInstance = new ModelInstance(model);
environment = new Environment();
environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.8f, 0.8f, 0.8f, 1.0f));}@Overridepublic void dispose() {
modelBatch.dispose();
model.dispose();}@Overridepublic void render() {
Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
Gdx.gl.glClearColor(1, 1, 1, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);
camera.update();
modelBatch.begin(camera);
modelBatch.render(modelInstance, environment);
modelBatch.end();}@Overridepublic void resize(int width, int height) {}@Overridepublic void pause() {}@Overridepublic void resume() {}}

 

And we run it and:

image

 

Wow, a model downloaded randomly from the Internet actually working in the game engine!  How often does that actually happen? ;)

Programming, Art, ,





CocoonJS 2.0.2 released

16. July 2014

CocoonJS 2.0.2 was just released. CocoonJS is a development platform that allows you to wrap your HTML5 application in a streamlined browser optimized for games. This allows you to deploy your application to mobile devices as an actual application, with near native performance.

 

The release announcement:

 

Good news! The new version 2.0.2 of CocoonJS is live! It comes with some very important bug fixes and improvements. You can read the full changelog here but here are some of the highlights in this version.

Canvas+

Fixed the crash on Tegra-based Android devices like the Samsung Galaxy Tab 10.

Fixed texture corruption bug that affects Phaser based games using WebGL.

Other improvements in audio, DOM node management, camera speed, computeStyle, etc.

More...

WebView+

Updated the WebView+ to the latest stable Chromium version. Fixes some crashes, improves WebGL support, etc.

Other stability bugs fixed.

More...

CocoonJS Launcher

Fixed the support for Android 2.3.

Settings are more homogeneous both on iOS and Android and are correctly stored between sessions.

Improved URL handling. The final slash is no longer necessary for URLs to a folder (a more browser-like behaviour).

The URL history button on Android shows all your URLs.

More...

Extensions

Added a new native share functionality. CocoonJS.App.share() inside CocoonJS_App.js.

The CocoonJS Extension repository now provides branches for previous CocoonJS versions.

Fixed several bugs and updated the SDKs in the ad extension for MoPub and AdMob.

Fixed bugs on social, notification and multiplayer extensions.

More...

VERY IMPORTANT NOTE: CocoonJS 1.4.7 will be deprecated soon

CocoonJS version 1.4.7 support will be discontinued by August 1 2014 as the GoogleAd SDK that it is using will be deprecated by Google. More Info

REMINDER: CocoonJS Cordova Command Line Interface (CLI)

Have you tried it yet? Remember, it allows for the compilation of Cordova projects using Ludei’s unique WebView+ technology! More Info

 

 





Month List

DisqusCommentsSummary