|
|
|||||
Регистрация: Jun 2014
Сообщений: 558
|
эффект высыхающей капли
Добрый день. Вопрос, мне нужно создать эффект, как будто капля впитывается и высыхает. Есть что нибудь, чего можно добиться с помощью кода(не клипать кадры в фотошопе)? Просто изменение размера и альфы маловато будет, хочу что бы сначала высыхали края, двигаясь к центру, возможно ли такой сделать эффект?
|
|
|||||
Теоретически я представляю это так - находите края и постепенно прибавляете атрибуты цвета процентной части дельты между свежей и высохшей каплей, и постепенно капля должна "высохнуть" полностью.(это при условии, что высохшая и свежая капли одного размера).
Радиус высыхания также укажите, и чем ближе к краю, тем больше прибавляйте. Добавлено через 1 минуту Я не мастер шейдеринга, но предполагаю, что язык PixelBender должен работать быстрее стандартных функций работы с пикселами во много раз
__________________
There is no thing in this world that is not simple. |
|
|||||
Регистрация: Jun 2013
Адрес: Воронеж
Сообщений: 101
|
Вот так можно, например:
package { import flash.display.Sprite; public class Drop extends Sprite { private var drop_parts:Vector.<Sprite> = null; private var drop_part:Sprite = null; public var is_gone:Boolean = false; public static const COUNT:int = 10; public function Drop() { drop_parts = new <Sprite>[]; for ( var i:int = 0; i < COUNT; i++ ) { drop_part = new DropClip(); drop_part.alpha = 1 / COUNT; drop_parts.push( drop_part ); this.addChild( drop_part ); } } public function updateDrop():void { for ( var i:int = COUNT - 1; i >= 0; i-- ) { drop_part = drop_parts[ i ]; drop_part.scaleX = drop_part.scaleY *= Math.pow( 0.95, 0.5 * ( i * 0.25 + 1 ) ); } if ( drop_part.scaleX < 0.01 ) { is_gone = true; } } } } import flash.display.Sprite; import flash.display.Shape; import flash.events.Event; var drop:Drop = null; createDrop(); this.addEventListener( Event.ENTER_FRAME, update ); function createDrop() { drop = new Drop(); drop.x = 275; drop.y = 200; this.addChild( drop ); } function update( e:Event ):void { drop.updateDrop(); if ( drop.is_gone ) { this.removeChild( drop ); createDrop(); } }
__________________
В лесу родилась ёлочка, в лесу она росла! Зимой и летом... |
|
|||||
вот такой алгоритм у меня нашелся, может сгодится на что
package { import flash.display.Bitmap; import flash.display.BitmapData; import flash.display.Sprite; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.events.Event; import flash.filters.BlurFilter; import flash.geom.Matrix; import flash.geom.Point; public class Main extends Sprite { [Embed(source = "bg.png")] public static const bg_png:Class; private var src:BitmapData = (new bg_png() as Bitmap).bitmapData; private var bmd:BitmapData = new BitmapData(src.width, src.height); private var bmp:Bitmap = new Bitmap(bmd); private var size:Number = 100; private var coef:Number = 1.25; private var tX:Number = 100; private var tY:Number = 100; public function Main():void { stage.scaleMode = StageScaleMode.NO_SCALE; stage.align = StageAlign.TOP_LEFT; addChild(bmp); this.addEventListener(Event.ENTER_FRAME, this_enterFrame); } //=======================================// private function this_enterFrame(e:Event):void { bmd.copyPixels(src, bmd.rect, new Point()); size-= 1; coef *= 0.99; if (size > 0) { drawDrop(bmd, tX, tY, size, 2, coef, true); }else { size = 100; coef = 1.25; tX = 50 + Math.random() * 150; tY = 50 + Math.random() * 150; //this.removeEventListener(Event.ENTER_FRAME, this_enterFrame); } } //====================================// public static function drawDrop(src:BitmapData, dropX:int, dropY:int, dropSize:int = 20, blurVal:int = 2, coeff:Number = 2, append:Boolean=false):BitmapData { if (dropSize <= 0) return null; if (coeff <= 0) coeff = 1; dropSize += dropSize % 2; var w1:int, h1:int;// , w2:int, h2:int; var halfSize:int = dropSize / 2; var radius:Number, oldRadius:Number, angle:Number, div:Number; var res:BitmapData = new BitmapData(dropSize + 2 * blurVal, dropSize + 2 * blurVal, true, 0x0); div = halfSize / Math.log( coeff * halfSize + 1); for ( var h:int = -halfSize; h <= halfSize; ++h ) { for ( var w:int = -halfSize; w <= halfSize; ++w ) { radius = Math.sqrt( h * h + w * w ); angle = Math.atan2( h, w ); if ( radius <= halfSize ) { oldRadius = radius; radius = (Math.exp(radius/div)-1)/coeff; w1 = radius * Math.cos(angle);// + dropX; h1 = radius * Math.sin(angle); // подсветка в зависимости от относительного радиуса и угла var bright:int = 0; var relRadius:int = Math.ceil(10 * oldRadius / halfSize); switch(relRadius) { case 3: if ( (angle >= 0.5) && (angle < 1.75) ) bright = 20; break; case 4: if ( (angle >= 0.0) && (angle < 2.25) ) bright = 30; break; case 5: if ( (angle >= 0.5) && (angle < 1.75) ) bright = 40; break; case 6: if ( (angle >= 0.25) && (angle < 0.50) ) bright = 30; if ( (angle >= 1.75 ) && (angle < 2.0) ) bright = 30; break; case 7: if ( (angle >= 0.50) && (angle < 1.75)) bright = -20; if ( (angle >= 0.0) && (angle < 0.25) ) bright = 20; if ( (angle >= 2.0) && (angle < 2.25) ) bright = 20; break; case 8: if ( (angle >= 0.10) && (angle < 2.0) ) bright = -20; if ( (angle >= -2.50) && (angle < -1.90) ) bright = 60; break; case 9: if ( (angle >= 0.75) && (angle < 1.50) ) bright = -40; if ( (angle >= -0.10) && (angle < 0.75) ) bright = -30; if ( (angle >= 1.50) && (angle < 2.35)) bright = -30; break; case 10: if ( (angle >= 0.0) && (angle < 2.25) ) bright = -80; if ( (angle >= 2.25) && (angle < 2.5) ) bright = -40; if ( (angle >= -0.25) && (angle < 0.0)) bright = -40; break; } var pixel:int = src.getPixel(dropX + w1, dropY + h1); var r:int = (pixel >> 16 & 0xFF) + bright; var g:int = (pixel >> 8 & 0xFF) + bright; var b:int = (pixel & 0xFF) + bright; //диапазон r = ( r < 0 ) ? 0 : ( r > 0xFF ? 0xFF : r ); g = ( g < 0 ) ? 0 : ( g > 0xFF ? 0xFF : g ); b = ( b < 0 ) ? 0 : ( b > 0xFF ? 0xFF : b ); res.setPixel32(blurVal + halfSize + w, blurVal + halfSize + h, (0xFF << 24 | r << 16 | g << 8 | b)); } } } res.applyFilter(res, res.rect, new Point(), new BlurFilter(blurVal, blurVal)); if (append) { var mtrx:Matrix = new Matrix(); mtrx.translate(dropX - res.width/2, dropY - res.height/2); src.draw(res, mtrx); res.dispose(); return null; }else { return res; } } } } |
|
|||||
Капли, как правило, так не сохнут.
http://kbogdanov4.narod.ru/drying_drops.htm http://journals.ioffe.ru/jtf/2007/02/p17-21.pdf Добавлено через 2 минуты http://journals.ioffe.ru/jtf/2009/08/p133-141.pdf Добавлено через 6 минут Т.е. такой вариант, как привел silin, возможен только на несмачиваемой поверхности. Но искажения при этом должны быть значительно большими из-за сферической формы капли. Для смачиваемых поверхностей, площадь капли будет меняться гораздо в меньших масштабах.
__________________
משיח לא בא משיח גם לא מטלפן |
|
|||||
Регистрация: Jun 2014
Сообщений: 558
|
Спасибо за ответы, буду эксперементировать
Пришёл ещё вопрос, а возможно ли спрайт скрутить программно по спирали? или есть библиотеки? |
|
|||||
не уверен, что правильно понял вопрос,
есть вариант 'cкручивания' c помощью DisplacementMapFilter http://silin.su/#AS3/filters/swirl |
|
|||||
Регистрация: Jun 2014
Сообщений: 558
|
silin спасибо - это интересно
|
Часовой пояс GMT +4, время: 11:59. |
|
« Предыдущая тема | Следующая тема » |
Опции темы | |
Опции просмотра | |
|
|