terrain blending tutorial


(ratty redemption) #1

first off, credit should go again to ydnar and rgoer for developing the excellent alphamod volume brushes, which without, our mapping would be a lot slower and more painful.

the blending will work in any q3 engine game that uses ydnar`s q3map2, although we need at least version 2.5.14

edit: updated shaders as recommended by ydnar to use q3map_baseshaders

image 257 shows a piece of hand built ground with shallow bumps, although for this type of blending it could be totally flat and or have steep angles like a rock face, ie the angles aren`t very important.

the trisouped brushes are painted with caulk on all but the top faces, where a simple lightmapped grass shader is used, but almost any shader or plain tex could be used on the top face.

also note the shapes of the tris brushes aren`t all the same in my example, so neatly aligned grids of trisouping are no longer needed, like with the old indexmap and meta shader terrain blending.

textures/_ratty_terrain/grass
{
	qer_editorimage textures/_ratty_terrain/green_terrain.tga
	q3map_lightmapsampleoffset 16
	q3map_lightmapmergable
	q3map_shadeangle 178
	q3map_tcmod rotate 33
	q3map_nonplanar
	q3map_forcemeta
	q3map_tcgen ivector ( 512 0 0 ) ( 0 512 0 )
	surfaceparm grasssteps
	{
		map textures/stone/mxrock0b.tga
	}
	{
		map $lightmap
		blendfunc filter
	}
}

image 258 shows two smaller areas I`ve selected and painted with a dirt shader, again almost any shader or plain tex could be used for those.

textures/_ratty_terrain/base6
{
	q3map_lightmapsampleoffset 16
	q3map_shadeangle 178
	q3map_nonplanar
	q3map_forcemeta
}

textures/_ratty_terrain/dirt
{
	qer_editorimage textures/_ratty_terrain/brown_terrain.tga
	q3map_baseshader textures/_ratty_terrain/base6
	q3map_tcmod rotate 33
	q3map_tcgen ivector ( 256 0 0 ) ( 0 256 0 )
	surfaceparm grasssteps
	{
		map textures/_ratty_terrain/ratty_dirt_m03.tga  // dirt
		//rgbgen const ( 0.6 0 0 )  // uncomment to debug
	}
	{
		map $lightmap
		blendfunc filter
	}
}

image 259 shows one of the dirt areas cloned and “regioned” off, ie all other brushes are hidden from view.

the clones are then grouped and painted with a nodraw shader on all but their top faces, where the blend shader is painted… the func_group doesnt need any additional keys added to it, just its classname.

around the outside, but still part of the group, are the alphamod volume brushes which can be any size and shape, as long as they enclose the specific verts, from the other grouped brushes that we want faded… the shader for them is below the nodraw and blend shaders.

textures/_ratty_water/nodraw_nonsolid_trans
{
	qer_editorimage textures/_ratty_terrain/nodraw_water.tga
	qer_trans 0.5
	surfaceparm nonsolid
	surfaceparm nodraw
	surfaceparm trans
}

textures/_ratty_terrain/base1
{
	q3map_shadeangle 178
	q3map_tcmod rotate -66
	q3map_nonplanar
	q3map_forcemeta
	q3map_nolightmap
	surfaceparm nonsolid
	surfaceparm nomarks
	surfaceparm trans
}

textures/_ratty_terrain/dirt_volume_blend
{
	qer_editorimage textures/_ratty_terrain/red_grey_terrain.tga
	q3map_baseshader textures/_ratty_terrain/base1
	q3map_tcgen ivector ( 256 0 0 ) ( 0 256 0 )
	//cull disable  // uncomment to debug
	polygonoffset
	{
		map textures/_ratty_terrain/ratty_dirt_m03.tga  // dirt
		rgbgen vertex
		//rgbgen const ( 0.5 0 0 )  // uncomment to debug
		alphagen oneminusvertex  // inverses the value of the volume alpha
		alphafunc ge128
	}
}

textures/_ratty_water/alpha_0
{
	qer_editorimage textures/_ratty_terrain/alpha_0.tga
	qer_trans 0.75
	q3map_alphamod volume
	q3map_alphamod scale 0
	surfaceparm nonsolid
	surfaceparm nodraw
	surfaceparm trans
}

image 262 shows the original rtcw dirt tex and the alpha channel I made for it, note the gamma is quite high although there is still some contrast.

image 263 is a shot of psp7, and the right side image shows where I layered in some slightly darker staining, around the middle of what will become the alpha channel, using psp`s multiply blending.

although the staining could be around the border where the tex would tile in game, which is how I set up some of my rock tex alpha channels.

Im assuming photoshop would have similar ways of blending layers? ...and possibly easier to use, but I like psp7 partly as its cheap but also because I like it`s interface.

anyway… the left side image shows the gamma altered, grayscale version of the original dirt tex before the staining was layered in.

I also found the more speckled the layers are, the better the eventual blend results will be, as these types of tex filtering then help the map`s vertex alpha and shaders alphafunc, determine where to break up the tiled blend tex in game.

ie the resulting blending is more dithered and natural looking, then a smooth linear gradient would produce which is what the old terrain. meta shaders used.

if your making your own tex and or alpha channel, almost any alpha channel would work, providing its gamma is high enough, so dont be put off if any of you aren`t familiar with a paint program.

back to the map…

image 260 shows both the dirt areas which can be grouped into one func_group.

the important thing here is I cloned some more of the original grass brushes, around the outer edge of the volume brushes, and added them to the group, then painted them to use the same nodraw and blend shaders as above.

note, I also deleted any brushes that dont have at least one vert enclosed by a volume brush, as they wont be visible in game, so are redundant and probably would add to the over draw if left in as I`m assuming they would still need to be culled by the alphafunc, thus wasting fps.

if the blend area was larger or it`s trisouping was made of smaller brushes, then most of the middle of the group could be deleted.

it also doesn`t matter if two or more blend areas are touching each other, as long as there are at least two tris brushes, separating any volume brushes from different areas… other wise the volume brushes cancel each other out, and the blending would result in more of a visibly “joined” area, rather then two or more “separate” but nearby areas of dirt.

image 261 shows the selected groups overlapping the original grass brushes and the simple non blended dirt brushes, in the middle of the blending brushes.

hopefully it should be more obvious what were doing here, but in case its not, here`s roughly how it works.

the non blended dirt brushes are drawn as normal in game with little or no overdraw, so are the grass brushes.

the alphamod volume brushes produce a solid, 100% opaque border, which the polygon offset, decal type blending, fades towards from it`s 100% translucent edges, which are dithered looking like the dotproduct terrain blending.

this covers up the noticeable seems between the dirt and the grass brushes, although it does produce some overdraw, but as I only use alphafunc ge128, and not the slower but more precise blendfunc blend, then this is still quicker then most multi layered dotproduct shaders take to draw, and a more flexible system to work with, as we can control almost exactly where we want the blending to be.

note, the blended brushes could use a different color channel instead of dirt… eg sand, so it could be dirt areas blending into sand, blending into grass.

k, that may look a little odd as the sand would appear to surround the dirt areas in this example, although we dont have to have closed areas, so they could be borders between fields, or a winding dirt path with grass on either side... technically the principle would be the exactly same, and Im sure some of you will find creative uses for this :wink:

image 264 is a high up, in game shot with r_showtris 1, looking down on the dirt areas with no blending.

an rgbgen const ( 0.6 0 0 ) is used to color the dirt red for debugging purposes… ie this makes it much easier to see where there are hard edged borders between the dirt and grass.

the values are normalized rgb, ie between 0.0 and 1.0

image 265 shows the same scene but now with the dirt blending, again colored red, clearly showing a dithered dot product type edge… notice how it “bleeds” over the white tris lines.

side note, I found the best dotproduct results are when the angles of the tris are tweaked vertically, so any dotproduct blends don`t lie sharply along tris edges, ie we want them bleeding over instead of cut off.

image 238 shows an example of this, which I`ll cover in more detail in another tutorial.

image 266 shows just the blending colored red with no showtris.

I often use the cull disable lines in my shaders, when debugging so I can view in game the blending from underneath, this is especially useful when doing dot product or volume blending on rock or mountain faces, which I`ll be covering in my next tutorial …as well as showing a couple of methods to reduce the amount of tex tiling patterns, using volume blending and alpha channeled decals.

although the latter method is mostly redundant now, but some mappers might still find it useful to know.

image 267 shows the final blending result in game with the camera at normal player head height, although I also took the shot with cg_drawgun 0.

imo, this is worth mentioning as sometimes the apparent camera height or scale of the tex and or brush work can be deceptive, especially if there are no man made buildings or models like trees to use as scale ref.

more relevant in this case, note the non blended dirt in the lower left of the pic is slightly darker then the blended dirt, although I quite like this result.

but if it was too obvious then I would use the q3map_vertexscale to lower the gamma of the blend tex, which remember is rgbgen vertex lit, as opposed to lightmapped lit.

this is to save on fps, and because it`s difficult to blend the lightmap stages, but some mappers will probably pref to use all lightmap shaders where possible.

and lastly for now… I`m sure most of you will agree, the blending between the dirt and grass is very natural looking, even more so then the old linear blends of terrain meta shaders :drink:


(ydnar) #2

Nice.

Two things I’ll suggest right off the bat (before I’ve read the rest of it)

  • use q3map_baseShader to specify a base shader with texture projection, nonplanar, shadeangle, etc
  • put a comment above q3map_lightmapMergable:

// only works well in Enemy Territory, which supports external lightmaps

y


(ratty redemption) #3

@ydnar, thanx for the tips and does that mean q3map_baseShader will work with any shaders, not just meta ones? if so, my .shader file will be a lot shorter :slight_smile:


(ydnar) #4

q3map_baseShader works with any shader, as long as they have explicit texture coords (models, patches, or q3map_tcGen).

y


(ratty redemption) #5

great, I`ll update my shader files tomorrow and then edit my post to reflect this, which will have the added benefit of making my post easier to read :slight_smile:


(way) #6

// only works well in Enemy Territory, which supports external lightmaps

hi,

Do you mean the whole tutorial does just work with enemy territory?

PS: well done ratty redemption :clap:


(ratty redemption) #7

nope, just that line of the shader, the blending will work in any q3 engine game that uses ydnars q3map2, although I should of mentioned we need at least version 2.5.14, Ill go edit my post at the top.

and thanx way :smiley:


(dime1622) #8

double post


(dime1622) #9

well, i tried this all out. however, the blend isnt pretty… any ideas?

haha you guys must think im retarded for asking so many questions :uhoh:


(ratty redemption) #10

your blending appears to be working in that its bleeding over the tris lines, but the blend edge doesn`t look dithered, just a hard edge… are you using the same shader parms as I did?

can you post a pic of your alpha channel?

edit: the only questions I personally dont like people asking, are ones from trolls who think its fun to ask questions they dont really want answers to, other then that, anyone is welcome to post questions or suggestions for improvement regarding this topic, but if I think someone is a troll Ill ignore them.


(dime1622) #11

ah, i thought i had a nice alpha channel, but photoshop isnt saving my tga file once i add the alpha channel, i think its because it only allows an 8-bit alpha channel. ill have to see what i can figure out.


(ratty redemption) #12

ok, but I think alpha channels in q3 engine games are 8 bit, so you want to save your 32 bit .tga iirc

in psp, we save them as 24 bit, but it then adds the 8 bit alpha channel to make it 32 bit, unless I`ve got that wrong?

but anyway psp7 works fine for all but .png files, so photoshop should work once you find what format to save them in.


(dime1622) #13

ok i downloaded the tga update for photoshop 7, apparently they dropped support for alpha channels when 7 was released. anyway, i now have an alpha channel and its all nice a pretty, but now its not blended at all. im using ydnar’s original alpha_0 etc. textures and shader file. then i have my “dimesblend.shader” both shaders are listed in my shaderlist.txt. my dimesblend.shader looks like this:

textures/dimesblend/dimegrass
{
qer_editorimage textures/dimesblend/dimegrass.tga
q3map_lightmapsampleoffset 16
q3map_shadeangle 178
q3map_tcmod rotate 33
q3map_nonplanar
q3map_forcemeta
q3map_tcgen ivector ( 512 0 0 ) ( 0 512 0 )
surfaceparm grasssteps
{
map textures/dimesblend/dimegrass.tga
}
{
map $lightmap
tcgen lightmap
blendfunc filter
}
}

textures/dimesblend/dimedirt
{
qer_editorimage textures/dimesblend/dimedirt.tga
q3map_lightmapsampleoffset 16
q3map_shadeangle 178
q3map_tcmod rotate -66
q3map_nonplanar
q3map_forcemeta
q3map_tcgen ivector ( 256 0 0 ) ( 0 256 0 )
surfaceparm grasssteps
{
map textures/dimesblend/dimedirt.tga
}
{
map $lightmap
tcgen lightmap
blendfunc filter
}
}

textures/common/dimesblend
{
qer_editorimage textures/common/dimesblend.tga
q3map_shadeangle 178
q3map_tcmod rotate -66
q3map_nonplanar
q3map_forcemeta
q3map_nolightmap
q3map_tcgen ivector ( 256 0 0 ) ( 0 256 0 )
surfaceparm nonsolid
surfaceparm nomarks
surfaceparm trans
polygonoffset
{
map textures/dimesblend/dimedirt.tga
rgbgen vertex
alphagen oneminusvertex // inverses the value of the volume alpha
alphafunc ge128
}
}

so now the edge of the dirt comes to the vertexes instead of halfway between. (theres a row of grass around the dirt, like the pic above, as if the dirt receded)

my alpha channel:


(ratty redemption) #14

oh btw, if we want to use the alphamod volume brushes to produce linear fades like the old terrain blending, then we can leave out the alpha channel, and save our tex as .jpg

then use blendfunc blend (gl_src_alpha gl_one_minus_src_alpha) instead of the alphafunc ge128 and that should produce a linear fade from 0-100% translucency.

edit:

image279 shows a linear volume blend.

image280 shows the same scene with showtris.


(ratty redemption) #15

hmm, check ydnar`s common_alphascale.shader is using the q3map_alphamod scale 0 for the volume shader your using in radiant.

if it is, try adding some contrast to your alpha channel, or do a test where you paint, layer in some lettering to the alpha channel in black or dark grey, like the word “test” that should help you debug where on the tex the edge is being made.


(dime1622) #16

almost there:

the alpha channel now has parts that are 95% white and parts that are 95% black, but im still not getting enough dirt out there. any more ideas?


(ratty redemption) #17

could you replace that last pic with a version using an rgbgen const added to your blend or dirt stage, as it`s hard to see from that pic where the blending is actually happening, although I can make out some dithering which is an improvement.

other then more tweaking of your alpha channel, you could try tweaking the verts of your ground by 4-16 map units in places, and see if that affects the dithering.

it should be possible to get the desired results on a totally flat surface, but it might be easier to tweak the verts then the alpha channel.

I don`t see anything wrong with your shader and I assume your using a latter version of q3map2?


(dime1622) #18

yeah, i have 2.5.14.


(ratty redemption) #19

so that latest pic of yours shows an rgbgen const added to your blend shader? …it`s a bit faint, what rgbgen const values did you use?

anyway, if thats the case, then I can see that its just not covering up what`s underneath it.

you can test this by grouping the non blended grass and dirt and moving the group away from your blend group, or turning the underneath group into a func_group2 which won`t compile and can be hidden from view in radiant along with other entities.

taken from my ratty_entities.def which is simply a renamed .txt file in the scripts folder.

/*QUAKED func_group2 (0 0.8 0) ?
Used to group brushes together for editor convenience. Not compiled.
*/

this way your be able to just see the blend group in game, then I think your need to tweak the alpha channel so that after compiling it is mainly opaque nearest the volume brushes, and fading towards the inner and outer borders of the blend brushes.

hope that makes sense?

I know this stuff is complicated for most mappers, which is why I`m hoping someone will make newbie friendly versions of my tuts, once they have learned the advanced stuff themselves, ie what I talk about in the first versions of the water and terrain tutorials.

unfortunately, I`m just too busy to make step by step tutorials as my time is better spent helping dev the capabilities of the engine, but anyone is welcome to write newbie friendly tuts based on mine, if they credit me as the original author.


(ratty redemption) #20

dime, Ive just noticed the dimensions of your alpha channel arent square? is that just the posted image or your original dimensions?

iirc all q3 engine tex dimensions should be to the power of 2, eg, 256x128 or 64x256, 512x512 etc