Categories
General

Real reflections in Papervision3D!

You know I’m a fan of the Papervision BasicView, it’s just such a good entry point into Papervision – so easy to work with, and you can even extend it for your document class.

But how cool would it be if you could have something as simple as a BasicView, but that automatically created a reflection on the ground? Very cool! That’s how!

Which is exactly why I made a ReflectionView. You can pretty much just replace your BasicView with this new class.

[kml_flashembed movie=”/wp-content/uploads/manual/2008/reflectioncube1.swf” width=”445″ height=”340″ FVERSION=”9″ QUALITY=”high” /]

At the moment it only works with reflections on an xz plane (ie the floor).

There are only two new things you need to consider :

surfaceHeight
This is the y position of the floor. You need to make sure none of your objects go underneath this or it’ll look weird!

setReflectionColor()
This function adjusts the color transform for the reflection by settings mutlipliers and offsets for red, green and blue, just like the colorTransform property of MovieClips.

By default this is set to darken the reflection but you can use it to lighten or even colorise it.

It’s very alpha, but very simple and very quick!


You can also add blur to the reflection by adding a filter to the reflection viewport :

viewportReflection.filters = [new BlurFilter(4,4,1)];

And if you want it to actually be transparent (if you’re using a floor plane for example) you can also add a ColorMatrixFilter to the viewportReflection filters.

I’m looking at improved effects to this with Andy’s help but I thought I’d at least get a basic version out there for you to play with.

Basic cube source code here :

package {
	import flash.events.Event;

	import org.papervision3d.cameras.Camera3D;
	import org.papervision3d.core.effects.view.ReflectionView;
	import org.papervision3d.materials.ColorMaterial;
	import org.papervision3d.materials.utils.MaterialsList;
	import org.papervision3d.objects.primitives.Cube;

	[SWF (width="640", height="480", backgroundColor="0x000000", frameRate="30")]

	public class ReflectionCubeSimple extends ReflectionView
	{

		private var cube : Cube;

		public function ReflectionCubeSimple()
		{

			super(640,480,false, false);

			//the height of the reflection plane
			surfaceHeight = -100;

			initCube();

			camera.z = -400;

			addEventListener(Event.ENTER_FRAME, enterFrame);

		}


		public function initCube() : void
		{

			// create a materials list for the cube.
			var ml : MaterialsList = new MaterialsList();
			ml.addMaterial(new ColorMaterial(0x880000), "all");
 			ml.addMaterial(new ColorMaterial(0x660000),"right");
			ml.addMaterial(new ColorMaterial(0x440000),"bottom");
  			ml.addMaterial(new ColorMaterial(0xdd0000),"top");
			ml.addMaterial(new ColorMaterial(0xdd0000),"left");

			cube = new Cube(ml,100,100,100);

			// add the cube to the scene
			scene.addChild(cube);

		}

		public function enterFrame(e:Event) : void
		{
			// rotate the cube dependent on the mouse position
			cube.yaw((320-mouseX)*0.05);
			cube.y=(120-(mouseY/2));

			if(cube.y<0) cube.y = 0;

			singleRender();

		}

	}
}


(Cue about a million CoverFlow type effects… 🙂 )

103 replies on “Real reflections in Papervision3D!”

Thanks guys!

Mark, next on my list is to create fall-off and even culling, so I’m currently studying the renderers.

cheers!

Seb

I tried use it in a project, but it looks like the reflection is not sync with the objects. It looks like the reflection has one frame delay.

Hi Thijs,

I suspect this may be to do with a bug in the DisplayObject rotation methods… are you adjusting your objects using rotationX, Y, Z etc? Could I see the code?

Seb

Yes this is a bug not related to ReflectionView, currently your actual main display will be getting updated a frame late. There are several workarounds :

1) Switch rotationY for a relative rotation using yaw();
or
2) Add yaw(0) after all your updates on your object;
or
3) Wait until we fix the rotation bug. 🙂

Would love to see how you’re getting along with this though.

cheers!

Seb

I did the first option with a relative rotation using yaw():

public function get rotation():Number
{
return this._rotation;
}

public function set rotation(value:Number ):void
{
this.yaw(value – this._rotation);
this._rotation = value;
}

And it works great. Thanks!

Really weird things happen when I change the pitch or tilt of the camera. It looks like the reflection surface also changes.

But rotating the camera using rotationX works ok.

Hi Thijs, that sounds weird, I’ve never seen that… do you have code I can test?

cheers

Seb

Yeah that is weird! Pretty sure it’s to do with the new camera stuff… can u send me the code and I’ll investigate.

cheers!

Seb

I’ve been searching for tutorials on getting nice reflections and I haven’t found any (yet). I love what you’ve done, its awesome! One question where can the classe(s) be obtained?

Of course I could always check out the latest SVN….
If you had smilies I would use the embarassed one!

OK so now I get this error…
1195: Attempted access of inaccessible method yaw through a reference with static type org.papervision3d.objects.primitives:Cube.

If I comment the line out it works fine. I guess the camera.yaw method has been revised?
Its still seriously cool to just be able to add reflections though. Thanks a lot!

Hi gordee,

yes there are some major reworkings at the moment to DisplayObject3D rotations. I’ll wait for all of them to be completed and then make sure ReflectionView still works.

Seb

OK I’ve uploaded a new ReflectionView to the svn server and this should fix the rotation problems. The DisplayObject3D rotation system (which Camera3D inherits) is undergoing some major revisions at the moment, so please let me know if this breaks again.

BTW the ReflectionView currently only works if you use the new pitch, roll and yaw properties of your camera, which replace rotationX, rotationY and rotationZ respectively.

cheers!

Seb

Hi…first of all: great work… I was working on one myself but this looks gooood…

One issue: I use MovieMaterials for my planes. The movieclips i use for my materials have events on them (mouseover and click). These events fail as soon as I use the ReflectionView…

Is this a known issue????

Hi Wink,

ah thanks for that, I’m surprised it doesn’t work but then I didn’t actually test it. So to be clear, the events on the non-reflected version stop working?

Seb

Hi Seb…
Exactly…The ‘original’ non reflected items stop working…
I am also checking out if it is me… changing the surfaceHeight seems to be off influence….

surfaceHeight = -100 — there is some interacting. But very irregular. Sometimes it works, sometimes it doesn’t

surfaceHeight = – 300 — no interaction at all

Wink

Hey Seb,

I’ve got a bunch of MovieMaterials that are working fine (interactivity wise), but my reflection is off. It’s as if the Reflection’s Camera’s Pitch and Z are off. It’s weird. I can send you code if you would like.

Thanks,
Seantron

Hi Seantron,

yes please do send me code, and I’ll check it out.

The DisplayObject3D rotation refactoring seems to be screwing this up, so I’ll see what I can do.

cheers!

Seb

Hi Wink, yes as I suspected it’s to do with the new rotation stuff… but I’m on it…

cheers!

Seb

nice thinking behind that class mate.
do you think there is any way the reflection can be tapered off the further away it is from the main object?

Hi Paul,

yes there are several ways to do this, mostly involving layers. I will be integrating this in to reflection view at some point!

cheers!

Seb

Hi, I’ve been using you ReflectionView for a while and it’s wonderful!.

I had some problems setting it up, thought: I have to manually set its size to the size defined by the stage, because if not, the projection of the reflection does not match the original projection. Maybe you need to trap the resize events, or recompute the projection on every frame?

thanks in advance!

Hi, I was looking for something like that, but where dit it go? its not in the ‘view’-folder. Am i looking in the wrong place?

thanks,

maik

Hi Maik,

it’s inorg.papervision3d.core.effects.view.ReflectionView – maybe we should move it to view – what do you think?

Seb

Hey Seb great work!!

I’m curious where you’re at with that interactivity bug. I’m having the same issue, but using BasicView it works fine. If you need any more info or code, or anything I can do just let me know! Thanks and great work so far!

Hi Seb…
I see there is a problem with interaction. Just found it out and now read it here…
I also encounter this: I am not able to change my surfaceHeight. It stays 0….No matter what value I try to give it…..very strange… If I change it in the class it works…
With kind regards. Wink

I found something out.
I placed surfaceHeight = -300; above the line super(etc..etc);

If I place it under the super() line, the surfaceHeigt works fine..

BUT!!!!

If I do NOT!!! set a value for surfaceHeight. I DO have interactivity. If I set a value for surfaceHeight, my interactivity is GONE!

I do not know if you allready knew that…just found it out. Can it be that the reflection is layered “over” the original???
Interactivity and surfaceHeight are connected. I

Hi guys,

I’ve made some changes to ReflectionView (and in fact IteractiveSceneManager) which hopefully should fix these problems.

There still seems to be a little weirdness with interactivity and rendering multiple viewports (ReflectionView is basically just 2 viewports) but we’re looking into this now…

cheers!

Seb

Hi

After revision 686-687, all interactivity in my project is gone!

Before today’s update, I had interactivity (I was receiving OVER events every time I moved the mouse over an interactive object, and random OUT events, never receiving MOVE events even if I registered for them)

But since today’s update, I don’t receive any event at all!!

Yes, I’m using reflection view, actually, I overload reflection view and “singleRender” function, which dos NOT call super; the reason is that I need to render things in a particular order ( I have a transparent floor and a landscape that are tricky to render ), so it’s just a series of renderer.renderScene. I also use ViewportLayers, so the whole thing is quite complex.

Currently the InteractiveSceneManager doesn’t work very well with multiple viewports. This is an ISM issue, not a ReflectionView issue. The interactivity seems to only work on the last viewport you render. We will look into this but in the meantime just experiment with the order that you render things.

Cheers!

Seb

Ok, I managed to make it work with the latest changes on PV3D. To make it work, I had to remove my own SingleRender… I lost a bit of the functionality, but nothing I can’t live with. Forgot to mention that I was also adding an extra viewport to the stage’s child list; I needed this one to render the landscape. ReflectionView renders everything two times, but I my scene, I needed to render the floor and the lanscape only once, so I created that extra viewport just for these.

Great Work but at revision 702 i can´t see any reflection by now.(I was using your democode) Your still working to get it runnng again?

Hi tm2003,

just to confirm this code is working in the latest revision. So you must be doing something else wrong 😉

Seb

Hi seb,

you are definetly right. I compiled your code with FlashDevelop3, and didn´t check if there are diference between playing the swf directly in FD3 or with the Flash -Player. Now it works fine and stable! Great Work, great support! I´m a new fan of your stuff 🙂
Greetings,
tm2003

hi there, i ve been trying to use this incredible class and i had some trouble since i changed the z position of an object. check this out
//tiscar.fr/perso/reflectionTest/Main.html
i guess you re aware of this bug and since i am really not good at math… i just can tell about it 🙂
thank you for the job your doing on papervision, it is defenitly marvelous!

Hey Seb, thanks for the info. I’ve been trying to get the reflection to fade out into the floor. Kind of like an alpha gradient? Do you have any creative idea on how to do this off the top of your head?

that’s really nice ..but i was wondering why if i put a clip underneath the reflektion disappears…i just wanted to put a gradient but i cant ..how to blur just the reflektions btw?
Thanks

Hi Seb

Any updates on this topic?

I’ve checked out the latest papervision revision and started using your ReflectionView, it’s a really great class. Would have saved me a lot of headaches on a previous project.

The particular topics I’m interested about is the possibility to create a falloff, apply effects to only the reflection (like a blur).

Hi guys,

I can see you’re all after creating a kind of drop off effect, there are a few ways we could approach this, but none of them are very easy 🙂

I expect it’d take some work on the renderer.

Bart, it’s easy to add a blur to the whole reflection, there’s a separate viewport in the ReflectionView class that you can apply effects to. From memory the viewport is called reflectionViewport, and you can set the filters like this :

reflectionViewport.filters = [new BlurFilter(4,4,1)];

Don’t forget that the blur filter is optimised for values that are exponents of 2, ie, 2, 4, 8, 16, 32 etc.

cheers!

Seb

Hi Seb,
I’m trying to extend the ReflectionView class but I’m getting this continuous error:

ERROR: lookAt error

What can be the reason?

Thanks

Hey, I’ve been checking out your blog, as well as over 400 other blogs over the past week (since I started my portfolio project at school) and have finally come up with some of your tutorials, other tuts, and put them together. Right now, here’s the demo of what I have:
//www.geocities.com/bombermangraal/CubeTest.swf
As far as I know, I have a script to make the cube face the camera when a side is clicked, but don’t have one where you click outside of the cube and it goes back to its spinning self.

If it’s too much, then could you possibly give me tips on limiting the speed at which the cube spins via x, y, z?

haha silly me, I just read your code and used that to slow down my cube, thanks anyway!

sincerely,
Jim

Hi Seb,
great work! I just started using pv3dGW some days ago and while i definitely think that it is great in some way, it seems to be still a little raw in many areas – hopefully i can help in one way or the other in the upcoming christmas holidays.

That being said, I haven’t succeeded in using your ReflectionView as it just doesn’t display anthing. I also still haven’t found a good way to debug the issue, as pv3d gets a bit ugly when it comes to following inheritances – thank god it doesn’t seem to make much use of polymorphism.

I’m not sure if I could send you my code, because it gets its data from a server of our client, which i think i shouldn’t hand out to anyone.

Still i got some leads which I think you could maybe comment on:

1. I’m using Plane’s for everything, so i got no solid objects

2. The viewport is not set to scale with the stage, I instead scale it manually (which leads to another oddity, as culling seems to only work correct for the portion of the viewport in a quadratic area)

3. my surfaceheight is -1120 and my camera is set up with z=-1000, fov=60, near=10, far=5000, x=0, y=0 with the main display object being 1120 units in height and some thousand units in width

Got any ideas?

P.S. I could probably strip out those url’s which would leave my code not working because of no data, as that is being loaded from an external xml file.

@Jim

Thx for your answer –
How would i test for that? My normal viewport / planes just show up fine, and I already tried different heights for the surfaceheight, negative as well as positive, to no avail.

Hi Seb,

Using your example, but change the cube rotation with a camera movement (targeted to center) based on mouse position.
And there’s a bad effect, the second cube (in second viewport) seems to be late.

So i’ve made a little change for fixe it , just put your line super.singleRender(); as the first line of yours singleRenderer function in ReflectionView.

Thanks for your works.

Cheers

Hy everyone,

just found out, what was making the reflection not show up:
setChildIndex(viewportReflection,0);

I have a background image in my flash movie which covers the whole available space, so the reflection was in fact behind it. I’d suggest to change this part to swapping the index instead of plainly setting it to 0.

Merry Xmas

Next problem:

When i tilt the camera around the Y axis (i always confuse the words tilt / yaw / pitch so forgive me if I do it this time as well…) the reflection does not rotate the same way and it always seems to look at the camera, like a bilboard reflection…

Am i doing something wrong or is reflectionview not yet cut out for doing such reflections? Also, about a drop off: How would it be possible with the way reflectionview works at the moment? If i’d just overlay the viewport with a gradient mask it would not change with the rotation…

Any idea on one of those two problems?

Any update on the interactivity issues and reflection “lags”?

If I leave everything as is, I get interactivity when using reflectionview. However, if I orbit or move the camera, the reflection seems to be lagging.

If I move the line:

super.singleRender();

to the top of the singleRender() override function (ReflectionView.as) it seems to solve the reflection lag issue, but then interactivity goes mad. Kind of like if the “hot areas” are offset vertically.

I’ve been struggling with reflections for some time. Then the Merry Christmas post came out, and i noticed it used ReflectionView! Thanks so much!

I’m trying to figure out how to put a Plane down as the surface/ground. I first tried setting the y value of the plane below the surfaceHeight value, that didn’t work.

I saw your reply about using viewportReflection’s viewportObjectFilter, but i tried (try…catch) accessing it but it is null… maybe i need to research more…

I was then looking at the comment, and code: setChildIndex(viewportReflection,0) and was thinking that if the reflection is at childIndex of 0 and the normal viewport is above that, using myView.scene.addChild() will always put my plane above the reflection.

I’m sure im missing something, but it almost seems like i need a third viewport, below the reflection, if i want to simulate the reflection being “cast” or “above” my ground plane.

Let me know if you want code or if you can point me in the right direction.

Any help would be greatly appreciated! Thanks in advance!

Oh, also, i remember a talk you gave on particles back at FlashForward in Austin TX. I was blown away with your easy explanations and LOVED the plug-in media page, so much fun to playwith. Thanks for sharing with us flash mortals!

I’ve also been struggling with the reflections during the past days. When I move the camera the reflection does not sync properly.

Is this a known issue, seb?

For jason : just put the line super.singleRender(); as the first line of your singleRenderer function in ReflectionView. it works fine for me !

Fidiman: Yeah… I tried that before and it solves the reflection problem. However, if I do it, the mouse events go crazy for some reason (same problem as Paul). I’ve got some planes with mouse events and it seems as if the “hitareas” are above them 🙁

Chech if you’re set the ReflectionView as interactive or not when you call the super method

super(800,600,false, true);

the last parameter is to set the flag for interactivty..

Has ANYONE been able to get a Plane or any other do3d below/underneath the reflection/viewportReflection?

OK, i figured out a way to get an object (ground-plane) to appear below the reflection. And yes, I took Seb’s advice to use ViewportObjectFilter (see comment 59, above).

1. add a third viewport – viewportGround.
2. rearrange the viewports using setChildIndex(), placing viewportGround at zero
3. add another ‘render.renderScene()’ line to the singleRenderer() method
4. remove the ground-plane from both viewport and viewportReflection
5. remove all objects except the ground-plane from the viewportGround.

My earlier attempts at using ViewportObjectFilter were just improper usage/syntax.
Here’s a sample of what worked (to remove plane from viewportReflection):
viewportReflection.viewportObjectFilter = new ViewportObjectFilter(ViewportObjectFilterMode.EXCLUSIVE);
viewportReflection.viewportObjectFilter.addObject(plane);

On to the next feature/bug on my list… 🙂

Hi guys,

sorry I haven’t responded, I’m only just catching up with all this stuff.

The “lag” should be fixed now, so please test it and let me know how it works for you. Moving the singleRender function will cause problems with interactivity -from memory, interactivity only works on the last viewport rendered.

@darren_db glad you got that sorted, it sounds like a good solution.

Hey. This is working really good :), just what i was looking for too.

I have been trying to make the reflection taper of so that it is stronger in the beginning and then fades of. Should this be done with a ColorMatrixFilter? Anyone got an example of this?

Hi Christian,

take a look at the ReflectionView class, it just makes a new viewport and renders a moved camera into that. I’m not sure what would happen with RenderLayers, but I can’t imagine that it’ll work 🙂

Maybe I’ll take a look when I get a chance, but I can’t imagine it’d be an easy update.

cheers!

Seb

Seems to work well with renderlayers except that the reflections graphics are never cleared. So every frame it adds more and more reflections.

Hi Seb,

First of all, thanks for all the hard work. This class is awesome!

Maybe you can also help me in my problem. I used this Reflection class, worked great so far but when i added filters on the vieport elements like blur, the reflectionViewport doesnt seem to get the same display.

Still looking for answers around other forums though. But hope you can shed some light into this.

Thanks!

[…] Papervision3D 2.0 GreatWhite revision 641 でReflectionViewってのが追加されてる。 サンプルとか詳しいことはこちら。 […]

Hi Seb, thanks for this, a really useful class.
I know people have mentioned this already, but I haven’t seen any solutions…. I need to add some kind of falloff to the reflections, and before I start delving too deep, I thought I’d check here first.
You had mentioned that you were going to take a look at it, did you get anywhere? Maybe you could point me in the right direction, and I will of course contribute if I come up with a solution.

Drop-Offs 🙂

here’s a simple vertical alpha mask that simulates “drop-off” on the reflection.

add this function to ReflectionView:

protected function addDropOff():void
{
var shape:Sprite = new Sprite();
var mxBox:Matrix = new Matrix();
mxBox.createGradientBox( 640, 480 , Math.PI/2 , 0 , 0 );
shape.graphics.beginGradientFill(GradientType.LINEAR ,[0x000000, 0x000000], [0, 1], [0x00, 0x7E], mxBox);
shape.graphics.drawRect( 0, 0, 640, 480 );
shape.graphics.endFill();
shape.cacheAsBitmap=true;
viewportReflection.cacheAsBitmap = true;
viewportReflection.addChild(shape);
viewportReflection.mask = shape;
}

call it from the constructor (circa line 63):
ie change:
setReflectionColor(0.5,0.5,0.5);

to:
setReflectionColor(0.5,0.5,0.5);
addDropOff();

simple processor friendly solution – hope that helps anybody else looking

Hi there,

How should we use this class if we’re already extending PaperBase in our project’s MainClass… I’ve tried extending PaperBase by ReflectionView, and it throws the following errors when compiling:

Error: A conflict exists with inherited definition org.papervision3d.view:AbstractView.viewport in namespace public.

Error: A conflict exists with inherited definition org.papervision3d.view:AbstractView.renderer in namespace public.

to be more specific with my problem, I am adding a load of Planes to a Page class which extends DisplayObject3D. I tried adding my Pages as children of an instance of ReflectionView but it is expecting a DisplayObject, not a DisplayObject3D!

Having an issue compiling this example in Flashdevelop with the latest build of p3d. Am getting an error in papervision3dcoregeomVertices3D.as:

Can not resolve a multiname reference unambiguously.

and also that Vertex3D is not a compile time constant.

possible conflict between versions of Vertex3D in geom and geom.renderables?

ok, rolled back to rev 869 and it’s working. definitely doesn’t seem to like 883. :o(

I’ve been working with ReflectionView for a few days now one problem I cant seem to sort out is the positioning of the reflection.

If I leave the viewport set to autoScale=true everything works fine. But I find the scene sits really high up on the screen.

If i set it to false the objects recenter and render based to my specified viewport height but the reflection stays auto-centered.

Any idea why… Ive tried adjusting the surfaceHeight but everything is still off kilt.

Well I did some searching found the culprit. It lies in the onAddedToStage function within ReflectionView

It’s set to call onStageResize whether autoScale is true or false. And since the onStageResize reads the stage.stageHeight it threw off the positioning so I just added a quick boolean check to onAddedToStage…

if (_autoScaleToStage)
{
stage.addEventListener(Event.RESIZE, onStageResize);
onStageResize();
}

Hi Seb —

Quick question about the reflection. In my probject I’m creating a cube with Bitmaps and a GouraudShader applied to it. I notice in the reflection, I see one face that is black and when the cube starts spinning it quickly looks normal like the main cube. Then as it spins instead of a smooth reflection it pops back to being black. Any ideas on why this would happen?

Thanks,

@mike, thanks for that, I’ll def check that out when I get a chance (not sure when that is though!)

@Ryan I can’t imagine that this will work very well with the shaders, sorry!

I have a question.
How can i put a movieclip above the papervision viewport ?
I know that i can do that if the class is extends Sprite but with extends ReflexionView, i dont know how to do that…
Thx

[…] the animation is based on ReflectView an interesting class available for greatWhite after the merging of the two branches. All we have to do is to extend the ReflectionView and set the surfaceHeight of the reflection plane in this case: surfaceHeight = -212 the animation is based on this tutorial: //www.sebleedelisle.com/?p=196 […]

Comments are closed.