View Full Version : Using a separate alpha channel for a repeating texture
TomorrowPlusX
2004.10.20, 05:57 PM
I'm curious if there's a way to selectivly multitexture based on values in a 3rd 8-bit luminance type texture ( acting as a separate alpha-channel )
Now, to try to explain this better, my situation is that I've got a terrain, with repeating surface and detail textures ( applied via auto texture coordinate generation and specially set up texture matrix ) and it looks nice and all. That said, I'd like to be able to apply different textures based on some factor -- perhaps height, perhaps something else. My terrain is uploaded via VBO, so I can't just draw in immediate mode and use glColor4f to set the alpha on a per texture vertex basis.
My textures are small and repeating, so I can't just embed a large alpha channel to them. So what I was thinking was what if I had a large 8-bit texture acting as a mask where 0 means don't apply the X texture and 255 means fully apply the X texture.
Is there some way to tell opengl to apply texture X for fragment A based on the value of texture Y for fragment A?
Thanks,
OneSadCookie
2004.10.20, 06:17 PM
you could use ARB_texture_env_combine to use one texture as the interpolation parameter between two others, but you'd need a 3-texture card to do it in one pass (Radeon or GeForce3).
You could do it in two passes with two textures per pass (the mask and one detail texture) quite straightforwardly...
arekkusu
2004.10.20, 06:18 PM
What is your target hardware?
TomorrowPlusX
2004.10.21, 10:24 AM
What is your target hardware?
To be honest, the game right now isn't meant for mass consumption -- I'm just having fun adapting my robotics code for a game engine. I'm using it as an opportunity to study flocking AI and emergent behaviors. And to drive around Mars and shoot aliens ;)
So, that said, my PB has a 5200 Fx GO, which as far as I can tell from Opengl profiler supports 4 texture units. The trouble is, I'm already using 3 -- a surface texture, a detail texture, and a lightmap/colormap texture. The first two are applied with an inverse scaling to repeat across the terrain and the latter is a 1 to 1 mapping across the terrain.
So this means I'd have just one texture unit left. I'm willing to drop the detail texture, so I'd be able to apply the surface texture across the whole terrain, then use 2 texture units for my blending of an alternate texture.
Since I'm an ABSOLUTE OPENGL NOOB ( self taught, sporadically as needed, over that last 13 months using NeHE and The red Book ) can somebody give me a 10'000 foot view of how to approach this? As in what ARB_texture_env_combine *is*?
My work has focused on AI, electronics, and machine-shop work for the last couple years -- all for my robotics work -- so my OpenGL has mainly been a minimum; as in how do I do exactly what I need. Accordingly, my robot simulator is pretty simple graphically. Example: http://home.earthlink.net/~zakariya/files/Quadruped.png
Writing a game has taught me a lot, but I've got a way to go, yet.
OneSadCookie
2004.10.21, 04:01 PM
If you only care about things working on a GeForce FX, then ARB_vertex_program and ARB_fragment_program are definitely the way to go -- much easier than ARB_texture_env_combine :)
Take a look at the OpenGL Shader Builder in /Developer/Applications...
arekkusu
2004.10.21, 06:43 PM
The 10,000 foot view is that hardware compatibility is a pain in the ass. Already, using three texture units, your application won't work on a GeForce 2MX or 4MX, which eliminates Macs sold as recently as this year (Rev A 17" PowerBook G4.)
Your GFFXGo actually has 8 texture units, but only 4 are exposed through the fixed-function pipeline. Compare (http://homepage.mac.com/arekkusu/bugs/GLInfo.html) MAX_TEXTURE_UNITS and MAX_TEXTURE_IMAGE_UNITS_ARB.
ARB_texture_env_combine (http://oss.sgi.com/projects/ogl-sample/registry/ARB/texture_env_combine.txt) is the extension to allow flexible texture combining in the fixed-function pipeline. It is supported on all renderers under OS X, so within your available texture units you can play with the combining to achieve different effects. In your case using interpolation mode like OSC said.
The modern approach this this sort of problem is to use ARB_fragment_program (http://oss.sgi.com/projects/ogl-sample/registry/ARB/fragment_program.txt) where you have total control on how texels are chosen. But this is supported on a much smaller set of hardware, so although it might work out fine for your application, I can't recommend it in general until Apple ships capable hardware in everything they sell. That means sticking a Radeon 9600 into the iBook, sometime next year.
TomorrowPlusX
2004.10.21, 06:46 PM
Thanks for the answers; I would love to pester you two further but I'm leaving for vacation to san diego tomorrow. When I get back I'll take a look at the two approaches.
TomorrowPlusX
2004.11.01, 12:15 PM
It looks to me like ARB_texture_env_combine is the way to go for me since, well, I don't know spittle about fragment programming and at the moment it's not worth my time to remedy that.
Now, that said, I'm going to attempt to write a simple program to learn how to use ARB_texture_env_combine. Probably just slapping a textured quad on the screen and seeing what I can do.
So, reading the SGI page it looks like I can pass COMBINE_ARB to glTexEnf and friends, but I'm not exactly certain of the syntax. Could you give me a pointer? Also, do I need to explicitly turn *on* the functionality, or does it just work, provided the card supports it?
Sorry to pester.
Anyway, on a side note, during free time on my vacation I wrote a cool flocking/hive-mind system for the enemies in my game. It's really cool -- the enemies by themselves are unintelligent but as they team up their "intelligence" grows and they're capable of independent as well as hive-mind group directed actions. In my demo they look and act creepily like cellular phenomena, tracking down and engulfing targets. Very lifelike.
TomorrowPlusX
2004.11.01, 12:31 PM
I've done a little more reading and I have some more specific questions.
Let's say I've got an 8-bit luminance style texture, called "A" which I want to use as my "alpha channel". And I've got another texture "B" which is my texture I want to apply.
Wherever A is white I want full application of B. Where A is black, no application of B, and linearly interpolated in between.
So, given the definition of glTexEnf,
void glTexEnvf(GLenum target, GLenum pname, GLfloat param);
And the SGI docs, it looks like I'd want to use the MODULATE parameter.
glTexEnv( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE );
But, the question is, how do I set up the texture units, so it knows which is which? I'm sorry if I'm being dense, here.
would it be something like this?
glTexEnvi( GL_TEXTURE_ENV, SOURCE0_RGB_ARB, GL_TEXTURE_0_ARB );
glTexEnvi( GL_TEXTURE_ENV, SOURCE1_RGB_ARB, GL_TEXTURE_1_ARB );
//or
glTexEnvi( GL_TEXTURE_ENV, SOURCE0_RGB_ARB, surfaceTextureID );
glTexEnvi( GL_TEXTURE_ENV, SOURCE1_RGB_ARB, surfaceAlphaTextureID );
Thanks,
arekkusu
2004.11.01, 02:54 PM
No... but that first approach is like texture_env_crossbar, which is available on ATI hardware.
With texture_env_combine, you only get one texture input per texture unit, you can't specify TEXTURE_N. Only TEXTURE, PREVIOUS, PRIMARY, and CONSTANT.
There are some posts on the board with example code for texture_env_combine effects, check them out:
one (http://www.idevgames.com/forum/showthread.php?t=4748)
two (http://www.idevgames.com/forum/showthread.php?t=7214)
Apple also has some sample code called TexCombineLab which is good for experimenting with the possible combinations. It is no longer listed on their download page but you can still get it from the ftp archive (ftp://ftp.apple.com/developer/Sample_Code/Archive/Graphics/Texcombine_Lab.sit).
TomorrowPlusX
2004.11.04, 09:39 AM
So, this morning, after reading the pages arrekusu linked on idevgames as well as ( http://www.cs.auckland.ac.nz/~jvan006/multitex/multitex.html ) and some more, I wrote a quick GLUT app to try to figure this thing out.
I made it simple as possible, I've got three textures. An "X" over blue, repeating. An "O" over purple, repeating as well. And a mixmap which is a black square fading to white in the center. The idea being that I'd try to use the mixmap to cause the "O" texture to show in the middle, fading out to the "X" texture on the rest. By the way, I'm aware that I can use vertex colors to do my mixing -- it even seems like a good idea but my terrain engine has an LOD system which results in tesselation which probably wouldn't be too useful for this task. Ultimately, I figure I might use the alpha channel of my colormap to do the mixing.
I managed to get it to work, sort of, but I'm doing something dumb. Here's a screenshot.
http://home.earthlink.net/~zakariya/files/BooHoo.png
So here's what's happening, as I see it. The "O" texture is correctly being blended in in the center fading out to the "X" texture everywhere else, just as I want. But the mixmap is being drawn *over* the whole thing, anyway.
Here's my display function:
void display(void)
{
glClearColor (0.5,0.5,0.5,1);
glClearDepth( 0 );
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glDisable( GL_LIGHTING );
glShadeModel( GL_SMOOTH );
int cx = _width / 2;
int cy = _height / 2;
int size = (int)((_width * 3.0) / 4.0);
int hSize = size / 2;
float tex0Scale = 12.0f;
float tex1Scale = 12.0f;
/*
Bind textures
*/
glActiveTextureARB( GL_TEXTURE0_ARB );
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, _texture0 );
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
glActiveTextureARB( GL_TEXTURE1_ARB );
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, _texture1 );
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
glActiveTextureARB( GL_TEXTURE2_ARB );
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, _mixmap );
glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
glActiveTextureARB( GL_TEXTURE1_ARB );
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );
glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE1_ARB );
glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR );
glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE0_ARB );
glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR );
glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE2_ARB );
glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_COLOR );
glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB );
glPushMatrix();
glTranslatef( cx, cy, 0 );
glColor4f( 1, 1, 1, 1 );
glBegin( GL_QUADS );
glMultiTexCoord2fARB( GL_TEXTURE0_ARB, -tex0Scale, -tex0Scale );
glMultiTexCoord2fARB( GL_TEXTURE1_ARB, -tex1Scale, -tex1Scale );
glMultiTexCoord2fARB( GL_TEXTURE2_ARB, 0, 0 );
glVertex2i( -hSize, -hSize );
glMultiTexCoord2fARB( GL_TEXTURE0_ARB, tex0Scale, -tex0Scale );
glMultiTexCoord2fARB( GL_TEXTURE1_ARB, tex1Scale, -tex1Scale );
glMultiTexCoord2fARB( GL_TEXTURE2_ARB, 1, 0 );
glVertex2i( hSize, -hSize );
glMultiTexCoord2fARB( GL_TEXTURE0_ARB, tex0Scale, tex0Scale );
glMultiTexCoord2fARB( GL_TEXTURE1_ARB, tex1Scale, tex1Scale );
glMultiTexCoord2fARB( GL_TEXTURE2_ARB, 1, 1 );
glVertex2i( hSize, hSize );
glMultiTexCoord2fARB( GL_TEXTURE0_ARB, -tex0Scale, tex0Scale );
glMultiTexCoord2fARB( GL_TEXTURE1_ARB, -tex1Scale, tex1Scale );
glMultiTexCoord2fARB( GL_TEXTURE2_ARB, 0, 1 );
glVertex2i( -hSize, hSize );
glEnd();
glPopMatrix();
glutSwapBuffers();
}
I suppose what I need is to figure out how to get GL_TEXTURE2_ARB to be mixed against, but not drawn.
TomorrowPlusX
2004.11.04, 09:41 AM
Oh no! Just seconds after posting I solved it.
glActiveTextureARB( GL_TEXTURE1_ARB );
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );
It should have been GL_TEXTURE2_ARB.
TomorrowPlusX
2004.11.04, 02:56 PM
New developments, new troubles.
I managed to extend the testbed such that instead of using the whole RGB mixmap texture as a channel for blending the two other textures, I got it to just use the alpha channel of the mixmap -- such that in principle I could use the RGB channels for a colormap. I would need 4 texture units but only three textures. Without applying the colormap, it works great!
So, I figured, I have three textures, A, B, & ColorMixmap, where the RGB channels of ColorMixmap are the colormap and the alpha is the mixmap for A & B. Then, all I have to do is bind the colormap to a fourth texture unit and set it up to blend just the RGB parts.
Here's my code:
void display(void)
{
glClearColor (0.5,0.5,0.5,1);
glClearDepth( 0 );
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
glDisable( GL_LIGHTING );
glShadeModel( GL_SMOOTH );
int cx = _width / 2;
int cy = _height / 2;
int size = (int)((_width * 3.0) / 4.0);
int hSize = size / 2;
float tex0Scale = 12.0f;
float tex1Scale = 12.0f;
/*
Bind textures
*/
glActiveTextureARB( GL_TEXTURE0_ARB );
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, _texture0 );
glActiveTextureARB( GL_TEXTURE1_ARB );
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, _texture1 );
glActiveTextureARB( GL_TEXTURE2_ARB );
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, _mixmap );
glActiveTextureARB( GL_TEXTURE3_ARB );
glEnable( GL_TEXTURE_2D );
glBindTexture( GL_TEXTURE_2D, _mixmap );
/*
Set up mixmap blending, use alpha channel of TEXTURE2
as interpolative factor between TEXTURE0 and TEXTURE1
*/
glActiveTextureARB( GL_TEXTURE2_ARB );
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );
glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE0_ARB );
glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR );
glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE1_ARB );
glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR );
glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_TEXTURE2_ARB );
glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND2_ALPHA_ARB, GL_SRC_ALPHA );
glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB );
/*
Set up colormap blending
*/
glActiveTextureARB( GL_TEXTURE3_ARB );
glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB );
glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS );
glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR );
glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE3_ARB );
glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR );
//why doesn't this give me a constant alpha -- it seems to still blend against
//the images alpha channel
glTexEnvi( GL_TEXTURE_ENV, GL_SOURCE1_ALPHA_ARB, GL_CONSTANT_ARB );
glTexEnvi( GL_TEXTURE_ENV, GL_OPERAND1_ALPHA_ARB, GL_SRC_ALPHA );
glTexEnvi( GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE );
glPushMatrix();
glTranslatef( cx, cy, 0 );
glColor4f( 1, 1, 1, 1 );
glBegin( GL_QUADS );
glMultiTexCoord2fARB( GL_TEXTURE0_ARB, -tex0Scale, -tex0Scale );
glMultiTexCoord2fARB( GL_TEXTURE1_ARB, -tex1Scale, -tex1Scale );
glMultiTexCoord2fARB( GL_TEXTURE2_ARB, 0, 0 );
glMultiTexCoord2fARB( GL_TEXTURE3_ARB, 0, 0 );
glVertex2i( -hSize, -hSize );
glMultiTexCoord2fARB( GL_TEXTURE0_ARB, tex0Scale, -tex0Scale );
glMultiTexCoord2fARB( GL_TEXTURE1_ARB, tex1Scale, -tex1Scale );
glMultiTexCoord2fARB( GL_TEXTURE2_ARB, 1, 0 );
glMultiTexCoord2fARB( GL_TEXTURE3_ARB, 1, 0 );
glVertex2i( hSize, -hSize );
glMultiTexCoord2fARB( GL_TEXTURE0_ARB, tex0Scale, tex0Scale );
glMultiTexCoord2fARB( GL_TEXTURE1_ARB, tex1Scale, tex1Scale );
glMultiTexCoord2fARB( GL_TEXTURE2_ARB, 1, 1 );
glMultiTexCoord2fARB( GL_TEXTURE3_ARB, 1, 1 );
glVertex2i( hSize, hSize );
glMultiTexCoord2fARB( GL_TEXTURE0_ARB, -tex0Scale, tex0Scale );
glMultiTexCoord2fARB( GL_TEXTURE1_ARB, -tex1Scale, tex1Scale );
glMultiTexCoord2fARB( GL_TEXTURE2_ARB, 0, 1 );
glMultiTexCoord2fARB( GL_TEXTURE3_ARB, 0, 1 );
glVertex2i( -hSize, hSize );
glEnd();
glPopMatrix();
glutSwapBuffers();
}
What I get is the blended TEXTURE0 and TEXTURE1 as expected, but the colormap is applied only where the colormap's alpha channel is non-zero. And everywhere else blends to black.
http://home.earthlink.net/~zakariya/files/BooHoo2.png
Any ideas? Perhaps there's a way without needing to use the fourth texture unit?
arekkusu
2004.11.04, 07:43 PM
Quick question, how are you loading your texture data for the colormap. Are you sure that the texels are not being premultiplied by the image loader?
arekkusu
2004.11.04, 08:35 PM
I think this setup does what you want; interpolate between two textures using the alpha channel of a third texture, and modulate the RGB color by the RGB of the same third texture. I do it with three units using combine and crossbar:
// setup first texture unit as REPLACE (no vertex colors for us)
glActiveTextureARB(GL_TEXTURE0);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[GRASS]);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
// setup second texture unit as INTERPOLATE (using the mixmap alpha via crossbar)
glActiveTextureARB(GL_TEXTURE1);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[WATER]);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_INTERPOLATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_RGB, GL_TEXTURE2);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_RGB, GL_SRC_ALPHA);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_INTERPOLATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_ALPHA, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE2_ALPHA, GL_TEXTURE2);
glTexEnvi(GL_TEXTURE_ENV, GL_OPERAND2_ALPHA, GL_SRC_ALPHA);
// setup third unit as MODULATE (colormap tinting, passthrough alpha)
glActiveTextureARB(GL_TEXTURE2);
glEnable(GL_TEXTURE_2D);
glBindTexture(GL_TEXTURE_2D, texture[MIXMAP]);
glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_RGB, GL_MODULATE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_RGB, GL_TEXTURE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE1_RGB, GL_PREVIOUS);
glTexEnvi(GL_TEXTURE_ENV, GL_COMBINE_ALPHA, GL_REPLACE);
glTexEnvi(GL_TEXTURE_ENV, GL_SOURCE0_ALPHA, GL_PREVIOUS);
Note that I am using crossbar to specify the third texture as the interpolation parameter. Also note that this requires an image loader which will give you the raw RGB,A values of your mixmap without destroying them with premultiplication. QuickTime works, NSImage will not.
arekkusu
2004.11.04, 08:44 PM
With crossbar, you could actually do this using only two units, interpolating between TEXTURE0, TEXTURE1 using TEXTURE2 as the interpolator. But because you need three textures, your hardware still has to support three units. You could fold some other effect into the first unit in the setup I gave above though, like vertex color modulation.
TomorrowPlusX
2004.11.05, 01:35 PM
I'm going to give this a shot. Interestingly, I *am* using NSImage for all my other textures, but the colormap and mixmap are being procedurally generated in my game. So, I'll procedurally generate them for the test as well.
I didn't know NSImage premultiplied... Is there any way to prevent that?
Addendum: Are you sure about the alpha premultiplcation? My texture loading code reports RGBA PNG images as having four channels, as I'd expect, and all blending using such textures using GL_SRC_ALPHA and GL_ONE_MINUS_SRC_ALPHA *seems* to work.
arekkusu
2004.11.05, 06:01 PM
Yes, I'm sure that NSImage premultiplies the RGB. As of Panther, there's no way to turn it off. It expects that you are going to always be drawing the image to the display, not treating the data as four separate channels.
Double check your PNG data (in hex) after it is loaded to see that the RGB is what you expect. Sometimes it's hard to notice the double-multiplied case, depending on your alpha ranges.
TomorrowPlusX
2004.11.08, 09:32 AM
Yes, I'm sure that NSImage premultiplies the RGB. As of Panther, there's no way to turn it off. It expects that you are going to always be drawing the image to the display, not treating the data as four separate channels.
Double check your PNG data (in hex) after it is loaded to see that the RGB is what you expect. Sometimes it's hard to notice the double-multiplied case, depending on your alpha ranges.
Thanks to all your help, I've gotten it working! My terrain system can now interpolate across two different textures, in my implementation based on the normal of the surface. It works beautifully. Plus, I've implemented a fallback for older cards with two texture units to just use the surface texture and colormap.
Anyway, I really appreciate the help. Thanks!
arekkusu
2004.11.08, 06:53 PM
Pics? :)
TomorrowPlusX
2004.11.09, 11:34 AM
Here:
http://home.earthlink.net/~zakariya/files/mixmapped.jpg
http://home.earthlink.net/~zakariya/files/mixmapped2.jpg
http://home.earthlink.net/~zakariya/files/mixmapped3.jpg
I think it looks pretty sweet, if I do say so myself. Notice, if you will, the self-shadowing terrain ;) I'm pretty proud of that part.
The coolest part, which I implemented this morning, is the delegation from the Terrain class itself of colormap/mixmap generation to a factory generated object, I'm calling a TerrainShader. I'm going to implement a few, for example: desert, snow, etc. The TerrainShaders can do the dirty work in a situation appropriate manner.
arekkusu
2004.11.10, 07:04 AM
Nice. This inspires me to write an interior generator (one more distraction for the pile...)
For your shadowing, I'm guessing it's a heightmap/raycaster? Do you update the colormap dynamically with sun rotation?
TomorrowPlusX
2004.11.10, 08:05 AM
Mine is a ray caster, in fact. However, it's static. It's not that the performance is bad -- it's able to calculate the shadowmap in less than a second. I could in principle have a separate thread recalculate the shadowmap once every minute or so in accordance to movement of the sun. But I don't ;) Sounds like an interesting diversion, but at the moment I've got bigger fish to fry -- regarding threading, in fact.
My implementation of the raycaster is simple; since I'm modelling the terrain using the OpenDynamicsEngine, I just cast rays and calculate their intersection with the terrain geometry. I pass the occluder position and distance from the surface to my shader so it can make soft shadows, too. The nice part about using ODE is that I can also include static level geometry in my shadow calculations.
What do you mean by an interior generator? Are you talking about a renderer? Or something which can actually generate interior geometry?
Wow, that stuff looks neat.
TomorrowPlusX
2004.11.10, 05:49 PM
Wow, that stuff looks neat.
Thanks,
I *really* wanted to have an entry in this year's contest, but I knew I wouldn't make it in time. And right now, my enemies are still 2-d only in a separate testbed. Boo.
arekkusu
2004.11.10, 11:03 PM
What do you mean by an interior generator?
I mean generating Silent (http://gallery.felixmcli.org/albums/sh3caps/sh3pc_random_64.jpg) Hill (http://gallery.felixmcli.org/albums/sh3caps/sh3pc_random_56.jpg) rooms (http://gallery.felixmcli.org/albums/sh3caps/sh3pc_random_033.jpg) programatically, including all textures, models, layout, and radiosity.
TomorrowPlusX
2004.11.11, 10:36 AM
I mean generating Silent (http://gallery.felixmcli.org/albums/sh3caps/sh3pc_random_64.jpg) Hill (http://gallery.felixmcli.org/albums/sh3caps/sh3pc_random_56.jpg) rooms (http://gallery.felixmcli.org/albums/sh3caps/sh3pc_random_033.jpg) programatically, including all textures, models, layout, and radiosity.
That sounds like a serious bit of work. I assume your radiosity will be done via shadow maps? I can't imagine that people have real-time radiosity yet via fragment shaders.
By the way, I consider Silent Hill 2 to be The Best Game of All Time.
arekkusu
2004.11.11, 07:51 PM
Yes, much work. I'm still fiddling with various ideas, but currently I'm aiming low-- run on a GF2MX. So a statically solved radiosity solution for a generated room layout, using vertex coloring for the lighting and two texture units for base and decal. A third unit for detail, if available.
There is some interesting radiosity work in fragment shaders now, as in Half Life 2's "radiosity normal mapping (http://www2.ati.com/developer/gdc/D3DTutorial10_Half-Life2_Shading.pdf)". I think this is still a static solution though.
Silent Hill series is good, but the best game of all time is still Super Metroid... ;)
vBulletin® v3.6.8, Copyright ©2000-2008, Jelsoft Enterprises Ltd.