three.js icon indicating copy to clipboard operation
three.js copied to clipboard

DecalGeometry: Decal projections without distortions.

Open ManishJu opened this issue 3 years ago β€’ 26 comments

Describe the bug

The decal gets replicated when splatted. This happens when you try to splat just around the corners; you can then clearly see the partial/full replication (just once) of that decal on the adjacent side to the face you have splatted on.

To Reproduce

Steps to reproduce the behavior:

  1. Go to https://threejs.org/examples/?q=decal#webgl_decals
  2. Click on bottom part of the model's shoulder
  3. You can see the decal being replicated partially on the adjacent side

Expected behavior

The decal should only be present on the side splatted on

Screenshots

Splat_bug

Platform tested on:

  • Device: [Desktop]
  • OS: [Windows, MacOS, Linux]
  • Browser: [Chrome, Firefox]
  • Three.js version: [r125]

ManishJu avatar Feb 01 '21 14:02 ManishJu

This is a limitation of the used approach. More information here:

https://discourse.threejs.org/t/distorted-decal-texture/18442

Mugen87 avatar Feb 01 '21 14:02 Mugen87

Instead of using a planar projection to compute texture coordinates, it might be conceivable to use a different approach in DecalGeometry. However, the current code is easy to understand and compact. I would not vote for a solution that noticeably increase the complexity of DecalGeometry.

Mugen87 avatar Feb 02 '21 10:02 Mugen87

The model is also problematic. May be better to just change the model.

mrdoob avatar Feb 03 '21 14:02 mrdoob

Shouldnot a more efficient solution be in place with good documentation instead of a simple solution that does not work at places ? :)

ManishJu avatar Feb 05 '21 08:02 ManishJu

@ManishJu Definitely ! Would you like to work on that ? :)

mrdoob avatar Feb 05 '21 09:02 mrdoob

Instead of using a planar projection to compute texture coordinates, it might be conceivable to use a different approach in DecalGeometry.

what if you use vertex normal to intersect a sphere of certain radius around the decal box center, and use the intersection point to assign a uv as if decal texture was mapped on this sphere in an eyeball-like way? does this make sense to anyone, lol

on 2nd thought, that would probably stretch it a bit in the middle

makc avatar Feb 05 '21 16:02 makc

Sidenote: I actually don't find it so great how the decal texture wraps around. Right now, it is stretched but even if you fix it this particular behavior would be questionable. I like how the Source engine used to handle Decals.

Decals are "sprayed" from a location and mark every surface in their path. For instance, a decal applied downward onto a staircase would cascade down onto the top (but not front) of each step.

Would be interesting to have a flag or enum that controls how textures are projected onto the surface.

Mugen87 avatar Feb 07 '21 18:02 Mugen87

what would be the best way to tackle this problem ? Any papers to look into for implementation ? @Mugen87 does source engine's implementation handle complex surfaces ?

ManishJu avatar Feb 08 '21 11:02 ManishJu

what would be the best way to tackle this problem ?

First, study the related work and find an existing algorithm that can implement the requirement.

A paper would be the best resource but I'm not aware of one. The other option is to study an existing solution and try to figure out a port. Although this can be quite time consuming. And it's not guaranteed to have something workable at the end. And it's important to honor the respective license and other potential clauses (e.g. a solution might be protected by a patent).

Mugen87 avatar Feb 08 '21 12:02 Mugen87

BTW: It seems Unity devs have/had similar problems πŸ˜‡ :

https://forum.unity.com/threads/any-better-alternative-to-decal-projector-for-decals.742424/

Mugen87 avatar Feb 08 '21 12:02 Mugen87

/cc @spite

mrdoob avatar Feb 08 '21 14:02 mrdoob

Yes, it's a limitation of the way the geometry is generated. ThatΒ΄s why the decal volume has a parameter to define its dimensions, in order to mitigate this kind of problems. A solution for this specific use case would be to project a single quad, but that solution has the problem of having "shadow holes": i.e. some parts of the geometry in theory covered by the decal would have no texture.

Another potential solution is to add an attenuation factor for the texture along the projection axis, but this would have its own set of problems and edge cases.

spite avatar Feb 08 '21 15:02 spite

Any updates on this issue? There is a paper about Interactive Decal Compositing with Discrete Exponential Maps. Has anybody implemented this approach in three.js? We are planning to implement this. πŸ€”

http://www.unknownroad.com/publications/ExpMapSIGGRAPH06.pdf

dipeshdulal avatar Sep 19 '22 05:09 dipeshdulal

No updates so far but the linked paper actually looks promising. It seems an implementation would solve the distortions mentioned in this issue.

Mugen87 avatar Sep 19 '22 07:09 Mugen87

I see. Thank You. Let's see if we can implement the paper or not. I am still trying to understand. πŸ€” 🀞 As with most of the research papers, things look harder to understand.

dipeshdulal avatar Sep 19 '22 08:09 dipeshdulal

For anybody interested here is the full thesis : http://www.dgp.toronto.edu/~rms/pubs/PhDThesis10.html http://papervideos.s3.amazonaws.com/RyanSchmidtPhDThesis.pdf

ManishJu avatar Sep 30 '22 12:09 ManishJu

@ManishJu Awesome Thank you. πŸ™‡ I haven't fully started to implement the algorithm but generating uv coordinates through matlab implementation and plugging in the coordinates. I was able to achieve something like shown in the video.

https://user-images.githubusercontent.com/8201857/193405501-e8940cd1-6948-4da1-86bc-c8952f298bb1.mp4

dipeshdulal avatar Oct 01 '22 10:10 dipeshdulal

@ManishJu Awesome Thank you. πŸ™‡ I haven't fully started to implement the algorithm but generating uv coordinates through matlab implementation and plugging in the coordinates. I was able to achieve something like shown in the video. custom-texture-shader.mp4

Do keep us up-to-date, looks great so far!

cptSwing avatar Oct 28 '22 13:10 cptSwing

@cptSwing Sure. After some playing with the algorithm, I have found the algorithm mesh dependant and if there are not enough triangles the algorithm wont work properly and there will be clipping. I think even after implementation, it wont be usable for all the cases but after some tinkering with mesh I have found it usable for my use case. I have started implementing the algorithm (writing some js code πŸƒβ€β™‚οΈπŸ€ž) after testing.

I will keep on updating about the progress.

PS: There are performance impacts during start up as well because of distance calculation that is needed to be done during start up (one time process). πŸ€”

dipeshdulal avatar Oct 28 '22 14:10 dipeshdulal

maybe someone can port this to three https://www.babylonjs-playground.com/#9BVW2S#15

RGdevz avatar Jan 21 '23 20:01 RGdevz

@RGdevz it is pretty much the same: Screenshot 2023-01-24 at 21-24-34 Babylon js Playground

makc avatar Jan 24 '23 20:01 makc

I found that rotating the model (not the camera) completely eliminates this. I wonder how the camera position contributes to the issue.

troisiemeoeil avatar Nov 26 '23 20:11 troisiemeoeil

@troisiemeoeil Any chance you can create a jsfiddle of that so we can investigate?

mrdoob avatar Nov 28 '23 09:11 mrdoob

@cptSwing Sure. After some playing with the algorithm, I have found the algorithm mesh dependant and if there are not enough triangles the algorithm wont work properly and there will be clipping. I think even after implementation, it wont be usable for all the cases but after some tinkering with mesh I have found it usable for my use case. I have started implementing the algorithm (writing some js code πŸƒβ€β™‚οΈπŸ€ž) after testing.

I will keep on updating about the progress.

PS: There are performance impacts during start up as well because of distance calculation that is needed to be done during start up (one time process). πŸ€”

but if we are dragging decal in real time, the distances need to be recalculated, right?

iefreer avatar Dec 09 '23 10:12 iefreer

@dipeshdulal did you get this to work? Would you mind sharing your code? Would love to test it for my use case.

karmacod3r avatar Jan 05 '24 13:01 karmacod3r

@karmacod3r I shared some part of expmap code over in this thread. πŸ™ https://discourse.threejs.org/t/threejs-decalgeometry-alternative/39205/28

dipeshdulal avatar Jan 07 '24 12:01 dipeshdulal

@ManishJu Awesome Thank you. πŸ™‡ I haven't fully started to implement the algorithm but generating uv coordinates through matlab implementation and plugging in the coordinates. I was able to achieve something like shown in the video.

custom-texture-shader.mp4

Hi Can you tell me is the solution? How can we use it?

shahbaziparisa avatar Mar 27 '24 12:03 shahbaziparisa