protected override void WriteFrame(Texture2D tex) { byte[] bytes; Profiler.BeginSample("AOVRecorder.EncodeImage"); try { switch (Settings.outputFormat) { case AOVRecorderOutputFormat.EXR: { #if OIIO_AVAILABLE TypeDesc typedesc = new TypeDesc(TypeDesc.BASETYPE.HALF); var width = tex.width; var height = tex.height; int nchanels = 4; m_imgSpec = new ImageSpec(width, height, nchanels, typedesc); string comp = m_Settings.AOVCompression.ToString(); m_imgSpec.attribute("compression", comp); bytes = tex.GetRawTextureData(); string path = m_PathQueue.Dequeue(); m_imgOutput.open(path, m_imgSpec); GCHandle bufferHandle = GCHandle.Alloc(bytes, GCHandleType.Pinned); int scanwidth = width * nchanels * sizeof(float); int scanheight = nchanels * sizeof(float); int scanlinesize = (int)m_imgSpec.scanline_bytes(); TypeDesc odesc = new TypeDesc(TypeDesc.BASETYPE.FLOAT); m_imgOutput.write_image(odesc, new IntPtr(bufferHandle.AddrOfPinnedObject().ToInt64() + (height - 1) * scanwidth), scanheight, -scanwidth, Globals.AutoStride); bufferHandle.Free(); m_imgOutput.close(); #else bytes = tex.EncodeToEXR(); WriteToFile(bytes); #endif break; } case AOVRecorderOutputFormat.PNG: bytes = tex.EncodeToPNG(); WriteToFile(bytes); break; case AOVRecorderOutputFormat.JPEG: bytes = tex.EncodeToJPG(); WriteToFile(bytes); break; default: Profiler.EndSample(); throw new ArgumentOutOfRangeException(); } } finally { Profiler.EndSample(); } if (m_Inputs[0] is BaseRenderTextureInput || Settings.outputFormat != AOVRecorderOutputFormat.JPEG) { UnityHelpers.Destroy(tex); } }