terrain decals shader

hi there,

i would just like to show the shader i am working on right now which is a terrain shader that will allow you to add decals to the built in terrain without adding any geometry nor forcing any additional draw call nor shader pass: it is just a single pass shader which will allow you to use 4 detail splats + 4 detail normal splats and 4 (or even 9) additional detail decals (normal mapped) blended in according to height.

the shader will cost only 3 additional textures being passed to it: 1 diffuse map atlas, 1 normal map atlas, 1 splatmap, so it works well within the sm 3.0 boundaries (which is 16 texture samplers – currently used like: 1 splatmap, 4 diffuse texures, 4 normal maps, 2 lightmaps).

i am not sure whether it will support perfectly tiling detail decals as the only way i have found to incorporate these is using the “tex2Dlod” command – it gives you perfectly tiling textures but does not support anisotropic filtering.
so i am thinking about not supporting continuous tiling textures but just single decals using the standard “tex2D” command.

this is what i have right now:

image 01: comparision of using tex2dlod and tex2d
in a still image even using “tex2Dlod” looks good, but moving around the terrain will produce some rather strange artifacts.

image 02: texture atlas used for the decals

1039256--38588--$texture_preview.jpg

image 03: texture atlas anisotropic filtered but not allowing to use continuously tiling textures in order to hide seams. well – of course this is not what i wanted to archive but in the other hand: hey, those are just decals! just think of some smaller stones here and there, some dry twigs or blossoms…

performance
my first tests look quite promising:
– using the standard terrain shader with the given terrain (size: 1000 x 200 x 1000 m, heightmap resolution: 1025, pixel error: 5) which does not support any bump mapping at all, using 4 splat maps will cost 0,31 ms in deferred rendering.
– using the standard terrain shader with the given terrain, which does not support any bumpmapping at all, using 8 splat maps will cost 0,4 ms in deferred rendering.

– using the modified terrain shader with the given terrain (4 detail splats + 4 normal maps + 4 terrain decals icliding their normal maps) will cost 0,31 ms in deferred rendering.

(mac book pro, nvidia geforce 9400M)

and now?
well – i would really like to get some feedback: is a decal shader interesting to you – even if it does not support seamlessly tiling textures?
do you have any other idea?

lars

It seems like this would mostly be useful when you need uneven coverage of the terrain…like leaves, or stone here and there.

i guess, you are right.
but even those details would make any terrain much more unique and interesting, wouldn’t it?

lars

but the best solution i can find is to use “tex2dlod” and fade in and out the decals!
so you can have seamlessly decals.

image

watch the webplayer: http://bit.ly/RpKStU

it shows seamlessly tiled terrain decals using “tex2Dlod” and fading in and out them in order to minimize artifacts due to the missing anisotropic filtering.

lars

Oh, I wasn’t trying to say “it’s boring, what good is it”. Please don’t think that, it wasn’t my intent at all.

Being able to add more detail to the terrain, without a big performance penalty is always a good thing I would think! And seeing how the numbers are -underneath- some textures, but over others…that’s -very- interesting. I’m picturing old stone pathways, covered by dirt and grass.

I’m curious…I was playing with the projector shader, and getting solid color projectors to paint onto the terrain (no transparency). It’s a really nice effect, and I’d be interested in your thoughts on using this to get a similar effect.

I realize this is an icon sort of effect, but it seems like it could be used to paint tiled textures onto the terrain also. I’m a complete amateur at shaders, but if a projector shader could use a splatmap, to paint tiled textures…I dunno. Just wondering.

hi jc,

as far as projected decals are concerned:
– they do not support bumpmapping
– they are veeeeeeeeeeeeery expensive to render as the terrain would have to be rendered at least twice…

–> i don’t think that using projectors is a good solution at all.

sorry about this,
lars

Interesting i was in need of such shader half year ago, i found one solution on Moddb, forgot whats the project name but this one seams much easier to do.

Oh i just run webplayer, this is way better than i thought at start. Looks awesome. One thing, is there any chance that you could get this working with your color terrain shader? Also can you change decal size that you want to paint, or is decal always the same size?

Thanks lars…I was afraid of that. I’ll have to continue to projectors sparingly :slight_smile:
Meanwhile, I’m curious to see the uses that come out of this shader!

I think any kind of shader that will allow for detailing specific areas of the terrain is good in my book. If it can utilize normal and spec maps all the better!

hi there,

i just wanted to show you the possibility to layer decals on top of each other:

image 01: shows 4 detail terrain textures mixed with 3 different decals layered on top of each other.

lars

Lars last picture looks great, i am wondering one thing: Lets say for example that i want to make grassy part and rocky part of terrain, where there are both parts very exagurated and clearly different, which means there is all rock texture where rocks are and all grass where grass is. Is it possible to somehow do that considering that you can use only 4 textures, this would mean that 2 textures would be for main base detail texture and 2 of them would be decals. Is that possible or do all textures have to be decals with alpha channel?

hi janpec,

i guess i haven’t explained very well how the shader works, so i will try again:
first of all it is a regular terrain shader supporting 4 detail textures (plus their normal maps).
you can paint those just like you are used to do using unity’s terrain paintbrush or import a splatmap.

on top of these 4 regular terrain textures you have 4 additional bumped terrain decals. those are blended with the terrain textures using their respective heightmap and can even be placed on top of each other.

so all together you have up to 8 bumped terrain textures – all drawn within on single shader pass.

saying this means that it should not be any problem to draw rocks and grass… it is just like on any other unity terrain!
just a have look at the pictures attached.

lars

image 01: just the base terrain textures: rock, sand grass –*ordinary blened

image 02: base terrain textures plus 2 decals (cobblestones and leaves)

Lars this is exactly what i meant, its way too good. Now there is ultimate question, do you think that you could anyhow implement this with your color terrain shader? Becouse the thing is this is at the momment very difficult position, both shaders / solutions are great but i still wouldnt use this one over color terrain, if you could combine them both it would be awesome.

hi janpec,

thanks…
as far as the colormap shader is concerned: it already uses 11 texture samplers ( + 2 for lightmapping) → there are 3 left…
that would be enough if you were using atlased decal textures – but that would be a very, very heavy shader!

right now i am into rendering speed. it looks a bit like using tex2dlod is very slow – at least on my machine.
so i might fall back to regular textures which would mean: max 2 decals…

i will keep you updated.

lars

I think we need a new feature on the forum. Subscribe to poster.

Your stuff is impressive as always!

Lol indeed, the good thing is that his stuff is always bumped on first page otherwise it would be a shame.

thanks.

why isn’t unity recruiting you?

impressive, like the rest of your work.

hi there,

now i have done all different versions of the shader and did the first tests.
unfortunately my bad dreams came true: using “tex2dlod” is pretty heavy.

but the decal shader using 2 regular textures + packed normal maps (both not atlased) is pretty fast – almost as fast as a simple bumped diffuse terrain shader supporting 4 textures (4 diffuse + 4 normal).
so you can have 2 additional decal textures at more or less no costs (despite the texture memory of course…)!
another advantage: anisotropic filtering is back! so we don’t have to fade out the decal textures and can have them even at very far viewing distances – nicely tiled and filtered.
there is only one drawback: both decal normal maps have to be composed into on DXT5nm-like texture which means that both normal maps will have the same resolution.

im am pretty surprised by the fact that the 2 decals atlased shader is not significantly faster than the 4 decals atlased shader although is does only 5 additional texturelookups compared to 9 texturelookups which the 4 decals atlased shader has to perform.

comparing the decal shaders using texture atlasing and the 2 pass terrain shader supporting 8 detail textures plus normal maps it seems not to make much sense to use texture atlasing unless the number of draw calls and triangles is not the bottleneck of your rendering pipeline – hmmmpf…
this might even get better with unity 4 as we don’t have to pass additional textures as global textures to the shader as far as i know. so may be the nearby future will bring 8 detail textures + normal maps + 4 decal textures (2 in each pass).

the stats

mac book pro, nvidia geforce 9400M – deferred rendering / real time shadows enabled

decal shader

2 decals using regular textures:
camera render: 0.8 – 0.9 ms
draw calls: 120
fps: 26.0

2 decals atlased textures:
camera render: 1.75 – 1.9 ms
draw calls: 120
fps: 19

4 decals using atlased textures:
camera render: 1.8 – 1.9 ms
draw calls: 120
fps: 15

simple bumped terrain shaders

simple terrain 4 splats bump mapped
(more or less the standard shader from sixtimesnothing)
camera render: 0.8 – 0.9 ms
draw calls: 120
fps: 26.5

simple terrain 8 splats bump mapped
(double pass)
camer render: 1.0 – 1.1 ms
draw calls: 209
fps: 25