This commit is contained in:
CortexCore
2024-05-17 16:24:41 +08:00
parent 81913ff82f
commit e2650195a5
186 changed files with 72475 additions and 1 deletions

View File

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

View File

@@ -0,0 +1,279 @@
//////////////////////////////////////////////////////
// MicroSplat
// Copyright (c) Jason Booth
//////////////////////////////////////////////////////
using UnityEngine;
using System.Collections;
using UnityEditor;
using UnityEditor.Callbacks;
using System.Collections.Generic;
using System.Text;
namespace JBooth.MicroSplat
{
#if __MICROSPLAT__ && (VEGETATION_STUDIO || VEGETATION_STUDIO_PRO)
[InitializeOnLoad]
public class MicroSplatVegetationStudio : FeatureDescriptor
{
public override string ModuleName()
{
return "Vegetation Studio";
}
public enum DefineFeature
{
_VSGRASSMAP,
_VSSHADOWMAP,
_VSSHADOWTAPNONE,
_VSSHADOWTAPLOW,
_VSSHADOWTAPMEDIUM,
_VSSHADOWTAPHIGH,
kNumFeatures,
}
public enum ShadowTapCount
{
None,
Low,
Medium,
High,
}
public bool grassMap;
public bool shadowMap;
public ShadowTapCount shadowTapCount = ShadowTapCount.Medium;
public TextAsset propsGrassMap;
public TextAsset funcGrassMap;
public TextAsset propsShadowMap;
public TextAsset funcShadowMap;
public TextAsset cbufferGrassMap;
public TextAsset cbufferShadowMap;
GUIContent CShaderGrassMap = new GUIContent("Vegetation Studio GrassMap", "Enable texturing of distant grasses");
GUIContent CShaderShadowMap = new GUIContent("Vegetation Studio ShadowMap", "Enable distance shadows for trees");
GUIContent CShaderTapCount = new GUIContent("Shadow Map Quality", "Higher quality gives smoother shadows in the distance");
// Can we template these somehow?
public static string GetFeatureName(DefineFeature feature)
{
return System.Enum.GetName(typeof(DefineFeature), feature);
}
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)
{
grassMap = EditorGUILayout.Toggle(CShaderGrassMap, grassMap);
shadowMap = EditorGUILayout.Toggle(CShaderShadowMap, shadowMap);
if (shadowMap)
{
EditorGUI.indentLevel++;
shadowTapCount = (ShadowTapCount)EditorGUILayout.EnumPopup(CShaderTapCount, shadowTapCount);
EditorGUI.indentLevel--;
}
}
GUIContent CShaderTint = new GUIContent("Grass Mask Tint", "Tint the grass overlay color, or reduce it's overall effect with the alpha");
//GUIContent CShadowMap = new GUIContent("Shadow Map", "Shadow Map for distant terrain");
public override void DrawShaderGUI(MicroSplatShaderGUI shaderGUI, MicroSplatKeywords keywords, Material mat, MaterialEditor materialEditor, MaterialProperty[] props)
{
if ((grassMap || shadowMap) && MicroSplatUtilities.DrawRollup("Vegetation Studio"))
{
if (grassMap && mat.HasProperty("_VSTint"))
{
EditorGUI.BeginChangeCheck();
var c = mat.GetColor("_VSTint");
c = EditorGUILayout.ColorField(CShaderTint, c);
if (EditorGUI.EndChangeCheck())
{
mat.SetColor("_VSTint", c);
EditorUtility.SetDirty(mat);
}
}
if (shadowMap && mat.HasProperty("_VSShadowMap"))
{
var offsetProp = shaderGUI.FindProp("_VSShadowMapOffsetStrength", props);
Vector4 v = offsetProp.vectorValue;
EditorGUI.BeginChangeCheck();
//v.x = EditorGUILayout.FloatField("Offset", v.x);
v.y = EditorGUILayout.Slider("Min Tree Height", v.y, 0, 1.0f);
v.z = EditorGUILayout.Slider("Shadow Strength", v.z, 0, 1.0f);
v.w = EditorGUILayout.Slider("Shadow Ambient", v.w, 0, 1.0f);
if (EditorGUI.EndChangeCheck())
{
offsetProp.vectorValue = v;
}
}
}
}
public override void InitCompiler(string[] paths)
{
for (int i = 0; i < paths.Length; ++i)
{
string p = paths[i];
if (p.EndsWith("microsplat_properties_vsgrassmap.txt"))
{
propsGrassMap = AssetDatabase.LoadAssetAtPath<TextAsset>(p);
}
if (p.EndsWith("microsplat_func_vsgrassmap.txt"))
{
funcGrassMap = AssetDatabase.LoadAssetAtPath<TextAsset>(p);
}
if (p.EndsWith("microsplat_properties_vsshadowmap.txt"))
{
propsShadowMap = AssetDatabase.LoadAssetAtPath<TextAsset>(p);
}
if (p.EndsWith("microsplat_func_vsshadowmap.txt"))
{
funcShadowMap = AssetDatabase.LoadAssetAtPath<TextAsset>(p);
}
if (p.EndsWith ("microsplat_cbuffer_vsshadowmap.txt"))
{
cbufferShadowMap = AssetDatabase.LoadAssetAtPath<TextAsset> (p);
}
if (p.EndsWith ("microsplat_cbuffer_vsgrassmap.txt"))
{
cbufferGrassMap = AssetDatabase.LoadAssetAtPath<TextAsset> (p);
}
}
}
public override void WriteProperties(string[] features, System.Text.StringBuilder sb)
{
if (grassMap)
{
sb.Append(propsGrassMap.text);
}
if (shadowMap)
{
sb.Append(propsShadowMap.text);
}
}
public override void ComputeSampleCounts(string[] features, ref int arraySampleCount, ref int textureSampleCount, ref int maxSamples, ref int tessellationSamples, ref int depTexReadLevel)
{
if (grassMap)
{
textureSampleCount++;
}
if (shadowMap)
{
textureSampleCount += ((int)shadowTapCount);
}
}
public override string[] Pack()
{
List<string> features = new List<string>();
if (grassMap)
{
features.Add(GetFeatureName(DefineFeature._VSGRASSMAP));
}
if (shadowMap)
{
features.Add(GetFeatureName(DefineFeature._VSSHADOWMAP));
switch (shadowTapCount)
{
case ShadowTapCount.None:
features.Add(GetFeatureName(DefineFeature._VSSHADOWTAPNONE));
break;
case ShadowTapCount.Low:
features.Add(GetFeatureName(DefineFeature._VSSHADOWTAPLOW));
break;
case ShadowTapCount.Medium:
features.Add(GetFeatureName(DefineFeature._VSSHADOWTAPMEDIUM));
break;
case ShadowTapCount.High:
features.Add(GetFeatureName(DefineFeature._VSSHADOWTAPHIGH));
break;
}
}
return features.ToArray();
}
public override void WritePerMaterialCBuffer (string [] features, StringBuilder sb)
{
if (grassMap)
{
sb.AppendLine (cbufferGrassMap.text);
}
if (shadowMap)
{
sb.AppendLine (cbufferShadowMap.text);
}
}
public override void WriteFunctions(string[] features, System.Text.StringBuilder sb)
{
if (grassMap)
{
sb.AppendLine(funcGrassMap.text);
}
if (shadowMap)
{
sb.AppendLine(funcShadowMap.text);
}
}
public override void Unpack(string[] keywords)
{
grassMap = HasFeature(keywords, DefineFeature._VSGRASSMAP);
shadowMap = HasFeature(keywords, DefineFeature._VSSHADOWMAP);
shadowTapCount = ShadowTapCount.Medium;
if (HasFeature(keywords, DefineFeature._VSSHADOWTAPNONE))
{
shadowTapCount = ShadowTapCount.None;
}
else if (HasFeature(keywords, DefineFeature._VSSHADOWTAPLOW))
{
shadowTapCount = ShadowTapCount.Low;
}
else if (HasFeature(keywords, DefineFeature._VSSHADOWTAPHIGH))
{
shadowTapCount = ShadowTapCount.High;
}
}
}
#endif
}

View File

@@ -0,0 +1,4 @@
float4 _VSGrassFade;
half4 _VSTint;

View File

@@ -0,0 +1,8 @@

float4 _VSShadowMap_TexelSize;
float4 _VSShadowMapFadeScale;
float4 _VSShadowMapOffsetStrength;
float4 gVSSunSettings;

View File

@@ -0,0 +1,18 @@
sampler2D _VSGrassMap;
// no per tex is faster, just final value.
void VSGrassTexture(inout half3 albedo, Config config, float camDist)
{
#if _VSGRASSMAP
half4 tex = tex2D(_VSGrassMap, config.uv);
half3 tint = _VSTint.rgb;
#ifdef UNITY_COLORSPACE_GAMMA
tint = GammaToLinearSpace(_VSTint.rgb);
#endif
tex *= half4(tint, _VSTint.a) * 2;
float fade = saturate((camDist - _VSGrassFade.x) / max(_VSGrassFade.y, 0.01));
albedo = lerp(albedo, BlendMult2X(albedo, tex.rgb), saturate(fade * tex.a));
#endif
}

View File

@@ -0,0 +1,64 @@

sampler2D _VSShadowMap;
void VSShadowTexture(inout MicroSplatLayer o, Input i, Config config, float camDist)
{
#if _VSSHADOWMAP
#if _VSSHADOWTAPNONE
const int taps = 1;
#elif _VSSHADOWTAPLOW
const int taps = 4;
#elif _VSSHADOWTAPHIGH
const int taps = 16;
#else
const int taps = 8; // medium
#endif
const int maxTreeHeight = 64;
// start at light and raycast back
// offset the UVs to the end and subdivide the UV offset
float3 tang = mul( GetTBN(i), gVSSunDirection.xyz ).xyz;
float2 uvOffset = tang.xy * _VSShadowMap_TexelSize.xy * maxTreeHeight;
float2 uv = config.uv + uvOffset;
uvOffset /= taps;
// we move down/back along the ray
float heightStep = (1.0 / (float)taps);
float currentHeight = 1;
float maxHeight = 0;
// do taps.
float dist = 1;
for (int i = 0; i < taps; ++i)
{
uv -= uvOffset;
currentHeight -= heightStep;
half4 tex = tex2D(_VSShadowMap, uv);
half top = tex.r;
half bottom = 0.13; // hard coded min tree hight for now, use tex.g to see issue with dynamic.
if (top > currentHeight && bottom < currentHeight)
{
maxHeight = 1;
dist = i * heightStep;
}
}
if (maxHeight > 0)
{
float fade = saturate((camDist - _VSShadowMapFadeScale.x) / max(_VSShadowMapFadeScale.y, 0.01));
half shadow = fade * _VSShadowMapOffsetStrength.z * dist;
shadow *= saturate(gVSSunDirection.w);
o.Occlusion = saturate(o.Occlusion - shadow);
o.Albedo = saturate(o.Albedo - shadow * _VSShadowMapOffsetStrength.w * gVSSunSettings.x * o.Albedo);
o.Smoothness = saturate(o.Smoothness - shadow);
o.Normal.xy *= (1-shadow);
}
#endif
}

View File

@@ -0,0 +1,4 @@
_VSGrassMap("VS Grass Map", 2D) = "white" {}
_VSTint("VS Tint", Color) = (0.5,0.5,0.5,1)
//global//_VSGrassFade("VS Fade", Vector) = (50, 150, 1, 1)

View File

@@ -0,0 +1,4 @@
_VSShadowMap("VS Shadow Map", 2D) = "black" {}
_VSShadowMapOffsetStrength("VS Shadow Offset/Strength", Vector) = (16,0.13,0.4,0.3)
//_VSShadowMapFadeScale("VS Fade and UV Scale", Vector) = (50, 150, 1.1, 1.1)