Example #1
0
func renderer(
	width, height int,
	renderedImages chan *hdrimage.Image,
	scene *scene.Scene,
	seed int64,
	totalSamples int,
	threads int,
	quiet bool,
) {
	randomGen := random.New(seed)

	sampleCounter := rpc.NewSampleCounter(totalSamples)
	var bar *progress.ProgressBar
	if !quiet {
		bar = progress.StartProgressBar(totalSamples, "rendering samples")
	}

	wg := sync.WaitGroup{}
	wg.Add(threads)

	defer func() {
		wg.Wait()
		if !quiet {
			bar.Done()
		}
	}()

	for i := 0; i < threads; i++ {
		go func(seed int64) {
			defer wg.Done()

			raytracer := raytracer.Raytracer{
				Scene:  scene,
				Random: random.New(seed),
			}

			image := hdrimage.New(width, height)
			image.Divisor = 0

			for {
				if sampleCounter.Dec(1) == 0 {
					renderedImages <- image
					return
				}
				raytracer.Sample(image)
				if !quiet {
					bar.Add(1)
				}
			}
		}(randomGen.NewSeed())
	}
}
Example #2
0
// RenderLoop renders samples of an image until the sample counter reaches
// 0, and then returns the combined result. If synchronous is set, images
// will be transferred from the worker after every sample. Otherwise,
// the image is transferred at the end.
func RenderLoop(
	sampleCounter *rpc.SampleCounter,
	client *rpc.RemoteRaytracerCaller,
	renderedImages chan<- *hdrimage.Image,
	globalSettings *rpc.SampleSettings,
	synchronous bool,
	bar *progress.ProgressBar,
) {
	settings := *globalSettings
	for {
		settings.SamplesAtOnce = sampleCounter.Dec(globalSettings.SamplesAtOnce)
		if settings.SamplesAtOnce == 0 {
			return
		}
		var err error
		var image *hdrimage.Image

		if synchronous {
			image, err = client.Sample(&settings)
		} else {
			err = client.StoreSample(&settings)
		}
		//both samples log the error, but only synchronous sample pushes
		//image into the channel
		if err == nil {
			if synchronous {
				renderedImages <- image
			}
			if bar != nil {
				bar.Add(1)
			}
		} else {
			log.Printf("No sample :( %s\n", err)
		}
	}
}