我正在尝试创建一个光线跟踪器,并在Perspective投影中遇到一些问题,如下图所示。对我来说,看起来它有曲线,即观察平面的表面会弯曲。 有人有任何想法或可以帮助我吗?
这是我的主要课程
import entity.Image;
import primitives.Mesh;
import projection.Perspective1;
import projection.Projection;
import sampler.JitteredSample;
import sampler.Sampler;
import scene.Camera;
import scene.Lightning;
import scene.Lights;
import scene.World;
import scene.lightning.Ambient;
import scene.lightning.Parallel;
import scene.lightning.PointLight;
import tracer.Tracer;
import xmlReader.XmlReader;
public class Engine {
public static World world;
public static Image image;
public static Tracer Tracer;
public static Lights lights;
public static Camera camera;
public static Sampler sampler;
public static Projection projection;
public static Lightning lightning;
public static Mesh mesh;
public static void main(String[] args){
//Create Engine Objects
camera = new Camera(xmlReader.getCamera(source)); System.out.println("Create Camera");
lights = new Lights(xmlReader.getLight(source)); System.out.println("Create Lights");
world = new World(camera.getHoriziontalResolution(), camera.getVerticalResolution(), 1, source); System.out.println("Create World");
image = new Image(xmlReader.getOutputFile(source)); System.out.println("Create Image File");
Tracer = new Tracer();System.out.println("Create Tracer");
sampler = new JitteredSample(4);System.out.println("Create Sampler");
projection = new Perspective1();System.out.println("Create Projection");
//start tracing time
System.out.println("\n Start Tracing ... \n");
start = System.nanoTime();
//Start tracing
for (int x = 0; x<world.viewplane.width; x++){
for (int y = 0; y<world.viewplane.height; y++){
if (!black)
Tracer.trace(x, y, source);
}
}
//Save image as png
image.write("PNG");
//Stop tracing time
end = System.nanoTime();
//get results
System.out.println("\n" + "Render Time: " + (end-start)/1000000000.F+ "\n");
if (!black)
System.out.println("Saved to: " + System.getProperty("user.dir") + "/" + xmlReader.getOutputFile(source));
else
System.out.println("Saved to: " + System.getProperty("user.dir") + "/" + "example0.png");
}
}
import engine.Engine;
import entity.Colara;
import entity.Point2D;
import entity.Point3D;
import entity.Ray;
import entity.Vector3D;
import primitives.Sphere;
import primitives.Triangle;
import scene.Lightning;
import scene.lightning.Ambient;
public class Tracer {
public void trace(int x, int y, String source){
Colara color = Engine.world.background;
boolean hit = false;
Ray ray;
//Find Color of each Pixel/(samples*samples)
for (int row = 0; row < Engine.sampler.samples; row++){
for (int col = 0; col < Engine.sampler.samples; col++){
//Point to write on in the image
Point2D point = Engine.sampler.sample(row,col,x,y);
//Ray to find something. Depends on Projection
ray = Engine.projection.createRay(point);
double min = Double.MAX_VALUE;
Colara tempColor = new Colara();
//For every Object
for(int i = 0; i<Engine.world.objects.size(); i++){
//Hit Object with ray
double temp = Engine.world.objects.get(i).hit(ray);
/*
Shadow Rays
*/
//If hit add appropriate color ...
}
以下是采样器类,如Point2D point = Engine.sampler.sample(row,col,x,y);
public class JitteredSample extends Sampler{
public JitteredSample(int samples){
this.samples = samples;
}
public Point2D sample(int row, int col, int x, int y){
Point2D point = new Point2D();
Random random = new Random();
//Create Sample points
point.x = x-Engine.world.viewplane.width/2+(col+random.nextFloat())/samples;
point.y = y-Engine.world.viewplane.height/2+(row+random.nextFloat())/samples;
return point;
}
这是投影类,其中正在创建光线。
public class Perspective1 extends Projection {
public Perspective1(){
eye = new Point3D(Engine.camera.getPosition());
lookat = new Point3D(Engine.camera.getLookat());
up = new Vector3D(Engine.camera.getUp());
up.normalize();
double fov = Engine.camera.getHorizontal_fov();
distance = Engine.world.viewplane.height/2/Math.tan(Math.toRadians(fov));
uvw();
}
public Ray createRay(Point2D point){
Ray ray = new Ray(eye, u.mul(point.x).add(v.mul(point.y).sub(w.mul(-distance))));
ray.direction.normalize();
return ray;
}
}