After a bit of research I stumbled upon the following approaches to multi-texturing- using ARB_multitexture extension. Seems to be limited by available hardware units.- using GPU multitexturing using separate texture units. Also limited by available texture units on hardware
- using multi-pass rendering. Probably slower but not limited by hardware.
Question 1: Is there a way to generically supply the textures and UV coordinate sets and let OSG choose the best rendering technique from the list above?
There's no difference between these two. ARB_multitexture is a 15-year old extension that simply provides the specification for how multitexturing is done. Multitexturing has been part of standard OpenGL since version 1.3.
I doubt you'll need to resort to this, but with the vague description of what you're doing, I can't be 100% sure.
- using multi-pass rendering. Probably slower but not limited by hardware.
If this is true, you can generate the texture coordinates directly from the position/orientation of the photo and the positions of each vertex in the mesh. Read up on projective texturing to see how this is done. OSG can do this easily if you write a shader for it, or you can use the osg::TexGen state attribute to handle it for you (it works just like glTexGen in regular OpenGL).
The other thing you'll need to do is divide up the mesh so that only the faces that are covered by a given photo or photos are being drawn and textured by those photos. This will eliminate the need for you to have as many texture units as there are photos. There may be regions of the mesh where you want to blend two or more photos together, and this is the only time where you'd need multitexturing. You should be able to handle this mesh segmentation with a not-too-complicated preprocessing step.
Hi Jason,
On Tue, Oct 23, 2012 at 5:27 PM, Jason Daly <jd...@ist.ucf.edu> wrote:
There's no difference between these two. ARB_multitexture is a 15-year old extension that simply provides the specification for how multitexturing is done. Multitexturing has been part of standard OpenGL since version 1.3.
Ok I see, I stumbled upon this terms when looking at
I doubt you'll need to resort to this, but with the vague description of what you're doing, I can't be 100% sure.
- using multi-pass rendering. Probably slower but not limited by hardware.
Actually what I do is that I have a mesh that is generated from depth-maps. In a post-processing step I want to apply photos (taken by arbitrary cameras, but with known intrinsics) as textures. What I know is the position of which the photo was taken (relativ to the mesh) and the camera intrinsics.
How can TexGen and a shader help here? Would it allow me to calculate the UV coordinates for a given photo (camera position etc.) and the mesh?
I wanted to avoid splitting the mesh, at least for the internal representation (which I hoped included visualization). Pros and cons have been discussed in this thread (in case you are interested)
The more I think about it, the more I think you'll want to use a shader for this. The basis for your technique will be the EYE_LINEAR TexGen mode that old-fashioned projective texturing used, so you'll probably want to read up on that. There's some sample code written in pure OpenGL here:How can TexGen and a shader help here? Would it allow me to calculate the UV coordinates for a given photo (camera position etc.) and the mesh?
http://www.sgi.com/products/software/opengl/examples/glut/advanced/source/projtex.c
The equation used for EYE_LINEAR TexGen is given in the OpenGL spec. You can also find it in the man page for glTexGen, available here:
http://www.opengl.org/sdk/docs/man2/xhtml/glTexGen.xml
Once you're familiar with that technique, you'll probably be able to come up with a specific technique that works better for your situation.
Another benefit of using shaders is that you'll be able to do any blending, exposure compensation, etc. that you might be needing to do really easily as part of the texturing process.
You might not need to segment the mesh. If you don't segment the mesh, it means that you'll have to have all of your photo textures active at the same time. Most modern graphics cards can handle at least 8, decent mid range gaming cards can handle as many as 64, and the high-end enthusiast cards can even hit 128. If you're photo count is less than this number for your hardware, you'll probably be OK. You'll just need to encode which photo or photos are important for each vertex, so you can look them up in the shader, you'd do this as a vertex attribute.
Your photo texture samplers will be one set of uniforms, and you'll need another set to encode the photo position and orientation, as these will be needed to calculate the texture coordinates. You won't need to pass texture coordinates as vertex attributes, because you'll be generating them in the vertex shader. As long as you don't have more than a few photos per vertex, you shouldn't have any issues with the limited number of vertex attributes that can be passed between shader stages.
Thanks for the hints. From browsing the documentation it seems though that this would also texture non-visible triangles (i.e backfacing triangles)? This however would lead to messy texturing, since I have photos from around the mesh.
Once you're familiar with that technique, you'll probably be able to come up with a specific technique that works better for your situation.
Another benefit of using shaders is that you'll be able to do any blending, exposure compensation, etc. that you might be needing to do really easily as part of the texturing process.
I think I'd need a starter sample for how to use EYE_LINEAR in combination with a shader.
Your photo texture samplers will be one set of uniforms, and you'll need another set to encode the photo position and orientation, as these will be needed to calculate the texture coordinates. You won't need to pass texture coordinates as vertex attributes, because you'll be generating them in the vertex shader. As long as you don't have more than a few photos per vertex, you shouldn't have any issues with the limited number of vertex attributes that can be passed between shader stages.
That sounds interesting. You don't have an example at hands?
A rather related problem is the export of meshes. Using the shader approach, how would one deliver such a textured mesh? Wouldn't it make more sense to pre-calucate the UV coordinates for each vertex/foto infront (incl. visibility detection) and pass this to the shader (possible?), so that I could decide on file export (based on the format chosen) to either- split the mesh if the format does not support multiple texture layers (.ply/.obj maybe).- don't split the mesh if the format supports multiple layers (.fbx)
Hi Chirstoph,
I'm surprised by you not getting any replies, guess everyone has been
busy, or perhaps confused by what you are after.
It sounds like to me you just need to use the OSG's standard
multi-texturing support, the OSG will manage handling of OpenGL
versions/extensions for you so you won't need to worry about the
OpenGL backend. All modern OpenGL hardware supports multi-texturing
with the fixed function pipeline and with GLSL shaders, with GLSL you
have greater flexibility and range of units that you can use.
How many textures do you want to assign to a single mesh?
On 10/24/2012 03:03 AM, Christoph Heindl wrote:
Ah, yes. If you want to end up exporting the mesh, then a real-time shader might be a problem. It's not impossible, as there are formats like COLLADA that allow you to embed shaders, but from my experience, run-time systems don't often fully support those features.
If you do need to export to a static format (like fbx), then I don't see a way around splitting the mesh. If your maximum photo count is 64, there's no way you can have all of the textures enabled and statically mapped at the same time (that would mean you'd need 64 sets of texture coordinates, and no graphics card supports that many vertex attributes).
I think you'd need to do an initial pass to see which photos cover which vertices, then divide up the mesh accordingly. Only one (maybe two or three) textures will need to be active for each patch, which means you'd only need at most three sets of texture coordinates for each vertes. This should be exportable to one of several modern formats. Yes, you'll have some duplication of vertices along the boundaries, but this isn't really a huge problem. The vertex processing most likely isn't going to be your bottleneck here.
Maybe someone smarter than me can come up with a solution that doesn't require splitting the mesh, but I don't see one...
This might well push you over the limit supported by fixed function
pipeline on your hardware so it's likely you'll need to look at using
GLSL shaders. As you have a pretty straight forward usage case this
won't require anything too complicated.
With OpenGL the whole mesh will be textured by all textures you apply,
the way to get non and textured parts for areas outside the texture
coordinate range 0,0 to 1,1 is to set a alpha value of 0 for the
border colour, something like (1,1,1,0) would be appropriate. However
if you are using GLSL you can use test the texture coordinate prior to
reading the texture and then just blend the colours as you require.
It's not really me place to teach you GLSL so I have to recommend that
you look at online resources for GLSL, and on the OSG side have a look
at the osgshaders example and any other places where osg::Program
crops up in the OSG examples or code base.
I think you'd need to do an initial pass to see which photos cover which vertices, then divide up the mesh accordingly. Only one (maybe two or three) textures will need to be active for each patch, which means you'd only need at most three sets of texture coordinates for each vertes. This should be exportable to one of several modern formats. Yes, you'll have some duplication of vertices along the boundaries, but this isn't really a huge problem. The vertex processing most likely isn't going to be your bottleneck here.
I agree, but I think for further mesh processing duplicate vertices could be problem (decimation, ...).
Maybe someone smarter than me can come up with a solution that doesn't require splitting the mesh, but I don't see one...
Just one more thought. In my research I found that most modelling software support UV unwrapping (not sure if it is the right term). What I mean is that the user marks a seam on the mesh and the mesh is then unfolded along that seem into individual patches that can be mapped to the UV space. Do you know how such seams are handled by the rendering engine? It seems naturally to me that at seems one need to split the mesh and duplicate vertices.
I would try multipass rendering first. It is likely to be the slowest, but also probably the easiest to implement and you don't have to worry about exceeding your hardware limits. This falls into the category of "just get it working" and then worry about optimizing it later if necessary. Who knows -- maybe the performance will be acceptable.
Right. So for multipass in general, you have a root node; then under that node there is one Group node per pass; then all these Group nodes share a common child (the geometry to render). Each per-pass Group node can hold a unique StateSet that assigns the proper texture, etc.
Since you will also need to use the TexGen capabilities (discussed earlier in this thread) to generate the correct texture coordinates for each pass, you might use an osg::TexGenNode in place of the osg::Group. TexGen will generate the UV coordinates for you.
You might also look at the osgFX::Effect class. This is a framework for rendering a subgraph multiple times (multipass), using a separate StateSet for each pass (just what I described above) so it might be a good fit, or at least good reference material.
On Fri, Oct 26, 2012 at 3:57 PM, Glenn Waldron <gwal...@gmail.com> wrote:Right. So for multipass in general, you have a root node; then under that node there is one Group node per pass; then all these Group nodes share a common child (the geometry to render). Each per-pass Group node can hold a unique StateSet that assigns the proper texture, etc.Very clever. Thanks for sharingSince you will also need to use the TexGen capabilities (discussed earlier in this thread) to generate the correct texture coordinates for each pass, you might use an osg::TexGenNode in place of the osg::Group. TexGen will generate the UV coordinates for you.I don't think so, as I already have the UV coordinates. I calculate them myself in order to allow for camera lens distortions and such. I think that TexGen (EYE_LINEAR) mentioned previously assumes a plain pinhole camera model without regarding effects from lens distortion.
You might also look at the osgFX::Effect class. This is a framework for rendering a subgraph multiple times (multipass), using a separate StateSet for each pass (just what I described above) so it might be a good fit, or at least good reference material.Sounds good, just the name (Effect) puzzles me. From looking at the documentation it seems that actually a lot of effects such as outlines, glow etc are done with that.
Hi Christoph,
If you use your own shaders then you'll be able to compute the ST
On 26 October 2012 17:04, Christoph Heindl <christop...@gmail.com> wrote:
>> Since you will also need to use the TexGen capabilities (discussed earlier
>> in this thread) to generate the correct texture coordinates for each pass,
>> you might use an osg::TexGenNode in place of the osg::Group. TexGen will
>> generate the UV coordinates for you.
>
>
> I don't think so, as I already have the UV coordinates. I calculate them
> myself in order to allow for camera lens distortions and such. I think that
> TexGen (EYE_LINEAR) mentioned previously assumes a plain pinhole camera
> model without regarding effects from lens distortion.
coordinates (what OpenGL calls the UV coords) and do something more
sophisticated than standard OpenGL TexGen.
For cases where the ST coordinates can't be computed in object or eye
coordinates then you'll need to rely upon the UV coords that you've
computed. The OSG supports as many texture units as the underlying
OpenGL implementation supports and will scale up to 8 without problem
on most hardware/drivers. Going this route would be the most straight
forward.
For cases where the ST coordinates can't be computed in object or eye
coordinates then you'll need to rely upon the UV coords that you've
computed. The OSG supports as many texture units as the underlying
OpenGL implementation supports and will scale up to 8 without problem
on most hardware/drivers. Going this route would be the most straight
forward.
Another idea is to use a TextureArray (GL_EXT_texture_array). This removes the limit on the number of textures, but adds the constraint that they all must be the same size and that you need GL 2.0.
Another idea is to use a TextureArray (GL_EXT_texture_array). This removes the limit on the number of textures, but adds the constraint that they all must be the same size and that you need GL 2.0.
On 10/26/2012 01:19 PM, Glenn Waldron wrote:
From what I can tell, the main issue isn't the number of textures, it's the number of varying parameters between the vertex and fragment shader. If there are too many textures being applied at once (each with their own set of texture coordinates), it may be possible to run out of these, depending on what else is being interpolated between shader stages.
How are they stored? Per vertex? Or is it some kind of regular grid that does distortion correction? Is the computation something you could do in a vertex shader if the shader can access to the camera parameters?