Welcome to DefBlog!

Welcome


Photon mapping & Spectral rendering with caustics

2010-02-10 12:21:02.0 - [Permalink]   [0 Comments]

Motsvarande såhär ska min räknare se ut snart om jag orkar implementera en photon mapper med caustics med spektralbaserad renderare:
http://www.cc.gatech.edu/~phlosoft/photon/

Lyckas jag med det så ser jag det som att jag skapat avtryck i akvariehistorien, och har något extremt imponerande att visa i min CV.

Lite länksamlande följer.

Opensource projektet Luxrender gör i princip all jag vill göra utom beräknar ett verkligt intensitetsmått på valfri yta:
http://www.luxrender.net/

Opensource projektet Sunflow har photonmapping på plats och är i ren Java men är inte spektralbaserad:
http://sunflow.sourceforge.net/

Sunflow är övergivet och skaparen jobbar på Google med det här intressanta projektet. Vore kul att använda OSL i min räknare:
http://code.google.com/p/openshadinglanguage/

Denna rapport verkar använda tre generalla kurvor för att syntetisera vilket spektrum som helst vilket innebär att dom inte kan härma lysrör speciellet bra, men jävlar vad mycket bra ekvationer det är i den här:
ftp://fas.sfu.ca/pub/cs/TH/2000/YinlongSunPhD.pdf

Den här snubbens bok borde man förmodligen köpa:
http://graphics.stanford.edu/~henrik/papers/

Följande är ganska bra på att förklara photon mapping och en metod för att komprimera spektralfördelningen så att renderaren tar mindre minne, men jag tror faktiskt inte det behövs för min del. Jag ska inte skjuta överdrivet många fotoner eftersom min scen kommer vara brutalt enkel, möjligtvis att volumetric caustics kan öka antalet en del (kan öka antalet med runt 4 miljoner strålar i exemplet med prismat ehmm..)
http://wscg.zcu.cz/wscg2007/Papers_2007/short/F03-full.pdf

Ganska många bra småsnuttar kod för optimering och förståelse för Photon Mapping:
http://www.pbrt.org/plugins/exphotonmap.pdf

Absorption & Scattering coefficients of turbid coastal waters:
http://www.opticsinfobase.org/view_article.cfm?gotourl=http://www.opticsinfobase.org/DirectPDFAccess/B6BACA9F-BDB9-137E-C8EA831AEA0E4F2F_79600.pdf%3Fda%3D1%26id%3D79600%26seq%3D0&org=

Underwater caustics
http://www-graphics.stanford.edu/courses/cs348b-competition/cs348b-04/underwater/index.html

Metropolis Light Transport

2010-02-14 00:08:18.0 - [Permalink]   [0 Comments]

LuxRender har en Metropolis-renderare, och jag hittade en grym doktorsavhandling där konceptet uppfinns:
http://graphics.stanford.edu/papers/veach_thesis/thesis-bw.pdf

Mer Metropolis

2010-02-14 12:34:57.0 - [Permalink]   [0 Comments]

Anledningen att jag fastnade för Metropolis Light Transport är att den känns lite mer fokuserad och logiskt sund än vanlig Photon Mapping som bara häver ur sig fotoner slumpmässigt (ala Monte Carlo). Det gör visserligen MLT också men mycket smartare. Den ruckar lite på varje fotonväg och undersöker lokalt intressanta vägar som bidrar mycket till slutbilden. Är det ställen som har hög intensitet, som t ex när en lins fokuserar ljuset, så kommer MLT hitta dessa och skjuta ut fler strålar där.

Förra pdf:en jag länkade till är ganska svårläst, men nu hittade jag en avhandling som förklarar det mycket enklare och med pseudokod:
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.71.4481&rep=rep1&type=pdf

Här är några som optimerat MTL:
http://citeseerx.ist.psu.edu/viewdoc/download?doi=10.1.1.88.944&rep=rep1&type=pdf

Alla vinnare från världens största växtakvarietävling

2010-02-15 21:26:01.0 - [Permalink]   [3 Comments]

http://en.iaplc.com/about/gp_works.html

Det blir inte bättre än så. 2002 gillar jag mest.

Akvariebelysningsrejtrejser

2010-02-24 07:59:38.0 - [Permalink]   [0 Comments]

Inladdning av godtycklig 3D-modell - Check.
Hårdvaruaccelererad realtidsvisualisering av 3D-modellen - Check.
Ett styck fejkstråle skjuten genom hela modellen - Check.

Bara det svåra kvar med andra ord. Jag har dock ett äss i skjortärmen. Jag har fixat en mentor som gjort en egen spektralbaserad metropolis-renderare och han har redan gett mig lite feedback på vilken typ av renderare jag förmodligen är intresserad av. Turligt nog kommer det handla om photon mapping som konceptuellt är relativt "enkelt", eventuellt en hybridiserad form av Metropolis Light Transport och Photon Mapping som kallas "Metropolis Photon Sampling":
http://pages.cs.wisc.edu/~yu-chi/research/mps/MetropolisPhotonSampling.html

Det häftiga med den metoden är att man kan ge den tips om var i scenen den ska lägga mest krut (skjuta mest fotoner). Det passar väldigt bra in i vårt fall med en glaslåda med vatten i eftersom vi vet exakt varifrån ljuset alltid skjuts och kan därför ge tydliga och enkla tips till renderingsmotorn vilka ytor som är mest intressanta.

Igårnatt låg jag och funderade om det inte kommer vara väldigt enkelt att räkna alla fotoner som tar sig ut ur "glaslådan", dvs för en viss reflektor på en viss höjd direkt kunna se hur mycket ljus som går till spillo aka reflektoreffektivitet..

Intersection with Java3D pickfast API

2010-02-25 23:12:09.0 - [Permalink]   [1 Comments]

It took me awhile to figure out how to use the new Java3D pickfast API with setShapeRay. It was straightforward when I had figured out the need for setting the mode and flag of PickTool. But until I had figured that out the shapeRay was not working at all. Here is some example code:

// Test intersection from y=1.5 with a small vector pointing downwards the y-axis
final Point3d startPoint = new Point3d(0f, 1.5f, 0f);
final Vector3d direction = new Vector3d(0, -0.05, 0);
final PickTool myPicker = new PickTool(scene);
myPicker.setMode(PickInfo.PICK_GEOMETRY);
myPicker.setFlags(PickInfo.CLOSEST_INTERSECTION_POINT);
myPicker.setShapeRay(startPoint, direction);
final PickInfo closest = myPicker.pickClosest();

System.out.println("getClosestDistance: " + closest.getClosestDistance());
System.out.println("getClosestIntersectionPoint: " + closest.getClosestIntersectionPoint());

How to draw/render PickShapes in Java 3D

2010-02-26 20:55:58.0 - [Permalink]   [0 Comments]

Ok, I need a source code formatter for my blog. Wanted to share this, because I have a feeling the first thing most Java 3D programmers want to do when using the PickTool is visualize the pick-shapes.

This code will transform each type of PickShape to a corresponding 3D-object and draw it in the scene with transparancy to see if the picker is picking in the correct direction and correct size etc.

Hold your breath. Here is the code:


public class PickUtils {

public static final void drawPicker(final BranchGroup scene, final PickShape pickShape) {
scene.addChild(getPickShapeAsGroup(pickShape));
}

public static final BranchGroup getPickShapeAsGroup(final PickShape pickShape) {
final double rayLength = 1000;
final BranchGroup group = new BranchGroup();
final Appearance appearance = new Appearance();

final Color3f yellow = new Color3f(1.0f, 1.0f, 0.0f);
final ColoringAttributes ca = new ColoringAttributes(yellow, ColoringAttributes.SHADE_GOURAUD);
appearance.setColoringAttributes(ca);

final TransparencyAttributes transparency = new TransparencyAttributes();
transparency.setTransparencyMode(TransparencyAttributes.BLENDED);
transparency.setTransparency(0.6f);
appearance.setTransparencyAttributes(transparency);

if (pickShape instanceof PickBounds) {
// Note that you need to use flag PickInfo.NODE and mode PickInfo.PICK_BOUNDS to use this..
final PickBounds pickBounds = (PickBounds) pickShape;

final BoundingSphere boundingSphere = (BoundingSphere) pickBounds.get();

final Point3d pointCoordinates = new Point3d();
boundingSphere.getCenter(pointCoordinates);
final double radius = boundingSphere.getRadius();

Sphere sphere = new Sphere((float) radius, appearance);

TransformGroup directionRotation = new TransformGroup();
Transform3D t3d = new Transform3D();
t3d.setTranslation(new Vector3d(pointCoordinates));
directionRotation.setTransform(t3d);

directionRotation.addChild(sphere);

group.addChild(directionRotation);
} else if (pickShape instanceof PickRay) {
final PickRay pickRay = (PickRay) pickShape;

final Point3d origin = new Point3d();
final Vector3d direction = new Vector3d();
pickRay.get(origin, direction);

direction.scale(rayLength);
final Point3d firstEndPoint = new Point3d(direction.getX(), direction.getY(), direction.getZ());
direction.negate();
final Point3d secondEndPoint = new Point3d(direction.getX(), direction.getY(), direction.getZ());

final Point3d[] lineEndPoints = new Point3d[2];
lineEndPoints[0] = firstEndPoint;
lineEndPoints[1] = secondEndPoint;
final LineArray lineArray = new LineArray(2, LineArray.COORDINATES);
lineArray.setCoordinates(0, lineEndPoints);
final Shape3D plShape = new Shape3D(lineArray, appearance);
plShape.setName("Pick ray");

group.addChild(plShape);
} else if (pickShape instanceof PickSegment) {
final PickSegment pickSegment = (PickSegment) pickShape;

final Point3d origin = new Point3d();
final Point3d end = new Point3d();
pickSegment.get(origin, end);

final Point3d[] lineEndPoints = new Point3d[2];
lineEndPoints[0] = origin;
lineEndPoints[1] = end;
final LineArray lineArray = new LineArray(2, LineArray.COORDINATES);
lineArray.setCoordinates(0, lineEndPoints);
final Shape3D plShape = new Shape3D(lineArray, appearance);
plShape.setName("Pick segment");

group.addChild(plShape);
} else if (pickShape instanceof PickCylinderRay) {
final PickCylinderRay pickCylinderRay = (PickCylinderRay) pickShape;

final float radius = (float) pickCylinderRay.getRadius();
final Point3d origin = new Point3d();
pickCylinderRay.getOrigin(origin);
final Vector3d direction = new Vector3d();
pickCylinderRay.getDirection(direction);

Cylinder cylinder = new Cylinder(radius, (float) rayLength, appearance);

TransformGroup directionRotation = new TransformGroup();
Transform3D t3d = new Transform3D();
t3d.setRotation(new Quat4d(direction.getX(), direction.getY(), direction.getZ(), 1));
directionRotation.setTransform(t3d);

directionRotation.addChild(cylinder);

group.addChild(directionRotation);
} else if (pickShape instanceof PickCylinderSegment) {
final PickCylinderSegment pickCylinderSegment = (PickCylinderSegment) pickShape;

final float radius = (float) pickCylinderSegment.getRadius();
final Point3d origin = new Point3d();
pickCylinderSegment.getOrigin(origin);
final Vector3d direction = new Vector3d();
pickCylinderSegment.getDirection(direction);
final Point3d end = new Point3d();
pickCylinderSegment.getEnd(end);
double cylLength = origin.distance(end);

Cylinder cylinder = new Cylinder(radius, (float) cylLength, appearance);

TransformGroup directionRotation = new TransformGroup();
Transform3D t3d = new Transform3D();
t3d.setRotation(new Quat4d(direction.getX(), direction.getY(), direction.getZ(), 1));
directionRotation.setTransform(t3d);

directionRotation.addChild(cylinder);

group.addChild(directionRotation);
} else if (pickShape instanceof PickConeRay) {
final PickConeRay pickConeRay = (PickConeRay) pickShape;
final float coneLength = 10;

final double spreadAngle = pickConeRay.getSpreadAngle();
final Point3d origin = new Point3d();
pickConeRay.getOrigin(origin);
final Vector3d direction = new Vector3d();
pickConeRay.getDirection(direction);
final float radius = coneLength * (float) Math.tan(spreadAngle);
final Cone cone = new Cone(radius, coneLength, appearance);

final TransformGroup directionRotation = new TransformGroup();
final Transform3D t3d = new Transform3D();
t3d.setRotation(new Quat4d(direction.getX(), direction.getY(), direction.getZ(), 1));
directionRotation.setTransform(t3d);

directionRotation.addChild(cone);
group.addChild(directionRotation);
} else if (pickShape instanceof PickConeSegment) {
final PickConeSegment pickConeSegment = (PickConeSegment) pickShape;

final double spreadAngle = pickConeSegment.getSpreadAngle();
final Point3d origin = new Point3d();
pickConeSegment.getOrigin(origin);
final Point3d end = new Point3d();
pickConeSegment.getEnd(end);
final Vector3d direction = new Vector3d();
pickConeSegment.getDirection(direction);
final float coneLength = (float) origin.distance(end);
final float radius = coneLength * (float) Math.tan(spreadAngle);

final Cone cone = new Cone(radius, coneLength, appearance);

final TransformGroup directionRotation = new TransformGroup();
final Transform3D t3d = new Transform3D();
t3d.setRotation(new Quat4d(direction.getX(), direction.getY(), direction.getZ(), 1));
directionRotation.setTransform(t3d);

directionRotation.addChild(cone);
group.addChild(directionRotation);
}

return group;
}
}

Snyggt växtakvarium

2010-02-28 11:34:15.0 - [Permalink]   [3 Comments]

Månadsväljare

[2013-4]  [2013-3]  [2012-5]  [2012-3]  [2012-1]  [2011-12]  [2011-8]  [2011-5]  [2011-4]  [2011-3]  [2011-2]  [2011-1]  [2010-12]  [2010-11]  [2010-10]  [2010-9]  [2010-8]  [2010-7]  [2010-6]  [2010-5]  [2010-4]  [2010-3]  [2010-2]  [2010-1]  [2009-12]  [2009-11]  [2009-10]  [2009-9]  [2009-8]  [2009-7]  [2009-6]  [2009-5]  [2009-4]  [2009-3]  [2009-2]  [2009-1]  [2008-12]  [2008-11]  [2008-10]  [2008-9]  [2008-8]  [2008-7]  [2008-6]  [2008-5]  [2008-4]  [2008-3]  [2008-2]  [2008-1]  [2007-12]  [2007-11]  [2007-10]  [2007-9]  [2007-8]  [2007-7]  [2007-6]  [2007-5]  [2007-4]  [2007-3]  [2007-2]  [2007-1]  [2006-12]  [2006-11]  [2006-10]  [2006-9]  [2006-8]  [2006-7]  [2006-6]  [2006-5]  [2006-4]  [2006-3]  [2006-2]  [2006-1]  [2005-12]  [2005-11]  [2005-10]  [2005-9]  [2005-8]  [2005-7]  [2005-6]  [2005-5]  [2005-4]  [2005-3]  [2005-2]  [2005-1]  [2004-12]  [2004-11]  [2004-10]  [2004-9]  [2004-8]  [2004-7]  [2004-6]  [2004-5]  [2004-4]  [2004-3]  [2004-2]  [2004-1]  [2003-12]  [2003-11]  [2003-10]  [2003-9