Sign in to follow this  
wlb2001

Terrain multitexturing problem

Recommended Posts

Hi there:
I am currently working on a terrain rendering project. I have 2 problems with it.
1: The terrain has 4 textures for multi-textureing(grass,sand,rock ....), and also has a 4 channels(RGBA) detail texture to indicate weight of each texture.(ie.128,0,127,0 roughly means %50 grass and %50rock). By using shader, this is easy, final = a*R + b *G + c*B + d*A where a,b,c,d are sample color from textures.But how to implement it without shader? For example, we might use glTexEnv for multitextureing?
Is that possible to render it without shader and in single pass?
2: if terrain textures are up to 8, then it will be 10 texture units(8 textures,2 details) it seems it is impossible to render it within single pass even if with shader.(because most video cards only support 8 texture units for multitextureing)
Is there any way to render it in single pass?

thanks for your helps!

Share this post


Link to post
Share on other sites
To the best of my knowledge, what you are trying to do isn't really possible using fixed-function alone, and especially not in a single pass. I remember implementing something similar a very long time ago using glVertexAttribPointerARB to specify an array of vertex attributes per blend layer to perform the blending, but even still I had to set up a vertex program (old school) to do the alpha replacement.

Maybe you could figure something out if you split the blending RGBA texture up into separate GL_ALPHA format textures, but this of course would eat up available binding slots.

Share this post


Link to post
Share on other sites
[quote name='JTippetts' timestamp='1317476379' post='4867963']
To the best of my knowledge, what you are trying to do isn't really possible using fixed-function alone, and especially not in a single pass. I remember implementing something similar a very long time ago using glVertexAttribPointerARB to specify an array of vertex attributes per blend layer to perform the blending, but even still I had to set up a vertex program (old school) to do the alpha replacement.

Maybe you could figure something out if you split the blending RGBA texture up into separate GL_ALPHA format textures, but this of course would eat up available binding slots.
[/quote]

Really thanks for the help.
Is it could be done by multipass? Use depth function to set equal for second pass?

Share this post


Link to post
Share on other sites
[quote name='Murdocki' timestamp='1317485809' post='4868003']
A2: Texture atlassing is key, just put the four textures into one and sample it four times( once for each detail channel )
[/quote]

Thanks for the reply Murdocki;
would you give any details for putting 4 textures into one? I really have no idea how to put four textures into one (each texture at least has 3 channels RGB,and for enable textures I have to call glActiveTexture() 4 times.).

Share this post


Link to post
Share on other sites
"Is it could be done by multipass? Use depth function to set equal for second pass?"

Yes, this is typically how it would be done.

Make sure you write solidly for the first pass (to populate the depth buffer), turn off depth writing for the subsequent passes (for speed), set equal as the test and then use chained texture blend units to feed the R G or B component from one stage as the alpha into the second.

The key phrase to look up here is "texture combiners".

Basically if you imagine the fixed functionality has a bunch of little units in it which can have the inputs fed from selections of different things -- constant colours, a texture lookup, the glColor or (crucially here) the output from one of the earlier stages.

Setting them up is faffy and fiddly and involves a big stack of glTexEnvi(GL_TEXTURE_ENV,...) calls; it's a good idea to plan out carefully what needs setting up before starting to write the code.

You'll need to do some jiggery pokery with the texture coordinate scales; because one of your textures is big (landscape sized) and one of them is the grass/sand/rock tile. I *think* you do this by chosing the active texture unit and then manipulating the texture matrix, and it'll apply to just that unit. So you can put a scaling on one of the lookups.

You could I guess, possibly do this in one go. Maybe. You'd have to look really carefully at the texture combiner modes available.

Is there any reason why you can't just do this in a modern vertex shader? It seems a lot of work to go to to do this ye olde fashionedey wayey.

Share this post


Link to post
Share on other sites
If you got four images of 256*256 dimensions you can create one image of 512*512 which contains one of the images in each corner, you can do this with paint / gimp or any other image editing tool.

Something like this:

[img]http://www.echo-gaming.eu/base1.png[/img]


This image is then loaded and bound as a single texture, in your fragment program you can calculate the texture coordinates for each individual image with something like this
[code] vec2 t1Coords = vec2( texCoord.x / 2.0, texCoord.y / 2.0 );
vec2 t2Coords = vec2( texCoord.x / 2.0 + 0.5, texCoord.y / 2.0 );
vec2 t3Coords = vec2( texCoord.x / 2.0, texCoord.y / 2.0 - 0.5 );
vec2 t4Coords = vec2( texCoord.x / 2.0 + 0.5, texCoord.y / 2.0 - 0.5 );[/code]

Share this post


Link to post
Share on other sites
Just as an aside, I'm finding it hard to think of a justification these days for not using shaders. If it's a "supporting older hardware" thing, you might keep this in mind: the original ARB_vertex_program and ARB_fragment_program extensions were created in 2002 or thereabouts. That's almost a decade ago. Even with those ancient and decrepit extensions, the texture splatting problem is an order of magnitude easier to solve. All the "jiggery pokery", as Katie so awesomely described it, is meant to "fake" an actual programmable shader by setting up a complex set of cascading texture stage states. I honestly believe that you can safely assume a very high percentage of gamers will have hardware that supports at least a basic level of programmability, and forego all the [b]glTexEnv[/b] voodoo.

Share this post


Link to post
Share on other sites
These days I'd be very suprised if you had to go below 'DX9 level' hardware, which is basically shaders; I have a hard time imagining there are much hardware 'in the wild' these days which wouldn't support GLSL1.0, and that which didn't probably wouldn't have the fill rate to pull of other hacks or multi-pass tricks at an acceptable speed anyway.

I'd advise that, unless you know for certain a large percentage of your target can't run even basic shaders, to go in the shader direction.

If you are doing it 'just to learn' then stop right now. The API is dead, there is nothing to learn which would be useful and you would be better served picking up shaders instead.

Share this post


Link to post
Share on other sites
[quote name='Murdocki' timestamp='1317503455' post='4868082']
If you got four images of 256*256 dimensions you can create one image of 512*512 which contains one of the images in each corner, you can do this with paint / gimp or any other image editing tool.

Something like this:

[img]http://www.echo-gaming.eu/base1.png[/img]


This image is then loaded and bound as a single texture, in your fragment program you can calculate the texture coordinates for each individual image with something like this
[code] vec2 t1Coords = vec2( texCoord.x / 2.0, texCoord.y / 2.0 );
vec2 t2Coords = vec2( texCoord.x / 2.0 + 0.5, texCoord.y / 2.0 );
vec2 t3Coords = vec2( texCoord.x / 2.0, texCoord.y / 2.0 - 0.5 );
vec2 t4Coords = vec2( texCoord.x / 2.0 + 0.5, texCoord.y / 2.0 - 0.5 );[/code]
[/quote]


Okya. It sounds works.I'd try it later. Really thanks for the idea.

Share this post


Link to post
Share on other sites
[quote name='phantom' timestamp='1317512060' post='4868115']
These days I'd be very suprised if you had to go below 'DX9 level' hardware, which is basically shaders; I have a hard time imagining there are much hardware 'in the wild' these days which wouldn't support GLSL1.0, and that which didn't probably wouldn't have the fill rate to pull of other hacks or multi-pass tricks at an acceptable speed anyway.

I'd advise that, unless you know for certain a large percentage of your target can't run even basic shaders, to go in the shader direction.

If you are doing it 'just to learn' then stop right now. The API is dead, there is nothing to learn which would be useful and you would be better served picking up shaders instead.
[/quote]

Yeah, I am sure most of my targets can't run shaders. I hate those on board video chips. Most of them only support up to OpenGL v1.4(maybe 1.5).That's why I have to figure out the way without shader. Anyway, still really thanks for the advices.

Share this post


Link to post
Share on other sites
[quote name='wlb2001' timestamp='1317561445' post='4868252']
Yeah, I am sure most of my targets can't run shaders. I hate those on board video chips. Most of them only support up to OpenGL v1.4(maybe 1.5).That's why I have to figure out the way without shader. Anyway, still really thanks for the advices.
[/quote]

Those would be Intel and they most likely CAN run shaders. Use DirectX9 and shaders and it will work great.
As for GL, Intel doesn't update or put in much effort in their GL driver. Their drivers tend to be buggy (search these forums and you'll find plenty of posts).

Good luck.

Share this post


Link to post
Share on other sites
I am new to this as well, but when texturing my terrain I develop the terrain in an modeling program like blender. From there I usually change my nurbs surface into a mesh after that I export my mesh into a UV map. Then I export my UV maps to a painting program such as gimp or photoshop. Then if you export your file as a .obj file or something similar. You will get texture coordinates for your uv maps, vertex coordinates, and vertex normals. From there all you have to do is read the .obj file and it can load up your textures onto your model for you. I don't know if this is the best approach, but its the approach that I am using to texture my terrain.

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this