creasso

Hi to everyone! and an Amazing 2007!

STATUS:

I'm working with an effect to damage the armors, itens and etc from my game characters I did notice that the "easy" way to do this was have 2 textures, one to the default difuse channel and another with the holes and scratches overlayed above the Difuse one with alpha channels to "damage" just some areas from the equipment model surface.

Since the .X exporters collapse the material maps inside 3ds MAX, I can't use the Composite MAP, and the export to .fx function in Material Editor don't accept any map than not a simple bitmap to this, what lead me to write a HLSL shader to do the texture overlay. I already got one texture above another with different map channels.

ISSUE:

But I plan use to the overlay texture a single texture with 4 damage categories (also 4 different source rectangles), lets suppose "fine, scratched, damaged and broken" but I can't figure how to do the shader feeding, while I can change the entire map not even one instruction points how to get just a source rectangle from a loaded texture. I did notice that the return of a "Texture2D" call can be passed like my Effect.Parameter so I can change the entire texture (what can be a "just works" solution), but I didn't find not even one of the Texture2D constructors or methods that crops a given file returning a texture area.

This was new, and give me another way to do the cropping, since a Texture2D can being sent to HLSL processing directly, I can cut and crop it inside my XNA code sending to my effect just quads to be used in effect composing.

Writing the Text function, I did learnt that the SpriteBatch object do exactly what I'm searching for, but it don't have a method that returns the Texture2D that it is using to draw, after do the source rectangle reading. A detail is that looks like the SpriteBatch don't does any new file creation or render to texture operation while doing this, what can means that it reads and sample the texture directly from/to GPU memory.

I did read the HLSL reference searching for a way to do the cropping inside the shader, but the tex2D function don't do this, also I can't do this inside the Texture Sampler2D since its AddressU, V and W States are enumerators and don't have support to receive a float coordinate directly. Also to do this following the 3dsmax texture cropping process I need an AddressH that is not a Sampler_State valid statement.

I fear that doing the entire texture change at runtime I'll lose performance, if yes, a solution will be have 4 shaders loaded since the beggining of execution doing almost the same thing, what I think is a bad use of resources since with this same effects I can apply 3 different effects to another models.

Looks like both XNA Framework and HLSL can do the desired operation, but I can't figure how to do it with not even one of then . I'm missing something but I can't figure what. I did look at AnimatedTexture( ) but looks like this class was removed from XNA, probably being replaced by SpriteBatch.

QUESTION:

Does exists already a XNA object or HLSL instruction that does texture reading and cropping

Please do you can suggest any way, class or documentation to use/read to discover how to do the desired cropping

Any advice will be greatly appreciated .

Thank you!



Re: XNA Game Studio Express "SPRITE TEXTURE MAP" I need some directions/suggestions

wakawaka54

To answer your question, no there is not a class specificly designed to handle texture manipulation. But I am currently creating a Halo 2D game and I am doing something similiar to what you are doing. Except I am not using a diffuse texture or blah, blah, blah. What I suggest on doing is this...

 

public class MyDiffuseTexture

{

//In this example I am using a Collection but you can use an array with a little of adjusting

public Collection<Vector4> DiffuseTextureValues = new Collection<Vector4>();

//This will hold the diffuse texture

public Texture2D DiffuseTexture;

//This method will run at the beggining when everything has loaded

//You must assign DiffuseTexture a value before you can run this method!!!

public void ProcessDiffuseTexture()

{

//In this example I use a Color array but you can use an integar array if you want

Color[] tColors = new Color[DiffuseTexture.Width * DiffuseTexture.Height];

DiffuseTexture.GetData<Color>(tColors);

for(int i = 0; i != tColors.Length; i++)

{

//If the pixel color is not equal to (in this case white will be the background color) white

if(tColorsIdea != Color.White)

{

//Now all you have to do is get this Collection and when you apply damage you

//the index of the pixel (this will require both textures to be the same size) and the color of the pixel

DiffuseTextureValues.Add(new Vector4(tColorIdea.R, tColorIdea.G, tColorIdea.B, i));

}

}

}

}

Then in your armor or whatever class you would a version of the following method...

public class MyArmor

{

public MyDiffuseTexture DiffuseTexture;

public Texture2D ArmorTexture;

//You must set the DiffuseTexture and ArmorTexture before this method can be ran

public void ApplyDamage()

{

Color[] armorData = new Color[ArmorTexture.Width, ArmorTexture.Height];

foreach(Vector4 pixel in DiffuseTexture.DiffuseTextureValues)

{

armorData[pixel.W] = new Color(new Vector3(pixel.X, pixel.Y, pixel.Z));

}

ArmorTexture.SetData<Color>(armorData);

}

}

 

 

This is the way I would do it. Because I don't know how much stuff you have to process each frame I don't know if this will really affect proformance. But something like this is what I would suggest.

 

Hope this helped

 

wakawaka54!!!!!!!!!!!!!!!!!!!!!!!!

 

The 13 year old genius

 

PS. Sorry about those lightbulds I have to figure out how to get rid of them just copy and paste this into a textfile and I think you should see everything.






Re: XNA Game Studio Express "SPRITE TEXTURE MAP" I need some directions/suggestions

creasso

Amazing! Thanks for the help waka!

I did not get noticed about Texture2.getdata and setdata, your post points an interesting path to follow! Thanks!

Now i just need create a dummy texture with the desired size, getdata from the source rectangle in my top texture to an array and after write to my dummy texture before send it to the shader (theorically it will works) . Now I'll do some coding and tests to see how much perforance I can get doing this at runtime.

Really thanks for your help.





Re: XNA Game Studio Express "SPRITE TEXTURE MAP" I need some directions/suggestions

parlance

This is not the correct way to do this. From what I understand, this is your problem:

You have a 3D mesh with one set of UV coordinates and a base texture that together comprises the item itself. You also have a 'damage' texture in which there are several portions of the texture related to various levels of damage. You are using a custom shader to do multi-texturing to give the item a damaged look and you would like to use the different areas of the damage texture to correspond with the item's various levels of damage.

The first and foremost thing I would say here is using a custom HLSL shader just to do multitexturing isn't necessary. Multitexturing can be accomplished through the fixed function pipeline with the proper configuration of texture stage states and render states, although I won't get into here since it sounds like you already have a working shader to do this.

The first and easiest solution (and the one that I would suggest, seeing as how the number of damage levels seems fairly limited) is to split your overlay texture into seperate textures per damage level, and set the correct overlay texture corresponding to the damage level before rendering your item model. The overhead associated with individual textures (and render state changes) in most cases isn't worth avoiding for something like this.

On the other hand, if you'd like to keep your overlay texture as a single texture, the correct and by far the most efficient way to 'select' the correct rectangle of the overlay texture is by using a texture transformation matrix. Texture transformation matrices work like regular transformation matrices, except they will be used to transform your local U,V,W coordinates rather than your X,Y,Z coordinates. The fixed function pipeline supports an individual texture matrix per texture stage, but since you are using a custom shader you are going to have to emulate that functionality yourself. The first thing you need to do is to add a second pair of UV coordinates to the output structure of your vertex shader, these will represent the UV coordinates we will use to sample from the overlay texture in the pixel shader, and the other UV coordinates will be the coordinates used to sample the item texture. You will also need to add a 3x3 or 4x4 matrix to your vertex shader constants, name it overlayMatrix or something similar to that. The code in your vertex shader will set the value of our second pair of UV coordinates in the output structure to the incoming UV coordinates transformed by the texture matrix. After you have finished making the modifications to your shader, you need to create and set the texture matrix before rendering your object. The construction of the texture matrix defines the source rectangle such that (0, 0) * texture matrix, (0, 1) * texture matrix, (1, 0) * texture matrix, and (1, 1) * texture matrix are the corners of the rectangle. Obviously given an identity matrix, the rectangle would still be (0,0), (0, 1), (1, 0), (1, 1), however, we will wish to specify only a fraction of that. The code itself will vary depending on how you arranged the subtextures in your overlay texture and the size of the texture, but regardless you will need to generate a translation and scale matrix, and multiply those together to generate your final texture matrix before setting the shader parameter.

Hope this helps.





Re: XNA Game Studio Express "SPRITE TEXTURE MAP" I need some directions/suggestions

creasso

Greetings Parlance and Thank You!

Like I did tell, I did suspect that both XNA and HLSL can do the task, waka told me about a way to do inside XNA, preprocessing the texture before send it to my shader, now you teach me a way to modify the shader to achieve the same inside HLSL. Really Thanks!

In really I'll need do experiments with both processes and (why not ) understand both to apply the most indicated to each case, while texture.(getdata; setdata;) give me pixel precision I still don't have idea about its performance, and the UV matrix modification that you suggest will work fine with textures divided in "pair numbers" I don't know how a (0.3, 0),(0.6, 0),(0.3, 0.3),(0.3, 0.6) will works if I had a 3x3 framed texture sent to the shader.

The nice thing about your solution is that I can test it inside FX Composer so I'll not have the needs of setup an entire XNA project to do the tests.

Thanks for your time!





Re: XNA Game Studio Express "SPRITE TEXTURE MAP" I need some directions/suggestions

parlance

creasso wrote:

Greetings Parlance and Thank You!

Like I did tell, I did suspect that both XNA and HLSL can do the task, waka told me about a way to do inside XNA, preprocessing the texture before send it to my shader, now you teach me a way to modify the shader to achieve the same inside HLSL. Really Thanks!

In really I'll need do experiments with both processes and (why not ) understand both to apply the most indicated to each case, while texture.(getdata; setdata;) give me pixel precision I still don't have idea about its performance, and the UV matrix modification that you suggest will work fine with textures divided in "pair numbers" I don't know how a (0.3, 0),(0.6, 0),(0.3, 0.3),(0.3, 0.6) will works if I had a 3x3 framed texture sent to the shader.

The nice thing about your solution is that I can test it inside FX Composer so I'll not have the needs of setup an entire XNA project to do the tests.

Thanks for your time!

You're welcome =) Feel free to experiment with both techniques, but I think you will find that the uv coordinate modulation approach vastly more effective in terms of performance, especially in scenes with many objects the overlay texture.

Cheers!