Unity exports particle light effects to PNG sequence frames

Source: Internet
Author: User
Tags set time

This function is not very practical, but the art students have such a demand, then spent a little time to study the next.

We didn't use Unity's engine, but the students who did the special effects found a bunch of unity particle effects and wanted to export it as a PNG sequence frame, and then we used the game. This is equivalent to working with unity as a special effects editor. This is not very "scary", because using phantom particles, or 3dmax, is almost the same idea, except that the software provides formal export functionality, while unity does not.

First on the code

Using unityengine;using unityeditor;using system;using system.io;using system.collections;using System.collections.generic;public class particleexporter:monobehaviour{//Default folder name where you want the ANI    Mations to is output public string folder = "Png_animations";                  Framerate at which-want to play the animation public int framerate = 25;              Export frame rate, set time.captureframerate will ignore the real time, directly use this frame rate of public float framecount = 100; Export frame count exports the number of frames, and 100 frames is equivalent to exporting 5 seconds of light-effect time.               Because the time to export each frame is long, the export time is much longer than the intuitive optical effect playback time public int screenwidth = 960;    Not the use is temporarily useless, you want to be able to directly set the size of the screen (that is, the size of the light effect canvas) public int screenheight = 640;    Public Vector3 cameraposition = Vector3.zero;    Public Vector3 camerarotation = Vector3.zero; private string realfolder = ""; Real folder where the output files would be private float originaltimescaletime;  Track the original time scale so we can freeze the animation between frames  private float currenttime = 0;    private bool over = FALSE;    private int currentindex = 0;    Private Camera Exportcamera; Camera for export exports the optical effect camera, using rendertexture public void Start () {//Set frame rate Time.capturefram        Erate = framerate; Create a folder that doesn ' t exist yet.        Append number if necessary.        Realfolder = path.combine (folder, name); Create the folder if (!        Directory.Exists (Realfolder)) {directory.createdirectory (Realfolder);        } originaltimescaletime = Time.timescale;        Gameobject Gocamera = Camera.main.gameObject;        if (cameraposition! = Vector3.zero) {goCamera.transform.position = cameraposition;        } if (camerarotation! = Vector3.zero) {goCamera.transform.rotation = Quaternion.euler (camerarotation);        } Gameobject go = Instantiate (Gocamera) as Gameobject; Exportcamera = go.        Getcomponent<camera> (); Currenttime = 0;        } void Update () {currenttime + = Time.deltatime;            if (!over && currentindex >= framecount) {over = true;            Cleanup ();            Debug.Log ("Finish");        Return    }//screenshot startcoroutine per frame (captureframe ());        } void Cleanup () {destroyimmediate (Exportcamera);    Destroyimmediate (Gameobject);        } IEnumerator Captureframe () {//Stop time Time.timescale = 0; Yield to next frame and then start the rendering//This is important, otherwise would have error yield re        Turn new Waitforendofframe ();        string filename = String.Format ("{0}/{1:d04}.png", Realfolder, ++currentindex);        Debug.Log (filename);        int width = screen.width;        int height = screen.height; Initialize and render textures rendertexture blackcamrendertexture = new Rendertexture (width, height, rendert        EXTUREFORMAT.ARGB32); RendertExture whitecamrendertexture = new Rendertexture (width, height, rendertextureformat.argb32);        Exportcamera.targettexture = blackcamrendertexture;        Exportcamera.backgroundcolor = Color.Black;        Exportcamera.render ();        Rendertexture.active = blackcamrendertexture;        Texture2d Texb = gettex2d ();        Now does it for Alpha Camera exportcamera.targettexture = whitecamrendertexture;        Exportcamera.backgroundcolor = Color.White;        Exportcamera.render ();        Rendertexture.active = whitecamrendertexture;        Texture2d TEXW = gettex2d (); If we have both textures then create final output texture if (Texw && texb) {texture2d OUTPU            Ttex = new Texture2d (width, height, textureformat.argb32, false); We need to check alpha Ourselves,because particle use additive shader//Create alpha from the difference be Tween black and white camera renders for (int y = 0; y < Outputtex.Height ++y) {//each row for (int x = 0, x < outputtex.width; ++x) {//each column float a                    Lpha; Alpha = Texw. GetPixel (x, y). R-texb.                    GetPixel (x, y). R;                    Alpha = 1.0f-alpha;                    Color color;                    if (alpha = = 0) {color = Color.clear; } else {color = Texb.                    GetPixel (x, y);                    } COLOR.A = Alpha; Outputtex.                SetPixel (x, y, color); }}//Encode the resulting output texture to a byte array then write to the file byte[] Pngshot = Outputtex.            Encodetopng ();            File.writeallbytes (filename, pngshot);            Cleanup, otherwise would memory leak pngshot = null;            Rendertexture.active = null;            Destroyimmediate (Outputtex);            Outputtex = null; Destroyimmediate (BlackcamrenDertexture);            Blackcamrendertexture = null;            Destroyimmediate (whitecamrendertexture);            Whitecamrendertexture = null;            Destroyimmediate (TEXB);            TEXB = null;            Destroyimmediate (TEXW);            TEXB = null;            System.GC.Collect ();            Reset the time scale and then move on to the next frame.        Time.timescale = Originaltimescaletime;        }}//Get the texture from the screens, render all or only half of the camera private texture2d gettex2d () {        Create a texture the size of the screen, RGB24 format int width = screen.width;        int height = screen.height;        Texture2d tex = new texture2d (width, height, textureformat.argb32, false); Read screen contents into the texture Tex.        Readpixels (New Rect (0, 0, width, height), 0, 0); Tex.        Apply ();    Return Tex; }}

Here are a few key points of knowledge to illustrate:

1, the overall idea is this, unity, adjust the camera, normal play effects, and then each frame screenshot, save as we need the PNG sequence frame. This is not only a special effect can be used, in fact, the model can be. For example, we need to display hundreds of thousands of people in the same screen, or insignificant monsters, scene objects and so on, can use this exported to 2d sequence frame, can greatly improve the efficiency, make some impossible situation become possible.

2, about the time and frame rate control. Since the time required to intercept a screen is much larger than the frame interval, the optical effect if it is played for 1 seconds, the export time may be more than one minute. Time.captureframerate can set the frame rate, then ignore the real time after setting, the light effect, the model will play according to the frame rate time. This interface happens to be used for video recording.

3, light effect canvas control. This is not a good way to find, because it is a full screen screenshot, so the size of the game window is the size of the light effect canvas.

4. Control the display information of the light effect by adjusting the position and rotation of the camera.

5, screenshot function is gettex2d (). The main thing here is the Readpixels function. It should be noted that the Captureframe function must be run in a co-process, because there is a yield return of new waitforendofframe (); If there is no such sentence, a mistake will be reported, It probably means that readpixels is not running inside Drawframe.

6, the screenshot time consumption is very large, so need to start using time.timescale=0 pause time in the screenshot to run, screen and then restore

7, pay attention to the screen after the completion of the removal of various resources, and GC. Otherwise the memory is probably not enough, cut 100 frames of pictures, memory is likely to be two or three G.

8, screenshot of the time using two rendertexture, respectively, draw white and black bottom of the picture, and then based on these two pictures to calculate the alpha. If it is not the light effect can actually not be so troublesome, directly to the camera's backgroundcolor in the Alpha set to 0 can be. But the light effect uses special shader, such as additive, where Alpha blend is involved. If you set this when you draw the light, the exported picture has nothing. So you have to have a real color background.

Unity exports particle light effects to PNG sequence frames

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.