Title: Shading techniques for rendering 3D fractals Post by: Buddhi on September 28, 2009, 10:00:28 PM Hi
I would like to start discussion about shading techniques for 3D fractals. At start I will share my experience in this topic. I rendered the same view of 3D Mandelbrot fractal (Twenbee's formula) in several shading techniques. My method of rendering bases on high resolution slices (big 3D array) containing information about number of iteration for each voxel (3D pixel). I know that this is not most efficient method but 3D arrays deliver information about whole fractal and enable rendering with complex shading. Another benefit is possibility to render transparent fog where opacity is proportional to number of iterations. I have developed following shading methods: - hard shadows - angle of incidence of light based on estimated normal vectors - environment mapping based on estimated normal vectors - global illumination Hard shadows (http://www.fractalforums.com/gallery/0/thumb_640_28_09_09_8_14_04.jpg) http://www.fractalforums.com/gallery/?sa=view;id=927 This is the simplest method for shading 3D fractals. From each visible voxel you have to send virtual ray towards light source. If ray meets some obstacle you have to set light intensity for rendered point as zero or decrease light intensity proportional to opacity of encountered voxel (number of fractal iterations). Angle of incidence of light (http://www.fractalforums.com/gallery/0/thumb_640_28_09_09_8_15_39.jpg) http://www.fractalforums.com/gallery/?sa=view;id=928 Calculating angle of incidence of light requires information about angle of normal vector for surface near rendered voxel. It is very difficult to calculate accurate normal vector for 3D array of voxels when fractal is rendered using iteration count. Iteration count function unfortunately is not solid. There is Distance Estimation method which provides solid function of distance to fractal border but it is possible to use this method only for hypercomplex fractals. David Makin developed method for calculating distance function but I tried with this with no result :( (I don't understand enough David's algorithm). The simplest method of getting normal vector is calculate something like gradient of potential function where potential equals to iteration count or estimated distance. This is very simple to calculate. For normal vector calculation you have only subtract values of adjacent pixel in every direction (x,y and z). For example: delta x = f(x+0.5,y,z) - f(x-0.5,y,z) delta y = f(x,y+0.5,z) - f(x,y-0.5,z) delta z = f(x,y,z+0.5) - f(x,y,z-0.5) (I can use 0.5 offset value because I'm using 3D interpolation) Next you have to normalize this vector by dividing each component by length of above vector. Dot product of normal vector and light direction vector will be intensity of light. light intensity = N.x * light.x + N.y*light.y + N.z*light.z This simple method is working but looks not so good in zoom (http://www.fractalforums.com/gallery/0/640_28_09_09_8_17_42.jpg) You can achieve best result when you calculate average gradient for some small area near calculated point. I usually use 3x3x3 voxels area. Bellow is an example render with this approach. On this image fractal surface is smooth but unfortunately lost some details. (http://www.fractalforums.com/gallery/0/thumb_640_28_09_09_8_20_20.jpg) http://www.fractalforums.com/gallery/?sa=view;id=930 To be continued... Title: Re: Shading techniques for rendering 3D fractals Post by: Buddhi on September 29, 2009, 07:45:04 PM Environment mapping (http://www.fractalforums.com/gallery/0/thumb_640_28_09_09_8_22_22.jpg) http://www.fractalforums.com/gallery/?sa=view;id=931 This technique in technical details is very similar to calculating angle of incidence of light but end effect is completely another. This shading method simulates reflections of environment (virtual sky) surrounding fractal. For this method there is needed some additional bitmap with reflection map (for example photo of sky). You also have to calculate normal vector. Horizontal and vertical (x and y) components will be used as coordinates of pixel on reflection bitmap. Of course x and y values has to be multiplied by proper factor to adjust to bitmap size. Colour of actual rendered pixel will be equal to pointed pixel by normal vector. Global illumination (http://www.fractalforums.com/gallery/0/thumb_640_28_09_09_8_25_10.jpg) http://www.fractalforums.com/gallery/?sa=view;id=932 I think this is the most impressive technique for 3D fractal rendering but unfortunately the slowest. This method simulates ambient light and the final effect is similar to radiosity method (radiosity additionally includes light diffusion and is even slower). Rendering algorithm is similar to calculation of shadows but you have to calculate not one ray but tens or hundreds. The best effect is when rays are sent in spherical directions. When you calculate all beams the final intensity of light will be average brightness from all rays. Rendering time is very long because program has to calculate many rays. If average beam length is about 500 voxels and there is about 200 beams program has to scan about 100 thousands voxels for each rendered pixel. For optimisation I used not constant steps for scaning each ray. I wrote something like this (pseudo code): Code: for ray_number=0 to max_ray_number If I use high accuracy for small distance form centre and lower accuracy for higher distances calculations are much more faster and final effect is nearly the same like when I use constant step. Complex shading (http://www.fractalforums.com/gallery/0/thumb_640_28_09_09_8_28_09.jpg) http://www.fractalforums.com/gallery/?sa=view;id=933 If you have to much free time for rendering you can use all shading techniques together. Rendering is very very slow but result of shading is very realistic. For calculation of resultant brightness of pixel I use following formula: brightness = normal * (1.0 - ambient)*hard_shadows + ambient) + global_illumination + reflection where: normal - brightness corresponded to angle of incidence of light hard_shadows - brightness calculated using hard shadows algorithm ambient - constant ambient light value global_illumination - brightness calculated using global illumination algorithm reflection - brightness from environment mapping |