• Advertisement
Sign in to follow this  

DX11 FXAA and Color Space

This topic is 1994 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

Hey guys,

I know, there were a few topics on FXAA, but it didn't help me with my problem, hence the new thread.

The problem is, I don't see any difference between the FXAA and Non-FXAA Render.

Then again I am not passing a non-linear color space texture to the FXAA shader. And not sure how to.
If my understanding is correct Linear color space is the one that is got when you sample a texture (0 to 1 range or 0 - 255 range) where the colors change in a linear fashion.

I am not sure what sRGB is about ?
Currently my texture is in RGBA8 dx format.

According to Fxaa3.11 release by Timothy.
"Applying FXAA to a framebuffer with linear RGB color will look worse.
This is very counter intuitive, but happens to be true in this case.
The reason is because dithering artifacts will be more visiable
in a linear colorspace."


The FXAA paper mentions something about using the following in DX9 (which is what i am working on)
// sRGB->linear conversion when fetching from TEX SetSamplerState(sampler, D3DSAMP_SRGBTEXTURE, 1);
// on SetSamplerState(sampler, D3DSAMP_SRGBTEXTURE, 0); // off
// linear->sRGB conversion when writing to ROP SetRenderState(D3DRS_SRGBWRITEENABLE, 1);
// on SetRenderState(D3DRS_SRGBWRITEENABLE, 0); // off

This is what I am doing.
1. Render to texture using D3DRS_SRGBWRITEENABLE = 1, and turn it off after I am done.
When I render this texture, it looks brighter than usual.
2. Render screen quad with this texture using D3DSAMP_SRGBTEXTURE = 1, and turn it off after I am done.
When this texture renders, it looks correct.

But the aliasing still remains. I figured I shouldn't be doing step two because that would turn the non-linear color to linear while sampling.
But doing that results in the texture/scene got from the first step.

I have attached my shaders here.
Any help is greatly appreciated.

P.S, Timothy also mentioned something about pixel offset being different on dx11 w.r.t dx9 by 0.5 of a pixel.

Thanks a lot !


Share this post

Link to post
Share on other sites

The problem is, I don't see any difference between the FXAA and Non-FXAA Render.

Could you post some comparison screenshots ?

Share this post

Link to post
Share on other sites
Oh I forgot, about the pics.

I have an abstraction going on for directx9 and opengl2.
So the same window in the pics support both of them.

I got hold of a glsl shader for FXAA and integrated to the opengl side.
(am not sure what version it is, but it appears to be from the same source)

Seems to work. But when I made changes to the directx hlsl with updated inputs, it still doesn't work sad.png

I am reattaching all the shaders and the screenshots here.

Note the difference w.r.t the directx screenshots only. The window name holds the name of the renderer
When I use GLSL it works fine.

Jerry Edited by jerrinx

Share this post

Link to post
Share on other sites
The major difference between DX9 and OGL2 is, that DX9 is, well, DX9, but OGL2 can be pimped by using extensions. The FXAA shaders use a lot of extensions, I would test it on a higher DX version, maybe the FXAA implemenation has reached its limits on DX9, or you should choose a preset better suited for DX9.

Share this post

Link to post
Share on other sites
The problem with DX9 is that it has the "half pixel offset problem", which will wreak havoc with any kind of post-processing shader.

The official description of the problem is here:

In the versions of FXAA that I've used, it expects you to account for this flaw in DX9 yourself and EITHER shift your full-screen vertices OR texture coordinates by half a pixel as described in the MSDN link, so that the pixel shader receives the same interpolated values as it would in GL/DX10/DX11. Edited by Hodgman

Share this post

Link to post
Share on other sites
If you want to understand the linear color space, try to google "gamma correction". Generally speaking, to the monitor, the relationship between luminance and color is not linear, but a Exponential curve. So in order to output the linear color, texture color was also been precorrected by an exponent value. So although you can see the correct color on the screen,the color you used before is nonlinear. This can cause problems in some algrithm,but in my work,the FXAA use nonlinear color space works well.

Share this post

Link to post
Share on other sites
Hey Thanks guys.

Like Hodgman said, My initial setting was 1/2 texel size off on DX9.
After fixing the issue the textures still renders the old jaggy pattern sad.png

Initially I noticed some difference in the image when rendering to texture vs normal rendering in the case of DX9.
Now, both look the same. I am assuming the 1/2 texel problem is accounted for.

I used this article to understand the color space stuff

Tried to use the color space as in the Fxaa_3.11 header. But still no dice.

Reattaching updated shaders.

lol... Maybe I should go for SMAA smile.png
Fxaa3 (lower quality 0.62 ms) vs SMAA Tx2 (higher quality 1.32 ms)
Hard to decide

Thanks guys
Jerry Edited by jerrinx

Share this post

Link to post
Share on other sites
I`ve read your code,you need to #define FXAA_GREEN_AS_LUMA 1,otherwise it will take the alpha of tex color as luminance,as your input alpha is always 1,nothing will be changed. And your parameters seemed to have some problems,try to read the annotation and check them.

Share this post

Link to post
Share on other sites
Managed to port glsl code to hlsl for FXAA.
Seems to work.

Attaching it for people who need it. It looks simpler than the Fxaa 3.11. I am guessing its the old version. But it performs better.
Tried with and without Luma. Works in both cases.

On DX9 you need to do color space conversion, in order to use it correctly.

I do something like this:

Stage 0
Render Main Scene to texture
- Texture Read convert - SRGB to Linear
- Texture Write convert - None

Stage 0.5 (Optional, if filling alpha with luma)
Render Texture to Texture
- Texture Read convert - None
- Texture Write convert - None

Stage 1
Render Texture to Monitor using FXAA
- Texture Read convert - None
- Texture Write convert - Linear to SRGB (as Monitor requires SRGB format)

Hopefully that clarifies some stuff.

For now this works.

@Dragon. Couldn't get the Fxaa 3.11 to work though. I rechecked all the variables, I am not sure whats the problem. if you find something wrong, please tell me. Attaching the updated old one again. Attaching some part of the code, if someone wants to see.

I have a question
FPS drops as follows (@1080p):
- Normal Render (1500 FPS)
- Render To Texture (1000 FPS)
- Texture To Scene with FXAA (500 FPS)
Is that normal ?

Jerry Edited by jerrinx

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
  • Advertisement
  • Popular Tags

  • Advertisement
  • Popular Now

  • Similar Content

    • By AxeGuywithanAxe
      I wanted to see how others are currently handling descriptor heap updates and management.
      I've read a few articles and there tends to be three major strategies :
      1 ) You split up descriptor heaps per shader stage ( i.e one for vertex shader , pixel , hull, etc)
      2) You have one descriptor heap for an entire pipeline
      3) You split up descriptor heaps for update each update frequency (i.e EResourceSet_PerInstance , EResourceSet_PerPass , EResourceSet_PerMaterial, etc)
      The benefits of the first two approaches is that it makes it easier to port current code, and descriptor / resource descriptor management and updating tends to be easier to manage, but it seems to be not as efficient.
      The benefits of the third approach seems to be that it's the most efficient because you only manage and update objects when they change.
    • By evelyn4you
      until now i use typical vertexshader approach for skinning with a Constantbuffer containing the transform matrix for the bones and an the vertexbuffer containing bone index and bone weight.
      Now i have implemented realtime environment  probe cubemaping so i have to render my scene from many point of views and the time for skinning takes too long because it is recalculated for every side of the cubemap.
      For Info i am working on Win7 an therefore use one Shadermodel 5.0 not 5.x that have more options, or is there a way to use 5.x in Win 7
      My Graphic Card is Directx 12 compatible NVidia GTX 960
      the member turanszkij has posted a good for me understandable compute shader. ( for Info: in his engine he uses an optimized version of it )
      Now my questions
       is it possible to feed the compute shader with my orignial vertexbuffer or do i have to copy it in several ByteAdressBuffers as implemented in the following code ?
        the same question is about the constant buffer of the matrixes
       my more urgent question is how do i feed my normal pipeline with the result of the compute Shader which are 2 RWByteAddressBuffers that contain position an normal
      for example i could use 2 vertexbuffer bindings
      1 containing only the uv coordinates
      2.containing position and normal
      How do i copy from the RWByteAddressBuffers to the vertexbuffer ?
      (Code from turanszkij )
      Here is my shader implementation for skinning a mesh in a compute shader:
      1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 struct Bone { float4x4 pose; }; StructuredBuffer<Bone> boneBuffer;   ByteAddressBuffer vertexBuffer_POS; // T-Pose pos ByteAddressBuffer vertexBuffer_NOR; // T-Pose normal ByteAddressBuffer vertexBuffer_WEI; // bone weights ByteAddressBuffer vertexBuffer_BON; // bone indices   RWByteAddressBuffer streamoutBuffer_POS; // skinned pos RWByteAddressBuffer streamoutBuffer_NOR; // skinned normal RWByteAddressBuffer streamoutBuffer_PRE; // previous frame skinned pos   inline void Skinning(inout float4 pos, inout float4 nor, in float4 inBon, in float4 inWei) {  float4 p = 0, pp = 0;  float3 n = 0;  float4x4 m;  float3x3 m3;  float weisum = 0;   // force loop to reduce register pressure  // though this way we can not interleave TEX - ALU operations  [loop]  for (uint i = 0; ((i &lt; 4) &amp;&amp; (weisum&lt;1.0f)); ++i)  {  m = boneBuffer[(uint)inBon].pose;  m3 = (float3x3)m;   p += mul(float4(pos.xyz, 1), m)*inWei;  n += mul(nor.xyz, m3)*inWei;   weisum += inWei;  }   bool w = any(inWei);  pos.xyz = w ? p.xyz : pos.xyz;  nor.xyz = w ? n : nor.xyz; }   [numthreads(1024, 1, 1)] void main( uint3 DTid : SV_DispatchThreadID ) {  const uint fetchAddress = DTid.x * 16; // stride is 16 bytes for each vertex buffer now...   uint4 pos_u = vertexBuffer_POS.Load4(fetchAddress);  uint4 nor_u = vertexBuffer_NOR.Load4(fetchAddress);  uint4 wei_u = vertexBuffer_WEI.Load4(fetchAddress);  uint4 bon_u = vertexBuffer_BON.Load4(fetchAddress);   float4 pos = asfloat(pos_u);  float4 nor = asfloat(nor_u);  float4 wei = asfloat(wei_u);  float4 bon = asfloat(bon_u);   Skinning(pos, nor, bon, wei);   pos_u = asuint(pos);  nor_u = asuint(nor);   // copy prev frame current pos to current frame prev pos streamoutBuffer_PRE.Store4(fetchAddress, streamoutBuffer_POS.Load4(fetchAddress)); // write out skinned props:  streamoutBuffer_POS.Store4(fetchAddress, pos_u);  streamoutBuffer_NOR.Store4(fetchAddress, nor_u); }  
    • By mister345
      Hi, can someone please explain why this is giving an assertion EyePosition!=0 exception?
      _lightBufferVS->viewMatrix = DirectX::XMMatrixLookAtLH(XMLoadFloat3(&_lightBufferVS->position), XMLoadFloat3(&_lookAt), XMLoadFloat3(&up));
      It looks like DirectX doesnt want the 2nd parameter to be a zero vector in the assertion, but I passed in a zero vector with this exact same code in another program and it ran just fine. (Here is the version of the code that worked - note XMLoadFloat3(&m_lookAt) parameter value is (0,0,0) at runtime - I debugged it - but it throws no exceptions.
          m_viewMatrix = DirectX::XMMatrixLookAtLH(XMLoadFloat3(&m_position), XMLoadFloat3(&m_lookAt), XMLoadFloat3(&up)); Here is the repo for the broken code (See LightClass) https://github.com/mister51213/DirectX11Engine/blob/master/DirectX11Engine/LightClass.cpp
      and here is the repo with the alternative version of the code that is working with a value of (0,0,0) for the second parameter.
    • By mister345
      Hi, can somebody please tell me in clear simple steps how to debug and step through an hlsl shader file?
      I already did Debug > Start Graphics Debugging > then captured some frames from Visual Studio and
      double clicked on the frame to open it, but no idea where to go from there.
      I've been searching for hours and there's no information on this, not even on the Microsoft Website!
      They say "open the  Graphics Pixel History window" but there is no such window!
      Then they say, in the "Pipeline Stages choose Start Debugging"  but the Start Debugging option is nowhere to be found in the whole interface.
      Also, how do I even open the hlsl file that I want to set a break point in from inside the Graphics Debugger?
      All I want to do is set a break point in a specific hlsl file, step thru it, and see the data, but this is so unbelievably complicated
      and Microsoft's instructions are horrible! Somebody please, please help.

    • By mister345
      I finally ported Rastertek's tutorial # 42 on soft shadows and blur shading. This tutorial has a ton of really useful effects and there's no working version anywhere online.
      Unfortunately it just draws a black screen. Not sure what's causing it. I'm guessing the camera or ortho matrix transforms are wrong, light directions, or maybe texture resources not being properly initialized.  I didnt change any of the variables though, only upgraded all types and functions DirectX3DVector3 to XMFLOAT3, and used DirectXTK for texture loading. If anyone is willing to take a look at what might be causing the black screen, maybe something pops out to you, let me know, thanks.
      Also, for reference, here's tutorial #40 which has normal shadows but no blur, which I also ported, and it works perfectly.
  • Advertisement