public ChunkRenderer(Effect simpleShader, GraphicsDevice graphicsDevice, Matrix projection, Texture2DArray textures) { this.graphicsDevice = graphicsDevice; this.textures = textures; this.lastReset = -1; simple = simpleShader; GenerateIndexBuffer(); }
public Pair(string key, Texture2DArray value) { this.key = key; this.value = value; }
static public VFXValue <Texture> Constant(Texture2DArray value) { return(new VFXTexture2DArrayValue(value, Mode.Constant)); }
private void DoSliceScrubber(Rect controlRect, Texture2DArray t) { int id = GUIUtility.GetControlID(kScrubberHash, FocusType.Keyboard); Rect prevFrameRect = controlRect; prevFrameRect.width = kSliceStepWidth; Rect nextFrameRect = prevFrameRect; nextFrameRect.x += nextFrameRect.width; var scrubberRect = controlRect; scrubberRect.xMin = nextFrameRect.xMax; var evt = Event.current; switch (evt.GetTypeForControl(id)) { case EventType.MouseDown: { if (scrubberRect.Contains(evt.mousePosition)) { GUIUtility.keyboardControl = id; GUIUtility.hotControl = id; m_MouseDrag = evt.mousePosition.x - scrubberRect.xMin; m_Slice = (int)(m_MouseDrag * t.depth / scrubberRect.width); evt.Use(); } break; } case EventType.MouseDrag: { if (GUIUtility.hotControl == id) { m_MouseDrag += evt.delta.x; m_Slice = (int)(Mathf.Clamp(m_MouseDrag, 0.0f, scrubberRect.width) * t.depth / scrubberRect.width); evt.Use(); } break; } case EventType.MouseUp: { if (GUIUtility.hotControl == id) { GUIUtility.hotControl = 0; evt.Use(); } break; } case EventType.KeyDown: { if (GUIUtility.keyboardControl == id) { if (evt.keyCode == KeyCode.LeftArrow) { if (m_Slice > 0) { --m_Slice; } evt.Use(); } if (evt.keyCode == KeyCode.RightArrow) { if (m_Slice < t.depth - 1) { ++m_Slice; } evt.Use(); } } break; } case EventType.Repaint: { Styles.sliceScrubber.Draw(controlRect, GUIContent.none, id); float normalizedPosition = Mathf.Lerp(scrubberRect.x, scrubberRect.xMax, m_Slice / (float)(t.depth - 1)); TimeArea.DrawPlayhead(normalizedPosition, scrubberRect.yMin, scrubberRect.yMax, 2f, (GUIUtility.keyboardControl == id) ? 1f : 0.5f); break; } } using (new EditorGUI.DisabledGroupScope(m_Slice <= 0)) { if (GUI.Button(prevFrameRect, Styles.prevSliceIcon, Styles.stepSlice)) { m_Slice--; } } using (new EditorGUI.DisabledGroupScope(m_Slice >= t.depth - 1)) { if (GUI.Button(nextFrameRect, Styles.nextSliceIcon, Styles.stepSlice)) { m_Slice++; } } }
/// <summary> /// Initialize the needed resources /// </summary> private void InitializeResources() { _postProcessShader = Aura.ResourcesCollection.postProcessShader; _blueNoiseTexturesArray = Aura.ResourcesCollection.blueNoiseTextureArray; }
void LoadWorldTextures() { requireTextureArrayUpdate = false; // Init texture array if (worldTextures == null) { worldTextures = new List <WorldTexture> (); } else { worldTextures.Clear(); } if (worldTexturesDict == null) { worldTexturesDict = new Dictionary <Texture2D, int> (); } else { worldTexturesDict.Clear(); } // Clear definitions if (voxelDefinitions != null) { // Voxel Definitions no longer are added to the dictionary, clear the index field. for (int k = 0; k < voxelDefinitionsCount; k++) { if (voxelDefinitions [k] != null) { voxelDefinitions [k].Reset(); } } } else { voxelDefinitions = new VoxelDefinition[128]; } voxelDefinitionsCount = 0; if (voxelDefinitionsDict == null) { voxelDefinitionsDict = new Dictionary <string, VoxelDefinition> (); } else { voxelDefinitionsDict.Clear(); } if (sessionUserVoxels == null) { sessionUserVoxels = new List <VoxelDefinition> (); } // The null voxel definition VoxelDefinition nullVoxelDefinition = ScriptableObject.CreateInstance <VoxelDefinition> (); nullVoxelDefinition.name = "Null"; nullVoxelDefinition.hidden = true; nullVoxelDefinition.canBeCollected = false; nullVoxelDefinition.ignoresRayCast = true; nullVoxelDefinition.renderType = RenderType.Empty; AddVoxelTextures(nullVoxelDefinition); // Check default voxel if (defaultVoxel == null) { defaultVoxel = Resources.Load <VoxelDefinition> ("VoxelPlay/Defaults/DefaultVoxel"); } AddVoxelTextures(defaultVoxel); // Add all biome textures if (world.biomes != null) { for (int k = 0; k < world.biomes.Length; k++) { BiomeDefinition biome = world.biomes [k]; if (biome == null) { continue; } AddVoxelTextures(biome.voxelTop); if (biome.voxelTop.biomeDirtCounterpart == null) { biome.voxelTop.biomeDirtCounterpart = biome.voxelDirt; } AddVoxelTextures(biome.voxelDirt); if (biome.vegetation != null) { for (int v = 0; v < biome.vegetation.Length; v++) { AddVoxelTextures(biome.vegetation [v].vegetation); } } if (biome.trees != null) { for (int t = 0; t < biome.trees.Length; t++) { ModelDefinition tree = biome.trees [t].tree; if (tree == null) { continue; } for (int b = 0; b < tree.bits.Length; b++) { AddVoxelTextures(tree.bits [b].voxelDefinition); } } } if (biome.ores != null) { for (int v = 0; v < biome.ores.Length; v++) { // ensure proper size if (biome.ores [v].veinMinSize == biome.ores [v].veinMaxSize && biome.ores [v].veinMaxSize == 0) { biome.ores [v].veinMinSize = 2; biome.ores [v].veinMaxSize = 6; biome.ores [v].veinsCountMin = 1; biome.ores [v].veinsCountMax = 2; } AddVoxelTextures(biome.ores [v].ore); } } } } // Special voxels if (world.cloudVoxel == null) { world.cloudVoxel = Resources.Load <VoxelDefinition> ("VoxelPlay/Defaults/VoxelCloud"); } AddVoxelTextures(world.cloudVoxel); // Add additional world voxels if (world.moreVoxels != null) { for (int k = 0; k < world.moreVoxels.Length; k++) { AddVoxelTextures(world.moreVoxels [k]); } } // Add all items' textures are available if (world.items != null) { int itemCount = world.items.Length; for (int k = 0; k < itemCount; k++) { ItemDefinition item = world.items [k]; if (item.category == ItemCategory.Voxel) { AddVoxelTextures(item.voxelType); } } } // Add any other voxel found inside Defaults VoxelDefinition[] vdd = Resources.LoadAll <VoxelDefinition> ("VoxelPlay/Defaults"); for (int k = 0; k < vdd.Length; k++) { AddVoxelTextures(vdd [k]); } // Add any other voxel found inside World directory vdd = Resources.LoadAll <VoxelDefinition> ("Worlds/" + world.name); for (int k = 0; k < vdd.Length; k++) { AddVoxelTextures(vdd [k]); } // Add any other voxel found inside a resource directory with same name of world (if not placed into Worlds directory) vdd = Resources.LoadAll <VoxelDefinition> (world.name); for (int k = 0; k < vdd.Length; k++) { AddVoxelTextures(vdd [k]); } // Add any other voxel found inside a resource directory under the world definition asset if (!string.IsNullOrEmpty(world.resourceLocation)) { vdd = Resources.LoadAll <VoxelDefinition> (world.resourceLocation); for (int k = 0; k < vdd.Length; k++) { AddVoxelTextures(vdd [k]); } } // Add user provided voxels during playtime int count = sessionUserVoxels.Count; for (int k = 0; k < count; k++) { AddVoxelTextures(sessionUserVoxels [k]); } // Unload textures (doesn't work at runtime on PC! this commented section should be removed) // #if !UNITY_EDITOR // for (int k = 0; k < voxelDefinitionsCount; k++) { // VoxelDefinition vd = voxelDefinitions [k]; // if (vd.index == 0) // continue; // if (vd.textureTop != null) // Resources.UnloadAsset (vd.textureTop); // if (vd.textureTopEmission != null) // Resources.UnloadAsset (vd.textureTopEmission); // if (vd.textureTopNRM != null) // Resources.UnloadAsset (vd.textureTopNRM); // if (vd.textureTopDISP != null) // Resources.UnloadAsset (vd.textureTopDISP); // if (vd.textureLeft != null) // Resources.UnloadAsset (vd.textureLeft); // if (vd.textureLeftEmission != null) // Resources.UnloadAsset (vd.textureLeftEmission); // if (vd.textureLeftNRM != null) // Resources.UnloadAsset (vd.textureLeftNRM); // if (vd.textureLeftDISP != null) // Resources.UnloadAsset (vd.textureLeftDISP); // if (vd.textureRight != null) // Resources.UnloadAsset (vd.textureRight); // if (vd.textureRightEmission != null) // Resources.UnloadAsset (vd.textureRightEmission); // if (vd.textureRightNRM != null) // Resources.UnloadAsset (vd.textureRightNRM); // if (vd.textureRightDISP != null) // Resources.UnloadAsset (vd.textureRightDISP); // if (vd.textureBottom != null) // Resources.UnloadAsset (vd.textureBottom); // if (vd.textureBottomEmission != null) // Resources.UnloadAsset (vd.textureBottomEmission); // if (vd.textureBottomNRM != null) // Resources.UnloadAsset (vd.textureBottomNRM); // if (vd.textureBottomDISP != null) // Resources.UnloadAsset (vd.textureBottomDISP); // if (vd.textureSide != null) // Resources.UnloadAsset (vd.textureSide); // if (vd.textureSideEmission != null) // Resources.UnloadAsset (vd.textureSideEmission); // if (vd.textureSideNRM != null) // Resources.UnloadAsset (vd.textureSideNRM); // if (vd.textureSideDISP != null) // Resources.UnloadAsset (vd.textureSideDISP); // if (vd.textureForward != null) // Resources.UnloadAsset (vd.textureForward); // if (vd.textureForwardEmission != null) // Resources.UnloadAsset (vd.textureForwardEmission); // if (vd.textureForwardNRM != null) // Resources.UnloadAsset (vd.textureForwardNRM); // if (vd.textureForwardDISP != null) // Resources.UnloadAsset (vd.textureForwardDISP); // } // #endif // Add transparent voxel definitions for the see-through effect if (seeThrough) { for (int k = 0; k < voxelDefinitionsCount; k++) { VoxelDefinition vd = voxelDefinitions [k]; float alpha = vd.seeThroughAlphaMultiplier * seeThroughAlpha; if (vd.seeThroughMode == SeeThroughMode.Transparency && vd.seeThroughVoxelTempTransp <= 0) { if (alpha > 0 && vd.renderType.supportsSeeThrough()) { vd.seeThroughVoxelTempTransp = CreateSeeThroughVariantVoxelDefinition(vd, alpha); } else { vd.seeThroughMode = SeeThroughMode.None; } } } } // Create array texture int textureCount = worldTextures.Count; if (textureCount > 0) { Texture2DArray pointFilterTextureArray = new Texture2DArray(textureSize, textureSize, textureCount, TextureFormat.ARGB32, hqFiltering); if (enableReliefMapping || !enableSmoothLighting) { pointFilterTextureArray.wrapMode = TextureWrapMode.Repeat; } else { pointFilterTextureArray.wrapMode = TextureWrapMode.Clamp; } pointFilterTextureArray.filterMode = hqFiltering ? FilterMode.Bilinear : FilterMode.Point; pointFilterTextureArray.mipMapBias = -mipMapBias; for (int k = 0; k < textureCount; k++) { if (worldTextures [k].colorsAndEmission != null) { pointFilterTextureArray.SetPixels32(worldTextures [k].colorsAndEmission, k); } else if (worldTextures [k].normalsAndElevation != null) { pointFilterTextureArray.SetPixels32(worldTextures [k].normalsAndElevation, k); } } worldTextures.Clear(); pointFilterTextureArray.Apply(hqFiltering, true); // Assign textures to materials for (int k = 0; k < materials.Length; k++) { if (materials [k] != null && materials [k].HasProperty("_MainTex")) { materials [k].SetTexture("_MainTex", pointFilterTextureArray); } } if (modelHighlightMat == null) { modelHighlightMat = Instantiate <Material> (Resources.Load <Material> ("VoxelPlay/Materials/VP Highlight Model")) as Material; } modelHighlightMat.SetTexture("_MainTex", pointFilterTextureArray); } }
void RestorePrototypes() { if (templateMaterial != null) { Texture2DArray diffuseArray = templateMaterial.GetTexture("_Diffuse") as Texture2DArray; if (diffuseArray != null) { var cfg = JBooth.MicroSplat.TextureArrayConfig.FindConfig(diffuseArray); if (cfg != null) { int count = cfg.sourceTextures.Count; if (count > 32) { count = 32; } #if UNITY_2018_3_OR_NEWER var protos = terrain.terrainData.terrainLayers; bool needsRefresh = false; if (protos.Length != count) { needsRefresh = true; } if (!needsRefresh) { for (int i = 0; i < protos.Length; ++i) { if (protos[i] == null) { needsRefresh = true; break; } if (protos[i] != null && cfg.sourceTextures[i] != null && protos[i].diffuseTexture != cfg.sourceTextures[i].diffuse) { needsRefresh = true; break; } } } if (needsRefresh) { Vector4 v4 = templateMaterial.GetVector("_UVScale"); Vector2 uvScales = new Vector2(v4.x, v4.y); uvScales = MicroSplatRuntimeUtil.UVScaleToUnityUVScale(uvScales, terrain); protos = new TerrainLayer[count]; for (int i = 0; i < count; ++i) { string path = UnityEditor.AssetDatabase.GetAssetPath(cfg); path = path.Replace("\\", "/"); path = path.Substring(0, path.LastIndexOf("/")); path += "/microsplat_layer_"; path = path.Replace("//", "/"); if (cfg.sourceTextures[i].diffuse != null) { path += cfg.sourceTextures[i].diffuse.name; } path += "_" + i; path += ".terrainlayer"; TerrainLayer sp = UnityEditor.AssetDatabase.LoadAssetAtPath <TerrainLayer>(path); if (sp != null) { if (sp.diffuseTexture == cfg.sourceTextures[i].diffuse) { protos[i] = sp; continue; } } sp = new TerrainLayer(); sp.diffuseTexture = cfg.sourceTextures[i].diffuse; sp.tileSize = uvScales; if (cfg.sourceTextures[i].normal != null) { sp.normalMapTexture = cfg.sourceTextures[i].normal; } protos[i] = sp; UnityEditor.AssetDatabase.CreateAsset(sp, path); } terrain.terrainData.terrainLayers = protos; UnityEditor.EditorUtility.SetDirty(terrain); UnityEditor.EditorUtility.SetDirty(terrain.terrainData); } #else var protos = terrain.terrainData.splatPrototypes; bool needsRefresh = false; if (protos.Length != count) { needsRefresh = true; } if (!needsRefresh) { for (int i = 0; i < protos.Length; ++i) { if (protos[i].texture != cfg.sourceTextures[i].diffuse) { needsRefresh = true; } } } if (needsRefresh) { Vector4 v4 = templateMaterial.GetVector("_UVScale"); Vector2 uvScales = new Vector2(v4.x, v4.y); uvScales = MicroSplatRuntimeUtil.UVScaleToUnityUVScale(uvScales, terrain); protos = new SplatPrototype[count]; for (int i = 0; i < count; ++i) { SplatPrototype sp = new SplatPrototype(); sp.texture = cfg.sourceTextures[i].diffuse; sp.tileSize = uvScales; if (cfg.sourceTextures[i].normal != null) { sp.normalMap = cfg.sourceTextures[i].normal; } protos[i] = sp; } terrain.terrainData.splatPrototypes = protos; UnityEditor.EditorUtility.SetDirty(terrain); UnityEditor.EditorUtility.SetDirty(terrain.terrainData); } #endif } } } }
public override void OnImportAsset(AssetImportContext ctx) { byte[] bytes = File.ReadAllBytes(ctx.assetPath); Texture2D sourceTexture = new Texture2D(1, 1, TextureFormat.ARGB32, false); sourceTexture.LoadImage(bytes); originalWidth = sourceTexture.width; originalHeight = sourceTexture.height; cols = sourceTexture.width / pageSize; if (cols == 0) { cols = 1; } rows = sourceTexture.height / pageSize; if (rows == 0) { rows = 1; } bool changedPageSize = false; while (cols * rows > 2048) { pageSize *= 2; cols /= 2; rows /= 2; changedPageSize = true; } if (changedPageSize) { ctx.LogImportWarning("Texture Width * Texture Height * Page Size must be less or equal to 2048, so the Page Size is increased to " + pageSize); } int resizeX = sourceTexture.width; int resizeY = sourceTexture.height; if (sourceTexture.width % pageSize != 0) { resizeX = cols * pageSize; } if (sourceTexture.height % pageSize != 0) { resizeY = rows * pageSize; } if (resizeX != sourceTexture.width || resizeY != sourceTexture.height) { TextureScaler.Scale(sourceTexture, resizeX, resizeY); ctx.LogImportWarning("The width and height of the texture must be equal to Page Size * N, so the texture size is changed to " + resizeX + "x" + resizeY); } Texture2DArray array = InitTexture2DArray(sourceTexture, ctx); ctx.AddObjectToAsset("_MainTex", array); ctx.SetMainObject(array); DestroyImmediate(sourceTexture); }
private Texture2DArray InitTexture2DArray(Texture2D sourceTexture, AssetImportContext ctx) { TextureFormat format = GetTextureFormat(ctx.selectedBuildTarget, compressed, transparent); EditorUtility.DisplayProgressBar("Import Huge Texture", ctx.assetPath, 0); Texture2DArray array = null; try { if (format == sourceTexture.format) { array = new Texture2DArray(pageSize, pageSize, cols * rows, sourceTexture.format, false); array.wrapMode = TextureWrapMode.Clamp; for (int x = 0; x < cols; x++) { for (int y = 0; y < rows; y++) { EditorUtility.DisplayProgressBar("Import Huge Texture", ctx.assetPath, (x * rows + y) / (float)(cols * rows)); Graphics.CopyTexture(sourceTexture, 0, 0, x * pageSize, y * pageSize, pageSize, pageSize, array, y * cols + x, 0, 0, 0); } } } else if (!compressed) { array = new Texture2DArray(pageSize, pageSize, cols * rows, format, false); array.wrapMode = TextureWrapMode.Clamp; for (int x = 0; x < cols; x++) { for (int y = 0; y < rows; y++) { EditorUtility.DisplayProgressBar("Import Huge Texture", ctx.assetPath, (x * rows + y) / (float)(cols * rows)); Color[] colors = sourceTexture.GetPixels(x * pageSize, y * pageSize, pageSize, pageSize); array.SetPixels(colors, y * cols + x); } } } else if (transparent) { array = new Texture2DArray(pageSize, pageSize, cols * rows, format, false); array.wrapMode = TextureWrapMode.Clamp; for (int x = 0; x < cols; x++) { for (int y = 0; y < rows; y++) { EditorUtility.DisplayProgressBar("Import Huge Texture", ctx.assetPath, (x * rows + y) / (float)(cols * rows)); Texture2D tempTexture = new Texture2D(pageSize, pageSize); Color[] colors = sourceTexture.GetPixels(x * pageSize, y * pageSize, pageSize, pageSize); tempTexture.SetPixels(colors); tempTexture.Apply(); EditorUtility.CompressTexture(tempTexture, format, quality); array.SetPixelData(tempTexture.GetRawTextureData(), 0, y * cols + x); DestroyImmediate(tempTexture); } } } else { array = new Texture2DArray(pageSize, pageSize, cols * rows, format, false); array.wrapMode = TextureWrapMode.Clamp; for (int x = 0; x < cols; x++) { for (int y = 0; y < rows; y++) { EditorUtility.DisplayProgressBar("Import Huge Texture", ctx.assetPath, (x * rows + y) / (float)(cols * rows)); Texture2D tempTexture = new Texture2D(pageSize, pageSize, TextureFormat.RGB24, false); Color[] colors = sourceTexture.GetPixels(x * pageSize, y * pageSize, pageSize, pageSize); tempTexture.SetPixels(colors); tempTexture.Apply(); EditorUtility.CompressTexture(tempTexture, format, quality); array.SetPixelData(tempTexture.GetRawTextureData(), 0, y * cols + x); DestroyImmediate(tempTexture); } } } array.Apply(false); } catch { } EditorUtility.ClearProgressBar(); return(array); }
public bool AllocTextureArray(int numCubeMaps, int width, GraphicsFormat format, bool isMipMapped, Material cubeBlitMaterial) { var res = AllocTextureArray(numCubeMaps); m_NumMipLevels = GetNumMips(width, width); // will calculate same way whether we have cube array or not if (!TextureCache.supportsCubemapArrayTextures) { m_CubeBlitMaterial = cubeBlitMaterial; int panoWidthTop = 4 * width; int panoHeightTop = 2 * width; // create panorama 2D array. Hardcoding the render target for now. No convenient way atm to // map from TextureFormat to RenderTextureFormat and don't want to deal with sRGB issues for now. m_CacheNoCubeArray = new Texture2DArray(panoWidthTop, panoHeightTop, numCubeMaps, TextureFormat.RGBAHalf, isMipMapped) { hideFlags = HideFlags.HideAndDontSave, wrapMode = TextureWrapMode.Repeat, wrapModeV = TextureWrapMode.Clamp, filterMode = FilterMode.Trilinear, anisoLevel = 0, name = CoreUtils.GetTextureAutoName(panoWidthTop, panoHeightTop, TextureFormat.RGBAHalf, TextureDimension.Tex2DArray, depth: numCubeMaps, name: m_CacheName) }; m_NumPanoMipLevels = isMipMapped ? GetNumMips(panoWidthTop, panoHeightTop) : 1; m_StagingRTs = new RenderTexture[m_NumPanoMipLevels]; for (int m = 0; m < m_NumPanoMipLevels; m++) { m_StagingRTs[m] = new RenderTexture(Mathf.Max(1, panoWidthTop >> m), Mathf.Max(1, panoHeightTop >> m), 0, RenderTextureFormat.ARGBHalf) { hideFlags = HideFlags.HideAndDontSave }; m_StagingRTs[m].name = CoreUtils.GetRenderTargetAutoName(Mathf.Max(1, panoWidthTop >> m), Mathf.Max(1, panoHeightTop >> m), 1, RenderTextureFormat.ARGBHalf, String.Format("PanaCache{0}", m)); } if (m_CubeBlitMaterial) { m_CubeMipLevelPropName = Shader.PropertyToID("_cubeMipLvl"); m_cubeSrcTexPropName = Shader.PropertyToID("_srcCubeTexture"); } } else { var desc = new RenderTextureDescriptor(width, width, format, 0) { dimension = TextureDimension.CubeArray, volumeDepth = numCubeMaps * 6, // We need to multiply by the face count of a cubemap here autoGenerateMips = false, useMipMap = isMipMapped, msaaSamples = 1, }; m_Cache = new RenderTexture(desc) { hideFlags = HideFlags.HideAndDontSave, wrapMode = TextureWrapMode.Clamp, filterMode = FilterMode.Trilinear, anisoLevel = 0, // It is important to set 0 here, else unity force anisotropy filtering name = CoreUtils.GetTextureAutoName(width, width, format, desc.dimension, depth: numCubeMaps, name: m_CacheName, mips: isMipMapped) }; // We need to clear the content in case it is read on first frame, since on console we have no guarantee that // the content won't be NaN ClearCache(); m_Cache.Create(); } return(res); }
public void FinalizeTextures() { if (coordList.Count == 0) // There's nothing that uses this. { Debug.LogWarningFormat("Tile page \"{0}\" has no sprites used!", pageName); return; } int scaleFactor = 1; if (tileWidth * 4 <= GameSettings.Instance.rendering.maxTextureSize && tileHeight * 4 <= GameSettings.Instance.rendering.maxTextureSize) { scaleFactor = 4; } else if (tileWidth * 3 <= GameSettings.Instance.rendering.maxTextureSize && tileHeight * 3 <= GameSettings.Instance.rendering.maxTextureSize) { scaleFactor = 3; } else if (tileWidth * 2 <= GameSettings.Instance.rendering.maxTextureSize && tileHeight * 2 <= GameSettings.Instance.rendering.maxTextureSize) { scaleFactor = 2; } tileArray = new Texture2DArray(Mathf.ClosestPowerOfTwo(tileWidth * scaleFactor), Mathf.ClosestPowerOfTwo(tileHeight * scaleFactor), coordList.Count, TextureFormat.ARGB32, true); normalArray = new Texture2DArray(Mathf.ClosestPowerOfTwo(tileWidth * scaleFactor), Mathf.ClosestPowerOfTwo(tileHeight * scaleFactor), coordList.Count, TextureFormat.ARGB32, true, true); for (int i = 0; i < coordList.Count; i++) { var coord = coordList[i]; var tileSource = originalPage.GetPixels(coord.x * tileWidth, (pageHeight - coord.y - 1) * tileHeight, tileWidth, tileHeight); var tileSource32 = new Color32[tileSource.Length]; for (int j = 0; j < tileSource.Length; j++) { tileSource32[j] = tileSource[j]; } var tileDest32 = new Color32[tileWidth * scaleFactor * tileHeight * scaleFactor]; switch (scaleFactor) { case 4: HqxSharp.Scale4(tileSource32, tileDest32, tileWidth, tileHeight); break; case 3: HqxSharp.Scale3(tileSource32, tileDest32, tileWidth, tileHeight); break; case 2: HqxSharp.Scale2(tileSource32, tileDest32, tileWidth, tileHeight); break; default: tileDest32 = tileSource32; break; } Texture2D texture = new Texture2D(tileWidth * scaleFactor, tileHeight * scaleFactor, TextureFormat.ARGB32, false); texture.SetPixels32(tileDest32); TextureScale.Bilinear(texture, Mathf.ClosestPowerOfTwo(tileWidth * scaleFactor), Mathf.ClosestPowerOfTwo(tileHeight * scaleFactor)); tileArray.SetPixels(texture.GetPixels(), i); normalArray.SetPixels(TextureTools.Bevel(texture.GetPixels(), texture.width, texture.height), i); } tileArray.Apply(); normalArray.Apply(); }
private void BuildArray() { int sizeX = m_sizes[m_selectedSizeX]; int sizeY = m_sizes[m_selectedSizeY]; Texture2DArray textureArray = new Texture2DArray(sizeX, sizeY, m_allTextures.Count, m_selectedFormatEnum, m_mipMaps, m_linearMode); textureArray.wrapMode = m_wrapMode; textureArray.filterMode = m_filterMode; textureArray.anisoLevel = m_anisoLevel; textureArray.Apply(false); RenderTexture cache = RenderTexture.active; RenderTexture rt = new RenderTexture(sizeX, sizeY, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default); rt.Create(); for (int i = 0; i < m_allTextures.Count; i++) { // build report int widthChanges = m_allTextures[i].width <sizeX ? -1 : m_allTextures[i].width> sizeX ? 1 : 0; int heightChanges = m_allTextures[i].height <sizeY ? -1 : m_allTextures[i].height> sizeY ? 1 : 0; if ((widthChanges < 0 && heightChanges <= 0) || (widthChanges <= 0 && heightChanges < 0)) { m_message += m_allTextures[i].name + " was upscaled\n"; } else if ((widthChanges > 0 && heightChanges >= 0) || (widthChanges >= 0 && heightChanges > 0)) { m_message += m_allTextures[i].name + " was downscaled\n"; } else if ((widthChanges > 0 && heightChanges < 0) || (widthChanges < 0 && heightChanges > 0)) { m_message += m_allTextures[i].name + " changed dimensions\n"; } // blit image to upscale or downscale the image to any size RenderTexture.active = rt; bool cachedsrgb = GL.sRGBWrite; GL.sRGBWrite = !m_linearMode; Graphics.Blit(m_allTextures[i], rt); GL.sRGBWrite = cachedsrgb; Texture2D t2d = new Texture2D(sizeX, sizeY, TextureFormat.ARGB32, m_mipMaps, m_linearMode); t2d.ReadPixels(new Rect(0, 0, sizeX, sizeY), 0, 0, m_mipMaps); RenderTexture.active = null; bool isCompressed = UncompressedFormats.FindIndex(x => x.Equals(m_selectedFormatEnum)) < 0; if (isCompressed) { EditorUtility.CompressTexture(t2d, m_selectedFormatEnum, m_quality); t2d.Apply(false); } if (m_mipMaps) { int maxSize = Mathf.Max(sizeX, sizeY); for (int mip = 0; mip < MipCount[maxSize]; mip++) { CopyToArray(ref t2d, ref textureArray, i, mip, isCompressed); } } else { CopyToArray(ref t2d, ref textureArray, i, 0, isCompressed); } } rt.Release(); RenderTexture.active = cache; if (m_message.Length > 0) { m_message = m_message.Substring(0, m_message.Length - 1); } string path = m_folderPath + m_fileName + ".asset"; Texture2DArray outfile = AssetDatabase.LoadMainAssetAtPath(path) as Texture2DArray; if (outfile != null) { EditorUtility.CopySerialized(textureArray, outfile); AssetDatabase.SaveAssets(); EditorGUIUtility.PingObject(outfile); m_lastSaved = outfile; } else { AssetDatabase.CreateAsset(textureArray, path); EditorGUIUtility.PingObject(textureArray); m_lastSaved = textureArray; } }
private void OnGUI() { GUILayout.Space(verticalWindowPadding); using (var c = new EditorGUILayout.HorizontalScope()) { GUILayout.Space(horizontalWindowPadding); using (var a = new EditorGUILayout.VerticalScope()) { // Ramp Collection Field EditorGUI.BeginChangeCheck(); rampCollectionRaw = (RampCollectionData)EditorGUILayout.ObjectField(rampCollectionLabel, rampCollectionRaw, typeof(RampCollectionData), false); if (rampCollectionRaw != null) { // Create serialized asset mirror if missing if (EditorGUI.EndChangeCheck() || rampCollection == null) { rampCollection = new SerializedObject(rampCollectionRaw); resolution = rampCollection.FindProperty(nameof(RampCollectionData.resolution)); height = rampCollection.FindProperty(nameof(RampCollectionData.height)); ramps = rampCollection.FindProperty(nameof(RampCollectionData.ramps)); } } else { EditorGUI.EndChangeCheck(); EditorGUILayout.Space(8); using (var b = new EditorGUILayout.HorizontalScope()) { rampCollectionName = EditorGUILayout.TextField(rampCollectionNameLabel, rampCollectionName); GUILayout.Space(32); if (GUILayout.Button(createNewCollectionLabel)) { rampCollectionPath = "Assets/Toon Shader URP/Ramp Collections"; rampCollectionRaw = CreateInstance <RampCollectionData>(); if (rampCollectionName == null || rampCollectionName.Length == 0) { rampCollectionName = "New Ramp Collection"; rampCollectionRaw.name = rampCollectionName; } Directory.CreateDirectory($"{Application.dataPath}/Toon Shader URP/Ramp Collections"); AssetDatabase.CreateAsset(rampCollectionRaw, $"{rampCollectionPath}/{rampCollectionName}.asset"); rampCollection = new SerializedObject(rampCollectionRaw); SerializedProperty name = rampCollection.FindProperty(nameof(RampCollectionData.arrayName)); resolution = rampCollection.FindProperty(nameof(RampCollectionData.resolution)); height = rampCollection.FindProperty(nameof(RampCollectionData.height)); ramps = rampCollection.FindProperty(nameof(RampCollectionData.ramps)); name.stringValue = rampCollectionName; resolution.intValue = defaultRampResolution; height.intValue = defaultRowHeight; rampCollection.ApplyModifiedProperties(); } else { rampCollection = null; ramps = null; } } EditorGUILayout.Space(8); } if (rampCollection != null && ramps != null) { rampCollection.UpdateIfRequiredOrScript(); resolution.intValue = EditorGUILayout.IntField(rampResolutionLabel, resolution.intValue); height.intValue = Mathf.Clamp(EditorGUILayout.IntField(rowHeightLabel, height.intValue), 1, int.MaxValue); EditorGUILayout.PropertyField(ramps); rampCollection.ApplyModifiedProperties(); if (Event.current.type == EventType.MouseUp || (Event.current.type == EventType.KeyUp && Event.current.keyCode == KeyCode.Return)) { AssetDatabase.SaveAssets(); } using (var d = new EditorGUILayout.HorizontalScope()) { if (GUILayout.Button(saveRampTextureArrayLabel)) { Texture2DArray rasterizedRampArray = new Texture2DArray( resolution.intValue, 1, ramps.arraySize, TextureFormat.RGBA32, false) { wrapMode = TextureWrapMode.Clamp, filterMode = FilterMode.Bilinear, anisoLevel = 0 }; for (int i = 0; i < ramps.arraySize; ++i) { Color32[] arrayRamp = new Color32[resolution.intValue]; for (int j = 0; j < resolution.intValue; ++j) { arrayRamp[j] = rampCollectionRaw.ramps[i].Evaluate((float)j / resolution.intValue); } rasterizedRampArray.SetPixels32(arrayRamp, i); } rasterizedRampArray.Apply(); string path = EditorUtility.SaveFilePanelInProject( "Save Texture Array", defaultRampTextureArrayName, "asset", "Select a location to save your generated texture array in."); if (path.Length != 0) { AssetDatabase.CreateAsset(rasterizedRampArray, path); } } else if (GUILayout.Button(saveRampTextureAtlasLabel)) { Texture2D rasterizedRampAtlas = new Texture2D( resolution.intValue, ramps.arraySize * height.intValue, TextureFormat.RGBA32, false) { wrapMode = TextureWrapMode.Clamp, filterMode = FilterMode.Bilinear, anisoLevel = 0, }; for (int i = 0; i < ramps.arraySize; ++i) { Color32[] rampRow = new Color32[resolution.intValue]; for (int j = 0; j < resolution.intValue; ++j) { rampRow[j] = rampCollectionRaw.ramps[i].Evaluate((float)j / resolution.intValue); } for (int k = 0; k < height.intValue; ++k) { rasterizedRampAtlas.SetPixels32(0, k + (i * height.intValue), resolution.intValue, 1, rampRow); } } rasterizedRampAtlas.Apply(); string path = EditorUtility.SaveFilePanelInProject( "Save Texture Atlas", defaultRampTextureAtlasName, "png", "Select a location to save your generated texture atlas in."); if (path.Length != 0) { string localPath = path.Substring("Assets".Length); RampAtlasPreprocessor.isRampTexture = true; File.WriteAllBytes($"{Application.dataPath}/{localPath}", rasterizedRampAtlas.EncodeToPNG()); } } } } } GUILayout.Space(horizontalWindowPadding); } GUILayout.Space(verticalWindowPadding); }
private Texture2DArray InitTexture2DArray(Stream stream, AssetImportContext ctx) { TextureFormat format = GetTextureFormat(ctx.selectedBuildTarget, compressed, transparent); Texture2DArray array = null; EditorUtility.DisplayProgressBar("Import Huge Texture", ctx.assetPath, 0); try { array = new Texture2DArray(pageSize, pageSize, cols * rows, format, false); array.wrapMode = TextureWrapMode.Clamp; TextureFormat textureFormat = transparent ? TextureFormat.RGBA32 : TextureFormat.RGB24; Texture2D texture = new Texture2D(pageSize, pageSize, textureFormat, false); BinaryReader reader = new BinaryReader(stream); int colorSize = GetPixelSize(colorFormat); int bufferSize = pageSize * colorSize * depth / 8; Color32[] colors = new Color32[pageSize * pageSize]; int lastY = rows * pageSize - 1; for (int row = 0; row < rows; row++) { for (int col = 0; col < cols; col++) { EditorUtility.DisplayProgressBar("Import Huge Texture", ctx.assetPath, (row * cols + col) / (float)(cols * rows)); for (int y = 0; y < pageSize; y++) { int srow = lastY - row * pageSize - y; int scol = col * pageSize; long offset = ((long)srow * originalWidth + scol) * colorSize * depth / 8; stream.Seek(offset, SeekOrigin.Begin); byte[] buffer = reader.ReadBytes(bufferSize); if (depth == 8) { Parse8BitRow(buffer, colors, y); } else { Parse16BitRow(buffer, colors, y); } } texture.SetPixels32(colors); texture.Apply(false); if (compressed) { EditorUtility.CompressTexture(texture, format, quality); } array.SetPixelData(texture.GetRawTextureData(), 0, row * cols + col); if (compressed) { DestroyImmediate(texture); texture = new Texture2D(pageSize, pageSize, textureFormat, false); } } } DestroyImmediate(texture); reader.Close(); array.Apply(); } catch { } EditorUtility.ClearProgressBar(); return(array); }
public Texture2D GetTexture2D() { Texture2D newTexture2D = null; if (texture is Cubemap) { var format = TextureFormat.RGBA32; if (isHDR) { format = TextureFormat.RGBAFloat; } newTexture2D = new Texture2D(texture.width * 6, texture.height, format, texture.mipmapCount, true); for (var mipLevel = 0; mipLevel < texture.mipmapCount; mipLevel++) { var width = (int)(texture.width / Math.Pow(2, mipLevel)); var height = (int)(texture.height / Math.Pow(2, mipLevel)); var array = new Texture2DArray(texture.width, texture.height, 6, texture.graphicsFormat, UnityEngine.Experimental.Rendering.TextureCreationFlags.MipChain); var allPixels = new List <Color[]>(); for (var i = 0; i < 6; i++) { Graphics.CopyTexture(texture, i, array, i); allPixels.Add(array.GetPixels(i, mipLevel)); } var pixels = new List <Color>(); for (var h = 0; h < height; h++) { for (var fi = 0; fi < 6; fi++) { for (var w = 0; w < width; w++) { var colors = allPixels[fi]; pixels.Add(colors[w + h * width]); } } } newTexture2D.SetPixels(pixels.ToArray(), mipLevel); } } else if (texture is Texture2D) { if (!texture.isReadable) { newTexture2D = new Texture2D(texture.width, texture.height, texture.graphicsFormat, UnityEngine.Experimental.Rendering.TextureCreationFlags.MipChain); Graphics.CopyTexture(texture, newTexture2D); } else { newTexture2D = texture as Texture2D; } if (extName == ".psd") { flipY = !flipY; } } return(newTexture2D); }
void Start() { m_Material = render_object.GetComponent <Renderer>().material; render_object.GetComponent <Renderer>().material.SetTexture("_ColorTex", scene_prepare.color_texture); render_object.GetComponent <Renderer>().material.SetTexture("_PosTex", scene_prepare.position_texture); render_object.GetComponent <Renderer>().material.SetTexture("_NormalsTex", scene_prepare.normals_texture); render_object.transform.localScale = new Vector3(Camera.main.orthographicSize * 2.0f * Screen.width / Screen.height, Camera.main.orthographicSize * 2.0f, 0.1f); int totalVertexes = 0; int totalTriangles = 0; int object_i = 0; const int max_triangles_per_object = 2048; const int max_objects = 9; float[] triangles_per_object = new float[max_objects]; Matrix4x4[] transform_matrices = new Matrix4x4[max_objects]; Vector4[] transform_positions = new Vector4[max_objects]; float[] aabbs = new float[max_objects * 6]; Color[] colors = new Color[max_objects]; Texture2DArray triangles_tex = new Texture2DArray(max_triangles_per_object, 3, max_objects, TextureFormat.RGBAFloat, false, true); m_Material.SetTexture("_TrianglesTex", triangles_tex); Texture2DArray triangle_normals_tex = new Texture2DArray(max_triangles_per_object, 1, max_objects, TextureFormat.RGBAFloat, false, true); m_Material.SetTexture("_TriangleNormalsTex", triangle_normals_tex); foreach (MeshFilter mf in FindObjectsOfType(typeof(MeshFilter))) { if (mf.gameObject.name == transform.GetChild(0).name) { continue; } print("Name: " + mf.name); print("Position: " + mf.transform.position); print("Transform Matrix: " + mf.transform.localToWorldMatrix); print("Vertices: " + mf.sharedMesh.vertexCount); print("Triangles: " + mf.sharedMesh.triangles.Length / 3); print("Normals: " + mf.sharedMesh.normals.Length); print("UVs: " + mf.sharedMesh.uv.Length); Color[] _triangles = new Color[max_triangles_per_object * 3]; Color[] _normals = new Color[max_triangles_per_object]; for (int i = 0; i < mf.sharedMesh.triangles.Length / 3; i++) { _triangles[i] = new Color(mf.sharedMesh.vertices[mf.sharedMesh.triangles[i * 3]].x, mf.sharedMesh.vertices[mf.sharedMesh.triangles[i * 3]].y, mf.sharedMesh.vertices[mf.sharedMesh.triangles[i * 3]].z, 1.0f); _triangles[i + max_triangles_per_object] = new Color(mf.sharedMesh.vertices[mf.sharedMesh.triangles[i * 3 + 1]].x, mf.sharedMesh.vertices[mf.sharedMesh.triangles[i * 3 + 1]].y, mf.sharedMesh.vertices[mf.sharedMesh.triangles[i * 3 + 1]].z, 1.0f); _triangles[i + max_triangles_per_object * 2] = new Color(mf.sharedMesh.vertices[mf.sharedMesh.triangles[i * 3 + 2]].x, mf.sharedMesh.vertices[mf.sharedMesh.triangles[i * 3 + 2]].y, mf.sharedMesh.vertices[mf.sharedMesh.triangles[i * 3 + 2]].z, 1.0f); // HACKY normal calculation Vector3 normal = mf.sharedMesh.normals[mf.sharedMesh.triangles[i * 3]] + mf.sharedMesh.normals[mf.sharedMesh.triangles[i * 3 + 1]] + mf.sharedMesh.normals[mf.sharedMesh.triangles[i * 3 + 2]]; normal /= 3.0f; _normals[i] = new Color(normal.x, normal.y, normal.z, 1.0f); } triangles_tex.SetPixels(_triangles, object_i); triangles_tex.Apply(); triangle_normals_tex.SetPixels(_normals, object_i); triangle_normals_tex.Apply(); triangles_per_object[object_i] = mf.sharedMesh.triangles.Length / 3; transform_matrices[object_i] = mf.transform.localToWorldMatrix; transform_positions[object_i] = mf.transform.position; aabbs[object_i * 6] = mf.sharedMesh.bounds.min.x * 1.1f; aabbs[object_i * 6 + 1] = mf.sharedMesh.bounds.min.y * 1.1f; aabbs[object_i * 6 + 2] = mf.sharedMesh.bounds.min.z * 1.1f; aabbs[object_i * 6 + 3] = mf.sharedMesh.bounds.max.x * 1.1f; aabbs[object_i * 6 + 4] = mf.sharedMesh.bounds.max.y * 1.1f; aabbs[object_i * 6 + 5] = mf.sharedMesh.bounds.max.z * 1.1f; colors[object_i] = mf.GetComponent <Renderer>().material.GetColor("_Color"); totalTriangles += mf.sharedMesh.triangles.Length / 3; object_i++; } m_Material.SetInt("objects", object_i); m_Material.SetFloatArray("triangles_per_object", triangles_per_object); m_Material.SetMatrixArray("transform_matrices", transform_matrices); m_Material.SetVectorArray("transform_positions", transform_positions); m_Material.SetFloatArray("aabbs", aabbs); m_Material.SetColorArray("object_diffuse_colors", colors); print("Total Vertices: " + totalVertexes); print("Total Triangles: " + totalTriangles); }
/// <summary> /// Gets terrain metallic gloss map texture array containing each terrain tile in a seperate array slice. /// </summary> /// <param name="archive">Archive index.</param> /// <param name="stayReadable">Texture should stay readable.</param> /// <param name="nonAlphaFormat">Non-alpha TextureFormat.</param> /// <returns>Texture2DArray or null</returns> public Texture2DArray GetTerrainMetallicGlossMapTextureArray( int archive, bool stayReadable = false) { Color32 defaultMetallicGlossColor = new Color32(0, 0, 0, 255); Color32[] defaultMetallicGlossMap; // Load texture file and check count matches terrain tiles TextureFile textureFile = new TextureFile(Path.Combine(Arena2Path, TextureFile.IndexToFileName(archive)), FileUsage.UseMemory, true); int numSlices = 0; if (textureFile.RecordCount == 56) { numSlices = textureFile.RecordCount; } else { return null; } Texture2DArray textureArray; if (!stayReadable && TextureReplacement.TryImportTextureArray(archive, numSlices, TextureMap.MetallicGloss, defaultMetallicGlossColor, out textureArray)) return textureArray; int width; int height; // try to import first replacement texture for tile archive to determine width and height of replacement texture set (must be the same for all replacement textures for Texture2DArray) Texture2D metallicGlossMap; if (TextureReplacement.TryImportTexture(archive, 0, 0, TextureMap.MetallicGloss, false, out metallicGlossMap)) { width = metallicGlossMap.width; height = metallicGlossMap.height; } else { // create default texture array (1x1 texture) width = 1; height = 1; } textureArray = new Texture2DArray(width, height, numSlices, TextureFormat.ARGB32, MipMaps); defaultMetallicGlossMap = new Color32[width*height]; for (int i = 0; i < width * height; i++) { defaultMetallicGlossMap[i] = defaultMetallicGlossColor; } // Rollout tiles into texture array for (int record = 0; record < textureFile.RecordCount; record++) { // Import custom texture(s) if (!TextureReplacement.TryImportTexture(archive, record, 0, TextureMap.MetallicGloss, false, out metallicGlossMap)) { metallicGlossMap = new Texture2D(width, height, TextureFormat.ARGB32, MipMaps); metallicGlossMap.SetPixels32(defaultMetallicGlossMap); } // enforce that all custom metallicgloss map textures have the same dimension (requirement of Texture2DArray) if ((metallicGlossMap.width != width) || (metallicGlossMap.height != height)) { Debug.LogErrorFormat("Terrain: failed to inject metallicgloss maps for archive {0}, incorrect size at record {1}.", archive, record); return null; } // Insert into texture array textureArray.SetPixels32(metallicGlossMap.GetPixels32(), record, 0); } textureArray.Apply(true, !stayReadable); // Change settings for these textures textureArray.wrapMode = TextureWrapMode.Clamp; textureArray.anisoLevel = 8; return textureArray; }
public override void OnGUI(MaterialEditor materialEditor, MaterialProperty[] props) { if (GUI.enabled == false) { EditorGUILayout.HelpBox("You must edit the template material, not the instance being used", MessageType.Info); return; } EditorGUI.BeginChangeCheck(); // sync materials Material targetMat = materialEditor.target as Material; Texture2DArray diff = targetMat.GetTexture("_Diffuse") as Texture2DArray; compiler.Init(); // must unpack everything before the generator draws- otherwise we get IMGUI errors for (int i = 0; i < compiler.extensions.Count; ++i) { var ext = compiler.extensions[i]; ext.Unpack(targetMat.shaderKeywords); } string shaderName = targetMat.shader.name; DrawModules(); EditorGUI.BeginChangeCheck(); // needs compile if (MicroSplatUtilities.DrawRollup("Shader Generator")) { shaderName = EditorGUILayout.DelayedTextField(CShaderName, shaderName); if (DrawRenderLoopGUI(targetMat)) { needsCompile = true; } for (int i = 0; i < compiler.extensions.Count; ++i) { var e = compiler.extensions[i]; if (e.GetVersion() == MicroSplatVersion) { //using (new GUILayout.VerticalScope(GUI.skin.box)) { e.DrawFeatureGUI(targetMat); } } else { EditorGUILayout.HelpBox("Extension : " + e + " is version " + e.GetVersion() + " and MicroSplat is version " + MicroSplatVersion + ", please update", MessageType.Error); } } for (int i = 0; i < availableRenderLoops.Count; ++i) { var rl = availableRenderLoops[i]; if (rl.GetVersion() != MicroSplatVersion) { EditorGUILayout.HelpBox("Render Loop : " + rl.GetDisplayName() + " is version " + rl.GetVersion() + " and MicroSplat is version " + MicroSplatVersion + ", please update", MessageType.Error); } } } needsCompile = needsCompile || EditorGUI.EndChangeCheck(); int featureCount = targetMat.shaderKeywords.Length; // note, ideally we wouldn't draw the GUI for the rest of stuff if we need to compile. // But we can't really do that without causing IMGUI to split warnings about // mismatched GUILayout blocks if (!needsCompile) { for (int i = 0; i < compiler.extensions.Count; ++i) { var ext = compiler.extensions[i]; if (ext.GetVersion() == MicroSplatVersion) { ext.DrawShaderGUI(this, targetMat, materialEditor, props); } else { EditorGUILayout.HelpBox("Extension : " + ext + " is version " + ext.GetVersion() + " and MicroSplat is version " + MicroSplatVersion + ", please update so that all modules are using the same version.", MessageType.Error); } } if (diff != null && MicroSplatUtilities.DrawRollup("Per Texture Properties")) { var propTex = FindOrCreatePropTex(targetMat); perTexIndex = MicroSplatUtilities.DrawTextureSelector(perTexIndex, diff); for (int i = 0; i < compiler.extensions.Count; ++i) { var ext = compiler.extensions[i]; if (ext.GetVersion() == MicroSplatVersion) { ext.DrawPerTextureGUI(perTexIndex, targetMat, propTex); } } } } if (!needsCompile) { if (featureCount != targetMat.shaderKeywords.Length) { needsCompile = true; } } int arraySampleCount = 0; int textureSampleCount = 0; int maxSamples = 0; int tessSamples = 0; int depTexReadLevel = 0; builder.Length = 0; for (int i = 0; i < compiler.extensions.Count; ++i) { var ext = compiler.extensions[i]; if (ext.GetVersion() == MicroSplatVersion) { ext.ComputeSampleCounts(targetMat.shaderKeywords, ref arraySampleCount, ref textureSampleCount, ref maxSamples, ref tessSamples, ref depTexReadLevel); } } if (MicroSplatUtilities.DrawRollup("Debug")) { string shaderModel = compiler.GetShaderModel(targetMat.shaderKeywords); builder.Append("Shader Model : "); builder.AppendLine(shaderModel); if (maxSamples != arraySampleCount) { builder.Append("Texture Array Samples : "); builder.AppendLine(arraySampleCount.ToString()); builder.Append("Regular Samples : "); builder.AppendLine(textureSampleCount.ToString()); } else { builder.Append("Texture Array Samples : "); builder.AppendLine(arraySampleCount.ToString()); builder.Append("Regular Samples : "); builder.AppendLine(textureSampleCount.ToString()); } if (tessSamples > 0) { builder.Append("Tessellation Samples : "); builder.AppendLine(tessSamples.ToString()); } if (depTexReadLevel > 0) { builder.Append(depTexReadLevel.ToString()); builder.AppendLine(" areas with dependent texture reads"); } EditorGUILayout.HelpBox(builder.ToString(), MessageType.Info); } if (EditorGUI.EndChangeCheck() && !needsCompile) { MicroSplatTerrain.SyncAll(); #if __MICROSPLAT_MESH__ MicroSplatMesh.SyncAll(); #endif } if (needsCompile) { needsCompile = false; targetMat.shaderKeywords = null; for (int i = 0; i < compiler.extensions.Count; ++i) { compiler.extensions[i].Pack(targetMat); } if (compiler.renderLoop != null) { targetMat.EnableKeyword(compiler.renderLoop.GetRenderLoopKeyword()); } // horrible workaround to GUI warning issues compileMat = targetMat; compileName = shaderName; targetCompiler = compiler; EditorApplication.delayCall += TriggerCompile; } }
private void BuildArray() { int sizeX = m_sizes[m_selectedSizeX]; int sizeY = m_sizes[m_selectedSizeY]; Texture2DArray textureArray = new Texture2DArray(sizeX, sizeY, m_allTextures.Count, m_formats[m_selectedFormat], m_mipMaps, m_linearMode); for (int i = 0; i < m_allTextures.Count; i++) { // build report int widthChanges = m_allTextures[i].width <sizeX ? -1 : m_allTextures[i].width> sizeX ? 1 : 0; int heightChanges = m_allTextures[i].height <sizeY ? -1 : m_allTextures[i].height> sizeY ? 1 : 0; if ((widthChanges < 0 && heightChanges <= 0) || (widthChanges <= 0 && heightChanges < 0)) { m_message += m_allTextures[i].name + " was upscaled\n"; } else if ((widthChanges > 0 && heightChanges >= 0) || (widthChanges >= 0 && heightChanges > 0)) { m_message += m_allTextures[i].name + " was downscaled\n"; } else if ((widthChanges > 0 && heightChanges < 0) || (widthChanges < 0 && heightChanges > 0)) { m_message += m_allTextures[i].name + " changed dimensions\n"; } // blit image to upscale or downscale the image to any size RenderTexture rt = RenderTexture.GetTemporary(sizeX, sizeY, 24, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Default, 8); RenderTexture cache = RenderTexture.active; RenderTexture.active = rt; bool cachedsrgb = GL.sRGBWrite; GL.sRGBWrite = true; Graphics.Blit(m_allTextures[i], rt); GL.sRGBWrite = cachedsrgb; Texture2D t2d = new Texture2D(sizeX, sizeY); t2d.ReadPixels(new Rect(0, 0, sizeX, sizeY), 0, 0); RenderTexture.active = cache; RenderTexture.ReleaseTemporary(rt); textureArray.SetPixels(t2d.GetPixels(0), i, 0); } if (m_message.Length > 0) { m_message = m_message.Substring(0, m_message.Length - 1); } textureArray.wrapMode = m_wrapMode; textureArray.filterMode = m_filterMode; textureArray.anisoLevel = m_anisoLevel; textureArray.Apply(); string path = m_folderPath + m_fileName + ".asset"; Texture2DArray outfile = AssetDatabase.LoadMainAssetAtPath(path) as Texture2DArray; if (outfile != null) { EditorUtility.CopySerialized(textureArray, outfile); AssetDatabase.SaveAssets(); EditorGUIUtility.PingObject(outfile); m_lastSaved = outfile; } else { AssetDatabase.CreateAsset(textureArray, path); EditorGUIUtility.PingObject(textureArray); m_lastSaved = textureArray; } }
public static void GetShaderArrays(out Texture2DArray texArray, out Matrix4x4[] worldToCameraMatrixArray, out Matrix4x4[] projectionMatrixArray) { string[] clippedTexFiles = Directory.GetFiles(Constants.Folders.ClippedRoomTextureFolderPath); string[] cameraLocFiles = Directory.GetFiles(Constants.Folders.CameraLocationFolderPath); Resolution camRes = Constants.Camera.CameraResolution(); Resolution downgradedRes = GetDowngradedResolution(camRes); int numLegitimateTextureFiles = 0; foreach (string texFile in clippedTexFiles) { string fileExtension = Path.GetExtension(texFile); if (!fileExtension.Equals(Constants.Suffixes.FileSuffix_PNG) && !fileExtension.Equals(Constants.Suffixes.FileSuffix_JPG)) { continue; } ++numLegitimateTextureFiles; } if (clippedTexFiles.Length > 0) { texArray = new Texture2DArray(downgradedRes.width, downgradedRes.height, numLegitimateTextureFiles, Constants.Camera.Format, false); } else { texArray = null; } worldToCameraMatrixArray = new Matrix4x4[cameraLocFiles.Length]; projectionMatrixArray = new Matrix4x4[cameraLocFiles.Length]; int arrayIndex = 0; foreach (string texFile in clippedTexFiles) { string fileExtension = Path.GetExtension(texFile); if (!fileExtension.Equals(Constants.Suffixes.FileSuffix_PNG) && !fileExtension.Equals(Constants.Suffixes.FileSuffix_JPG)) { continue; } // ERROR TESTING REMOVE // Adjust the texture filepath to ready it for loading by Resources.Load, which requires a relative path with NO file extension //string correctFilepath = Constants.Folders.ClippedRoomTextureFolderPath_Load + Path.GetFileNameWithoutExtension(texFile); Texture2D tex = LoadTexture.Load(texFile); Texture2D downgradedTex = DowngradeTexture(tex, downgradedRes); // copy texture into texture array texArray.SetPixels32(downgradedTex.GetPixels32(), arrayIndex); // ERROR TESTING REMOVE //Graphics.CopyTexture(downgradedTex, 0, 0, texArray, arrayIndex, 0); CameraLocation camLoc = CameraLocation.Load(Constants.Folders.CameraLocationFolderPath + FileNameTranslator.ClippedTextureToCameraLocation(Path.GetFileNameWithoutExtension(texFile)) + Constants.Suffixes.FileSuffix_CameraLocation); if (camLoc != null) { worldToCameraMatrixArray[arrayIndex] = camLoc.WorldToCameraTransform; projectionMatrixArray[arrayIndex] = camLoc.ProjectionTransform; } ++arrayIndex; } }
public override void Draw(DrawInfo drawInfo) { base.Draw(drawInfo); if (m_isEditingPicker && m_drawPicker) { Rect hitRect = m_previewRect; hitRect.height = 14 * drawInfo.InvertedZoom; hitRect.y = m_previewRect.yMax - hitRect.height; hitRect.width = 4 * 14 * drawInfo.InvertedZoom; bool restoreMouse = false; if (Event.current.type == EventType.MouseDown && hitRect.Contains(drawInfo.MousePosition)) { restoreMouse = true; Event.current.type = EventType.Ignore; } EditorGUI.BeginChangeCheck(); m_colorBuffer = GUI.color; GUI.color = Color.clear; if (m_materialMode) { m_materialTextureArray = EditorGUIObjectField(m_previewRect, m_materialTextureArray, typeof(Texture2DArray), false) as Texture2DArray; } else { m_defaultTextureArray = EditorGUIObjectField(m_previewRect, m_defaultTextureArray, typeof(Texture2DArray), false) as Texture2DArray; } GUI.color = m_colorBuffer; if (EditorGUI.EndChangeCheck()) { CheckTextureImporter(true); SetTitleText(PropertyInspectorName); SetAdditonalTitleText(string.Format(Constants.PropertyValueLabel, GetPropertyValStr())); ConfigureInputPorts(); ConfigureOutputPorts(); BeginDelayedDirtyProperty(); m_requireMaterialUpdate = true; } if (restoreMouse) { Event.current.type = EventType.MouseDown; } if ((drawInfo.CurrentEventType == EventType.MouseDown || drawInfo.CurrentEventType == EventType.MouseUp)) { DrawPreviewMaskButtonsLayout(drawInfo, m_previewRect); } } if (drawInfo.CurrentEventType != EventType.Repaint) { return; } switch (m_state) { default: case ReferenceState.Self: if (drawInfo.CurrentEventType == EventType.Repaint) { m_drawPreview = false; m_drawPicker = true; DrawTexturePicker(drawInfo); } break; case ReferenceState.Connected: if (drawInfo.CurrentEventType == EventType.Repaint) { m_drawPreview = true; m_drawPicker = false; if (m_previewTextProp != null) { SetTitleTextOnCallback(m_previewTextProp.TitleContent.text, (instance, newTitle) => instance.TitleContent.text = newTitle + " (Input)"); SetAdditonalTitleText(m_previewTextProp.AdditonalTitleContent.text); } // Draw chain lock GUI.Label(m_iconPos, string.Empty, UIUtils.GetCustomStyle(CustomStyle.SamplerTextureIcon)); // Draw frame around preview GUI.Label(m_previewRect, string.Empty, UIUtils.GetCustomStyle(CustomStyle.SamplerFrame)); } break; case ReferenceState.Instance: { m_drawPreview = true; m_drawPicker = false; if (m_referenceSampler != null) { SetTitleTextOnCallback(m_referenceSampler.PreviewTextProp.TitleContent.text, (instance, newTitle) => instance.TitleContent.text = newTitle + Constants.InstancePostfixStr); SetAdditonalTitleText(m_referenceSampler.PreviewTextProp.AdditonalTitleContent.text); } // Draw chain lock GUI.Label(m_iconPos, string.Empty, UIUtils.GetCustomStyle(CustomStyle.SamplerTextureIcon)); // Draw frame around preview GUI.Label(m_previewRect, string.Empty, UIUtils.GetCustomStyle(CustomStyle.SamplerFrame)); } break; } }
//THIS public void CreateStyleShapes() { string fileNormal = TextureFolder + "/Normal/normal_{0:000}"; string fileAO = TextureFolder + "/AO/ao_{0:000}"; string fileBlindsMask = TextureFolder + "/BlindsGradient/depth_{0:000}"; string mask = TextureFolder + "/Mask/diff_{0:000}"; string depth = TextureFolder + "/Depth/depth_{0:000}"; Texture2DArray textureArray = new Texture2DArray(size, size, slices * 2, compressionFormat, true, true); for (int i = 0; i < slices; i++) { string filename = string.Format(fileNormal, i + 1); string filenameAO = string.Format(fileAO, i + 1); string filenameAdd = string.Format(fileBlindsMask, i + 1); Debug.Log("Loading " + filename); Texture2D tex = (Texture2D)Resources.Load(filename); Texture2D texAO = (Texture2D)Resources.Load(filenameAO); Texture2D texAdd = (Texture2D)Resources.Load(filenameAdd); Texture2D scaleTex = scaled(tex, size, size, 0); Texture2D scaleTexAO = scaled(texAO, size, size, 0); Texture2D scaleTexAdd = scaled(texAdd, size, size, 0); Color[] texCol = scaleTex.GetPixels(0); Color[] texColAO = scaleTexAO.GetPixels(0); Color[] texColAdd = scaleTexAdd.GetPixels(0); Color[] texComposite = texCol; for (int j = 0; j < texCol.Length; j++) { texComposite[j] = new Color(texCol[j].r, texCol[j].g, texColAdd[j].r, texColAO[j].r); } Texture2D final = new Texture2D(size, size, TextureFormat.RGBA32, true); final.SetPixels(texComposite); final.Apply(true); EditorUtility.CompressTexture(final, compressionFormat, 100); final.Apply(true); for (int mip = 0; mip < MipCount[size]; mip++) { Graphics.CopyTexture(final, 0, mip, textureArray, i, mip); } string filenameMask = string.Format(mask, i + 1); string filenameDepth = string.Format(depth, i + 1); Debug.Log("Loading " + filenameMask); tex = (Texture2D)Resources.Load(filenameMask); texAO = (Texture2D)Resources.Load(filenameDepth); scaleTex = scaled(tex, size, size, 0); scaleTexAO = scaled(texAO, size, size, 0); texCol = scaleTex.GetPixels(0); texColAO = scaleTexAO.GetPixels(0); texComposite = texCol; for (int j = 0; j < texCol.Length; j++) { texComposite[j] = new Color(texColAO[j].b, texCol[j].g, texCol[j].b, texColAO[j].r); } final = new Texture2D(size, size, TextureFormat.RGBA32, true); final.SetPixels(texComposite); final.Apply(true); EditorUtility.CompressTexture(final, compressionFormat, 100); final.Apply(true); for (int mip = 0; mip < MipCount[size]; mip++) { Graphics.CopyTexture(final, 0, mip, textureArray, i + slices, mip); } } textureArray.Apply(false); System.IO.Directory.CreateDirectory("Assets/CScape/Editor/Resources/TextureArrays/" + TextureFolder); string path = "Assets/CScape/Editor/Resources/TextureArrays/" + TextureFolder + "/NormaltextureArray.asset"; AssetDatabase.CreateAsset(textureArray, path); Debug.Log("Saved asset to " + path); normalArray = Resources.Load("TextureArrays/" + TextureFolder + "/NormaltextureArray") as Texture2DArray; cityMaterial.SetTexture("_MaskTexArray", normalArray); }
/// <summary> /// Gets Unity Material from Daggerfall terrain using texture arrays. /// </summary> /// <param name="archive">Archive index.</param> /// <returns>Material or null.</returns> public Material GetTerrainTextureArrayMaterial(int archive) { // Ready check if (!IsReady) { return(null); } // Return from cache if present int key = MakeTextureKey((short)archive, (byte)0, (byte)0, TileMapKeyGroup); if (materialDict.ContainsKey(key)) { CachedMaterial cm = GetMaterialFromCache(key); if (cm.filterMode == MainFilterMode) { // Properties are the same return(cm.material); } else { // Properties don't match, remove material and reload materialDict.Remove(key); } } // Generate texture array Texture2DArray textureArrayTerrainTiles = textureReader.GetTerrainTextureArray(archive, TextureMap.Albedo); Texture2DArray textureArrayTerrainTilesNormalMap = textureReader.GetTerrainTextureArray(archive, TextureMap.Normal); Texture2DArray textureArrayTerrainTilesParallaxMap = textureReader.GetTerrainTextureArray(archive, TextureMap.Height); Texture2DArray textureArrayTerrainTilesMetallicGloss = textureReader.GetTerrainTextureArray(archive, TextureMap.MetallicGloss); textureArrayTerrainTiles.filterMode = MainFilterMode; Shader shader = Shader.Find(_DaggerfallTilemapTextureArrayShaderName); Material material = new Material(shader); material.name = string.Format("TEXTURE.{0:000} [TilemapTextureArray]", archive); material.SetTexture(TileTexArrUniforms.TileTexArr, textureArrayTerrainTiles); if (textureArrayTerrainTilesNormalMap != null) { // If normal map texture array was loaded successfully enable _NORMALMAP in shader and set texture material.SetTexture(TileTexArrUniforms.TileNormalMapTexArr, textureArrayTerrainTilesNormalMap); material.EnableKeyword(KeyWords.NormalMap); //textureArrayTerrainTilesNormalMap.filterMode = MainFilterMode; } if (textureArrayTerrainTilesParallaxMap != null) { // If parallax map texture array was loaded successfully enable _PARALLAXMAP in shader and set texture material.SetTexture(TileTexArrUniforms.TileParallaxMapTexArr, textureArrayTerrainTilesParallaxMap); material.EnableKeyword(KeyWords.HeightMap); //textureArrayTerrainTilesParallaxMap.filterMode = MainFilterMode; } if (textureArrayTerrainTilesMetallicGloss != null) { // If metallic gloss map texture array was loaded successfully enable _METALLICGLOSSMAP in shader and set texture material.SetTexture(TileTexArrUniforms.TileMetallicGlossMapTexArr, textureArrayTerrainTilesMetallicGloss); material.EnableKeyword(KeyWords.MetallicGlossMap); material.SetFloat(Uniforms.Smoothness, 0.35f); //textureArrayTerrainTilesMetallicGloss.filterMode = MainFilterMode; } CachedMaterial newcm = new CachedMaterial() { key = key, keyGroup = TileMapKeyGroup, material = material, filterMode = MainFilterMode, }; materialDict.Add(key, newcm); return(material); }
public void Load() { // ------------------ CONFIGURATION DATA --------------------------------- Debug.Log("Loading Quantum System Configuration."); ImportData importData = JsonUtility.FromJson <ImportData>(systemConfig.ToString()); numberOfStates = importData.numberOfStates; energyLevels = new float[numberOfStates]; for (int i = 0; i < numberOfStates; i++) { energyLevels[i] = (float)importData.energyLevels[i]; } resolution = importData.resolution; length = (float)importData.length; mass = (float)importData.mass; potentialMin = (float)importData.potentialMin; potentialMax = (float)importData.potentialMax; dx = length / (resolution - 1); stateChannels = importData.statesAtlasChannels; numberOfStates = Mathf.Min(numberOfStates, stateChannels * MaterialController.instance.shaderMaxReservedIndex); qMath = new QMath(resolution, length); // ------------------- POTENTAL ---------------------------- potentialTexture = new Texture2D(resolution, resolution, TextureFormat.RFloat, false); Color[] textureData = potentialTextureEXR.GetPixels(0); float maximumPotentialCompressed = 0.0f; float potentialValue; for (int i = 0; i < resolution; i++) { for (int j = 0; j < resolution; j++) { for (int k = 0; k < importData.potentialAtlasChannels; k++) { potentialValue = 0.5f * (1.0f + Mathf.Log(textureData[j + i * resolution][k])); textureData[j + i * resolution][k] = potentialValue; if (potentialValue > maximumPotentialCompressed) { maximumPotentialCompressed = potentialValue; } } } } // the only reason the EXR does not fill the potential range is if // the potenital is constant every where. in that case the potentialMax // would have been set to potentialMin + 1 to avoid division by zero. if (maximumPotentialCompressed < 0.1f) { potentialMax = potentialMin; } potentialTexture.SetPixels(textureData, 0); potentialTexture.Apply(); MaterialController.currentMaterial.SetTexture("_MainTex", potentialTexture); // ------------------- STATES ---------------------------- // load state data to states textureData = statesTextureEXR.GetPixels(0); int stateIndex = 0; // initalize states states = new float[numberOfStates][, ]; for (int i = 0; i < numberOfStates; i++) { states[i] = new float[resolution, resolution]; } // get states data from EXR texture and decode by takig the Log // read in textures from grid red channel to green channel, left to right, top to bottom for (int grid_i = importData.statesAtlasGrid - 1; grid_i >= 0; grid_i--) { for (int grid_j = 0; grid_j < importData.statesAtlasGrid; grid_j++) { for (int grid_c = 0; grid_c < stateChannels; grid_c++) { for (int pixel_i = 0; pixel_i < resolution; pixel_i++) { for (int pixel_j = 0; pixel_j < resolution; pixel_j++) { states[stateIndex][pixel_i, pixel_j] = Mathf.Log(textureData[pixel_j + resolution * (grid_j + importData.statesAtlasGrid * (pixel_i + grid_i * resolution))][grid_c]); } } stateIndex++; if (stateIndex >= numberOfStates) { break; // cascading breaks } } if (stateIndex >= numberOfStates) { break; // cascading breaks } } if (stateIndex >= numberOfStates) { break; // cascading breaks } } if (numberOfStates % stateChannels != 0) { Debug.LogError("Error: " + numberOfStates + " quantum states can not fit into an integer number of " + importData.statesAtlasChannels + " channel textures."); } // pack states as triplets in a color texture2DArray maxTextureLayer = numberOfStates / stateChannels; statesTexture = new Texture2DArray(resolution, resolution, maxTextureLayer, TextureFormat.RGBAFloat, false); for (int layer = 0; layer < maxTextureLayer; layer++) { Color[] tempState = new Color[resolution * resolution]; for (int i = 0; i < resolution; i++) { for (int j = 0; j < resolution; j++) { for (int k = 0; k < stateChannels; k++) { tempState[j + i * resolution][k] = states[k + layer * stateChannels][i, j]; } } } statesTexture.SetPixels(tempState, layer); } statesTexture.Apply(); MaterialController.currentMaterial.SetTexture("_States", statesTexture); MaterialController.currentMaterial.SetInt("_MaxIndex", maxTextureLayer); Debug.Log("Texture Loaded!"); }
public void ApplyTexture(Texture2DArray texture2DArray, List <Matrix4x4> world2cameraList, List <Matrix4x4> projectionMatrixList) { Mesh mesh = gameObject.GetComponent <MeshFilter>().mesh; Vector3[] vertecs = mesh.vertices; int photoNum = world2cameraList.Count; //x,yの2つの要素を一つの要素として写真の枚数分この配列に格納。あとでGPU側に投げる var uvArray = new float[vertecs.Length * 2 * photoNum]; //使うテクスチャの番号使わない場合は-1を格納します。これもあとでGPUに投げる。 var textureIdxArray = new int[vertecs.Length]; //初期化 for (int i = 0; i < uvArray.Length; i++) { uvArray[i] = -1; } for (int i = 0; i < vertecs.Length; i++) { textureIdxArray[i] = -1; } int vertecsIdx = 0; foreach (var v in vertecs) { int textureIdx = -1; float score = 0; for (int i = 0; i < photoNum; i++) { Vector3 worldSpacePosition = transform.TransformPoint(new Vector3(v.x, v.y, v.z)); Matrix4x4 world2CameraMatrix = world2cameraList[i]; Matrix4x4 projectionMatrix = projectionMatrixList[i]; //カメラ座標系に変換 Vector3 cameraSpacePosition = world2CameraMatrix.MultiplyPoint(worldSpacePosition); //Hololensでのカメラの座標系は、カメラが向いている方向がzが負の方向。カメラの売りろ側は映ってないからスルー //詳しくは https://docs.microsoft.com/en-us/windows/mixed-reality/locatable-camera if (0 <= cameraSpacePosition.z) { continue; } //カメラ座標系上の点とプロジェクション行列かけて表示するところの空間に写像する //(あの空間のことをhomogeneous coordinatesっていうところもあるみたいだけど。 //同次座標って意味だとなんか違うのでprojected spaceとかにしておきます。) Vector3 projectedSpacePosition = projectionMatrix.MultiplyPoint(cameraSpacePosition); //左下原点。平面で考える。 Vector2 projectedPanelPosition = new Vector2(projectedSpacePosition.x, projectedSpacePosition.y); if (float.IsNaN(projectedPanelPosition.x) || float.IsNaN(projectedPanelPosition.y)) { continue; } //プロジェクション行列かけられた空間は(普通)-1~1の空間の中。 //ここめっちゃわかりやすい。 http://marupeke296.com/DXG_No70_perspective.html if (Mathf.Abs(projectedPanelPosition.x) <= 1f && Mathf.Abs(projectedPanelPosition.y) <= 1f) { //-1~1の空間を0~1の空間に写像 Vector2 normalizedProjectPosition = 0.5f * Vector2.one + 0.5f * projectedPanelPosition; if (CameraManager.Instance.CorrespondingPositionInTexture(normalizedProjectPosition)) { Vector2 uvPos = CameraManager.Instance.ConvertTexturePoint(normalizedProjectPosition); float newScore = 10 - Mathf.Abs(uvPos.x - 0.5f) - Mathf.Abs(uvPos.y - 0.5f); if (score < newScore) { score = newScore; textureIdx = i; } uvArray[2 * vertecsIdx * photoNum + 2 * i] = uvPos.x; uvArray[2 * vertecsIdx * photoNum + 2 * i + 1] = uvPos.y; } } } textureIdxArray[vertecsIdx] = textureIdx; vertecsIdx++; }//foreach (var v in vertecs) if (vertecs.Length == 0) { return; } Material material = gameObject.GetComponent <Renderer>().material; uvBuffer?.Release(); uvBuffer = new ComputeBuffer(vertecs.Length * photoNum, sizeof(float) * 2); uvBuffer.SetData(uvArray); material.SetBuffer("_UVArray", uvBuffer); textureIndexBuffer?.Release(); textureIndexBuffer = new ComputeBuffer(textureIdxArray.Length, sizeof(int)); textureIndexBuffer.SetData(textureIdxArray); material.SetBuffer("_TextureIdxArray", textureIndexBuffer); material.SetInt("_TextureCount", photoNum); material.SetTexture("_TextureArray", texture2DArray); }
/// <summary> /// Gets Unity Material from Daggerfall terrain using texture arrays. /// </summary> /// <param name="archive">Archive index.</param> /// <returns>Material or null.</returns> public Material GetTerrainTextureArrayMaterial(int archive) { // Ready check if (!IsReady) { return(null); } // Return from cache if present int key = MakeTextureKey((short)archive, (byte)0, (byte)0, TileMapKeyGroup); if (materialDict.ContainsKey(key)) { CachedMaterial cm = materialDict[key]; if (cm.filterMode == MainFilterMode) { // Properties are the same return(cm.material); } else { // Properties don't match, remove material and reload materialDict.Remove(key); } } // Generate texture array Texture2DArray textureArrayTerrainTiles = textureReader.GetTerrainAlbedoTextureArray(archive); Texture2DArray textureArrayTerrainTilesNormalMap = textureReader.GetTerrainNormalMapTextureArray(archive); Texture2DArray textureArrayTerrainTilesMetallicGloss = textureReader.GetTerrainMetallicGlossMapTextureArray(archive); textureArrayTerrainTiles.filterMode = MainFilterMode; Shader shader = Shader.Find(_DaggerfallTilemapTextureArrayShaderName); Material material = new Material(shader); material.name = string.Format("TEXTURE.{0:000} [TilemapTextureArray]", archive); material.SetTexture("_TileTexArr", textureArrayTerrainTiles); if (textureArrayTerrainTilesNormalMap != null) { // if normal map texture array was loaded successfully enable normalmap in shader and set texture material.SetTexture("_TileNormalMapTexArr", textureArrayTerrainTilesNormalMap); material.EnableKeyword("_NORMALMAP"); } if (textureArrayTerrainTilesMetallicGloss != null) { // if metallic gloss map texture array was loaded successfully set texture (should always contain a valid texture array - since it defaults to 1x1 textures) material.SetTexture("_TileMetallicGlossMapTexArr", textureArrayTerrainTilesMetallicGloss); } CachedMaterial newcm = new CachedMaterial() { key = key, keyGroup = TileMapKeyGroup, material = material, filterMode = MainFilterMode, }; materialDict.Add(key, newcm); return(material); }
public override void Draw(DrawInfo drawInfo) { EditorGUI.BeginChangeCheck(); base.Draw(drawInfo); if (m_forceSamplerUpdate) { m_forceSamplerUpdate = false; m_referenceSampler = UIUtils.GetNode(m_referenceNodeId) as TextureArrayNode; m_referenceArrayId = UIUtils.GetTextureArrayNodeRegisterId(m_referenceNodeId); } if (EditorGUI.EndChangeCheck()) { OnPropertyNameChanged(); } bool instanced = CheckReference(); if (m_referenceType == TexReferenceType.Instance && m_referenceSampler != null) { SetTitleText(m_referenceSampler.PropertyInspectorName + Constants.InstancePostfixStr); SetAdditonalTitleText(m_referenceSampler.AdditonalTitleContent.text); } else { SetTitleText(PropertyInspectorName); SetAdditonalTitleText(AdditonalTitleContent.text); } if (m_tittleOverlayIndex == -1) { m_tittleOverlayIndex = Array.IndexOf <GUIStyle>(GUI.skin.customStyles, GUI.skin.GetStyle("ObjectFieldThumbOverlay")); } m_titleOverlay = GUI.skin.customStyles[m_tittleOverlayIndex]; int fontSizeUpper = m_titleOverlay.fontSize; Rect newRect = m_globalPosition; newRect.width = (128) * drawInfo.InvertedZoom; newRect.height = (128) * drawInfo.InvertedZoom; newRect.x = m_previewRect.x; newRect.y = m_previewRect.y; m_titleOverlay.fontSize = ( int )(9 * drawInfo.InvertedZoom); Rect smallButton = newRect; smallButton.height = 14 * drawInfo.InvertedZoom; smallButton.y = newRect.yMax - smallButton.height - 2; smallButton.width = 40 * drawInfo.InvertedZoom; smallButton.x = newRect.xMax - smallButton.width - 2; m_showPreview = true; if (instanced) { DrawPreview(drawInfo, m_previewRect); if (GUI.Button(newRect, string.Empty, GUIStyle.none)) { UIUtils.FocusOnNode(m_referenceSampler, 1, true); } } else { EditorGUI.BeginChangeCheck(); if (m_materialMode) { if (m_materialTextureArray == null) { GUI.Box(newRect, "", UIUtils.ObjectFieldThumb); Color temp = GUI.color; GUI.color = Color.clear; m_materialTextureArray = EditorGUIObjectField(newRect, m_materialTextureArray, typeof(Texture2DArray), false) as Texture2DArray; GUI.color = temp; GUI.Button(smallButton, "Select", UIUtils.GetCustomStyle(CustomStyle.SamplerButton)); if (ContainerGraph.LodLevel <= ParentGraph.NodeLOD.LOD2) { GUI.Label(newRect, "None (Texture2DArray)", UIUtils.ObjectFieldThumbOverlay); } } else { Rect butRect = m_previewRect; butRect.y -= 1; butRect.x += 1; Rect hitRect = butRect; hitRect.height = 14 * drawInfo.InvertedZoom; hitRect.y = butRect.yMax - hitRect.height; hitRect.width = 4 * 14 * drawInfo.InvertedZoom; Color temp = GUI.color; GUI.color = Color.clear; bool restoreMouse = false; if (Event.current.type == EventType.mouseDown && hitRect.Contains(Event.current.mousePosition)) { restoreMouse = true; Event.current.type = EventType.ignore; } m_materialTextureArray = EditorGUIObjectField(newRect, m_materialTextureArray, typeof(Texture2DArray), false) as Texture2DArray; if (restoreMouse) { Event.current.type = EventType.mouseDown; } GUI.color = temp; DrawPreview(drawInfo, m_previewRect); DrawPreviewMaskButtons(drawInfo, butRect); GUI.Box(newRect, string.Empty, UIUtils.GetCustomStyle(CustomStyle.SamplerFrame)); GUI.Box(smallButton, "Select", UIUtils.GetCustomStyle(CustomStyle.SamplerButton)); } } else { if (m_defaultTextureArray == null) { GUI.Box(newRect, "", UIUtils.ObjectFieldThumb); Color temp = GUI.color; GUI.color = Color.clear; m_defaultTextureArray = EditorGUIObjectField(newRect, m_defaultTextureArray, typeof(Texture2DArray), false) as Texture2DArray; GUI.color = temp; GUI.Button(smallButton, "Select", UIUtils.GetCustomStyle(CustomStyle.SamplerButton)); if (ContainerGraph.LodLevel <= ParentGraph.NodeLOD.LOD2) { GUI.Label(newRect, "None (Texture2DArray)", UIUtils.ObjectFieldThumbOverlay); } } else { Rect butRect = m_previewRect; butRect.y -= 1; butRect.x += 1; Rect hitRect = butRect; hitRect.height = 14 * drawInfo.InvertedZoom; hitRect.y = butRect.yMax - hitRect.height; hitRect.width = 4 * 14 * drawInfo.InvertedZoom; Color temp = GUI.color; GUI.color = Color.clear; bool restoreMouse = false; if (Event.current.type == EventType.mouseDown && hitRect.Contains(Event.current.mousePosition)) { restoreMouse = true; Event.current.type = EventType.ignore; } m_defaultTextureArray = EditorGUIObjectField(newRect, m_defaultTextureArray, typeof(Texture2DArray), false) as Texture2DArray; if (restoreMouse) { Event.current.type = EventType.mouseDown; } GUI.color = temp; DrawPreview(drawInfo, m_previewRect); DrawPreviewMaskButtons(drawInfo, butRect); GUI.Box(newRect, string.Empty, UIUtils.GetCustomStyle(CustomStyle.SamplerFrame)); GUI.Box(smallButton, "Select", UIUtils.GetCustomStyle(CustomStyle.SamplerButton)); } } //if ( m_materialMode ) // m_materialTextureArray = ( Texture2DArray ) EditorGUI.ObjectField( newRect, m_materialTextureArray, typeof( Texture2DArray ), false ); //else // m_defaultTextureArray = ( Texture2DArray ) EditorGUI.ObjectField( newRect, m_defaultTextureArray, typeof( Texture2DArray ), false ); if (EditorGUI.EndChangeCheck()) { CheckTextureImporter(true); SetAdditonalTitleText(string.Format(Constants.PropertyValueLabel, GetPropertyValStr())); BeginDelayedDirtyProperty(); m_requireMaterialUpdate = true; } m_titleOverlay.fontSize = fontSizeUpper; } }
void GenerateArrays() { int AlbedoSize = 256; int MipMapCount = 10; for (int i = 0; i < 8; i++) { if (Textures[i + 1].Albedo.width > AlbedoSize) { AlbedoSize = Textures[i + 1].Albedo.width; MipMapCount = Textures[i + 1].Albedo.mipmapCount; } if (Textures[i + 1].Albedo.height > AlbedoSize) { AlbedoSize = Textures[i + 1].Albedo.height; MipMapCount = Textures[i + 1].Albedo.mipmapCount; } } Texture2DArray AlbedoArray = new Texture2DArray(AlbedoSize, AlbedoSize, 8, TextureFormat.RGBA32, true); for (int i = 0; i < 8; i++) { if (Textures[i + 1].Albedo.width <= 4 && Textures[i + 1].Albedo.height <= 4) { continue; } if (Textures[i + 1].Albedo.width != AlbedoSize || Textures[i + 1].Albedo.height != AlbedoSize) { //Debug.Log("Rescale texture from" + Textures[i + 1].Albedo.width + "x" + Textures[i + 1].Albedo.height + " to: " + AlbedoSize); Textures[i + 1].Albedo = TextureScale.Bilinear(Textures[i + 1].Albedo, AlbedoSize, AlbedoSize); } //if (i == 0) // MipMapCount = Textures[i + 1].Albedo.mipmapCount; if (MipMapCount != Textures[i + 1].Albedo.mipmapCount) { Debug.LogWarning("Wrong mipmap Count: " + Textures[i + 1].Albedo.mipmapCount + " for texture" + Textures[i + 1].AlbedoPath); } for (int m = 0; m < MipMapCount; m++) { AlbedoArray.SetPixels(Textures[i + 1].Albedo.GetPixels(m), i, m); } } //AlbedoArray.mipMapBias = 0.5f; AlbedoArray.filterMode = FilterMode.Bilinear; AlbedoArray.anisoLevel = 4; AlbedoArray.mipMapBias = 0.0f; AlbedoArray.Apply(false); TerrainMaterial.SetTexture("_SplatAlbedoArray", AlbedoArray); AlbedoSize = 256; for (int i = 0; i < 8; i++) { if (Textures[i + 1].Normal == null) { continue; } if (Textures[i + 1].Normal.width > AlbedoSize) { AlbedoSize = Textures[i + 1].Normal.width; } if (Textures[i + 1].Normal.height > AlbedoSize) { AlbedoSize = Textures[i + 1].Normal.height; } } Texture2DArray NormalArray = new Texture2DArray(AlbedoSize, AlbedoSize, 8, TextureFormat.RGBA32, true); for (int i = 0; i < 8; i++) { if (Textures[i + 1].Normal == null) { continue; } if (Textures[i + 1].Normal.width != 1024 || Textures[i + 1].Normal.height != 1024) { Textures[i + 1].Normal = TextureScale.Bilinear(Textures[i + 1].Normal, AlbedoSize, AlbedoSize); } for (int m = 0; m < Textures[i + 1].Normal.mipmapCount; m++) { NormalArray.SetPixels(Textures[i + 1].Normal.GetPixels(m), i, m); } } //NormalArray.mipMapBias = -0.5f; NormalArray.filterMode = FilterMode.Bilinear; NormalArray.anisoLevel = 2; NormalArray.Apply(false); TerrainMaterial.SetTexture("_SplatNormalArray", NormalArray); }
void DrawScatterGUI() { if (MicroSplatUtilities.DrawRollup("Brush Settings")) { brushSize = EditorGUILayout.Slider("Brush Size", brushSize, 0.01f, 30.0f); brushFlow = EditorGUILayout.Slider("Brush Flow", brushFlow, 0.1f, 128.0f); brushFalloff = EditorGUILayout.Slider("Brush Falloff", brushFalloff, 0.1f, 3.5f); Material tempMat = null; for (int i = 0; i < rawTerrains.Count; ++i) { Terrain t = rawTerrains [i]; MicroSplatTerrain mst = t.GetComponent <MicroSplatTerrain> (); if (mst != null) { if (mst.templateMaterial != null && mst.templateMaterial.HasProperty("_ScatterDiffuse")) { Texture2DArray diff = mst.templateMaterial.GetTexture("_ScatterDiffuse") as Texture2DArray; scatterIndex = MicroSplatUtilities.DrawTextureSelector(scatterIndex, diff, false); tempMat = mst.templateMaterial; } else { scatterIndex = EditorGUILayout.IntField("Scatter Index", scatterIndex); } } else { scatterIndex = EditorGUILayout.IntField("Scatter Index", scatterIndex); } } //EditorGUILayout.MinMaxSlider (CSlopeRange, ref slopeRange.x, ref slopeRange.y, 0.0f, 1.0f); paintValue = EditorGUILayout.Slider("Target Opacity", paintValue, 0.0f, 1.0f); #if __MICROSPLAT_SCATTER__ if (tempMat != null) { scatterLayer = (ScatterLayer)EditorGUILayout.EnumPopup(CScatterLayer, scatterLayer); EditorGUILayout.Separator(); using (new GUILayout.VerticalScope(GUI.skin.box)) { EditorGUI.BeginChangeCheck(); EditorGUILayout.LabelField("Per Texture Properties"); bool changed = MicroSplatScatter.DrawPerTexExternal(tempMat, scatterIndex); EditorGUILayout.Separator(); // sync compile changes if (changed) { MicroSplatShaderGUI.MicroSplatCompiler comp = new MicroSplatShaderGUI.MicroSplatCompiler(); comp.Init(); comp.Compile(tempMat); } // sync property changes if (EditorGUI.EndChangeCheck()) { MicroSplatObject.SyncAll(); } } } #endif GUILayout.Box("", new GUILayoutOption [] { GUILayout.ExpandWidth(true), GUILayout.Height(1) }); EditorGUILayout.Separator(); } DrawFillGUI(); }
/// <summary> /// Gets terrain normal map texture array containing each terrain tile in a seperate array slice. /// </summary> /// <param name="archive">Archive index.</param> /// <param name="stayReadable">Texture should stay readable.</param> /// <param name="nonAlphaFormat">Non-alpha TextureFormat.</param> /// <returns>Texture2DArray or null</returns> public Texture2DArray GetTerrainNormalMapTextureArray( int archive, bool stayReadable = false, SupportedAlphaTextureFormats alphaFormat = SupportedAlphaTextureFormats.ARGB32) { // Load texture file and check count matches terrain tiles TextureFile textureFile = new TextureFile(Path.Combine(Arena2Path, TextureFile.IndexToFileName(archive)), FileUsage.UseMemory, true); int numSlices = 0; if (textureFile.RecordCount == 56) { numSlices = textureFile.RecordCount; } else { return null; } Texture2DArray textureArray; if (!stayReadable && TextureReplacement.TryImportTextureArray(archive, numSlices, TextureMap.Normal, null, out textureArray)) return textureArray; int width; int height; // try to import first replacement texture for tile archive to determine width and height of replacement texture set (must be the same for all replacement textures for Texture2DArray) Texture2D normalMap; if (TextureReplacement.TryImportTexture(archive, 0, 0, TextureMap.Normal, false, out normalMap)) { width = normalMap.width; height = normalMap.height; } else { return null; } textureArray = new Texture2DArray(width, height, numSlices, ParseTextureFormat(alphaFormat), MipMaps); // Rollout tiles into texture array for (int record = 0; record < textureFile.RecordCount; record++) { // Import custom texture(s) if (!TextureReplacement.TryImportTexture(archive, record, 0, TextureMap.Normal, false, out normalMap)) { // if current texture does not exist Debug.LogErrorFormat("Terrain: imported archive {0} does not contain normal for record {1}.", archive, record); return null; } // enforce that all custom normal map textures have the same dimension (requirement of Texture2DArray) if ((normalMap.width != width) || (normalMap.height != height)) { Debug.LogErrorFormat("Terrain: failed to inject normal maps for archive {0}, incorrect size at record {1}.", archive, record); return null; } // Insert into texture array textureArray.SetPixels32(normalMap.GetPixels32(), record, 0); } textureArray.Apply(true, !stayReadable); // Change settings for these textures textureArray.wrapMode = TextureWrapMode.Clamp; textureArray.anisoLevel = 8; return textureArray; }
public SceneControl(ScreenComponent manager, string style = "") : base(manager, style) { player = manager.Player; camera = manager.Camera; assets = manager.Game.Assets; Manager = manager; simpleShader = manager.Game.Content.Load<Effect>("simple"); sunTexture = assets.LoadTexture(typeof(ScreenComponent), "sun"); //List<Bitmap> bitmaps = new List<Bitmap>(); var definitions = DefinitionManager.Instance.GetBlockDefinitions(); int textureCount = 0; foreach (var definition in definitions) { textureCount += definition.Textures.Length; } int bitmapSize = 128; blockTextures = new Texture2DArray(manager.GraphicsDevice, 1, bitmapSize, bitmapSize, textureCount); int layer = 0; foreach (var definition in definitions) { foreach (var bitmap in definition.Textures) { System.Drawing.Bitmap texture = manager.Game.Assets.LoadBitmap(definition.GetType(), bitmap); var scaled = texture;//new Bitmap(bitmap, new System.Drawing.Size(bitmapSize, bitmapSize)); int[] data = new int[scaled.Width * scaled.Height]; var bitmapData = scaled.LockBits(new System.Drawing.Rectangle(0, 0, scaled.Width, scaled.Height), ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format32bppArgb); System.Runtime.InteropServices.Marshal.Copy(bitmapData.Scan0, data, 0, data.Length); blockTextures.SetData(data, layer); scaled.UnlockBits(bitmapData); layer++; } } /*int size = (int)Math.Ceiling(Math.Sqrt(bitmaps.Count)); Bitmap blocks = new Bitmap(size * TEXTURESIZE, size * TEXTURESIZE); using (Graphics g = Graphics.FromImage(blocks)) { int counter = 0; foreach (var bitmap in bitmaps) { int x = counter % size; int y = (int)(counter / size); g.DrawImage(bitmap, new System.Drawing.Rectangle(TEXTURESIZE * x, TEXTURESIZE * y, TEXTURESIZE, TEXTURESIZE)); counter++; } } using (MemoryStream stream = new MemoryStream()) { blocks.Save(stream, ImageFormat.Png); stream.Seek(0, SeekOrigin.Begin); blockTextures = Texture2D.FromStream(manager.GraphicsDevice, stream); }*/ planet = ResourceManager.Instance.GetPlanet(0); // TODO: evtl. Cache-Size (Dimensions) VIEWRANGE + 1 int range = ((int)Math.Pow(2, VIEWRANGE) - 2) / 2; localChunkCache = new LocalChunkCache(ResourceManager.Instance.GlobalChunkCache, VIEWRANGE, range); chunkRenderer = new ChunkRenderer[ (int)Math.Pow(2, VIEWRANGE) * (int)Math.Pow(2, VIEWRANGE), planet.Size.Z]; orderedChunkRenderer = new List<ChunkRenderer>( (int)Math.Pow(2, VIEWRANGE) * (int)Math.Pow(2, VIEWRANGE) * planet.Size.Z); for (int i = 0; i < chunkRenderer.GetLength(0); i++) { for (int j = 0; j < chunkRenderer.GetLength(1); j++) { ChunkRenderer renderer = new ChunkRenderer(simpleShader, manager.GraphicsDevice, camera.Projection, blockTextures); chunkRenderer[i, j] = renderer; orderedChunkRenderer.Add(renderer); } } backgroundThread = new Thread(BackgroundLoop); backgroundThread.Priority = ThreadPriority.Lowest; backgroundThread.IsBackground = true; backgroundThread.Start(); var selectionVertices = new[] { new VertexPositionColor(new Vector3(-0.001f, +1.001f, +1.001f), Color.Black * 0.5f), new VertexPositionColor(new Vector3(+1.001f, +1.001f, +1.001f), Color.Black * 0.5f), new VertexPositionColor(new Vector3(-0.001f, -0.001f, +1.001f), Color.Black * 0.5f), new VertexPositionColor(new Vector3(+1.001f, -0.001f, +1.001f), Color.Black * 0.5f), new VertexPositionColor(new Vector3(-0.001f, +1.001f, -0.001f), Color.Black * 0.5f), new VertexPositionColor(new Vector3(+1.001f, +1.001f, -0.001f), Color.Black * 0.5f), new VertexPositionColor(new Vector3(-0.001f, -0.001f, -0.001f), Color.Black * 0.5f), new VertexPositionColor(new Vector3(+1.001f, -0.001f, -0.001f), Color.Black * 0.5f), }; var billboardVertices = new[] { new VertexPositionTexture(new Vector3(-0.5f, 0.5f, 0), new Vector2(0, 0)), new VertexPositionTexture(new Vector3(0.5f, 0.5f, 0), new Vector2(1, 0)), new VertexPositionTexture(new Vector3(-0.5f, -0.5f, 0), new Vector2(0, 1)), new VertexPositionTexture(new Vector3(0.5f, 0.5f, 0), new Vector2(1, 0)), new VertexPositionTexture(new Vector3(0.5f, -0.5f, 0), new Vector2(1, 1)), new VertexPositionTexture(new Vector3(-0.5f, -0.5f, 0), new Vector2(0, 1)), }; var selectionIndices = new short[] { 0, 1, 0, 2, 1, 3, 2, 3, 4, 5, 4, 6, 5, 7, 6, 7, 0, 4, 1, 5, 2, 6, 3, 7 }; selectionLines = new VertexBuffer(manager.GraphicsDevice, VertexPositionColor.VertexDeclaration, selectionVertices.Length); selectionLines.SetData(selectionVertices); selectionIndexBuffer = new IndexBuffer(manager.GraphicsDevice, DrawElementsType.UnsignedShort, selectionIndices.Length); selectionIndexBuffer.SetData(selectionIndices); billboardVertexbuffer = new VertexBuffer(manager.GraphicsDevice, VertexPositionTexture.VertexDeclaration, billboardVertices.Length); billboardVertexbuffer.SetData(billboardVertices); sunEffect = new BasicEffect(manager.GraphicsDevice); sunEffect.TextureEnabled = true; selectionEffect = new BasicEffect(manager.GraphicsDevice); selectionEffect.VertexColorEnabled = true; MiniMapTexture = new RenderTarget2D(manager.GraphicsDevice, 128, 128, PixelInternalFormat.Rgb8); // , false, SurfaceFormat.Color, DepthFormat.Depth24Stencil8, 0, RenderTargetUsage.PreserveContents); miniMapProjectionMatrix = Matrix.CreateOrthographic(128, 128, 1, 10000); }
void LoadWorldTextures() { requireTextureArrayUpdate = false; // Init texture array if (worldTextures == null) { worldTextures = new List <WorldTexture> (); } else { worldTextures.Clear(); } if (worldTexturesDict == null) { worldTexturesDict = new Dictionary <Texture2D, int> (); } else { worldTexturesDict.Clear(); } // Clear definitions if (voxelDefinitions != null) { // Voxel Definitions no longer are added to the dictionary, clear the index field. for (int k = 0; k < voxelDefinitionsCount; k++) { if (voxelDefinitions [k] != null) { voxelDefinitions [k].Reset(); } } } else { voxelDefinitions = new VoxelDefinition [128]; } voxelDefinitionsCount = 0; if (voxelDefinitionsDict == null) { voxelDefinitionsDict = new Dictionary <string, VoxelDefinition> (); } else { voxelDefinitionsDict.Clear(); } if (sessionUserVoxels == null) { sessionUserVoxels = new List <VoxelDefinition> (); } // The null voxel definition VoxelDefinition nullVoxelDefinition = ScriptableObject.CreateInstance <VoxelDefinition> (); nullVoxelDefinition.name = "Null"; nullVoxelDefinition.hidden = true; nullVoxelDefinition.canBeCollected = false; nullVoxelDefinition.ignoresRayCast = true; nullVoxelDefinition.renderType = RenderType.Empty; AddVoxelTextures(nullVoxelDefinition); // Check default voxel if (defaultVoxel == null) { defaultVoxel = Resources.Load <VoxelDefinition> ("VoxelPlay/Defaults/DefaultVoxel"); } AddVoxelTextures(defaultVoxel); // Add all biome textures if (world.biomes != null) { for (int k = 0; k < world.biomes.Length; k++) { BiomeDefinition biome = world.biomes [k]; if (biome == null) { continue; } if (biome.voxelTop != null) { AddVoxelTextures(biome.voxelTop); if (biome.voxelTop.biomeDirtCounterpart == null) { biome.voxelTop.biomeDirtCounterpart = biome.voxelDirt; } } AddVoxelTextures(biome.voxelDirt); if (biome.vegetation != null) { for (int v = 0; v < biome.vegetation.Length; v++) { AddVoxelTextures(biome.vegetation [v].vegetation); } } if (biome.trees != null) { for (int t = 0; t < biome.trees.Length; t++) { ModelDefinition tree = biome.trees [t].tree; if (tree == null) { continue; } for (int b = 0; b < tree.bits.Length; b++) { AddVoxelTextures(tree.bits [b].voxelDefinition); } } } if (biome.ores != null) { for (int v = 0; v < biome.ores.Length; v++) { // ensure proper size if (biome.ores [v].veinMinSize == biome.ores [v].veinMaxSize && biome.ores [v].veinMaxSize == 0) { biome.ores [v].veinMinSize = 2; biome.ores [v].veinMaxSize = 6; biome.ores [v].veinsCountMin = 1; biome.ores [v].veinsCountMax = 2; } AddVoxelTextures(biome.ores [v].ore); } } } } // Special voxels if (enableClouds) { if (world.cloudVoxel == null) { world.cloudVoxel = Resources.Load <VoxelDefinition> ("VoxelPlay/Defaults/VoxelCloud"); } AddVoxelTextures(world.cloudVoxel); } // Add additional world voxels if (world.moreVoxels != null) { for (int k = 0; k < world.moreVoxels.Length; k++) { AddVoxelTextures(world.moreVoxels [k]); } } // Add all items' textures are available if (world.items != null) { int itemCount = world.items.Length; for (int k = 0; k < itemCount; k++) { ItemDefinition item = world.items [k]; if (item != null && item.category == ItemCategory.Voxel) { AddVoxelTextures(item.voxelType); } } } // Add any other voxel found inside Defaults VoxelDefinition [] vdd = Resources.LoadAll <VoxelDefinition> ("VoxelPlay/Defaults"); for (int k = 0; k < vdd.Length; k++) { AddVoxelTextures(vdd [k]); } // Add any other voxel found inside World directory if (!string.IsNullOrEmpty(world.name)) { vdd = Resources.LoadAll <VoxelDefinition> ("Worlds/" + world.name); for (int k = 0; k < vdd.Length; k++) { AddVoxelTextures(vdd [k]); } // Add any other voxel found inside a resource directory with same name of world (if not placed into Worlds directory) vdd = Resources.LoadAll <VoxelDefinition> (world.name); for (int k = 0; k < vdd.Length; k++) { AddVoxelTextures(vdd [k]); } } // Add any other voxel found inside a resource directory under the world definition asset if (!string.IsNullOrEmpty(world.resourceLocation)) { vdd = Resources.LoadAll <VoxelDefinition> (world.resourceLocation); for (int k = 0; k < vdd.Length; k++) { AddVoxelTextures(vdd [k]); } } // Add connected textures ConnectedTexture [] ctt = Resources.LoadAll <ConnectedTexture> (""); for (int k = 0; k < ctt.Length; k++) { ConnectedTexture ct = ctt [k]; VoxelDefinition vd = ctt [k].voxelDefinition; if (vd == null || vd.index == 0) { continue; } for (int j = 0; j < ct.config.Length; j++) { ct.config [j].textureIndex = AddTexture(ct.config [j].texture, null, null, null); } ct.Init(); } // Add user provided voxels during playtime int count = sessionUserVoxels.Count; for (int k = 0; k < count; k++) { AddVoxelTextures(sessionUserVoxels [k]); } sessionUserVoxelsLastIndex = voxelDefinitionsCount - 1; // Add transparent voxel definitions for the see-through effect if (seeThrough) { int lastOne = voxelDefinitionsCount; // this loop will add voxels so end at the last regular voxel definition (don't process see-through versions) for (int k = 0; k < lastOne; k++) { VoxelDefinition vd = voxelDefinitions [k]; if (vd.renderType == RenderType.CutoutCross) { vd.seeThroughMode = SeeThroughMode.FullyInvisible; } else { if (vd.seeThroughMode == SeeThroughMode.Transparency) { if (vd.renderType.supportsAlphaSeeThrough()) { vd.seeThroughVoxelTempTransp = CreateSeeThroughVoxelDefinition(vd); } else { vd.seeThroughMode = SeeThroughMode.FullyInvisible; } } } } } // Create array texture int textureCount = worldTextures.Count; if (textureCount > 0) { Texture2DArray pointFilterTextureArray = new Texture2DArray(textureSize, textureSize, textureCount, TextureFormat.ARGB32, hqFiltering); if (enableReliefMapping || !enableSmoothLighting) { pointFilterTextureArray.wrapMode = TextureWrapMode.Repeat; } else { pointFilterTextureArray.wrapMode = TextureWrapMode.Clamp; } pointFilterTextureArray.filterMode = hqFiltering ? FilterMode.Bilinear : FilterMode.Point; pointFilterTextureArray.mipMapBias = -mipMapBias; for (int k = 0; k < textureCount; k++) { if (worldTextures [k].colorsAndEmission != null) { pointFilterTextureArray.SetPixels32(worldTextures [k].colorsAndEmission, k); } else if (worldTextures [k].normalsAndElevation != null) { pointFilterTextureArray.SetPixels32(worldTextures [k].normalsAndElevation, k); } } worldTextures.Clear(); pointFilterTextureArray.Apply(hqFiltering, true); // Assign textures to materials if (renderingMaterials != null) { for (int k = 0; k < renderingMaterials.Length; k++) { if (renderingMaterials [k].usesTextureArray) { Material mat = renderingMaterials [k].material; if (mat != null && mat.HasProperty("_MainTex")) { mat.SetTexture("_MainTex", pointFilterTextureArray); } } } } matDynamicOpaque.SetTexture("_MainTex", pointFilterTextureArray); matDynamicCutout.SetTexture("_MainTex", pointFilterTextureArray); if (modelHighlightMat == null) { modelHighlightMat = Instantiate <Material> (Resources.Load <Material> ("VoxelPlay/Materials/VP Highlight Model")) as Material; } modelHighlightMat.SetTexture("_MainTex", pointFilterTextureArray); } }