Xbox LIVE Indie Games
Sort Discussions: Previous Discussion Next Discussion
Page 1 of 3 (55 posts) 1 2 3 Next >

Brushing away sand effect

Last post 8/3/2010 8:48 AM by Stainless. 54 replies.
  • 7/8/2010 10:37 PM

    Brushing away sand effect

    Hi guys,

    I'm familiar with programming (mainly C++/PHP and Java) but am fairly new to XNA. Now, the question:

    I was wondering how I would go about implementing an effect whereby a user brushes away sand which is covering the entire screen by clicking/dragging on it (thus revealing the background below it - say just a black screen).

    Would this be possible by using one image of sand which is then manipulated through slicing/rotating etc or would this be better implemented through some sort of particle system?

    Thanks in advance,

    P
  • 7/8/2010 11:01 PM In reply to

    Re: Brushing away sand effect

    I'd probably do it with one or more layers of seamless sand texture, and some sort of alpha mask for each one.  To create the "brush" effect, you'd effectively be painting the alpha mask(s) progressively more transparent each time the user dragged across it.  For a chunkier effect, you could alternately have a lot of small overlapping sand sprites, and when a user brushed over them, either remove them or increment some counter on them that would fade them out gradually.  I'd recommend against trying to do individual sand grains as particles unless you're dead set on a very specific, very processor-intensive effect.

    You could also have some sort of short-lived, low-alpha dust puff effect that you could generate around the cursor as a particle effect, which would help mask any abrupt change in the underlying image.  Not necessary, but would probably look more polished that way.
  • 7/9/2010 1:17 AM In reply to

    Re: Brushing away sand effect

    Sigil:
    I'd probably do it with one or more layers of seamless sand texture, and some sort of alpha mask for each one.  To create the "brush" effect, you'd effectively be painting the alpha mask(s) progressively more transparent each time the user dragged across it.  For a chunkier effect, you could alternately have a lot of small overlapping sand sprites

    Wouldn't this mean that the user would effectively be dragging relatively 'large' (when compared to a grain of sand) images around? I'd preferably like the sand to be as realistic as possible...

    Also, I'm assuming making each particle/grain of sand an object would result in too much of a performance hit.
  • 7/10/2010 4:30 PM In reply to

    Re: Brushing away sand effect

    pierisc:
    Also, I'm assuming making each particle/grain of sand an object would result in too much of a performance hit.


    That's almost certainly true.  At 720p resolution, 1-pixel grains of sand would require just short of a million objects just to cover the screen 1 grain deep, and you'd need at least 5 or 10 deep to get the effect right.  Real-time graphics engines on modern hardware don't operate well in the 'tens of millions of individual objects' scale quite yet.  Even a rendering package like Max or Maya would have to gnaw on that scene for a while to do it convincingly.

    pierisc:
    Wouldn't this mean that the user would effectively be dragging relatively 'large' (when compared to a grain of sand) images around?


    Yes, one way or another, but real-time graphics are all about faking something in a sufficiently convincing way.  If you used several layers of larger sprites full of many sand grains, but feathered and alpha-blended them on the edges, and then covered over the edges and transitions with some hand-waving like fades, scaling effects, low-alpha dust overlays, and some small particle systems of small individual grains spraying out from the cursor as it wipes, you can probably fake it pretty effectively.
  • 7/10/2010 7:29 PM In reply to

    Re: Brushing away sand effect

    Sigil:

    Yes, one way or another, but real-time graphics are all about faking something in a sufficiently convincing way.  If you used several layers of larger sprites full of many sand grains, but feathered and alpha-blended them on the edges, and then covered over the edges and transitions with some hand-waving like fades, scaling effects, low-alpha dust overlays, and some small particle systems of small individual grains spraying out from the cursor as it wipes, you can probably fake it pretty effectively.


    In that case, it sounds like I'm going to have to spend a sufficient amount of time image editing in order to make convincing and seamless sand sprites before continuing with development!
  • 7/10/2010 9:05 PM In reply to

    Re: Brushing away sand effect

    Is the sand a central, critical element in your game?  If not, I would advise against getting too hung up on that particular element.  Pretend it's snow, and just do the whole thing with white-to-black greyscale images for starters.  You can probably get something convincing working pretty quickly, and revisit the texture later, working out the specifics of seamlessness, and precise levels of feathering, alpha, and element size.
  • 7/11/2010 2:38 AM In reply to

    Re: Brushing away sand effect

    Thanks for the reply Sigil.

    The sand is a core component of the game, the rest shouldn't be too hard. That's why I'm aiming on making the sand seem as convincing as possible.

    I've managed to feather the texture and can drag a single 'sand sprite'. The next step will be to look into the various blending techniques et al you mentioned before. The snow idea i.e. the white-to-black greyscale images sounds like a good idea - I'm assuming that will enable me to 'practice' blending techniques?
  • 7/11/2010 2:15 PM In reply to

    Re: Brushing away sand effect

    pierisc:
    The snow idea i.e. the white-to-black greyscale images sounds like a good idea - I'm assuming that will enable me to 'practice' blending techniques?


    Correct.  I was recommending that so you can learn how blending works without getting too hung up on the precise sand texture.  Once you have a convincing sprite size and blending level, then you can add the texture back in and season to taste.
  • 7/12/2010 3:41 PM In reply to

    Re: Brushing away sand effect

    Just a quick thought; If the sand is represented by a height map of the same size as the screen, then it could easyly be manipulated with effects like gravity and storm.

    /Robert
  • 7/13/2010 9:13 PM In reply to

    Re: Brushing away sand effect

    Robert Warnestam:
    Just a quick thought; If the sand is represented by a height map of the same size as the screen, then it could easyly be manipulated with effects like gravity and storm.

    /Robert


    Please could you elaborate? I don't understand how I could incorporate a height map into the project. At present, I have multiple sand images which fade (i.e. become more and more transparent) when clicked upon.
  • 7/15/2010 1:29 PM In reply to

    Re: Brushing away sand effect

    The way I would approach it is to use an array

    The array holds the amount of sand in a particular area of the screen.

    When the user interacts you move some of the sand from one area to another.

    In the display code I would take each array element and render it as a region of the screen.

    I would have several sand textures and render the relevant one depending on the amount of sand in the array.

    I would also do a faked bump map so you get the illusion of a dune forming.

    I haven't tried it, but in theory it should look pretty good.


  • 7/15/2010 4:50 PM In reply to

    Re: Brushing away sand effect

    Stainless:
    The way I would approach it is to use an array
    Yeah, I've done something similar using arrays.  :-)
    Stainless:
    I would also do a faked bump map so you get the illusion of a dune forming.

    I have a question regarding the illusion of a dune forming: is there a generic method for BoundingBox which returns true/false based upon whether its hit anything? 

    What I mean by generic is that, it doesn't matter what the BoundingBox has hit, all that matters is that it returns true if it has.

    I know of the Intersects method but this is not suitable because I want to find out whether a sand sprite is touching another sand sprite. Using the intersects method would mean I'd have to iterate through a large array of objects along the lines of 

    if((spriteBox.Intersects(spriteInArray.BoundingBox))

    and that'd be for every single sand object, i.e. extremely inefficient and cause major slowdown.

    Thanks for the replies, they're much appreciated.
  • 7/15/2010 9:21 PM In reply to

    Re: Brushing away sand effect

    The height map could be used to track the amount of dust/sand in each pixel on the screen. Manipulating a height map is as easy as if it had been an array but one benefit by using a height map is that you could use it in your shader.
  • 7/15/2010 9:46 PM In reply to

    Re: Brushing away sand effect

    Sand from another perspective;

    http://chir.ag/stuff/sand/
  • 7/16/2010 2:46 AM In reply to

    Re: Brushing away sand effect

    Thanks for the replies Robert. Ah yes, I've seen (and played!) the falling sand game. Tis good fun.

    I'm intrigued by this concept of a height map and how an image can be used to track the amount of sand on screen. 

    However, since I come from a developer/programming background I'm a bit lost and up until now have only been using typical constructs such as arrays/objects. I found this tutorial on height maps but am not sure whether it'd be suitable since I'm trying to create a height map from a 2d image of sand.

    Furthermore, the app I'm developing is from a birds eye point of view, would a height map still be suitable?

    Thanks again.
  • 7/16/2010 8:00 PM In reply to

    Re: Brushing away sand effect

    Hi again,

    I was playing around with some ideas and got the following lines to use a heigh map, paint on it and then draw it on the screen;

    1 // ---------------------------------------------  
    2             // Member declarations  
    3             // ---------------------------------------------  
    4               
    5             // The workTarget is our "height map" where Red indicates how much sand there is  
    6             RenderTarget2D workTarget;  
    7             // We are drawing over a nice background (same size as screen)  
    8             Texture2D background;  
    9             // We have a picture containing a sand brush (big)  
    10             Texture2D sandTexture;  
    11             // And a texture to paint with (a softed red circle, 64x64)  
    12             Texture2D pen;  
    13             // Shader to render the screen  
    14             Effect dustShader;  
    15             // Screen dimensions  
    16             int width;   
    17             int height;  
    18             Rectangle screenRectangle;  
    19             SpriteBatch spriteBatch;  
    20             MouseState mouse;  
    21  
    22             // ---------------------------------------------  
    23             // Loading resources  
    24             // ---------------------------------------------  
    25             spriteBatch = new SpriteBatch(Game.GraphicsDevice);  
    26             width = GraphicsDevice.Viewport.Width;  
    27             height  = GraphicsDevice.Viewport.Height;  
    28             screenRectangle = new Rectangle(0, 0, width, height);  
    29             background = Game.Content.Load<Texture2D>("Dust/penguins");  
    30             sandTexture = Game.Content.Load<Texture2D>("Dust/sand");  
    31             pen = Game.Content.Load<Texture2D>("Dust/brush");  
    32             dustShader = Game.Content.Load<Effect>("Dust/DustShader");  
    33             workTarget = new RenderTarget2D(GraphicsDevice, width, height, false,  
    34                 GraphicsDevice.PresentationParameters.BackBufferFormat,  
    35                 DepthFormat.None,  
    36                 0,  
    37                 RenderTargetUsage.PreserveContents);  
    38  
    39             // ---------------------------------------------  
    40             // Paint when user presses mouse   
    41             // observe that we are painting directly to our height map  
    42             // ---------------------------------------------  
    43  
    44             mouse = Mouse.GetState();  
    45             int x = mouse.X;  
    46             int y = mouse.Y;  
    47             RenderTargetBinding[] previousRenderTargets = GraphicsDevice.GetRenderTargets();  
    48             GraphicsDevice.SetRenderTarget(workTarget);  
    49             spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive);  
    50             spriteBatch.Draw(pen,  
    51                 new Vector2(x - pen.Width / 2, y - pen.Height / 2),  
    52                 new Color(255, 255, 255, 255));  
    53             spriteBatch.End();  
    54             GraphicsDevice.SetRenderTargets(previousRenderTargets);  
    55  
    56             // ---------------------------------------------  
    57             // Render the screen (Draw method)  
    58             // ---------------------------------------------  
    59  
    60             spriteBatch.Begin(  
    61                 SpriteSortMode.Immediate,  
    62                 BlendState.Opaque,  
    63                 SamplerState.LinearWrap,  
    64                 DepthStencilState.None,  
    65                 RasterizerState.CullNone,  
    66                 fDustShader);  
    67             Effect effect = dustShader;  
    68             effect.CurrentTechnique = effect.Techniques["PaintDust"];  
    69             effect.Parameters["ScreenTexture"].SetValue(workTarget);// is done by Draw() method  
    70             effect.Parameters["Background"].SetValue(background);  
    71             effect.Parameters["Sand"].SetValue(sandTexture);  
    72             effect.Techniques["PaintDust"].Passes[0].Apply();  
    73             spriteBatch.Draw(workTarget, screenRectangle, Color.White);  
    74             spriteBatch.End(); 

    Shader code:
    1 uniform extern texture ScreenTexture;      
    2  
    3 sampler paintTexture = sampler_state  
    4 {  
    5     Texture = <ScreenTexture>;      
    6 };  
    7    
    8    
    9 texture Sand;  
    10 sampler2D sandTexture = sampler_state {  
    11     Texture = (Sand);  
    12 };  
    13  
    14 texture Background;  
    15 sampler2D backgroundTexture = sampler_state {  
    16     Texture = (Background);  
    17 };   
    18  
    19 float4  PS_PaintDust(float2 texCoord: TEXCOORD0) : COLOR0  
    20 {  
    21     float4 color = tex2D(backgroundTexture, texCoord);  
    22     float4 colorSand = tex2D(sandTexture, texCoord);  
    23     float4 colorHeight = tex2D(paintTexture, texCoord);   
    24  
    25     float sandFactor = colorHeight.r;  
    26     float backgroundFactor = 1.0 - sandFactor;  
    27  
    28     color = color * backgroundFactor + colorSand * sandFactor;  
    29     return color;  
    30 }  
    31    
    32 technique PaintDust  
    33 {  
    34     pass Pass1  
    35     {  
    36         PixelShader = compile ps_2_0 PS_PaintDust();  
    37     }  
    38 }  
    39  
    40 float4 getpixel(float2 texCoord, float du, float dv)  
    41 {  
    42     texCoord.x = texCoord.x + du;  
    43     texCoord.y = texCoord.x + du;  
    44     return tex2D(paintTexture, texCoord);  
    45 }  
    46  
    47  
    48  

    Then also you need some textures;

    • Background: I took a wallpaper from windows
    • Sand: Use google or create one by using Photoshop and the clouds effect
    • Pen: I used a 64x64 tga picture with alpha layer

    Of course there is lot of thinks to do like;

    • Add more to the "PaintDust" shader. Like lightning and motion...
    • Replace the "painting" with a custom shader: such a shader could also do other stuff like removal of sand
    • Implement the blur effect where the sand would get some realistic physics added

    Good luck

    Robert

  • 7/16/2010 10:01 PM In reply to

    Re: Brushing away sand effect

    Hi Robert, thank you for the detailed response.

    I've managed to get the 'pen' to paint its texture on the screen based upon were the cursor was but am experiencing errors with the other parts of the code. (I believe its because you're using XNA 4.0(?) whereas I'm using 3.1)

    the problem areas are as follows:

    Line 47 - Missing directive or assembly reference?
    Line 48 - works if I change it to...
    47             RenderTargetBinding[] previousRenderTargets = GraphicsDevice.GetRenderTargets();  
    48  From ->GraphicsDevice.SetRenderTarget(workTarget);  
      
    To ->    GraphicsDevice.SetRenderTarget(0, workTarget)

    Line 49 - I had to change it to...
    49  From -> spriteBatch.Begin(SpriteSortMode.Deferred, BlendState.Additive);  

    To -> spriteBatch.Begin(SpriteBlendMode.Additive);

    Line 62 - I do not have a 'BlendState', instead I used SpriteBlendMode but 'Opaque' doesn't exist.
    Lines 63-66 Errors stating 'not existing in the current context'
    60             spriteBatch.Begin(  
    61                 SpriteSortMode.Immediate,  
    62                 BlendState.Opaque,  
    63                 SamplerState.LinearWrap,  
    64                 DepthStencilState.None,  
    65                 RasterizerState.CullNone,  
    66                 fDustShader);  

    Line 69 - it is expecting workTarget to be a Texture, not a RenderTarget2D.
    Line 72 - Missing directive or assembly reference?
    69             effect.Parameters["ScreenTexture"].SetValue(workTarget);// is done by Draw() method  
    72             effect.Techniques["PaintDust"].Passes[0].Apply();  

    it wants workTarget to be a Texture2D as opposed to a RenderTarget2D.
    73             spriteBatch.Draw(workTarget, screenRectangle, Color.White);  

    Sorry for the long post!
  • 7/16/2010 10:12 PM In reply to

    Re: Brushing away sand effect

    I just converted my app to 4.0 and have not 3.1 installed anymore. But I don't think there should be any problems.

    Line 47: skip it. After you have done your work restore by using SetRenderTarget(0,null) or something
    Line 48: ok
    Line 49: ok
    Line 60: I'm not sure of how to replace the begin call. The imortant think here is to make sure the spriteBatch is using the dustSdahder
    Line 69: The RenderTarget class has a method GetTexture() - hasn't it?
    Line 72: In 3.1 you have to use Begin() and End() instead of only using Apply()
    Line 73: See line 69



  • 7/16/2010 11:46 PM In reply to

    Re: Brushing away sand effect

    Thanks for the swift response.

    I managed to get the code to compile using the following in the Draw method:

    spriteBatch.Begin(SpriteBlendMode.None,SpriteSortMode.Immediate,SaveStateMode.None);
    Effect effect = dustShader;
    effect.Begin();
    effect.CurrentTechnique.Passes[0].Begin();
    effect.Parameters["ScreenTexture"].SetValue(workTarget.GetTexture());// is done by Draw() method
    effect.Parameters["Background"].SetValue(background);
    effect.Parameters["Sand"].SetValue(sandTexture);
    spriteBatch.Draw(workTarget.GetTexture(), screenRectangle, Color.White);
    spriteBatch.End();
    effect.Techniques["PaintDust"].Passes[0].End();
    effect.End();

    Now I have a background image which I can paint over using the pen variable (brush texture).
  • 7/17/2010 4:02 PM In reply to

    Re: Brushing away sand effect

    Robert Warnestam:
    I just converted my app to 4.0 and have not 3.1 installed anymore. But I don't think there should be any problems.

    Line 47: skip it. After you have done your work restore by using SetRenderTarget(0,null) or something
    Line 48: ok
    Line 49: ok
    Line 60: I'm not sure of how to replace the begin call. The imortant think here is to make sure the spriteBatch is using the dustSdahder
    Line 69: The RenderTarget class has a method GetTexture() - hasn't it?
    Line 72: In 3.1 you have to use Begin() and End() instead of only using Apply()
    Line 73: See line 69

    Thanks for the replies Rob, I appreciate the help. Unfortunately, I just don't have any experience with heightmaps/shaders so am sticking to the array/object approach.

    Stainless:
    The array holds the amount of sand in a particular area of the screen.

    When the user interacts you move some of the sand from one area to another.

    In the display code I would take each array element and render it as a region of the screen.

    I would have several sand textures and render the relevant one depending on the amount of sand in the array.

    I would also do a faked bump map so you get the illusion of a dune forming.


    I'm using arrays, I liked the idea of a dune forming so attempted to change my implementation to something more like this. 

    Unfortunately, when moving sand from one area (array) to another array, this causes too much of a performance hit since multiple items need to be shifted and when they are redrawn in the new area/array, the transition doesn't look smooth.

    As a result, I'm sticking with what I've got at the moment which is simply 2 arrays, a 'main' array and an 'overlay' array which holds another sand texture. The user is able to drag the sand and the sand will fade thus giving a 'brushing effect'. It looks decent but an issue is with how 'tiled' the sand looks since I'm only using 2 textures at the moment. 

  • 7/18/2010 11:08 AM In reply to

    Re: Brushing away sand effect

    Okay how about this.

    Have a texture, say half the size of the final display.

    Surface format single.

    Call this the sand map, actually you will need two of these

    Have another texture, surface format vector2

    Call this the displacement map.

    When the user swipes the screen, write the velocity to apply to the sand into the displacement map at the correct location.

    Then 

    Update:

     set one of the sand maps as the source, and the other as destination
     use a shader to move the sand using the displacement map as the velocity source
     swap source and destination

    Draw:

    take the value from the sand map, use this to generate an alpha value for the final pixel
    pass in the light direction as a normalised vector2
    multiply this by the size of one pixel
    sample the sand map at this position
    use the difference in sane values to do a simple bump map
    texture the pixel and draw it

    This should give you the appearance of several hundred thousand individual grains of sand.

    You should even be able to apply simple physics to the particles, allowing them to slide back down a slope if the slope is steep enough.


     
  • 7/18/2010 5:03 PM In reply to

    Re: Brushing away sand effect

    Answer
    Reply Quote
    Thanks for the reply, just some clarification:

    Stainless:
    Have a texture, say half the size of the final display.
    Surface format single.
    Call this the sand map, actually you will need two of these


    I've created 2 Texture2D variables containing SurfaceFormat.single

    Stainless:

    Have another texture, surface format vector2
    Call this the displacement map.
    I've also created a Texture2D displacementMap variable with a 'velocity' variable of type Vector2.

    Stainless:
    When the user swipes the screen, write the velocity to apply to the sand into the displacement map at the correct location.
    I'm a bit confused by the second half of this sentence. I've managed to capture the users input i.e. I know when they swipe and which direction. I've also made the sandmap1 follow the users cursor when they drag i.e. if they drag left - the sandmap1 will move left etc... but what do you mean by "write the velocity to apply to the sand into the displacement map at the correct location"?

    Please could you also elaborate on the 'Update' and 'Draw' functions. I'm struggling to grasp how using a sandmap/displacementMap can be used in order to create the illusion of several hundred thousand individual grains of sand.

    Sorry for being slow, I really appreciate the help.



  • 7/19/2010 8:53 AM In reply to

    Re: Brushing away sand effect

    The user clicks on the screen at a given location, call this x,y and drags with a velocity dx,dy.

    What you need to do is write a velocity into the displacement map at that location, and a few pixels around it as well.

    This displacement is used to move the sand around.

    The simplest solution would be to keep an array of Vector2's in memory, initially set this up so they are all Vector2.Zero.

    If the user is pressing the screen at x,y, set the vector2 in the array at x,y to dx,dy.  Really what you want to do is set not just the actual x,y but an area around it, but you can think about that later when you have got your head around this idea.

    Then call setdata on your velocity map with the array of Vector2's

    In your update shader you advect the sand map density using the velocity texture, some thing like this..

    float4 AdvectDensity(float2 Coords : TEXCOORD0) : COLOR0 
        float2 vel = tex2D(VelocityMapSampler, Coords).xy; 
        vel=2*(vel-0.5); 
         
        float2 pos = Coords - timestep * rdx * vel; 
        float4 xNew = dissipation * bilerp(DensityMapSampler, pos);   
        xNew.w=1; 
        return xNew; 
      
    //=============================================================================================== 
    //= These methods perform texture lookups at the four nearest neighbors of the position s and   = 
    //= bilinearly interpolate them.                                                                = 
    //=============================================================================================== 
    float4 bilerp(sampler tex, float2 s) 
      float4 st; 
      st.x = -rdx; 
      st.y = -rdx; 
      st.z = rdx; 
      st.w = rdx; 
      st.xy+=s; 
      st.zw+=s; 
       
      float2 t = float2(0.5,0.5); 
         
      float4 tex11 = tex2D(tex, st.xy); 
      float4 tex21 = tex2D(tex, st.zy); 
      float4 tex12 = tex2D(tex, st.xw); 
      float4 tex22 = tex2D(tex, st.zw); 
     
      // bilinear interpolation 
      return lerp(lerp(tex11, tex21, t.x), lerp(tex12, tex22, t.x), t.y); 

    This "moves" the sand about.

    At the end of the update you have an array of sand densities, stored in a texture.

    To render it you would do something like this, note you would have to play with the actual values to work out what works best, but anyway....

      float density=tex2D(sand,input.TexCoords).x; 
      float next=tex2D(sand,input.TexCoords+(Light*SizeofPixel)).x; 
      next-=density; 
      next *= 8; 
      next=clamp(0,1,next); 
      next=1-next; 
       
      float4 color=tex1D(pallete,density); 
      color.rgb *= next; 
      return color; 
     
       

    This does a fake bump map on the density, gets a colour from a pallete based on the density (note this should contain alpha), and displays the result.


    This is just a colourised version, no texture but it makes the idea a bit easier to understand, I hope.




  • 7/19/2010 8:45 PM In reply to

    Re: Brushing away sand effect

    Stainless:
    The simplest solution would be to keep an array of Vector2's in memory, initially set this up so they are all Vector2.Zero.

    If the user is pressing the screen at x,y, set the vector2 in the array at x,y to dx,dy.  Really what you want to do is set not just the actual x,y but an area around it, but you can think about that later when you have got your head around this idea.

    Then call setdata on your velocity map with the array of Vector2's




    Hi again, I've created an array of Vector2s (called vectorArray) based upon the users dragging action. I'm trying to call setData in the update method but keep getting the following error

    "The type you are using for T in this method is an invalid size for this resource."

    Code snippet:

                displacementMap = new Texture2D(graphics.GraphicsDevice, (int)singleNumber, viewportRect.Height, 0, 
                    TextureUsage.None, SurfaceFormat.Vector2);

    in update (once a 'swipe' has been detected): 

       displacementMap.SetData<Vector2>(vectorArray);

    I don't understand what I'm doing wrong?
  • 7/19/2010 11:49 PM In reply to

    Re: Brushing away sand effect

    Hi again, I've created an array of Vector2s (called vectorArray) based upon the users dragging action. I'm trying to call setData in the update method but keep getting the following error

    "The type you are using for T in this method is an invalid size for this resource."

    The SetData method looks as follows:

     displacementMap.SetData<Vector2>(vectorArray);

    I don't understand what I'm doing wrong?


    It means the texture's buffer was initialized with a data type other than Vector2.  By default, surface buffers are initialized using the Color struct in XNA.  So, when you create the texture you must explicitly tell it to initialize using Vector2 instead.

       Texture2D DisplacementMap = new Texture2D(GraphicsDevice, width, height, 1, TextureUsage.None, SurfaceFormat.Vector2);


    By the way, I fully support this method of imitating sand, I've done similar effects this way before myself.  I also think it would be relatively trivial to modify my Navier-Stokes fluid solver to simulate sand, because when you get down to it, sand is basically an incompressible fluid with variable viscosity (i.e. a non-Newtonian fluid).  Essentially then what you have is an interplay between the divergence of the density map gradient and other internal forces trying to bring the sand to a steady state and external forces trying to rip it apart.

    I might have to give this a try, sounds like a fun weekend project. :)
Page 1 of 3 (55 posts) 1 2 3 Next > Previous Discussion Next Discussion