补齐备份工程打开依赖
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 557c32d7360c26949947ac9dd8c308fc
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: b933d9ff2aad75c47a4970139d6a01e6
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8217f1589415f28408ff7a0dfe9142df
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: bdbc0567055e3424da2363638a6ffd14
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
After Width: | Height: | Size: 2.0 KiB |
@@ -0,0 +1,144 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f88b6df342d5c4f4a969fb6eb4799d3e
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 11
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 1
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
aniso: 2
|
||||
mipBias: 0
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 1
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 0
|
||||
alphaIsTransparency: 0
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 64
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 64
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: iPhone
|
||||
maxTextureSize: 64
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Android
|
||||
maxTextureSize: 64
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Windows Store Apps
|
||||
maxTextureSize: 8192
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
After Width: | Height: | Size: 121 B |
@@ -0,0 +1,144 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 27623e5a17b6fd44a9af57a733ee993a
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 11
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 0
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 0
|
||||
aniso: 2
|
||||
mipBias: 0
|
||||
wrapU: 0
|
||||
wrapV: 0
|
||||
wrapW: 0
|
||||
nPOTScale: 1
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 0
|
||||
alphaIsTransparency: 0
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 0
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 32
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 0
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 32
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 0
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: iPhone
|
||||
maxTextureSize: 32
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 0
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Android
|
||||
maxTextureSize: 32
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 0
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Windows Store Apps
|
||||
maxTextureSize: 8192
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 76d974e53c74fd642a7607b4a9bbf0a4
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,128 @@
|
||||
// WaterCausticsModules
|
||||
// Copyright (c) 2021 Masataka Hakozaki
|
||||
|
||||
#if WCE_URP
|
||||
using System.Collections.Generic;
|
||||
using MH.WaterCausticsModules.Effect;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace MH.WaterCausticsModules {
|
||||
[ExecuteAlways]
|
||||
[DisallowMultipleComponent]
|
||||
[AddComponentMenu ("")]
|
||||
internal class AtOnce : MonoBehaviour {
|
||||
private WaterCausticsEffect _summoner;
|
||||
private MeshRenderer _render;
|
||||
internal MeshRenderer render => _render;
|
||||
private void setRenderEnable (bool isOn) {
|
||||
if (_render && _render.enabled != isOn) _render.enabled = isOn;
|
||||
}
|
||||
|
||||
private bool _inited;
|
||||
private AtOnce init (WaterCausticsEffect summoner, Material mat) {
|
||||
_inited = true;
|
||||
_summoner = summoner;
|
||||
var mf = gameObject.AddComponent<MeshFilter> ();
|
||||
mf.sharedMesh = getMesh ();
|
||||
_render = gameObject.AddComponent<MeshRenderer> ();
|
||||
_render.sharedMaterial = mat;
|
||||
_render.shadowCastingMode = ShadowCastingMode.Off;
|
||||
_render.lightProbeUsage = LightProbeUsage.Off;
|
||||
_render.reflectionProbeUsage = ReflectionProbeUsage.Off;
|
||||
_render.allowOcclusionWhenDynamic = true;
|
||||
_render.receiveShadows = true;
|
||||
updateTransform ();
|
||||
// -- HideFlags --
|
||||
gameObject.hideFlags = HideFlags.HideAndDontSave | HideFlags.HideInInspector;
|
||||
// gameObject.hideFlags &= (~HideFlags.HideInHierarchy); // デバッグ用 Hierarchyで表示
|
||||
// ---------------
|
||||
return this;
|
||||
}
|
||||
|
||||
private void OnDisable () {
|
||||
setRenderEnable (false);
|
||||
}
|
||||
|
||||
private void OnDestroy () {
|
||||
destroy (ref __mesh);
|
||||
}
|
||||
|
||||
private void LateUpdate () {
|
||||
if (!_summoner || !_summoner.isActiveAndEnabled || _summoner.method != Method.AtOnce) {
|
||||
setRenderEnable (false);
|
||||
} else {
|
||||
setRenderEnable (true);
|
||||
updateTransform ();
|
||||
}
|
||||
}
|
||||
|
||||
private void updateTransform () {
|
||||
if (gameObject.layer != _summoner.gameObject.layer)
|
||||
gameObject.layer = _summoner.gameObject.layer;
|
||||
var sumTra = _summoner.transform;
|
||||
if (transform.parent != sumTra.parent)
|
||||
transform.SetParent (sumTra.parent, worldPositionStays : false);
|
||||
if (transform.localToWorldMatrix != sumTra.localToWorldMatrix) {
|
||||
transform.localPosition = sumTra.localPosition;
|
||||
transform.localRotation = sumTra.localRotation;
|
||||
transform.localScale = sumTra.localScale;
|
||||
}
|
||||
}
|
||||
|
||||
private void Update () {
|
||||
bool isLeaked = (!_inited || !_summoner || _summoner.atOnce != this);
|
||||
if (isLeaked) destroy (gameObject);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------- Mesh
|
||||
private Mesh __mesh;
|
||||
private Mesh getMesh () {
|
||||
if (!__mesh) {
|
||||
Mesh m = new Mesh ();
|
||||
m.name = "WCEMeshForAtOnce";
|
||||
m.vertices = new Vector3 [] { new Vector3 (-.5f, -.5f, -.5f), new Vector3 (.5f, -.5f, -.5f), new Vector3 (-.5f, .5f, -.5f), new Vector3 (.5f, .5f, -.5f), new Vector3 (-.5f, -.5f, .5f), new Vector3 (.5f, -.5f, .5f), new Vector3 (-.5f, .5f, .5f), new Vector3 (.5f, .5f, .5f), /* */ Vector3.zero, Vector3.zero, Vector3.zero, Vector3.zero, Vector3.zero, Vector3.zero, Vector3.zero, Vector3.zero };
|
||||
m.triangles = new int [] { 2, 6, 7, 2, 7, 3, 0, 2, 3, 0, 3, 1, 1, 3, 7, 1, 7, 5, 0, 4, 6, 0, 6, 2, 4, 5, 7, 4, 7, 6, 0, 1, 5, 0, 5, 4, /* */ 15, 8, 9, 15, 9, 10, 15, 10, 11, 15, 11, 12, 15, 12, 13, 15, 13, 14 };
|
||||
m.bounds = new Bounds (Vector3.zero, Vector3.one);
|
||||
m.hideFlags = HideFlags.HideAndDontSave;
|
||||
m.UploadMeshData (markNoLongerReadable: true);
|
||||
__mesh = m;
|
||||
}
|
||||
return __mesh;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------- Static
|
||||
|
||||
static internal AtOnce Create (WaterCausticsEffect summoner, Material mat) {
|
||||
var name = "(WCE Renderer) (Deletable)";
|
||||
var go = new GameObject (name);
|
||||
go.SetActive (false); // ← Flags設定時にOnEnable,OnDisableが呼ばれる不具合の回避
|
||||
var a = go.AddComponent<AtOnce> ().init (summoner, mat);
|
||||
go.SetActive (true);
|
||||
return a;
|
||||
}
|
||||
|
||||
static internal void OnSummonerDestroyed (ref AtOnce a) {
|
||||
if (a == null) return;
|
||||
destroy (a.gameObject);
|
||||
a = null;
|
||||
}
|
||||
|
||||
static private void destroy<T> (ref T o) where T : Object {
|
||||
if (o == null) return;
|
||||
destroy (o);
|
||||
o = null;
|
||||
}
|
||||
|
||||
static private void destroy (Object o) {
|
||||
if (o == null) return;
|
||||
if (Application.isPlaying)
|
||||
Destroy (o);
|
||||
else
|
||||
DestroyImmediate (o);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
}
|
||||
}
|
||||
#endif // End of WCE_URP
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 22b1121aa1f7879478a6b6b90e1a9738
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: eb81f73566a5654488dbc4e168ae6b26
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,97 @@
|
||||
// WaterCausticsModules
|
||||
// Copyright (c) 2021 Masataka Hakozaki
|
||||
|
||||
#if UNITY_EDITOR && (!WCE_URP || WCE_DEVELOPMENT)
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
#pragma warning disable 162
|
||||
|
||||
namespace MH.WaterCausticsModules {
|
||||
/*------------------------------------------------------------------------
|
||||
URP10.4以上のパッケージを持っていない場合にEffectモジュールを削除。
|
||||
initializeOnLoad と インポート時に削除を試す
|
||||
-------------------------------------------------------------------------*/
|
||||
public class CheckRenderPipeline : AssetPostprocessor {
|
||||
static private readonly string classFileName = $"{typeof(CheckRenderPipeline).Name}.cs";
|
||||
|
||||
#if WCE_DEVELOPMENT
|
||||
[MenuItem ("WCM/TestDialog/DeleteEffectModuleDialog")]
|
||||
static void dialogTest () => showDialogAndWarning ();
|
||||
static private readonly bool isDeveloping = true;
|
||||
#else
|
||||
static private readonly bool isDeveloping = false;
|
||||
#endif
|
||||
|
||||
[InitializeOnLoadMethod]
|
||||
private static void initializeOnLoad () {
|
||||
EditorApplication.delayCall += delayCall;
|
||||
}
|
||||
private static void delayCall () {
|
||||
if (isDeveloping) return;
|
||||
if (findAsset<EffectModuleRef> (out var asset, out var path)) {
|
||||
if (asset.effectModule) {
|
||||
var folderPath = AssetDatabase.GetAssetPath (asset.effectModule);
|
||||
if (!string.IsNullOrEmpty (folderPath) && folderPath.EndsWith (Constant.EFFECT_FOLDER_NAME)) {
|
||||
deleteEffectFolder (folderPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static string s_folderPath;
|
||||
static void OnPostprocessAllAssets (string [] imported, string [] deleted, string [] moved, string [] movedFrom) {
|
||||
if (isDeveloping) return;
|
||||
if (findAsset<EffectModuleRef> (out var asset, out var path) && asset.effectModule) {
|
||||
var folderPath = AssetDatabase.GetAssetPath (asset.effectModule);
|
||||
if (!string.IsNullOrEmpty (folderPath) && folderPath.EndsWith (Constant.EFFECT_FOLDER_NAME)) {
|
||||
if (imported.Any (a => a.StartsWith (folderPath))) {
|
||||
// Shaderファイルなどを先に削除 ※Shader Error回避
|
||||
deleteWithoutMat (folderPath);
|
||||
// フォルダの削除はDelayCallで行う ※MaterialPostprocessorでのNullエラー回避
|
||||
s_folderPath = folderPath;
|
||||
EditorApplication.delayCall += () => deleteEffectFolder (s_folderPath);
|
||||
} else {
|
||||
deleteEffectFolder (folderPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void deleteWithoutMat (string folderPath) {
|
||||
string [] guids = AssetDatabase.FindAssets ("", new [] { folderPath });
|
||||
string [] paths = guids.Select (guid => AssetDatabase.GUIDToAssetPath (guid)).Where (p => p.EndsWith (".shader") || p.EndsWith (".asset") || p.EndsWith (".lighting")).ToArray ();
|
||||
#if UNITY_2020_1_OR_NEWER
|
||||
AssetDatabase.DeleteAssets (paths, new List<string> ());
|
||||
#else
|
||||
foreach (var p in paths) AssetDatabase.DeleteAsset (p);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void deleteEffectFolder (string folderPath) {
|
||||
if (isDeveloping || string.IsNullOrEmpty (folderPath)) return;
|
||||
if (AssetDatabase.DeleteAsset (folderPath)) {
|
||||
AssetDatabase.Refresh ();
|
||||
showDialogAndWarning ();
|
||||
}
|
||||
}
|
||||
|
||||
static void showDialogAndWarning () {
|
||||
// ----- Dialog表示
|
||||
EditorUtility.DisplayDialog ("Effect module removed.", $"The Effect module of this asset was removed.\n\nBecause the UniversalRP package {Constant.REQUIRE_URP_VER} could not be detected in this project.\n\nSee the Manual for details.\n\n\n({Constant.ASSET_NAME})", "OK");
|
||||
}
|
||||
|
||||
static private bool findAsset<T> (out T asset, out string path) where T : Object {
|
||||
asset = null;
|
||||
path = null;
|
||||
var guids = AssetDatabase.FindAssets ($"t:{typeof (T).ToString()}", new [] { "Assets" }); // ※フォルダ名の最後にスラッシュがあると古いUnityでエラーになるので注意
|
||||
if (guids.Length == 0) return false;
|
||||
path = AssetDatabase.GUIDToAssetPath (guids [0]);
|
||||
asset = AssetDatabase.LoadAssetAtPath<T> (path);
|
||||
return asset != null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,13 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 4373c16da8bab7841b9c9f883fd8ca5c
|
||||
labels:
|
||||
- WaterCausticsModules
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,67 @@
|
||||
// WaterCausticsModules
|
||||
// Copyright (c) 2021 Masataka Hakozaki
|
||||
|
||||
#if UNITY_EDITOR && WCE_URP
|
||||
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor;
|
||||
using UnityEditor.Build;
|
||||
using UnityEditor.Build.Reporting;
|
||||
using UnityEditor.Rendering;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace MH.WaterCausticsModules {
|
||||
/*------------------------------------------------------------------------
|
||||
Previewウィンドウでエフェクトを無効化
|
||||
-------------------------------------------------------------------------*/
|
||||
public class DisableInPreviewWindow : IPreprocessBuildWithReport, IPostprocessBuildWithReport {
|
||||
private static readonly string KEYWORD = "_WCE_DISABLED";
|
||||
public int callbackOrder => 1;
|
||||
public void OnPreprocessBuild (BuildReport report) {
|
||||
// ビルド前処理
|
||||
disableEvent ();
|
||||
}
|
||||
|
||||
public void OnPostprocessBuild (BuildReport report) {
|
||||
// ビルド後処理
|
||||
enableEvent ();
|
||||
}
|
||||
|
||||
[InitializeOnLoadMethod]
|
||||
static void OnInitialize () {
|
||||
// Editor起動直後、プレイ開始時
|
||||
enableEvent ();
|
||||
}
|
||||
|
||||
static private void enableEvent () {
|
||||
WaterCausticsEffectFeature.onCamRender -= onEnqueue;
|
||||
WaterCausticsEffectFeature.onCamRender += onEnqueue;
|
||||
}
|
||||
|
||||
static private void disableEvent () {
|
||||
Shader.DisableKeyword (KEYWORD);
|
||||
WaterCausticsEffectFeature.onCamRender -= onEnqueue;
|
||||
}
|
||||
|
||||
static private void onEnqueue (Camera cam) {
|
||||
if (cam.cameraType == CameraType.Preview)
|
||||
Shader.EnableKeyword (KEYWORD);
|
||||
else
|
||||
Shader.DisableKeyword (KEYWORD);
|
||||
}
|
||||
|
||||
public class ShaderPreprocessor : IPreprocessShaders {
|
||||
// シェーダバリアント削除
|
||||
public int callbackOrder => 1;
|
||||
public void OnProcessShader (Shader shader, ShaderSnippetData snippet, IList<ShaderCompilerData> data) {
|
||||
var deleteKeyword = new ShaderKeyword (DisableInPreviewWindow.KEYWORD);
|
||||
for (var i = data.Count - 1; i >= 0; --i)
|
||||
if (data [i].shaderKeywordSet.IsEnabled (deleteKeyword))
|
||||
data.RemoveAt (i);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8326956518b565e44a9cb612c6b7f963
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,17 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 276d321c87e0f494fb5e61d87eb50ad6, type: 3}
|
||||
m_Name: EffectModuleRef
|
||||
m_EditorClassIdentifier:
|
||||
m_effectModule: {fileID: 102900000, guid: 557c32d7360c26949947ac9dd8c308fc, type: 3}
|
||||
m_customFunc: {fileID: 102900000, guid: 5c458e7b6a8f6024aba7bed0ab7b3320, type: 3}
|
||||
m_packageForASE: {fileID: 102900000, guid: cd1a5fad241143647aa5403add1f9fd8, type: 3}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9e71d80f209a88447bb8a57499210fd2
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,25 @@
|
||||
// WaterCausticsModules
|
||||
// Copyright (c) 2021 Masataka Hakozaki
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEngine;
|
||||
|
||||
namespace MH.WaterCausticsModules {
|
||||
#if WCE_DEVELOPMENT
|
||||
[CreateAssetMenu]
|
||||
#endif
|
||||
public class EffectModuleRef : ScriptableObject {
|
||||
// WaterCausticEffectフォルダ
|
||||
[SerializeField] private Object m_effectModule;
|
||||
internal Object effectModule => m_effectModule;
|
||||
|
||||
// ShaderFunctionsフォルダ
|
||||
[SerializeField] private Object m_customFunc;
|
||||
internal Object customFunc => m_customFunc;
|
||||
|
||||
// ForAmplifyShaderEditor.unitypackageファイル
|
||||
[SerializeField] private Object m_packageForASE;
|
||||
internal Object packageForASE => m_packageForASE;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 276d321c87e0f494fb5e61d87eb50ad6
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,50 @@
|
||||
// WaterCausticsModules
|
||||
// Copyright (c) 2021 Masataka Hakozaki
|
||||
|
||||
#if UNITY_EDITOR && WCE_URP && AMPLIFY_SHADER_EDITOR
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
#pragma warning disable 162
|
||||
|
||||
namespace MH.WaterCausticsModules {
|
||||
/*------------------------------------------------------------------------
|
||||
AmplifyShaderEditorがある環境でアセットがインポートされた際、
|
||||
AmplifyShaderEditor用のカスタムファンクションパッケージを自動インポート
|
||||
-------------------------------------------------------------------------*/
|
||||
public class ImportPackageForASE {
|
||||
#if WCE_DEVELOPMENT
|
||||
static private readonly bool isDeveloping = true;
|
||||
#else
|
||||
static private readonly bool isDeveloping = false;
|
||||
#endif
|
||||
|
||||
[InitializeOnLoadMethod]
|
||||
public static void registerCallback () {
|
||||
AssetDatabase.importPackageCompleted -= importCompleted;
|
||||
AssetDatabase.importPackageCompleted += importCompleted;
|
||||
}
|
||||
|
||||
static void importCompleted (string packageName) {
|
||||
if (isDeveloping) return;
|
||||
if (Constant.CheckPackageName (packageName) && findAsset<EffectModuleRef> (out var asset, out var path) && asset.packageForASE) {
|
||||
string packagePath = AssetDatabase.GetAssetPath (asset.packageForASE);
|
||||
if (packagePath != null && packagePath.EndsWith (Constant.ASE_PACKAGE_NAME)) {
|
||||
AssetDatabase.ImportPackage (packagePath, false);
|
||||
AssetDatabase.DeleteAsset (packagePath);
|
||||
AssetDatabase.Refresh ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static private bool findAsset<T> (out T asset, out string path) where T : Object {
|
||||
asset = null;
|
||||
path = null;
|
||||
var guids = AssetDatabase.FindAssets ($"t:{typeof (T).ToString()}", new [] { "Assets" });
|
||||
if (guids.Length == 0) return false;
|
||||
path = AssetDatabase.GUIDToAssetPath (guids [0]);
|
||||
asset = AssetDatabase.LoadAssetAtPath<T> (path);
|
||||
return asset != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: abb96ab8cc4602440a3c0f2ddea9415e
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,54 @@
|
||||
// WaterCausticsModules
|
||||
// Copyright (c) 2021 Masataka Hakozaki
|
||||
|
||||
#if UNITY_EDITOR && WCE_URP
|
||||
using System.Collections.Generic;
|
||||
using UnityEditor.Build;
|
||||
using UnityEditor.Rendering;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
|
||||
namespace MH.WaterCausticsModules {
|
||||
/*------------------------------------------------------------------------
|
||||
ビルド時シェーダバリアント削除
|
||||
-------------------------------------------------------------------------*/
|
||||
public class OptimizeShader : IPreprocessShaders {
|
||||
public int callbackOrder => 1;
|
||||
|
||||
private readonly ShaderKeyword [] delKeys = {
|
||||
new ShaderKeyword ("WCE_DEBUG_NORMAL"),
|
||||
new ShaderKeyword ("WCE_DEBUG_DEPTH"),
|
||||
new ShaderKeyword ("WCE_DEBUG_FACING"),
|
||||
new ShaderKeyword ("WCE_DEBUG_CAUSTICS"),
|
||||
new ShaderKeyword ("WCE_DEBUG_AREA"),
|
||||
#if !WCE_URP_12_0 // URP12より下の場合
|
||||
new ShaderKeyword ("_GBUFFER_NORMALS_OCT"),
|
||||
new ShaderKeyword ("_LIGHT_LAYERS"),
|
||||
new ShaderKeyword ("_LIGHT_COOKIES"),
|
||||
#endif
|
||||
#if !WCE_URP_14_0 // URP14より下の場合
|
||||
new ShaderKeyword ("_FORWARD_PLUS"),
|
||||
#endif
|
||||
};
|
||||
|
||||
private bool hasDelKey (ShaderKeywordSet set) {
|
||||
foreach (var key in delKeys)
|
||||
if (set.IsEnabled (key))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
public void OnProcessShader (Shader shader, ShaderSnippetData snippet, IList<ShaderCompilerData> data) {
|
||||
// シェーダ名チェック
|
||||
if (!shader.name.StartsWith (Constant.SHADER_NAME_HEADER)) return;
|
||||
// キーを持っているか確認 & 削除
|
||||
for (var i = data.Count - 1; i >= 0; --i) {
|
||||
if (hasDelKey (data [i].shaderKeywordSet))
|
||||
data.RemoveAt (i);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cacb7892edc3def4f8111ae95a40c233
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,40 @@
|
||||
// WaterCausticsModules
|
||||
// Copyright (c) 2021 Masataka Hakozaki
|
||||
|
||||
#if UNITY_EDITOR && WCE_URP
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MH.WaterCausticsModules {
|
||||
/*------------------------------------------------------------------------
|
||||
「missing SubGraph references」エラーを防ぐため、このスクリプトが移動した
|
||||
ことを検知した際にShaderFunctionsフォルダを再インポート。
|
||||
-------------------------------------------------------------------------*/
|
||||
public class ReimportFunctions : AssetPostprocessor {
|
||||
static private readonly string classFileName = $"{typeof (ReimportFunctions).Name}.cs";
|
||||
static void OnPostprocessAllAssets (string [] imported, string [] deleted, string [] moved, string [] movedFrom) {
|
||||
// ※移動時と名称変更時、フォルダは importedAssetsとmovedAssetsに入るので注意、アセットはmovedAssetsのみ
|
||||
if (moved.Any (a => a.EndsWith (classFileName)) && !imported.Any (a => a.EndsWith (classFileName))) {
|
||||
if (findAsset<EffectModuleRef> (out var asset, out var path) && asset.customFunc) {
|
||||
var folderPath = AssetDatabase.GetAssetPath (asset.customFunc);
|
||||
if (!string.IsNullOrEmpty (folderPath) && moved.Any (a => a == folderPath)) {
|
||||
AssetDatabase.ImportAsset (folderPath, ImportAssetOptions.ImportRecursive);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static private bool findAsset<T> (out T asset, out string path) where T : Object {
|
||||
asset = null;
|
||||
path = null;
|
||||
var guids = AssetDatabase.FindAssets ($"t:{typeof (T).ToString()}", new [] { "Assets" });
|
||||
if (guids.Length == 0) return false;
|
||||
path = AssetDatabase.GUIDToAssetPath (guids [0]);
|
||||
asset = AssetDatabase.LoadAssetAtPath<T> (path);
|
||||
return asset != null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 262d8e92d9439494bbb7bb9d66dee10a
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,15 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 71d38c23289312844bc6e88159ed75c7, type: 3}
|
||||
m_Name: WaterCausticsEffectData
|
||||
m_EditorClassIdentifier:
|
||||
m_autoManageFeature: 1
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 062a4f28f6d145a4798a42cbe2bf6992
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,47 @@
|
||||
// WaterCausticsModules
|
||||
// Copyright (c) 2021 Masataka Hakozaki
|
||||
|
||||
#if UNITY_EDITOR && WCE_URP
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MH.WaterCausticsModules {
|
||||
public class WaterCausticsEffectData : ScriptableObject {
|
||||
// ---------------------------------------------------------
|
||||
[SerializeField] internal bool m_autoManageFeature = true;
|
||||
internal bool AutoManageFeature => m_autoManageFeature;
|
||||
|
||||
// ---------------------------------------------------------
|
||||
static private WaterCausticsEffectData _s_ins;
|
||||
static internal WaterCausticsEffectData GetAsset () {
|
||||
if (_s_ins) return _s_ins;
|
||||
if (findAsset<WaterCausticsEffectData> (out var ins, out var path)) return _s_ins = ins;
|
||||
return _s_ins = createAsset<WaterCausticsEffectData> ();
|
||||
}
|
||||
|
||||
static private bool findAsset<T> (out T asset, out string path) where T : Object {
|
||||
asset = null;
|
||||
path = null;
|
||||
var guids = AssetDatabase.FindAssets ($"t:{typeof (T).ToString()}", new [] { "Assets" });
|
||||
if (guids.Length == 0) return false;
|
||||
path = AssetDatabase.GUIDToAssetPath (guids [0]);
|
||||
asset = AssetDatabase.LoadAssetAtPath<T> (path);
|
||||
return asset != null;
|
||||
}
|
||||
|
||||
static private T createAsset<T> () where T : ScriptableObject {
|
||||
T asset = ScriptableObject.CreateInstance<T> ();
|
||||
MonoScript mono = MonoScript.FromScriptableObject (asset);
|
||||
string scriptPath = AssetDatabase.GetAssetPath (mono);
|
||||
string folderPath = Path.GetDirectoryName (scriptPath).Replace ("\\", "/");
|
||||
string path = $"{folderPath}/{Path.GetFileNameWithoutExtension (scriptPath)}.asset";
|
||||
AssetDatabase.CreateAsset (asset, path);
|
||||
AssetDatabase.SaveAssets ();
|
||||
return asset;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 71d38c23289312844bc6e88159ed75c7
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,935 @@
|
||||
// WaterCausticsModules
|
||||
// Copyright (c) 2021 Masataka Hakozaki
|
||||
|
||||
#if UNITY_EDITOR && WCE_URP
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text.RegularExpressions;
|
||||
using MH.WaterCausticsModules.Effect;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.Rendering.Universal;
|
||||
|
||||
namespace MH.WaterCausticsModules {
|
||||
[CanEditMultipleObjects]
|
||||
[CustomEditor (typeof (WaterCausticsEffect))]
|
||||
public class WaterCausticsEffectEditor : Editor {
|
||||
private SerializedProperty m_method;
|
||||
private SerializedProperty m_normalSrc;
|
||||
private SerializedProperty m_debugInfo;
|
||||
private SerializedProperty m_debugMode;
|
||||
private SerializedProperty m_useLayer;
|
||||
private SerializedProperty m_renderLayerMask;
|
||||
private SerializedProperty m_layerMask;
|
||||
private SerializedProperty m_clipOutside;
|
||||
private SerializedProperty m_texture;
|
||||
private SerializedProperty m_textureChannel;
|
||||
private SerializedProperty m_textureRotation;
|
||||
private SerializedProperty m_texRotSinCos;
|
||||
private SerializedProperty m_useRandomTiling;
|
||||
private SerializedProperty m_tilingSeed;
|
||||
private SerializedProperty m_tilingRotation;
|
||||
private SerializedProperty m_tilingHardness;
|
||||
private SerializedProperty m_intensity;
|
||||
private SerializedProperty m_mainLit;
|
||||
private SerializedProperty m_addLit;
|
||||
private SerializedProperty m_colorShift;
|
||||
private SerializedProperty m_colorShiftDir;
|
||||
private SerializedProperty m_scale;
|
||||
private SerializedProperty m_surfaceY;
|
||||
private SerializedProperty m_surfFadeStart;
|
||||
private SerializedProperty m_surfFadeEnd;
|
||||
private SerializedProperty m_useDepthFade;
|
||||
private SerializedProperty m_depthFadeStart;
|
||||
private SerializedProperty m_depthFadeEnd;
|
||||
private SerializedProperty m_useDistanceFade;
|
||||
private SerializedProperty m_distanceFadeStart;
|
||||
private SerializedProperty m_distanceFadeEnd;
|
||||
private SerializedProperty m_litSaturation;
|
||||
private SerializedProperty m_multiply;
|
||||
private SerializedProperty m_normalAttenRate;
|
||||
private SerializedProperty m_normalAtten;
|
||||
private SerializedProperty m_transparentBackside;
|
||||
private SerializedProperty m_backsideShadow;
|
||||
private SerializedProperty m_shadowIntensity;
|
||||
private SerializedProperty m_receiveShadows;
|
||||
private SerializedProperty m_useMainLit;
|
||||
private SerializedProperty m_useAddLit;
|
||||
private SerializedProperty m_useImageMask;
|
||||
private SerializedProperty m_imageMaskTexture;
|
||||
private SerializedProperty m_stencilRef;
|
||||
private SerializedProperty m_stencilReadMask;
|
||||
private SerializedProperty m_stencilWriteMask;
|
||||
private SerializedProperty m_stencilComp;
|
||||
private SerializedProperty m_stencilPass;
|
||||
private SerializedProperty m_stencilFail;
|
||||
private SerializedProperty m_stencilZFail;
|
||||
private SerializedProperty m_cullMode;
|
||||
private SerializedProperty m_zWriteMode;
|
||||
private SerializedProperty m_zTestMode;
|
||||
private SerializedProperty m_depthOffsetFactor;
|
||||
private SerializedProperty m_depthOffsetUnits;
|
||||
private SerializedProperty m_shader;
|
||||
private SerializedProperty m_noTexture;
|
||||
private SerializedProperty m_useCustomFunc;
|
||||
private SerializedProperty m_renderEvent;
|
||||
private SerializedProperty m_renderEventAdjust;
|
||||
|
||||
private void prepProperties () {
|
||||
if (m_method != null) return;
|
||||
m_method = serializedObject.FindProperty ("m_method");
|
||||
m_normalSrc = serializedObject.FindProperty ("m_normalSrc");
|
||||
m_debugInfo = serializedObject.FindProperty ("m_debugInfo");
|
||||
m_debugMode = serializedObject.FindProperty ("m_debugMode");
|
||||
m_useLayer = serializedObject.FindProperty ("m_useLayer");
|
||||
m_renderLayerMask = serializedObject.FindProperty ("m_renderLayerMask");
|
||||
m_layerMask = serializedObject.FindProperty ("m_layerMask");
|
||||
m_clipOutside = serializedObject.FindProperty ("m_clipOutside");
|
||||
m_texture = serializedObject.FindProperty ("m_texture");
|
||||
m_textureChannel = serializedObject.FindProperty ("m_textureChannel");
|
||||
m_textureRotation = serializedObject.FindProperty ("m_textureRotation");
|
||||
m_texRotSinCos = serializedObject.FindProperty ("m_texRotSinCos");
|
||||
m_useRandomTiling = serializedObject.FindProperty ("m_useRandomTiling");
|
||||
m_tilingSeed = serializedObject.FindProperty ("m_tilingSeed");
|
||||
m_tilingRotation = serializedObject.FindProperty ("m_tilingRotation");
|
||||
m_tilingHardness = serializedObject.FindProperty ("m_tilingHardness");
|
||||
m_intensity = serializedObject.FindProperty ("m_intensity");
|
||||
m_mainLit = serializedObject.FindProperty ("m_mainLit");
|
||||
m_addLit = serializedObject.FindProperty ("m_addLit");
|
||||
m_colorShift = serializedObject.FindProperty ("m_colorShift");
|
||||
m_colorShiftDir = serializedObject.FindProperty ("m_colorShiftDir");
|
||||
m_scale = serializedObject.FindProperty ("m_scale");
|
||||
m_surfaceY = serializedObject.FindProperty ("m_surfaceY");
|
||||
m_surfFadeStart = serializedObject.FindProperty ("m_surfFadeStart");
|
||||
m_surfFadeEnd = serializedObject.FindProperty ("m_surfFadeEnd");
|
||||
m_useDepthFade = serializedObject.FindProperty ("m_useDepthFade");
|
||||
m_depthFadeStart = serializedObject.FindProperty ("m_depthFadeStart");
|
||||
m_depthFadeEnd = serializedObject.FindProperty ("m_depthFadeEnd");
|
||||
m_useDistanceFade = serializedObject.FindProperty ("m_useDistanceFade");
|
||||
m_distanceFadeStart = serializedObject.FindProperty ("m_distanceFadeStart");
|
||||
m_distanceFadeEnd = serializedObject.FindProperty ("m_distanceFadeEnd");
|
||||
m_litSaturation = serializedObject.FindProperty ("m_litSaturation");
|
||||
m_multiply = serializedObject.FindProperty ("m_multiply");
|
||||
m_normalAttenRate = serializedObject.FindProperty ("m_normalAttenRate");
|
||||
m_normalAtten = serializedObject.FindProperty ("m_normalAtten");
|
||||
m_transparentBackside = serializedObject.FindProperty ("m_transparentBackside");
|
||||
m_backsideShadow = serializedObject.FindProperty ("m_backsideShadow");
|
||||
m_shadowIntensity = serializedObject.FindProperty ("m_shadowIntensity");
|
||||
m_receiveShadows = serializedObject.FindProperty ("m_receiveShadows");
|
||||
m_useMainLit = serializedObject.FindProperty ("m_useMainLit");
|
||||
m_useAddLit = serializedObject.FindProperty ("m_useAddLit");
|
||||
m_useImageMask = serializedObject.FindProperty ("m_useImageMask");
|
||||
m_imageMaskTexture = serializedObject.FindProperty ("m_imageMaskTexture");
|
||||
m_stencilRef = serializedObject.FindProperty ("m_stencilRef");
|
||||
m_stencilReadMask = serializedObject.FindProperty ("m_stencilReadMask");
|
||||
m_stencilWriteMask = serializedObject.FindProperty ("m_stencilWriteMask");
|
||||
m_stencilComp = serializedObject.FindProperty ("m_stencilComp");
|
||||
m_stencilPass = serializedObject.FindProperty ("m_stencilPass");
|
||||
m_stencilFail = serializedObject.FindProperty ("m_stencilFail");
|
||||
m_stencilZFail = serializedObject.FindProperty ("m_stencilZFail");
|
||||
m_cullMode = serializedObject.FindProperty ("m_cullMode");
|
||||
m_zWriteMode = serializedObject.FindProperty ("m_zWriteMode");
|
||||
m_zTestMode = serializedObject.FindProperty ("m_zTestMode");
|
||||
m_depthOffsetFactor = serializedObject.FindProperty ("m_depthOffsetFactor");
|
||||
m_depthOffsetUnits = serializedObject.FindProperty ("m_depthOffsetUnits");
|
||||
m_shader = serializedObject.FindProperty ("m_shader");
|
||||
m_noTexture = serializedObject.FindProperty ("m_noTexture");
|
||||
m_useCustomFunc = serializedObject.FindProperty ("m_useCustomFunc");
|
||||
m_renderEvent = serializedObject.FindProperty ("m_renderEvent");
|
||||
m_renderEventAdjust = serializedObject.FindProperty ("m_renderEventAdjust");
|
||||
}
|
||||
|
||||
private SerializedObject _wceData;
|
||||
private SerializedProperty m_autoManageFeature;
|
||||
private SerializedObject prepWceData () {
|
||||
if (_wceData == null)
|
||||
_wceData = new SerializedObject (WaterCausticsEffectData.GetAsset ());
|
||||
if (m_autoManageFeature == null) {
|
||||
m_autoManageFeature = _wceData.FindProperty ("m_autoManageFeature");
|
||||
}
|
||||
_wceData.Update ();
|
||||
return _wceData;
|
||||
}
|
||||
|
||||
static readonly GUIContent [] _cullingEnumStr = {
|
||||
new GUIContent ("Both"),
|
||||
new GUIContent ("Back"),
|
||||
new GUIContent ("Front"),
|
||||
};
|
||||
|
||||
static readonly string descGenFromDepth = "[Generate from Depth] \nGenerate from _CameraDepthTexture generated by the system. This method is not good for smooth surfaces, but it does produce the correct normals.";
|
||||
static readonly string descCamNormalTex = "[Camera Normals Tex] \nSampling _CameraNormalsTexture generated by the system. This is high quality, but may produce strange results with materials that do not support normal output.";
|
||||
|
||||
static readonly GUIContent [] _normalSrcStr = {
|
||||
new GUIContent ("Generate from Depth (LQ)", $"{descGenFromDepth}\n\n{descCamNormalTex}"),
|
||||
new GUIContent ("Camera Normals Tex (HQ)", $"{descGenFromDepth}\n\n{descCamNormalTex}"),
|
||||
};
|
||||
|
||||
static readonly string [] _renderingLayerMaskNamesSpare = { "Layer1", "Layer2", "Layer3", "Layer4", "Layer5", "Layer6", "Layer7", "Layer8", "Layer9", "Layer10", "Layer11", "Layer12", "Layer13", "Layer14", "Layer15", "Layer16", "Layer17", "Layer18", "Layer19", "Layer20", "Layer21", "Layer22", "Layer23", "Layer24", "Layer25", "Layer26", "Layer27", "Layer28", "Layer29", "Layer30", "Layer31", "Layer32", };
|
||||
|
||||
private List<ScriptableRendererData> _rendererDataList;
|
||||
private bool _hasGetRenderData;
|
||||
|
||||
protected virtual void OnEnable () {
|
||||
foreach (var tar in targets.OfType<WaterCausticsEffect> ())
|
||||
tar.VersionCheck ();
|
||||
}
|
||||
|
||||
UniversalRenderPipelineAsset urpAsset => GraphicsSettings.currentRenderPipeline as UniversalRenderPipelineAsset;
|
||||
public override void OnInspectorGUI () {
|
||||
if (urpAsset) {
|
||||
var wceData = prepWceData ();
|
||||
prepProperties ();
|
||||
serializedObject.Update ();
|
||||
using (var check = new EditorGUI.ChangeCheckScope ()) {
|
||||
drawProperties ();
|
||||
serializedObject.ApplyModifiedProperties ();
|
||||
wceData.ApplyModifiedProperties ();
|
||||
if (check.changed) {
|
||||
foreach (var tar in targets.OfType<WaterCausticsEffect> ())
|
||||
tar.OnInspectorChanged ();
|
||||
}
|
||||
}
|
||||
} else {
|
||||
// -- URP設定が完了していない場合
|
||||
onInspectorGUI_NotSettingYet ();
|
||||
}
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
readonly Color colorPinkBar = new Color (1f, 0.3f, 0.6f, 0.3f);
|
||||
readonly Color colorPinkContent = new Color (1f, 0.3f, 0.6f, 1f);
|
||||
readonly Color colorGreenContent = new Color (0.4f, 1f, 0.7f, 1f);
|
||||
private float lineH = EditorGUIUtility.singleLineHeight + 2;
|
||||
readonly float SPACE_SUB_TOP_5 = 5f;
|
||||
readonly float SPACE_SUB_BTM_12 = 12f;
|
||||
readonly float SPACE_MAIN_TOP_7 = 7f;
|
||||
readonly float SPACE_MAIN_BTM_5 = 5f;
|
||||
private Color _defaultGUIColor;
|
||||
|
||||
private void setLabelAreaWidth (float labelWidthMin, float valWidthMin) {
|
||||
if (EditorGUIUtility.labelWidth < labelWidthMin)
|
||||
EditorGUIUtility.labelWidth = labelWidthMin;
|
||||
if (EditorGUIUtility.currentViewWidth - EditorGUIUtility.labelWidth < valWidthMin)
|
||||
EditorGUIUtility.labelWidth = EditorGUIUtility.currentViewWidth - valWidthMin;
|
||||
}
|
||||
|
||||
private void drawProperties () {
|
||||
_defaultGUIColor = GUI.color;
|
||||
storeIndentWidth ();
|
||||
EditorGUIUtility.labelWidth += 6;
|
||||
EditorGUI.indentLevel++;
|
||||
setLabelAreaWidth (labelWidthMin: 140f, valWidthMin: 170f);
|
||||
bool isEditingMultiObj = serializedObject.isEditingMultipleObjects;
|
||||
bool isMethodEach = (m_method.enumValueIndex == (int) Method.EachMesh && !m_method.hasMultipleDifferentValues);
|
||||
bool isMethodOnce = (m_method.enumValueIndex == (int) Method.AtOnce && !m_method.hasMultipleDifferentValues);
|
||||
// ---------------------------------------------------------------------------------- System
|
||||
|
||||
// ------ RendererFeature
|
||||
if (!_hasGetRenderData) {
|
||||
_hasGetRenderData = true;
|
||||
WaterCausticsEffectFeatureEditor.GetAllRendererData (out _rendererDataList);
|
||||
if (WaterCausticsEffectData.GetAsset ().AutoManageFeature)
|
||||
WaterCausticsEffectFeatureEditor.AddFeatureToAllRenderers (_rendererDataList, useUndo : false);
|
||||
}
|
||||
bool someRenderNotHasFeature = !WaterCausticsEffectFeatureEditor.CheckAllHasActiveFeature (_rendererDataList);
|
||||
bool currentRenderNotHasFeature = someRenderNotHasFeature && !WaterCausticsEffectFeature.effective;
|
||||
// ----------------------
|
||||
|
||||
if (expandMainGroup (m_method, true, "System", isPink : currentRenderNotHasFeature)) {
|
||||
EditorGUILayout.Space (SPACE_MAIN_TOP_7);
|
||||
|
||||
// ------ RendererFeature
|
||||
if (someRenderNotHasFeature) {
|
||||
EditorGUI.indentLevel -= 1;
|
||||
// labelWarning("To apply this effect, a Renderer Feature needs to be added to a Renderer.", 11);
|
||||
using (new ColorScope (currentRenderNotHasFeature ? colorPinkContent : _defaultGUIColor)) {
|
||||
string str = "To apply this effect, a Renderer Feature needs to be added to a Renderer.";
|
||||
if (currentRenderNotHasFeature)
|
||||
EditorGUILayout.HelpBox ($"The Renderer Feature has not been added or activated in the current Renderer.\n{str}", MessageType.Warning);
|
||||
else
|
||||
EditorGUILayout.HelpBox ($"The Renderer Feature has not been added or activated in some Renderers.\n{str}", MessageType.Warning);
|
||||
EditorGUILayout.Space (2);
|
||||
Rect rect = GUILayoutUtility.GetRect (0, 0);
|
||||
rect.height = lineH;
|
||||
rect.width *= 0.5f;
|
||||
if (GUI.Button (rect, new GUIContent ("Select Renderer", "Search and select RendererData assets."), EditorStyles.miniButton)) {
|
||||
// -- 選択ボタン
|
||||
if (WaterCausticsEffectFeatureEditor.GetAllRendererData (out var list)) {
|
||||
// -- 成功
|
||||
WaterCausticsEffectFeatureEditor.SelectAndPing (list);
|
||||
if (list.Count >= 2) {
|
||||
var pathStr = WaterCausticsEffectFeatureEditor.AssetsToPathStr (list);
|
||||
EditorApplication.delayCall += () => EditorApplication.delayCall += () =>
|
||||
EditorUtility.DisplayDialog ("Multiple found.", $"Multiple RendererData assets found.\n\n{pathStr}", "OK");
|
||||
}
|
||||
} else {
|
||||
// -- 見つからない
|
||||
EditorUtility.DisplayDialog ("Not found.", $"Not found.", "OK");
|
||||
}
|
||||
}
|
||||
rect.x += rect.width;
|
||||
if (GUI.Button (rect, new GUIContent ("Fix It", "Add a Renderer Feature to Renderers."), EditorStyles.miniButton)) {
|
||||
// -- 追加ボタン
|
||||
if (WaterCausticsEffectFeatureEditor.AddFeatureToAllRenderers (useUndo: true)) {
|
||||
// -- 成功
|
||||
} else {
|
||||
// -- 失敗
|
||||
bool showURL = EditorUtility.DisplayDialog ("Failed", "Processing failed. Please add the Renderer Feature to Renderers manually.", "Open URP Manual", "Cancel");
|
||||
if (showURL) Application.OpenURL (Constant.URL_HOW_TO_ADD_FEATURE);
|
||||
}
|
||||
}
|
||||
EditorGUILayout.Space (lineH);
|
||||
using (new ColorScope (_defaultGUIColor)) {
|
||||
EditorGUILayout.Space (1);
|
||||
if (labelLink (new GUIContent ("How to add Renderer Feature to Renderer", Constant.URL_HOW_TO_ADD_FEATURE), 10))
|
||||
Application.OpenURL (Constant.URL_HOW_TO_ADD_FEATURE);
|
||||
EditorGUILayout.Space (4);
|
||||
}
|
||||
EditorGUI.indentLevel += 1;
|
||||
EditorGUILayout.Space (15);
|
||||
}
|
||||
}
|
||||
// ----------------------
|
||||
|
||||
EditorGUILayout.PropertyField (m_method, new GUIContent ("Effect Method", "[At Once]\nDraws the effect at once using the camera's depth and normal texture. It can also be applied to objects with materials that are deformed by shaders. \n\n[Each Mesh]\nDraws effects to each mesh. Masking with layers and the surface to be drawn can be specified. However, it cannot be applied to objects with materials that deform with shaders. For such objects, embed custom function in the shader or use the At Once method."));
|
||||
if (isMethodOnce) {
|
||||
using (new IndentScope (-2f, 0f)) {
|
||||
popup (m_normalSrc, _normalSrcStr, "Normal Data", $"How to get normal vector in world space.\n\n{descGenFromDepth}\n\n{descCamNormalTex}");
|
||||
}
|
||||
}
|
||||
drawBoolAndValue (m_debugInfo, m_debugMode, true, new GUIContent ("Debug Info", "Display data for debugging. This is only valid on the editor.\n\n" +
|
||||
$"[{DebugMode.Normal}]\nDisplays world-space normal data.\n\n" +
|
||||
$"[{DebugMode.Depth}]\nDisplays the depth data.\n\n" +
|
||||
$"[{DebugMode.Facing}]\nDisplays the plane facing the camera as bright.\n\n" +
|
||||
$"[{DebugMode.Caustics}]\nDisplays only caustics effects.\n\n" +
|
||||
$"[{DebugMode.LightArea}]\nDisplays the affected area by each light.\n\n" +
|
||||
$"If some objects are not rendering correctly on At Once method with Camera Normals Tex, the object's material is outputting the wrong normals. Check the normals on this screen and modify the material (shader) of the object."));
|
||||
|
||||
EditorGUILayout.Space (SPACE_SUB_BTM_12);
|
||||
// ---------------------------------------------------------------------------------- Influence Scope
|
||||
if (expandSubGroup (m_useImageMask, true, "Influence Scope")) {
|
||||
EditorGUILayout.Space (SPACE_SUB_TOP_5);
|
||||
selectGameObjectLayer (new GUIContent ("Layer", "The layer in which this effect exists."));
|
||||
if (isMethodEach) {
|
||||
EditorGUILayout.PropertyField (m_layerMask, new GUIContent ("Layer Mask", "Specify the layer on which the effect will be drawn. Objects on unchecked layers will be ignored."));
|
||||
}
|
||||
if (isMethodEach) {
|
||||
EditorGUILayout.PropertyField (m_clipOutside, new GUIContent ("Clip Outside", "Draw effects only inside the volume."));
|
||||
}
|
||||
drawBoolAndValue (m_useImageMask, m_imageMaskTexture, hide : true, new GUIContent ("Image Mask", "Masking with an image."));
|
||||
|
||||
if (isMethodEach) {
|
||||
popup (m_cullMode, _cullingEnumStr, "Render Face", "Which face to draw.");
|
||||
}
|
||||
|
||||
// EditorGUILayout.Space (2);
|
||||
// if (isExpand (m_renderEventAdjust, false, new GUIContent ("Advanced", "Advanced Settings"))) {
|
||||
// using (new IndentScope (0f, 0f)) {
|
||||
EditorGUILayout.PropertyField (m_useCustomFunc, new GUIContent ("Custom Function", "Supports Custom Function for shader. \nTransmits the settings to the WaterCausticsEmissionSync function embedded in the shader. \nTurning this On will copy the settings to a global shader variable. \n\nIf there are multiple effects with this setting On in a scene, the last active effect will be used."));
|
||||
|
||||
{
|
||||
// 描画タイミング設定
|
||||
bool isExpanded = isExpand (m_renderEvent, true, new GUIContent (""));
|
||||
EditorGUILayout.Space (-EditorGUIUtility.singleLineHeight - 2f);
|
||||
string baseTimingName = splitCamelCase (((RenderPassEvent) m_renderEvent.intValue).ToString ());
|
||||
int sysOpqTiming = (int) WaterCausticsEffect.SYS_OPAQUE_TEX_EVENT;
|
||||
string sysOpqName = WaterCausticsEffect.SYS_OPAQUE_TEX_EVENT.ToString ();
|
||||
string sysOpqDesc = $"{sysOpqName}({sysOpqTiming})";
|
||||
string sysOpqDescPlusOne = $"{sysOpqName}+1 ({sysOpqTiming+1})";
|
||||
string defaultTiming = WaterCausticsEffect.RENDER_EVENT.ToString ();
|
||||
int defaultTimingAdj = WaterCausticsEffect.RENDER_EVENT_ADJ;
|
||||
int baseTiming = m_renderEvent.intValue;
|
||||
int adjTiming = m_renderEventAdjust.intValue;
|
||||
int adjusted = baseTiming + adjTiming;
|
||||
bool isHasDifVal = m_renderEvent.hasMultipleDifferentValues || m_renderEventAdjust.hasMultipleDifferentValues;
|
||||
EditorGUILayout.LabelField (new GUIContent ("Draw Timing", $"Specifies the timing of drawing.\n\nTo display this effect on _CameraOpaqueTexture, it must be drawn before {sysOpqDesc}."), new GUIContent (isHasDifVal ? "-" : $"{baseTimingName} {(adjTiming < 0 ? "-" : "+")}{Mathf.Abs(adjTiming)} ({Mathf.Clamp(adjusted, 0, 1000)})"));
|
||||
if (isExpanded) {
|
||||
using (new IndentScope (-2f, 4f)) {
|
||||
EditorGUILayout.PropertyField (m_renderEvent, new GUIContent ($"Render Event", $"Controls when the render executes. \n[Default: {defaultTiming}]"));
|
||||
EditorGUILayout.PropertyField (m_renderEventAdjust, new GUIContent ("Adjustment", $"Controls when the render executes. This number is added to the Draw Timing above. \n[Default: {defaultTimingAdj}]"));
|
||||
bool isEarly = (adjusted <= sysOpqTiming);
|
||||
string warning = isEarly ? $"To use a value between 0 and 1 in the Multiply Color setting, set it after {sysOpqDescPlusOne}." :
|
||||
$"To display this effect on _CameraOpaqueTexture, it must be drawn before {sysOpqDesc}.";
|
||||
EditorGUILayout.HelpBox (new GUIContent (warning, ""), true);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (isMethodOnce) {
|
||||
var names = urpAsset.renderingLayerMaskNames;
|
||||
if (names == null) names = _renderingLayerMaskNamesSpare;
|
||||
bitMask (m_renderLayerMask, names, "Render Mask", "Rendering Layer Mask of this effect. It works as same as RenderingLayerMask of MeshRenderer.");
|
||||
}
|
||||
if (isMethodEach) {
|
||||
if (isExpand (m_zTestMode, false, new GUIContent ("Depth Buffer", "Adjust Depth Testing and Depth Offset."))) {
|
||||
using (new IndentScope (0, 2)) {
|
||||
EditorGUILayout.PropertyField (m_zWriteMode, new GUIContent ("ZWrite", "Whether to write depth values to the depth buffer."));
|
||||
EditorGUILayout.PropertyField (m_zTestMode, new GUIContent ("ZTest", "Comparison method with already existing depth values."));
|
||||
EditorGUILayout.PropertyField (m_depthOffsetFactor, new GUIContent ("Offset Factor", "Offset Factor"));
|
||||
EditorGUILayout.PropertyField (m_depthOffsetUnits, new GUIContent ("Offset Units", "Offset Units"));
|
||||
}
|
||||
}
|
||||
EditorGUILayout.Space (2);
|
||||
}
|
||||
if (isExpand (m_stencilRef, false, new GUIContent ("Stencil Buffer", "The Stencil Buffer can be used to limit the objects to be drawn or used for subsequent effects."))) {
|
||||
using (new IndentScope (0, 2)) {
|
||||
EditorGUILayout.PropertyField (m_stencilRef, new GUIContent ("Ref", "Stencil Reference Value"));
|
||||
EditorGUILayout.PropertyField (m_stencilReadMask, new GUIContent ("ReadMask", "Stencil Read Mask"));
|
||||
EditorGUILayout.PropertyField (m_stencilWriteMask, new GUIContent ("WriteMask", "Stencil Write Mask"));
|
||||
EditorGUILayout.PropertyField (m_stencilComp, new GUIContent ("Comp", "Stencil Compare Operation"));
|
||||
EditorGUILayout.PropertyField (m_stencilPass, new GUIContent ("Pass", "Stencil Pass Operation"));
|
||||
EditorGUILayout.PropertyField (m_stencilFail, new GUIContent ("Fail", "Stencil Fail Operation"));
|
||||
EditorGUILayout.PropertyField (m_stencilZFail, new GUIContent ("ZFail", "Stencil Z Fail Operation"));
|
||||
}
|
||||
}
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
EditorGUILayout.Space (SPACE_SUB_BTM_12);
|
||||
}
|
||||
|
||||
EditorGUILayout.Space (SPACE_MAIN_BTM_5);
|
||||
// ---------------------------------------------------------------------------------- Effect Group
|
||||
bool useTextureWarning = (m_texture.objectReferenceValue == null && isGameObjectOnScene () && !isEditingMultiObj);
|
||||
if (expandMainGroup (m_texture, true, "Caustics Effect", isPink : useTextureWarning && m_texture.isExpanded)) {
|
||||
EditorGUILayout.Space (SPACE_MAIN_TOP_7);
|
||||
|
||||
if (expandSubGroup (m_textureRotation, true, "Texture", isPink : useTextureWarning)) {
|
||||
EditorGUILayout.Space (SPACE_SUB_TOP_5);
|
||||
|
||||
using (new ColorScope (useTextureWarning?colorPinkContent : GUI.color)) {
|
||||
EditorGUILayout.PropertyField (m_texture, new GUIContent ("Caustics Texture", $"Set the RenderTexture specified as the output destination in the {typeof(WaterCausticsTexGenerator).Name}."));
|
||||
if (!m_texture.hasMultipleDifferentValues) {
|
||||
if (useTextureWarning) {
|
||||
EditorGUILayout.Space (1);
|
||||
EditorGUILayout.BeginHorizontal ();
|
||||
GUILayout.FlexibleSpace ();
|
||||
if (GUILayout.Button ("Search from this Scene", EditorStyles.miniButton, GUILayout.Width (150))) {
|
||||
var gen = FindObjectsOfType<WaterCausticsTexGenerator> ().FirstOrDefault (g => g.renderTexture != null);
|
||||
if (gen != null)
|
||||
m_texture.objectReferenceValue = gen.renderTexture;
|
||||
else
|
||||
EditorUtility.DisplayDialog ("Not Found", $"There is no {typeof(WaterCausticsTexGenerator).Name} with active and having RenderTexture in this scene.", "OK");
|
||||
}
|
||||
EditorGUILayout.EndHorizontal ();
|
||||
EditorGUILayout.Space (3);
|
||||
} else {
|
||||
var tex = m_texture.objectReferenceValue as Texture;
|
||||
if (tex != null) {
|
||||
EditorGUILayout.HelpBox ($"{tex.width}x{tex.height} / {tex.graphicsFormat}", MessageType.None);
|
||||
EditorGUILayout.Space (3);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
EditorGUILayout.PropertyField (m_textureChannel, new GUIContent ("Channel", "Channels to be used. Set to R if using R-channel only textures."));
|
||||
using (var check = new EditorGUI.ChangeCheckScope ()) {
|
||||
using (new IndentScope (0f, 0f, 1)) {
|
||||
EditorGUILayout.PropertyField (m_textureRotation, new GUIContent ("Rotation", "Rotate the texture."));
|
||||
drawDirMark (m_textureRotation, true);
|
||||
}
|
||||
if (check.changed) {
|
||||
float rad = m_textureRotation.floatValue * Mathf.Deg2Rad;
|
||||
m_texRotSinCos.vector2Value = new Vector2 (Mathf.Sin (rad), Mathf.Cos (rad));
|
||||
}
|
||||
}
|
||||
EditorGUILayout.PropertyField (m_useRandomTiling, new GUIContent ("Random Tiling", "Use randomized hexagonal tiling. This reduces unnatural repetitions that appear on distant planes."));
|
||||
if (m_useRandomTiling.boolValue) {
|
||||
using (new IndentScope (-2f, 0f)) {
|
||||
EditorGUILayout.PropertyField (m_tilingSeed, new GUIContent ("Seed", "Random seed value."));
|
||||
EditorGUILayout.PropertyField (m_tilingHardness, new GUIContent ("Hardness", "Edge hardness."));
|
||||
EditorGUILayout.PropertyField (m_tilingRotation, new GUIContent ("Rotation", "Rotate tiles randomly."));
|
||||
}
|
||||
}
|
||||
EditorGUILayout.Space (SPACE_SUB_BTM_12);
|
||||
}
|
||||
|
||||
if (expandSubGroup (m_scale, true, "Dimensions")) {
|
||||
EditorGUILayout.Space (SPACE_SUB_TOP_5);
|
||||
|
||||
EditorGUILayout.PropertyField (m_scale, new GUIContent ("Scale", "Texture size at the height of the water surface."));
|
||||
EditorGUILayout.PropertyField (m_surfaceY, new GUIContent ("Water Surface Y", "Height of the water surface. Y-axis. The projected position of the light is calculated with respect to this plane."));
|
||||
|
||||
EditorGUILayout.Space (4);
|
||||
drawStartEndProp (m_surfFadeStart, m_surfFadeEnd, new GUIContent ("Surface Fade", "Attenuates light as it approaches the surface of the water."));
|
||||
EditorGUILayout.PropertyField (m_useDepthFade, new GUIContent ("Depth Fade", "Attenuates light as depth increases."));
|
||||
if (m_useDepthFade.boolValue) {
|
||||
using (new IndentScope (-2f, 0f))
|
||||
drawStartEndProp (m_depthFadeStart, m_depthFadeEnd, new GUIContent ("Range", "Attenuates light as depth increases."));
|
||||
}
|
||||
EditorGUILayout.PropertyField (m_useDistanceFade, new GUIContent ("Distance Fade", "Attenuates light as distance increases."));
|
||||
if (m_useDistanceFade.boolValue) {
|
||||
using (new IndentScope (-2f, 0f))
|
||||
drawStartEndProp (m_distanceFadeStart, m_distanceFadeEnd, new GUIContent ("Range", "Attenuates light as distance increases."));
|
||||
}
|
||||
|
||||
EditorGUILayout.Space (SPACE_SUB_BTM_12);
|
||||
}
|
||||
if (expandSubGroup (m_intensity, true, "Effect")) {
|
||||
EditorGUILayout.Space (SPACE_SUB_TOP_5);
|
||||
|
||||
EditorGUILayout.PropertyField (m_intensity, new GUIContent ("Intensity", "Intensity of effect."));
|
||||
using (new IndentScope (-1f, 1f)) {
|
||||
drawBoolAndValue (m_useMainLit, m_mainLit, hide : true, new GUIContent ("Main Light", "Adjust the intensity of the main light. If the checkbox is Off, the main light calculation is skipped."));
|
||||
drawBoolAndValue (m_useAddLit, m_addLit, hide : true, new GUIContent ("Additional Lights", "Adjust the intensity of the additional lights. If the check box is Off, the calculation of additional lights is skipped."));
|
||||
}
|
||||
EditorGUILayout.Space (2);
|
||||
|
||||
drawBoolAndValue (m_receiveShadows, m_shadowIntensity, hide : true, new GUIContent ("Shadow", "Strength of shadow. If the checkbox is unchecked, the shadow calculation is skipped. \n\nFor the At Once method, \"Transparent Receive Shadows\" in the URP settings must also be set to On."));
|
||||
EditorGUILayout.Space (2);
|
||||
EditorGUILayout.PropertyField (m_colorShift, new GUIContent ("Color Shift", "Amount of RGB channel shift."));
|
||||
if (m_colorShift.floatValue > 0f) {
|
||||
using (new IndentScope (-2f, 0f, 2)) {
|
||||
EditorGUILayout.PropertyField (m_colorShiftDir, new GUIContent ("Direction", "Direction of shift for RGB channels."));
|
||||
drawDirMark (m_colorShiftDir, true);
|
||||
}
|
||||
}
|
||||
EditorGUILayout.Space (2);
|
||||
|
||||
EditorGUILayout.PropertyField (m_litSaturation, new GUIContent ("Light Color", "Color intensity of the light."));
|
||||
EditorGUILayout.Space (2);
|
||||
EditorGUILayout.PropertyField (m_multiply, new GUIContent ("Multiply Color", "Multiply by the screen color and then add. \nIf this value is 1 or 0, it is processed faster because it uses the shader's Blend function. Otherwise, _CameraOpaqueTexture is sampled and multiplied. If the Draw Timing setting is before _CameraOpaqueTexture is drawn, it is processed as 1."));
|
||||
if (!isEditingMultiObj && (m_multiply.floatValue > 0f && m_multiply.floatValue < 1f) &&
|
||||
((m_renderEvent.intValue + m_renderEventAdjust.intValue) <= (int) WaterCausticsEffect.SYS_OPAQUE_TEX_EVENT)
|
||||
) {
|
||||
// 描画タイミングが早すぎる場合警告
|
||||
using (new IndentScope (0f, 0f)) {
|
||||
EditorGUILayout.HelpBox (new GUIContent ("Only 0 or 1 is valid because the Draw Timing is too early.", "Draw Timing in Influence Scope settings is too early and _CameraOpaqueTexture does not exist, so it cannot be drawn with a setting between 0 and 1. Therefore, it is drawn as 1."), true);
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.Space (3);
|
||||
EditorGUILayout.PropertyField (m_normalAtten, new GUIContent ("Normal Attenuation", "Attenuation due to the angle between the normal and the light ray. \n[Default: 1]")); {
|
||||
using (new IndentScope (-2f, 2f)) {
|
||||
using (new DisableScope (m_normalAtten.floatValue > 0f)) {
|
||||
EditorGUILayout.PropertyField (m_normalAttenRate, new GUIContent ("Rate", "Rate of normal attenuation. How quickly does the light fade. \n[Default: 1.5]"));
|
||||
EditorGUILayout.PropertyField (m_transparentBackside, new GUIContent ("Transparent", "The intensity of light transmitted to the backside. \n[Default: 0]"));
|
||||
}
|
||||
using (new DisableScope (m_receiveShadows.boolValue && (m_normalAtten.floatValue < 1f || m_transparentBackside.floatValue > 0f))) {
|
||||
EditorGUILayout.PropertyField (m_backsideShadow, new GUIContent ("Backside Shadow", "The intensity of shadow on the backside. \n[Default: 0]"));
|
||||
}
|
||||
}
|
||||
}
|
||||
EditorGUILayout.Space (SPACE_SUB_BTM_12);
|
||||
}
|
||||
}
|
||||
|
||||
EditorGUILayout.Space (SPACE_MAIN_BTM_5);
|
||||
// ---------------------------------------------------------------------------------- Advanced Settings
|
||||
if (expandMainGroup (m_backsideShadow, false, "Advanced Settings")) {
|
||||
EditorGUILayout.Space (SPACE_MAIN_TOP_7);
|
||||
|
||||
if (expandSubGroup (m_normalAttenRate, false, "Renderer Feature")) {
|
||||
EditorGUILayout.Space (SPACE_SUB_TOP_5);
|
||||
using (var check = new EditorGUI.ChangeCheckScope ()) {
|
||||
EditorGUILayout.PropertyField (m_autoManageFeature, new GUIContent ("Auto-Management", "Automatically manages Renderer Feature. It automatically adds the Renderer Feature for this effect to all Renderer Data in the project.\n\nIf this is turned off, it is required to manually add the Renderer Feature to the Renderer Data."));
|
||||
if (check.changed && m_autoManageFeature.boolValue == true) {
|
||||
WaterCausticsEffectFeatureEditor.AddFeatureToAllRenderers (useUndo: false);
|
||||
}
|
||||
if (!m_autoManageFeature.boolValue) {
|
||||
EditorGUILayout.Space (1);
|
||||
EditorGUI.indentLevel++;
|
||||
EditorGUILayout.HelpBox ("To apply this effect, a Renderer Feature needs to be added to a Renderer.", MessageType.None);
|
||||
EditorGUILayout.Space (1);
|
||||
if (labelLink (new GUIContent ("How to add Renderer Feature to Renderer", Constant.URL_HOW_TO_ADD_FEATURE), 10, 2))
|
||||
Application.OpenURL (Constant.URL_HOW_TO_ADD_FEATURE);
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
}
|
||||
EditorGUILayout.Space (SPACE_SUB_BTM_12);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
EditorGUILayout.Space (SPACE_SUB_BTM_12);
|
||||
EditorGUILayout.Space (SPACE_MAIN_BTM_5);
|
||||
EditorGUILayout.Space (SPACE_MAIN_BTM_5);
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------- Parts
|
||||
private string splitCamelCase (string str) {
|
||||
return Regex.Replace (
|
||||
Regex.Replace (str, @"(\P{Ll})(\P{Ll}\p{Ll})", "$1 $2"), @"(\p{Ll})(\P{Ll})", "$1 $2");
|
||||
}
|
||||
|
||||
private float _indentWidth;
|
||||
private void storeIndentWidth () {
|
||||
if (_indentWidth != 0f) return;
|
||||
var x0 = EditorGUI.IndentedRect (Rect.zero).x;
|
||||
EditorGUI.indentLevel++;
|
||||
_indentWidth = EditorGUI.IndentedRect (Rect.zero).x - x0;
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
private void drawBoolAndValue (SerializedProperty propBool, SerializedProperty propValue, bool hide, GUIContent label) {
|
||||
EditorGUILayout.PropertyField (propBool, label);
|
||||
var rect = GUILayoutUtility.GetLastRect ();
|
||||
var labelW = EditorGUIUtility.labelWidth;
|
||||
if (!hide || propBool.boolValue) {
|
||||
using (new DisableScope (propBool.boolValue)) {
|
||||
EditorGUIUtility.labelWidth += 25;
|
||||
EditorGUI.PropertyField (rect, propValue, new GUIContent (" "));
|
||||
}
|
||||
}
|
||||
EditorGUIUtility.labelWidth = labelW;
|
||||
}
|
||||
|
||||
private void selectGameObjectLayer (GUIContent label) {
|
||||
var gameObjects = targets.Select (t => (t as WaterCausticsEffect).gameObject).ToArray ();
|
||||
var layers = gameObjects.Select (go => go.layer).Distinct ().ToArray ();
|
||||
using (var check = new EditorGUI.ChangeCheckScope ()) {
|
||||
EditorGUI.showMixedValue = (layers.Length != 1);
|
||||
int newVal = EditorGUILayout.LayerField (label, layers [0]);
|
||||
EditorGUI.showMixedValue = false;
|
||||
if (check.changed) {
|
||||
Undo.RecordObjects (gameObjects, "Changed Layer");
|
||||
foreach (var go in gameObjects) {
|
||||
go.layer = newVal;
|
||||
EditorUtility.SetDirty (go);
|
||||
}
|
||||
if (layers.Length >= 2 && gameObjects.Length == Selection.objects.Length) {
|
||||
// 上部のレイヤー表示Multiple(-)を更新するため選択中の場合は再選択
|
||||
bool isSelected = true;
|
||||
foreach (var o in gameObjects) {
|
||||
if (!Selection.objects.Contains (o)) {
|
||||
isSelected = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isSelected) {
|
||||
Selection.activeGameObject = null;
|
||||
EditorApplication.delayCall += () => { Selection.objects = gameObjects; };
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void selectLayer (SerializedProperty prop, GUIContent label) {
|
||||
using (var check = new EditorGUI.ChangeCheckScope ()) {
|
||||
EditorGUI.showMixedValue = prop.hasMultipleDifferentValues;
|
||||
var newVal = EditorGUILayout.LayerField (label, prop.intValue);
|
||||
EditorGUI.showMixedValue = false;
|
||||
if (check.changed)
|
||||
prop.intValue = newVal;
|
||||
}
|
||||
}
|
||||
|
||||
private void drawStartEndProp (SerializedProperty propStt, SerializedProperty propEnd, GUIContent label) {
|
||||
EditorGUILayout.LabelField (label);
|
||||
var rect = GUILayoutUtility.GetLastRect ();
|
||||
rect.x += EditorGUIUtility.labelWidth;
|
||||
rect.width -= EditorGUIUtility.labelWidth;
|
||||
drawStartEndPropInRect (rect, propStt, propEnd);
|
||||
}
|
||||
|
||||
|
||||
private void drawStartEndPropInRect (Rect rect, SerializedProperty propStt, SerializedProperty propEnd) {
|
||||
bool isWide = (rect.width > 140);
|
||||
float span = isWide ? 5f : 3f;
|
||||
var rect2 = rect;
|
||||
var rect3 = rect;
|
||||
rect2.width = rect3.width = (rect.width - span) * 0.5f;
|
||||
rect3.x += rect2.width + span;
|
||||
var storeIndent = EditorGUI.indentLevel;
|
||||
EditorGUI.indentLevel = 0;
|
||||
var labelW = EditorGUIUtility.labelWidth;
|
||||
using (var check = new EditorGUI.ChangeCheckScope ()) {
|
||||
EditorGUI.showMixedValue = propStt.hasMultipleDifferentValues;
|
||||
EditorGUIUtility.labelWidth = isWide? 32 : 10;
|
||||
float newStt = EditorGUI.FloatField (rect2, isWide ? "Start" : "S", propStt.floatValue);
|
||||
if (check.changed)
|
||||
propStt.floatValue = Mathf.Clamp (newStt, 0, propEnd.floatValue);
|
||||
}
|
||||
using (var check = new EditorGUI.ChangeCheckScope ()) {
|
||||
EditorGUI.showMixedValue = propEnd.hasMultipleDifferentValues;
|
||||
EditorGUIUtility.labelWidth = isWide ? 26 : 10;
|
||||
float newEnd = EditorGUI.FloatField (rect3, isWide ? "End" : "E", propEnd.floatValue);
|
||||
if (check.changed)
|
||||
propEnd.floatValue = Mathf.Max (newEnd, propStt.floatValue);
|
||||
}
|
||||
EditorGUI.showMixedValue = false;
|
||||
EditorGUIUtility.labelWidth = labelW;
|
||||
EditorGUI.indentLevel = storeIndent;
|
||||
}
|
||||
|
||||
static private Color colorMulAlpha (Color c, float mulAlpha) => new Color (c.r, c.g, c.b, c.a * mulAlpha);
|
||||
|
||||
private void drawDirMark (SerializedProperty prop, bool isActive = true) {
|
||||
EditorGUI.indentLevel--;
|
||||
var rect = EditorGUI.IndentedRect (GUILayoutUtility.GetLastRect ());
|
||||
drawDirMark (rect, prop, isActive);
|
||||
EditorGUI.indentLevel++;
|
||||
}
|
||||
private void drawDirMark (Rect rect, SerializedProperty prop, bool isActive = true) {
|
||||
rect.width = EditorGUIUtility.labelWidth;
|
||||
Vector2 origin = new Vector2 (CIRCLE_R + 1, rect.height * 0.5f);
|
||||
float dir = prop.floatValue;
|
||||
Handles.color = colorMulAlpha (EditorStyles.label.normal.textColor, isActive ? 0.8f : 0.4f);
|
||||
var tmpMatrix = Handles.matrix;
|
||||
GUI.BeginClip (rect, origin, Vector2.zero, false);
|
||||
Handles.matrix = tmpMatrix * Matrix4x4.Scale (Vector3.one * CIRCLE_R);
|
||||
Handles.DrawAAPolyLine (Texture2D.whiteTexture, 1, circlePts);
|
||||
if (!prop.hasMultipleDifferentValues) {
|
||||
Handles.matrix = tmpMatrix * Matrix4x4.Rotate (Quaternion.Euler (0f, 0f, dir)) * Matrix4x4.Scale (Vector3.one * (CIRCLE_R - 0.5f));
|
||||
Handles.DrawAAConvexPolygon (arrowAry);
|
||||
}
|
||||
Handles.matrix = tmpMatrix;
|
||||
GUI.EndClip ();
|
||||
}
|
||||
|
||||
static private Vector2 dirToVec (float dir) => new Vector2 (Mathf.Sin (dir * Mathf.Deg2Rad), -Mathf.Cos (dir * Mathf.Deg2Rad));
|
||||
const float CIRCLE_R = 5f;
|
||||
static readonly private Vector3 [] arrowAry = {
|
||||
dirToVec (0),
|
||||
dirToVec (150f),
|
||||
dirToVec (170f),
|
||||
dirToVec (-170f),
|
||||
dirToVec (-150f),
|
||||
};
|
||||
static readonly private Vector3 [] circlePts = {
|
||||
new Vector3 (-1f, 0f),
|
||||
new Vector3 (-0.87f, -0.5f),
|
||||
new Vector3 (-0.5f, -0.87f),
|
||||
new Vector3 (0f, -1f),
|
||||
new Vector3 (0.5f, -0.87f),
|
||||
new Vector3 (0.87f, -0.5f),
|
||||
new Vector3 (1f, 0f),
|
||||
new Vector3 (0.87f, 0.5f),
|
||||
new Vector3 (0.5f, 0.87f),
|
||||
new Vector3 (0f, 1f),
|
||||
new Vector3 (-0.5f, 0.87f),
|
||||
new Vector3 (-0.87f, 0.5f),
|
||||
new Vector3 (-1f, 0f),
|
||||
};
|
||||
|
||||
bool isGameObjectOnScene () {
|
||||
return (target as Component).gameObject.scene.IsValid ();
|
||||
}
|
||||
|
||||
private void drawRectMain (bool isPink = false) {
|
||||
Color color = isPink ? colorPinkBar : new Color (0f, 0f, 0f, 0.2f);
|
||||
Rect rect = GUILayoutUtility.GetRect (0, 0);
|
||||
rect.height = lineH;
|
||||
rect.x -= _indentWidth + 4;
|
||||
rect.width += _indentWidth + 8;
|
||||
EditorGUI.DrawRect (rect, color);
|
||||
}
|
||||
|
||||
private bool expandMainGroup (SerializedProperty prop, bool defOpen, string label, bool isPink = false) {
|
||||
EditorGUI.indentLevel--;
|
||||
drawRectMain (isPink);
|
||||
bool expand = isExpand (prop, true, new GUIContent (label));
|
||||
EditorGUI.indentLevel++;
|
||||
return expand;
|
||||
}
|
||||
|
||||
private bool expandSubGroup (SerializedProperty prop, bool defOpen, string label, bool isPink = false) {
|
||||
Color color = isPink ? colorPinkBar : colorMulAlpha (EditorStyles.label.normal.textColor, 0.1f);
|
||||
GUILayout.Label (" ");
|
||||
Rect rect = GUILayoutUtility.GetLastRect ();
|
||||
rect.y += 1f;
|
||||
rect.x += 3f;
|
||||
rect.width -= 3f;
|
||||
Rect rect2 = rect;
|
||||
rect2.x -= 14f;
|
||||
rect2.width += 15f;
|
||||
EditorGUI.DrawRect (rect2, color);
|
||||
GUI.Label (rect, label);
|
||||
if (prop == null) {
|
||||
return true;
|
||||
} else {
|
||||
rect.x -= 14;
|
||||
prop.isExpanded = EditorGUI.Foldout (rect, prop.isExpanded != defOpen, " ") != defOpen;
|
||||
return prop.isExpanded != defOpen;
|
||||
}
|
||||
}
|
||||
|
||||
private void popup (SerializedProperty prop, GUIContent [] enumStr, string text, string tooltip) {
|
||||
using (var check = new EditorGUI.ChangeCheckScope ()) {
|
||||
EditorGUI.showMixedValue = prop.hasMultipleDifferentValues;
|
||||
var newVal = EditorGUILayout.Popup (new GUIContent (text, tooltip), prop.enumValueIndex, enumStr);
|
||||
EditorGUI.showMixedValue = false;
|
||||
if (check.changed)
|
||||
prop.enumValueIndex = newVal;
|
||||
}
|
||||
}
|
||||
|
||||
private void popup (SerializedProperty prop, string [] enumStr, string text, string tooltip) {
|
||||
using (var check = new EditorGUI.ChangeCheckScope ()) {
|
||||
EditorGUI.showMixedValue = prop.hasMultipleDifferentValues;
|
||||
var newVal = EditorGUILayout.Popup (new GUIContent (text, tooltip), prop.enumValueIndex, enumStr);
|
||||
EditorGUI.showMixedValue = false;
|
||||
if (check.changed)
|
||||
prop.enumValueIndex = newVal;
|
||||
}
|
||||
}
|
||||
|
||||
private void bitMask (SerializedProperty prop, string [] options, string text, string tooltip) {
|
||||
using (var check = new EditorGUI.ChangeCheckScope ()) {
|
||||
EditorGUI.showMixedValue = prop.hasMultipleDifferentValues;
|
||||
int newVal = EditorGUILayout.MaskField (new GUIContent (text, tooltip), prop.intValue, options);
|
||||
EditorGUI.showMixedValue = false;
|
||||
if (check.changed) {
|
||||
uint uintVal = unchecked ((uint) newVal);
|
||||
prop.longValue = uintVal;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private bool isExpand (SerializedProperty prop, bool isDefaultOpen, GUIContent label) {
|
||||
prop.isExpanded = EditorGUILayout.Foldout (prop.isExpanded != isDefaultOpen, label) != isDefaultOpen;
|
||||
return prop.isExpanded != isDefaultOpen;
|
||||
}
|
||||
|
||||
private bool isExpandMarkOnly (SerializedProperty prop, bool isDefaultOpen, float adjustX = 0f, float adjustY = 0f) {
|
||||
var rect = GUILayoutUtility.GetLastRect ();
|
||||
prop.isExpanded = EditorGUI.Foldout (rect, prop.isExpanded != isDefaultOpen, " ") != isDefaultOpen;
|
||||
return prop.isExpanded != isDefaultOpen;
|
||||
}
|
||||
|
||||
private void drawLine () {
|
||||
Rect r = GUILayoutUtility.GetRect (0, 0);
|
||||
Color col = colorMulAlpha (EditorStyles.label.normal.textColor, 0.09f);
|
||||
EditorGUI.DrawRect (new Rect (r.x + 14f, r.y, r.width - 14f, 1f), col);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------- Scope
|
||||
private class AdjustLabelSpaceWidthScope : GUI.Scope {
|
||||
private readonly float _store;
|
||||
internal AdjustLabelSpaceWidthScope (float adjust) {
|
||||
_store = EditorGUIUtility.labelWidth;
|
||||
EditorGUIUtility.labelWidth += adjust;
|
||||
}
|
||||
protected override void CloseScope () {
|
||||
EditorGUIUtility.labelWidth = _store;
|
||||
}
|
||||
}
|
||||
|
||||
private class LabelAndIndentScope : GUI.Scope {
|
||||
private float _spaceBtm;
|
||||
internal LabelAndIndentScope (GUIContent label, float spaceTop = 0f, float spaceMid = 2f, float spaceBtm = 0f) {
|
||||
_spaceBtm = spaceBtm;
|
||||
EditorGUILayout.Space (spaceTop);
|
||||
EditorGUILayout.LabelField (label);
|
||||
EditorGUILayout.Space (spaceMid);
|
||||
EditorGUI.indentLevel++;
|
||||
}
|
||||
protected override void CloseScope () {
|
||||
EditorGUI.indentLevel--;
|
||||
EditorGUILayout.Space (_spaceBtm);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class IndentScope : GUI.Scope {
|
||||
private float _spaceBtm;
|
||||
private int _indent;
|
||||
internal IndentScope (float spaceTop = 3f, float spaceBtm = 10f, int indent = 1) {
|
||||
_spaceBtm = spaceBtm;
|
||||
_indent = indent;
|
||||
EditorGUILayout.Space (spaceTop);
|
||||
EditorGUI.indentLevel += indent;
|
||||
}
|
||||
protected override void CloseScope () {
|
||||
EditorGUI.indentLevel -= _indent;
|
||||
EditorGUILayout.Space (_spaceBtm);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class DisableScope : GUI.Scope {
|
||||
private readonly bool _tmp;
|
||||
internal DisableScope (bool isActive = false) {
|
||||
_tmp = isActive;
|
||||
if (!_tmp) EditorGUI.BeginDisabledGroup (true);
|
||||
}
|
||||
protected override void CloseScope () {
|
||||
if (!_tmp) EditorGUI.EndDisabledGroup ();
|
||||
}
|
||||
}
|
||||
|
||||
private class ColorScope : GUI.Scope {
|
||||
private readonly Color _tmp;
|
||||
internal ColorScope (Color color) {
|
||||
_tmp = GUI.color;
|
||||
GUI.color = color;
|
||||
}
|
||||
protected override void CloseScope () {
|
||||
GUI.color = _tmp;
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------- URPパッケージは在るけれど 設定が完了していない場合
|
||||
private bool isDark => EditorGUIUtility.isProSkin;
|
||||
private GUIStyle _textStyle, _linkUrlStyle, _warningStyle;
|
||||
|
||||
private void prepStyle () {
|
||||
if (_textStyle == null) {
|
||||
_textStyle = new GUIStyle (EditorStyles.label);
|
||||
_textStyle.wordWrap = true;
|
||||
_textStyle.fontSize = 14;
|
||||
|
||||
_linkUrlStyle = new GUIStyle (_textStyle);
|
||||
_linkUrlStyle.wordWrap = false;
|
||||
_linkUrlStyle.normal.textColor = isDark ? new Color (0f, 0.8f, 1f, 1f) : new Color (0f, 0.4f, 0.8f, 1f);
|
||||
_linkUrlStyle.hover.textColor = _linkUrlStyle.normal.textColor + Color.white * (isDark ? 0.3f : 0.2f);
|
||||
_linkUrlStyle.stretchWidth = false;
|
||||
|
||||
_warningStyle = new GUIStyle (_textStyle);
|
||||
_warningStyle.normal.textColor = isDark ? Color.white : new Color (0.8f, 0.1f, 0f, 1f);
|
||||
_warningStyle.normal.background = Texture2D.whiteTexture;
|
||||
}
|
||||
}
|
||||
|
||||
private void onInspectorGUI_NotSettingYet () {
|
||||
prepStyle ();
|
||||
storeIndentWidth ();
|
||||
EditorGUILayout.Space (50);
|
||||
labelWarning ($"UniversalRP setup is not completed.");
|
||||
EditorGUILayout.Space (10);
|
||||
GUILayout.Label ($"Please refer to the Unity manual page to setup, or create a new project with the URP 3D template.", _textStyle);
|
||||
EditorGUILayout.Space (10);
|
||||
var urlA = "https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@12.0/manual/InstallURPIntoAProject.html";
|
||||
if (labelLink (new GUIContent ("Unity URP Setup Manual", urlA)))
|
||||
Application.OpenURL (urlA);
|
||||
EditorGUILayout.Space (5);
|
||||
var urlB = Constant.URL_MANUAL;
|
||||
if (labelLink (new GUIContent ("Asset Manual", urlB)))
|
||||
Application.OpenURL (urlB);
|
||||
EditorGUILayout.Space (50);
|
||||
}
|
||||
|
||||
void labelWarning (string text, int fontSize = 18) {
|
||||
prepStyle ();
|
||||
_warningStyle.fontSize = fontSize;
|
||||
Color tmp = GUI.backgroundColor;
|
||||
GUI.backgroundColor = isDark ? new Color (1f, 0.3f, 0.6f, 0.4f) : new Color (1f, 0.3f, 0.6f, 0.5f);
|
||||
GUILayout.Label (text, _warningStyle);
|
||||
GUI.backgroundColor = tmp;
|
||||
}
|
||||
|
||||
private bool labelLink (GUIContent label, int fontSize = 14, int indent = 0, params GUILayoutOption [] options) {
|
||||
prepStyle ();
|
||||
_linkUrlStyle.fontSize = fontSize;
|
||||
var rect = GUILayoutUtility.GetRect (label, _linkUrlStyle, options);
|
||||
rect.x += indent * _indentWidth;
|
||||
Handles.BeginGUI ();
|
||||
Handles.color = _linkUrlStyle.normal.textColor;
|
||||
Handles.DrawLine (new Vector3 (rect.xMin, rect.yMax), new Vector3 (rect.xMax, rect.yMax));
|
||||
Handles.color = Color.white;
|
||||
Handles.EndGUI ();
|
||||
EditorGUIUtility.AddCursorRect (rect, MouseCursor.Link);
|
||||
return GUI.Button (rect, label, _linkUrlStyle);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif // End of WCE_URP
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5998e4477e64d9b47a7297a804fff2ab
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,207 @@
|
||||
// WaterCausticsModules
|
||||
// Copyright (c) 2021 Masataka Hakozaki
|
||||
|
||||
#if UNITY_EDITOR && WCE_URP
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering;
|
||||
using UnityEngine.Rendering.Universal;
|
||||
|
||||
namespace MH.WaterCausticsModules {
|
||||
[CustomEditor (typeof (WaterCausticsEffectFeature), true)]
|
||||
public class WaterCausticsEffectFeatureEditor : Editor {
|
||||
private GUIStyle _style;
|
||||
private void init () {
|
||||
_style = new GUIStyle (EditorStyles.label);
|
||||
_style.wordWrap = true;
|
||||
_style.fontSize -= 1;
|
||||
}
|
||||
public override void OnInspectorGUI () {
|
||||
if (_style == null) init ();
|
||||
EditorGUILayout.Space (10);
|
||||
string str = "This Renderer Function is required to apply WaterCausticsEffect.";
|
||||
GUILayout.Label (str, _style);
|
||||
}
|
||||
|
||||
//--------------------------------------------------------------------------------------------------------------
|
||||
// static internal bool AddToCurrentRendererData (bool useUndo) {
|
||||
// if (GetCurrentRendererData (out var dt))
|
||||
// return AddFeatureToRenderer (dt, useUndo);
|
||||
// return false;
|
||||
// }
|
||||
|
||||
// static internal bool GetCurrentRendererData (out ScriptableRendererData dt) {
|
||||
// dt = null;
|
||||
// try {
|
||||
// var urpAsset = GraphicsSettings.currentRenderPipeline as UniversalRenderPipelineAsset;
|
||||
// var propertyInfo = typeof (UniversalRenderPipelineAsset).GetProperty ("scriptableRendererData", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic);
|
||||
// if (propertyInfo == null) return false;
|
||||
// dt = propertyInfo.GetValue (urpAsset) as ScriptableRendererData;
|
||||
// return dt != null;
|
||||
// } catch { }
|
||||
// return false;
|
||||
// }
|
||||
|
||||
|
||||
public class ModificationProcessor : UnityEditor.AssetModificationProcessor {
|
||||
// WaterCausticsEffectFeatureスクリプトが削除されるとき、登録済みのRendererFeatureを削除
|
||||
// ※フォルダ削除時、中身のパスは渡されないので注意
|
||||
private static AssetDeleteResult OnWillDeleteAsset (string deletePath, RemoveAssetOptions options) {
|
||||
bool isDirectory = File.GetAttributes (deletePath).HasFlag (FileAttributes.Directory);
|
||||
string scriptPath = getScriptPath<WaterCausticsEffectFeature> ();
|
||||
if ((isDirectory && scriptPath.StartsWith (deletePath)) || deletePath == scriptPath) {
|
||||
// RendererFeatureを削除
|
||||
DeleteAllFeatures ();
|
||||
}
|
||||
return AssetDeleteResult.DidNotDelete;
|
||||
}
|
||||
}
|
||||
|
||||
static private string getScriptPath<T> () where T : ScriptableObject {
|
||||
T asset = ScriptableObject.CreateInstance<T> ();
|
||||
MonoScript mono = MonoScript.FromScriptableObject (asset);
|
||||
string path = AssetDatabase.GetAssetPath (mono);
|
||||
if (Application.isPlaying) Destroy (asset);
|
||||
else DestroyImmediate (asset);
|
||||
return path;
|
||||
}
|
||||
|
||||
#if WCE_DEVELOPMENT
|
||||
[MenuItem ("WCM/RendererFeatureTest/DeleteAllFeatures")]
|
||||
#endif
|
||||
static internal void DeleteAllFeatures () {
|
||||
if (GetAllRendererData (out var list))
|
||||
foreach (var dt in list)
|
||||
DeleteFeature (dt);
|
||||
}
|
||||
|
||||
static internal void DeleteFeature (ScriptableRendererData dt) {
|
||||
if (!dt) return;
|
||||
try {
|
||||
// ※ TODO URPのバージョンが上がるたび処理方法に変更がないか要確認
|
||||
if (dt.rendererFeatures.Any (a => a is WaterCausticsEffectFeature)) {
|
||||
if (!EditorUtility.IsPersistent (dt)) return;
|
||||
var feature = dt.rendererFeatures.FirstOrDefault (a => a is WaterCausticsEffectFeature);
|
||||
AssetDatabase.RemoveObjectFromAsset (feature);
|
||||
dt.rendererFeatures.Remove (feature);
|
||||
dt.SetDirty ();
|
||||
EditorUtility.SetDirty (dt);
|
||||
saveAssetSafe (dt);
|
||||
}
|
||||
} catch { }
|
||||
}
|
||||
|
||||
static private void saveAssetSafe (Object o) {
|
||||
// ※AssetDatabase.SaveAssetIfDirty は Unity 2021.1.17、2020.3.16で追加されたので分岐
|
||||
#if !UNITY_2020_3_OR_NEWER || UNITY_2020_3_0 || UNITY_2020_3_1 || UNITY_2020_3_2 || UNITY_2020_3_3 || UNITY_2020_3_4 || UNITY_2020_3_5 || UNITY_2020_3_6 || UNITY_2020_3_7 || UNITY_2020_3_8 || UNITY_2020_3_9 || UNITY_2020_3_10 || UNITY_2020_3_11 || UNITY_2020_3_12 || UNITY_2020_3_13 || UNITY_2020_3_14 || UNITY_2020_3_15 || UNITY_2021_1
|
||||
AssetDatabase.SaveAssets ();
|
||||
#else
|
||||
AssetDatabase.SaveAssetIfDirty (o);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
static internal bool AddFeatureToRenderer (ScriptableRendererData dt, bool useUndo) {
|
||||
if (!dt) return false;
|
||||
try {
|
||||
if (dt.rendererFeatures.Any (a => a is WaterCausticsEffectFeature)) {
|
||||
// -- すでにある場合 アクティブ化
|
||||
var feature = dt.rendererFeatures.FirstOrDefault (a => a is WaterCausticsEffectFeature) as WaterCausticsEffectFeature;
|
||||
//if (!feature.isActive) {
|
||||
//if (useUndo) Undo.RegisterCompleteObjectUndo (feature, "Feature Set Active");
|
||||
//feature.SetActive (true);
|
||||
//EditorUtility.SetDirty (feature);
|
||||
//saveAssetSafe (dt);
|
||||
//}
|
||||
WaterCausticsEffectFeature.OnAddedByScript ();
|
||||
return true;
|
||||
} else {
|
||||
// -- まだ無い場合
|
||||
// ※ TODO URPのバージョンが上がるたび処理方法に変更がないか要確認 10.9, 12.1, 14.0 OK
|
||||
if (!EditorUtility.IsPersistent (dt)) return false;
|
||||
var validateMethod = dt.GetType ().GetMethod ("ValidateRendererFeatures", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
|
||||
if (validateMethod == null) return false;
|
||||
var feature = ScriptableRendererFeature.CreateInstance<WaterCausticsEffectFeature> ();
|
||||
feature.name = typeof (WaterCausticsEffect).Name;
|
||||
if (useUndo) {
|
||||
Undo.RegisterCreatedObjectUndo (feature, "Add Renderer Feature");
|
||||
Undo.RegisterCompleteObjectUndo (dt, "Add Renderer Feature");
|
||||
}
|
||||
AssetDatabase.AddObjectToAsset (feature, dt);
|
||||
dt.rendererFeatures.Add (feature);
|
||||
validateMethod.Invoke (dt, null);
|
||||
dt.SetDirty ();
|
||||
EditorUtility.SetDirty (dt);
|
||||
saveAssetSafe (dt);
|
||||
WaterCausticsEffectFeature.OnAddedByScript ();
|
||||
return true;
|
||||
}
|
||||
} catch { }
|
||||
return false;
|
||||
}
|
||||
|
||||
static internal bool CheckAllHasActiveFeature (List<ScriptableRendererData> list) {
|
||||
return list != null && !list.Any (a => checkHasActiveFeature (a) == false);
|
||||
}
|
||||
|
||||
static internal bool checkHasActiveFeature (ScriptableRendererData dt) {
|
||||
return dt != null && dt.rendererFeatures.Any (a => a is WaterCausticsEffectFeature && a.isActive);
|
||||
}
|
||||
|
||||
static internal bool AddFeatureToAllRenderers (out List<ScriptableRendererData> list, bool useUndo) {
|
||||
if (GetAllRendererData (out list))
|
||||
return AddFeatureToAllRenderers (list, useUndo);
|
||||
return false;
|
||||
}
|
||||
|
||||
#if WCE_DEVELOPMENT
|
||||
[MenuItem ("WCM/RendererFeatureTest/AddFeatureToAllRenderers")]
|
||||
#endif
|
||||
static internal bool AddFeatureToAllRenderers () {
|
||||
return AddFeatureToAllRenderers (useUndo: true);
|
||||
|
||||
}
|
||||
static internal bool AddFeatureToAllRenderers (bool useUndo) {
|
||||
if (GetAllRendererData (out var list))
|
||||
return AddFeatureToAllRenderers (list, useUndo);
|
||||
return false;
|
||||
}
|
||||
|
||||
static internal bool AddFeatureToAllRenderers (List<ScriptableRendererData> list, bool useUndo) {
|
||||
if (list == null) return false;
|
||||
bool result = true;
|
||||
foreach (var dt in list)
|
||||
result &= AddFeatureToRenderer (dt, useUndo);
|
||||
return result;
|
||||
}
|
||||
|
||||
static internal bool GetAllRendererData (out List<ScriptableRendererData> list) {
|
||||
list = new List<ScriptableRendererData> ();
|
||||
var guids = AssetDatabase.FindAssets ($"t:{typeof(ScriptableRendererData).ToString()}", new [] { "Assets" });
|
||||
if (guids.Length == 0) return false;
|
||||
foreach (var guid in guids) {
|
||||
var dt = AssetDatabase.LoadAssetAtPath<ScriptableRendererData> (AssetDatabase.GUIDToAssetPath (guid));
|
||||
list.Add (dt);
|
||||
}
|
||||
return list.Count != 0;
|
||||
}
|
||||
|
||||
static internal void SelectAndPing (List<ScriptableRendererData> list) {
|
||||
Selection.objects = list.ToArray ();
|
||||
foreach (var dt in list) EditorGUIUtility.PingObject (dt);
|
||||
}
|
||||
|
||||
static internal string AssetsToPathStr (List<ScriptableRendererData> list) {
|
||||
var str = "";
|
||||
for (int i = 0; i < list.Count; i++)
|
||||
str += $"{i+1}: {AssetDatabase.GetAssetPath (list [i])}\n";
|
||||
return str;
|
||||
}
|
||||
//------------------------------------------------------------------------
|
||||
}
|
||||
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d8b3f56e6e68f2d4fbdf5ad470a2fa4d
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,48 @@
|
||||
// WaterCausticsModules
|
||||
// Copyright (c) 2021 Masataka Hakozaki
|
||||
|
||||
#if UNITY_EDITOR && WCE_URP
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MH.WaterCausticsModules {
|
||||
public class WaterCausticsEffectMenuItem {
|
||||
[MenuItem ("GameObject/WaterCausticsModules/TexGen and Effect (with RenderTexture Asset)", false, 0)]
|
||||
static public void CreateTexGenAndEffectPair () {
|
||||
var texGen = WaterCausticsTexGeneratorMenuItem.CreateTexGeneratorWithRT ();
|
||||
var effect = createEffectGO ();
|
||||
effect.texture = texGen.renderTexture;
|
||||
}
|
||||
|
||||
[MenuItem ("GameObject/WaterCausticsModules/Effect", false, 3)]
|
||||
static public void CreateEffectGO () {
|
||||
GameObject selectedGO = Selection.activeGameObject;
|
||||
var effect = createEffectGO ();
|
||||
var texGen = selectedGO?.GetComponent<WaterCausticsTexGenerator> ();
|
||||
if (texGen == null)
|
||||
texGen = Object.FindObjectOfType<WaterCausticsTexGenerator> ();
|
||||
if (texGen != null)
|
||||
effect.texture = texGen.renderTexture;
|
||||
}
|
||||
|
||||
static private WaterCausticsEffect createEffectGO () {
|
||||
var go = new GameObject ("WaterCausticsEffect");
|
||||
Undo.RegisterCreatedObjectUndo (go, "Create WaterCausticsEffect");
|
||||
var tra = go.transform;
|
||||
if (Selection.activeGameObject != null) {
|
||||
var baseTra = Selection.activeGameObject.transform;
|
||||
tra.parent = baseTra.parent;
|
||||
tra.SetSiblingIndex (baseTra.GetSiblingIndex () + 1);
|
||||
}
|
||||
tra.localPosition = Vector3.zero;
|
||||
tra.localRotation = Quaternion.identity;
|
||||
tra.localScale = Vector3.one * 3f;
|
||||
Selection.activeObject = go;
|
||||
Selection.activeObject = null;
|
||||
Selection.activeObject = go;
|
||||
return go.AddComponent<WaterCausticsEffect> ();
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: cde63416afd7d524cb16551f6e60fa41
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,15 @@
|
||||
fileFormatVersion: 2
|
||||
guid: e975b56feadc05a4a9da076c953ae619
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- m_imageMaskTexture: {fileID: 2800000, guid: f88b6df342d5c4f4a969fb6eb4799d3e, type: 3}
|
||||
- m_texture: {instanceID: 0}
|
||||
- m_shader: {fileID: 4800000, guid: 348afebc23c3c6e4c8f05f2ea8f758fc, type: 3}
|
||||
- m_noTexture: {fileID: 2800000, guid: 27623e5a17b6fd44a9af57a733ee993a, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,49 @@
|
||||
// WaterCausticsModules
|
||||
// Copyright (c) 2021 Masataka Hakozaki
|
||||
|
||||
#if WCE_URP
|
||||
using System;
|
||||
using UnityEngine;
|
||||
using UnityEngine.Rendering.Universal;
|
||||
|
||||
namespace MH.WaterCausticsModules {
|
||||
/*------------------------------------------------------------------------
|
||||
This RendererFeature is used to stably apply WaterCausticsEffect to cameras
|
||||
created by other effects.
|
||||
For example, a mirror or water reflection effect may use a temporary camera
|
||||
that is not placed in the scene, and the effect cannot be applied stably.
|
||||
In that case, register this RendererFeature to the RendererData Asset.
|
||||
The effect will be applied stably to all cameras.
|
||||
|
||||
このRendererFeatureは、他のエフェクトで作成されたカメラへWaterCausticsEffect
|
||||
を安定的に適用するために使用します。
|
||||
鏡や水面の反射エフェクトなどではシーンに配置されない一時的なカメラを使用する
|
||||
場合があり、安定してエフェクトを適用出来ません。その場合はこの RendererFeature
|
||||
を RendererData Asset に登録して下さい。安定してエフェクトが適用されるように
|
||||
なります。
|
||||
-------------------------------------------------------------------------*/
|
||||
|
||||
#if UNITY_2021_2_OR_NEWER
|
||||
[DisallowMultipleRendererFeature ("WaterCausticsEffect (Renderer Feature)")]
|
||||
#elif WCE_URP_10_8
|
||||
[DisallowMultipleRendererFeature]
|
||||
#endif
|
||||
[HelpURL (Constant.URL_MANUAL)]
|
||||
public class WaterCausticsEffectFeature : ScriptableRendererFeature {
|
||||
static private WaterCausticsEffectFeature s_ins;
|
||||
static public event Action<Camera> onCamRender;
|
||||
static public event Action<ScriptableRenderer, Camera> onEnqueue;
|
||||
static private int s_lastFrame;
|
||||
static internal bool effective => (s_ins != null && s_ins.isActive && s_lastFrame >= Time.renderedFrameCount - 1);
|
||||
static internal void OnAddedByScript () => s_lastFrame = Time.renderedFrameCount;
|
||||
public override void Create () { }
|
||||
public override void AddRenderPasses (ScriptableRenderer renderer, ref RenderingData rendData) {
|
||||
s_ins = this;
|
||||
s_lastFrame = Time.renderedFrameCount;
|
||||
var cam = rendData.cameraData.camera;
|
||||
onCamRender?.Invoke (cam);
|
||||
onEnqueue?.Invoke (renderer, cam);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 63239fdff9bcf7545bae0204cba6eb96
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5408d0311478d0c4984c6debe06c8308
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,522 @@
|
||||
// WaterCausticsModules
|
||||
// Copyright (c) 2021 Masataka Hakozaki
|
||||
|
||||
Shader "Hidden/WaterCausticsModules/Effect" {
|
||||
Properties {
|
||||
// --- Scope
|
||||
_WCE_ClipOutside ("Clip Outside Volume", Int) = 1
|
||||
_WCE_UseImageMask ("Use Image Mask", Int) = 0
|
||||
[NoScaleOffset]_WCE_ImageMaskTex ("Texture", 2D) = "white" { }
|
||||
[Enum(UnityEngine.Rendering.CullMode)] _CullMode ("Cull Mode", Int) = 2
|
||||
// --- Texture
|
||||
[NoScaleOffset]_WCE_CausticsTex ("Caustics Texture", 2D) = "black" { }
|
||||
_WCE_TexChannels ("Channel", Vector) = (0, 1, 2, 0)
|
||||
_WCE_TexRotateSinCos ("Rotation Sin and Cos", Vector) = (0, 1, 0, 0)
|
||||
_WCE_TilingSeed ("Tiling Seed", Int) = -1
|
||||
_WCE_TilingRot ("Tiling Rot", Float) = 0.02
|
||||
_WCE_TilingHard ("Tiling Hard", Float) = 0.85
|
||||
// --- Dimension
|
||||
_WCE_Density ("Density", Float) = 0.2
|
||||
_WCE_SurfaceY ("Water Surface Y", Float) = 2
|
||||
_WCE_SurfFadeCoef ("Surface Fade Coef", Float) = 2
|
||||
_WCE_SurfFadeStart ("Surface Fade Start", Float) = 0
|
||||
_WCE_DepthFadeStart ("Depth Fade Start", Float) = 0
|
||||
_WCE_DepthFadeCoef ("Depth Fade Coef", Float) = 0.01
|
||||
_WCE_DistanceFadeStart ("Distance Fade Start", Float) = 0
|
||||
_WCE_DistanceFadeCoef ("Distance Fade Coef", Float) = 0.01
|
||||
// --- Effect
|
||||
_WCE_IntensityMainLit ("Main Light Intensity", Range(0, 50)) = 1
|
||||
_WCE_IntensityAddLit ("Additional Lights Intensity", Range(0, 50)) = 1
|
||||
[ToggleOff(_RECEIVE_SHADOWS_OFF)] _RECEIVE_SHADOWS_OFF ("Receive Shadow", Float) = 1
|
||||
_WCE_ShadowIntensity ("Shadow Intensity", Range(0, 1)) = 1
|
||||
_WCE_ColorShift ("ColorShift", Vector) = (0.004, -0.001, 0, 0)
|
||||
_WCE_LitSaturation ("Light Saturation", Range(0, 2)) = 0.2
|
||||
_WCE_MultiplyByTex ("Multiply Color", Range(0, 1)) = 1
|
||||
// --- Normal Atten
|
||||
_WCE_NormalAtten ("Normal Atten Intensity", Range(0, 1)) = 1
|
||||
_WCE_NormalAttenRate ("Normal Atten Rate", Range(1, 8)) = 2
|
||||
_WCE_TransparentBack ("Transparent Backside", Range(0, 1)) = 0
|
||||
_WCE_BacksideShadow ("Backside Shadow", Range(0, 1)) = 0
|
||||
// --- Depth Buffer
|
||||
_ZWrite ("ZWrite", Int) = 0
|
||||
[Enum(UnityEngine.Rendering.CompareFunction)] _ZTest ("ZTest", Int) = 4
|
||||
_OffsetFactor ("Offset Factor", float) = 0
|
||||
_OffsetUnits ("Offset Units", float) = 0
|
||||
// --- Stencil Buffer
|
||||
_StencilRef ("Ref [0-255]", Range(0, 255)) = 0
|
||||
_StencilReadMask ("Read Mask [0-255]", Range(0, 255)) = 255
|
||||
_StencilWriteMask ("Write Mask [0-255]", Range(0, 255)) = 255
|
||||
[Enum(UnityEngine.Rendering.CompareFunction)] _StencilComp ("Comp", Int) = 8
|
||||
[Enum(UnityEngine.Rendering.StencilOp)] _StencilPass ("Pass", Int) = 0
|
||||
[Enum(UnityEngine.Rendering.StencilOp)] _StencilFail ("ZFail", Int) = 0
|
||||
[Enum(UnityEngine.Rendering.StencilOp)] _StencilZFail ("ZFail", Int) = 0
|
||||
// --- Blend
|
||||
[Enum(UnityEngine.Rendering.BlendMode)] _BlendSrcFactor ("SrcFactor", Int) = 1
|
||||
[Enum(UnityEngine.Rendering.BlendMode)] _BlendDstFactor ("DstFactor", Int) = 1
|
||||
// ※ Properties は SRPBatcher に必須
|
||||
|
||||
}
|
||||
|
||||
SubShader {
|
||||
LOD 0
|
||||
Tags { "RenderPipeline" = "UniversalPipeline" "RenderType" = "Transparent" "Queue" = "Transparent" "DisableBatching" = "True" "IgnoreProjector" = "True" }
|
||||
|
||||
Pass {
|
||||
Name "WCE_EffectPass"
|
||||
Tags { "LightMode" = "WCE_EffectPass" }
|
||||
|
||||
Blend [_BlendSrcFactor] [_BlendDstFactor]
|
||||
ZWrite [_ZWrite]
|
||||
ZTest [_ZTest]
|
||||
Offset [_OffsetFactor], [_OffsetUnits]
|
||||
Cull [_CullMode]
|
||||
Stencil {
|
||||
Ref [_StencilRef]
|
||||
ReadMask [_StencilReadMask]
|
||||
WriteMask [_StencilWriteMask]
|
||||
Comp [_StencilComp]
|
||||
Pass [_StencilPass]
|
||||
Fail [_StencilFail]
|
||||
ZFail [_StencilZFail]
|
||||
}
|
||||
|
||||
HLSLPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#pragma exclude_renderers d3d11_9x
|
||||
#pragma target 3.5
|
||||
|
||||
#define WCE_EFFECT_SHADER
|
||||
#define REQUIRE_OPAQUE_TEXTURE
|
||||
|
||||
#pragma multi_compile_local _ _WCE_ONE_PASS_NORMAL _WCE_ONE_PASS_DEPTH
|
||||
#pragma multi_compile_local_fragment _ WCE_DEBUG_NORMAL WCE_DEBUG_DEPTH WCE_DEBUG_FACING WCE_DEBUG_CAUSTICS WCE_DEBUG_AREA
|
||||
#if defined(_WCE_ONE_PASS_NORMAL) || defined(_WCE_ONE_PASS_DEPTH)
|
||||
#define REQUIRE_DEPTH_TEXTURE
|
||||
#if defined(_WCE_ONE_PASS_NORMAL)
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/DeclareNormalsTexture.hlsl"
|
||||
#endif
|
||||
#else
|
||||
#define WCE_EACH_MESH
|
||||
#endif
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Version.hlsl"
|
||||
#if VERSION_GREATER_EQUAL(11, 0)
|
||||
#pragma multi_compile_fragment _ _MAIN_LIGHT_SHADOWS _MAIN_LIGHT_SHADOWS_CASCADE _MAIN_LIGHT_SHADOWS_SCREEN
|
||||
#else
|
||||
#pragma multi_compile_fragment _ _MAIN_LIGHT_SHADOWS
|
||||
#pragma multi_compile_fragment _ _MAIN_LIGHT_SHADOWS_CASCADE
|
||||
#endif
|
||||
#pragma multi_compile_fragment _ _SHADOWS_SOFT
|
||||
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHTS
|
||||
|
||||
// ---- ※ URP14のDeferredで影が現れない問題応急処置
|
||||
// ※ TODO URP14のバージョンが上がったら修正されたか要確認
|
||||
#if UNITY_VERSION >= 202220 // Unity2022.2.0 URP14.0 以上
|
||||
#if !defined(_RECEIVE_SHADOWS_OFF)
|
||||
#define _ADDITIONAL_LIGHT_SHADOWS
|
||||
#endif
|
||||
#else
|
||||
#pragma multi_compile_fragment _ _ADDITIONAL_LIGHT_SHADOWS
|
||||
#endif
|
||||
// ----
|
||||
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/ShaderGraphFunctions.hlsl"
|
||||
|
||||
// ---- 使用しない
|
||||
// #pragma multi_compile_fragment _ LIGHTMAP_ON
|
||||
// #pragma multi_compile_fragment _ LIGHTMAP_SHADOW_MIXING
|
||||
// #pragma multi_compile_fragment _ SHADOWS_SHADOWMASK
|
||||
// #pragma multi_compile_fragment _ _MIXED_LIGHTING_SUBTRACTIVE
|
||||
// ----
|
||||
|
||||
#if UNITY_VERSION >= 202120 // Unity2021.2.0 URP12.0 以上
|
||||
#pragma multi_compile_fragment _ _GBUFFER_NORMALS_OCT
|
||||
#pragma multi_compile_fragment _ _LIGHT_LAYERS
|
||||
#pragma multi_compile_fragment _ _LIGHT_COOKIES
|
||||
#endif
|
||||
#if UNITY_VERSION >= 202220 // Unity2022.2.0 URP14.0 以上
|
||||
#pragma multi_compile_fragment _ _FORWARD_PLUS
|
||||
#endif
|
||||
|
||||
#pragma multi_compile_fog
|
||||
#if defined(FOG_LINEAR) || defined(FOG_EXP) || defined(FOG_EXP2)
|
||||
#define _USE_FOG
|
||||
#endif
|
||||
|
||||
#include "WaterCausticsEffectCommon.hlsl"
|
||||
#pragma multi_compile_local_fragment _ _RECEIVE_SHADOWS_OFF
|
||||
|
||||
struct appdata {
|
||||
float4 vertex : POSITION;
|
||||
#if defined(WCE_EACH_MESH)
|
||||
float3 normal : NORMAL;
|
||||
#else
|
||||
uint vID : SV_VertexID;
|
||||
#endif
|
||||
UNITY_VERTEX_INPUT_INSTANCE_ID
|
||||
};
|
||||
|
||||
struct v2f {
|
||||
float4 posClip : SV_POSITION;
|
||||
float4 posScrn : TEXCOORD0;
|
||||
#if defined(WCE_EACH_MESH)
|
||||
float3 posWld : TEXCOORD1;
|
||||
float3 posEffect : TEXCOORD2;
|
||||
float3 normalWS : TEXCOORD3;
|
||||
#if defined(_USE_FOG)
|
||||
float viewDepth : TEXCOORD4;
|
||||
#endif
|
||||
#endif
|
||||
UNITY_VERTEX_OUTPUT_STEREO
|
||||
};
|
||||
|
||||
CBUFFER_START(UnityPerMaterial)
|
||||
float _WCE_Density;
|
||||
int3 _WCE_TexChannels;
|
||||
float2 _WCE_TexRotateSinCos;
|
||||
int _WCE_TilingSeed;
|
||||
float _WCE_TilingRot;
|
||||
float _WCE_TilingHard;
|
||||
float _WCE_SurfaceY;
|
||||
float _WCE_SurfFadeStart;
|
||||
float _WCE_SurfFadeCoef;
|
||||
float _WCE_DepthFadeStart;
|
||||
float _WCE_DepthFadeCoef;
|
||||
float _WCE_DistanceFadeStart;
|
||||
float _WCE_DistanceFadeCoef;
|
||||
half _WCE_IntensityMainLit;
|
||||
half _WCE_IntensityAddLit;
|
||||
float2 _WCE_ColorShift;
|
||||
half _WCE_LitSaturation;
|
||||
half _WCE_MultiplyByTex;
|
||||
half _WCE_NormalAtten;
|
||||
half _WCE_NormalAttenRate;
|
||||
half _WCE_TransparentBack;
|
||||
half _WCE_BacksideShadow;
|
||||
half _WCE_ShadowIntensity;
|
||||
int _WCE_ClipOutside;
|
||||
int _WCE_UseImageMask;
|
||||
CBUFFER_END
|
||||
|
||||
#if defined(WCE_EACH_MESH)
|
||||
CBUFFER_START(FrequentlyUpdateVariables)
|
||||
float4x4 _WCE_WorldToObjMatrix;
|
||||
CBUFFER_END
|
||||
#endif
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------ Fill Clipped Hole
|
||||
bool WCE_intersectPlaneAndLine(float3 ptA, float3 ptB, float3 planeP, float3 planeN, bool isAllowEndOnPlane, out float3 PT) {
|
||||
float dotPA = dot(ptA - planeP, planeN);
|
||||
float dotPB = dot(ptB - planeP, planeN);
|
||||
bool isCross = (sign(dotPA) != sign(dotPB));
|
||||
bool isPtOnPlane = (dotPA == 0 || dotPB == 0);
|
||||
[branch] if (isCross && (isAllowEndOnPlane || !isPtOnPlane)) {
|
||||
float3 AB = ptB - ptA;
|
||||
float dif = abs(dotPA) + abs(dotPB);
|
||||
float rate = abs(dotPA) / dif;
|
||||
PT = ptA + AB * rate;
|
||||
return true;
|
||||
} else {
|
||||
PT = float3(0, 0, 0);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
float3 WCE_camDirWS() {
|
||||
return -UNITY_MATRIX_V[2].xyz;
|
||||
}
|
||||
|
||||
float3 WCE_viewDirWS(float3 posWS) {
|
||||
return (unity_OrthoParams.w == 0) ? normalize(posWS - _WorldSpaceCameraPos) : WCE_camDirWS();
|
||||
}
|
||||
float3 WCE_viewDirRawWS(float3 posWS) {
|
||||
return (unity_OrthoParams.w == 0) ? posWS - _WorldSpaceCameraPos : WCE_camDirWS();
|
||||
}
|
||||
|
||||
float4 WCE_fillClippedHole(uint vID) {
|
||||
const float3 pts[8] = {
|
||||
float3(-0.5, -0.5, -0.5), float3(0.5, -0.5, -0.5), float3(-0.5, 0.5, -0.5), float3(0.5, 0.5, -0.5),
|
||||
float3(-0.5, -0.5, 0.5), float3(0.5, -0.5, 0.5), float3(-0.5, 0.5, 0.5), float3(0.5, 0.5, 0.5),
|
||||
};
|
||||
const uint2 idxs [12] = {
|
||||
uint2(0, 4), uint2(1, 5), uint2(2, 6), uint2(3, 7), uint2(0, 2), uint2(1, 3), uint2(4, 6), uint2(5, 7), uint2(0, 1), uint2(4, 5), uint2(2, 3), uint2(6, 7),
|
||||
};
|
||||
// ObliqueMatrix対応のためClipSpaceの端点からNearClipPlaneを得る
|
||||
float near = UNITY_NEAR_CLIP_VALUE; // ← D3D11/Metal/Vulkan/Switch:1, GLCore/GLES:-1
|
||||
float3 p0 = ComputeWorldSpacePosition(float4(0, 0, near, 1), UNITY_MATRIX_I_VP);
|
||||
float3 p1 = ComputeWorldSpacePosition(float4(1, 0, near, 1), UNITY_MATRIX_I_VP);
|
||||
float3 p2 = ComputeWorldSpacePosition(float4(0, 1, near, 1), UNITY_MATRIX_I_VP);
|
||||
float3 planeN_WS = cross(p1 - p0, p2 - p0);
|
||||
planeN_WS *= sign(dot(planeN_WS, -WCE_camDirWS()));
|
||||
|
||||
float3 planeN = TransformWorldToObjectNormal(planeN_WS, true);
|
||||
float3 planeP = TransformWorldToObject(p0);
|
||||
float3 rightV = TransformWorldToObjectDir(p1 - p0, true);
|
||||
|
||||
uint cnt = 0u;
|
||||
float3 center = float3(0, 0, 0);
|
||||
float4 intersectPts[6];
|
||||
[unroll(12)] for (uint i = 0u; i < 12u; i++) {
|
||||
float3 ptA = pts [idxs [i].x];
|
||||
float3 ptB = pts [idxs [i].y];
|
||||
float3 PT;
|
||||
bool isIntersect = WCE_intersectPlaneAndLine(ptA, ptB, planeP, planeN, (i < 4), PT);
|
||||
[branch] if (isIntersect) {
|
||||
intersectPts [cnt].xyz = PT;
|
||||
center += PT;
|
||||
cnt++;
|
||||
}
|
||||
}
|
||||
center /= cnt;
|
||||
|
||||
float3 outputPt = center;
|
||||
[branch] if (cnt >= 3u && vID <= cnt) {
|
||||
[unroll(6)] for (uint k = 0u; k < cnt; k++) {
|
||||
// 時計回りにwを設定 -2~+2
|
||||
float3 v = normalize(intersectPts [k].xyz - center);
|
||||
intersectPts [k].w = - (dot(v, rightV) - 1.0) * sign(dot(cross(v, rightV), planeN));
|
||||
}
|
||||
// ソート
|
||||
[unroll(5)] for (uint m = 0u; m < cnt - 1u; m++) {
|
||||
[unroll(5)] for (uint o = m + 1u; o < cnt; o++) {
|
||||
[branch] if (intersectPts[m].w < intersectPts[o].w) {
|
||||
float4 swap = intersectPts[m];
|
||||
intersectPts[m] = intersectPts[o];
|
||||
intersectPts[o] = swap;
|
||||
}
|
||||
}
|
||||
}
|
||||
outputPt = intersectPts[vID % cnt].xyz;
|
||||
}
|
||||
float4 posClip = TransformObjectToHClip(outputPt);
|
||||
posClip.z = UNITY_NEAR_CLIP_VALUE * posClip.w;
|
||||
return posClip;
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------ Vertex Shader
|
||||
v2f vert(appdata v) {
|
||||
v2f o = (v2f)0;
|
||||
UNITY_SETUP_INSTANCE_ID(v);
|
||||
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
|
||||
#if defined(WCE_EACH_MESH)
|
||||
// [Each Mesh]
|
||||
float4 posClip = TransformObjectToHClip(v.vertex.xyz);
|
||||
float3 posWld = TransformObjectToWorld(v.vertex.xyz);
|
||||
float4 posScrn = ComputeScreenPos(posClip);
|
||||
o.posClip = posClip;
|
||||
o.posWld = posWld;
|
||||
o.posScrn = posScrn;
|
||||
o.posEffect = mul(_WCE_WorldToObjMatrix, float4(posWld, 1)).xyz;
|
||||
o.normalWS = TransformObjectToWorldNormal(v.normal, true);
|
||||
#if defined(_USE_FOG)
|
||||
o.viewDepth = -TransformWorldToView(posWld).z;
|
||||
#endif
|
||||
#else
|
||||
// [At Once]
|
||||
float4 posClip;
|
||||
[branch]if (v.vID < 8u) {
|
||||
posClip = TransformObjectToHClip(v.vertex.xyz);
|
||||
} else {
|
||||
posClip = WCE_fillClippedHole(v.vID - 8u);
|
||||
}
|
||||
float4 posScrn = ComputeScreenPos(posClip);
|
||||
o.posClip = posClip;
|
||||
o.posScrn = posScrn;
|
||||
#endif
|
||||
return o;
|
||||
}
|
||||
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------ Reconstruct World Pos and Normal
|
||||
float WCE_fixReversedZ(float Depth) {
|
||||
#if UNITY_REVERSED_Z
|
||||
return 1 - Depth;
|
||||
#else
|
||||
return Depth;
|
||||
#endif
|
||||
}
|
||||
|
||||
float3 WCE_reconstructPosWS(float2 screenUV, float rawDepth) {
|
||||
#if !UNITY_REVERSED_Z
|
||||
rawDepth = lerp(UNITY_NEAR_CLIP_VALUE, 1, rawDepth);
|
||||
#endif
|
||||
return ComputeWorldSpacePosition(screenUV, rawDepth, UNITY_MATRIX_I_VP);
|
||||
}
|
||||
|
||||
bool WCE_checkOutside(float3 posES) {
|
||||
return (abs(posES.x) > 0.5 || abs(posES.y) > 0.5 || abs(posES.z) > 0.5);
|
||||
}
|
||||
|
||||
#if !defined(WCE_EACH_MESH)
|
||||
#define RECONSTRUCT_NORMAL_HQ 1
|
||||
half3 WCE_reconstructNormalWS(float2 screenUV, float3 posWS, float rdC) {
|
||||
#if (!RECONSTRUCT_NORMAL_HQ)
|
||||
return normalize(cross(ddy(posWS), ddx(posWS)));
|
||||
#else
|
||||
float2 offsetU = float2(_ScreenParams.z - 1, 0);
|
||||
float2 offsetV = float2(0, _ScreenParams.w - 1);
|
||||
float2 uvN = screenUV + offsetV;
|
||||
float2 uvS = screenUV - offsetV;
|
||||
float2 uvE = screenUV + offsetU;
|
||||
float2 uvW = screenUV - offsetU;
|
||||
float rdN = SampleSceneDepth(uvN);
|
||||
float rdS = SampleSceneDepth(uvS);
|
||||
float rdE = SampleSceneDepth(uvE);
|
||||
float rdW = SampleSceneDepth(uvW);
|
||||
float3 vV = abs(rdN - rdC) < abs(rdS - rdC) ? WCE_reconstructPosWS(uvN, rdN) - posWS : posWS - WCE_reconstructPosWS(uvS, rdS);
|
||||
float3 vU = abs(rdE - rdC) < abs(rdW - rdC) ? WCE_reconstructPosWS(uvE, rdE) - posWS : posWS - WCE_reconstructPosWS(uvW, rdW);
|
||||
return normalize(cross(vV, vU));
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
half3 WCE_getNormal(v2f IN, float2 screenUV, float3 posWS, float rawDepth) {
|
||||
#if defined(WCE_EACH_MESH)
|
||||
float3 normal = IN.normalWS; // VFACEセマンティクスでの向きの取得はメッシュのデータに不具合があると正しくないことがあるので廃止
|
||||
normal *= -sign(dot(normal, WCE_viewDirRawWS(posWS)));
|
||||
return normal;
|
||||
#elif defined(_WCE_ONE_PASS_NORMAL)
|
||||
float3 normal = SampleSceneNormals(screenUV);
|
||||
#if VERSION_LOWER(10, 9) || (VERSION_GREATER_EQUAL(11, 0) && VERSION_LOWER(12, 0))
|
||||
// ViewSpaceで保存されているURPのバージョン対応
|
||||
normal.z *= -1;
|
||||
normal = mul((float3x3)UNITY_MATRIX_I_V, normal).xyz;
|
||||
normal = normalize(normal);
|
||||
#endif
|
||||
// normal *= -sign(dot(normal, WCE_viewDirWS(posWS))+0.07 );
|
||||
normal *= -sign(dot(normal, WCE_viewDirRawWS(posWS)));
|
||||
return normal;
|
||||
#else
|
||||
return WCE_reconstructNormalWS(screenUV, posWS, rawDepth);
|
||||
#endif
|
||||
}
|
||||
|
||||
// ------------------------------------------------------------------------ Fog (Oblique Projection Supported)
|
||||
#if defined(_USE_FOG)
|
||||
float WCE_computeFogFactorZ0ToFar(float z) {
|
||||
#if defined(FOG_LINEAR)
|
||||
return saturate(z * unity_FogParams.z + unity_FogParams.w);
|
||||
#elif defined(FOG_EXP) || defined(FOG_EXP2)
|
||||
return unity_FogParams.x * z;
|
||||
#else
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
float WCE_calcFog(float viewDepth) {
|
||||
float nearToFarZ = max(viewDepth - _ProjectionParams.y, 0);
|
||||
return ComputeFogIntensity(WCE_computeFogFactorZ0ToFar(nearToFarZ));
|
||||
}
|
||||
#endif
|
||||
|
||||
// ------------------------------------------------------------------------
|
||||
#if defined(WCE_EACH_MESH)
|
||||
// [Each Mesh]
|
||||
#define WCE_clipOutside (_WCE_ClipOutside == 1)
|
||||
#else
|
||||
// [At Once]
|
||||
#define WCE_clipOutside true
|
||||
#endif
|
||||
|
||||
|
||||
// ------------------------------------------------------------------------ Fragment
|
||||
#define CLR_COL half4(0, 0, 0, 0)
|
||||
|
||||
TEXTURE2D(_WCE_CausticsTex);
|
||||
TEXTURE2D(_WCE_ImageMaskTex);
|
||||
SAMPLER(sampler_WCE_CausticsTex);
|
||||
SAMPLER(sampler_WCE_ImageMaskTex);
|
||||
|
||||
half4 frag(v2f IN) : SV_Target {
|
||||
UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(IN);
|
||||
|
||||
// ---------- WorldPos
|
||||
float2 screenUV = IN.posScrn.xy / IN.posScrn.w;
|
||||
#if defined(WCE_EACH_MESH)
|
||||
// [Each Mesh]
|
||||
float3 posWS = IN.posWld;
|
||||
float3 posES = IN.posEffect;
|
||||
float rawDepth = 0.5;
|
||||
#else
|
||||
// [At Once]
|
||||
float rawDepth = SampleSceneDepth(screenUV);
|
||||
float3 posWS = WCE_reconstructPosWS(screenUV, rawDepth);
|
||||
float3 posES = TransformWorldToObject(posWS);
|
||||
#endif
|
||||
|
||||
// ---------- Debug Info
|
||||
#if defined(WCE_DEBUG_NORMAL) || defined(WCE_DEBUG_DEPTH) || defined(WCE_DEBUG_FACING) || defined(WCE_DEBUG_CAUSTICS) || defined(WCE_DEBUG_AREA)
|
||||
if ((WCE_clipOutside && WCE_checkOutside(posES)) || rawDepth == UNITY_RAW_FAR_CLIP_VALUE) discard;
|
||||
#endif
|
||||
#if defined(WCE_DEBUG_NORMAL)
|
||||
return half4(pow(saturate(WCE_getNormal(IN, screenUV, posWS, rawDepth) * 0.5 + 0.5), 4) * 0.9, 1);
|
||||
#elif defined(WCE_DEBUG_DEPTH)
|
||||
float debugDepth = -TransformWorldToView(posWS).z * _ProjectionParams.w;
|
||||
return half4(pow(abs(debugDepth), 0.7).xxx, 1);
|
||||
#elif defined(WCE_DEBUG_FACING)
|
||||
float3 n = WCE_getNormal(IN, screenUV, posWS, rawDepth);
|
||||
float b = dot(-n, WCE_viewDirWS(posWS));
|
||||
return half4((saturate(pow(abs(b), 2) * 0.5)).xxx, 1);
|
||||
#elif defined(WCE_DEBUG_CAUSTICS)
|
||||
_WCE_MultiplyByTex = 0;
|
||||
#elif defined(WCE_DEBUG_AREA)
|
||||
_WCE_MultiplyByTex = 0;
|
||||
#endif
|
||||
|
||||
// ---------- Clip Outside
|
||||
[branch] if ((WCE_clipOutside && WCE_checkOutside(posES)) || rawDepth == UNITY_RAW_FAR_CLIP_VALUE) return CLR_COL;
|
||||
|
||||
// ---------- Atten Start
|
||||
float atten = 1; // halfだとVRシングルパスで不安定?
|
||||
const float ATTEN_TH = 0.001;
|
||||
|
||||
// ---------- Fog
|
||||
#if defined(_USE_FOG)
|
||||
#if defined(WCE_EACH_MESH)
|
||||
float viewDepth = IN.viewDepth;
|
||||
#else
|
||||
float viewDepth = -TransformWorldToView(posWS).z;
|
||||
#endif
|
||||
atten *= WCE_calcFog(viewDepth);
|
||||
#endif
|
||||
|
||||
// ---------- Distance Fade
|
||||
float3 viewDir = posWS - _WorldSpaceCameraPos; // ←ifに入れるとVR SinglePassでエラー
|
||||
[branch] if (atten > ATTEN_TH && _WCE_DistanceFadeCoef > 0.0001f) {
|
||||
atten *= smoothstep(0, 1, 1 - (length(viewDir) - _WCE_DistanceFadeStart) * _WCE_DistanceFadeCoef);
|
||||
}
|
||||
|
||||
// ---------- Image Mask
|
||||
[branch] if (atten > ATTEN_TH && _WCE_UseImageMask != 0) {
|
||||
atten *= _WCE_ImageMaskTex.Sample(sampler_WCE_ImageMaskTex, posES.xz + 0.5).r;
|
||||
}
|
||||
|
||||
// ---------- Atten End
|
||||
[branch] if (atten <= ATTEN_TH) return CLR_COL;
|
||||
_WCE_IntensityMainLit *= atten;
|
||||
_WCE_IntensityAddLit *= atten;
|
||||
|
||||
// ---------- Normal
|
||||
half3 normalWS = WCE_getNormal(IN, screenUV, posWS, rawDepth);
|
||||
|
||||
// ---------- Caustics
|
||||
half3 c = WCE_EffectCore(posWS, normalWS, screenUV, _WCE_CausticsTex, sampler_WCE_CausticsTex, _WCE_TexRotateSinCos, _WCE_TexChannels, _WCE_TilingSeed, _WCE_TilingRot, _WCE_TilingHard, _WCE_Density, _WCE_SurfaceY, _WCE_SurfFadeStart, _WCE_SurfFadeCoef, _WCE_DepthFadeStart, _WCE_DepthFadeCoef, _WCE_IntensityMainLit, _WCE_IntensityAddLit, _WCE_ShadowIntensity, _WCE_ColorShift, _WCE_LitSaturation, _WCE_NormalAtten, _WCE_NormalAttenRate, _WCE_TransparentBack, _WCE_BacksideShadow);
|
||||
|
||||
// ---------- Multiply Opaque Tex
|
||||
[branch] if (_WCE_MultiplyByTex > 0) {
|
||||
c *= 1 - (1 - SHADERGRAPH_SAMPLE_SCENE_COLOR(screenUV)) * _WCE_MultiplyByTex;
|
||||
}
|
||||
return half4(c, 1);
|
||||
}
|
||||
|
||||
ENDHLSL
|
||||
}
|
||||
}
|
||||
|
||||
Fallback "Hidden/InternalErrorShader"
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 348afebc23c3c6e4c8f05f2ea8f758fc
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
preprocessorOverride: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,377 @@
|
||||
// WaterCausticsModules
|
||||
// Copyright (c) 2021 Masataka Hakozaki
|
||||
|
||||
#ifndef WCE_COMMON_INCLUDED
|
||||
#define WCE_COMMON_INCLUDED
|
||||
|
||||
#if defined(_LIGHT_COOKIES)
|
||||
#pragma warning(disable : 3595) // ループ内勾配命令warning
|
||||
#endif
|
||||
|
||||
#if !defined(SHADERGRAPH_PREVIEW)
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"
|
||||
#include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Lighting.hlsl"
|
||||
#include "hextiling.hlsl"
|
||||
#endif
|
||||
|
||||
#define WCE_LIT_DIR_MIN_Y 0.1
|
||||
|
||||
#if defined(WCE_USE_SAMPLER2D_INSTEAD_TEXTURE2D)
|
||||
#define WCE_TEX_ARGS(texName) sampler2D texName
|
||||
#define WCE_TEX_SAMPLE_GRAD(st, texName, uv, dx, dy) tex2Dgrad(st.texName, uv, dx, dy)
|
||||
#define WCE_TEX_STRUCT(texName) sampler2D texName
|
||||
#define WCE_TEX_STORE(st, texName) st.texName = texName
|
||||
#else
|
||||
#define WCE_TEX_ARGS(texName) TEXTURE2D(texName), SAMPLER(texName##SS)
|
||||
#define WCE_TEX_SAMPLE_GRAD(st, texName, uv, dx, dy) SAMPLE_TEXTURE2D_GRAD(st.texName, st.texName##SS, uv, dx, dy)
|
||||
#define WCE_TEX_STRUCT(texName) TEXTURE2D(texName); SAMPLER(texName##SS)
|
||||
#define WCE_TEX_STORE(st, texName) st.texName = texName; st.texName##SS = texName##SS
|
||||
#endif
|
||||
|
||||
|
||||
struct WCE_SamplingData {
|
||||
WCE_TEX_STRUCT(CausticsTex);
|
||||
float3 pos;
|
||||
float3 posDDX;
|
||||
float3 posDDY;
|
||||
int3 channel;
|
||||
float2 colShift;
|
||||
float2x2 rotMatrix;
|
||||
bool useTiling;
|
||||
uint tilingSeed;
|
||||
float tilingRot;
|
||||
float tilingHard;
|
||||
float2 dx;
|
||||
float2 dy;
|
||||
};
|
||||
|
||||
struct WCE_Lit {
|
||||
half3 dir;
|
||||
half3 dirDDX;
|
||||
half3 dirDDY;
|
||||
half3 color;
|
||||
half atten;
|
||||
half shadow;
|
||||
};
|
||||
|
||||
struct WCE_CommonData {
|
||||
float3 posW;
|
||||
float3 posWdX;
|
||||
float3 posWdY;
|
||||
half3 normWS;
|
||||
float2 scrnUV;
|
||||
half shadow;
|
||||
half saturation;
|
||||
half normAtten;
|
||||
half normRate;
|
||||
half transparent;
|
||||
half backShadow;
|
||||
float depthSign;
|
||||
half depthFade;
|
||||
uint layer;
|
||||
float3 posOnSurf;
|
||||
};
|
||||
|
||||
|
||||
// Mainライト事前チェック 水面通過時、光線が上向き(1)か下向き(-1)か / RenderingLayerMaskチェック
|
||||
void WCE_mainLitPreCheck(WCE_CommonData dt, out float signLitY, out bool result) {
|
||||
#if defined(SHADERGRAPH_PREVIEW)
|
||||
signLitY = -1;
|
||||
result = true;
|
||||
#else
|
||||
Light l = GetMainLight();
|
||||
signLitY = sign(l.direction.y);
|
||||
#ifdef _LIGHT_LAYERS
|
||||
result = (dt.depthSign == signLitY) && IsMatchingLightLayer(l.layerMask, dt.layer);
|
||||
#else
|
||||
result = (dt.depthSign == signLitY);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
// Addライト事前チェック 水面通過時、光線が上向き(1)か下向き(-1)か / RenderingLayerMaskチェック
|
||||
void WCE_addLitPreCheck(uint idx, WCE_CommonData dt, out float signLitY, out bool result) {
|
||||
#if defined(SHADERGRAPH_PREVIEW)
|
||||
signLitY = -1;
|
||||
result = false;
|
||||
#else
|
||||
Light l = GetAdditionalLight(idx, dt.posOnSurf);
|
||||
signLitY = sign(l.direction.y);
|
||||
#ifdef _LIGHT_LAYERS
|
||||
result = (dt.depthSign == signLitY) && IsMatchingLightLayer(l.layerMask, dt.layer);
|
||||
#else
|
||||
result = (dt.depthSign == signLitY);
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// Main Light Data
|
||||
void WCE_getMainLitData(WCE_CommonData dt, out WCE_Lit lit) {
|
||||
lit = (WCE_Lit)0;
|
||||
#if defined(SHADERGRAPH_PREVIEW)
|
||||
lit.dir = normalize(half3(0, 1, -0.4));
|
||||
lit.color = half3(1, 1, 1);
|
||||
lit.atten = lit.shadow = 1;
|
||||
#else
|
||||
#if (defined(_MAIN_LIGHT_SHADOWS) || defined(_MAIN_LIGHT_SHADOWS_CASCADE) || defined(_MAIN_LIGHT_SHADOWS_SCREEN)) && !defined(_RECEIVE_SHADOWS_OFF)
|
||||
#if defined(_MAIN_LIGHT_SHADOWS_SCREEN) && !defined(_SURFACE_TYPE_TRANSPARENT)
|
||||
float4 shadowCoord = float4(dt.scrnUV.xy, 0, 1);
|
||||
#else
|
||||
float4 shadowCoord = TransformWorldToShadowCoord(dt.posW);
|
||||
#endif
|
||||
Light l = GetMainLight(shadowCoord, dt.posW, half4(1, 1, 1, 1));
|
||||
#else
|
||||
Light l = GetMainLight();
|
||||
#endif
|
||||
lit.dir = lit.dirDDX = lit.dirDDY = l.direction;
|
||||
lit.color = l.color;
|
||||
lit.atten = l.distanceAttenuation;
|
||||
lit.shadow = l.shadowAttenuation;
|
||||
#endif
|
||||
}
|
||||
|
||||
// Additional Light Data
|
||||
void WCE_getAddLitData(uint idx, WCE_CommonData dt, out WCE_Lit lit) {
|
||||
lit = (WCE_Lit)0;
|
||||
#if defined(SHADERGRAPH_PREVIEW)
|
||||
lit.dir = lit.color = lit.dirDDX = lit.dirDDY = half3(0, -1, 0);
|
||||
lit.atten = lit.shadow = 0;
|
||||
#else
|
||||
#if defined(_ADDITIONAL_LIGHT_SHADOWS) && !defined(_RECEIVE_SHADOWS_OFF)
|
||||
Light l = GetAdditionalLight(idx, dt.posW, half4(1, 1, 1, 1));
|
||||
#else
|
||||
Light l = GetAdditionalLight(idx, dt.posW);
|
||||
#endif
|
||||
lit.dir = l.direction;
|
||||
lit.color = l.color;
|
||||
lit.atten = l.distanceAttenuation;
|
||||
lit.shadow = l.shadowAttenuation;
|
||||
lit.dirDDX = GetAdditionalLight(idx, dt.posWdX).direction;
|
||||
lit.dirDDY = GetAdditionalLight(idx, dt.posWdY).direction;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
// 水面付近減衰
|
||||
half WCE_SurfFade(float depthAbs, float SurfFadeStart, float SurfFadeCoef) {
|
||||
return saturate((depthAbs - SurfFadeStart) * SurfFadeCoef);
|
||||
}
|
||||
|
||||
// 深さによる減衰
|
||||
half WCE_depthFade(float depthAbs, float DepthFadeStart, float DepthFadeCoef) {
|
||||
return saturate(1 - (depthAbs - DepthFadeStart) * DepthFadeCoef);
|
||||
}
|
||||
|
||||
// ライト角度での減衰
|
||||
half WCE_litDirAtten(half3 litDir) {
|
||||
return saturate((abs(litDir.y) - WCE_LIT_DIR_MIN_Y) / (0.4 - WCE_LIT_DIR_MIN_Y));
|
||||
}
|
||||
|
||||
|
||||
// 減衰をまとめる
|
||||
half WCE_calcAtten(WCE_CommonData dt, WCE_Lit lit, half dotLN) {
|
||||
half dot = saturate(dotLN) + saturate(-dotLN) * dt.transparent;
|
||||
dot = pow(abs(dot), dt.normRate);
|
||||
dot = 1 - (1 - dot) * dt.normAtten;
|
||||
half litDirAtten = WCE_litDirAtten(lit.dir);
|
||||
return lit.atten * lit.shadow * dot * litDirAtten * dt.depthFade;
|
||||
}
|
||||
|
||||
|
||||
// 彩度調整
|
||||
half3 WCE_adjustSaturation(half3 litColor, WCE_CommonData dt) {
|
||||
half gray = dot(litColor, half3(0.299, 0.587, 0.114));
|
||||
return lerp(gray.xxx, litColor, dt.saturation.xxx);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
half3 WCE_sampleColGrad(WCE_SamplingData smpDt, float2 uvG) {
|
||||
float2 uvR = uvG - smpDt.colShift;
|
||||
float2 uvB = uvG + smpDt.colShift;
|
||||
half3 c;
|
||||
c.r = WCE_TEX_SAMPLE_GRAD(smpDt, CausticsTex, uvR, smpDt.dx, smpDt.dy)[smpDt.channel[0]];
|
||||
c.g = WCE_TEX_SAMPLE_GRAD(smpDt, CausticsTex, uvG, smpDt.dx, smpDt.dy)[smpDt.channel[1]];
|
||||
c.b = WCE_TEX_SAMPLE_GRAD(smpDt, CausticsTex, uvB, smpDt.dx, smpDt.dy)[smpDt.channel[2]];
|
||||
return c;
|
||||
}
|
||||
|
||||
half3 WCE_sampleRandomTiling(WCE_SamplingData smpDt, float2 uvG) {
|
||||
#if defined(SHADERGRAPH_PREVIEW)
|
||||
return WCE_sampleColGrad(smpDt, uvG);
|
||||
#else
|
||||
float2 uv1, uv2, uv3;
|
||||
float3 w;
|
||||
HEX_TILING_GetUV(uvG, smpDt.tilingRot, smpDt.tilingSeed, uv1, uv2, uv3, w);
|
||||
half3 c1 = WCE_sampleColGrad(smpDt, uv1);
|
||||
half3 c2 = WCE_sampleColGrad(smpDt, uv2);
|
||||
half3 c3 = WCE_sampleColGrad(smpDt, uv3);
|
||||
return HEX_TILING_MixColor(smpDt.tilingHard, c1, c2, c3, w);
|
||||
#endif
|
||||
}
|
||||
|
||||
// テクスチャサンプリング
|
||||
half3 WCE_sampleCausticsTex(WCE_SamplingData smpDt, WCE_Lit lit, float signLitY) {
|
||||
// ※litDir.yの絶対値がWCE_LIT_DIR_MIN_Y以下の場合はattenが0なので0除算は無視
|
||||
// smpDt.posは水面基準の位置(Density乗算済み) yは深さ
|
||||
float2 uvG = (lit.dir.xz / lit.dir.y) * smpDt.pos.y + smpDt.pos.xz;
|
||||
float2 uvDDX = (lit.dirDDX.xz / lit.dirDDX.y) * smpDt.posDDX.y + smpDt.posDDX.xz;
|
||||
float2 uvDDY = (lit.dirDDY.xz / lit.dirDDY.y) * smpDt.posDDY.y + smpDt.posDDY.xz;
|
||||
uvG = mul(smpDt.rotMatrix, uvG);
|
||||
smpDt.dx = mul(smpDt.rotMatrix, uvDDX) - uvG;
|
||||
smpDt.dy = mul(smpDt.rotMatrix, uvDDY) - uvG;
|
||||
|
||||
uvG += signLitY * 0.05; // ←鏡面すぎると不自然なのでずらす
|
||||
half3 c;
|
||||
[branch] if (smpDt.useTiling) {
|
||||
c = WCE_sampleRandomTiling(smpDt, uvG);
|
||||
} else {
|
||||
c = WCE_sampleColGrad(smpDt, uvG);
|
||||
}
|
||||
return c;
|
||||
}
|
||||
|
||||
half WCE_calcShadowIntensity(WCE_Lit lit, half dotLN, WCE_CommonData dt) {
|
||||
#if defined(_RECEIVE_SHADOWS_OFF)
|
||||
return lit.shadow;
|
||||
#else
|
||||
return 1 - (1 - lit.shadow) * lerp(dt.backShadow * (1 - step(dt.transparent, 0) * step(1, dt.normAtten)), dt.shadow, step(0, dotLN));
|
||||
#endif
|
||||
}
|
||||
|
||||
uint WCE_getMeshRendLayer() {
|
||||
#if defined(SHADERGRAPH_PREVIEW) || !defined(_LIGHT_LAYERS)
|
||||
return 255;
|
||||
#else
|
||||
return GetMeshRenderingLightLayer();
|
||||
#endif
|
||||
}
|
||||
|
||||
half3 WCE_commonLitProcess(WCE_CommonData dt, WCE_SamplingData smpDt, half Intensity, WCE_Lit lit, float signLitY, half3 debugCol) {
|
||||
half dotLN = dot(lit.dir, dt.normWS);
|
||||
lit.shadow = WCE_calcShadowIntensity(lit, dotLN, dt);
|
||||
half3 color = half3(0, 0, 0);
|
||||
[branch] if (lit.atten * lit.shadow > 0) {
|
||||
half atten = WCE_calcAtten(dt, lit, dotLN);
|
||||
[branch] if (atten > 0) {
|
||||
#if defined(WCE_DEBUG_AREA)
|
||||
color = debugCol;
|
||||
#else
|
||||
half3 texColor = WCE_sampleCausticsTex(smpDt, lit, signLitY);
|
||||
lit.color = WCE_adjustSaturation(lit.color, dt);
|
||||
color = texColor * lit.color * atten * Intensity;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
|
||||
half3 WCE_addLitProcess(uint i, WCE_CommonData dt, WCE_SamplingData smpDt, half Intensity) {
|
||||
WCE_Lit lit;
|
||||
float signLitY;
|
||||
bool checkResult;
|
||||
half3 debugCol = half3(0, 0.1, 0);
|
||||
WCE_addLitPreCheck(i, dt, /*out*/ signLitY, checkResult);
|
||||
half3 color = half3(0, 0, 0);
|
||||
[branch] if (checkResult) {
|
||||
WCE_getAddLitData(i, dt, /*out*/ lit);
|
||||
color = WCE_commonLitProcess(dt, smpDt, Intensity, lit, signLitY, debugCol);
|
||||
}
|
||||
return color;
|
||||
}
|
||||
|
||||
|
||||
// Main
|
||||
half3 WCE_EffectCore(float3 WorldPos, half3 NormalWS, float2 ScreenUV, WCE_TEX_ARGS(CausticsTex), float2 TexRotSinCos, int3 TexChannels, int TilingSeed, float TilingRot, float TilingHard, float Density, float SurfY, float SurfFadeStart, float SurfFadeCoef, float DepthFadeStart, float DepthFadeCoef, half MainLitIntensity, half AddLitIntensity, half ShadowIntensity, float2 ColorShift, half LitSaturation, half NormalAtten, half NormalAttenRate, half TransparentBack, half BacksideShadow) {
|
||||
#if defined(SHADERGRAPH_PREVIEW)
|
||||
SurfY = 10;
|
||||
SurfFadeStart = DepthFadeStart = DepthFadeCoef = AddLitIntensity = 0;
|
||||
SurfFadeCoef = 1;
|
||||
#endif
|
||||
|
||||
#if defined(_WCE_DISABLED)
|
||||
return half3(0, 0, 0);
|
||||
#else
|
||||
WCE_CommonData dt;
|
||||
dt.posW = WorldPos;
|
||||
dt.posWdX = WorldPos + ddx(WorldPos);
|
||||
dt.posWdY = WorldPos + ddy(WorldPos);
|
||||
dt.normWS = NormalWS;
|
||||
dt.scrnUV = ScreenUV;
|
||||
dt.shadow = ShadowIntensity;
|
||||
dt.saturation = LitSaturation;
|
||||
dt.normAtten = NormalAtten;
|
||||
dt.normRate = max(NormalAttenRate, 1);
|
||||
dt.transparent = TransparentBack;
|
||||
dt.backShadow = BacksideShadow;
|
||||
float depth = SurfY - WorldPos.y;
|
||||
float depthAbs = abs(depth);
|
||||
dt.depthSign = sign(depth);
|
||||
dt.depthFade = WCE_SurfFade(depthAbs, SurfFadeStart, SurfFadeCoef) * WCE_depthFade(depthAbs, DepthFadeStart, DepthFadeCoef);
|
||||
dt.layer = WCE_getMeshRendLayer();
|
||||
dt.posOnSurf = float3(WorldPos.x, SurfY, WorldPos.z);
|
||||
|
||||
WCE_SamplingData smpDt;
|
||||
smpDt.useTiling = (TilingSeed >= 0);
|
||||
smpDt.tilingSeed = asuint(TilingSeed);
|
||||
smpDt.tilingRot = TilingRot;
|
||||
smpDt.tilingHard = TilingHard;
|
||||
smpDt.rotMatrix = float2x2(TexRotSinCos.y, -TexRotSinCos.x, TexRotSinCos.x, TexRotSinCos.y);
|
||||
smpDt.colShift = mul(smpDt.rotMatrix, ColorShift);
|
||||
smpDt.channel = TexChannels;
|
||||
smpDt.pos = float3(dt.posW.x, depth, dt.posW.z) * Density;
|
||||
smpDt.posDDX = float3(dt.posWdX.x, depth, dt.posWdX.z) * Density;
|
||||
smpDt.posDDY = float3(dt.posWdY.x, depth, dt.posWdY.z) * Density;
|
||||
WCE_TEX_STORE(smpDt, CausticsTex);
|
||||
|
||||
half3 color = half3(0, 0, 0);
|
||||
|
||||
[branch] if (MainLitIntensity > 0) {
|
||||
float signLitY;
|
||||
bool checkResult;
|
||||
WCE_mainLitPreCheck(dt, /*out*/ signLitY, checkResult);
|
||||
[branch] if (checkResult) {
|
||||
WCE_Lit lit;
|
||||
half3 debugCol = half3(0.2, 0, 0);
|
||||
WCE_getMainLitData(dt, /*out*/ lit);
|
||||
color = WCE_commonLitProcess(dt, smpDt, MainLitIntensity, lit, signLitY, debugCol);
|
||||
}
|
||||
}
|
||||
|
||||
#if !defined(SHADERGRAPH_PREVIEW)
|
||||
#if defined(_ADDITIONAL_LIGHTS) || (defined(SHADERPASS) && (SHADERPASS == SHADERPASS_GBUFFER)) // Deferredは素通り
|
||||
[branch] if (AddLitIntensity > 0) {
|
||||
#if defined(_FORWARD_PLUS)
|
||||
// [Forward+]
|
||||
uint dirLitCnt = URP_FP_DIRECTIONAL_LIGHTS_COUNT;
|
||||
[loop] for (uint i = 0; i < min(dirLitCnt, MAX_VISIBLE_LIGHTS); i++) {
|
||||
color += WCE_addLitProcess(i, dt, smpDt, AddLitIntensity);
|
||||
}
|
||||
uint idx;
|
||||
ClusterIterator iterator = ClusterInit(ScreenUV, WorldPos, 0);
|
||||
[loop] while (ClusterNext(iterator, /*out*/ idx)) {
|
||||
color += WCE_addLitProcess(idx + dirLitCnt, dt, smpDt, AddLitIntensity);
|
||||
}
|
||||
#else
|
||||
// [Forward] & [Deferred]
|
||||
uint pixelLitCnt = GetAdditionalLightsCount();
|
||||
[loop] for (uint i = 0u; i < pixelLitCnt; i++) {
|
||||
color += WCE_addLitProcess(i, dt, smpDt, AddLitIntensity);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
return color;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if defined(_LIGHT_COOKIES)
|
||||
#pragma warning(enable : 3595) // ループ内勾配命令warning
|
||||
#endif
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3401e4fcc8ae3fa44926828d678fb61d
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
preprocessorOverride: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,95 @@
|
||||
//
|
||||
// Description : HexTilingFunction based on mmikk's hextile-demo
|
||||
// Original : mmikk
|
||||
// License : Copyright (c) 2022 mmikk
|
||||
// Distributed under the MIT License. See LICENSE file.
|
||||
// https://github.com/mmikk/hextile-demo/blob/main/LICENSE
|
||||
// Edited by : M.Hakozaki
|
||||
//
|
||||
|
||||
#ifndef HEX_TILING_INCLUDED
|
||||
#define HEX_TILING_INCLUDED
|
||||
|
||||
uint lowBias32(uint x) {
|
||||
// Best Integer Hash by FabriceNeyret2
|
||||
// https://www.shadertoy.com/view/WttXWX#
|
||||
x ^= x >> 16;
|
||||
x *= 0x7feb352dU;
|
||||
x ^= x >> 15;
|
||||
x *= 0x846ca68bU;
|
||||
x ^= x >> 16;
|
||||
return x;
|
||||
}
|
||||
|
||||
float2 HEX_TILING_hash3_2(int2 v, uint hashSeed) {
|
||||
uint2 u = uint2(asuint(v));
|
||||
uint x0 = u.x + (u.y << 16) + hashSeed;
|
||||
uint x1 = (u.x << 16) + u.y + (hashSeed << 16);
|
||||
return float2(lowBias32(x0), lowBias32(x1)) / float(0xffffffffU);
|
||||
}
|
||||
|
||||
float2 HEX_TILING_hash1_2(uint hashSeed) {
|
||||
return float2(hashSeed, lowBias32(hashSeed)) / float(0xffffffffU);
|
||||
}
|
||||
|
||||
float2x2 HEX_TILING_getRot(float2 hash, float rot) {
|
||||
const float M_PI = 3.14159;
|
||||
float rad = (frac((hash.x + hash.y) * 65536) - 0.5) * M_PI * rot;
|
||||
float c = cos(rad);
|
||||
float s = sin(rad);
|
||||
return float2x2(c, -s, s, c);
|
||||
}
|
||||
|
||||
void HEX_TILING_GetUV(float2 uv, float rot, uint seed, out float2 uv1, out float2 uv2, out float2 uv3, out float3 w) {
|
||||
const float TILE_SIZE = 1.3;
|
||||
const float HEX_RATE = sqrt(3) * 0.5; // 0.86602... 六角形の縦横比
|
||||
const float2x2 gridToSkewedGrid = float2x2(1 / HEX_RATE, 0, -0.5 / HEX_RATE, 1);
|
||||
uint hashSeed = lowBias32(seed);
|
||||
uv += HEX_TILING_hash1_2(hashSeed);
|
||||
float2 skewedCoord = mul(gridToSkewedGrid, uv * TILE_SIZE);
|
||||
int2 baseIdx = floor(skewedCoord);
|
||||
float3 temp = float3(frac(skewedCoord), 0);
|
||||
temp.z = 1 - temp.x - temp.y;
|
||||
float s = step(0, -temp.z);
|
||||
float s2 = 2 * s - 1;
|
||||
int2 idx1 = baseIdx + int2(s, s);
|
||||
int2 idx2 = baseIdx + int2(s, 1 - s);
|
||||
int2 idx3 = baseIdx + int2(1 - s, s);
|
||||
float2 hash1 = HEX_TILING_hash3_2(idx1, hashSeed);
|
||||
float2 hash2 = HEX_TILING_hash3_2(idx2, hashSeed);
|
||||
float2 hash3 = HEX_TILING_hash3_2(idx3, hashSeed);
|
||||
float2x2 rot1 = HEX_TILING_getRot(hash1, rot);
|
||||
float2x2 rot2 = HEX_TILING_getRot(hash2, rot);
|
||||
float2x2 rot3 = HEX_TILING_getRot(hash3, rot);
|
||||
uv1 = mul(uv, rot1) + hash1;
|
||||
uv2 = mul(uv, rot2) + hash2;
|
||||
uv3 = mul(uv, rot3) + hash3;
|
||||
w.x = -temp.z * s2;
|
||||
w.y = s - temp.y * s2;
|
||||
w.z = s - temp.x * s2;
|
||||
return;
|
||||
}
|
||||
|
||||
float3 HEX_TILING_gain3(float3 w, float hardness) {
|
||||
float k = log(1 - hardness) / log(0.5);
|
||||
float3 s = 2 * step(0.5, w);
|
||||
float3 m = 2 * (1 - s);
|
||||
w = 0.5 * s + 0.25 * m * pow(max(0.0, s + w * m), k);
|
||||
return w.xyz / (w.x + w.y + w.z);
|
||||
}
|
||||
|
||||
half3 HEX_TILING_MixColor(float hardness, half3 c1, half3 c2, half3 c3, float3 w) {
|
||||
half3 Lw = half3(0.299, 0.587, 0.114);
|
||||
half3 Dw = half3(dot(c1, Lw), dot(c2, Lw), dot(c3, Lw));
|
||||
Dw = lerp(1, Dw, 0.1);
|
||||
w = Dw * pow(w, 7); // 7
|
||||
w /= (w.x + w.y + w.z);
|
||||
w = HEX_TILING_gain3(w, hardness);
|
||||
return w.x * c1 + w.y * c2 + w.z * c3;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0b3dda1ff7ed7ad49aa545454b7a9d6e
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
preprocessorOverride: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5c458e7b6a8f6024aba7bed0ab7b3320
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 3694e90a2c2614f4ca5b8d6abd67d1ee
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,98 @@
|
||||
// WaterCausticsModules
|
||||
// Copyright (c) 2021 Masataka Hakozaki
|
||||
|
||||
#ifndef WCECF_SYNC_COMMON_INCLUDED
|
||||
#define WCECF_SYNC_COMMON_INCLUDED
|
||||
|
||||
#include "../../Effect/Shaders/WaterCausticsEffectCommon.hlsl"
|
||||
|
||||
CBUFFER_START(_WCECF_)
|
||||
float _WCECF_Density;
|
||||
int3 _WCECF_TexChannels;
|
||||
float2 _WCECF_TexRotateSinCos;
|
||||
int _WCECF_TilingSeed;
|
||||
float _WCECF_TilingRot;
|
||||
float _WCECF_TilingHard;
|
||||
float _WCECF_SurfaceY;
|
||||
float _WCECF_SurfFadeStart;
|
||||
float _WCECF_SurfFadeCoef;
|
||||
float _WCECF_DepthFadeStart;
|
||||
float _WCECF_DepthFadeCoef;
|
||||
float _WCECF_DistanceFadeStart;
|
||||
float _WCECF_DistanceFadeCoef;
|
||||
half _WCECF_IntensityMainLit;
|
||||
half _WCECF_IntensityAddLit;
|
||||
float2 _WCECF_ColorShift;
|
||||
half _WCECF_LitSaturation;
|
||||
half _WCECF_MultiplyIntensity;
|
||||
half _WCECF_NormalAtten;
|
||||
half _WCECF_NormalAttenRate;
|
||||
half _WCECF_TransparentBack;
|
||||
half _WCECF_BacksideShadow;
|
||||
half _WCECF_ShadowIntensity;
|
||||
int _WCECF_ClipOutside;
|
||||
int _WCECF_UseImageMask;
|
||||
float4x4 _WCECF_WorldToObjMatrix;
|
||||
CBUFFER_END
|
||||
|
||||
#if defined(WCE_USE_SAMPLER2D_INSTEAD_TEXTURE2D)
|
||||
sampler2D _WCECF_CausticsTex;
|
||||
sampler2D _WCECF_ImageMaskTex;
|
||||
#define WCE_TEX_PARAMS_RAW(texName) texName
|
||||
#define WCE_TEX_SAMPLE_RAW(texName, uv) tex2D(texName, uv)
|
||||
#else
|
||||
TEXTURE2D(_WCECF_CausticsTex);
|
||||
TEXTURE2D(_WCECF_ImageMaskTex);
|
||||
SAMPLER(sampler_WCECF_CausticsTex);
|
||||
SAMPLER(sampler_WCECF_ImageMaskTex);
|
||||
#define WCE_TEX_PARAMS_RAW(texName) texName, sampler##texName
|
||||
#define WCE_TEX_SAMPLE_RAW(texName, uv) texName.Sample(sampler##texName, (uv))
|
||||
#endif
|
||||
|
||||
|
||||
half3 WCECF_syncCore(float3 WorldPos, half3 NormalWS, float2 ScreenUV, half3 BaseColor, half aten) {
|
||||
half3 c = WCE_EffectCore(WorldPos, NormalWS, ScreenUV, WCE_TEX_PARAMS_RAW(_WCECF_CausticsTex), _WCECF_TexRotateSinCos, _WCECF_TexChannels, _WCECF_TilingSeed, _WCECF_TilingRot, _WCECF_TilingHard, _WCECF_Density, _WCECF_SurfaceY, _WCECF_SurfFadeStart, _WCECF_SurfFadeCoef, _WCECF_DepthFadeStart, _WCECF_DepthFadeCoef, _WCECF_IntensityMainLit * aten, _WCECF_IntensityAddLit * aten, _WCECF_ShadowIntensity, _WCECF_ColorShift, _WCECF_LitSaturation, _WCECF_NormalAtten, _WCECF_NormalAttenRate, _WCECF_TransparentBack, _WCECF_BacksideShadow);
|
||||
|
||||
c *= 1 - (1 - BaseColor) * _WCECF_MultiplyIntensity;
|
||||
return c;
|
||||
}
|
||||
|
||||
|
||||
half3 WCECF_SyncCommon(float3 WorldPos, half3 NormalWS, float2 ScreenUV, half3 BaseColor) {
|
||||
#if defined(_WCE_DISABLED)
|
||||
return half3(0, 0, 0);
|
||||
#elif defined(SHADERGRAPH_PREVIEW)
|
||||
return WCECF_syncCore(WorldPos, NormalWS, ScreenUV, BaseColor, 1);
|
||||
#else
|
||||
float atten = 1;
|
||||
const float ATTEN_TH = 0.001;
|
||||
// Distance Fade
|
||||
float3 viewDir = WorldPos - _WorldSpaceCameraPos; // ←ifに入れるとVR SinglePassでエラー
|
||||
[branch] if (_WCECF_DistanceFadeCoef > 0.0001) {
|
||||
atten *= smoothstep(0, 1, 1 - (length(viewDir) - _WCECF_DistanceFadeStart) * _WCECF_DistanceFadeCoef);
|
||||
}
|
||||
// Volume & Image Mask
|
||||
[branch] if (atten > ATTEN_TH && (_WCECF_ClipOutside != 0 || _WCECF_UseImageMask != 0)) {
|
||||
float3 posES = mul(_WCECF_WorldToObjMatrix, float4(WorldPos, 1)).xyz;
|
||||
[branch] if (atten > ATTEN_TH && _WCECF_ClipOutside != 0 && (abs(posES.x) > 0.5 || abs(posES.y) > 0.5 || abs(posES.z) > 0.5)) {
|
||||
atten = 0;
|
||||
}
|
||||
[branch] if (atten > ATTEN_TH && _WCECF_UseImageMask != 0) {
|
||||
atten *= WCE_TEX_SAMPLE_RAW(_WCECF_ImageMaskTex, posES.xz + 0.5).r;
|
||||
}
|
||||
}
|
||||
[branch] if (atten > ATTEN_TH) {
|
||||
return WCECF_syncCore(WorldPos, NormalWS, ScreenUV, BaseColor, atten);
|
||||
} else {
|
||||
return half3(0, 0, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
// for ShaderGraph
|
||||
void WCECF_SyncForShaderGraph_float(float3 WorldPos, half3 NormalWS, float2 ScreenUV, half3 BaseColor, out half3 EmissionColor) {
|
||||
EmissionColor = WCECF_SyncCommon(WorldPos, NormalWS, ScreenUV, BaseColor);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 702e58733f1eade43bc3acab9149cd79
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
preprocessorOverride: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8e1bb73059427954f8a2c3b980c2ee68
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,53 @@
|
||||
// WaterCausticsModules
|
||||
// Copyright (c) 2021 Masataka Hakozaki
|
||||
|
||||
#ifndef WCECF_FOR_HLSL_INCLUDED
|
||||
#define WCECF_FOR_HLSL_INCLUDED
|
||||
|
||||
#define REQUIRE_OPAQUE_TEXTURE
|
||||
#include "../Common/WaterCausticsEmissionSync_Common.hlsl"
|
||||
|
||||
// --------------------------------------------
|
||||
// Custom Function (for HLSL Scripting)
|
||||
half3 WCE_WaterCausticsEmission(float3 WorldPos, half3 NormalWS, Texture2D CausticsTex, SamplerState CausticsTexSS, float2 TexRotSinCos = float2(0, 1), int3 TexChannels = int3(0, 1, 2), bool UseTiling = false, int TilingSeed = 0, float TilingRot = 0, float TilingHard = 0.85, float Density = 0.2, float SurfaceY = 2, float SurfFadeStart = 0, float SurfFadeEnd = 0.5, float DepthFadeStart = 0, float DepthFadeEnd = 10000, half MainLitIntensity = 1, half AddLitIntensity = 1, half ShadowIntensity = 1, float ColorShiftX = 0.4, float ColorShiftZ = -0.1, half LitSaturation = 0.2, half NormalAtten = 1, half NormalAttenRate = 2, half TransparentBack = 0, half BacksideShadow = 0) {
|
||||
|
||||
float4 posSS = ComputeScreenPos(TransformWorldToHClip(WorldPos));
|
||||
float2 ScreenUV = posSS.xy / posSS.w;
|
||||
float SurfFadeCoef = 1 / max(SurfFadeEnd - SurfFadeStart, 0.000001);
|
||||
float DepthFadeCoef = 1 / max(DepthFadeEnd - DepthFadeStart, 0.000001);
|
||||
float2 ColorShift = float2(ColorShiftX, ColorShiftZ) * 0.01;
|
||||
SurfFadeStart = max(SurfFadeStart, 0);
|
||||
TilingSeed = UseTiling ? max(TilingSeed, 0) : - 1;
|
||||
TilingHard = clamp(TilingHard, 0.75, 0.999);
|
||||
|
||||
half3 e = WCE_EffectCore(WorldPos, NormalWS, ScreenUV, CausticsTex, CausticsTexSS, TexRotSinCos, TexChannels, TilingSeed, TilingRot, TilingHard, Density, SurfaceY, SurfFadeStart, SurfFadeCoef, DepthFadeStart, DepthFadeCoef, MainLitIntensity, AddLitIntensity, ShadowIntensity, ColorShift, LitSaturation, NormalAtten, NormalAttenRate, TransparentBack, BacksideShadow);
|
||||
|
||||
return e;
|
||||
}
|
||||
|
||||
// Old 1.2.0
|
||||
half3 WCE_WaterCausticsEmission(float3 WorldPos, half3 NormalWS, Texture2D CausticsTex, SamplerState CausticsTexSS, float Scale, float SurfaceY, float SurfFadeWidth, float SurfFadeOffset, float DepthFadeCoef, half MainLitIntensity, half AddLitIntensity, float ColorShiftX, float ColorShiftZ, half LitSaturation, half NormalAtten, half NormalAttenRate, half TransparentBack) {
|
||||
float Density = 1 / max(Scale, 0.0001);
|
||||
float DepthFadeEnd = 1 / max(DepthFadeCoef, 0.000001);
|
||||
// to Newest
|
||||
return WCE_WaterCausticsEmission(WorldPos, NormalWS, CausticsTex, CausticsTexSS, float2(0, 1), int3(0, 1, 2), false, 0, 0, 0.85, Density, SurfaceY, SurfFadeOffset, SurfFadeWidth, 0, DepthFadeEnd, MainLitIntensity, AddLitIntensity, 1, ColorShiftX, ColorShiftZ, LitSaturation, NormalAtten, NormalAttenRate, TransparentBack, 0);
|
||||
}
|
||||
|
||||
// Old 1.1.4
|
||||
half3 WCE_WaterCausticsEmission(float3 WorldPos, half3 NormalWS, Texture2D CausticsTex, SamplerState CausticsTexSS, float Scale, float SurfaceY, float SurfFadeWidth, float SurfFadeOffset, half MainLitIntensity, half AddLitIntensity, float ColorShiftX, float ColorShiftZ, half LitSaturation, half NormalAtten, half NormalAttenRate, half TransparentBack) {
|
||||
|
||||
// to 1.2.0
|
||||
return WCE_WaterCausticsEmission(WorldPos, NormalWS, CausticsTex, CausticsTexSS, Scale, SurfaceY, SurfFadeWidth, SurfFadeOffset, 0, MainLitIntensity, AddLitIntensity, ColorShiftX, ColorShiftZ, LitSaturation, NormalAtten, NormalAttenRate, TransparentBack);
|
||||
}
|
||||
|
||||
// --------------------------------------------
|
||||
// Custom Function Sync with effect script on the scene. (for HLSL Scripting)
|
||||
half3 WCE_WaterCausticsEmissionSync(float3 WorldPos, half3 NormalWS, half3 BaseColor = half3(1, 1, 1)) {
|
||||
float4 posSS = ComputeScreenPos(TransformWorldToHClip(WorldPos));
|
||||
float2 ScreenUV = posSS.xy / posSS.w;
|
||||
return WCECF_SyncCommon(WorldPos, NormalWS, ScreenUV, BaseColor);
|
||||
}
|
||||
|
||||
// --------------------------------------------
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 832df1354b7c37f41842fd11b0365e8c
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
preprocessorOverride: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 5a3b2a20ed95082499666114b7e76013
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8410e5d1e5fac2b4196a22217f3f03e9
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 11500000, guid: 60072b568d64c40a485e0fc55012dc9f, type: 3}
|
||||
@@ -0,0 +1,30 @@
|
||||
// WaterCausticsModules
|
||||
// Copyright (c) 2021 Masataka Hakozaki
|
||||
|
||||
#ifndef WCECF_FOR_SHADER_GRAPH_INCLUDED
|
||||
#define WCECF_FOR_SHADER_GRAPH_INCLUDED
|
||||
|
||||
#include "../../Effect/Shaders/WaterCausticsEffectCommon.hlsl"
|
||||
|
||||
// Custom Function (for ShaderGraph)
|
||||
void WCECF_Emission_float(float3 WorldPos, half3 NormalWS, float2 ScreenUV, UnityTexture2D CausticsTex, float2 TexRotSinCos, int3 TexChannels, bool UseTiling, int TilingSeed, float TilingRot, float TilingHard, float Density, float SurfaceY, float SurfFadeStart, float SurfFadeCoef, float DepthFadeStart, float DepthFadeCoef, half MainLitIntensity, half AddLitIntensity, half ShadowIntensity, float2 ColorShift, half LitSaturation, half NormalAtten, half NormalAttenRate, half TransparentBack, half BacksideShadow, out half3 EmissionColor) {
|
||||
|
||||
SurfFadeStart = max(SurfFadeStart, 0);
|
||||
TilingSeed = UseTiling ? max(TilingSeed, 0) : - 1;
|
||||
TilingHard = clamp(TilingHard, 0.75, 0.999);
|
||||
|
||||
half3 e = WCE_EffectCore(WorldPos, NormalWS, ScreenUV, CausticsTex.tex, CausticsTex.samplerstate, TexRotSinCos, TexChannels, TilingSeed, TilingRot, TilingHard, Density, SurfaceY, SurfFadeStart, SurfFadeCoef, DepthFadeStart, DepthFadeCoef, MainLitIntensity, AddLitIntensity, ShadowIntensity, ColorShift, LitSaturation, NormalAtten, NormalAttenRate, TransparentBack, BacksideShadow);
|
||||
|
||||
EmissionColor = e;
|
||||
}
|
||||
|
||||
// Custom Function Through
|
||||
void WCECF_EmissionThrough_float(float3 WorldPos, half3 NormalWS, float2 ScreenUV, UnityTexture2D CausticsTex, float2 TexRotSinCos, int3 TexChannels, int TilingSeed, float TilingRot, float TilingHard, float Density, float SurfaceY, float SurfFadeStart, float SurfFadeCoef, float DepthFadeStart, float DepthFadeCoef, half MainLitIntensity, half AddLitIntensity, half ShadowIntensity, float2 ColorShift, half LitSaturation, half NormalAtten, half NormalAttenRate, half TransparentBack, half BacksideShadow, out half3 EmissionColor) {
|
||||
|
||||
half3 e = WCE_EffectCore(WorldPos, NormalWS, ScreenUV, CausticsTex.tex, CausticsTex.samplerstate, TexRotSinCos, TexChannels, TilingSeed, TilingRot, TilingHard, Density, SurfaceY, SurfFadeStart, SurfFadeCoef, DepthFadeStart, DepthFadeCoef, MainLitIntensity, AddLitIntensity, ShadowIntensity, ColorShift, LitSaturation, NormalAtten, NormalAttenRate, TransparentBack, BacksideShadow);
|
||||
|
||||
EmissionColor = e;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ab406b74f7edc354da8c8cad2f7f2b97
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
preprocessorOverride: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 2dbc7b6e0e182924990f86f7fa2c8bbd
|
||||
ScriptedImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
script: {fileID: 11500000, guid: 60072b568d64c40a485e0fc55012dc9f, type: 3}
|
||||
@@ -0,0 +1,39 @@
|
||||
{
|
||||
"name": "WaterCausticsModules.Effect",
|
||||
"rootNamespace": "",
|
||||
"references": [
|
||||
"GUID:15fc0a57446b3144c949da3e2b9737a9",
|
||||
"GUID:df380645f10b7bc4b97d4f5eb6303d95",
|
||||
"GUID:e9406619edab4444f88f65f33c307684"
|
||||
],
|
||||
"includePlatforms": [],
|
||||
"excludePlatforms": [],
|
||||
"allowUnsafeCode": false,
|
||||
"overrideReferences": false,
|
||||
"precompiledReferences": [],
|
||||
"autoReferenced": true,
|
||||
"defineConstraints": [],
|
||||
"versionDefines": [
|
||||
{
|
||||
"name": "com.unity.render-pipelines.universal",
|
||||
"expression": "10.4",
|
||||
"define": "WCE_URP"
|
||||
},
|
||||
{
|
||||
"name": "com.unity.render-pipelines.universal",
|
||||
"expression": "10.8",
|
||||
"define": "WCE_URP_10_8"
|
||||
},
|
||||
{
|
||||
"name": "com.unity.render-pipelines.universal",
|
||||
"expression": "12.0",
|
||||
"define": "WCE_URP_12_0"
|
||||
},
|
||||
{
|
||||
"name": "com.unity.render-pipelines.universal",
|
||||
"expression": "14.0",
|
||||
"define": "WCE_URP_14_0"
|
||||
}
|
||||
],
|
||||
"noEngineReferences": false
|
||||
}
|
||||
@@ -0,0 +1,7 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 361f86fa5a6f5a64d93320fc9858673b
|
||||
AssemblyDefinitionImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 05cc36a4b7f8df24499d7e13464045a6
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6802d3dcf7fe5274680866daa29e85e0
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7ce3ae1808996354b896e05cadbd5196
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f31dc67949f82694bbbba2e4ed6662d7
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,71 @@
|
||||
// WaterCausticsModules
|
||||
// Copyright (c) 2021 Masataka Hakozaki
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
#pragma warning disable 162
|
||||
|
||||
namespace MH.WaterCausticsModules {
|
||||
/*------------------------------------------------------------------------
|
||||
スクリプトインポート時チェック
|
||||
古いバージョンのファイルがまだある場合にダイアログとWarningを表示
|
||||
※他でスクリプトエラーが発生していると呼ばれないので注意
|
||||
-------------------------------------------------------------------------*/
|
||||
public class CheckConflict {
|
||||
|
||||
// ファイルのGUID ※TexGenフォルダ内のファイルであること
|
||||
static readonly string GUID = "3a4975b64748c9a4db8c082b2e1877eb";
|
||||
static readonly string OLD_FILE_NAME = "IconPause.png"; // v2には無い
|
||||
static bool conflicting {
|
||||
get {
|
||||
var path = AssetDatabase.GUIDToAssetPath (GUID);
|
||||
// ※削除した後、実際に無くてもパスが返ってくるので注意 File.Exists必須
|
||||
return !string.IsNullOrEmpty (path) && path.EndsWith (OLD_FILE_NAME) && File.Exists (path);
|
||||
}
|
||||
}
|
||||
static readonly double INTERVAL = 30d;
|
||||
static double s_NestTime;
|
||||
|
||||
[InitializeOnLoadMethod]
|
||||
static private void initializeOnLoad () {
|
||||
EditorApplication.delayCall += delayFunc;
|
||||
}
|
||||
|
||||
static void delayFunc () {
|
||||
EditorApplication.update -= editorUpdate;
|
||||
if (conflicting) {
|
||||
EditorApplication.update += editorUpdate;
|
||||
showDialog ();
|
||||
}
|
||||
}
|
||||
|
||||
static void editorUpdate () {
|
||||
if (EditorApplication.timeSinceStartup > s_NestTime) {
|
||||
if (conflicting) {
|
||||
showError ();
|
||||
s_NestTime = EditorApplication.timeSinceStartup + INTERVAL;
|
||||
} else {
|
||||
EditorApplication.update -= editorUpdate;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if WCE_DEVELOPMENT
|
||||
[MenuItem ("WCM/TestDialog/CheckConflict")]
|
||||
static void test () { showDialog (); showError (); }
|
||||
#endif
|
||||
|
||||
static string title = $"Conflicting Error ({Constant.ASSET_NAME})";
|
||||
static string body = $"Conflicting error with older version.\nPlease re-import after delete the folder.\n\n1, Delete the \"Assets/{Constant.ASSET_FOLDER_NAME}\" folder.\n\n2, Re-import this asset again.\n\n[{Constant.ASSET_NAME}]";
|
||||
static void showDialog () {
|
||||
EditorUtility.DisplayDialog ($"Conflicting Error ({Constant.ASSET_NAME})", body, "OK");
|
||||
}
|
||||
static void showError () {
|
||||
Debug.LogError ($"{title} {body.Replace("\n", " ")}\n\n\n");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 03231be3beb7fa54bae3130503848057
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,46 @@
|
||||
// WaterCausticsModules
|
||||
// Copyright (c) 2021 Masataka Hakozaki
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using System.Text.RegularExpressions;
|
||||
#endif
|
||||
|
||||
namespace MH.WaterCausticsModules {
|
||||
public class Constant {
|
||||
public const string URL_MANUAL = "https://hacoapp.com/asset/wce/v2/ManualPDF.pdf";
|
||||
public const string ASSET_NAME = "WaterCausticsEffect for URP";
|
||||
public const string ASSET_FOLDER_NAME = "WaterCausticsModules";
|
||||
public const string EFFECT_FOLDER_NAME = "WaterCausticsEffect";
|
||||
public const string ASE_PACKAGE_NAME = "ForAmplifyShaderEditor.unitypackage";
|
||||
public const string REQUIRE_UNITY_VER = "2020.3 or later";
|
||||
public const string REQUIRE_URP_VER = "10.4 or later";
|
||||
public const string SHADER_NAME_HEADER = "Hidden/WaterCausticsModules/";
|
||||
public const string URL_HOW_TO_ADD_FEATURE = "https://docs.unity3d.com/Packages/com.unity.render-pipelines.universal@14.0/manual/urp-renderer-feature-how-to-add.html";
|
||||
public const string README_MENU_ITEM_PATH = "Window/WaterCausticsModules/Readme";
|
||||
public const int WCE_VERSION_INT = 20001;
|
||||
public const string WCE_VERSION_STR = "2.0.1";
|
||||
|
||||
#if UNITY_EDITOR
|
||||
static public bool CheckPackageName (string packageName) {
|
||||
// OK : "Water Caustics Effect for URP"
|
||||
// OK : "Water Caustics Effect for URP V2"
|
||||
// OK : "WaterCausticsEffect for URP"
|
||||
// OK : "WaterCausticsEffectForURP"
|
||||
// OK : "WaterCausticsEffectForURP_V2"
|
||||
// OK : "Water Caustics Modules"
|
||||
// OK : "Water Caustics Module"
|
||||
// OK : "PackageWaterCausticsModules_v2"
|
||||
// OK : "WaterCausticsTexGen"
|
||||
// NO : "WaterEffect"
|
||||
packageName = packageName.ToLower ();
|
||||
if (new Regex (".*water ?caustics ?effect ?for ?urp.*").IsMatch (packageName))
|
||||
return true;
|
||||
if (new Regex (".*water ?caustics ?modules?.*").IsMatch (packageName))
|
||||
return true;
|
||||
if (new Regex (".*water ?caustics ?(tex|texture) ?gen?.*").IsMatch (packageName))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 9b3cf681b8dff4740b11e2f3bef2383b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 32a93edaee788e44d88724c553bfce84
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
After Width: | Height: | Size: 261 B |
@@ -0,0 +1,144 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 00f635a8489e49047bc7e1e9a86437ae
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 11
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 1
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 0
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 0
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 2
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 32
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: 63
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 32
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: 63
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: iPhone
|
||||
maxTextureSize: 32
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: 63
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Android
|
||||
maxTextureSize: 32
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: 63
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Windows Store Apps
|
||||
maxTextureSize: 8192
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
After Width: | Height: | Size: 188 B |
@@ -0,0 +1,144 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 84b574295abb91649b9f9a4dd8d7d14b
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 11
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 1
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 0
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 0
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 2
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 32
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: 63
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 32
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: 63
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: iPhone
|
||||
maxTextureSize: 32
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: 63
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Android
|
||||
maxTextureSize: 32
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: 63
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Windows Store Apps
|
||||
maxTextureSize: 8192
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,50 @@
|
||||
// WaterCausticsModules
|
||||
// Copyright (c) 2021 Masataka Hakozaki
|
||||
|
||||
Shader "Hidden/WaterCausticsModules/Icon" {
|
||||
Properties {
|
||||
_MainTex ("Texture", 2D) = "Black" { }
|
||||
}
|
||||
SubShader {
|
||||
LOD 100
|
||||
Pass {
|
||||
Tags { "RenderType" = "Transparent" }
|
||||
Blend SrcAlpha OneMinusSrcAlpha
|
||||
CGPROGRAM
|
||||
#pragma vertex vert
|
||||
#pragma fragment frag
|
||||
#include "UnityCG.cginc"
|
||||
|
||||
struct appdata {
|
||||
float4 vertex : POSITION;
|
||||
float2 uv : TEXCOORD0;
|
||||
};
|
||||
|
||||
struct v2f {
|
||||
float2 uv : TEXCOORD0;
|
||||
float4 vertex : SV_POSITION;
|
||||
};
|
||||
|
||||
sampler2D _MainTex;
|
||||
float4 _MainTex_ST;
|
||||
|
||||
v2f vert(appdata v) {
|
||||
v2f o;
|
||||
o.vertex = UnityObjectToClipPos(v.vertex);
|
||||
o.uv = TRANSFORM_TEX(v.uv, _MainTex);
|
||||
return o;
|
||||
}
|
||||
|
||||
fixed4 frag(v2f i) : SV_Target {
|
||||
fixed4 col;
|
||||
col.rgb = 1;
|
||||
col.a = tex2D(_MainTex, i.uv).r;
|
||||
return col;
|
||||
}
|
||||
ENDCG
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
fileFormatVersion: 2
|
||||
guid: f4badb18dc89fef40ae07e8a56416ae5
|
||||
ShaderImporter:
|
||||
externalObjects: {}
|
||||
defaultTextures: []
|
||||
nonModifiableTextures: []
|
||||
preprocessorOverride: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
After Width: | Height: | Size: 231 B |
@@ -0,0 +1,144 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ef50b6a95a84a124f98087051f675cde
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 11
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 1
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 1
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 0
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 0
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 2
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 32
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: 63
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 32
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: 63
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: iPhone
|
||||
maxTextureSize: 32
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: 63
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Android
|
||||
maxTextureSize: 32
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: 63
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Windows Store Apps
|
||||
maxTextureSize: 8192
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,67 @@
|
||||
// WaterCausticsModules
|
||||
// Copyright (c) 2021 Masataka Hakozaki
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MH.WaterCausticsModules {
|
||||
/*------------------------------------------------------------------------
|
||||
アセット上書きアップデート防止
|
||||
このアセットがインポートされようとした際、古いバージョンを削除するようダイアログ表示
|
||||
-------------------------------------------------------------------------*/
|
||||
public class PreventOverwriteAsset {
|
||||
[InitializeOnLoadMethod]
|
||||
static private void registerCallback () {
|
||||
AssetDatabase.importPackageStarted -= importStarted;
|
||||
AssetDatabase.importPackageStarted += importStarted;
|
||||
}
|
||||
|
||||
static void importStarted (string packageName) {
|
||||
var str = packageName.ToLower ();
|
||||
if (!str.Contains ("patch") && !str.Contains ("fix") && Constant.CheckPackageName (str)) {
|
||||
// フォルダ削除後もこのスクリプトがしばらく残っていてダイアログが表示されてしまうのでFile.Existsでチェック
|
||||
if (findAsset<TexGenModuleRef> (out var asset, out var path) && File.Exists (path)) {
|
||||
if (asset.assetFolder && asset.assetFolder.name == Constant.ASSET_FOLDER_NAME) {
|
||||
// アセットルートPathが取得出来た場合
|
||||
var folderPath = AssetDatabase.GetAssetPath (asset.assetFolder);
|
||||
showDialog (folderPath);
|
||||
} else {
|
||||
// アセットルートPathが取得出来ない場合
|
||||
showDialog ($"Assets/{Constant.ASSET_FOLDER_NAME}");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#if WCE_DEVELOPMENT
|
||||
[MenuItem ("WCM/TestDialog/PreventOverwrite")]
|
||||
static void dialogTest2 () {
|
||||
if (findAsset<TexGenModuleRef> (out var asset, out var path) && asset.assetFolder) {
|
||||
var folderPath = AssetDatabase.GetAssetPath (asset.assetFolder);
|
||||
showDialog (folderPath);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
static void showDialog (string folderPath) {
|
||||
string str0 = "Please delete old version before update.";
|
||||
string str1 = $"If this package is a different version,\nthe older version must be removed first to avoid conflicts.\n\n1, Cancel in the Import window appearing after this.\n\n2, Delete the \"{folderPath}\" folder.\n\n3, Import this asset again.\n\n\n({Constant.ASSET_NAME})";
|
||||
EditorUtility.DisplayDialog (str0, str1, "OK", "It's not different version.");
|
||||
}
|
||||
|
||||
static private bool findAsset<T> (out T asset, out string path) where T : Object {
|
||||
asset = null;
|
||||
path = null;
|
||||
var guids = AssetDatabase.FindAssets ($"t:{typeof (T).ToString()}", new [] { "Assets" }); // "t:MH.WaterCausticsModules.TexGenModuleRef"
|
||||
if (guids.Length == 0) return false;
|
||||
path = AssetDatabase.GUIDToAssetPath (guids [0]);
|
||||
asset = AssetDatabase.LoadAssetAtPath<T> (path);
|
||||
return asset != null;
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: c6d53284efe324f4abf18af23f2a010c
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,361 @@
|
||||
// WaterCausticsModules
|
||||
// Copyright (c) 2021 Masataka Hakozaki
|
||||
|
||||
#if UNITY_EDITOR && UNITY_2020_3_OR_NEWER
|
||||
using System.IO;
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MH.WaterCausticsModules {
|
||||
internal class PreviewWindow : EditorWindow {
|
||||
// --------------------------------------------------------------- Static
|
||||
internal static void OpenWindow (WaterCausticsTexGenerator target) {
|
||||
var win = GetWindow<PreviewWindow> (true);
|
||||
PreviewWindowStore.instance.window = win;
|
||||
win.setTarget (target);
|
||||
}
|
||||
|
||||
internal static void SetTargetIfShowing (WaterCausticsTexGenerator target) {
|
||||
var win = PreviewWindowStore.instance.window;
|
||||
if (win != null)
|
||||
win.setTarget (target);
|
||||
}
|
||||
|
||||
internal static void RemoveTarget (WaterCausticsTexGenerator target) {
|
||||
var win = PreviewWindowStore.instance.window;
|
||||
if (win != null && win._target == target)
|
||||
win.setTarget (null);
|
||||
}
|
||||
|
||||
internal static bool IsShowing () {
|
||||
return EditorWindow.HasOpenInstances<PreviewWindow> ();
|
||||
}
|
||||
|
||||
internal static void InspectorChanged (WaterCausticsTexGenerator target) {
|
||||
var win = PreviewWindowStore.instance.window;
|
||||
if (win != null && win._target == target)
|
||||
win.inspectorChanged ();
|
||||
}
|
||||
|
||||
internal static void CloseWindow () {
|
||||
var win = PreviewWindowStore.instance.window;
|
||||
if (win != null)
|
||||
win.Close ();
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
// --------------------------------------------------------------- SerializeField
|
||||
[SerializeField] private Texture m_iconUnlock;
|
||||
[SerializeField] private Texture m_iconLock;
|
||||
[SerializeField] private Texture m_iconMenu;
|
||||
[SerializeField] private Shader m_shaderIcon;
|
||||
|
||||
private WaterCausticsTexGenerator _target, _subTarget;
|
||||
private RenderTexture _rt;
|
||||
private double _lastTime;
|
||||
|
||||
private bool __locked;
|
||||
private bool isLocked {
|
||||
get => __locked;
|
||||
set {
|
||||
__locked = value;
|
||||
if (value == false)
|
||||
setTarget (_subTarget);
|
||||
}
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------- Event
|
||||
private void OnEnable () { }
|
||||
|
||||
private void OnDisable () {
|
||||
releaseTarget ();
|
||||
releaseTmpRT ();
|
||||
}
|
||||
|
||||
private void OnDestroy () {
|
||||
releaseTarget ();
|
||||
releaseTmpRT ();
|
||||
destroy (ref __matIcon);
|
||||
}
|
||||
|
||||
private void destroy<T> (ref T o) where T : Object {
|
||||
if (o == null) return;
|
||||
if (Application.isPlaying)
|
||||
Destroy (o);
|
||||
else
|
||||
DestroyImmediate (o);
|
||||
o = null;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------- Target
|
||||
private void releaseTarget () {
|
||||
if (_target != null) _target.FinishPreview ();
|
||||
_target = null;
|
||||
}
|
||||
private void setTarget (WaterCausticsTexGenerator target) {
|
||||
if (isLocked) {
|
||||
_subTarget = target;
|
||||
return;
|
||||
}
|
||||
if (_target != target)
|
||||
releaseTarget ();
|
||||
_target = _subTarget = target;
|
||||
_lastTime = EditorApplication.timeSinceStartup;
|
||||
setTitle ();
|
||||
previewUpdate ();
|
||||
}
|
||||
|
||||
private void setTitle () {
|
||||
string tarName = (_target != null) ? _target.name : "No Generator";
|
||||
this.titleContent = new GUIContent (tarName);
|
||||
}
|
||||
|
||||
private void inspectorChanged () {
|
||||
previewUpdate ();
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------- RenderTexture
|
||||
private void releaseTmpRT () {
|
||||
if (_rt) RenderTexture.ReleaseTemporary (_rt);
|
||||
_rt = null;
|
||||
}
|
||||
|
||||
private void getTmpRT (RenderTexture rt) {
|
||||
if (rt) _rt = RenderTexture.GetTemporary (rt.descriptor);
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------- Material
|
||||
private Material __matIcon;
|
||||
private Material matIcon () {
|
||||
if (__matIcon == null) {
|
||||
if (m_shaderIcon == null) {
|
||||
Debug.LogError ("Shader is null. " + this);
|
||||
Close ();
|
||||
} else {
|
||||
__matIcon = new Material (m_shaderIcon);
|
||||
__matIcon.hideFlags = HideFlags.HideAndDontSave;
|
||||
}
|
||||
}
|
||||
return __matIcon;
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------- OnGUI
|
||||
|
||||
private bool isLockable => (_target != null);
|
||||
private Rect getIconRect (float x, float y, float iconW = 20f) {
|
||||
var iconHalf = iconW * 0.5f;
|
||||
return new Rect (position.width - x - iconHalf, y - iconHalf, iconW, iconW);
|
||||
}
|
||||
|
||||
private bool clickCheck (Vector2 mousePos, float x, float y, float r) {
|
||||
return (mousePos - new Vector2 (position.width - x, y)).sqrMagnitude < r * r;
|
||||
}
|
||||
|
||||
void OnGUI () {
|
||||
// Draw Contents
|
||||
var winW = position.width;
|
||||
|
||||
if (_rt != null) {
|
||||
EditorGUI.DrawPreviewTexture (new Rect (0, 0, winW, winW), _rt, null, ScaleMode.StretchToFill, 0);
|
||||
} else if (_target != null) {
|
||||
GUILayout.Space (position.size.y / 2 - 10);
|
||||
EditorGUILayout.LabelField ("No Output Render Texture", StyleConstant.alertPinkCenter);
|
||||
} else {
|
||||
isLocked = false;
|
||||
GUILayout.Space (position.size.y / 2 - 10);
|
||||
EditorGUILayout.LabelField ("No Generator Selected", StyleConstant.alertCenter);
|
||||
}
|
||||
|
||||
EditorGUI.DrawPreviewTexture (getIconRect (10f, 10f), m_iconMenu, matIcon (), ScaleMode.StretchToFill, 0f, -1f);
|
||||
if (isLockable)
|
||||
EditorGUI.DrawPreviewTexture (getIconRect (30f, 10f), isLocked ? m_iconLock : m_iconUnlock, matIcon (), ScaleMode.StretchToFill, 0f, -1f);
|
||||
|
||||
|
||||
// Support Click
|
||||
if (Event.current != null && Event.current.type == EventType.MouseDown && Event.current.button == 0) {
|
||||
var mousePos = Event.current.mousePosition;
|
||||
if (clickCheck (mousePos, x : 10f, y : 10f, r : 10f))
|
||||
openContext ();
|
||||
else if (isLockable && clickCheck (mousePos, x : 30f, y : 10f, r : 10f))
|
||||
toggleLock ();
|
||||
}
|
||||
|
||||
// ContextMenu
|
||||
Event evt = Event.current;
|
||||
if (evt.type == EventType.ContextClick) {
|
||||
openContext ();
|
||||
evt.Use ();
|
||||
}
|
||||
}
|
||||
|
||||
private void openContext () {
|
||||
GenericMenu menu = new GenericMenu ();
|
||||
var winW = position.width;
|
||||
if (isLockable) {
|
||||
menu.AddItem (new GUIContent ("Lock", "Unlocked when entered into play mode."), isLocked, (o) => toggleLock (), null);
|
||||
menu.AddSeparator ("");
|
||||
}
|
||||
string curSize = $"Window Size ({winW.ToString ("F0")}x{winW.ToString ("F0")})/";
|
||||
if (_rt && _rt.width == _rt.height) {
|
||||
string rtW = _rt.width.ToString ("F0");
|
||||
menu.AddItem (new GUIContent ($"{curSize}Fit Texture {rtW}x{rtW}"), winW == _rt.width, specifyWindowSize, (float) _rt.width);
|
||||
menu.AddSeparator (curSize);
|
||||
}
|
||||
menu.AddItem (new GUIContent ($"{curSize}128x128"), winW == 128f, specifyWindowSize, 128f);
|
||||
menu.AddItem (new GUIContent ($"{curSize}256x256"), winW == 256f, specifyWindowSize, 256f);
|
||||
menu.AddItem (new GUIContent ($"{curSize}512x512"), winW == 512f, specifyWindowSize, 512f);
|
||||
menu.AddItem (new GUIContent ($"{curSize}1024x1024"), winW == 1024f, specifyWindowSize, 1024f);
|
||||
|
||||
if (_target != null) {
|
||||
menu.AddSeparator ("");
|
||||
menu.AddItem (new GUIContent ("Select Generator : " + _target.name), false, (o) => pingAndSelect (_target, true), null);
|
||||
if (_target.renderTexture != null) {
|
||||
bool isLocking = isLockable && isLocked;
|
||||
string action = isLocking ? "Select" : "Ping";
|
||||
menu.AddItem (new GUIContent (action + " Texture : " + _target.renderTexture.name), false, (o) => pingAndSelect (_target.renderTexture, isLocking), null);
|
||||
if (_rt != null) {
|
||||
menu.AddSeparator ("");
|
||||
menu.AddItem (new GUIContent ("Save PNG 8bit", "Save PNG 8bit"), false, savePng, null);
|
||||
menu.AddItem (new GUIContent ("Save EXR 32bit", "Save EXR 32bit"), false, saveEXR, null);
|
||||
}
|
||||
}
|
||||
}
|
||||
menu.AddSeparator ("");
|
||||
menu.AddItem (new GUIContent ("Close"), false, (o) => Close (), null);
|
||||
|
||||
menu.ShowAsContext ();
|
||||
}
|
||||
|
||||
|
||||
private string _preSaveImagePath;
|
||||
private void savePng (object o) {
|
||||
saveImage (isEXR: false);
|
||||
}
|
||||
private void saveEXR (object o) {
|
||||
saveImage (isEXR: true);
|
||||
}
|
||||
private void saveImage (bool isEXR) {
|
||||
if (_target == null || _target.renderTexture == null || _rt == null) return;
|
||||
string defaultPath = string.IsNullOrEmpty (_preSaveImagePath) ? Application.dataPath : Path.GetDirectoryName (_preSaveImagePath);
|
||||
string defaultName = string.IsNullOrEmpty (_preSaveImagePath) ? "WaterCausticsTexture" : Path.GetFileNameWithoutExtension (_preSaveImagePath);
|
||||
string path = EditorUtility.SaveFilePanel (isEXR ? "Save EXR Image" : "Save PNG Image", defaultPath, defaultName, isEXR ? "exr" : "png");
|
||||
if (string.IsNullOrEmpty (path)) return;
|
||||
_preSaveImagePath = path;
|
||||
|
||||
Texture2D tex = new Texture2D (_rt.width, _rt.height, TextureFormat.RGBAFloat, false);
|
||||
var tmp = RenderTexture.active;
|
||||
RenderTexture.active = _rt;
|
||||
tex.ReadPixels (new Rect (0, 0, _rt.width, _rt.height), 0, 0);
|
||||
var pixels = tex.GetPixels ();
|
||||
for (int i = 0; i < pixels.Length; i++) {
|
||||
if (!isEXR && PlayerSettings.colorSpace == ColorSpace.Linear) {
|
||||
pixels [i].r = Mathf.Pow (pixels [i].r, 1f / 2.2f);
|
||||
pixels [i].g = Mathf.Pow (pixels [i].g, 1f / 2.2f);
|
||||
pixels [i].b = Mathf.Pow (pixels [i].b, 1f / 2.2f);
|
||||
} else if (isEXR && PlayerSettings.colorSpace == ColorSpace.Gamma) {
|
||||
pixels [i].r = Mathf.Pow (pixels [i].r, 2.2f);
|
||||
pixels [i].g = Mathf.Pow (pixels [i].g, 2.2f);
|
||||
pixels [i].b = Mathf.Pow (pixels [i].b, 2.2f);
|
||||
}
|
||||
pixels [i].a = 1f;
|
||||
}
|
||||
tex.SetPixels (pixels);
|
||||
tex.Apply ();
|
||||
RenderTexture.active = tmp;
|
||||
|
||||
byte [] bytes = isEXR ? tex.EncodeToEXR (Texture2D.EXRFlags.CompressZIP) : tex.EncodeToPNG ();
|
||||
destroy (ref tex);
|
||||
File.WriteAllBytes (path, bytes);
|
||||
AssetDatabase.Refresh ();
|
||||
}
|
||||
|
||||
|
||||
private void pingAndSelect (Object obj, bool isSelect) {
|
||||
EditorGUIUtility.PingObject (obj);
|
||||
if (isSelect)
|
||||
Selection.activeObject = obj;
|
||||
}
|
||||
|
||||
private void toggleLock () {
|
||||
isLocked = !isLocked;
|
||||
Repaint ();
|
||||
}
|
||||
|
||||
private void specifyWindowSize (object w) {
|
||||
var pos = position;
|
||||
pos.size = new Vector2 ((float) w, (float) w);
|
||||
position = pos;
|
||||
}
|
||||
|
||||
// --------------------------------------------------------------- Update
|
||||
|
||||
private void setWindowSize () {
|
||||
var pos = position;
|
||||
if (pos.width != pos.height) {
|
||||
pos.size = new Vector2 (pos.width, pos.width);
|
||||
position = pos;
|
||||
}
|
||||
}
|
||||
|
||||
private void Update () {
|
||||
if (!UnityEditorInternal.InternalEditorUtility.isApplicationActive) return;
|
||||
if (PreviewWindowStore.instance.window != this) Close ();
|
||||
setWindowSize ();
|
||||
previewUpdate ();
|
||||
}
|
||||
|
||||
private void previewUpdate () {
|
||||
var curTime = EditorApplication.timeSinceStartup;
|
||||
var deltaTime = curTime - _lastTime;
|
||||
_lastTime = curTime;
|
||||
bool usablePreview = (_target != null && _target.renderTexture != null);
|
||||
if (usablePreview) {
|
||||
releaseTmpRT ();
|
||||
getTmpRT (_target.renderTexture);
|
||||
if (deltaTime > 0.15) deltaTime = 0;
|
||||
_target.Preview ((float) deltaTime, _rt);
|
||||
} else {
|
||||
releaseTmpRT ();
|
||||
}
|
||||
Repaint ();
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------- Style
|
||||
|
||||
private static class StyleConstant {
|
||||
internal static GUIStyle alertCenter;
|
||||
internal static GUIStyle alertPink;
|
||||
internal static GUIStyle alertPinkCenter;
|
||||
static StyleConstant () {
|
||||
alertPink = new GUIStyle ("Label");
|
||||
alertPink.normal.textColor = new Color (1f, 0.3f, 0.6f, 1f);
|
||||
|
||||
alertPinkCenter = new GUIStyle (alertPink);
|
||||
alertPinkCenter.alignment = TextAnchor.MiddleCenter;
|
||||
|
||||
alertCenter = new GUIStyle ("Label");
|
||||
alertCenter.alignment = TextAnchor.MiddleCenter;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
|
||||
}
|
||||
|
||||
|
||||
// --------------------------------------------------------------- Singleton
|
||||
internal class PreviewWindowStore : ScriptableSingleton<PreviewWindowStore> {
|
||||
internal PreviewWindow window;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------------------
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -0,0 +1,19 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 6a62b3cb9074a074a8c2d2e124f9e663
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- m_ViewDataDictionary: {instanceID: 0}
|
||||
- m_iconUnlock: {fileID: 2800000, guid: ef50b6a95a84a124f98087051f675cde, type: 3}
|
||||
- m_iconLock: {fileID: 2800000, guid: 00f635a8489e49047bc7e1e9a86437ae, type: 3}
|
||||
- m_iconPause: {fileID: 2800000, guid: 3a4975b64748c9a4db8c082b2e1877eb, type: 3}
|
||||
- m_iconResume: {fileID: 2800000, guid: d7a7047de193e4647b9c83dec83d813c, type: 3}
|
||||
- m_iconMenu: {fileID: 2800000, guid: 84b574295abb91649b9f9a4dd8d7d14b, type: 3}
|
||||
- m_shaderIcon: {fileID: 4800000, guid: f4badb18dc89fef40ae07e8a56416ae5, type: 3}
|
||||
- m_shaderImg: {fileID: 4800000, guid: fbe4f8dba6701284b9405ecf1901c10d, type: 3}
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0182e4a02e4c40c469a3f6ef1bc2a1e8
|
||||
folderAsset: yes
|
||||
DefaultImporter:
|
||||
externalObjects: {}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,66 @@
|
||||
// WaterCausticsModules
|
||||
// Copyright (c) 2021 Masataka Hakozaki
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MH.WaterCausticsModules {
|
||||
/*------------------------------------------------------------------------
|
||||
Readme
|
||||
※クラス名がReadmeだと他の名前空間のReadmeでもアイコンが変わってしまうので注意
|
||||
-------------------------------------------------------------------------*/
|
||||
public class WCMReadme : ScriptableObject {
|
||||
// ------------------------------------ ScriptableObject
|
||||
public Texture2D icon;
|
||||
public string title;
|
||||
public Section [] sections;
|
||||
|
||||
[System.Serializable]
|
||||
public class Section {
|
||||
public string heading, text, linkText, linkDesc, url;
|
||||
public Object obj;
|
||||
}
|
||||
|
||||
// ------------------------------------ AssetDatabase Callback
|
||||
// このアセットがインポートされた場合にReadmeを選択
|
||||
[InitializeOnLoadMethod]
|
||||
static private void registerCallback () {
|
||||
AssetDatabase.importPackageCompleted -= importCompleted;
|
||||
AssetDatabase.importPackageCompleted += importCompleted;
|
||||
}
|
||||
|
||||
static void importCompleted (string packageName) {
|
||||
if (Constant.CheckPackageName (packageName))
|
||||
EditorApplication.delayCall += selectReadme;
|
||||
}
|
||||
|
||||
// TODO ウィンドウ化
|
||||
[MenuItem (Constant.README_MENU_ITEM_PATH)]
|
||||
static void selectReadme () {
|
||||
if (findAsset<WCMReadme> (out var asset, out var path)) {
|
||||
showInspectorWindow ();
|
||||
EditorGUIUtility.PingObject (asset);
|
||||
Selection.activeObject = asset;
|
||||
}
|
||||
}
|
||||
|
||||
private static void showInspectorWindow () {
|
||||
var windowType = typeof (Editor).Assembly.GetType ("UnityEditor.InspectorWindow");
|
||||
EditorWindow.GetWindow (windowType);
|
||||
}
|
||||
|
||||
static private bool findAsset<T> (out T asset, out string path) where T : Object {
|
||||
asset = null;
|
||||
path = null;
|
||||
var guids = AssetDatabase.FindAssets ($"t:{typeof (T).ToString()}", new [] { "Assets" });
|
||||
if (guids.Length == 0) return false;
|
||||
path = AssetDatabase.GUIDToAssetPath (guids [0]);
|
||||
asset = AssetDatabase.LoadAssetAtPath<T> (path);
|
||||
return asset != null;
|
||||
}
|
||||
|
||||
// -------------------------------------------------------
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,12 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 7014fb6ed4db25e49a7ce277160913ee
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences:
|
||||
- icon: {instanceID: 0}
|
||||
executionOrder: 0
|
||||
icon: {fileID: 2800000, guid: d9814e54a4057294780a501cf65720c3, type: 3}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,146 @@
|
||||
// WaterCausticsModules
|
||||
// Copyright (c) 2021 Masataka Hakozaki
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MH.WaterCausticsModules {
|
||||
|
||||
[CustomEditor (typeof (WCMReadme))]
|
||||
public class WCMReadmeEditor : Editor {
|
||||
private bool isDark => EditorGUIUtility.isProSkin;
|
||||
private GUIStyle _baseStyle, _titleStyle, _textStyle, _headerStyle, _linkUrlStyle, _linkObjStyle, _warningStyle;
|
||||
void prepStyle () {
|
||||
if (_baseStyle != null) return;
|
||||
_baseStyle = new GUIStyle (EditorStyles.label);
|
||||
_baseStyle.wordWrap = true;
|
||||
_baseStyle.fontSize = 13;
|
||||
_baseStyle.richText = true;
|
||||
|
||||
_titleStyle = new GUIStyle (_baseStyle);
|
||||
_titleStyle.fontStyle = FontStyle.Bold;
|
||||
_titleStyle.fontSize = 18;
|
||||
|
||||
_textStyle = new GUIStyle (_baseStyle);
|
||||
_textStyle.fontSize = 14;
|
||||
|
||||
_headerStyle = new GUIStyle (_baseStyle);
|
||||
_headerStyle.fontStyle = FontStyle.Bold;
|
||||
_headerStyle.fontSize = 16;
|
||||
|
||||
_linkUrlStyle = new GUIStyle (_baseStyle);
|
||||
_linkUrlStyle.wordWrap = false;
|
||||
_linkUrlStyle.normal.textColor = isDark ? new Color (0f, 0.8f, 1f, 1f) : new Color (0f, 0.4f, 0.8f, 1f);
|
||||
_linkUrlStyle.hover.textColor = _linkUrlStyle.normal.textColor + Color.white * (isDark ? 0.3f : 0.2f);
|
||||
_linkUrlStyle.stretchWidth = false;
|
||||
|
||||
_linkObjStyle = new GUIStyle (_linkUrlStyle);
|
||||
_linkObjStyle.normal.textColor = isDark ? new Color (0f, 0.85f, 0.4f, 1f) : new Color (0f, 0.5f, 0.2f, 1f);
|
||||
_linkObjStyle.hover.textColor = _linkObjStyle.normal.textColor + Color.white * (isDark ? 0.3f : 0.2f);
|
||||
|
||||
_warningStyle = new GUIStyle (_baseStyle);
|
||||
_warningStyle.normal.textColor = isDark ? Color.white : new Color (0.8f, 0.1f, 0f, 1f);
|
||||
_warningStyle.normal.background = Texture2D.whiteTexture;
|
||||
}
|
||||
|
||||
protected override void OnHeaderGUI () {
|
||||
var icon = (target as WCMReadme).icon;
|
||||
if (icon == null) return;
|
||||
float iconW = EditorGUIUtility.currentViewWidth;
|
||||
float iconH = Mathf.Min (iconW * icon.height / icon.width, 150f);
|
||||
iconW = iconH * icon.width / icon.height;
|
||||
Rect rect = GUILayoutUtility.GetRect (iconW, iconH);
|
||||
rect.width -= 1f;
|
||||
GUI.DrawTexture (rect, icon, ScaleMode.ScaleAndCrop);
|
||||
}
|
||||
|
||||
|
||||
#if !UNITY_2020_3_OR_NEWER //|| WCE_DEVELOPMENT
|
||||
private readonly bool UNITY_VER_OK = false;
|
||||
#else
|
||||
private readonly bool UNITY_VER_OK = true;
|
||||
#endif
|
||||
|
||||
#if !WCM_URP_10 //|| WCE_DEVELOPMENT
|
||||
private readonly bool URP_OK = false;
|
||||
#else
|
||||
private readonly bool URP_OK = true;
|
||||
#endif
|
||||
|
||||
public override void OnInspectorGUI () {
|
||||
prepStyle ();
|
||||
|
||||
var tar = target as WCMReadme;
|
||||
GUILayout.Space (6);
|
||||
GUILayout.Label (tar.title, _titleStyle);
|
||||
GUILayout.Space (2);
|
||||
GUILayout.Label (Constant.WCE_VERSION_STR, _baseStyle);
|
||||
GUILayout.Space (4);
|
||||
|
||||
if (!UNITY_VER_OK) {
|
||||
GUILayout.Space (2);
|
||||
labelWarning ($"This asset is not compatible with current Unity version {Application.unityVersion}. Unity {Constant.REQUIRE_UNITY_VER} is required.");
|
||||
GUILayout.Space (6);
|
||||
}
|
||||
|
||||
if (!URP_OK) {
|
||||
GUILayout.Space (2);
|
||||
GUILayout.Label ($"This asset contains two modules TexGenerator and Effect. The Effect module is available for import in environments using UniversalRP {Constant.REQUIRE_URP_VER}. TexGenerator works with all render pipelines. The generated texture could be used in Light Cookie, Decal, Projector, and Materials.", _textStyle);
|
||||
GUILayout.Space (6);
|
||||
}
|
||||
|
||||
GUILayout.Space (2);
|
||||
|
||||
foreach (var section in tar.sections) {
|
||||
bool used = false;
|
||||
if (hasStr (section.heading)) {
|
||||
GUILayout.Space (12);
|
||||
GUILayout.Label (section.heading, _headerStyle);
|
||||
used = true;
|
||||
}
|
||||
if (hasStr (section.text)) {
|
||||
GUILayout.Space (2);
|
||||
GUILayout.Label (section.text, _baseStyle);
|
||||
used = true;
|
||||
}
|
||||
if (hasStr (section.linkText) && (hasStr (section.url) || section.obj != null)) {
|
||||
GUILayout.Space (2);
|
||||
bool isObj = (section.obj != null);
|
||||
used = true;
|
||||
if (labelLink (new GUIContent (section.linkText, hasStr (section.linkDesc) ? section.linkDesc : section.url), isObj)) {
|
||||
if (isObj) {
|
||||
AssetDatabase.OpenAsset (section.obj);
|
||||
} else {
|
||||
Application.OpenURL (section.url);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (used) GUILayout.Space (4);
|
||||
}
|
||||
GUILayout.Space (80);
|
||||
}
|
||||
|
||||
private bool hasStr (string str) => !string.IsNullOrEmpty (str);
|
||||
|
||||
void labelWarning (string text) {
|
||||
Color tmp = GUI.backgroundColor;
|
||||
GUI.backgroundColor = isDark ? new Color (1f, 0.3f, 0.6f, 0.4f) : new Color (1f, 0.3f, 0.6f, 0.5f);
|
||||
GUILayout.Label (text, _warningStyle);
|
||||
GUI.backgroundColor = tmp;
|
||||
}
|
||||
|
||||
private bool labelLink (GUIContent label, bool isObj = false, params GUILayoutOption [] options) {
|
||||
GUIStyle style = isObj ? _linkObjStyle : _linkUrlStyle;
|
||||
var rect = GUILayoutUtility.GetRect (label, style, options);
|
||||
Handles.BeginGUI ();
|
||||
Handles.color = style.normal.textColor;
|
||||
Handles.DrawLine (new Vector3 (rect.xMin, rect.yMax), new Vector3 (rect.xMax, rect.yMax));
|
||||
Handles.color = Color.white;
|
||||
Handles.EndGUI ();
|
||||
EditorGUIUtility.AddCursorRect (rect, MouseCursor.Link);
|
||||
return GUI.Button (rect, label, style);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: ec73cd83e04473b4b8bfea0e73a586fb
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
After Width: | Height: | Size: 2.8 KiB |
@@ -0,0 +1,144 @@
|
||||
fileFormatVersion: 2
|
||||
guid: d9814e54a4057294780a501cf65720c3
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 11
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 1
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 0
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 1
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 1
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 2
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 8192
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 8192
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: iPhone
|
||||
maxTextureSize: 8192
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Android
|
||||
maxTextureSize: 8192
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Windows Store Apps
|
||||
maxTextureSize: 8192
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID: 5e97eb03825dee720800000000000000
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
|
After Width: | Height: | Size: 22 KiB |
@@ -0,0 +1,144 @@
|
||||
fileFormatVersion: 2
|
||||
guid: df4ebd6140d53224396c4acf7d948291
|
||||
TextureImporter:
|
||||
internalIDToNameTable: []
|
||||
externalObjects: {}
|
||||
serializedVersion: 11
|
||||
mipmaps:
|
||||
mipMapMode: 0
|
||||
enableMipMap: 0
|
||||
sRGBTexture: 1
|
||||
linearTexture: 0
|
||||
fadeOut: 0
|
||||
borderMipMap: 0
|
||||
mipMapsPreserveCoverage: 0
|
||||
alphaTestReferenceValue: 0.5
|
||||
mipMapFadeDistanceStart: 1
|
||||
mipMapFadeDistanceEnd: 3
|
||||
bumpmap:
|
||||
convertToNormalMap: 0
|
||||
externalNormalMap: 0
|
||||
heightScale: 0.25
|
||||
normalMapFilter: 0
|
||||
isReadable: 0
|
||||
streamingMipmaps: 0
|
||||
streamingMipmapsPriority: 0
|
||||
vTOnly: 0
|
||||
grayScaleToAlpha: 0
|
||||
generateCubemap: 6
|
||||
cubemapConvolution: 0
|
||||
seamlessCubemap: 0
|
||||
textureFormat: 1
|
||||
maxTextureSize: 2048
|
||||
textureSettings:
|
||||
serializedVersion: 2
|
||||
filterMode: 1
|
||||
aniso: 1
|
||||
mipBias: 0
|
||||
wrapU: 1
|
||||
wrapV: 1
|
||||
wrapW: 0
|
||||
nPOTScale: 0
|
||||
lightmap: 0
|
||||
compressionQuality: 50
|
||||
spriteMode: 0
|
||||
spriteExtrude: 1
|
||||
spriteMeshType: 1
|
||||
alignment: 0
|
||||
spritePivot: {x: 0.5, y: 0.5}
|
||||
spritePixelsToUnits: 100
|
||||
spriteBorder: {x: 0, y: 0, z: 0, w: 0}
|
||||
spriteGenerateFallbackPhysicsShape: 1
|
||||
alphaUsage: 0
|
||||
alphaIsTransparency: 1
|
||||
spriteTessellationDetail: -1
|
||||
textureType: 2
|
||||
textureShape: 1
|
||||
singleChannelComponent: 0
|
||||
flipbookRows: 1
|
||||
flipbookColumns: 1
|
||||
maxTextureSizeSet: 0
|
||||
compressionQualitySet: 0
|
||||
textureFormatSet: 0
|
||||
ignorePngGamma: 0
|
||||
applyGammaDecoding: 0
|
||||
platformSettings:
|
||||
- serializedVersion: 3
|
||||
buildTarget: DefaultTexturePlatform
|
||||
maxTextureSize: 8192
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Standalone
|
||||
maxTextureSize: 8192
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: iPhone
|
||||
maxTextureSize: 8192
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Android
|
||||
maxTextureSize: 8192
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 0
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
- serializedVersion: 3
|
||||
buildTarget: Windows Store Apps
|
||||
maxTextureSize: 8192
|
||||
resizeAlgorithm: 0
|
||||
textureFormat: -1
|
||||
textureCompression: 1
|
||||
compressionQuality: 50
|
||||
crunchedCompression: 0
|
||||
allowsAlphaSplitting: 0
|
||||
overridden: 0
|
||||
androidETC2FallbackOverride: 0
|
||||
forceMaximumCompressionQuality_BC6H_BC7: 0
|
||||
spriteSheet:
|
||||
serializedVersion: 2
|
||||
sprites: []
|
||||
outline: []
|
||||
physicsShape: []
|
||||
bones: []
|
||||
spriteID:
|
||||
internalID: 0
|
||||
vertices: []
|
||||
indices:
|
||||
edges: []
|
||||
weights: []
|
||||
secondaryTextures: []
|
||||
spritePackingTag:
|
||||
pSDRemoveMatte: 0
|
||||
pSDShowRemoveMatteOption: 0
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,16 @@
|
||||
%YAML 1.1
|
||||
%TAG !u! tag:unity3d.com,2011:
|
||||
--- !u!114 &11400000
|
||||
MonoBehaviour:
|
||||
m_ObjectHideFlags: 0
|
||||
m_CorrespondingSourceObject: {fileID: 0}
|
||||
m_PrefabInstance: {fileID: 0}
|
||||
m_PrefabAsset: {fileID: 0}
|
||||
m_GameObject: {fileID: 0}
|
||||
m_Enabled: 1
|
||||
m_EditorHideFlags: 0
|
||||
m_Script: {fileID: 11500000, guid: 0f4dc12126bc22543afc6fdad86a286b, type: 3}
|
||||
m_Name: TexGenModuleRef
|
||||
m_EditorClassIdentifier:
|
||||
m_assetFolder: {fileID: 102900000, guid: fd4ab3b30e03a184483ced099b43ec19, type: 3}
|
||||
m_texGenModule: {fileID: 102900000, guid: 05cc36a4b7f8df24499d7e13464045a6, type: 3}
|
||||
@@ -0,0 +1,8 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 8049e24e9bb6d27469ea2050d91944cb
|
||||
NativeFormatImporter:
|
||||
externalObjects: {}
|
||||
mainObjectFileID: 11400000
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,21 @@
|
||||
// WaterCausticsModules
|
||||
// Copyright (c) 2021 Masataka Hakozaki
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using UnityEngine;
|
||||
|
||||
namespace MH.WaterCausticsModules {
|
||||
#if WCE_DEVELOPMENT
|
||||
[CreateAssetMenu]
|
||||
#endif
|
||||
public class TexGenModuleRef : ScriptableObject {
|
||||
// WaterCausticsModulesフォルダ
|
||||
[SerializeField] private Object m_assetFolder;
|
||||
internal Object assetFolder => m_assetFolder;
|
||||
|
||||
// WaterCausticsTexGeneratorフォルダ
|
||||
[SerializeField] private Object m_texGenModule;
|
||||
internal Object texGenModule => m_texGenModule;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 0f4dc12126bc22543afc6fdad86a286b
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,43 @@
|
||||
// WaterCausticsModules
|
||||
// Copyright (c) 2021 Masataka Hakozaki
|
||||
|
||||
#if UNITY_EDITOR && (!UNITY_2020_3_OR_NEWER || WCE_DEVELOPMENT)
|
||||
using UnityEditor;
|
||||
using UnityEngine;
|
||||
#pragma warning disable 162
|
||||
|
||||
namespace MH.WaterCausticsModules {
|
||||
/*------------------------------------------------------------------------
|
||||
このアセットがインポートされた際、Unityのバージョンが低い場合にダイアログとWarningを表示
|
||||
-------------------------------------------------------------------------*/
|
||||
public class VersionCheck {
|
||||
#if WCE_DEVELOPMENT
|
||||
[MenuItem ("WCM/TestDialog/VersionCheck")]
|
||||
static void dialogTest () => showDialog ();
|
||||
static private readonly bool isDeveloping = true;
|
||||
#else
|
||||
static private readonly bool isDeveloping = false;
|
||||
#endif
|
||||
|
||||
[InitializeOnLoadMethod]
|
||||
static private void registerCallback () {
|
||||
AssetDatabase.importPackageCompleted -= importCompleted;
|
||||
AssetDatabase.importPackageCompleted += importCompleted;
|
||||
}
|
||||
|
||||
static void importCompleted (string packageName) {
|
||||
if (isDeveloping) return;
|
||||
if (Constant.CheckPackageName (packageName))
|
||||
showDialog ();
|
||||
}
|
||||
|
||||
static void showDialog () {
|
||||
string str0 = $"Requires Unity {Constant.REQUIRE_UNITY_VER}";
|
||||
string str1 = $"This asset is not compatible with current Unity version.\n\nCurrent : {Application.unityVersion} \nRequire : {Constant.REQUIRE_UNITY_VER}\n\n\n({Constant.ASSET_NAME})";
|
||||
EditorUtility.DisplayDialog (str0, str1, "OK");
|
||||
Debug.LogWarning ($"{str1.Replace("\n", " ")}\n\n\n");
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -0,0 +1,11 @@
|
||||
fileFormatVersion: 2
|
||||
guid: 457ec14637a5af748b3988768371cc74
|
||||
MonoImporter:
|
||||
externalObjects: {}
|
||||
serializedVersion: 2
|
||||
defaultReferences: []
|
||||
executionOrder: 0
|
||||
icon: {instanceID: 0}
|
||||
userData:
|
||||
assetBundleName:
|
||||
assetBundleVariant:
|
||||
@@ -0,0 +1,865 @@
|
||||
// WaterCausticsModules
|
||||
// Copyright (c) 2021 Masataka Hakozaki
|
||||
|
||||
#if UNITY_EDITOR
|
||||
using System.Linq;
|
||||
using UnityEditor;
|
||||
using UnityEditorInternal;
|
||||
using UnityEngine;
|
||||
|
||||
namespace MH.WaterCausticsModules.TexGen {
|
||||
|
||||
[CanEditMultipleObjects]
|
||||
[CustomEditor (typeof (WaterCausticsTexGenerator))]
|
||||
public class WaterCausticsTexGeneratorEditor : Editor {
|
||||
#if UNITY_2020_3_OR_NEWER //&& !WCE_DEVELOPMENT
|
||||
private SerializedProperty m_generateInEditMode;
|
||||
private SerializedProperty m_animateInEditMode;
|
||||
private SerializedProperty m_pause;
|
||||
private SerializedProperty m_density;
|
||||
private SerializedProperty m_height;
|
||||
private SerializedProperty m_speed;
|
||||
private SerializedProperty m_flow;
|
||||
private SerializedProperty m_flowDirection;
|
||||
private SerializedProperty m_waves;
|
||||
private SerializedProperty m_calcResolution;
|
||||
private SerializedProperty m_renderTexture;
|
||||
private SerializedProperty m_FillGap;
|
||||
private SerializedProperty m_lightRay;
|
||||
private SerializedProperty m_lightTransform;
|
||||
private SerializedProperty m_lightVector;
|
||||
private SerializedProperty m_lightDirection;
|
||||
private SerializedProperty m_lightIncidentAngle;
|
||||
private SerializedProperty m_style;
|
||||
private SerializedProperty m_refractedRay;
|
||||
private SerializedProperty m_brightness;
|
||||
private SerializedProperty m_gamma;
|
||||
private SerializedProperty m_clamp;
|
||||
private SerializedProperty m_refractionIndex;
|
||||
private SerializedProperty m_useChromaticAberration;
|
||||
private SerializedProperty m_chromaticAberration;
|
||||
private SerializedProperty m_usePostProcessing;
|
||||
private SerializedProperty m_useBlur;
|
||||
private SerializedProperty m_blurIterations;
|
||||
private SerializedProperty m_blurSpread;
|
||||
private SerializedProperty m_msaa;
|
||||
private SerializedProperty m_blurDirectional;
|
||||
private SerializedProperty m_blurDirection;
|
||||
private SerializedProperty m_colorShift;
|
||||
private SerializedProperty m_colorShiftDir;
|
||||
private SerializedProperty m_useSyncDirection;
|
||||
private SerializedProperty m_postContrast;
|
||||
private SerializedProperty m_postBrightness;
|
||||
private SerializedProperty m_computeShader;
|
||||
private SerializedProperty m_shader;
|
||||
|
||||
private void prepProperties () {
|
||||
if (m_generateInEditMode != null) return;
|
||||
m_generateInEditMode = serializedObject.FindProperty ("m_generateInEditMode");
|
||||
m_animateInEditMode = serializedObject.FindProperty ("m_animateInEditMode");
|
||||
m_pause = serializedObject.FindProperty ("m_pause");
|
||||
m_density = serializedObject.FindProperty ("m_density");
|
||||
m_height = serializedObject.FindProperty ("m_height");
|
||||
m_speed = serializedObject.FindProperty ("m_speed");
|
||||
m_flow = serializedObject.FindProperty ("m_flow");
|
||||
m_flowDirection = serializedObject.FindProperty ("m_flowDirection");
|
||||
m_waves = serializedObject.FindProperty ("m_waves");
|
||||
m_calcResolution = serializedObject.FindProperty ("m_calcResolution");
|
||||
m_renderTexture = serializedObject.FindProperty ("m_renderTexture");
|
||||
m_FillGap = serializedObject.FindProperty ("m_FillGap");
|
||||
m_lightRay = serializedObject.FindProperty ("m_lightRay");
|
||||
m_lightTransform = serializedObject.FindProperty ("m_lightTransform");
|
||||
m_lightVector = serializedObject.FindProperty ("m_lightVector");
|
||||
m_lightDirection = serializedObject.FindProperty ("m_lightDirection");
|
||||
m_lightIncidentAngle = serializedObject.FindProperty ("m_lightIncidentAngle");
|
||||
m_style = serializedObject.FindProperty ("m_style");
|
||||
m_refractedRay = serializedObject.FindProperty ("m_refractedRay");
|
||||
m_brightness = serializedObject.FindProperty ("m_brightness");
|
||||
m_gamma = serializedObject.FindProperty ("m_gamma");
|
||||
m_clamp = serializedObject.FindProperty ("m_clamp");
|
||||
m_refractionIndex = serializedObject.FindProperty ("m_refractionIndex");
|
||||
m_useChromaticAberration = serializedObject.FindProperty ("m_useChromaticAberration");
|
||||
m_chromaticAberration = serializedObject.FindProperty ("m_chromaticAberration");
|
||||
m_usePostProcessing = serializedObject.FindProperty ("m_usePostProcessing");
|
||||
m_useBlur = serializedObject.FindProperty ("m_useBlur");
|
||||
m_blurIterations = serializedObject.FindProperty ("m_blurIterations");
|
||||
m_blurSpread = serializedObject.FindProperty ("m_blurSpread");
|
||||
m_msaa = serializedObject.FindProperty ("m_msaa");
|
||||
m_blurDirectional = serializedObject.FindProperty ("m_blurDirectional");
|
||||
m_blurDirection = serializedObject.FindProperty ("m_blurDirection");
|
||||
m_colorShift = serializedObject.FindProperty ("m_colorShift");
|
||||
m_colorShiftDir = serializedObject.FindProperty ("m_colorShiftDir");
|
||||
m_useSyncDirection = serializedObject.FindProperty ("m_useSyncDirection");
|
||||
m_postContrast = serializedObject.FindProperty ("m_postContrast");
|
||||
m_postBrightness = serializedObject.FindProperty ("m_postBrightness");
|
||||
m_computeShader = serializedObject.FindProperty ("m_computeShader");
|
||||
m_shader = serializedObject.FindProperty ("m_shader");
|
||||
}
|
||||
|
||||
static readonly GUIContent [] _litRayTypeEnumGC = {
|
||||
new GUIContent ("Direction"),
|
||||
new GUIContent ("Vector"),
|
||||
new GUIContent ("Transform"),
|
||||
new GUIContent ("Sun"),
|
||||
new GUIContent ("Auto"),
|
||||
};
|
||||
|
||||
static readonly int [] _litDirTypeEnumOrder = { 4, 0, 1, 2, 3, };
|
||||
|
||||
static readonly string [] _resEnumStr = {
|
||||
"64 x 64",
|
||||
"96 x 96",
|
||||
"128 x 128",
|
||||
"160 x 160",
|
||||
"256 x 256",
|
||||
"320 x 320",
|
||||
"512 x 512",
|
||||
};
|
||||
|
||||
static readonly string [] _msaaEnumStr = { "None", "2x", "4x", "8x" };
|
||||
|
||||
private enum EnumMSAA {
|
||||
NoMSAA = 1,
|
||||
MSAA2x = 2,
|
||||
MSAA4x = 4,
|
||||
MSAA8x = 8
|
||||
}
|
||||
|
||||
private readonly string _animInEditModeDesc = "Animate the wave even in edit mode, and force update scene and game view.\n\nTo use it, AdvancedSettings / In EditMode / Generate needs to be On.";
|
||||
|
||||
// -----------------------------------------------------------
|
||||
private void OnEnable () {
|
||||
foreach (var tar in targets.OfType<WaterCausticsTexGenerator> ()) {
|
||||
tar.VersionCheck ();
|
||||
tar.CheckRenderTex ();
|
||||
}
|
||||
PreviewWindow.SetTargetIfShowing (target as WaterCausticsTexGenerator);
|
||||
}
|
||||
|
||||
private void OnDisable () {
|
||||
PreviewWindow.RemoveTarget (target as WaterCausticsTexGenerator);
|
||||
}
|
||||
|
||||
public override void OnInspectorGUI () {
|
||||
prepProperties ();
|
||||
prepWaveList ();
|
||||
serializedObject.Update ();
|
||||
using (var check = new EditorGUI.ChangeCheckScope ()) {
|
||||
drawProperties ();
|
||||
serializedObject.ApplyModifiedProperties ();
|
||||
if (check.changed)
|
||||
PreviewWindow.InspectorChanged (target as WaterCausticsTexGenerator);
|
||||
}
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------- Draw
|
||||
readonly Color colorPinkBar = new Color (1f, 0.3f, 0.6f, 0.3f);
|
||||
readonly Color colorPinkContent = new Color (1f, 0.3f, 0.6f, 1f);
|
||||
readonly Color colorGreenButton = new Color (0.0f, 1f, 0.66f, 1f);
|
||||
readonly float SPACE_SUB_TOP_5 = 5f;
|
||||
readonly float SPACE_SUB_BTM_12 = 12f;
|
||||
readonly float SPACE_MAIN_TOP_7 = 7f;
|
||||
readonly float SPACE_MAIN_BTM_5 = 5f;
|
||||
|
||||
private void setLabelAreaWidth (float labelWidthMin, float valWidthMin) {
|
||||
if (EditorGUIUtility.labelWidth < labelWidthMin)
|
||||
EditorGUIUtility.labelWidth = labelWidthMin;
|
||||
if (EditorGUIUtility.currentViewWidth - EditorGUIUtility.labelWidth < valWidthMin)
|
||||
EditorGUIUtility.labelWidth = EditorGUIUtility.currentViewWidth - valWidthMin;
|
||||
}
|
||||
|
||||
private void drawProperties () {
|
||||
storeIndentWidth ();
|
||||
EditorGUIUtility.labelWidth += 6;
|
||||
EditorGUI.indentLevel++;
|
||||
setLabelAreaWidth (labelWidthMin: 145f, valWidthMin: 170f);
|
||||
|
||||
bool useTextureWarning = (m_renderTexture.objectReferenceValue == null && isGameObjectOnScene () && !serializedObject.isEditingMultipleObjects);
|
||||
// ---------------------------------------------------------------------------------- Calculation
|
||||
bool expandCalc = expandMainGroup (m_calcResolution, true, "Calculation", isPink : useTextureWarning);
|
||||
// --------- Preview Window Button
|
||||
if (!expandCalc) {
|
||||
var rect = GUILayoutUtility.GetLastRect ();
|
||||
float width = 150f;
|
||||
rect.x += rect.width - width;
|
||||
rect.width = width;
|
||||
rect.y += 1f;
|
||||
if (PreviewWindow.IsShowing ()) {
|
||||
if (GUI.Button (rect, "Close Preview", EditorStyles.miniButton)) {
|
||||
PreviewWindow.CloseWindow ();
|
||||
}
|
||||
} else {
|
||||
bool useBtn = !serializedObject.isEditingMultipleObjects && !useTextureWarning;
|
||||
using (new DisableScope (useBtn)) {
|
||||
using (new ColorScope (useBtn?colorGreenButton : GUI.color))
|
||||
if (GUI.Button (rect, "Open Preview", EditorStyles.miniButton)) {
|
||||
PreviewWindow.OpenWindow (target as WaterCausticsTexGenerator);
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
EditorGUILayout.Space (SPACE_MAIN_TOP_7);
|
||||
// --------- RenderTexture
|
||||
using (new ColorScope (useTextureWarning ? colorPinkContent : GUI.color)) {
|
||||
EditorGUILayout.PropertyField (m_renderTexture, new GUIContent ("Render Texture", "Output destination RenderTexture."));
|
||||
if (!m_renderTexture.hasMultipleDifferentValues) {
|
||||
if (useTextureWarning) {
|
||||
EditorGUILayout.BeginHorizontal ();
|
||||
GUILayout.FlexibleSpace ();
|
||||
var descBtn = new GUIContent ("Create RenderTexture", "Create a new RenderTexture asset. It will be created in the same folder as the scene file.");
|
||||
if (GUILayout.Button (descBtn, EditorStyles.miniButton, GUILayout.Width (150))) {
|
||||
m_renderTexture.objectReferenceValue = WaterCausticsTexGeneratorMenuItem.CreateRTAsset ();
|
||||
}
|
||||
EditorGUILayout.EndHorizontal ();
|
||||
} else {
|
||||
if (m_renderTexture.objectReferenceValue != null) {
|
||||
var rt = m_renderTexture.objectReferenceValue as RenderTexture;
|
||||
string mipmapStr = rt.useMipMap ? "MipMapOn" : "MipMapOff";
|
||||
string str = $"{rt.width}x{rt.height} / {rt.graphicsFormat} / {(EnumMSAA)rt.antiAliasing} / {mipmapStr}";
|
||||
EditorGUILayout.HelpBox (str, MessageType.None);
|
||||
if (rt.antiAliasing > 1 && rt.useMipMap) {
|
||||
EditorGUILayout.Space (1);
|
||||
str = "MipMap is not applied because RenderTexture's Anti-aliasing (MSAA) is On. To use MipMap and MSAA together, turn off MSAA of RenderTexture and use MSAA in PostProcessing of this component.";
|
||||
EditorGUILayout.HelpBox (str, MessageType.Warning);
|
||||
EditorGUILayout.BeginHorizontal ();
|
||||
GUILayout.FlexibleSpace ();
|
||||
if (GUILayout.Button (new GUIContent ("Fix", "Turn off MSAA of RenderTexture and use MSAA in PostProcessing of this component."), EditorStyles.miniButton, GUILayout.Width (150))) {
|
||||
Undo.RecordObject (rt, "Turn off MSAA of RenderTexture and use MSAA in PostProcessing of this component.");
|
||||
EditorUtility.SetDirty (rt);
|
||||
int tmp = rt.antiAliasing;
|
||||
if (rt.IsCreated ()) {
|
||||
bool isActive = (RenderTexture.active == rt);
|
||||
if (isActive) RenderTexture.active = null;
|
||||
rt.Release ();
|
||||
rt.antiAliasing = 1;
|
||||
rt.Create ();
|
||||
if (isActive) RenderTexture.active = rt;
|
||||
} else {
|
||||
rt.antiAliasing = 1;
|
||||
}
|
||||
m_usePostProcessing.boolValue = true;
|
||||
m_msaa.intValue = Mathf.Max (tmp, m_msaa.intValue);
|
||||
}
|
||||
EditorGUILayout.EndHorizontal ();
|
||||
EditorGUILayout.Space (4);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
EditorGUILayout.Space (1);
|
||||
popup (m_calcResolution, _resEnumStr, "Calc Resolution", "Resolution used for internal calculations.");
|
||||
EditorGUILayout.PropertyField (m_FillGap, new GUIContent ("Fill Gap", "If the edges of the output image are not drawn, increase the value. Make it as small as possible to reduce the load."));
|
||||
using (new DisableScope (m_generateInEditMode.boolValue)) {
|
||||
EditorGUILayout.PropertyField (m_animateInEditMode, new GUIContent ("Animate In EditMode", _animInEditModeDesc));
|
||||
}
|
||||
|
||||
// ---------------------------------------------------------------------------------- Preview Window Button
|
||||
EditorGUILayout.Space (5);
|
||||
EditorGUILayout.BeginHorizontal ();
|
||||
GUILayout.FlexibleSpace ();
|
||||
if (PreviewWindow.IsShowing ()) {
|
||||
if (GUILayout.Button ("Close Preview", EditorStyles.miniButton, GUILayout.Width (150))) {
|
||||
PreviewWindow.CloseWindow ();
|
||||
}
|
||||
} else {
|
||||
bool useBtn = !serializedObject.isEditingMultipleObjects && !useTextureWarning;
|
||||
using (new DisableScope (useBtn)) {
|
||||
using (new ColorScope (useBtn?colorGreenButton : GUI.color))
|
||||
if (GUILayout.Button ("Open Preview", EditorStyles.miniButton, GUILayout.Width (150))) {
|
||||
PreviewWindow.OpenWindow (target as WaterCausticsTexGenerator);
|
||||
}
|
||||
}
|
||||
}
|
||||
EditorGUILayout.EndHorizontal ();
|
||||
|
||||
|
||||
EditorGUILayout.Space (SPACE_SUB_BTM_12 - SPACE_MAIN_BTM_5);
|
||||
}
|
||||
|
||||
EditorGUILayout.Space (SPACE_MAIN_BTM_5);
|
||||
|
||||
|
||||
// ---------------------------------------------------------------------------------- Parameters
|
||||
if (expandMainGroup (m_density, true, "Parameters")) {
|
||||
EditorGUILayout.Space (SPACE_MAIN_TOP_7);
|
||||
// ----------------------------------------- Wave
|
||||
if (expandSubGroup (m_pause, true, "Wave")) {
|
||||
EditorGUILayout.Space (SPACE_SUB_TOP_5);
|
||||
EditorGUILayout.PropertyField (m_pause, new GUIContent ("Pause", "Suspend the overall waves."));
|
||||
EditorGUILayout.PropertyField (m_density, new GUIContent ("Density", "Adjust the overall density."));
|
||||
EditorGUILayout.PropertyField (m_height, new GUIContent ("Height", "Adjust the overall height."));
|
||||
|
||||
using (new DisableScope (!m_pause.boolValue)) {
|
||||
EditorGUILayout.PropertyField (m_speed, new GUIContent ("Speed", "Adjust the overall speed."));
|
||||
}
|
||||
EditorGUILayout.Space (1);
|
||||
using (new DisableScope (!m_pause.boolValue)) {
|
||||
EditorGUILayout.PropertyField (m_flow, new GUIContent ("Flow", "Adjust the overall flow."));
|
||||
if (m_flow.floatValue != 0f) {
|
||||
using (new IndentScope (-2f, 0f, 2)) {
|
||||
EditorGUILayout.PropertyField (m_flowDirection, new GUIContent ("Direction", "Adjust the overall direction of flow."));
|
||||
drawDirMark (m_flowDirection, !m_pause.boolValue);
|
||||
}
|
||||
}
|
||||
}
|
||||
EditorGUILayout.Space (8);
|
||||
drawLine ();
|
||||
EditorGUILayout.Space (8);
|
||||
if (isExpand (m_waves, false, new GUIContent ("Waves", $"Wave settings. Supports up to {WaterCausticsTexGenerator.WAVE_MAX_CNT}."))) {
|
||||
EditorGUILayout.Space (3);
|
||||
drawWaveList ();
|
||||
} else {
|
||||
EditorGUILayout.Space (5);
|
||||
}
|
||||
EditorGUILayout.Space (SPACE_SUB_BTM_12);
|
||||
}
|
||||
// ----------------------------------------- Refraction
|
||||
if (expandSubGroup (m_refractionIndex, true, "Refraction")) {
|
||||
EditorGUILayout.Space (SPACE_SUB_TOP_5);
|
||||
|
||||
EditorGUILayout.PropertyField (m_style, new GUIContent ("Style", "How to calculate light focusing."));
|
||||
EditorGUILayout.PropertyField (m_refractionIndex, new GUIContent ("Refraction Index", "Index of refraction."));
|
||||
|
||||
EditorGUILayout.Space (1);
|
||||
if (isExpand (m_lightRay, false, new GUIContent ("Details"))) {
|
||||
EditorGUILayout.PropertyField (m_useChromaticAberration, new GUIContent ("Chromatic Aberration", "Simulate more realistic chromatic aberrations. \nAmount of calculation increases. For mobile devices, consider using color shift.\n\nRequires RenderTexture having RGB channels."));
|
||||
if (m_useChromaticAberration.boolValue) {
|
||||
using (new IndentScope (-2, 2)) {
|
||||
EditorGUILayout.PropertyField (m_chromaticAberration, new GUIContent ("Intensity", "Shifts the refractive index in the RGB channels."));
|
||||
}
|
||||
}
|
||||
EditorGUILayout.Space (1);
|
||||
orderedPopup (m_lightRay, _litRayTypeEnumGC, _litDirTypeEnumOrder, "Light Ray", "Direction of the ray from the Light.");
|
||||
using (new IndentScope (0, 1)) {
|
||||
switch ((LightRay) m_lightRay.enumValueIndex) {
|
||||
case LightRay.Vector:
|
||||
EditorGUILayout.PropertyField (m_lightVector, new GUIContent ("Direction", "Specify the direction of light rays as a vector. It will be normalized."));
|
||||
break;
|
||||
case LightRay.Transform:
|
||||
EditorGUILayout.PropertyField (m_lightTransform, new GUIContent ("Transform", "Transforms the light to be referenced."));
|
||||
break;
|
||||
case LightRay.LitSettingSun:
|
||||
EditorGUILayout.LabelField ("Use the sun setting in the Light Settings window.", new GUIStyle ("HelpBox"));
|
||||
break;
|
||||
case LightRay.Auto:
|
||||
EditorGUILayout.LabelField ("Use the shader's global variable \"_LightDirection\".", new GUIStyle ("HelpBox"));
|
||||
break;
|
||||
case LightRay.Direction:
|
||||
default:
|
||||
EditorGUILayout.PropertyField (m_lightIncidentAngle, new GUIContent ("Incident Angle", "Angle of incidence of light rays."));
|
||||
if (m_lightIncidentAngle.floatValue > 0f) {
|
||||
drawSyncDirProp (m_lightDirection, true, new GUIContent ("Direction", "Direction of light rays. \n\nChain mark is On, the Light Ray, Directional Blur, and Color Shift directions are synchronized."));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
EditorGUILayout.Space (1);
|
||||
EditorGUILayout.PropertyField (m_refractedRay, new GUIContent ("Refracted Ray", "Normalize the rays after refraction or extend them until they hit the bottom."));
|
||||
}
|
||||
EditorGUILayout.Space (SPACE_SUB_BTM_12);
|
||||
}
|
||||
// ----------------------------------------- Adjustment
|
||||
if (expandSubGroup (m_brightness, true, "Adjustment")) {
|
||||
EditorGUILayout.Space (SPACE_SUB_TOP_5);
|
||||
EditorGUILayout.PropertyField (m_gamma, new GUIContent ("Gamma", "Adjusts the contrast."));
|
||||
EditorGUILayout.PropertyField (m_brightness, new GUIContent ("Brightness", "Adjust the brightness."));
|
||||
EditorGUILayout.PropertyField (m_clamp, new GUIContent ("Clamp", "Limit the brightness to this value."));
|
||||
}
|
||||
EditorGUILayout.Space (SPACE_SUB_BTM_12 - SPACE_MAIN_BTM_5);
|
||||
}
|
||||
EditorGUILayout.Space (SPACE_MAIN_BTM_5);
|
||||
// ---------------------------------------------------------------------------------- Post Processing
|
||||
if (expandMainGroup (m_usePostProcessing, true, "Post Processing")) {
|
||||
EditorGUILayout.Space (SPACE_MAIN_TOP_7);
|
||||
|
||||
EditorGUILayout.PropertyField (m_usePostProcessing, new GUIContent ("Post Processing", "Apply the post processing effect. \nWhen post-processing is used, it is first drawn to a temporary RenderTexture, then post-processed, and output to a destination RenderTexture."));
|
||||
using (new DisableScope (m_usePostProcessing.boolValue)) {
|
||||
EditorGUILayout.Space (1);
|
||||
popup (m_msaa, _msaaEnumStr, "MSAA", "Multi-Sampling Anti-Alias. \nWhen post-processing is used, it is first drawn to a temporary RenderTexture, then post-processed, and output to a destination RenderTexture. This setting is MSAA for that first drawing. \n\nIf using Post Processing, MSAA of the RenderTexture for output is not used and will be disabled on the actual device.");
|
||||
EditorGUILayout.Space (1);
|
||||
EditorGUILayout.PropertyField (m_useBlur, new GUIContent ("Blur", "Use blur or not."));
|
||||
if (isExpandMarkOnly (m_useBlur, true)) {
|
||||
using (new IndentScope (-2f, 1f)) {
|
||||
using (new DisableScope (m_useBlur.boolValue)) {
|
||||
EditorGUILayout.PropertyField (m_blurIterations, new GUIContent ("Blur Iteration", "Number of iterations."));
|
||||
EditorGUILayout.PropertyField (m_blurSpread, new GUIContent ("Spread", "Amount of spread."));
|
||||
using (new DisableScope (m_blurIterations.intValue > 1 || m_blurSpread.floatValue > 0f)) {
|
||||
EditorGUILayout.PropertyField (m_blurDirectional, new GUIContent ("Directional", "Give directionality to the blur."));
|
||||
if (m_blurDirectional.floatValue > 0f) {
|
||||
bool isActive = m_usePostProcessing.boolValue && m_useBlur.boolValue && (m_blurIterations.intValue > 1 || m_blurSpread.floatValue > 0f);
|
||||
drawSyncDirProp (m_blurDirection, isActive, new GUIContent ("Direction", "Blur direction.\n\nChain mark is On, the Light Ray, Directional Blur, and Color Shift directions are synchronized."));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
EditorGUILayout.Space (1);
|
||||
EditorGUILayout.PropertyField (m_colorShift, new GUIContent ("Color Shift", "Amount of color shift.\n\nRequires RenderTexture having RGB channels."));
|
||||
if (m_colorShift.floatValue > 0f) {
|
||||
drawSyncDirProp (m_colorShiftDir, m_usePostProcessing.boolValue, new GUIContent ("Direction", "Color Shift direction.\n\nChain mark is On, the Light Ray, Directional Blur, and Color Shift directions are synchronized."));
|
||||
}
|
||||
EditorGUILayout.Space (1);
|
||||
EditorGUILayout.PropertyField (m_postContrast, new GUIContent ("Contrast", "Contrast adjustment."));
|
||||
EditorGUILayout.PropertyField (m_postBrightness, new GUIContent ("Brightness", "Brightness adjustment in post-processing."));
|
||||
}
|
||||
EditorGUILayout.Space (SPACE_SUB_BTM_12 - SPACE_MAIN_BTM_5);
|
||||
}
|
||||
EditorGUILayout.Space (SPACE_MAIN_BTM_5);
|
||||
// ---------------------------------------------------------------------------------- Advanced Settings
|
||||
if (expandMainGroup (m_computeShader, false, "Advanced Settings")) {
|
||||
EditorGUILayout.Space (SPACE_MAIN_TOP_7);
|
||||
if (expandSubGroup (m_generateInEditMode, true, "In EditMode")) {
|
||||
EditorGUILayout.Space (SPACE_SUB_TOP_5);
|
||||
EditorGUILayout.PropertyField (m_generateInEditMode, new GUIContent ("Generate", "Whether to generate while in edit mode."));
|
||||
using (new DisableScope (m_generateInEditMode.boolValue)) {
|
||||
EditorGUILayout.PropertyField (m_animateInEditMode, new GUIContent ("Animate", _animInEditModeDesc));
|
||||
}
|
||||
}
|
||||
}
|
||||
EditorGUILayout.Space (SPACE_SUB_BTM_12);
|
||||
EditorGUILayout.Space (SPACE_MAIN_BTM_5);
|
||||
EditorGUILayout.Space (SPACE_MAIN_BTM_5);
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------- Wave List
|
||||
private ReorderableList _waveList;
|
||||
private float lineH = EditorGUIUtility.singleLineHeight + 2;
|
||||
private void prepWaveList () {
|
||||
if (_waveList != null) return;
|
||||
_waveList = new ReorderableList (serializedObject, m_waves, true, false, true, true);
|
||||
_waveList.drawElementCallback = (Rect rect, int index, bool isActive, bool isFocused) => {
|
||||
rect.x += 12f;
|
||||
rect.width -= 12f;
|
||||
rect.y += 2f;
|
||||
using (new AdjustLabelSpaceWidthScope (-48f)) {
|
||||
rect.height = EditorGUIUtility.singleLineHeight;
|
||||
|
||||
var element = m_waves.GetArrayElementAtIndex (index);
|
||||
element.isExpanded = EditorGUI.Foldout (rect, element.isExpanded, new GUIContent ($" ", ""));
|
||||
var m_active = element.FindPropertyRelative ("m_active");
|
||||
EditorGUI.PropertyField (rect, m_active, new GUIContent ($"Wave [{index}]", "Enables/Disables this wave."));
|
||||
if (element.isExpanded) {
|
||||
var m_density = element.FindPropertyRelative ("m_density");
|
||||
var m_height = element.FindPropertyRelative ("m_height");
|
||||
var m_fluctuation = element.FindPropertyRelative ("m_fluctuation");
|
||||
var m_flow = element.FindPropertyRelative ("m_flow");
|
||||
var m_direction = element.FindPropertyRelative ("m_direction");
|
||||
var indent2 = 10f;
|
||||
using (new AdjustLabelSpaceWidthScope (-indent2)) {
|
||||
rect.x += indent2;
|
||||
rect.width -= indent2;
|
||||
rect.y += 2;
|
||||
using (new DisableScope (m_active.boolValue)) {
|
||||
rect.y += lineH;
|
||||
EditorGUI.PropertyField (rect, m_density, new GUIContent ($"Density", "Density of this wave."));
|
||||
rect.y += lineH;
|
||||
EditorGUI.PropertyField (rect, m_height, new GUIContent ($"Height", "Height of this wave."));
|
||||
}
|
||||
bool isEnable = m_active.boolValue && !m_pause.boolValue && !this.m_pause.boolValue;
|
||||
using (new DisableScope (isEnable)) {
|
||||
rect.y += lineH;
|
||||
EditorGUI.PropertyField (rect, m_fluctuation, new GUIContent ($"Fluctuation", "Fluctuation of this wave."));
|
||||
rect.y += lineH + 2;
|
||||
EditorGUI.PropertyField (rect, m_flow, new GUIContent ($"Flow", "Amount of flow."));
|
||||
bool showFlowDir = (m_flow.floatValue != 0f || m_flow.hasMultipleDifferentValues);
|
||||
if (showFlowDir) {
|
||||
rect.y += lineH;
|
||||
rect.x += _indentWidth;
|
||||
rect.width -= _indentWidth;
|
||||
drawDirMark (rect, m_direction, isEnable);
|
||||
rect.x += _indentWidth;
|
||||
rect.width -= _indentWidth;
|
||||
using (new AdjustLabelSpaceWidthScope (-_indentWidth * 2f)) {
|
||||
EditorGUI.PropertyField (rect, m_direction, new GUIContent ($"Direction", "Flow Direction. \n\n -90:Up \n180:Left 0:Right \n 90:Down"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
};
|
||||
_waveList.drawElementBackgroundCallback = (Rect rect, int index, bool isActive, bool isFocused) => {
|
||||
ReorderableList.defaultBehaviours.DrawElementBackground (rect, index, isActive && isFocused, isFocused, true);
|
||||
};
|
||||
_waveList.elementHeightCallback = (int index) => {
|
||||
var element = m_waves.GetArrayElementAtIndex (index);
|
||||
var height = EditorGUI.GetPropertyHeight (m_waves.GetArrayElementAtIndex (index)) + 4f;
|
||||
if (element.isExpanded) height += -lineH + 10;
|
||||
var m_flow = element.FindPropertyRelative ("m_flow");
|
||||
bool showFlowDir = (m_flow.floatValue != 0f || m_flow.hasMultipleDifferentValues);
|
||||
if (!showFlowDir) height += -lineH;
|
||||
return height;
|
||||
};
|
||||
}
|
||||
|
||||
private void drawWaveList () {
|
||||
var rect = GUILayoutUtility.GetRect (0f, _waveList.GetHeight ());
|
||||
rect = EditorGUI.IndentedRect (rect);
|
||||
_waveList.displayAdd = _waveList.count < WaterCausticsTexGenerator.WAVE_MAX_CNT;
|
||||
_waveList.displayRemove = _waveList.count > 1;
|
||||
_waveList.DoList (rect);
|
||||
}
|
||||
|
||||
|
||||
// ----------------------------------------------------------- Parts
|
||||
private float _indentWidth;
|
||||
private void storeIndentWidth () {
|
||||
if (_indentWidth != 0f) return;
|
||||
var x0 = EditorGUI.IndentedRect (Rect.zero).x;
|
||||
EditorGUI.indentLevel++;
|
||||
_indentWidth = EditorGUI.IndentedRect (Rect.zero).x - x0;
|
||||
EditorGUI.indentLevel--;
|
||||
}
|
||||
|
||||
static private Vector3 [] syncIconPts = {
|
||||
new Vector3 (-0.18f, -0.135f),
|
||||
new Vector3 (-0.29f, -0.135f),
|
||||
new Vector3 (-0.332426f, -0.117426f),
|
||||
new Vector3 (-0.35f, -0.075f),
|
||||
new Vector3 (-0.35f, 0.075f),
|
||||
new Vector3 (-0.332426f, 0.117426f),
|
||||
new Vector3 (-0.29f, 0.135f),
|
||||
new Vector3 (0.02f, 0.135f),
|
||||
new Vector3 (0.0624264f, 0.117426f),
|
||||
new Vector3 (0.08f, 0.075f),
|
||||
new Vector3 (0.08f, -0.01f),
|
||||
};
|
||||
static private Vector3 [] asyncIconPts = {
|
||||
new Vector3 (-0.07f, -0.135f),
|
||||
new Vector3 (-0.29f, -0.135f),
|
||||
new Vector3 (-0.332426f, -0.117426f),
|
||||
new Vector3 (-0.35f, -0.075f),
|
||||
new Vector3 (-0.35f, 0.075f),
|
||||
new Vector3 (-0.332426f, 0.117426f),
|
||||
new Vector3 (-0.29f, 0.135f),
|
||||
new Vector3 (-0.07f, 0.135f),
|
||||
};
|
||||
|
||||
private void drawSyncDirProp (SerializedProperty prop, bool isActive, GUIContent label) {
|
||||
using (new IndentScope (-2f, 0f, 2)) {
|
||||
// ----- Sync Icon
|
||||
{
|
||||
var rect = GUILayoutUtility.GetRect (0, 0);
|
||||
rect.height = lineH;
|
||||
rect.x += EditorGUIUtility.labelWidth - 15f;
|
||||
rect.y += 2f;
|
||||
rect.width = 15f;
|
||||
bool clicked = isActive && Event.current != null && Event.current.type == EventType.MouseDown && Event.current.button == 0 && rect.Contains (Event.current.mousePosition);
|
||||
if (clicked) {
|
||||
bool newVal = m_useSyncDirection.hasMultipleDifferentValues ? true : !m_useSyncDirection.boolValue;
|
||||
m_useSyncDirection.boolValue = newVal;
|
||||
if (newVal) m_lightDirection.floatValue = m_blurDirection.floatValue = m_colorShiftDir.floatValue = prop.floatValue;
|
||||
}
|
||||
GUI.BeginClip (rect, new Vector2 (rect.width * 0.5f, rect.height * 0.5f), Vector2.zero, false);
|
||||
if (!m_useSyncDirection.hasMultipleDifferentValues) {
|
||||
float alpha = (isActive? 0.8f : 0.4f) * (m_useSyncDirection.boolValue? 1f : 0.4f);
|
||||
drawSyncIcon (m_useSyncDirection.boolValue, 15f, 0f, alpha);
|
||||
} else {
|
||||
float alpha = (isActive? 0.8f : 0.4f) * 0.7f;
|
||||
drawSyncIcon (true, 15f, -2f, alpha);
|
||||
alpha *= 0.6f;
|
||||
drawSyncIcon (false, 15f, 2f, alpha);
|
||||
}
|
||||
GUI.EndClip ();
|
||||
void drawSyncIcon (bool sync, float size, float shiftX, float alpha) {
|
||||
var pts = sync? syncIconPts : asyncIconPts;
|
||||
var tmpMatrix = Handles.matrix;
|
||||
Handles.color = colorMulAlpha (EditorStyles.label.normal.textColor, alpha);
|
||||
Handles.matrix = tmpMatrix * Matrix4x4.TRS (Vector3.right * shiftX, Quaternion.Euler (0f, 0f, -45f), Vector3.one * size);
|
||||
Handles.DrawAAPolyLine (Texture2D.whiteTexture, 1.1f, pts);
|
||||
Handles.matrix *= Matrix4x4.Rotate (Quaternion.Euler (0f, 0f, 180f));
|
||||
Handles.DrawAAPolyLine (Texture2D.whiteTexture, 1.1f, pts);
|
||||
Handles.matrix = tmpMatrix;
|
||||
}
|
||||
}
|
||||
|
||||
// ----- DirMark & Slider
|
||||
using (var check = new EditorGUI.ChangeCheckScope ()) {
|
||||
EditorGUI.showMixedValue = prop.hasMultipleDifferentValues;
|
||||
float newDir = EditorGUILayout.Slider (label, prop.floatValue, -180f, 180f);
|
||||
drawDirMark (prop, isActive);
|
||||
if (check.changed) {
|
||||
for (int i = 0; i < serializedObject.targetObjects.Length; i++) {
|
||||
var so = new SerializedObject (serializedObject.targetObjects [i]);
|
||||
var useSyncProp = so.FindProperty (m_useSyncDirection.name);
|
||||
if (useSyncProp.boolValue) {
|
||||
so.FindProperty (m_lightDirection.name).floatValue = newDir;
|
||||
so.FindProperty (m_blurDirection.name).floatValue = newDir;
|
||||
so.FindProperty (m_colorShiftDir.name).floatValue = newDir;
|
||||
} else {
|
||||
so.FindProperty (prop.name).floatValue = newDir;
|
||||
}
|
||||
so.ApplyModifiedProperties ();
|
||||
}
|
||||
serializedObject.SetIsDifferentCacheDirty ();
|
||||
}
|
||||
EditorGUI.showMixedValue = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static private Color colorMulAlpha (Color c, float mulAlpha) => new Color (c.r, c.g, c.b, c.a * mulAlpha);
|
||||
|
||||
private void drawDirMark (SerializedProperty prop, bool isActive = true) {
|
||||
EditorGUI.indentLevel--;
|
||||
var rect = EditorGUI.IndentedRect (GUILayoutUtility.GetLastRect ());
|
||||
drawDirMark (rect, prop, isActive);
|
||||
EditorGUI.indentLevel++;
|
||||
}
|
||||
private void drawDirMark (Rect rect, SerializedProperty prop, bool isActive = true) {
|
||||
rect.width = EditorGUIUtility.labelWidth;
|
||||
Vector2 origin = new Vector2 (CIRCLE_R + 1, rect.height * 0.5f);
|
||||
float dir = prop.floatValue;
|
||||
Handles.color = colorMulAlpha (EditorStyles.label.normal.textColor, isActive ? 0.8f : 0.4f);
|
||||
var tmpMatrix = Handles.matrix;
|
||||
GUI.BeginClip (rect, origin, Vector2.zero, false);
|
||||
Handles.matrix = tmpMatrix * Matrix4x4.Scale (Vector3.one * CIRCLE_R);
|
||||
Handles.DrawAAPolyLine (Texture2D.whiteTexture, 1, circlePts);
|
||||
if (!prop.hasMultipleDifferentValues) {
|
||||
Handles.matrix = tmpMatrix * Matrix4x4.Rotate (Quaternion.Euler (0f, 0f, dir)) * Matrix4x4.Scale (Vector3.one * (CIRCLE_R - 0.5f));
|
||||
Handles.DrawAAConvexPolygon (arrowAry);
|
||||
}
|
||||
Handles.matrix = tmpMatrix;
|
||||
GUI.EndClip ();
|
||||
}
|
||||
|
||||
static private Vector2 dirToVec (float dir) => new Vector2 (Mathf.Sin (dir * Mathf.Deg2Rad), -Mathf.Cos (dir * Mathf.Deg2Rad));
|
||||
const float CIRCLE_R = 5f;
|
||||
static readonly private Vector3 [] arrowAry = {
|
||||
dirToVec (0),
|
||||
dirToVec (150f),
|
||||
dirToVec (170f),
|
||||
dirToVec (-170f),
|
||||
dirToVec (-150f),
|
||||
};
|
||||
static readonly private Vector3 [] circlePts = {
|
||||
new Vector3 (-1f, 0f),
|
||||
new Vector3 (-0.87f, -0.5f),
|
||||
new Vector3 (-0.5f, -0.87f),
|
||||
new Vector3 (0f, -1f),
|
||||
new Vector3 (0.5f, -0.87f),
|
||||
new Vector3 (0.87f, -0.5f),
|
||||
new Vector3 (1f, 0f),
|
||||
new Vector3 (0.87f, 0.5f),
|
||||
new Vector3 (0.5f, 0.87f),
|
||||
new Vector3 (0f, 1f),
|
||||
new Vector3 (-0.5f, 0.87f),
|
||||
new Vector3 (-0.87f, 0.5f),
|
||||
new Vector3 (-1f, 0f),
|
||||
};
|
||||
|
||||
bool isGameObjectOnScene () {
|
||||
return (target as Component).gameObject.scene.IsValid ();
|
||||
}
|
||||
|
||||
private void drawRectMain (bool isPink = false) {
|
||||
Color color = isPink ? colorPinkBar : new Color (0f, 0f, 0f, 0.2f);
|
||||
Rect rect = GUILayoutUtility.GetRect (0, 0);
|
||||
rect.height = lineH;
|
||||
rect.x -= _indentWidth + 4;
|
||||
rect.width += _indentWidth + 8;
|
||||
EditorGUI.DrawRect (rect, color);
|
||||
}
|
||||
|
||||
private bool expandMainGroup (SerializedProperty prop, bool defOpen, string label, bool isPink = false) {
|
||||
EditorGUI.indentLevel--;
|
||||
drawRectMain (isPink);
|
||||
bool expand = isExpand (prop, true, new GUIContent (label));
|
||||
EditorGUI.indentLevel++;
|
||||
return expand;
|
||||
}
|
||||
|
||||
|
||||
private bool expandSubGroup (SerializedProperty prop, bool defOpen, string label, bool isPink = false) {
|
||||
Color color = isPink ? colorPinkBar : colorMulAlpha (EditorStyles.label.normal.textColor, 0.1f);
|
||||
GUILayout.Label (" ");
|
||||
Rect rect = GUILayoutUtility.GetLastRect ();
|
||||
rect.y += 1f;
|
||||
rect.x += 3f;
|
||||
rect.width -= 3f;
|
||||
Rect rect2 = rect;
|
||||
rect2.x -= 14f;
|
||||
rect2.width += 15f;
|
||||
EditorGUI.DrawRect (rect2, color);
|
||||
GUI.Label (rect, label);
|
||||
if (prop == null) {
|
||||
return true;
|
||||
} else {
|
||||
rect.x -= 14;
|
||||
prop.isExpanded = EditorGUI.Foldout (rect, prop.isExpanded != defOpen, " ") != defOpen;
|
||||
return prop.isExpanded != defOpen;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void popup (SerializedProperty prop, string [] enumStr, string text, string tooltip) {
|
||||
using (var check = new EditorGUI.ChangeCheckScope ()) {
|
||||
EditorGUI.showMixedValue = prop.hasMultipleDifferentValues;
|
||||
var newVal = EditorGUILayout.Popup (new GUIContent (text, tooltip), prop.enumValueIndex, enumStr);
|
||||
if (check.changed)
|
||||
prop.enumValueIndex = newVal;
|
||||
EditorGUI.showMixedValue = false;
|
||||
}
|
||||
}
|
||||
|
||||
private void orderedPopup (SerializedProperty prop, GUIContent [] enumStr, int [] intAry, string text, string tooltip) {
|
||||
using (var check = new EditorGUI.ChangeCheckScope ()) {
|
||||
EditorGUI.showMixedValue = prop.hasMultipleDifferentValues;
|
||||
var newVal = EditorGUILayout.IntPopup (new GUIContent (text, tooltip), prop.enumValueIndex, enumStr, intAry);
|
||||
if (check.changed)
|
||||
prop.enumValueIndex = newVal;
|
||||
EditorGUI.showMixedValue = false;
|
||||
}
|
||||
}
|
||||
|
||||
private bool isExpand (SerializedProperty prop, bool defOpen, GUIContent label) {
|
||||
prop.isExpanded = EditorGUILayout.Foldout (prop.isExpanded != defOpen, label) != defOpen;
|
||||
return prop.isExpanded != defOpen;
|
||||
}
|
||||
|
||||
private bool isExpandMarkOnly (SerializedProperty prop, bool defOpen, float adjustX = 0f, float adjustY = 0f) {
|
||||
var rect = GUILayoutUtility.GetLastRect ();
|
||||
prop.isExpanded = EditorGUI.Foldout (rect, prop.isExpanded != defOpen, " ") != defOpen;
|
||||
return prop.isExpanded != defOpen;
|
||||
}
|
||||
|
||||
private void drawLine () {
|
||||
Rect r = GUILayoutUtility.GetRect (0, 0);
|
||||
Color col = colorMulAlpha (EditorStyles.label.normal.textColor, 0.09f);
|
||||
EditorGUI.DrawRect (new Rect (r.x + 14f, r.y, r.width - 14f, 1f), col);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------------- Scope
|
||||
|
||||
private class AdjustLabelSpaceWidthScope : GUI.Scope {
|
||||
private readonly float _store;
|
||||
internal AdjustLabelSpaceWidthScope (float adjust) {
|
||||
_store = EditorGUIUtility.labelWidth;
|
||||
EditorGUIUtility.labelWidth += adjust;
|
||||
}
|
||||
protected override void CloseScope () {
|
||||
EditorGUIUtility.labelWidth = _store;
|
||||
}
|
||||
}
|
||||
|
||||
private class LabelAndIndentScope : GUI.Scope {
|
||||
private float _spaceBtm;
|
||||
internal LabelAndIndentScope (string label, float spaceTop = 0f, float spaceMid = 2f, float spaceBtm = 0f) {
|
||||
_spaceBtm = spaceBtm;
|
||||
EditorGUILayout.Space (spaceTop);
|
||||
EditorGUILayout.LabelField (label);
|
||||
EditorGUILayout.Space (spaceMid);
|
||||
EditorGUI.indentLevel++;
|
||||
}
|
||||
protected override void CloseScope () {
|
||||
EditorGUI.indentLevel--;
|
||||
EditorGUILayout.Space (_spaceBtm);
|
||||
}
|
||||
}
|
||||
|
||||
private class IndentScope : GUI.Scope {
|
||||
private float _spaceBtm;
|
||||
private int _indent;
|
||||
internal IndentScope (float spaceTop = 0f, float spaceBtm = 0f, int indent = 1) {
|
||||
_spaceBtm = spaceBtm;
|
||||
_indent = indent;
|
||||
EditorGUILayout.Space (spaceTop);
|
||||
EditorGUI.indentLevel += indent;
|
||||
}
|
||||
protected override void CloseScope () {
|
||||
EditorGUI.indentLevel -= _indent;
|
||||
EditorGUILayout.Space (_spaceBtm);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private class DisableScope : GUI.Scope {
|
||||
private readonly bool _tmp;
|
||||
internal DisableScope (bool isActive = false) {
|
||||
_tmp = isActive;
|
||||
if (!_tmp) EditorGUI.BeginDisabledGroup (true);
|
||||
}
|
||||
protected override void CloseScope () {
|
||||
if (!_tmp) EditorGUI.EndDisabledGroup ();
|
||||
}
|
||||
}
|
||||
|
||||
private class ColorScope : GUI.Scope {
|
||||
private readonly Color _tmp;
|
||||
internal ColorScope (Color color) {
|
||||
_tmp = GUI.color;
|
||||
GUI.color = color;
|
||||
}
|
||||
protected override void CloseScope () {
|
||||
GUI.color = _tmp;
|
||||
}
|
||||
}
|
||||
|
||||
#else
|
||||
// ----------------------------------------------------------- 以下 UNITY 2030.3より下用
|
||||
public override void OnInspectorGUI () {
|
||||
onInspectorGUI_UnityVersionLow ();
|
||||
}
|
||||
#endif
|
||||
|
||||
private bool isDark => EditorGUIUtility.isProSkin;
|
||||
private GUIStyle _textStyle, _linkUrlStyle, _warningStyle;
|
||||
private void onInspectorGUI_UnityVersionLow () {
|
||||
if (_textStyle == null) {
|
||||
_textStyle = new GUIStyle (EditorStyles.label);
|
||||
_textStyle.wordWrap = true;
|
||||
_textStyle.fontSize = 14;
|
||||
|
||||
_linkUrlStyle = new GUIStyle (_textStyle);
|
||||
_linkUrlStyle.wordWrap = false;
|
||||
_linkUrlStyle.normal.textColor = isDark ? new Color (0f, 0.8f, 1f, 1f) : new Color (0f, 0.4f, 0.8f, 1f);
|
||||
_linkUrlStyle.hover.textColor = _linkUrlStyle.normal.textColor + Color.white * (isDark ? 0.3f : 0.2f);
|
||||
_linkUrlStyle.stretchWidth = false;
|
||||
|
||||
_warningStyle = new GUIStyle (_textStyle);
|
||||
_warningStyle.normal.textColor = isDark ? Color.white : new Color (0.8f, 0.1f, 0f, 1f);
|
||||
_warningStyle.normal.background = Texture2D.whiteTexture;
|
||||
}
|
||||
|
||||
EditorGUILayout.Space (50);
|
||||
labelWarning ($"This asset is not compatible with current Unity version {Application.unityVersion}. Unity {Constant.REQUIRE_UNITY_VER} is required.");
|
||||
EditorGUILayout.Space (10);
|
||||
GUILayout.Label ($"Current : Unity {Application.unityVersion}", _textStyle);
|
||||
GUILayout.Label ($"Require : Unity {Constant.REQUIRE_UNITY_VER}", _textStyle);
|
||||
|
||||
EditorGUILayout.Space (10);
|
||||
var url = Constant.URL_MANUAL;
|
||||
if (labelLink (new GUIContent ("Open Asset Manual", url)))
|
||||
Application.OpenURL (url);
|
||||
EditorGUILayout.Space (50);
|
||||
}
|
||||
|
||||
void labelWarning (string text) {
|
||||
Color tmp = GUI.backgroundColor;
|
||||
GUI.backgroundColor = isDark ? new Color (1f, 0.3f, 0.6f, 0.4f) : new Color (1f, 0.3f, 0.6f, 0.5f);
|
||||
GUILayout.Label (text, _warningStyle);
|
||||
GUI.backgroundColor = tmp;
|
||||
}
|
||||
|
||||
private bool labelLink (GUIContent label, params GUILayoutOption [] options) {
|
||||
GUIStyle style = _linkUrlStyle;
|
||||
var rect = GUILayoutUtility.GetRect (label, style, options);
|
||||
Handles.BeginGUI ();
|
||||
Handles.color = style.normal.textColor;
|
||||
Handles.DrawLine (new Vector3 (rect.xMin, rect.yMax), new Vector3 (rect.xMax, rect.yMax));
|
||||
Handles.color = Color.white;
|
||||
Handles.EndGUI ();
|
||||
EditorGUIUtility.AddCursorRect (rect, MouseCursor.Link);
|
||||
return GUI.Button (rect, label, style);
|
||||
}
|
||||
|
||||
// -----------------------------------------------------------
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#endif
|
||||