/////////////////////////////////////////////// void FillTransparentPixelsByNearPixels2(ref ImageUtility.Image2D image, Vector2I[,] opacityImageNearestCellTable) { for (int y = 0; y < image.Size.Y; y++) { for (int x = 0; x < image.Size.X; x++) { var takeFrom = opacityImageNearestCellTable[x, y]; var pixel = image.GetPixelByte(new Vector2I(takeFrom.X, takeFrom.Y)); image.SetPixel(new Vector2I(x, y), pixel); //var transparent = opacityImage.GetPixel( new Vector2I( x, y ) ).ToVector3F() == Vector3F.Zero; //ColorByte pixel; //if( transparent ) //{ // var takeFrom = opacityImageNearestCellTable[ x, y ]; // pixel = image.GetPixelByte( new Vector2I( takeFrom.X, takeFrom.Y ) ); //} //else // pixel = image.GetPixelByte( new Vector2I( x, y ) ); //image.SetPixel( new Vector2I( x, y ), pixel ); } } }
void RenderMaterial(Component_Camera camera, string destRealFileName) { var renderToFile = RenderToFile; var scene = renderToFile.ParentRoot as Component_Scene; var textureFileNames = new string[5]; //ImageUtility.Image2D opacityImage = null; Vector2I[,] opacityImageNearestCellTable = null; //write textures for (int nChannel = 0; nChannel < 5; nChannel++) { var channel = (MaterialChannel)nChannel; Component_Image texture = null; Component_Image textureRead = null; try { //!!!!все каналы //!!!!какие еще параметры? var prefix = Path.GetFileNameWithoutExtension(destRealFileName) + "_"; string fileName = ""; switch (nChannel) { case 0: fileName = prefix + "Opacity.png"; break; case 1: fileName = prefix + "BaseColor.png"; break; case 2: fileName = prefix + "Metallic.png"; break; case 3: fileName = prefix + "Roughness.png"; break; case 4: fileName = prefix + "Normal.png"; break; } var fullPath = Path.Combine(Path.GetDirectoryName(destRealFileName), fileName); //create var resolution = renderToFile.Resolution.Value; PixelFormat format = PixelFormat.A8R8G8B8; texture = ComponentUtility.CreateComponent <Component_Image>(null, true, false); texture.CreateType = Component_Image.TypeEnum._2D; texture.CreateSize = resolution; texture.CreateMipmaps = false; texture.CreateFormat = format; texture.CreateUsage = Component_Image.Usages.RenderTarget; texture.CreateFSAA = 0; texture.Enabled = true; var renderTexture = texture.Result.GetRenderTarget(0, 0); var viewport = renderTexture.AddViewport(true, true); viewport.AttachedScene = scene; textureRead = ComponentUtility.CreateComponent <Component_Image>(null, true, false); textureRead.CreateType = Component_Image.TypeEnum._2D; textureRead.CreateSize = resolution; textureRead.CreateMipmaps = false; textureRead.CreateFormat = format; textureRead.CreateUsage = Component_Image.Usages.ReadBack | Component_Image.Usages.BlitDestination; textureRead.CreateFSAA = 0; textureRead.Enabled = true; //!!!! textureRead.Result.PrepareNativeObject(); var restorePipeline = scene.RenderingPipeline; var pipeline = ComponentUtility.CreateComponent <Component_RenderingPipeline_Default>(null, true, true); switch (nChannel) { case 0: pipeline.DebugMode = Component_RenderingPipeline_Basic.DebugModeEnum.Normal; break; case 1: pipeline.DebugMode = Component_RenderingPipeline_Basic.DebugModeEnum.BaseColor; break; case 2: pipeline.DebugMode = Component_RenderingPipeline_Basic.DebugModeEnum.Metallic; break; case 3: pipeline.DebugMode = Component_RenderingPipeline_Basic.DebugModeEnum.Roughness; break; case 4: pipeline.DebugMode = Component_RenderingPipeline_Basic.DebugModeEnum.Normal; break; } try { scene.RenderingPipeline = pipeline; scene.GetDisplayDevelopmentDataInThisApplicationOverride += Scene_GetDisplayDevelopmentDataInThisApplicationOverride; var cameraSettings = new Viewport.CameraSettingsClass(viewport, camera); viewport.Update(true, cameraSettings); //clear temp data viewport.RenderingContext.MultiRenderTarget_DestroyAll(); viewport.RenderingContext.DynamicTexture_DestroyAll(); } finally { scene.RenderingPipeline = restorePipeline; scene.GetDisplayDevelopmentDataInThisApplicationOverride -= Scene_GetDisplayDevelopmentDataInThisApplicationOverride; } texture.Result.GetRealObject(true).BlitTo(viewport.RenderingContext.CurrentViewNumber, textureRead.Result.GetRealObject(true), 0, 0); //!!!!pitch //get data var totalBytes = PixelFormatUtility.GetNumElemBytes(format) * resolution.X * resolution.Y; var data = new byte[totalBytes]; unsafe { fixed(byte *pBytes = data) { var demandedFrame = textureRead.Result.GetRealObject(true).Read((IntPtr)pBytes, 0); while (RenderingSystem.CallBgfxFrame() < demandedFrame) { } } } var image = new ImageUtility.Image2D(format, resolution, data); if (channel == MaterialChannel.Opacity) { //convert pixels for (int y = 0; y < image.Size.Y; y++) { for (int x = 0; x < image.Size.X; x++) { var pixel = image.GetPixel(new Vector2I(x, y)); if (pixel.ToVector3F() != Vector3F.Zero) { pixel = Vector4F.One; } else { pixel = Vector4F.Zero; } image.SetPixel(new Vector2I(x, y), pixel); } } //opacityImageNearestCellTable if (renderToFile.FillTransparentPixelsByNearPixels) { var boolOpacityImage = new bool[image.Size.X, image.Size.Y]; for (int y = 0; y < image.Size.Y; y++) { for (int x = 0; x < image.Size.X; x++) { var c = image.GetPixelByte(new Vector2I(x, y)); boolOpacityImage[x, y] = c.Red == 0; } } var distanceMap = GetDistanceMap(image); opacityImageNearestCellTable = new Vector2I[image.Size.X, image.Size.Y]; for (int y = 0; y < image.Size.Y; y++) { for (int x = 0; x < image.Size.X; x++) { opacityImageNearestCellTable[x, y] = new Vector2I(x, y); } } var table = opacityImageNearestCellTable; //!!!!slowly Parallel.For(0, image.Size.Y, delegate(int y) //for( int y = 0; y < image.Size.Y; y++ ) { for (int x = 0; x < image.Size.X; x++) { var transparent = boolOpacityImage[x, y]; if (transparent) { for (int n = 0; n < distanceMap.Length; n++) //foreach( var indexItem in distanceMap ) { ref var indexItem = ref distanceMap[n]; var takeFrom = new Vector2I(x, y) + indexItem.offset; if (takeFrom.X >= 0 && takeFrom.X < image.Size.X && takeFrom.Y >= 0 && takeFrom.Y < image.Size.Y) { var transparent2 = boolOpacityImage[takeFrom.X, takeFrom.Y]; if (!transparent2) { table[x, y] = takeFrom; break; } } } } } }); } }