First post. Been googling this to no end and not finding anything similar. I’m trying to make a 2D Ripple Effect shader to make some of my tilemaps “underwater”. I have a ShaderGraph with some basic sinusoidal displacement to evoke the water ripple effect and that works fine (I use this shader on other assets/sprites with minor variations). I’m beginning to find issues trying to use this with a Tilemap Renderer though.
I find that no displacement appears at all if I use this Shadergraph/Material on the Tilemap Renderer set to “Chunk” mode. If I set the mode to “Individual”, the displacement/ripple does appear but each effect is essentially bound to a single tile, which means at tile boundaries the flow is discontinuous and the underlying sprite for said tile sort of bleeds into whatever was adjacent on the sprite sheet.
What I want is the displacement to work in chunk mode - I don’t want to process a ripple effect for every individual tile (mainly because of the discontinuities in how the ripple effect looks at tile boundaries), I think the effect would look much better if it applies macroscopically to the entirety of the rendered “chunks” on said tilemap.
Does anyone know how to do this, or if there are any reasons why my shadergraph ripple won’t show up in “chunk” mode?
The first thing that comes to mind is that perhaps you need to be displacing relative to the world using the Position node, rather than relative to the natural UVs.
Thanks, attached a screenshot of my shadergraph in this post. I’m not too sure how I would go about using the position node in my current shadergraph layout to try what you’re suggesting?
Could I see the effect now vs. an illustration of intended effect?
This is a sidescrolling game? Have you tried exposing a parameter for ripple magnitude? Perhaps the effect not showing up in chunk is an artifact of having the wrong magnitude.
The magnitude may be off because if in texture sprite that’s not in a spritesheet may be 0…1 U and 0…1 V in its texture, whereas within a spritesheet it could be 0…0.2 U, 0…0.1 V for example. So you may be looking at a scaling issue. Furthermore, it makes sense that within a spritesheet it could sample into another sprite because if sprites on the same spritesheet are nearby and you’re offsetting the UV into that other sprite’s territory then it will bleed. You could add padding or a region for anticipated bleed into the texture itself.
You might also consider a different approach, e.g. are you going for something like this? This is a two-camera approach which means you won’t have spritesheet problems because this alternate approach does not offset the UVs to sample the main tex.
I’ve attached a gif of how the Ripple effect works while the Individual Mode is selected. It’s subtle, but you can see that, because the effect operates on a per-tile basis, the effect is discontinuous at the boundary of each tile.
I’ve also attached a (crude, sorry!) diagram of how the shader effect works in Individual mode, and how I’d -like- it to work in Chunk mode. In my mind, chunk mode should stop the displacements becoming discontinuous at tile boundaries. Also attached an update of my shadergraph - I tried to use a Position node (trying both World and Absolute World) as the positional inputs before reverting back to the UV node as nothing was happening.
You can also see that I parameterised several of the variables, most importantly the amplitude of the sine wave. I tried varying this at runtime over many (maaaaany) orders of magnitude while in chunk mode and still no displacement would show. FYI, the Texture2D applied in this graph is just _MainTex, though I see no improvements using any others…
I have seen that video before and it’s pretty good, and I’ve actually used it as a basis for an approach for another water shader in another scene (but one that is non-interacting - just a background effect), and I have found it difficult using that approach to get the rendered output to match the pixel-size of all my other objects after going through the rendering cam - it’s fiddly and I’ll be the first to admit I’m not the most knowledgeable about it. I also want to avoid cameras for this generally because I know everything I want to influenced by this affect will be on a tilemap.
It may be that there is no other way to get this working than to use a camera approach, but I would find this surprising - the Shader works fine in individual mode, it’s just this final little piece of the puzzle in translating that into a macroscopic effect across the composite of multiple tiles as opposed to doing it individually…
EDIT: Another clue - It appears that in Chunk mode, the Tiles don’t render -at all- when the shader/material is applied. It isn’t a case of the Tilemap is visible but the ripple doesn’t show, but that the tilemap isn’t visible full stop
See attached for how implemented and snapshot of the spritesheet. Could add vertex offset to make even more wiggly.
This is what I’m talking about using world position. The black bars are clearly being displaced in sync; that’s due to world position. It’s not exactly the same as your template because it uses noise but there would be an equivalent for your case.
Chunked tilemap or non-chunked tilemap it makes no difference.
Thanks for the help! So, I can see that as long as I use a world-centric position as the source for the displacements I do actually get a proper continuous ripple that spans across multiple tiles in the desired way Only remaining issue I have is that since I’m still using individual mode I still have bleed from the adjacent tiles, but at this point I think I might just move certain edge-case tiles to an emptier region on my spritesheet so that there’s nothing there for it to bleed into. Still not sure why chunk-mode doesn’t seem to render at all with my shaders, but for now I’ve got an effect that I’m happy enough with