public static void SetupRenderer(GrassColorMapRenderer renderer) { if (!renderer.renderCam) { renderer.renderCam = new GameObject().AddComponent <Camera>(); } renderer.renderCam.name = "Grass color map renderCam"; renderer.renderCam.enabled = false; //Camera set up renderer.renderCam.orthographic = true; renderer.renderCam.orthographicSize = (renderer.colorMap.bounds.size.x / 2); renderer.renderCam.farClipPlane = 5000f; renderer.renderCam.clearFlags = CameraClearFlags.Color; renderer.renderCam.backgroundColor = Color.clear; //Position cam in given center of terrain(s) renderer.renderCam.transform.position = new Vector3( renderer.colorMap.bounds.center.x, renderer.colorMap.bounds.center.y + renderer.colorMap.bounds.extents.y + CLIP_PADDING, renderer.colorMap.bounds.center.z ); renderer.renderCam.transform.localEulerAngles = new Vector3(90, 0, 0); }
public static void RenderColorMap(GrassColorMapRenderer renderer) { if (!renderer.colorMap) { renderer.colorMap = ScriptableObject.CreateInstance <GrassColorMap>(); } //If no area was defined, automatically calculate it if (renderer.colorMap.bounds.size == Vector3.zero) { ApplyUVFromTerrainBounds(renderer.colorMap, renderer); } else { renderer.colorMap.uv = BoundsToUV(renderer.colorMap.bounds); } renderer.colorMap.overrideTexture = false; SetupRenderer(renderer); SetupLighting(); RenderToTexture(renderer); RestoreLighting(); renderer.colorMap.SetActive(); }
private void OnDisable() { Instance = null; //Disable sampling of color map GrassColorMap.DisableGlobally(); #if UNITY_EDITOR EditorSceneManager.sceneSaved -= OnSceneSave; #endif }
public static void SetupRenderer(GrassColorMapRenderer renderer) { if (!renderer.renderCam) { renderer.renderCam = new GameObject().AddComponent <Camera>(); } renderer.renderCam.name = "Grass color map renderCam"; renderer.renderCam.enabled = false; //Camera set up renderer.renderCam.orthographic = true; renderer.renderCam.orthographicSize = (renderer.colorMap.bounds.size.x / 2); renderer.renderCam.farClipPlane = renderer.colorMap.bounds.size.y + CLIP_PADDING; renderer.renderCam.clearFlags = CameraClearFlags.Color; renderer.renderCam.backgroundColor = Color.red; renderer.renderCam.cullingMask = renderer.useLayers ? (int)renderer.renderLayer : -1; //Position cam in given center of terrain(s) renderer.renderCam.transform.position = new Vector3( renderer.colorMap.bounds.center.x, renderer.colorMap.bounds.center.y + renderer.colorMap.bounds.extents.y + CLIP_PADDING + (renderer.useLayers ? 0f : HEIGHT_OFFSET), renderer.colorMap.bounds.center.z ); renderer.renderCam.transform.localEulerAngles = new Vector3(90, 0, 0); #if URP UniversalAdditionalCameraData camData = renderer.renderCam.gameObject.AddComponent <UniversalAdditionalCameraData>(); camData.renderShadows = false; camData.renderPostProcessing = false; camData.antialiasing = AntialiasingMode.None; camData.requiresColorOption = CameraOverrideOption.Off; camData.requiresDepthOption = CameraOverrideOption.Off; camData.requiresColorTexture = false; camData.requiresDepthTexture = false; if (UniversalRenderPipeline.asset) { #if UNITY_EDITOR //Only runs in editor, but will be referenced in instance from there on if (!renderer.renderData) { renderer.renderData = PipelineUtilities.GetRenderer(("ColormapRenderer")); } #endif PipelineUtilities.ValidatePipelineRenderers(renderer.renderData); PipelineUtilities.AssignRendererToCamera(camData, renderer.renderData); } else { Debug.LogError("[StylizedGrassRenderer] No Universal Render Pipeline is currently active."); } #endif }
private void OnEnable() { Instance = this; AssignColorMap(); #if UNITY_EDITOR if (this.gameObject.name == "GameObject") { this.gameObject.name = "Grass Colormap renderer"; } #endif }
private void OnEnable() { Instance = this; AssignColorMap(); #if UNITY_EDITOR if (this.gameObject.name == "GameObject") { this.gameObject.name = "Grass Colormap renderer"; } EditorSceneManager.sceneSaved += OnSceneSave; #endif }
private void OnEnable() { script = (GrassColorMapRenderer)target; colorMap = serializedObject.FindProperty("colorMap"); resIdx = serializedObject.FindProperty("resIdx"); resolution = serializedObject.FindProperty("resolution"); renderLayer = serializedObject.FindProperty("renderLayer"); useLayers = serializedObject.FindProperty("useLayers"); terrainObjects = serializedObject.FindProperty("terrainObjects"); if (!script.colorMap) { script.colorMap = ColorMapEditor.NewColorMap(); } }
private static void GenerateScalemap(List <Terrain> terrains, GrassColorMapRenderer renderer, RenderTexture rgb) { if (terrains.Count == 0) { return; } if (renderer.layerScaleSettings.Count > 0) { Material originalMaterial = terrains[0].materialTemplate; splatExtractionMat = new Material(Shader.Find("Hidden/TerrainSplatmask")); //Temporarily override terrain material foreach (Terrain t in terrains) { t.materialTemplate = splatExtractionMat; } RenderTexture alphaBuffer = new RenderTexture(renderer.resolution, renderer.resolution, 0, RenderTextureFormat.R8, RenderTextureReadWrite.Linear); RenderTexture heightmapBuffer = new RenderTexture(renderer.resolution, renderer.resolution, 0, RenderTextureFormat.R8, RenderTextureReadWrite.Linear); RenderTexture heightmap = new RenderTexture(renderer.resolution, renderer.resolution, 0, RenderTextureFormat.R8, RenderTextureReadWrite.Linear); Shader.SetGlobalTexture("_InputAlphamap", alphaBuffer); Shader.SetGlobalTexture("_InputHeightmap", heightmap); MaterialPropertyBlock props = new MaterialPropertyBlock(); //Sort by strength List <GrassColorMapRenderer.LayerScaleSettings> settings = renderer.layerScaleSettings.OrderByDescending(o => o.strength).ToList(); int currentSplatIndex = 0; foreach (GrassColorMapRenderer.LayerScaleSettings layer in renderer.layerScaleSettings) { int splatmapID = GetSplatmapID(layer.layerID); Shader.SetGlobalVector("_SplatMask", ColorMapEditor.GetVectorMask(layer.layerID)); Shader.SetGlobalFloat("_SplatChannelStrength", layer.strength); //Terrain render splatmap 0 by default, force to render next splatmap in base pass if (splatmapID != currentSplatIndex) { //Debug.Log("layer.layerID requres splatmap switch to " + splatmapID); foreach (Terrain t in terrains) { props.SetTexture("_Control", t.terrainData.GetAlphamapTexture(splatmapID)); t.SetSplatMaterialPropertyBlock(props); } currentSplatIndex = splatmapID; } //Render now visible alpha weight into buffer renderer.renderCam.targetTexture = alphaBuffer; renderer.renderCam.Render(); //Max blending copy here! Graphics.Blit(alphaBuffer, heightmapBuffer, splatExtractionMat, (int)Pass.MaxBlend); Graphics.Blit(heightmapBuffer, heightmap); } //Fill any black pixels with white (taking into account blank splatmap channels) Shader.SetGlobalTexture("_InputHeightmap", heightmapBuffer); Graphics.Blit(null, heightmap, splatExtractionMat, (int)Pass.FillWhite); //Restore materials foreach (Terrain t in terrains) { t.materialTemplate = originalMaterial; t.SetSplatMaterialPropertyBlock(null); } //Add heightmap to alpha channel of rgb map RenderTexture colorBuffer = new RenderTexture(rgb); Graphics.Blit(rgb, colorBuffer); Shader.SetGlobalTexture("_InputColormap", rgb); Shader.SetGlobalTexture("_InputHeightmap", heightmap); Graphics.Blit(null, colorBuffer, splatExtractionMat, (int)Pass.AlphaMerge); Graphics.Blit(colorBuffer, rgb); //Graphics.Blit(heightmap, rgb); renderer.colorMap.hasScalemap = true; } else { renderer.colorMap.hasScalemap = false; } }
private static void RenderToTexture(GrassColorMapRenderer renderer) { if (!renderer.renderCam) { Debug.LogError("Renderer does not have a render cam set up"); return; } bool isTerrain = false; //Get all terrains List <Terrain> terrains = new List <Terrain>(); foreach (GameObject item in renderer.terrainObjects) { if (item == null) { continue; } Terrain t = item.GetComponent <Terrain>(); if (t) { isTerrain = true; terrains.Add(t); } } if (isTerrain) { foreach (Terrain t in terrains) { t.drawTreesAndFoliage = false; } } //Temporarly move terrains up 1000 units if (renderer.terrainObjects != null || renderer.terrainObjects.Count != 0) { if (renderer.terrainObjects[0]) { originalTerrainHeight = renderer.terrainObjects[0].transform.position.y; } foreach (GameObject item in renderer.terrainObjects) { if (item == null) { continue; } if (renderer.useLayers == false && renderer.terrainObjects[0]) { item.transform.position = new Vector3(item.transform.position.x, item.transform.position.y + HEIGHT_OFFSET, item.transform.position.z); } } } //Set up render texture RenderTexture rt = new RenderTexture(renderer.resolution, renderer.resolution, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear); renderer.renderCam.targetTexture = rt; RenderTexture.active = rt; //Render camera into a texture renderer.renderCam.Render(); //Generate heightmap from terrain layers if (isTerrain) { GenerateScalemap(terrains, renderer, rt); } Graphics.SetRenderTarget(rt); Texture2D render = new Texture2D(renderer.resolution, renderer.resolution, TextureFormat.ARGB32, false, true); render.ReadPixels(new Rect(0, 0, renderer.resolution, renderer.resolution), 0, 0); render.Apply(); render.Compress(false); render.name = renderer.colorMap.name; if (!renderer.colorMap.texture) { renderer.colorMap.texture = new Texture2D(renderer.colorMap.resolution, renderer.colorMap.resolution); } //Saving texture if (EditorUtility.IsPersistent(renderer.colorMap)) { //string texPath = AssetDatabase.GetAssetPath(renderer.colorMap.texture); //byte[] bytes = render.EncodeToPNG(); //System.IO.File.WriteAllBytes(texPath, bytes); //AssetDatabase.ImportAsset(texPath, ImportAssetOptions.Default); //SaveTexture(render, renderer.colorMap); EditorUtility.CopySerialized(render, renderer.colorMap.texture); DestroyImmediate(render); } else { renderer.colorMap.texture = render; } SetName(renderer.colorMap); EditorUtility.SetDirty(renderer.colorMap); //Cleanup renderer.renderCam.targetTexture = null; RenderTexture.active = null; DestroyImmediate(rt); DestroyImmediate(renderer.renderCam.gameObject); renderer.renderCam = null; #if URP PipelineUtilities.RemoveRendererFromPipeline(renderer.renderData); #endif if (isTerrain) { //Restore materials foreach (Terrain t in terrains) { t.drawTreesAndFoliage = true; } } //Restore terrains to original position height foreach (var item in renderer.terrainObjects) { if (item == null) { continue; } if (renderer.useLayers == false && renderer.terrainObjects[0]) { item.transform.position = new Vector3(item.transform.position.x, originalTerrainHeight, item.transform.position.z); } } }
public static void ApplyUVFromTerrainBounds(GrassColorMap colorMap, GrassColorMapRenderer renderer) { colorMap.bounds = ColorMapEditor.GetTerrainBounds(renderer.terrainObjects); colorMap.uv = ColorMapEditor.BoundsToUV(renderer.colorMap.bounds); }
private static void RenderToTexture(GrassColorMapRenderer renderer) { if (!renderer.renderCam) { Debug.LogError("Renderer does not have a render cam set up"); return; } //Temporarly disable foliage and move terrains up 1000 units if (renderer.terrainObjects != null || renderer.terrainObjects.Count != 0) { if (renderer.terrainObjects[0]) { originalTerrainHeight = renderer.terrainObjects[0].transform.position.y; } foreach (var item in renderer.terrainObjects) { Terrain t = item.GetComponent <Terrain>(); if (!t) { continue; } t.drawTreesAndFoliage = false; if (renderer.useLayers == false && renderer.terrainObjects[0]) { item.transform.position = new Vector3(item.transform.position.x, item.transform.position.y + 1000, item.transform.position.z); } } } if (renderer.useLayers) { renderer.renderCam.cullingMask = renderer.renderLayer; } else { //Position cam in given center of terrain(s) renderer.renderCam.transform.position = new Vector3( renderer.colorMap.bounds.center.x, renderer.colorMap.bounds.center.y + renderer.colorMap.bounds.extents.y + CLIP_PADDING + HEIGHT_OFFSET, renderer.colorMap.bounds.center.z ); } //Set up render texture RenderTexture rt = new RenderTexture(renderer.resolution, renderer.resolution, 0, RenderTextureFormat.ARGB32, RenderTextureReadWrite.Linear); renderer.renderCam.targetTexture = rt; RenderTexture.active = rt; //Render camera into a texture renderer.renderCam.Render(); Texture2D render = new Texture2D(rt.width, rt.height, TextureFormat.RGB24, false, true); render.ReadPixels(new Rect(0, 0, renderer.resolution, renderer.resolution), 0, 0); render.Apply(); render.Compress(false); render.name = renderer.colorMap.name; //Restore terrains to original state foreach (var item in renderer.terrainObjects) { Terrain t = item.GetComponent <Terrain>(); if (!t) { continue; } t.drawTreesAndFoliage = true; if (renderer.useLayers == false && renderer.terrainObjects[0]) { item.transform.position = new Vector3(item.transform.position.x, originalTerrainHeight, item.transform.position.z); } } if (!renderer.colorMap.texture) { renderer.colorMap.texture = new Texture2D(renderer.colorMap.resolution, renderer.colorMap.resolution); } //Saving texture if (EditorUtility.IsPersistent(renderer.colorMap)) { //string texPath = AssetDatabase.GetAssetPath(renderer.colorMap.texture); //byte[] bytes = render.EncodeToPNG(); //System.IO.File.WriteAllBytes(texPath, bytes); //AssetDatabase.ImportAsset(texPath, ImportAssetOptions.Default); //SaveTexture(render, renderer.colorMap); EditorUtility.CopySerialized(render, renderer.colorMap.texture); DestroyImmediate(render); } else { renderer.colorMap.texture = render; } SetName(renderer.colorMap); EditorUtility.SetDirty(renderer.colorMap); //Cleanup renderer.renderCam.targetTexture = null; RenderTexture.active = null; DestroyImmediate(rt); DestroyImmediate(renderer.renderCam.gameObject); renderer.renderCam = null; }
private void OnDisable() { Instance = null; //Disable sampling of color map GrassColorMap.DisableGlobally(); }