<?xml version="1.0" encoding="UTF-8" standalone="yes"?><oembed><version><![CDATA[1.0]]></version><provider_name><![CDATA[Ondrej Paska Blog]]></provider_name><provider_url><![CDATA[https://fishtrone.wordpress.com]]></provider_url><author_name><![CDATA[Ondrej Paska]]></author_name><author_url><![CDATA[https://fishtrone.wordpress.com/author/randalfien/]]></author_url><title><![CDATA[Unity &#8220;Long exposure&#8221;&nbsp;VFX]]></title><type><![CDATA[link]]></type><html><![CDATA[<p>I wanted to make an effect like what you get when you take a long exposure picture of a the night sky &#8211; the stars get stretched because of Earth&#8217;s rotation.</p>
<p><img loading="lazy" data-attachment-id="76" data-permalink="https://fishtrone.wordpress.com/2020/04/16/unity-long-exposure-vfx/pexels-photo-169789/" data-orig-file="https://fishtrone.files.wordpress.com/2020/04/pexels-photo-169789.jpeg" data-orig-size="2250,1500" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="pexels-photo-169789" data-image-description="" data-image-caption="" data-medium-file="https://fishtrone.files.wordpress.com/2020/04/pexels-photo-169789.jpeg?w=300" data-large-file="https://fishtrone.files.wordpress.com/2020/04/pexels-photo-169789.jpeg?w=1024" class="alignnone size-full wp-image-76" src="https://fishtrone.files.wordpress.com/2020/04/pexels-photo-169789.jpeg?w=900&#038;h=500" alt="pexels-photo-169789" width="900" height="500" /></p>
<p>I first created about 500 star sprites in the scene in a rough half circle. I created a new layer called Stars.</p>
<p>I used a second camera to render the stars to a <a href="https://docs.unity3d.com/ScriptReference/RenderTexture.html" target="_blank" rel="noopener">RenderTexture.</a> That means the camera will not output to the screen but instead into a texture. In Unity you do this by assigning the <strong>Target Texture</strong> field of the camera.</p>
<p>The trick to retain everything from the previous render is to select the <strong>Don&#8217;t Clear</strong> option in the Clear Flags field of the camera. The <strong>Culling Mask</strong> field is used to tell the camera what layers it should render.</p>
<p><img loading="lazy" data-attachment-id="79" data-permalink="https://fishtrone.wordpress.com/2020/04/16/unity-long-exposure-vfx/captureasdf/" data-orig-file="https://fishtrone.files.wordpress.com/2020/04/captureasdf.png" data-orig-size="275,71" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Captureasdf" data-image-description="" data-image-caption="" data-medium-file="https://fishtrone.files.wordpress.com/2020/04/captureasdf.png?w=275" data-large-file="https://fishtrone.files.wordpress.com/2020/04/captureasdf.png?w=275" class="alignnone size-full wp-image-79" src="https://fishtrone.files.wordpress.com/2020/04/captureasdf.png?w=275&#038;h=71" alt="Captureasdf" width="275" height="71" srcset="https://fishtrone.files.wordpress.com/2020/04/captureasdf.png 275w, https://fishtrone.files.wordpress.com/2020/04/captureasdf.png?w=150&amp;h=39 150w" sizes="(max-width: 275px) 100vw, 275px" /></p>
<p>To actually display the texture, I created a fullscreen Quad in the scene and added the render texture as a main texture to a unlit shader. I added a tween to rotate the stars and voilà:</p>
<p><img loading="lazy" data-attachment-id="80" data-permalink="https://fishtrone.wordpress.com/2020/04/16/unity-long-exposure-vfx/ezgif-com-optimize/" data-orig-file="https://fishtrone.files.wordpress.com/2020/04/ezgif.com-optimize.gif" data-orig-size="600,340" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="ezgif.com-optimize" data-image-description="" data-image-caption="" data-medium-file="https://fishtrone.files.wordpress.com/2020/04/ezgif.com-optimize.gif?w=300" data-large-file="https://fishtrone.files.wordpress.com/2020/04/ezgif.com-optimize.gif?w=600" class="alignnone size-full wp-image-80" src="https://fishtrone.files.wordpress.com/2020/04/ezgif.com-optimize.gif?w=600&#038;h=340" alt="ezgif.com-optimize" width="600" height="340" /></p>
<p>Well&#8230; almost! could we just clear the texture &#8220;a little&#8221; every frame to make the &#8220;tails&#8221; dissappear with time? On the CPU this could be done by the ReadPixels and SetPixels of the RenderTexture. But a faster way is to do it on the GPU with a shader!</p>
<p>Don&#8217;t worry &#8211; it&#8217;s very simple. You can create a shader with all the boilerplate code by right clicking the project window and selecting Create-&gt;Shader-&gt;UnlitShader.</p>
<p><!-- HTML generated using hilite.me -->Now we use the <strong>frag</strong> function, which is called for each individual pixel, to decrease the alpha value by a small amount each frame.</p>
<div style="background:#f8f8f8;overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;">
<pre style="margin:0;line-height:125%;"><span style="color:#000000;">fixed4</span> <span style="color:#000000;">frag</span> <span style="color:#000000;font-weight:bold;">(</span><span style="color:#000000;">v2f</span> <span style="color:#000000;">i</span><span style="color:#000000;font-weight:bold;">)</span> <span style="color:#ce5c00;font-weight:bold;">:</span> <span style="color:#000000;">SV_Target</span>
<span style="color:#000000;font-weight:bold;">{</span>
    <span style="color:#000000;">fixed4</span> <span style="color:#000000;">tx</span> <span style="color:#ce5c00;font-weight:bold;">=</span> <span style="color:#000000;">tex2D</span><span style="color:#000000;font-weight:bold;">(</span><span style="color:#000000;">_MainTex</span><span style="color:#000000;font-weight:bold;">,</span> <span style="color:#000000;">i</span><span style="color:#000000;font-weight:bold;">.</span><span style="color:#000000;">uv</span><span style="color:#000000;font-weight:bold;">);</span>
    <span style="color:#000000;">tx</span><span style="color:#000000;font-weight:bold;">.</span><span style="color:#000000;">a</span> <span style="color:#ce5c00;font-weight:bold;">*=</span> <span style="color:#0000cf;font-weight:bold;">0.96</span><span style="color:#000000;font-weight:bold;">;</span>
    <span style="color:#204a87;font-weight:bold;">if</span><span style="color:#000000;font-weight:bold;">(</span> <span style="color:#000000;">tx</span><span style="color:#000000;font-weight:bold;">.</span><span style="color:#000000;">a</span> <span style="color:#ce5c00;font-weight:bold;">&lt;</span> <span style="color:#0000cf;font-weight:bold;">0.1</span><span style="color:#000000;font-weight:bold;">)</span>
    <span style="color:#000000;font-weight:bold;">{</span>
       <span style="color:#000000;">tx</span> <span style="color:#ce5c00;font-weight:bold;">*=</span> <span style="color:#0000cf;font-weight:bold;">0</span><span style="color:#000000;font-weight:bold;">;</span>
    <span style="color:#000000;font-weight:bold;">}</span>
    <span style="color:#204a87;font-weight:bold;">return</span> <span style="color:#000000;">tx</span><span style="color:#000000;font-weight:bold;">;</span>
<span style="color:#000000;font-weight:bold;">}</span>
</pre>
</div>
<p>&nbsp;</p>
<p>To actually use this shader, we first need to create a material that uses it. Then we use the <a href="https://docs.unity3d.com/ScriptReference/Graphics.Blit.html">Graphics.Blit</a> function to run a texture through it. This function copies data from one texture to another and also applies a material on it. Because it is not allowed to Blit from a texture into itself, we need to create two RenderTextures and swap between them.<!-- HTML generated using hilite.me --></p>
<div style="background:#f8f8f8;overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;">
<pre style="margin:0;line-height:125%;"><span style="color:#008000;font-weight:bold;">public</span> <span style="color:#008000;font-weight:bold;">void</span> <span style="color:#0000ff;">OnPreRender</span>()
{
    Graphics.Blit(_renderTexture, _renderTextureTemp, _dimStarsMat);
    <span style="color:#b00040;">var</span> temp = _renderTexture; // swap
    _renderTexture = _renderTextureTemp;
    _renderTextureTemp = temp;
}</pre>
</div>
<p>A good place to call this code is in the OnPreRender callback which gets called on all scripts attached to a camera.</p>
<p>And that&#8217;s it! The finished effect now looks like this:</p>
<p><img loading="lazy" data-attachment-id="74" data-permalink="https://fishtrone.wordpress.com/2020/04/16/unity-long-exposure-vfx/hnet-image/" data-orig-file="https://fishtrone.files.wordpress.com/2020/04/hnet-image.gif" data-orig-size="900,500" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="Hnet-image" data-image-description="" data-image-caption="" data-medium-file="https://fishtrone.files.wordpress.com/2020/04/hnet-image.gif?w=300" data-large-file="https://fishtrone.files.wordpress.com/2020/04/hnet-image.gif?w=900" class="alignnone size-full wp-image-74" src="https://fishtrone.files.wordpress.com/2020/04/hnet-image.gif?w=900&#038;h=500" alt="Hnet-image" width="900" height="500" /></p>
<p>The technique has many other uses. I tweaked the shader and added a displacement texture to create this ghostly smiley: <!-- HTML generated using hilite.me --></p>
<div style="background:#f8f8f8;overflow:auto;width:auto;border:solid gray;border-width:.1em .1em .1em .8em;padding:.2em .6em;">
<pre style="margin:0;line-height:125%;"><span style="color:#000000;">fixed4</span> <span style="color:#000000;">frag</span> <span style="color:#000000;font-weight:bold;">(</span><span style="color:#000000;">v2f</span> <span style="color:#000000;">i</span><span style="color:#000000;font-weight:bold;">)</span> <span style="color:#ce5c00;font-weight:bold;">:</span> <span style="color:#000000;">SV_Target</span>
<span style="color:#000000;font-weight:bold;">{</span>
    <span style="color:#000000;">fixed4</span> <span style="color:#000000;">noise</span> <span style="color:#ce5c00;font-weight:bold;">=</span> <span style="color:#000000;">tex2D</span><span style="color:#000000;font-weight:bold;">(</span><span style="color:#000000;">_NoiseTex</span><span style="color:#000000;font-weight:bold;">,</span> <span style="color:#000000;">i</span><span style="color:#000000;font-weight:bold;">.</span><span style="color:#000000;">uv</span><span style="color:#ce5c00;font-weight:bold;">+</span><span style="color:#000000;">fixed2</span><span style="color:#000000;font-weight:bold;">(</span><span style="color:#0000cf;font-weight:bold;">0</span><span style="color:#000000;font-weight:bold;">,</span><span style="color:#000000;">_Time</span><span style="color:#000000;font-weight:bold;">.</span><span style="color:#000000;">x</span><span style="color:#ce5c00;font-weight:bold;">*</span><span style="color:#0000cf;font-weight:bold;">8</span><span style="color:#000000;font-weight:bold;">));</span>
    <span style="color:#000000;">fixed2</span> <span style="color:#000000;">displ</span> <span style="color:#ce5c00;font-weight:bold;">=</span> <span style="color:#000000;font-weight:bold;">(</span><span style="color:#000000;">noise</span><span style="color:#000000;font-weight:bold;">.</span><span style="color:#000000;">rg</span> <span style="color:#ce5c00;font-weight:bold;">-</span> <span style="color:#0000cf;font-weight:bold;">0.5</span><span style="color:#000000;font-weight:bold;">)</span><span style="color:#ce5c00;font-weight:bold;">*</span><span style="color:#000000;">_DisplAmount</span><span style="color:#ce5c00;font-weight:bold;">*</span><span style="color:#0000cf;font-weight:bold;">0.01</span><span style="color:#000000;font-weight:bold;">;</span>
    <span style="color:#000000;">fixed4</span> <span style="color:#000000;">tx</span> <span style="color:#ce5c00;font-weight:bold;">=</span> <span style="color:#000000;">tex2D</span><span style="color:#000000;font-weight:bold;">(</span><span style="color:#000000;">_MainTex</span><span style="color:#000000;font-weight:bold;">,</span> <span style="color:#000000;">i</span><span style="color:#000000;font-weight:bold;">.</span><span style="color:#000000;">uv</span><span style="color:#ce5c00;font-weight:bold;">+</span><span style="color:#000000;">displ</span><span style="color:#000000;font-weight:bold;">);</span>
    <span style="color:#000000;">tx</span><span style="color:#000000;font-weight:bold;">.</span><span style="color:#000000;">a</span> <span style="color:#ce5c00;font-weight:bold;">*=</span> <span style="color:#0000cf;font-weight:bold;">0.96</span><span style="color:#000000;font-weight:bold;">;</span>
    <span style="color:#204a87;font-weight:bold;">if</span><span style="color:#000000;font-weight:bold;">(</span> <span style="color:#000000;">tx</span><span style="color:#000000;font-weight:bold;">.</span><span style="color:#000000;">a</span> <span style="color:#ce5c00;font-weight:bold;">&lt;</span> <span style="color:#0000cf;font-weight:bold;">0.1</span><span style="color:#000000;font-weight:bold;">)</span>
    <span style="color:#000000;font-weight:bold;">{</span>
        <span style="color:#000000;">tx</span> <span style="color:#ce5c00;font-weight:bold;">*=</span> <span style="color:#0000cf;font-weight:bold;">0</span><span style="color:#000000;font-weight:bold;">;</span>
    <span style="color:#000000;font-weight:bold;">}</span>
    <span style="color:#204a87;font-weight:bold;">return</span> <span style="color:#000000;">tx</span><span style="color:#000000;font-weight:bold;">;</span>
<span style="color:#000000;font-weight:bold;">}</span>
</pre>
</div>
<p><img loading="lazy" data-attachment-id="78" data-permalink="https://fishtrone.wordpress.com/2020/04/16/unity-long-exposure-vfx/gifduch/" data-orig-file="https://fishtrone.files.wordpress.com/2020/04/gifduch.gif" data-orig-size="600,333" data-comments-opened="1" data-image-meta="{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;,&quot;orientation&quot;:&quot;0&quot;}" data-image-title="gifDuch" data-image-description="" data-image-caption="" data-medium-file="https://fishtrone.files.wordpress.com/2020/04/gifduch.gif?w=300" data-large-file="https://fishtrone.files.wordpress.com/2020/04/gifduch.gif?w=600" class="alignnone size-full wp-image-78" src="https://fishtrone.files.wordpress.com/2020/04/gifduch.gif?w=600&#038;h=333" alt="gifDuch" width="600" height="333" /><br />
This was just a brief overview of how this effect works, find the <a href="https://github.com/randalfien/unity-temporal-vfx">full source code on github</a>.</p>
<p>What do you think? Is there a simpler way to achieve a similar effect? Let me know in the comments or <a href="https://twitter.com/OndraPaska" target="_blank" rel="noopener">on Twitter</a>.</p>
]]></html><thumbnail_url><![CDATA[https://fishtrone.files.wordpress.com/2020/04/ezgif.com-optimize.gif?fit=440%2C330]]></thumbnail_url><thumbnail_width><![CDATA[440]]></thumbnail_width><thumbnail_height><![CDATA[249]]></thumbnail_height></oembed>