新插件

This commit is contained in:
2025-06-04 09:09:39 +08:00
parent 83ced83b6b
commit d76b763fbf
1718 changed files with 1234489 additions and 1 deletions

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: e1a5efd994efb484f84fba5fb64d14f2
folderAsset: yes
DefaultImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 35264053cc3c943709456784a9744965
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,648 @@
#if _DECAL_MAX0
#define _DECALMAX 1
#elif _DECAL_MAX4
#define _DECALMAX 4
#elif _DECAL_MAX8
#define _DECALMAX 8
#elif _DECAL_MAX16
#define _DECALMAX 16
#elif _DECAL_MAX32
#define _DECALMAX 32
#elif _DECAL_MAX64
#define _DECALMAX 64
#elif _DECAL_MAX128
#define _DECALMAX 128
#elif _DECAL_MAX256
#define _DECALMAX 256
#else
#define _DECALMAX 1
#endif
#if _DECAL_STATICMAX0
#define _STATICDECALMAX 1
#elif _DECAL_STATICMAX64
#define _STATICDECALMAX 64
#elif _DECAL_STATICMAX128
#define _STATICDECALMAX 128
#elif _DECAL_STATICMAX256
#define _STATICDECALMAX 256
#elif _DECAL_STATICMAX512
#define _STATICDECALMAX 512
#elif _DECAL_STATICMAX1024
#define _STATICDECALMAX 1024
#elif _DECAL_STATICMAX2048
#define _STATICDECALMAX 2048
#else
#define _STATICDECALMAX 1
#endif
TEXTURE2D_ARRAY(_DecalAlbedo);
TEXTURE2D_ARRAY(_DecalNormalSAO);
#if _DECAL_EMISMETAL
TEXTURE2D_ARRAY(_DecalEmisMetal);
#endif
#if _DECAL_SPLAT
TEXTURE2D_ARRAY(_DecalSplats);
#endif
int _MSDecalCount;
TEXTURE2D(_DecalCullData);
float4 _DecalCullData_TexelSize;
UNITY_DECLARE_TEX2D(_DecalControl);
float4 _DecalControl_TexelSize;
TEXTURE2D(_DecalStaticData);
float4 _DecalStaticData_TexelSize;
TEXTURE2D(_DecalDynamicData);
float4 _DecalDynamicData_TexelSize;
#define DECALDATA1 4
#define DECALDATA2 5
#define DECALSPLATS 6
#define DECALTINT 7
float4 GetDecalStaticData(float index, float y)
{
float2 uv = float2(index + 0.5, y + 0.5) * _DecalStaticData_TexelSize.xy;
return SAMPLE_TEXTURE2D_LOD(_DecalStaticData, sampler_DecalControl, uv, 0);
}
float4x4 GetDecalStaticMtx(float index)
{
float4x4 mtx;
float sz = _DecalStaticData_TexelSize.y;
float u = index * _DecalStaticData_TexelSize.x;
mtx._m00_m01_m02_m03 = SAMPLE_TEXTURE2D_LOD(_DecalStaticData, sampler_DecalControl, float2(u, 0), 0);
mtx._m10_m11_m12_m13 = SAMPLE_TEXTURE2D_LOD(_DecalStaticData, sampler_DecalControl, float2(u, 1*sz), 0);
mtx._m20_m21_m22_m23 = SAMPLE_TEXTURE2D_LOD(_DecalStaticData, sampler_DecalControl, float2(u, 2*sz), 0);
mtx._m30_m31_m32_m33 = SAMPLE_TEXTURE2D_LOD(_DecalStaticData, sampler_DecalControl, float2(u, 3*sz), 0);
return mtx;
}
float4 GetDecalDynamicData(float index, float y)
{
float2 uv = float2(index + 0.5, y + 0.5) * _DecalDynamicData_TexelSize.xy;
return SAMPLE_TEXTURE2D_LOD(_DecalDynamicData, sampler_DecalControl, uv, 0);
}
float4x4 GetDecalDynamicMtx(float index)
{
float4x4 mtx;
float sz = _DecalDynamicData_TexelSize.y;
float u = index * _DecalDynamicData_TexelSize.x;
mtx._m00_m01_m02_m03 = SAMPLE_TEXTURE2D_LOD(_DecalDynamicData, sampler_DecalControl, float2(u, 0), 0);
mtx._m10_m11_m12_m13 = SAMPLE_TEXTURE2D_LOD(_DecalDynamicData, sampler_DecalControl, float2(u, 1*sz), 0);
mtx._m20_m21_m22_m23 = SAMPLE_TEXTURE2D_LOD(_DecalDynamicData, sampler_DecalControl, float2(u, 2*sz), 0);
mtx._m30_m31_m32_m33 = SAMPLE_TEXTURE2D_LOD(_DecalDynamicData, sampler_DecalControl, float2(u, 3*sz), 0);
return mtx;
}
DecalLayer InitDecalLayer()
{
DecalLayer o = (DecalLayer)0;
o.uv = float3(0,0,-1);
o.dx = float2(0,0);
o.dy = float2(0,0);
o.dynamic = 0;
o.decalIndex = 0;
return o;
}
DecalOutput InitDecalOutput()
{
DecalOutput o = (DecalOutput)0;
o.l0 = InitDecalLayer();
o.l1 = InitDecalLayer();
o.l2 = InitDecalLayer();
o.l3 = InitDecalLayer();
o.Weights = half4(0,0,0,0);
o.Indexes = half4(0,1,2,3);
o.fxLevels = half4(0,0,0,0);
return o;
}
// we are drawn from highest to the lowest
void DecalInsert(inout DecalOutput o, DecalLayer l)
{
if (o.l0.uv.z < 0)
{
o.l0 = l;
}
else if (o.l1.uv.z < 0)
{
o.l1 = o.l0;
o.l0 = l;
}
else if (o.l2.uv.z < 0)
{
o.l2 = o.l1;
o.l1 = o.l0;
o.l0 = l;
}
else
{
o.l3 = o.l2;
o.l2 = o.l1;
o.l1 = o.l0;
o.l0 = l;
}
}
void DrawDecal(int decalIndex, inout DecalOutput o, float4 data, bool dynamic, float2 uv, float2 dx, float2 dy)
{
#if !_DECAL_NOTEXTURES || _DECAL_EMISMETAL
int texIndex = data.x - floor(data.x * 0.01);
DecalLayer l = InitDecalLayer();
l.uv = float3(uv, texIndex);
l.dx = ddx(uv); //recalculate derivative to reduce artifacts
l.dy = ddy(uv);
l.dynamic = dynamic;
l.decalIndex = decalIndex;
DecalInsert(o, l);
#endif
#if _DECAL_SPLAT
int splatTexIndex = floor(data.x * 0.01);
half4 splats = SAMPLE_TEXTURE2D_GRAD(_DecalSplats, shared_linear_clamp_sampler, float3(uv.xy, splatTexIndex), dx, dy);
float4 splatIndexes = 0;
UNITY_BRANCH
if (dynamic)
{
splatIndexes = GetDecalDynamicData(decalIndex, DECALSPLATS);
}
else
{
splatIndexes = GetDecalStaticData(decalIndex, DECALSPLATS);
}
float splatOpacity = abs(data.z) - 1;
float splatMode = data.z > 0 ? 1 : 0;
splats *= splatOpacity * 2;
UNITY_BRANCH
if (splatMode > 0.5)
{
// Another odity, splat index 0 won't register..
DoMergeDecalSplats(splats, splatIndexes, o.Weights, o.Indexes);
}
else
{
o.fxLevels = max(o.fxLevels, splats);
}
#endif
}
void CullDrawStaticDecal(int i, float3 worldPos, float3 localPos, inout DecalOutput o, float2 dx, float2 dy)
{
i = min(_STATICDECALMAX-1, i);
float3 localProj = mul(GetDecalStaticMtx(i), float4(localPos, 1)).xyz;
float2 uv = localProj.xz + 0.5;
float4 decalData1 = GetDecalStaticData(i, DECALDATA1);
float scaleY = decalData1.y;
float clipPos = (localProj.y + 0.5) - 1.0/max(scaleY, 0.001);
bool clipBounds = (uv.x == saturate(uv.x) && uv.y == saturate(uv.y) && clipPos == saturate(clipPos));
UNITY_BRANCH
if (clipBounds)
{
DrawDecal(i, o, decalData1, false, uv, dx, dy);
}
}
void CullDrawDynamicDecal(int i, float3 worldPos, float3 localPos, inout DecalOutput o)
{
float3 localProj = mul(GetDecalDynamicMtx(i), float4(localPos, 1)).xyz;
float2 uv = localProj.xz + 0.5;
float2 dx = ddx(uv);
float2 dy = ddy(uv);
float4 decalData1 = GetDecalDynamicData(i, DECALDATA1);
float scaleY = decalData1.y;
float clipPos = (localProj.y + 0.5) - 1.0/max(scaleY, 0.001);
bool clipBounds = (uv.x == saturate(uv.x) && uv.y == saturate(uv.y) && clipPos == saturate(clipPos));
UNITY_BRANCH
if (clipBounds)
{
DrawDecal(i, o, decalData1, true, uv, dx, dy);
}
}
void CullDrawDynamicDecalTess(int i, float3 worldPos, float3 localPos, inout DecalOutput o)
{
float3 localProj = mul(GetDecalDynamicMtx(i), float4(localPos, 1)).xyz;
float2 uv = localProj.xz + 0.5;
float2 dx = 0;
float2 dy = 0;
float4 decalData1 = GetDecalDynamicData(i, DECALDATA1);
float scaleY = decalData1.y;
float clipPos = (localProj.y + 0.5) - 1.0/max(scaleY, 0.001);
bool clipBounds = (uv.x == saturate(uv.x) && uv.y == saturate(uv.y) && clipPos == saturate(clipPos));
UNITY_BRANCH
if (clipBounds)
{
DrawDecal(i, o, decalData1, true, uv, dx, dy);
}
}
// Distance based culling
void RoughCullDynamicDecal(int i, float3 worldPos, float3 localPos, inout DecalOutput o)
{
float4 cullData = SAMPLE_TEXTURE2D_LOD(_DecalCullData, sampler_DecalControl, float2((i+0.5) * _DecalCullData_TexelSize.x, 0.5), 0);
float3 lv = worldPos - cullData.xyz;
float dist = lv.x * lv.x + lv.y * lv.y + lv.z * lv.z;
UNITY_BRANCH
if (dist < cullData.w)
{
CullDrawDynamicDecal(i, worldPos, localPos, o);
}
}
// Distance based culling
void RoughCullDynamicDecalTess(int i, float3 worldPos, float3 localPos, inout DecalOutput o)
{
float4 cullData = SAMPLE_TEXTURE2D_LOD(_DecalCullData, sampler_DecalControl, float2((i+0.5) * _DecalCullData_TexelSize.x, 0.5), 0);
float3 lv = worldPos - cullData.xyz;
float dist = lv.x * lv.x + lv.y * lv.y + lv.z * lv.z;
UNITY_BRANCH
if (dist < cullData.w)
{
CullDrawDynamicDecalTess(i, worldPos, localPos, o);
}
}
DecalOutput DoDecals(float2 uv, float3 worldPos, float camDist, float3 worldNormalVertex)
{
DecalOutput o = InitDecalOutput();
// Terrain matrix's lie, so in terrain mode, we just use worldPos
float3 localPos = worldPos;
#if !_DECAL_STATICMAX0
// Static
float2 cuv = uv;
half4 c0 = SAMPLE_TEXTURE2D_LOD(_DecalControl, sampler_DecalControl, uv, 0);
c0 -= 1;
// OK, I don't quite understand this, and expect it to break, but haven't so far.
// The issue is that we get derivative lines when we have overlapping decals. This is
// because the index map may report (2,1,0,0) on one pixel, and (1,0,0,0) on the next when
// one decal ends. Thus, when mip map data is shared and the indexes change, you get derivative issues.
//
// For regular UV scale blending, I just average the derivatives of all texels being used. But
// here we can't do that. So while testing, I just transformed the first decal in the list into
// decal space and used it's derivatives for all decals. But this can't possibly work right!? Right?
int initialIdx = max(c0.r, 0);
float3 localProj = mul(GetDecalStaticMtx(initialIdx), float4(localPos, 1)).xyz;
float2 xuv = localProj.xy + 0.5;
float2 dx = ddx(xuv);
float2 dy = ddy(xuv);
UNITY_BRANCH
if (c0.r >= 0)
{
CullDrawStaticDecal((int)c0.r, worldPos, localPos, o, dx, dy);
UNITY_BRANCH
if (c0.g >= 0)
{
CullDrawStaticDecal((int)c0.g, worldPos, localPos, o, dx, dy);
UNITY_BRANCH
if (c0.b >= 0)
{
CullDrawStaticDecal((int)c0.b, worldPos, localPos, o, dx, dy);
UNITY_BRANCH
if (c0.a >= 0)
{
CullDrawStaticDecal((int)c0.a, worldPos, localPos, o, dx, dy);
}
}
}
}
#endif
#if !_DECAL_MAX0
// dynamic
int count = _MSDecalCount;
if (count > _DECALMAX)
count = _DECALMAX;
[loop] for (int i = 0; i < count; i++)
{
RoughCullDynamicDecal(i, worldPos, localPos, o);
}
#endif //!_DECAL_MAX0
return o;
}
#if (_TESSDISTANCE || _TESSEDGE) && _DECAL_TESS
DecalOutput DoDecalsTess(float2 uv, float3 worldPos, float camDist, float3 worldNormalVertex)
{
DecalOutput o = InitDecalOutput();
// Terrain matrix's lie, so in terrain mode, we just use worldPos
float3 localPos = worldPos;
#if !_DECAL_STATICMAX0
// Static
// texture must be clamped, but we want to share samplers, so floor
float2 cuv = uv;
half4 c0 = SAMPLE_TEXTURE2D_LOD(_DecalControl, sampler_DecalControl, uv, 0);
c0 -= 1;
// OK, I don't quite understand this, and expect it to break, but haven't so far.
// The issue is that we get derivative lines when we have overlapping decals. This is
// because the index map may report (2,1,0,0) on one pixel, and (1,0,0,0) on the next when
// one decal ends. Thus, when mip map data is shared and the indexes change, you get derivative issues.
//
// For regular UV scale blending, I just average the derivatives of all texels being used. But
// here we can't do that. So while testing, I just transformed the first decal in the list into
// decal space and used it's derivatives for all decals. But this can't possibly work right!? Right?
UNITY_BRANCH
if (c0.r >= 0)
{
CullDrawStaticDecal((int)c0.r, worldPos, localPos, o, 0, 0);
UNITY_BRANCH
if (c0.g >= 0)
{
CullDrawStaticDecal((int)c0.g, worldPos, localPos, o, 0, 0);
UNITY_BRANCH
if (c0.b >= 0)
{
CullDrawStaticDecal((int)c0.b, worldPos, localPos, o, 0, 0);
UNITY_BRANCH
if (c0.a >= 0)
{
CullDrawStaticDecal((int)c0.a, worldPos, localPos, o, 0, 0);
}
}
}
}
#endif
#if !_DECAL_MAX0
// dynamic
int count = _MSDecalCount;
if (count > _DECALMAX)
count = _DECALMAX;
[loop] for (int i = 0; i < count; i++)
{
RoughCullDynamicDecalTess(i, worldPos, localPos, o);
}
#endif //!_DECAL_MAX0
return o;
}
#endif
// mode is encoded in sign
float BlendDecalNormal(half2 src, inout half2 dest, float opacity)
{
if (opacity < 0)
{
dest = BlendNormal2(src, dest);
}
half alpha = abs(opacity)-1;
return alpha;
}
void SampleDecalTexLayer(DecalLayer l, inout half4 albedo, inout half4 normalSAO, inout half3 surf, inout half4 emisMetal)
{
int texIndex = l.uv.z;
int decalIndex = l.decalIndex;
float4 data1;
float4 data2;
fixed3 tint = fixed3(1,1,1);
UNITY_BRANCH
if (l.dynamic)
{
data1 = GetDecalDynamicData(decalIndex, DECALDATA1);
data2 = GetDecalDynamicData(decalIndex, DECALDATA2);
#if _DECAL_TINT
tint = GetDecalDynamicData(decalIndex, DECALTINT);
#endif
}
else
{
data1 = GetDecalStaticData(decalIndex, DECALDATA1);
data2 = GetDecalStaticData(decalIndex, DECALDATA2);
#if _DECAL_TINT
tint = GetDecalStaticData(decalIndex, DECALTINT);
#endif
}
float albedoOpacity = abs(data2.x) - 1;
float normalOpacity = data2.y;
float smoothnessOpacity = data2.z;
float heightBlend = data2.w;
half4 dalbedo = SAMPLE_TEXTURE2D_GRAD(_DecalAlbedo, sampler_Diffuse, l.uv, l.dx, l.dy);
COUNTSAMPLE
half4 dnsao = SAMPLE_TEXTURE2D_GRAD(_DecalNormalSAO, sampler_NormalSAO, l.uv, l.dx, l.dy).agrb;
COUNTSAMPLE
dnsao.xy *= 2;
dnsao.xy -= 1;
half alpha = dnsao.a;
#if _DECAL_TINT
dalbedo.rgb *= tint;
#endif
// reconstruct ao
dnsao.a = 1 - (dnsao.x * dnsao.y);
half hb = lerp(alpha, HeightBlend(albedo.a, dalbedo.a, alpha, _Contrast), heightBlend);
if (data2.x < 0)
{
dalbedo.rgb = BlendMult2X(albedo.rgb, dalbedo.rgb);
}
albedo = lerp(albedo, dalbedo, albedoOpacity * hb);
#if _SURFACENORMALS
half3 surfN = ConvertNormal2ToGradient(dnsao.xy);
#endif
float alpha0 = BlendDecalNormal(normalSAO.xy, dnsao.xy, normalOpacity);
normalSAO.xy = lerp(normalSAO.xy, dnsao.xy, alpha0 * hb);
normalSAO.zw = lerp(normalSAO.zw, dnsao.zw, smoothnessOpacity * hb);
#if _SURFACENORMALS
if (normalOpacity < 0)
surf += surfN * alpha0 * hb;
else
surf = lerp(surf, surfN, alpha * hb);
#endif
#if _DECAL_EMISMETAL
half4 demisMetal = SAMPLE_TEXTURE2D_GRAD(_DecalEmisMetal, sampler_Diffuse, l.uv, l.dx, l.dy);
COUNTSAMPLE
emisMetal.w = lerp(emisMetal.w, demisMetal.w, heightBlend);
emisMetal.rgb += demisMetal.rgb;
#endif
}
void DoDecalBlend(DecalOutput i, inout half4 albedo, inout half4 normalSAO, inout half3 surf, inout half4 emisMetal, float2 uv)
{
#if !_DECAL_NOTEXTURES
UNITY_BRANCH
if (i.l0.uv.z >= 0)
{
SampleDecalTexLayer(i.l0, albedo, normalSAO, surf, emisMetal);
#if _DEBUG_DECAL_STATIC
albedo.r += 0.5;
#endif
UNITY_BRANCH
if (i.l1.uv.z >= 0)
{
#if _DEBUG_DECAL_STATIC
albedo.g += 0.5;
#endif
SampleDecalTexLayer(i.l1, albedo, normalSAO, surf, emisMetal);
UNITY_BRANCH
if (i.l2.uv.z >= 0)
{
#if _DEBUG_DECAL_STATIC
albedo.b += 0.5;
#endif
SampleDecalTexLayer(i.l2, albedo, normalSAO, surf, emisMetal);
UNITY_BRANCH
if (i.l3.uv.z >= 0)
{
SampleDecalTexLayer(i.l3, albedo, normalSAO, surf, emisMetal);
}
}
}
}
float2 cuv = uv;
#endif
}
#if (_TESSDISTANCE || _TESSEDGE) && _DECAL_TESS
void SampleDecalTexLayerTess(DecalLayer l, inout half h0, inout half h1, inout half h2, inout half h3, float mipLevel)
{
int texIndex = l.uv.z;
int decalIndex = l.decalIndex;
float4 data1;
float4 data2;
if (l.dynamic)
{
data1 = GetDecalDynamicData(decalIndex, DECALDATA1);
data2 = GetDecalDynamicData(decalIndex, DECALDATA2);
}
else
{
data1 = GetDecalStaticData(decalIndex, DECALDATA1);
data2 = GetDecalStaticData(decalIndex, DECALDATA2);
}
float tessOpacity = data1.w;
float heightBlend = data2.w;
half4 dalbedo = SAMPLE_TEXTURE2D_ARRAY_LOD(_DecalAlbedo, sampler_Diffuse, l.uv.xy, l.uv.z, mipLevel);
half4 dnsao = SAMPLE_TEXTURE2D_ARRAY_LOD(_DecalNormalSAO, sampler_Diffuse, l.uv.xy, l.uv.z, mipLevel).agrb;
half alpha = dnsao.a;
const float dec = 1.0 / 0.95;
float alphaOp = frac(tessOpacity) * dec;
float offset = floor(tessOpacity) / 256;
half height = (dalbedo.a - 0.5 + offset);
half blend = alpha * alphaOp;
h0 = lerp(h0, HeightBlend(h0, height, heightBlend, _Contrast), blend);
h1 = lerp(h1, HeightBlend(h1, height, heightBlend, _Contrast), blend);
h2 = lerp(h2, HeightBlend(h2, height, heightBlend, _Contrast), blend);
h3 = lerp(h3, HeightBlend(h3, height, heightBlend, _Contrast), blend);
}
void DoDecalBlendTess(DecalOutput i, inout half h0, inout half h1, inout half h2, inout half h3, float mipLevel)
{
#if !_DECAL_NOTEXTURES && _DECAL_TESS
UNITY_BRANCH
if (i.l0.uv.z >= 0)
{
SampleDecalTexLayerTess(i.l0, h0, h1, h2, h3, mipLevel);
UNITY_BRANCH
if (i.l1.uv.z >= 0)
{
SampleDecalTexLayerTess(i.l1, h0, h1, h2, h3, mipLevel);
UNITY_BRANCH
if (i.l2.uv.z >= 0)
{
SampleDecalTexLayerTess(i.l2, h0, h1, h2, h3, mipLevel);
UNITY_BRANCH
if (i.l3.uv.z >= 0)
{
SampleDecalTexLayerTess(i.l3, h0, h1, h2, h3, mipLevel);
}
}
}
}
#endif
}
#endif

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 61f35886a28b64a9eaf8535303f0c79d
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,6 @@
_DecalAlbedo("Decal Albedo", 2DArray) = "white" {}
_DecalNormalSAO("Decal Normal SAO", 2DArray) = "bump" {}
_DecalSplats("Decal Splats", 2DArray) = "red" {}
_DecalControl("Decal Control", 2D) = "black" {}
_DecalStaticData("Decal Static Data", 2D) = "black" {}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: 9c54dd670b2904cd68df91f91229e8d3
TextScriptImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,3 @@
{
"reference": "GUID:90ab0119788ed4ec6b8fe54dd44f01fa"
}

View File

@@ -0,0 +1,7 @@
fileFormatVersion: 2
guid: cae0fd65af842486e9c5ed21cf82d1d3
AssemblyDefinitionReferenceImporter:
externalObjects: {}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,223 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using JBooth.MicroSplat;
[CustomEditor (typeof (MicroSplatDecal))]
public class MicroSplatDecalEditor : Editor
{
static GUIContent CDynamic = new GUIContent ("Render Mode", "Static decals are fast to render, but slow to move. Dynamic decals are slow to render, but fast to move");
static GUIContent CReceiver = new GUIContent ("Receiver", "Object which decal is applied to");
static bool firstInit = true;
enum DrawMode
{
Static,
Dynamic
}
Bounds OnGetFrameBounds ()
{
MicroSplatDecal d = (MicroSplatDecal)target;
Bounds bounds = new Bounds (d.transform.position, d.transform.lossyScale * 0.75f);
return bounds;
}
bool HasFrameBounds ()
{
return true;
}
public override void OnInspectorGUI ()
{
if (firstInit)
{
firstInit = false;
MicroSplatDecal.gizmoMode = (MicroSplatDecal.GizmoMode)EditorPrefs.GetInt ("MicroSplatDecal_GizmoMode", (int)MicroSplatDecal.gizmoMode);
MicroSplatDecal.staticGizmoColor.r = EditorPrefs.GetFloat ("MicroSplatDecal_staticgizmocolor-r", MicroSplatDecal.staticGizmoColor.r);
MicroSplatDecal.staticGizmoColor.g = EditorPrefs.GetFloat ("MicroSplatDecal_staticgizmocolor-g", MicroSplatDecal.staticGizmoColor.g);
MicroSplatDecal.staticGizmoColor.b = EditorPrefs.GetFloat ("MicroSplatDecal_staticgizmocolor-b", MicroSplatDecal.staticGizmoColor.b);
MicroSplatDecal.staticGizmoColor.a = EditorPrefs.GetFloat ("MicroSplatDecal_staticgizmocolor-a", MicroSplatDecal.staticGizmoColor.a);
MicroSplatDecal.staticGizmoSelectedColor.r = EditorPrefs.GetFloat ("MicroSplatDecal_staticgizmoselectedcolor-r", MicroSplatDecal.staticGizmoSelectedColor.r);
MicroSplatDecal.staticGizmoSelectedColor.g = EditorPrefs.GetFloat ("MicroSplatDecal_staticgizmoselectedcolor-g", MicroSplatDecal.staticGizmoSelectedColor.g);
MicroSplatDecal.staticGizmoSelectedColor.b = EditorPrefs.GetFloat ("MicroSplatDecal_staticgizmoselectedcolor-b", MicroSplatDecal.staticGizmoSelectedColor.b);
MicroSplatDecal.staticGizmoSelectedColor.a = EditorPrefs.GetFloat ("MicroSplatDecal_staticgizmoselectedcolor-a", MicroSplatDecal.staticGizmoSelectedColor.a);
MicroSplatDecal.dynamicGizmoColor.r = EditorPrefs.GetFloat ("MicroSplatDecal_dynamicgizmocolor-r", MicroSplatDecal.dynamicGizmoColor.r);
MicroSplatDecal.dynamicGizmoColor.g = EditorPrefs.GetFloat ("MicroSplatDecal_dynamicgizmocolor-g", MicroSplatDecal.dynamicGizmoColor.g);
MicroSplatDecal.dynamicGizmoColor.b = EditorPrefs.GetFloat ("MicroSplatDecal_dynamicgizmocolor-b", MicroSplatDecal.dynamicGizmoColor.b);
MicroSplatDecal.dynamicGizmoColor.a = EditorPrefs.GetFloat ("MicroSplatDecal_dynamicgizmocolor-a", MicroSplatDecal.dynamicGizmoColor.a);
MicroSplatDecal.dynamicGizmoSelectedColor.r = EditorPrefs.GetFloat ("MicroSplatDecal_dynamicgizmoselectedcolor-r", MicroSplatDecal.dynamicGizmoSelectedColor.r);
MicroSplatDecal.dynamicGizmoSelectedColor.g = EditorPrefs.GetFloat ("MicroSplatDecal_dynamicgizmoselectedcolor-g", MicroSplatDecal.dynamicGizmoSelectedColor.g);
MicroSplatDecal.dynamicGizmoSelectedColor.b = EditorPrefs.GetFloat ("MicroSplatDecal_dynamicgizmoselectedcolor-b", MicroSplatDecal.dynamicGizmoSelectedColor.b);
MicroSplatDecal.dynamicGizmoSelectedColor.a = EditorPrefs.GetFloat ("MicroSplatDecal_dynamicgizmocselectedolor-a", MicroSplatDecal.dynamicGizmoSelectedColor.a);
}
EditorGUI.BeginChangeCheck ();
MicroSplatDecal d = (MicroSplatDecal)target;
d.targetObject = EditorGUILayout.ObjectField(CReceiver, d.targetObject, typeof(MicroSplatDecalReceiver), true) as MicroSplatDecalReceiver;
if (d.targetObject == null || d.targetObject.msObj == null)
{
return;
}
var msObj = d.targetObject.msObj;
if (msObj.matInstance != null && msObj.matInstance.HasProperty ("_DecalAlbedo"))
{
Texture2DArray ta = null;
if (!msObj.keywordSO.IsKeywordEnabled ("_DECAL_NOTEXTURES"))
{
ta = (Texture2DArray)msObj.matInstance.GetTexture ("_DecalAlbedo");
if (ta != null)
{
d.textureIndex = JBooth.MicroSplat.MicroSplatUtilities.DrawTextureSelector (d.textureIndex, ta);
}
}
using (new GUILayout.VerticalScope (GUI.skin.box))
{
d.dynamic = DrawMode.Dynamic == (DrawMode)EditorGUILayout.EnumPopup (CDynamic, d.dynamic == true ? DrawMode.Dynamic : DrawMode.Static);
}
if (!msObj.keywordSO.IsKeywordEnabled ("_DECAL_NOTEXTURES"))
{
using (new GUILayout.VerticalScope (GUI.skin.box))
{
d.albedoBlend = (MicroSplatDecal.AlbedoBlend)EditorGUILayout.EnumPopup ("Albedo Blend Mode", d.albedoBlend);
d.albedoOpacity = EditorGUILayout.Slider ("Albedo Opacity", d.albedoOpacity, 0, 1);
if (msObj.keywordSO.IsKeywordEnabled ("_DECAL_TINT"))
{
d.tint = EditorGUILayout.ColorField ("Tint", d.tint);
}
}
using (new GUILayout.VerticalScope (GUI.skin.box))
{
d.heightBlend = EditorGUILayout.Slider ("Height Blend", d.heightBlend, 0, 1);
}
using (new GUILayout.VerticalScope (GUI.skin.box))
{
d.normalBlend = (MicroSplatDecal.NormalBlend)EditorGUILayout.EnumPopup ("Normal Blend Mode", d.normalBlend);
d.normalOpacity = EditorGUILayout.Slider ("Normal Opacity", d.normalOpacity, 0, 1);
}
using (new GUILayout.VerticalScope (GUI.skin.box))
{
d.smoothnessOpacity = EditorGUILayout.Slider ("Smoothness/AO Opacity", d.smoothnessOpacity, 0, 1);
}
#if __MICROSPLAT_TESSELLATION__
if (msObj.keywordSO.IsKeywordEnabled ("_DECAL_TESS") && msObj.keywordSO.IsKeywordEnabled ("_TESSDISTANCE"))
{
using (new GUILayout.VerticalScope (GUI.skin.box))
{
d.tessOpacity = EditorGUILayout.Slider ("Displacement Opacity", d.tessOpacity, 0, 1);
d.tessOffset = EditorGUILayout.Slider ("Displacement Offset", d.tessOffset, -1, 1);
}
}
#endif
}
if (msObj.keywordSO.IsKeywordEnabled ("_DECAL_SPLAT"))
{
bool on = d.splatOpacity >= 0.01f;
bool newOn = EditorGUILayout.Toggle ("Effect Splat Maps", on);
if (newOn != on)
{
d.splatOpacity = newOn == false ? 0 : 0.5f;
}
if (newOn)
{
Texture2DArray splatsArray = (Texture2DArray)msObj.templateMaterial.GetTexture ("_DecalSplats");
if (splatsArray != null)
{
d.splatTextureIndex = JBooth.MicroSplat.MicroSplatUtilities.DrawTextureSelector (d.splatTextureIndex, splatsArray);
d.splatOpacity = EditorGUILayout.Slider ("Splat Opacity", d.splatOpacity * 2, 0.01f, 2) * 0.5f;
d.splatMode = (MicroSplatDecal.SplatMode)EditorGUILayout.EnumPopup ("SplatMode", d.splatMode);
if (d.splatMode == MicroSplatDecal.SplatMode.SplatMap)
{
ta = msObj.templateMaterial.GetTexture ("_Diffuse") as Texture2DArray;
d.splatIndexes.x = JBooth.MicroSplat.MicroSplatUtilities.DrawTextureSelector ((int)d.splatIndexes.x, ta, true);
d.splatIndexes.y = JBooth.MicroSplat.MicroSplatUtilities.DrawTextureSelector ((int)d.splatIndexes.y, ta, true);
d.splatIndexes.z = JBooth.MicroSplat.MicroSplatUtilities.DrawTextureSelector ((int)d.splatIndexes.z, ta, true);
d.splatIndexes.w = JBooth.MicroSplat.MicroSplatUtilities.DrawTextureSelector ((int)d.splatIndexes.w, ta, true);
}
}
else
{
EditorGUILayout.HelpBox ("Splat's array is enabled, but not assigned to the material. Please assign", MessageType.Error);
}
}
}
}
using (new GUILayout.VerticalScope (GUI.skin.box))
{
d.sortOrder = EditorGUILayout.IntField ("Sort Order", d.sortOrder);
}
EditorGUILayout.Space ();
MicroSplatTerrain mst = d.targetObject.msObj as MicroSplatTerrain;
bool terrainExists = mst != null;
#if __MICROSPLAT_MESHTERRAIN__
if ((d.targetObject.msObj as MicroSplatMeshTerrain) != null)
terrainExists = true;
#endif
if (terrainExists && GUILayout.Button ("Bake Static Decals"))
{
d.targetObject.RerenderCacheMap ();
}
EditorGUILayout.Space ();
EditorGUILayout.Space ();
if (JBooth.MicroSplat.MicroSplatUtilities.DrawRollup ("Display Settings", false, false))
{
EditorGUI.BeginChangeCheck ();
MicroSplatDecal.gizmoMode = (MicroSplatDecal.GizmoMode)EditorGUILayout.EnumPopup ("Gizmo Mode", MicroSplatDecal.gizmoMode);
if (MicroSplatDecal.gizmoMode != MicroSplatDecal.GizmoMode.Hide)
{
MicroSplatDecal.staticGizmoColor = EditorGUILayout.ColorField ("Static Gizmo Color", MicroSplatDecal.staticGizmoColor);
MicroSplatDecal.staticGizmoSelectedColor = EditorGUILayout.ColorField ("Static Gizmo Selected Color", MicroSplatDecal.staticGizmoSelectedColor);
MicroSplatDecal.dynamicGizmoColor = EditorGUILayout.ColorField ("Dynamic Gizmo Color", MicroSplatDecal.dynamicGizmoColor);
MicroSplatDecal.dynamicGizmoSelectedColor = EditorGUILayout.ColorField ("Dynamic Gizmo Selected Color", MicroSplatDecal.dynamicGizmoSelectedColor);
}
if (EditorGUI.EndChangeCheck())
{
EditorPrefs.SetInt ("MicroSplatDecal_GizmoMode", (int)MicroSplatDecal.gizmoMode);
EditorPrefs.SetFloat ("MicroSplatDecal_staticgizmocolor-r", MicroSplatDecal.staticGizmoColor.r);
EditorPrefs.SetFloat ("MicroSplatDecal_staticgizmocolor-g", MicroSplatDecal.staticGizmoColor.g);
EditorPrefs.SetFloat ("MicroSplatDecal_staticgizmocolor-b", MicroSplatDecal.staticGizmoColor.b);
EditorPrefs.SetFloat ("MicroSplatDecal_staticgizmocolor-a", MicroSplatDecal.staticGizmoColor.a);
EditorPrefs.SetFloat ("MicroSplatDecal_staticgizmoselectedcolor-r", MicroSplatDecal.staticGizmoSelectedColor.r);
EditorPrefs.SetFloat ("MicroSplatDecal_staticgizmoselectedcolor-g", MicroSplatDecal.staticGizmoSelectedColor.g);
EditorPrefs.SetFloat ("MicroSplatDecal_staticgizmoselectedcolor-b", MicroSplatDecal.staticGizmoSelectedColor.b);
EditorPrefs.SetFloat ("MicroSplatDecal_staticgizmoselectedcolor-a", MicroSplatDecal.staticGizmoSelectedColor.a);
EditorPrefs.SetFloat ("MicroSplatDecal_dynamicgizmocolor-r", MicroSplatDecal.dynamicGizmoColor.r);
EditorPrefs.SetFloat ("MicroSplatDecal_dynamicgizmocolor-g", MicroSplatDecal.dynamicGizmoColor.g);
EditorPrefs.SetFloat ("MicroSplatDecal_dynamicgizmocolor-b", MicroSplatDecal.dynamicGizmoColor.b);
EditorPrefs.SetFloat ("MicroSplatDecal_dynamicgizmocolor-a", MicroSplatDecal.dynamicGizmoColor.a);
EditorPrefs.SetFloat ("MicroSplatDecal_dynamicgizmoselectedcolor-r", MicroSplatDecal.dynamicGizmoSelectedColor.r);
EditorPrefs.SetFloat ("MicroSplatDecal_dynamicgizmoselectedcolor-g", MicroSplatDecal.dynamicGizmoSelectedColor.g);
EditorPrefs.SetFloat ("MicroSplatDecal_dynamicgizmoselectedcolor-b", MicroSplatDecal.dynamicGizmoSelectedColor.b);
EditorPrefs.SetFloat ("MicroSplatDecal_dynamicgizmocselectedolor-a", MicroSplatDecal.dynamicGizmoSelectedColor.a);
}
}
if (EditorGUI.EndChangeCheck())
{
d.targetObject.RerenderCacheMap ();
EditorUtility.SetDirty (d);
d.Reset ();
}
MicroSplatDecalReceiver dr = d.targetObject;
if (dr.cacheMask != null && terrainExists)
{
Rect r = EditorGUILayout.GetControlRect (GUILayout.Width (256), GUILayout.Height (256));
EditorGUI.DrawPreviewTexture (r, dr.cacheMask);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: e42b48fd1c7664ffba149220b86bcdf6
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,438 @@
//////////////////////////////////////////////////////
// MicroSplat
// Copyright (c) Jason Booth
//////////////////////////////////////////////////////
using UnityEngine;
using System.Collections;
using UnityEditor;
using UnityEditor.Callbacks;
using System.Collections.Generic;
namespace JBooth.MicroSplat
{
#if __MICROSPLAT__
[InitializeOnLoad]
public class MicroSplatDecalModule : FeatureDescriptor
{
[MenuItem ("Window/MicroSplat/Create Decal")]
static void AddEmitter ()
{
GameObject go = new GameObject ("Decal");
go.transform.localScale = new Vector3 (10, 10, 10);
go.AddComponent<MicroSplatDecal> ();
}
const string sDefine = "__MICROSPLAT_DECAL__";
static MicroSplatDecalModule()
{
MicroSplatDefines.InitDefine(sDefine);
}
[PostProcessSceneAttribute (0)]
public static void OnPostprocessScene()
{
MicroSplatDefines.InitDefine(sDefine);
}
public override string ModuleName()
{
return "Decal";
}
public override string GetHelpPath ()
{
return "https://docs.google.com/document/d/1I7kDLojwVQbnTkmtSMfVrFW9yaVQLLQi0ibqFLY960A/edit?usp=sharing";
}
public enum DefineFeature
{
_DECAL,
_DECAL_MAX0,
_DECAL_MAX4,
_DECAL_MAX8,
_DECAL_MAX16,
_DECAL_MAX32,
_DECAL_MAX64,
_DECAL_MAX128,
_DECAL_MAX256,
_DECAL_STATICMAX0,
_DECAL_STATICMAX64,
_DECAL_STATICMAX128,
_DECAL_STATICMAX256,
_DECAL_STATICMAX512,
_DECAL_STATICMAX1024,
_DECAL_STATICMAX2048,
_DECAL_NOTEXTURES,
_DECAL_EMISMETAL,
_DECAL_SPLAT,
_DECAL_TESS,
_DECAL_TINT,
kNumFeatures,
}
public enum MaxDecals
{
None,
k4,
k8,
k16,
k32,
k64,
}
public enum MaxStaticDecals
{
None,
k64,
k128,
k256,
k512,
k1024,
k2048,
}
public bool decals = false;
public MaxDecals maxDecals = MaxDecals.k16;
public MaxStaticDecals maxStaticDecals = MaxStaticDecals.k512;
public bool effectTextures = true;
public bool effectSplats = false;
public bool tint = false;
public bool emisMetal = false;
#if __MICROSPLAT_TESSELLATION__
public bool effectTess = false;
#endif
static TextAsset properties;
static TextAsset funcs;
static TextAsset cbuffer;
GUIContent CDecals = new GUIContent ("Decals", "Enable decal system");
GUIContent CEffectTextures = new GUIContent ("Effect Diffuse/Normal", "Should decals modify the albedo and normal data");
GUIContent CEffectEmisMetal = new GUIContent ("Support Emissive/Metallic map", "When enabled, you can use an emissive/metallic array with decals");
GUIContent CEffectSplats = new GUIContent ("Effect Splat Maps", "Should decals modify the splat map or FX (wetness, puddles, streams, lava) data");
#if __MICROSPLAT_TESSELLATION__
GUIContent CAffectTess = new GUIContent ("Effect Displacement", "Should decals modify the displacement when tessellation is enabled");
#endif
GUIContent CMaxDecals = new GUIContent ("Max Dynamic", "Maximum number of dynamic decals allowed on a single object or terrain. Dynamic decals have a runtime GPU cost based on how many decals are on an object");
GUIContent CMaxStaticDecals = new GUIContent ("Max Static", "Maximum number of static decals allowed on a single terrain. Static Decals have very small runtime cost, but are CPU intensive when moved or adjusted at runtime");
GUIContent CAlbedo = new GUIContent ("Albedo Array", "Albedo/alpha for decals");
GUIContent CEmisMetal = new GUIContent ("Emissive/Metal Array", "Emissive/Metallic array for decals");
GUIContent CNormalSAO = new GUIContent ("Normal SAO Array", "NSAO Array for decals");
GUIContent CSplat = new GUIContent ("Splat Map Array", "Array for splat maps, 3 texture weights (RGB) and alpha blend (A)");
GUIContent CPerDecalTint = new GUIContent ("Decal Tint", "Allows you to tint each decal");
static Dictionary<DefineFeature, string> sFeatureNames = new Dictionary<DefineFeature, string>();
public static string GetFeatureName(DefineFeature feature)
{
string ret;
if (sFeatureNames.TryGetValue(feature, out ret))
{
return ret;
}
string fn = System.Enum.GetName(typeof(DefineFeature), feature);
sFeatureNames[feature] = fn;
return fn;
}
public static bool HasFeature(string[] keywords, DefineFeature feature)
{
string f = GetFeatureName(feature);
for (int i = 0; i < keywords.Length; ++i)
{
if (keywords[i] == f)
return true;
}
return false;
}
public override string GetVersion()
{
return "3.9";
}
public override void DrawFeatureGUI(MicroSplatKeywords keywords)
{
decals = EditorGUILayout.Toggle (CDecals, decals);
if (decals)
{
EditorGUI.indentLevel++;
using (new GUILayout.VerticalScope (GUI.skin.box))
{
maxDecals = (MaxDecals)EditorGUILayout.EnumPopup (CMaxDecals, maxDecals);
maxStaticDecals = (MaxStaticDecals)EditorGUILayout.EnumPopup (CMaxStaticDecals, maxStaticDecals);
}
effectTextures = EditorGUILayout.Toggle (CEffectTextures, effectTextures);
emisMetal = EditorGUILayout.Toggle (CEffectEmisMetal, emisMetal);
effectSplats = EditorGUILayout.Toggle (CEffectSplats, effectSplats);
#if __MICROSPLAT_TESSELLATION__
effectTess = EditorGUILayout.Toggle (CAffectTess, effectTess);
#endif
tint = EditorGUILayout.Toggle (CPerDecalTint, tint);
EditorGUI.indentLevel--;
}
}
public override void DrawShaderGUI(MicroSplatShaderGUI shaderGUI, MicroSplatKeywords keywords, Material mat, MaterialEditor materialEditor, MaterialProperty[] props)
{
if (decals)
{
if (MicroSplatUtilities.DrawRollup("Decal") && mat.HasProperty("_DecalAlbedo"))
{
if (effectTextures)
{
var albedoMap = shaderGUI.FindProp ("_DecalAlbedo", props);
materialEditor.TexturePropertySingleLine (CAlbedo, albedoMap);
var normalMap = shaderGUI.FindProp ("_DecalNormalSAO", props);
materialEditor.TexturePropertySingleLine (CNormalSAO, normalMap);
}
if (emisMetal && mat.HasProperty("_DecalEmisMetal"))
{
var emis = shaderGUI.FindProp ("_DecalEmisMetal", props);
materialEditor.TexturePropertySingleLine (CEmisMetal, emis);
}
if (effectSplats && mat.HasProperty("_DecalSplats"))
{
var splatsMap = shaderGUI.FindProp ("_DecalSplats", props);
materialEditor.TexturePropertySingleLine (CSplat, splatsMap);
}
}
}
}
public override string[] Pack()
{
List<string> features = new List<string>();
if (decals)
{
features.Add(GetFeatureName(DefineFeature._DECAL));
if (maxDecals == MaxDecals.None)
{
features.Add (GetFeatureName (DefineFeature._DECAL_MAX0));
}
else if (maxDecals == MaxDecals.k4)
{
features.Add (GetFeatureName (DefineFeature._DECAL_MAX4));
}
else if (maxDecals == MaxDecals.k8)
{
features.Add (GetFeatureName (DefineFeature._DECAL_MAX8));
}
else if (maxDecals == MaxDecals.k16)
{
features.Add (GetFeatureName (DefineFeature._DECAL_MAX16));
}
else if (maxDecals == MaxDecals.k32)
{
features.Add (GetFeatureName (DefineFeature._DECAL_MAX32));
}
else if (maxDecals == MaxDecals.k64)
{
features.Add (GetFeatureName (DefineFeature._DECAL_MAX64));
}
if (maxStaticDecals == MaxStaticDecals.None)
{
features.Add (GetFeatureName (DefineFeature._DECAL_STATICMAX0));
}
if (maxStaticDecals == MaxStaticDecals.k64)
{
features.Add (GetFeatureName (DefineFeature._DECAL_STATICMAX64));
}
else if (maxStaticDecals == MaxStaticDecals.k128)
{
features.Add (GetFeatureName (DefineFeature._DECAL_STATICMAX128));
}
else if (maxStaticDecals == MaxStaticDecals.k256)
{
features.Add (GetFeatureName (DefineFeature._DECAL_STATICMAX256));
}
else if (maxStaticDecals == MaxStaticDecals.k512)
{
features.Add (GetFeatureName (DefineFeature._DECAL_STATICMAX512));
}
else if (maxStaticDecals == MaxStaticDecals.k1024)
{
features.Add (GetFeatureName (DefineFeature._DECAL_STATICMAX1024));
}
else if (maxStaticDecals == MaxStaticDecals.k2048)
{
features.Add (GetFeatureName (DefineFeature._DECAL_STATICMAX2048));
}
if (!effectTextures)
{
features.Add (GetFeatureName (DefineFeature._DECAL_NOTEXTURES));
}
if (effectSplats)
{
features.Add (GetFeatureName (DefineFeature._DECAL_SPLAT));
}
#if __MICROSPLAT_TESSELLATION__
if (effectTess)
{
features.Add (GetFeatureName (DefineFeature._DECAL_TESS));
}
#endif
if (tint)
{
features.Add (GetFeatureName (DefineFeature._DECAL_TINT));
}
if (emisMetal)
{
features.Add (GetFeatureName (DefineFeature._DECAL_EMISMETAL));
}
}
return features.ToArray();
}
public override void Unpack(string[] keywords)
{
decals = HasFeature (keywords, DefineFeature._DECAL);
maxDecals = MaxDecals.k4;
if (HasFeature(keywords, DefineFeature._DECAL_MAX0))
{
maxDecals = MaxDecals.None;
}
else if (HasFeature (keywords, DefineFeature._DECAL_MAX8))
{
maxDecals = MaxDecals.k8;
}
else if (HasFeature(keywords, DefineFeature._DECAL_MAX16))
{
maxDecals = MaxDecals.k16;
}
else if (HasFeature (keywords, DefineFeature._DECAL_MAX32))
{
maxDecals = MaxDecals.k32;
}
else if (HasFeature (keywords, DefineFeature._DECAL_MAX64))
{
maxDecals = MaxDecals.k64;
}
maxStaticDecals = MaxStaticDecals.k512;
if (HasFeature(keywords, DefineFeature._DECAL_STATICMAX0))
{
maxStaticDecals = MaxStaticDecals.None;
}
else if (HasFeature (keywords, DefineFeature._DECAL_STATICMAX64))
{
maxStaticDecals = MaxStaticDecals.k64;
}
else if (HasFeature (keywords, DefineFeature._DECAL_STATICMAX128))
{
maxStaticDecals = MaxStaticDecals.k128;
}
else if (HasFeature (keywords, DefineFeature._DECAL_STATICMAX256))
{
maxStaticDecals = MaxStaticDecals.k256;
}
else if (HasFeature (keywords, DefineFeature._DECAL_STATICMAX512))
{
maxStaticDecals = MaxStaticDecals.k512;
}
else if (HasFeature (keywords, DefineFeature._DECAL_STATICMAX1024))
{
maxStaticDecals = MaxStaticDecals.k1024;
}
else if (HasFeature (keywords, DefineFeature._DECAL_STATICMAX2048))
{
maxStaticDecals = MaxStaticDecals.k2048;
}
effectTextures = !HasFeature (keywords, DefineFeature._DECAL_NOTEXTURES);
emisMetal = HasFeature (keywords, DefineFeature._DECAL_EMISMETAL);
effectSplats = HasFeature (keywords, DefineFeature._DECAL_SPLAT);
tint = HasFeature (keywords, DefineFeature._DECAL_TINT);
#if __MICROSPLAT_TESSELLATION__
effectTess = HasFeature (keywords, DefineFeature._DECAL_TESS);
#endif
}
public override void InitCompiler(string[] paths)
{
for (int i = 0; i < paths.Length; ++i)
{
string p = paths[i];
if (p.EndsWith("microsplat_properties_decal.txt"))
{
properties = AssetDatabase.LoadAssetAtPath<TextAsset>(p);
}
if (p.EndsWith("microsplat_func_decal.txt"))
{
funcs = AssetDatabase.LoadAssetAtPath<TextAsset>(p);
}
if (p.EndsWith ("microsplat_cbuffer_decal.txt"))
{
cbuffer = AssetDatabase.LoadAssetAtPath<TextAsset> (p);
}
}
}
public override void WriteProperties(string[] features, System.Text.StringBuilder sb)
{
if (decals)
{
sb.Append(properties.text);
if (emisMetal)
{
sb.AppendLine ("_DecalEmisMetal(\"Decal Emissive Metal\", 2DArray) = \"black\" {}");
}
}
}
public override void WriteFunctions(string [] features, System.Text.StringBuilder sb)
{
if (decals)
{
sb.Append(funcs.text);
}
}
public override void WritePerMaterialCBuffer (string[] features, System.Text.StringBuilder sb)
{
if (decals)
{
sb.Append(cbuffer.text);
}
}
public override void ComputeSampleCounts(string[] features, ref int arraySampleCount, ref int textureSampleCount, ref int maxSamples, ref int tessellationSamples, ref int depTexReadLevel)
{
if (decals)
{
// this is rather arbitrary, could do some approximation based on static vs. dynamic counts, but wouldn't be any more or less
// correct than this..
arraySampleCount += 8;
}
#if __MICROSPLAT_TESSELLATION__
if (effectTess)
{
tessellationSamples += 8;
}
#endif
}
}
#endif
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b34a7e6c2739b4c6b921cf77a41dda6a
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,45 @@
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using UnityEditor;
using JBooth.MicroSplat;
[CustomEditor (typeof (MicroSplatDecalReceiver))]
public class MicroSplatDecalReceiverEditor : Editor
{
public override void OnInspectorGUI ()
{
MicroSplatDecalReceiver dr = (MicroSplatDecalReceiver)target;
if (dr.GetComponent<MicroSplatTerrain> () != null
#if __MICROSPLAT_MESHTERRAIN__
|| dr.GetComponent<MicroSplatMeshTerrain>() != null
#endif
)
{
serializedObject.Update ();
EditorGUILayout.PropertyField(serializedObject.FindProperty("generateCacheOnLoad"));
EditorGUILayout.PropertyField(serializedObject.FindProperty("staticCacheSize"));
serializedObject.ApplyModifiedProperties ();
EditorGUILayout.Space ();
EditorGUILayout.Space ();
EditorGUILayout.LabelField ("Dynamic Count: " + dr.dynamicCount);
EditorGUILayout.LabelField ("Static Count: " + dr.staticCount);
if (dr.cacheMask != null)
{
Rect r = EditorGUILayout.GetControlRect (GUILayout.Width (256), GUILayout.Height (256));
EditorGUI.DrawPreviewTexture (r, dr.cacheMask);
}
}
else
{
EditorGUILayout.LabelField ("Dynamic Count: " + dr.dynamicCount);
}
}
}

View File

@@ -0,0 +1,11 @@
fileFormatVersion: 2
guid: b767abc50fc1340eebeea34f28bd2a9e
MonoImporter:
externalObjects: {}
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant: