I’m working on a blood pool/decal system and I’m trying to come up with a solution to project the blood on any surface on my map.
The current system writes blood textures into a subViewport, which I can then run a shader on and make the ‘decals’ interact with each other and animate them (see the attachment).
The problem is - it works good only for one surface. It’s basically a megatexture (1080x1080) that covers the floor and I want it properly conform to underlying surfaces so the blood could cover walls, ceilings and such.
I found this tutorial which is great but works only if you have one texture that covers the whole map, while I have many materials (generated by Qodot, for example). Any ideas how I can approach this?
I know that Portal 2’s gels were stored in a lightmap-like texture. I thought about solutions as crazy as creating my own atlas texture that would contain all the surfaces that need the blood projected on them (faces somehow derived from the meshes). Simple decals are out of the question as they z-fight and can’t be easily cut off on the edges and I need a shader that runs on the texture and it would be impossible to have many decals that way, as Godot shaders support only 1 per-instance texture uniform
Did you read my post? I listed many reasons why decals are out of the question [sic] and I need the shader for visual effects (such as using the screen’s normal texture).
Oh sorry, actually I not have much knowledge on shaders but I think creating that blood effect on both wall and floor with decals node will possible if one decal node is rotated somehow and the other normal.
I need the decals to have an animation and to interact with each other seamlessly. The decal approach won’t work because
Simple decals are out of the question as they z-fight and can’t be easily cut off on the edges and I need a shader that runs on the texture
And also they won’t seamlessly blend with each other. My current approach makes the blood’s edges more saturated, and if they were separate decals the seams would be seen. Keeping them in one texture allows me to read it from a shader and apply effects on it as a whole, so it blends in a seamless way.
All the other problems still apply. Z-fighting, stacking up causing performance cost, non-conforming to the underlying surfaces (decal extends beyond the face it’s on) and I couldn’t use a simple shader material this way because
Godot shaders support only 1 per-instance texture uniform
On the surface that’s supposed to have the decals on them? This is a good idea, but they are still stored in one texture and I first have to divide it somehow
Yup, that’s what I’ve been thinking too. This would require me to create an atlas of all faces that need the blood to be displayed on them. Seems like an insane task but it’s probably doable.
Can you expand on this thought? I didn’t really understand what you were saying here.
What I was initially trying to do (with meshes that acted as decals) was having a simple texture uniform uniform sampler2D texture: hint_default_black; and pass the blood texture to the shader this way.
However, updating the texture in one shader changed the effect on every other instance. This would be fixed with instance uniform sampler2D texture: hint_default_black; if it was supported by Godot, but it isn’t The 'SCOPE_UNSTANCE' qualifier is not supported for sampler types.
I think there’d be a programmatic way. Find the polygon face of the first surface and use that to calculate the start for the other adjoining faces. It’d be more difficult initially, but you’d never have to worry about what was in your scene. Basically like using your faces like a cookie-cutter - or fitting a puzzle together.
Any uniform sampler2D texture you create can be made unique in the editor, which means there’s a way to do it through code - just perhaps not in the shader code. Apply the shader, make the texture unique, should be good.
Most of what I know about gdshader I’ve learned by converting 3.5 gdshaders to 4.x Visual Shaders.
Maybe there’s a way of doing this I didn’t think of, but having multiple (possibly hundreds, thousands) shader materials would probably impact the performance way too much
Definitely. A guy was doing something similar in the link In my original post, to paint on textures in real time. So there is a way, but I feel like I’m fighting with the engine this way. Trying to brainstorm
Is there a reason your shaders can’t disappear after a while?
FWIW, I’m going to play with decals. I didn’t even know they existed in Godot until your post. I’ve been reading up on them. I’m going to try creating a frost effect with them I can apply to an object. Right now I’m using the overlay and a Visual Shader to make only part of the object frosted. I think this will work better. If I come up with any ideas, I’ll let you know.
They could, but still using decals for this would be a terrible solution, as I mentioned there will be z-fighting issues, the decals won’t blend with each other and they just don’t know the underlying geometry. I need something way more flexible.
FWIW, I’m going to play with decals. I didn’t even know they existed in Godot until your post
What I usually mean by decals is just a quadmesh that I use as a decal, as simple godot decals are way too restrictive and for advanced use cases it’s better to just write your own solution. But for quick enhancements of visuals of environments for example they are great
You did help, I thought of a different way of getting the face I want to apply the blood on from the mesh because of your responses. Thanks for chiming in