GitHub
6 年前
当前提交
4312d844
共有 40 个文件被更改,包括 432 次插入 和 452 次删除
-
166com.unity.render-pipelines.high-definition/HDRP/Editor/AssetProcessors/NormalMapAverageLengthTexturePostprocessor.cs
-
53com.unity.render-pipelines.high-definition/HDRP/Editor/BuildProcessors/HDRPPreprocessBuild.cs
-
2com.unity.render-pipelines.high-definition/HDRP/Editor/BuildProcessors/HDRPreprocessShaders.cs
-
3com.unity.render-pipelines.high-definition/HDRP/Editor/Camera/HDAdditionalCameraEditor.cs
-
2com.unity.render-pipelines.high-definition/HDRP/Editor/Camera/HDCameraEditor.Handlers.cs
-
4com.unity.render-pipelines.high-definition/HDRP/Editor/Camera/HDCameraEditor.cs
-
2com.unity.render-pipelines.high-definition/HDRP/Editor/Camera/HDCameraUI.cs
-
2com.unity.render-pipelines.high-definition/HDRP/Editor/Camera/SerializedHDCamera.cs
-
280com.unity.render-pipelines.high-definition/HDRP/Editor/Lighting/Reflection/HDCubemapInspector.cs
-
2com.unity.render-pipelines.high-definition/HDRP/Editor/Lighting/Reflection/HDReflectionProbeEditor.Gizmos.cs
-
3com.unity.render-pipelines.high-definition/HDRP/Editor/Lighting/Reflection/HDReflectionProbeEditor.Handles.cs
-
2com.unity.render-pipelines.high-definition/HDRP/Editor/Lighting/Reflection/HDReflectionProbeEditor.Preview.cs
-
6com.unity.render-pipelines.high-definition/HDRP/Editor/Lighting/Reflection/HDReflectionProbeEditor.ProbeUtility.cs
-
2com.unity.render-pipelines.high-definition/HDRP/Editor/Lighting/Reflection/HDReflectionProbeEditor.Skin.cs
-
2com.unity.render-pipelines.high-definition/HDRP/Editor/Lighting/Reflection/HDReflectionProbeEditor.cs
-
8com.unity.render-pipelines.high-definition/HDRP/Editor/Lighting/Reflection/HDReflectionProbeEditorUtility.cs
-
3com.unity.render-pipelines.high-definition/HDRP/Editor/Lighting/Reflection/HDReflectionProbeUI.Drawers.cs
-
2com.unity.render-pipelines.high-definition/HDRP/Editor/Lighting/Reflection/HDReflectionProbeUI.cs
-
2com.unity.render-pipelines.high-definition/HDRP/Editor/Lighting/Reflection/ScreenSpaceRefractionEditor.cs
-
2com.unity.render-pipelines.high-definition/HDRP/Editor/Lighting/Reflection/SerializedHDReflectionProbe.cs
-
2com.unity.render-pipelines.high-definition/HDRP/Editor/RenderPipeline/BaseUI.cs
-
2com.unity.render-pipelines.high-definition/HDRP/Editor/RenderPipeline/HDRenderPipelineUI.cs
-
2com.unity.render-pipelines.high-definition/HDRP/Editor/RenderPipeline/Settings/FrameSettingsUI.cs
-
4com.unity.render-pipelines.high-definition/HDRP/Editor/RenderPipeline/Settings/GlobalDecalSettingsUI.cs
-
2com.unity.render-pipelines.high-definition/HDRP/Editor/RenderPipeline/Settings/GlobalLightLoopSettingsUI.cs
-
2com.unity.render-pipelines.high-definition/HDRP/Editor/RenderPipeline/Settings/LightLoopSettingsUI.cs
-
2com.unity.render-pipelines.high-definition/HDRP/Editor/RenderPipeline/Settings/RenderPipelineSettingsUI.cs
-
2com.unity.render-pipelines.high-definition/HDRP/Editor/RenderPipeline/Settings/SerializedFrameSettings.cs
-
2com.unity.render-pipelines.high-definition/HDRP/Editor/RenderPipeline/Settings/SerializedGlobalDecalSettings.cs
-
2com.unity.render-pipelines.high-definition/HDRP/Editor/RenderPipeline/Settings/SerializedGlobalLightLoopSettings.cs
-
2com.unity.render-pipelines.high-definition/HDRP/Editor/RenderPipeline/Settings/SerializedHDRenderPipelineAsset.cs
-
2com.unity.render-pipelines.high-definition/HDRP/Editor/RenderPipeline/Settings/SerializedLightLoopSettings.cs
-
2com.unity.render-pipelines.high-definition/HDRP/Editor/RenderPipeline/Settings/SerializedRenderPipelineSettings.cs
-
2com.unity.render-pipelines.high-definition/HDRP/Editor/RenderPipeline/Settings/SerializedShadowInitParameters.cs
-
5com.unity.render-pipelines.high-definition/HDRP/Editor/RenderPipeline/Settings/ShadowInitParametersUI.cs
-
2com.unity.render-pipelines.high-definition/HDRP/Editor/Shadows/HDShadowSettingsEditor.cs
-
2com.unity.render-pipelines.high-definition/HDRP/Editor/Sky/HDRISky/HDRISkyEditor.cs
-
230com.unity.render-pipelines.high-definition/HDRP/Lighting/SphericalHarmonics.cs
-
64com.unity.render-pipelines.high-definition/HDRP/RenderPipeline/SceneViewDrawMode.cs
-
3com.unity.render-pipelines.high-definition/HDRP/RenderPipeline/Texture2DAtlas.cs
|
|||
using System; |
|||
using UnityEditor; |
|||
public class NormalMapAverageLengthTexturePostprocessor : AssetPostprocessor |
|||
namespace UnityEditor.Experimental.Rendering.HDPipeline |
|||
// This class will process a normal map and add the value of average normal length to the blue or alpha channel
|
|||
// The texture is save as BC7.
|
|||
// Tangent space normal map: BC7 RGB (normal xy - average normal length)
|
|||
// Object space normal map: BC7 RGBA (normal xyz - average normal length)
|
|||
static string s_Suffix = "_NA"; |
|||
//static string s_SuffixOS = "_OSNA"; // Suffix for object space case - TODO
|
|||
public class NormalMapAverageLengthTexturePostprocessor : AssetPostprocessor |
|||
{ |
|||
// This class will process a normal map and add the value of average normal length to the blue or alpha channel
|
|||
// The texture is save as BC7.
|
|||
// Tangent space normal map: BC7 RGB (normal xy - average normal length)
|
|||
// Object space normal map: BC7 RGBA (normal xyz - average normal length)
|
|||
static string s_Suffix = "_NA"; |
|||
//static string s_SuffixOS = "_OSNA"; // Suffix for object space case - TODO
|
|||
void OnPreprocessTexture() |
|||
{ |
|||
// Any texture with _NA suffix will store average normal lenght in alpha
|
|||
if (Path.GetFileNameWithoutExtension(assetPath).EndsWith(s_Suffix, StringComparison.InvariantCultureIgnoreCase)) |
|||
void OnPreprocessTexture() |
|||
// Make sure we don't convert as a normal map.
|
|||
TextureImporter textureImporter = (TextureImporter)assetImporter; |
|||
textureImporter.convertToNormalmap = false; |
|||
textureImporter.alphaSource = TextureImporterAlphaSource.None; |
|||
textureImporter.mipmapEnabled = true; |
|||
textureImporter.textureCompression = TextureImporterCompression.CompressedHQ; // This is BC7 for Mac/PC
|
|||
// Any texture with _NA suffix will store average normal lenght in alpha
|
|||
if (Path.GetFileNameWithoutExtension(assetPath).EndsWith(s_Suffix, StringComparison.InvariantCultureIgnoreCase)) |
|||
{ |
|||
// Make sure we don't convert as a normal map.
|
|||
TextureImporter textureImporter = (TextureImporter)assetImporter; |
|||
textureImporter.convertToNormalmap = false; |
|||
textureImporter.alphaSource = TextureImporterAlphaSource.None; |
|||
textureImporter.mipmapEnabled = true; |
|||
textureImporter.textureCompression = TextureImporterCompression.CompressedHQ; // This is BC7 for Mac/PC
|
|||
textureImporter.linearTexture = true; // Says deprecated but won't work without it.
|
|||
textureImporter.linearTexture = true; // Says deprecated but won't work without it.
|
|||
textureImporter.sRGBTexture = false; // But we're setting the new property just in case it changes later...
|
|||
textureImporter.sRGBTexture = false; // But we're setting the new property just in case it changes later...
|
|||
} |
|||
} |
|||
private static Color GetColor(Color[] source, int x, int y, int width, int height) |
|||
{ |
|||
x = (x + width) % width; |
|||
y = (y + height) % height; |
|||
private static Color GetColor(Color[] source, int x, int y, int width, int height) |
|||
{ |
|||
x = (x + width) % width; |
|||
y = (y + height) % height; |
|||
int index = y * width + x; |
|||
var c = source[index]; |
|||
int index = y * width + x; |
|||
var c = source[index]; |
|||
return c; |
|||
} |
|||
return c; |
|||
} |
|||
private static Vector3 GetNormal(Color[] source, int x, int y, int width, int height) |
|||
{ |
|||
Vector3 n = (Vector4)GetColor(source, x, y, width, height); |
|||
n = 2.0f * n - Vector3.one; |
|||
n.Normalize(); |
|||
private static Vector3 GetNormal(Color[] source, int x, int y, int width, int height) |
|||
{ |
|||
Vector3 n = (Vector4)GetColor(source, x, y, width, height); |
|||
n = 2.0f * n - Vector3.one; |
|||
n.Normalize(); |
|||
return n; |
|||
} |
|||
|
|||
private static Vector3 GetAverageNormal(Color[] source, int x, int y, int width, int height, int texelFootprint) |
|||
{ |
|||
Vector3 averageNormal = new Vector3(0, 0, 0); |
|||
return n; |
|||
} |
|||
// Calculate the average color over the texel footprint.
|
|||
for (int i = 0; i < texelFootprint; ++i) |
|||
private static Vector3 GetAverageNormal(Color[] source, int x, int y, int width, int height, int texelFootprint) |
|||
for (int j = 0; j < texelFootprint; ++j) |
|||
Vector3 averageNormal = new Vector3(0, 0, 0); |
|||
|
|||
// Calculate the average color over the texel footprint.
|
|||
for (int i = 0; i < texelFootprint; ++i) |
|||
averageNormal += GetNormal(source, x + i, y + j, width, height); |
|||
for (int j = 0; j < texelFootprint; ++j) |
|||
{ |
|||
averageNormal += GetNormal(source, x + i, y + j, width, height); |
|||
} |
|||
} |
|||
averageNormal /= (texelFootprint * texelFootprint); |
|||
averageNormal /= (texelFootprint * texelFootprint); |
|||
return averageNormal; |
|||
} |
|||
return averageNormal; |
|||
} |
|||
void OnPostprocessTexture(Texture2D texture) |
|||
{ |
|||
if (Path.GetFileNameWithoutExtension(assetPath).EndsWith(s_Suffix, StringComparison.InvariantCultureIgnoreCase)) |
|||
void OnPostprocessTexture(Texture2D texture) |
|||
// Based on The Order : 1886 SIGGRAPH course notes implementation. Sample all normal map
|
|||
// texels from the base mip level that are within the footprint of the current mipmap texel.
|
|||
Color[] source = texture.GetPixels(0); |
|||
for (int m = 1; m < texture.mipmapCount; m++) |
|||
if (Path.GetFileNameWithoutExtension(assetPath).EndsWith(s_Suffix, StringComparison.InvariantCultureIgnoreCase)) |
|||
Color[] c = texture.GetPixels(m); |
|||
// Based on The Order : 1886 SIGGRAPH course notes implementation. Sample all normal map
|
|||
// texels from the base mip level that are within the footprint of the current mipmap texel.
|
|||
Color[] source = texture.GetPixels(0); |
|||
for (int m = 1; m < texture.mipmapCount; m++) |
|||
{ |
|||
Color[] c = texture.GetPixels(m); |
|||
int mipWidth = Math.Max(1, texture.width >> m); |
|||
int mipHeight = Math.Max(1, texture.height >> m); |
|||
int mipWidth = Math.Max(1, texture.width >> m); |
|||
int mipHeight = Math.Max(1, texture.height >> m); |
|||
for (int x = 0; x < mipWidth; ++x) |
|||
{ |
|||
for (int y = 0; y < mipHeight; ++y) |
|||
for (int x = 0; x < mipWidth; ++x) |
|||
int texelFootprint = 1 << m; |
|||
Vector3 averageNormal = GetAverageNormal(source, x * texelFootprint, y * texelFootprint, |
|||
texture.width, texture.height, texelFootprint); |
|||
for (int y = 0; y < mipHeight; ++y) |
|||
{ |
|||
int texelFootprint = 1 << m; |
|||
Vector3 averageNormal = GetAverageNormal(source, x * texelFootprint, y * texelFootprint, |
|||
texture.width, texture.height, texelFootprint); |
|||
// Store the normal length for the average normal.
|
|||
int outputPosition = y * mipWidth + x; |
|||
// Store the normal length for the average normal.
|
|||
int outputPosition = y * mipWidth + x; |
|||
// Clamp to avoid any issue (TODO: Check this)
|
|||
// Write into the blue channel
|
|||
float averageNormalLength = Math.Max(0.0f, Math.Min(1.0f, averageNormal.magnitude)); |
|||
// Clamp to avoid any issue (TODO: Check this)
|
|||
// Write into the blue channel
|
|||
float averageNormalLength = Math.Max(0.0f, Math.Min(1.0f, averageNormal.magnitude)); |
|||
c[outputPosition].b = averageNormalLength; |
|||
c[outputPosition].a = 1.0f; |
|||
c[outputPosition].b = averageNormalLength; |
|||
c[outputPosition].a = 1.0f; |
|||
} |
|||
|
|||
texture.SetPixels(c, m); |
|||
texture.SetPixels(c, m); |
|||
} |
|||
|
|||
// Now overwrite the first mip average normal channel - order is important as above we read the mip0
|
|||
// For mip 0, set the normal length to 1.
|
|||
{ |
|||
Color[] c = texture.GetPixels(0); |
|||
for (int i = 0; i < c.Length; i++) |
|||
// Now overwrite the first mip average normal channel - order is important as above we read the mip0
|
|||
// For mip 0, set the normal length to 1.
|
|||
c[i].b = 1.0f; |
|||
c[i].a = 1.0f; |
|||
Color[] c = texture.GetPixels(0); |
|||
for (int i = 0; i < c.Length; i++) |
|||
{ |
|||
c[i].b = 1.0f; |
|||
c[i].a = 1.0f; |
|||
} |
|||
texture.SetPixels(c, 0); |
|||
texture.SetPixels(c, 0); |
|||
} |
|||
} |
|||
} |
|
|||
using UnityEditor; |
|||
using UnityEngine; |
|||
class HDRPPreprocessBuild : IPreprocessBuildWithReport |
|||
namespace UnityEditor.Experimental.Rendering.HDPipeline |
|||
public int callbackOrder { get { return 0; } } |
|||
class HDRPPreprocessBuild : IPreprocessBuildWithReport |
|||
{ |
|||
public int callbackOrder { get { return 0; } } |
|||
public void OnPreprocessBuild(BuildReport report) |
|||
{ |
|||
// Don't execute the preprocess if we are not HDRenderPipeline
|
|||
HDRenderPipeline hdrp = RenderPipelineManager.currentPipeline as HDRenderPipeline; |
|||
if (hdrp == null) |
|||
return; |
|||
public void OnPreprocessBuild(BuildReport report) |
|||
{ |
|||
// Don't execute the preprocess if we are not HDRenderPipeline
|
|||
HDRenderPipeline hdrp = RenderPipelineManager.currentPipeline as HDRenderPipeline; |
|||
if (hdrp == null) |
|||
return; |
|||
// Note: If you add new platform in this function, think about adding support in IsSupportedPlatform() function in HDRenderPipeline.cs
|
|||
// Note: If you add new platform in this function, think about adding support in IsSupportedPlatform() function in HDRenderPipeline.cs
|
|||
// If platform is supported all good
|
|||
if (report.summary.platform == BuildTarget.StandaloneWindows || |
|||
report.summary.platform == BuildTarget.StandaloneWindows64 || |
|||
report.summary.platform == BuildTarget.StandaloneLinux64 || |
|||
report.summary.platform == BuildTarget.StandaloneLinuxUniversal || |
|||
report.summary.platform == BuildTarget.StandaloneOSX || |
|||
report.summary.platform == BuildTarget.XboxOne || |
|||
report.summary.platform == BuildTarget.PS4 || |
|||
report.summary.platform == BuildTarget.Switch) |
|||
{ |
|||
return; |
|||
} |
|||
// If platform is supported all good
|
|||
if (report.summary.platform == BuildTarget.StandaloneWindows || |
|||
report.summary.platform == BuildTarget.StandaloneWindows64 || |
|||
report.summary.platform == BuildTarget.StandaloneLinux64 || |
|||
report.summary.platform == BuildTarget.StandaloneLinuxUniversal || |
|||
report.summary.platform == BuildTarget.StandaloneOSX || |
|||
report.summary.platform == BuildTarget.XboxOne || |
|||
report.summary.platform == BuildTarget.PS4 || |
|||
report.summary.platform == BuildTarget.Switch) |
|||
{ |
|||
return; |
|||
} |
|||
string msg = "The platform " + report.summary.platform.ToString() + " is not supported with Hight Definition Render Pipeline"; |
|||
string msg = "The platform " + report.summary.platform.ToString() + " is not supported with Hight Definition Render Pipeline"; |
|||
// Throw an exception to stop the build
|
|||
throw new BuildFailedException(msg); |
|||
// Throw an exception to stop the build
|
|||
throw new BuildFailedException(msg); |
|||
} |
|||
} |
|||
} |
|
|||
using UnityEngine; |
|||
using UnityEditor; |
|||
[CustomEditorForRenderPipeline(typeof(Cubemap), typeof(HDRenderPipelineAsset))] |
|||
class HDCubemapInspector : Editor |
|||
namespace UnityEditor.Experimental.Rendering.HDPipeline |
|||
private enum NavMode |
|||
[CustomEditorForRenderPipeline(typeof(Cubemap), typeof(HDRenderPipelineAsset))] |
|||
class HDCubemapInspector : Editor |
|||
None = 0, |
|||
Zooming = 1, |
|||
Rotating = 2 |
|||
} |
|||
private enum NavMode |
|||
{ |
|||
None = 0, |
|||
Zooming = 1, |
|||
Rotating = 2 |
|||
} |
|||
static GUIContent s_MipMapLow, s_MipMapHigh, s_ExposureLow; |
|||
static GUIStyle s_PreLabel; |
|||
static Mesh s_SphereMesh; |
|||
static GUIContent s_MipMapLow, s_MipMapHigh, s_ExposureLow; |
|||
static GUIStyle s_PreLabel; |
|||
static Mesh s_SphereMesh; |
|||
static Mesh sphereMesh |
|||
{ |
|||
get { return s_SphereMesh ?? (s_SphereMesh = Resources.GetBuiltinResource(typeof(Mesh), "New-Sphere.fbx") as Mesh); } |
|||
} |
|||
static Mesh sphereMesh |
|||
{ |
|||
get { return s_SphereMesh ?? (s_SphereMesh = Resources.GetBuiltinResource(typeof(Mesh), "New-Sphere.fbx") as Mesh); } |
|||
} |
|||
Material m_ReflectiveMaterial; |
|||
PreviewRenderUtility m_PreviewUtility; |
|||
float m_CameraPhi = 0.75f; |
|||
float m_CameraTheta = 0.5f; |
|||
float m_CameraDistance = 2.0f; |
|||
NavMode m_NavMode = NavMode.None; |
|||
Vector2 m_PreviousMousePosition = Vector2.zero; |
|||
Material m_ReflectiveMaterial; |
|||
PreviewRenderUtility m_PreviewUtility; |
|||
float m_CameraPhi = 0.75f; |
|||
float m_CameraTheta = 0.5f; |
|||
float m_CameraDistance = 2.0f; |
|||
NavMode m_NavMode = NavMode.None; |
|||
Vector2 m_PreviousMousePosition = Vector2.zero; |
|||
public float previewExposure = 0f; |
|||
public float mipLevelPreview = 0f; |
|||
public float previewExposure = 0f; |
|||
public float mipLevelPreview = 0f; |
|||
void Awake() |
|||
{ |
|||
m_ReflectiveMaterial = new Material(Shader.Find("Debug/ReflectionProbePreview")) |
|||
void Awake() |
|||
hideFlags = HideFlags.HideAndDontSave |
|||
}; |
|||
} |
|||
m_ReflectiveMaterial = new Material(Shader.Find("Debug/ReflectionProbePreview")) |
|||
{ |
|||
hideFlags = HideFlags.HideAndDontSave |
|||
}; |
|||
} |
|||
void OnEnable() |
|||
{ |
|||
if (m_PreviewUtility == null) |
|||
InitPreview(); |
|||
|
|||
m_ReflectiveMaterial.SetTexture("_Cubemap", target as Texture); |
|||
} |
|||
void OnEnable() |
|||
{ |
|||
if (m_PreviewUtility == null) |
|||
InitPreview(); |
|||
void OnDisable() |
|||
{ |
|||
if (m_PreviewUtility != null) |
|||
m_PreviewUtility.Cleanup(); |
|||
} |
|||
m_ReflectiveMaterial.SetTexture("_Cubemap", target as Texture); |
|||
} |
|||
public override bool HasPreviewGUI() |
|||
{ |
|||
return true; |
|||
} |
|||
void OnDisable() |
|||
{ |
|||
if (m_PreviewUtility != null) |
|||
m_PreviewUtility.Cleanup(); |
|||
} |
|||
public override void OnPreviewGUI(Rect r, GUIStyle background) |
|||
{ |
|||
if (m_ReflectiveMaterial != null) |
|||
public override bool HasPreviewGUI() |
|||
m_ReflectiveMaterial.SetFloat("_Exposure", previewExposure); |
|||
m_ReflectiveMaterial.SetFloat("_MipLevel", mipLevelPreview); |
|||
return true; |
|||
if (m_PreviewUtility == null) |
|||
InitPreview(); |
|||
public override void OnPreviewGUI(Rect r, GUIStyle background) |
|||
{ |
|||
if (m_ReflectiveMaterial != null) |
|||
{ |
|||
m_ReflectiveMaterial.SetFloat("_Exposure", previewExposure); |
|||
m_ReflectiveMaterial.SetFloat("_MipLevel", mipLevelPreview); |
|||
} |
|||
UpdateCamera(); |
|||
if (m_PreviewUtility == null) |
|||
InitPreview(); |
|||
m_PreviewUtility.BeginPreview(r, GUIStyle.none); |
|||
m_PreviewUtility.DrawMesh(sphereMesh, Matrix4x4.identity, m_ReflectiveMaterial, 0); |
|||
m_PreviewUtility.camera.Render(); |
|||
m_PreviewUtility.EndAndDrawPreview(r); |
|||
UpdateCamera(); |
|||
if (Event.current.type != EventType.Repaint) |
|||
{ |
|||
if (HandleMouse(r)) |
|||
Repaint(); |
|||
m_PreviewUtility.BeginPreview(r, GUIStyle.none); |
|||
m_PreviewUtility.DrawMesh(sphereMesh, Matrix4x4.identity, m_ReflectiveMaterial, 0); |
|||
m_PreviewUtility.camera.Render(); |
|||
m_PreviewUtility.EndAndDrawPreview(r); |
|||
|
|||
if (Event.current.type != EventType.Repaint) |
|||
{ |
|||
if (HandleMouse(r)) |
|||
Repaint(); |
|||
} |
|||
} |
|||
|
|||
public override void OnPreviewSettings() |
|||
{ |
|||
if (s_MipMapLow == null) |
|||
InitIcons(); |
|||
var mipmapCount = 0; |
|||
var cubemap = target as Cubemap; |
|||
var rt = target as RenderTexture; |
|||
if (cubemap != null) |
|||
mipmapCount = cubemap.mipmapCount; |
|||
if (rt != null) |
|||
mipmapCount = rt.useMipMap |
|||
? (int)(Mathf.Log(Mathf.Max(rt.width, rt.height)) / Mathf.Log(2)) |
|||
: 1; |
|||
public override void OnPreviewSettings() |
|||
{ |
|||
if (s_MipMapLow == null) |
|||
InitIcons(); |
|||
GUI.enabled = true; |
|||
var mipmapCount = 0; |
|||
var cubemap = target as Cubemap; |
|||
var rt = target as RenderTexture; |
|||
if (cubemap != null) |
|||
mipmapCount = cubemap.mipmapCount; |
|||
if (rt != null) |
|||
mipmapCount = rt.useMipMap |
|||
? (int)(Mathf.Log(Mathf.Max(rt.width, rt.height)) / Mathf.Log(2)) |
|||
: 1; |
|||
GUILayout.Box(s_ExposureLow, s_PreLabel, GUILayout.MaxWidth(20)); |
|||
GUI.changed = false; |
|||
previewExposure = GUILayout.HorizontalSlider(previewExposure, -10f, 10f, GUILayout.MaxWidth(80)); |
|||
GUILayout.Space(5); |
|||
GUILayout.Box(s_MipMapHigh, s_PreLabel, GUILayout.MaxWidth(20)); |
|||
GUI.changed = false; |
|||
mipLevelPreview = GUILayout.HorizontalSlider(mipLevelPreview, 0, mipmapCount, GUILayout.MaxWidth(80)); |
|||
GUILayout.Box(s_MipMapLow, s_PreLabel, GUILayout.MaxWidth(20)); |
|||
} |
|||
GUI.enabled = true; |
|||
void InitPreview() |
|||
{ |
|||
if (m_PreviewUtility != null) |
|||
m_PreviewUtility.Cleanup(); |
|||
m_PreviewUtility = new PreviewRenderUtility(false, true); |
|||
m_PreviewUtility.cameraFieldOfView = 50.0f; |
|||
m_PreviewUtility.camera.nearClipPlane = 0.01f; |
|||
m_PreviewUtility.camera.farClipPlane = 20.0f; |
|||
m_PreviewUtility.camera.transform.position = new Vector3(0, 0, 2); |
|||
m_PreviewUtility.camera.transform.LookAt(Vector3.zero); |
|||
} |
|||
GUILayout.Box(s_ExposureLow, s_PreLabel, GUILayout.MaxWidth(20)); |
|||
GUI.changed = false; |
|||
previewExposure = GUILayout.HorizontalSlider(previewExposure, -10f, 10f, GUILayout.MaxWidth(80)); |
|||
GUILayout.Space(5); |
|||
GUILayout.Box(s_MipMapHigh, s_PreLabel, GUILayout.MaxWidth(20)); |
|||
GUI.changed = false; |
|||
mipLevelPreview = GUILayout.HorizontalSlider(mipLevelPreview, 0, mipmapCount, GUILayout.MaxWidth(80)); |
|||
GUILayout.Box(s_MipMapLow, s_PreLabel, GUILayout.MaxWidth(20)); |
|||
} |
|||
bool HandleMouse(Rect Viewport) |
|||
{ |
|||
var result = false; |
|||
void InitPreview() |
|||
{ |
|||
if (m_PreviewUtility != null) |
|||
m_PreviewUtility.Cleanup(); |
|||
m_PreviewUtility = new PreviewRenderUtility(false, true); |
|||
m_PreviewUtility.cameraFieldOfView = 50.0f; |
|||
m_PreviewUtility.camera.nearClipPlane = 0.01f; |
|||
m_PreviewUtility.camera.farClipPlane = 20.0f; |
|||
m_PreviewUtility.camera.transform.position = new Vector3(0, 0, 2); |
|||
m_PreviewUtility.camera.transform.LookAt(Vector3.zero); |
|||
} |
|||
if (Event.current.type == EventType.MouseDown) |
|||
bool HandleMouse(Rect Viewport) |
|||
if (Event.current.button == 0) |
|||
m_NavMode = NavMode.Rotating; |
|||
else if (Event.current.button == 1) |
|||
m_NavMode = NavMode.Zooming; |
|||
var result = false; |
|||
m_PreviousMousePosition = Event.current.mousePosition; |
|||
result = true; |
|||
} |
|||
if (Event.current.type == EventType.MouseDown) |
|||
{ |
|||
if (Event.current.button == 0) |
|||
m_NavMode = NavMode.Rotating; |
|||
else if (Event.current.button == 1) |
|||
m_NavMode = NavMode.Zooming; |
|||
if (Event.current.type == EventType.MouseUp || Event.current.rawType == EventType.MouseUp) |
|||
m_NavMode = NavMode.None; |
|||
m_PreviousMousePosition = Event.current.mousePosition; |
|||
result = true; |
|||
} |
|||
if (m_NavMode != NavMode.None) |
|||
{ |
|||
var mouseDelta = Event.current.mousePosition - m_PreviousMousePosition; |
|||
switch (m_NavMode) |
|||
if (Event.current.type == EventType.MouseUp || Event.current.rawType == EventType.MouseUp) |
|||
m_NavMode = NavMode.None; |
|||
|
|||
if (m_NavMode != NavMode.None) |
|||
case NavMode.Rotating: |
|||
m_CameraTheta = (m_CameraTheta - mouseDelta.x * 0.003f) % (Mathf.PI * 2); |
|||
m_CameraPhi = Mathf.Clamp(m_CameraPhi - mouseDelta.y * 0.003f, 0.2f, Mathf.PI - 0.2f); |
|||
break; |
|||
case NavMode.Zooming: |
|||
m_CameraDistance = Mathf.Clamp(mouseDelta.y * 0.01f + m_CameraDistance, 1, 10); |
|||
break; |
|||
var mouseDelta = Event.current.mousePosition - m_PreviousMousePosition; |
|||
switch (m_NavMode) |
|||
{ |
|||
case NavMode.Rotating: |
|||
m_CameraTheta = (m_CameraTheta - mouseDelta.x * 0.003f) % (Mathf.PI * 2); |
|||
m_CameraPhi = Mathf.Clamp(m_CameraPhi - mouseDelta.y * 0.003f, 0.2f, Mathf.PI - 0.2f); |
|||
break; |
|||
case NavMode.Zooming: |
|||
m_CameraDistance = Mathf.Clamp(mouseDelta.y * 0.01f + m_CameraDistance, 1, 10); |
|||
break; |
|||
} |
|||
result = true; |
|||
result = true; |
|||
|
|||
m_PreviousMousePosition = Event.current.mousePosition; |
|||
return result; |
|||
m_PreviousMousePosition = Event.current.mousePosition; |
|||
return result; |
|||
} |
|||
void UpdateCamera() |
|||
{ |
|||
var pos = new Vector3(Mathf.Sin(m_CameraPhi) * Mathf.Cos(m_CameraTheta), Mathf.Cos(m_CameraPhi), Mathf.Sin(m_CameraPhi) * Mathf.Sin(m_CameraTheta)) * m_CameraDistance; |
|||
m_PreviewUtility.camera.transform.position = pos; |
|||
m_PreviewUtility.camera.transform.LookAt(Vector3.zero); |
|||
} |
|||
void UpdateCamera() |
|||
{ |
|||
var pos = new Vector3(Mathf.Sin(m_CameraPhi) * Mathf.Cos(m_CameraTheta), Mathf.Cos(m_CameraPhi), Mathf.Sin(m_CameraPhi) * Mathf.Sin(m_CameraTheta)) * m_CameraDistance; |
|||
m_PreviewUtility.camera.transform.position = pos; |
|||
m_PreviewUtility.camera.transform.LookAt(Vector3.zero); |
|||
} |
|||
|
|||
static void InitIcons() |
|||
{ |
|||
s_MipMapLow = EditorGUIUtility.IconContent("PreTextureMipMapLow"); |
|||
s_MipMapHigh = EditorGUIUtility.IconContent("PreTextureMipMapHigh"); |
|||
s_ExposureLow = EditorGUIUtility.IconContent("SceneViewLighting"); |
|||
s_PreLabel = "preLabel"; |
|||
static void InitIcons() |
|||
{ |
|||
s_MipMapLow = EditorGUIUtility.IconContent("PreTextureMipMapLow"); |
|||
s_MipMapHigh = EditorGUIUtility.IconContent("PreTextureMipMapHigh"); |
|||
s_ExposureLow = EditorGUIUtility.IconContent("SceneViewLighting"); |
|||
s_PreLabel = "preLabel"; |
|||
} |
|||
} |
|||
} |
|
|||
using System; |
|||
using UnityEngine; |
|||
public struct ZonalHarmonicsL2 |
|||
{ |
|||
public float[] coeffs; // Must have the size of 3
|
|||
public static ZonalHarmonicsL2 GetHenyeyGreensteinPhaseFunction(float anisotropy) |
|||
namespace UnityEngine.Experimental.Rendering.HDPipeline |
|||
{ |
|||
public struct ZonalHarmonicsL2 |
|||
float g = anisotropy; |
|||
public float[] coeffs; // Must have the size of 3
|
|||
var zh = new ZonalHarmonicsL2(); |
|||
zh.coeffs = new float[3]; |
|||
public static ZonalHarmonicsL2 GetHenyeyGreensteinPhaseFunction(float anisotropy) |
|||
{ |
|||
float g = anisotropy; |
|||
zh.coeffs[0] = 0.5f * Mathf.Sqrt(1.0f / Mathf.PI); |
|||
zh.coeffs[1] = 0.5f * Mathf.Sqrt(3.0f / Mathf.PI) * g; |
|||
zh.coeffs[2] = 0.5f * Mathf.Sqrt(5.0f / Mathf.PI) * g * g; |
|||
var zh = new ZonalHarmonicsL2(); |
|||
zh.coeffs = new float[3]; |
|||
return zh; |
|||
} |
|||
zh.coeffs[0] = 0.5f * Mathf.Sqrt(1.0f / Mathf.PI); |
|||
zh.coeffs[1] = 0.5f * Mathf.Sqrt(3.0f / Mathf.PI) * g; |
|||
zh.coeffs[2] = 0.5f * Mathf.Sqrt(5.0f / Mathf.PI) * g * g; |
|||
public static ZonalHarmonicsL2 GetCornetteShanksPhaseFunction(float anisotropy) |
|||
{ |
|||
float g = anisotropy; |
|||
return zh; |
|||
} |
|||
var zh = new ZonalHarmonicsL2(); |
|||
zh.coeffs = new float[3]; |
|||
public static ZonalHarmonicsL2 GetCornetteShanksPhaseFunction(float anisotropy) |
|||
{ |
|||
float g = anisotropy; |
|||
|
|||
var zh = new ZonalHarmonicsL2(); |
|||
zh.coeffs = new float[3]; |
|||
zh.coeffs[0] = 0.282095f; |
|||
zh.coeffs[1] = 0.293162f * g * (4.0f + (g * g)) / (2.0f + (g * g)); |
|||
zh.coeffs[2] = (0.126157f + 1.44179f * (g * g) + 0.324403f * (g * g) * (g * g)) / (2.0f + (g * g)); |
|||
zh.coeffs[0] = 0.282095f; |
|||
zh.coeffs[1] = 0.293162f * g * (4.0f + (g * g)) / (2.0f + (g * g)); |
|||
zh.coeffs[2] = (0.126157f + 1.44179f * (g * g) + 0.324403f * (g * g) * (g * g)) / (2.0f + (g * g)); |
|||
return zh; |
|||
return zh; |
|||
} |
|||
} |
|||
public class SphericalHarmonicMath |
|||
{ |
|||
// Ref: "Stupid Spherical Harmonics Tricks", p. 6.
|
|||
public static SphericalHarmonicsL2 Convolve(SphericalHarmonicsL2 sh, ZonalHarmonicsL2 zh) |
|||
public class SphericalHarmonicMath |
|||
for (int l = 0; l <= 2; l++) |
|||
// Ref: "Stupid Spherical Harmonics Tricks", p. 6.
|
|||
public static SphericalHarmonicsL2 Convolve(SphericalHarmonicsL2 sh, ZonalHarmonicsL2 zh) |
|||
float n = Mathf.Sqrt((4.0f * Mathf.PI) / (2 * l + 1)); |
|||
float k = zh.coeffs[l]; |
|||
float p = n * k; |
|||
|
|||
for (int m = -l; m <= l; m++) |
|||
for (int l = 0; l <= 2; l++) |
|||
int i = l * (l + 1) + m; |
|||
float n = Mathf.Sqrt((4.0f * Mathf.PI) / (2 * l + 1)); |
|||
float k = zh.coeffs[l]; |
|||
float p = n * k; |
|||
for (int c = 0; c < 3; c++) |
|||
for (int m = -l; m <= l; m++) |
|||
sh[c, i] *= p; |
|||
int i = l * (l + 1) + m; |
|||
|
|||
for (int c = 0; c < 3; c++) |
|||
{ |
|||
sh[c, i] *= p; |
|||
} |
|||
|
|||
return sh; |
|||
return sh; |
|||
} |
|||
// Undoes coefficient rescaling due to the convolution with the clamped cosine kernel
|
|||
// to obtain the canonical values of SH.
|
|||
public static SphericalHarmonicsL2 UndoCosineRescaling(SphericalHarmonicsL2 sh) |
|||
{ |
|||
const float c0 = 0.28209479177387814347f; // 1/2 * sqrt(1/Pi)
|
|||
const float c1 = 0.32573500793527994772f; // 1/3 * sqrt(3/Pi)
|
|||
const float c2 = 0.27313710764801976764f; // 1/8 * sqrt(15/Pi)
|
|||
const float c3 = 0.07884789131313000151f; // 1/16 * sqrt(5/Pi)
|
|||
const float c4 = 0.13656855382400988382f; // 1/16 * sqrt(15/Pi)
|
|||
// Undoes coefficient rescaling due to the convolution with the clamped cosine kernel
|
|||
// to obtain the canonical values of SH.
|
|||
public static SphericalHarmonicsL2 UndoCosineRescaling(SphericalHarmonicsL2 sh) |
|||
{ |
|||
const float c0 = 0.28209479177387814347f; // 1/2 * sqrt(1/Pi)
|
|||
const float c1 = 0.32573500793527994772f; // 1/3 * sqrt(3/Pi)
|
|||
const float c2 = 0.27313710764801976764f; // 1/8 * sqrt(15/Pi)
|
|||
const float c3 = 0.07884789131313000151f; // 1/16 * sqrt(5/Pi)
|
|||
const float c4 = 0.13656855382400988382f; // 1/16 * sqrt(15/Pi)
|
|||
|
|||
// Compute the inverse of SphericalHarmonicsL2::kNormalizationConstants.
|
|||
// See SetSHEMapConstants() in "Stupid Spherical Harmonics Tricks".
|
|||
float[] invNormConsts = { 1 / c0, -1 / c1, 1 / c1, -1 / c1, 1 / c2, -1 / c2, 1 / c3, -1 / c2, 1 / c4 }; |
|||
// Compute the inverse of SphericalHarmonicsL2::kNormalizationConstants.
|
|||
// See SetSHEMapConstants() in "Stupid Spherical Harmonics Tricks".
|
|||
float[] invNormConsts = { 1 / c0, -1 / c1, 1 / c1, -1 / c1, 1 / c2, -1 / c2, 1 / c3, -1 / c2, 1 / c4 }; |
|||
for (int c = 0; c < 3; c++) |
|||
{ |
|||
for (int i = 0; i < 9; i++) |
|||
for (int c = 0; c < 3; c++) |
|||
sh[c, i] *= invNormConsts[i]; |
|||
for (int i = 0; i < 9; i++) |
|||
{ |
|||
sh[c, i] *= invNormConsts[i]; |
|||
} |
|||
} |
|||
return sh; |
|||
} |
|||
return sh; |
|||
} |
|||
// Premultiplies the SH with the polynomial coefficients of SH basis functions,
|
|||
// which avoids using any constants during SH evaluation.
|
|||
// The resulting evaluation takes the form:
|
|||
// (c_0 - c_6) + c_1 y + c_2 z + c_3 x + c_4 x y + c_5 y z + c_6 (3 z^2) + c_7 x z + c_8 (x^2 - y^2)
|
|||
public static SphericalHarmonicsL2 PremultiplyCoefficients(SphericalHarmonicsL2 sh) |
|||
{ |
|||
const float k0 = 0.28209479177387814347f; // {0, 0} : 1/2 * sqrt(1/Pi)
|
|||
const float k1 = 0.48860251190291992159f; // {1, 0} : 1/2 * sqrt(3/Pi)
|
|||
const float k2 = 1.09254843059207907054f; // {2,-2} : 1/2 * sqrt(15/Pi)
|
|||
const float k3 = 0.31539156525252000603f; // {2, 0} : 1/4 * sqrt(5/Pi)
|
|||
const float k4 = 0.54627421529603953527f; // {2, 2} : 1/4 * sqrt(15/Pi)
|
|||
// Premultiplies the SH with the polynomial coefficients of SH basis functions,
|
|||
// which avoids using any constants during SH evaluation.
|
|||
// The resulting evaluation takes the form:
|
|||
// (c_0 - c_6) + c_1 y + c_2 z + c_3 x + c_4 x y + c_5 y z + c_6 (3 z^2) + c_7 x z + c_8 (x^2 - y^2)
|
|||
public static SphericalHarmonicsL2 PremultiplyCoefficients(SphericalHarmonicsL2 sh) |
|||
{ |
|||
const float k0 = 0.28209479177387814347f; // {0, 0} : 1/2 * sqrt(1/Pi)
|
|||
const float k1 = 0.48860251190291992159f; // {1, 0} : 1/2 * sqrt(3/Pi)
|
|||
const float k2 = 1.09254843059207907054f; // {2,-2} : 1/2 * sqrt(15/Pi)
|
|||
const float k3 = 0.31539156525252000603f; // {2, 0} : 1/4 * sqrt(5/Pi)
|
|||
const float k4 = 0.54627421529603953527f; // {2, 2} : 1/4 * sqrt(15/Pi)
|
|||
float[] ks = { k0, -k1, k1, -k1, k2, -k2, k3, -k2, k4 }; |
|||
float[] ks = { k0, -k1, k1, -k1, k2, -k2, k3, -k2, k4 }; |
|||
for (int c = 0; c < 3; c++) |
|||
{ |
|||
for (int i = 0; i < 9; i++) |
|||
for (int c = 0; c < 3; c++) |
|||
sh[c, i] *= ks[i]; |
|||
for (int i = 0; i < 9; i++) |
|||
{ |
|||
sh[c, i] *= ks[i]; |
|||
} |
|||
|
|||
return sh; |
|||
return sh; |
|||
} |
|||
|
|||
public static SphericalHarmonicsL2 RescaleCoefficients(SphericalHarmonicsL2 sh, float scalar) |
|||
{ |
|||
for (int c = 0; c < 3; c++) |
|||
public static SphericalHarmonicsL2 RescaleCoefficients(SphericalHarmonicsL2 sh, float scalar) |
|||
for (int i = 0; i < 9; i++) |
|||
for (int c = 0; c < 3; c++) |
|||
sh[c, i] *= scalar; |
|||
for (int i = 0; i < 9; i++) |
|||
{ |
|||
sh[c, i] *= scalar; |
|||
} |
|||
|
|||
return sh; |
|||
return sh; |
|||
} |
|||
// Packs coefficients so that we can use Peter-Pike Sloan's shader code.
|
|||
// Does not perform premultiplication with coefficients of SH basis functions.
|
|||
// See SetSHEMapConstants() in "Stupid Spherical Harmonics Tricks".
|
|||
public static Vector4[] PackCoefficients(SphericalHarmonicsL2 sh) |
|||
{ |
|||
Vector4[] coeffs = new Vector4[7]; |
|||
|
|||
// Constant + linear
|
|||
for (int c = 0; c < 3; c++) |
|||
{ |
|||
coeffs[c].x = sh[c, 3]; |
|||
coeffs[c].y = sh[c, 1]; |
|||
coeffs[c].z = sh[c, 2]; |
|||
coeffs[c].w = sh[c, 0] - sh[c, 6]; |
|||
} |
|||
// Packs coefficients so that we can use Peter-Pike Sloan's shader code.
|
|||
// Does not perform premultiplication with coefficients of SH basis functions.
|
|||
// See SetSHEMapConstants() in "Stupid Spherical Harmonics Tricks".
|
|||
public static Vector4[] PackCoefficients(SphericalHarmonicsL2 sh) |
|||
{ |
|||
Vector4[] coeffs = new Vector4[7]; |
|||
// Quadratic (4/5)
|
|||
for (int c = 0; c < 3; c++) |
|||
{ |
|||
coeffs[3 + c].x = sh[c, 4]; |
|||
coeffs[3 + c].y = sh[c, 5]; |
|||
coeffs[3 + c].z = sh[c, 6] * 3.0f; |
|||
coeffs[3 + c].w = sh[c, 7]; |
|||
} |
|||
// Constant + linear
|
|||
for (int c = 0; c < 3; c++) |
|||
{ |
|||
coeffs[c].x = sh[c, 3]; |
|||
coeffs[c].y = sh[c, 1]; |
|||
coeffs[c].z = sh[c, 2]; |
|||
coeffs[c].w = sh[c, 0] - sh[c, 6]; |
|||
} |
|||
// Quadratic (5)
|
|||
coeffs[6].x = sh[0, 8]; |
|||
coeffs[6].y = sh[1, 8]; |
|||
coeffs[6].z = sh[2, 8]; |
|||
coeffs[6].w = 1.0f; |
|||
// Quadratic (4/5)
|
|||
for (int c = 0; c < 3; c++) |
|||
{ |
|||
coeffs[3 + c].x = sh[c, 4]; |
|||
coeffs[3 + c].y = sh[c, 5]; |
|||
coeffs[3 + c].z = sh[c, 6] * 3.0f; |
|||
coeffs[3 + c].w = sh[c, 7]; |
|||
return coeffs; |
|||
|
|||
// Quadratic (5)
|
|||
coeffs[6].x = sh[0, 8]; |
|||
coeffs[6].y = sh[1, 8]; |
|||
coeffs[6].z = sh[2, 8]; |
|||
coeffs[6].w = 1.0f; |
|||
|
|||
return coeffs; |
|||
} |
|||
} |
|
|||
#if UNITY_EDITOR
|
|||
using System.Collections; |
|||
using UnityEditor; |
|||
using UnityEditor.Experimental.Rendering; |
|||
public class SceneViewDrawMode |
|||
namespace UnityEngine.Experimental.Rendering.HDPipeline |
|||
static private bool RejectDrawMode(SceneView.CameraMode cameraMode) |
|||
public class SceneViewDrawMode |
|||
if (cameraMode.drawMode == DrawCameraMode.TexturedWire || |
|||
cameraMode.drawMode == DrawCameraMode.ShadowCascades || |
|||
cameraMode.drawMode == DrawCameraMode.RenderPaths || |
|||
cameraMode.drawMode == DrawCameraMode.AlphaChannel || |
|||
cameraMode.drawMode == DrawCameraMode.Overdraw || |
|||
cameraMode.drawMode == DrawCameraMode.Mipmaps || |
|||
cameraMode.drawMode == DrawCameraMode.DeferredDiffuse || |
|||
cameraMode.drawMode == DrawCameraMode.DeferredSpecular || |
|||
cameraMode.drawMode == DrawCameraMode.DeferredSmoothness || |
|||
cameraMode.drawMode == DrawCameraMode.DeferredNormal || |
|||
cameraMode.drawMode == DrawCameraMode.ValidateAlbedo || |
|||
cameraMode.drawMode == DrawCameraMode.ValidateMetalSpecular || |
|||
cameraMode.drawMode == DrawCameraMode.LightOverlap |
|||
) |
|||
return false; |
|||
static private bool RejectDrawMode(SceneView.CameraMode cameraMode) |
|||
{ |
|||
if (cameraMode.drawMode == DrawCameraMode.TexturedWire || |
|||
cameraMode.drawMode == DrawCameraMode.ShadowCascades || |
|||
cameraMode.drawMode == DrawCameraMode.RenderPaths || |
|||
cameraMode.drawMode == DrawCameraMode.AlphaChannel || |
|||
cameraMode.drawMode == DrawCameraMode.Overdraw || |
|||
cameraMode.drawMode == DrawCameraMode.Mipmaps || |
|||
cameraMode.drawMode == DrawCameraMode.DeferredDiffuse || |
|||
cameraMode.drawMode == DrawCameraMode.DeferredSpecular || |
|||
cameraMode.drawMode == DrawCameraMode.DeferredSmoothness || |
|||
cameraMode.drawMode == DrawCameraMode.DeferredNormal || |
|||
cameraMode.drawMode == DrawCameraMode.ValidateAlbedo || |
|||
cameraMode.drawMode == DrawCameraMode.ValidateMetalSpecular || |
|||
cameraMode.drawMode == DrawCameraMode.LightOverlap |
|||
) |
|||
return false; |
|||
return true; |
|||
} |
|||
return true; |
|||
} |
|||
static public void SetupDrawMode() |
|||
{ |
|||
ArrayList sceneViewArray = SceneView.sceneViews; |
|||
foreach (SceneView sceneView in sceneViewArray) |
|||
sceneView.onValidateCameraMode += RejectDrawMode; |
|||
} |
|||
static public void SetupDrawMode() |
|||
{ |
|||
ArrayList sceneViewArray = SceneView.sceneViews; |
|||
foreach (SceneView sceneView in sceneViewArray) |
|||
sceneView.onValidateCameraMode += RejectDrawMode; |
|||
} |
|||
static public void ResetDrawMode() |
|||
{ |
|||
ArrayList sceneViewArray = SceneView.sceneViews; |
|||
foreach (SceneView sceneView in sceneViewArray) |
|||
sceneView.onValidateCameraMode -= RejectDrawMode; |
|||
static public void ResetDrawMode() |
|||
{ |
|||
ArrayList sceneViewArray = SceneView.sceneViews; |
|||
foreach (SceneView sceneView in sceneViewArray) |
|||
sceneView.onValidateCameraMode -= RejectDrawMode; |
|||
} |
|||
} |
|||
} |
|||
#endif
|
撰写
预览
正在加载...
取消
保存
Reference in new issue