Determine a mesh is covered by other mesh (shade)?

Blitz3D Forums/Blitz3D Programming/Determine a mesh is covered by other mesh (shade)?

RustyKristi(Posted 2016) [#1]
This is kind of how you project shadows but you just mark it if it's covered up. I know entity visible will do this but maybe something better like raycasting?


RemiD(Posted 2016) [#2]
Yes you could use linepicks and low details pickables, or color each thing in a different color and fullbright and do a small render from the point of view of the light, then analyze which colors are in the image of the small render.

See this discussion :
http://www.blitzbasic.com/Community/posts.php?topic=103889 (#5 #7 #8)
(not about shadows but about how to detect if a shape is visible or masked by another)


Kryzon(Posted 2016) [#3]
An alternative is to use shadow volumes, and do some tests to see if the object is contained in that volume.
http://www.gamedev.net/page/resources/_/technical/graphics-programming-and-theory/the-theory-of-stencil-shadow-volumes-r1873


RustyKristi(Posted 2016) [#4]
@Kryzon
Is there an existing example here where I can test it out?

I just need a couple of cubes and probably a cylinder which will represent the dynamic object.

@RemiD

Say I have a dir light at 300,300,300 and I want to obscure a dynamic object like a cylinder and there are cube walls that are high enough to block the angle. It's like casting a shadow but just dimming the dynamic object when it gets covered enough.

I don't know if entityvisible will do but maybe I'll give it a try.


Cube 2 engine does this exact thing mix with stencil shadows for player shadows




Kryzon(Posted 2016) [#5]
The only plug-and-play example I know of is the Devil Shadow System:
https://bytecode77.com/coding/devilengines/devilshadowsystem

With what you added on the problem, Quake 1 had a simple dynamic lighting effect by sampling the lightmap texture at the point below the character and modulating the lighting of the character based on that sampled value.
So if you're walking on part of the ground that's shadowed, the character would get dark. It's not really accurate but it helped sell the effect.

To do something like this you would have to pick UV coordinates of the level mesh below the character:
http://www.blitzbasic.com/codearcs/codearcs.php?code=2895
Don't forget that this code archive gets the UV coordinates for the first texture coordinate channel, and lightmaps are usually put on the second. You'd have to modify that function, the VertexU and VertexV calls, by setting to 1 the "coord_set" parameter:
http://www.blitzbasic.com/b3ddocs/command.php?name=VertexU&ref=3d_cat


RustyKristi(Posted 2016) [#6]
Thanks Kryzon.

I did some test with entityvisible and it looks like this will do.

Graphics3D 640,480,0,2

SetBuffer BackBuffer()

Sphere1 = CreateSphere(25)
PositionEntity Sphere1,0,0,-3
EntityColor Sphere1,255,0,0
EntityPickMode Sphere1,2,1

Box = CreateCube()
ScaleEntity Box,2.4,2.5,0.2
PositionEntity Box,0,0.75,0
EntityColor Box,200,200,200
EntityPickMode Box,2,1

Plain = CreateCube()
ScaleEntity Plain,5,0.000001,5
PositionEntity Plain,0,-1,0

Texture = CreateTexture(128,128)
SetBuffer TextureBuffer(Texture)
ClsColor 0,0,0 : Cls

For X = 0 To 128 Step 7.7
   Color 255,0,0 : Line X,0,X,128
Next

For Y = 0 To 128 Step 7.7
   Color 255,0,0 : Line 0,Y,128,Y
Next

EntityTexture Plain,Texture
SetBuffer BackBuffer()

Sphere2 = CreateSphere(25)
PositionEntity Sphere2,0,10,10
EntityColor Sphere2,255,255,0
EntityPickMode Sphere2,2,1

Camera = CreateCamera()
PositionEntity Camera,5,15,10
PointEntity Camera,Box

Light = CreateLight(1,Camera)

While Not KeyHit(1)

   If KeyDown(203) Then MoveEntity Sphere1,0,0,-0.03
   If KeyDown(205) Then MoveEntity Sphere1,0,0,0.03

   Visible = EntityVisible(Sphere1,Sphere2)

   UpdateWorld
   RenderWorld

   If Visible = 1 Then
      Color 255,255,255
      Text 0,0,"ball 1 is out in the sun"
	EntityColor Sphere1,255,0,0
   Else
      Color 255,255,255
      Text 0,0,"ball 1 is in the shade"
	EntityColor Sphere1,139,0,0
   EndIf
   Flip
Wend
End


I have some 200 walls that I need to reiterate to check if it's blocking. Do you think this will cause some performance?


RemiD(Posted 2016) [#7]
if i remember correctly, entityvisible is similar to linepick, but it is a thin 3dline between the entity root and the otherentity root, and so it is not a precise way to check if the entity is visible or not.

You may want to use several linepicks from the entity to different parts of the other entity and throw linepicks with a radius (not a thin 3dline)


Bobysait(Posted 2016) [#8]
EntityVisible use the picking methods to check if an entity is visible from a source.
it's not very fast and inacurate for any other "receiver" that is not a sphere (it only check a radius -> so it works pretty well for a sphere, but it 's a poor method for a cube).

but ... All really depends on your expectation (as 200 walls is not a big deal for collisions, unless you're using a low CPU, and shape precisions are not always that important, most of the time, the feeling it gives is good enough).
In the end, there is only one rule to follow -> the only thing that is important is whether or not it works in your context (as all implementation always depend on a context ^^).


RustyKristi(Posted 2016) [#9]
thanks, I guess this will have to do and I'm good with it.

@RemiD

I did post an example above, it's good for me. If you can modify it a little bit to present what you are trying to suggest then I would appreciate it.


RustyKristi(Posted 2016) [#10]
checking 20 entities works great but halfs my framerate. Maybe it is faster using threads or any suggestions?

RenderWorld

For e.obj = each obj
  visible = EntityVisible(e\mesh, light)
  if visible then EntityColor e\mesh,255,255,255
  else EntityColor e\mesh,0,0,0
Next

Flip



RemiD(Posted 2016) [#11]

If you can modify it a little bit to present what you are trying to suggest then I would appreciate it.


just add more pivots childs of your entity (or of the joints/bones of your rigged entity) an try to pick them...


Some possible optimizations :
-use only low details pickables (with entityalpha 0 so that they are considered for the picks but not rendered).

-check which entities are near enough and which entities are too far (with a distance check) and only set the near enough entities as pickable.

-separate your map in different zones (connected by passages) so that you only have to browse the lists of the entities in the active zone and in the zone connected to this zone.


you may want to search for "line of sight" "ai sight" "ai view" on the forums/codearchives, there are several examples related to this.


RustyKristi(Posted 2016) [#12]
ok thanks, maybe the low details pickable would work. will try this one


RustyKristi(Posted 2016) [#13]
still slow with cube as mesh, using entityvisible and before renderworld, show hide toggle


RemiD(Posted 2016) [#14]
If i understand what you want, there is another way :
Have a 3 dimensions arrays where each entry represents a small 3d area of your zone (like many small cubes, and the interior of each cube being the small 3d area, let's say that each small 3d area would measure 0.1x0.1y0.1z unit)
Then precalculate for each small 3d area, if it is visible from the light or not (if yes the small 3d area will be lighted, if no it will be in the shadows).
Then after you have turned moved your character, determine in which small 3d area each bodypart is, and then you can light/shade the bodypart accordingly.

It is probably doable and faster than to use many linepicks, but maybe a little complicated to code...


Bobysait(Posted 2016) [#15]
Your best bet is with bsp tree but, it's still under license, and it's a bit hard to implement.

For best performances, improve the picking method by simplifying the pickmode to the maximum -> use as many entityradius (elipsoid pickmode) as possible and entitybox if radius is not relevant. Then if really required use polygon pickmode on simplified meshes.

And by the way, you can pre hide/show the most relevant entities by yourself, so the picking update will be really faster -> just a quick distance test from camera to entities may be relevant (I suppose) to eliminate anything that wouldn't be usefull to "occlude" with your method
(outside the range, hide the entities, do your entityvisible test, then show the hidden stuff)
And as, you'll do it for maybe several entitites, you'll have "pairs" of entities to test -> occluders vs receivers, so you can minimize this by unpairing stuff that is not relevant to the receiver you're testing.
Finally, you can also use the list of the last frame to get an optimization (it will mostly be the same, so no reason to update it on each frame -> just perform a full update after some loop and if the entities have moved)


RustyKristi(Posted 2016) [#16]
With the hideentities and distance stuff, it gets faster but the performance fluctuates and it looks worse than before.

If I can batch them and not use for loop, will it perform master? I guess I have to try.


RustyKristi(Posted 2016) [#17]
@RemiD No it's actually simple and applies to the whole mesh, not body parts.


RemiD(Posted 2016) [#18]
If you use "lightmaps", you could also use a combination of what Kryzon suggested and what i suggested...


Kryzon(Posted 2016) [#19]
Thread reminded me of this:
http://www.blitzbasic.com/Community/posts.php?topic=94413

It's the largest-scale shadow map demo there's been around. Everything uses the same system, so all objects cast shadows on each other.


RustyKristi(Posted 2016) [#20]
Thanks Kryzon. That was a good demo but it uses FastLibs which I cannot consider adding.

@RemiD

Detecting lightmaps is quite complicated or I'm not familiar with it.

@BobySait

Finally, you can also use the list of the last frame to get an optimization (it will mostly be the same, so no reason to update it on each frame -> just perform a full update after some loop and if the entities have moved)


how do you do this?


RemiD(Posted 2016) [#21]
@RustyKristi>>a "lightmap" is a texture with lighting/shading/shadows informations made of texels.
Each triangle will be texelsfilled (have xtexels*ytexels depending in the texel size you chose), uvmapped, then its texels will be colored depending on the distance between the light and the texel, the orientation of the texel (= the orientation of the triangle), and if you want shadows, depending on if the texel can be reached or not by the light->texel vector (there can be obstacles such as columns, containers, furnitures, machines, rocks, plants, etc...).

So, if you use a small enough texel size so that they are not noticeable (for texels lighting/shading, i suggest to use 1texel for each 0.1unit) and if the texel size is not too small either (because it is unecessary and will waste HD space and memory and increase rendering time), then you could create for each texel of your "lightmap", a corresponding 3d pivot/point (that you could store in a 2d array), that you could then use (after a distance check) to know how to light/shade your character mesh (or the bodyparts of your character)

Or, as Kryzon suggested, you could pick the triangle below the character and retrieve the corresponding texel at pickedU,pickedV, but i am not sure if this is fast enough to do that each loop...


Rick Nasher(Posted 2016) [#22]
Well, just in case that someone finds it useful, I remember the example mentioned by Kryzon is sitting on my drive. So here's the ProShadows_008(sdk), which actually contains the multi-shadows code and media(posted in original thread too, just in case).
Enjoy.


RustyKristi(Posted 2016) [#23]
Thanks Rick Nasher.