反思没有正确反映

时间:2015-09-25 15:11:59

标签: java colors raytracing depth

我正在写一个光线跟踪器。我正在研究反射。但似乎没有正确反映。我继续得到StackOverflowError.I增加了内存,它现在运行但反射不像我想的那样是的。

What I thought http://www.ageofarmour.com/3d/tutorials/AoA_metalized_glass_shader_help_files/raytrace_depth.jpg

我认为这会反映出来的反思!但它最终会像这样结束。

注意:这是在移动对象的法线并更改颜色计算之后!检查Cal_Reflection以进行新的颜色计算!

My Sad Reflections

这是我的示踪剂代码!

@lightcolor

这是我的球体代码!

@gLightBlue

这是我的发射器控制场景和示踪剂!

@lightcolor

这是场景代码!

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 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;
        Vector3D Origin = normal.Origin.Add(normal.Direction.Mul(1E-100));
        Vector3D Direction = normal.Direction;
        Direction.normalize();
        Ray r = new Ray(Origin, Direction);
        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) {
            System.out.println(ReflectionDepthCount);
            Color Reflected = new Color(ShadePixel(ReflectionDepthCount++, LastGO, LastRay, LastT));
            Color HitColor = new Color(LastGO.Color);
            Color FinalColor = new Color(OriginalObject.Color);
            Reflected.Mul(OriginalObject.Reflectivity);
            HitColor.Mul(OriginalObject.Reflectivity);
            FinalColor.Add(HitColor);
            FinalColor.Add(Reflected);
            FinalColor.Divide(2);
            return FinalColor;
        }
    } else {
        return BackGroundColor;
    }
    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);
            }
        }
    }
}}

如果您需要我发布更多我的代码,请告诉我们!

提前致谢!

第一次反射的变量!

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);
    NDir.normalize();
    return new Normal(NPos,NDir);
}}

Project Zip File

1 个答案:

答案 0 :(得分:2)

您正在物体表面上反射光线完全。检查与反射光线的交点时,再次点击同一个对象。你假设检查距离是否等于0.0足以避免这种情况,但FP数字比你想象的要复杂......