01
Artykuł poświęcony jest eksportowaniu modeli (stworzonych w programie blender) do formatu JSON i ładowaniu ich w WebGL. Zrobimy również mały porządek z shaderami, które wrzucimy do osobnych plików, co daje lepszą czytelność i pozwala chociażby na kolorowanie składni, jeśli mamy edytor, który rozpoznaje GLSL.
Lekcja ta jest modyfikacją poprzedniej lekcji. Efekt końcowy na rysunku poniżej lub na żywo tutaj.

JSON (JavaScript Object Notation) jest czytelnym i intuicyjnym formatem, który ma swoje korzenie w JavaScript (więcej możecie doczytać na wikipedii). JavaScript posiada wbudowany obiekt globalny JSON, który potrafi parsować ten format. Poniżej mamy zawartość pliku „file_functions.js”
// Zwraca zawartosc pliku tekstowego
var getSourceSynch = function(url) {
var req = new XMLHttpRequest();
req.open("GET", url, false);
req.send(null);
return (req.status === 200) ? req.responseText : null;
};
// Zwraca obiekt zawarty w pliku .json
var loadJSON = function(url) {
return JSON.parse(getSourceSynch(url));
};
Pierwsza z funkcji, używając obiektu XMLHttpRequest, czyta zawartość pliku synchronicznie (więcej tu XMLHttpRequest), natomiast druga (loadJSON) zamienia zawartość pliku w obiekt JavaScript. Rozdzieliliśmy te dwie funkcje, gdyż pierwszej z użyjemy dodatkowo do ładowania shaderów z osobnego pliku (po prostu skopiowaliśmy shadery z pliku html i zapisaliśmy je osobno do plików „shaders/vertex.shdr” oraz „shaders/fragment.shdr”). Modyfikacja funkcji getShader wygląda teraz tak:
function getShader(gl, type, path){
var shader = gl.createShader(type);
gl.shaderSource(shader, getSourceSynch(path));
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
alert(gl.getShaderInfoLog(shader));
return null;
}
return shader;
}
– przyjmuje ona parametry: kontekst graficzny, typ shadera (gl.VERTEX_SHADERS lub gl.FRAGMENT_SHADER) oraz ścieżka do pliku z shaderem. Jest wywoływana więc dwukrotnie w funkcji initShaders:
function initShaders(){
var fragmentShader = getShader(gl, gl.FRAGMENT_SHADER, "shaders/fragment.shdr");
var vertexShader = getShader(gl, gl.VERTEX_SHADER, "shaders/vertex.shdr");
shaderProgram = gl.createProgram();
gl.attachShader(shaderProgram, vertexShader);
gl.attachShader(shaderProgram, fragmentShader);
...
Mając plik json (eksportowanie z blendera omówione jest niżej) z danymi modelu (koordynatami wierzchołków, wektorami normalnymi, koordynatami tekstur oraz indeksami wierzchołków) ładujemy go teraz w następujący sposób:
function g_Init()
{
var monkeyData = loadJSON("objects/monkey.json");
Sphere.init("textures/monkey.png", 0, 0,
monkeyData.vertices, monkeyData.texCoords, monkeyData.indices, monkeyData.normals);
}
Z racji, że WebGL czyta odwrotnie obrazki (do góry nogami), w funkcji ładującej teksturę włączymy specjalną opcję przywracającą „normalność”:
tempImage.onload = function()
{
gl.bindTexture(gl.TEXTURE_2D, that.Texture);
gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, true);
...
Uwaga! Przeglądarka chrome / chromium, z powodów bezpieczeństwa, ma domyślnie wyłączoną możliwość ładowania plików z lokalnego dysku. Oznacza to, że w czasie testów na lokalnym komputerze będzie zgłaszał błąd (gdy umieścimy naszą aplikację na serwerze wliczając w to lokalny serwer http, wszystko będzie działać). Aby wyłączyć tą funkcję na czas testowania, należy dodać jako parametr uruchamiania przeglądarki(we właściwościach skrótu) –allow-file-access-from-files
Oprócz opisanego tutaj eksportera, znalazłem w sieci jeszcze dwa inne:
Aby użyć skrypu:
W razie pytań lub zgłoszeń błedów, czy propozycji poprawek, piszcie na naszym forum w tym temacie
Additionaly to the one described here, I found 2 others:
To use our exporter script:
If you found some bugs, have questions or improvement advice just drop me e-mail biegunka(at)op(dot)pl or post in this thread
Jak ktoś ma Win7 to skrypty wrzucamy do:
C:\Users\USER_NAME\AppData\Roaming\Blender Foundation\Blender\.blender\scripts
[...] not tried this Blender WebGL export module, but it looks promising (the article is in Polish first, English translation [...]
I have several exported by Blender models and a note at
http://www.ibiblio.org/e-notes/webgl/webgl.htm
What is the most compact file format for Web (e.g. are binary data compressed efficiently)?
I haven’t heard about real compact files which can be easily (and fast) used by JavaScript. I’m not web expert but AFAIK JSON format is the most efficient format for external files in web world (JavaScript engine (using its JSON global object) parses .json file much faster than C++)
[...] This post was mentioned on Twitter by nakamura001 and nyamadan, Brendon Smith. Brendon Smith said: Blender -> JSON Exporter #webGL: http://bit.ly/g8EwOi [...]
Hello.
I am making blender exporter for WebGL,too.
https://sites.google.com/site/hackthewebgl/blender-exporter
To my regret,this site which explains how to use was written only in Japanese.
The demonstration that uses the exported model has been opened to the public.
https://sites.google.com/site/hackthewebgl/how-to/blender-modelhyouji
(I checked only chrome.)
Let’s hold out mutually.
vest regards.
(sorry,poor english)
Thanks for the script and the tutorial, works well!
Thank for that tutorial.
It is really good to see.
But I get some trouble that when I try to convert a big model. The Blender work well with smaller model but it stop working with the bigger.
So, Help me please.
What error do you get in the console?
check if the mesh has more than 65000 vertices,this might be your problem