I am implementing an Away3D 4.x app where I have some meshes that should cast shadows. I setup a DirectionalLight and a FilteredShadowMapMethod, then apply the method onto the materials. However, as you can see on the screenshot, the light as if ignores objects that are close to the ground (their Y position is small) and only casts shadows for objects that are above certain Y coordinate. You can see this nicely on the bricks on the right.
I don't understand what I am doing wrong, could someone please help? This is the main part of my code:
light1 = new DirectionalLight(0, -3, -5);
light1.ambient = 0.5;
light1.diffuse = 1.0;
light1.specular = 1.0;
lightPicker = new StaticLightPicker([light1]);
this.scene.addChild(light1);
shadowMapMethod = new FilteredShadowMapMethod(light1);
groundCloseMaterial = new TextureMaterial(Cast.bitmapTexture(GroundDiffuseClose));
groundCloseMaterial.lightPicker = lightPicker;
groundCloseMaterial.specular = 0;
groundCloseMaterial.ambient = 1;
groundCloseMaterial.shadowMethod = shadowMapMethod;
groundCloseMaterial.repeat = true;
groundCloseMaterial.mipmap = false;
groundClose = new Mesh(new PlaneGeometry(MAX_WORLD_X*2, MAX_WORLD_Z*2), groundCloseMaterial);
groundClose.geometry.scaleUV(20, 20);
groundClose.y = 0.1;
//-- create bricks
greyBrickMaterial = new TextureMaterial(Cast.bitmapTexture(BrickDiffuse));
greyBrickMaterial.specularMap = Cast.bitmapTexture(BrickSpecular);
greyBrickMaterial.normalMap = Cast.bitmapTexture(BrickNormals);
greyBrickMaterial.lightPicker = lightPicker;
greyBrickMaterial.mipmap = false;
greyBrickMaterial.specular = 1;
greyBrickMaterial.ambient = 1;
greyBrickMaterial.shadowMethod = shadowMapMethod;
Bricks are created as just CubeMeshes with the brick material. Similarly, the are some SphereMeshes with their own material, that is created the same way as greyBrickMaterial, flying around and one huge CubeMesh in the distance.
Notice also the weird light effect on the big brown cube - that kind of lighting just doesn't make sense!
Ok with a help of a community member on Away3d forums, I found a solution.
In short, the light's position values should be < 1.0 to prevent strong reflections on some surfaces:
light1 = new DirectionalLight(0., -0.7, -0.7);
Secondly, playing with the .epsilon attribute of the shadowMapMethod helps bring the shadows to start from where they should, rather than to be offset:
shadowMapMethod = new FilteredShadowMapMethod(light1);
shadowMapMethod.epsilon = 0.08;
Long answer here: http://away3d.com/forum/viewthread/5787/
Related
I'm playing around with Bullet, I have a ground-floor and a ball, and I want the ball to fall and bounce on the ground. However this doesn't happen, even with very high values of m_restitution, which is supposed to regulate the bounciness.
Any clue why this is happening? This is torturing me for some hours now with no luck.
btBroadphaseInterface* broadphase = new btDbvtBroadphase();
btDefaultCollisionConfiguration* collisionConfiguration = new btDefaultCollisionConfiguration();
btCollisionDispatcher* dispatcher = new btCollisionDispatcher(collisionConfiguration);
btSequentialImpulseConstraintSolver* solver = new btSequentialImpulseConstraintSolver;
dynamicsWorld = new btDiscreteDynamicsWorld(dispatcher, broadphase, solver, collisionConfiguration);
dynamicsWorld->setGravity(btVector3(0,+9.8,0)); // GLWidget - y axis points downwards !!!
/////////////////////////////////////////////////////////////////////////////
//// Ground ///////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
btDefaultMotionState* groundMotionState = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1), btVector3(0,0,0)));
btRigidBody::btRigidBodyConstructionInfo groundRigidBodyCI(0, groundMotionState, groundShape, btVector3(0,0,0));
groundRigidBodyCI.m_restitution = 1.0f;
groundRigidBodyCI.m_friction = 3.0f;
groundRigidBodyCI.m_rollingFriction = 3.0f;
groundRigidBodyCI.m_mass = 0.0f;
btRigidBody* groundRigidBody = new btRigidBody(groundRigidBodyCI);
dynamicsWorld->addRigidBody(groundRigidBody);
/////////////////////////////////////////////////////////////////////////////
//// Ball /////////////////////////////////////////////////////////////////
/////////////////////////////////////////////////////////////////////////////
btDefaultMotionState* ballMotionState = new btDefaultMotionState(btTransform(btQuaternion(0,0,0,1), btVector3(0,-100,0)));
btScalar ballMass = 1;
btVector3 ballInertia;//(0,0,0);
ballShape->calculateLocalInertia(ballMass, ballInertia);
btRigidBody::btRigidBodyConstructionInfo ballRigidBodyCI(ballMass, ballMotionState, ballShape, ballInertia);
groundRigidBodyCI.m_restitution = 1.0f;
ballRigidBodyCI.m_friction = 1.0f;
ballRigidBodyCI.m_rollingFriction = 1.0f;
btRigidBody* ballRigidBody = new btRigidBody(ballRigidBodyCI);
dynamicsWorld->addRigidBody(ballRigidBody);
//Without the next it doesn't bounce at all
//With it, it bounces just a TINY little bit
dynamicsWorld->getSolverInfo().m_splitImpulse = false;
OK, the above code should work in theory, but I'm not sure why it doesn't work.
As said, the property that regulates bounciness is m_restitution. This can be set in two ways. The first way is noted in the question-post. The other way is the following:
groundRigidBody->setRestitution(1.0);
ballRigidBody->setRestitution(1.0);
...and it works. Based on what I read on the net (e.g. here), both ways should be fine, but in my case it works only with the second way. I'm using bullet-2.82-r2704 on Ubuntu.
This happens only with the m_restitution property, All the other properties are set fine in the way of my question-post.
Plus, the line dynamicsWorld->getSolverInfo().m_splitImpulse = false; is not needed any more.
Well, I'm working on a shooting game in which I have to click enemies to make two counters count the number of hits I get. In this case the enemies are ghosts and I tried making some kind of animation when they are shot so the animation replaces them after I click on them.
However I can't seem to make them reappear again in the same location, it's a very simple drawing made with the shape and drawing tools of Flash CS5.
The code I use in this case for the shooting part is this one:
function disparar (event:MouseEvent):void{
contar +=1;
disparos.text = contar.toString();
var destino1:Boolean = this.mira.hitTestObject(this.FRojo)
if (destino1 == true){
cuenta +=1;
aciertos.text = cuenta.toString();
this.FRojo.visible = false;
colorante.color = 0xFF0000;
this.bang.transform.colorTransform = colorante;
this.bang.x = this.FRojo.x;
this.bang.y = this.FRojo.y;
this.bang.scaleX = this.FRojo.scaleX;
this.bang.scaleY = this.FRojo.scaleY;
this.bang.play();
this.FRojo.visible = true;
}
In fact you can see the whole file in here, it's very simple, but I can't seem to make the movieclip either disappear and reappear or make the animation that follows reappear each time I hit one of the ghosts. Could anyone help me with this? I'd really appreciate the help.
You're hiding the movie clip by setting this.FRojo.visible = false; and then setting it back to true pretty much right after so it never hides.
Try replacing this.FRojo.visible = true;
with
setTimeout(function(){FRojo.visible = true;}, 1000);
That will make it reappear after 1 second (1000 milliseconds).
So remove this and make sure each one is FRojo, FAzul and FMorado.
If you use a tweening library like greensock you can do some cool fades rather than it just reappearing.
EDIT
You have another error inside your BANG movie clip. On frame 10 replace
this.bang.x = 50;
this.bang.y = 10;
this.bang.scaleX = 1;
this.bang.scaleY = 1;
with
this.x = 50;
this.y = 10;
this.scaleX = 1;
this.scaleY = 1;
Im currently building a little 3D particle engine in flash the uses sprites.
to set the position of each sprite I am using the projectVector function below. (the viewTransform matrix is the particles world matrix concatenated with a perspective projection matrix)
var projectedPoint:Vector3D = Utils3D.projectVector(viewTransform, point);
sprite.x = projectedPoint.x;
sprite.y = projectedPoint.y;
this works really well an places the sprites exactly where they should be :D
The problem I am having is trying to figure out how to calculate the scale of the each particle based on is distance from the camera..
sprite.scaleX = sprite.scaleY = ??
If I wasn't using a perspective projection matrix I would usually do something like this..
var scaleRatio:Number = (focus * zoom)/(focus + particle.globalz);
particle.depth = scaleRatio;
sprite.x = particle.globalx * scaleRatio;
sprite.y = particle.globaly * scaleRatio;
// set scale..
sprite.scaleX = sprite.scaleY = scaleRatio;
If there is anyone out there able to show me how to calculate the "scaleRatio" using a perspective projection matrix that would be ace
thanks!
I'm sure there's a more succinct way to do this, but since you already know how to project a point, you could do this:
var tl:Point = sprite.getRect(sprite.parent).topLeft;
var br:Point = sprite.getRect(sprite.parent).bottomRight;
var projectedTL:Point = Utils3D.projectVector(viewTransform, tl);
var projectedBR:Point = Utils3D.projectVector(viewTransform, br);
trace("projected width = "+(projectedBR.x - projectedTL.x));
trace("projected height = "+(projectedBR.y - projectedTL.y));
I want to draw a 3D ball or sphere in HTML 5.0 canvas. I want to understand the Algorithm about how to draw a 3D sphere. Who can share this with me?
You will need to model a sphere, and have it be varying colors so that as it rotates you can see that it is not only a sphere, but being rendered.
Otherwise, a sphere in space, with not point of reference around it looks like a circle, if it is all one solid color.
To start with you will want to try drawing a circle with rectangles, as that is the main primitive you have.
Once you understand how to do that, or create a new primitive, such as a triangle, using the Path method, and create a circle, then you are ready to move it to 3D.
3D is just a trick, as you will take your model, probably generated by an equation, and then flatten it, as you determine which parts will be seen, and then display it.
But, you will want to change the color of the triangles based on how far they are from a source of light, as well as based on the angle of that part to the light source.
This is where you can start to do optimizations, as, if you do this pixel by pixel then you are raytracing. If you have larger blocks, and a point source of light, and the object is rotating but not moving around then you can recalculate how the color changes for each triangle, then it is just a matter of changing colors to simulate rotating.
The algorithm will depend on what simplifications you want to make, so as you gain experience come back and ask, showing what you have done so far.
Here is an example of doing it, and below I copied the 3D sphere part, but please look at the entire article.
function Sphere3D(radius) {
this.point = new Array();
this.color = "rgb(100,0,255)"
this.radius = (typeof(radius) == "undefined") ? 20.0 : radius;
this.radius = (typeof(radius) != "number") ? 20.0 : radius;
this.numberOfVertexes = 0;
// Loop from 0 to 360 degrees with a pitch of 10 degrees ...
for(alpha = 0; alpha <= 6.28; alpha += 0.17) {
p = this.point[this.numberOfVertexes] = new Point3D();
p.x = Math.cos(alpha) * this.radius;
p.y = 0;
p.z = Math.sin(alpha) * this.radius;
this.numberOfVertexes++;
}
// Loop from 0 to 90 degrees with a pitch of 10 degrees ...
// (direction = 1)
// Loop from 0 to 90 degrees with a pitch of 10 degrees ...
// (direction = -1)
for(var direction = 1; direction >= -1; direction -= 2) {
for(var beta = 0.17; beta < 1.445; beta += 0.17) {
var radius = Math.cos(beta) * this.radius;
var fixedY = Math.sin(beta) * this.radius * direction;
for(var alpha = 0; alpha < 6.28; alpha += 0.17) {
p = this.point[this.numberOfVertexes] = new Point3D();
p.x = Math.cos(alpha) * radius;
p.y = fixedY;
p.z = Math.sin(alpha) * radius;
this.numberOfVertexes++;
}
}
}
}
u can try with three.js library , which abstracts a lot of code from core webgl programming. Include three.js library in your html from three.js lib.
u can use canvas renderer for safari browser , webgl works for chrome
please find the JS FIDDLE FOR SPHERE
var camera, scene, material, mesh, geometry, renderer
function drawSphere() {
init();
animate();
}
function init() {
// camera
scene = new THREE.Scene()
camera = new THREE.PerspectiveCamera(50, window.innerWidth / innerHeight, 1, 1000);
camera.position.z = 300;
scene.add(camera);
// sphere object
var radius = 50,
segments = 10,
rings = 10;
geometry = new THREE.SphereGeometry(radius, segments, rings);
material = new THREE.MeshNormalMaterial({
color: 0x002288
});
mesh = new THREE.Mesh(geometry, material);
//scene
;
scene.add(mesh);
// renderer
renderer = new THREE.WebGLRenderer();
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
}
function animate() {
requestAnimationFrame(animate);
render();
}
function render() {
mesh.rotation.x += .01;
mesh.rotation.y += .02;
renderer.render(scene, camera);
}
// fn callin
drawSphere();
Update: This code is quite old and limited. There are libraries for doing 3D spheres now: http://techslides.com/d3-globe-with-canvas-webgl-and-three-js/
Over ten years ago I wrote a Java applet to render a textured sphere by actually doing the math to work out where the surface of the sphere was in the scene (not using triangles).
I've rewritten it in JavaScript for canvas and I've got a demo rendering the earth as a sphere:
(source: haslers.info)
I get around 22 fps on my machine. Which is about as fast as the Java version it was based on renders at, if not a little faster!
Now it's a long time since I wrote the Java code - and it was quite obtuse - so I don't really remember exactly how it works, I've just ported it JavaScript. However this is from a slow version of the code and I'm not sure if the faster version was due to optimisations in the Java methods I used to manipulate pixels or from speedups in the math it does to work out which pixel to render from the texture. I was also corresponding at the time with someone who had a similar applet that was much faster than mine but again I don't know if any of the speed improvements they had would be possible in JavaScript as it may have relied on Java libraries. (I never saw their code so I don't know how they did it.)
So it may be possible to improve on the speed. But this works well as a proof of concept.
I'll have a go at converting my faster version some time to see if I can get any speed improvements into the JavaScript version.
Well, an image of a sphere will always have a circular shape on your screen, so the only thing that matters is the shading. This will be determined by where you place your light source.
As for algorithms, ray tracing is the simplest, but also the slowest by far — so you probably wouldn't want to use it to do anything very complicated in a <CANVAS> (especially given the lack of graphics acceleration available in that environment), but it might be fast enough if you just wanted to do a single sphere.
Say I have a movie clip that when loaded I set it's .z position to 2000 to make it look far off in the background... How in the world can I set it's x and y points with any certainty as to where it will appear on the stage? Is there an equation?
E.g.;
original.x = 200;
original.y = 200;
original.z = 0;
new.z = 2000;
new.x = original.x*10;
new.y = original.y*10;
you have to seperate out the actual x and y points with the 3D space points (i use _x, _y and _z). using a basic idea that anything further away from you is going to be you will need to define an origin for the vanishing point and a "focal length" (think of a camera lens) that will define how quickly things dissappear into the background. try playing with values, but something around 200 usually works fairly well.
this should give you something simple like this where my_mc is the object you want to have the effect on:
my_mc._x = 0;
my_mc._y = 0;
my_mc._z = 200;
var scaleRatio = focalLength/(focalLength + my_mc._z);
my_mc.x = origin.x + my_mc._x * scaleRatio;
my_mc.y = origin.y + my_mc._y * scaleRatio;
my_mc.scaleX = my_mc.scaleY = scaleRatio;
there are some really good tutorials at kirupa on this subject, try this one (though it is in as2 the theory is the same)
http://www.kirupa.com/developer/actionscript/3dexplore.htm