Most recent edit on 2006-11-28 13:58:33 by CyrilleDamez

Additions:
If you create your own FXMaps, do not hesitate to re-use them, they will be computed only once for all the textures which use them.
Then if you want to re-use a part of your compositing graph from a previously created texture, create external links in your new texture by right clicking in your graph and selecting the "Add External Links..." option. The library dialog box will then be displayed: open a file and select the ressources that you need in a list of available shared ressources in this file.
This operation creates external links nodes to selected shared ressources in your compositing graph.
Common shared ressources will be computed only once for multiple textures.
However to get these optimisation working well you will need to merge all the textures of a given level in a single .pfx file. To do that use the Export/Merge tool as described here.
Do not hesitate to use the transformations ("Tranform" option just below the compositing graph).
For example if you do a 1k*1k texture using a 256*256 noise, tile it 4x4 times by using the "Scale" option to get a higher level of detail.
Regarding imported SVGs remember that these filters rendering speed and the size of their result depend on the precision you specify when you import the file. Usually it is faster to draw a simple shape with an FXMap than with vector file (and the resulting file will be smaller too).


Deletions:
If you do your own FXMaps, do not hesitate to re-use them, they will be computed only once for all the textures wich use them.
Then if you want to re-use a part of your CompositingGraph from a texture done earlier, create ExternalLinks in your new texture by right clicking in your graph and select the "Add External Links..." option, then the library dialog box will be displayed: open a file and select the ressources that you need in a list of available SharedRessources in this file.
This operation creates ExternalLinks nodes to selected SharedRessources in your compositing graph.
Common SharedRessources will be computed only once for multiple textures.
However to get these optimisation working well you will need to merge all the texture of a level in a single .pfx file. To do that use the Export/Merge tool as described here: ExportingTextures
Do not hesitate to use the transformations ("Tranform" option just under the Compositing Graph).
For example if you do a 1k*1k texture using a 256*256 noise to not hesitate to make it tiled by using the "Scale" option to get a higher level of details.
Regarding ImportingSvgs remember that these filters rendering speed and the size of their result depend on the precision you specify when you import the file. Usually it is faster to draw a simple shape with an FXMap than with vector file (and the resulting file will be smaller too).




Edited on 2006-11-28 11:37:31 by ThierryFrey

Additions:
The main idea to keep in mind when trying to reduce the rendering time of textures, is that, generally speaking, rendering procedural noises is slow, whereas applying filters is fast. Therefore, in most cases, optimizing the use of FXMaps in a graph will much be more efficient than working on the filters. As a consequence, most of this document will concentrate on either making FXMaps render faster, or reducing their number.
1- The FXMaps' resolution. Bigger maps entail increased computation time. Generate maps of various sizes and select the smallest which will provide adequate quality.
As previously indicated, try to use pre-optimized FXMaps as often as possible.
For example if you do a 1k*1k texture using a 256*256 noise to not hesitate to make it tiled by using the "Scale" option to get a higher level of details.
However to get a texture which will tile only use a scale factor which is a multiple of 100%, i.e. 200%, 300%, etc.
So if you need a brick wall fo a large texture, make a few bricks that you will tile.


Deletions:
The main idea to keep in mind when trying to reduce the rendering time of textures, is that usually rendering procedural noises is slow, whereas applying filters is fast. Therefore, in most cases, optimizing the use of FXMaps in a graph will much be more efficient than working on the filters. As a consequence, most of this document will concentrate on either making FXMaps render faster, or reduce their number.
1- The FXMaps' resolution. The larger the resulting images, the more there is to draw. Therefore the resolution of an FXMap has a huge impact on its computation time.
First as said earlier, use as often as possible pre-optimized FXMaps.
For example if you do a 1k*1k texture using a 256*256 noise to not hesitate to make it tiling by using the "Scale" option to get a higher level od details.
However to get a texture which will tile only use multiple of 100%.
So if you need a brick wall fo a large texture, only do some bricks and make them tiling.




Edited on 2006-11-28 09:50:51 by ChristopheSoum

Additions:
Shared ressources
External Links nodes


Deletions:
Shared ressources
External Links nodes




Edited on 2006-11-28 09:50:30 by ChristopheSoum

Additions:
Then if you want to re-use a part of your CompositingGraph from a texture done earlier, create ExternalLinks in your new texture by right clicking in your graph and select the "Add External Links..." option, then the library dialog box will be displayed: open a file and select the ressources that you need in a list of available SharedRessources in this file.
Shared ressources
This operation creates ExternalLinks nodes to selected SharedRessources in your compositing graph.
External Links nodes
Common SharedRessources will be computed only once for multiple textures.


Deletions:
Then if you want to re-use a part of your CompositingGraph from a texture done earlier, create ExternalLinks in your new texture by right clicking in your graph and select the "Add External Links..." option, then the library dialog box will be displayed: open a file and select the ressources that you need in a list of available SharedRessources in this file. This operation creates ExternalLinks nodes to selected SharedRessources in your compositing graph. Common SharedRessources will be computed only once for multiple textures.



Edited on 2006-11-28 09:36:28 by ChristopheSoum [New ExternalLinks / SharedRessources system]

Additions:
Then if you want to re-use a part of your CompositingGraph from a texture done earlier, create ExternalLinks in your new texture by right clicking in your graph and select the "Add External Links..." option, then the library dialog box will be displayed: open a file and select the ressources that you need in a list of available SharedRessources in this file. This operation creates ExternalLinks nodes to selected SharedRessources in your compositing graph. Common SharedRessources will be computed only once for multiple textures.

Deletions:
Then if you want to re-use a part of your CompositingGraph from a texture done earlier, import it in your new texture by right clicking in your graph and select the "Import" option, then two options will be available: "make reference" and "duplicate", if you chose the first one ("make reference"), the part of the graph re-used will be computed only once for the two textures.



Edited on 2006-10-26 18:01:48 by NicoWirrmann

Additions:
- Whenever possible, replace a "Hue Saturation Lum. Shift" filter with a "Colorize+Blend" filter.
- To get a faster Uniform Blur, set up a filter in a lower resolution and then set the next filter in the resolution you want, so the former one will be blured due to interpolation.
- Similarly the Motion Blur filter can be replaced by the use of non-square texture as an input to filters with a square output. The input texture will be stretched and you will get a result similar to a Motion Blur.
- Prefer using a Mix than using some Colorize filters converted to a FX Filter To FXMap.


Deletions:
- Whenever possible, replace a "HLS" filter with a "Colorize Map (blending mode)" filter.
- To get a faster uniform blur, set up a filter in a lower resolution and then set the next filter in the resolution you want, so the former one will be blured due to interpolation.
- Similarly the uniform motion blur filter can be replaced by the use of non-square texture as an input to filters with a square output. The input texture will be stretched and you will get a result similar to a uniform motion blur.
- Prefer using a mix than using some "Colorize Map" filters converted to a FX Filter To FXMap.




Edited on 2006-10-26 17:58:49 by NicoWirrmann

No differences.


Edited on 2006-10-26 17:58:17 by NicoWirrmann

Additions:
- Colorize, Colorize+Blend, Alpha, Uniform Luminosity/Contrast and Uniform Color are the fastest filters do not hesitate to use them.
- DirectionalWarp, Mix and Uniform Mix are a bit slower but really fast too.
- Warp, Emboss,Normal Map and Warp+Emboss are a bit slower. But globally all these filter are fast.
- Hue Saturation Lum. Shift and Uniform Hue Saturation Lum. which are a bit slower than the filters seen before.
- Motion Blur which is even slower than the "HSL" filters but faster than:
- Uniform Blur and Blur which are the slowest filters.


Deletions:
- "Colorize MaP", "Colorize MaP (Blending Mode)", "Alpha", "Uniform Luminosity/Contrast" and "Uniform Color" are the fastest filters do not hesitate to use them.
- "Directional Warp", "Mix" and "Uniform Mix" are a bit slower but really fast too.
- "Warp", "Emboss", "Normal" and "Warp+Emboss" are a bit slower. But globally all these filter are fast.
- "HSL" and "Uniform HSL" which are a bit slower than the filters seen before.
- "Motion Blur" which is even slower than the "HSL" filters but faster than:
- "Uniform Blur" and "Blur" which are the slowest filters.




Edited on 2006-10-25 12:51:48 by NicoWirrmann

No differences.


Edited on 2006-09-27 12:48:59 by GillesFleury

Additions:
If you do your own FXMaps, do not hesitate to re-use them, they will be computed only once for all the textures wich use them.
Then if you want to re-use a part of your CompositingGraph from a texture done earlier, import it in your new texture by right clicking in your graph and select the "Import" option, then two options will be available: "make reference" and "duplicate", if you chose the first one ("make reference"), the part of the graph re-used will be computed only once for the two textures.
However to get these optimisation working well you will need to merge all the texture of a level in a single .pfx file. To do that use the Export/Merge tool as described here: ExportingTextures
Do not hesitate to use the transformations ("Tranform" option just under the Compositing Graph).
For example if you do a 1k*1k texture using a 256*256 noise to not hesitate to make it tiling by using the "Scale" option to get a higher level od details.
However to get a texture which will tile only use multiple of 100%.
If you want a variation of a specific FXMap noise


Deletions:
If you do your own FXMaps, do not hesitate to reuse them, they will be computed only once for all the textures wich use them.
Then if you want to re-use a part of your CompositingGraph from a texture done earlier, import it in your new texture by right clicking in your graph and select the "Import" option, then two options will be available: "make reference" and "duplicate", if you chose the first one, the part of the graph re-used will be computed only once for the two textures.
However to get these optimisation working well you will need to merge all the texture of a level in a single .pfx file. To do that use the Export/Merge tool as descibed here: ExportingTextures
Do not hesitate to use the transformation ("Tranform" option just under the Compositing Graph).
For example if you do a 1k*1k texture using a 256*256 noise to not hesitate to make it tiling by using the "Scale" option. However to get a texture which will tile only use multiple of 100%.




Edited on 2006-09-27 12:40:17 by GillesFleury

Additions:
First as said earlier, use as often as possible pre-optimized FXMaps.
If you do your own FXMaps, do not hesitate to reuse them, they will be computed only once for all the textures wich use them.
Then if you want to re-use a part of your CompositingGraph from a texture done earlier, import it in your new texture by right clicking in your graph and select the "Import" option, then two options will be available: "make reference" and "duplicate", if you chose the first one, the part of the graph re-used will be computed only once for the two textures.
However to get these optimisation working well you will need to merge all the texture of a level in a single .pfx file. To do that use the Export/Merge tool as descibed here: ExportingTextures
Do not hesitate to use the transformation ("Tranform" option just under the Compositing Graph).
For example if you do a 1k*1k texture using a 256*256 noise to not hesitate to make it tiling by using the "Scale" option. However to get a texture which will tile only use multiple of 100%.
So if you need a brick wall fo a large texture, only do some bricks and make them tiling.


Deletions:
~& Here we need a bit of text about sharing FXMaps between textures used in the same shader, and also the same game level. We should explain why doing it (it's much faster to render and to design textures) and how to do it (i.e. using references, and merging all textures of a given game level in a single file).
1- The FXMaps' resolution. The larger the resulting images, the more there is to draw. Therefore the resolution of an FXMap has a huge impact on its computation time.
2- The bouding box size. The patterns' bouding box size matters just as much as the map resolution. Try reducing them as much as possible, while keeping them larger than the patterns they contain. So reduce them until you start seeing artefacts (vertical or horizontal discontinuities) on your map.
3- The Level of Detail. Try to not specify a level of detail larger than 7.
Please note that on the left hand side of the MaPZone2 editor window you can find a set of pre-optimized FXMaps. As we'll see in the next section, re-using FXMaps is also a key for shorter computations. We recommend to use them as often as possible.
If you need to create your own optimized FXMaps, you can also assign them a specific ID (right click on the FXMap) and re-use them in other textures.


Deletions:
There are three major things about individual FXMap optimization:
1- The FXMaps resolution. Resolution of a FXMap have a huge impact on its computation time.
2- The bouding box size. Decreasing the bouding box size as much as possible in function of the map's patterns size has a large impact too on computation time. So reduce it until you start seeing artefacts (vertical or horizontal discontinuities) on your map.
3- The Level of Detail. Try to not specify a Level Of Detail larger than 7.
Please note that on the left hand side of the MaPZone2 editor window you can find a set of pre-optimized FXMaps. As we'll see in the next section, re-using FXMaps is also a key for shorter computations we recommend to use them as much as often as possible.
If you need to create your own FXMaps, you can still assign it a specific ID (right click on the FXMap) and re-use it in other textures.




Edited on 2006-09-15 13:57:45 by GillesFleury

Additions:
1- The FXMaps resolution. Resolution of a FXMap have a huge impact on its computation time.
2- The bouding box size. Decreasing the bouding box size as much as possible in function of the map's patterns size has a large impact too on computation time. So reduce it until you start seeing artefacts (vertical or horizontal discontinuities) on your map.
3- The Level of Detail. Try to not specify a Level Of Detail larger than 7.
- "Colorize MaP", "Colorize MaP (Blending Mode)", "Alpha", "Uniform Luminosity/Contrast" and "Uniform Color" are the fastest filters do not hesitate to use them.
- "Directional Warp", "Mix" and "Uniform Mix" are a bit slower but really fast too.
- "Warp", "Emboss", "Normal" and "Warp+Emboss" are a bit slower. But globally all these filter are fast.
Then come some slower filters to use sparingly:
- "HSL" and "Uniform HSL" which are a bit slower than the filters seen before.
- "Motion Blur" which is even slower than the "HSL" filters but faster than:
- "Uniform Blur" and "Blur" which are the slowest filters.


Deletions:
1- The FXMaps resolution. Resolution of a FXMap have a huge impact on its computation time.
2- The bouding box size. Decreasing the bouding box size as much as possible in function of the map's patterns size has a large impact too on computation time. So reduce it until you start seeing artefacts (vertical or horizontal discontinuities) on your map.
3- The Level of Detail. Try to not specify a Level Of Detail larger than 7.
- "Colorize MaP", "Colorize MaP (Blending Mode)", "Alpha" "Uniform Luminosity/Contrast" and "Uniform Color" are the fastest filters do not hesitate to use them.
- "Directional Warp", "Mix" and "Uniform Mix" are a bit slower but really fast too.
- "Warp", "Emboss", "Normal" and "Warp+Emboss" are a bit slower. But globally all these filter are fast.
Then come some slower filters to use sparingly:
- "HSL" and "Uniform HSL" which are a bit slower than the filters seen before.
- "Motion Blur" which is even slower then the "HSL" filters but faster than:
- "Uniform Blur" and "Blur" which are the slowest filters.




Edited on 2006-09-13 13:19:01 by WikiAdmin

Additions:
Then come some slower filters to use sparingly:

Deletions:
Then come some slower filter to use sparingly:



Edited on 2006-09-13 13:18:44 by WikiAdmin

Additions:
- To get a faster uniform blur, set up a filter in a lower resolution and then set the next filter in the resolution you want, so the former one will be blured due to interpolation.
- Similarly the uniform motion blur filter can be replaced by the use of non-square texture as an input to filters with a square output. The input texture will be stretched and you will get a result similar to a uniform motion blur.
- Prefer using a mix than using some "Colorize Map" filters converted to a FX Filter To FXMap.
- When working e.g. on a 1024*1024 texture try to make the smoother noises in 512*512. Then at the end of the CompositingGraph add the higher frequency noise filters in 1024*1024 to take care of the small scale details.
- And of course the less boxes used in your graph the faster it will be
Regarding the relative speed of filters:
- "Colorize MaP", "Colorize MaP (Blending Mode)", "Alpha" "Uniform Luminosity/Contrast" and "Uniform Color" are the fastest filters do not hesitate to use them.
- "Directional Warp", "Mix" and "Uniform Mix" are a bit slower but really fast too.
- "Warp", "Emboss", "Normal" and "Warp+Emboss" are a bit slower. But globally all these filter are fast.
Then come some slower filter to use sparingly:
- "HSL" and "Uniform HSL" which are a bit slower than the filters seen before.
- "Motion Blur" which is even slower then the "HSL" filters but faster than:
- "Uniform Blur" and "Blur" which are the slowest filters.
Regarding ImportingSvgs remember that these filters rendering speed and the size of their result depend on the precision you specify when you import the file. Usually it is faster to draw a simple shape with an FXMap than with vector file (and the resulting file will be smaller too).


Deletions:
~&
- To get a faster uniform blur, set up a filter in lower resolution and then set the next filter in the resolution you want, so the former one will be blured due to interpolation.
- If a uniform motion blur can satisfy you, use non square texture in square filters so the texture will be stretched and you will get the same result than a uniform motion blur.
- Globally prefer a mix than some "Colorize Map" filters converted to a FX Filter To FXMap.
- For exemple if you work on a 1024*1024 texture try to work in 512*512 for the smooth noises and then at the end of the CompositingGraph add the High Frequency noise filters in 1024*1024
- And of course the less boxes you will have to get a result the better it will be
Globally about the filters remember that:
"Colorize MaP", "Colorize MaP (Blending Mode)", "Alpha" "Uniform Luminosity/Contrast" and "Uniform Color" are the fastest filters do not hesitate to use them.
"Directional Warp", "Mix" and "Uniform Mix" are a bit slower but really fast too.
"Warp", "Emboss", "Normal" and "Warp+Emboss" are a bit slower. But globally all these filter are fast.
Then come some slower filter to use sparingly.
"HSL" and "Uniform HSL" which are a bit slower than the filters seen before.
"Motion Blur" which is even slower then the "HSL" filters but faster than:
"Uniform Blur, "Blur" which are the slowest filter.
About ImportingSvgs remember than these filters speed and size are totally dependant of the precision you specify when you import the file, but globally if you can do something with a FXMap instead of a vector file do it this way.




Edited on 2006-09-13 12:59:47 by WikiAdmin

Additions:
1- The FXMaps resolution. Resolution of a FXMap have a huge impact on its computation time.
2- The bouding box size. Decreasing the bouding box size as much as possible in function of the map's patterns size has a large impact too on computation time. So reduce it until you start seeing artefacts (vertical or horizontal discontinuities) on your map.
3- The Level of Detail. Try to not specify a Level Of Detail larger than 7.
Please note that on the left hand side of the MaPZone2 editor window you can find a set of pre-optimized FXMaps. As we'll see in the next section, re-using FXMaps is also a key for shorter computations we recommend to use them as much as often as possible.
If you need to create your own FXMaps, you can still assign it a specific ID (right click on the FXMap) and re-use it in other textures.
- Whenever possible, replace a "HLS" filter with a "Colorize Map (blending mode)" filter.
- To get a faster uniform blur, set up a filter in lower resolution and then set the next filter in the resolution you want, so the former one will be blured due to interpolation.
- If a uniform motion blur can satisfy you, use non square texture in square filters so the texture will be stretched and you will get the same result than a uniform motion blur.
- Globally prefer a mix than some "Colorize Map" filters converted to a FX Filter To FXMap.
- For exemple if you work on a 1024*1024 texture try to work in 512*512 for the smooth noises and then at the end of the CompositingGraph add the High Frequency noise filters in 1024*1024
- And of course the less boxes you will have to get a result the better it will be


Deletions:
1- The FXMaps resolution. Resolution of a FXMap have a huge inpact on its computation time.
2- The bouding box size. Decreasing the bouding box size as much as possible in fonction of the map's patterns size have a huge inpact too on computation time. So decrease it until you start to see artefacts on your map.
3- The Level of Detail. Try to not specify a Level Of Detail superior to 7.
However on the left of MaPZone2 window you will get pre-optimized FXMaps, and since re-use of the FXMaps is a key for short computation time we recommend to use them ase much as possible.
Althought if you create your own FXMaps assign it a specific ID (right click on the FXMap) and to re-use it in other textures.
Any time you can replace a "HLS" filter by a "Colorize Map (blending mode)" filter do it.
To get a faster uniform blur, set up a filter in lower resolution and then set the next filter in the resolution you want, so the precedent one will be blured due to interpolation.
If a uniform motion blur can satisfy you, use non square texture in square filters so the texture will be stretched and you will get the same result than a uniform motion blur.
Globally prefer a mix than some "Colorize Map" filters converted to a FX Filter To FXMap.
For exemple if you work on a 1024*1024 texture try to work in 512*512 for the smooth noises and then at the end of the CompositingGraph add the High Frequency noise filters in 1024*1024
And of course the less boxes you will have to get a result the better it will be




Edited on 2006-09-13 12:29:59 by GillesFleury

Additions:
2- The bouding box size. Decreasing the bouding box size as much as possible in fonction of the map's patterns size have a huge inpact too on computation time. So decrease it until you start to see artefacts on your map.
3- The Level of Detail. Try to not specify a Level Of Detail superior to 7.
Althought if you create your own FXMaps assign it a specific ID (right click on the FXMap) and to re-use it in other textures.


Deletions:
2- The bouding box size. Decreasing the bouding box size as much as possible in fonction of the map's patterns size have a huge inpact too on computation time. So decrease it until you start to see artefacts on your map.try to not specify a Level Of Detail superior to 7.
Althought if you create your own FXMaps assign them a specific ID (right click on the FXMap) and to re-use it in other textures.




Edited on 2006-09-13 12:26:37 by GillesFleury

Additions:
"Colorize MaP", "Colorize MaP (Blending Mode)", "Alpha" "Uniform Luminosity/Contrast" and "Uniform Color" are the fastest filters do not hesitate to use them.
About ImportingSvgs remember than these filters speed and size are totally dependant of the precision you specify when you import the file, but globally if you can do something with a FXMap instead of a vector file do it this way.


Deletions:
"Colorize MaP", "Colorize MaP (Blending Mode)", "Alpha" "Uniform Luminosity/Contrast" and "Uniform Color" are the fastest filters do not hesitate to use them.
SVG taille et gourmandise en fonction complexité




Edited on 2006-09-13 12:20:36 by GillesFleury

Additions:
Any time you can replace a "HLS" filter by a "Colorize Map (blending mode)" filter do it.
To get a faster uniform blur, set up a filter in lower resolution and then set the next filter in the resolution you want, so the precedent one will be blured due to interpolation.
If a uniform motion blur can satisfy you, use non square texture in square filters so the texture will be stretched and you will get the same result than a uniform motion blur.
Globally prefer a mix than some "Colorize Map" filters converted to a FX Filter To FXMap.
For exemple if you work on a 1024*1024 texture try to work in 512*512 for the smooth noises and then at the end of the CompositingGraph add the High Frequency noise filters in 1024*1024
And of course the less boxes you will have to get a result the better it will be
Globally about the filters remember that:
"Colorize MaP", "Colorize MaP (Blending Mode)", "Alpha" "Uniform Luminosity/Contrast" and "Uniform Color" are the fastest filters do not hesitate to use them.
"Directional Warp", "Mix" and "Uniform Mix" are a bit slower but really fast too.
"Warp", "Emboss", "Normal" and "Warp+Emboss" are a bit slower. But globally all these filter are fast.
Then come some slower filter to use sparingly.
"HSL" and "Uniform HSL" which are a bit slower than the filters seen before.
"Motion Blur" which is even slower then the "HSL" filters but faster than:
"Uniform Blur, "Blur" which are the slowest filter.
SVG taille et gourmandise en fonction complexité


Deletions:
~& Here we can put all tips that don't address FXMaps, e.g. about expensive filters like the non-uniform blur, or about SVGs.



Oldest known version of this page was edited on 2006-09-13 10:38:18 by GillesFleury []
Page view:

Map Optimization






This document describes various techniques to reduce the rendering times of textures in ProFX2. Using these, it is possible to render hundreds of textures in a few seconds. It is therefore very important for artists working on textures for a computer game to read and understand this document, in particular the section about sharing and reusing FXMaps.




I. Understanding the basics


The main idea to keep in mind when trying to reduce the rendering time of textures, is that usually rendering procedural noises is slow, whereas applying filters is fast. Therefore, in most cases, optimizing the use of FXMaps in a graph will much be more efficient than working on the filters. As a consequence, most of this document will concentrate on either making FXMaps render faster, or reduce their number.

In the next section, we will review what settings have the most influence on FXMaps rendering times.



II. Optimizing individual FXMaps


There are three major things about individual FXMap optimization:
1- The FXMaps resolution. Resolution of a FXMap have a huge inpact on its computation time.
2- The bouding box size. Decreasing the bouding box size as much as possible in fonction of the map's patterns size have a huge inpact too on computation time. So decrease it until you start to see artefacts on your map.try to not specify a Level Of Detail superior to 7.
Compositing Graph

However on the left of MaPZone2 window you will get pre-optimized FXMaps, and since re-use of the FXMaps is a key for short computation time we recommend to use them ase much as possible.
Althought if you create your own FXMaps assign them a specific ID (right click on the FXMap) and to re-use it in other textures.



III. Computing less FXMaps


A. Sharing and reusing FXMaps



B. Using transforms





IV. Other possible optimizations






Category:
CategoryGraphism
Page was generated in 0.6064 seconds