ground multitexturing- combine textures of different stages?

hi all,

we would like to generate a ground covered by different kinds of textures … grass, rock, dirt, road for example …

of course de map is huge… so we can’t apply a simple composed texture on it, without loosing to much precision…

so we made 2 set of UV for the ground …

the first one, just fitting a “cell” of the ground allows texture tilling, keeping local precision of the picture good enought

the second one fitting the entire map, have been affected by a grayscale image (or an image using alpha channel)

the first step we would like to do, is to combine the alpha on the second texture set, with the first one, allowing by this way to seem some rocky areas on grass covered land for example …

I’have read the documentation for a long time and I haven’t find a way to do that … is it possible or should I implement cg-shaders for that specific purpose ?

Its very easy to write a CG shader to do that job. I have one lying around here, so give a squeal if you need something.

Without shaders, your closest approximation is to use a third texture to switch between textures A and B, using CMInterpolate mode. If shaders are an option, they’re probably your best bet.

David

ho … pro-rsoft … every help you can bring to us is welcome of course … I have take a look to CG shader language … but with my poor level in coding … it’s hard enought :confused: (basically, i’am a 3D modeler, giving a hand to the code team)

@drwr : the purpose is to make ground composed bye more than 2 textures (the more we can put on it the best it will look) … so the way you describe risk to become very complex :frowning: but thanks anyway :wink:

ok

I have studied cg for days and managed to generate a 3 textures covered land (grass, dirt, and stone) blending using the R,G or B channel of a fourth texture…

the (new) problem I encountered is that it seems to be a limit of 4 textures applied on an objext at the same time …

what can I do if I want to add one or more extra texture on the land … should I divide It into separted meshes (witch can involved problem because the mesh is generated bye heightfield) or is there another way to bypass the limitation … ?

The limitation is imposed by your hardware. Different graphics cards have different limits.

You can use the alpha channel of one of the first three textures to determine the switch condition. That way you can save at least one texture.

David

is it possible pour put the four 512x512 texture on a same 1024x1024 pict and modify the coordonates of the sampling point in the fragment shader program ?

[edit] : humpf :confused: it seems to be impossible to acces the interpolated texture coordinates of a fragment to adujst it to the right chunck of the composed texture… if anyone know a technic I can use for this purpose … he is welcome :wink:

I’m looking for something like that. Anything changed since 2007 ? Anyone saw ready to use solution ?

Texture combine modes and texture matrixes let you have masks that set the alpha for tiled detail textures.

panda3d.org/manual/index.php/T … bine_Modes

Thanks !

codepad.org/agsXeq6y

Wroks great - thanks :slight_smile:

Hm, I don’t seem to get lightning working.

import direct.directbase.DirectStart
from pandac.PandaModules import *


terrain = loader.loadModel('terrain')
terrain.reparentTo(render)

# Stage 1: stencil
ts = TextureStage("stage-stencil")
ts.setSort(0)
ts.setMode(TextureStage.MReplace)
ts.setSavedResult(True)
terrain.setTexture(ts, loader.loadTexture("stencil.png"))

# Stage 2: the first texture
ts = TextureStage("stage-first")
ts.setSort(1)
ts.setMode(TextureStage.MReplace)
terrain.setTexture(ts, loader.loadTexture("dirt.png"))

# Stage 3: the second texture
ts = TextureStage("stage-second")
ts.setSort(3)
ts.setCombineRgb(TextureStage.CMInterpolate, TextureStage.CSTexture, TextureStage.COSrcColor,
                                             TextureStage.CSPrevious, TextureStage.COSrcColor,
                                             TextureStage.CSLastSavedResult, TextureStage.COSrcColor)
terrain.setTexture(ts, loader.loadTexture("grass.png"))


# lightning
slight = Spotlight('slight')
slight.setColor(VBase4(1, 0.1, 0.1, 1))
lens = PerspectiveLens()
slight.setLens(lens)
slnp = render.attachNewNode(slight)
slnp.setPos(0, 0, 3)
slnp.setHpr(0, -90, 0)
slnp.lookAt(terrain)


run()



terrain.egg : mediafire.com/?hfw32d0yjwv

Or mediafire.com/?jjnzn0jzg2j

Either create a stage that blends in the primary colour, or call setShaderAuto to enable the shader generator, which doesn’t suffer from the same issue.

More info please.

terrain.setShaderAuto() or render.setShaderAuto() , but I still don’t see any changes.

EDIT: Look below.

There’s a few things going on.

First, your dirt texture is set to MReplace, not MModulate, so that it will completely replace the vertex lighting. Similarly, your grass texture is painted with COSrcColor, so the same problem happens.

You should restructure your texture chain so that your grass and dirt textures are the first two textures, and they are applied with MReplace. Then apply the stencil texture as the third texture, applied with CMInterpolate. This will allow the lighting to show through.

Once lighting shows through, your terrain will be almost entirely black, because it is illuminated only by a single spotlight which is only three units above the terrain and pointed straight down. (Use slight.showFrustum() to reveal its position.) So you might want to broaden this light, or better yet, use a directional light (since it is, after all, an outdoor scene).

David

Sorry, for some reason that manual page is a bit confusing for me.
Is this what you mean?:

import direct.directbase.DirectStart
from pandac.PandaModules import *

terrain = loader.loadModel('terrain')
terrain.reparentTo(render)


# Stage 1: the first texture
ts = TextureStage("stage-first")
ts.setSort(0)
ts.setMode(TextureStage.MReplace)

ts.setSavedResult(True)

terrain.setTexture(ts, loader.loadTexture("dirt.png"))

# Stage 2: the second texture
ts = TextureStage("stage-second")
ts.setSort(1)
ts.setMode(TextureStage.MReplace)
terrain.setTexture(ts, loader.loadTexture("grass.png"))

# Stage 3: stencil
ts = TextureStage("stage-stencil")
ts.setSort(2)
ts.setCombineRgb(TextureStage.CMInterpolate, TextureStage.CSPrevious, TextureStage.COSrcColor,
				TextureStage.CSLastSavedResult, TextureStage.COSrcColor, 
				TextureStage.CSTexture, TextureStage.COSrcColor) 
terrain.setTexture(ts, loader.loadTexture("stencil.png"))


# lightning
slight = Spotlight('slight')
slight.setColor(VBase4(1, 0.1, 0.1, 1))
lens = PerspectiveLens()
slight.setLens(lens)
slnp = render.attachNewNode(slight)
slnp.setPos(0, 0, 3)
slnp.setHpr(0, -90, 0)
slnp.lookAt(terrain)

terrain.setShaderAuto()
render.setLight(slnp)


run()