public void parallelRender(int[] raster, int width, int height){
        //calculate view frustrum
        if (!isInitialized) init();
        Ray[] rays = cam.generateRays(width, height);
        int threadCount = 8;
        TracerThread[] tts = new TracerThread[threadCount]; 
        
        for (int i = 0; i <threadCount; i++ ){
            tts[i] = new TracerThread(rays,((i*rays.length)/threadCount),(((i+1)*rays.length)/threadCount),world);
            tts[i].start();
        }
  
        for(TracerThread thread : tts) try {
            thread.join();
            
//        for (Ray r : rays) r.voxel = trace(r);
            } catch (InterruptedException ex) {
                Logger.getLogger(Tracer.class.getName()).log(Level.SEVERE, null, ex);
            }
        
//        for (Ray r : rays) r.voxel = trace(r);
    
        
        
        for(int x = 0; x < width; x++){
            for(int y = 0; y < height;y++){
                Ray r = rays[(x*height) +y];
                raster[x+width*y] = r.voxel!=null?voxelColors[0x000000ff&r.voxel.ID].getRGB():Color.black.getRGB();
                
            }
        }

        
    }