示例#1
0
        /// <summary>
        /// This sets a texture ONLY if it has changed (i.e. not the same or content is dirty)
        /// </summary>
        /// <param name="_Name"></param>
        /// <param name="_Value"></param>
        /// <param name="_bClearDirtyFlag">True to mark the texture as "clean" once assigned</param>
        public static void SetGlobalTexture( string _Name, NuajTexture2D _Value, bool _bClearDirtyFlag )
        {
            NuajTexture2D	CurrentTexture = ms_GlobalParamName2Texture.ContainsKey( _Name ) ? ms_GlobalParamName2Texture[_Name] : null;
            if ( _Value == CurrentTexture && _Value != null && !_Value.IsDirty )
                return;	// No change in texture or content...

            ms_GlobalParamName2Texture[_Name] = _Value;	// Update to new texture

            // Upload...
            Shader.SetGlobalTexture( _Name, _Value != null ? _Value.Texture : null );

            if ( _bClearDirtyFlag && _Value != null )
                _Value.IsDirty = false;	// This texture has been uploaded so it's not dirty anymore...

            // Notify
            Help.LogDebugWarning( "Texture \"" + (_Value != null && _Value.Texture ? _Value.Texture.name : "null") + "\" has been uploaded as GLOBAL \"" + _Name + "\"" );
        }
        /// <summary>
        /// Builds the table containing the Mie phase function
        /// </summary>
        protected void BuildPhaseFunction( double[] _PhaseFunction )
        {
            // Compute MIN/MAX indices of the phase function
            int		MinIndex = Mathf.FloorToInt( _PhaseFunction.Length * PHASE_START_ANGLE / Mathf.PI );
            int		MaxIndex = Mathf.FloorToInt( (_PhaseFunction.Length-1) * PHASE_END_ANGLE / Mathf.PI );

            // Compute integral of provided function
            double	fIntegral = 0.0;
            for ( int Index=0; Index < PHASE_TEXTURE_SIZE; Index++ )
            {
                int	OriginalPhaseIndex = MinIndex + (MaxIndex - MinIndex) * Index / (PHASE_TEXTURE_SIZE-1);
                fIntegral += _PhaseFunction[OriginalPhaseIndex];
            }

            fIntegral *= Math.PI / PHASE_TEXTURE_SIZE;	// * dTheta
            fIntegral *= 2.0 * Math.PI;
            fIntegral = 1.0 / fIntegral;

            // Copy source function into collapsed table
            float[]	PhaseFactors = new float[PHASE_TEXTURE_SIZE];
            double	IntegralCheck = 0.0;
            for ( int Index=0; Index < PHASE_TEXTURE_SIZE; Index++ )
            {
                int		OriginalPhaseIndex = MinIndex + (MaxIndex - MinIndex) * Index / PHASE_TEXTURE_SIZE;
                PhaseFactors[Index] = (float) (_PhaseFunction[OriginalPhaseIndex] * fIntegral);

                IntegralCheck += PhaseFactors[Index];
            }
            IntegralCheck *= Math.PI / PHASE_TEXTURE_SIZE;	// * dTheta
            IntegralCheck *= 2.0 * Math.PI;

            // Create phase function for 0- and single-scattering
            Color[]	Pixels = new Color[PHASE_TEXTURE_SIZE];
            for ( int i=0; i < PHASE_TEXTURE_SIZE; i++ )
            {
                float	Value = PhaseFactors[i] * 256.0f;
                float	R = Mathf.Floor( Value );
                float	G = Value - R;
                Pixels[i] = new Color( R / 256.0f, G, 0.0f, 0.0f );
            }

            // Build the convolved phase function for double-scattering
            double[]	PhaseConvolved = new double[PHASE_TEXTURE_SIZE];
            double		DeltaAngle = Math.PI / PHASE_TEXTURE_SIZE;
            for ( int AngleIndex0=0; AngleIndex0 < PHASE_TEXTURE_SIZE; AngleIndex0++ )
            {
                double	Phase0 = PhaseFactors[AngleIndex0];
                double	Convolution = 0.0;
                for ( int AngleIndex1=0; AngleIndex1 < PHASE_TEXTURE_SIZE; AngleIndex1++ )
                    Convolution += Phase0 * PhaseFactors[(PHASE_TEXTURE_SIZE + AngleIndex0 - AngleIndex1) % PHASE_TEXTURE_SIZE];

                PhaseConvolved[AngleIndex0] = (float) (DeltaAngle * Convolution);
            }

            for ( int i=0; i < PHASE_TEXTURE_SIZE; i++ )
            {
                float	Value = (float) (PhaseConvolved[i] * 256.0);
                float	B = Mathf.Floor( Value );
                float	A = Value - B;
                Pixels[i].b = B / 256.0f;
                Pixels[i].a = A;
            }

            // Build texture
            m_TexturePhase = Help.CreateTexture( "Layered Clouds Phase Function", PHASE_TEXTURE_SIZE, 1, TextureFormat.ARGB32, false, FilterMode.Bilinear, TextureWrapMode.Clamp );
            m_TexturePhase.SetPixels( 0, 0, PHASE_TEXTURE_SIZE, 1, Pixels, 0 );
            m_TexturePhase.Apply();
        }