光线跟踪反射,反思错误的一面

时间:2015-09-25 04:59:34

标签: java reflection raytracing lighting

嘿,我正在写一个光线追踪器,我试着添加反射。 我有两个问题。我的射线方向计算是正确的,因为它似乎没有错。我的第二个问题是如何实现反射,因为这不是很好。

Reflections

似乎反思是相反的。

这是我的代码For Trace!

public class Tracer {

public boolean Tracing;
public Camera Cam;
public int Width, Height;
public BufferedImage Image;
public Color BackGroundColor;
public int StartX, StartY, EndX, EndY,RowCount,ColCount;
public double AmbientLight;
public double DiffuseLight;
public int MaxReflectionCount;
public ArrayList<GeometricObject> GeoObjects;
public ArrayList<LightObject> LightObjects;

public Tracer(Camera cam, int width, int height, BufferedImage image, Color backGroundColor, int startX, int startY, int endX, int endY, int rowCount, int colCount, double ambientLight, double diffuseLight, int maxReflectionCount, ArrayList<GeometricObject> geoObjects, ArrayList<LightObject> lightObjects) {
    super();
    Cam = cam;
    Width = width;
    Height = height;
    Image = image;
    BackGroundColor = backGroundColor;
    StartX = startX;
    StartY = startY;
    EndX = endX;
    EndY = endY;
    RowCount = rowCount;
    ColCount = colCount;
    AmbientLight = ambientLight;
    DiffuseLight = diffuseLight;
    MaxReflectionCount = maxReflectionCount;
    GeoObjects = geoObjects;
    LightObjects = lightObjects;
}

public void TracePixelFast(int x, int y) {
    Color color = new Color(BackGroundColor.r,BackGroundColor.g,BackGroundColor.b);
    for(int o = 0;o < GeoObjects.size();o++){
        GeometricObject GO = GeoObjects.get(o);
        Ray r = new Ray(Cam.GetRayPos(Width, Height, x, y, 1, 1, RowCount, ColCount), Cam.GetRayDir(Width, Height, x, y, 1,1, RowCount, ColCount));
        double hit = GO.hit(r);
        if (hit != 0.0) {
            color = Cal_Pixel(x,y);
            Image.setRGB(x, y, color.toInt());
            break;
        }
    }
}

public void TracePixelSmooth(int x, int y) {
    Image.setRGB(x, y,Cal_Pixel(x,y).toInt());
}

public Color Cal_Pixel(int x,int y){
    Color color = new Color(BackGroundColor);
    Color colorh = new Color(BackGroundColor);
    Color bgc = new Color(BackGroundColor);
    int HIT = 0;
    int MISS = 0;
    for (int row = 0; row < RowCount; row++) {
        for (int col = 0; col < ColCount; col++) {
            double min = Double.MAX_VALUE;
            Ray r = new Ray(Cam.GetRayPos(Width, Height, x, y, row, col, RowCount, ColCount),Cam.GetRayDir(Width, Height, x, y, row, col, RowCount, ColCount));
            for (int o = 0; o < GeoObjects.size(); o++) {
                GeometricObject GO = GeoObjects.get(o);
                double hit = GO.hit(r);
                if (hit != 0.0 && hit < min) {
                    min = hit;
                    colorh = ShadePixel(0,GO, r, hit);
                    HIT++;
                } else {
                    double min2 = Double.MAX_VALUE;
                    for (int o2 = 0; o2 < GeoObjects.size(); o2++) {
                        if(o!=o2){
                        GeometricObject GO2 = GeoObjects.get(o2);
                        double hit2 = GO2.hit(r);
                        if (hit2 != 0.0 && hit2 < min2) {
                        min2 = hit2;
                        bgc = ShadePixel(0,GO2, r, hit2);
                        }
                     }
                    }
                    MISS++;
                }
            }
        }
    }
    for(int h = 0;h < HIT;h++){
        color.Add(colorh);
    }
    for(int m = 0;m < MISS;m++){
        color.Add(bgc);
    }
    color.Divide(RowCount * ColCount);
    return color;
}

public Color ShadePixel(int ReflectionDepthCount,GeometricObject GO,Ray ray,double t){
    Normal normal = GO.Cal_Normal(ray, t);
    if(GO.Reflectivity > 0){
    Color GoColor = new Color(Cal_Reflection(GO,ReflectionDepthCount, ray, normal));
    Color finalcolor = new Color(Cal_Light(GoColor, normal));
    return finalcolor;
    }else{;
        Color finalcolor = new Color(Cal_Light(GO.Color, normal));
        return finalcolor;  
    }
}

public Color ShadePixel_End(GeometricObject GO,Normal normal){
    Color GoColor = new Color(GO.Color);
    Color finalcolor = new Color(Cal_Light(GoColor, normal));
    return finalcolor;
}

public Color Cal_Light(Color color,Normal normal){
    ArrayList<Color> PixelShade = new ArrayList<Color>();
    Color Final = new Color();
    for(int l = 0;l < LightObjects.size();l++){
        LightObject light = LightObjects.get(l);
        Vector3D r_Dir = light.Pos.Sub(normal.Origin);
        r_Dir.normalize();
        Ray raytolight = new Ray(normal.Origin,r_Dir);
        int WAS_HIT = 0;
        for(int o = 0;o < GeoObjects.size();o++){
            GeometricObject NGO = GeoObjects.get(o);
            double hit = NGO.hit(raytolight);
            if (hit != 0.0) {
               WAS_HIT = 1;
            }
        }
        PixelShade.add(light.ShadePixel(WAS_HIT, normal, r_Dir, color, AmbientLight, DiffuseLight));
    }
    for(int s = 0;s < PixelShade.size();s++){
        Final.Add(PixelShade.get(s));
    }
    Final.Divide(PixelShade.size());
    return Final;
}

  public Color Cal_Reflection(GeometricObject OriginalObject,int ReflectionDepthCount,Ray InRay,Normal normal){
    if(ReflectionDepthCount <= MaxReflectionCount){
        GeometricObject LastGO  = null;
        Ray LastRay = null;
        double LastT = 0.0;
        double min = Double.MAX_VALUE;
        double Dir_Out_Dot = InRay.Direction.Dot(normal.Direction);
        Vector3D Dir_Out = normal.Direction.Mul(2).Mul(Dir_Out_Dot).Sub(InRay.Direction);
        Ray r = new Ray(normal.Origin,Dir_Out);
        for (int o = 0; o < GeoObjects.size(); o++) {
            GeometricObject GO = GeoObjects.get(o);
            double hit = GO.hit(r);
            if (hit != 0.0 && hit < min) {
                min = hit;
                LastGO = GO;
                LastRay = r;
                LastT = hit;
            }
       }

        if(LastGO != null){
            Color Reflected = new Color(ShadePixel(ReflectionDepthCount, LastGO,LastRay, LastT));
            Color HitColor = new Color(LastGO.Color);
            Color FinalColor = new Color();
            Reflected.Mul(OriginalObject.Reflectivity);
            FinalColor.Add(HitColor);
            FinalColor.Add(Reflected);
            FinalColor.Divide(2);
            FinalColor.Add(OriginalObject.Color);
            FinalColor.Divide(2);
            return FinalColor;
        }
    }
    return OriginalObject.Color;
}

public void TraceArea(boolean SmoothTracing) {
    Tracing = true;
    if(SmoothTracing){
        for (int x = StartX; x < EndX; x++) {
            for (int y = StartY; y < EndY; y++) {
                TracePixelSmooth(x,y);
            }
        }
    }else{
        for (int x = StartX; x < EndX; x++) {
            for (int y = StartY; y < EndY; y++) {
                TracePixelFast(x,y);
            }
        }
    }
}

}

这是我的Sphere的代码。

public class Sphere extends GeometricObject{

public Vector3D Center;
public double Radius;

public Sphere(Vector3D Center,Color Color,double Radius,double Reflectivity){
    this.Center = Center;
    this.Radius = Radius;
    this.Color = Color;
    this.Reflectivity = Reflectivity;
}

public double hit(Ray ray) {
    double a = ray.Direction.Dot(ray.Direction);
    double b = 2 * ray.Origin.Sub(Center).Dot(ray.Direction);
    double c = ray.Origin.Sub(Center).Dot(ray.Origin.Sub(Center))-Radius*Radius;
    double discreminant = b*b-4*a*c;
    if(discreminant < 0.0f){
        return 0.0;
    }else{
        double t = (-b - Math.sqrt(discreminant))/(2*a);
        if(t > 10E-9){
            return t;
        }else{
            return 0.0;
        }
    }
}

public Normal Cal_Normal(Ray ray,double t) {
    Vector3D NPos = new Vector3D(ray.Origin.x + ray.Direction.x*t,ray.Origin.y + ray.Direction.y*t,ray.Origin.z + ray.Direction.z*t);
    Vector3D NDir = NPos.Sub(Center).Div(Radius);
    return new Normal(NPos,NDir);
}

}

如果您需要更多我的代码请求它,我会上传它。 如果你想帮助我改善我的光线追踪器的反射部分,我希望它看起来更像这样。只是如果你想把光线追踪的知识倾注到我可怜的破碎的灵魂上!

Picture Of Hope

1 个答案:

答案 0 :(得分:0)

找到答案!我只需要翻转In_Ray.Direction就可以了!