Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/351.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 光线跟踪:出现暗环_Java_Pixel_Raytracing_Lighting - Fatal编程技术网

Java 光线跟踪:出现暗环

Java 光线跟踪:出现暗环,java,pixel,raytracing,lighting,Java,Pixel,Raytracing,Lighting,当我使用灯光渲染时,球体上会出现奇怪的黑色光环。我只是添加了灯光,我不明白为什么要创建黑环 这是我的追踪代码 public class Tracer { public Camera Cam; public int Width, Height; public BufferedImage Image; public Color BackGroundColor; public int StartX, StartY, EndX, EndY,RowCount,C

当我使用灯光渲染时,球体上会出现奇怪的黑色光环。我只是添加了灯光,我不明白为什么要创建黑环

这是我的追踪代码

public class Tracer {

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

    public Tracer(Camera cam, int width, int height, BufferedImage image, Color backGroundColor, int startX, int startY, int endX, int endY, int rowCount, int colCount, ArrayList<GeometricObject> Geoobjects,ArrayList<LightObject> Lightobjects,double ambientLight) {
        super();
        Cam = cam;
        Width = width;
        Height = height;
        Image = image;
        BackGroundColor = backGroundColor;
        StartX = startX;
        StartY = startY;
        EndX = endX;
        EndY = endY;
        RowCount = rowCount;
        ColCount = colCount;
        GeoObjects = Geoobjects;
        LightObjects = Lightobjects;
        if(ambientLight > 1){
            AmbientLight = 1;
        }else if(ambientLight < 0){
            AmbientLight = 0;
        }else{
            AmbientLight = ambientLight;
        }
    }

    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;
                for (int o = 0; o < GeoObjects.size(); o++) {
                    GeometricObject GO = GeoObjects.get(o);
                    Ray r = new Ray(Cam.GetRayPos(Width, Height, x, y, row, col, RowCount, ColCount),Cam.GetRayDir(Width, Height, x, y, row, col, RowCount, ColCount));
                    double hit = GO.hit(r);
                    if (hit != 0.0 && hit < min) {
                        min = hit;
                        colorh = ShadePixel(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(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(GeometricObject GO,Ray ray,double t){
        ArrayList<Color> PixelShade = new ArrayList<Color>();
        Normal normal = GO.Cal_Normal(ray, t);
        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;
                }
            }
            if(WAS_HIT == 0){
                 double Dot = normal.Direction.Dot(r_Dir);
                 if(Dot < 0){
                    Dot = 0;
                 }
                 double Diffuse = 1 - AmbientLight;
                 Color color = new Color(GO.Color);
                 double Shade = AmbientLight + Diffuse*Dot;
                 color.Mul(Shade);
                 PixelShade.add(color);
            }else{
                 Color color = new Color(GO.Color);
                 double Shade = AmbientLight;
                 color.Mul(Shade);
                 PixelShade.add(color);
            }
        }
        Color Final = new Color();
        for(int s = 0;s < PixelShade.size();s++){
            Final.Add(PixelShade.get(s));
        }
        Final.Divide(PixelShade.size());
        return Final;
    }

    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);
                }
            }
        }
    }
}

此代码存在多个问题,但产生这些环的直接原因是颜色分量值溢出了0-255范围。这反过来又是由于我认为是在
Cal_Pixel()
中尝试抗锯齿的错误计算,以及在
ShadePixel()

中无法控制任何数值范围所造成的。请考虑如何以视觉方式调试此场景

首先,法线是否正确?将它们显示为要查看的颜色

将每个组件的范围
[-1..1]
设置为范围
[0..255]

r = 255*(n.x + 1)/2;
g = 255*(n.y + 1)/2;
b = 255*(n.z + 1)/2;
一旦你认为他们看起来是正确的,就进入下一个阶段,逐步建立起来

e、 g.你可以看看你的点积是否如预期的那样(同样是
[-1..1]
,因为向量应该是标准化的):


晚安,伙计们,我明天要去上学。我希望你能在我不在的时候弄清楚。这与场景中的物体数量有关,我90%确定问题出在阴影中。晚安,祝你好运!你的色彩课怎么样?看起来是你写的一门课。这看起来很奇怪。我现在在学校,但我会在回家后尝试。但我仍然不明白为什么它会为我在场景中的所有对象制作一个戒指。某种原因导致了一个mod(
color%256
)的发生,这会产生锯齿状图案。如果你对这段代码进行注释,这将非常有帮助,特别是Cal_Pixel()和ShadePixel()。例如,当Cal_Pixel()的最内层循环中的条件解析为false时,我不清楚您试图实现什么。
public class Color {

public float r,g,b;

public Color(){
    r = 0.0f;
    g = 0.0f;
    b = 0.0f;
}

public Color(float fr,float fg,float fb){
    r = fr;
    g = fg;
    b = fb;
}

public Color(Color color){
    r = color.r;
    g = color.g;
    b = color.b;
}

public void Add(Color color){
    r += color.r;
    g += color.g;
    b += color.b;
}

public void Divide(int scalar){
    r /= scalar;
    g /= scalar;
    b /= scalar;
}

public void Mul(double mul){
    r *= mul;
    g *= mul;
    b *= mul;
}

public int toInt(){
    return (int) (r*255)<<16 | (int) (g*255)<<8 | (int) (b*255); 
}
r = 255*(n.x + 1)/2;
g = 255*(n.y + 1)/2;
b = 255*(n.z + 1)/2;
r = 255*(dot + 1)/2;
g = 255*(dot + 1)/2;
b = 255*(dot + 1)/2;