新插件

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,9 @@
fileFormatVersion: 2
guid: 2fc4d33dc55024c64865ce322cf2bedb
folderAsset: yes
timeCreated: 1499097806
licenseType: Store
DefaultImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,51 @@
Shader "Hidden/MicroSplat/ExtractHeight"
{
Properties
{
_MainTex ("Texture", 2DArray) = "white" {}
}
SubShader
{
// No culling or depth
Cull Off ZWrite Off ZTest Always
Pass
{
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;
};
v2f vert (appdata v)
{
v2f o;
o.vertex = UnityObjectToClipPos(v.vertex);
o.uv = v.uv;
return o;
}
UNITY_DECLARE_TEX2DARRAY(_MainTex);
int index;
fixed4 frag (v2f i) : SV_Target
{
float h = UNITY_SAMPLE_TEX2DARRAY(_MainTex, float3(i.uv, index)).a;
return fixed4(h,h,h,h);
}
ENDCG
}
}
}

View File

@@ -0,0 +1,9 @@
fileFormatVersion: 2
guid: 5db7d3ad4fc4e466b90bded5b823fd20
timeCreated: 1503023234
licenseType: Store
ShaderImporter:
defaultTextures: []
userData:
assetBundleName:
assetBundleVariant:

View File

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

View File

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

View File

@@ -0,0 +1,551 @@
//////////////////////////////////////////////////////
// MicroSplat
// Copyright (c) Jason Booth
//////////////////////////////////////////////////////
using UnityEngine;
using System.Collections;
using UnityEditor;
using UnityEditor.Callbacks;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace JBooth.MicroSplat
{
#if __MICROSPLAT__
[InitializeOnLoad]
public class MicroSplatTessellation : FeatureDescriptor
{
const string sGlobalTess = "__MICROSPLAT_TESSELLATION__";
static MicroSplatTessellation()
{
MicroSplatDefines.InitDefine(sGlobalTess);
}
[PostProcessSceneAttribute (0)]
public static void OnPostprocessScene()
{
MicroSplatDefines.InitDefine(sGlobalTess);
}
public override string ModuleName()
{
return "Tessellation & Parallax";
}
public override string GetHelpPath ()
{
return "https://docs.google.com/document/d/1F94JgR2y8zyaxJLVQ4K77tXzRGwfeLJyyX5kgD_BoTU/edit?usp=sharing";
}
public enum DefineFeature
{
_TESSDISTANCE,
_PERTEXTESSDISPLACE,
_PERTEXTESSUPBIAS,
_PERTEXTESSOFFSET,
_PERTEXTESSMIPLEVEL,
_PERTEXTESSSHAPING,
_PARALLAX,
_POM,
_PERTEXPARALLAX,
_TESSFADEHOLES,
_TESSONLYDISPLACE,
kNumFeatures,
}
public enum ParallaxMode
{
None = 0,
Offset,
POM
}
public enum DisplacementMode
{
None = 0,
OnlyDisplacement,
Tessellation
}
public bool isTessellated = false;
public bool isDisplaced = false;
public DisplacementMode displacementMode = DisplacementMode.None;
public bool perTexDisplace;
public bool perTexUpBias;
public bool perTexOffset;
public ParallaxMode parallax = ParallaxMode.None;
public bool perTexParallax;
public bool perTexShaping;
public bool perTexMipLevel;
public bool fadeNearHoles;
public TextAsset properties_tess;
public TextAsset func_tess;
public TextAsset func_parallax;
public TextAsset func_pom;
public TextAsset cbuffer_tess;
public TextAsset cbuffer_parallax;
public TextAsset cbuffer_pom;
GUIContent CShaderDisplacementOptions = new GUIContent("Displacement Mode", "Displace Original or Tessellated vertices?");
GUIContent CTessUpBias = new GUIContent("Up Bias", "How much to bias displacement along the normal, or up");
GUIContent CTessDisplacement = new GUIContent("Displacement", "How far to displace the surface from it's original position");
GUIContent CTessMipBias = new GUIContent("Mip Bias", "Allows you to use lower mip map levels for displacement, which often produces a better looking result and is slightly faster");
GUIContent CTessShaping = new GUIContent("Shaping", "A seperate contrast blend for tessellation, lower values tend to look best");
GUIContent CTessMinDistance = new GUIContent("Min Distance", "Distance in which distance based tessellation is at maximum. Also acts as the distance in which tessellation amount begins to fade when fade tessellation is on");
GUIContent CTessMaxDistance = new GUIContent("Max Distance", "Distance in which distance based tessellation is at minimum. Also acts as the distance in which tessellation amount begins is completely faded when fade tessellation is on");
GUIContent CTessTessellation = new GUIContent("Tessellation", "How much to tesselate the mesh at min distance, lower values are more performant");
GUIContent CParallax = new GUIContent("Parallax", "Parallax mapping, which does an extra height map lookup to create a deeper looking texture effect. Offset requires one extra sample, POM uses many but creates a better effect");
// Can we template these somehow?
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 bool RequiresShaderModel46()
{
return isTessellated;
}
public override int CompileSortOrder()
{
return 1; // after most stuff, so variables, etc, can all be declared..
}
public override void DrawFeatureGUI(MicroSplatKeywords keywords)
{
if (!keywords.IsKeywordEnabled ("_MICROVERTEXMESH"))
{
displacementMode = (DisplacementMode)EditorGUILayout.EnumPopup(CShaderDisplacementOptions, displacementMode);
switch(displacementMode)
{
case DisplacementMode.None:
isTessellated = isDisplaced = false;
break;
case DisplacementMode.OnlyDisplacement:
isTessellated = false; isDisplaced = true; break;
case DisplacementMode.Tessellation:
isTessellated = true; isDisplaced = false; break;
}
fadeNearHoles = EditorGUILayout.Toggle(new GUIContent("Fade Near Holes", "Fades tessellation around terrain holes"), fadeNearHoles);
}
parallax = (ParallaxMode)EditorGUILayout.EnumPopup(CParallax, parallax);
}
public override void DrawShaderGUI(MicroSplatShaderGUI shaderGUI, MicroSplatKeywords keywords, Material mat, MaterialEditor materialEditor, MaterialProperty[] props)
{
if ((isTessellated || isDisplaced) && mat.HasProperty("_TessData1") && MicroSplatUtilities.DrawRollup("Tessellation"))
{
var td1 = shaderGUI.FindProp("_TessData1", props);
var td2 = shaderGUI.FindProp("_TessData2", props);
EditorGUI.BeginChangeCheck();
var td1v = td1.vectorValue;
var td2v = td2.vectorValue;
td1v.y = EditorGUILayout.Slider(CTessDisplacement, td1v.y, 0, 3);
td1v.z = (float)EditorGUILayout.IntSlider(CTessMipBias, (int)td1v.z, 0, 6);
td2v.z = 1.0f - (float)EditorGUILayout.Slider(CTessShaping, 1.0f - td2v.z, 0.0f, 0.999f);
if (!perTexUpBias)
{
td2v.w = (float)EditorGUILayout.Slider(CTessUpBias, td2v.w, 0.0f, 1);
}
if (isTessellated)
{
td1v.x = EditorGUILayout.Slider(CTessTessellation, td1v.x, 1, 32);
td2v.x = EditorGUILayout.FloatField(CTessMinDistance, td2v.x);
td2v.y = EditorGUILayout.FloatField(CTessMaxDistance, td2v.y);
}
if (EditorGUI.EndChangeCheck())
{
td1.vectorValue = td1v;
td2.vectorValue = td2v;
}
}
if (parallax == ParallaxMode.Offset && MicroSplatUtilities.DrawRollup("Parallax") && mat.HasProperty("_ParallaxParams"))
{
EditorGUI.BeginChangeCheck();
var parprop = shaderGUI.FindProp("_ParallaxParams", props);
Vector4 vec = parprop.vectorValue;
vec.x = EditorGUILayout.Slider("Parallax Height", vec.x, 0.0f, 0.12f);
vec.y = EditorGUILayout.FloatField("Parallax Fade Start", vec.y);
vec.z = EditorGUILayout.FloatField("Parallax Fade Distance", vec.z);
if (EditorGUI.EndChangeCheck())
{
parprop.vectorValue = vec;
}
}
if (parallax == ParallaxMode.POM && MicroSplatUtilities.DrawRollup("POM") && mat.HasProperty("_POMParams"))
{
EditorGUI.BeginChangeCheck();
var parprop = shaderGUI.FindProp("_POMParams", props);
Vector4 vec = parprop.vectorValue;
vec.x = EditorGUILayout.Slider("POM Height", vec.x, 0.0f, 0.4f);
vec.y = EditorGUILayout.FloatField("POM Fade Start", vec.y);
vec.z = EditorGUILayout.FloatField("POM Fade Distance", vec.z);
vec.w = (int)EditorGUILayout.IntSlider("Steps", (int)vec.w, 2, 32);
if (EditorGUI.EndChangeCheck())
{
parprop.vectorValue = vec;
}
}
}
public override void InitCompiler(string[] paths)
{
for (int i = 0; i < paths.Length; ++i)
{
string p = paths[i];
if (p.EndsWith("microsplat_properties_tess.txt"))
{
properties_tess = AssetDatabase.LoadAssetAtPath<TextAsset>(p);
}
if (p.EndsWith("microsplat_func_tess.txt"))
{
func_tess = AssetDatabase.LoadAssetAtPath<TextAsset>(p);
}
if (p.EndsWith("microsplat_cbuffer_tess.txt"))
{
cbuffer_tess = AssetDatabase.LoadAssetAtPath<TextAsset>(p);
}
if (p.EndsWith("microsplat_func_parallax.txt"))
{
func_parallax = AssetDatabase.LoadAssetAtPath<TextAsset>(p);
}
if (p.EndsWith("microsplat_func_pom.txt"))
{
func_pom = AssetDatabase.LoadAssetAtPath<TextAsset>(p);
}
if (p.EndsWith("microsplat_cbuffer_parallax.txt"))
{
cbuffer_parallax = AssetDatabase.LoadAssetAtPath<TextAsset>(p);
}
if (p.EndsWith("microsplat_cbuffer_pom.txt"))
{
cbuffer_pom = AssetDatabase.LoadAssetAtPath<TextAsset>(p);
}
}
}
public override void WriteProperties(string[] features, System.Text.StringBuilder sb)
{
if (isTessellated || isDisplaced)
{
sb.Append(properties_tess.text);
}
if (parallax == ParallaxMode.Offset)
{
sb.AppendLine(" _ParallaxParams(\"Parallax Height\", Vector) = (0.08, 30, 30, 0)");
}
if (parallax == ParallaxMode.POM)
{
sb.AppendLine(" _POMParams(\"POM Params\", Vector) = (0.08, 30, 30, 8)");
}
}
public override void ComputeSampleCounts(string[] features, ref int arraySampleCount, ref int textureSampleCount, ref int maxSamples, ref int tessellationSamples, ref int depTexReadLevel)
{
if (parallax == ParallaxMode.Offset)
{
arraySampleCount += 2;
if (!features.Contains<string>(MicroSplatBaseFeatures.GetFeatureName(MicroSplatBaseFeatures.DefineFeature._MAX2LAYER)))
{
arraySampleCount += 1;
}
if (!features.Contains<string>(MicroSplatBaseFeatures.GetFeatureName(MicroSplatBaseFeatures.DefineFeature._MAX3LAYER)))
{
arraySampleCount += 1;
}
}
if (parallax == ParallaxMode.POM)
{
arraySampleCount += 2 * 8; // would need to read this from the material
}
if (isTessellated)
{
if (features.Contains<string>(MicroSplatBaseFeatures.GetFeatureName(MicroSplatBaseFeatures.DefineFeature._MAX2LAYER)))
{
tessellationSamples += 2;
}
else if (features.Contains<string>(MicroSplatBaseFeatures.GetFeatureName(MicroSplatBaseFeatures.DefineFeature._MAX3LAYER)))
{
tessellationSamples += 3;
}
else
{
tessellationSamples += 4;
}
textureSampleCount += 4; // control textures
}
}
public override string[] Pack()
{
List<string> features = new List<string>();
if (isTessellated) features.Add(GetFeatureName(DefineFeature._TESSDISTANCE));
if (isDisplaced) features.Add(GetFeatureName(DefineFeature._TESSONLYDISPLACE));
if (isTessellated || isDisplaced)
{
if (perTexDisplace)
{
features.Add(GetFeatureName(DefineFeature._PERTEXTESSDISPLACE));
}
if (perTexUpBias)
{
features.Add(GetFeatureName(DefineFeature._PERTEXTESSUPBIAS));
}
if (perTexOffset)
{
features.Add(GetFeatureName(DefineFeature._PERTEXTESSOFFSET));
}
if (perTexMipLevel)
{
features.Add(GetFeatureName(DefineFeature._PERTEXTESSMIPLEVEL));
}
if (perTexShaping)
{
features.Add(GetFeatureName(DefineFeature._PERTEXTESSSHAPING));
}
if (fadeNearHoles)
{
features.Add(GetFeatureName(DefineFeature._TESSFADEHOLES));
}
}
if (parallax != ParallaxMode.None)
{
if (parallax == ParallaxMode.Offset)
{
features.Add(GetFeatureName(DefineFeature._PARALLAX));
if (perTexParallax)
{
features.Add(GetFeatureName(DefineFeature._PERTEXPARALLAX));
}
}
if (parallax == ParallaxMode.POM)
{
features.Add(GetFeatureName(DefineFeature._POM));
if (perTexParallax)
{
features.Add(GetFeatureName(DefineFeature._PERTEXPARALLAX));
}
}
}
return features.ToArray();
}
public override void WritePerMaterialCBuffer (string[] features, StringBuilder sb)
{
if (isTessellated || isDisplaced)
{
sb.AppendLine(cbuffer_tess.text);
}
if (parallax == ParallaxMode.Offset)
{
sb.AppendLine(cbuffer_parallax.text);
}
if (parallax == ParallaxMode.POM)
{
sb.AppendLine(cbuffer_pom.text);
}
}
public override void WriteFunctions(string [] features, System.Text.StringBuilder sb)
{
if (isTessellated || isDisplaced)
{
sb.AppendLine(func_tess.text);
}
if (parallax == ParallaxMode.Offset)
{
sb.AppendLine(func_parallax.text);
}
if (parallax == ParallaxMode.POM)
{
sb.AppendLine(func_pom.text);
}
}
public override void WriteAfterVetrexFunctions(StringBuilder sb)
{
}
public override void Unpack(string[] keywords)
{
isTessellated = (HasFeature(keywords, DefineFeature._TESSDISTANCE));
isDisplaced = (HasFeature(keywords, DefineFeature._TESSONLYDISPLACE));
displacementMode = isTessellated ? DisplacementMode.Tessellation : isDisplaced ? DisplacementMode.OnlyDisplacement : DisplacementMode.None;
perTexDisplace = (HasFeature(keywords, DefineFeature._PERTEXTESSDISPLACE));
perTexUpBias = (HasFeature(keywords, DefineFeature._PERTEXTESSUPBIAS));
perTexOffset = (HasFeature(keywords, DefineFeature._PERTEXTESSOFFSET));
perTexShaping = (HasFeature(keywords, DefineFeature._PERTEXTESSSHAPING));
perTexMipLevel = (HasFeature(keywords, DefineFeature._PERTEXTESSMIPLEVEL));
fadeNearHoles = (HasFeature(keywords, DefineFeature._TESSFADEHOLES));
if (HasFeature(keywords, DefineFeature._PARALLAX))
{
parallax = ParallaxMode.Offset;
perTexParallax = HasFeature(keywords, DefineFeature._PERTEXPARALLAX);
}
if (HasFeature(keywords, DefineFeature._POM))
{
parallax = ParallaxMode.POM;
perTexParallax = HasFeature(keywords, DefineFeature._PERTEXPARALLAX);
}
}
// for combined tessellation
public static float IdealOffset(Texture2D src, int channel)
{
RenderTexture rt = new RenderTexture(128, 128, 0, RenderTextureFormat.ARGB32);
Graphics.Blit(src, rt);
RenderTexture.active = rt;
Texture2D tex = new Texture2D(128, 128);
tex.ReadPixels(new Rect(0, 0, 128, 128), 0, 0);
tex.Apply();
RenderTexture.active = null;
rt.Release();
GameObject.DestroyImmediate(rt);
var colors = tex.GetPixels();
GameObject.DestroyImmediate(tex);
float h = 0;
for (int i = 0; i < colors.Length; ++i)
{
h += colors [i] [channel];
}
h /= (float)colors.Length;
return -h;
}
float IdealOffset(Texture2DArray ta, int index)
{
Material mat = new Material(Shader.Find("Hidden/MicroSplat/ExtractHeight"));
mat.SetInt("index", index);
RenderTexture rt = new RenderTexture(128, 128, 0, RenderTextureFormat.ARGB32);
Graphics.Blit(ta, rt, mat);
RenderTexture.active = rt;
Texture2D tex = new Texture2D(128, 128);
tex.ReadPixels(new Rect(0, 0, 128, 128), 0, 0);
tex.Apply();
RenderTexture.active = null;
rt.Release();
GameObject.DestroyImmediate(rt);
GameObject.DestroyImmediate(mat);
var colors = tex.GetPixels();
GameObject.DestroyImmediate(tex);
float h = 0;
for (int i = 0; i < colors.Length; ++i)
{
h += colors[i].a;
}
h /= (float)colors.Length;
return -h;
}
static GUIContent CPerTexDisplace = new GUIContent("Displacement", "Scale for tessellation displacement");
static GUIContent CPerTexUpBias = new GUIContent("Tess Up Bias", "Bias displacement from normal angle to up");
static GUIContent CPerTexOffset = new GUIContent("Tess Offset", "Offset displacement center, to push this texture up and down along the displacement vector");
static GUIContent CPerTexMipLevel = new GUIContent("Tess Mip Bias", "Biases mip map selection in tessellation stage");
static GUIContent CPerTexShaping = new GUIContent("Tess Shaping", "Adjusts tessellation shaping for individual texture");
static GUIContent CPerTexParallax = new GUIContent("Parallax Height", "Parallax height for given texture");
static GUIContent CComputeIdeal = new GUIContent("Compute Ideal Offset", "Compute per-texture offsets based on the texture data - the idea is to get the majority of the terrain as close to the collider as possible");
static GUIContent CComputeIdealAll = new GUIContent("Compute All", "Compute per-texture offsets for all textures based on the texture data - the idea is to get the majority of the terrain as close to the collider as possible");
public override void DrawPerTextureGUI(int index, MicroSplatKeywords keywords, Material mat, MicroSplatPropData propData)
{
if (isTessellated || isDisplaced)
{
InitPropData(6, propData, new Color(1.0f, 0.0f, 0.0f, 0.5f)); // displace, up, offset
perTexDisplace = DrawPerTexFloatSlider(index, 6, GetFeatureName(DefineFeature._PERTEXTESSDISPLACE),
keywords, propData, Channel.R, CPerTexDisplace, 0, 2);
perTexUpBias = DrawPerTexFloatSlider(index, 6, GetFeatureName(DefineFeature._PERTEXTESSUPBIAS),
keywords, propData, Channel.G, CPerTexUpBias, 0, 1);
perTexOffset = DrawPerTexFloatSlider(index, 6, GetFeatureName(DefineFeature._PERTEXTESSOFFSET),
keywords, propData, Channel.B, CPerTexOffset, -1, 1);
perTexMipLevel = DrawPerTexFloatSlider(index, 4, GetFeatureName(DefineFeature._PERTEXTESSMIPLEVEL),
keywords, propData, Channel.A, CPerTexMipLevel, 0, 6);
perTexShaping = DrawPerTexFloatSlider(index, 14, GetFeatureName(DefineFeature._PERTEXTESSSHAPING),
keywords, propData, Channel.A, CPerTexShaping, 0.001f, 0.999f);
if (perTexOffset)
{
EditorGUILayout.BeginHorizontal();
if (GUILayout.Button(CComputeIdeal))
{
float h = IdealOffset(mat.GetTexture("_Diffuse") as Texture2DArray, index);
propData.SetValue(index, 6, (int)Channel.B, h);
AssetDatabase.Refresh();
}
if (GUILayout.Button(CComputeIdealAll))
{
var ta = mat.GetTexture("_Diffuse") as Texture2DArray;
for (int i = 0; i < 16; ++i)
{
float h = IdealOffset(ta, i);
propData.SetValue(i, 6, (int)Channel.B, h);
}
}
EditorGUILayout.EndHorizontal();
}
}
if (parallax == ParallaxMode.Offset || parallax == ParallaxMode.POM)
{
perTexParallax = DrawPerTexFloatSlider(index, 6, GetFeatureName(DefineFeature._PERTEXPARALLAX),
keywords, propData, Channel.A, CPerTexParallax, 0, 1);
}
}
}
#endif
}

View File

@@ -0,0 +1,12 @@
fileFormatVersion: 2
guid: ed512ce26986141bab89d510705f1b4e
timeCreated: 1499198412
licenseType: Store
MonoImporter:
serializedVersion: 2
defaultReferences: []
executionOrder: 0
icon: {instanceID: 0}
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,4 @@
half3 _ParallaxParams;

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: d99f4ee251f5f4cf3bbc8e9f8e9a5094
timeCreated: 1575837871
licenseType: Store
TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,3 @@
half4 _POMParams; // strength, fade beging, fade end, steps

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 40acab2f015a64de3adb6d5730544e2b
timeCreated: 1575837871
licenseType: Store
TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,11 @@
half4 _TessData1; // tess, displacement, mipBias, edge length
half4 _TessData2; // distance min, max, shaping, upbias
#if _MESHCOMBINEDHEIGHT || _MESHCOMBINEDPACKEDMAP
half _MeshCombineTessBlend;
#endif

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 6458337dc2d274f0381c6379575c98fa
timeCreated: 1575837871
licenseType: Store
TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,60 @@
float2 MSParallaxOffset( half h, half height, half3 viewDir )
{
h = h * height - height/2.0;
float3 v = normalize(viewDir);
v.z += 0.42;
return h * (v.xy / v.z);
}
void DoParallax(Input i, half h, inout Config c, inout TriplanarConfig tc, inout RawSamples s, half4 weights, float camDist)
{
float fade = (1 - saturate((camDist - _ParallaxParams.y) / max(_ParallaxParams.z, 0.01)));
float2 offset = MSParallaxOffset(h, _ParallaxParams.x * fade, i.viewDir);
#if !_TRIPLANAR
#if _PERTEXPARALLAX
SAMPLE_PER_TEX(ptp, 6.5, c, 0.0);
c.uv0.xy += offset * ptp0.a;
c.uv1.xy += offset * ptp1.a;
c.uv2.xy += offset * ptp2.a;
c.uv3.xy += offset * ptp3.a;
#else
c.uv0.xy += offset;
c.uv1.xy += offset;
c.uv2.xy += offset;
c.uv3.xy += offset;
#endif
#else
#if _PERTEXPARALLAX
SAMPLE_PER_TEX(ptp, 6.5, c, 0.0);
tc.uv0[0].xy += offset * ptp0.a;
tc.uv0[1].xy += offset * ptp0.a;
tc.uv0[2].xy += offset * ptp0.a;
tc.uv1[0].xy += offset * ptp1.a;
tc.uv1[1].xy += offset * ptp1.a;
tc.uv1[2].xy += offset * ptp1.a;
tc.uv2[0].xy += offset * ptp2.a;
tc.uv2[1].xy += offset * ptp2.a;
tc.uv2[2].xy += offset * ptp2.a;
tc.uv3[0].xy += offset * ptp3.a;
tc.uv3[1].xy += offset * ptp3.a;
tc.uv3[2].xy += offset * ptp3.a;
#else
tc.uv0[0].xy += offset;
tc.uv0[1].xy += offset;
tc.uv0[2].xy += offset;
tc.uv1[0].xy += offset;
tc.uv1[1].xy += offset;
tc.uv1[2].xy += offset;
tc.uv2[0].xy += offset;
tc.uv2[1].xy += offset;
tc.uv2[2].xy += offset;
tc.uv3[0].xy += offset;
tc.uv3[1].xy += offset;
tc.uv3[2].xy += offset;
#endif
#endif
}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 22dbee0bd5d714ca8a0331a42559c8f4
timeCreated: 1500349075
licenseType: Store
TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,282 @@
#if _TRIPLANAR
#define OffsetUVChannel(config, tc, offset, channel) tc.uv##channel[0].xy += offset; tc.uv##channel[1].xy += offset; tc.uv##channel[2].xy += offset
#else
#define OffsetUVChannel(config, tc, offset, channel) config.uv##channel.xy += offset
#endif
void OffsetUVs(inout Config c, inout TriplanarConfig tc, float2 offset)
{
OffsetUVChannel(c, tc, offset, 0);
OffsetUVChannel(c, tc, offset, 1);
OffsetUVChannel(c, tc, offset, 2);
OffsetUVChannel(c, tc, offset, 3);
}
half SampleHeightsPOM0(Config config, TriplanarConfig tc, MIPFORMAT mipLevel, float2 offset, half4 ptHeight)
{
OffsetUVChannel(config, tc, offset, 0);
float height = 0;
#if _TRIPLANAR
#if _USEGRADMIP
float4 d0 = mipLevel.d0;
float4 d1 = mipLevel.d1;
float4 d2 = mipLevel.d2;
#elif _USELODMIP
float d0 = mipLevel.x;
float d1 = mipLevel.y;
float d2 = mipLevel.z;
#else
MIPFORMAT d0 = mipLevel;
MIPFORMAT d1 = mipLevel;
MIPFORMAT d2 = mipLevel;
#endif
{
half a0 = MICROSPLAT_SAMPLE_DIFFUSE(tc.uv0[0], config.cluster0, d0).a;
half a1 = MICROSPLAT_SAMPLE_DIFFUSE(tc.uv0[1], config.cluster0, d1).a;
half a2 = MICROSPLAT_SAMPLE_DIFFUSE(tc.uv0[2], config.cluster0, d2).a;
half3 bf = tc.pN0;
height = a0 * bf.x + a1 * bf.y + a2 * bf.z;
}
#else
height = MICROSPLAT_SAMPLE_DIFFUSE(config.uv0, config.cluster0, mipLevel).a;
#endif
#if _PERTEXHEIGHTOFFSET || _PERTEXHEIGHTCONTRAST
#if _PERTEXHEIGHTOFFSET
height = saturate(height + ptHeight.b - 1);
#endif
#if _PERTEXHEIGHTCONTRAST
height = saturate(pow(height + 0.5, ptHeight.a) - 0.5);
#endif
#endif
return height;
}
half SampleHeightsPOM1(Config config, TriplanarConfig tc, MIPFORMAT mipLevel, float2 offset, half4 ptHeight)
{
OffsetUVChannel(config, tc, offset, 1);
float height = 0;
#if _TRIPLANAR
#if _USEGRADMIP
float4 d0 = mipLevel.d0;
float4 d1 = mipLevel.d1;
float4 d2 = mipLevel.d2;
#elif _USELODMIP
float d0 = mipLevel.x;
float d1 = mipLevel.y;
float d2 = mipLevel.z;
#else
MIPFORMAT d0 = mipLevel;
MIPFORMAT d1 = mipLevel;
MIPFORMAT d2 = mipLevel;
#endif
{
half a0 = MICROSPLAT_SAMPLE_DIFFUSE(tc.uv1[0], config.cluster1, d0).a;
half a1 = MICROSPLAT_SAMPLE_DIFFUSE(tc.uv1[1], config.cluster1, d1).a;
half a2 = MICROSPLAT_SAMPLE_DIFFUSE(tc.uv1[2], config.cluster1, d2).a;
half3 bf = tc.pN0;
height = a0 * bf.x + a1 * bf.y + a2 * bf.z;
}
#else
height = MICROSPLAT_SAMPLE_DIFFUSE(config.uv1, config.cluster1, mipLevel).a;
#endif
#if _PERTEXHEIGHTOFFSET || _PERTEXHEIGHTCONTRAST
#if _PERTEXHEIGHTOFFSET
height = saturate(height+ ptHeight.b - 1);
#endif
#if _PERTEXHEIGHTCONTRAST
height = saturate(pow(height + 0.5, ptHeight.a) - 0.5);
#endif
#endif
return height;
}
float2 POMLayer0(Config config, TriplanarConfig tc, MIPFORMAT mipLevel, float3 viewDirTan,
int numSteps, float2 texOffsetPerStep, float stepSize, half4 ptData, out float outHeight)
{
// Do a first step before the loop to init all value correctly
float2 texOffsetCurrent = float2(0.0, 0.0);
float prevHeight = SampleHeightsPOM0(config, tc, mipLevel, texOffsetCurrent, ptData);
texOffsetCurrent += texOffsetPerStep;
float currHeight = SampleHeightsPOM0(config, tc, mipLevel, texOffsetCurrent, ptData);
float rayHeight = 1.0 - stepSize; // Start at top less one sample
// Linear search
for (int stepIndex = 0; stepIndex < numSteps; ++stepIndex)
{
if (currHeight > rayHeight)
break;
prevHeight = currHeight;
rayHeight -= stepSize;
texOffsetCurrent += texOffsetPerStep;
currHeight = SampleHeightsPOM0(config, tc, mipLevel, texOffsetCurrent, ptData);
}
// secant search method
float pt0 = rayHeight + stepSize;
float pt1 = rayHeight;
float delta0 = pt0 - prevHeight;
float delta1 = pt1 - currHeight;
float delta;
float2 offset;
for (int i = 0; i < 5; ++i)
{
float intersectionHeight = (pt0 * delta1 - pt1 * delta0) / (delta1 - delta0);
offset = (1 - intersectionHeight) * texOffsetPerStep * numSteps;
currHeight = SampleHeightsPOM0(config, tc, mipLevel, offset, ptData);
delta = intersectionHeight - currHeight;
if (abs(delta) <= 0.01)
break;
// intersectionHeight < currHeight => new lower bounds
if (delta < 0.0)
{
delta1 = delta;
pt1 = intersectionHeight;
}
else
{
delta0 = delta;
pt0 = intersectionHeight;
}
}
outHeight = currHeight;
return offset;
}
float2 POMLayer1(Config config, TriplanarConfig tc, MIPFORMAT mipLevel, float3 viewDirTan,
int numSteps, float2 texOffsetPerStep, float stepSize, half4 ptData, out float outHeight)
{
// Do a first step before the loop to init all value correctly
float2 texOffsetCurrent = float2(0.0, 0.0);
float prevHeight = SampleHeightsPOM1(config, tc, mipLevel, texOffsetCurrent, ptData);
texOffsetCurrent += texOffsetPerStep;
float currHeight = SampleHeightsPOM1(config, tc, mipLevel, texOffsetCurrent, ptData);
float rayHeight = 1.0 - stepSize; // Start at top less one sample
// Linear search
for (int stepIndex = 0; stepIndex < numSteps; ++stepIndex)
{
if (currHeight > rayHeight)
break;
prevHeight = currHeight;
rayHeight -= stepSize;
texOffsetCurrent += texOffsetPerStep;
currHeight = SampleHeightsPOM1(config, tc, mipLevel, texOffsetCurrent, ptData);
}
// secant search method
float pt0 = rayHeight + stepSize;
float pt1 = rayHeight;
float delta0 = pt0 - prevHeight;
float delta1 = pt1 - currHeight;
float delta;
float2 offset;
for (int i = 0; i < 3; ++i)
{
float intersectionHeight = (pt0 * delta1 - pt1 * delta0) / (delta1 - delta0);
offset = (1 - intersectionHeight) * texOffsetPerStep * numSteps;
currHeight = SampleHeightsPOM1(config, tc, mipLevel, offset, ptData);
delta = intersectionHeight - currHeight;
if (abs(delta) <= 0.01)
break;
// intersectionHeight < currHeight => new lower bounds
if (delta < 0.0)
{
delta1 = delta;
pt1 = intersectionHeight;
}
else
{
delta0 = delta;
pt0 = intersectionHeight;
}
}
outHeight = currHeight;
return offset;
}
void DoPOM(Input i, inout Config c, inout TriplanarConfig tc, MIPFORMAT mipLevel,
half4 weights, float camDist, float3 worldNormal)
{
// prefetch heights, so we don't do it every sample
#if _PERTEXHEIGHTOFFSET || _PERTEXHEIGHTCONTRAST
SAMPLE_PER_TEX(ptHeight, 10.5, c, 1);
#else
half4 ptHeight0 = half4(1,1,1,1);
half4 ptHeight1 = half4(1,1,1,1);
#endif
float3 worldView = normalize(_WorldSpaceCameraPos - i.worldPos);
float ndot = dot( worldNormal, worldView);
int numSteps = (int)lerp(4, _POMParams.w, ndot);
float3 viewDirTS = i.viewDir;
float angleFade = viewDirTS.z;
float distFade = 1 - saturate((camDist - _POMParams.y) / _POMParams.z);
float stepSize = 1.0 / (float)numSteps;
float2 parallaxMaxOffsetTS = (viewDirTS.xy / -viewDirTS.z);
float2 texOffsetPerStep = stepSize * parallaxMaxOffsetTS * _POMParams.x * distFade * angleFade;
float outHeight0 = 0;
float outHeight1 = 0;
float2 offset0 = POMLayer0(c, tc, mipLevel, viewDirTS, numSteps, texOffsetPerStep, stepSize, ptHeight0, outHeight0);
float2 offset1 = POMLayer1(c, tc, mipLevel, viewDirTS, numSteps, texOffsetPerStep, stepSize, ptHeight1, outHeight1);
#if _PERTEXPARALLAX
SAMPLE_PER_TEX(ptp, 6.5, c, 0.0);
offset0 *= ptp0.a;
offset1 *= ptp1.a;
#endif
weights.xy = TotalOne(weights.xy);
float l = HeightBlend(outHeight0, outHeight1, 1.0 - weights.x, _Contrast);
float2 offset = lerp(offset0, offset1, l);
OffsetUVs(c, tc, offset);
}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f89da6a581bfa4e74a7cf4e8958a8eac
timeCreated: 1552524285
licenseType: Store
TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,684 @@
#if _DISPLACEMENTDAMPENING
TEXTURE2D(_DisplacementDampening);
#endif
#if _MESHCOMBINEDHEIGHT || _MESHCOMBINEDPACKEDMAP
float SampleMeshCombinedTess(half h, half4 heightWeights, Config config, float mipLevel)
{
float stAlpha = 1;
if (config.uv0.z == _MeshAlphaIndex)
stAlpha = 1 - heightWeights.x;
else if (config.uv1.z == _MeshAlphaIndex)
stAlpha = 1 - heightWeights.y;
else if (config.uv2.z == _MeshAlphaIndex)
stAlpha = 1 - heightWeights.z;
else if (config.uv3.z == _MeshAlphaIndex)
stAlpha = 1 - heightWeights.w;
float2 stuv = config.uv * _StandardUVScaleOffset.xy + _StandardUVScaleOffset.zw;
#if _MESHCOMBINEDPACKEDMAP
half standardHeight = SAMPLE_TEXTURE2D_LOD(_StandardPackedMap, sampler_StandardDiffuse, stuv, mipLevel).b;
#elif _MESHCOMBINEDHEIGHT
half standardHeight = SAMPLE_TEXTURE2D_LOD(_StandardHeight, sampler_StandardDiffuse, stuv, mipLevel).g;
#endif
// offset
standardHeight += _MeshCombineTessOffset;
// weight
standardHeight *= (1-_MeshCombineTessBlend);
h *= _MeshCombineTessBlend;
h *= stAlpha;
return standardHeight + h;
}
#endif
#if _DISTANCERESAMPLE
void DistanceResampleLOD(inout half oalbedo0, inout half oalbedo1, Config config, TriplanarConfig tc, half4 fxLevels, float3 worldPos, half4 weights, float3 worldNormalVertex)
{
float distanceBlend = 0;
#if _DISTANCERESAMPLENOISE
#if _TRIPLANAR
distanceBlend = _DistanceResampleConstant + FBM3D(worldPos * _DistanceResampleNoiseParams.x) * _DistanceResampleNoiseParams.y;
#else
distanceBlend = _DistanceResampleConstant + FBM2D(config.uv * _DistanceResampleNoiseParams.x) * _DistanceResampleNoiseParams.y;
#endif // triplanar
#elif _DISTANCERESAMPLENOFADE
distanceBlend = _DistanceResampleConstant;
#endif
float dblend0 = distanceBlend;
float dblend1 = distanceBlend;
config.uv0.xy *= _ResampleDistanceParams.xx;
config.uv1.xy *= _ResampleDistanceParams.xx;
half albedo0;
half albedo1;
half4 mipLevel = _TessData1.z;
#if _PERTEXTESSMIPLEVEL
SAMPLE_PER_TEX(perTexMipLevel, 4.5, config, half4(1.0, 0.0, 0, 0.0));
mipLevel.x = perTexMipLevel0.a;
mipLevel.y = perTexMipLevel1.a;
mipLevel.z = perTexMipLevel2.a;
mipLevel.w = perTexMipLevel3.a;
#endif
#if _PERTEXDISTANCERESAMPLESTRENGTH
SAMPLE_PER_TEX(strs, 4.5, config, half4(1.0, 1.0, 1.0, 0.0));
dblend0 *= strs0.b;
dblend1 *= strs1.b;
#endif
#if _STREAMS || _PUDDLES || _LAVA
half fac = 1.0 - min(fxLevels.y + fxLevels.z + fxLevels.w, 1.0f);
dblend0 *= fac;
dblend1 *= fac;
#endif
#if _TRIPLANAR
#if _BRANCHSAMPLES
UNITY_BRANCH if (dblend0 > 0)
#endif
{
#if _RESAMPLECLUSTERS && (_TEXTURECLUSTER2 || _TEXTURECLUSTER3)
half a0 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv0[0], config.cluster0, mipLevel.x).a;
half a1 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv0[1], config.cluster0, mipLevel.x).a;
half a2 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv0[2], config.cluster0, mipLevel.x).a;
#else
half a0 = UNITY_SAMPLE_TEX2DARRAY_LOD(_Diffuse, tc.uv0[0], mipLevel.x).a;
half a1 = UNITY_SAMPLE_TEX2DARRAY_LOD(_Diffuse, tc.uv0[1], mipLevel.x).a;
half a2 = UNITY_SAMPLE_TEX2DARRAY_LOD(_Diffuse, tc.uv0[2], mipLevel.x).a;
#endif
albedo0 = a0 * tc.pN0.x + a1 * tc.pN0.y + a2 * tc.pN0.z;
}
#if _BRANCHSAMPLES
UNITY_BRANCH if (dblend1 * weights.y > 0)
#endif
{
#if _RESAMPLECLUSTERS && (_TEXTURECLUSTER2 || _TEXTURECLUSTER3)
half a0 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv1[0], config.cluster1, mipLevel.y).a;
half a1 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv1[1], config.cluster1, mipLevel.y).a;
half a2 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv1[2], config.cluster1, mipLevel.y).a;
#else
half a0 = UNITY_SAMPLE_TEX2DARRAY_LOD(_Diffuse, tc.uv1[0], mipLevel.y).a;
half a1 = UNITY_SAMPLE_TEX2DARRAY_LOD(_Diffuse, tc.uv1[1], mipLevel.y).a;
half a2 = UNITY_SAMPLE_TEX2DARRAY_LOD(_Diffuse, tc.uv1[2], mipLevel.y).a;
#endif
albedo1 = a0 * tc.pN1.x + a1 * tc.pN1.y + a2 * tc.pN1.z;
}
#else
#if _RESAMPLECLUSTERS && (_TEXTURECLUSTER2 || _TEXTURECLUSTER3)
#if _BRANCHSAMPLES
UNITY_BRANCH if (dblend0 > 0)
#endif
{
albedo0 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(config.uv0, config.cluster0, mipLevel.x).a;
}
#if _BRANCHSAMPLES
UNITY_BRANCH if (dblend1 * weights.y > 0)
#endif
{
albedo1 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(config.uv1, config.cluster1, mipLevel.y).a;
}
#else
#if _BRANCHSAMPLES
UNITY_BRANCH if (dblend0 > 0)
#endif
{
albedo0 = UNITY_SAMPLE_TEX2DARRAY_LOD(_Diffuse, config.uv0, mipLevel.x).a;
}
#if _BRANCHSAMPLES
UNITY_BRANCH if (dblend1 * weights.y > 0)
#endif
{
albedo1 = UNITY_SAMPLE_TEX2DARRAY_LOD(_Diffuse, config.uv1, mipLevel.y).a;
}
#endif
#endif
#if _DISTANCERESAMPLEHEIGHTBLEND
dblend0 = HeightBlend(oalbedo0, albedo0, dblend0, _Contrast);
dblend1 = HeightBlend(oalbedo1, albedo1, dblend1, _Contrast);
#endif
oalbedo0 = lerp(oalbedo0, albedo0, dblend0);
oalbedo1 = lerp(oalbedo1, albedo1, dblend1);
}
#endif
void SampleSplatsLOD(float2 controlUV, inout fixed4 w0, inout fixed4 w1, inout fixed4 w2, inout fixed4 w3, inout fixed4 w4, inout fixed4 w5, inout fixed4 w6, inout fixed4 w7)
{
#if _CUSTOMSPLATTEXTURES
#if !_MICROMESH
controlUV = (controlUV * (_CustomControl0_TexelSize.zw - 1.0f) + 0.5f) * _CustomControl0_TexelSize.xy;
#endif
#if _CONTROLNOISEUV
controlUV += (SAMPLE_TEXTURE2D_LOD(_NoiseUV, sampler_Diffuse, controlUV * _CustomControl0_TexelSize.zw * 0.2 * _NoiseUVParams.x, 0).ga - 0.5) * _CustomControl0_TexelSize.xy * _NoiseUVParams.y;
#endif
w0 = SAMPLE_TEXTURE2D_LOD(_CustomControl0, shared_linear_clamp_sampler, controlUV.xy, 0);
#if !_MAX4TEXTURES
w1 = SAMPLE_TEXTURE2D_LOD(_CustomControl1, shared_linear_clamp_sampler, controlUV.xy, 0);
#endif
#if !_MAX4TEXTURES && !_MAX8TEXTURES
w2 = SAMPLE_TEXTURE2D_LOD(_CustomControl2, shared_linear_clamp_sampler, controlUV.xy, 0);
#endif
#if !_MAX4TEXTURES && !_MAX8TEXTURES && !_MAX12TEXTURES
w3 = SAMPLE_TEXTURE2D_LOD(_CustomControl3, shared_linear_clamp_sampler, controlUV.xy, 0);
#endif
#if _MAX20TEXTURES || _MAX24TEXTURES || _MAX28TEXTURES || _MAX32TEXTURES
w4 = SAMPLE_TEXTURE2D_LOD(_CustomControl4, shared_linear_clamp_sampler, controlUV.xy, 0);
#endif
#if _MAX24TEXTURES || _MAX28TEXTURES || _MAX32TEXTURES
w5 = SAMPLE_TEXTURE2D_LOD(_CustomControl5, shared_linear_clamp_sampler, controlUV.xy, 0);
#endif
#if _MAX28TEXTURES || _MAX32TEXTURES
w6 = SAMPLE_TEXTURE2D_LOD(_CustomControl6, shared_linear_clamp_sampler, controlUV.xy, 0);
#endif
#if _MAX32TEXTURES
w7 = SAMPLE_TEXTURE2D_LOD(_CustomControl7, shared_linear_clamp_sampler, controlUV.xy, 0);
#endif
#else
#if !_MICROMESH
controlUV = (controlUV * (_Control0_TexelSize.zw - 1.0f) + 0.5f) * _Control0_TexelSize.xy;
#endif
#if _CONTROLNOISEUV
controlUV += (SAMPLE_TEXTURE2D_LOD(_NoiseUV, sampler_Diffuse, controlUV * _Control0_TexelSize.zw * 0.2 * _NoiseUVParams.x, 0).ga - 0.5) * _Control0_TexelSize.xy * _NoiseUVParams.y;
#endif
w0 = SAMPLE_TEXTURE2D_LOD(_Control0, shared_linear_clamp_sampler, controlUV.xy, 0);
#if !_MAX4TEXTURES
w1 = SAMPLE_TEXTURE2D_LOD(_Control1, shared_linear_clamp_sampler, controlUV.xy, 0);
#endif
#if !_MAX4TEXTURES && !_MAX8TEXTURES
w2 = SAMPLE_TEXTURE2D_LOD(_Control2, shared_linear_clamp_sampler, controlUV.xy, 0);
#endif
#if !_MAX4TEXTURES && !_MAX8TEXTURES && !_MAX12TEXTURES
w3 = SAMPLE_TEXTURE2D_LOD(_Control3, shared_linear_clamp_sampler, controlUV.xy, 0);
#endif
#if _MAX20TEXTURES || _MAX24TEXTURES || _MAX28TEXTURES || _MAX32TEXTURES
w4 = SAMPLE_TEXTURE2D_LOD(_Control4, shared_linear_clamp_sampler, controlUV.xy, 0);
#endif
#if _MAX24TEXTURES || _MAX28TEXTURES || _MAX32TEXTURES
w5 = SAMPLE_TEXTURE2D_LOD(_Control5, shared_linear_clamp_sampler, controlUV.xy, 0);
#endif
#if _MAX28TEXTURES || _MAX32TEXTURES
w6 = SAMPLE_TEXTURE2D_LOD(_Control6, shared_linear_clamp_sampler, controlUV.xy, 0);
#endif
#if _MAX32TEXTURES
w7 = SAMPLE_TEXTURE2D_LOD(_Control7, shared_linear_clamp_sampler, controlUV.xy, 0);
#endif
#endif
}
float3 OffsetVertex(VertexData v, ExtraV2F ex)
{
float2 texcoord = v.texcoord0.xy;
float3 vertex = v.vertex.xyz;
float3 normal = v.normal;
#if _MICROVERSEPREVIEW
float4 recipSize = _TerrainHeightmapTexture_TexelSize;
recipSize.zw = (1.0f / (_TerrainHeightmapTexture_TexelSize.zw-1));
float2 sampleCoords = (texcoord / recipSize.zw + 0.5f) * recipSize.xy;
float height = UnpackHeightmap(SAMPLE_TEXTURE2D_LOD(_TerrainHeightmapTexture, shared_linear_clamp_sampler, sampleCoords, 0));
return float3(0,1,0) * height * _TerrainHeight * 2;
#elif (defined(UNITY_INSTANCING_ENABLED) && _MICROTERRAIN && !_TERRAINBLENDABLESHADER)
float2 sampleCoords = (texcoord.xy / _TerrainHeightmapRecipSize.zw + 0.5f) * _TerrainHeightmapRecipSize.xy;
normal = normalize(SAMPLE_TEXTURE2D_LOD(_TerrainNormalmapTexture, shared_linear_clamp_sampler, sampleCoords, 0).xyz * 2 - 1);
#elif _PERPIXNORMAL && (_MICROTERRAIN || _MICROMESHTERRAIN) && !_TERRAINBLENDABLESHADER
float2 sampleCoords = (texcoord.xy * _PerPixelNormal_TexelSize.zw + 0.5f) * _PerPixelNormal_TexelSize.xy;
normal = normalize(SAMPLE_TEXTURE2D_LOD(_PerPixelNormal, shared_linear_clamp_sampler, sampleCoords, 0).xyz * 2 - 1);
#endif
float2 controlUV = v.texcoord0.xy;
#if _MICROMESH
controlUV = InverseLerp(_UVMeshRange.xy, _UVMeshRange.zw, controlUV);
#endif
half4 weights;
#if _HDRP || _URP
float3 worldPos = GetAbsolutePositionWS(TransformObjectToWorld(vertex.xyz));
#else
float3 worldPos = TransformObjectToWorld(vertex).xyz;
#endif
#if _FORCELOCALSPACE
worldPos = v.vertex;
#endif
float3 worldNormal = float3(0,0,1);
#if _SNOW || _TRIPLANAR
worldNormal = UnityObjectToWorldNormal(normal);
#endif
Config config = (Config)0;
half4 mipLevel = _TessData1.z;
fixed4 w0 = fixed4(1,0,0,0);
fixed4 w1 = 0; fixed4 w2 = 0; fixed4 w3 = 0; fixed4 w4 = 0; fixed4 w5 = 0; fixed4 w6 = 0; fixed4 w7 = 0;
DecalOutput decalOutput = (DecalOutput)0;
#if _DECAL_TESS || _DECAL_SPLATS
decalOutput = DoDecalsTess(texcoord, worldPos, 0, normal);
#endif
#if _MICRODIGGERMESH
Input inp = (Input)0;
UnpackVertexMesh(inp, ex);
DiggerSetup(inp, weights, texcoord, config, worldPos, decalOutput);
#elif _MEGASPLAT
Input inp = (Input)0;
UnpackMegaSplat(v, inp, ex);
MegaSplatVertexSetup(inp, weights, texcoord, config, worldPos, decalOutput);
#elif _MEGASPLATTEXTURE
MegaSplatTextureSetup(controlUV, weights, texcoord.xy, config, worldPos, decalOutput);
#elif _MEGASPLATTEXTURE && _PROCEDURALTEXTURE && !_DISABLESPLATMAPS && _PROCEDURALBLENDSPLATS
MegaSplatTextureSetup(controlUV, weights, texcoord.xy, config, worldPos, decalOutput);
float3 up = float3(0,1,0);
float3 procNormal = normal;
float height = worldPos.y;
Input i = (Input)0;
ProceduralSetup(i, worldPos, height, procNormal, up, weights, texcoord.xy, config, 0, 0, 0, 0, decalOutput);
#elif _MICROVERTEXMESH || _MICRODIGGERMESH
Input inp = (Input)0;
UnpackVertexMesh(inp, ex);
VertexSetup(inp, weights, texcoord, config, worldPos, decalOutput);
#elif _PROCEDURALTEXTURE && !_DISABLESPLATMAPS && _PROCEDURALBLENDSPLATS
SampleSplatsLOD(controlUV, w0, w1, w2, w3, w4, w5, w6, w7);
Setup(weights, texcoord.xy, config, w0, w1, w2, w3, w4, w5, w6, w7, worldPos, decalOutput);
float3 up = float3(0,1,0);
float3 procNormal = normal;
float height = worldPos.y;
Input i = (Input)0;
ProceduralSetup(i, worldPos, height, procNormal, up, weights, texcoord.xy, config, 0, 0, 0, 0, decalOutput);
#elif _PROCEDURALTEXTURE && !_DISABLESPLATMAPS
float3 up = float3(0,1,0);
float3 procNormal = normal;
float height = worldPos.y;
Input input = (Input)0;
ProceduralSetup(input, worldPos, height, procNormal, up, weights, texcoord.xy, config, 0, 0, 0, 0, decalOutput);
#elif !_DISABLESPLATMAPS
SampleSplatsLOD(controlUV, w0, w1, w2, w3, w4, w5, w6, w7);
Setup(weights, texcoord.xy, config, w0, w1, w2, w3, w4, w5, w6, w7, worldPos, decalOutput);
#endif // _DISABLESPLATMAPS
#if _SLOPETEXTURE
SlopeTexture(config, weights, normal);
#endif
#if _PERTEXTESSMIPLEVEL && !_DISABLESPLATMAPS
SAMPLE_PER_TEX(perTexMipLevel, 4.5, config, half4(1.0, 0.0, 0, 0.0));
mipLevel.x = perTexMipLevel0.a;
mipLevel.y = perTexMipLevel1.a;
mipLevel.z = perTexMipLevel2.a;
mipLevel.w = perTexMipLevel3.a;
#endif
#if _PERTEXCURVEWEIGHT
SAMPLE_PER_TEX(ptCurveWeight, 19.5, config, half4(0.5,1,1,1));
weights.x = smoothstep(0.5 - ptCurveWeight0.r, 0.5 + ptCurveWeight0.r, weights.x);
weights.y = smoothstep(0.5 - ptCurveWeight1.r, 0.5 + ptCurveWeight1.r, weights.y);
weights.z = smoothstep(0.5 - ptCurveWeight2.r, 0.5 + ptCurveWeight2.r, weights.z);
weights.w = smoothstep(0.5 - ptCurveWeight3.r, 0.5 + ptCurveWeight3.r, weights.w);
weights = TotalOne(weights);
#endif
float traxBuffer = 0;
#if _SNOWFOOTSTEPS || _TRAXSINGLE || _TRAXARRAY || _TRAXNOTEXTURE
traxBuffer = SampleTraxBufferLOD(worldPos, normal, 1);
#endif
fixed4 levelFx = 0;
#if _PUDDLES || _STREAMS || _LAVA || _WETNESSMASKSNOW
#if _MICROMESH
levelFx = SampleFXLevelsLOD(controlUV.xy, traxBuffer);
#else
levelFx = SampleFXLevelsLOD(texcoord.xy, traxBuffer);
#endif
#endif
// uvScale before anything
#if _PERTEXUVSCALEOFFSET && !_TRIPLANAR && !_DISABLESPLATMAPS
SAMPLE_PER_TEX(ptUVScale, 0.5, config, half4(1,1,0,0));
config.uv0.xy = config.uv0.xy * ptUVScale0.rg + ptUVScale0.ba;
config.uv1.xy = config.uv1.xy * ptUVScale1.rg + ptUVScale1.ba;
#if !_MAX2LAYER
config.uv2.xy = config.uv2.xy * ptUVScale2.rg + ptUVScale2.ba;
#endif
#if !_MAX3LAYER || !_MAX2LAYER
config.uv3.xy = config.uv3.xy * ptUVScale3.rg + ptUVScale3.ba;
#endif
#endif
#if _PERTEXUVROTATION && !_TRIPLANAR && !_DISABLESPLATMAPS
SAMPLE_PER_TEX(ptUVRot, 16.5, config, half4(0,0,0,0));
config.uv0.xy = RotateUV(config.uv0.xy, ptUVRot0.x);
config.uv1.xy = RotateUV(config.uv1.xy, ptUVRot1.x);
#if !_MAX2LAYER
config.uv2.xy = RotateUV(config.uv2.xy, ptUVRot2.x);
#endif
#if !_MAX3LAYER || !_MAX2LAYER
config.uv3.xy = RotateUV(config.uv3.xy, ptUVRot0.x);
#endif
#endif
TriplanarConfig tc = (TriplanarConfig)0;
UNITY_INITIALIZE_OUTPUT(TriplanarConfig,tc);
#if _TRIPLANAR && !_DISABLESPLATMAPS
MIPFORMAT a = INITMIPFORMAT
MIPFORMAT b = INITMIPFORMAT
MIPFORMAT c = INITMIPFORMAT
MIPFORMAT d = INITMIPFORMAT
PrepTriplanarDisplace(v.texcoord0, worldNormal, worldPos, config, tc, weights, a, b, c, d);
#endif
#if _TEXTURECLUSTER2 || _TEXTURECLUSTER3 && !_DISABLESPLATMAPS
PrepClustersDisplace(config.uv, config, worldPos, worldNormal);
#endif
half albedo0 = 0;
half albedo1 = 0;
half albedo2 = 0;
half albedo3 = 0;
#if !_DISABLESPLATMAPS
#if _TRIPLANAR
half4 contrasts = _Contrast.xxxx;
#if _PERTEXTRIPLANARCONTRAST
SAMPLE_PER_TEX(ptc, 5.5, config, half4(1,0.5,0,0));
contrasts = half4(ptc0.y, ptc1.y, ptc2.y, ptc3.y);
#endif
{
half4 a0 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv0[0], config.cluster0, mipLevel.x);
half4 a1 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv0[1], config.cluster0, mipLevel.x);
half4 a2 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv0[2], config.cluster0, mipLevel.x);
half3 bf = tc.pN0;
#if _TRIPLANARHEIGHTBLEND
bf = TriplanarHBlend(a0.a, a1.a, a2.a, tc.pN0, contrasts.x);
tc.pN0 = bf;
#endif
albedo0 = a0.a * bf.x + a1.a * bf.y + a2.a * bf.z;
}
#if _BRANCHSAMPLES
UNITY_BRANCH if (weights.y > 0)
#endif
{
half4 a0 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv1[0], config.cluster1, mipLevel.y);
half4 a1 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv1[1], config.cluster1, mipLevel.y);
half4 a2 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv1[2], config.cluster1, mipLevel.y);
half3 bf = tc.pN1;
#if _TRIPLANARHEIGHTBLEND
bf = TriplanarHBlend(a0.a, a1.a, a2.a, tc.pN1, contrasts.x);
tc.pN1 = bf;
#endif
albedo1 = a0.a * bf.x + a1.a * bf.y + a2.a * bf.z;
}
#if !_MAX2LAYER
#if _BRANCHSAMPLES
UNITY_BRANCH if (weights.z > 0)
#endif
{
half4 a0 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv2[0], config.cluster2, mipLevel.z);
half4 a1 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv2[1], config.cluster2, mipLevel.z);
half4 a2 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv2[2], config.cluster2, mipLevel.z);
half3 bf = tc.pN2;
#if _TRIPLANARHEIGHTBLEND
bf = TriplanarHBlend(a0.a, a1.a, a2.a, tc.pN2, contrasts.x);
tc.pN2 = bf;
#endif
albedo2 = a0.a * bf.x + a1.a * bf.y + a2.a * bf.z;
}
#endif
#if !_MAX3LAYER || !_MAX2LAYER
#if _BRANCHSAMPLES
UNITY_BRANCH if (weights.w > 0)
#endif
{
half4 a0 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv3[0], config.cluster3, mipLevel.w);
half4 a1 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv3[1], config.cluster3, mipLevel.w);
half4 a2 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(tc.uv3[2], config.cluster3, mipLevel.w);
half3 bf = tc.pN3;
#if _TRIPLANARHEIGHTBLEND
bf = TriplanarHBlend(a0.a, a1.a, a2.a, tc.pN3, contrasts.x);
tc.pN3 = bf;
#endif
albedo3 = a0.a * bf.x + a1.a * bf.y + a2.a * bf.z;
}
#endif
#else
albedo0 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(config.uv0, config.cluster0, mipLevel.x).a;
#if _BRANCHSAMPLES
UNITY_BRANCH if (weights.y > 0)
#endif
albedo1 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(config.uv1, config.cluster1, mipLevel.y).a;
#if !_MAX2LAYER
#if _BRANCHSAMPLES
UNITY_BRANCH if (weights.z > 0)
#endif
albedo2 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(config.uv2, config.cluster2, mipLevel.z).a;
#endif
#if !_MAX3LAYER || !_MAX2LAYER
#if _BRANCHSAMPLES
UNITY_BRANCH if (weights.w > 0)
#endif
albedo3 = MICROSPLAT_SAMPLE_DIFFUSE_LOD(config.uv3, config.cluster3, mipLevel.w).a;
#endif
#endif
#endif //_DISABLESPLATMAPS
#if !_DISABLESPLATMAPS && _DISTANCERESAMPLE && (_DISTANCERESAMPLENOFADE || _DISTANCERESAMPLENOISE)
DistanceResampleLOD(albedo0, albedo1, config, tc, levelFx, worldPos, weights, normal);
#endif
#if (_PERTEXTESSDISPLACE || _PERTEXTESSOFFSET || _PERTEXTESSUPBIAS) && !_DISABLESPLATMAPS
SAMPLE_PER_TEX(perTexDispOffsetBias, 6.5, config, half4(1.0, 0.0, 0, 0.0));
#endif
float shaping = _TessData2.z;
#if _PERTEXTESSSHAPING && !_DISABLESPLATMAPS
SAMPLE_PER_TEX(perTexShaping, 14.5, config, half4(0.5, 0.5, 0.5, 0.5));
shaping = perTexShaping0.a * weights.x + perTexShaping1.a * weights.y + perTexShaping2.a * weights.z + perTexShaping3.a * weights.w;
#endif
#if _NOISEHEIGHT
float oldAlb0 = albedo0;
float oldAlb1 = albedo1;
float oldAlb2 = albedo2;
float oldAlb3 = albedo3;
ApplyNoiseHeightLOD(albedo0, albedo1, albedo2, albedo3, config.uv, config, vertex.rgb, normal);
#endif
float4 heightWeights = ComputeWeights(weights, albedo0, albedo1, albedo2, albedo3, shaping);
#if _NOISEHEIGHT
albedo0 = oldAlb0;
albedo1 = oldAlb1;
albedo2 = oldAlb2;
albedo3 = oldAlb3;
#endif
#if _PERTEXTESSDISPLACE && !_DISABLESPLATMAPS
albedo0 *= perTexDispOffsetBias0.x;
albedo1 *= perTexDispOffsetBias1.x;
#if !_MAX2LAYER
albedo2 *= perTexDispOffsetBias2.x;
#endif
#if !_MAX3LAYER || !_MAX2LAYER
albedo3 *= perTexDispOffsetBias3.x;
#endif
#endif
#if _PERTEXTESSOFFSET && !_DISABLESPLATMAPS
albedo0 += perTexDispOffsetBias0.z;
albedo1 += perTexDispOffsetBias1.z;
albedo2 += perTexDispOffsetBias2.z;
albedo3 += perTexDispOffsetBias3.z;
#endif
#if _MESHOVERLAYSPLATS || _MESHCOMBINED
if (_MeshAlphaIndex == config.uv0.z)
{
albedo0 = 0;
}
else if (_MeshAlphaIndex == config.uv1.z)
{
albedo1 = 0;
}
#if !_MAX2LAYER
else if (_MeshAlphaIndex == config.uv2.z)
{
albedo2 = 0;
}
#endif
#if !_MAX3LAYER || !_MAX2LAYER
else if (_MeshAlphaIndex == config.uv3.z)
{
albedo3 = 0;
}
#endif
#endif
#if _DECAL_TESS
DoDecalBlendTess(decalOutput, albedo0, albedo1, albedo2, albedo3, mipLevel);
#endif
#if _TRAXSINGLE || _TRAXARRAY || _TRAXNOTEXTURE || _SNOWFOOTSTEPS
ApplyTraxTess(albedo0, albedo1, albedo2, albedo3, config, worldPos, traxBuffer, _TessData1.z, _TessData1.y);
#endif
half h = albedo0 * heightWeights.x + albedo1 * heightWeights.y + albedo2 * heightWeights.z + albedo3 * heightWeights.w;
#if _MESHCOMBINEDHEIGHT || _MESHCOMBINEDPACKEDMAP
h = SampleMeshCombinedTess(h, heightWeights, config, _TessData1.z);
#endif
#if _PUDDLES || _STREAMS || _LAVA
#if _STREAMS && _STREAMHEIGHTFILTER
{
float shf = saturate((worldPos.y - _StreamFades.x) / max(_StreamFades.y - _StreamFades.x, 0.0001));
shf *= 1.0 - saturate((worldPos.y - _StreamFades.z) / max(_StreamFades.w - _StreamFades.z, 0.0001));
levelFx.b *= shf;
}
#endif
#if _LAVA && _LAVAHEIGHTFILTER
{
float lhf = saturate((worldPos.y - _LavaFades.x) / max(_LavaFades.y - _LavaFades.x, 0.0001));
lhf *= 1.0 - saturate((worldPos.y - _LavaFades.z) / max(_LavaFades.w - _LavaFades.z, 0.0001));
levelFx.a *= lhf;
}
#endif
half maxLevel = max(max(levelFx.g, levelFx.b), levelFx.a);
h = max(h, maxLevel);
#endif
#if _SNOW
float snowAmount = DoSnowDisplace(h, texcoord.xy, worldNormal, worldPos, 0, config, weights);
#if _SNOWFOOTSTEPS
snowAmount *= traxBuffer;
#endif
#if _WETNESSMASKSNOW
snowAmount *= 1-levelFx.x;
#endif
h = lerp(h + snowAmount * _TessDisplaceSnowMultiplier, max(h, snowAmount * _TessDisplaceSnowMultiplier), pow(saturate(snowAmount - 0.3), 2.0));
//h += snowAmount * _TessDisplaceSnowMultiplier;
#endif
#if _SNOW && _SNOWFOOTSTEPS
h = lerp(h/3.0, h, traxBuffer); // maybe expose this?
#endif
float dist = distance(_WorldSpaceCameraPos, worldPos);
float tessFade = saturate((dist - _TessData2.x) / (_TessData2.y - _TessData2.x));
tessFade *= tessFade;
tessFade = 1 - tessFade;
half upBias = _TessData2.w;
#if _PERTEXTESSUPBIAS && !_DISABLESPLATMAPS
upBias = BlendWeights(perTexDispOffsetBias0.y, perTexDispOffsetBias1.y, perTexDispOffsetBias2.y, perTexDispOffsetBias3.y, weights);
#endif
float3 offset = (lerp(normal, float3(0,1,0), upBias) * (_TessData1.y * h * tessFade));
#if _DISPLACEMENTDAMPENING
offset *= (1.0 - SAMPLE_TEXTURE2D_LOD(_DisplacementDampening, sampler_Diffuse, controlUV, 0).g);
#endif
// fade tessellation near alpha holes. This helps seem stuff with digger, etc.
#if defined(_ALPHATEST_ON) && _TESSFADEHOLES
{
float2 cuv = floor(controlUV * _TerrainHolesTexture_TexelSize.zw + 0.5) * _TerrainHolesTexture_TexelSize.xy;
float hole = SAMPLE_TEXTURE2D_LOD(_TerrainHolesTexture, shared_linear_clamp_sampler, cuv, 0).r;
hole = saturate((hole - 0.5) * 2);
offset *= hole;
}
#endif
#if _ALPHAHOLETEXTURE
{
float2 cuv2 = floor(controlUV * _AlphaHoleTexture_TexelSize.zw + 0.5) * _AlphaHoleTexture_TexelSize.xy;
offset *= SAMPLE_TEXTURE2D_LOD(_AlphaHoleTexture, shared_linear_clamp_sampler, cuv2, 0).r;
}
#endif
return offset;
}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: a978a118c2d1146d79deda39f07f38a0
timeCreated: 1499197582
licenseType: Store
TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,214 @@
struct OutputPatchConstant
{
float edge[3] : SV_TessFactor;
float inside : SV_InsideTessFactor;
};
#if defined(SHADER_API_XBOXONE) || defined(SHADER_API_PSSL)
// AMD recommand this value for GCN http://amd-dev.wpengine.netdna-cdn.com/wordpress/media/2013/05/GCNPerformanceTweets.pdf
#define MAX_TESSELLATION_FACTORS 15.0
#else
#define MAX_TESSELLATION_FACTORS 64.0
#endif
float CalcDistanceTessFactor (float3 wpos, float minDist, float maxDist, float tess, float3 camPos)
{
float dist = distance (wpos, camPos);
float f = clamp(1.0 - (dist - minDist) / (maxDist - minDist), 0.01, 1.0) * tess;
return f;
}
float4 CalcTriEdgeTessFactors (float3 triVertexFactors)
{
float4 tess;
tess.x = 0.5 * (triVertexFactors.y + triVertexFactors.z);
tess.y = 0.5 * (triVertexFactors.x + triVertexFactors.z);
tess.z = 0.5 * (triVertexFactors.x + triVertexFactors.y);
tess.w = (triVertexFactors.x + triVertexFactors.y + triVertexFactors.z) / 3.0f;
return tess;
}
float4 DistanceBasedTess (float3 v0, float3 v1, float3 v2, float minDist, float maxDist, float tess)
{
float3 f;
float3 camPos = TransformWorldToObject(GetCameraWorldPosition());
f.x = CalcDistanceTessFactor (v0,minDist,maxDist,tess, camPos);
f.y = CalcDistanceTessFactor (v1,minDist,maxDist,tess, camPos);
f.z = CalcDistanceTessFactor (v2,minDist,maxDist,tess, camPos);
return CalcTriEdgeTessFactors (f);
}
#if _TESSEDGE || _TESSPHONG
float CalcEdgeTessFactor (float3 wpos0, float3 wpos1, float edgeLen)
{
float3 camPos = TransformWorldToObject(GetCameraWorldPosition());
// distance to edge center
float dist = distance (0.5 * (wpos0+wpos1), GetCameraWorldPosition());
// length of the edge
float len = distance(wpos0, wpos1);
// edgeLen is approximate desired size in pixels
float f = max(len * _ScreenParams.y / (edgeLen * dist), 1.0);
return f;
}
float TessDistanceFromPlane (float3 pos, float4 plane)
{
float d = dot (float4(pos,1.0f), plane);
return d;
}
float4 EdgeLengthBasedTessCull (float4 v0, float4 v1, float4 v2, float edgeLength)
{
float3 pos0 = mul(unity_ObjectToWorld,v0).xyz;
float3 pos1 = mul(unity_ObjectToWorld,v1).xyz;
float3 pos2 = mul(unity_ObjectToWorld,v2).xyz;
float4 tess;
tess.x = CalcEdgeTessFactor (pos1, pos2, edgeLength);
tess.y = CalcEdgeTessFactor (pos2, pos0, edgeLength);
tess.z = CalcEdgeTessFactor (pos0, pos1, edgeLength);
tess.w = (tess.x + tess.y + tess.z) / 3.0f;
return tess;
}
#endif
float4 Tessellation (TessVertex v0, TessVertex v1, TessVertex v2)
{
float3 fac = GetTessFactors();
#if _TESSEDGE
return EdgeLengthBasedTessCull(v0.vertex, v1.vertex, v2.vertex, fac.y);
#else
return DistanceBasedTess(v0.vertex.xyz, v1.vertex.xyz, v2.vertex.xyz, fac.x, fac.y, fac.z);
#endif
}
OutputPatchConstant Hullconst (InputPatch<TessVertex,3> v)
{
OutputPatchConstant o = (OutputPatchConstant)0;
float4 tf = Tessellation( v[0], v[1], v[2] );
tf = min(tf, MAX_TESSELLATION_FACTORS);
o.edge[0] = tf.x;
o.edge[1] = tf.y;
o.edge[2] = tf.z;
o.inside = tf.w;
return o;
}
[maxtessfactor(MAX_TESSELLATION_FACTORS)]
[domain("tri")]
[partitioning("fractional_odd")]
[outputtopology("triangle_cw")]
[patchconstantfunc("Hullconst")]
[outputcontrolpoints(3)]
TessVertex Hull (InputPatch<TessVertex,3> v, uint id : SV_OutputControlPointID)
{
return v[id];
}
TessVertex TessVert(VertexData i)
{
TessVertex o = (TessVertex)o;
UNITY_SETUP_INSTANCE_ID(i);
UNITY_TRANSFER_INSTANCE_ID(i, o);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
VertexToPixel v2p = (VertexToPixel)0;
ChainModifyVertex(i, v2p);
o.vertex = i.vertex;
o.normal = i.normal;
o.texcoord0 = i.texcoord0;
#if !_MICROTERRAIN || _TERRAINBLENDABLESHADER
o.tangent = i.tangent;
o.texcoord1 = i.texcoord1;
o.texcoord2 = i.texcoord2;
#endif
%UV3% o.texcoord3 = i.texcoord3;
%VERTEXCOLOR% o.vertexColor = i.vertexColor;
%EXTRAV2F0% o.extraV2F0 = v2p.extraV2F0;
%EXTRAV2F1% o.extraV2F1 = v2p.extraV2F1;
%EXTRAV2F2% o.extraV2F2 = v2p.extraV2F2;
%EXTRAV2F3% o.extraV2F3 = v2p.extraV2F3;
%EXTRAV2F4% o.extraV2F4 = v2p.extraV2F4;
%EXTRAV2F5% o.extraV2F5 = v2p.extraV2F5;
%EXTRAV2F6% o.extraV2F6 = v2p.extraV2F6;
%EXTRAV2F7% o.extraV2F7 = v2p.extraV2F7;
#if _HDRP && (_PASSMOTIONVECTOR || (_PASSFORWARD && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))
o.previousPositionOS = i.previousPositionOS;
#if defined (_ADD_PRECOMPUTED_VELOCITY)
o.precomputedVelocity = i.precomputedVelocity;
#endif
#endif
return o;
}
[domain("tri")]
VertexToPixel Domain (OutputPatchConstant tessFactors, const OutputPatch<TessVertex,3> vi, float3 bary : SV_DomainLocation)
{
precise VertexData v = (VertexData)0;
UNITY_TRANSFER_INSTANCE_ID(vi[0], v);
v.vertex = vi[0].vertex * bary.x + vi[1].vertex * bary.y + vi[2].vertex * bary.z;
v.normal = vi[0].normal * bary.x + vi[1].normal * bary.y + vi[2].normal * bary.z;
v.texcoord0 = vi[0].texcoord0 * bary.x + vi[1].texcoord0 * bary.y + vi[2].texcoord0 * bary.z;
#if !_MICROTERRAIN || _TERRAINBLENDABLESHADER
v.tangent = vi[0].tangent * bary.x + vi[1].tangent * bary.y + vi[2].tangent * bary.z;
v.texcoord1 = vi[0].texcoord1 * bary.x + vi[1].texcoord1 * bary.y + vi[2].texcoord1 * bary.z;
v.texcoord2 = vi[0].texcoord2 * bary.x + vi[1].texcoord2 * bary.y + vi[2].texcoord2 * bary.z;
#endif
%UV3% v.texcoord3 = vi[0].texcoord3 * bary.x + vi[1].texcoord3 * bary.y + vi[2].texcoord3 * bary.z;
%VERTEXCOLOR% v.vertexColor = vi[0].vertexColor * bary.x + vi[1].vertexColor * bary.y + vi[2].vertexColor * bary.z;
#if _HDRP && (_PASSMOTIONVECTOR || (_PASSFORWARD && defined(_WRITE_TRANSPARENT_MOTION_VECTOR)))
v.previousPositionOS = vi[0].previousPositionOS * bary.x + vi[1].previousPositionOS * bary.y + vi[2].previousPositionOS * bary.z;
#if defined (_ADD_PRECOMPUTED_VELOCITY)
v.precomputedVelocity = vi[0].precomputedVelocity * bary.x + vi[1].precomputedVelocity * bary.y + vi[2].precomputedVelocity * bary.z;
#endif
#endif
VertexToPixel d = (VertexToPixel)0;
%EXTRAV2F0% d.extraV2F0 = vi[0].extraV2F0 * bary.x + vi[1].extraV2F0 * bary.y + vi[2].extraV2F0 * bary.z;
%EXTRAV2F1% d.extraV2F1 = vi[0].extraV2F1 * bary.x + vi[1].extraV2F1 * bary.y + vi[2].extraV2F1 * bary.z;
%EXTRAV2F2% d.extraV2F2 = vi[0].extraV2F2 * bary.x + vi[1].extraV2F2 * bary.y + vi[2].extraV2F2 * bary.z;
%EXTRAV2F3% d.extraV2F3 = vi[0].extraV2F3 * bary.x + vi[1].extraV2F3 * bary.y + vi[2].extraV2F3 * bary.z;
%EXTRAV2F4% d.extraV2F4 = vi[0].extraV2F4 * bary.x + vi[1].extraV2F4 * bary.y + vi[2].extraV2F4 * bary.z;
%EXTRAV2F5% d.extraV2F5 = vi[0].extraV2F5 * bary.x + vi[1].extraV2F5 * bary.y + vi[2].extraV2F5 * bary.z;
%EXTRAV2F6% d.extraV2F6 = vi[0].extraV2F6 * bary.x + vi[1].extraV2F6 * bary.y + vi[2].extraV2F6 * bary.z;
%EXTRAV2F7% d.extraV2F7 = vi[0].extraV2F7 * bary.x + vi[1].extraV2F7 * bary.y + vi[2].extraV2F7 * bary.z;
ChainModifyTessellatedVertex(v, d);
VertexToPixel v2p = Vert(v);
%EXTRAV2F0% v2p.extraV2F0 = d.extraV2F0;
%EXTRAV2F1% v2p.extraV2F1 = d.extraV2F1;
%EXTRAV2F2% v2p.extraV2F2 = d.extraV2F2;
%EXTRAV2F3% v2p.extraV2F3 = d.extraV2F3;
%EXTRAV2F4% v2p.extraV2F0 = d.extraV2F4;
%EXTRAV2F5% v2p.extraV2F1 = d.extraV2F5;
%EXTRAV2F6% v2p.extraV2F2 = d.extraV2F6;
%EXTRAV2F7% v2p.extraV2F3 = d.extraV2F7;
UNITY_TRANSFER_INSTANCE_ID(vi[0], v2p);
UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(v2p);
return v2p;
}

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: f17bd99919a15449f860ab68934c2c5d
timeCreated: 1558704135
licenseType: Store
TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,3 @@
_TessData1("TessData1", Vector) = (12, 0.8, 4, 0) // tess, displacement, mipBias, unused
_TessData2("TessData2", Vector) = (20, 45, 0.2, 0.25) // distance min, max, shaping, upbias

View File

@@ -0,0 +1,8 @@
fileFormatVersion: 2
guid: 33996b4764a314ecb8e90c6408c9f4ff
timeCreated: 1499083310
licenseType: Store
TextScriptImporter:
userData:
assetBundleName:
assetBundleVariant:

View File

@@ -0,0 +1,3 @@
{
"reference": "GUID:4bdfb2239705740718731d0b4d54061d"
}

View File

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