package { import caurina.transitions.Tweener; import flash.display.Bitmap; import flash.display.BitmapDataChannel; import flash.display.StageQuality; import flash.display.StageAlign; import flash.display.StageScaleMode; import flash.display.Sprite; import flash.display.BitmapData; import flash.events.Event; import flash.events.MouseEvent; import flash.filters.BlurFilter; import flash.filters.DisplacementMapFilter; import flash.geom.ColorTransform; import flash.geom.Matrix; import flash.geom.Point; import flash.geom.Rectangle; import flash.utils.getTimer; import org.papervision3d.materials.BitmapMaterial; import org.papervision3d.materials.BitmapViewportMaterial; import org.papervision3d.materials.shadematerials.GouraudMaterial; import org.papervision3d.materials.shaders.PhongShader; import org.papervision3d.materials.shaders.ShadedMaterial; import org.papervision3d.objects.primitives.Cylinder; import org.papervision3d.view.BitmapViewport3D; import org.papervision3d.core.geom.renderables.Triangle3D; import org.papervision3d.core.geom.renderables.Vertex3D; import org.papervision3d.core.proto.MaterialObject3D; import org.papervision3d.materials.shadematerials.EnvMapMaterial; import org.papervision3d.objects.primitives.Sphere; import org.papervision3d.objects.DisplayObject3D; import org.papervision3d.cameras.Camera3D; import org.papervision3d.render.BasicRenderEngine; import org.papervision3d.scenes.Scene3D; import org.papervision3d.view.Viewport3D; import com.mrdoob.utils.Debugger; [SWF( backgroundColor='0x000000', frameRate='25', width='800', height='600')] public class shader extends Sprite { public var sceneBg :Scene3D; public var scene :Scene3D; public var renderer :BasicRenderEngine; public var camera :Camera3D; public var camera_shadow :Camera3D; public var viewport :Viewport3D; public var bpviewport :Viewport3D; //public var bpviewport :BitmapViewport3D; public var rtt :BitmapData; public var object3D :DisplayObject3D; public var ref_object3D :DisplayObject3D; public var ref2_object3D :DisplayObject3D; public var count :Number = 0; [Embed(source="/objects/underwater7.jpg")] public var EnvTexture :Class; public var heightTexture :BitmapData; public var quality :Number = 30 public var tween :Number public function shader() { stage.quality = StageQuality.LOW; stage.align = StageAlign.TOP_LEFT; stage.scaleMode = StageScaleMode.NO_SCALE; init(); init3D(); sceneSetup(); //Debugger.setup(this, { fps:true, tracer:true } ); addEventListener(Event.ENTER_FRAME, loop); addEventListener(MouseEvent.CLICK, calculateTerrain); buttonMode = true; } public function init():void { } public function init3D():void { sceneBg = new Scene3D(); scene = new Scene3D(); renderer = new BasicRenderEngine(); camera = new Camera3D(); //camera.target.y = 100; camera.z = 500; camera.zoom = 3; camera.focus = 200; viewport = new Viewport3D(800, 600, true); bpviewport = new Viewport3D(800, 600, true); addChild(bpviewport); addChild(viewport); //bpviewport.alpha = .5; } public function sceneSetup():void { var bgTexture:BitmapData = new EnvTexture().bitmapData; var bg:DisplayObject3D = new Sphere(new BitmapMaterial(bgTexture), 2000, 50, 50); bg.material.doubleSided = true; sceneBg.addChild(bg); var material:MaterialObject3D = new GouraudMaterial(null, 0xFFFFFF, 0x000000); ref_object3D = new Sphere(null, 400, quality, quality); ref2_object3D = new Sphere(null, 400, quality, quality); object3D = new Sphere(material, 400, quality, quality); scene.addChild(object3D); heightTexture = new BitmapData(quality, quality); calculateTerrain() //addChild(new Bitmap(heightTexture)); } public function calculateTerrain(e:MouseEvent = null):void { heightTexture.perlinNoise(Math.random() * 20 + 10, Math.random() * 20 + 10, 1, Math.random() * 100, true, false, 1, true); count = 0; for each(var vertex:Vertex3D in object3D.geometry.vertices) { ref_object3D.geometry.vertices[count].x = object3D.geometry.vertices[count].x ref_object3D.geometry.vertices[count].y = object3D.geometry.vertices[count].y ref_object3D.geometry.vertices[count].z = object3D.geometry.vertices[count].z count++; } tween = 0; Tweener.addTween(this, { tween:1, time:2, transition:"easeOutElastic", onUpdate:animateMesh, onComplete:calculateTerrain } ); } public function animateMesh():void { count = 0; for each(var vertex:Vertex3D in object3D.geometry.vertices) { var destPoint:Number = Math.max(heightTexture.getPixel(count % quality, (count / (quality * quality + quality)) * quality) * .00000007 + .4, 0); object3D.geometry.vertices[count].x = ( (ref2_object3D.geometry.vertices[count].x * destPoint - ref_object3D.geometry.vertices[count].x ) * tween) + ref_object3D.geometry.vertices[count].x object3D.geometry.vertices[count].y = ( (ref2_object3D.geometry.vertices[count].y * destPoint - ref_object3D.geometry.vertices[count].y ) * tween) + ref_object3D.geometry.vertices[count].y object3D.geometry.vertices[count].z = ( (ref2_object3D.geometry.vertices[count].z * destPoint - ref_object3D.geometry.vertices[count].z ) * tween) + ref_object3D.geometry.vertices[count].z count++; } for each(var face:Triangle3D in object3D.geometry.faces) face.createNormal(); for each(vertex in object3D.geometry.vertices) vertex.calculateNormal(); } // .. LOOP ........................................................................................................... private function loop(e:Event):void { camera.x += ( ( (mouseX - (stage.stageWidth * .5)) * 3 ) - camera.x ) * .05; camera.y += ( ( (mouseY- (stage.stageHeight * .5)) * 3 ) - camera.y ) * .05; renderer.renderScene(scene, camera, bpviewport); renderer.renderScene(sceneBg, camera, viewport); var rect:Rectangle = bpviewport.containerSprite.getRect(bpviewport.containerSprite); rtt = new BitmapData(rect.width >> 0, rect.height >> 0, false, 0x808080); var mtr:Matrix = new Matrix() mtr.translate(-rect.x, -rect.y); rtt.draw(bpviewport.containerSprite, mtr, null, null); viewport.filters = [new DisplacementMapFilter(rtt, new Point(stage.stageWidth * .5 - (rect.width * .5), stage.stageHeight * .5 - (rect.height * .5)), 2, 2, 300, 300)]; } } }