闪电效果
最近要用到两个电极间的放电效果,记得AS3有一个现成的类,想拿过来直接用。
关于as3版本的类库,中文介绍:
https://www.cnblogs.com/chenhongyu/archive/2013/09/13/3318642.html
源网站:
http://blog.oaxoa.com/2009/07/27/actionscript-3-as3-lightning-thunderbolt-electric-discharge-class/
源码下载下来看看,虽然没有注释,还好文件不是特别大,就一个类。
实现过程用到了柏林噪声。
顺便学习一下柏林噪声。
关于柏林噪声,参考:
http://blog.csdn.net/mahabharata_/article/details/54743672
http://www.cnblogs.com/Memo/archive/2008/09/08/1286963.html
http://blog.sina.com.cn/s/blog_68f6e8a901013t7d.html
http://www.cnblogs.com/babyrender/archive/2008/10/27/BabyRender.html
http://www.jianshu.com/p/27e29d50116b
http://blog.csdn.net/ZJU_fish1996/article/details/71136348
http://mrl.nyu.edu/~perlin/doc/oscar.html#noise
http://gad.qq.com/article/detail/19340
Ken Perlin的源代码:
http://mrl.nyu.edu/~perlin/noise/
闪电效果:
关于柏林噪声,这里有个js的代码,可以直接运行:http://jsfiddle.net/GZCye/
试着改写了一个,感觉有问题,还是不知道flash里边的是怎么实现的。
<canvas id="canvas" width="512" height="512"></canvas>
<script>
//==============================
//http://jsfiddle.net/GZCye/
function Noise( x, y )
{
var seed = ( x << 18 ) | ( y << 4 ) | 49734321;
// Robert Jenkins' 32 bit integer hash function.
// See http://www.concentric.net/~ttwang/tech/inthash.htm (original)
// and http://stackoverflow.com/questions/3428136/javascript-integer-math-incorrect-results/3428186#3428186 (JavaScript version)
seed = ((seed + 0x7ed55d16) + (seed << 12)) & 0xffffffff;
seed = ((seed ^ 0xc761c23c) ^ (seed >>> 19)) & 0xffffffff;
seed = ((seed + 0x165667b1) + (seed << 5)) & 0xffffffff;
seed = ((seed + 0xd3a2646c) ^ (seed << 9)) & 0xffffffff;
seed = ((seed + 0xfd7046c5) + (seed << 3)) & 0xffffffff;
seed = ((seed ^ 0xb55a4f09) ^ (seed >>> 16)) & 0xffffffff;
return (seed & 0xfffffff) / 0x10000000;
}
function SmoothedNoise( x, y )
{
var corners = ( Noise( x - 1, y - 1 ) + Noise( x + 1, y - 1 ) + Noise( x - 1, y + 1 ) + Noise( x + 1, y + 1 ) ) / 16;
var sides = ( Noise( x - 1, y ) + Noise( x + 1, y ) + Noise( x, y - 1 ) + Noise( x, y + 1 ) ) / 8;
var center = Noise( x, y ) / 4;
return corners + sides + center;
}
function Interpolate( a, b, x )
{
var ft = x * Math.PI;
var f = ( 1.0 - Math.cos( ft ) ) * 0.5;
return ( a * ( 1.0 - f ) ) + ( b * f );
}
function InterpolatedNoise( x, y )
{
var x_int = Math.floor( x );
var x_fractional = x - x_int;
var y_int = Math.floor( y );
var y_fractional = y - y_int;
var v1 = SmoothedNoise( x_int, y_int );
var v2 = SmoothedNoise( x_int + 1, y_int );
var v3 = SmoothedNoise( x_int, y_int + 1 );
var v4 = SmoothedNoise( x_int + 1, y_int + 1 );
var i1 = Interpolate( v1, v2, x_fractional );
var i2 = Interpolate( v3, v4, x_fractional );
return Interpolate( i1, i2, y_fractional );
}
function Noise2D( x, y, octaves, persistence )
{
var total = 0;
for ( var octave = 0; octave < octaves; ++octave )
{
var frequency = Math.pow( 2, octave );
var amplitude = Math.pow( persistence, octave );
total += InterpolatedNoise( x * frequency, y * frequency, octave ) * amplitude;
}
return total;
}
//========================================
//http://mrl.nyu.edu/~perlin/noise/
function noise0(x,y) {
let n = x + y *57;
n = (n << 13) ^ n;
return ( 1.0 - ( (n * (n * n * 15731 + 789221) + 1376312589) & 0x7fffffff) / 1073741824.0);
}
function noise(x, y) {
var X = Math.floor(x) & 255, // FIND UNIT CUBE THAT
Y = Math.floor(y) & 255; // CONTAINS POINT.
x -= Math.floor(x); // FIND RELATIVE X,Y,Z
y -= Math.floor(y); // OF POINT IN CUBE.
var u = fade(x), // COMPUTE FADE CURVES
v = fade(y); // FOR EACH OF X,Y,Z.
var g0 = p[p[X]+Y];
var g1 = p[p[X]+Y+1];
var g2 = p[p[X+1]+Y];
var g3 = p[p[X+1]+Y+1];
var grad0 = grad(g0, x, y);
var grad1 = grad(g1, x, y-1);
var grad2 = grad(g2, x-1, y);
var grad3 = grad(g3, x-1, y-1);
return lerp(v, lerp(u,grad0,grad2),lerp(u,grad1,grad3));
}
function fade(t) {
return t * t * t * (t * (t * 6 - 15) + 10);
}
function lerp(t, a, b) {
return a + t * (b - a);
}
function grad(hash, x, y) {
switch(hash & 0x3){
case 0x0: return x;
case 0x1: return -x;
case 0x2: return y;
case 0x3: return -y;
default: return 0; // never happens
}
}
var p = [], permutation = [151,160,137,91,90,15,
131,13,201,95,96,53,194,233,7,225,140,36,103,30,69,142,8,99,37,240,21,10,23,
190, 6,148,247,120,234,75,0,26,197,62,94,252,219,203,117,35,11,32,57,177,33,
88,237,149,56,87,174,20,125,136,171,168, 68,175,74,165,71,134,139,48,27,166,
77,146,158,231,83,111,229,122,60,211,133,230,220,105,92,41,55,46,245,40,244,
102,143,54, 65,25,63,161, 1,216,80,73,209,76,132,187,208, 89,18,169,200,196,
135,130,116,188,159,86,164,100,109,198,173,186, 3,64,52,217,226,250,124,123,
5,202,38,147,118,126,255,82,85,212,207,206,59,227,47,16,58,17,182,189,28,42,
223,183,170,213,119,248,152, 2,44,154,163, 70,221,153,101,155,167, 43,172,9,
129,22,39,253, 19,98,108,110,79,113,224,232,178,185, 112,104,218,246,97,228,
251,34,242,193,238,210,144,12,191,179,162,241, 81,51,145,235,249,14,239,107,
49,192,214, 31,181,199,106,157,184, 84,204,176,115,121,50,45,127, 4,150,254,
138,236,205,93,222,114,67,29,24,72,243,141,128,195,78,66,215,61,156,180
];
for (var i=0; i < 256 ; i++) p[256+i] = p[i] = permutation[i];
function OctavePerlin(x, y, octaves, persistence) {
var total = 0;
var frequency = 1;
var amplitude = 1;
var maxValue = 0; // Used for normalizing result to 0.0 - 1.0
for(var i=0;i<octaves;i++) {
total += noise(x * frequency, y * frequency) * amplitude;
maxValue += amplitude;
amplitude *= persistence;
frequency *= 2;
}
return total/maxValue;
}
//=====================================
var context = document.getElementById("canvas").getContext("2d");
var imageData = context.getImageData(0, 0, 512, 512);
for(var y = 0; y < imageData.height; y++) {
for(var x = 0; x < imageData.width; x++) {
//var color = Math.round(perlin[x][y] * 255);
//var color = Noise2D(x, y, 8, 0.5) * 128; //PerlinNoise_2D
//var color = noise(x/50,y/50)*255;
var color = OctavePerlin(x/128,y/128, 8 ,0.5)*255;
var index = ((y * imageData.width) + x) * 4;
imageData.data[index + 0] = color;
imageData.data[index + 1] = color;
imageData.data[index + 2] = color;
imageData.data[index + 3] = 255;
}
}
console.log(imageData);
context.putImageData(imageData, 0, 0);
</script>
