Lugaidster


Well the real thing here is that I'm new to the programming pipeline so I kinda need some help on this. The thing is that I want to render primitives but with a custom texture format (CLUT, as in Color Look-Up Table, from the PSx anyone ). This textures instead of having a color have an index that goes to another 1D texture containing the actual color.

Imagine this, you have a regular texture that has 4-bytes per color RGBA32, and each component instead of being the brightness level of that color is an index to a 256x1 texture containing the actual color.

The problem relies in the fact that you have 4 colors in a "color" or fragment for that matter. But once you get to the pixel shader rendering part you can't 'spawn' new fragments. So how do I do it to map the correct color on the fragment... Or another way, how do I do it to transform that texture into the correct format and then in another pass use that texture.

Any approach or Idea would be greatly appreciated. It would simplify my work alot by simply handling this conversion or transformation in the GPU, and I figured, since the gpu usually does tasks that are way more complex than this in regular games, why should I lose performance by doing it in software, besides the fact that it would complicate things a lot more by doing it in that way.

Thanks in advace, and I'm sorry if I didn't explained better, but english isn't my native language.

Regards,
Alberto


Re: Help on some shader issues

Ross Ridge


The simple answer to your problem is to use a 1 byte per colour format like D3DFMT_L8 for your texture. Unfortunately, doing a palette lookup like this in a pixel shader may not produce the results you're expecting. You'll need to disable filtering (ie. use point sampling) otherwise your texture's index values will get interpolated before being sent to the pixel shader. If you want filtering you'll need to do it yourself in the shader.

As for the complexity of colour indexed textures, video card manufactures actually dropped support for them because they were too expensive, in terms of space on the chip, to implement. You should consider whether it's possible for you to use one of the DXTn compressed texture formats (eg. D3DFMT_DXT1) instead.





Re: Help on some shader issues

Lugaidster

I'm aware that palleted textures aren't the best way of doing things or even a good way of doing things this days, the deal is that I'm stuck to using 16-bit color textures with 8-bit palletes (2 pallete indexes per texture color), that is the constraint. So I was trying to pass all the work to the gpu since I though that the .NET framework would do things like that pretty slow even on fast computers. I'll see if I can come up with something. BTW thanks for pointing out the point sampling issue, that would've had my head spinning otherwise.

Again, if someone has any ideas no matter how crazy they are, please share.

Regards,
Alberto





Re: Help on some shader issues

Ross Ridge

You said before you were trying get four indexes out of a 32-bit ARGB colour, now you're saying you want to get two indexes out of 16-bit colour. If your texture data is in fact really just 8-bit indexes, one per byte, then Format.L8 is the solution to your problem. You get one 8-bit unsigned value per 8-bit "colour" which you can then look up in a 1D texture in your pixel shader.

Also, converting your texture data to an uncompressed format wouldn't be slow using managed code, especially if you use the texture loading methods to do it for you.





Re: Help on some shader issues

Lugaidster

Looks like you nailed it. I'll be looking into it and see if I can get it working. One question though, since the texture is in that format what is the type of value I should expect from the tex1D intrinsic And one more question, probably rather simple but still (since I'm pretty new to 3d graphics concepts). Imagine I have my vertex data already transformed and lit, that means that for a vertex I have a "brightness" in a range from 0 to 127 for each color component, a screen space position and a texture coordinate. How do I apply this brightness value to the end color through the pixel shader .

Well thanks, it looks rather simple now that you mention that format.

Regards,
Alberto




Re: Help on some shader issues

Ross Ridge

You would use the tex2D() intrinsic to sample your 2D Format.L8 texture containing the colour indexes and tex1D() to lookup the index in the 1D "palette" texture. Both intrinsics return 4 element float vector, representing the colour sampled. In the case of sampling from the 2D Format.L8 texture, the unsigned value in the range of 0 to 255 will be scaled to a floating-point value in the range of 0.0 to 1.0 and replicated in all 4 elements (RGBA) of the returned colour.

Your vertex data would actually have a value from 0 to 255 for each component, assuming you're using the standard 32-bit RGBA diffuse colour values. When passed to your vertex shader the diffuse colour would be converted into a 4 element float vector with a value of 0.0 to 1.0 for each component. Your vertex shader would then presumably output the colour unmodified and after being interpolated it would be passed to your pixel shader. You would normally apply the diffuse colour by multiplying (modulating) it with the colour sampled from the texture.

btw. D3DFMT_L8 is the unmanaged equivilent of Format.L8.





Re: Help on some shader issues

Caele

 Ross Ridge wrote:

You would use the tex2D() intrinsic to sample your 2D Format.L8 texture containing the colour indexes and tex1D() to lookup the index in the 1D "palette" texture. Both intrinsics return 4 element float vector, representing the colour sampled. In the case of sampling from the 2D Format.L8 texture, the unsigned value in the range of 0 to 255 will be scaled to a floating-point value in the range of 0.0 to 1.0 and replicated in all 4 elements (RGBA) of the returned colour.

Your vertex data would actually have a value from 0 to 255 for each component, assuming you're using the standard 32-bit RGBA diffuse colour values. When passed to your vertex shader the diffuse colour would be converted into a 4 element float vector with a value of 0.0 to 1.0 for each component. Your vertex shader would then presumably output the colour unmodified and after being interpolated it would be passed to your pixel shader. You would normally apply the diffuse colour by multiplying (modulating) it with the colour sampled from the texture.

btw. D3DFMT_L8 is the unmanaged equivilent of Format.L8.



Hi, I'm trying to do this exact thing. The problem I get is when I try to use the index from my 2d texture to look in the 1d texture, it doesn't seem to produce any output. If I pass the index as a color directly I get something so the indexTexture seems to work correctly.
In the pixel shader:
index = tex2D(positionToIndex,PSIn.TexCoords);
color = tex1D(arrayToColor, index);

I've figured that the problem either is in the sampler:
Texture indexTexture;
Texture colorTexture;
sampler positionToIndex = sampler_state { texture = <indexTexture> ;
magfilter = POINT; minfilter = POINT; mipfilter=POINT; ADDRESSU = mirror; ADDRESSV = mirror;};
sampler arrayToColor = sampler_state { texture = <colorTexture> ;
magfilter = POINT; minfilter = POINT; mipfilter=POINT; ADDRESSU = mirror; ADDRESSV = mirror;};

Or in ny texture decleration (the texture seems to contain the correct typ of data):
Texture txtrManaged = new Texture(_device, 255, 1, 1, Usage.AutoGenerateMipMap, Format.A8R8G8B8, Pool.Managed); //colorTexture

Texture txtrManaged = new Texture(_device, _textureSize, _textureSize, 1, Usage.AutoGenerateMipMap, Format.L8, Pool.Managed); // indexTexture

Any help would be great, hopefully I've only done some stupid mistake somewhere above.