Projective Texture Mapping (15 posts)

Topic tags: post processor, Projective Texture Mapping, SceneProcessor
  • Profile picture of survivor survivor106p said 4 months, 1 week ago:

    Update:
    - “(Single)TextureProjectorRenderer” is default again. I said multi would be faster, but that was a mistake.
    - Some refactoring:
    — “ProjectiveTextureMapping1pass” -> “ProjectiveMultiTextureMapping”
    — “TextureProjectorRenderer1pass” -> “MultiTextureProjectorRenderer”
    - Z-fighting fix “setPolyOffset(-0.1f, -0.1f)” by default
    - Different CombineMethods in “MultiTextureProjectorRenderer”
    - Bugfixes
    - ul and li don’t work btw :D

    Snapshot: ProjectiveTextureMapping-2012-03-15.zip

    I wrote a post processor which does Projective Texture Mapping. See also this paper by nVidia. It is related to the thread Projected Texture on this forum.

    Features:
    - Can project an arbitrary number of textures onto scene geometry
    - You can choose which geometry shall be affected (GeometryList)
    - Perspective and parallel projection
    - Back projection and backside projection fixed
    - Fall off distance and fall off power to limit the projection

    Video demonstration of latest version (note the rune is just projected onto one geometry):

    Motivation:
    A use case of projected textures are targeting circles and ground effects known from popular MMOs by BlizZzard and Buy-o-ware. It can also be used to simulate the light cone of a flashlight/torch.

    The code including a test application can be checked out here:
    http://code.google.com/p/survivor-jme/source/browse/#svn%2Ftrunk%2FProjectiveTextureMapping

    Please note that this is work in progress. It might change frequently and it will surely have bugs.

    Future work:
    I’m planning to write a shader that can do all in one pass like this:

    uniform vec3 m_ProjectorLocation[NUM_PROJECTORS];
    uniform mat4 m_ProjectorViewProjectionMatrix[NUM_PROJECTORS];
    
    for (int i = 0; i < NUM_PROJECTORS; i++)
    {
      vec3 pl = m_ProjectorLocation[i];
      mat4 pm = m_ProjectorViewProjectionMatrix[i];
    
      // process an arbitrary number of projectors in a single pass
    }
    

    I don’t know if this makes sense, though. I can’t yet estimate performance bottlenecks.

    I’d also love to see this in the GL1Renderer.

  • Profile picture of thetoucher thetoucher349p said 4 months, 1 week ago:

    excellent man, really nice work =)

    what is performance like in it’s current form ?

  • Profile picture of normen normen1271p said 4 months, 1 week ago:

    Thanks very much for this contribution! I am sure many people will be happy to see this :)

  • Profile picture of survivor survivor106p said 4 months, 1 week ago:

    At the moment, a projected texture costs approximately 5% fps. I suppose it’s the render*() calls. I’m curious if the one pass shader can improve things. Unfortunately, holidays are over for me tomorrow. :/

  • Profile picture of udoprog udoprog1p said 4 months ago:

    This is really cool!

    I am currently trying to apply it as a flashlight in a game I’m messing around with.

    Is it possible in the current state to limit the projection distance, possibly with some kind of degradation.

    And is it possible mark objects as cast and receive shadow of the projection?. In effect having geometry block parts of the projection for surfaces behind it?

  • Profile picture of survivor survivor106p said 4 months ago:

    You can use “projector.setTargetGeometryList(gl)” to limit the projector to that geomerty. It might also be possible to limit the projection by “projCoord.w” in “ProjectiveTextureMapping.frag” but that’s not yet implemented. Edit: Just implemented. Shadow-mapping-like occlusion is also not (yet?) implemented.

    @udoprog: Added support for fall off. Usage:

      projector.setFallOffDistance(2.1f);
      projector.setFallOffPower(4f);
    

    “TestProjectiveTextureMapping.java” demonstrates it.

  • Profile picture of survivor survivor106p said 2 months, 1 week ago:

    I made some optimizations, especially to “TextureProjectorRenderer1pass” which can now handle an arbitrary number of projectors by using multiple passes with up to 8 projectors per pass (“1pass” is a bit misleading). Since it’s ~3.3x faster than “TextureProjectorRenderer”, “TestProjectiveTextureMapping1pass” has become the new default run target of the project.

    Unfortunately, these decals will not work with displacement / parallax mapped surfaces. Does anyone have an idea how to handle that?

  • Profile picture of iamcreasy iamcreasy57p said 2 months, 1 week ago:

    Wonderful! Wonderful!
    Wondering how it would feel to play with this in the fully fledge editor of jme :)

  • Profile picture of feengur feengur18p said 2 months, 1 week ago:

    @survivor could you just run the displacement/parallax methods after the projective texturing?

  • Profile picture of survivor survivor106p said 2 months, 1 week ago:

    No, sice I need the displaced texture coordinates to do the lookup in the projective texture map. Normal mapping would be ok as it is since it does not offset the diffuse texture anyway. But correct parallax of decals would require to pass the offset texture coordinates to the projective texture shader somehow.

    Here’s a video demonstrating the problem:

    Edit: I think the way to do this is a pre-pass that combines the decal / projective texture and the diffuse texture and replaces the diffuse texture of the original material. This way, one could even create decals that have normal and parallax map themself. This would enable bumped and parallaxed decals on bumped and parallaxed surfaces without altering the material / shader (it is altered on-the-fly). I don’t know if it’s doable and the performance might be horrible due to many texture swiches, but the idea is interesting.

    Edit2: Related stuff:
    http://www.unitymagic.com/shop/en/unity-decal-framework/

  • Profile picture of feengur feengur18p said 2 months, 1 week ago:

    @survivor said:

    Edit: I think the way to do this is a pre-pass that combines the decal / projective texture and the diffuse texture and replaces the diffuse texture of the original material. This way, one could even create decals that have normal and parallax map themself. This would enable bumped and parallaxed decals on bumped and parallaxed surfaces without altering the material / shader (it is altered on-the-fly). I don’t know if it’s doable and the performance might be horrible due to many texture swiches, but the idea is interesting.

    @survivor That’s kinda what I was getting at. Shaders definitely aren’t my forte however…. I was assuming that if you projected the texture onto a flat surface then the later pass of the parallax shader would already have the appropriately colored frag information. The stuff that I have read isn’t very clear on this.

  • Profile picture of mifth mifth132p said 2 months ago:

    @survivor , I added a link to your code. Because it’s very vital for the community.

    http://code.google.com/p/jme-glsl-shaders/

    http://i.imgur.com/fy0oz.png

  • Profile picture of survivor survivor106p said 2 months ago:

    Thanks! I’m currently fixing bugs and doing some cleanup. I’ll let you know when I’m done and there’s an initial version that can be put into another repository. My google code repository will stay my playground for preliminary version.

  • Profile picture of survivor survivor106p said 2 months ago:

    Update:
    - “(Single)TextureProjectorRenderer” is default again. I said multi would be faster, but that was a mistake.
    - Some refactoring:
    — “ProjectiveTextureMapping1pass” -> “ProjectiveMultiTextureMapping”
    — “TextureProjectorRenderer1pass” -> “MultiTextureProjectorRenderer”
    - Z-fighting fix “setPolyOffset(-0.1f, -0.1f)” by default
    - Different CombineMethods in “MultiTextureProjectorRenderer”
    - Bugfixes
    - ul and li don’t work btw :D

    Snapshot: ProjectiveTextureMapping-2012-03-15.zip

    I’d like to discuss two things:

    1. How to be a “good guy” SceneProcessor that works together with others. Because at the moment, mine doesn’t. HDRRenderer for example: If HDR is before PTM, there are no projective textures. If HDR is after PTM, there are completely black parts of geometry (where “gl_FragColor.a = 0.0″ in PTM shader). PSSM shows similar behavior in combination with HDR. My question: Am I doing something wrong or are SceneProcessors not meant to work together?

    2. How to combine multiple textures? MultiTextureProjectorRenderer enables advanced methods of combining multiple textures that aren’t possible if I render one texture per pass (standard TextureProjectorRenderer). But it would be possible if PTM was implemented as Filter that first renders / combines all textures to an offscreen buffer and then blends this combined texture into the main frame buffer. Filter also seems to be better designed for working together with others.

    Perhaps someone (@nehon ?) could review my code an let me know which things I could do better or what one wouldn’t do the way I do. Other than that, this snapshot should work.

  • Profile picture of oxplay2 oxplay255p said 2 months ago:

    great! you are a real shader guru. nehon guru propably will accept other guru :D