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); }
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; }