Showing posts with label gpu. Show all posts
Showing posts with label gpu. Show all posts

Friday, July 22, 2011

Multisample Soft Shadows

Recently, I was thinking which way should further develop the implementation of soft shadows. I can see clearly now that the approximation of extended light source to a single point is unacceptable. Of course, we can restrict light source area to a smaller size: in this case errors caused by approximation are negligible. However, this is one of the main advantages of the algorithm, and I don't want to drop it. To get a better understanding of errors caused by approximation, I added to the implementation the possibility to work with multiple samples on light source: silhouette, shadow volume and penumbra are considered for each sample. Here are some images:

1x

4x

1x

4x

Penumbra area (debug view)

It's clearly seen that if extended light source is approximated by single sample, penumbra become incorrect. Several samples instead of one slow down the algorithm, but one can notice that umbra and penumbra now separated from each other to some extent: the shadow becomes more plausible.

The authors of the original penumbra wedges algorithm do not set themselves to solve the problem of approximation. To solve it, it's needed to change the approach. For example, the algorithm was originally based on the construction of the shadow volume from the center of the light source, followed by lighting compensation in penumbra around the edges of hard shadow. I think it would be better to go this way: consider coverage in penumbra without the sign (it depends on whether we're inside the hard shadow or outside it), and instead of extrusion of classic shadow volume, determine the umbra region and shade it to black - there's no any lighting contribution. Thus here are two logical parts: umbra, where there's no illumination and penumbra, where the pixel shader computes it analytically.

It's unclear now how to calculate umbra for an extended light source, but definitely nothing impossible.

Monday, June 13, 2011

Multipoint Silhouette Determination

I have developed multipoint silhouette determination on CPU with volume extrusion in the geometry shader. The reason why CPU is used is that geometry shader uses adjacency faces for silhouette determination, but for efficient implementation we need to iterate over mesh edges and see the orientation of their left and right adjacent faces that geometry shader can't do. The problem can be solved using compute shader with arbitrary data layout, but my laptop GPU is capable only of SM 4.1.



Of course with each additional light sample the shadow volume overdraw is significantly increased.

Friday, June 3, 2011

Rectangular Light Source

The last few days I was in the debugging of penumbra shaders for rectangular light source. All my previous soft shadows implementations supported spherical light sources only and with rectagular light there was an incorrect shading. In the end I wrote a shader algorithm in C++ and debugged a few test cases. It turned out that the correct solution requires inverting 3x3 matrix directly in the pixel shader, which in the original implementation of the algorithm I haven't seen. Software implementation helped to understand all the subtleties of the algorithm (that's almost impossible with HLSL and GPU-oriented tools).




Due to low-poly geometry and rectangular shape of light source penumbra looks a bit angular. But the major problem is "single point silhouette approximation", I've written about it here (sorry, in russian). Because of this simplification the shadow looks like overshadowed, because not all potential silhouette edges contributed to penumbra. I don't like how the shadow looks, so I plan to implement more sophisticated silhouette edges determination.

Friday, May 27, 2011

Second Anniversary

Due to the second anniversary of my russian blog, I have prepared some screenshots:





The code is still far from perfect, images have a lot of artifacts (fireflies), there are numerous thing that I want to develop, debug and polish. But for the first time soft shadows are implemented using the power of Direct3D 11.

Tuesday, April 26, 2011

Depth of Field: First Experiments

I started to experiment with various depth of field techniques. This area is rather difficult so first I decided to implement a few brute-force approaches for reference purpose. From that scratch a more advanced and real-time friendly algorithms could be implemented.

The first, most simple approach: to render from different positions on virtual camera lens into accumulation buffer:



I used 48 samples, for each frame 1024 cubes are rendered with instancing, distance to focal plane is taken into account when building a look-at matrix. 48 "samples" is less than necessary for quality images - banding is highly noticable. I think that well distributed 128 samples will be sufficient for images that resemble ray-traced one.

The second approach: for each window pixel we draw a vertex, then geometry shader expands it to a sprite with some diameter. Then an additive blending is used to blend sprite's color with background. Pretty ugly approach, but at first glance may produce plausible images. Currently I have a troubles with preserving image energy, there are some artifacts and so on.


A few words about implementation: 1024 cubes are rendered with instancing, view space Z is written to depth buffer. Then rendered w * h vertices, each vertex maps to a single window pixel. To reduce workload, there is no vertex buffer at input, vertex shader is called by DrawInstanced() API, vertex coordinate computation is based on SV_InstanceID semantic. Vertex shader fetches color and depth and pass these to geometry shader. The latter computes circle of confusion diameter and expands vertex to a sprite. Then trivial output in the pixel shader and blending to the framebuffer. The bottleneck is in the heavy FP-blending, not in the geometry pipeline.

One thing that I considered important - right computation of CoC diameter. It depends on optical system parameters: lens diameter, focal distance and distance to focal plane. I took the appropriate formula from Dynamic Light Field Generation and Filtering paper.


The curve resembles in some way another curve that is given in this paper on DoF: Pyramidal Image Processing.

I hope that my math is right.