743 lines
33 KiB
C#
743 lines
33 KiB
C#
#if GRIFFIN
|
|
#if UNITY_EDITOR
|
|
using UnityEngine;
|
|
using UnityEngine.Rendering;
|
|
|
|
namespace Pinwheel.Griffin
|
|
{
|
|
public static class GLivePreviewDrawer
|
|
{
|
|
private static MaterialPropertyBlock previewPropertyBlock = new MaterialPropertyBlock();
|
|
|
|
public static void DrawGeometryLivePreview(GStylizedTerrain t, Camera cam, Texture newHeightMap, Rect dirtyRect)
|
|
{
|
|
if (t.transform.rotation != Quaternion.identity ||
|
|
t.transform.lossyScale != Vector3.one)
|
|
return;
|
|
|
|
Mesh previewMesh = GEditorSettings.Instance.livePreview.GetTriangleMesh(t.TerrainData.Geometry.MeshResolution);
|
|
|
|
Vector3 terrainSize = new Vector3(
|
|
t.TerrainData.Geometry.Width,
|
|
t.TerrainData.Geometry.Height,
|
|
t.TerrainData.Geometry.Length);
|
|
previewPropertyBlock.Clear();
|
|
previewPropertyBlock.SetTexture("_OldHeightMap", t.TerrainData.Geometry.HeightMap);
|
|
previewPropertyBlock.SetTexture("_NewHeightMap", newHeightMap);
|
|
previewPropertyBlock.SetTexture("_MainTex", newHeightMap);
|
|
previewPropertyBlock.SetFloat("_Height", t.TerrainData.Geometry.Height);
|
|
previewPropertyBlock.SetVector("_BoundMin", t.transform.position);
|
|
previewPropertyBlock.SetVector("_BoundMax", t.transform.TransformPoint(terrainSize));
|
|
Material mat = GInternalMaterials.GeometryLivePreviewMaterial;
|
|
mat.renderQueue = 4000;
|
|
|
|
int gridSize = t.TerrainData.Geometry.ChunkGridSize;
|
|
for (int x = 0; x < gridSize; ++x)
|
|
{
|
|
for (int z = 0; z < gridSize; ++z)
|
|
{
|
|
Rect uvRect = GCommon.GetUvRange(gridSize, x, z);
|
|
if (!uvRect.Overlaps(dirtyRect))
|
|
continue;
|
|
Vector3 localPos = new Vector3(
|
|
terrainSize.x * uvRect.x,
|
|
0f,
|
|
terrainSize.z * uvRect.y);
|
|
Vector3 worldPos = t.transform.TransformPoint(localPos);
|
|
Quaternion rotation = Quaternion.identity;
|
|
Vector3 scale = new Vector3(terrainSize.x * uvRect.width, 1, terrainSize.z * uvRect.height);
|
|
|
|
Graphics.DrawMesh(
|
|
previewMesh,
|
|
Matrix4x4.TRS(worldPos, rotation, scale),
|
|
mat,
|
|
LayerMask.NameToLayer("Default"),
|
|
cam,
|
|
0,
|
|
previewPropertyBlock);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void DrawGeometryLivePreview(GStylizedTerrain t, Camera cam, Texture newHeightMap, bool[] chunkCulling)
|
|
{
|
|
if (t.transform.rotation != Quaternion.identity ||
|
|
t.transform.lossyScale != Vector3.one)
|
|
return;
|
|
|
|
Mesh previewMesh = GEditorSettings.Instance.livePreview.GetTriangleMesh(t.TerrainData.Geometry.MeshResolution);
|
|
|
|
Vector3 terrainSize = new Vector3(
|
|
t.TerrainData.Geometry.Width,
|
|
t.TerrainData.Geometry.Height,
|
|
t.TerrainData.Geometry.Length);
|
|
previewPropertyBlock.Clear();
|
|
previewPropertyBlock.SetTexture("_OldHeightMap", t.TerrainData.Geometry.HeightMap);
|
|
previewPropertyBlock.SetTexture("_NewHeightMap", newHeightMap);
|
|
previewPropertyBlock.SetTexture("_MainTex", newHeightMap);
|
|
previewPropertyBlock.SetFloat("_Height", t.TerrainData.Geometry.Height);
|
|
previewPropertyBlock.SetVector("_BoundMin", t.transform.position);
|
|
previewPropertyBlock.SetVector("_BoundMax", t.transform.TransformPoint(terrainSize));
|
|
Material mat = GInternalMaterials.GeometryLivePreviewMaterial;
|
|
mat.renderQueue = 4000;
|
|
|
|
Rect[] chunkRects = t.GetChunkRects();
|
|
for (int i = 0; i < chunkRects.Length; ++i)
|
|
{
|
|
if (chunkCulling[i] == false)
|
|
continue;
|
|
Rect r = chunkRects[i];
|
|
Vector3 position = new Vector3(r.x, t.transform.position.y, r.y);
|
|
Quaternion rotation = Quaternion.identity;
|
|
Vector3 scale = new Vector3(r.width, 1, r.height);
|
|
Matrix4x4 trs = Matrix4x4.TRS(position, rotation, scale);
|
|
|
|
Graphics.DrawMesh(
|
|
previewMesh,
|
|
trs,
|
|
mat,
|
|
LayerMask.NameToLayer("Default"),
|
|
cam,
|
|
0,
|
|
previewPropertyBlock,
|
|
ShadowCastingMode.Off,
|
|
false,
|
|
null,
|
|
LightProbeUsage.Off,
|
|
null);
|
|
}
|
|
}
|
|
|
|
public static void DrawSubdivLivePreview(GStylizedTerrain t, Camera cam, Texture newHeightMap, Rect dirtyRect, Texture mask, Matrix4x4 worldPointToMaskMatrix)
|
|
{
|
|
if (t.transform.rotation != Quaternion.identity ||
|
|
t.transform.lossyScale != Vector3.one)
|
|
return;
|
|
|
|
t.TerrainData.Geometry.Internal_CreateNewSubDivisionMap(newHeightMap);
|
|
|
|
int baseResolution = t.TerrainData.Geometry.MeshBaseResolution;
|
|
int resolution = t.TerrainData.Geometry.MeshResolution;
|
|
int maxLevel = baseResolution + Mathf.Min(Mathf.FloorToInt(1f / GCommon.SUB_DIV_STEP), resolution - baseResolution);
|
|
|
|
Vector3 terrainSize = new Vector3(
|
|
t.TerrainData.Geometry.Width,
|
|
t.TerrainData.Geometry.Height,
|
|
t.TerrainData.Geometry.Length);
|
|
previewPropertyBlock.Clear();
|
|
previewPropertyBlock.SetColor("_Color", new Color(0, 0, 0, 0.6f));
|
|
previewPropertyBlock.SetTexture("_HeightMap", newHeightMap);
|
|
previewPropertyBlock.SetVector("_Dimension", terrainSize);
|
|
previewPropertyBlock.SetVector("_BoundMin", t.transform.position);
|
|
previewPropertyBlock.SetVector("_BoundMax", t.transform.TransformPoint(terrainSize));
|
|
previewPropertyBlock.SetTexture("_SubdivMap", t.TerrainData.Geometry.Internal_SubDivisionMap);
|
|
previewPropertyBlock.SetTexture("_Mask", mask);
|
|
previewPropertyBlock.SetMatrix("_WorldPointToMask", worldPointToMaskMatrix);
|
|
|
|
Material mat = GInternalMaterials.SubdivLivePreviewMaterial;
|
|
mat.renderQueue = 4000;
|
|
Mesh previewMesh = null;
|
|
|
|
int gridSize = t.TerrainData.Geometry.ChunkGridSize;
|
|
for (int x = 0; x < gridSize; ++x)
|
|
{
|
|
for (int z = 0; z < gridSize; ++z)
|
|
{
|
|
Rect uvRect = GCommon.GetUvRange(gridSize, x, z);
|
|
if (!uvRect.Overlaps(dirtyRect))
|
|
continue;
|
|
Vector3 localPos = new Vector3(
|
|
terrainSize.x * uvRect.x,
|
|
0f,
|
|
terrainSize.z * uvRect.y);
|
|
Vector3 worldPos = t.transform.TransformPoint(localPos);
|
|
Quaternion rotation = Quaternion.identity;
|
|
Vector3 scale = new Vector3(terrainSize.x * uvRect.width, 1, terrainSize.z * uvRect.height);
|
|
|
|
for (int i = baseResolution; i <= maxLevel; ++i)
|
|
{
|
|
previewMesh = GEditorSettings.Instance.livePreview.GetWireframeMesh(i);
|
|
previewPropertyBlock.SetVector("_SubdivRange", new Vector4(
|
|
(i - baseResolution) * GCommon.SUB_DIV_STEP,
|
|
i != maxLevel ? (i - baseResolution + 1) * GCommon.SUB_DIV_STEP : 1f,
|
|
0, 0));
|
|
|
|
Graphics.DrawMesh(
|
|
previewMesh,
|
|
Matrix4x4.TRS(worldPos, rotation, scale),
|
|
mat,
|
|
LayerMask.NameToLayer("Default"),
|
|
cam,
|
|
0,
|
|
previewPropertyBlock);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void DrawVisibilityLivePreview(GStylizedTerrain t, Camera cam, Texture newHeightMap, Rect dirtyRect, Texture mask, Matrix4x4 worldPointToMaskMatrix)
|
|
{
|
|
if (t.transform.rotation != Quaternion.identity ||
|
|
t.transform.lossyScale != Vector3.one)
|
|
return;
|
|
|
|
t.TerrainData.Geometry.Internal_CreateNewSubDivisionMap(newHeightMap);
|
|
int baseResolution = t.TerrainData.Geometry.MeshBaseResolution;
|
|
int resolution = t.TerrainData.Geometry.MeshResolution;
|
|
int maxLevel = baseResolution + Mathf.Min(Mathf.FloorToInt(1f / GCommon.SUB_DIV_STEP), resolution - baseResolution);
|
|
|
|
Vector3 terrainSize = new Vector3(
|
|
t.TerrainData.Geometry.Width,
|
|
t.TerrainData.Geometry.Height,
|
|
t.TerrainData.Geometry.Length);
|
|
previewPropertyBlock.Clear();
|
|
previewPropertyBlock.SetColor("_Color", new Color(0, 0, 0, 0.6f));
|
|
previewPropertyBlock.SetTexture("_HeightMap", newHeightMap);
|
|
previewPropertyBlock.SetVector("_Dimension", terrainSize);
|
|
previewPropertyBlock.SetVector("_BoundMin", t.transform.position);
|
|
previewPropertyBlock.SetVector("_BoundMax", t.transform.TransformPoint(terrainSize));
|
|
previewPropertyBlock.SetTexture("_SubdivMap", t.TerrainData.Geometry.Internal_SubDivisionMap);
|
|
if (mask == null)
|
|
mask = Texture2D.whiteTexture;
|
|
previewPropertyBlock.SetTexture("_Mask", mask);
|
|
previewPropertyBlock.SetMatrix("_WorldPointToMask", worldPointToMaskMatrix);
|
|
|
|
Material mat = GInternalMaterials.VisibilityLivePreviewMaterial;
|
|
mat.EnableKeyword("USE_MASK");
|
|
mat.renderQueue = 4000;
|
|
Mesh previewMesh = null;
|
|
|
|
int gridSize = t.TerrainData.Geometry.ChunkGridSize;
|
|
for (int x = 0; x < gridSize; ++x)
|
|
{
|
|
for (int z = 0; z < gridSize; ++z)
|
|
{
|
|
Rect uvRect = GCommon.GetUvRange(gridSize, x, z);
|
|
if (!uvRect.Overlaps(dirtyRect))
|
|
continue;
|
|
Vector3 localPos = new Vector3(
|
|
terrainSize.x * uvRect.x,
|
|
0f,
|
|
terrainSize.z * uvRect.y);
|
|
Vector3 worldPos = t.transform.TransformPoint(localPos);
|
|
Quaternion rotation = Quaternion.identity;
|
|
Vector3 scale = new Vector3(terrainSize.x * uvRect.width, 1, terrainSize.z * uvRect.height);
|
|
|
|
for (int i = baseResolution; i <= maxLevel; ++i)
|
|
{
|
|
previewMesh = GEditorSettings.Instance.livePreview.GetWireframeMesh(i);
|
|
previewPropertyBlock.SetVector("_SubdivRange", new Vector4(
|
|
(i - baseResolution) * GCommon.SUB_DIV_STEP,
|
|
i != maxLevel ? (i - baseResolution + 1) * GCommon.SUB_DIV_STEP : 1f,
|
|
0, 0));
|
|
|
|
Graphics.DrawMesh(
|
|
previewMesh,
|
|
Matrix4x4.TRS(worldPos, rotation, scale),
|
|
mat,
|
|
LayerMask.NameToLayer("Default"),
|
|
cam,
|
|
0,
|
|
previewPropertyBlock);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void DrawVisibilityLivePreview(GStylizedTerrain t, Camera cam, Texture newHeightMap, bool[] chunkCulling, Texture mask, Matrix4x4 worldPointToMaskMatrix)
|
|
{
|
|
if (t.transform.rotation != Quaternion.identity ||
|
|
t.transform.lossyScale != Vector3.one)
|
|
return;
|
|
|
|
t.TerrainData.Geometry.Internal_CreateNewSubDivisionMap(newHeightMap);
|
|
int baseResolution = t.TerrainData.Geometry.MeshBaseResolution;
|
|
int resolution = t.TerrainData.Geometry.MeshResolution;
|
|
int maxLevel = baseResolution + Mathf.Min(Mathf.FloorToInt(1f / GCommon.SUB_DIV_STEP), resolution - baseResolution);
|
|
|
|
Vector3 terrainSize = new Vector3(
|
|
t.TerrainData.Geometry.Width,
|
|
t.TerrainData.Geometry.Height,
|
|
t.TerrainData.Geometry.Length);
|
|
previewPropertyBlock.Clear();
|
|
previewPropertyBlock.SetColor("_Color", new Color(0, 0, 0, 0.6f));
|
|
previewPropertyBlock.SetTexture("_HeightMap", newHeightMap);
|
|
previewPropertyBlock.SetVector("_Dimension", terrainSize);
|
|
previewPropertyBlock.SetVector("_BoundMin", t.transform.position);
|
|
previewPropertyBlock.SetVector("_BoundMax", t.transform.TransformPoint(terrainSize));
|
|
previewPropertyBlock.SetTexture("_SubdivMap", t.TerrainData.Geometry.Internal_SubDivisionMap);
|
|
if (mask == null)
|
|
mask = Texture2D.whiteTexture;
|
|
previewPropertyBlock.SetTexture("_Mask", mask);
|
|
previewPropertyBlock.SetMatrix("_WorldPointToMask", worldPointToMaskMatrix);
|
|
|
|
Material mat = GInternalMaterials.VisibilityLivePreviewMaterial;
|
|
mat.EnableKeyword("USE_MASK");
|
|
mat.renderQueue = 4000;
|
|
Mesh previewMesh = null;
|
|
|
|
Rect[] chunkRects = t.GetChunkRects();
|
|
for (int i = 0; i < chunkRects.Length; ++i)
|
|
{
|
|
if (chunkCulling[i] == false)
|
|
continue;
|
|
Rect r = chunkRects[i];
|
|
Vector3 position = new Vector3(r.x, t.transform.position.y, r.y);
|
|
Quaternion rotation = Quaternion.identity;
|
|
Vector3 scale = new Vector3(r.width, 1, r.height);
|
|
Matrix4x4 trs = Matrix4x4.TRS(position, rotation, scale);
|
|
|
|
for (int res = baseResolution; res <= maxLevel; ++res)
|
|
{
|
|
previewMesh = GEditorSettings.Instance.livePreview.GetWireframeMesh(res);
|
|
previewPropertyBlock.SetVector("_SubdivRange", new Vector4(
|
|
(res - baseResolution) * GCommon.SUB_DIV_STEP,
|
|
res != maxLevel ? (res - baseResolution + 1) * GCommon.SUB_DIV_STEP : 1f,
|
|
0, 0));
|
|
|
|
Graphics.DrawMesh(
|
|
previewMesh,
|
|
trs,
|
|
mat,
|
|
LayerMask.NameToLayer("Default"),
|
|
cam,
|
|
0,
|
|
previewPropertyBlock,
|
|
ShadowCastingMode.Off,
|
|
false,
|
|
null,
|
|
LightProbeUsage.Off,
|
|
null);
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void DrawVisibilityLivePreview(GStylizedTerrain t, Camera cam, Texture newHeightMap, Rect dirtyRect)
|
|
{
|
|
if (t.transform.rotation != Quaternion.identity ||
|
|
t.transform.lossyScale != Vector3.one)
|
|
return;
|
|
|
|
t.TerrainData.Geometry.Internal_CreateNewSubDivisionMap(newHeightMap);
|
|
int baseResolution = t.TerrainData.Geometry.MeshBaseResolution;
|
|
int resolution = t.TerrainData.Geometry.MeshResolution;
|
|
int maxLevel = baseResolution + Mathf.Min(Mathf.FloorToInt(1f / GCommon.SUB_DIV_STEP), resolution - baseResolution);
|
|
|
|
Vector3 terrainSize = new Vector3(
|
|
t.TerrainData.Geometry.Width,
|
|
t.TerrainData.Geometry.Height,
|
|
t.TerrainData.Geometry.Length);
|
|
previewPropertyBlock.Clear();
|
|
previewPropertyBlock.SetColor("_Color", new Color(0, 0, 0, 0.6f));
|
|
previewPropertyBlock.SetTexture("_HeightMap", newHeightMap);
|
|
previewPropertyBlock.SetVector("_Dimension", terrainSize);
|
|
previewPropertyBlock.SetVector("_BoundMin", t.transform.position);
|
|
previewPropertyBlock.SetVector("_BoundMax", t.transform.TransformPoint(terrainSize));
|
|
previewPropertyBlock.SetTexture("_SubdivMap", t.TerrainData.Geometry.Internal_SubDivisionMap);
|
|
|
|
Material mat = GInternalMaterials.VisibilityLivePreviewMaterial;
|
|
mat.DisableKeyword("USE_MASK");
|
|
mat.renderQueue = 4000;
|
|
Mesh previewMesh = null;
|
|
|
|
int gridSize = t.TerrainData.Geometry.ChunkGridSize;
|
|
for (int x = 0; x < gridSize; ++x)
|
|
{
|
|
for (int z = 0; z < gridSize; ++z)
|
|
{
|
|
Rect uvRect = GCommon.GetUvRange(gridSize, x, z);
|
|
if (!uvRect.Overlaps(dirtyRect))
|
|
continue;
|
|
Vector3 localPos = new Vector3(
|
|
terrainSize.x * uvRect.x,
|
|
0f,
|
|
terrainSize.z * uvRect.y);
|
|
Vector3 worldPos = t.transform.TransformPoint(localPos);
|
|
Quaternion rotation = Quaternion.identity;
|
|
Vector3 scale = new Vector3(terrainSize.x * uvRect.width, 1, terrainSize.z * uvRect.height);
|
|
|
|
for (int i = baseResolution; i <= maxLevel; ++i)
|
|
{
|
|
previewMesh = GEditorSettings.Instance.livePreview.GetWireframeMesh(i);
|
|
previewPropertyBlock.SetVector("_SubdivRange", new Vector4(
|
|
(i - baseResolution) * GCommon.SUB_DIV_STEP,
|
|
i != maxLevel ? (i - baseResolution + 1) * GCommon.SUB_DIV_STEP : 1f,
|
|
0, 0));
|
|
|
|
Graphics.DrawMesh(
|
|
previewMesh,
|
|
Matrix4x4.TRS(worldPos, rotation, scale),
|
|
mat,
|
|
LayerMask.NameToLayer("Default"),
|
|
cam,
|
|
0,
|
|
previewPropertyBlock);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void DrawAlbedoLivePreview(GStylizedTerrain t, Camera cam, Texture newAlbedo, Rect dirtyRect)
|
|
{
|
|
Material mat = t.TerrainData.Shading.MaterialToRender;
|
|
if (mat == null)
|
|
return;
|
|
|
|
previewPropertyBlock.Clear();
|
|
if (!string.IsNullOrEmpty(t.TerrainData.Shading.AlbedoMapPropertyName))
|
|
{
|
|
previewPropertyBlock.SetTexture(t.TerrainData.Shading.AlbedoMapPropertyName, newAlbedo);
|
|
}
|
|
|
|
GTerrainChunk[] chunks = t.GetChunks();
|
|
for (int i = 0; i < chunks.Length; ++i)
|
|
{
|
|
Rect uvRange = chunks[i].GetUvRange();
|
|
if (uvRange.Overlaps(dirtyRect))
|
|
{
|
|
Mesh chunkMesh = chunks[i].GetMesh(0);
|
|
if (chunkMesh != null)
|
|
{
|
|
Graphics.DrawMesh(
|
|
chunkMesh,
|
|
chunks[i].transform.localToWorldMatrix * Matrix4x4.Translate(Vector3.up * 0.01f),
|
|
mat,
|
|
chunks[i].gameObject.layer,
|
|
cam,
|
|
0,
|
|
previewPropertyBlock,
|
|
t.TerrainData.Rendering.CastShadow,
|
|
t.TerrainData.Rendering.ReceiveShadow);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void DrawMetallicSmoothnessLivePreview(GStylizedTerrain t, Camera cam, Texture newMetallicMap, Rect dirtyRect)
|
|
{
|
|
Material mat = t.TerrainData.Shading.MaterialToRender;
|
|
if (mat == null)
|
|
return;
|
|
|
|
previewPropertyBlock.Clear();
|
|
if (!string.IsNullOrEmpty(t.TerrainData.Shading.MetallicMapPropertyName))
|
|
{
|
|
previewPropertyBlock.SetTexture(t.TerrainData.Shading.MetallicMapPropertyName, newMetallicMap);
|
|
}
|
|
|
|
GTerrainChunk[] chunks = t.GetChunks();
|
|
for (int i = 0; i < chunks.Length; ++i)
|
|
{
|
|
Rect uvRange = chunks[i].GetUvRange();
|
|
if (uvRange.Overlaps(dirtyRect))
|
|
{
|
|
Mesh chunkMesh = chunks[i].GetMesh(0);
|
|
if (chunkMesh != null)
|
|
{
|
|
Graphics.DrawMesh(
|
|
chunkMesh,
|
|
chunks[i].transform.localToWorldMatrix * Matrix4x4.Translate(Vector3.up * 0.01f),
|
|
mat,
|
|
chunks[i].gameObject.layer,
|
|
cam,
|
|
0,
|
|
previewPropertyBlock,
|
|
t.TerrainData.Rendering.CastShadow,
|
|
t.TerrainData.Rendering.ReceiveShadow);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void DrawAMSLivePreview(GStylizedTerrain t, Camera cam, Texture newAlbedo, Texture newMetallicMap, Rect dirtyRect)
|
|
{
|
|
Material mat = t.TerrainData.Shading.MaterialToRender;
|
|
if (mat == null)
|
|
return;
|
|
|
|
previewPropertyBlock.Clear();
|
|
if (!string.IsNullOrEmpty(t.TerrainData.Shading.AlbedoMapPropertyName))
|
|
{
|
|
previewPropertyBlock.SetTexture(t.TerrainData.Shading.AlbedoMapPropertyName, newAlbedo);
|
|
}
|
|
if (!string.IsNullOrEmpty(t.TerrainData.Shading.MetallicMapPropertyName))
|
|
{
|
|
previewPropertyBlock.SetTexture(t.TerrainData.Shading.MetallicMapPropertyName, newMetallicMap);
|
|
}
|
|
|
|
|
|
GTerrainChunk[] chunks = t.GetChunks();
|
|
for (int i = 0; i < chunks.Length; ++i)
|
|
{
|
|
Rect uvRange = chunks[i].GetUvRange();
|
|
if (uvRange.Overlaps(dirtyRect))
|
|
{
|
|
|
|
Mesh chunkMesh = chunks[i].GetMesh(0);
|
|
if (chunkMesh != null)
|
|
{
|
|
Graphics.DrawMesh(
|
|
chunkMesh,
|
|
chunks[i].transform.localToWorldMatrix * Matrix4x4.Translate(Vector3.up * 0.01f),
|
|
mat,
|
|
chunks[i].gameObject.layer,
|
|
cam,
|
|
0,
|
|
previewPropertyBlock,
|
|
t.TerrainData.Rendering.CastShadow,
|
|
t.TerrainData.Rendering.ReceiveShadow);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void DrawAMSLivePreview(GStylizedTerrain t, Camera cam, Texture newAlbedo, Texture newMetallicMap, bool[] chunkCulling)
|
|
{
|
|
Material mat = t.TerrainData.Shading.MaterialToRender;
|
|
if (mat == null)
|
|
return;
|
|
|
|
previewPropertyBlock.Clear();
|
|
if (!string.IsNullOrEmpty(t.TerrainData.Shading.AlbedoMapPropertyName))
|
|
{
|
|
previewPropertyBlock.SetTexture(t.TerrainData.Shading.AlbedoMapPropertyName, newAlbedo);
|
|
}
|
|
if (!string.IsNullOrEmpty(t.TerrainData.Shading.MetallicMapPropertyName))
|
|
{
|
|
previewPropertyBlock.SetTexture(t.TerrainData.Shading.MetallicMapPropertyName, newMetallicMap);
|
|
}
|
|
|
|
int gridSize = t.TerrainData.Geometry.ChunkGridSize;
|
|
GTerrainChunk[] chunks = t.GetChunks();
|
|
for (int i = 0; i < chunks.Length; ++i)
|
|
{
|
|
int chunkIndex = GUtilities.To1DIndex((int)chunks[i].Index.x, (int)chunks[i].Index.y, gridSize);
|
|
if (chunkCulling[chunkIndex] == false)
|
|
continue;
|
|
|
|
Graphics.DrawMesh(
|
|
chunks[i].GetMesh(0),
|
|
chunks[i].transform.localToWorldMatrix * Matrix4x4.Translate(Vector3.up * 0.01f),
|
|
mat,
|
|
LayerMask.NameToLayer("Default"),
|
|
cam,
|
|
0,
|
|
previewPropertyBlock,
|
|
ShadowCastingMode.Off,
|
|
false,
|
|
null,
|
|
LightProbeUsage.Off,
|
|
null);
|
|
}
|
|
}
|
|
|
|
public static void DrawSplatLivePreview(GStylizedTerrain t, Camera cam, Texture[] newControlMaps, Rect dirtyRect)
|
|
{
|
|
Material mat = t.TerrainData.Shading.MaterialToRender;
|
|
if (mat == null)
|
|
return;
|
|
int controlMapResolution = t.TerrainData.Shading.SplatControlResolution;
|
|
int controlMapCount = t.TerrainData.Shading.SplatControlMapCount;
|
|
if (controlMapCount == 0)
|
|
return;
|
|
|
|
previewPropertyBlock.Clear();
|
|
for (int i = 0; i < controlMapCount; ++i)
|
|
{
|
|
if (!string.IsNullOrEmpty(t.TerrainData.Shading.SplatControlMapPropertyName))
|
|
{
|
|
previewPropertyBlock.SetTexture(t.TerrainData.Shading.SplatControlMapPropertyName + i, newControlMaps[i] ?? Texture2D.blackTexture);
|
|
}
|
|
}
|
|
|
|
GTerrainChunk[] chunks = t.GetChunks();
|
|
for (int i = 0; i < chunks.Length; ++i)
|
|
{
|
|
Rect uvRange = chunks[i].GetUvRange();
|
|
if (uvRange.Overlaps(dirtyRect))
|
|
{
|
|
Mesh chunkMesh = chunks[i].GetMesh(0);
|
|
if (chunkMesh != null)
|
|
{
|
|
Graphics.DrawMesh(
|
|
chunkMesh,
|
|
chunks[i].transform.localToWorldMatrix * Matrix4x4.Translate(Vector3.up * 0.01f),
|
|
mat,
|
|
chunks[i].gameObject.layer,
|
|
cam,
|
|
0,
|
|
previewPropertyBlock,
|
|
t.TerrainData.Rendering.CastShadow,
|
|
t.TerrainData.Rendering.ReceiveShadow);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public static void DrawSplatLivePreview(GStylizedTerrain t, Camera cam, Texture[] newControlMaps, bool[] chunkCulling)
|
|
{
|
|
Material mat = t.TerrainData.Shading.MaterialToRender;
|
|
if (mat == null)
|
|
return;
|
|
int controlMapCount = t.TerrainData.Shading.SplatControlMapCount;
|
|
if (controlMapCount == 0)
|
|
return;
|
|
|
|
previewPropertyBlock.Clear();
|
|
for (int i = 0; i < controlMapCount; ++i)
|
|
{
|
|
if (!string.IsNullOrEmpty(t.TerrainData.Shading.SplatControlMapPropertyName))
|
|
{
|
|
previewPropertyBlock.SetTexture(t.TerrainData.Shading.SplatControlMapPropertyName + i, newControlMaps[i] ?? Texture2D.blackTexture);
|
|
}
|
|
}
|
|
|
|
int gridSize = t.TerrainData.Geometry.ChunkGridSize;
|
|
GTerrainChunk[] chunks = t.GetChunks();
|
|
for (int i = 0; i < chunks.Length; ++i)
|
|
{
|
|
int chunkIndex = GUtilities.To1DIndex((int)chunks[i].Index.x, (int)chunks[i].Index.y, gridSize);
|
|
if (chunkCulling[chunkIndex] == false)
|
|
continue;
|
|
|
|
Graphics.DrawMesh(
|
|
chunks[i].GetMesh(0),
|
|
chunks[i].transform.localToWorldMatrix * Matrix4x4.Translate(Vector3.up * 0.01f),
|
|
mat,
|
|
LayerMask.NameToLayer("Default"),
|
|
cam,
|
|
0,
|
|
previewPropertyBlock,
|
|
ShadowCastingMode.Off,
|
|
false,
|
|
null,
|
|
LightProbeUsage.Off,
|
|
null);
|
|
}
|
|
}
|
|
|
|
public static void DrawMasksLivePreview(GStylizedTerrain t, Camera cam, Texture[] masks, Color[] colors, Rect dirtyRect, int channel = 0)
|
|
{
|
|
Material mat = GInternalMaterials.MaskVisualizerMaterial;
|
|
if (mat == null)
|
|
return;
|
|
|
|
previewPropertyBlock.Clear();
|
|
previewPropertyBlock.SetVector("_Dimension", new Vector4(t.TerrainData.Geometry.Width, t.TerrainData.Geometry.Height, t.TerrainData.Geometry.Length));
|
|
|
|
GTerrainChunk[] chunks = t.GetChunks();
|
|
for (int i = 0; i < chunks.Length; ++i)
|
|
{
|
|
Rect uvRange = chunks[i].GetUvRange();
|
|
if (uvRange.Overlaps(dirtyRect))
|
|
{
|
|
Mesh chunkMesh = chunks[i].GetMesh(0);
|
|
if (chunkMesh != null)
|
|
{
|
|
for (int j = 0; j < masks.Length; ++j)
|
|
{
|
|
previewPropertyBlock.SetColor("_Color", colors[j]);
|
|
previewPropertyBlock.SetTexture("_MainTex", masks[j]);
|
|
previewPropertyBlock.SetInt("_Channel", channel);
|
|
Graphics.DrawMesh(
|
|
chunkMesh,
|
|
chunks[i].transform.localToWorldMatrix * Matrix4x4.Translate(Vector3.up * 0.05f * j),
|
|
mat,
|
|
chunks[i].gameObject.layer,
|
|
cam,
|
|
0,
|
|
previewPropertyBlock,
|
|
t.TerrainData.Rendering.CastShadow,
|
|
t.TerrainData.Rendering.ReceiveShadow);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public static void DrawMasksLivePreview(GStylizedTerrain t, Camera cam, Texture[] masks, Color[] colors, bool[] chunkCulling, int channel = 0)
|
|
{
|
|
Material mat = GInternalMaterials.MaskVisualizerMaterial;
|
|
if (mat == null)
|
|
return;
|
|
|
|
previewPropertyBlock.Clear();
|
|
previewPropertyBlock.SetVector("_Dimension", new Vector4(t.TerrainData.Geometry.Width, t.TerrainData.Geometry.Height, t.TerrainData.Geometry.Length));
|
|
|
|
int gridSize = t.TerrainData.Geometry.ChunkGridSize;
|
|
GTerrainChunk[] chunks = t.GetChunks();
|
|
for (int i = 0; i < chunks.Length; ++i)
|
|
{
|
|
int chunkIndex = GUtilities.To1DIndex((int)chunks[i].Index.x, (int)chunks[i].Index.y, gridSize);
|
|
if (chunkCulling[chunkIndex] == false)
|
|
continue;
|
|
Mesh chunkMesh = chunks[i].GetMesh(0);
|
|
for (int j = 0; j < masks.Length; ++j)
|
|
{
|
|
previewPropertyBlock.SetColor("_Color", colors[j]);
|
|
previewPropertyBlock.SetTexture("_MainTex", masks[j]);
|
|
previewPropertyBlock.SetInt("_Channel", channel);
|
|
Graphics.DrawMesh(
|
|
chunkMesh,
|
|
chunks[i].transform.localToWorldMatrix * Matrix4x4.Translate(Vector3.up * 0.05f * j),
|
|
mat,
|
|
chunks[i].gameObject.layer,
|
|
cam,
|
|
0,
|
|
previewPropertyBlock,
|
|
t.TerrainData.Rendering.CastShadow,
|
|
t.TerrainData.Rendering.ReceiveShadow);
|
|
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void DrawTerrainMask(GStylizedTerrain t, Camera cam)
|
|
{
|
|
if (t.TerrainData == null)
|
|
return;
|
|
GLivePreviewDrawer.DrawMasksLivePreview(
|
|
t, cam,
|
|
new Texture[] { t.TerrainData.Mask.MaskMapOrDefault },
|
|
new Color[] { Color.red },
|
|
GCommon.UnitRect);
|
|
}
|
|
|
|
public static void DrawMask4ChannelsLivePreview(GStylizedTerrain t, Camera cam, Texture masks, Rect dirtyRect)
|
|
{
|
|
Material mat = GInternalMaterials.Mask4ChannelsMaterial;
|
|
if (mat == null)
|
|
return;
|
|
|
|
previewPropertyBlock.Clear();
|
|
GTerrainChunk[] chunks = t.GetChunks();
|
|
for (int i = 0; i < chunks.Length; ++i)
|
|
{
|
|
Rect uvRange = chunks[i].GetUvRange();
|
|
if (uvRange.Overlaps(dirtyRect))
|
|
{
|
|
Mesh chunkMesh = chunks[i].GetMesh(0);
|
|
if (chunkMesh != null)
|
|
{
|
|
previewPropertyBlock.SetTexture("_MainTex", masks);
|
|
Graphics.DrawMesh(
|
|
chunkMesh,
|
|
chunks[i].transform.localToWorldMatrix * Matrix4x4.Translate(Vector3.up * 0.05f),
|
|
mat,
|
|
chunks[i].gameObject.layer,
|
|
cam,
|
|
0,
|
|
previewPropertyBlock,
|
|
t.TerrainData.Rendering.CastShadow,
|
|
t.TerrainData.Rendering.ReceiveShadow);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
#endif
|
|
#endif
|