Some months ago, César David sent me an email about Eagle3D, a sort of plugin for the circuit board design package Eagle. This plugin turns any board into a POV-Ray scene, using parts from a 3D library of POV-Ray objects. Additionally, this library can be expanded, and César wanted to know if I will be able to help rewriting the parts from an old scene of mine, to add them to the Eagle3D library.
It could be done, but as I downloaded and played with Eagle & Eagle3D (via Wine on Linux), I found the library from Eagle3D was actually vast and very detailed, with real electronic parts. The parts from my old scene were not real, just invented, and it wouldn’t make any sense to try to add them to the library.
Anyhow, while playing with Eagle3D I noticed that the default POV-Ray scene generated could be enhanced greatly with better textures and lighting… so, as I’m not an engineer, I just used the example scene included with Eagle (hexapod), to enhance the textures and lighting. The last was easy: I deleted all the lights and placed there a sphere with an HDRI map. Textures were more difficult, as they are scattered within the include files for each part.
Tutorial
After publishing these images, some Eagle3D users asked me to explain more about my changes to the code, so I did a little tutorial and asked Matthias Weisser for permission to publish the changes, which you can download on the link at the top of the page. Please, note it’s not a replacement for Eagle3D: I included just the files I needed to change while enhancing the modsmega.pov scene.
As I’m not a regular user of Eagle, I can’t give any advice about using it with Eagle3D. In fact, as I was not able to use it under Linux/Wine due to some problems with fonts, I had to use the included example scenes in POV format. So, I will supose you already exported your PCB with Eagle using Eagle3D ULP, and saved it into a folder for this project.
First, note I used MegaPOV 1.2.1 for this experiment, not the official POV-Ray 3.6, as I wanted to use HDRI for the lighting. The code generated by Eagle3D works mostly with MegaPOV, except for a little detail: the variable environment conflicts with an internal identifier and gives an error, so you will have to change the name for something else, like environment2 for example.
Then, to simplify the process, I suggest copying the include files from the /povray folder from the Egale3D installation, into the project folder: at the end, if we are satisfied, we can replace back the original files for future use. If you prefer to modify the original files directly, remember to add the path to your povray.ini file with a Library_Path sentence (and surely you will have to do the same with the path to the required fonts).
Well, let’s start with the real stuff… open the pov file exported by Eagle3D and switch off the enviroment:
1 | #declare environment=0; |
Also, get rid of the default background by deleting the line:
1 | background{col_bgr} |
as we are going to use an spherical HDRI to light up the scene and provide reflections. For effect, we will add a wooden table top: copy and paste the following code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 | //======================================================== #version unofficial MegaPov 1.21; // radiosity control #declare use_radiosity= 2; // 1=load, 2=save, 0=off #declare rad_quality= 1; // 1-10 (1=very basic ... 10=very good) #declare rad_bounces= 1; // >0 (more of 5 hardly makes a difference) #declare rad_brightness=1; // increase if needed global_settings { assumed_gamma 1.9 #if (use_radiosity) radiosity { // don't touch these settings, use the control variables above #declare rad_count=rad_quality; #if (use_radiosity=2) // saving radiosity pretrace_start 0.05 pretrace_end 0.005 count 160*rad_count nearest_count 10+rad_quality error_bound 0.5/rad_quality recursion_limit rad_bounces brightness rad_brightness save_file "saved.rad" #else // loading radiosity load_file "saved.rad" pretrace_start 1 pretrace_end 1 count 160*rad_count nearest_count 10+rad_quality error_bound 0.5/rad_quality recursion_limit rad_bounces always_sample off brightness rad_brightness #end gray_threshold .5 randomize on // only if you are using MegaPOV } #end } // default finish for all textures: #default{texture{finish{ambient 0 diffuse 1 conserve_energy}}} // HDRI environment sphere{ 0,500 texture{ pigment{image_map{hdr "kitchen_probe" map_type 7 interpolate 2}} finish{ambient .5 diffuse 0} rotate 90*y } } // wood table plane{y,-3 texture{ pigment{image_map{jpeg "oakdoor.jpg"}} // use any jpg of your choice normal{bump_map{jpeg "oakdoor.jpg"}} finish{reflection{0,.1}} translate -.5 rotate <90,90,0> scale <10,10,5>*30 } } //======================================================== |
but be sure to put it before the line:
1 | #include "tools.inc" |
The HDRI map I used is the classic kitchen probe by Paul Debevec, and the wood texture is a free image from Accustudio.
Next is to delete the lights from the scene: search for the lines with
1 | light_source |
and delete them (or coment them out with //). The only thing left now is to enhance the textures, which is simple but laborious. The biggest problem is knowing which files contain the textures used by the components on the board.
Some common textures are located in tools.inc, but the most specific to each component are on the same macro creating the object, so it has to be identified and located on the corresponding include file (cap.inc, diode.inc, resistor.inc, etc..). The ideal situation would be to have a centralized file for textures, where the authors of the parts can add their texture definitions, and users can change them easily. IMHO, the textures should never be defined inside the macros using them, but passed as a parameter or predeclared somewhere else.
Going back to the textures, the problem with most of them is that they don’t have a
1 | finish{} |
and consist basically on a simple pigment. We are going to add finishes depending on the surface type. Start by changing the following textures on tools.inc:
1 | #declare col_silver = texture {T_Chrome_3C finish{ambient 0}}; |
There are more default textures in tools.inc, but only a set is used depending on the value of the col_preset switch. In my case, using the modsmega scene, the value was 2, so I substituted the textures of the second case with:
1 2 3 4 5 6 7 8 | #declare col_brd = texture{pigment{rgb<0.117647,0.243137,0.015686>} finish{reflection{.05,.2} ambient 0}} //Farbe der Platine #declare col_wrs = texture{pigment{rgb<0.368627,0.352941,0.054902>} finish{reflection{.05,.2} ambient 0}} //Farbe der Leiterbahnen #declare col_pds = texture{pigment{Gray70} finish{F_MetalB ambient 0}} //Farbe der Pad's und SMD's #declare col_hls = texture{pigment{Black} finish{ambient 0}} //Farbe der Pseudobohrungen #declare col_bgr = Gray50; //Hintergrundfarbe wenn keine Umgebung aktiviert #declare col_slk = texture{pigment{White} finish{ambient 0}} //Farbe des Best�ckungsdruck #declare col_thl = texture{pigment{Gray70} finish{F_MetalB ambient 0}} //Farbe der Durchkontaktierungen #declare col_pol = col_wrs //Farbe der Polygone |
From here on, you will have to chase the textures used by the components of your board, on the corresponding include file. Look in my source files to see my changes to the textures used by the parts on the modsmega board… basically, add variable reflection where it’s needed, remember to set ambient to 0, and try to desaturate a bit the colors so they don’t look too standard.