Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Translating C to C# and HLSL: will this be possible?

Tags:

c

c#

xna

hlsl

I've taken on quite a daunting challenge for myself. In my XNA game, I want to implement Blargg's NTSC filter. This is a C library that transforms a bitmap to make it look like it was output on a CRT TV with the NTSC standard. It's quite accurate, really.

The first thing I tried, a while back, was to just use the C library itself by calling it as a dll. Here I had two problems, 1. I couldn't get some of the data to copy correctly so the image was messed up, but more importantly, 2. it was extremely slow. It required getting the XNA Texture2D bitmap data, passing it through the filter, and then setting the data again to the texture. The framerate was ruined, so I couldn't go down this route.

Now I'm trying to translate the filter into a pixel shader. The problem here (if you're adventurous to look at the code - I'm using the SNES one because it's simplest) is that it handles very large arrays, and relies on interesting pointer operations. I've done a lot of work rewriting the algorithm to work independently per pixel, as a pixel shader will require. But I don't know if this will ever work. I've come to you to see if finishing this is even possible.

  1. There's precalculated array involved containing 1,048,576 integers. Is this alone beyond any limits for the pixel shader? It only needs to be set once, not once per frame.
  2. Even if that's ok, I know that HLSL cannot index arrays by a variable. It has to unroll it into a million if statements to get the correct array element. Will this kill the performance and make it a fruitless endeavor again? There are multiple array accesses per pixel.
  3. Is there any chance that my original plan to use the library as is could work? I just need it to be fast.
  4. I've never written a shader before. Is there anything else I should be aware of?

edit: Addendum to #2. I just read somewhere that not only can hlsl not access arrays by variable, but even to unroll it, the index has to be calculable at compile time. Is this true, or does the "unrolling" solve this? If it's true I think I'm screwed. Any way around that? My algorithm is basically a glorified version of "the input pixel is this color, so look up my output pixel values in this giant array."

like image 434
Tesserex Avatar asked Apr 18 '11 03:04

Tesserex


1 Answers

From my limited understanding of Shader languages, your problem can easily be solved by using texture instead of array.

  1. Pregenerate it on CPU and then save as texture. 1024x1024 in your case.
  2. Use standard texture access functions as if texture was the array. Posibly using nearest-neighbor to limit blendinding of individual pixels.
  3. I dont think this is possible if you want speed.
like image 155
Euphoric Avatar answered Sep 17 '22 18:09

Euphoric