void Create3DTextures(TextureResource[] baseMaps, TextureResource[] normalMaps)
        {
            Texture2D simpleWhite = new Texture2D(GFX.Device, 1, 1, 1, TextureUsage.None, SurfaceFormat.Color);
            Texture2D simpleNormal = new Texture2D(GFX.Device, 1, 1, 1, TextureUsage.None, SurfaceFormat.Color);
            Color[] whiteColor = new Color[1] { Color.White };
            Color[] normalColor = new Color[1] { Color.Blue };
            simpleWhite.SetData<Color>(whiteColor);
            simpleNormal.SetData<Color>(normalColor);

            List<Texture2D> baseTextures = new List<Texture2D>(TerrainClimateVoxels.MAX_BLEND_ZONES);
            List<Texture2D> normalTextures = new List<Texture2D>(TerrainClimateVoxels.MAX_BLEND_ZONES);
            int maxBaseSize = 256;
            int maxNormalSize = 256;

            for (int i = 0; i < TerrainClimate.MAX_BLEND_ZONES; i++)
            {
                if(baseMaps[i] != null)
                {
                    Texture2D baseMap = (Texture2D)baseMaps[i].GetTexture();
                    maxBaseSize = Math.Max(maxBaseSize, baseMap.Width);
                    baseTextures.Add(baseMap);
                }
                else
                    baseTextures.Add(simpleWhite);
                if(normalMaps[i] != null)
                {
                    Texture2D normalMap = (Texture2D)normalMaps[i].GetTexture();
                    maxNormalSize = Math.Max(maxNormalSize, normalMap.Width);
                    normalTextures.Add(normalMap);
                }
                else
                    normalTextures.Add(simpleNormal);
            }

            Texture3D baseAtlas = new Texture3D(GFX.Device, maxBaseSize, maxBaseSize, TerrainClimateVoxels.MAX_BLEND_ZONES, 1, TextureUsage.None, SurfaceFormat.Color);
            Texture3D normalAtlas = new Texture3D(GFX.Device, maxNormalSize, maxNormalSize, TerrainClimateVoxels.MAX_BLEND_ZONES, 1, TextureUsage.None, SurfaceFormat.Color);

            width = maxBaseSize;
            height = maxBaseSize;
            depth = TerrainClimate.MAX_BLEND_ZONES;

            PopulateAtlas(baseTextures.ToArray(), baseAtlas);

            PopulateAtlas(normalTextures.ToArray(), normalAtlas);

            BaseMapAtlas = new TextureResource();
            BaseMapAtlas.SetTexture(TextureResourceType.Texture3D, baseAtlas);

            NormalMapAtlas = new TextureResource();
            NormalMapAtlas.SetTexture(TextureResourceType.Texture3D, normalAtlas);

            baseAtlas.Save("BaseMapAtlas.dds", ImageFileFormat.Dds);

            normalAtlas.Save("NormalMapAtlas.dds", ImageFileFormat.Dds);
        }
Esempio n. 2
0
        void CreateImposter()
        {
            const int textureSize = 128;
            const int numViews = 4;

            int textureWidth = textureSize * numViews;
            int textureHeight = textureSize;

            imposterGeometry = new Imposter(this);
            imposterGeometry.BaseMap = new RenderTarget2D(GFX.Device, textureWidth, textureHeight, 1, SurfaceFormat.Color);
            imposterGeometry.NormalMap = new RenderTarget2D(GFX.Device, textureWidth, textureHeight, 1, SurfaceFormat.Vector2);

            ImposterRenderView renderViewImposter = new ImposterRenderView(Matrix.Identity, Matrix.Identity, Vector3.Zero, 1.0f, 1000.0f);

            Vector3 centerPos = (this.meshBounds.Min + this.meshBounds.Max)*0.5f;
            float rad = Math.Max(this.meshBounds.Min.Length(), this.meshBounds.Max.Length());

            renderViewImposter.SetNearPlane(1.0f);
            renderViewImposter.SetFarPlane(rad * rad);
            renderViewImposter.SetProjection(Matrix.CreateOrthographicOffCenter(-rad * 0.5f, rad * 0.5f, -rad*0.5f, rad*0.5f, 1.0f, rad * rad));

            Viewport oldViewport = GFX.Device.Viewport;
            DepthStencilBuffer oldDSBuffer = GFX.Device.DepthStencilBuffer;
            DepthStencilBuffer dsBufferImposter = new DepthStencilBuffer(GFX.Device, textureWidth, textureHeight, oldDSBuffer.Format);
            GFX.Device.DepthStencilBuffer = dsBufferImposter;

            float deltaTheta = MathHelper.TwoPi / (float)numViews;

            GFX.Device.SetRenderTarget(0, imposterGeometry.BaseMap);
            GFX.Device.SetRenderTarget(1, imposterGeometry.NormalMap);
            GFX.Device.Clear(Color.TransparentBlack);

            for (int i = 0; i < numViews; i++)
            {
                float theta = deltaTheta * i;
                Vector3 offset = new Vector3((float)Math.Sin(theta), 0, (float)Math.Cos(theta)) * rad;
                Vector3 camPos = centerPos + offset;

                renderViewImposter.SetPosition(camPos);
                renderViewImposter.SetView(Matrix.CreateLookAt(camPos, centerPos, Vector3.Up));

                Viewport newViewport = new Viewport();
                newViewport.X = i * textureSize;
                newViewport.Y = 0;
                newViewport.Width = textureSize;
                newViewport.Height = textureHeight;

                GFX.Device.Viewport = newViewport;
                this.RenderNoLOD(Matrix.Identity, renderViewImposter);
                renderViewImposter.Render();
            }

            GFX.Device.SetRenderTarget(1, null);

            for (int i = 0; i < numViews; i++)
            {
                float theta = deltaTheta * i;
                Vector3 offset = new Vector3((float)Math.Cos(theta), 0, (float)Math.Sin(theta)) * rad;
                Vector3 camPos = centerPos + offset;

                renderViewImposter.SetPosition(camPos);
                renderViewImposter.SetView(Matrix.CreateLookAt(camPos, centerPos, Vector3.Up));

                Viewport newViewport = new Viewport();
                newViewport.X = i * textureSize;
                newViewport.Y = 0;
                newViewport.Width = textureSize;
                newViewport.Height = textureHeight;

                GFX.Device.Viewport = newViewport;
                this.RenderNoLOD(Matrix.Identity, renderViewImposter);
                renderViewImposter.RenderBlended();
            }

            GFX.Device.SetRenderTarget(0, null);

            GFX.Device.Viewport = oldViewport;
            GFX.Device.DepthStencilBuffer = oldDSBuffer;
            dsBufferImposter.Dispose();
            imposterGeometry.BaseMap.GetTexture().Save("BaseMapImposter.dds", ImageFileFormat.Dds);

            imposterGeometry.ImposterMaterial.SetShader(ResourceManager.Inst.GetShader("ImposterShader"));
            TextureResource baseMap = new TextureResource();
            baseMap.SetTexture(TextureResourceType.Texture2D, imposterGeometry.BaseMap.GetTexture());
            imposterGeometry.BaseMap.GetTexture().GenerateMipMaps(TextureFilter.GaussianQuad);
            TextureResource normalMap = new TextureResource();
            normalMap.SetTexture(TextureResourceType.Texture2D, imposterGeometry.NormalMap.GetTexture());
            imposterGeometry.ImposterMaterial.SetTexture(0, baseMap);
            imposterGeometry.ImposterMaterial.SetTexture(1, normalMap);
            imposterGeometry.ImposterMaterial.SetName(name + "_IMPOSTER_MATERIAL");
            imposterGeometry.ImposterMaterial.IsFoliage = true;
        }