📜 ⬆️ ⬇️

Experiment platform for Three.JS and WebGL

If you do not play and do not consider the photos of familiar girls in contact, then programming is my favorite pastime at the computer. I especially like “fast” programming. It is such programming when the project is small and when we are not engaged in fundamental research, and planning does not need documentation. By the way, at work all the projects are not the same, but also focused on a closed audience. This is basically why you are reading my article now, and I also want to get on Habr.

I want to share with you the results of my weekend project. This is a pure client javascript / html application, which consists of a source editor in Javascript and GLSL shaders, a mini-linker, a window with Three.JS / WebGL and a small runtime interface. All this is glued to jquery, and the gallery with the video is screwed over it. The gallery features several demonstrations. You can select your favorite demonstration and play with its code, as well as export and import entire projects from several files via JSON.

The code for each demonstration can be located in several files. These files are loaded with ajax and are immediately stored in local storage where they can be edited, new ones added and deleted. Again, the application is purely client. File api is used to add files to local storage. You can add only text files, because with the volume of local storage you will not clear up when storing base64-representations of binary files.

I will not give a link to a working application, because I do not have my own normal hosting. It remains only to download the source and host them on your web server. The web server is still needed, because recently for WebGL loading textures from the local file system has been banned.
')
All sources are available on Bitbucket in the Mercurial system: https://bitbucket.org/Bangybug/treejsplayground , you can also download the Zip-archive there.

There is still a short video to interest you:

If you are interested and decided to download the source code, then I consider it a duty to warn you that it normally works only on Chrome (I have 21.0.1180.60). In Firefox (I have 14.0.1), WebGL is now disabled, and to enable it, you need to type in about: config in the address bar, then install a filter on the webgl, set force-enabled = true and disabled = false . But this is not the end of the Firefox sorrow - read below about the Gallery.

How it all began and what it turned into


First there was the need to write a shader. I do not have much experience in this matter, so the plans were to ask my virtual friends for advice. I also wanted to make their work a bit easier by showing my prototype right away, without having to install anything, but with the ability to make changes on the fly and observe the result.

Conceived - done, the choice immediately fell on WebGL. I didn’t want to build my bike out of the function calls of WebGL itself, since the library Three.JS turned out well. Then the thought flashed that it would be nice to choose an editor with backlight instead of textarea. The choice fell on ACE . It seemed to me to be quite high quality, it works with large files, supports code folding , analyzes the code and can tell where the error is, or how to do it better.

Then I wanted to make a similarity to the project manager, which would include a list of files and could delete and add files at the discretion of the client. I really didn’t want to communicate with the server code, there was a way out - Html5 innovations: File API and Local Storage , at the same time to see what and how.

After the project manager with the list of files was ready, the need for a linker for the source files was automatically generated. An elementary linker was written, which, using the eval function, traverses all files. If in some of the source code the functionality of another is required, to which the linker has not yet reached, then it is enough to call the special function of the linker APP.require . In this case, the linker will not go through the previously connected files.

Without meeting any problems, I decided to continue the lesson. Interest has shifted to other Html5 innovations in the field of CSS and visual effects. I wanted to make a video gallery, where each video would be shown with some CSS effect. There are already difficulties. It is written about them further.

The final step was to separate the shader code into a separate type of source. When editing shaders, the editor switched to the grammar of the C language. This turned out to be convenient, because otherwise you would have to store the shader code either inside Javascript or inside Html.

Compilation of project files and minimal runtime interface


As already noted, there is an elemental linker. It is in the app / linker.js file . It has a require function, which is available from source as APP.require . This function should be called in order to ensure that the compiled source code is connected in the correct order. An example of use is a demonstration of “Brothers in arms” (see gallery).

There is also a minimal runtime interface, which consists of such objects:


This is the minimum runtime that is provided for client sources. In turn, the client’s source code must define the main and exit functions. These functions are responsible for starting and stopping the demonstration. It is recommended to clear resources inside exit.

Experiments with video gallery


Here I have comprehended difficulties. Firstly, border-radius in Chrome does not apply to the video element. More precisely, it applies only to the image that is used as poster. As soon as the video starts playing, the rounds disappear. Box-reflection style works only in webkit.

Firefox has problems with the layout, and that is very sad, with the very idea of ​​a video gallery. You can't just take and stick even 4-5 video elements, even if only one of them will play when you hover the cursor. Firefox sends a lot of requests, it curls the page and even my local Apache httpd. It is necessary to close the browser.

In Chrome, there are no problems with hanging, although there is still something to meditate on looking at memory consumption.

As a result, simply added a parameter to the file app / gallery.js / initialize - useImages . When you set it to true, instead of the video will be pictures.

Shader Compilation


To compile shaders, I added the APP.shader function, it is described above. Just to clarify that the code from Three.JS is used here. This code will automatically set an attribute with the name “position” in your vertex shader. Keep this in mind, do not try to write a shader with a different name for this attribute. There is an alternative - to rewrite the app / webgl.js / shader function, but at the same time you will lose the ability to use the Three.JS drawing tool.

Comparison with sample code on “clean” WebGL


It goes without saying that the code will be much less on Three.JS. And if you use my playground, the code will still decrease. The only obstacle is the need to understand how WebGL functions are wrapped in the Three.JS library. For example, the mode of sending vertex data TRIANGLE_STRIP in Three.JS corresponds to the THREE.Ribbon object.

For comparison, open directories with an identical project: / defaults / sources / water and / defaults / sources / water_webgl . So you can get an idea of ​​the differences when using pure WebGL and Three.JS.

Preparing a new demonstration and inserting it into the project


All demonstrations are described in app / gallery.js / projects . A typical description looks like this:
'spheres' : { files : [{type:'source', path:'defaults/sources/spheres/main.js', content:null}], category : 'Basic', title : 'Many ballz', image : 'defaults/sources/spheres/img.png', video : 'defaults/sources/spheres/video.ogv', description: 'Basic demo from Three.JS package, creates 50k spheres with different materials. Demonstrates on-the-fly texture generation.' } 

I used the free Camstudio program to record videos. From it you need to get a video in the size of 320x200. To do this, you can pre-set the size of the window 320x200 in webgl.css , and in Camstudio itself set up video removal from this area. Also help hotkeys, they eliminate the need to edit the video. I recommend to immediately select the directory where the video files will be added. Preferably not root.

In order for the video to be embedded in the video element, you will have to convert it to OGG Theora. I used FFMpeg2Theora .

Using parameters in url


For convenience, it is possible to use the parameters in the url. For example, to show a gallery, it’s enough to add the following to the address :? Gallery = category , where category is the category of the demonstrations (see the description of the demonstration).

You can immediately redirect to the desired project by adding ? Project = project_id , where project_id is the key in app / gallery.js / projects , for example spheres .

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


All Articles