internal virtual void RenderVectors( Camera camera, CommandBuffer renderCB, float scale, AmplifyMotion.Quality quality ) {}
	internal void OnRenderVectors( Camera camera, CommandBuffer renderCB, float scale, AmplifyMotion.Quality quality )
#endif
	{
		AmplifyMotion.MotionState state;
		if ( m_states.TryGetValue( camera, out state ) )
		{
			if ( !state.Error )
			{
			#if UNITY_4
				state.RenderVectors( camera, scale, quality );
			#else
				state.RenderVectors( camera, renderCB, scale, quality );
			#endif
			}
		}
	}
	internal virtual void RenderVectors( Camera camera, float scale, AmplifyMotion.Quality quality ) {}
	public void RenderVectors( float scale, float fixedScale, AmplifyMotion.Quality quality )
	public void RenderVectors( CommandBuffer renderCB, float scale, float fixedScale, AmplifyMotion.Quality quality )
#endif
	{
		if ( !m_initialized )
			Initialize();

		// For some reason Unity's own values weren't working correctly on Windows/OpenGL
		float near = m_camera.nearClipPlane;
		float far = m_camera.farClipPlane;
		Vector4 zparam;

		if ( AmplifyMotionEffectBase.IsD3D )
		{
			zparam.x = 1.0f - far / near;
			zparam.y = far / near;
		}
		else
		{
			// OpenGL
			zparam.x = ( 1.0f - far / near ) / 2.0f;
			zparam.y = ( 1.0f + far / near ) / 2.0f;
		}

		zparam.z = zparam.x / far;
		zparam.w = zparam.y / far;

		Shader.SetGlobalVector( "_AM_ZBUFFER_PARAMS", zparam );

		if ( m_affectedObjectsChanged )
			UpdateAffectedObjects();

		for ( int i = 0; i < m_affectedObjects.Length; i++ )
		{
			// don't render objects excluded via camera culling mask
			if ( ( m_camera.cullingMask & ( 1 << m_affectedObjects[ i ].gameObject.layer ) ) != 0 )
			{
			#if UNITY_4
				m_affectedObjects[ i ].OnRenderVectors( m_camera, m_affectedObjects[ i ].FixedStep ? fixedScale : scale, quality );
			#else
				m_affectedObjects[ i ].OnRenderVectors( m_camera, renderCB, m_affectedObjects[ i ].FixedStep ? fixedScale : scale, quality );
			#endif
			}
		}
	}
	internal void OnRenderVectors( Camera camera, float scale, AmplifyMotion.Quality quality )
	{
		AmplifyMotion.MotionState state = null;
		if ( m_states.TryGetValue( Camera.current, out state ) )
		{
			if ( !state.Error )
				state.RenderVectors( camera, scale, quality );
		}
	}
	internal override void RenderVectors( Camera camera, float scale, AmplifyMotion.Quality quality )
	{
		Profiler.BeginSample( "Skinned.Render" );

		if ( m_initialized && !m_error && m_renderer.isVisible )
		{
			WaitForAsyncUpdate();

			m_clonedMesh.vertices = m_currVertices;
			m_clonedMesh.normals = m_prevVertices;

			const float rcp255 = 1 / 255.0f;
			int objectId = m_mask ? m_owner.Instance.GenerateObjectId( m_obj.gameObject ) : 255;

			Shader.SetGlobalFloat( "_EFLOW_OBJECT_ID", objectId * rcp255 );
			Shader.SetGlobalFloat( "_EFLOW_MOTION_SCALE", m_mask ? scale : 0 );

			int qualityPass = ( quality == AmplifyMotion.Quality.Mobile ) ? 0 : 2;

			for ( int i = 0; i < m_sharedMaterials.Length; i++ )
			{
				MaterialDesc matDesc = m_sharedMaterials[ i ];
				int pass = qualityPass + ( matDesc.coverage ? 1 : 0 );

				if ( matDesc.coverage )
				{
					m_owner.Instance.SkinnedVectorsMaterial.mainTexture = matDesc.material.mainTexture;
					if ( matDesc.cutoff )
						m_owner.Instance.SkinnedVectorsMaterial.SetFloat( "_Cutoff", matDesc.material.GetFloat( "_Cutoff" ) );
				}

				if ( m_owner.Instance.SkinnedVectorsMaterial.SetPass( pass ) )
					Graphics.DrawMeshNow( m_clonedMesh, m_obj.transform.localToWorldMatrix, i );
			}
		}

		Profiler.EndSample();
	}
	internal override void RenderVectors( Camera camera, CommandBuffer renderCB, float scale, AmplifyMotion.Quality quality )
	{
		if ( m_initialized && !m_error && m_renderer.isVisible )
		{
			Profiler.BeginSample( "Skinned.Update" );

			if ( !m_useFallback )
			{
				if ( !m_useGPU )
					WaitForAsyncUpdate();
			}

			Profiler.EndSample();

			Profiler.BeginSample( "Skinned.Render" );
			if ( !m_useGPU )
			{
				if ( !m_useFallback )
					m_clonedMesh.vertices = m_currVertices;
				m_clonedMesh.normals = m_prevVertices;
			}

			const float rcp255 = 1 / 255.0f;
			bool mask = ( m_owner.Instance.CullingMask & ( 1 << m_obj.gameObject.layer ) ) != 0;
			int objectId = mask ? m_owner.Instance.GenerateObjectId( m_obj.gameObject ) : 255;

			Matrix4x4 prevModelViewProj;
			if ( m_obj.FixedStep )
				prevModelViewProj = m_owner.PrevViewProjMatrixRT * m_currLocalToWorld;
			else
				prevModelViewProj = m_owner.PrevViewProjMatrixRT * m_prevLocalToWorld;

			renderCB.SetGlobalMatrix( "_AM_MATRIX_PREV_MVP", prevModelViewProj );
			renderCB.SetGlobalFloat( "_AM_OBJECT_ID", objectId * rcp255 );
			renderCB.SetGlobalFloat( "_AM_MOTION_SCALE", mask ? scale : 0 );

			if ( m_useGPU )
			{
			#if !UNITY_4
				Vector4 vertexTexelSize = new Vector4( 1.0f / m_gpuVertexTexWidth, 1.0f / m_gpuVertexTexHeight, m_gpuVertexTexWidth, m_gpuVertexTexHeight );

				renderCB.SetGlobalVector( "_AM_VERTEX_TEXEL_SIZE", vertexTexelSize );
				renderCB.SetGlobalVector( "_AM_VERTEX_TEXEL_HALFSIZE", vertexTexelSize * 0.5f );

				renderCB.SetGlobalTexture( "_AM_PREV_VERTEX_TEX", m_gpuPrevVertices );
				renderCB.SetGlobalTexture( "_AM_CURR_VERTEX_TEX", m_gpuCurrVertices );
			#endif
			}

			int hardwarePass = m_useGPU ? 4 : 0;
			int qualityPass = ( quality == AmplifyMotion.Quality.Mobile ) ? 0 : 2;
			int basePass = hardwarePass + qualityPass;

			for ( int i = 0; i < m_sharedMaterials.Length; i++ )
			{
				MaterialDesc matDesc = m_sharedMaterials[ i ];
				int pass = basePass + ( matDesc.coverage ? 1 : 0 );

				if ( matDesc.coverage )
				{
					Texture mainTex = matDesc.material.mainTexture;
					if ( mainTex != null )
						matDesc.propertyBlock.SetTexture( "_MainTex", mainTex );
					if ( matDesc.cutoff )
						matDesc.propertyBlock.SetFloat( "_Cutoff", matDesc.material.GetFloat( "_Cutoff" ) );
				}

				renderCB.DrawMesh( m_clonedMesh, m_currLocalToWorld, m_owner.Instance.SkinnedVectorsMaterial, i, pass, matDesc.propertyBlock );
			}

			Profiler.EndSample();
		}
	}
	internal void EnqueueAsyncUpdate( AmplifyMotion.MotionState state )
	{
	#if NETFX_CORE
		Task.Run( () => AsyncUpdateCallback( state ) );
	#elif UNITY_WEBGL
		AsyncUpdateCallback( state );
	#else
		if ( !m_threadPoolFallback )
		{
			lock ( m_threadStateQueueLocks[ m_threadPoolIndex ] )
			{
				m_threadStateQueues[ m_threadPoolIndex ].Enqueue( state );
			}

			m_threadPoolContinueSignals[ m_threadPoolIndex ].Set();

			m_threadPoolIndex++;
			if ( m_threadPoolIndex >= m_threadPoolSize )
				m_threadPoolIndex = 0;
		}
		else
			ThreadPool.QueueUserWorkItem( new WaitCallback( AsyncUpdateCallback ), state );
	#endif
	}
	internal override void RenderVectors( Camera camera, float scale, AmplifyMotion.Quality quality )
	{
		Profiler.BeginSample( "Solid.Render" );

		if ( m_initialized && !m_error && m_meshRenderer.isVisible )
		{
			bool mask = ( m_owner.Instance.CullingMask & ( 1 << m_obj.gameObject.layer ) ) != 0;
			if ( !mask || ( mask && m_moved ) )
			{
				const float rcp255 = 1 / 255.0f;
				int objectId = mask ? m_owner.Instance.GenerateObjectId( m_obj.gameObject ) : 255;

				Matrix4x4 prevModelViewProj;
				if ( m_obj.FixedStep )
					prevModelViewProj = m_owner.PrevViewProjMatrixRT * m_currLocalToWorld;
				else
					prevModelViewProj = m_owner.PrevViewProjMatrixRT * m_prevLocalToWorld;

				Shader.SetGlobalMatrix( "_EFLOW_MATRIX_PREV_MVP", prevModelViewProj );
				Shader.SetGlobalFloat( "_EFLOW_OBJECT_ID", objectId * rcp255 );
				Shader.SetGlobalFloat( "_EFLOW_MOTION_SCALE", mask ? scale : 0 );

				int qualityPass = ( quality == AmplifyMotion.Quality.Mobile ) ? 0 : 2;

				for ( int i = 0; i < m_sharedMaterials.Length; i++ )
				{
					MaterialDesc matDesc = m_sharedMaterials[ i ];
					int pass = qualityPass + ( matDesc.coverage ? 1 : 0 );

					if ( matDesc.coverage )
					{
						m_owner.Instance.SolidVectorsMaterial.mainTexture = matDesc.material.mainTexture;
						if ( matDesc.cutoff )
							m_owner.Instance.SolidVectorsMaterial.SetFloat( "_Cutoff", matDesc.material.GetFloat( "_Cutoff" ) );
					}

					if ( m_owner.Instance.SolidVectorsMaterial.SetPass( pass ) )
						Graphics.DrawMeshNow( m_mesh, m_obj.transform.localToWorldMatrix, i );
				}
			}
		}

		Profiler.EndSample();
	}
	internal override void RenderVectors( Camera camera, float scale, AmplifyMotion.Quality quality )
	{
		Profiler.BeginSample( "Particle.Render" );

		if ( m_initialized && !m_error && m_meshRenderer.isVisible )
		{
			bool mask = ( m_owner.Instance.CullingMask & ( 1 << m_obj.gameObject.layer ) ) != 0;
			if ( !mask || ( mask && m_moved ) )
			{
				const float rcp255 = 1 / 255.0f;
				int objectId = mask ? m_owner.Instance.GenerateObjectId( m_obj.gameObject ) : 255;

				Shader.SetGlobalFloat( "_EFLOW_OBJECT_ID", objectId * rcp255 );
				Shader.SetGlobalFloat( "_EFLOW_MOTION_SCALE", mask ? scale : 0 );

				int qualityPass = ( quality == AmplifyMotion.Quality.Mobile ) ? 0 : 2;

				for ( int i = 0; i < m_sharedMaterials.Length; i++ )
				{
					Material mat = m_sharedMaterials[ i ];
					bool coverage = m_sharedMaterialCoverage[ i ];
					int pass = qualityPass + ( coverage ? 1 : 0 );

					if ( coverage )
					{
						m_owner.Instance.SolidVectorsMaterial.mainTexture = mat.mainTexture;
						m_owner.Instance.SolidVectorsMaterial.SetFloat( "_Cutoff", mat.GetFloat( "_Cutoff" ) );
					}

					var enumerator = m_particleDict.GetEnumerator();
					while ( enumerator.MoveNext() )
					{
						KeyValuePair<uint, Particle> pair = enumerator.Current;

						Matrix4x4 prevModelViewProj = m_owner.PrevViewProjMatrixRT * pair.Value.prevLocalToWorld;
						Shader.SetGlobalMatrix( "_EFLOW_MATRIX_PREV_MVP", prevModelViewProj );

						if ( m_owner.Instance.SolidVectorsMaterial.SetPass( pass ) )
							Graphics.DrawMeshNow( m_mesh, pair.Value.currLocalToWorld, i );
					}
				}
			}
		}

		Profiler.EndSample();
	}
Beispiel #12
0
	internal override void RenderVectors( Camera camera, CommandBuffer renderCB, float scale, AmplifyMotion.Quality quality )
	{
		if ( m_initialized && !m_error && m_meshRenderer.isVisible )
		{
			Profiler.BeginSample( "Solid.Render" );

			bool mask = ( m_owner.Instance.CullingMask & ( 1 << m_obj.gameObject.layer ) ) != 0;
			if ( !mask || ( mask && m_moved ) )
			{
				const float rcp255 = 1 / 255.0f;
				int objectId = mask ? m_owner.Instance.GenerateObjectId( m_obj.gameObject ) : 255;

				Matrix4x4 prevModelViewProj;
				if ( m_obj.FixedStep )
					prevModelViewProj = m_owner.PrevViewProjMatrixRT * m_currLocalToWorld;
				else
					prevModelViewProj = m_owner.PrevViewProjMatrixRT * m_prevLocalToWorld;

				renderCB.SetGlobalMatrix( "_AM_MATRIX_PREV_MVP", prevModelViewProj );
				renderCB.SetGlobalFloat( "_AM_OBJECT_ID", objectId * rcp255 );
				renderCB.SetGlobalFloat( "_AM_MOTION_SCALE", mask ? scale : 0 );

				// TODO: cache property blocks

				int qualityPass = ( quality == AmplifyMotion.Quality.Mobile ) ? 0 : 2;

				for ( int i = 0; i < m_sharedMaterials.Length; i++ )
				{
					MaterialDesc matDesc = m_sharedMaterials[ i ];
					int pass = qualityPass + ( matDesc.coverage ? 1 : 0 );

					if ( matDesc.coverage )
					{
						Texture mainTex = matDesc.material.mainTexture;
						if ( mainTex != null )
							matDesc.propertyBlock.SetTexture( "_MainTex", mainTex );
						if ( matDesc.cutoff )
							matDesc.propertyBlock.SetFloat( "_Cutoff", matDesc.material.GetFloat( "_Cutoff" ) );
					}

					renderCB.DrawMesh( m_mesh, m_transform.localToWorldMatrix, m_owner.Instance.SolidVectorsMaterial, i, pass, matDesc.propertyBlock );
				}
			}

			Profiler.EndSample();
		}
	}
	internal void RenderVectors( float scale, float fixedScale, AmplifyMotion.Quality quality )
	{
		if ( Instance != null )
		{
			// For some reason Unity's own values weren't working correctly on Windows/OpenGL
			float near = m_camera.nearClipPlane;
			float far = m_camera.farClipPlane;
			Vector4 zparam;

			if ( AmplifyMotionEffectBase.IsD3D )
			{
				zparam.x = 1.0f - far / near;
				zparam.y = far / near;
			}
			else
			{
				// OpenGL
				zparam.x = ( 1.0f - far / near ) / 2.0f;
				zparam.y = ( 1.0f + far / near ) / 2.0f;
			}

			zparam.z = zparam.x / far;
			zparam.w = zparam.y / far;

			Shader.SetGlobalVector( "_EFLOW_ZBUFFER_PARAMS", zparam );

			if ( m_affectedObjectsChanged )
				UpdateAffectedObjects();

			for ( int i = 0; i < m_affectedObjects.Length; i++ )
			{
				// don't render objects excluded via camera culling mask
				if ( ( m_camera.cullingMask & ( 1 << m_affectedObjects[ i ].gameObject.layer ) ) != 0 )
					m_affectedObjects[ i ].OnRenderVectors( m_camera, m_affectedObjects[ i ].FixedStep ? fixedScale : scale, quality );
			}
		}
	}
	internal override void RenderVectors( Camera camera, CommandBuffer renderCB, float scale, AmplifyMotion.Quality quality )
	{
		Profiler.BeginSample( "Particle.Render" );

		// TODO: batch

		if ( m_initialized && !m_error && m_renderer.isVisible )
		{
			bool mask = ( m_owner.Instance.CullingMask & ( 1 << m_obj.gameObject.layer ) ) != 0;
			if ( !mask || ( mask && m_moved ) )
			{
				const float rcp255 = 1 / 255.0f;
				int objectId = mask ? m_owner.Instance.GenerateObjectId( m_obj.gameObject ) : 255;

				renderCB.SetGlobalFloat( "_AM_OBJECT_ID", objectId * rcp255 );
				renderCB.SetGlobalFloat( "_AM_MOTION_SCALE", mask ? scale : 0 );

				int qualityPass = ( quality == AmplifyMotion.Quality.Mobile ) ? 0 : 2;

				for ( int i = 0; i < m_sharedMaterials.Length; i++ )
				{
					MaterialDesc matDesc = m_sharedMaterials[ i ];
					int pass = qualityPass + ( matDesc.coverage ? 1 : 0 );

					if ( matDesc.coverage )
					{
						Texture mainTex = matDesc.material.mainTexture;
						if ( mainTex != null )
							matDesc.propertyBlock.SetTexture( "_MainTex", mainTex );
						if ( matDesc.cutoff )
							matDesc.propertyBlock.SetFloat( "_Cutoff", matDesc.material.GetFloat( "_Cutoff" ) );
					}

					var enumerator = m_particleDict.GetEnumerator();
					while ( enumerator.MoveNext() )
					{
						KeyValuePair<uint, Particle> pair = enumerator.Current;

						Matrix4x4 prevModelViewProj = m_owner.PrevViewProjMatrixRT * pair.Value.prevLocalToWorld;
						renderCB.SetGlobalMatrix( "_AM_MATRIX_PREV_MVP", prevModelViewProj );

						renderCB.DrawMesh( m_mesh, pair.Value.currLocalToWorld, m_owner.Instance.SolidVectorsMaterial, i, pass, matDesc.propertyBlock );
					}
				}
			}
		}

		Profiler.EndSample();
	}