PDA

View Full Version : Nanhua's Shader Library with source code



Nanhua
July 12th, 2010, 09:39
Hi, all

(sorry for my poor English)

Major features:

1.Multidimensional Adaptive Sampling
1.1 Regular grid – it use the regular grid rather than the KD-tree for neighbor queries, it is simple, fast and able to measure all of the neighboring nodes.
1.2 Region detection – it can detect not only edges but also regions of high variance.
1.3 Multidimensional adaptive constructing – the method for adaptive sampling could be extended for adaptive constructing, for example, to adaptively construct the lookup acceleration data structure for importance-sampling of the environment (Image Based Lighting).
1.4 Multidimensional adaptive Quasi-Monte Carlo method – it has a suitable Quasi-Monte Carlo method for adaptive sampling, which can produce the (0, m, 2)-net in base 2.
2.Image Based Lighting (IBL)
2.1 Multidimensional adaptive constructing – as mentioned above.
2.2 Importance sampling for the product of environment and BRDF (so far, only the Lambert BRDF is supported).
2.3 Photon emission – it combines the algorithms for importance-sampling and emitting photon from the sky to provide an efficient photon emission approach.
3.Volumetric particle rendering
3.1 3dsmax particle system supported – and it could be extended to support other particle systems.
3.2 Bounding Interval Hierarchy – it uses the BIH as the acceleration data structure to support varying particle size and 3D motion blur.
3.3 Volume photon mapping – the algorithm for non-uniform volume photon mapping is adaptive and efficient.
3.4 Photon illumination – it can store the primary photon from lights instead of directly sampling them to improve performance. It will be very useful for scenes with the flame light (see below).
3.5 Flame volume/light – besides volume rendering it is also a real light which can trace shadow ray and emit photon from the space based on the position and radiance of the particles (for efficiency, it uses the multidimensional adaptive constructing method to construct the data structure for importance-sampling).
3.6 Ray-marching volume mixing – a simple way to mix overlapped volumes is to average their respective results, but it can not provide physically plausible result for complex shaders which are based on ray-marching. This issue can be solved by ray-marching volume mixing, both of volume rendering and volume photon mapping are supported.
4.A microfacet model for glossy sampling – in the real world, the effective roughness of a surface will vary with the incidence angle. This phenomenon could be interpreted and implemented by a principle which is based on the microfacet model, both of isotropic and anisotropic distribution are supported.

Update (2010.10.10)


64bit support.
The performance of IBL is much improved.
For non-uniform media and motion-blurred particle volumes, the quality of photon illumination is much improved.
For heavy particle volumes, the performance is improved in many cases.
Fixed a bug of MDAS.
Fixed an issue relating to hull objects.
Fixed a potential infinite loop of BIH.
The statistics of MDAC was incorrect, fixed.

(If you have the previous version, the mi file should also be replaced.)

Nanhua
July 14th, 2010, 05:11
nslib_dof


“nslib_dof” (Fig 1-1) is a lens shader which simulates depth of field (DOF). Its displayed name in the material browser is “DOF (NSLIB)”. The key difference between it and other similar lens shader is that it use the multidimensional adaptive sampling method to improve performance.


The first three parameters are “plane”, “size” and “mode”. The usages of “plane” and “size” are same as “physical_lens_dof” (for convenience, “plane” uses positive values instead of negative ones). The “mode” controls the distribution of the samples, there are three possible values for it: 0 – Box, 1 – Gauss, 2 – Blade (it's a hexagon). The difference is showed in Fig 1-2.


The rest parameters are all in the “Sampling” rollout, they control the adaptive sampling. Before you can understand them, we should first explore the theory of the multidimensional adaptive sampling.

Fig 1-1:
1678

Fig 1-2:
1679

Nanhua
July 14th, 2010, 05:15
Multidimensional Adaptive Sampling


Many applications in computer graphics rely on taking a large number of samples to get satisfied results, such as depth of field, area lighting and motion blur etc. Because taking many samples is expensive, adaptive sampling scheme was suggested.


Paper [1] proposed a multidimensional adaptive sampling strategy which use KD-tree for storing and neighbor queries. Due to the irregularity of KD-tree, this method can only measure the variance of each individual node. In order to avoid under-sampling features near the common edge of two nodes, they generate samples in a region slightly larger than the node’s extent, but no guarantee can be given by this approach.


Instead, we could use the regular grid to store samples, which is the quadtree in 2D and the octree in 3D etc. To maintain such regular data structure is easy and we can measure the variance of each square region which consisted of 2^D nodes (Fig 2-1). Because these 2x2 regions evenly cover the entire sampling domain and any feature which is larger than 2x2 area will cover at least one node regardless of its location, a guarantee can be given that all of these features can be detected by measuring the variance of each 2x2 region (Fig 2-2).


My approach first constructs a regular grid of 2^min_level nodes, each node has one sample (Fig 2-3a) – min_level is a user-specified number, if (min_level % D != 0) the node count will be less than 2^min_level and the sample count of each node will be larger than 1 (Fig 2-3b). The distribution of the samples is a low discrepancy point set which will be described later, you can assume it is a uniform random sequence for the moment.


Then, we travel the nodes, from left to right, top to down, measure the variance of each 2x2 region (2x2x2 region in 3D etc.), if the variance exceeds the user-specified threshold, the first node of the region will be labeled a flag f_probe and other nodes will be labeled a flag f_update (Fig 2-4), the flag f_probe means when we meet a node with this flag we should probe its neighbors to measure the variance of the region consisted of these nodes, the flag f_update means when we meet such a node we only need to update its state.


The second time we travel the nodes, we insert new samples into the nodes with f_probe flag or f_update flag (in practice, it's done when we probe the f_probe node's neighbors), and update their state (the flag and function value etc.). If the node contains only one sample, we divide the node along the X-axis, if the previous sample falls into left side, we insert the new one into right side and vice versa. If the node contains 2 or more samples, it should have been divided along the X-axis, we compare the sample counts of left and right side, if the counts are not equal, we insert the new sample into the side which has less samples, if they are equal, the order of inserting could be determined by a random number. After divided the node alone the X-axis, the next time to divide the node we will alone the Y-axis (Fig 2-5).


When the nodes labeled the f_probe or f_update flag have contained 2^D samples, we should begin to travel their sub-nodes. The flags of the sub-nodes will be written in this way: the sub-nodes of the node which has f_probe flag will all inherit the f_probe flag; the sub-nodes of the node which has f_update flag will inherit the f_update flag except the neighbors of the f_probe nodes, which will be labeled the f_probe flag instead (Fig 2-6).


We repeat these steps until reach the user-specified max_level or there is no node has the f_probe flag.


(For more technical details, please read the source code: src/Common/Lv0_Algo/MDAM/MDAS/)

Fig 2-1:
1680

Fig 2-2:
1681

Fig 2-3:
1682

Nanhua
July 14th, 2010, 05:17
Fig 2-4:
1685

Fig 2-5:
1686

Fig 2-6:
1687

Nanhua
July 14th, 2010, 05:20
Let's go back to the nslib_dof.


The parameters “min” and “max” in the “Sampling” rollout control the sampling rate per point. At each point there will be traced at least 2^min eye-rays and at most 2^max eye-rays. The parameter “step” specifies that each time we travel the grid 2^step samples will be added to each labeled node, increase it will force the shader to trace more rays. The parameter “threshold” determines whether a node in the grid need more samples, if the variance of a region exceeds the threshold, all of the nodes in the region will be added more samples. In practice, this threshold is modified based on the recursion level (multiplied by 2^level), if you increase the “max” parameter in order to trace more rays, you should also decrease the “threshold” accordingly.


Fig 3-1 is a reference image, it is rendered by assigning 6 to both of the “min” and “max”, which will force the shader to trace 2^6 = 64 rays everywhere, the total of traced ray is 23,090,112. The Fig 3-2 is rendering by MDAS, the minimum sample count is 2^4 = 16 and the maximum sample count is 2^6 = 64 at each point, the total of traced ray is 16,767,616. Fig 3-3 is the sampling density image of Fig 3-2, there are many noise in it because shader can only determine the sampling rate within its own domain and doesn't have the power to affect the sampling rate through the image plane (it's controlled by mental ray exclusively). This issue could be alleviated by the super-sampling of mental ray, but if the quality of the result still doesn't meet your requirement, you could use a map to control the sampling rate, for example, we could blur the Fig 3-3 and use the blurred image as the control map (Fig 3-4). The Fig 3-5 is rendered in this way.

Fig 3-1:
1688

Fig 3-2:
1689

Fig 3-3:
1690

Fig 3-4:
1691

Fig 3-5:
1692

Nanhua
July 14th, 2010, 05:22
nslib_collector


“nslib_collector” (Fig 4-1) is an utility shader which collects the Arbitrary Output Variables (AOV) from other shaders and writes the collected data into frame-buffer. Its displayed name in the material browser is “Collector (NSLIB)”. A main usage of it is to display the sampling density of MDAS.


In order to display the sampling density of nslib_dof, we should assign the “Shader List” shader to the Lens slot in the Renderer Panel > Camera Effects rollout (Fig 4-2) and add the nslib_collector and the nslib_dof to the List of shaders (Fig 4-3), nslib_collector must be the first one. Turn on the “diagnosis” parameter in the “Sampling” rollout of nslib_dof (Fig 4-4), turn on the parameters of nslib_collector (Fig 4-5). In the “Sampling Density” rollout of nslib_collector, there is a string parameter “frame buffer” which defines the name of the user frame-buffer to be written to (named frame-buffer is available since mental ray 3.6 and hasn't been supported by 3dsmax yet). If there is not any available user frame-buffer, the shader will write the value to the alpha channel (Fig 4-6). If you intend to modify the alpha channel, you should set the alpha contrast to 1.0 (Fig 4-7), otherwise mental ray will do many unnecessary super-sampling.

Fig 4-1:
1693

Fig 4-2:
1694

Fig 4-3:
1695

Fig 4-4:
1696

Nanhua
July 14th, 2010, 05:23
Fig 4-5:
1697

Fig 4-6:
1698

Fig 4-7:
1699

Nanhua
July 14th, 2010, 05:25
Region Detection


Paper [2] pointed out that the MDAS will suffer from the curse of dimensionality and they proposed an adaptive wavelet sampling method which is free from this issue.


The key for avoiding the curse of dimensionality is to sample the scene in low dimensional space and use a heuristic method to detect both of edges and the regions of high variance which are the projections of the higher dimension, add more samples near the edges or into the regions.


Update (2010.10.10)


In the previous version, I try to use a basic approach to implement the region detection but there is a bug of it, which causes a false appearance that it will significantly improve the quality. In fact, we don't need to make extra effort for region detection, the MDAS method described above is enough.


Fig 5-1 is a scene contains only a sphere assigned the DGS material. Fig 5-2 is the same scene rendered with nslib_dof (“size” = 0.001, “min” = 4, “max” = 8, “step” = 0 and “threshold” = 0.01). Fig 5-3 is the sampling density image of Fig 5-2. As can be seen from Fig 5-2 and Fig 5-3, the glossy reflection of the sphere has been successfully detected.

Fig 5-1:
1956

Fig 5-2:
1957

Fig 5-3:
1958

Nanhua
July 14th, 2010, 05:28
Multidimensional Adaptive Quasi-Monte Carlo Method

screenshot 6-1:
1703

screenshot 6-2:
1704

screenshot 6-3:
1959

Nanhua
July 14th, 2010, 05:29
Multidimensional Adaptive Quasi-Monte Carlo Method (2)

screenshot 6-4:
1706

screenshot 6-5:
1707

screenshot 6-6:
1708

screenshot 6-7:
1960

Nanhua
July 14th, 2010, 05:30
Multidimensional Adaptive Constructing


The MDAS method could be modified to adaptively construct the data structure for importance sampling. The data structure and the hierarchical sample warping algorithm used by MDAC are similar to [4]. A difference between MADS and MADC is that the MDAC should try to minimize the memory usage, for example, if the variance of the nodes in a region is less than a user-specified value, we can store the average value of the region in a parent node then discard the sub-nodes in the region. Another issue which will be encountered by MADC is that sometime the object to be sampled may be sparse, to sample the sparse object is inefficient because many samples will receive blank value. This issue could be solved by requesting the caller to provide the range-query, we can use the range-query to determine whether a region is empty and terminate the constructing early to avoid any useless sampling.


To extend MDAC to support interpolation like [10] is also possible.


(For more technical details, please read the source code: src/Common/Lv0_Algo/MDAM/MDAC/)

Nanhua
July 14th, 2010, 05:33
nslib_skylight

“nslib_skylight” (Fig 8-1) is a light shader which implements the image based lighting (IBL). Its displayed name in the material browser is “Sky Light (NSLIB)”.

There are several importance sampling approaches for sampling the product of environment and BRDF ([4]-[7]). The implementation of nslib_skylight is similar to [4] except that it makes use of the MDAC.

The first three parameters control the appearance of the IBL. The “hemisphere” determines whether the light only traces rays from the upper hemisphere (Fig 8-2). The “environment” controls the color of the sky, if it is turned on, the light will use the color returned by the environment shader assigned to the camera in the scene, otherwise the light will use the “sky color” instead, for example, user can assign a high resolution environment map to the camera while assign a low resolution environment map to the “sky color” for efficiency.

The parameters in the “Importance Sampling” rollout control how to sample the environment and BRDF. When turn on the “structured sampling”, the light will use the MDAC to construct the data structure for environment sampling, when turn on the “Lambert model”, the light will take count of the BRDF (so far, only the Lambert BRDF is supported), turn on both of them will get the optimized quality for diffuse objects. The “min”, “max”, “step” and “threshold” control the MDAC, their usages are same as MDAS, the appropriate values for them are dependent on the environment map.

A brief flow of tuning the MDAC:


1.Set the minimum and maximum sample rate of mental ray to the same value, for example one sample per pixel, because the adaptive sampling will affect the quality.

2.Set the number of samples of the light to a small value, for example 4 or 8, we will increase it later.

3.Set the “min” and “max” parameters to moderate values (“min” = 14, “max” = 16 or “min” = “max = 16 etc.), render the scene, increase the “min” and “max” by 2, render the scene again, if the quality improves, you should further increase the parameters, otherwise the previous setting is good enough.

4.Increase the number of samples of the light and adjust the sample rate of mental ray until the desired quality is reached.

One thing should be noticed that when you increase the “min” and “max” parameters, the memory consumption will become heavier, some relative information could be found in the mental ray message window (Fig 8-3). If the memory consumption is too heavy, you can try to increase the “threshold” parameter.

Fig 8-4 is rendered with the HDR map “St. Peter's Basilica, Rome” (1500*1500), “min” = 20, “max” = 20, “threshold” = 0.4, 256 shadow rays per point, sample rate 0 1. Fig 8-5 is rendered with another HDR map “Funston Beach at Sunset” (640*640), “min” = 16, “max” = 18, “threshold” = 0.1, 64 shadow rays per point, sample rate 0 1. Fig 8-6 and Fig 8-7 are rendered with the caustic, the algorithm for emitting photon from the sky is similar to [8] except that it uses the importance sampling for the product of environment and the projection-area of the bounding-box of the scene.

Notice:
Because nslib_skylight has its own control of sampling, the light source must be an area light of the user-defined type (see below the nslib_geo_userlight).

Fig 8-1:
1709

Fig 8-2:
1710

Fig 8-3:
1711

Fig 8-4:
1712

Nanhua
July 14th, 2010, 05:35
Fig 8-5:
1713

Fig 8-6:
1714

Fig 8-7:
1715

Nanhua
July 14th, 2010, 05:37
nslib_geo_userlight


“nslib_geo_userlight” (Fig 9-1) is an utility geometry shader. Its displayed name in the material browser is “User-Light Modifier (NSLIB)”. Because nslib_skylight needs the user-defined area light source which is not well supported in 3dsmax, we have to use a geometry shader to modify the relative fields of the light object.


Before you can access any geometry shader, you must install a plug-in mrGeomShaderObject.dlo which could be downloaded from the Internet.


Suppose you have created a box attached the nslib_geo_userlight in the scene, then we should assign a light to the “light” parameter (Fig 9-2), the light will be modified to the user-defined type. The parameter “samples” in the “Light Sampling” rollout specifies the number of samples. To use nslib_skylight, we should assign it to both of the “shader” and “emitter” parameters in the “Light Shader” rollout (Fig 9-3).

Fig 9-1:
1716

Fig 9-2:
1717

Fig 9-3:
1718

Nanhua
July 14th, 2010, 05:38
Before we enter into the subject of volumetric rendering, there are three relevant issues should be discussed:




Importance sampling for non-uniform medium.
Estimating the path-length of the photons traveling in non-uniform medium.
Russian roulette.

Nanhua
July 14th, 2010, 05:39
Importance sampling for non-uniform medium

screenshot 11-1:
1719

screenshot 11-2:
1720

screenshot 11-3:
1721

Nanhua
July 14th, 2010, 05:40
Estimating the path-length of the photons traveling in non-uniform medium

screenshot 12-1:
1722

Nanhua
July 14th, 2010, 05:41
Russian roulette


Russian roulette is an important technique in photon mapping ([9] §5.2.4). For RGB color model, a simple approach for Russian roulette is to use the average value of the r, g, b bands as the probability of scattering. This approach has a weakness that suppose there is an incoming photon of energy (1.0 , 1.0, 1.0), it hits an object of color (1.0, 0.0, 0.0), the probability of scatting is 1/3 and the energy of the scattering photon will become (3.0, 0.0, 0.0), if the scattering photon hits another object which is also of color (1.0, 0.0, 0.0), the probability of scatting is 1/3 too and the the energy of the scattering photon will become (9.0, 0.0, 0.0). If the colors of the objects are the same, the more bounces, the larger energy of the scattering photon, in rare cases, it will cause the overflow of floating-point.


According to testings, the mi_choose_scatter_type provided by mental ray uses the maximum value of the r, g, b bands as the probability of scattering. This approach can avoid the overflow of floating-point, but it will cause a performance issue, for example, the importance of an object of color (1.0, 0.0, 0.0) and another object of color (1.0, 1.0, 1.0) will be the same.


If we take account of the incident energy when determine the probability of scattering, we could solve the above issues. Suppose the luminance of the photon emitted by the light is L, the energy of the incoming photon is I, the scattering coefficient of the object hit by the photon is S (it's RGB), then the probability of scattering will be luminance(I * S) / L (the luminance() is to compute the luminance of a color).


The third approach can avoid the potential overflow and it is more efficient than the second one. The same principle could be applied to spectral rendering.

Nanhua
July 14th, 2010, 05:42
nslib_parti_volume


“nslib_parti_volume” (Fig 14-1) is a volume shader which simulatesparticipating media. Its displayed name in the material browser is “Parti Volume (NSLIB)”. Although in some aspects it is similar to the parti_volume shader shipped with mental ray, it has its own features.


Unlike parti_volume, it doesn't have any built-in noise function. Instead, user can use the texture shader to control the density and/or scattering color of the medium. Fig 14-2 is rendered by using the Cellular shader to control the density (Fig 14-3), the alpha channel is also available (Fig 14-4). Fig 14-5 is rendered by using the Perlin Marble shader to control the scattering color (Fig 14-6). To let the volume shaders could cast shadows, the shadow mode should be “segments” (Fig 14-7).


The parameters in the “Ray Marching” rollout control the ray-marching algorithm. The “step” determines the initial step length (for parti_volume, it's the “max_step_len”). The “rate” is the factor mentioned above which could be used for fine-tuning the importance-sampling. The “max level” is the maximum recursion level of adaptive sampling (for parti_volume, the max-level is determined by the “min_step_len”). If the contrast value of two neighboring points exceeds the “threshold”, new samples will be inserted between them.


The “unit scale” in the “Scene Data” rollout will be useful when user rescales the world units. If you want to get the same result as the one before rescaling the world units, you should modify the parameters “step” and “extinction” accordingly, it's not convenient. Instead, the “unit scale” will be modified automatically when you use the Rescale World Units Utility (Fig 14-8) and you don't need to manually modify any parameter in order to get the same result.

Fig 14-1:
1961

Fig 14-2:
1724

Fig 14-3:
1725

Fig 14-4:
1726

Nanhua
July 14th, 2010, 05:43
Fig 14-5:
1727

Fig 14-6:
1728

Fig 14-7:
1729

Fig 14-8:
1730

Nanhua
July 14th, 2010, 05:47
Photon illumination


Generally, the main usage of photon mapping is to simulate the indirect illumination. In fact, photon mapping can also be used for direct lighting. For example, volume shader can store the primary photon from area lights instead of directly sampling them to improve performance. Fig 15-1 is rendered with a disc area light by the conventional method while Fig 15-2 is rendered by the photon mapping method.


To configure the scene for photon illumination, you should assign nslib_parti_volume to the Volume and Photon Volume component of the material (Fig 15-3), set the parameter “photon illumination” to 1 – Area Lights or 2 – All Lights (Fig 15-4), turn on the Caustics (Fig 15-5), the object which attached the nslib_parti_volume should be set to generate caustics (Fig 15-6), if the area light is within the volume, you should turn on the Auto-volume mode (Fig 15-7).


If the computation of the lighting is simple, the speedup from photon illumination may be few or no, but for complex lights and complex volume effects, the benefit of photon illumination will be great (see the Flame light which will be described later).


An issue of photon illumination is that if the light is outside of the volume, the radiance will be blurred near the border. For example, Fig 15-8 is rendered with the nslib_skylight by light sampling while Fig 15-9 is rendered by photon illumination. This issue is due to the wrong estimate of the covered area/volume of the photons ([9] §7.2). Although there are several solutions to this issue, mental ray doesn't make any use of them for volume photon mapping.

Fig 15-1:
1731

Fig 15-2:
1732

Fig 15-3:
1733

Fig 15-4:
1962

Fig 15-5:
1735

Nanhua
July 14th, 2010, 05:49
Fig 15-6:
1740

Fig 15-7:
1741

Fig 15-8:
1742

Fig 15-9:
1743

Nanhua
July 14th, 2010, 05:52
nslib_particle_cloud


“nslib_particle_cloud” (Fig 16-1) is a particle volume shader. Its displayed name in the material browser is “Particle Cloud (NSLIB)”. The main difference between it and nslib_parti_volume is the particle volume shader can use the particle data to control the properties of the medium.


So far, only the 3dsmax particle system is supported but it can be extended to support other particle systems.


The basic steps for using nslib_particle_cloud are:




Create a particle system, assign a material to it. Choosing which material doesn't much matter, except that it must contain the Particle Age and Particle MBlur shader (Fig 16-2), otherwise 3dsmax will not output the required particle data. You can, for instance, use the DGS material and assign the Particle Age and Particle MBlur to the parameter “diffuse” and “glossy” respectively (Fig 16-3).
Attach the particle system object to the parameter “particles” (Fig 16-4), set the particle system object to non-renderable (Fig 16-5) because we only need the particle data for volumetric rendering and don't want to render the real particle objects.
If you are not going to use the volume photon mapping, you could assign nslib_particle_cloud to the Volume slot in the Renderer Panel > Camera Effects rollout (Fig 16-6).
Otherwise, you should create a box object which is big enough to case the particle system (Fig 16-7), assign the material which contains nslib_particle_cloud as the Volume and Photon Volume component to the box object. The Surface shader and Photon shader of the material should make correct inside/outside decisions about the ray/photon, if you are not sure about this, the simplest way is to leave the Surface and Photon component alone (Fig 16-8) and turn on the Auto-volume mode (In 3dsmax, when you turn on the Auto-volume mode the Photon Auto-volume mode will be turned on automatically). The GI effect is shown in Fig 16-9 and Fig 16-10.



The usage of most of the parameters of nslib_particle_cloud is similar to nslib_parti_volume. Below are the peculiar parameters of nslib_particle_cloud.


The parameter “motion blur” determines whether the motion blurring is enable. The approach used for motion blurring is similar to the Particle MBlur shader shipped with 3dsmax. The effect is shown in Fig 16-11 and Fig 16-12. (It's implemented by the shader itself, you don't need to turn on the motion blurring of mental ray.)


Besides using texture shader to control the properties of the medium, there are particular particle texture shader which could be used by assigning them to the “particle density” and/or “particle scattering” (for more details, see the nslib_particle_age below).


(I am not familiar with the fluid simulation, so the demos of particle rendering are rather poor.)

Fig 16-1:
1963

Fig 16-2:
1745

Fig 16-3:
1746

Fig 16-4:
2020

Nanhua
July 14th, 2010, 05:56
Fig 16-5:
1756

Fig 16-6:
1757

Fig 16-7:
1758

Fig 16-8:
1759

Nanhua
July 14th, 2010, 05:58
Fig 16-9:
1964

Fig 16-10:
1965

Fig 16-11:
1966

Fig 16-12:
1967

Nanhua
July 14th, 2010, 06:00
Bounding Interval Hierarchy


nslib_particle_cloud uses the Bounding Interval Hierarchy (BIH) as the acceleration data structure for querying the particle data, which is proposed by [11]. For constructing the BIH tree, [11] uses the spatial median as the split plane, this strategy is simple and fast but it will reduce the traversal performance when the scene is a mixture of small and large geometric elements.


There is an effort to find the optimum binary search trees, which is to make the weights of the sub-trees as near to being equal as possible ([12] §6.2.2). Although this approach can not guarantee to construct the optimum trees, a feature of it is the large leaves tend to be putted on low level while the small leaves tend to be putted on deep level, that's what we expected. In an analogue way, we could try to balance the surface area of the sub-nodes when construct the BIH tree. If the primitives are evenly distributed, the resulting tree will be similar to the one built by median-split. If the primitives are unevenly distributed, the performance issue of median-split could be alleviated by the balancing-split. For example, there are four triangles in Fig 17-1. If we construct the BIH tree by median-split, the resulting tree (Fig 17-2) will put the largest triangle A on level 2. While by balancing-split (using the center of each object as the split candidates), the triangle A will be putted on level 1 (Fig 17-3). Because the triangle A has the highest probability of being hit, put it on lower level could improve the traversal performance.


BIH vs. BVH


A difference between BIH and BVH is the traversal of BIH only need to check the range of the axis which is perpendicular to the split plane, while the traversal of BVH need to check the ranges of all the axes. Suppose we divide a node along the X-axis and the ranges of the sub-nodes in the Y-dimension don't change (Fig 17-4), to check the range of the Y-axis will make no sense because the identical checking has been done before entering the sub-nodes. In another case, the range of the Y-axis of the left sub-node in Fig 17-5 is half of its parent node, to check the Y-range can terminate the traversal early in many cases.

Fig 17-1:
1768

Fig 17-2:
1769

Fig 17-3:
1770

Fig 17-4:
1771

Fig 17-5:
1772

Nanhua
July 14th, 2010, 06:02
nslib_particle_age


“nslib_particle_age” (Fig 18-1) is a particle texture shader. Its displayed name in the material browser is “Particle Texture Age (NSLIB)”.


nslib_particle_age has only one parameter “color”, it first writes the particle's age into miState::tex and miState::point (because the texture shaders shipped with 3dsmax are unaware of the variable miState::tex) then uses the mi_eval to evaluate the input “color” and returns the obtained value.


To use nslib_particle_age, we should assign it to the “particle density” and/or “particle scattering” parameter of nslib_particle_cloud (Fig 18-2), connect a texture shader – for example, the Gradient or Gradient Ramp (Fig 18-3) – to the “color” (Fig 18-4), set the mapping method of the texture shader to “Planar from World XYZ” (Fig 18-5).


One thing should be noticed that the particle texture shader is different from other texture shaders, it needs the cooperation with the particle volume shaders, you should not assign nslib_particle_age to the “density” or “scattering” parameter of nslib_particle_cloud, which should be connected to the ordinary texture shader, nor assign an ordinary texture shader to the “particle density” or “particle scattering” parameter of nslib_particle_cloud, where only the particle texture shader is acceptable.


Update (2010.10.10)

Added a new particle texture shader “nslib_particle_ptex” (see here).


Fig 18-1:
1773

Fig 18-2:
2021

Fig 18-3:
1775

Fig 18-4:
1776

Fig 18-5:
1777

Nanhua
July 14th, 2010, 06:05
nslib_particle_flame


“nslib_particle_flame” (Fig 19-1) is a particle volume and light shader. Its displayed name in the material browser is “Particle Flame (NSLIB)”.


Unlike other volume shaders, nslib_particle_flame doesn't sample the lights, instead, it will give off light by itself. To light up the scene, we could use nslib_particle_flame as a light shader, due to its own control of sampling, we need the nslib_geo_userlight again (Fig 19-2). The parameter “color” and “particle color” in the “Irradiance” rollout define the color of the flame and for convenience the intensity of the flame could also be modified by the parameter “intensity”.


Besides light sampling, Final-Gathering is a general-purpose approach for self-illumination objects. If the flame is large or close to the target objects, FG will be suitable, otherwise, light sampling will be a good choice. If you want the flame to still cast light when the FG is on, you should turn on the parameter “FG invisible”.


Because the 3D area light source is more complex than the 2D area light source, sampling the flame is an expensive computation especially of the volume effect for which the FG is also not available. Fortunately, we have the photon illumination which could substitute the light sampling. Fig 19-3 is rendered in this way, it's much faster than to directly sample the flame light. To configure the scene of Fig 19-3 is a bit complex because we need to mix two different volume shaders (nslib_particle_cloud and nslib_particle_flame), the details will be described later.


In order to trace shadow ray and/or emit photon based on the distribution of the particles, nslib_particle_flame use the MDAC to construct the data structure for importance-sampling. The parameters in the “Importance Sampling” rollout which control the MDAC have the same usage as nslib_skylight.

Fig 19-1:
1778

Fig 19-2:
1779

Fig 19-3:
1968

Nanhua
July 14th, 2010, 06:07
Ray-marching volume mixing


nslib_parti_volume, nslib_particle_cloud and nslib_particle_flame are all based on ray-marching, if they overlap with one another, the simplest way to mix them is to average their final results, but such an approach is only suitable for simple volumes. A more correct way for mixing them is to average their results on each point when we perform the ray-marching. For nslib_parti_volume and nslib_particle_cloud, their results should be averaged based on their density, while for nslib_particle_flame, because it's self-illumination, its result should be added into the sum without change.


For photon volume mixing, the estimation of the path-length of the photon traveling in the mixed volumes should be based on the averaged extinction coefficient. If a photon will be absorbed, the choice of which component-volume to store and/or scatter the photon should be based on the extinction coefficient of each of them. For self-illumination objects (nslib_particle_flame), they only need to emit photons and don't necessarily be involved in photon volume mixing.


(For more technical details, please read the source code: src/Volume/Helper/Mixing/RayMarching/)


To mix the volumes, the Auto-volume mode must be turned on, for each volume, user should create a box object to which the volume shader will be attached. Don't attach the volume shader to the camera since the priority level of the volume shader of the camera is lower than the volume shader of objects, if you want to use a volume shader to fill the scene, you could create a large box to case the scene and the camera then attach the volume shader to it. Fig 20-1 is the mixture of two cloud volumes.


The ray-marching algorithm of volume mixing is controlled by the parameters taken from the mixed volume shaders (the parameters in their “Ray Marching” rollout). In order to get a consistent result, the ray-marching settings of the mixed volume shaders should be the same.


Generally speaking, the position of the light object of user-defined area light source doesn't affect the rendering, but if the Photon Auto-volume mode is turned on, the position of the light object will be considered by mental ray to determine whether the light is in a object volume. So, if you want to mix nslib_particle_flame and nslib_particle_cloud and use the photon illumination to substitute the light sampling, the box and the light object of the flame should be encased by the box object of the cloud (Fig 20-2), otherwise the inside/outside decisions about the photons will be incorrect.


One thing should be noticed that the ray-marching mixing of the volumes needs the cooperation among them, only nslib_parti_volume, nslib_particle_cloud and nslib_particle_flame could be mixed in this way, don't mix them with other volume shaders.

Fig 20-1:
1969

Fig 20-2:
1782

Nanhua
July 14th, 2010, 06:08
A microfacet model for glossy sampling


In the real world, the effective roughness of a surface will vary with the incidence angle, a brief description of this phenomenon can be found in [13]. Fig 21-1 is rendered with a shader (DGS Material) which doesn't take account of the variability of the effective roughness while Fig 21-2 does.


If we use the microfacet model to simulate the rough surfaces, the probability of the facet being hit by the incident ray would be proportional to the dot product of the normal of the facet and the inverted direction of the incident ray. If the incidence angle is zero (Fig 21-3a), the facets of different azimuthal angles will have equal chances to be hit, in this case, the variance of the reflecting directions is high. If the incidence angle increases (Fig 21-3b), the facets which face forward the incident ray will have more chances to be hit than the backward facets, since the hits concentrate toward a part of the facets, the variance of the reflecting directions will be lower than the former. When the incidence angle approaches grazing (Fig 21-3c), only the forward facets can be hit, the variance of the reflecting directions will be the lowest one. As you can see, the variability of the effective roughness can be interpreted by the microfacet model. Because there is no assumption about the facet distribution, the above principle could be applied to arbitrary microfacet models. Besides reflection, the transmission could also be simulated by the microfacet model like [14].


“nslib_metal” (Fig 21-4) is a material shader which is implemented according to the above principle. Its displayed name in the material browser is “Metal (NSLIB)”. After I finished nslib_metal, I found that the mia_material can also achieve the similar results (Fig 21-5), but I don't know how it works, maybe it uses an approximate method?

Fig 21-1:
1783

Fig 21-2:
1784

Fig 21-3:
1785

Fig 21-4:
1786

Fig 21-5:
1787

Nanhua
July 14th, 2010, 06:12
References

[1] Hachisuka, T., Jarosz, W., Weistroffer, R. P., Dale, K., Humphreys, G., Zwicker, M., and Jensen, H. W. Multidimensional adaptive sampling and reconstruction for ray tracing.

[2] Overbeck, R. S., Donner, C., and Ramamoorthi, R. Adaptive wavelet rendering.

[3] Keller, A. Strictly deterministic sampling methods in computer graphics.

[4] Clarberg, P., and Akenine-Möller, T. Practical product importance sampling for direct illumination.

[5] Cline, D., Egbert, P. K., Talbot, J. F., and Cardon, D. L. Two stage importance sampling for direct lighting.

[6] Clarberg, P., Jarosz, W., Akenine-Möller, T., and Jensen, H. W. Wavelet importance sampling: efficiently evaluating products of complex functions.

[7] Jarosz, W., Carr, N. A., and Jensen, H. W. Importance Sampling Spherical Harmonics.

[8] Dammertz, H., and Hanika, J. Plane sampling for light paths from the environment map.

[9] Jensen, H. W. Realistic Image Synthesis Using Photon Mapping.

[10] Benson, D., and Davis, J. Octree textures.

[11] Wächter, C., and Keller, A. Instant ray tracing: the bounding interval hierarchy.

[12] Knuth, D. E. Sorting and Searching, volume 3 of The Art of Computer Programming.

[13] Westin, S. H., Li, H., and Torrance, K. E. A comparison of four BRDF models.

[14] Walter, B., Marschner, S. R., Li, H., and Torrance, K. E., Microfacet models for refraction through rough surfaces.

Javadevil
July 14th, 2010, 09:07
Wow a lot of work there. I look forward to trying some of these shaders.

regards

mb42
July 14th, 2010, 10:48
Very cool, thanks for posting, incl. sources! One thing that would be awesome would be if you could collect all the detailed informations and figures you posted here into a PDF. That would make for much easier reading and could also serve as a reference to your shaders!

Thanks again!

rlevene
July 14th, 2010, 11:15
WOW. These seem like seriously powerful shaders. I have very little experience with writing shaders so I just want to know if there is anything that would prevent these shaders from working in Maya?

Obviously you have provided the .mi and dll files for various versions of 3d max but I assume these relate to the various versions of mental ray rather than max specifically?

Thanks,

Richard

--EDIT---

Just read the readme file in your source zip file and it explains what to do to use them in maya/XSI.

Cheers,

Rich

Nanhua
July 16th, 2010, 10:19
I modify the display of the figures, hopefully it could be easier for reading :)

andre3d1
July 18th, 2010, 11:56
Very good, congratulations. 3ds Max needed it. Thanks for sharing.

cbflex
September 1st, 2010, 19:18
Ok, it should've been mentioned that the parti volume shader you provided only works when the lights you are using are using Ray traced Shadow maps. Mental Ray Shadows maps will not work with this shader. [QUOTE=Nanhua;28528]nslib_parti_volume
Unlike parti_volume, it doesn't have any built-in noise function. Instead, user can use the texture shader to control the density and/or scattering color of the medium. Fig 14-2 is rendered by using the Cellular shader to control the density (Fig 14-3), the alpha channel is also available (Fig 14-4). Fig 14-5 is rendered by using the Perlin Marble shader to control the scattering color (Fig 14-6). To let the volume shaders could cast shadows, the shadow mode should be “segments” (Fig 14-7).

zzubnik
September 3rd, 2010, 22:46
Is it possible to get this to work on Max 2011-64bit? I'd love to give this a try.

Nanhua
September 4th, 2010, 05:58
Is it possible to get this to work on Max 2011-64bit? I'd love to give this a try.

Unfortunately, I only have a 32bit compiler, it can not build the the 64bit version :cry:

zzubnik
September 6th, 2010, 16:07
Unfortunately, I only have a 32bit compiler, it can not build the the 64bit version :cry:

Well, thanks anyway, your work looks great. Mental ray needs something like these methods built in to it.

Thanks,
Nik

Remydrh
September 7th, 2010, 01:18
The progressive renderer is a similar implementation.

I would love to try these with it. But I too need 64bit. :-(

maxplugins
September 8th, 2010, 10:01
If I can find the time over the next few days, I'll try and do 64-bit versions of everything.
As soon as I'm done I'll post it here.

Dave

Nanhua
September 9th, 2010, 06:31
Hi, Dave

I find the Microsoft Platform SDK also contains the tools and libraries for 64bit applications (I don't know before), I will try to build the 64bit version soon and still thank you :-)



There will be some improvements, when completed, I will post the new libraries (32bit/64bit) here.

Sagroth
September 11th, 2010, 17:51
(I've missed the answer to my question :))

3danim8d
September 24th, 2010, 22:19
Nanhua,

This shader is looking great, any idea when the next update and 64bit version might be available for download.

Thanks for the awesome work.

Jeff

Nanhua
September 29th, 2010, 05:45
Hi, Jeff

Please wait, I will post them as soon as possible, hopefully I can complete in the next month :-)

Nanhua
October 11th, 2010, 14:38
Update (2010.10.10)


64bit support.
The performance of IBL is much improved.
For non-uniform media and motion-blurred particle volumes, the quality of photon illumination is much improved.
For heavy particle volumes, the performance is improved in many cases.
Fixed a bug of MDAS.
Fixed an issue relating to hull objects.
Fixed a potential infinite loop of BIH.
The statistics of MDAC was incorrect, fixed.

Remydrh
October 11th, 2010, 19:16
Awesome, 64-bit, thanks! Will hopefully have time to test soon.

moulder6
October 12th, 2010, 12:40
10x for the x64 bit version :P Just downloaded it :)
what's that particle texture ptex :P shader?

installed to max2011 getting this in my message window:
PHEN 0.3 error: nslib_particle_ptex: invalid shader type (the rendering is being terminated)

Nanhua
October 12th, 2010, 17:18
10x for the x64 bit version :P Just downloaded it :)
what's that particle texture ptex :P shader?

installed to max2011 getting this in my message window:
PHEN 0.3 error: nslib_particle_ptex: invalid shader type (the rendering is being terminated)

It's a new shader in this release, I will write a description of it.

PS: I sent a PM to you :-)

Nanhua
October 14th, 2010, 05:33
nslib_v3dsMax2011 is available.

Thank moulder6 for helping!

moulder6
October 14th, 2010, 07:51
We thank you for the great work!

tigre_g5
October 15th, 2010, 06:17
Thank you Nanhua, your shaders are awesome in special the Sky Light (NSLIB), 3dsmax really needed a IBL. But please fix a new bug with Sky Light (NSLIB) and Irradiance Particles in 3dsmax 2011 that don´t work together anymore:(. The 2010 shader worked flawless in 3dsmax 2011.

Nanhua
October 15th, 2010, 06:52
Thank you Nanhua, your shaders are awesome in special the Sky Light (NSLIB), 3dsmax really needed a IBL. But please fix a new bug with Sky Light (NSLIB) and Irradiance Particles in 3dsmax 2011 that don´t work together anymore:(. The 2010 shader worked flawless in 3dsmax 2011.

In fact it's not a bug :-), the Irradiance Particles can achieve the IBL by itself (see http://forum.mentalimages.com/showthread.php?t=4757).

tigre_g5
October 15th, 2010, 20:50
In fact it's not a bug , the Irradiance Particles can achieve the IBL by itself (see http://forum.mentalimages.com/showthread.php?t=4757).

Hello Nanhua, yes i konw, actually your Sky Light (NSLIB) shader is really similar to Irradiance Particles with Environment Evaluation, but yes the shader have a bug please take a look to the next pictures that I´ve render in 3ds max 2011 with your 2010 and 2011 shader.

The Character have an A&D Material with Falloff type Shadow / Light in the Diffuse Color Map.

tigre_g5
October 15th, 2010, 20:54
Overexposed when you used Irradiance Particles with Environment Evaluation and Sky Light (NSLIB)

Nanhua
October 16th, 2010, 06:44
Hi, tigre_g5

Have you used the “User-Light Modifier (NSLIB)” to convert the light (see http://forum.mentalimages.com/showthread.php?t=6690&page=2#14) ?

BTW, I don't know why you use the Falloff with the type Shadow / Light, because in this way, the Falloff shader will sample the light while the A&D Material will also do this task, it will be inefficient to sample the light twice.

tigre_g5
October 16th, 2010, 10:16
Hello Nanhua, thanks for answer, your shaders are awesome, special IBL with Irradiance Particles, really are faster that FG or Irradiance Particles with Environment Evaluation. But please take a look a nslib_v3dsMax2011 have a bug IBL don´t work with Irradiance Particles anymore.

Nanhua
October 16th, 2010, 11:37
Hi, tigre_g5

Could you please first tell me that whether you have used the “User-Light Modifier (NSLIB)" to convert the light attached the nslib_skylight shader? If not, the nslib_skylight will not work certainly.

moulder6
October 17th, 2010, 19:40
Following the workflow Nanhua pointed in the presentation of the shaders, IBL works for me in max 2011.

Nanhua
October 20th, 2010, 05:41
nslib_particle_ptex


“nslib_particle_ptex” (Fig 22-1) is a particle texture shader which provides the per-particle texture mapping (don't confuse it with the per-face texture mapping). Its displayed name in the material browser is “Particle Texture PTex (NSLIB)”.


The first parameter is “input” which should be connected to a texture shader, nslib_particle_ptex will provide a local coordinate of the particle for texture mapping, so the texture will stick to the particles without the swimming artifact (for more details, see here (http://www.djx.com.au/blog/2008/07/21/particlesamplerinfo-smoke/)). For example, you can assign the Noise shader to “input” (Fig 22-2). Turn on the “normalize” parameter will scale the texture coordinate with the particle size, in this way, the texture size will grow with the particle size. When this parameter has been turned on, the size control of the connected texture shader should be set to a constant, for example 1.0 (Fig 22-3).


The “falloff” parameter controls the attenuation of the texture, the attenuation begins at the center of the particle and fades to zero at the border of it. The default value is 0.5, set it to 0.0 will disable it, increase it will cause rapider fading. If you use nslib_particle_ptex to modify the density of the particles, turning on “falloff” could alleviate the dim border issue of Photon Illumination (see here). But if you use nslib_particle_ptex to modify the scattering color of the particles, the “falloff” should be disabled because it's not necessary in this case.


When the motion blurring of the particles was turned on (Fig 22-4), we need to sample the input texture multiple times to get a blurred result. The parameter “step” in the “Motion Blurring” rollout determines how many samples will be taken. Generally, if the “normalize” is on, set “step” to 1.0 will be a good start. Increase it for faster preview, decrease it for better quality.


Again, as a particle texture shader like the nslib_particle_age (here), nslib_particle_ptex needs the cooperation with the particle volume shaders, you should not apply it to any other shaders.


Fig 16-9, Fig 16-10 (here), Fig 19-3 (here) and Fig 20-1 (here) are rendered with nslib_particle_ptex.


Fig 22-1:
2016


Fig 22-2:
2017


Fig 22-3:
2018


Fig 22-4:
2019

Nanhua
October 20th, 2010, 05:45
A widely known issue of volumetric particle rendering is when we use texture shaders to control the properties of the medium the rendering speed will be very slow especially for self-shadowing. There are two resolutions to this issue, one is Deep Shadow Map, another one is Lookup Table. Besides them, my resolution is the Photon Illumination (see here).


Moreover, to illuminate smoke from volumetric light sources (for example, flames) is difficult. There is a renderer which employs the Point-Based method to achieve this task. For mental ray, this effect can also be implemented by the Photon Illumination (see Fig 19-3 here).

thorsten hartmann
October 29th, 2010, 01:22
Hi

first... great work! I have try the sky_light and your workflow, but i have only black renderings. 3dsmaxdesign 2011. Can you upload Demoscene of your different Shader´s?

mfg
hot chip

Nanhua
October 29th, 2010, 05:34
Hi, thorsten

There is a necessary step that using the "User-Light Modifier (NSLIB)" to convert the light source (see here).

Lokken
April 21st, 2013, 17:45
Heart felt gratitude for this plugin. It has unlocked more creative techniques for me. Much appreciate by myself and the Animation team in Kingston, England.

Lokken

jb_alvarado
May 20th, 2013, 13:19
I was trying to add some functions to the nslib_geo_userlight, but 3ds max always crash after rendering when they want to clean up the scene (with the original shader also). I try to read the code, but this one is very special for me, so I don't find out what is happen.

boumay
October 6th, 2013, 00:08
I tried to download the shaders but when I try to log in, it keeps saying me that I'm not logged or don't have the permission.
Can you provide us with a link? And do these shaders work with max 2012?
Thank you.

[mod: you need to be approved from your first post to have permission, so you should now. How do you use mental ray?]