11using System ;
22using System . Collections . Generic ;
3+ using System . IO ;
4+ using System . Linq ;
35
46namespace UnityEngine . FrameRecorder . Input
57{
@@ -145,6 +147,8 @@ public override void NewFrameStarting(RecordingSession session)
145147 {
146148 case EImageSource . GameDisplay :
147149 {
150+ bool sort = false ;
151+
148152 // Find all cameras targetting Display
149153 foreach ( var cam in Resources . FindObjectsOfTypeAll < Camera > ( ) )
150154 {
@@ -166,6 +170,12 @@ public override void NewFrameStarting(RecordingSession session)
166170 hookedCam = new HookedCamera ( ) { camera = cam , textureBackup = cam . targetTexture } ;
167171 cam . targetTexture = m_renderRT ;
168172 m_hookedCameras . Add ( hookedCam ) ;
173+ sort = true ;
174+ }
175+
176+ if ( sort )
177+ {
178+ m_hookedCameras = m_hookedCameras . OrderBy ( x => x . camera . depth ) . ToList ( ) ;
169179 }
170180 break ;
171181 }
@@ -186,6 +196,7 @@ public override void NewFrameStarting(RecordingSession session)
186196 break ;
187197
188198 var hookedCam = new HookedCamera ( ) { camera = cam , textureBackup = cam . targetTexture } ;
199+ cam . targetTexture = m_renderRT ;
189200 m_hookedCameras . Add ( hookedCam ) ;
190201 break ;
191202 }
@@ -227,33 +238,23 @@ protected override void Dispose(bool disposing)
227238
228239 public override void NewFrameReady ( RecordingSession session )
229240 {
230- foreach ( var hookedCam in m_hookedCameras )
231- {
232- RenderTexture src ;
233- if ( adamSettings . m_SuperSampling == ESuperSamplingCount . x1 || hookedCam . textureBackup == hookedCam . camera . targetTexture )
234- {
235- src = hookedCam . camera . targetTexture ;
236- }
237- else
238- {
239- src = PerformSubSampling ( hookedCam . camera ) ;
240- }
241+ PerformSubSampling ( ) ;
241242
242- if ( adamSettings . m_RenderSize == adamSettings . m_FinalSize )
243- {
244- // Blit with normalization if sizes match.
245- m_normalizeMaterial . SetFloat ( "_NormalizationFactor" , 1.0f / ( float ) adamSettings . m_SuperSampling ) ;
246- Graphics . Blit ( src , outputRT , m_normalizeMaterial ) ;
247- }
248- else
249- {
250- // Ideally we would use a separable filter here, but we're massively bound by readback and disk anyway for hi-res.
251- m_superMaterial . SetVector ( "_Target_TexelSize" , new Vector4 ( 1f / m_outputWidth , 1f / m_outputHeight , m_outputWidth , m_outputHeight ) ) ;
252- m_superMaterial . SetFloat ( "_KernelCosPower ", adamSettings . m_SuperKernelPower ) ;
253- m_superMaterial . SetFloat ( "_KernelScale " , adamSettings . m_SuperKernelScale ) ;
254- m_superMaterial . SetFloat ( "_NormalizationFactor " , 1.0f / ( float ) adamSettings . m_SuperSampling ) ;
255- Graphics . Blit ( src , outputRT , m_superMaterial ) ;
256- }
243+ if ( adamSettings . m_RenderSize == adamSettings . m_FinalSize )
244+ {
245+ // Blit with normalization if sizes match.
246+ m_normalizeMaterial . SetFloat ( "_NormalizationFactor" , 1.0f / ( float ) adamSettings . m_SuperSampling ) ;
247+ Graphics . Blit ( m_renderRT , outputRT , m_normalizeMaterial ) ;
248+ SaveRT ( outputRT ) ;
249+ }
250+ else
251+ {
252+ // Ideally we would use a separable filter here, but we're massively bound by readback and disk anyway for hi-res.
253+ m_superMaterial . SetVector ( "_Target_TexelSize ", new Vector4 ( 1f / m_outputWidth , 1f / m_outputHeight , m_outputWidth , m_outputHeight ) ) ;
254+ m_superMaterial . SetFloat ( "_KernelCosPower " , adamSettings . m_SuperKernelPower ) ;
255+ m_superMaterial . SetFloat ( "_KernelScale " , adamSettings . m_SuperKernelScale ) ;
256+ m_superMaterial . SetFloat ( "_NormalizationFactor" , 1.0f / ( float ) adamSettings . m_SuperSampling ) ;
257+ Graphics . Blit ( m_renderRT , outputRT , m_superMaterial ) ;
257258 }
258259 }
259260
@@ -297,5 +298,67 @@ RenderTexture PerformSubSampling(Camera cam)
297298
298299 return dst ;
299300 }
301+
302+ void PerformSubSampling ( )
303+ {
304+ if ( adamSettings . m_SuperSampling == ESuperSamplingCount . x1 )
305+ return ;
306+
307+ if ( m_hookedCameras . Count == 1 )
308+ {
309+ Graphics . Blit ( PerformSubSampling ( m_hookedCameras [ 0 ] . camera ) , m_renderRT ) ;
310+ }
311+ else
312+ {
313+ RenderTexture accumulateInto = null ;
314+ m_renderRT . wrapMode = TextureWrapMode . Clamp ;
315+ m_renderRT . filterMode = FilterMode . Point ;
316+
317+ Graphics . SetRenderTarget ( m_accumulateRTs [ 0 ] ) ;
318+ GL . Clear ( false , true , Color . black ) ;
319+
320+ for ( int i = 0 , n = ( int ) adamSettings . m_SuperSampling ; i < n ; i ++ )
321+ {
322+ foreach ( var hookedCam in m_hookedCameras )
323+ {
324+ var cam = hookedCam . camera ;
325+
326+ // Render n times the camera and accumulate renders.
327+ var oldProjectionMatrix = cam . projectionMatrix ;
328+ ShiftProjectionMatrix ( cam , m_samples [ i ] - new Vector2 ( 0.5f , 0.5f ) ) ;
329+ cam . Render ( ) ;
330+ cam . projectionMatrix = oldProjectionMatrix ;
331+ }
332+
333+ accumulateInto = m_accumulateRTs [ ( i + 1 ) % 2 ] ;
334+ var accumulatedWith = m_accumulateRTs [ i % 2 ] ;
335+ m_accumulateMaterial . SetTexture ( "_PreviousTexture" , accumulatedWith ) ;
336+ Graphics . Blit ( m_renderRT , accumulateInto , m_accumulateMaterial ) ;
337+ }
338+
339+ Graphics . Blit ( accumulateInto , m_renderRT ) ;
340+ }
341+ }
342+
343+ void SaveRT ( RenderTexture input )
344+ {
345+
346+ var width = input . width ;
347+ var height = input . height ;
348+
349+ var tex = new Texture2D ( width , height , TextureFormat . RGBA32 , false ) ;
350+ var backupActive = RenderTexture . active ;
351+ RenderTexture . active = input ;
352+ tex . ReadPixels ( new Rect ( 0 , 0 , width , height ) , 0 , 0 ) ;
353+ tex . Apply ( ) ;
354+ RenderTexture . active = backupActive ;
355+
356+ byte [ ] bytes ;
357+ bytes = tex . EncodeToPNG ( ) ;
358+
359+ UnityHelpers . Destroy ( tex ) ;
360+
361+ File . WriteAllBytes ( "Recorder/DebugDump.png" , bytes ) ;
362+ }
300363 }
301364}
0 commit comments