void RaytracingConfig::loadFromJSON(const nlohmann::json & config) {

    enabled = config.get<bool>("enabled");
    title = config.get<std::string>("title");
    controlsCamera = config.get<bool>("controlsCamera");

    renderOutputWidth = config.get<int>("outputWidth");
    renderOutputHeight = config.get<int>("outputHeight");
    
    computationDevice = (ComputationDevice) config.get<int>("computationDevice");
    brdfType = (SupportedBRDF) config.get<int>("brdfType");
    supportedPhotonMap = (SupportedPhotonMap) config.get<int>("supportedPhotonMap");
    
    numberOfPhotonsToGather = config.get<int>("numberOfPhotonsToGather");
    raysPerLight = config.get<int>("raysPerLight");
    float maxPhotonGatherDistance = config.get<double>("maxPhotonGatherDistance", -1.0);
    if (maxPhotonGatherDistance != -1.0f) {
        this->maxPhotonGatherDistance = maxPhotonGatherDistance;
    }
    else {
        this->maxPhotonGatherDistance = std::numeric_limits<float>::infinity();
    }
    
    lumensPerLight = config.get<int>("lumensPerLight");
    
    photonBounceProbability = config.get<double>("photonBounceProbability");
    photonBounceEnergyMultipler = config.get<double>("photonBounceEnergyMultipler");
    
    usePhotonMappingForDirectIllumination = config.get<bool>("usePhotonMappingForDirectIllumination");
    
    directIlluminationEnabled = config.get<bool>("directIlluminationEnabled");
    indirectIlluminationEnabled = config.get<bool>("indirectIlluminationEnabled");
    shadowsEnabled = config.get<bool>("shadowsEnabled");
    
    if (config.has("Hashmap_properties")) {
        hashmapCellsize = config["Hashmap_properties"].get<double>("cellsize");
        hashmapSpacing = config["Hashmap_properties"].get<int>("spacing");
        hashmapGridStart = vec3FromData(config["Hashmap_properties"].get<std::vector<double>>("gridStart", make_vector<double>(0,0,0)));
        hashmapGridEnd = vec3FromData(config["Hashmap_properties"].get<std::vector<double>>("gridEnd", make_vector<double>(0,0,0)));
    }
    
    if (config.has("Tile_properties")) {
        tile_width = config["Tile_properties"].get<int>("tileHeight");
        tile_height = config["Tile_properties"].get<int>("tileWidth");
        
        tile_photonEffectRadius = config["Tile_properties"].get<double>("photonEffectRadius");
        tile_photonSampleRate = config["Tile_properties"].get<double>("photonSampleRate");
    }
    
    if (config.has("photonEffectRadius")) {
        this->maxPhotonGatherDistance = config.get<double>("photonEffectRadius", 1.0);
        tile_photonEffectRadius = this->maxPhotonGatherDistance;
    }
}