手工编写asm.js
writing asm.js by hand
我正在尝试将asm.js注释添加到perlin单纯形噪声函数:
"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 banksean@gmail.com
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错误控制台只显示:
警告:TypeError:asm.js类型错误:asm.js必须以返回结尾export语句源文件:perlin_simplex.js线路:9
我已经搜索了关于错误可能是什么的帮助,但只找到了https://github.com/zbjornson/human-asmjs这通常是非常有用的,但在这种特定情况下没有帮助。
我做错了什么?这个perlin噪声函数怎么会被人模仿?
问题出在以下行:
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;
在asm.js模块的顶级作用域中只允许声明。不允许在顶级作用域中定义变量。
根据规范,您只能将文字值分配给全局变量(以及其他导入语句)。因此,您也不能执行以下操作,因为F2
、F3
、G2
和G3
没有被分配文字值:
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;
因此,您需要将F2
、F3
、G2
和G3
的定义移动到一个函数中(可能是init
函数)。因此,您的代码应该看起来像:
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确实告诉了你这个问题,但他们给了你一个数组的例子,而不是一个简单的变量:
请注意,这些类型化数组不能在函数之外进行修改:
function MyModule(stdlib, foreign, heap) {
var arr = new stdlib.Int8Array(heap);
arr[0] = 1; // "asm.js must end with a return export statement"
// ...
}
相反,可以这样做:
function MyModule(stdlib, foreign, heap) {
var arr = new stdlib.Int8Array(heap);
function init() {
arr[0] = 1;
}
return {
init: init
};
}
给你。asm.js不是很痛苦吗?
相关文章:
- 可以't让我的if语句处理js中的html表单输入
- 使用agility.js进行页面布局和合成
- asm.js如何处理除以零
- 如何检查Firefox是否使用asm.js代码
- 有没有一种方法可以验证asm.js代码
- Emscripten似乎不使用asm.js
- Emscripten 编译C++ 到 JavaScript 和 Asm.js 的结果很糟糕
- ASM.js 类型错误:比较的参数必须同时是有符号、无符号或双精度
- 在普通javascript中插入ASM.JS代码
- 手工编写asm.js
- 当asm.js比普通JS代码快的时候,我为什么要用JS写新代码呢?
- Asm.js对编译器的限制
- 为什么asm.js会降低性能
- 了解Emscripten/ASM.js和浏览器沙盒
- 可以将常规的JavaScript转换为asm.js吗,还是只是为了加速静态类型的低级语言?
- asm.js模块.调用/模块.cwrap回调
- asm.js和WebAssembly的区别是什么?
- TypeError: asm.js类型错误:被调试器禁用
- 为什么asm.js项目在Chrome中的运行速度比FireFox快
- 如何使用asm.js进行测试和开发