Are there non-projective decals?

Anything and everything that's related to OGRE or the wider graphics field that doesn't fit into the other forums.
Post Reply
pierreofthefrench
Halfling
Posts: 75
Joined: Sat Jul 17, 2010 9:43 pm
Location: Binghamton University
x 3

Are there non-projective decals?

Post by pierreofthefrench »

I noticed the tutorial on projective decals and it seemed alright but I was wondering. Why can't a decal be permanently placed on a current texture , thus replacing the old one with the new one. This wouldn't require several passes to render because it would always be a single texture correct? I would like to add bullet hole decals to the mesh textures the projectile hits but the only tutorial I could find was that projective decal one. Is there any other way to achieve this goal more efficiently? Thanks.
jonim8or
Goblin
Posts: 287
Joined: Mon Dec 08, 2008 4:49 pm
x 10

Re: Are there non-projective decals?

Post by jonim8or »

You could literally copy the bullethole texture on the surface texture. However, that only works if you don't re-use textures. So no repeating texture, no using of the same wall texture on different walls, etc. So I guess that won't work for most of the games.
pierreofthefrench
Halfling
Posts: 75
Joined: Sat Jul 17, 2010 9:43 pm
Location: Binghamton University
x 3

Re: Are there non-projective decals?

Post by pierreofthefrench »

Ahh, I see what you mean. I guess only by creating a brand new texture for that entity would it be possible which I'm sure would be inefficient to create an entire new texture every time a decal is placed. Makes sense now, thanks. Guess I will be looking more into the projective decals :)
Guardian121
Gnoblar
Posts: 9
Joined: Sun Nov 29, 2009 1:24 am
x 1

Re: Are there non-projective decals?

Post by Guardian121 »

Does it have to involve the texture, if not, cant you just do geometry clipping?
Sinbad wrote a few ways dealing with decals here http://www.ogre3d.org/forums/viewtopic.php?f=2&t=35131
User avatar
Praetor
OGRE Retired Team Member
OGRE Retired Team Member
Posts: 3335
Joined: Tue Jun 21, 2005 8:26 pm
Location: Rochester, New York, US
x 3
Contact:

Re: Are there non-projective decals?

Post by Praetor »

General technique is this:

Take a frustum (6 planes) that you place however you feel like. Intersect those planes with the world geometry. Collect the intersected triangles into a new object geometry (you could use ManualObject for this, extra points for doing it with raw vertex and index buffers). You then run through and either replace existing texture coordinates or add a new texture coordinate channel with the "projected" texture coordinates. If you use Ogre's camera class to represent the projector here then the projection matrix needed to do this is managed for you. Otherwise you can do it yourself without too much trouble. Then you can apply whatever material you like to these decal objects to make them look like bullet holes, blood splatter, posters, etc.

You get extra extra points if during the geometry intersection test you handle the case where the frustum plane splits the triangle by actually doing the split calculation instead of just accepting the straddled triangle. Then you get a tight intersection to your projector. May or may not be worth the extra calculation (depends on the kind of material you want to use, how many split triangles there are, and how much waste (triangle sticking outside the frustum) you are willing to accept).
Game Development, Engine Development, Porting
http://www.darkwindmedia.com
pierreofthefrench
Halfling
Posts: 75
Joined: Sat Jul 17, 2010 9:43 pm
Location: Binghamton University
x 3

Re: Are there non-projective decals?

Post by pierreofthefrench »

This is a bit late but thanks! I'm revisiting this now and I just noticed that there were answers past I last thought :) The explanation is great even though I don't really understand it completely. I will certainly research the concepts on my own and see if I can figure it out. Thanks again.
pierreofthefrench
Halfling
Posts: 75
Joined: Sat Jul 17, 2010 9:43 pm
Location: Binghamton University
x 3

Re: Are there non-projective decals?

Post by pierreofthefrench »

Okay it's been a while but I started looking into your solution and this is about what I have gotten to... So you mention a frustrum and I'm guessing sine you mentioned a camera this will be used to determine if the decal that will be placed is even in sight. Then if so check the area around where the collision occured which I was going to do with a Ray->Triangle intersection and then place a AABB at that point the size of the decals material. Then, check the for triangle collisions with the AABB. After the triangles that collided are returned create a ManualObject model with these triangles only moving their points up slightly in front of the geometry it collided with and set the ManualObjects material to the texture of whatever the decal is (blood or bullet hole etc) illustrated poorly by:

Image

I wasn't sure if the manual materializing would be possible as in centering the material at a certain point on the geometry but I will certainly look into it. I was just wondering if there was anything I forgot to do or should be doing. Thanks again.

EDIT: Well it's been going relatively well, I think I have most everything working except there is a major hurdle before I can complete this system, I need to make the collided triangles lay flat on the ground (maintaining their shape) so that I can map them to the texture (so there will be no stretching or tearing of the texture) this mathematical process has been plaguing me for a few days now.
pierreofthefrench
Halfling
Posts: 75
Joined: Sat Jul 17, 2010 9:43 pm
Location: Binghamton University
x 3

Re: Are there non-projective decals?

Post by pierreofthefrench »

If anyone is curious this is how far the mesh based decal system has progressed thus far. Still a lot of bugs to work on but I think its starting to come around :)



Edit: Newer video
Olive
Gnoblar
Posts: 2
Joined: Fri Jan 15, 2010 4:14 pm
Location: France

Re: Are there non-projective decals?

Post by Olive »

Hi,

Really good video.
I'm also trying to do some decals like in your video but I'm really far from your result.
Is it possible that you post your code ?

Thanks
User avatar
Pangamini
Gremlin
Posts: 179
Joined: Fri Sep 17, 2010 2:21 pm
Location: Kosice, Slovakia
x 3
Contact:

Re: Are there non-projective decals?

Post by Pangamini »

Does every decal/spill/bulet hole produce a batch?
Ancient Greeks did have a culture, but they didn't have gasoline.
...and we have gasoline.
chairman
Gnoblar
Posts: 5
Joined: Mon Sep 26, 2011 8:23 pm

Re: Are there non-projective decals?

Post by chairman »

I'm not sure if anyone is still using this, but I have a question regarding the method that pierre implemented. I'm having problems at two points during this implementation.

When creating the bounding box, the 3 dimensions of the box should match the 2 dimensions of the decal, but that would only work if the decal's width and height are equal. It would probably have to check the normal of the hit-point and create the box depending on that.

The one thing I'm having a lot of difficulty with is understanding how to get the texture to map onto the ManualObject. So far, I'm using the code from http://www.ogre3d.org/tikiwiki/Raycasti ... ygon+level to test collision of each triangle on a mesh with the bounding box, and storing the ones that collide to be used in the ManualObject's creation. The ManualObject still has to be UV mapped, though, and I'm not entirely sure how to go about this because the number of triangles that intersect will always be variable. Does anyone have ideas/suggestions?
pierreofthefrench
Halfling
Posts: 75
Joined: Sat Jul 17, 2010 9:43 pm
Location: Binghamton University
x 3

Re: Are there non-projective decals?

Post by pierreofthefrench »

Been a long time since I checked this post! I didn't think anyone would be interested, my codes not pretty but I wouldn't mind sharing some of it for technical help. Let me dig through the mess of that tech demo and see if I can pick out the texturing portion.

Oh wow, it's horrible big surprise. the texturing goes a little something like this:

Code: Select all

Ogre::ManualObject * manual = mSceneMgr->createManualObject();
std::string material_name = "Blood"; 
manual->begin(material_name, Ogre::RenderOperation::OT_TRIANGLE_LIST); 
for (int i = 0; i < indicies; i++) {
	Ogre::Vector3 p1 = vertices_model[indices[tris[i]]];
	Ogre::Vector3 p2 = vertices_model[indices[tris[i]+1]];
	Ogre::Vector3 p3 = vertices_model[indices[tris[i]+2]];

        // The pain is converting your triangles from 3d space to 2d (which can be done relatively easy just taking two edges and the angle between them!
        // Then you have to line them up together on the texture (find two common points between connected triangles and rotate the attached (not the original starting one)
        // so that they line up. You will want to use some linear algebra to determine if the angle between them is acute or obtuse. (Dot product)

        manual->position(working+tri_norm);
        manual->textureCoord(temp1, temp2);
       //...
       manual->position(working+tri_norm);
       manual->textureCoord(temp1, temp2);
       //...
       manual->position(working+tri_norm);
       manual->textureCoord(temp1, temp2);

       manual->triangle(working_index*3,working_index*3+1,working_index*3+2);
}

Ogre::MeshPtr ptr = manual->convertToMesh(s);
Ogre::Entity *GEMEntity = mSceneMgr->createEntity(s2, s);
Ogre::StaticGeometry *sg = mSceneMgr->createStaticGeometry(s + s2);
sg->addEntity(GEMEntity, Ogre::Vector3(0.0, 0.0, 0.0));
sg->build();


One problem I found is when the angle between triangles is 90 degrees, you can't tell what way to rotate it. That's the special case where this method fails.
something like:

((m1tx-m1bx)*(m2tx-m1bx) + (m1ty-m1by)*(m2ty-m1by)) == 0

I'm not sure if this code helps you out at all, the actual code is horrible... I'm having trouble remembering what all of it does. The concept still stands the same though. I'll try and decipher more code if you guys want!
chairman
Gnoblar
Posts: 5
Joined: Mon Sep 26, 2011 8:23 pm

Re: Are there non-projective decals?

Post by chairman »

I'm sorry, I don't really follow that well. Converting from 3D to 2D and then lining it up against the texture..., sorry, but can you go into a bit more detail with how to do those?

Also, maybe I don't know enough about ManualObjects since this is my first time using them, and maybe this isn't the best place to ask, but when using the textureCoord() function after a position(), is a triangle still created afterwards? Or is that just applying that position to the texture, so you have use a triangle function at the end?
pierreofthefrench
Halfling
Posts: 75
Joined: Sat Jul 17, 2010 9:43 pm
Location: Binghamton University
x 3

Re: Are there non-projective decals?

Post by pierreofthefrench »

Yeah to be honest, I never used manual object until I hacked together this code 8) this is the same set up I have in my code, most of that is straight from my code which has a few missing elements. But from what I can tell you need to do it that way for the triangles to be generated (though I didn't really try any other methods). I could be doing this completely wrong in terms of syntax which is why the logic might be more useful than actual code.

In terms of the converting from 3d to 2d this is the general approach I took:

Code: Select all

1) Using the raycast you get the triangle you hit along with the point it hit (this will be used when offsetting the triangles texture coordinate)
2) You will want to do some sort of additional hit detection to get all the possible triangles that the decal will cover ( I used a bounding box approach )
    This will get you all the triangles the decal potentially will cover (the bounding box should be large enough to contain the decal at any rotation)
3) now that you have all of the triangles and the offset you can begin setting up the texture coordinates
4) First take the triangle that was hit by the raycast and convert it into 2d (texture coordinate)
    This is done by:
          a) Taking two sides of the triangle and getting their lengths.
          b) taking these two vectors and getting the angle between them
          c) Now you can plainly convert it into 2d (make one along the x axis (centered at 0) then rotate upwards the angle between them placing the second point)
          d) Now you want to find that offset, this is done the same method as above but instead of using 2 points above, you use the one that you place on the x axis and the collision point
          e) Focus this around the x-axis as you did with the original and now you have the point in the x,y plane where the collision point is
          f) Now you have your raycast collision triangle in 2d and the point at which the raycast hit that triangle also in 2d
          g) Use this as an offset and shift the (0,0) origin by the offset (After this you have 1 triangle created and correctly offsetted on the texture so that the texture is centered where the raycast hit)
          h) Now you essentially just have to recursively do the same for triangles connected to the centered one and connect them to the texture coord of the original
               i) This provides the problem of when converting to 2d you do not maintain the original orientation so you have to do the following:
                    1) Find the two points that the connected triangles have in common.
                    2) find the correct offset by 'attaching' one of the points of the new triangle to the one you already computed
                    3) rotate the new triangle so that the second point (that was not attached) is correctly over the already computed ones equivalent
          i) repeat 'h' until all connected triangles that were found during the bounding box detection have been created and texture coords were generated
          j) Also, you will need to offset the created decal triangles by a value of their norm (so they are not directly over the other triangle but slightly in front)
5) Done!
There is one limitation to this approach however, I didn't account for if two polygons go through each other but are not connected, the decal will only be applied to the one that has the raycasted triangle collision.

So, 4 is essentially what I'm guessing you would like to do. It is not trivial that is for, took me a few weeks to work out all of the bugs/equations to get the end result. I hope this is helpful, I can MS-Paint up a diagram explaining the same general concept if you would like too. This may not necessarily be the best way of adding this functionality, it's just what I was able to hack together. At one point I will be cleaning up this code and snippets of that may be more helpful but it's current state would most likely just be a hassle to understand. The above is essentially the entire process though.
Post Reply