📜 ⬆️ ⬇️

What to choose for a 3D site - Three.js or Blend4Web?

I have known Blender for many years, using Unity for my games, but a complete newcomer to WebGL. However, the future is precisely for this technology, and it would be nice to deal with its use. Unfortunately, the Unity exporter for WebGL is not yet working and a different tool is needed.

I do not like to reinvent the wheel and prefer ready-made solutions. Blend4Web found earlier looks very tempting (integration with Blender, quality exporter, etc.), but there are quite a few other libraries and platforms for working with WebGL.

The eternal question: what to choose a newbie? I worked with the Blend4Web and Three.js platforms. What came of it - read on.
image

')
Basic knowledge:

I will not consider in detail the process of setting up both platforms, but I will touch on one important point. Since the systems are designed exclusively for creating WebGL applications, for testing they need to raise a local server. In the case of Blend4Web, after deploying the SDK, you will already get a working server at: localhost: 6687 (the port can be changed in the settings). For Three.js, this server will have to be installed separately. For example, use WampServer or select the appropriate one from the Utils folder (SDK Three.js).

However, you can do it easier and configure the browser to load local data. Just keep in mind that with such a browser you should not go on the real Internet.

Work with Three.js


Do you think the familiar “Hello World”? No, the specialized “hello”, but only from the 3D point of view. First of all, I am interested in practical application and usability. Therefore, I tried to do the most primitive - a standard scene with objects, a camera, lighting and simple animation.

In addition, the study and work with each platform was supposed to spend no more than 3 hours (for the purity of the experiment). A sort of marathon from scratch.

The initial choice fell on Three.js. So start ...

It all starts with the documentation. It is concise with the engine and has individual small examples for almost every function. The SDK has a large number of practical projects.

First, consider the preparation of HTML:

<html> <head> <title>Test</title> <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script> <script type="text/javascript" src="three.js"></script> </head> <body> <div> <div id="webGL-container" > </div> <script type="text/javascript" src="main.js"></script> </body> </html> 

This universal preparation and there is nothing interesting here. The Three.js library connects to the string. There is a more compact version of three.min.js. However, I decided to stop at the full version. The executable code is in a separate main.js file. It is in it that I am going to store the code for working with the engine.

Creating code for Three.js begins with a scene ad, camera, and render:

 var scene = new THREE.Scene(); var camera = new THREE.PerspectiveCamera( 75, window.innerWidth/window.innerHeight, 0.1, 1000 ); var renderer = new THREE.WebGLRenderer(); 

After that, you can start creating objects. In my case, I settled on a regular cube.

 var geometry = new THREE.BoxGeometry( 1, 1, 1 ); var material = new THREE.MeshBasicMaterial( { color: 0xffffff } ); var cube = new THREE.Mesh( geometry, material ); 

Created geometry, set up color, mixed and here it is Cube. Oh yes, you still need to add it to the scene with the scene.add (cube) command;

Now you can do anything with this object. For example, rotate it slightly along one axis.

 cube.rotation.z += 0.1; 

Likewise, it is necessary to displace the camera, because by default it is created in coordinates (0,0,0), like a cube.

 camera.position.z = 5; 

And the final finishing touch is the initialization and render call. The entire base code of the test scene is as follows:

 $(function() { var scene = new THREE.Scene(); var camera = new THREE.PerspectiveCamera( 45, window.innerWidth/window.innerHeight, 0.1, 1000 ); var renderer = new THREE.WebGLRenderer(); renderer.setSize (window.innerWidth,window.innerHeight); renderer.setClearColor (0x000000); var geometry = new THREE.BoxGeometry( 1, 1, 1 ); var material = new THREE.MeshBasicMaterial( { color: 0xffffff } ); var cube = new THREE.Mesh( geometry, material ); scene.add( cube ); camera.position.z = 5; cube.rotation.z += 0.1; $("#webGL-container").append (renderer.domElement); renderer.render(scene, camera); }); 

I did not explain some points in the code, but another thing is important, the realization that for the declaration of a primitive cube in the scene, as many as 4 lines were used. It inspired sad reflections on full-fledged models with textures, animation.

After reading the documentation, the features of Three.js became clear. Several types of cameras, full-fledged types of lighting, support for materials, textures, animations, stage effects are a completely credible list. Basically, all this wealth is added to the scene as previously indicated. For example, a lamp can be created and placed as follows:

 var light = new THREE.PointLight(0xffffff); light.position.set(-100,200,100); scene.add(light); 

As an indie game developer, I realized that the lack of an editor puts an end to the use of this library, at least for me. But people work with her and do cool things! And having rummaged on a site of developers, I found two interesting utilities: a plug-in under Blender and a certain editor, sharpened exclusively under Three.js.

First of all I tried to work with the plugin. Remember what task was assigned? Create a scene with objects, camera and light.

Suppose it should be a cube lying on a plane. Indeed, there is no problem to draw all this with the help of the engine functions, and transfer the placement, rotation, and scale parameters from the same Blender, having previously created this scene in it. But let's imagine for a minute a typical game level consisting of hundreds of objects, and it will become sickening.

Therefore, I looked at the plugin with great hope. With it, you can export both a single object and the entire scene (meaning only objects in the scene). And with animation, bones, textures. It looked very tempting. However, in practice, everything was more complicated.

The epic began with an attempt to download only one model. There are no complaints about the work of the exporter in JSON. The code is generated intuitively and complex settings are not there. But to introduce it into the engine was not easy.

API Three.js contains more than a dozen loaders for various objects. Naturally, I chose the universal THREE.JSONLoader. This was facilitated by the official documentation and a large number of lessons that I reviewed. That's just a damn thing it did not work!

 // var loader = new THREE.JSONLoader(); loader.load( "plane.json", createScene1 ); //    function createScene1( geometry, materials ) { mesh = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial( materials ) ); scene.add( mesh ); } 

I experimented with different settings of the exporter, tried other bootloader designs, drawn from lessons on the Internet, alternative functions - the result is zero. The console persistently repeated to me: “Incorrect JSON”, and the screen showed a pristine clean look.

Where do you think the snag was? It is ridiculous to say - in the absence of light. Yes, this is a stupid mistake of a person who is used to working in full-fledged editors. In the same Blender or Unity, removing light sources made it possible to see objects in the scene, right there is a clean program code. But the absence of such a seemingly obvious feature in official tutorials has spoiled a lot of my blood. By the way, the error “Incorrect JSON” has not disappeared. Well, okay, turn to the loading scene.

Actually - this is the most important thing that interested me. Ability to configure and place objects in Blender, overtake them in JSON and manage them in code. An Internet search led me to the THREE.SceneLoader function. Like what you need!

But there is no such function in the official API reference. Further searches on the network brought information that this function was removed as unnecessary. It was a cool bummer ...

The option with the placement of objects in Blender and the transfer of pens to the code I dismissed immediately. The productivity of this approach is questionable. In addition, one would have to take into account the inconsistency between the Blender and Three.js coordinate systems. So I decided to look at the editor proposed by the Three.js developers. It is available at the link on the official site.

So what we have. Launched in the browser, the 3D editor allows you to import models, arrange them and perform customization. Back you can export a separate object, the scene as a JSON and a solid application with a wrapper in HTML. I didn’t study the editor, because I hadn’t found the JSON scene loading function in my project before. In addition, two in the morning signaled that the time allotted for Three.js was clearly over.

The working code of the test application, if anyone is interested. Experimental constructions deleted:

 $(function() { var container,scene,camera,render,cube; init(); render(); function init() { container = document.getElementById( 'webGL-container' ); camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 10000 ); camera.position.z = 10; scene = new THREE.Scene(); light = new THREE.DirectionalLight( 0xffffff ); light.position.set( 0, 0, 1 ).normalize(); scene.add( light ); var loader = new THREE.JSONLoader(); loader.load( "cube.json", createScene1 ); renderer = new THREE.WebGLRenderer( { antialias: true } ); renderer.setPixelRatio( window.devicePixelRatio ); renderer.setSize( window.innerWidth, window.innerHeight ); container.appendChild( renderer.domElement ); } function createScene1( geometry, materials ) { cube = new THREE.Mesh( geometry, new THREE.MeshFaceMaterial( materials ) ); scene.add( cube ); } function render() { requestAnimationFrame( render ); cube.rotation.y +=0.01; //  renderer.render( scene, camera ); } }); 


Work with Blend4Web


I already considered Blend4Web from the point of view of the designer and I was curious about what this platform could offer the programmer. Here, in comparison with Three.js, on the contrary, you are afraid of too close integration with the editor, and thereby reducing the possibility of programming.

Blend4Web offers all the visual work to do in Blender: adjust the scene, create models and arrange them, control physics or particles. Therefore, there is no such problem as with Three.js. But to get a complex application only visual means will not succeed.

The task remains the same - creating a simple scene with several objects, a camera, a light source. Plus simple animation of one object programmatically. And, of course, the time limit is 3 hours. So let's see how easy and complete the documentation will be, working with the API is intuitive. Go…

The official website has clear instructions on the location of the project files in the SDK folders. So Blender projects are stored in the SDK / Blender / ProjectName folder, and the resources and the actual result of the export to SDK / Deploy / Assets / ProjectName. Initially, it looks like snobbery and you do not understand the meaning of such stringent requirements, but over time it comes to why this is necessary.

After installing the SDK, the server automatically rises and becomes available at localhost : 6687. Documentation and examples are offered on the start page, but the main thing is that the server can be used to test your applications.

I created a simple scene in Blender with the above mentioned objects and saved all the data, as required by the SDK help. The first surprise was waiting when trying to export to JSON. In the exporter settings there is a Run in Viewer option and if it is enabled, then after export the result will immediately open in the browser in a special viewer. In it you can finally check your scene and even customize all the parameters of the objects or the environment.

So, the export result is two files: json and bin. The latter contains arrays of data on the models. Now it’s time to create the file being run.

The first question that puzzled me is not how to write, but where to save the scripts and HTML. Since the developers of Blend4Web urge to use certain folders for the project, it would be logical to assume that there is a place for software parts. I did not find confirmation of this and simply created files in the folder with Deploy / Assets / ProjectName.

By tradition, I rendered the executable code in a separate script. In this regard, the HTML wrapper looks like this:

 <!DOCTYPE html> <html> <head> <script type="text/javascript" src="b4w.full.min.js"></script> <script type="text/javascript" src="main.js"></script> <style> body { margin: 0; overflow: hidden; } #container_id { position: absolute; width: 100%; height: 100%; } </style> </head> <body> <div id="container_id"></div> </body> </html> 

There is nothing interesting in HTML, so let's go to main.js. Initialization of the engine and loading the scene is carried out in several stages. First, we connect the necessary modules:

 var app = b4w.require("app"); var data = b4w.require("data"); 

Then we perform initialization:
 app.init({ canvas_container_id: "container_id", physics_enabled: false, autoresize: true, callback: load_cb }); 

By the name of the arguments, I think it is clear what the init function does. After initialization, the load_cb function is called. It can accommodate JSON downloads.

 function load_cb() { data.load("test.json", loaded_cb); } 

The last function in the test script is loaded_cb, which is called after the scene is loaded. This is where the application logic is created.

 function loaded_cb() { //-  //       app.enable_controls(); app.enable_camera_controls(); } 

Loading a scene in Blend4Web was very easy. Everything that I included in Blender - the engine correctly displayed. There are no problems with the placement of objects, the inclusion of shadows, setting meshes, etc. But how about access to individual objects? It is clear that you can make animations in Blender and run them programmatically. I am sure of it, although I did not search. But I need a simple rotation around the axis, according to the principle performed for Three.js (cube.rotation.y + = 0.01).

It turned out to be more difficult than I expected. The Blend4Web API has a function that allows you to call custom procedures every frame, and from this side everything is fine. However, I did not find the possibility of direct rotation along the axes. Only quaternions can be used. In this regard, the code is somewhat cumbersome:

 function render () { var Cube = scene.get_object_by_name("Cube"); var _angle = 0.05; var _vec4; var obj_quat = transform.get_rotation(Cube, _vec4); quat.rotateY(obj_quat, _angle, obj_quat); transform.set_rotation_v(Cube, obj_quat); } 

Small results


I set myself a simple and clear task - to explore the capabilities of both platforms on the example of a standard scene. The conditions were the same, but the result was not unambiguous.

Three.js is a popular library for which a lot of lessons are written, including on Habré. However, the basic functions were created by me with difficulty. Fabulous time spent on the simplest loading model in the scene. Could, probably, in the official tutorial to enter information about the mandatory light sources. Well, at least, for such "cool" programmers like me.

Most importantly, I used to work with comfort and see what I was doing. I need an editor to prepare the scene and are not at all interested in the problems associated with driving the data to the engine. I sat down to make a game, not poking around with broken basic functions. Time is money, and Three.js has taken it away.

The situation with Blend4Web looks much better, but not everything is so brilliant.

The entire preparation of the scene is carried out in a full-fledged editor, and you don’t even think about how the engine will take it all in - this is its task, not the developer. However, problems have arisen related to direct programming.

Much time was spent on the initial reading of the documentation on the part of working with the SDK. I still wanted to do what the developers advise. For example, they suggest using a special Python script to build a complete application. With it, you can pack data, collect scattered files in a heap, etc. It looked tempting, but I did not. Popped up errors in the Python script, which I did not even consider.

The Three.js documentation is replete with many small examples. Unfortunately, for Blend4Web there are none. So you had to scroll through the lessons and watch extensive listings. Took a little from one page, a little more from another. As a result, I wrote code that could successfully be already in the examples of the SDK documentation. Yes, there is such an application in the SDK - Code Snippets , demonstrating the various possibilities of the platform with the source code. But I would like to just small and simple examples. How to move the object, how to rotate the model, how to link the execution of the function to the frame update, etc. So, to rotate the object, I took a piece of code from the example of the game on the official site. But maybe there is a more optimal rotation option than through direct change of quaternions? In the end, I used only what I found.

Still, you feel more comfortable with Blend4Web. This platform is much more user friendly than the considered opponent.

Scene Three.js
Blend4Web Scene

Source: https://habr.com/ru/post/262749/


All Articles