Frustum Far for specific Nodes

I didn’t know what to search for, and the first few searches didn’t yield any useful results. What I want is to check whether it is possible to achieve an effect like a camera’s far frustum effect, but on a node/s. This means that objects within a set distance are rendered, while the others are not. However, I’d like this to work only on a/some Node/s.



Say, for example, there’s a racing track and vegetation on the sides. I want the track to stay visible always, but the vegetation which is further than x units a way does not get rendered.



Thanks in advance.

you can do culling based on distance, its not the same but can hide specific Spatials, i.e

[java]spatial.setCullHint(CullHint.ALWAYS); // or w/e it is[/java]

I actually would do the opposite and treat the “special case” (the track in this case) as CullHint.Never since this is the known factor that will never change and should always be rendered no matter what the distance is.

If the track and ground are in chunks then you’d want to frustum cull them because you don’t want to waste time rendering the stuff behind you. CullHint.Never is probably pretty brutal in that case.



As for the track-side objects, etc. you are better off doing a control or something that turns them on and off based on distance. (Use a dot product on the camera’s look vector… it’s fast.) This would also allow you to do something fancy like fade them in and out when you learn enough to do stuff like that. This also lets you set the cull distance differently for different types of objects. A little bush probably wants to get culled much nearer than a giant tree or whatever.

I can’t understand how the dot product gives you the distance though.



Can I use this link to learn about dot product? (Because it’s about jME2)



http://test.hub.jmonkeyengine.org/wiki/doku.php/jme2:vector



Also, can the vectors be Vector3f?

Another final question; if an object is in front of the camera, would the result be positive? And if an object is behind, would would the result be negative?

Dot product is simple. It works in any dimensionality, 2D, 3D, 11D, whatever.



Given two vectors, the dot product is the scaled cosine of the angle between them.



This means that if one vector is a unit vector (like a direction vector) then the dot product is the distance of the other vector projected along that first direction vector.



You have to turn a position to a camera-relative vector to use it:

Vector3f relative = pos.subtract(camera.getLocation());



But then the dot product is the distance in front of you:

float dot = cam.getDirection().dot(relative);



dot will be positive in front of you and negative behind you. It is my favorite vector operation because it can be used for so many things.



(a mind blower: a matrix transform is 3 dot products with the three axis unit vectors that are the matrix columns… mind blower because when you know this you can look at a rotation matrix and “see” what the numbers mean. Less relevant with the rise of Quaternions which are just pure magic.)

1 Like

Thanks for your help.


dot will be positive in front of you and negative behind you. It is my favorite vector operation because it can be used for so many things.


So that means that if I am using a Chase Camera, anything I can see in front of me will result in a positive, and anything I can't see will result in a negative?

Also, is it fast? Would you recommend it if I was to use it every frame? Previously, I calculated the distance using only something like this:

Vector3f relative = pos.subtract(camera.getLocation());


However, when I had a lot of objects in the scene, the game ran very slowly.

pos.subtract is already doing 3 subtractions and creating a new object.



Were you doing length() as well? If so then you are really going to hit performance as you start getting requirements for multiplications and square roots etc.

@memonick said:
Thanks for your help.

So that means that if I am using a Chase Camera, anything I can see in front of me will result in a positive, and anything I can't see will result in a negative?


If you use the chase cams direction vector, then yes.

@memonick said:
Also, is it fast? Would you recommend it if I was to use it every frame? Previously, I calculated the distance using only something like this:
Vector3f relative = pos.subtract(camera.getLocation());
However, when I had a lot of objects in the scene, the game ran very slowly.


That will not give you distance. That only gets you a relative vector. You'd have to call length() on it to get distance and that requires a sqrt. (expensive)

A dot product with Vector3f is just 3 multiplies and 2 adds. Extremely fast.
@zarch said:
Were you doing length() as well? If so then you are really going to hit performance as you start getting requirements for multiplications and square roots etc.


The old rule of thumb used to be that if you gave add a score of 1 then multiply also gets a score of 1 and sqrt gets a score of 100 (divides used to be 10, I think). In benchmarking, sqrt is actually faster than that these days... but it is still a performance bottleneck. Avoid it when possible.

The dot product has other advantages in this case since it gives you screen-parallel distance and not raw distance. Raw distance causes weird artifacts like objects popping in and out as you turn since the object directly in front of you is closer than the one on the edge of the screen.

I wasn’t doing length(). I was keeping things simple and just calculating the Z-Distance (that’s what mattered in the game). It doesn’t require sqrt, but still made the game run very slow.

@memonick said:
I wasn't doing length(). I was keeping things simple and just calculating the Z-Distance (that's what mattered in the game). It doesn't require sqrt, but still made the game run very slow.


No it didn't. Unless you have a million objects then it was something else.

Never in a hundred years will v1.subtract(v2) cause a performance problem.

Unless he had a few hundred objects and was comparing them each against each other with a naive algorithm (n^2).

@zarch said:
Unless he had a few hundred objects and was comparing them each against each other with a naive algorithm (n^2).


But subtract() wasn't the problem, then.

Of course. The algorithm was the problem. However by that argument subtract() wasn’t the problem when he had a million objects either :wink:

Yeah, and either way, I’m still doubtful.



“Program was running fine until I added this subtract() in here.” Seems incredibly unlikely.

@pspeed said:
Yeah, and either way, I'm still doubtful.

"Program was running fine until I added this subtract() in here." Seems incredibly unlikely.


I can't argue with that :D

All I was doing was:


  1. for loop in the array of walls.
  2. Check the z-distance from camera to object,
  3. Add to rootNode (if it is not added) if the distance is smaller than x.
  4. Remove from rootNode (if it is not removed) if the distance is bigger than x.



    I’ll check it out tomorrow to see if I made any mistake. Won’t rule it out :smiley:
@memonick said:
3. Add to rootNode (if it is not added) if the distance is smaller than x.
4. Remove from rootNode (if it is not removed) if the distance is bigger than x.


Yikes. Yeah, n ^ 2 problem, roughly... depending on how you were determining if already added or already removed.

I guarantee you that it wasn't the subtract that was the problem.

I must have been making some mistake. It’s fixed now though :slight_smile:



This worked well:



[java]for (int i = 0; i < 100; i++){

if (a == true && (p - cam.getLocation().x) > 25){

y.detachChild(walls);

a = false;

}



if (a == false && (p - cam.getLocation().x) < 2){

y.attachChild(walls);

a = true;

}

}[/java]