What is easySunflow?
easySunflow is an user interface, to simplify the creating of scenes for Sunflow Render engine.
This software is written in Processing using the Sunflow API, is based on a simplified version of the java library SunflowAPIAPI and others, with custom functions to manage the rendering and the scenes.
I added commands to import the mesh from the library TOXILIBS with the possibility to use the powerful class from TOXILIBS Phisics. It is possible to use HEMESH library, with full use of primitives and modifiers.
You can load external geometries using the Sunflow parser or the OBJLoader library, this is Wavefront .OBJ file loader for Processing, while for the stl models you can use TOXILIBS STLLoader.
Also i added a timeline with the possibility to animate many properties of objects and the camera, for every object you can create an Animator to manage keyframes. The new interface controls most of the necessary parameters to Sunflow, the camera position, the lights and quality of rendering and various types of global illumination. Using the new commands implemented in easysunflow, you can create very complex scenes in a short time.
Features
in this video we can discover many new features of easySunflow 2.0
Tutorials
There are three tutorials on using easysunflow
Source Code
The following examples illustrate just some of the uses of the new classes of easySunflow 2.0
-
//------------------------------------------------------------------ // PRIMITIVES //------------------------------------------------------------------ // set sun position guiSunPosition(-150,30); // shader diffuse ShaderDiffuse diffuse_white =new ShaderDiffuse("diffuse_white", new SunflowColor(.9, .9, .9)); ESF.addShader(diffuse_white); // shader shine ShaderShine shaderground=new ShaderShine("shaderground",new SunflowColor(.1, .1, .1),.1); ESF.addShader(shaderground); // sphere parameters Sphere thesphere= new Sphere(); thesphere.setSize(50); thesphere.setPosition(-300,50,0); thesphere.setShader(diffuse_white); ESF.addGeometry("thesphere", thesphere); //cube parameters Cube thecube= new Cube(); thecube.setSize(50); thecube.setPosition(-100,50,0); thecube.setShader(diffuse_white); ESF.addGeometry("thecube",thecube); // cylinder parameters Cylinder thecylinder=new Cylinder(); thecylinder.setSize(50); thecylinder.setPosition(100,50,0); thecylinder.setRotation(90,0,0); thecylinder.setShader(diffuse_white); ESF.addGeometry("thecylinder",thecylinder); //torus parameters Torus thetorus=new Torus(); thetorus.setSize(50); thetorus.setPosition(300,60,0); thetorus.setShader(diffuse_white); ESF.addGeometry("thetorus",thetorus); //ground parameters Ground ground=new Ground(); ground.setShader(shaderground); ESF.addGeometry("ground", ground); -
//------------------------------------------------------------------ // LIGHTS //------------------------------------------------------------------ // disable sun light guiSetSunVisible(false); // SpericalLight SpericalLight spherical=new SpericalLight("sperical",new PVector(-300,100,-200)); spherical.setColor(color(200,200,200)); spherical.setPower(5); spherical.setSize(60); ESF.addLight(spherical); // PointLight PointLight pointLight=new PointLight("pointLight",new PVector(300,100,-200)); pointLight.setPower(200); ESF.addLight(pointLight); // Spotlight Spotlight spotlight=new Spotlight("spotlight",new PVector(0,200,100),new PVector(0,0,-450)); spotlight.setPower(5); spotlight.setRadius(300); ESF.addLight(spotlight); // shader diffuse ShaderDiffuse shaderground =new ShaderDiffuse("shaderground", new SunflowColor(.8, .8, .8)); ESF.addShader(shaderground); //cube parameters Cube room= new Cube(); room.setSize(500); room.setPosition(0,500,0); room.setShader(shaderground); ESF.addGeometry("room",room); ShaderDiffuse shadersphere =new ShaderDiffuse("shadersphere", new SunflowColor(1, 0, 0)); ESF.addShader(shadersphere); // sphere parameters Sphere thesphere= new Sphere(); thesphere.setSize(50); thesphere.setPosition(-100,50,0); thesphere.setShader(shadersphere); ESF.addGeometry("thesphere", thesphere); -
//------------------------------------------------------------------ // COLORS //------------------------------------------------------------------ int radius=300; int spherenum=16; float step=TWO_PI/spherenum; for(int i=0;i
-
//------------------------------------------------------------------ // SHADERS //------------------------------------------------------------------ // set camera parameters ESF.setCamera(new float[]{-235.33,-288.22,507.12,-235.00,-287.78,506.28,-0.18,0.90,0.39,60.0}); // ground shader ShaderDiffuse shaderground =new ShaderDiffuse("shaderground", new SunflowColor(.4, .4, .45)); ESF.addShader(shaderground); //add ground Ground ground=new Ground(); ground.setShader(shaderground); ESF.addGeometry("ground", ground); ShaderDiffuse diffuse_neutral = new ShaderDiffuse("diffuse_neutral", new SunflowColor(.95, .95, .95)); ESF.addShader(diffuse_neutral); // sphere diffuse Sphere sphere1= new Sphere(new PVector(-270,50,0)); sphere1.setSize(50); sphere1.setShader(diffuse_neutral); ESF.addGeometry("sphere1", sphere1); ShaderMirror mirror_neutral=new ShaderMirror("mirror_neutral", new SunflowColor(0.6, 0.6, 0.6)); ESF.addShader(mirror_neutral); // sphere mirror Sphere sphere2= new Sphere(new PVector(-120,50,0)); sphere2.setSize(50); sphere2.setShader(mirror_neutral); ESF.addGeometry("sphere2", sphere2); ShaderShine shiny_neutral = new ShaderShine("shiny_neutral", new SunflowColor(0.5, 0.5, 0.5), .5); ESF.addShader(shiny_neutral); // sphere shiny Sphere sphere3= new Sphere(new PVector(0,50,0)); sphere3.setSize(50); sphere3.setShader(shiny_neutral); ESF.addGeometry("sphere3", sphere3); ShaderGlass glass_neutral = new ShaderGlass("glass_neutral", new SunflowColor(.7, .7, .7), 3.1); ESF.addShader(glass_neutral); // sphere glass Sphere sphere4= new Sphere(new PVector(120,50,0)); sphere4.setSize(50); sphere4.setShader(glass_neutral); ESF.addGeometry("sphere4", sphere4); ShaderPhong phong_neutral=new ShaderPhong("phong_neutral", new SunflowColor(.5, .5, .5), new SunflowColor(1, 1, 1), 1, 1); ESF.addShader(phong_neutral); // sphere phong Sphere sphere5= new Sphere(new PVector(270,50,0)); sphere5.setSize(50); sphere5.setShader(phong_neutral); ESF.addGeometry("sphere5", sphere5); -
//------------------------------------------------------------------ // ANIMATORS & TIMELINE //------------------------------------------------------------------ // ground shader ShaderShine shaderground = new ShaderShine("shaderground", new SunflowColor(0.5, 0.5, 0.5), .5); ESF.addShader(shaderground); //ground parameters Ground ground=new Ground(); ground.setShader(shaderground); ESF.addGeometry("ground", ground); // FileGeometry use Sunflow standard parser FileGeometry model=new FileGeometry("examples/models/topmod1.obj",false); ESF.addGeometry("external_obj",model); model.setPosition(0,100,0); model.setSize(50); // add light SpericalLight sp=new SpericalLight("Sperical",new PVector(-300,50,200)); sp.setColor(color(200,200,200)); sp.setPower(10); sp.setSize(50); ESF.addLight(sp); //------------------------------------------------------------------ // some animators in action //------------------------------------------------------------------ // set the sun position guiSunPosition(-30,-10); // sun animator Animator animsun=new Animator( ESF.thesun,"setLatitude"); animsun.addKeyFrame(0,-10f); animsun.addKeyFrame(timeline.getEnd()/2,-20f); animsun.Dump(); // animator for model position Animator animpos=new Animator(model,"setPosition"); animpos.addKeyFrame(0, new PVector(-300,100,0)); animpos.addKeyFrame(timeline.getEnd()/2,new PVector(0,200,0)); animpos.addKeyFrame(timeline.getEnd(), new PVector(300,100,0)); // model rotation Animator animarot=new Animator(model,"setRotation"); animarot.addKeyFrame(0, new PVector(0,0,0)); animarot.addKeyFrame(timeline.getEnd(), new PVector(0,180,0)); // animator for light color Animator animalc=new Animator(sp,"setColor"); animalc.addKeyFrame(0, new SunflowColor (color(200,0,0))); animalc.addKeyFrame(timeline.getEnd()/2,new SunflowColor (color(0,200,0))); animalc.addKeyFrame(timeline.getEnd(), new SunflowColor (color(200,200,200))); animalc.setInterpolationType(animpos.LINEAR_INTERPOLATION); // animator with custom listener for movement Animator animsp=new Animator(this,"SpericalLightListener"); animsp.addKeyFrame(0, 0f); animsp.addKeyFrame(timeline.getEnd(), 1f); // add animators to timeline timeline.addAnimator(animsun); timeline.addAnimator(animpos); timeline.addAnimator(animarot); timeline.addAnimator(animalc); timeline.addAnimator(animsp); // set timeline to frame 1 timeline.Stop(); //------------------------------------------------------------------------------ // custom listener void SpericalLightListener(float t) { float a=t*(TWO_PI*4); PVector position=new PVector(-300+600*t, 50+abs(100*sin(a)), 300); sp.setPosition(position); } -
//------------------------------------------------------------------ // CAMERA KEYFRAMES //------------------------------------------------------------------ // sphere parameters Sphere thesphere= new Sphere(); thesphere.setSize(50); thesphere.setPosition(0,50,0); ESF.addGeometry("thesphere", thesphere); // set keyframes for camera ESF.addKeyFrame( new PVector(-155.37,-44.077,2594.277), new PVector(-155.31,-44.093,2593.279), new PVector(-0.0090,1.0,-0.017),60); ESF.addKeyFrame( new PVector(-70.165,-507.827,954.997), new PVector(-70.098,-507.43,954.082), new PVector(-0.02,0.918,0.397),60); ESF.addKeyFrame( new PVector(637.068,-542.27,477.246), new PVector(636.412,-541.727,476.722), new PVector(0.434,0.84,0.327),60); ESF.addKeyFrame( new PVector(397.549,-53.279,-875.667), new PVector(397.113,-53.247,-874.767), new PVector(0.017,1.0,-0.026),60); ESF.addKeyFrame( new PVector(-60.33,-259.086,-3207.984), new PVector(-60.319,-259.013,-3206.986), new PVector(0.0080,0.997,-0.073),60); // enable camera action guisetActionCamera(true); // set action camera jitter and amplitude guiSetActionCameraParameters(.1,10); -
//------------------------------------------------------------------ // PARTICLES SYSTEM //------------------------------------------------------------------ // shader diffuse ShaderDiffuse shader =new ShaderDiffuse("shader_particles", new SunflowColor(.9, .2, .2)); ESF.addShader(shader); Particles particles=new Particles(new PVector(0,0,0)); particles.setShader(shader); particles.setRadius(1); int np =10000; float res=.005; float radius=300; PVector pos=new PVector(0,0,0); for (int i=0;i -
//------------------------------------------------------------------ // TOXILIBS OBJECT //------------------------------------------------------------------ // add shaders ShaderDiffuse shader =new ShaderDiffuse("diffuse_color", new SunflowColor(.8, .8, .8)); ESF.addShader(shader); ShaderDiffuse groundshader =new ShaderDiffuse("groundshader", new SunflowColor(.3, .1, .1)); ESF.addShader(groundshader); // add ground Ground ground=new Ground(); ground.setShader(groundshader); ESF.addGeometry("ground", ground); //------------------------------------------------------------------ // source code: http://openprocessing.org/sketch/29202 //------------------------------------------------------------------ int VOXEL_RES=50; int VOXEL_STROKE_WEIGHT=5; int SPHERE_RES=50; int SMOOTH_ITER=12; // create a hemi-sphere mesh WETriangleMesh tmp=new WETriangleMesh().addMesh(new toxi.geom.Sphere(150).toMesh(SPHERE_RES)); WETriangleMesh obj=MeshLatticeBuilder.build(tmp, VOXEL_RES, VOXEL_STROKE_WEIGHT); // smooth mesh filter for(int i=0; i -
//------------------------------------------------------------------ // TOXILIBS INSTANCES //------------------------------------------------------------------ // low details guiSetSceneDetails(5); // create shaders ShaderDiffuse shader =new ShaderDiffuse("diffuse_color", new SunflowColor(.8, .8, .8)); ESF.addShader(shader); ShaderDiffuse groundshader =new ShaderDiffuse("groundshader", new SunflowColor(.3, .1, .1)); ESF.addShader(groundshader); ShaderMirror mirror_neutral=new ShaderMirror("mirror_neutral", new SunflowColor(0.6, 0.6, 0.6)); ESF.addShader(mirror_neutral); ShaderPhong phong_neutral=new ShaderPhong("phong_neutral", new SunflowColor(.5, .5, .5), new SunflowColor(1, 1, 1), 1, 1); ESF.addShader(phong_neutral); Ground ground=new Ground(); ground.setShader(groundshader); ESF.addGeometry("ground", ground); // Spherical Harmonics Mesh SurfaceMeshBuilder shape = new SurfaceMeshBuilder(new SphericalHarmonics(new float[]{2,4,6,4,0,6,4,2})); toxi.geom.mesh.TriangleMesh toximesh = (toxi.geom.mesh.TriangleMesh)shape.createMesh(null,60,50); // add toxi to the scene ToxiMesh mesh=new ToxiMesh(); mesh.setMesh(toximesh); mesh.setPosition(0,150,0); mesh.setShader(shader); ESF.addGeometry("toxiobj",mesh); // create instances int n=10; int id=0; for (int z=0;z.5?mirror_neutral:phong_neutral); inst.setSize(caso); inst.setRotation(0,random(180),random(180)); inst.setPosition(x*100,120,z*100); ESF.addGeometry("ins"+id++,inst); } } -
//------------------------------------------------------------------ // TOXILIBS STLReader //------------------------------------------------------------------ // load STL model toxi.geom.mesh.TriangleMesh stl = (toxi.geom.mesh.TriangleMesh)new STLReader().loadBinary(sketchPath("examples/models/giraffa.stl"),STLReader.TRIANGLEMESH); ToxiMesh m=new ToxiMesh(); m.setMesh(stl); m.setPosition(0,0,0); m.setSize(100); m.setRotation(-90,0,0); ESF.addGeometry("toxitest",m); -
//------------------------------------------------------------------ // HEMESH OBJECT //------------------------------------------------------------------ // hemesh creator HEC_Cube cube = new HEC_Cube().setEdge(300).setWidthSegments(1).setHeightSegments(1).setDepthSegments(1); // hemesh modifiers HEM_Lattice lattice = new HEM_Lattice().setDepth(6).setWidth(6); HES_Planar planar = new HES_Planar().setRandom(true).setRange(0.7); HES_Smooth sm = new HES_Smooth(); // add modifiers to mesh HE_Mesh m = new HE_Mesh(cube); m.subdivide( planar, 2 ); m.subdivide( sm, 1); m.modify(lattice); // add hemesh to scene HemeshMesh mesh=new HemeshMesh(m); mesh.setPosition(0,150,0); mesh.setSmooth(false); ESF.addGeometry("hemesh_",mesh); -
//------------------------------------------------------------------ // HEMESH INSTANCES //------------------------------------------------------------------ // shader diffuse ShaderDiffuse shaderground =new ShaderDiffuse("shaderground", new SunflowColor(.2, .2, .2)); ESF.addShader(shaderground); //ground parameters Ground ground=new Ground(); ground.setShader(shaderground); ESF.addGeometry("ground", ground); //------------------------------------------------------------------ // hemesh creator HEC_Cube cube = new HEC_Cube().setEdge(100).setWidthSegments(1).setHeightSegments(1).setDepthSegments(1); //hemesh modifiers HEM_Lattice lattice = new HEM_Lattice().setDepth(2).setWidth(2); HES_Planar planar = new HES_Planar().setRandom(true).setRange(0.7); HES_Smooth sm = new HES_Smooth(); // add modifiers to mesh HE_Mesh m = new HE_Mesh(cube); m.subdivide( planar, 2 ); m.subdivide( sm, 1); m.modify(lattice); //------------------------------------------------------------------ // add emesh to scene HemeshMesh mesh=new HemeshMesh(m); mesh.setPosition(0,60,0); mesh.setSmooth(false); ESF.addGeometry("hemesh_",mesh); ShaderDiffuse shader =new ShaderDiffuse("diffuse", new SunflowColor(.9, .9, .9)); ESF.addShader(shader); int n=3; int id=0; for (int i=0;i<=n;i++) { HemeshInstance item=new HemeshInstance(mesh, shader); item.setPosition(new PVector(0,120+100*i,0)); item.setRotation(new PVector(0,45*i,0)); ESF.addGeometry("hemeshinstance"+id, item); id++; } -
//------------------------------------------------------------------ // HEMESH MODIFIERS ANIMATION //------------------------------------------------------------------ //hemesh creator HEC_Cube cube = new HEC_Cube().setEdge(400).setWidthSegments(4).setHeightSegments(4).setDepthSegments(4); //hemesh modifiers HEM_Lattice lattice = new HEM_Lattice().setDepth(6).setWidth(6); // create dynamic mesh HE_DynamicMesh hm = new HE_DynamicMesh(new HE_Mesh(cube)); // add modifiers and update hm.add(lattice); hm.update(); ShaderDiffuse shader =new ShaderDiffuse("shader", new SunflowColor(.8,.01, .02)); ESF.addShader(shader); HemeshMesh themesh=new HemeshMesh(hm); themesh.setPosition(0,200,0); themesh.setSmooth(false); themesh.setShader(shader); ESF.addGeometry("hemesh_",themesh); // animator for hemesh modifiers Animator animmesh=new Animator(this,"HemeshMeshListener"); animmesh.addKeyFrame(0,0.0); animmesh.addKeyFrame(timeline.getEnd()/2,1.0); animmesh.addKeyFrame(timeline.getEnd(),.5); timeline.addAnimator(animmesh); timeline.Stop(); void HemeshMeshListener(float t){ float a=t*TWO_PI*2; float c=cos(a); float s=sin(a); lattice.setDepth(30+10*c); lattice.setWidth(15+10*s); themesh.update(); } -
//------------------------------------------------------------------ // OBJLOADER EXAMPLE //------------------------------------------------------------------ // disable sun light guiSetSunVisible(false); // custom wire shader // name,fill color,wire color,wire size,samples,distance ShaderWireframeAO wire=new ShaderWireframeAO("wire",new SunflowColor(.9,.9,.9),new SunflowColor(.5,.5,.5),.5,32,200); ESF.addShader(wire); // ObjLoader load model and set the scale to 80 ObjLoader topmod=new ObjLoader("examples/models/topmod2.obj",80); topmod.setShader(wire); topmod.setPosition(0,250,0); // add background Background back=new Background(); back.setColor(40,80,100); ESF.addGeometry("background_",back); -
//------------------------------------------------------------------ // OBJLOADER INSTANCES //------------------------------------------------------------------ // low details guiSetSceneDetails(5); ObjLoader model=new ObjLoader("examples/models/girl.obj",.5); ESF.addGeometry("_model_",model); // create instances int n=10; int m=10; int id=0; for (int y=0;y



































