Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
Fast way to render lots of spheres
Setup:
1. Index buffer containing N quads (each 2 triangles), where N is the max amount of spheres. Repeating pattern of {0,1,2,1,3,2} + K*4.
2. No vertex buffer.
Render N*2 triangles, where N is the number of spheres you have.
Vertex shader:
1. Sphere index = N/4 (N = SV_VertexId)
2. Quad coord: Q = float2(N%2, (N%4)/2) * 2.0 - 1.0
3. Transform sphere center -> pos
4. Calculate the optimal oriented bounding box of the sphere. See: http://www.iquilezles.org/www/articles/sphereproj/sphereproj.htm
5. Output bounding box vertex (xy): pos + bbox_xaxis * Q.x + bbox_yaxis * Q.y
6. Bias depth output by sphere radius. (we want front of the sphere)
Pixel shader:
1. Calculate ray-sphere intersection: https://en.wikipedia.org/wiki/Line%E2%80%93sphere_intersection
2. If ray misses sphere, discard the pixel.
3. Calculate surface position and normal using the ray-sphere intersection result.
4. Calculate all g-buffer outputs, shading, etc that you need.
5. Output depth calculated with ray-sphere intersection.
6. Use SV_DepthGreaterEqual conservative depth output. This way you get HiZ culling (measured up to 6x speedup vs SV_Depth)
Preferably sort spheres front to back, if you have lots of overdraw.
If you have HUGE amount of overdraw, use the two-phase occlusion cull described in page 53 of this SIGGRAPH 2015 presentation:
http://advances.realtimerendering.com/s2015/aaltonenhaar_siggraph2015_combined_final_footer_220dpi.pdf
@stevesan

This comment has been minimized.

Copy link

@stevesan stevesan commented Feb 18, 2018

hello! so where do you get the sphere centers from?

@sebbbi

This comment has been minimized.

Copy link
Owner Author

@sebbbi sebbbi commented Feb 19, 2018

In my case I have a raw buffer written by my GPGPU simulators. I use this technique for debug views of SPH fluids and PBD physics simulation.

In DirectX, you can use one of the following:

Buffer<float4> spheres;
ByteAddressBuffer spheres;
StructuredBuffer<float4> spheres;

Store sphere position to xyz and radius to w. SV_VertexId % 4 gives you the index to address the sphere buffer.

@alexsr

This comment has been minimized.

Copy link

@alexsr alexsr commented May 12, 2018

Hello. Could you elaborate on the way you calculate the rays and possibly the ray origin? I get the vertex shader to work to the point where I can render oriented quads, but I'm struggling with implementing the pixel shader. Thank you for compiling this guide btw.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment