1

How can I manually set where the pixel ends up in the texture in PixelShaderFunction HLSL? Ideally I want the GPU to follow the next logic:

  1. Write pixels one by one in no particular order. Meaning whenever first pixel comes out, write it into the top left corner of the texture. Write second one to the right of the first one and the third one to the right of the first one, and so on.
  2. When you reach the end of the line - go to the next line.
  3. When you reach the end of the texture - drop all the remaining pixels.

Thanks.

I feel like I can do it by manually computing the needed position for my pixel at the vertex shader level. If I could understand better how the pixel positioning works I might be able to pull it out. If I have a render target 2000*4. How can I ensure at the vertex shader level that my pixel will end up in the second row?

What if my RenderTarget is a texture with height = 1 can I not bother computing the positions? Or do I risk loosing data via pixel merging? I am planning to draw nothing but long lines through the screen, one by one and clear the target in between.

cubrman
  • 782
  • 6
  • 20

1 Answers1

0

Basically you can't do what you're describing.

After the vertex shader, the GPU has a collection of triangles to draw. It fills them, pixel-by-pixel, on the render target (possibly the backbuffer). As part of this filling process - to determine the colour of each pixel - your pixel shader gets called (like a function) for that specific pixel being filled. There is no capacity at this point for "moving" the output pixel.

What you can do is modulate the texture coordinate parameter to tex2D (MSDN) when sampling from a texture in your pixel shader. You can apply whatever functions make sense to achieve your desired result.

Or, if the transform is simple, you can simply set the texture coordinates appropriately either in the vertex data, or using a vertex shader.

Andrew Russell
  • 26,137
  • 7
  • 54
  • 104
  • What I am trying to achieve is the following: my pass will return a huge array with several unique numbers repeating over and over, which I need to retrieve and process on CPU. I tried rendering into a 2000x1 texture and then sampled it on the CPU with RenderTarget2d.GetData<>() and a foreach loop. It was awfully slow :). So I sidestepped my problem, the idea now is to render to a 1x1 texture multiple times. Inbetween passes I will extend a parameter array in my shader to include the numbers already returned. – cubrman Jul 26 '13 at 18:26
  • Each pixel will than query the array and clip itself if it holds a number that already appeared. The problem now is that pixel color never changes nomatter what I render. Can it be because I render too small a content into it (I am drawing a line on the screen and sample the scene's color along the line)? Here is the link to another thread where I ask this question: http://stackoverflow.com/questions/17888689/rendering-a-line-into-a-1x1-rendertarget2d-does-not-change-the-targets-pixel-co – cubrman Jul 26 '13 at 18:41
  • It really sounds like you're trying to achieve "something" and you've decided on a solution - that doesn't necessarily work well - and you're asking how to implement that solution. When, instead, you should perhaps be starting from a higher level by explaining what your "something" is and asking for the best way to achieve it. (And it could be that your solution is the correct one - but then at least it could provide some context for your other questions - which are confusing without that context.) – Andrew Russell Jul 28 '13 at 10:27
  • Otherwise, all I can say is that `GetData` is a very slow call: It allocates memory (fast but can trigger a slow garbage collection), it pulls data back from the GPU (slow) and stalls the GPU pipeline (very slow). So, if you must use it, then hopefully you're not calling it repeatedly for single-pixel regions (this wasn't clear from your comment). You'd be much better off grabbing a large region with a single `GetData` call. – Andrew Russell Jul 28 '13 at 10:32
  • I want to implement a pixel perfect collision detection on GPU. Our game has specific firing mechanics where the bullet has to hit the first visible object on its way. The objects are skeletaly animated and skinned on gpu. We have already implemented ordinary collision detection system with bounding cubes that we skin on cpu. But I think pixel perfect collision would be a much better and faster approach (esp for artists). This is how I want to do this: 1. I draw my skeletal monsters into some rendertarget as ID-s (numbers). 2. I draw my bullet into 1x1 rendertarget with a shader... – cubrman Jul 28 '13 at 10:37
  • ... the shader recieves the scene with monster ID-s as texture, samples it according to bullet's screen coordinates and returns a) monster ID and b) computes the distance between the bullet's start position and the current position. 3. The distance gets stored into the z coordinate and the depth buffer clips all the pixels but the one with the smallest distance. 4. I end up with a 1x1 rendertarget which I read to get the monsterID and then damage the monster on cpu. – cubrman Jul 28 '13 at 10:40
  • That sounds massively over-complicated. Personally I would probably look into implementing CPU-side collision detection using per-bone spheroids (or similar) that tightly wrap the skeleton (probably after a bounding-box broadphase). That should be fast and close-enough to pixel-perfect. – Andrew Russell Jul 28 '13 at 11:07
  • If you *really* want pixel-perfect accuracy, then I'd do the really simple thing: Calculate the potential bounds for a collision, render all the collidable objects from the scene that fall within that region. Bring the whole region back to the CPU (single `GetData` call), and calculate pixel-collisions there. (You know, some people go so far as to implement simple 3D rendering on the CPU for this). But this is really too complex to discuss in detail in comments, so I encourage you to ask a full question (probably on the [gamedev site](http://gamedev.stackexchange.com/)). – Andrew Russell Jul 28 '13 at 11:09
  • I don't think it should be that slow. If I figure out how to specify in the VertexShader where a pixel should end up in the rendertarget i would end up with 1 texture with as many pixels as I have bullets this frame (like 200 top). And then I will need but 1 GetData call to process them all. Maybe if it is possible I would wait until the next frame, or run another thread and then process the read data in the next frame which is quite tolerable. The whole problem now is that I cannot make all the pixels write into the same area. – cubrman Jul 28 '13 at 11:21
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/34321/discussion-between-cubrman-and-andrew-russell) – cubrman Jul 28 '13 at 11:22
  • Accepted as an answer as my experience with shaders proved repositioning pixels in pixel shader is indeed impossible. – cubrman Jun 24 '17 at 06:43