How can i tell a filter shader wich pixels belong to terrain or other models?

I am trying something like a special visual mode for a game where the player can switch to a view that tells him where to find resources. In essence it is something similar to a infrared view, just with the difference that it should highlight certain areas on the terrain instead of heat.

Now the problem, for applying the filter i thought i can use one of the existing grayscale filters which turn the whole scene to grayscale, then i want i could add a colour to the shader so that it doesn’t just grayscale but convert it to shades of that colour (like greenish view if infra-red views), then i have to add the areas that should be highlighted and what color to use to highlight. I was thinking of adding a texture to the shader on wich i can paint rgb colours, this would give me the option to create 3 different sorts of highlighting.
All of that i understand how to add to the shader, now i just have the problem that i dont want the highlighting to be on everything in the scene but just on the terrain (or model/node that represents my “floor”). But i just can’t figure out how i can tell the shader wich pixels belong to the terrain an wich are from something else.

I understand that if i would make this a material shader instead it would be just on the terrain, but i want to have the whole scene in a different view, so it has to be a filter shader.
Anyone can help me on this ?

Why not combine a filter shader and a terrain material shader?

<cite>@zarch said:</cite> Why not combine a filter shader and a terrain material shader?

If i knew how to do this :smiley:
Is it possible ? And how ?

I am just reading up on how to use shaders and understood the parts on using a texture to map the pixels to world coordinates and blending the colours in and all that, so i thought this would be a good way on doing this. But if you can combine the two…
Can you give an example please ? Or point me to one that uses this ?

I can’t give an example as this isn’t something I’ve ever done. Looking at some of the water filters might be interesting for you.

My thought was that for example you could switch the material on the terrain to a custom shader (or the standard shader but a different texture) which is brighter where resources are and darker elsewhere.

Then apply the filter.

Tweak as required.

I wanted to avoid switching material on terrain because it bight be that i don’t have a single material on whole terrain because i am creating the world out of static meshes put together, so it would be quite some world to create a texture for each individual mesh and go through them to switch the material, reference to world coordinates would have been much easier.
But even when doing this wouldn’t the filter to grayscale everything take away what the material does to the terrain anyways ? Ok, can get it brighter/darker, but i want whole scene in gray (or maybe another colour shading) and just the spots on terrain be a different colour.

Imagine something like haveing a scene all in grayscale and maybe those areas on the ground that are radioactive or have biohazards or are “hot zones” for some other reasons have red colours depending on the magnitude of this “hot zone”.

Viewports maybe? Render everything and filter it then use a separate viewport to draw in only the stuff you want with hot zones over the top of it.

Viewports and Filters are something I have no experience with though so I can’t help you any more.

Just use one set of shaders for the terrain and another set for other kinds of objects, I’d say.
If you feel that you’ll have too much redundant shader code, maybe the new shader nodes framework will help; I haven’t used it myself, but from the descriptions, it looks like it can take care of that.

Create a second technique for your terrain. Create a filter with depthtest=equal and use the specified technique to render the terrain a second time.
I guess thats the most simple way to implement.

@ryukajiya look at how the SSAO filter is done.

The SSAO filter before rendering SSAO renders the whole scene normals. This is done with an additional pass of the scene with a forced material.
The forced material is something you set on the renderer and all the object will be rendered with this material without altering the objects original material.

Another way would be to use a forced technique. That’s the same principle as the force material except it’s a technique. An example of this is the bloom filter that renders the objects with their glow color or glow textures.

So basically, what you can do is to make a pass that renders the terrain geometry only, with your forces material (the one that draws the different “heat” colors on the terrain) then combine it in the final pass of the filter (apply a gray scale tot he back buffer, then mix the color with the terrain render).

Look at how the shadow render makes sure it only renders the casting models for the shadow stuff, i guess you could a similar approach.

@Empire Phoenix said: Look at how the shadow render makes sure it only renders the casting models for the shadow stuff, i guess you could a similar approach.
Not really, the shadow renderer use a shadow queue (populated according to the ShadowMode set on the spatial), and that's deeply entangled into the core.

Ok, some of what you are talking about i understand some of it causes weird question marks to spawn arround my head.
But it sounds like all you suggest needs another render pass, while all that would be neccesary is identifying the pixels belonging to the terrain and render them differently.

As i said i am not that deeply into shaders yet, but reading up quite a lot lately. In material shaders you have some information like the origin of the model you are working on, so thought i could pass in a reference to the mesh and if the pixel i am painting currently is for the object with same origin i can apply the “hot color”.
Then again maybe i am thinking completely along the wrong paths since filter shaders don’t have any kind of object reference, so there probably is no vector to the origin inside the pixel shader ?

Ok so I think you miss important information.
A filter is a full screen quad on which you apply the texture of the scene. So the geometry you are rendering is the full screen quad, period. No more terrain, trees sky or anything

@ryukajiya said: But it sounds like all you suggest needs another render pass, while all that would be neccesary is identifying the pixels belonging to the terrain and render them differently.
So how to identify those pixels? You need to pass the information somehow to the shader. There are 2 ways to send information to a shader. As attribute that is some information stored in the mesh's buffers...but the mesh you're actually rendering and as I mentioned before, we are rendering a Quad on the screen...so there not much information we can pass this way. The other way is by passing a uniform, which are materialized in JME with material parameters. So...what kind of structure could we pass as a uniform to have an information for each pixel on screen? an array? not sure that's the best way... usually one use a texture...as it provide an easy way to store information on a pixel basis. And to have a texture representing information on the scene you need an extra render pass.

You could get away without it by setting a new material on the terrain, like unshaded with a color that is very unlikely to appear in your scene (like a bleue/green screen) and let the engine render the frame in the back buffer, then, in the filter every pixel that has this particular color would be the one belonging to the terrain…but you’d have to branch a lot in the shader and IMO it gonna be slower that the extra pass way…

Ok, thanks @nehon that cleared up a few things i did not understand about filter shaders so far.
Guess i have to dig into shader basics a bit further before trying this, will come back to this a bit later then.
But maybe i planted some ideas in some heads and someone else tries to do something like this meanwhile :wink: