Jump to content

  • Log In with Google      Sign In   
  • Create Account


low sample count screen space reflections


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
18 replies to this topic

#1 RPTD   Members   -  Reputation: 313

Like
1Likes
Like

Posted 30 July 2013 - 06:31 AM

The basic idea behind SSR is clear to me. Although there is little useful information around the basic idea is to ismply march along a ray in either view or screen space. Personally I do it in screen space as I think this is better but that I can't say for sure for the lack of information around.

 

Whatever the case the common approach seems to be to do a linear stepping along the ray and then doing a bisecting search to refine the result. The bisecting search is clear and depending on the step size is around 5-6 steps for a large screen and a ray running across a large part of the screen. The problematic part is the step size.

 

I made tests with a step size of 20 (not counting the refinement). In this case for a large screen (1680x1050 as an example) this gives for a moderately long ray bouncing from one side of the screen to the other of lets say 1000 pixel length a step size of 1000/20 = 50 pixels. This is quite large and steps right scross thiner geometry like for example the edges of the boxes in the test-bed I put together attached below (smaller than 1680x1050 as it's from the editor). Furthermore it leads to incorrect sampling as seen on the right side.

test1b.jpg

 

Now I've seen other people claiming they do (on the same large screen or larger) 16 samples only even for long rays running across the screen. 16 Samples is even less than the 20 I used in the test which already misses geometry a large deal. Nobody ever stated though how these under-sampling issues work out with such a low sampling count. In my tests I required 80-100 samples to keep these undersampling issues somewhat at bay (speed is gruesome).

 

So the question is:

 

1) how can 16 samples for the linear search possibly work without these undersampling issues?

 

 

 

Another issue is stuff like a chair or table resting on the ground. All rays passing underneath would work with an exhaustive search across the entire ray. With the linear test though the test goes into the bisecting phase at the first step the ray crosses geometry like the table or chair. The bisecting test then finds no solution and thus leaks the env-map through. Some others seem to not be affected by this problem but what happens there? Do they continue steping along the ray if the bisecting fails? This though would increase the sample count beyond 20+6 and kills the worst case. So another question is:

 

2) with rays passing underneath geometry at the first linear search hit and bisecting fails to return a result, what do you do? continue on the ray with worse worst case sample count or fail out?

 

3) how to detect these cases properly to fade out? bluring or more intelligent?


Life's like a Hydra... cut off one problem just to have two more popping out.
Leader and Coder: Project Epsylon | Drag[en]gine Game Engine

Sponsor:

#2 kalle_h   Members   -  Reputation: 1278

Like
1Likes
Like

Posted 30 July 2013 - 02:15 PM

Usually you use sub resolution buffer for raymarching this not only reduce amount of rays but also shorten the max distance. Another trick is to use randomized jitter pattern and blur resulted reflection buffer slightly(more vertical blurthan horizontal). Then use bilateral upsampling when you combine reflections to main scene. You can also skip too far away pixels, all rough materials, screen edges(not enough data) and pixels with normal that point towards camera. Cry engine 3 use half precision depth for all other samples but center sample. With all these ray count is reduced quite radically so you can use little bit more samples if needed.



#3 RPTD   Members   -  Reputation: 313

Like
0Likes
Like

Posted 30 July 2013 - 02:43 PM

Usually you use sub resolution buffer for raymarching this not only reduce amount of rays but also shorten the max distance. Another trick is to use randomized jitter pattern and blur resulted reflection buffer slightly(more vertical blurthan horizontal). Then use bilateral upsampling when you combine reflections to main scene. You can also skip too far away pixels, all rough materials, screen edges(not enough data) and pixels with normal that point towards camera. Cry engine 3 use half precision depth for all other samples but center sample. With all these ray count is reduced quite radically so you can use little bit more samples if needed.

 

I thought about the smaller resolution buffer too but there is something that doesn't connect for me with that idea and that's the blur. Let's say I go 2 levels lower than this is a factor of 2 in both directions. Thus 1 pixel covers 16 pixels (4x4). So let's say I calculate a result for this 16 pixel block. Do then all pixels obtain this hit point texture coordinate and jitter around it? This would be like applying a 5x5 blur on the input image.

 

Furthermore with subtle rough materials like a subtle rippled leather normals are slightly different for all pixels in the 16 pixel group. Yet with this down-sampling approach all pixels end up on the same texture coordinate.

 

Last but not least using the sampel case above what for the edge of the boxes? if one group of 16 pixels scores a hit just on the edge but the next 16 pixels group sitting right next to it does not would this not introduce a 4x4 pixel wide stair-step artifact?


Life's like a Hydra... cut off one problem just to have two more popping out.
Leader and Coder: Project Epsylon | Drag[en]gine Game Engine

#4 kalle_h   Members   -  Reputation: 1278

Like
0Likes
Like

Posted 30 July 2013 - 05:32 PM

Simple answer. 2 levels lower might be too low res. Start from half resolution and see if that works.



#5 RPTD   Members   -  Reputation: 313

Like
0Likes
Like

Posted 30 July 2013 - 05:46 PM

One level lower is a factor of two as you said. With 20 steps a ray though the step size is 50 pixels as mentioned in my first post. This gives log2(50)~=5.6 which is roughly 5 levels. I just experimented with some smaller screen but the results are full of holes since blocks of 4 (2x2) pixels scores incorrect hits entering the bisection on incorrect situations. That's not a possible solution to get down to 16 samples.

 

Somebody once claimed the CryEngine uses something with 20x20 pixel blocks? I have a hard time to believe this as this would be 400 pixels mapped to one single test-ray. The results would be brutally crappy.


Life's like a Hydra... cut off one problem just to have two more popping out.
Leader and Coder: Project Epsylon | Drag[en]gine Game Engine

#6 Styves   Members   -  Reputation: 952

Like
1Likes
Like

Posted 31 July 2013 - 04:28 AM

Your best option is to use a min-max hierarchy to accelerate your ray march.

 

The idea is to store a mip-chain that contains the minimum and maximum depths of the current surrounding pixels. Then you just check your ray to see if it's inside a tile that has an intersection (compare the min/max depths) and if it's not, move to the boundary of the tile (box-intersection) and do it again. If it's inside you go down a level and test it again. You do this until you've reached a maximum number of samples or until you reach the lowest level.

 

In practice this hugely reduces the ray marching cost because you end up skipping all of the empty spaces that you'd normally be marching along, so you don't need as many steps to get good results. smile.png


Edited by Styves, 31 July 2013 - 06:19 AM.


#7 Yours3!f   Members   -  Reputation: 1257

Like
0Likes
Like

Posted 31 July 2013 - 04:39 AM

hey there,

what I do is 8+32 samples. 8 for getting closer to the surface in big steps (and terminate earlier if reached), and 32 in a binary search algorithm. This gives me perfect results without all the jittering blurring downsampling. Although if you'd like to have rough (blurred) reflections, then you'll need to do downsampling. I found that 16 samples is good enough in terms of performance, but in some cases Moire patterns appear.

 

Best regards,

Yours3lf



#8 RPTD   Members   -  Reputation: 313

Like
0Likes
Like

Posted 31 July 2013 - 08:00 AM

Your best option is to use a min-max hierarchy to accelerate your ray march.

 

The idea is to store a mip-chain that contains the minimum and maximum depths of the current surrounding pixels. Then you just check your ray to see if it's inside a tile that has an intersection (compare the min/max depths) and if it's not, move to the boundary of the tile (box-intersection) and do it again. If it's inside you go down a level and test it again. You do this until you've reached a maximum number of samples or until you reach the lowest level.

 

In practice this hugely reduces the ray marching cost because you end up skipping all of the empty spaces that you'd normally be marching along, so you don't need as many steps to get good results. smile.png

 

I experimented already with that beforehand but it fails for various reasons.

 

For one the min-max criteria is incorrect. If you have for example a box parallel to the screen all pixels in the mip-mapped level have the same depth value. The minimum and maximum is thus the same. Box-testing against this pixel scores no hit since the ray-test considers it a thin piece of paper instead of a thick box. The same happens with walls. So the min-max is of no use since wrong information are stored. The results are broad and long stripes of black across the entire image (not shown here but you can imagine).

EDIT: To be more presice the test fails because rays can pass behind geometry and not score a hit. A box would be typically fully missed since the ray is tested against a thin box and thus only scores an intersection if the ray runs through the thin box in the very same pixel. If it enters and leaves the pixel though slightly behind the thin box no hit is scored and the result fails.

 

Another reason is the initial-sampling problem. The starting point (or rather one next to it) is always included in the first mip-map level you sample. Let's say this is level 5. Due to this for the first sample you always run down to level 0 for testing just to find no hit (since the first testing pixel is in every mip-map level above and thus min-max will always score a hit no matter what). You loose thus 6 samples of your total 16 just for this inevitable first case.

 

Another problem is are the higher level groups pixels around the ray not hit by the ray. If a pixel in this group is closer than the z-value of the ray the group is tested due to min-max criteria resulting in an early hit doing bisection on a group of pixels not possibly scoring a hit. Results in large black stripes again.

 

Last but not least the recursive nature of this approach (even if programmed iterative) is a huge slow-down. 30 samples with an iterative implementation of min-max on my Radeon HD 4870 is as slow as doing 100 samples with the current flawed approach while producing crappy results.

EDIT: I did some more testing. Maybe it's just the Radeon 4870. I noticed that if I do a "loop1 then loop2" where loop2 is run only once then I get good speed. If I do though "loop2 inside loop1" then the speed drops down to 50% or less. Chances are the loops mixed with the if-else branches required to do more clever stepping solution is too much for the Radeon 4870 to muster up. That doesn't change though the mathematical problems with this approach but would explain the slow speed.

 

There is though maybe a possibility to modify the problem a bit that might work. I have though to experiment with that.

 

 

 

hey there,

what I do is 8+32 samples. 8 for getting closer to the surface in big steps (and terminate earlier if reached), and 32 in a binary search algorithm. This gives me perfect results without all the jittering blurring downsampling. Although if you'd like to have rough (blurred) reflections, then you'll need to do downsampling. I found that 16 samples is good enough in terms of performance, but in some cases Moire patterns appear.

 

Best regards,

Yours3lf

 

8 samples is gruesome on 1680x1050 screen this is a block size of 1680/8 = 210 pixels. Steping over 210 pixel should miss even large scale objects (it's 12.5% of the screen size). What kind of scene do you use? Also why 32 samples for the bisection test? As soon as you get to a step size below 1 pixel there is no gain anymore to quality. For 210 pixels this is floor(log2(210))+1 = 8 samples. 32-8 = 24 samples wasted. Mind elaborate the reason for the 32 samples? Or are you using after the first hit a starting step size that is larger than 210/2 = 105 pixels?


Edited by RPTD, 31 July 2013 - 09:39 AM.

Life's like a Hydra... cut off one problem just to have two more popping out.
Leader and Coder: Project Epsylon | Drag[en]gine Game Engine

#9 Yours3!f   Members   -  Reputation: 1257

Like
0Likes
Like

Posted 31 July 2013 - 10:28 AM


8 samples is gruesome on 1680x1050 screen this is a block size of 1680/8 = 210 pixels. Steping over 210 pixel should miss even large scale objects (it's 12.5% of the screen size). What kind of scene do you use? Also why 32 samples for the bisection test? As soon as you get to a step size below 1 pixel there is no gain anymore to quality. For 210 pixels this is floor(log2(210))+1 = 8 samples. 32-8 = 24 samples wasted. Mind elaborate the reason for the 32 samples? Or are you using after the first hit a starting step size that is larger than 210/2 = 105 pixels?
 


I'm not doing this in screen space, because as you wrote it, things get rather bad at high resolutions. Instead I move around in view space, where I have the nearz at 1.0 and farz at 1000. My step size for the initial pass is 1/4th of the view space z length. I do the initial pass until I go 'beyond' the view space z at the given pixel. (So this pass may terminate before 8 steps are done) Then I do the binary search halving the step size at each step. (32 or 16 steps, fixed)

The scene is the sponza scene from crytek.

I have no idea why 32. It is an empirical value tongue.png

That is a good idea I could check for the step size, I'm only worried about the non-uniform flow control that's going on, and I'm not sure yet which would hurt more.

As for the 'when to fade out', ie. when we reach the boundaries of screen space, I do a lot of checks. I check if the resulting screen space coordinate is in the screen, I also have a max search distance that makes it fade when it reaches the end (artist controlled). I also check the normal vectors at the given pixel, and at the resulting pixel.

For 16 samples it runs at 5ms at 720p. For 8 samples that IMHO looks a lot like the 16 samples it runs at 3ms at 720p. (AMD A8-4500m)


Edited by Yours3!f, 31 July 2013 - 10:41 AM.


#10 RPTD   Members   -  Reputation: 313

Like
0Likes
Like

Posted 31 July 2013 - 11:16 AM

 


8 samples is gruesome on 1680x1050 screen this is a block size of 1680/8 = 210 pixels. Steping over 210 pixel should miss even large scale objects (it's 12.5% of the screen size). What kind of scene do you use? Also why 32 samples for the bisection test? As soon as you get to a step size below 1 pixel there is no gain anymore to quality. For 210 pixels this is floor(log2(210))+1 = 8 samples. 32-8 = 24 samples wasted. Mind elaborate the reason for the 32 samples? Or are you using after the first hit a starting step size that is larger than 210/2 = 105 pixels?
 


I'm not doing this in screen space, because as you wrote it, things get rather bad at high resolutions. Instead I move around in view space, where I have the nearz at 1.0 and farz at 1000. My step size for the initial pass is 1/4th of the view space z length. I do the initial pass until I go 'beyond' the view space z at the given pixel. (So this pass may terminate before 8 steps are done) Then I do the binary search halving the step size at each step. (32 or 16 steps, fixed)

The scene is the sponza scene from crytek.

I have no idea why 32. It is an empirical value tongue.png

That is a good idea I could check for the step size, I'm only worried about the non-uniform flow control that's going on, and I'm not sure yet which would hurt more.

As for the 'when to fade out', ie. when we reach the boundaries of screen space, I do a lot of checks. I check if the resulting screen space coordinate is in the screen, I also have a max search distance that makes it fade when it reaches the end (artist controlled). I also check the normal vectors at the given pixel, and at the resulting pixel.

For 16 samples it runs at 5ms at 720p. For 8 samples that IMHO looks a lot like the 16 samples it runs at 3ms at 720p. (AMD A8-4500m)

 

 

Actually for a long ray running across the screen it does not matter that much if you are in screen space or view space. Both translate to the other using a simple calculation. So if you take the start and end point of the ray in view space and translate it into screen space and you split it up into 8 pieces you end up in average with a pixel block size of 210. The only difference is that stepping in view space instead of screen space the block size is not uniform (first step huge block size then smaller with each step). So from this point of view I still expect jumps of roughly 210 pixels per ray step which is more than 10% of the screen size for long rays. So how does it pan out with geometry thinner than roughly 200 pixels on screen?

 

What do you mean with "non-uniform flow control"? If you don't continue after fine-checking a pixel block where do you need non-uniform control flow? In this situation you need one initial loop to find the candidate pixel block for the fine-search and then a second loop afterwards doing the fine-search on the found candidate block (no matter if nested or not. on my card nesting drops speed like hell). So the performance is 8-loop + 32-loop hence 40-loop in total for all pixels in a warp.

 

Mind stating what card you run this on and how the artifacts look like?


Life's like a Hydra... cut off one problem just to have two more popping out.
Leader and Coder: Project Epsylon | Drag[en]gine Game Engine

#11 Yours3!f   Members   -  Reputation: 1257

Like
0Likes
Like

Posted 31 July 2013 - 12:51 PM

Actually for a long ray running across the screen it does not matter that much if you are in screen space or view space. Both translate to the other using a simple calculation. So if you take the start and end point of the ray in view space and translate it into screen space and you split it up into 8 pieces you end up in average with a pixel block size of 210. The only difference is that stepping in view space instead of screen space the block size is not uniform (first step huge block size then smaller with each step). So from this point of view I still expect jumps of roughly 210 pixels per ray step which is more than 10% of the screen size for long rays. So how does it pan out with geometry thinner than roughly 200 pixels on screen?



What do you mean with "non-uniform flow control"? If you don't continue after fine-checking a pixel block where do you need non-uniform control flow? In this situation you need one initial loop to find the candidate pixel block for the fine-search and then a second loop afterwards doing the fine-search on the found candidate block (no matter if nested or not. on my card nesting drops speed like hell). So the performance is 8-loop + 32-loop hence 40-loop in total for all pixels in a warp.



Mind stating what card you run this on and how the artifacts look like?


what do you mean 'long running'? If the ray travelled too far, I simply discard it. There's no reason to display it if the result not good enough. (see my prev post)

Yes, that is true, 210 pixels, but as I wrote previously my initial step size depends on the view space z value. So if it is close to the camera, then the step size will be smaller. Again reflections for far away objects are simply discarded.

I mean IFs and ELSEs. Video cards don't really like them, especially if a texture lookup is dependent upon it.
My loops are like this:
for c = 0 to 8
  if( beyond depth )

  {
    for d = 0 to 32
      other ifs... (and texture lookups)
    break;
  }

but yeah at max 40 lookups for high quality.

as I mentioned I ran it on a AMD A8-4500m APU, which has the 7640G IGP. (stock clocks)

see pics for error.

Attached Thumbnails

  • 32samples.png
  • 8samples.png


#12 RPTD   Members   -  Reputation: 313

Like
0Likes
Like

Posted 31 July 2013 - 01:14 PM

 

what do you mean 'long running'? If the ray travelled too far, I simply discard it. There's no reason to display it if the result not good enough. (see my prev post)

Yes, that is true, 210 pixels, but as I wrote previously my initial step size depends on the view space z value. So if it is close to the camera, then the step size will be smaller. Again reflections for far away objects are simply discarded.

I mean IFs and ELSEs. Video cards don't really like them, especially if a texture lookup is dependent upon it.
My loops are like this:
for c = 0 to 8
  if( beyond depth )

  {
    for d = 0 to 32
      other ifs... (and texture lookups)
    break;
  }

but yeah at max 40 lookups for high quality.

as I mentioned I ran it on a AMD A8-4500m APU, which has the 7640G IGP. (stock clocks)

see pics for error.

 

 

Long running or long ray is a ray which covers a large distance in screen space (number of pixels). So for example if the tubes would be with a reflective material the ray can easily run across the screen from the right border all the way to the left border. In this case the test-ray can easily run across >75% of the screen dimension. These are extreme cases and as you mentioned tricky. But since I'm using PBR everything reflects and just doing reflections for very close geometry shows considerably.

 

I agree with you that a result should not be shown if the result is not good enough. The problem is how to mathematically define when a result is good and when not. I could so far not find a robust definition to tell if the SSR influence for a single pixel should go to 0 or stay at 1 (or a percentage in the middle somewhere). It find it especially difficult with the missing hits due to undersampling while stepping. In this case pixels with full coverage (I call this influence factor coverage) are right next to those with no coverage as visible in the above image. I could not find a mathematically reasonable definition for the coverage there.

 

Judging from the images you provided you only check rays up to something like 5m in length or am I wrong? I currently allow rays up to the entire frustum range clamped to the frustum in screen space. This is so to speak the worst case hence a visible ray until it goes of view in the distance or any side of the screen. I heard CryEngine has a maximum length too for the rays but could never find any numbers on how this looks like. I tried limiting the length of the test-rays but somehow never got convincing results since the original problem of missing geometry still applied just with shorter step sizes.

 

I could give that view-space a try though. I think I've seen somebody using z-coordinate to calculate the step size for but I didn't figure out yet what the logic is behind it (if there is any).


Life's like a Hydra... cut off one problem just to have two more popping out.
Leader and Coder: Project Epsylon | Drag[en]gine Game Engine

#13 Yours3!f   Members   -  Reputation: 1257

Like
0Likes
Like

Posted 31 July 2013 - 02:13 PM

 

 

what do you mean 'long running'? If the ray travelled too far, I simply discard it. There's no reason to display it if the result not good enough. (see my prev post)

Yes, that is true, 210 pixels, but as I wrote previously my initial step size depends on the view space z value. So if it is close to the camera, then the step size will be smaller. Again reflections for far away objects are simply discarded.

I mean IFs and ELSEs. Video cards don't really like them, especially if a texture lookup is dependent upon it.
My loops are like this:
for c = 0 to 8
  if( beyond depth )

  {
    for d = 0 to 32
      other ifs... (and texture lookups)
    break;
  }

but yeah at max 40 lookups for high quality.

as I mentioned I ran it on a AMD A8-4500m APU, which has the 7640G IGP. (stock clocks)

see pics for error.

 

 

Long running or long ray is a ray which covers a large distance in screen space (number of pixels). So for example if the tubes would be with a reflective material the ray can easily run across the screen from the right border all the way to the left border. In this case the test-ray can easily run across >75% of the screen dimension. These are extreme cases and as you mentioned tricky. But since I'm using PBR everything reflects and just doing reflections for very close geometry shows considerably.

 

I agree with you that a result should not be shown if the result is not good enough. The problem is how to mathematically define when a result is good and when not. I could so far not find a robust definition to tell if the SSR influence for a single pixel should go to 0 or stay at 1 (or a percentage in the middle somewhere). It find it especially difficult with the missing hits due to undersampling while stepping. In this case pixels with full coverage (I call this influence factor coverage) are right next to those with no coverage as visible in the above image. I could not find a mathematically reasonable definition for the coverage there.

 

Judging from the images you provided you only check rays up to something like 5m in length or am I wrong? I currently allow rays up to the entire frustum range clamped to the frustum in screen space. This is so to speak the worst case hence a visible ray until it goes of view in the distance or any side of the screen. I heard CryEngine has a maximum length too for the rays but could never find any numbers on how this looks like. I tried limiting the length of the test-rays but somehow never got convincing results since the original problem of missing geometry still applied just with shorter step sizes.

 

I could give that view-space a try though. I think I've seen somebody using z-coordinate to calculate the step size for but I didn't figure out yet what the logic is behind it (if there is any).

 

I defined the distance to be 50 units. This is again empirical value, and is probably highly dependent on the scene. This is probably not 5 meters, as I don't really know how much that would be in the real world, but something like that. According to blender the length of the blue curtain is 28 meters, and the length of the vase is 5 meters... I have downloaded the original file from cryengine, and it is like 10x bigger. So based on real world photos I scaled it down, so that the columns are like 2.2m high in Blender. This way 5 units (or meters now?) seemed to be fine.

I'm looking forward to your view space implementation!


Edited by Yours3!f, 31 July 2013 - 02:13 PM.


#14 RPTD   Members   -  Reputation: 313

Like
0Likes
Like

Posted 01 August 2013 - 04:18 PM

I defined the distance to be 50 units. This is again empirical value, and is probably highly dependent on the scene. This is probably not 5 meters, as I don't really know how much that would be in the real world, but something like that. According to blender the length of the blue curtain is 28 meters, and the length of the vase is 5 meters... I have downloaded the original file from cryengine, and it is like 10x bigger. So based on real world photos I scaled it down, so that the columns are like 2.2m high in Blender. This way 5 units (or meters now?) seemed to be fine.

I'm looking forward to your view space implementation!

 

I gave it a try to implement it but the view-space version is even worse than the screen-space version what goes for the broad-phase. This I did expect since I looked for screen-space to counter exactly this problem. The narrow-phase though I had to adjust and this one works better. Coverage calculation though is totally horrible and results in punctured geometry worse than before. The marked areas show this problem well.

test2.jpg

 

So I guess the best solution is screen-space but with a modified narrow-phase calculation. Let's see if this works out.

 

Astonishing is that with the modified narrow-phase in the view-space version coverage actually fades out if samples turn not included in the image. If just the punctured pattern would go away it would be near optimal given the instable nature of the SSR algorithm to begin with.


Life's like a Hydra... cut off one problem just to have two more popping out.
Leader and Coder: Project Epsylon | Drag[en]gine Game Engine

#15 Quat   Members   -  Reputation: 402

Like
0Likes
Like

Posted 01 August 2013 - 04:35 PM

I am working on screen space reflections as well.  I also did both screen and view space marching.  I would support reflected rays in view space up to 50 meters.  Both seemed to have issues but I felt like screen space was less arifacts and it works well if you are using hardware depth values.  However, doing a coarse linear march followed by refinement did not give me very good results.  Basically I could not make the coarse step size too large.  Depending on the ray direction, the broad phase would miss intersection around the edges/boundaries of object resulting in noticeable aliasing.  I settled with a 10 pixel sized broad phase where the amount of aliasing was acceptable.  Then I would loop over the 10 pixels linearly (didn't feel like a binary chop was worth it for 10 because of the conditional instructions but I should try it anyway).  Next I need to try it at half resolution.  I should get satisfactory speed then. 


-----Quat

#16 Yours3!f   Members   -  Reputation: 1257

Like
1Likes
Like

Posted 02 August 2013 - 05:24 AM

 

I defined the distance to be 50 units. This is again empirical value, and is probably highly dependent on the scene. This is probably not 5 meters, as I don't really know how much that would be in the real world, but something like that. According to blender the length of the blue curtain is 28 meters, and the length of the vase is 5 meters... I have downloaded the original file from cryengine, and it is like 10x bigger. So based on real world photos I scaled it down, so that the columns are like 2.2m high in Blender. This way 5 units (or meters now?) seemed to be fine.

I'm looking forward to your view space implementation!

 

I gave it a try to implement it but the view-space version is even worse than the screen-space version what goes for the broad-phase. This I did expect since I looked for screen-space to counter exactly this problem. The narrow-phase though I had to adjust and this one works better. Coverage calculation though is totally horrible and results in punctured geometry worse than before. The marked areas show this problem well.

attachicon.giftest2.jpg

 

So I guess the best solution is screen-space but with a modified narrow-phase calculation. Let's see if this works out.

 

Astonishing is that with the modified narrow-phase in the view-space version coverage actually fades out if samples turn not included in the image. If just the punctured pattern would go away it would be near optimal given the instable nature of the SSR algorithm to begin with.

 

okay, so you were right saying that they may look really similar. I think that these artifacts could be filtered out by 'checking' some things:
-check if the resulting ss vector is on the screen (fade out by applying some math)
-check if the resulting ray is within search distance (again fade)
-check if the original vs normal and view direction are good (too big angles are baaad, again fade)
-check if the resulting vs normal and reflection vector are good (again big angles are bad, fade)
-also there's one more thing, you should check if the raycast even succeed. I consider it successful, if the binary search is launched.



#17 RPTD   Members   -  Reputation: 313

Like
0Likes
Like

Posted 02 August 2013 - 02:27 PM

I did now some experimenting by combining the broad-phase stepping from my screen-space with the narrow-stepping from the view-space. The rest is better in the narrow-phase but still not as clean as in the screen-space. I think though this problem is due to me currently using depth-reconstruction as I didn't yet switch back to hacing a full RGBF16 position texture in the gbuffer. And far away the differences in the depth value are so small that stepping fails to be accurate in the narrow-phase while in the view-space version the z-difference is precise enough. I'm going to change this once I have the position texture back in the gbuffer.

 

So right now I would say my screen-space version still wins in terms of overall quality once I have fixed the narrow-phase with using z instead of depth.


Life's like a Hydra... cut off one problem just to have two more popping out.
Leader and Coder: Project Epsylon | Drag[en]gine Game Engine

#18 Yours3!f   Members   -  Reputation: 1257

Like
0Likes
Like

Posted 02 August 2013 - 11:40 PM

I did now some experimenting by combining the broad-phase stepping from my screen-space with the narrow-stepping from the view-space. The rest is better in the narrow-phase but still not as clean as in the screen-space. I think though this problem is due to me currently using depth-reconstruction as I didn't yet switch back to hacing a full RGBF16 position texture in the gbuffer. And far away the differences in the depth value are so small that stepping fails to be accurate in the narrow-phase while in the view-space version the z-difference is precise enough. I'm going to change this once I have the position texture back in the gbuffer.

 

So right now I would say my screen-space version still wins in terms of overall quality once I have fixed the narrow-phase with using z instead of depth.

I used vs pos reconstruction too. It is supposed to be the same quality as a full-blown position buffer. This is why it is called reconstruction tongue.png

 

FYI: I've just tried Call of Juarez: Gunslinger, and they use SSR, and it is much worse than your or my version...


Edited by Yours3!f, 03 August 2013 - 05:19 AM.


#19 RPTD   Members   -  Reputation: 313

Like
0Likes
Like

Posted 03 August 2013 - 06:02 AM

 

I did now some experimenting by combining the broad-phase stepping from my screen-space with the narrow-stepping from the view-space. The rest is better in the narrow-phase but still not as clean as in the screen-space. I think though this problem is due to me currently using depth-reconstruction as I didn't yet switch back to hacing a full RGBF16 position texture in the gbuffer. And far away the differences in the depth value are so small that stepping fails to be accurate in the narrow-phase while in the view-space version the z-difference is precise enough. I'm going to change this once I have the position texture back in the gbuffer.

 

So right now I would say my screen-space version still wins in terms of overall quality once I have fixed the narrow-phase with using z instead of depth.

I used vs pos reconstruction too. It is supposed to be the same quality as a full-blown position buffer. This is why it is called reconstruction tongue.png

 

FYI: I've just tried Call of Juarez: Gunslinger, and they use SSR, and it is much worse than your or my version...

 

 

The problem is the lack of precision. Depth is calculated using a perspective division and most pixels on screen are not close to the camera with their depth value somewhere above 0.9 quickly approaching 1. The range of z-values mapping to the same pixel gets large quickly. With your reconstruction you obtain a sort of middle z-value midst in the range. Comparing this with the test ray doesn't do precision any good. So in most of the range of pixels in screen the depth difference is small although the z-difference is huge. Combine this now with stepping (reflectionDir / stepCount) and pair this up with 32-bit floats in shaders and their 6-7 digits of precision and you are up to a precision problem.


Life's like a Hydra... cut off one problem just to have two more popping out.
Leader and Coder: Project Epsylon | Drag[en]gine Game Engine




Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS