Ejemplo n.º 1
0
func Test_SimpleExample(t *testing.T) {

	Convey("Simple Example", t, func() {

		pipe := DefaultFilePipe()

		/* use a custom unique generator with a prefix for the light handles */
		lights := NewPrefixLightUniqueGenerator("light_")

		mgr := NewHandleManager(nil, lights, nil)

		ctx := NewContext(pipe, mgr, &Configuration{PrettyPrint: true})
		ri := RI(ctx)
		ri.Begin("output/exampleSimple.rib")
		ri.Display("sphere.tif", "file", "rgb")
		ri.Format(320, 240, 1)
		ri.Projection(PERSPECTIVE, RtToken("fov"), RtFloat(30))
		ri.Translate(0, 0, 6)
		ri.WorldBegin()
		ri.LightSource("ambientlight", RtToken("intensity"), RtFloat(0.5))
		ri.LightSource("distantlight", RtToken("intensity"), RtFloat(1.2), RtToken("from"), RtIntArray{0, 0, -6}, RtToken("to"), RtIntArray{0, 0, 0})
		ri.Color(RtColor{1, 0, 0})
		ri.Sphere(1, -1, 1, 360)
		ri.WorldEnd()

		So(ri.End(), ShouldBeNil)

		/* output gathered stats */
		p := pipe.GetByName(PipeToStats{}.Name())
		So(p, ShouldNotBeNil)
		s, ok := p.(*PipeToStats)
		So(s, ShouldNotBeNil)
		So(ok, ShouldBeTrue)

		p = pipe.GetByName(PipeTimer{}.Name())
		So(p, ShouldNotBeNil)
		t, ok := p.(*PipeTimer)
		So(t, ShouldNotBeNil)
		So(ok, ShouldBeTrue)

		fmt.Printf("%s%s", s, t)
	})

	Convey("Simple Example Flattened", t, func() {

		pipe := DefaultFilePipe()

		ctx := NewContext(pipe, nil, &Configuration{PrettyPrint: false})
		ri := RI(ctx)
		ri.Begin("output/exampleSimpleFlattened.rib")

		f, err := os.Open("output/exampleSimple.rib")
		So(err, ShouldBeNil)
		defer f.Close()
		So(ri.ParseRIB(f), ShouldBeNil)
		ri.End()
	})
}
Ejemplo n.º 2
0
/* go test -bench=. */
func Benchmark_SimpleExampleNumberHandlers(b *testing.B) {

	for i := 0; i < b.N; i++ {
		ri, _ := DefaultPipeline(nil)
		ri.Begin("simple.rib")
		ri.Display("sphere.tif", "file", "rgb")
		ri.Format(320, 240, 1)
		ri.Projection(PERSPECTIVE, RtToken("fov"), RtFloat(30))
		ri.Translate(0, 0, 6)
		ri.WorldBegin()
		ri.LightSource("ambientlight", RtToken("intensity"), RtFloat(0.5))
		ri.LightSource("distantlight", RtToken("intensity"), RtFloat(1.2), RtToken("from"), RtIntArray{0, 0, -6}, RtToken("to"), RtIntArray{0, 0, 0})
		ri.Color(RtColor{1, 0, 0})
		ri.Sphere(1, -1, 1, 360)
		ri.WorldEnd()
		ri.End()
	}
}
Ejemplo n.º 3
0
func Test_HandleCallbacks(t *testing.T) {

	lighthandle := func(name RtName, light RtLightHandle) {

		fmt.Printf("LightHandle -- %s %s\n", name, light)
	}

	Convey("Handle callbacks pipelining", t, func() {

		pipe := NewPipe()
		callback := new(PipeHookHandleCallback)
		callback.LightHandler = lighthandle

		pipe.Append(callback)

		mgr := NewHandleManager(nil, NewPrefixLightUniqueGenerator("light_"), nil)

		ri := RI(NewContext(pipe, mgr, nil))

		So(ri.Begin("output/filters-simple.rib"), ShouldBeNil)
		ri.Display("sphere.tif", "file", "rgb")
		ri.Format(320, 240, 1)
		ri.Projection(PERSPECTIVE, RtToken("fov"), RtFloat(30))
		ri.Translate(0, 0, 6)
		ri.WorldBegin()

		ambient, _ := ri.LightSource("ambientlight", RtToken("intensity"), RtFloat(0.5))
		So(ambient, ShouldNotBeNil)

		ri.LightSource("distantlight", RtToken("intensity"), RtFloat(1.2), RtToken("from"), RtIntArray{0, 0, -6}, RtToken("to"), RtIntArray{0, 0, 0})
		ri.Illuminate(ambient, false)
		ri.Color(RtColor{1, 0, 0})
		ri.Sphere(1, -1, 1, 360)

		ri.WorldEnd()
		So(ri.End(), ShouldBeNil)

	})
}
Ejemplo n.º 4
0
func Benchmark_SimpleExampleUniqueHandlers(b *testing.B) {

	for i := 0; i < b.N; i++ {
		pipe := NullPipe()
		mgr := NewHandleManager(nil, NewLightUniqueGenerator(), nil)

		ctx := NewContext(pipe, mgr, nil)
		ri := RI(ctx)
		ri.Begin("simple.rib")
		ri.Display("sphere.tif", "file", "rgb")
		ri.Format(320, 240, 1)
		ri.Projection(PERSPECTIVE, RtToken("fov"), RtFloat(30))
		ri.Translate(0, 0, 6)
		ri.WorldBegin()
		ri.LightSource("ambientlight", RtToken("intensity"), RtFloat(0.5))
		ri.LightSource("distantlight", RtToken("intensity"), RtFloat(1.2), RtToken("from"), RtIntArray{0, 0, -6}, RtToken("to"), RtIntArray{0, 0, 0})
		ri.Color(RtColor{1, 0, 0})
		ri.Sphere(1, -1, 1, 360)
		ri.WorldEnd()
		ri.End()
	}
}
Ejemplo n.º 5
0
func main() {

	optProduction := flag.Bool("production", false, "use production settings")
	optDevelopment := flag.Bool("development", false, "use development settings")
	optDebug := flag.Bool("debug", false, "use debug settings")
	optWidth := flag.Float64("width", 2100, "width of output")
	optHeight := flag.Float64("height", 900.0, "height of the output")
	optScale := flag.Float64("scale", 0.5, "scale of the output, [0.0,1.0)")
	optPrettyPrint := flag.Bool("pretty", true, "pretty print RIB output")
	optFine := flag.Bool("fine", false, "fine render, adjusts the max samples")
	optEffects := flag.Bool("effects", false, "use camera effects")
	optBunnies := flag.Bool("bunnies", false, "show other bunnies")
	flag.Parse()

	production := *optProduction
	development := *optDevelopment
	debug := *optDebug
	fine := *optFine
	effects := *optEffects
	width := *optWidth
	height := *optHeight
	scale := *optScale
	prettyPrint := *optPrettyPrint
	bunnies := *optBunnies

	if !production && !development && !debug {
		fmt.Fprintf(os.Stderr, "need to specify at least one rendering option\n\n")
		/* TODO: add flag output */
		os.Exit(1)
	}

	/* Rendering Options :
	   *
		 * Production - PxrPathTracer
	   * Development - PxrDirectLighting | PxrDefault
	   * Debug - PxrVisualizer | PxrDebugShadingContext
	*/

	pipe := rigo.DefaultFilePipe()

	shaders := NewPrefixShaderUniqueGenerator("shader_")
	lights := NewPrefixLightUniqueGenerator("light_")

	mgr := rigo.NewHandleManager(nil, lights, shaders)

	ctx := rigo.NewContext(pipe, mgr, &rigo.Configuration{PrettyPrint: prettyPrint})

	ri := rigo.RI(ctx)
	ris := rigo.RIS(ctx)

	/* Bxdf Shaders */
	pattern, err := ris.Pattern("PxrFractal", "-")
	if err != nil {
		fmt.Fprintf(os.Stderr, "error reading pattern shader -- %v\n", err)
		os.Exit(1)
	}

	hero, err := ris.Bxdf("PxrDisney", "-")
	if err != nil {
		fmt.Fprintf(os.Stderr, "error reading bxdf shader -- %v\n", err)
		os.Exit(1)
	}

	hero.SetValue("roughness", RtFloat(0.1))
	hero.SetValue("specular", RtFloat(0.2))
	hero.SetValue("clearcoatGloss", RtFloat(0.5))
	hero.SetValue("metallic", RtFloat(0.1))
	hero.SetValue("clearcoat", RtFloat(0.2))
	hero.SetValue("baseColor", RtColor{0.9, 0.9, 0.9})
	hero.SetValue("sheenTint", RtFloat(0.2))

	if err := hero.SetReferencedValue("specular", pattern.ReferenceOutput("resultF")); err != nil {
		fmt.Fprintf(os.Stderr, "error referencing resultF value -- %v\n", err)
		os.Exit(1)
	}

	bunny, err := ris.Bxdf("PxrDisney", "-")
	if err != nil {
		fmt.Fprintf(os.Stderr, "error reading bxdf shader -- %v\n", err)
		os.Exit(1)
	}

	bunny.SetValue("baseColor", RtColor{0.95, 0.95, 0.95})

	minSamples := RtInt(16)
	maxSamples := RtInt(32)
	heroModel := RtString("bunny_res4.rib")
	bunnyModel := RtString("bunny_res4.rib")

	if production {
		minSamples = RtInt(32)
		maxSamples = RtInt(64)
		heroModel = RtString("bunny_res2.rib")
		bunnyModel = RtString("bunny_res2.rib")

		if fine {
			minSamples = RtInt(64)
			maxSamples = RtInt(128)
		}
	}

	if err := ri.Begin("bunny.rib"); err != nil {
		fmt.Fprintf(os.Stderr, "error beginning -- %v\n", err)
		os.Exit(1)
	}

	curuser, err := user.Current()
	if err != nil {
		fmt.Fprintf(os.Stderr, "error reading current user -- %v\n", err)
		os.Exit(1)
	}

	ri.ArchiveRecord("structure", "Scene %s", Scene)
	ri.ArchiveRecord("structure", "Creator %s", Author)
	ri.ArchiveRecord("structure", "CreationDate %s", time.Now())
	ri.ArchiveRecord("structure", "For %s", curuser.Username)
	ri.ArchiveRecord("structure", "Frames %d", 1)

	ri.Option("searchpath", RtToken("string shader"), RtString("./shaders:@"))
	ri.Option("searchpath", RtToken("string texture"), RtString("./textures:@"))
	ri.Option("searchpath", RtToken("string archive"), RtString("./archives:@"))
	ri.Option("shading", RtToken("int directlightinglocalizedsampling"), RtInt(3))
	ri.Option("bucket", RtToken("string order"), RtString("horizontal"))

	ri.Clipping(0.1, 100)
	ri.Display("rabbit.tiff", "file", "rgba")

	fmt.Printf("Format %dx%d\n", int(width*scale), int(height*scale))
	ri.Format(RtInt(int(width*scale)), RtInt(int(height*scale)), 1)

	ri.ShadingRate(1)
	ri.ShadingInterpolation("smooth")

	ri.Attribute("trace", RtToken("int maxspeculardepth"), RtInt(3), RtToken("int displacements"), RtInt(1),
		RtToken("int maxdiffusedepth"), RtInt(3))

	ri.PixelFilter(GaussianFilter, RtFloat(5), RtFloat(5))
	ri.PixelVariance(0.001)

	/* declare some of the parameters */
	ri.Declare("minsamples", "int")
	ri.Declare("maxsamples", "int")
	ri.Declare("incremental", "int")
	ri.Declare("aperture", "float[4]")
	ri.Declare("integrationmode", "string")

	if err := ri.Hider("raytrace", RtToken("maxsamples"), maxSamples, RtToken("minsamples"), minSamples,
		RtToken("incremental"), RtInt(12), RtToken("aperture"), RtFloatArray{0, 0, 0, 0},
		RtToken("integrationmode"), RtString("path")); err != nil {

		fmt.Fprintf(os.Stderr, "hider error -- %v\n", err)
		os.Exit(1)
	}

	if production {
		fmt.Printf("Setting Production -- PxrPathTracer\n")

		ri.Integrator("PxrPathTracer", "production", RtToken("int maxPathLength"), RtInt(20),
			RtToken("string sampleMod"), RtString("bxdf"), RtToken("int rouletteDepth"), RtInt(12),
			RtToken("float rouletteThreshold"), RtFloat(0.2), RtToken("int clampDepth"), RtInt(2),
			RtToken("int clampLuminance"), RtInt(10))
	}

	if development {
		fmt.Printf("Setting Development -- PxrDirectLighting\n")

		ri.Integrator("PxrDirectLighting", "development") /* TODO */
	}

	if debug {
		fmt.Printf("Setting Debug -- PxrVisualizer\n")

		ri.Integrator("PxrVisualizer", "debug") /* TODO */
	}

	ri.Imager("background", RtToken("color color"), RtColor{.45, .45, .45}, RtToken("float alpha"), RtFloat(1))
	if effects {
		ri.Projection("PxrCamera", RtToken("float fov"), RtFloat(40),
			RtToken("float natural"), RtFloat(1),
			RtToken("float radial1"), RtFloat(-0.01))
	} else {
		ri.Projection("PxrCamera", RtToken("float fov"), RtFloat(40))
	}

	ri.Translate(0, -2, 20)
	ri.Rotate(-50, 1, 0, 0)
	ri.Rotate(-20, 0, 1, 0)

	ri.WorldBegin()
	ri.AttributeBegin()
	ri.Attribute("identifier", RtToken("string name"), RtString("sky"))
	ri.Attribute("visibility", RtToken("int camera"), RtInt(0))
	ri.Translate(0, 20, 0)
	ri.ShadingRate(1)

	sky, err := ri.AreaLightSource("PxrStdEnvDayLight", RtToken("float importance"), RtFloat(2),
		RtToken("float exposure"), RtFloat(1), RtToken("vector directionVector"),
		RtVector{0, 1, 0}, RtToken("color specAmount"), RtColor{.5, .5, .5},
		RtToken("float haziness"), RtFloat(1.7), RtToken("float enableShadows"),
		RtFloat(1))

	if err != nil {
		fmt.Fprintf(os.Stderr, "unable to create sky light -- %v\n", err)
		os.Exit(1)
	}

	ri.Bxdf("PxrLightEmission", RtShaderHandle(sky))
	ri.Geometry("envsphere", RtToken("constant float[2] resolution"), RtFloatArray{1024, 1024})
	ri.AttributeEnd()

	ri.Illuminate(sky, true)

	ri.AttributeBegin()
	ri.Attribute("identifier", RtToken("name"), RtString("hero"))
	ri.Attribute("visibility", RtToken("int camera"), RtInt(1), RtToken("int transmission"), RtInt(1))
	ri.Translate(0, -2, 0)
	ri.Rotate(-125, 0, 1, 0)

	ri.Pattern(pattern.Name(), pattern.Handle())
	ri.Bxdf(hero.Name(), hero.Handle())
	ri.Scale(50, 50, 50)

	if err := ri.Procedural2("DelayedReadArchive2", "SimpleBound", RtToken("string filename"), heroModel,
		RtToken("float[6] bound"), RtFloatArray{-1, 1, -1, 1, -1, 1}); err != nil {
		panic(err.Error())
	}

	ri.AttributeEnd()

	if bunnies {
		ri.AttributeBegin()
		ri.Attribute("identifier", RtToken("string name"), RtString("bunny_1"))
		ri.Attribute("visibility", RtToken("int camera"), RtInt(1), RtToken("int transmission"), RtInt(1),
			RtToken("int indirect"), RtInt(1))

		ri.Translate(-5, -1, 0)
		ri.Rotate(-75, 0, 1, 0)

		ri.Bxdf(bunny.Name(), bunny.Handle())
		ri.Scale(20, 20, 20)

		ri.Procedural2("DelayedReadArchive2", "SimpleBound", RtToken("string filename"), bunnyModel,
			RtToken("float[6] bound"), RtBound{-1, 1, -1, 1, -1, 1})

		ri.AttributeEnd()
		ri.AttributeBegin()
		ri.Attribute("identifier", RtToken("string name"), RtString("bunny_2"))
		ri.Attribute("visibility", RtToken("int camera"), RtInt(1), RtToken("int transmission"), RtInt(1),
			RtToken("int indirect"), RtInt(1))

		ri.Translate(-5, -1, 3)
		ri.Rotate(25, 0, 1, 0)

		ri.Bxdf(bunny.Name(), bunny.Handle())
		ri.Scale(20, 20, 20)

		ri.Procedural2("DelayedReadArchive2", "SimpleBound", RtToken("string filename"), bunnyModel,
			RtToken("float[6] bound"), RtFloatArray{-1, 1, -1, 1, -1, 1})

		ri.AttributeEnd()
	} /* end bunnies */

	ri.AttributeBegin()
	ri.Attribute("identifier", RtToken("string name"), RtString("painted_floor"))
	ri.Attribute("visibility", RtToken("int camera"), RtInt(1), RtToken("int transmission"), RtInt(1))
	ri.Rotate(90, 1, 0, 0)
	ri.Pattern("PxrTexture", "floor_pattern", RtToken("string filename"), RtString("ratGrid.tex"),
		RtToken("int invertT"), RtInt(0))
	ri.Bxdf("PxrDiffuse", "floor", RtToken("reference color diffuseColor"), RtString("floor_pattern:resultRGB"))
	ri.Scale(20, 20, 20)
	ri.Patch("bilinear", RtToken("vertex point P"), RtFloatArray{-1, 1, 0, 1, 1, 0, -1, -1, 0, 1, -1, 0})
	ri.AttributeEnd()
	ri.WorldEnd()

	if err := ri.End(); err != nil {
		fmt.Fprintf(os.Stderr, "error ending -- %v\n", err)
		os.Exit(1)
	}

	p := pipe.GetByName(rigo.PipeToStats{}.Name())
	if p == nil {
		fmt.Fprintf(os.Stderr, "Pipe Stats not found!\n")
		os.Exit(1)
	}

	s, ok := p.(*rigo.PipeToStats)
	if !ok {
		fmt.Fprintf(os.Stderr, "Pipe Stats not found\n")
		os.Exit(1)
	}

	p = pipe.GetByName(rigo.PipeTimer{}.Name())
	if p == nil {
		fmt.Fprintf(os.Stderr, "Pipe Timer not found\n")
		os.Exit(1)
	}
	t, ok := p.(*rigo.PipeTimer)
	if !ok {
		fmt.Fprintf(os.Stderr, "Pipe Timer not found\n")
		os.Exit(1)
	}

	fmt.Printf("%s\n\n%s\n\n", s, t)
}
Ejemplo n.º 6
0
func Test_RISExamples(t *testing.T) {

	Convey("RIS Examples", t, func() {
		Convey("PxrConstant -- bxdf shader", func() {

			cuser, err := user.Current()
			So(err, ShouldBeNil)

			pipe := DefaultFilePipe()
			So(pipe, ShouldNotBeNil)

			ctx := NewContext(pipe, nil, &Configuration{PrettyPrint: true})
			ri := RI(ctx)

			ri.Begin("output/risBxdfPxrConstant.rib")
			ri.ArchiveRecord("structure", "Scene Bxdf Constant")
			ri.ArchiveRecord("structure", "Creator %s", Author)
			ri.ArchiveRecord("structure", "CreationDate %s", time.Now())
			ri.ArchiveRecord("structure", "For %s", cuser.Username)
			ri.ArchiveRecord("structure", "Frames 1")

			ri.Display("risbxdf_sphere.tif", "file", "rgb")
			ri.Format(320, 240, 1)
			ri.PixelFilter(GaussianFilter, 4, 4)
			ri.Imager("background", RtToken("color color"), RtColor{.6, .6, .6}, RtToken("float alpha"), RtFloat(1))

			ri.Projection(PERSPECTIVE, RtToken("fov"), RtFloat(30))
			ri.Translate(0, 0, 6)
			ri.WorldBegin()
			ri.Color(RtColor{1, 0, 0})

			/* wrap the context with the RIS interface */
			ris := RIS(ctx)

			/* first we setup a pattern RIS */
			pattern, err := ris.Pattern("PxrHSL", "-")
			So(err, ShouldBeNil)
			So(pattern, ShouldNotBeNil)
			So(pattern.Name(), ShouldEqual, "PxrHSL")

			w := pattern.Widget("inputRGB")
			So(w, ShouldNotBeNil)
			So(w.SetValue(RtColor{0, 0, 0.3}), ShouldBeNil)

			ri.Pattern(pattern.Name(), pattern.Handle(), RtToken("inputRGB"), RtColor{0, 0, 0.3})

			/* load the PxrConstant bxdf shader, $RMANTREE/lib/RIS/bxdf/Args/PxrConstant.args is parsed
			 * for the constant shader.
			 */
			constant, err := ris.Bxdf("PxrConstant", "-")
			So(err, ShouldBeNil)
			So(constant, ShouldNotBeNil)

			/* we want to manipulate the emit color of the shader so we
			 * ask the shader for the widget interface
			 */
			w = constant.Widget("emitColor")
			So(w, ShouldNotBeNil)

			/* set the color via the widget; SetValue(Rter) */
			So(w.SetValue(RtColor{0.3, 0.2, 0.1}), ShouldBeNil)

			/* we know it's a color so we can convert directly to the
			 * RtColorWidget concrete type
			 */
			cw, ok := w.(*RtColorWidget)
			So(ok, ShouldBeTrue)
			So(cw, ShouldNotBeNil)

			/* we can directly set the color via our RtColorWidget :
			 * overriding our previous SetValue
			 */
			So(cw.Set(RtColor{0.1, 0.2, 0.3}), ShouldBeNil)

			/* As the widget (w & cw) is linked to the shader (constant), we can override
			 * what we set with the widget directly at the shader */
			So(constant.SetValue(RtToken("emitColor"), RtColor{0.45, 0.45, 0.45}), ShouldBeNil)
			/* The widget should be in sync with what we set at the shader */
			So(cw.Value().Equal(RtColor{0.45, 0.45, 0.45}), ShouldBeTrue)

			/* Here we over the shader again by including the emitColor inline; the constant.Handle()
			 * includes the handle created for the shader */
			ri.Bxdf("PxrConstant", constant.Handle(), RtToken("color emitColor"), RtColor{1, 0.25, 0.25})

			/* now instead we can reference the pattern we set earlier and replace the emitColor with a reference */
			refid := pattern.ReferenceOutput("resultRGB")
			So(refid, ShouldEqual, fmt.Sprintf("%s:resultRGB", string(pattern.Handle())))
			So(constant.SetReferencedValue("emitColor", refid), ShouldBeNil)

			/* this is another way of writing our shader : using the emitColor that we actually set above */
			ri.Bxdf(constant.Name(), constant.Handle())

			ri.Sphere(1, -1, 1, 360)
			ri.WorldEnd()

			So(ri.End(), ShouldBeNil)

			/* gather and print the statistics and time the
			 * pipe took */
			p := pipe.GetByName(PipeToStats{}.Name())
			So(p, ShouldNotBeNil)
			s, ok := p.(*PipeToStats)
			So(s, ShouldNotBeNil)
			So(ok, ShouldBeTrue)

			p = pipe.GetByName(PipeTimer{}.Name())
			So(p, ShouldNotBeNil)
			t, ok := p.(*PipeTimer)
			So(t, ShouldNotBeNil)
			So(ok, ShouldBeTrue)

			fmt.Printf("%s%s", s, t)
		})
	})
}
Ejemplo n.º 7
0
func Test_ExampleD14(t *testing.T) {

	Convey("Example D1.4", t, func() {

		sgroup := RtToken("shadinggroup")
		frames := 2
		cuser, err := user.Current()
		So(err, ShouldBeNil)

		ri, pipe := DefaultPipeline(&Configuration{PrettyPrint: true})
		ri.Begin("output/exampleD14.rib")
		ri.ArchiveRecord("structure", "Scene Bouncing Ball")
		ri.ArchiveRecord("structure", "Creator %s", Author)
		ri.ArchiveRecord("structure", "CreationDate %s", time.Now())
		ri.ArchiveRecord("structure", "For %s", cuser.Username)
		ri.ArchiveRecord("structure", "Frames %d", frames)
		ri.ArchiveRecord("structure", "Shaders PIXARmarble, PIXARwood, MyUserShader")
		ri.ArchiveRecord("structure", "CapabilitiesNeeded ShadingLanguage Displacements")
		ri.Declare("d", "uniform point")
		ri.Declare("squish", "uniform float")
		ri.Option("limits", RtToken("bucketsize"), RtIntArray{6, 6})
		ri.Option("limits", RtToken("gridsize"), RtIntArray{18})
		ri.Format(1024, 768, 1)
		ri.Projection(PERSPECTIVE)
		ri.Clipping(10, 1000.0)

		ri.FrameBegin(1)
		ri.ArchiveRecord("structure", "Shaders PIXARmarble, PIXARwood")
		ri.ArchiveRecord("structure", "CameraOrientation %.1f %.1f %.1f %.1f %.1f %.1f", 10., 10., 10., 0., 0., 0.)
		ri.Transform(RtMatrix{.707107, -.408248, 0.57735, 0, 0, .816497, -.57735, 0, -.707107, -.408248, -.57735, 0, 0, 0, 17.3205, 1})
		ri.WorldBegin()
		ri.AttributeBegin()
		ri.Attribute("identifier", RtToken("name"), RtString("myball"))
		ri.Displacement("MyUserShader", RtToken("squish"), RtInt(5))
		ri.AttributeBegin()
		ri.Attribute("identifier", sgroup, RtStringArray{"tophalf"})
		ri.Surface("plastic")
		ri.Sphere(.5, -.5, 0, 360)
		ri.AttributeEnd()
		ri.AttributeBegin()
		ri.Attribute("identifier", sgroup, RtStringArray{"bothalf"})
		ri.Surface("PIXARmarble")
		ri.Sphere(.5, 0, .5, 360)
		ri.AttributeEnd()
		ri.AttributeEnd()
		ri.AttributeBegin()
		ri.Attribute("identifier", RtToken("name"), RtStringArray{"floor"})
		ri.Surface("PIXARwood", RtToken("roughness"), RtFloatArray{.3}, RtToken("d"), RtIntArray{1})
		ri.Comment("geometry for floor")
		ri.Polygon(4, RtToken("P"), RtFloatArray{-100, 0, -100, -100, 0, 100, 100, 0, 100, 10, 0, -100})
		ri.AttributeEnd()
		ri.WorldEnd()
		ri.FrameEnd()

		ri.FrameBegin(2)
		ri.ArchiveRecord("structure", "Shaders PIXARwood, PIXARmarbles")
		ri.ArchiveRecord("structure", "CameraOrientation %.1f %.1f %.1f %.1f %.1f %.1f", 10., 20., 10., 0., 0., 0.)
		ri.Transform(RtMatrix{.707107, -.57735, -.408248, 0, 0, .57735, -.815447, 0, -.707107, -.57735, -.408248, 0, 0, 0, 24.4949, 1})
		ri.WorldBegin()
		ri.AttributeBegin()
		ri.Attribute("identifier", RtToken("name"), RtStringArray{"myball"})
		ri.AttributeBegin()
		ri.Attribute("identifier", sgroup, RtStringArray{"tophalf"})
		ri.Surface("PIXARmarble")
		ri.ShadingRate(.1)
		ri.Sphere(.5, 0, .5, 360)
		ri.AttributeEnd()
		ri.AttributeBegin()
		ri.Attribute("identifier", sgroup, RtStringArray{"bothalf"})
		ri.Surface("plastic")
		ri.Sphere(.5, -.5, 0, 360)
		ri.AttributeEnd()
		ri.AttributeEnd()
		ri.AttributeBegin()
		ri.Attribute("identifier", RtToken("name"), RtStringArray{"floor"})
		ri.Surface("PIXARwood", RtToken("roughness"), RtFloatArray{.3}, RtToken("d"), RtIntArray{1})
		ri.Comment("geometry for floor")
		ri.Polygon(4, RtToken("P"), RtFloatArray{-100, 0, -100, -100, 0, 100, 100, 0, 100, 10, 0, -100})
		ri.AttributeEnd()
		ri.WorldEnd()
		ri.FrameEnd()

		So(ri.End(), ShouldBeNil)

		/* output gathered stats */
		p := pipe.GetByName(PipeToStats{}.Name())
		So(p, ShouldNotBeNil)
		s, ok := p.(*PipeToStats)
		So(s, ShouldNotBeNil)
		So(ok, ShouldBeTrue)

		p = pipe.GetByName(PipeTimer{}.Name())
		So(p, ShouldNotBeNil)
		t, ok := p.(*PipeTimer)
		So(t, ShouldNotBeNil)
		So(ok, ShouldBeTrue)

		fmt.Printf("%s%s", s, t)
	})
}