![]() |
|
This thread is locked; no one can reply to it.
![]() ![]() |
1
2
|
Depth shading with a palette in a raycaster |
aybabtu
Member #2,891
November 2002
|
I switched my raycaster over from 16-bit to 8-bit, using the DOOM 2 palette. Since I ripped most of my sprites/textures from doom's wads anyway, there was little to no quality loss. I saw in the permadi (premadi? I dunno) tutorial, a really nice depth shading effect done with a palette. He used some sort of conversion tables or whatnot I think. Any Ideas?:P |
23yrold3yrold
Member #1,134
March 2001
![]() |
Quote: Or should I just make 5 texture maps, each a little darker untill black? Not sure what the conventional method is, but that's not a bad idea ... -- |
aybabtu
Member #2,891
November 2002
|
Making different texture maps that were lighter and darker would suck (too much work for what it is). I wonder what the conventional method is...? |
nonnus29
Member #2,606
August 2002
![]() |
Sounds like you'd need several palettes each of different 'brightnesses'. I'm not very knowledgable about color theory but I do know to lighten or darken a color you simply keep the ratio of red, green, and blues the same while increasing/decreasing their values. So just make a bunch of different palettes. I think 32 bit is the way to go though. Quote: When it was running in 16-bit, I made a really slow version, where it got the r,g,b values from the pixel, and modified them, then drew it. It was too slow... You should be able to optimize this by using bit-shifts and what not. In 32 bit it should be really fast. |
aybabtu
Member #2,891
November 2002
|
I would go into higher color depths, but I'm developing this in DJGPP, on a 586 with a crap-tastic gfx card. It can only go up to 24-bit (slowly). I'm trying my darndest to keep the framerate above 22...(easily goes to it's max on faster computers, though). So you're saying that I need different palettes? 1 for each "section" of deepness? |
james_lohr
Member #1,947
February 2002
|
Quote: Sounds like you'd need several palettes each of different 'brightnesses'. No, palettes don't work like that. You can only use one palette at any one time. (ie never more that 256 colours on the screen at any one time). The best way to achieve fading to black in 8-bit is to have a lookup table that, given a palette entry, gives the next most appropriate colour that is similar but slightly darker. I've used this a lot and it can be very effective. [edit] In fact you can use LUTs in 8-bit to get all sorts of filter effects like greyscales, fading to colours etc. Of course how good it looks depends on your palettte - fading to blue 'aint going to look good using a palette with olny three blueish colours.
|
Kitty Cat
Member #2,815
October 2002
![]() |
Doom uses a colormap table that has several remaps. Basically, it's this: -- |
Matt Smith
Member #783
November 2000
|
You could also, if you want to use 16/24 bit textures, have several RGB_MAPs which convert RGB (reduced to 15 bit) to palette indices. You would have to use a modified version of create_rgb_table() which includes a fudge-factor to make each RGB value map to a darker-than-normal index. This would then run with no further speed loss than normally found when converting 16/24 to 8 bit, and would be just as fast as remapping through COLOR_MAPs |
guru
Member #2,010
March 2002
![]() |
check out this tutorial on gamedev: http://www.gamedev.net/reference/articles/article861.asp |
aybabtu
Member #2,891
November 2002
|
Alright, I think I'll use the colormaps So, I think for starters I will have only 5. How's this for generating the maps?: //"pal" will be the palette loaded int light_map[5][256]; //Maybe I'll use 'char'? Any advantages? void generate_light_maps() { for(int i=0;i<256;i++) { light_map[0]<i>=makecol8(0,0,0); light_map[1]<i>=makecol8(pal.r*.25,pal.g*.25,pal.b*.25); light_map[2]<i>=makecol8(pal.r*.5,pal.g*.5,pal.b*.5); light_map[3]<i>=makecol8(pal.r*.75,pal.g*.75,pal.b*.75); light_map[4]<i>=i; } } Is that how makecol8() works? Does it use RGB values of 0-63, or 0-255? I have one slightly off-topic question: |
gnolam
Member #2,030
March 2002
![]() |
Quote: Color zero (mask color) in the palette is 63,0,63 (magic pink). I changed it from black, because apparently DOOM uses color 255 as the mask color...
This is a VGA limitation. The fix, however, is simple: just set palette index 0 in your palette to 0,0,0 somewhere at the start of your program. You get the best of both worlds: you can keep a distinctive (and hi-/truecolor friendly -- |
aybabtu
Member #2,891
November 2002
|
[EDIT: Didn't see your edit...;D] But won't this f**k up my masked blitting? (I changed all the sprites to use pink, along with color 0 on the palette). I use black as the transparent color in my RPG, but that sucks because I always can't find outlines of characters, and I have to make sure I don't put black in the sprites (I want to use black, though... oh well... the RPG still kicks arse!) |
gnolam
Member #2,030
March 2002
![]() |
Quote: But won't this f**k up my masked blitting? (I changed all the sprites to use pink, along with color 0 on the palette). No. The mask color is always palette index 0 in 8 bit, regardless of its color. Keep index 0 as magic pink in your sprites but set it to 0,0,0 at startup. This way you can still convert your sprites to a higher color depth (and/or edit them easily), but your program won't have the annoying border. -- |
aybabtu
Member #2,891
November 2002
|
Ohhhhh... |
nonnus29
Member #2,606
August 2002
![]() |
Your code will only work if the palette your working with is at the brightest range, otherwise it will be 5 shades to medium with no darkening. light_map[4]<i>=i; Is that what you want? It won't be colors related to pal.... |
james_lohr
Member #1,947
February 2002
|
Your code looks fine to me apart from: light_map[0]<i>=makecol8(0,0,0); Both LUTs are unecessary and it would be faster if they weren't even used.
|
aybabtu
Member #2,891
November 2002
|
Okay, I got it working for 5 light levels, but it wasn't really that nice looking. So, I changed it to 10 levels, but now there are problems.
I did put some code in to have it spit out the values of lite_map[9] to a file: /* LM9[#] is which index, RGB is the _current_pallete<i>.r .g .b*4, 'C' is the index that makecol8 returns. */ LM9[0] R 0 G 0 B 0 C 0 LM9[1] R 858993459 G 1077490483 B 0 C 1077018624 LM9[2] R 0 G 1077018624 B -1717986918 C 1076205977 LM9[3] R 858993459 G 1078997811 B 858993459 C 1078997811 LM9[4] R -1717986918 G 1080842649 B -1717986918 C 1080842649 LM9[5] R -1717986918 G 1077254553 B -1717986918 C 1077254553 LM9[6] R -858993459 G 1076677836 B -858993459 C 1076677836 LM9[7] R -858993459 G 1075629260 B -858993459 C 1075629260 LM9[8] R -858993459 G 1074580684 B -858993459 C 1074580684 ... You get the idea ... Here's the implementation of the lite_maps in the slice drawing code: /* buffer is the bitmap being drawn to column[srcy] is the pixel being placed on that buffer */ if(distance>=0&&distance<100) (buffer->line<i>)[x]=lite_map[9][column[srcy]]; if(distance>=100&&distance<200) (buffer->line<i>)[x]=lite_map[8][column[srcy]]; if(distance>=200&&distance<300) (buffer->line<i>)[x]=lite_map[7][column[srcy]]; if(distance>=300&&distance<400) (buffer->line<i>)[x]=lite_map[6][column[srcy]]; if(distance>=400&&distance<500) (buffer->line<i>)[x]=lite_map[5][column[srcy]]; if(distance>=500&&distance<600) (buffer->line<i>)[x]=lite_map[4][column[srcy]]; if(distance>=600&&distance<700) (buffer->line<i>)[x]=lite_map[3][column[srcy]]; if(distance>=700&&distance<800) (buffer->line<i>)[x]=lite_map[2][column[srcy]]; if(distance>=800&&distance<900) (buffer->line<i>)[x]=lite_map[1][column[srcy]]; if(distance>=900) (buffer->line<i>)[x]=0; //lite_map[0][column[srcy]]; On the screenshot, I marked levels 9 through 4, which are the problem levels. The FPS is low only when the bad levels take up a majority of the view. Otherwise, it's at about 25 fps. Thanks for any help... |
nonnus29
Member #2,606
August 2002
![]() |
You are multiplying and getting overflow in the unsigned chars of the RGB struct.
For each r,g, or b for each RGB struct in the palette you need to multiple by a fraction to get a different intensity, the *4 is not required. I would do this; lite_map[1]<i>.r=_current_pallete<i>.r*x; lite_map[1]<i>.g=_current_pallete<i>.g*x; lite_map[1]<i>.b=_current_pallete<i>.b*x; //where x varies from .1 to 1.9 not to exceed 255
|
aybabtu
Member #2,891
November 2002
|
So umm, no makecol()? |
nonnus29
Member #2,606
August 2002
![]() |
I edited that a little. No, I don't see why you'd need makecol. It seems a bit redundant. I could be wrong though.... |
james_lohr
Member #1,947
February 2002
|
Quote: I would do this; lite_map[1]<i>.r=_current_pallete<i>.r*x; I certainly wouldn't! It's not going to work in 8-bit mode. No offence but you appear to be confused. [edit] Let me explain in a bit more detail: In 8-bit mode you can have only 256 colours on the screen at any one time. To make a particular colour darker, you have to chose another one of the 256 colours that best fits a darker version of the original colour, you do not modify the palette unless you want all the onscreen pixels of the modified index to change. This is the whole purpose of the light_map look up table, it stores which of the 256 colours best fits the colour produced by modifying the original colour. Storing RGB values in the LUT is completely pointless unless you want to use makecol8 every time you wish to draw a pixel. considering that makecol8 has to search the whole palette this would be slooooow.
|
Steve Terry
Member #1,989
March 2002
![]() |
Why couldn't you just set up the pallete such that you have, for example with 4 shade depths, it broken down into 64x4 sections of colors. That way the lower 64 colors are all your regular pallete data but at the lightest intensity, then the next 64 colors are a shade darker and so on until you have 4 units of 64 colors. Then depth shading is trivial as you only have to shift up your color index based on depth to the next level... or is this what you are already doing? ___________________________________ |
james_lohr
Member #1,947
February 2002
|
Quote: Why couldn't you just set up the pallete such that you have, for example with 4 shade depths, it broken down into 64x4 sections of colors. but: Quote: I switched my raycaster over from 16-bit to 8-bit, using the DOOM 2 palette. Since I ripped most of my sprites/textures from doom's wads anyway, there was little to no quality loss. He switched to 8-bit so that he could youse the DOOM 2 palette. The whole point is to avoid having to change the palette. If you change the palette you'll have to change all the textures.
|
Steve Terry
Member #1,989
March 2002
![]() |
Well if it's the exact same pallete doom used and doom used depth shading then he needs to find the exact algorithm id used and mimic it, otherwise I guess setting up a LUT would work, however using percentages like he's using will probably not work since id may have used some other way of indexing the pallete.... I dunno. ___________________________________ |
Yves Rizoud
Member #909
January 2001
![]() |
You can use Doom's pre-calculated COLORMAP resource. Use a program like Wintex to extract the binary chunk from the game file. |
|
1
2
|