2013-07-21 35 views
13

Tôi cố gắng để thêm chú thích asm.js đến Perlin chức năng tiếng ồn simplex:viết asm.js bằng tay

"use strict"; 

// Ported from Stefan Gustavson's java implementation 
// http://staffwww.itn.liu.se/~stegu/simplexnoise/simplexnoise.pdf 
// Read Stefan's excellent paper for details on how this code works. 
// 
// Sean McCullough [email protected] 

function SimplexNoise(stdlib,foreign,heap) { 
    "use asm"; 
    // heap should be at least 1024*4+12*3*4 bytes long 
    var floor = stdlib.Math.floor, 
     sqrt = stdlib.Math.sqrt, 
     random = new stdlib.Float32Array(heap), 
     buf = new stdlib.Int32Array(heap), 
     F2 = 0.0, F3 = 0.0, 
     G2 = 0.0, G3 = 0.0; 
    F2 = (sqrt(3.0)-1.0)*0.5; F3 = 1.0/3.0; 
    G2 = (3.0-sqrt(3.0))/6.0; G3 = 1.0/6.0; 
    function init() { 
     // before calling this function, set the first 256 floats in the heap to be random numbers between 0..1 
     // the heap gets rewritten, but if you record the IV separately, the noise is reproducable 
     for(var i=0; i<256; i++) { 
      buf[i] = buf[i+256] = floor(random[i]*256.0) & 0xff; 
      buf[i+512] = buf[i+512+256] = (buf[i] % 12) * 3 + 1024; 
     } 
     i = 1024; 
     buf[i++] = 1; buf[i++] = 1; buf[i++] = 0; 
     buf[i++] = -1; buf[i++] = 1; buf[i++] = 0; 
     buf[i++] = 1; buf[i++] = -1; buf[i++] = 0; 
     buf[i++] = -1; buf[i++] = -1; buf[i++] = 0; 
     buf[i++] = 1; buf[i++] = 0; buf[i++] = 1; 
     buf[i++] = -1; buf[i++] = 0; buf[i++] = 1; 
     buf[i++] = 1; buf[i++] = 0; buf[i++] = -1; 
     buf[i++] = -1; buf[i++] = 0; buf[i++] = -1; 
     buf[i++] = 0; buf[i++] = 1; buf[i++] = 1; 
     buf[i++] = 0; buf[i++] = -1; buf[i++] = 1; 
     buf[i++] = 0; buf[i++] = 1; buf[i++] = -1; 
     buf[i++] = 0; buf[i++] = -1; buf[i++] = -1; 
    } 
    function noise2D(xin,yin) { 
     xin = +xin; yin = +yin; 
     var s = 0.0, i = 0, j = 0, 
      t = 0.0, 
      X0 = 0.0, Y0 = 0.0, 
      x0 = 0.0, y0 = 0.0, 
      i1 = 0, j1 = 0, 
      x1 = 0.0, y1 = 0.0, 
      x2 = 0.0, y2 = 0.0, 
      ii = 0, jj = 0, 
      gi0 = 0, gi1 = 0, gi2 = 0, 
      t0 = 0.0, t1 = 0.0, t2 = 0.0, 
      n0 = 0.0, n1 = 0.0, n2 = 0.0; 
     // Skew the input space to determine which simplex cell we're in 
     s = (xin+yin)*F2; // Hairy factor for 2D 
     i = floor(xin+s); j = floor(yin+s); 
     t = (i+j)*G2; 
     X0 = i-t; Y0 = j-t; // Unskew the cell origin back to (x;y) space 
     x0 = xin-X0; y0 = yin-Y0; // The x;y distances from the cell origin 
     // For the 2D case; the simplex shape is an equilateral triangle. 
     // Determine which simplex we are in. 
     i1 = (x0>y0?1:0); j1 = (x0>y0?0:1); // Offsets for second (middle) corner of simplex in (i;j) coords 
     // A step of (1;0) in (i;j) means a step of (1-c;-c) in (x;y); and 
     // a step of (0;1) in (i;j) means a step of (-c;1-c) in (x;y); where 
     // c = (3-sqrt(3))/6 
     x1 = x0-i1+G2; y1 = y0-j1+G2; // Offsets for middle corner in (x;y) unskewed coords 
     x2 = x0-1+2*G2; y2 = y0-1+2*G2; // Offsets for last corner in (x;y) unskewed coords 
     // Work out the hashed gradient indices of the three simplex corners 
     ii = i & 255; jj = j & 255; 
     gi0 = buf[ii+buf[jj]+512]; 
     gi1 = buf[ii+i1+buf[jj+j1]+512]; 
     gi2 = buf[ii+1+buf[jj+1]+512]; 
     // Calculate the contribution from the three corners 
     t0 = 0.5-x0*x0-y0*y0; t1 = 0.5-x1*x1-y1*y1; t2 = 0.5-x2*x2-y2*y2; 
     n0 = t0<0.0? 0.0: t0*t0*t0*t0*(buf[gi0]*x0+buf[gi0+1]*y0); // (x;y) of buf used for 2D gradient 
     n1 = t1<0.0? 0.0: t1*t1*t1*t1*(buf[gi1]*x1+buf[gi1+1]*y1); 
     n2 = t2<0.0? 0.0: t2*t2*t2*t2*(buf[gi2]*x2+buf[gi2+1]*y2); 
     // Add contributions from each corner to get the final noise value. 
     // The result is scaled to return values in the interval [-1,1]. 
     return 70.0 * (n0 + n1 + n2); 
    } 
    return { 
     init: init, 
     noise2D: noise2D 
    }; 
}; 

Firefox Javascript lỗi giao diện điều khiển được chỉ nói:

Warning: TypeError: asm.js type error: asm.js must end with a return export statement Source File: perlin_simplex.js Line: 9

Tôi có tìm kiếm sự giúp đỡ về những lỗi có thể và chỉ tìm thấy https://github.com/zbjornson/human-asmjs mà nói chung là rất hữu ích, nhưng không giúp đỡ trong trường hợp cụ thể này.

Tôi đã làm gì sai? Làm thế nào có thể chức năng tiếng ồn perlin này được asm.js-ised bởi một con người?

+0

Mã hóa asm.js? Bạn là gì: thiên tài hay điên rồ ?! –

Trả lời

13

Vấn đề là với những dòng sau:

F2 = (sqrt(3.0)-1.0)*0.5; F3 = 1.0/3.0; 
G2 = (3.0-sqrt(3.0))/6.0; G3 = 1.0/6.0; 

Chỉ tờ khai được cho phép trong phạm vi cấp cao nhất của một mô-đun asm.js. Bạn không được phép xác định biến trong phạm vi cấp cao nhất.

Theo spec bạn chỉ có thể gán giá trị bằng chữ cho các biến toàn cầu (trong số các báo cáo nhập khác). Do đó bạn không thể làm hoặc vì F2 giá trị theo nghĩa đen, F3, G2G3 không được phân công như sau:

var floor = stdlib.Math.floor, 
    sqrt = stdlib.Math.sqrt, 
    random = new stdlib.Float32Array(heap), 
    buf = new stdlib.Int32Array(heap), 
    F2 = (sqrt(3.0)-1.0)*0.5, F3 = 1.0/3.0, 
    G2 = (3.0-sqrt(3.0))/6.0, G3 = 1.0/6.0; 

Do đó bạn sẽ cần phải di chuyển các định nghĩa của F2, F3, G2G3 vào một chức năng (có lẽ là chức năng init). Như vậy mã của bạn sẽ giống như thế:

function SimplexNoise(stdlib,foreign,heap) { 
    "use asm"; 

    var floor = stdlib.Math.floor, 
     sqrt = stdlib.Math.sqrt, 
     random = new stdlib.Float32Array(heap), 
     buf = new stdlib.Int32Array(heap), 
     F2 = 0.0, F3 = 0.0, 
     G2 = 0.0, G3 = 0.0; 

    function init() { 
     F2 = (sqrt(3.0)-1.0)*0.5; F3 = 1.0/3.0; 
     G2 = (3.0-sqrt(3.0))/6.0; G3 = 1.0/6.0; 
     // rest of init 
    } 

    function noise2D(xin,yin) { 
     // function body 
    } 

    return { 
     init: init, 
     noise2D: noise2D 
    }; 
}; 

asm.js Nhân không nói với bạn về vấn đề này, nhưng họ cung cấp cho bạn những ví dụ về một mảng thay vì một biến đơn giản:

Note that these typed arrays cannot be modified outside of a function:

function MyModule(stdlib, foreign, heap) { 
    var arr = new stdlib.Int8Array(heap); 
    arr[0] = 1; // "asm.js must end with a return export statement" 
    // ... 
} 

Instead do something like this:

function MyModule(stdlib, foreign, heap) { 
    var arr = new stdlib.Int8Array(heap); 
    function init() { 
    arr[0] = 1; 
    } 

    return { 
    init: init 
    }; 
} 

Có bạn. Chẳng phải asm.js là một nỗi đau lớn sao?

+1

Thực ra đây là vấn đề. asm.js thực sự là một nỗi đau lớn, nhưng chủ yếu là do báo cáo lỗi kém. Nó sẽ được tốt đẹp để có thể chia sẻ các chức năng tiếng ồn nhanh của tôi khi tôi nhận được chúng được nhanh chóng, mặc dù. – Will

Các vấn đề liên quan