private static extern void Internal_SetDimension(RenderTexture rt, TextureDimension dim);
/// <summary> /// Writes DDS formatted data to a stream. Image data is expected to be DXGI-compliant data, but an effort is made to write out D3D9-compatible headers when possible. /// </summary> /// <param name="output">Output stream.</param> /// <param name="mipChains">Mipmap chains to write. Each mipmap chain represents a single face (so > 1 represents an array texture or a Cubemap). All faces must have /// equivalent dimensions and each chain must have the same number of mipmaps.</param> /// <param name="format">DXGI format the image data is stored as.</param> /// <param name="texDim">Dimension of the texture to write.</param> /// <param name="flags">Flags to control how the DDS data is saved.</param> /// <returns>True if writing the data was successful, false if otherwise.</returns> public static bool Write(Stream output, List <MipChain> mipChains, DXGIFormat format, TextureDimension texDim, DDSFlags flags = DDSFlags.None) { if (output == null || !output.CanWrite || mipChains == null || mipChains.Count == 0 || mipChains[0].Count == 0 || format == DXGIFormat.Unknown) { return(false); } //Extract details int width, height, depth, arrayCount, mipCount; MipData firstMip = mipChains[0][0]; width = firstMip.Width; height = firstMip.Height; depth = firstMip.Depth; arrayCount = mipChains.Count; mipCount = mipChains[0].Count; if (!ValidateInternal(mipChains, format, texDim)) { return(false); } //Setup a transfer buffer StreamTransferBuffer buffer = new StreamTransferBuffer(firstMip.RowPitch, false); //Write out header if (!WriteHeader(output, buffer, texDim, format, width, height, depth, arrayCount, mipCount, flags)) { return(false); } //Iterate over each array face... for (int i = 0; i < arrayCount; i++) { MipChain mipChain = mipChains[i]; //Iterate over each mip face... for (int mipLevel = 0; mipLevel < mipCount; mipLevel++) { MipData mip = mipChain[mipLevel]; //Compute pitch, based on MSDN programming guide. We will write out these pitches rather than the supplied in order to conform to the recomendation //that we compute pitch based on format int realMipWidth, realMipHeight, dstRowPitch, dstSlicePitch, bytesPerPixel; ImageHelper.ComputePitch(format, mip.Width, mip.Height, out dstRowPitch, out dstSlicePitch, out realMipWidth, out realMipHeight, out bytesPerPixel); //Ensure write buffer is sufficiently sized for a single scanline if (buffer.Length < dstRowPitch) { buffer.Resize(dstRowPitch, false); } //Sanity check if (dstRowPitch < mip.RowPitch) { return(false); } IntPtr srcPtr = mip.Data; //Advance stream one slice at a time... for (int slice = 0; slice < mip.Depth; slice++) { int bytesToWrite = dstSlicePitch; IntPtr sPtr = srcPtr; //Copy scanline into temp buffer, write to output for (int row = 0; row < realMipHeight; row++) { MemoryHelper.CopyMemory(buffer.Pointer, sPtr, dstRowPitch); buffer.WriteBytes(output, dstRowPitch); bytesToWrite -= dstRowPitch; //Advance to next scanline in source data sPtr = MemoryHelper.AddIntPtr(sPtr, mip.RowPitch); } //Pad slice if necessary if (bytesToWrite > 0) { MemoryHelper.ClearMemory(buffer.Pointer, 0, bytesToWrite); buffer.WriteBytes(output, bytesToWrite); } //Advance source pointer to next slice srcPtr = MemoryHelper.AddIntPtr(srcPtr, mip.SlicePitch); } } } return(true); }
public static string GetTextureAutoName(int width, int height, TextureFormat format, TextureDimension dim = TextureDimension.None, string name = "", bool mips = false, int depth = 0) { string temp; if (depth == 0) { temp = string.Format("{0}x{1}{2}_{3}", width, height, mips ? "_Mips" : "", format); } else { temp = string.Format("{0}x{1}x{2}{3}_{4}", width, height, depth, mips ? "_Mips" : "", format); } temp = String.Format("{0}_{1}_{2}", name == "" ? "Texture" : name, (dim == TextureDimension.None) ? "" : dim.ToString(), temp); return(temp); }
internal static bool ValidateInternal(List <MipChain> mipChains, DXGIFormat format, TextureDimension texDim) { if (format == DXGIFormat.Unknown) { return(false); } //Mipchains must exist, must have at least one, and chain must have mipmaps. if (mipChains == null || mipChains.Count == 0 || mipChains[0].Count == 0) { return(false); } //Validate cubemap...must have multiples of 6 faces (can be an array of cubes). if (texDim == TextureDimension.Cube && (mipChains.Count % 6) != 0) { return(false); } //Validate 3d texture..can't have arrays if (texDim == TextureDimension.Three && mipChains.Count > 1) { return(false); } int width, height, depth, rowPitch, slicePitch; //Save the first image dimensions MipData firstSurface = mipChains[0][0]; width = firstSurface.Width; height = firstSurface.Height; depth = firstSurface.Depth; rowPitch = firstSurface.RowPitch; slicePitch = firstSurface.SlicePitch; //Validate first surface if (width < 1 || height < 1 || depth < 1 || rowPitch < 1 || slicePitch < 1) { return(false); } //Validate 1D texture...must only have 1 height if (texDim == TextureDimension.One && height > 1) { return(false); } //Validate cubemap...width/height must be same if (texDim == TextureDimension.Cube && (width != height)) { return(false); } //Only 3d textures have depth if (texDim != TextureDimension.Three && depth > 1) { return(false); } //Go through each chain and validate against the first texture and ensure mipmaps are progressively smaller int mipCount = -1; for (int i = 0; i < mipChains.Count; i++) { MipChain mipmaps = mipChains[i]; //Mips must exist... if (mipmaps == null || mipmaps.Count == 0) { return(false); } //Grab a mip count from first chain if (mipCount == -1) { mipCount = mipmaps.Count; } //Each chain must have the same number of mip surfaces if (mipmaps.Count != mipCount) { return(false); } //Each mip surface must have data and check sizes MipData prevMip = mipmaps[0]; //Check against the first main image we looked at earlier if (prevMip.Width != width || prevMip.Height != height || prevMip.Depth != depth || prevMip.Data == IntPtr.Zero || prevMip.RowPitch != rowPitch || prevMip.SlicePitch != slicePitch) { return(false); } for (int mipLevel = 1; mipLevel < mipmaps.Count; mipLevel++) { MipData nextMip = mipmaps[mipLevel]; //Ensure each mipmap is progressively smaller or same at the least if (nextMip.Width > prevMip.Width || nextMip.Height > prevMip.Height || nextMip.Depth > prevMip.Depth || nextMip.Data == IntPtr.Zero || nextMip.RowPitch > prevMip.RowPitch || nextMip.SlicePitch > prevMip.SlicePitch || nextMip.RowPitch == 0 || nextMip.SlicePitch == 0) { return(false); } prevMip = nextMip; } } return(true); }
/// <summary> /// Writes a DDS file to a stream. Image data is expected to be 32-bit color data, if not then mipmaps are converted as necessary automatically without modifying input data. /// </summary> /// <param name="output">Output stream.</param> /// <param name="mipChains">Mipmap chains to write. Each mipmap chain represents a single face (so > 1 represents an array texture or a Cubemap). All faces must have /// equivalent dimensions and each chain must have the same number of mipmaps.</param> /// <param name="texDim">Dimension of the texture to write.</param> /// <param name="flags">Flags to control how the DDS data is saved.</param> /// <returns>True if writing the data was successful, false if otherwise.</returns> public static bool Write(Stream output, List <List <Surface> > mipChains, TextureDimension texDim, DDSFlags flags = DDSFlags.None) { if (mipChains == null || mipChains.Count == 0 || mipChains[0] == null || mipChains[0].Count == 0) { return(false); } //FreeImage doesn't support volume textures. if (texDim == TextureDimension.Three) { return(false); } //If texcube, must have multiples of 6, every 6 mipchains are a complete cubemap if (texDim == TextureDimension.Cube && (mipChains.Count % 6 != 0)) { return(false); } //FreeImage surfaces are always uncompressed and we expect 32-bit color, if not we'll convert. We'll export in whatever color order freeimage is in, //but we can force RGBA based on the flags List <MipChain> ddsMipChains = new List <MipChain>(mipChains.Count); bool forceRGBA = (flags & DDSFlags.ForceRgb) == DDSFlags.ForceRgb; bool isBGRAOrder = Surface.IsBGRAOrder; bool needToSwizzle = isBGRAOrder && forceRGBA; DXGIFormat format = (isBGRAOrder) ? DXGIFormat.B8G8R8A8_UNorm : DXGIFormat.R8G8B8A8_UNorm; if (forceRGBA) { format = DXGIFormat.R8G8B8A8_UNorm; } try { int mipCount = -1; foreach (List <Surface> fiMipChain in mipChains) { MipChain ddsMipChain = new MipChain(fiMipChain.Count); ddsMipChains.Add(ddsMipChain); if (mipCount == -1) { mipCount = fiMipChain.Count; } //All chains must have same # of mips if (mipCount != fiMipChain.Count) { return(false); } foreach (Surface fiMip in fiMipChain) { if (fiMip == null) { return(false); } //Validate dimension switch (texDim) { case TextureDimension.One: if (fiMip.Height > 1) { return(false); } break; case TextureDimension.Cube: if (fiMip.Width != fiMip.Height) { return(false); } break; } bool is32BitBitmap = fiMip.ImageType == ImageType.Bitmap && fiMip.ColorType == ImageColorType.RGBA && fiMip.BitsPerPixel == 32; if (is32BitBitmap) { //If no swizzling...just use the data directly if (!needToSwizzle) { ddsMipChain.Add(new MipData(fiMip)); } else { MipData newMip = new MipData(fiMip.Width, fiMip.Height, fiMip.Pitch); ImageHelper.CopyColorImageData(newMip.Data, newMip.RowPitch, 0, fiMip.DataPtr, fiMip.Pitch, 0, newMip.Width, newMip.Height, 1, true); ddsMipChain.Add(newMip); } } else { //Need to convert. Possible to map other DXGI formats to free image bitmaps (most likely RGBA floats), but we're keeping it simple. User can wrap surfaces //and use the general write method using (Surface converted = fiMip.Clone()) { if (!converted.ConvertTo(ImageConversion.To32Bits)) { return(false); } MipData newMip = new MipData(converted.Width, converted.Height, converted.Pitch); ImageHelper.CopyColorImageData(newMip.Data, newMip.RowPitch, 0, converted.DataPtr, converted.Pitch, 0, newMip.Width, newMip.Height, 1, needToSwizzle); ddsMipChain.Add(newMip); } } } } //Write out DDS return(Write(output, ddsMipChains, format, texDim, flags)); } finally { //Dispose of mip surfaces. If they own any data, it'll be cleaned up DisposeMipChains(ddsMipChains); } }
public static void SetRenderTarget(CommandBuffer cmd, RenderTargetIdentifier colorAttachment, RenderBufferLoadAction colorLoadAction, RenderBufferStoreAction colorStoreAction, ClearFlag clearFlags, Color clearColor, TextureDimension dimension) { if (dimension == TextureDimension.Tex2DArray) { CoreUtils.SetRenderTarget(cmd, colorAttachment, clearFlags, clearColor, 0, CubemapFace.Unknown, -1); } else { CoreUtils.SetRenderTarget(cmd, colorAttachment, colorLoadAction, colorStoreAction, clearFlags, clearColor); } }
bool PropertySupportsDimension(MaterialProperty prop, TextureDimension dim) { return(MixtureUtils.GetAllowedDimentions(prop.name).Contains(dim)); }
public void LoadImage(byte[] data, string resSFilePath = "") { using (MemoryStream ms = new MemoryStream(data)) { using (EndianBinaryReader br = new EndianBinaryReader(ms, Endian.LittleEndian)) { // int name_length = br.ReadInt32(); // this.name = Encoding.UTF8.GetString(br.ReadBytes(name_length)); // var pos = br.BaseStream.Position; // if (pos % 4 != 0) { // br.BaseStream.Seek(4 - pos % 4, SeekOrigin.Current); // } this.width = br.ReadInt32(); this.height = br.ReadInt32(); if ((this.width > 4096) || (this.height > 4096)) { isTexture2D = false; Console.WriteLine("Got error:{0}", "Width/Height Error\n Not a unity Texture2D data"); return; } this.textureSize = br.ReadInt32(); if ((this.width == 0) || (this.height == 0)) { isTexture2D = false; Console.WriteLine("Got error:{0}", "Width/Height Error\n Empty Texture"); return; } int tmp_pos = (int)br.BaseStream.Position; this.format = (TextureFormat)br.ReadInt32(); this.mipmapCount = br.ReadInt32(); if (this.mipmapCount > 1) { this.bMipmap = true; } int readable = br.ReadInt32(); int imageCount = br.ReadInt32(); this.dimension = (TextureDimension)br.ReadInt32(); this.filterMode = (FilterMode)br.ReadInt32(); this.anisoLevel = br.ReadInt32(); this.mipMapBias = br.ReadInt32(); this.wrapMode = (TextureWrapMode)br.ReadInt32(); int lightmapFormat = br.ReadInt32(); int colorSpace = br.ReadInt32(); this.dataSize = br.ReadInt32(); if (this.dataSize < 0) { Console.WriteLine("Got error:{0}", "Data Length Error\n Not a unity Texture2D data"); isTexture2D = false; return; } if (this.dataSize > 0) { this.resSName = this.name; this.dataPos = br.BaseStream.Position; textureData = br.ReadBytes(this.dataSize); return; } this.dataPos = br.ReadInt32(); this.dataSize = br.ReadInt32(); int name_len = br.ReadInt32(); if (this.dataSize <= 0) { Console.WriteLine("Got error:{0}", "Data Length is 0\n Not a unity Texture2D data"); isTexture2D = false; return; } this.resSName = Encoding.UTF8.GetString(br.ReadBytes(name_len)); if (resSFilePath == "") { resSFilePath = "./"; } string rname = string.Format("{0}\\{1}", resSFilePath, this.resSName); if (!File.Exists(rname)) { Console.WriteLine("Got error:{0}", "resS File not found\n can't get Texture2D data"); isTexture2D = false; return; } this.bHasResSData = true; // 图像数据在resS中 FileStream fs = File.Open(rname, FileMode.Open, FileAccess.Read); EndianBinaryReader bs = new EndianBinaryReader(fs); bs.BaseStream.Seek(this.dataPos, SeekOrigin.Begin); textureData = bs.ReadBytes(this.dataSize); bs.Close(); fs.Close(); } } }
public MaterialPropertyDescriptor(object target, object acessor, string label, RTShaderPropertyType type, PropertyInfo propertyInfo, RuntimeShaderInfo.RangeLimits limits, TextureDimension dims, PropertyEditorCallback callback, Action <object, object> eraseTargetCallback) : this(new [] { target }, new[] { acessor }, label, type, propertyInfo, limits, dims, callback, eraseTargetCallback) { }
public static PropertyInfo GetPropertyInfo(RTShaderPropertyType propertyType, TextureDimension dim) { PropertyInfo propertyInfo = null; switch (propertyType) { case RTShaderPropertyType.Color: propertyInfo = Strong.PropertyInfo((MaterialPropertyAccessor x) => x.Color, "Color"); break; case RTShaderPropertyType.Float: propertyInfo = Strong.PropertyInfo((MaterialPropertyAccessor x) => x.Float, "Float"); break; case RTShaderPropertyType.Range: propertyInfo = Strong.PropertyInfo((MaterialPropertyAccessor x) => x.Float, "Float"); break; case RTShaderPropertyType.TexEnv: switch (dim) { case TextureDimension.Any: propertyInfo = Strong.PropertyInfo((MaterialPropertyAccessor x) => x.Texture, "Texture"); break; case TextureDimension.Cube: propertyInfo = Strong.PropertyInfo((MaterialPropertyAccessor x) => x.Cubemap, "Cubemap"); break; case TextureDimension.None: propertyInfo = null; break; case TextureDimension.Tex2D: propertyInfo = Strong.PropertyInfo((MaterialPropertyAccessor x) => x.Texture2D, "Texture2D"); break; case TextureDimension.Tex2DArray: propertyInfo = Strong.PropertyInfo((MaterialPropertyAccessor x) => x.Texture2DArray, "Texture2DArray"); break; case TextureDimension.Tex3D: propertyInfo = Strong.PropertyInfo((MaterialPropertyAccessor x) => x.Texture3D, "Texture3D"); break; case TextureDimension.Unknown: propertyInfo = null; break; } break; case RTShaderPropertyType.Vector: propertyInfo = Strong.PropertyInfo((MaterialPropertyAccessor x) => x.Vector, "Vector"); break; } return(propertyInfo); }
public static MaterialPropertyDescriptor CreatePropertyDescriptor(Material[] materials, PropertyInfo propertyInfo, string propertyDescr, string propertyName, RTShaderPropertyType propertyType, TextureDimension dim, RuntimeShaderInfo.RangeLimits limits) { return(new MaterialPropertyDescriptor( materials, CreateAccessors(materials, propertyName), propertyDescr, propertyType, propertyInfo, limits, dim, null, (accessorRef, newTarget) => { MaterialPropertyAccessor accessor = (MaterialPropertyAccessor)accessorRef; accessor.Material = newTarget as Material; })); }
/// <summary> /// Configure the pass /// </summary> /// <param name="baseDescriptor"></param> /// <param name="colorHandle"></param> public void Setup(RenderTextureDescriptor baseDescriptor, RenderTargetHandle colorHandle) { m_Source = colorHandle; m_TargetDimension = baseDescriptor.dimension; m_IsMobileOrSwitch = Application.isMobilePlatform || Application.platform == RuntimePlatform.Switch; }
/// <summary> /// Constructs a new instance of the <see cref="DDSContainer"/> class. /// </summary> /// <param name="format">Format of the image data.</param> /// <param name="texDim">Identifies the dimensions of the image data.</param> public DDSContainer(DXGIFormat format, TextureDimension texDim) : this(new List <MipChain>(), format, texDim) { }
protected bool UpdateTempRenderTexture(ref CustomRenderTexture target, bool hasMips = false, bool autoGenerateMips = false, CustomRenderTextureUpdateMode updateMode = CustomRenderTextureUpdateMode.OnDemand, bool depthBuffer = false, GraphicsFormat overrideGraphicsFormat = GraphicsFormat.None) { if (graph.mainOutputTexture == null) { return(false); } bool changed = false; int outputWidth = rtSettings.GetWidth(graph); int outputHeight = rtSettings.GetHeight(graph); int outputDepth = rtSettings.GetDepth(graph); GraphicsFormat targetFormat = overrideGraphicsFormat != GraphicsFormat.None ? overrideGraphicsFormat : rtSettings.GetGraphicsFormat(graph); TextureDimension dimension = GetTempTextureDimension(); outputWidth = Mathf.Max(outputWidth, 1); outputHeight = Mathf.Max(outputHeight, 1); outputDepth = Mathf.Max(outputDepth, 1); if (dimension == TextureDimension.Cube) { outputHeight = outputDepth = outputWidth; // we only use the width for cubemaps } if (targetFormat == GraphicsFormat.None) { targetFormat = graph.mainOutputTexture.graphicsFormat; } if (dimension == TextureDimension.None) { dimension = TextureDimension.Tex2D; } if (target == null) { target = new CustomRenderTexture(outputWidth, outputHeight, targetFormat) { volumeDepth = Math.Max(1, outputDepth), depth = depthBuffer ? 32 : 0, dimension = dimension, name = $"Mixture Temp {name}", updateMode = CustomRenderTextureUpdateMode.OnDemand, doubleBuffered = rtSettings.doubleBuffered, wrapMode = rtSettings.wrapMode, filterMode = rtSettings.filterMode, useMipMap = hasMips, autoGenerateMips = autoGenerateMips, enableRandomWrite = true, hideFlags = HideFlags.HideAndDontSave, updatePeriod = GetUpdatePeriod(), }; target.Create(); target.material = MixtureUtils.dummyCustomRenderTextureMaterial; return(true); } // TODO: check if format is supported by current system // Warning: here we use directly the settings from the if (target.width != Math.Max(1, outputWidth) || target.height != Math.Max(1, outputHeight) || target.graphicsFormat != targetFormat || target.dimension != dimension || target.volumeDepth != outputDepth || target.filterMode != rtSettings.filterMode || target.doubleBuffered != rtSettings.doubleBuffered || target.wrapMode != rtSettings.wrapMode || target.useMipMap != hasMips || target.autoGenerateMips != autoGenerateMips || target.updatePeriod != GetUpdatePeriod()) { target.Release(); target.width = Math.Max(1, outputWidth); target.height = Math.Max(1, outputHeight); target.graphicsFormat = (GraphicsFormat)targetFormat; target.dimension = dimension; target.volumeDepth = outputDepth; target.doubleBuffered = rtSettings.doubleBuffered; target.wrapMode = rtSettings.wrapMode; target.filterMode = rtSettings.filterMode; target.useMipMap = hasMips; target.autoGenerateMips = autoGenerateMips; target.enableRandomWrite = true; target.updatePeriod = GetUpdatePeriod(); target.hideFlags = HideFlags.HideAndDontSave; target.Create(); if (target.material == null) { target.material = MixtureUtils.dummyCustomRenderTextureMaterial; } changed = true; } // Patch update mode based on graph type target.updateMode = updateMode; if (target.doubleBuffered) { target.EnsureDoubleBufferConsistency(); var rt = target.GetDoubleBufferRenderTexture(); if (rt.enableRandomWrite != true) { rt.Release(); rt.enableRandomWrite = true; rt.Create(); } } if (target.IsCreated()) { target.Create(); } return(changed); }
private static ImageDescription CreateDescription(TextureDimension dimension, int width, int height, int depth, MipMapCount mipMapCount, PixelFormat format, int arraySize) { return new ImageDescription() { Width = width, Height = height, Depth = depth, ArraySize = arraySize, Dimension = dimension, Format = format, MipLevels = mipMapCount, }; }
public MaterialPropertyDescriptor(object target, object acessor, string label, RTShaderPropertyType type, PropertyInfo propertyInfo, RuntimeShaderInfo.RangeLimits limits, TextureDimension dims, PropertyEditorCallback callback, Action <object, object> eraseTargetCallback) { Target = target; Accessor = acessor; Label = label; Type = type; PropertyInfo = propertyInfo; Limits = limits; TexDims = dims; ValueChangedCallback = callback; EraseTargetCallback = eraseTargetCallback; }
/// <summary> /// Creates a new <see cref="GpuResourceFormat"/> representing a 1, 2, or 3 dimensional texture /// </summary> /// <param name="dimension">The dimension of the texture</param> /// <param name="format">The format of the texture</param> /// <param name="width">The width of the texture</param> /// <param name="height">The height of the texture</param> /// <param name="depth">The depth of the texture</param> /// <returns>A new <see cref="GpuResourceFormat"/> representing the texture</returns> public static GpuResourceFormat Texture(TextureDimension dimension, DXGI_FORMAT format, ulong width, uint height = 1, ushort depth = 1) => TextureArray(dimension, format, width, height, depth); // Tex arrays and 3D texs share the same field for depth/arrayCount so same creation process
public MaterialPropertyDescriptor[] GetProperties(MaterialEditor editor) { RuntimeShaderInfo shaderInfo = RuntimeShaderUtil.GetShaderInfo(editor.Material.shader); if (shaderInfo == null) { return(null); } List <MaterialPropertyDescriptor> descriptors = new List <MaterialPropertyDescriptor>(); for (int i = 0; i < shaderInfo.PropertyCount; ++i) { bool isHidden = shaderInfo.IsHidden[i]; if (isHidden) { continue; } string propertyDescr = shaderInfo.PropertyDescriptions[i]; string propertyName = shaderInfo.PropertyNames[i]; if (propertyName != "_Color" && propertyName != "_MainTex") { continue; } RTShaderPropertyType propertyType = shaderInfo.PropertyTypes[i]; RuntimeShaderInfo.RangeLimits limits = shaderInfo.PropertyRangeLimits[i]; TextureDimension dim = shaderInfo.PropertyTexDims[i]; PropertyInfo propertyInfo = null; switch (propertyType) { case RTShaderPropertyType.Color: propertyInfo = Strong.PropertyInfo((MaterialPropertyAccessor x) => x.Color); break; case RTShaderPropertyType.Float: propertyInfo = Strong.PropertyInfo((MaterialPropertyAccessor x) => x.Float); break; case RTShaderPropertyType.Range: propertyInfo = Strong.PropertyInfo((MaterialPropertyAccessor x) => x.Float); break; case RTShaderPropertyType.TexEnv: switch (dim) { case TextureDimension.Any: propertyInfo = Strong.PropertyInfo((MaterialPropertyAccessor x) => x.Texture); break; case TextureDimension.Cube: propertyInfo = Strong.PropertyInfo((MaterialPropertyAccessor x) => x.Cubemap); break; case TextureDimension.None: propertyInfo = null; break; case TextureDimension.Tex2D: propertyInfo = Strong.PropertyInfo((MaterialPropertyAccessor x) => x.Texture2D); break; case TextureDimension.Tex2DArray: propertyInfo = Strong.PropertyInfo((MaterialPropertyAccessor x) => x.Texture2DArray); break; case TextureDimension.Tex3D: propertyInfo = Strong.PropertyInfo((MaterialPropertyAccessor x) => x.Texture3D); break; case TextureDimension.Unknown: propertyInfo = null; break; } break; case RTShaderPropertyType.Vector: propertyInfo = Strong.PropertyInfo((MaterialPropertyAccessor x) => x.Float); break; } if (propertyInfo == null) { continue; } MaterialPropertyAccessor accessor = new MaterialPropertyAccessor(editor.Material, propertyName); MaterialPropertyDescriptor propertyDescriptor = new MaterialPropertyDescriptor(accessor, propertyDescr, propertyType, propertyInfo, limits, dim, null); descriptors.Add(propertyDescriptor); } return(descriptors.ToArray()); }
/// <summary> /// Configure the pass /// </summary> /// <param name="baseDescriptor"></param> /// <param name="colorHandle"></param> public void Setup(RenderTextureDescriptor baseDescriptor, RenderTargetHandle colorHandle) { m_Source = colorHandle; m_TargetDimension = baseDescriptor.dimension; }
protected bool UpdateTempRenderTexture(ref CustomRenderTexture target, bool hasMips = false, bool autoGenerateMips = false) { if (graph.outputTexture == null) { return(false); } int outputWidth = rtSettings.GetWidth(graph); int outputHeight = rtSettings.GetHeight(graph); int outputDepth = rtSettings.GetDepth(graph); GraphicsFormat targetFormat = rtSettings.GetGraphicsFormat(graph); TextureDimension dimension = rtSettings.GetTextureDimension(graph); if (dimension == TextureDimension.Cube) { outputHeight = outputDepth = outputWidth; // we only use the width for cubemaps } if (targetFormat == GraphicsFormat.None) { targetFormat = graph.outputTexture.graphicsFormat; } if (dimension == TextureDimension.None) { dimension = TextureDimension.Tex2D; } if (target == null) { target = new CustomRenderTexture(outputWidth, outputHeight, targetFormat) { volumeDepth = Math.Max(1, outputDepth), dimension = dimension, name = $"Mixture Temp {name}", updateMode = CustomRenderTextureUpdateMode.OnDemand, doubleBuffered = rtSettings.doubleBuffered, wrapMode = rtSettings.wrapMode, filterMode = rtSettings.filterMode, useMipMap = hasMips, autoGenerateMips = autoGenerateMips, }; target.Create(); return(true); } // TODO: check if format is supported by current system // Warning: here we use directly the settings from the if (target.width != outputWidth || target.height != outputHeight || target.graphicsFormat != targetFormat || target.dimension != dimension || target.volumeDepth != outputDepth || target.filterMode != graph.outputTexture.filterMode || target.doubleBuffered != rtSettings.doubleBuffered || target.wrapMode != rtSettings.wrapMode || target.filterMode != rtSettings.filterMode || target.useMipMap != hasMips || target.autoGenerateMips != autoGenerateMips) { target.Release(); target.width = Math.Max(1, outputWidth); target.height = Math.Max(1, outputHeight); target.graphicsFormat = (GraphicsFormat)targetFormat; target.dimension = (TextureDimension)dimension; target.volumeDepth = outputDepth; target.doubleBuffered = rtSettings.doubleBuffered; target.wrapMode = rtSettings.wrapMode; target.filterMode = rtSettings.filterMode; target.useMipMap = hasMips; target.autoGenerateMips = autoGenerateMips; target.Create(); } return(false); }
public MaterialPropertyDescriptor[] GetProperties(MaterialEditor editor, object converter) { RuntimeShaderInfo shaderInfo = null; IRuntimeShaderUtil shaderUtil = IOC.Resolve <IRuntimeShaderUtil>(); if (shaderUtil != null) { shaderInfo = shaderUtil.GetShaderInfo(editor.Material.shader); } if (shaderInfo == null) { return(null); } List <MaterialPropertyDescriptor> descriptors = new List <MaterialPropertyDescriptor>(); if (shaderInfo != null) { for (int i = 0; i < shaderInfo.PropertyCount; ++i) { bool isHidden = shaderInfo.IsHidden[i]; if (isHidden) { continue; } string propertyDescr = shaderInfo.PropertyDescriptions[i]; string propertyName = shaderInfo.PropertyNames[i]; RTShaderPropertyType propertyType = shaderInfo.PropertyTypes[i]; RuntimeShaderInfo.RangeLimits limits = shaderInfo.PropertyRangeLimits[i]; TextureDimension dim = shaderInfo.PropertyTexDims[i]; PropertyInfo propertyInfo = null; switch (propertyType) { case RTShaderPropertyType.Color: propertyInfo = Strong.PropertyInfo((MaterialPropertyAccessor x) => x.Color, "Color"); break; case RTShaderPropertyType.Float: propertyInfo = Strong.PropertyInfo((MaterialPropertyAccessor x) => x.Float, "Float"); break; case RTShaderPropertyType.Range: propertyInfo = Strong.PropertyInfo((MaterialPropertyAccessor x) => x.Float, "Float"); break; case RTShaderPropertyType.TexEnv: switch (dim) { case TextureDimension.Any: propertyInfo = Strong.PropertyInfo((MaterialPropertyAccessor x) => x.Texture, "Texture"); break; case TextureDimension.Cube: propertyInfo = Strong.PropertyInfo((MaterialPropertyAccessor x) => x.Cubemap, "Cubemap"); break; case TextureDimension.None: propertyInfo = null; break; case TextureDimension.Tex2D: propertyInfo = Strong.PropertyInfo((MaterialPropertyAccessor x) => x.Texture2D, "Texture2D"); break; case TextureDimension.Tex2DArray: propertyInfo = Strong.PropertyInfo((MaterialPropertyAccessor x) => x.Texture2DArray, "Texture2DArray"); break; case TextureDimension.Tex3D: propertyInfo = Strong.PropertyInfo((MaterialPropertyAccessor x) => x.Texture3D, "Texture3D"); break; case TextureDimension.Unknown: propertyInfo = null; break; } break; case RTShaderPropertyType.Vector: propertyInfo = Strong.PropertyInfo((MaterialPropertyAccessor x) => x.Vector, "Vector"); break; } if (propertyInfo == null) { continue; } MaterialPropertyDescriptor propertyDescriptor = new MaterialPropertyDescriptor( editor.Material, new MaterialPropertyAccessor(editor.Material, propertyName), propertyDescr, propertyType, propertyInfo, limits, dim, null, (accessorRef, newTarget) => { MaterialPropertyAccessor accessor = (MaterialPropertyAccessor)accessorRef; accessor.Material = newTarget as Material; }); descriptors.Add(propertyDescriptor); } } return(descriptors.ToArray()); }
/// <summary> /// Reads DDS formatted data from a stream. Image data is always returned as DXGI-Compliant /// format, therefore some old legacy formats will automatically be converted. /// </summary> /// <param name="input">Input stream.</param> /// <param name="flags">Flags to control how the DDS data is loaded.</param> /// <returns>Loaded image data, or null if the data failed to load.</returns> public static DDSContainer Read(Stream input, DDSFlags flags = DDSFlags.None) { StreamTransferBuffer buffer = new StreamTransferBuffer(); Header header; Header10?headerExt; //Reads + validates header(s) if (!ReadHeader(input, buffer, out header, out headerExt)) { return(null); } //Gather up metadata List <MipChain> mipChains = null; DXGIFormat format = DXGIFormat.Unknown; TextureDimension texDim = TextureDimension.Two; ConversionFlags convFlags = ConversionFlags.None; bool legacyDword = (flags & DDSFlags.LegacyDword) == DDSFlags.LegacyDword ? true : false; int width = Math.Max((int)header.Width, 1); int height = Math.Max((int)header.Height, 1); int depth = Math.Max((int)header.Depth, 1); int mipCount = (int)header.MipMapCount; int arrayCount = 1; //Has extended header, a modern DDS if (headerExt.HasValue) { Header10 extendedHeader = headerExt.Value; arrayCount = (int)extendedHeader.ArraySize; format = extendedHeader.Format; switch (extendedHeader.ResourceDimension) { case D3D10ResourceDimension.Texture1D: { texDim = TextureDimension.One; if (height > 1 || depth > 1) { return(null); } } break; case D3D10ResourceDimension.Texture2D: { if ((extendedHeader.MiscFlags & Header10Flags.TextureCube) == Header10Flags.TextureCube) { //Specifies # of cubemaps, so to get total # of faces must multiple by 6 arrayCount *= 6; texDim = TextureDimension.Cube; } else { texDim = TextureDimension.Two; } if (depth > 1) { return(null); } } break; case D3D10ResourceDimension.Texture3D: { texDim = TextureDimension.Three; if (arrayCount > 1 || (header.Caps2 & HeaderCaps2.Volume) != HeaderCaps2.Volume) { return(null); } } break; } } else { //Otherwise, read legacy DDS and possibly convert data //Check volume flag if ((header.Caps2 & HeaderCaps2.Volume) == HeaderCaps2.Volume) { texDim = TextureDimension.Three; } else { //legacy DDS could not express 1D textures, so either a cubemap or a 2D non-array texture if ((header.Caps2 & HeaderCaps2.Cubemap) == HeaderCaps2.Cubemap) { //Must have all six faces. DirectX 8 and above always would write out all 6 faces if ((header.Caps2 & HeaderCaps2.Cubemap_AllFaces) != HeaderCaps2.Cubemap_AllFaces) { return(null); } arrayCount = 6; texDim = TextureDimension.Cube; } else { texDim = TextureDimension.Two; } } format = FormatConverter.DetermineDXGIFormat(header.PixelFormat, flags, out convFlags); } //Modify conversion flags, if necessary FormatConverter.ModifyConversionFormat(ref format, ref convFlags, flags); //If palette image, the palette will be the first thing int[] palette = null; if (FormatConverter.HasConversionFlag(convFlags, ConversionFlags.Pal8)) { palette = new int[256]; int palSize = palette.Length * sizeof(int); buffer.ReadBytes(input, palSize); if (buffer.LastReadByteCount != palSize) { return(null); } MemoryHelper.CopyBytes <int>(buffer.ByteArray, 0, palette, 0, palette.Length); } //Now read data based on available mip/arrays mipChains = new List <MipChain>(arrayCount); byte[] scanline = buffer.ByteArray; IntPtr scanlinePtr = buffer.Pointer; bool noPadding = (flags & DDSFlags.NoPadding) == DDSFlags.NoPadding ? true : false; bool isCompressed = FormatConverter.IsCompressed(format); bool errored = false; try { //Iterate over each array face... for (int i = 0; i < arrayCount; i++) { MipChain mipChain = new MipChain(mipCount); mipChains.Add(mipChain); //Iterate over each mip face... for (int mipLevel = 0; mipLevel < mipCount; mipLevel++) { //Calculate mip dimensions int mipWidth = width; int mipHeight = height; int mipDepth = depth; ImageHelper.CalculateMipmapLevelDimensions(mipLevel, ref mipWidth, ref mipHeight, ref mipDepth); //Compute pitch, based on MSDN programming guide which says PitchOrLinearSize is unreliable and to calculate based on format. //"real" mip width/height is the given mip width/height for all non-compressed, compressed images it will be smaller since each block //is a 4x4 region of pixels. int realMipWidth, realMipHeight, dstRowPitch, dstSlicePitch, bytesPerPixel; ImageHelper.ComputePitch(format, mipWidth, mipHeight, out dstRowPitch, out dstSlicePitch, out realMipWidth, out realMipHeight, out bytesPerPixel, legacyDword); int srcRowPitch = dstRowPitch; int srcSlicePitch = dstSlicePitch; //Are we converting from a legacy format, possibly? if (!headerExt.HasValue) { int legacySize = FormatConverter.LegacyFormatBitsPerPixelFromConversionFlag(convFlags); if (legacySize != 0) { srcRowPitch = (realMipWidth * legacySize + 7) / 8; srcSlicePitch = srcRowPitch * realMipHeight; } } //If output data is requested not to have padding, recompute destination pitches if (noPadding) { dstRowPitch = bytesPerPixel * realMipWidth; dstSlicePitch = dstRowPitch * realMipHeight; } //Setup memory to hold the loaded image MipData mipSurface = new MipData(mipWidth, mipHeight, mipDepth, dstRowPitch, dstSlicePitch); mipChain.Add(mipSurface); //Ensure read buffer is sufficiently sized for a single scanline if (buffer.Length < srcRowPitch) { buffer.Resize(srcRowPitch, false); } IntPtr dstPtr = mipSurface.Data; //Advance stream one slice at a time... for (int slice = 0; slice < mipDepth; slice++) { long slicePos = input.Position; IntPtr dPtr = dstPtr; //Copy scanline into temp buffer, do any conversions, copy to output for (int row = 0; row < realMipHeight; row++) { int numBytesRead = input.Read(scanline, 0, srcRowPitch); if (numBytesRead != srcRowPitch) { errored = true; System.Diagnostics.Debug.Assert(false); return(null); } //Copy scanline, optionally convert data FormatConverter.CopyScanline(dPtr, dstRowPitch, scanlinePtr, srcRowPitch, format, convFlags, palette); //Increment dest pointer to next row dPtr = MemoryHelper.AddIntPtr(dPtr, dstRowPitch); } //Advance stream and destination pointer to the next slice input.Position = slicePos + srcSlicePitch; dstPtr = MemoryHelper.AddIntPtr(dstPtr, dstSlicePitch); } } } } finally { //If errored, clean up any mip surfaces we allocated...no null entries should have been made either if (errored) { DisposeMipChains(mipChains); } } if (!ValidateInternal(mipChains, format, texDim)) { System.Diagnostics.Debug.Assert(false); return(null); } return(new DDSContainer(mipChains, format, texDim)); }
/// <summary> /// Initializes a new instance of the <see cref="TexImage"/> class. /// </summary> /// <param name="data">The data.</param> /// <param name="dataSize">Size of the data.</param> /// <param name="width">The width.</param> /// <param name="height">The height.</param> /// <param name="depth">The depth.</param> /// <param name="format">The format.</param> /// <param name="mipmapCount">The mipmap count.</param> /// <param name="arraySize">Size of the array.</param> /// <param name="dimension">The dimension.</param> /// <param name="faceCount">The face count (multiple of 6 if Texture Cube, 1 otherwise).</param> /// <param name="alphaDepth">The depth of the alpha channel</param> public TexImage(IntPtr data, int dataSize, int width, int height, int depth, PixelFormat format, int mipmapCount, int arraySize, TextureDimension dimension, int faceCount = 1, int alphaDepth = -1) { Data = data; DataSize = dataSize; Width = width; Height = height; Depth = depth; Format = format; MipmapCount = mipmapCount; ArraySize = arraySize; Dimension = dimension; FaceCount = faceCount; OriginalAlphaDepth = alphaDepth; Name = ""; int imageCount; if (Dimension == TextureDimension.Texture3D) { int subImagePerArrayElementCount = 0; int curDepth = Depth; for (int i = 0; i < MipmapCount; ++i) { subImagePerArrayElementCount += curDepth; curDepth = curDepth > 1 ? curDepth >>= 1 : curDepth; } imageCount = (int)(ArraySize * FaceCount * subImagePerArrayElementCount); } else { imageCount = (int)(ArraySize * FaceCount * MipmapCount); } SubImageArray = new SubImage[imageCount]; int ct = 0; int rowPitch, slicePitch, curHeight, curWidth; Tools.ComputePitch(Format, Width, Height, out rowPitch, out slicePitch); RowPitch = rowPitch; SlicePitch = slicePitch; for (uint i = 0; i < FaceCount; ++i) { for (uint j = 0; j < ArraySize; ++j) { depth = Depth; for (uint k = 0; k < MipmapCount; ++k) { curWidth = Width; curHeight = Height; Tools.ComputePitch(Format, curWidth, curHeight, out rowPitch, out slicePitch); for (int l = 0; l < depth; ++l) { SubImageArray[ct] = new TexImage.SubImage(); SubImageArray[ct].Width = curWidth; SubImageArray[ct].Height = curHeight; SubImageArray[ct].RowPitch = rowPitch; SubImageArray[ct].SlicePitch = slicePitch; SubImageArray[ct].DataSize = slicePitch; SubImageArray[ct].Data = new IntPtr(Data.ToInt64() + l * slicePitch); ++ct; } depth = depth > 1 ? depth >>= 1 : depth; } } } LibraryData = new Dictionary <ITexLibrary, ITextureLibraryData>(); Disposed = false; }
/// <summary> /// Writes a DDS file to disk. Image data is expected to be DXGI-compliant data, but an effort is made to write out D3D9-compatible headers when possible. /// </summary> /// <param name="fileName">File to write to. If it doesn't exist, it will be created.</param> /// <param name="mipChains">Mipmap chains to write. Each mipmap chain represents a single face (so > 1 represents an array texture or a Cubemap). All faces must have /// equivalent dimensions and each chain must have the same number of mipmaps.</param> /// <param name="format">DXGI format the image data is stored as.</param> /// <param name="texDim">Dimension of the texture to write.</param> /// <param name="flags">Flags to control how the DDS data is saved.</param> /// <returns>True if writing the data was successful, false if otherwise.</returns> public static bool Write(String fileName, List <MipChain> mipChains, DXGIFormat format, TextureDimension texDim, DDSFlags flags = DDSFlags.None) { if (!Directory.Exists(Path.GetDirectoryName(fileName))) { Directory.CreateDirectory(Path.GetDirectoryName(fileName)); } using (FileStream fs = File.Create(fileName)) return(Write(fs, mipChains, format, texDim, flags)); }
// Internal function RTHandle AllocAutoSizedRenderTexture( int width, int height, int slices, DepthBits depthBufferBits, GraphicsFormat colorFormat, FilterMode filterMode, TextureWrapMode wrapMode, TextureDimension dimension, bool enableRandomWrite, bool useMipMap, bool autoGenerateMips, bool isShadowMap, int anisoLevel, float mipMapBias, bool enableMSAA, bool bindTextureMS, bool useDynamicScale, RenderTextureMemoryless memoryless, string name ) { // Here user made a mistake in setting up msaa/bindMS, hence the warning if (!enableMSAA && bindTextureMS == true) { Debug.LogWarning("RTHandle allocated without MSAA but with bindMS set to true, forcing bindMS to false."); bindTextureMS = false; } bool allocForMSAA = m_ScaledRTSupportsMSAA ? enableMSAA : false; // Here we purposefully disable MSAA so we just force the bindMS param to false. if (!allocForMSAA) { bindTextureMS = false; } // MSAA Does not support random read/write. bool UAV = enableRandomWrite; if (allocForMSAA && (UAV == true)) { Debug.LogWarning("RTHandle that is MSAA-enabled cannot allocate MSAA RT with 'enableRandomWrite = true'."); UAV = false; } int msaaSamples = allocForMSAA ? (int)m_ScaledRTCurrentMSAASamples : 1; // We need to handle this in an explicit way since GraphicsFormat does not expose depth formats. TODO: Get rid of this branch once GraphicsFormat'll expose depth related formats RenderTexture rt; if (isShadowMap || depthBufferBits != DepthBits.None) { RenderTextureFormat format = isShadowMap ? RenderTextureFormat.Shadowmap : RenderTextureFormat.Depth; GraphicsFormat stencilFormat = isShadowMap ? GraphicsFormat.None : GraphicsFormat.R8_UInt; rt = new RenderTexture(width, height, (int)depthBufferBits, format, RenderTextureReadWrite.Linear) { hideFlags = HideFlags.HideAndDontSave, volumeDepth = slices, filterMode = filterMode, wrapMode = wrapMode, dimension = dimension, enableRandomWrite = UAV, useMipMap = useMipMap, autoGenerateMips = autoGenerateMips, anisoLevel = anisoLevel, mipMapBias = mipMapBias, antiAliasing = msaaSamples, bindTextureMS = bindTextureMS, useDynamicScale = m_HardwareDynamicResRequested && useDynamicScale, memorylessMode = memoryless, stencilFormat = stencilFormat, name = CoreUtils.GetRenderTargetAutoName(width, height, slices, colorFormat, dimension, name, mips: useMipMap, enableMSAA: allocForMSAA, msaaSamples: m_ScaledRTCurrentMSAASamples, dynamicRes: useDynamicScale) }; } else { rt = new RenderTexture(width, height, (int)depthBufferBits, colorFormat) { hideFlags = HideFlags.HideAndDontSave, volumeDepth = slices, filterMode = filterMode, wrapMode = wrapMode, dimension = dimension, enableRandomWrite = UAV, useMipMap = useMipMap, autoGenerateMips = autoGenerateMips, anisoLevel = anisoLevel, mipMapBias = mipMapBias, antiAliasing = msaaSamples, bindTextureMS = bindTextureMS, useDynamicScale = m_HardwareDynamicResRequested && useDynamicScale, memorylessMode = memoryless, name = CoreUtils.GetRenderTargetAutoName(width, height, slices, colorFormat, dimension, name, mips: useMipMap, enableMSAA: allocForMSAA, msaaSamples: m_ScaledRTCurrentMSAASamples, dynamicRes: useDynamicScale) }; } rt.Create(); var rth = new RTHandle(this); rth.SetRenderTexture(rt); rth.m_EnableMSAA = enableMSAA; rth.m_EnableRandomWrite = enableRandomWrite; rth.useScaling = true; rth.m_EnableHWDynamicScale = useDynamicScale; rth.m_Name = name; m_AutoSizedRTs.Add(rth); return(rth); }
private static bool WriteHeader(Stream output, StreamTransferBuffer buffer, TextureDimension texDim, DXGIFormat format, int width, int height, int depth, int arrayCount, int mipCount, DDSFlags flags) { //Force the DX10 header... bool writeDX10Header = (flags & DDSFlags.ForceExtendedHeader) == DDSFlags.ForceExtendedHeader; //Or do DX10 if the following is true...1D textures or 2D texture arrays that aren't cubemaps... if (!writeDX10Header) { switch (texDim) { case TextureDimension.One: writeDX10Header = true; break; case TextureDimension.Two: writeDX10Header = arrayCount > 1; break; } } //Figure out pixel format, if not writing DX10 header... PixelFormat pixelFormat; if (!writeDX10Header) { switch (format) { case DXGIFormat.R8G8B8A8_UNorm: pixelFormat = PixelFormat.A8B8G8R8; break; case DXGIFormat.R16G16_UNorm: pixelFormat = PixelFormat.G16R16; break; case DXGIFormat.R8G8_UNorm: pixelFormat = PixelFormat.A8L8; break; case DXGIFormat.R16_UNorm: pixelFormat = PixelFormat.L16; break; case DXGIFormat.R8_UNorm: pixelFormat = PixelFormat.L8; break; case DXGIFormat.A8_UNorm: pixelFormat = PixelFormat.A8; break; case DXGIFormat.R8G8_B8G8_UNorm: pixelFormat = PixelFormat.R8G8_B8G8; break; case DXGIFormat.G8R8_G8B8_UNorm: pixelFormat = PixelFormat.G8R8_G8B8; break; case DXGIFormat.BC1_UNorm: pixelFormat = PixelFormat.DXT1; break; case DXGIFormat.BC2_UNorm: pixelFormat = PixelFormat.DXT3; break; case DXGIFormat.BC3_UNorm: pixelFormat = PixelFormat.DXT5; break; case DXGIFormat.BC4_UNorm: pixelFormat = PixelFormat.BC4_UNorm; break; case DXGIFormat.BC4_SNorm: pixelFormat = PixelFormat.BC4_SNorm; break; case DXGIFormat.BC5_UNorm: pixelFormat = PixelFormat.BC5_UNorm; break; case DXGIFormat.BC5_SNorm: pixelFormat = PixelFormat.BC5_SNorm; break; case DXGIFormat.B5G6R5_UNorm: pixelFormat = PixelFormat.R5G6B5; break; case DXGIFormat.B5G5R5A1_UNorm: pixelFormat = PixelFormat.A1R5G5B5; break; case DXGIFormat.B8G8R8A8_UNorm: pixelFormat = PixelFormat.A8R8G8B8; break; case DXGIFormat.B8G8R8X8_UNorm: pixelFormat = PixelFormat.X8R8G8B8; break; case DXGIFormat.B4G4R4A4_UNorm: pixelFormat = PixelFormat.A4R4G4B4; break; case DXGIFormat.R32G32B32A32_Float: pixelFormat = PixelFormat.R32G32B32A32_Float; break; case DXGIFormat.R16G16B16A16_Float: pixelFormat = PixelFormat.R16G16B16A16_Float; break; case DXGIFormat.R16G16B16A16_UNorm: pixelFormat = PixelFormat.R16G16B16A16_UNorm; break; case DXGIFormat.R16G16B16A16_SNorm: pixelFormat = PixelFormat.R16G16B16A16_SNorm; break; case DXGIFormat.R32G32_Float: pixelFormat = PixelFormat.R32G32_Float; break; case DXGIFormat.R16G16_Float: pixelFormat = PixelFormat.R16G16_Float; break; case DXGIFormat.R32_Float: pixelFormat = PixelFormat.R32_Float; break; case DXGIFormat.R16_Float: pixelFormat = PixelFormat.R16_Float; break; default: pixelFormat = PixelFormat.DX10Extended; writeDX10Header = true; break; } } else { pixelFormat = PixelFormat.DX10Extended; } Header header = new Header(); header.Size = (uint)MemoryHelper.SizeOf <Header>(); header.PixelFormat = pixelFormat; header.Flags = HeaderFlags.Caps | HeaderFlags.Width | HeaderFlags.Height | HeaderFlags.PixelFormat; header.Caps = HeaderCaps.Texture; Header10?header10 = null; if (mipCount > 0) { header.Flags |= HeaderFlags.MipMapCount; header.MipMapCount = (uint)mipCount; header.Caps |= HeaderCaps.MipMap; } switch (texDim) { case TextureDimension.One: header.Width = (uint)width; header.Height = 1; header.Depth = 1; //Should always be writing out extended header for 1D textures System.Diagnostics.Debug.Assert(writeDX10Header); header10 = new Header10(format, D3D10ResourceDimension.Texture1D, Header10Flags.None, (uint)arrayCount, Header10Flags2.None); break; case TextureDimension.Two: header.Width = (uint)width; header.Height = (uint)height; header.Depth = 1; if (writeDX10Header) { header10 = new Header10(format, D3D10ResourceDimension.Texture2D, Header10Flags.None, (uint)arrayCount, Header10Flags2.None); } break; case TextureDimension.Cube: header.Width = (uint)width; header.Height = (uint)height; header.Depth = 1; header.Caps |= HeaderCaps.Complex; header.Caps2 |= HeaderCaps2.Cubemap_AllFaces; //can support array tex cubes, so must be multiples of 6 if (arrayCount % 6 != 0) { return(false); } if (writeDX10Header) { header10 = new Header10(format, D3D10ResourceDimension.Texture2D, Header10Flags.TextureCube, (uint)arrayCount / 6, Header10Flags2.None); } break; case TextureDimension.Three: header.Width = (uint)width; header.Height = (uint)height; header.Depth = (uint)depth; header.Flags |= HeaderFlags.Depth; header.Caps2 |= HeaderCaps2.Volume; if (arrayCount != 1) { return(false); } if (writeDX10Header) { header10 = new Header10(format, D3D10ResourceDimension.Texture3D, Header10Flags.None, 1, Header10Flags2.None); } break; } int realWidth, realHeight, rowPitch, slicePitch; ImageHelper.ComputePitch(format, width, height, out rowPitch, out slicePitch, out realWidth, out realHeight); if (FormatConverter.IsCompressed(format)) { header.Flags |= HeaderFlags.LinearSize; header.PitchOrLinearSize = (uint)slicePitch; } else { header.Flags |= HeaderFlags.Pitch; header.PitchOrLinearSize = (uint)rowPitch; } //Write out magic word, DDS header, and optionally extended header buffer.Write <FourCC>(output, DDS_MAGIC); buffer.Write <Header>(output, header); if (header10.HasValue) { System.Diagnostics.Debug.Assert(header.PixelFormat.IsDX10Extended); buffer.Write <Header10>(output, header10.Value); } return(true); }
public SerializedTextureProperty(BinaryReader reader) { m_DefaultName = reader.ReadAlignedString(); m_TexDim = (TextureDimension)reader.ReadInt32(); }
/// <summary> /// Allocate a new fixed sized RTHandle. /// </summary> /// <param name="width">With of the RTHandle.</param> /// <param name="height">Heigh of the RTHandle.</param> /// <param name="slices">Number of slices of the RTHandle.</param> /// <param name="depthBufferBits">Bit depths of a depth buffer.</param> /// <param name="colorFormat">GraphicsFormat of a color buffer.</param> /// <param name="filterMode">Filtering mode of the RTHandle.</param> /// <param name="wrapMode">Addressing mode of the RTHandle.</param> /// <param name="dimension">Texture dimension of the RTHandle.</param> /// <param name="enableRandomWrite">Set to true to enable UAV random read writes on the texture.</param> /// <param name="useMipMap">Set to true if the texture should have mipmaps.</param> /// <param name="autoGenerateMips">Set to true to automatically generate mipmaps.</param> /// <param name="isShadowMap">Set to true if the depth buffer should be used as a shadow map.</param> /// <param name="anisoLevel">Anisotropic filtering level.</param> /// <param name="mipMapBias">Bias applied to mipmaps during filtering.</param> /// <param name="msaaSamples">Number of MSAA samples for the RTHandle.</param> /// <param name="bindTextureMS">Set to true if the texture needs to be bound as a multisampled texture in the shader.</param> /// <param name="useDynamicScale">Set to true to use hardware dynamic scaling.</param> /// <param name="memoryless">Use this property to set the render texture memoryless modes.</param> /// <param name="name">Name of the RTHandle.</param> /// <returns></returns> public RTHandle Alloc( int width, int height, int slices = 1, DepthBits depthBufferBits = DepthBits.None, GraphicsFormat colorFormat = GraphicsFormat.R8G8B8A8_SRGB, FilterMode filterMode = FilterMode.Point, TextureWrapMode wrapMode = TextureWrapMode.Repeat, TextureDimension dimension = TextureDimension.Tex2D, bool enableRandomWrite = false, bool useMipMap = false, bool autoGenerateMips = true, bool isShadowMap = false, int anisoLevel = 1, float mipMapBias = 0f, MSAASamples msaaSamples = MSAASamples.None, bool bindTextureMS = false, bool useDynamicScale = false, RenderTextureMemoryless memoryless = RenderTextureMemoryless.None, string name = "" ) { bool enableMSAA = msaaSamples != MSAASamples.None; if (!enableMSAA && bindTextureMS == true) { Debug.LogWarning("RTHandle allocated without MSAA but with bindMS set to true, forcing bindMS to false."); bindTextureMS = false; } // We need to handle this in an explicit way since GraphicsFormat does not expose depth formats. TODO: Get rid of this branch once GraphicsFormat'll expose depth related formats RenderTexture rt; if (isShadowMap || depthBufferBits != DepthBits.None) { RenderTextureFormat format = isShadowMap ? RenderTextureFormat.Shadowmap : RenderTextureFormat.Depth; rt = new RenderTexture(width, height, (int)depthBufferBits, format, RenderTextureReadWrite.Linear) { hideFlags = HideFlags.HideAndDontSave, volumeDepth = slices, filterMode = filterMode, wrapMode = wrapMode, dimension = dimension, enableRandomWrite = enableRandomWrite, useMipMap = useMipMap, autoGenerateMips = autoGenerateMips, anisoLevel = anisoLevel, mipMapBias = mipMapBias, antiAliasing = (int)msaaSamples, bindTextureMS = bindTextureMS, useDynamicScale = m_HardwareDynamicResRequested && useDynamicScale, memorylessMode = memoryless, name = CoreUtils.GetRenderTargetAutoName(width, height, slices, format, name, mips: useMipMap, enableMSAA: enableMSAA, msaaSamples: msaaSamples) }; } else { rt = new RenderTexture(width, height, (int)depthBufferBits, colorFormat) { hideFlags = HideFlags.HideAndDontSave, volumeDepth = slices, filterMode = filterMode, wrapMode = wrapMode, dimension = dimension, enableRandomWrite = enableRandomWrite, useMipMap = useMipMap, autoGenerateMips = autoGenerateMips, anisoLevel = anisoLevel, mipMapBias = mipMapBias, antiAliasing = (int)msaaSamples, bindTextureMS = bindTextureMS, useDynamicScale = m_HardwareDynamicResRequested && useDynamicScale, memorylessMode = memoryless, name = CoreUtils.GetRenderTargetAutoName(width, height, slices, colorFormat, name, mips: useMipMap, enableMSAA: enableMSAA, msaaSamples: msaaSamples) }; } rt.Create(); var newRT = new RTHandle(this); newRT.SetRenderTexture(rt); newRT.useScaling = false; newRT.m_EnableRandomWrite = enableRandomWrite; newRT.m_EnableMSAA = enableMSAA; newRT.m_EnableHWDynamicScale = useDynamicScale; newRT.m_Name = name; newRT.referenceSize = new Vector2Int(width, height); return(newRT); }
private void GetActualClusterCamParams(int alignedClusterSize) { bool isStereoEnabled = XRSettings.isDeviceActive && !(m_Camera.cameraType == CameraType.SceneView) && m_Camera.stereoEnabled; //Debug.Log("Stereo Enabled: " + isStereoEnabled.ToString()); int currentScreenWidth = isStereoEnabled ? XRSettings.eyeTextureWidth : m_Camera.pixelWidth; int currentScreenHeight = isStereoEnabled ? XRSettings.eyeTextureHeight : m_Camera.pixelHeight; if (StereoEnabled != isStereoEnabled || currentScreenWidth != CameraWidth || currentScreenHeight != CameraHeight) { CameraResolutionChanged = true; m_CameraWidth = currentScreenWidth; m_CameraHeight = currentScreenHeight; StereoEnabled = isStereoEnabled; } else { CameraResolutionChanged = false; } m_ClusterFrustumWidth = (int)Mathf.Ceil((float)CameraWidth / (float)alignedClusterSize) * alignedClusterSize; m_ClusterFrustumHeight = (int)Mathf.Ceil((float)CameraHeight / (float)alignedClusterSize) * alignedClusterSize; if (CameraResolutionChanged) { ClusterResolutionChanged = true; } else { ClusterResolutionChanged = false; } float clusterCamAspect = (float)ClusterFrustumWidth / (float)ClusterFrustumHeight; float dist = CameraHeight * 0.5f / Mathf.Tan(m_Camera.fieldOfView * Mathf.Deg2Rad * 0.5f); float clusterFOV = Mathf.Atan(ClusterFrustumHeight * 0.5f / dist) * Mathf.Rad2Deg * 2.0f; if (StereoEnabled) { Vector3 leftCamPos = m_Camera.GetStereoViewMatrix(Camera.StereoscopicEye.Left).inverse.MultiplyPoint(new Vector3(0, 0, 0)); Vector3 rightCamPos = m_Camera.GetStereoViewMatrix(Camera.StereoscopicEye.Right).inverse.MultiplyPoint(new Vector3(0, 0, 0)); Vector3 rightPos = m_Camera.ScreenToWorldPoint(new Vector3(1, 0.5f, 500.0f), Camera.MonoOrStereoscopicEye.Right); float stereoCamDist = (leftCamPos - rightCamPos).magnitude; float height = Mathf.Tan(m_Camera.fieldOfView * Mathf.Deg2Rad * 0.5f) * m_Camera.farClipPlane * 2.0f; float width = CameraWidth * height / CameraHeight + stereoCamDist; float cameraWidthPixel = ClusterFrustumHeight * width / height; m_ClusterFrustumWidth = (int)Mathf.Ceil(cameraWidthPixel / (float)alignedClusterSize) * alignedClusterSize; float camBackDist = m_Camera.farClipPlane / (width / stereoCamDist - 1); Vector3 centerCamPos = (leftCamPos + rightCamPos) / 2.0f; Vector3 clusterCamPos = centerCamPos - camBackDist * m_Camera.transform.forward; float clusterNear = m_Camera.nearClipPlane + camBackDist; float clusterFar = m_Camera.farClipPlane + camBackDist; float clusterHeight = 0.5f * height * m_ClusterFrustumHeight / m_CameraHeight; float tempTanHalfFOV = 0.5f * height / clusterFar; clusterFOV = Mathf.Atan(clusterHeight / clusterFar) * Mathf.Rad2Deg * 2.0f; clusterCamAspect = (float)ClusterFrustumWidth / (float)ClusterFrustumHeight; Matrix4x4 clusterCamViewMat = Matrix4x4.LookAt(clusterCamPos, clusterCamPos - m_Camera.transform.forward, m_Camera.transform.up).inverse; Matrix4x4 clusterProjMatrix = GL.GetGPUProjectionMatrix(Matrix4x4.Perspective(clusterFOV, clusterCamAspect, clusterNear, clusterFar), true); NearClipPlane = clusterNear; FarClipPlane = clusterFar; ClusterCameraPos = m_Camera.transform.position; MVPMatrix = clusterProjMatrix * clusterCamViewMat; clusterProjMatrix.m22 = -1; clusterProjMatrix.m23 = 0; MVPMatrixLinearZ = clusterProjMatrix * clusterCamViewMat; //UnityEngine.Debug.Log("Cam back dist: " + camBackDist.ToString() + // "\nCamera width: " + CameraWidth.ToString() + // "\nCamera width: " + m_CameraWidth.ToString() + // "\nCamera aspect: " + m_Camera.aspect.ToString() + // "\nCamera forward: " + m_Camera.transform.forward.ToString() + // "\nCamera fov: " + m_Camera.fieldOfView.ToString() + // "\nLeft camera pos: " + leftCamPos.ToString() + // "\nRight camera Pos: " + rightCamPos.ToString() + // "\nRight edge pos: " + rightPos.ToString() + // "\nRight edge clusterPos" + MVPMatrixLinearZ.MultiplyPoint(rightPos).ToString() + // "\nCluster Camera aspect: " + clusterCamAspect.ToString() + // "\nCluster Camera matrix: " + MVPMatrixLinearZ.ToString() + // "\nCamera width: " + cameraWidthPixel.ToString() + // "\nStereo cam dist: " + stereoCamDist.ToString() + // "\nCam near width: " + width.ToString() + // "\nCam near: " + m_Camera.nearClipPlane.ToString() + // "\nCluster far: " + clusterFar.ToString() + // "\nCluster width: " + ClusterFrustumWidth.ToString() + // "\nCluster height: " + ClusterFrustumHeight.ToString() + // "\nCluster cam pos: " + clusterCamPos.ToString()); StereoCamDist = stereoCamDist; RenderTextureDimension = XRSettings.eyeTextureDesc.dimension; } else { NearClipPlane = m_Camera.nearClipPlane; FarClipPlane = m_Camera.farClipPlane;// Mathf.Min(m_Camera.farClipPlane, 500.0f); ClusterCameraPos = m_Camera.transform.position; Matrix4x4 clusterCamViewMat = Matrix4x4.LookAt(m_Camera.transform.position, m_Camera.transform.position - m_Camera.transform.forward, m_Camera.transform.up).inverse; Matrix4x4 projectionMatrix = GL.GetGPUProjectionMatrix(Matrix4x4.Perspective(clusterFOV, clusterCamAspect, NearClipPlane, FarClipPlane), true); MVPMatrix = projectionMatrix * clusterCamViewMat; projectionMatrix.m22 = -1; projectionMatrix.m23 = 0; MVPMatrixLinearZ = projectionMatrix * clusterCamViewMat; Vector3 clusterBottomLeft = MVPMatrix.inverse.MultiplyPoint(new Vector3(-1, -1, 0)); Vector3 clusterUpLeft = MVPMatrix.inverse.MultiplyPoint(new Vector3(-1, 1, 0)); Vector3 clusterBottomRight = MVPMatrix.inverse.MultiplyPoint(new Vector3(1, -1, 0)); clusterBottomLeftCorner = clusterBottomLeft; Vector3 clusterUpVector = (clusterUpLeft - clusterBottomLeft); Vector3 clusterRightVector = (clusterBottomRight - clusterBottomLeft); clusterUpDir = camera.transform.up; clusterUpDir.w = clusterUpVector.magnitude; clusterRightDir = camera.transform.right; clusterRightDir.w = clusterRightVector.magnitude; StereoCamDist = 0; RenderTextureDimension = TextureDimension.Tex2D; } }
/// <summary> /// Initializes a new instance of the <see cref="TexImage"/> class. /// </summary> /// <param name="data">The data.</param> /// <param name="dataSize">Size of the data.</param> /// <param name="width">The width.</param> /// <param name="height">The height.</param> /// <param name="depth">The depth.</param> /// <param name="format">The format.</param> /// <param name="mipmapCount">The mipmap count.</param> /// <param name="arraySize">Size of the array.</param> /// <param name="dimension">The dimension.</param> /// <param name="faceCount">The face count (multiple of 6 if Texture Cube, 1 otherwise).</param> /// <param name="alphaDepth">The depth of the alpha channel</param> public TexImage(IntPtr data, int dataSize, int width, int height, int depth, PixelFormat format, int mipmapCount, int arraySize, TextureDimension dimension, int faceCount = 1, int alphaDepth = -1) { Data = data; DataSize = dataSize; Width = width; Height = height; Depth = depth; Format = format; MipmapCount = mipmapCount; ArraySize = arraySize; Dimension = dimension; FaceCount = faceCount; OriginalAlphaDepth = alphaDepth; Name = ""; int imageCount; if (Dimension == TextureDimension.Texture3D) { int subImagePerArrayElementCount = 0; int curDepth = Depth; for (int i = 0; i < MipmapCount; ++i) { subImagePerArrayElementCount += curDepth; curDepth = curDepth > 1 ? curDepth >>= 1 : curDepth; } imageCount = (int)(ArraySize * FaceCount * subImagePerArrayElementCount); } else { imageCount = (int)(ArraySize * FaceCount * MipmapCount); } SubImageArray = new SubImage[imageCount]; int ct = 0; int rowPitch, slicePitch, curHeight, curWidth; Tools.ComputePitch(Format, Width, Height, out rowPitch, out slicePitch); RowPitch = rowPitch; SlicePitch = slicePitch; for (uint i = 0; i < FaceCount; ++i) { for (uint j = 0; j < ArraySize; ++j) { depth = Depth; for (uint k = 0; k < MipmapCount; ++k) { curWidth = Width; curHeight = Height; Tools.ComputePitch(Format, curWidth, curHeight, out rowPitch, out slicePitch); for (int l = 0; l < depth; ++l) { SubImageArray[ct] = new TexImage.SubImage(); SubImageArray[ct].Width = curWidth; SubImageArray[ct].Height = curHeight; SubImageArray[ct].RowPitch = rowPitch; SubImageArray[ct].SlicePitch = slicePitch; SubImageArray[ct].DataSize = slicePitch; SubImageArray[ct].Data = new IntPtr(Data.ToInt64() + l * slicePitch); ++ct; } depth = depth > 1 ? depth >>= 1 : depth; } } } LibraryData = new Dictionary<ITexLibrary, ITextureLibraryData>(); Disposed = false; }
// // function for creating a template shadermapping json file for a specific shader public static ShaderMapping CreateTemplateForShader(Shader shader) { ShaderMapping mapping = new ShaderMapping() { unityShaderName = shader.name, shaders = new List <ShaderResource>() { new ShaderResource() { sourceFile = shader.name, stages = VkShaderStageFlagBits.VK_SHADER_STAGE_VERTEX_BIT | VkShaderStageFlagBits.VK_SHADER_STAGE_FRAGMENT_BIT } } }; mapping.vertexDependancies = new List <VertexAttributeDependancies> { new VertexAttributeDependancies { attributeType = VertexAttribute.Position, dependantDefines = new List <string> { "ALL" } }, new VertexAttributeDependancies { attributeType = VertexAttribute.Normal, dependantDefines = new List <string> { "VSG_LIGHTING", "VSG_NORMAL_MAP" } }, new VertexAttributeDependancies { attributeType = VertexAttribute.Tangent, dependantDefines = new List <string> { "VSG_NORMAL_MAP" } }, new VertexAttributeDependancies { attributeType = VertexAttribute.Color, dependantDefines = new List <string> { "NONE" } }, new VertexAttributeDependancies { attributeType = VertexAttribute.TexCoord0, dependantDefines = new List <string> { "VSG_DIFFUSE_MAP", "VSG_NORMAL_MAP" } } }; for (int i = 0; i < ShaderUtil.GetPropertyCount(shader); i++) { ShaderUtil.ShaderPropertyType proptype = ShaderUtil.GetPropertyType(shader, i); string propname = ShaderUtil.GetPropertyName(shader, i); if (proptype == ShaderUtil.ShaderPropertyType.TexEnv) { TextureDimension texdims = ShaderUtil.GetTexDim(shader, i); UniformMapping.UniformType textype = UniformMapping.UniformType.UnkownUniform; switch (texdims) { case TextureDimension.Tex2D: { textype = UniformMapping.UniformType.Texture2DUniform; break; } case TextureDimension.Tex2DArray: { textype = UniformMapping.UniformType.Texture2DArrayUniform; break; } default: break; } if (textype == UniformMapping.UniformType.UnkownUniform) { continue; } mapping.uniformMappings.Add(new UniformMapping() { unityPropName = propname, uniformType = textype }); } else if (proptype == ShaderUtil.ShaderPropertyType.Float || proptype == ShaderUtil.ShaderPropertyType.Range) { mapping.uniformMappings.Add(new UniformMapping() { unityPropName = propname, uniformType = UniformMapping.UniformType.FloatUniform }); } else if (proptype == ShaderUtil.ShaderPropertyType.Vector) { mapping.uniformMappings.Add(new UniformMapping() { unityPropName = propname, uniformType = UniformMapping.UniformType.Vec4Uniform }); } else if (proptype == ShaderUtil.ShaderPropertyType.Color) { mapping.uniformMappings.Add(new UniformMapping() { unityPropName = propname, uniformType = UniformMapping.UniformType.ColorUniform }); } } return(mapping); }
// Simple DDS loader ported from http://msdn.microsoft.com/en-us/library/windows/apps/jj651550.aspx static void CreateD3DResources( SharpDX.Direct3D11.Device d3dDevice, TextureDimension resDim, int width, int height, int depth, int mipCount, int arraySize, Format format, bool isCubeMap, DataBox[] initData, //_In_reads_(mipCount*arraySize) D3D11_SUBRESOURCE_DATA* initData, out SharpDX.Direct3D11.Resource texture, out SharpDX.Direct3D11.ShaderResourceView textureView //_Out_opt_ ID3D11Resource** texture, //_Out_opt_ ID3D11ShaderResourceView** textureView ) { texture = null; textureView = null; if (d3dDevice == null || initData == null) { return; } switch (resDim) { case TextureDimension.Texture1D:// D3D11_RESOURCE_DIMENSION_TEXTURE1D: { Texture1DDescription desc = new Texture1DDescription(); //D3D11_TEXTURE1D_DESC desc; desc.Width = width; desc.MipLevels = mipCount; desc.ArraySize = arraySize; desc.Format = format; desc.Usage = ResourceUsage.Default; desc.BindFlags = BindFlags.ShaderResource;// D3D11_BIND_SHADER_RESOURCE; desc.CpuAccessFlags = CpuAccessFlags.None; desc.OptionFlags = ResourceOptionFlags.None; Texture1D tex = null; //ID3D11Texture1D* tex = nullptr; tex = new Texture1D(d3dDevice, desc, initData); //hr = d3dDevice->CreateTexture1D(&desc, initData, &tex); if (tex != null) { ShaderResourceViewDescription SRVDesc = new ShaderResourceViewDescription(); //D3D11_SHADER_RESOURCE_VIEW_DESC SRVDesc; //memset(&SRVDesc, 0, sizeof(SRVDesc)); SRVDesc.Format = format; if (arraySize > 1) { SRVDesc.Dimension = SharpDX.Direct3D.ShaderResourceViewDimension.Texture1DArray;// D3D_SRV_DIMENSION_TEXTURE1DARRAY; SRVDesc.Texture1DArray.MipLevels = desc.MipLevels; SRVDesc.Texture1DArray.ArraySize = arraySize; } else { SRVDesc.Dimension = SharpDX.Direct3D.ShaderResourceViewDimension.Texture1D;// D3D_SRV_DIMENSION_TEXTURE1D; SRVDesc.Texture1D.MipLevels = desc.MipLevels; } textureView = new ShaderResourceView(d3dDevice, tex, SRVDesc); //hr = d3dDevice->CreateShaderResourceView(tex, &SRVDesc, textureView); if (textureView == null) { tex.Dispose(); return; } texture = tex; } } break; case TextureDimension.TextureCube: case TextureDimension.Texture2D:// D3D11_RESOURCE_DIMENSION_TEXTURE2D: { Texture2DDescription desc = new Texture2DDescription(); desc.Width = width; desc.Height = height; desc.MipLevels = mipCount; desc.ArraySize = arraySize; desc.Format = format; desc.SampleDescription.Count = 1; desc.SampleDescription.Quality = 0; desc.Usage = ResourceUsage.Default; desc.BindFlags = BindFlags.ShaderResource; desc.CpuAccessFlags = CpuAccessFlags.None; desc.OptionFlags = (isCubeMap) ? ResourceOptionFlags.TextureCube : ResourceOptionFlags.None; Texture2D tex = null; tex = new Texture2D(d3dDevice, desc, initData); tex.DebugName = "Test"; //hr = d3dDevice->CreateTexture2D(&desc, initData, &tex); if (tex != null) { ShaderResourceViewDescription SRVDesc = new ShaderResourceViewDescription(); SRVDesc.Format = format; if (isCubeMap) { if (arraySize > 6) { SRVDesc.Dimension = SharpDX.Direct3D.ShaderResourceViewDimension.TextureCubeArray; SRVDesc.TextureCubeArray.MipLevels = desc.MipLevels; // Earlier we set arraySize to (NumCubes * 6) SRVDesc.TextureCubeArray.CubeCount = arraySize / 6; } else { SRVDesc.Dimension = SharpDX.Direct3D.ShaderResourceViewDimension.TextureCube; SRVDesc.TextureCube.MipLevels = desc.MipLevels; } } else if (arraySize > 1) { SRVDesc.Dimension = SharpDX.Direct3D.ShaderResourceViewDimension.Texture2DArray; SRVDesc.Texture2DArray.MipLevels = desc.MipLevels; SRVDesc.Texture2DArray.ArraySize = arraySize; } else { SRVDesc.Dimension = SharpDX.Direct3D.ShaderResourceViewDimension.Texture2D; SRVDesc.Texture2D.MipLevels = desc.MipLevels; } textureView = new ShaderResourceView(d3dDevice, tex, SRVDesc); //hr = d3dDevice->CreateShaderResourceView(tex, &SRVDesc, textureView); texture = tex; } } break; case TextureDimension.Texture3D: { Texture3DDescription desc = new Texture3DDescription(); desc.Width = width; desc.Height = height; desc.Depth = depth; desc.MipLevels = mipCount; desc.Format = format; desc.Usage = ResourceUsage.Default; desc.BindFlags = BindFlags.ShaderResource; desc.CpuAccessFlags = CpuAccessFlags.None; desc.OptionFlags = ResourceOptionFlags.None; Texture3D tex = null; tex = new Texture3D(d3dDevice, desc, initData); //hr = d3dDevice->CreateTexture3D(&desc, initData, &tex); if (tex != null) { ShaderResourceViewDescription SRVDesc = new ShaderResourceViewDescription(); SRVDesc.Format = format; SRVDesc.Dimension = SharpDX.Direct3D.ShaderResourceViewDimension.Texture3D; SRVDesc.Texture3D.MipLevels = desc.MipLevels; textureView = new ShaderResourceView(d3dDevice, tex, SRVDesc); texture = tex; } } break; } }
=> TextureArray(dimension, format, width, height, depth); // Tex arrays and 3D texs share the same field for depth/arrayCount so same creation process /// <summary> /// Creates a new <see cref="GpuResourceFormat"/> representing an array of 1 or 2 dimension textures /// </summary> /// <param name="dimension">The dimension of the textures in the array</param> /// <param name="format">The format of the textures in the array</param> /// <param name="width">The width of each texture</param> /// <param name="height">The height of each texture</param> /// <param name="arrayCount">The number of elements in the texture array</param> /// <returns>A new <see cref="GpuResourceFormat"/> representing an array of 1 or 2 dimensional textures</returns> public static GpuResourceFormat TextureArray(TextureDimension dimension, DXGI_FORMAT format, ulong width, uint height = 1, ushort arrayCount = 1) { // can't have 3D tex arrays Debug.Assert(dimension != TextureDimension.Tex3D); return(new GpuResourceFormat(D3D12_RESOURCE_DESC.Tex3D(format, width, height, arrayCount))); }