2 using UnityEngine
.Rendering
;
4 namespace UnityEngine
.Experimental
.Rendering
6 public class TextureCacheCubemap
: TextureCache
8 private CubemapArray m_Cache
;
10 const int k_NbFace
= 6;
12 // the member variables below are only in use when TextureCache.supportsCubemapArrayTextures is false
13 private Texture2DArray m_CacheNoCubeArray
;
14 private RenderTexture
[] m_StagingRTs
;
15 private int m_NumPanoMipLevels
;
16 private Material m_CubeBlitMaterial
;
17 private int m_CubeMipLevelPropName
;
18 private int m_cubeSrcTexPropName
;
20 public TextureCacheCubemap(string cacheName
= "", int sliceSize
= 1)
21 : base(cacheName
, sliceSize
)
25 override protected bool TransferToSlice(CommandBuffer cmd
, int sliceIndex
, Texture
[] textureArray
)
27 if (!TextureCache
.supportsCubemapArrayTextures
)
28 return TransferToPanoCache(cmd
, sliceIndex
, textureArray
);
31 // Make sure the array is not null or empty and that the first texture is a render-texture or a texture2D
32 if (textureArray
== null || textureArray
.Length
== 0)
37 // First check here is to check if all the sub-texture have the same size
38 for (int texIDx
= 1; texIDx
< textureArray
.Length
; ++texIDx
)
40 // We cannot update if the textures if they don't have the same size or not the right type
41 if (textureArray
[texIDx
].width
!= textureArray
[0].width
|| textureArray
[texIDx
].height
!= textureArray
[0].height
)
43 Debug
.LogWarning("All the sub-textures should have the same dimensions to be handled by the texture cache.");
48 var mismatch
= (m_Cache
.width
!= textureArray
[0].width
) || (m_Cache
.height
!= textureArray
[0].height
);
50 if (textureArray
[0] is Cubemap
)
52 mismatch
|= (m_Cache
.format
!= (textureArray
[0] as Cubemap
).format
);
55 for (int texIDx
= 0; texIDx
< textureArray
.Length
; ++texIDx
)
59 for (int f
= 0; f
< 6; f
++)
61 cmd
.ConvertTexture(textureArray
[texIDx
], f
, m_Cache
, 6 * (m_SliceSize
* sliceIndex
+ texIDx
) + f
);
66 for (int f
= 0; f
< 6; f
++)
67 cmd
.CopyTexture(textureArray
[texIDx
], f
, m_Cache
, 6 * (m_SliceSize
* sliceIndex
+ texIDx
) + f
);
75 public override Texture
GetTexCache()
77 return !TextureCache
.supportsCubemapArrayTextures
? (Texture
)m_CacheNoCubeArray
: m_Cache
;
80 public bool AllocTextureArray(int numCubeMaps
, int width
, TextureFormat format
, bool isMipMapped
, Material cubeBlitMaterial
)
82 var res
= AllocTextureArray(numCubeMaps
);
83 m_NumMipLevels
= GetNumMips(width
, width
); // will calculate same way whether we have cube array or not
85 if (!TextureCache
.supportsCubemapArrayTextures
)
87 m_CubeBlitMaterial
= cubeBlitMaterial
;
89 int panoWidthTop
= 4 * width
;
90 int panoHeightTop
= 2 * width
;
92 // create panorama 2D array. Hardcoding the render target for now. No convenient way atm to
93 // map from TextureFormat to RenderTextureFormat and don't want to deal with sRGB issues for now.
94 m_CacheNoCubeArray
= new Texture2DArray(panoWidthTop
, panoHeightTop
, numCubeMaps
, TextureFormat
.RGBAHalf
, isMipMapped
)
96 hideFlags
= HideFlags
.HideAndDontSave
,
97 wrapMode
= TextureWrapMode
.Repeat
,
98 wrapModeV
= TextureWrapMode
.Clamp
,
99 filterMode
= FilterMode
.Trilinear
,
101 name
= CoreUtils
.GetTextureAutoName(panoWidthTop
, panoHeightTop
, format
, TextureDimension
.Tex2DArray
, depth
: numCubeMaps
, name
: m_CacheName
)
104 m_NumPanoMipLevels
= isMipMapped
? GetNumMips(panoWidthTop
, panoHeightTop
) : 1;
105 m_StagingRTs
= new RenderTexture
[m_NumPanoMipLevels
];
106 for (int m
= 0; m
< m_NumPanoMipLevels
; m
++)
108 m_StagingRTs
[m
] = new RenderTexture(Mathf
.Max(1, panoWidthTop
>> m
), Mathf
.Max(1, panoHeightTop
>> m
), 0, RenderTextureFormat
.ARGBHalf
) { hideFlags = HideFlags.HideAndDontSave }
;
109 m_StagingRTs
[m
].name
= CoreUtils
.GetRenderTargetAutoName(Mathf
.Max(1, panoWidthTop
>> m
), Mathf
.Max(1, panoHeightTop
>> m
), 1, RenderTextureFormat
.ARGBHalf
, String
.Format("PanaCache{0}", m
));
112 if (m_CubeBlitMaterial
)
114 m_CubeMipLevelPropName
= Shader
.PropertyToID("_cubeMipLvl");
115 m_cubeSrcTexPropName
= Shader
.PropertyToID("_srcCubeTexture");
120 m_Cache
= new CubemapArray(width
, numCubeMaps
, format
, isMipMapped
)
122 hideFlags
= HideFlags
.HideAndDontSave
,
123 wrapMode
= TextureWrapMode
.Clamp
,
124 filterMode
= FilterMode
.Trilinear
,
125 anisoLevel
= 0, // It is important to set 0 here, else unity force anisotropy filtering
126 name
= CoreUtils
.GetTextureAutoName(width
, width
, format
, TextureDimension
.CubeArray
, depth
: numCubeMaps
, name
: m_CacheName
)
133 public void Release()
135 if (m_CacheNoCubeArray
)
137 CoreUtils
.Destroy(m_CacheNoCubeArray
);
138 for (int m
= 0; m
< m_NumPanoMipLevels
; m
++)
140 m_StagingRTs
[m
].Release();
143 CoreUtils
.Destroy(m_CubeBlitMaterial
);
146 CoreUtils
.Destroy(m_Cache
);
149 private bool TransferToPanoCache(CommandBuffer cmd
, int sliceIndex
, Texture
[] textureArray
)
151 for(int texIdx
= 0; texIdx
< textureArray
.Length
; ++texIdx
)
153 m_CubeBlitMaterial
.SetTexture(m_cubeSrcTexPropName
, textureArray
[texIdx
]);
154 for (int m
= 0; m
< m_NumPanoMipLevels
; m
++)
156 m_CubeBlitMaterial
.SetInt(m_CubeMipLevelPropName
, Mathf
.Min(m_NumMipLevels
- 1, m
));
157 cmd
.Blit(null, m_StagingRTs
[m
], m_CubeBlitMaterial
, 0);
160 for (int m
= 0; m
< m_NumPanoMipLevels
; m
++)
161 cmd
.CopyTexture(m_StagingRTs
[m
], 0, 0, m_CacheNoCubeArray
, m_SliceSize
* sliceIndex
+ texIdx
, m
);
166 internal static long GetApproxCacheSizeInByte(int nbElement
, int resolution
, int sliceSize
)
168 return (long)((long)nbElement
* resolution
* resolution
* k_NbFace
* k_FP16SizeInByte
* k_NbChannel
* k_MipmapFactorApprox
* sliceSize
);
171 internal static int GetMaxCacheSizeForWeightInByte(long weight
, int resolution
, int sliceSize
)
173 int theoricalResult
= Mathf
.FloorToInt(weight
/ ((long)resolution
* resolution
* k_NbFace
* k_FP16SizeInByte
* k_NbChannel
* k_MipmapFactorApprox
* sliceSize
));
174 return Mathf
.Clamp(theoricalResult
, 1, k_MaxSupported
);