Why is the directional light illuminating the box placed behind it? - javascript

I've added a DirectionalLightHelper to my code to illuminate a box. The light is placed at coordinates (2,2,1) and two boxes at (0,0,0) and (3,3,3). The box at (3,3,3) shouldn't be illuminated by the directionalLight, yet it is being illuminated the same way the box at (0,0,0) is. Any insight on this would be really helpful.
Scene Image Here

DirectionalLight doesn’t behave like a panel of light.
From the docs:
light will behave as though it is infinitely far away and the rays produced from it are all parallel.
So when you assign it’s position, it’s actually the vector from where the light rays are coming from, and it’ll affect all objects on the scene.
Maybe you’d like to use layers so the light only affects one box but not the other.

Related

Is there a way to make a capsule/ovoid shape with cannon using three JS with React?

The player of my 3d game using threeJS with react (R3F) cannon, fiber is currently a sphere. This is because i want it to slide with no friction, and the geometric shapes that has sides/vertexes dont.
The thing i wanted to achieve is to have the same no-friction movement but making the useSphere object (or any that i can use with cannon) taller. But as it is a sphere is completely rounded so that i can only increase radious and i only want to make it taller not wider.
Any solution to this problem is welcome as my game is first person camera so i dont even show the player just want the correct physics with cannon library.
Ive seen that three js includes geometries like capsules: https://threejs.org/docs/#api/en/geometries/CapsuleGeometry
That i feel might work if i had the chance to use it with cannon but i dont know how to. I simply want a no edge shape that is taller than a ball, like a ball but larger. I think there might be a way to make a custom shape but i sincerely havent found anything.
Thanks in advance for your help, would be really nice to me.

How to improve shadow quality in three.js

I have several object in a scene. And I want them moving on a wide plane, which will receive shadows. If I use only one point light or a very large directional light the shadow of a object when it moved to the corner will become very rough (rough shadow edge) . like this:
So I’m wondering should I use a light for every object above them and follow them in order to cast a high quality shadow edge? And in some case I can not set the shadow.mapsize higher .
There are a number of things that control shadow quality.
What it looks like to me, is your shadow cameras left / right / top / bottom are set too large, and its casting the shadow over too large an area.
Shadow casting lights are pretty expensive, so I would avoid trying to compensate by having multiple lights.
Try reducing the light.shadow.camera left/right/top/bottom to focus the map better on where you're objects are. Also trying increasing shadowmap size to something like 1024 or 2048 square.
Another thing that helps is to use THREE.PCFShadowmapping instead of the default. That will smooth the edges of your shadows.
edit: Also check out PCFSoftShadowMapping.. slower to render, but greatly smooths shadow edges.
Getting the shadow mapping right is a tricky process and requires a lot of fiddling.
Also, try attaching a DirectionalLightHelper to your light and also a CameraHelper to the lights camera. Those will help you figure out how big the shadow casting area is and where things are pointing.
https://imgur.com/a/Zo80z

Three.js - How to check if an object is visible to the camera

I'm having hard times figuring out what's the best way to check if a Object3d is visible for the eyes of the camera.
I'm having a sphere in the middle of the screen. Some cubes are added on it's surface randomly. What I would need is a way to check which cubes are visible (on the front half of the sphere) and which one are invisible (on the back half of the sphere) for the eyes of the camera.
What I have found so far seems to be the right direction - but I must be missing something with the THREE.Raytracer class.
Here is a fiddle of the code that I'm using: jsfiddle. I have tried to make it as clear as possible.
This part of the fiddle might contain the buggy code:
var raycaster = new THREE.Raycaster();
var origin = camera.position, direction, intersects, rayGeometry = new THREE.Geometry(), g;
pointGroup.children.forEach(function(pointMesh) {
direction = pointMesh.position.clone();
// I THINK THIS CALCULATION MIGHT BE WRONG - BUT DON'T KNOW HOW TO CORRECT IT
raycaster.set(origin, direction.sub(origin).normalize());
// if the pointMesh's position is on the back half of the globe, the ray should intersect with globe first and the hit the point as second target - because the cube is hidden behind the bigger sphere object
intersects = raycaster.intersectObject(pointMesh);
// this is always empty - should contain objects that are located on the back of the sphere ...
console.log(intersects);
});
Frustum Culling is not working as outlined in this stack overflow question here: post1
Also this post2 and this post3 are explaining the topic really good but not quite for this situation.
Thank you for you help!
You want to look at Occlusion Culling techniques. Frustum culling works fine and is not what you are describing. Frustum culling just checks if an object (or its bounding box) is inside the camera pyramid. You perform Occlusion culling in addition to Frustum Culling specially when you want to eliminate objects which are occluded by other objects inside the view frustum. But it is not an easy task.
I just worked though a similar problem where I was trying to detect when a point in world space passed out of view of the camera and behind specific objects in the scene. I created a jsfiddle, (see below) for it. When the red "target" passes behind any of the three "walls" a blue line is drawn from the "target" to the camera. I hope this helps.

Threejs: Visible light for spotlight

In my current project I need to make a visible spotlight, just like one which calls batman. I mean that cone of light, that you can see on a night sky.
I haven't any graphical or 3d experience and I just can't make light visible.
Would be nice if you can show me how do that or give couple advice.
Here is codepen for experiments.
Thanks a lot.
P.S. I need visible whole cone, not just reflection from box.
JSFiddle Demo of batsignal-type spotlight
Lights (and shadows) can be tricky for many reasons. They have many parameters and require much tweaking to look right. Just getting light to show up can be a little counter-intuitive which is why this line of code is your best friend:
light.shadowMapVisible = true;
Light objects are not visible. If you look at one, you won't see anything. If you want a sun in a sky that lights up your scene, you must create the light source and the sun object if you want something to see.
Getting light to show up usually means providing a surface upon which light can shine. In the example above, that surface is a sphere that surrounds us. In our example, we also build a yellow transparent cone to fake the beam of light. Try adding a texture to this cone to achieve greater realism. In real life, this cone would be visible as light from a spotlight reflecting off tiny particles in the air. In our 3d world, there are no particles to reflect off of unless we put them there, hence the cone. Good luck!
Tips:
Remember that there are many kinds of lights. Some can cast shadows, some cannot. Some affect only certain materials.
The renderer has a parameter called "maxLights" that defaults to 4.

Transparency Face-Jumping?

I've been working on a WebGL project that runs on top of the Three.js library. I am rendering several semi-transparent meshes, and I notice that depending on the angle you tilt the camera, a different object is on top.
To illustrate the problem, I made a quick demo using three semi-transparent cubes. When you rotate the image past perpendicular to the screen, the second half of the smallest cube "jumps" and is no longer visible. However, shouldn't it still be visible? I tried adjusting some of the blending equations, but that didn't seem to make a difference.
What I'm wondering is whether or not this is a bug in WebGL/Three, or something I can fix. Any insight would be much appreciated :)
Well, that's something they weren't able to solve when they invented all this hardware accelerated graphics business and sounds like we'll have to deal with this for a long while.
The issue here is that graphic cards do not sort the polygons, nor objects. The graphics card is "dumb", you tell it to draw an object and it will draw the pixels that represent it and also, in another non-visible "image" called zbuffer (or depthbuffer), will draw the pixels that represent the object but instead of color it will draw the distance to the camera for each pixels. Any other objects that you draw afterwards, the graphics card will check if the distance to the camera for each pixel, and if it's farther, it won't draw it (unless you disable the check, that is).
This speeds up things a lot and gives you nice intersections between solid objects. But it doesn't play well with transparency. Say that you have 2 transparent objects and you want A to be drawn behind B. You'll need to tell the graphics card to draw A first and then B. This works fine as long as they're not intersecting. In order to draw 2 transparent objects intersecting then the graphics would have to sort all the polygons, and as the graphics card doesn't do that, then you'll have to do it.
It's one of these things that you need to understand and specifically tweak for your case.
In three.js, if you set material.transparent = true we'll sort that object so it's drawn before (earlier) other objects that are in front. But we can't really help you if you want to intersect them.

Categories