How to get voxel opacity during gpu surface voxelization

Started by
16 comments, last by JoeJ 7 years, 6 months ago

Yea, you're right, accumulation would be faster, will also be my next approach if I find the time. Do you have any experience with or information about the quality of accumulation versus the quality of multisampling based coverage, regarding the sampling of higher mipmap levels? Since I'm okay with my current grid resolution (mipmap 0) in terms of popping, I would be interested how proper coverage calculation adds up after filtering.

Advertisement

No experience - i think it's a hard to decide if coverage is worth to implement or not, but you can test it's effect by increasing resolution and see what effect this has on popping.

Performance wise i assume MSAA performs not so well here because it increases the amount of atomic conflicts.

Also voxels are low resolution in comparision to framebuffer pixels, chances are that almost every voxel contains multiple samples.

I guess it's hard to beat higher voxel resolution with lower resolution + coverage if we leverage performance and quality.

To work against popping, you can also use a simple temporal filter (voxel = voxel*0.9 + newVoxel*0.1).

This smooths things out at the cost of temporal lag, which is not very noticeable with indirect lighting.

Hello guys :D I am back. During the pass few days I worked hard to make some progress and little time left for me to update my test results. So here is what I have got, which gives me some confidence to continue this works.

I have tried JoeJ's suggestion about msaa coverage density. But unfortunately, my result shows that its contribution for the visual quality is not quite obvious. This leads me to think that maybe the corrected edge opacitys (namely, voxel anti-aliasing) is not so crucial for the quality of results. I am not sure, but that is what I got.

One of most important things about the quality is the light injectction and the occlusion of the aniso-voxels (and its mipmap). I used a traditional RSM way to inject the light. Although I am not satisfied with the light-injected emitter volume and its VCT specular results, I find that the VCT diffuse results are not bad, in certain degree. The below is a demo shot for my VCT specular. Does anybody have the experiences to to improve that?

I heard that there exist some possible solutions to improve VCT quality by using SH opacity volume with SH representation (SEGI) or 6-face aniso-opacity volumes (tomorrow's children) etc. But I am not sure which way is better for me. How about your opinion? :)

One of most important things about the quality is the light injectction and the occlusion of the aniso-voxels (and its mipmap). I used a traditional RSM way to inject the light. Although I am not satisfied with the light-injected emitter volume and its VCT specular results, I find that the VCT diffuse results are not bad, in certain degree. The below is a demo shot for my VCT specular. Does anybody have the experiences to to improve that?

Very impressive result so far, looks very nice, way better than vct in my own engine :)

My first attempt was to simply do forward shading during voxelization. Why do you use RSM - do you have them already calculated, or do you plan to support more lightsources? I think you will have a performance loss when ditching RSM in favor to forward rendering, but the quality/resolution will be the best you can get for your grid resolution, I think.

Can't help you with your other question though. Do you have somehow a comparison between anisotropic and isometric voxels? Would be interested to see the difference it makes in your engine.

I'm a bit off there (don't even know the deference iso/aniso voxels, ist one solid color vs. 6 directions colors?).

I've also forgotten about RSMs - remember them a bit from Crysis2 GI and Imperfect Shadow Maps, but can't get the connection how this is related here exactly.

You'd need to describe what you to with them.

However, there are some ideas i have (not sure if they are new):

Create a distance field to adapt raymarching step size.

So you would do smaller steps near the surface, probably limiting banding like seen on the reflections of the vehicle doors.

An optimization idea is to use bit voxels to identify empty space quickly (4*4*4 voxels in 64bits).

This could give similar tracing speed than with octrees without the need for them.

They could also be used for shadows, visibility, or whatever... (But there is no hardware filtering).

Im my algorithm i have used SH to encode everything (surface color and surface area used for occlusion).

I wanted to use only 2 band SHs (4 values), because everyone says it's enough for diffuse lighting.

The problem is this: You have a thin wall, so front and back side side falls in a single voxel.

It's not possible to store this oppositing surface area information with 2 bands good enough, 3 bands (9 values) also was not really satisfying.

Result: My walls became transparent at distance where voxel resolution has to decrease... leaked like hell.

I guess the 6-face thing you use is more robust in this regard (you're snapping to main axis anyways whan using a grid, SHs won't fix this completely).

But i also don't know how they use it in Tomorrows Children, so just to keep in mind.

My first attempt was to simply do forward shading during voxelization. Why do you use RSM - do you have them already calculated, or do you plan to support more lightsources? I think you will have a performance loss when ditching RSM in favor to forward rendering, but the quality/resolution will be the best you can get for your grid resolution, I think.

I don't think doing simple forward shading without shadowmapping during voxelization is a proper method because it ignores the occlusion relationship between the voxels from the first place. In my opinion, close attension should be paid to every place that maybe affect the quality of occlusions. In fact, the decent maintaince of occlusion relationship is the very gist that VCT holds, when compared with other RTGI solutions, such as LPV, RSM, DeepG etc. And I also don’t think the following aniso-mipmap filtering is enough for compensating the losses of occlusion infos, because it is too coarse when compared with the shadowmap…

On the other hand, doing a full forward shading during voxelization (with shadowmap) is also not recommanded because of the redundant fragment rasterization. The performance loss caused by fragment shading during voxelization would be too hearvy to afford, especially when using some advanced shading tech. such as PBR etc.

The RSM-alike way is quite simple because the light shadowmap is there all at my disposal. So I decide to use RSM for the light injection of first bounce. Of couse for the limited solution of RSM, the direct light injection result would not be pretty. My strategy to overcome this is to introduce the calculation of second bounce, namely, after RSM injection I dispatched one diffuse VCT(4 lobes are enough) from every voxel that have non-null opacity to get its 2nd bounce light-injection. By doing so I find my quality of light injection is greatly improved.

I'm a bit off there (don't even know the deference iso/aniso voxels, ist one solid color vs. 6 directions colors?).

Yes. An iso-voxel in emittee volume has only one solid attribute, but an aniso-voxel would have multi-direction attributes. One common representation of aniso-voxel is 6-axis color. But I think the SH representation is more appropriate for this situation. Rumor shows that aniso-voxel would be helpful to prevent the exaggerated diffuse color-bleeding in a common svo-alike GI situation. But unfortunately I have not tried it, because of its terrible memory costs, especially when you have not a decent out-of-core voxel management mechanism. Maybe the VTR feature in dx11.3 is the cure! :P

Sorry for my rush reply JoeJ. I haven't finished the reading of your reply. I need more time to think about your suggestions, and I will post my responses in the following thread. :)

One common representation of aniso-voxel is 6-axis color. But I think the SH representation is more appropriate for this situation

qz1ykz.jpg

I made this pic to show the problem you get with SH.

On the left is a voxel of solid wall. If we want to know the visible surface area from any direction, we simply intersect the direction with the perfect blue circle for the correct answer.

(Should have been adding this to the picture - probably not very clear but the circle is exactly the signal we want to encode here to calculate accurate occlusion)

The red sketch of a 2-band SH is pretty accurate here.

In the middle is a double sided wall, so we want circles in both directions.

On right we see the 2-band red sketch again - a unit circle without any directional information, we get half occlusion no matter if we expect full or zero occlusion :(

The green is what a 3-band will look like: better, but still bad.

The big advantage is that SHs are rotational invariant. They can cover any surface normal exactly (as long as only one surface is in the voxel). No snapping to main directions.

But it definitively can not prevent color bleeding on low resolution.

Maybe the VTR feature in dx11.3 is the cure!

... in five years - maybe. Up to now no AMD hardware has support. Also, AFAIK any tiled resources need to be managed from CPU, which is... terrible?

It's a bit of a dilemma. I still think the only way using VCT is to carefully design levels so either walls are thick enough or leaks are no big problem.

This topic is closed to new replies.

Advertisement