├── .gitattributes ├── .gitignore ├── LICENSE ├── README.md └── XSShaderTemplates ├── Editor.meta ├── Editor ├── XSShaderTemplateCreator.cs └── XSShaderTemplateCreator.cs.meta ├── Templates.meta └── Templates ├── Fragment_Lit.meta ├── Fragment_Lit ├── Fragment_Lit.txt ├── Fragment_Lit.txt.meta ├── VertFrag.cginc └── VertFrag.cginc.meta ├── Geometry_Lit.meta ├── Geometry_Lit ├── Geometry_Lit.txt ├── Geometry_Lit.txt.meta ├── VertFragGeom.cginc └── VertFragGeom.cginc.meta ├── Shared.meta ├── Shared ├── Defines.cginc ├── Defines.cginc.meta ├── LightingBRDF.cginc ├── LightingBRDF.cginc.meta ├── LightingFunctions.cginc ├── LightingFunctions.cginc.meta ├── Properties.txt └── Properties.txt.meta ├── TessellatedGeometry_Lit.meta ├── TessellatedGeometry_Lit ├── TessellatedGeometry_Lit.txt ├── TessellatedGeometry_Lit.txt.meta ├── Tessellation.cginc ├── Tessellation.cginc.meta ├── VertFragTessGeom.cginc └── VertFragTessGeom.cginc.meta ├── Tessellated_Lit.meta └── Tessellated_Lit ├── Tessellated_Lit.txt ├── Tessellated_Lit.txt.meta ├── Tessellation.cginc ├── Tessellation.cginc.meta ├── VertFragTess.cginc └── VertFragTess.cginc.meta /.gitattributes: -------------------------------------------------------------------------------- 1 | # Auto detect text files and perform LF normalization 2 | * text=auto 3 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | XSShaderTemplates/*.mat 2 | XSShaderTemplates/New_Fragment_Lit/ 3 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2020 Xiexe 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | This is a set of template shaders that recieves lighting, but otherwise are untouched. 2 | 3 | They will get added under the "Create/Shaders/Custom" menu when right clicking in your project file browser within Unity. 4 | 5 | __The currently supported templates are:__ 6 | - Vertex Fragment Shaders 7 | - Geometry Shaders 8 | - Tessellated Geometry Shaders 9 | - Tessellated Shaders 10 | 11 | __Supported Lighting Features:__ 12 | - Full Shadow map support 13 | - Full Baked Lightmap support 14 | - Directional Lightmap support 15 | - Realtime Lightmap support 16 | - Specular Lightmap Occlusion 17 | - Vertex Light support (Sampled in Pixel Shader to allow for normal mapping) 18 | - Linear SH Light Probe sampling 19 | 20 | __Supported Extra Features:__ 21 | - Triplanar Mapping in World Space 22 | - Triplanar Mapping in Object Space 23 | 24 | __In Progress Features:__ 25 | - Mixed lighting support 26 | 27 | __Planned:__ 28 | - Subsurface Scattering -------------------------------------------------------------------------------- /XSShaderTemplates/Editor.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 13f69a84a8dd4564b8812d9ff8fcabfd 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /XSShaderTemplates/Editor/XSShaderTemplateCreator.cs: -------------------------------------------------------------------------------- 1 | using System.Collections; 2 | using System.Collections.Generic; 3 | using UnityEngine; 4 | using UnityEditor; 5 | using System.IO; 6 | using System.Linq; 7 | 8 | public class XSShaderTemplateCreator 9 | { 10 | public enum BlendModes 11 | { 12 | Opaque, 13 | Cutout, 14 | Dithered, 15 | Transparent, 16 | Fade 17 | } 18 | 19 | private static string createPath = ""; 20 | private static string templatePath = ""; 21 | private static string lightingBRDFPath = ""; 22 | private static string lightingFunctionsPath = ""; 23 | private static string defines = ""; 24 | private static string propertiesBlockPath = ""; 25 | 26 | private static List templateShaders = new List { "/Fragment_Lit", "/Geometry_Lit", "/Tessellated_Lit", "/TessellatedGeometry_Lit" }; 27 | private static List newShaders = new List { "/New_Fragment_Lit", "/New_Geometry_Lit", "/New_Tessellated_Lit", "/New_TessellatedGeometry_Lit" }; 28 | 29 | 30 | private static void getPathAndCreate(int index, BlendModes blendMode) 31 | { 32 | getTemplatePath(); 33 | if (IsAssetAFolder(Selection.activeObject)) 34 | { 35 | Create(index, blendMode); 36 | Debug.Log("Created at " + createPath); 37 | } 38 | else 39 | { 40 | Debug.Log("Not a valid path, creating in Assets."); 41 | createPath = "Assets"; 42 | 43 | Create(index, blendMode); 44 | Debug.Log("Created at " + createPath); 45 | } 46 | } 47 | 48 | //Creates file and renames the shader to the correct name 49 | private static void Create(int index, BlendModes blendModes) 50 | { 51 | string blendName = BlendModes.GetName(typeof(BlendModes), blendModes); 52 | string shaderIndex = $"{createPath}{newShaders[index]}_{blendName}"; 53 | //Copy files to new directory 54 | FileUtil.CopyFileOrDirectory($"{templatePath}{templateShaders[index]}", shaderIndex); 55 | AssetDatabase.Refresh(); 56 | 57 | //Derive the file name from the folder name. 58 | 59 | string dest = $"{shaderIndex}{templateShaders[index]}.txt"; 60 | string final = $"{shaderIndex}{templateShaders[index]}_{blendName}.shader"; 61 | //Path for Shared CGINC 62 | string finalBRDF = shaderIndex + "/LightingBRDF.cginc"; 63 | string finalFunc = shaderIndex + "/LightingFunctions.cginc"; 64 | string finalDefines = shaderIndex + "/Defines.cginc"; 65 | 66 | List shaderProperties = File.ReadAllLines(propertiesBlockPath).ToList(); 67 | List lines = File.ReadAllLines(dest).ToList(); 68 | lines[0] = $"Shader \"Lit Template{templateShaders[index]}_{blendName}\""; 69 | for (int i = 0; i < lines.Count; i++) 70 | { 71 | if (lines[i].Contains("$PROPERTIES")) 72 | { 73 | bool hasTess = lines[i].Contains("#TESS"); 74 | bool hasGeom = lines[i].Contains("#GEOM"); 75 | 76 | lines.RemoveAt(i); 77 | for (int x = 0; x < shaderProperties.Count; x++) 78 | { 79 | string shaderPropertiesLine = shaderProperties[x]; 80 | if ((shaderPropertiesLine.Contains("#TESS!") && hasTess) || (shaderPropertiesLine.Contains("#GEOM!") && hasGeom)) 81 | shaderPropertiesLine = shaderPropertiesLine.Substring(shaderPropertiesLine.LastIndexOf('!') + 1); 82 | 83 | if (blendModes == BlendModes.Cutout && shaderPropertiesLine.Contains("#CUTOUT!")) 84 | shaderPropertiesLine = shaderPropertiesLine.Substring(shaderPropertiesLine.LastIndexOf('!') + 1); 85 | 86 | lines.Insert(i + x, $" {shaderPropertiesLine}"); 87 | } 88 | } 89 | 90 | if (lines[i].Contains("$TAGS")) 91 | { 92 | lines.RemoveAt(i); 93 | if (blendModes == BlendModes.Opaque) 94 | lines.Insert(i, " Tags{\"RenderType\"=\"Opaque\" \"Queue\"=\"Geometry\"}"); 95 | 96 | if (blendModes == BlendModes.Cutout) 97 | lines.Insert(i, " Tags{\"RenderType\"=\"TransparentCutout\" \"Queue\"=\"AlphaTest\"}"); 98 | 99 | if (blendModes == BlendModes.Dithered) 100 | lines.Insert(i, " Tags{\"RenderType\"=\"TransparentCutout\" \"Queue\"=\"AlphaTest\"}"); 101 | 102 | if (blendModes == BlendModes.Transparent) 103 | lines.Insert(i, " Tags{\"RenderType\"=\"Transparent\" \"Queue\"=\"Transparent\"}"); 104 | 105 | if (blendModes == BlendModes.Fade) 106 | lines.Insert(i, " Tags{\"RenderType\"=\"Transparent\" \"Queue\"=\"Transparent\"}"); 107 | } 108 | 109 | if (lines[i].Contains("$BLENDMODE")) 110 | { 111 | lines.RemoveAt(i); 112 | if (blendModes == BlendModes.Transparent) 113 | lines.Insert(i, "Blend One OneMinusSrcAlpha"); 114 | 115 | if (blendModes == BlendModes.Fade) 116 | lines.Insert(i, "Blend SrcAlpha OneMinusSrcAlpha"); 117 | 118 | } 119 | 120 | if (lines[i].Contains("$BLENDDEFINE")) 121 | { 122 | lines.RemoveAt(i); 123 | if (blendModes == BlendModes.Cutout) 124 | lines.Insert(i, " #define ALPHATEST"); 125 | 126 | if (blendModes == BlendModes.Dithered) 127 | lines.Insert(i, " #define DITHERED"); 128 | 129 | if (blendModes == BlendModes.Transparent) 130 | lines.Insert(i, " #define TRANSPARENT"); 131 | 132 | if (blendModes == BlendModes.Fade) 133 | lines.Insert(i, " #define TRANSPARENT"); 134 | } 135 | } 136 | File.WriteAllLines(dest, lines); 137 | 138 | //Move main Files 139 | FileUtil.MoveFileOrDirectory(dest, final); 140 | //Move Shared CGINCs 141 | FileUtil.CopyFileOrDirectory(lightingBRDFPath, finalBRDF); 142 | FileUtil.CopyFileOrDirectory(lightingFunctionsPath, finalFunc); 143 | FileUtil.CopyFileOrDirectory(defines, finalDefines); 144 | 145 | AssetDatabase.Refresh(); 146 | } 147 | 148 | private static void getTemplatePath() 149 | { 150 | string[] guids1 = AssetDatabase.FindAssets("XSShaderTemplateCreator", null); 151 | string untouchedString = AssetDatabase.GUIDToAssetPath(guids1[0]); 152 | string[] splitString = untouchedString.Split('/'); 153 | 154 | ArrayUtility.RemoveAt(ref splitString, splitString.Length - 1); 155 | ArrayUtility.RemoveAt(ref splitString, splitString.Length - 1); 156 | 157 | templatePath = string.Join("/", splitString); 158 | templatePath += "/Templates"; 159 | lightingBRDFPath = templatePath + "/Shared/LightingBRDF.cginc"; 160 | lightingFunctionsPath = templatePath + "/Shared/LightingFunctions.cginc"; 161 | propertiesBlockPath = templatePath + "/Shared/Properties.txt"; 162 | defines = templatePath + "/Shared/Defines.cginc"; 163 | } 164 | 165 | private static bool IsAssetAFolder(Object obj) 166 | { 167 | if (obj == null) 168 | return false; 169 | 170 | createPath = AssetDatabase.GetAssetPath(obj.GetInstanceID()); 171 | 172 | if (createPath.Length > 0) 173 | { 174 | if (Directory.Exists(createPath)) 175 | { 176 | return true; 177 | } 178 | else 179 | { 180 | return false; 181 | } 182 | } 183 | 184 | return false; 185 | } 186 | 187 | //Opaque 188 | [MenuItem("Assets/Create/Shader/Lit/Opaque/Fragment")] 189 | private static void CreateShaderFragLit() 190 | { 191 | getPathAndCreate(0, BlendModes.Opaque); 192 | } 193 | 194 | [MenuItem("Assets/Create/Shader/Lit/Opaque/Geometry")] 195 | private static void CreateShaderGeoLit() 196 | { 197 | getPathAndCreate(1, BlendModes.Opaque); 198 | } 199 | 200 | [MenuItem("Assets/Create/Shader/Lit/Opaque/Tessellated")] 201 | private static void CreateShaderTessLit() 202 | { 203 | getPathAndCreate(2, BlendModes.Opaque); 204 | } 205 | 206 | [MenuItem("Assets/Create/Shader/Lit/Opaque/TessellatedGeometry")] 207 | private static void CreateShaderTessGeoLit() 208 | { 209 | getPathAndCreate(3, BlendModes.Opaque); 210 | } 211 | 212 | //Cutout 213 | [MenuItem("Assets/Create/Shader/Lit/Cutout/Fragment")] 214 | private static void CreateShaderFragLitCutout() 215 | { 216 | getPathAndCreate(0, BlendModes.Cutout); 217 | } 218 | 219 | [MenuItem("Assets/Create/Shader/Lit/Cutout/Geometry")] 220 | private static void CreateShaderGeoLitCutout() 221 | { 222 | getPathAndCreate(1, BlendModes.Cutout); 223 | } 224 | 225 | [MenuItem("Assets/Create/Shader/Lit/Cutout/Tessellated")] 226 | private static void CreateShaderTessLitCutout() 227 | { 228 | getPathAndCreate(2, BlendModes.Cutout); 229 | } 230 | 231 | [MenuItem("Assets/Create/Shader/Lit/Cutout/TessellatedGeometry")] 232 | private static void CreateShaderTessGeoLitCutout() 233 | { 234 | getPathAndCreate(3, BlendModes.Cutout); 235 | } 236 | 237 | //Dithered 238 | [MenuItem("Assets/Create/Shader/Lit/Dithered/Fragment")] 239 | private static void CreateShaderFragLitDithered() 240 | { 241 | getPathAndCreate(0, BlendModes.Dithered); 242 | } 243 | 244 | [MenuItem("Assets/Create/Shader/Lit/Dithered/Geometry")] 245 | private static void CreateShaderGeoLitDithered() 246 | { 247 | getPathAndCreate(1, BlendModes.Dithered); 248 | } 249 | 250 | [MenuItem("Assets/Create/Shader/Lit/Dithered/Tessellated")] 251 | private static void CreateShaderTessLitDithered() 252 | { 253 | getPathAndCreate(2, BlendModes.Dithered); 254 | } 255 | 256 | [MenuItem("Assets/Create/Shader/Lit/Dithered/TessellatedGeometry")] 257 | private static void CreateShaderTessGeoLitDithered() 258 | { 259 | getPathAndCreate(3, BlendModes.Dithered); 260 | } 261 | 262 | //Transparent 263 | [MenuItem("Assets/Create/Shader/Lit/Transparent/Fragment")] 264 | private static void CreateShaderFragLitTransparent() 265 | { 266 | getPathAndCreate(0, BlendModes.Transparent); 267 | } 268 | 269 | [MenuItem("Assets/Create/Shader/Lit/Transparent/Geometry")] 270 | private static void CreateShaderGeoLitTransparent() 271 | { 272 | getPathAndCreate(1, BlendModes.Transparent); 273 | } 274 | 275 | [MenuItem("Assets/Create/Shader/Lit/Transparent/Tessellated")] 276 | private static void CreateShaderTessLitTransparent() 277 | { 278 | getPathAndCreate(2, BlendModes.Transparent); 279 | } 280 | 281 | [MenuItem("Assets/Create/Shader/Lit/Transparent/TessellatedGeometry")] 282 | private static void CreateShaderTessGeoLitTransparent() 283 | { 284 | getPathAndCreate(3, BlendModes.Transparent); 285 | } 286 | 287 | //Fade 288 | [MenuItem("Assets/Create/Shader/Lit/Fade/Fragment")] 289 | private static void CreateShaderFragLitFade() 290 | { 291 | getPathAndCreate(0, BlendModes.Fade); 292 | } 293 | 294 | [MenuItem("Assets/Create/Shader/Lit/Fade/Geometry")] 295 | private static void CreateShaderGeoLitFade() 296 | { 297 | getPathAndCreate(1, BlendModes.Fade); 298 | } 299 | 300 | [MenuItem("Assets/Create/Shader/Lit/Fade/Tessellated")] 301 | private static void CreateShaderTessLitFade() 302 | { 303 | getPathAndCreate(2, BlendModes.Fade); 304 | } 305 | 306 | [MenuItem("Assets/Create/Shader/Lit/Fade/TessellatedGeometry")] 307 | private static void CreateShaderTessGeoLitFade() 308 | { 309 | getPathAndCreate(3, BlendModes.Fade); 310 | } 311 | } -------------------------------------------------------------------------------- /XSShaderTemplates/Editor/XSShaderTemplateCreator.cs.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1325f35b59899c34e8ba47fc82e1a317 3 | MonoImporter: 4 | externalObjects: {} 5 | serializedVersion: 2 6 | defaultReferences: [] 7 | executionOrder: 0 8 | icon: {instanceID: 0} 9 | userData: 10 | assetBundleName: 11 | assetBundleVariant: 12 | -------------------------------------------------------------------------------- /XSShaderTemplates/Templates.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 55e1611729bc26240aeb7f76f8a567e2 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /XSShaderTemplates/Templates/Fragment_Lit.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 04ebf87c003b94d43bf8eb308a17575c 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /XSShaderTemplates/Templates/Fragment_Lit/Fragment_Lit.txt: -------------------------------------------------------------------------------- 1 | Shader "Template/Fragment_Lit" 2 | { 3 | Properties 4 | { 5 | $PROPERTIES 6 | } 7 | 8 | SubShader 9 | { 10 | $TAGS 11 | $BLENDMODE 12 | 13 | Pass 14 | { 15 | Tags {"LightMode"="ForwardBase"} 16 | CGPROGRAM 17 | #pragma target 3.0 18 | #pragma vertex vert 19 | #pragma fragment frag 20 | #pragma multi_compile _ VERTEXLIGHT_ON 21 | #pragma multi_compile_fwdbase 22 | $BLENDDEFINE 23 | 24 | #ifndef UNITY_PASS_FORWARDBASE 25 | #define UNITY_PASS_FORWARDBASE 26 | #endif 27 | 28 | #include "UnityCG.cginc" 29 | #include "Lighting.cginc" 30 | #include "AutoLight.cginc" 31 | 32 | struct appdata 33 | { 34 | float4 vertex : POSITION; 35 | float2 uv : TEXCOORD0; 36 | float2 uv1 : TEXCOORD1; 37 | float2 uv2 : TEXCOORD2; 38 | float3 normal : NORMAL; 39 | float4 tangent : TANGENT; 40 | }; 41 | 42 | struct v2f 43 | { 44 | float4 pos : SV_POSITION; 45 | float2 uv : TEXCOORD0; 46 | float2 uv1 : TEXCOORD1; 47 | float2 uv2 : TEXCOORD2; 48 | float3 btn[3] : TEXCOORD3; //TEXCOORD2, TEXCOORD3 | bitangent, tangent, worldNormal 49 | float3 worldPos : TEXCOORD6; 50 | float3 objPos : TEXCOORD7; 51 | float3 objNormal : TEXCOORD8; 52 | float4 screenPos : TEXCOORD9; 53 | SHADOW_COORDS(10) 54 | }; 55 | 56 | #include "Defines.cginc" 57 | #include "LightingFunctions.cginc" 58 | #include "LightingBRDF.cginc" 59 | #include "VertFrag.cginc" 60 | 61 | ENDCG 62 | } 63 | 64 | Pass 65 | { 66 | Tags {"LightMode"="ForwardAdd"} 67 | Blend One One 68 | ZWrite Off 69 | 70 | CGPROGRAM 71 | #pragma target 3.0 72 | #pragma vertex vert 73 | #pragma fragment frag 74 | #pragma multi_compile_fwdadd_fullshadows 75 | $BLENDDEFINE 76 | 77 | #ifndef UNITY_PASS_FORWARDADD 78 | #define UNITY_PASS_FORWARDADD 79 | #endif 80 | 81 | #include "UnityCG.cginc" 82 | #include "Lighting.cginc" 83 | #include "AutoLight.cginc" 84 | 85 | struct appdata 86 | { 87 | float4 vertex : POSITION; 88 | float2 uv : TEXCOORD0; 89 | float3 normal : NORMAL; 90 | float4 tangent : TANGENT; 91 | }; 92 | 93 | struct v2f 94 | { 95 | float4 pos : SV_POSITION; 96 | float2 uv : TEXCOORD0; 97 | float3 btn[3] : TEXCOORD1; //TEXCOORD2, TEXCOORD3 | bitangent, tangent, worldNormal 98 | float3 worldPos : TEXCOORD4; 99 | float3 objPos : TEXCOORD5; 100 | float3 objNormal : TEXCOORD6; 101 | float4 screenPos : TEXCOORD7; 102 | SHADOW_COORDS(8) 103 | }; 104 | 105 | #include "Defines.cginc" 106 | #include "LightingFunctions.cginc" 107 | #include "LightingBRDF.cginc" 108 | #include "VertFrag.cginc" 109 | 110 | ENDCG 111 | } 112 | 113 | Pass 114 | { 115 | Tags{"LightMode" = "ShadowCaster"} //Removed "DisableBatching" = "True". If issues arise re-add this. 116 | Cull Off 117 | CGPROGRAM 118 | #pragma target 3.0 119 | #pragma vertex vert 120 | #pragma fragment frag 121 | #pragma multi_compile_shadowcaster 122 | $BLENDDEFINE 123 | 124 | #ifndef UNITY_PASS_SHADOWCASTER 125 | #define UNITY_PASS_SHADOWCASTER 126 | #endif 127 | 128 | #include "UnityCG.cginc" 129 | #include "Lighting.cginc" 130 | #include "AutoLight.cginc" 131 | 132 | struct appdata 133 | { 134 | float4 vertex : POSITION; 135 | float2 uv : TEXCOORD0; 136 | float3 normal : NORMAL; 137 | float4 tangent : TANGENT; 138 | }; 139 | 140 | struct v2f 141 | { 142 | float4 pos : SV_POSITION; 143 | float2 uv : TEXCOORD0; 144 | float3 btn[3] : TEXCOORD1; //TEXCOORD2, TEXCOORD3 | bitangent, tangent, worldNormal 145 | float3 worldPos : TEXCOORD4; 146 | float3 objPos : TEXCOORD5; 147 | float3 objNormal : TEXCOORD6; 148 | float4 screenPos : TEXCOORD7; 149 | }; 150 | 151 | #include "Defines.cginc" 152 | #include "LightingFunctions.cginc" 153 | #include "VertFrag.cginc" 154 | ENDCG 155 | } 156 | } 157 | } 158 | -------------------------------------------------------------------------------- /XSShaderTemplates/Templates/Fragment_Lit/Fragment_Lit.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 97397abe9d0bc5c4daafdac73f4ed035 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /XSShaderTemplates/Templates/Fragment_Lit/VertFrag.cginc: -------------------------------------------------------------------------------- 1 | //This file contains the vertex and fragment functions for both the ForwardBase and Forward Add pass. 2 | 3 | v2f vert (appdata v) 4 | { 5 | v2f o; 6 | float3 worldNormal = UnityObjectToWorldNormal(v.normal); 7 | float3 tangent = UnityObjectToWorldDir(v.tangent); 8 | float3 bitangent = cross(tangent, worldNormal) * v.tangent.w; 9 | 10 | o.pos = UnityObjectToClipPos(v.vertex); 11 | o.uv = v.uv, _MainTex; 12 | #if defined(UNITY_PASS_FORWARDBASE) 13 | o.uv1 = v.uv1; 14 | o.uv2 = v.uv2; 15 | #endif 16 | 17 | o.btn[0] = bitangent; 18 | o.btn[1] = tangent; 19 | o.btn[2] = worldNormal; 20 | o.worldPos = mul(unity_ObjectToWorld, v.vertex); 21 | o.objPos = v.vertex; 22 | o.objNormal = v.normal; 23 | o.screenPos = ComputeScreenPos(o.pos); 24 | 25 | #if !defined(UNITY_PASS_SHADOWCASTER) 26 | UNITY_TRANSFER_SHADOW(o, o.uv); 27 | #else 28 | TRANSFER_SHADOW_CASTER_NOPOS(o, o.pos); 29 | #endif 30 | 31 | return o; 32 | } 33 | 34 | fixed4 frag (v2f i) : SV_Target 35 | { 36 | //Return only this if in the shadowcaster 37 | #if defined(UNITY_PASS_SHADOWCASTER) 38 | float4 albedo = texTP(_MainTex, _MainTex_ST, i.worldPos, i.objPos, i.btn[2], i.objNormal, _TriplanarFalloff, i.uv) * _Color; 39 | float alpha; 40 | doAlpha(alpha, albedo.a, i.screenPos); 41 | SHADOW_CASTER_FRAGMENT(i); 42 | #else 43 | return CustomStandardLightingBRDF(i); 44 | #endif 45 | } -------------------------------------------------------------------------------- /XSShaderTemplates/Templates/Fragment_Lit/VertFrag.cginc.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 8989ae6457d6bc140bb3f0f17900f7cc 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: [] 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /XSShaderTemplates/Templates/Geometry_Lit.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 98334f9fe8140bf478c05b79152aa8f6 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /XSShaderTemplates/Templates/Geometry_Lit/Geometry_Lit.txt: -------------------------------------------------------------------------------- 1 | Shader "Template/Geometry_Lit" 2 | { 3 | Properties 4 | { 5 | $PROPERTIES#GEOM 6 | } 7 | 8 | SubShader 9 | { 10 | $TAGS 11 | $BLENDMODE 12 | 13 | Pass 14 | { 15 | Tags {"LightMode"="ForwardBase"} 16 | CGPROGRAM 17 | #pragma vertex vert 18 | #pragma geometry geom 19 | #pragma fragment frag 20 | #pragma multi_compile _ VERTEXLIGHT_ON 21 | #pragma multi_compile_fwdbase 22 | #pragma target 4.0 23 | #define GEOMETRY 24 | $BLENDDEFINE 25 | 26 | #ifndef UNITY_PASS_FORWARDBASE 27 | #define UNITY_PASS_FORWARDBASE 28 | #endif 29 | 30 | #include "UnityCG.cginc" 31 | #include "Lighting.cginc" 32 | #include "AutoLight.cginc" 33 | 34 | struct appdata 35 | { 36 | float4 vertex : POSITION; 37 | float2 uv : TEXCOORD0; 38 | float2 uv1 : TEXCOORD1; 39 | float2 uv2 : TEXCOORD2; 40 | float3 normal : NORMAL; 41 | float4 tangent : TANGENT; 42 | }; 43 | 44 | struct v2g 45 | { 46 | float4 vertex : SV_POSITION; 47 | float2 uv : TEXCOORD0; 48 | float2 uv1 : TEXCOORD1; 49 | float2 uv2 : TEXCOORD2; 50 | float3 normal : TEXCOORD3; 51 | float4 tangent : TEXCOORD4; 52 | }; 53 | 54 | struct g2f 55 | { 56 | float4 pos : SV_POSITION; 57 | float2 uv : TEXCOORD0; 58 | float2 uv1 : TEXCOORD1; 59 | float2 uv2 : TEXCOORD2; 60 | float3 btn[3] : TEXCOORD3; //TEXCOORD2, TEXCOORD3 | bitangent, tangent, worldNormal 61 | float3 worldPos : TEXCOORD6; 62 | float3 objPos : TEXCOORD7; 63 | float3 objNormal : TEXCOORD8; 64 | float4 screenPos : TEXCOORD9; 65 | SHADOW_COORDS(10) 66 | }; 67 | 68 | #include "Defines.cginc" 69 | #include "LightingFunctions.cginc" 70 | #include "LightingBRDF.cginc" 71 | #include "VertFragGeom.cginc" 72 | 73 | ENDCG 74 | } 75 | 76 | Pass 77 | { 78 | Tags {"LightMode"="ForwardAdd"} 79 | Blend One One 80 | ZWrite Off 81 | 82 | CGPROGRAM 83 | #pragma vertex vert 84 | #pragma geometry geom 85 | #pragma fragment frag 86 | #pragma multi_compile_fwdadd_fullshadows 87 | #pragma target 4.0 88 | #define GEOMETRY 89 | $BLENDDEFINE 90 | 91 | #ifndef UNITY_PASS_FORWARDADD 92 | #define UNITY_PASS_FORWARDADD 93 | #endif 94 | 95 | #include "UnityCG.cginc" 96 | #include "Lighting.cginc" 97 | #include "AutoLight.cginc" 98 | 99 | struct appdata 100 | { 101 | float4 vertex : POSITION; 102 | float2 uv : TEXCOORD0; 103 | float3 normal : NORMAL; 104 | float4 tangent : TANGENT; 105 | }; 106 | 107 | struct v2g 108 | { 109 | float4 vertex : SV_POSITION; 110 | float2 uv : TEXCOORD0; 111 | float3 normal : TEXCOORD1; 112 | float4 tangent : TEXCOORD2; 113 | }; 114 | 115 | struct g2f 116 | { 117 | float4 pos : SV_POSITION; 118 | float2 uv : TEXCOORD0; 119 | float3 btn[3] : TEXCOORD1; //TEXCOORD2, TEXCOORD3 | bitangent, tangent, worldNormal 120 | float3 worldPos : TEXCOORD4; 121 | float3 objPos : TEXCOORD5; 122 | float3 objNormal : TEXCOORD6; 123 | float4 screenPos : TEXCOORD7; 124 | SHADOW_COORDS(8) 125 | }; 126 | 127 | 128 | #include "Defines.cginc" 129 | #include "LightingFunctions.cginc" 130 | #include "LightingBRDF.cginc" 131 | #include "VertFragGeom.cginc" 132 | 133 | ENDCG 134 | } 135 | 136 | Pass 137 | { 138 | Tags{"LightMode" = "ShadowCaster"} //Removed "DisableBatching" = "True". If issues arise re-add this. 139 | Cull Off 140 | CGPROGRAM 141 | #include "UnityCG.cginc" 142 | #include "Lighting.cginc" 143 | #include "AutoLight.cginc" 144 | #pragma vertex vert 145 | #pragma fragment frag 146 | #pragma geometry geom 147 | #pragma multi_compile_shadowcaster 148 | #pragma target 4.0 149 | #define GEOMETRY 150 | $BLENDDEFINE 151 | 152 | #ifndef UNITY_PASS_SHADOWCASTER 153 | #define UNITY_PASS_SHADOWCASTER 154 | #endif 155 | 156 | struct appdata 157 | { 158 | float4 vertex : POSITION; 159 | float2 uv : TEXCOORD0; 160 | float3 normal : NORMAL; 161 | float4 tangent : TANGENT; 162 | }; 163 | 164 | struct v2g 165 | { 166 | float4 vertex : SV_POSITION; 167 | float2 uv : TEXCOORD0; 168 | float3 normal : TEXCOORD1; 169 | float4 tangent : TEXCOORD2; 170 | }; 171 | 172 | struct g2f 173 | { 174 | float4 pos : SV_POSITION; 175 | float2 uv : TEXCOORD0; 176 | float3 btn[3] : TEXCOORD1; //TEXCOORD2, TEXCOORD3 | bitangent, tangent, worldNormal 177 | float3 worldPos : TEXCOORD4; 178 | float3 objPos : TEXCOORD5; 179 | float3 objNormal : TEXCOORD6; 180 | float4 screenPos : TEXCOORD7; 181 | }; 182 | 183 | #include "Defines.cginc" 184 | #include "LightingFunctions.cginc" 185 | #include "VertFragGeom.cginc" 186 | ENDCG 187 | } 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /XSShaderTemplates/Templates/Geometry_Lit/Geometry_Lit.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 0dfb373ae003b3c4bbe53e6dbfb882f2 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /XSShaderTemplates/Templates/Geometry_Lit/VertFragGeom.cginc: -------------------------------------------------------------------------------- 1 | //This file contains the vertex, fragment, and Geometry functions for both the ForwardBase and Forward Add pass. 2 | #if defined(SHADOWS_CUBE) && !defined(SHADOWS_CUBE_IN_DEPTH_TEX) 3 | #define V2F_SHADOW_CASTER_NOPOS float3 vec : TEXCOORD0; 4 | #define TRANSFER_SHADOW_CASTER_NOPOS_GEOMETRY(o,opos) o.vec = mul(unity_ObjectToWorld, v[i].vertex).xyz - _LightPositionRange.xyz; opos = o.pos; 5 | #else 6 | #define V2F_SHADOW_CASTER_NOPOS 7 | #define TRANSFER_SHADOW_CASTER_NOPOS_GEOMETRY(o, opos, vertexPosition, vertexNormal) \ 8 | opos = UnityClipSpaceShadowCasterPos(vertexPosition, vertexNormal); \ 9 | opos = UnityApplyLinearShadowBias(opos); 10 | #endif 11 | 12 | v2g vert (appdata v) 13 | { 14 | v2g o = (v2g)0; 15 | o.vertex = v.vertex; 16 | o.uv = v.uv; 17 | 18 | #if defined(UNITY_PASS_FORWARDBASE) 19 | o.uv1 = v.uv1; 20 | o.uv2 = v.uv2; 21 | #endif 22 | 23 | o.normal = v.normal; 24 | o.tangent = v.tangent; 25 | 26 | return o; 27 | } 28 | 29 | [maxvertexcount(3)] 30 | void geom(triangle v2g v[3], inout TriangleStream tristream) 31 | { 32 | g2f o = (g2f)0; 33 | 34 | for (int i = 0; i < 3; i++) 35 | { 36 | v[i].vertex.xyz += _VertexOffset * v[i].normal; 37 | o.pos = UnityObjectToClipPos(v[i].vertex); 38 | o.uv = v[i].uv; 39 | #if defined(UNITY_PASS_FORWARDBASE) 40 | o.uv1 = v[i].uv1; 41 | o.uv2 = v[i].uv2; 42 | #endif 43 | float3 worldNormal = UnityObjectToWorldNormal(v[i].normal); 44 | float3 tangent = UnityObjectToWorldDir(v[i].tangent); 45 | float3 bitangent = cross(tangent, worldNormal) * v[i].tangent.w; 46 | 47 | o.btn[0] = bitangent; 48 | o.btn[1] = tangent; 49 | o.btn[2] = worldNormal; 50 | o.worldPos = mul(unity_ObjectToWorld, v[i].vertex); 51 | o.objPos = v[i].vertex; 52 | o.objNormal = v[i].normal; 53 | o.screenPos = ComputeScreenPos(o.pos); 54 | 55 | //Only pass needed things through for shadow caster 56 | #if !defined(UNITY_PASS_SHADOWCASTER) 57 | UNITY_TRANSFER_SHADOW(o, o.uv); 58 | #else 59 | TRANSFER_SHADOW_CASTER_NOPOS_GEOMETRY(o, o.pos, v[i].vertex, v[i].normal); 60 | #endif 61 | tristream.Append(o); 62 | } 63 | tristream.RestartStrip(); 64 | } 65 | 66 | fixed4 frag (g2f i) : SV_Target 67 | { 68 | //Return only this if in the shadowcaster 69 | #if defined(UNITY_PASS_SHADOWCASTER) 70 | float4 albedo = texTP(_MainTex, _MainTex_ST, i.worldPos, i.objPos, i.btn[2], i.objNormal, _TriplanarFalloff, i.uv) * _Color; 71 | float alpha; 72 | doAlpha(alpha, albedo.a, i.screenPos); 73 | SHADOW_CASTER_FRAGMENT(i); 74 | #else 75 | return CustomStandardLightingBRDF(i); 76 | #endif 77 | } -------------------------------------------------------------------------------- /XSShaderTemplates/Templates/Geometry_Lit/VertFragGeom.cginc.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6d7089b48cc4cbc449539f579599d5a7 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: [] 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /XSShaderTemplates/Templates/Shared.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a99e552d2aee40c40b26f26e5d1db5ee 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /XSShaderTemplates/Templates/Shared/Defines.cginc: -------------------------------------------------------------------------------- 1 | struct VertexLightInformation { 2 | float3 Direction[4]; 3 | float3 ColorFalloff[4]; 4 | float Attenuation[4]; 5 | }; 6 | 7 | sampler2D _MainTex; float4 _MainTex_ST; 8 | sampler2D _MetallicGlossMap; float4 _MetallicGlossMap_ST; 9 | sampler2D _OcclusionMap; float4 _OcclusionMap_ST; 10 | sampler2D _EmissionMap; float4 _EmissionMap_ST; 11 | sampler2D _BumpMap; float4 _BumpMap_ST; 12 | sampler2D _ClearcoatMap; float4 _ClearcoatMap_ST; 13 | sampler2D _CurvatureThicknessMap; float4 _CurvatureThicknessMap_ST; 14 | sampler2D _SubsurfaceColorMap; float4 _SubsurfaceColorMap_ST; 15 | 16 | float4 _Color, _EmissionColor, _OcclusionColor, _SubsurfaceScatteringColor; 17 | float _Metallic, _Glossiness, _Reflectance, _Anisotropy; 18 | float _ClearcoatAnisotropy, _Clearcoat, _ClearcoatGlossiness; 19 | float _BumpScale; 20 | float _Cutoff; 21 | float _SubsurfaceInheritDiffuse, _TransmissionNormalDistortion, _TransmissionPower, _TransmissionScale; 22 | 23 | float _VertexOffset; 24 | float _TessellationUniform; 25 | float _TessClose; 26 | float _TessFar; 27 | 28 | float _SpecularLMOcclusion, _SpecLMOcclusionAdjust; 29 | float _TriplanarFalloff; 30 | float _LMStrength, _RTLMStrength; 31 | 32 | int _TextureSampleMode; 33 | int _LightProbeMethod; 34 | int _TessellationMode; 35 | int _SubsurfaceMethod; -------------------------------------------------------------------------------- /XSShaderTemplates/Templates/Shared/Defines.cginc.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 38b40c087d281d14bb321fc845789ed6 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: [] 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /XSShaderTemplates/Templates/Shared/LightingBRDF.cginc: -------------------------------------------------------------------------------- 1 | //Since this is shared, and the output structs/input structs are all slightly differently named in each shader template, just handle them all here. 2 | float4 CustomStandardLightingBRDF( 3 | #if defined(GEOMETRY) 4 | g2f i 5 | #elif defined(TESSELLATION) 6 | vertexOutput i 7 | #else 8 | v2f i 9 | #endif 10 | ) 11 | { 12 | //LIGHTING PARAMS 13 | UNITY_LIGHT_ATTENUATION(attenuation, i, i.worldPos.xyz); 14 | float3 worldPos = i.worldPos; 15 | // fix for rare bug where light atten is 0 when there is no directional light in the scene 16 | #ifdef UNITY_PASS_FORWARDBASE 17 | if(all(_LightColor0.rgb == 0.0)) 18 | { 19 | attenuation = 1.0; 20 | } 21 | #endif 22 | 23 | //NORMAL 24 | float3 unmodifiedWorldNormal = normalize(i.btn[2]); 25 | float3 unmodifiedTangent = i.btn[1]; 26 | float3 unmodifiedBitangent = i.btn[0]; 27 | float4 normalMap = texTP(_BumpMap, _BumpMap_ST, i.worldPos, i.objPos, i.btn[2], i.objNormal, _TriplanarFalloff, i.uv); 28 | float3 worldNormal = i.btn[2]; 29 | float3 tangent = i.btn[1]; 30 | float3 bitangent = i.btn[0]; 31 | initBumpedNormalTangentBitangent(normalMap, bitangent, tangent, worldNormal); 32 | //---- 33 | 34 | //DIFFUSE 35 | float4 albedo = texTP(_MainTex, _MainTex_ST, i.worldPos, i.objPos, i.btn[2], i.objNormal, _TriplanarFalloff, i.uv) * _Color; 36 | float4 diffuse = albedo; 37 | float alpha; 38 | doAlpha(alpha, diffuse.a, i.screenPos); 39 | //---- 40 | 41 | //METALLIC SMOOTHNESS 42 | float4 metallicGlossMap = texTP(_MetallicGlossMap, _MetallicGlossMap_ST, i.worldPos, i.objPos, i.btn[2], i.objNormal, _TriplanarFalloff, i.uv); 43 | float4 metallicSmoothness = getMetallicSmoothness(metallicGlossMap); 44 | float metallic = metallicSmoothness.r; 45 | float reflectance = _Reflectance; 46 | float roughness = max(metallicSmoothness.a, getGeometricSpecularAA(worldNormal)); 47 | albedo.rgb *= 1-metallic; 48 | //---- 49 | 50 | //CURVATURE THICKNESS MAP 51 | float4 curvatureThicknessMap = 0; 52 | float4 subsurfaceColorMap = 0; 53 | if(_SubsurfaceMethod == 1) 54 | { 55 | //Contains Curvature, Thickness, and a Mask for both. 56 | curvatureThicknessMap = texTP(_CurvatureThicknessMap, _CurvatureThicknessMap_ST, i.worldPos, i.objPos, i.btn[2], i.objNormal, _TriplanarFalloff, i.uv); 57 | //SUBSURFACE COLOR TEXTURE 58 | subsurfaceColorMap = texTP(_CurvatureThicknessMap, _CurvatureThicknessMap_ST, i.worldPos, i.objPos, i.btn[2], i.objNormal, _TriplanarFalloff, i.uv); 59 | } 60 | 61 | //OCCLUSION 62 | float4 occlusionMap = texTP(_OcclusionMap, _OcclusionMap_ST, i.worldPos, i.objPos, i.btn[2], i.objNormal, _TriplanarFalloff, i.uv); 63 | float4 occlusion = lerp(_OcclusionColor, 1, occlusionMap); 64 | //---- 65 | 66 | //EMISSION 67 | float4 emission = 0; 68 | #if defined(UNITY_PASS_FORWARDBASE) || defined(UNITY_PASS_META) // Emissions should only happen in the forward base pass (and meta pass) 69 | float4 emissionMap = texTP(_EmissionMap, _EmissionMap_ST, i.worldPos, i.objPos, i.btn[2], i.objNormal, _TriplanarFalloff, i.uv); 70 | emission = emissionMap * _EmissionColor; 71 | #endif 72 | //---- 73 | 74 | //CLEARCOAT MAP 75 | float4 clearcoatMap = texTP(_ClearcoatMap, _ClearcoatMap_ST, i.worldPos, i.objPos, i.btn[2], i.objNormal, _TriplanarFalloff, i.uv); 76 | float4 clearcoatReflectivitySmoothness = getClearcoatSmoothness(clearcoatMap); 77 | float clearcoatReflectivity = clearcoatReflectivitySmoothness.r; 78 | float clearcoatRoughness = clearcoatReflectivitySmoothness.a; 79 | //---- 80 | 81 | //LIGHTING VECTORS 82 | bool lightEnv = any(_WorldSpaceLightPos0.xyz); 83 | float3 indirectDominantColor = half3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w); 84 | float3 lightDir = getLightDir(lightEnv, i.worldPos); 85 | float3 lightCol = getLightCol(lightEnv, _LightColor0.rgb, indirectDominantColor); 86 | float3 viewDir = normalize(_WorldSpaceCameraPos - i.worldPos); 87 | float3 halfVector = normalize(lightDir + viewDir); 88 | float3 reflViewDir = getAnisotropicReflectionVector(viewDir, bitangent, tangent, worldNormal, roughness, _Anisotropy); 89 | float3 reflLightDir = reflect(lightDir, worldNormal); 90 | //---- 91 | 92 | //DOT PRODUCTS FOR LIGHTING 93 | float ndl = dot(lightDir, worldNormal); 94 | float ndl01 = ndl * 0.5 + 0.5; 95 | float unsaturatedNdl = ndl; 96 | ndl = saturate(ndl); 97 | float vdn = abs(dot(viewDir, worldNormal)); 98 | float vdh = saturate(dot(viewDir, halfVector)); 99 | float rdv = saturate(dot(reflLightDir, float4(-viewDir, 0))); 100 | float ldh = saturate(dot(lightDir, halfVector)); 101 | float ndh = saturate(dot(worldNormal, halfVector)); 102 | //---- 103 | 104 | //LIGHTING 105 | float3 diffuseNDL = ndl; //Modified for diffuse if using Subsurface Preintegrated mode, otherwise use normal Lambertian NDL. 106 | 107 | //Diffuse BRDF 108 | #if defined(LIGHTMAP_ON) 109 | float3 indirectDiffuse = 0; 110 | float3 directDiffuse = albedo * getLightmap(i.uv1, worldNormal, i.worldPos); 111 | #if defined(DYNAMICLIGHTMAP_ON) 112 | float3 realtimeLM = getRealtimeLightmap(i.uv2, worldNormal); 113 | directDiffuse += realtimeLM; 114 | #endif 115 | #else 116 | //Gather up non-important lights 117 | float3 vertexLightData = 0; 118 | #if defined(VERTEXLIGHT_ON) && !defined(LIGHTMAP_ON) 119 | VertexLightInformation vLight = (VertexLightInformation)0; 120 | float4 vertexLightAtten = float4(0,0,0,0); 121 | float3 vertexLightColor = get4VertexLightsColFalloff(vLight, worldPos, worldNormal, vertexLightAtten); 122 | float3 vertexLightDir = getVertexLightsDir(vLight, worldPos, vertexLightAtten); 123 | for(int i = 0; i < 4; i++) 124 | { 125 | vertexLightData += saturate(dot(vLight.Direction[i], worldNormal)) * vLight.ColorFalloff[i]; 126 | } 127 | #endif 128 | float3 indirectDiffuse = (getIndirectDiffuse(worldNormal) * occlusion) + vertexLightData; 129 | 130 | if(_SubsurfaceMethod == 1) 131 | { 132 | //Calculates a Subsurface Scattering LUT with some cursed ass shit. 133 | float3 subsurfaceColor = _SubsurfaceScatteringColor * subsurfaceColorMap * lerp(1, diffuse, _SubsurfaceInheritDiffuse); 134 | float3 transmission = getTransmission(subsurfaceColor, attenuation, diffuse, 1-curvatureThicknessMap.g, lightDir, viewDir, worldNormal, lightCol, indirectDiffuse); 135 | float3 subsurface = getSubsurfaceFalloff(ndl01, unsaturatedNdl, curvatureThicknessMap, subsurfaceColor); 136 | diffuseNDL = lerp(subsurface + transmission, ndl, curvatureThicknessMap.b); 137 | } 138 | 139 | float3 atten = (attenuation * diffuseNDL * lightCol) + indirectDiffuse; 140 | float3 directDiffuse = (albedo * atten); 141 | #endif 142 | //---- 143 | 144 | //Specular BRDF 145 | // This is a pretty big hack of a specular brdf but I didn't like other implementations entirely. This is my own, mixed with some other stuff from other places. 146 | // This probably means it breaks energy conservation, fails the furnace test, etc, but, in my opinion, it looks better. 147 | // This makes things look a little bit better in baked lighting by forcing a "direct" specular highlight to always be visible by getting the dominant light probe direction and color. 148 | float3 f0 = 0.16 * reflectance * reflectance * (1.0 - metallic) + diffuse * metallic; 149 | float3 fresnel = lerp(F_Schlick(vdn, f0), f0, metallic); //Kill fresnel on metallics, it looks bad. 150 | float3 directSpecular = getDirectSpecular(roughness, ndh, vdn, ndl, ldh, f0, halfVector, tangent, bitangent, _Anisotropy) * attenuation * ndl * lightCol; 151 | float3 indirectSpecular = getIndirectSpecular(metallic, roughness, reflViewDir, worldPos, directDiffuse, worldNormal) * lerp(fresnel, f0, roughness); //Lightmap is stored in directDiffuse and used for specular lightmap occlusion 152 | 153 | //TODO: Move this into its own function... 154 | float3 vertexLightSpec = 0; 155 | float3 vertexLightClearcoatSpec = 0; 156 | #if defined(VERTEXLIGHT_ON) && !defined(LIGHTMAP_ON) 157 | [UNROLL(4)] 158 | for(int i = 0; i < 4; i++) 159 | { 160 | // All of these need to be recalculated for each individual light to treat them how we want to treat them. 161 | float3 vHalfVector = normalize(vLight.Direction[i] + viewDir); 162 | float vNDL = saturate(dot(vLight.Direction[i], worldNormal)); 163 | float vLDH = saturate(dot(vLight.Direction[i], vHalfVector)); 164 | float vNDH = saturate(dot(worldNormal, vHalfVector)); 165 | float vCndl = saturate(dot(vLight.Direction[i], unmodifiedWorldNormal)); 166 | float vCvdn = abs(dot(viewDir, unmodifiedWorldNormal)); 167 | float vCndh = saturate(dot(unmodifiedWorldNormal, vHalfVector)); 168 | 169 | float3 vLspec = getDirectSpecular(roughness, vNDH, vdn, vNDL, vLDH, f0, vHalfVector, tangent, bitangent, _Anisotropy) * vNDL; 170 | float3 vLspecCC = getDirectSpecular(clearcoatRoughness, vCndh, vCvdn, vCndl, vLDH, f0, vHalfVector, unmodifiedTangent, unmodifiedBitangent, _ClearcoatAnisotropy) * vNDL; 171 | vertexLightSpec += vLspec * vLight.ColorFalloff[i]; 172 | vertexLightClearcoatSpec += vLspecCC * vLight.ColorFalloff[i]; 173 | } 174 | #endif 175 | float3 specular = (indirectSpecular + directSpecular + vertexLightSpec); 176 | //---- 177 | 178 | //Clearcoat BRDF 179 | float3 creflViewDir = getAnisotropicReflectionVector(viewDir, unmodifiedBitangent, unmodifiedTangent, unmodifiedWorldNormal, roughness, _ClearcoatAnisotropy); 180 | float cndl = saturate(dot(lightDir, unmodifiedWorldNormal)); 181 | float cvdn = abs(dot(viewDir, unmodifiedWorldNormal)); 182 | float cndh = saturate(dot(unmodifiedWorldNormal, halfVector)); 183 | 184 | float3 clearcoatf0 = 0.16 * clearcoatReflectivity * clearcoatReflectivity; 185 | float3 clearcoatFresnel = F_Schlick(cvdn, clearcoatf0); 186 | float3 clearcoatDirectSpecular = getDirectSpecular(clearcoatRoughness, cndh, cvdn, cndl, ldh, clearcoatf0, halfVector, unmodifiedTangent, unmodifiedBitangent, _ClearcoatAnisotropy) * attenuation * cndl * lightCol; 187 | float3 clearcoatIndirectSpecular = getIndirectSpecular(0, clearcoatRoughness, creflViewDir, worldPos, directDiffuse, unmodifiedWorldNormal); 188 | float3 clearcoat = (clearcoatDirectSpecular + clearcoatIndirectSpecular + vertexLightClearcoatSpec) * clearcoatReflectivity * clearcoatFresnel; 189 | //---- 190 | 191 | //TODO: Implement subsurface scattering 192 | float3 litPixel = directDiffuse + ((specular + clearcoat) * occlusion) + emission; 193 | return float4(max(0, litPixel), alpha); 194 | } -------------------------------------------------------------------------------- /XSShaderTemplates/Templates/Shared/LightingBRDF.cginc.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 1f01519f9c4bc934d98b5ac0ddcc0b3b 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: [] 6 | nonModifiableTextures: [] 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /XSShaderTemplates/Templates/Shared/LightingFunctions.cginc: -------------------------------------------------------------------------------- 1 | //This file contains all of the neccisary functions for lighting to work a'la standard shading. 2 | //Feel free to add to this. 3 | #define grayscaleVec float3(0.2125, 0.7154, 0.0721) 4 | float pow5(float a) 5 | { 6 | return a * a * a * a * a; 7 | } 8 | 9 | float sq(float a) 10 | { 11 | return a*a; 12 | } 13 | 14 | float D_GGX(float NoH, float roughness) 15 | { 16 | float a2 = roughness * roughness; 17 | float f = (NoH * a2 - NoH) * NoH + 1.0; 18 | return a2 / (UNITY_PI * f * f); 19 | } 20 | 21 | float D_GGX_Anisotropic(float NoH, const float3 h, const float3 t, const float3 b, float at, float ab) 22 | { 23 | float ToH = dot(t, h); 24 | float BoH = dot(b, h); 25 | float a2 = at * ab; 26 | float3 v = float3(ab * ToH, at * BoH, a2 * NoH); 27 | float v2 = dot(v, v); 28 | float w2 = a2 / v2; 29 | return a2 * w2 * w2 * (1.0 / UNITY_PI); 30 | } 31 | 32 | float V_Kelemen(float LoH) { 33 | return 0.25 / (LoH * LoH); 34 | } 35 | 36 | float3 F_Schlick(float u, float3 f0) 37 | { 38 | return f0 + (1.0 - f0) * pow(1.0 - u, 5.0); 39 | } 40 | 41 | float3 F_Schlick(const float3 f0, float f90, float VoH) 42 | { 43 | // Schlick 1994, "An Inexpensive BRDF Model for Physically-Based Rendering" 44 | return f0 + (f90 - f0) * pow5(1.0 - VoH); 45 | } 46 | 47 | float3 F_FresnelLerp (float3 F0, float3 F90, float cosA) 48 | { 49 | float t = pow5(1 - cosA); // ala Schlick interpoliation 50 | return lerp (F0, F90, t); 51 | } 52 | 53 | float Fd_Burley(float roughness, float NoV, float NoL, float LoH) 54 | { 55 | // Burley 2012, "Physically-Based Shading at Disney" 56 | float f90 = 0.5 + 2.0 * roughness * LoH * LoH; 57 | float lightScatter = F_Schlick(1.0, f90, NoL); 58 | float viewScatter = F_Schlick(1.0, f90, NoV); 59 | return lightScatter * viewScatter * (1.0 / UNITY_PI); 60 | } 61 | 62 | float shEvaluateDiffuseL1Geomerics(float L0, float3 L1, float3 n) 63 | { 64 | // average energy 65 | float R0 = L0; 66 | 67 | // avg direction of incoming light 68 | float3 R1 = 0.5f * L1; 69 | 70 | // directional brightness 71 | float lenR1 = length(R1); 72 | 73 | // linear angle between normal and direction 0-1 74 | //float q = 0.5f * (1.0f + dot(R1 / lenR1, n)); 75 | //float q = dot(R1 / lenR1, n) * 0.5 + 0.5; 76 | float q = dot(normalize(R1), n) * 0.5 + 0.5; 77 | 78 | // power for q 79 | // lerps from 1 (linear) to 3 (cubic) based on directionality 80 | float p = 1.0f + 2.0f * lenR1 / R0; 81 | 82 | // dynamic range constant 83 | // should vary between 4 (highly directional) and 0 (ambient) 84 | float a = (1.0f - lenR1 / R0) / (1.0f + lenR1 / R0); 85 | 86 | return R0 * (a + (1.0f - a) * (p + 1.0f) * pow(q, p)); 87 | } 88 | 89 | // Energy conserving wrap diffuse term, does *not* include the divide by pi 90 | float Fd_Wrap(float NoL, float w) { 91 | return saturate((NoL + w) / sq(1.0 + w)); 92 | } 93 | 94 | float V_SmithGGXCorrelated(float NoV, float NoL, float a) 95 | { 96 | float a2 = a * a; 97 | float GGXL = NoV * sqrt((-NoL * a2 + NoL) * NoL + a2); 98 | float GGXV = NoL * sqrt((-NoV * a2 + NoV) * NoV + a2); 99 | return 0.5 / (GGXV + GGXL); 100 | } 101 | 102 | float Fd_Lambert() 103 | { 104 | return 1.0 / UNITY_PI; 105 | } 106 | 107 | //Lifted vertex light support from XSToon: https://github.com/Xiexe/Xiexes-Unity-Shaders 108 | //Returns the average color of all lights and writes to a struct contraining individual colors 109 | float3 get4VertexLightsColFalloff(inout VertexLightInformation vLight, float3 worldPos, float3 normal, inout float4 vertexLightAtten) 110 | { 111 | float3 lightColor = 0; 112 | #if defined(VERTEXLIGHT_ON) 113 | float4 toLightX = unity_4LightPosX0 - worldPos.x; 114 | float4 toLightY = unity_4LightPosY0 - worldPos.y; 115 | float4 toLightZ = unity_4LightPosZ0 - worldPos.z; 116 | 117 | float4 lengthSq = 0; 118 | lengthSq += toLightX * toLightX; 119 | lengthSq += toLightY * toLightY; 120 | lengthSq += toLightZ * toLightZ; 121 | 122 | float4 atten = 1.0 / (1.0 + lengthSq * unity_4LightAtten0); 123 | float4 atten2 = saturate(1 - (lengthSq * unity_4LightAtten0 / 25)); 124 | atten = min(atten, atten2 * atten2); 125 | // Cleaner, nicer looking falloff. Also prevents the "Snapping in" effect that Unity's normal integration of vertex lights has. 126 | vertexLightAtten = atten; 127 | 128 | lightColor.rgb += unity_LightColor[0] * atten.x; 129 | lightColor.rgb += unity_LightColor[1] * atten.y; 130 | lightColor.rgb += unity_LightColor[2] * atten.z; 131 | lightColor.rgb += unity_LightColor[3] * atten.w; 132 | 133 | vLight.ColorFalloff[0] = unity_LightColor[0] * atten.x; 134 | vLight.ColorFalloff[1] = unity_LightColor[1] * atten.y; 135 | vLight.ColorFalloff[2] = unity_LightColor[2] * atten.z; 136 | vLight.ColorFalloff[3] = unity_LightColor[3] * atten.w; 137 | 138 | vLight.Attenuation[0] = atten.x; 139 | vLight.Attenuation[1] = atten.y; 140 | vLight.Attenuation[2] = atten.z; 141 | vLight.Attenuation[3] = atten.w; 142 | #endif 143 | return lightColor; 144 | } 145 | 146 | //Returns the average direction of all lights and writes to a struct contraining individual directions 147 | float3 getVertexLightsDir(inout VertexLightInformation vLights, float3 worldPos, float4 vertexLightAtten) 148 | { 149 | float3 dir = float3(0,0,0); 150 | float3 toLightX = float3(unity_4LightPosX0.x, unity_4LightPosY0.x, unity_4LightPosZ0.x); 151 | float3 toLightY = float3(unity_4LightPosX0.y, unity_4LightPosY0.y, unity_4LightPosZ0.y); 152 | float3 toLightZ = float3(unity_4LightPosX0.z, unity_4LightPosY0.z, unity_4LightPosZ0.z); 153 | float3 toLightW = float3(unity_4LightPosX0.w, unity_4LightPosY0.w, unity_4LightPosZ0.w); 154 | 155 | float3 dirX = toLightX - worldPos; 156 | float3 dirY = toLightY - worldPos; 157 | float3 dirZ = toLightZ - worldPos; 158 | float3 dirW = toLightW - worldPos; 159 | 160 | dirX *= length(toLightX) * vertexLightAtten.x; 161 | dirY *= length(toLightY) * vertexLightAtten.y; 162 | dirZ *= length(toLightZ) * vertexLightAtten.z; 163 | dirW *= length(toLightW) * vertexLightAtten.w; 164 | 165 | vLights.Direction[0] = dirX; 166 | vLights.Direction[1] = dirY; 167 | vLights.Direction[2] = dirZ; 168 | vLights.Direction[3] = dirW; 169 | 170 | dir = (dirX + dirY + dirZ + dirW) / 4; 171 | return dir; 172 | } 173 | 174 | float4 getMetallicSmoothness(float4 metallicGlossMap) 175 | { 176 | float roughness = 1-(_Glossiness * metallicGlossMap.a); 177 | float metallic = metallicGlossMap.r * _Metallic; 178 | float reflectance = metallicGlossMap.g * _Reflectance; 179 | return float4(metallic, reflectance, 0, roughness); 180 | } 181 | 182 | float3 getIndirectDiffuse(float3 normal) 183 | { 184 | float3 indirectDiffuse; 185 | if(_LightProbeMethod == 0) 186 | { 187 | indirectDiffuse = max(0, ShadeSH9(float4(normal, 1))); 188 | } 189 | else 190 | { 191 | float3 L0 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w); 192 | indirectDiffuse.r = shEvaluateDiffuseL1Geomerics(L0.r, unity_SHAr.xyz, normal); 193 | indirectDiffuse.g = shEvaluateDiffuseL1Geomerics(L0.g, unity_SHAg.xyz, normal); 194 | indirectDiffuse.b = shEvaluateDiffuseL1Geomerics(L0.b, unity_SHAb.xyz, normal); 195 | } 196 | return max(0, indirectDiffuse); 197 | } 198 | 199 | //Reflection direction, worldPos, unity_SpecCube0_ProbePosition, unity_SpecCube0_BoxMin, unity_SpecCube0_BoxMax 200 | float3 getReflectionUV(float3 direction, float3 position, float4 cubemapPosition, float3 boxMin, float3 boxMax) 201 | { 202 | #if UNITY_SPECCUBE_BOX_PROJECTION 203 | if (cubemapPosition.w > 0) { 204 | float3 factors = ((direction > 0 ? boxMax : boxMin) - position) / direction; 205 | float scalar = min(min(factors.x, factors.y), factors.z); 206 | direction = direction * scalar + (position - cubemapPosition); 207 | } 208 | #endif 209 | return direction; 210 | } 211 | 212 | float3 getBoxProjection (float3 direction, float3 position, float4 cubemapPosition, float3 boxMin, float3 boxMax) 213 | { 214 | // #if defined(UNITY_SPECCUBE_BOX_PROJECTION) // For some reason this doesn't work? 215 | if (cubemapPosition.w > 0) { 216 | float3 factors = 217 | ((direction > 0 ? boxMax : boxMin) - position) / direction; 218 | float scalar = min(min(factors.x, factors.y), factors.z); 219 | direction = direction * scalar + (position - cubemapPosition); 220 | } 221 | // #endif 222 | return direction; 223 | } 224 | 225 | float3 getIndirectSpecular(float metallic, float roughness, float3 reflDir, float3 worldPos, float3 lightmap, float3 normal) 226 | { 227 | float3 spec = float3(0,0,0); 228 | #if defined(UNITY_PASS_FORWARDBASE) 229 | float3 indirectSpecular; 230 | Unity_GlossyEnvironmentData envData; 231 | envData.roughness = roughness; 232 | envData.reflUVW = getBoxProjection( 233 | reflDir, worldPos, 234 | unity_SpecCube0_ProbePosition, 235 | unity_SpecCube0_BoxMin, unity_SpecCube0_BoxMax 236 | ); 237 | 238 | float3 probe0 = Unity_GlossyEnvironment(UNITY_PASS_TEXCUBE(unity_SpecCube0), unity_SpecCube0_HDR, envData); 239 | float interpolator = unity_SpecCube0_BoxMin.w; 240 | UNITY_BRANCH 241 | if (interpolator < 0.99999) 242 | { 243 | envData.reflUVW = getBoxProjection( 244 | reflDir, worldPos, 245 | unity_SpecCube1_ProbePosition, 246 | unity_SpecCube1_BoxMin, unity_SpecCube1_BoxMax 247 | ); 248 | float3 probe1 = Unity_GlossyEnvironment(UNITY_PASS_TEXCUBE_SAMPLER(unity_SpecCube1, unity_SpecCube0), unity_SpecCube0_HDR, envData); 249 | indirectSpecular = lerp(probe1, probe0, interpolator); 250 | } 251 | else 252 | { 253 | indirectSpecular = probe0; 254 | } 255 | float horizon = min(1 + dot(reflDir, normal), 1); 256 | indirectSpecular *= horizon * horizon; 257 | 258 | spec = indirectSpecular; 259 | #if defined(LIGHTMAP_ON) 260 | float specMultiplier = max(0, lerp(1, pow(length(lightmap), _SpecLMOcclusionAdjust), _SpecularLMOcclusion)); 261 | spec *= specMultiplier; 262 | #endif 263 | #endif 264 | return spec; 265 | } 266 | 267 | float3 getDirectSpecular(float roughness, float ndh, float vdn, float ndl, float ldh, float3 f0, float3 halfVector, float3 tangent, float3 bitangent, float anisotropy) 268 | { 269 | #if !defined(LIGHTMAP_ON) 270 | float rough = max(roughness * roughness, 0.0045); 271 | float Dn = D_GGX(ndh, rough); 272 | float3 F = F_Schlick(ldh, f0); 273 | float V = V_SmithGGXCorrelated(vdn, ndl, rough); 274 | float3 directSpecularNonAniso = max(0, (Dn * V) * F); 275 | 276 | anisotropy *= saturate(5.0 * roughness); 277 | float at = max(rough * (1.0 + anisotropy), 0.001); 278 | float ab = max(rough * (1.0 - anisotropy), 0.001); 279 | float D = D_GGX_Anisotropic(ndh, halfVector, tangent, bitangent, at, ab); 280 | float3 directSpecularAniso = max(0, (D * V) * F); 281 | 282 | return lerp(directSpecularNonAniso, directSpecularAniso, saturate(abs(_Anisotropy * 100)) ) * 3; // * 100 to prevent blending, blend because otherwise tangents are fucked on lightmapped object 283 | #else 284 | return 0; 285 | #endif 286 | } 287 | 288 | void initBumpedNormalTangentBitangent(float4 normalMap, inout float3 bitangent, inout float3 tangent, inout float3 normal) 289 | { 290 | float3 tangentNormal = UnpackScaleNormal(normalMap, _BumpScale); 291 | float3 calcedNormal = normalize 292 | ( 293 | tangentNormal.x * tangent + 294 | tangentNormal.y * bitangent + 295 | tangentNormal.z * normal 296 | ); 297 | 298 | normal = normalize(calcedNormal); 299 | tangent = normalize(cross(normal, bitangent)); 300 | bitangent = normalize(cross(normal, tangent)); 301 | } 302 | 303 | float3 getAnisotropicReflectionVector(float3 viewDir, float3 bitangent, float3 tangent, float3 normal, float roughness, float anisotropy) 304 | { 305 | //_Anisotropy = lerp(-0.2, 0.2, sin(_Time.y / 20)); //This is pretty fun 306 | float3 anisotropicDirection = anisotropy >= 0.0 ? bitangent : tangent; 307 | float3 anisotropicTangent = cross(anisotropicDirection, viewDir); 308 | float3 anisotropicNormal = cross(anisotropicTangent, anisotropicDirection); 309 | float bendFactor = abs(anisotropy) * saturate(5.0 * roughness); 310 | float3 bentNormal = normalize(lerp(normal, anisotropicNormal, bendFactor)); 311 | return reflect(-viewDir, bentNormal); 312 | } 313 | 314 | float3 getRealtimeLightmap(float2 uv, float3 worldNormal) 315 | { 316 | float2 realtimeUV = uv * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw; 317 | float4 bakedCol = UNITY_SAMPLE_TEX2D(unity_DynamicLightmap, realtimeUV); 318 | float3 realtimeLightmap = DecodeRealtimeLightmap(bakedCol); 319 | 320 | #ifdef DIRLIGHTMAP_COMBINED 321 | float4 realtimeDirTex = UNITY_SAMPLE_TEX2D_SAMPLER(unity_DynamicDirectionality, unity_DynamicLightmap, realtimeUV); 322 | realtimeLightmap += DecodeDirectionalLightmap (realtimeLightmap, realtimeDirTex, worldNormal); 323 | #endif 324 | 325 | return realtimeLightmap * _RTLMStrength; 326 | } 327 | 328 | float3 getLightmap(float2 uv, float3 worldNormal, float3 worldPos) 329 | { 330 | float2 lightmapUV = uv * unity_LightmapST.xy + unity_LightmapST.zw; 331 | float4 bakedColorTex = UNITY_SAMPLE_TEX2D(unity_Lightmap, lightmapUV); 332 | float3 lightMap = DecodeLightmap(bakedColorTex); 333 | 334 | #ifdef DIRLIGHTMAP_COMBINED 335 | fixed4 bakedDirTex = UNITY_SAMPLE_TEX2D_SAMPLER (unity_LightmapInd, unity_Lightmap, lightmapUV); 336 | lightMap = DecodeDirectionalLightmap(lightMap, bakedDirTex, worldNormal); 337 | #endif 338 | return lightMap * _LMStrength; 339 | } 340 | 341 | // Get the most intense light Dir from probes OR from a light source. Method developed by Xiexe / Merlin 342 | float3 getLightDir(bool lightEnv, float3 worldPos) 343 | { 344 | //switch between using probes or actual light direction 345 | float3 lightDir = lightEnv ? UnityWorldSpaceLightDir(worldPos) : unity_SHAr.xyz + unity_SHAg.xyz + unity_SHAb.xyz; 346 | 347 | #if !defined(POINT) && !defined(SPOT) && !defined(VERTEXLIGHT_ON) // if the average length of the light probes is null, and we don't have a directional light in the scene, fall back to our fallback lightDir 348 | if(length(unity_SHAr.xyz*unity_SHAr.w + unity_SHAg.xyz*unity_SHAg.w + unity_SHAb.xyz*unity_SHAb.w) == 0 && length(lightDir) < 0.1) 349 | { 350 | lightDir = float4(1, 1, 1, 0); 351 | } 352 | #endif 353 | 354 | return normalize(lightDir); 355 | } 356 | 357 | float3 getLightCol(bool lightEnv, float3 lightColor, float3 indirectDominantColor) 358 | { 359 | float3 c = lightEnv ? lightColor : indirectDominantColor; 360 | return c; 361 | } 362 | 363 | float4 getClearcoatSmoothness(float4 clearcoatMap) 364 | { 365 | float roughness = 1-(_ClearcoatGlossiness * clearcoatMap.a); 366 | roughness = clamp(roughness, 0.0045, 1.0); 367 | roughness = roughness * roughness; 368 | 369 | float reflectivity = _Clearcoat * clearcoatMap.r; 370 | return float4(reflectivity, 0, 0, roughness); 371 | } 372 | 373 | float3 getClearcoat(float3 baseColor, float reflectivity, float roughness, float ldh, float ndh, float Fr, float3 Fd) 374 | { 375 | float Dc = D_GGX(roughness, ndh); 376 | float Vc = V_Kelemen(ldh); 377 | float Fc = F_Schlick(0.04, ldh) * reflectivity; 378 | float Frc = (Dc * Vc) * Fc; 379 | 380 | // account for energy loss in the base layer 381 | return baseColor * ((Fd + Fr * (1.0 - Fc)) * (1.0 - Fc) + Frc); 382 | } 383 | 384 | float2 getScreenUVs(float4 screenPos) 385 | { 386 | float2 uv = screenPos / (screenPos.w + 0.0000000001); //0.0x1 Stops division by 0 warning in console. 387 | #if UNITY_SINGLE_PASS_STEREO 388 | uv.xy *= float2(_ScreenParams.x * 2, _ScreenParams.y); 389 | #else 390 | uv.xy *= _ScreenParams.xy; 391 | #endif 392 | 393 | return uv; 394 | } 395 | 396 | float getScreenSpaceDithering(float2 screenUV) 397 | { 398 | //Iestyn's RGB dither(7 asm instructions) from Portal2 X360, slightly modified for VR 399 | float vDither = dot(float2(171.0,231.0), screenUV.xy + _Time.y).x; 400 | vDither = frac(vDither / float3(103.0, 71.0, 97.0)) - float3(0.5, 0.5, 0.5); 401 | return (vDither / 255.0) * 0.375; 402 | } 403 | 404 | float getCurvature(float3 normal, float3 pos) 405 | { 406 | float c = saturate((clamp(length(fwidth(normal.xyz)), 0.0, 1.0) / (length(fwidth(pos.xyz)) * 100) )); 407 | return c; 408 | } 409 | 410 | float3 getSubsurfaceFalloff(float ndl01, float ndl, float3 curvature, float3 subsurfaceColor) 411 | { 412 | float curva = (1/mad(curvature.r, 0.5 - 0.0625, 0.0625) - 2) / (16 - 2); 413 | float oneMinusCurva = 1.0 - curva; 414 | float x = ndl; 415 | float n = ndl01; 416 | float3 scatter = lerp(n, subsurfaceColor, saturate((1-x) * oneMinusCurva)) * smoothstep(0.2, 1, n * oneMinusCurva); 417 | scatter = lerp(scatter, n, smoothstep(0, 1.1, x)); 418 | return scatter; 419 | } 420 | 421 | float getGeometricSpecularAA(float3 normal) 422 | { 423 | float3 vNormalWsDdx = ddx(normal.xyz); 424 | float3 vNormalWsDdy = ddy(normal.xyz); 425 | float flGeometricRoughnessFactor = pow(saturate(max(dot(vNormalWsDdx.xyz,vNormalWsDdx.xyz), dot(vNormalWsDdy.xyz,vNormalWsDdy.xyz))), 0.333); 426 | return max(0, flGeometricRoughnessFactor); 427 | } 428 | 429 | //Transmission - Based on a 2011 GDC Conference from by Colin Barre-Bresebois & Marc Bouchard 430 | //Modified by Xiexe 431 | float3 getTransmission(float3 subsurfaceColor, float3 attenuation, float3 diffuseColor, float thickness, float3 lightDir, float3 viewDir, float3 normal, float3 lightCol, float3 indirectDiffuse) 432 | { 433 | float3 H = lightDir + normal * _TransmissionNormalDistortion; 434 | float VdotH = pow(saturate(dot(viewDir, -H)), _TransmissionPower) * _TransmissionScale; 435 | float3 I = attenuation * VdotH * thickness; 436 | float3 transmission = I * lightCol; 437 | return max(0, transmission * subsurfaceColor); // Make sure it doesn't go NaN 438 | } 439 | 440 | //Triplanar map a texture (Object or World space), or sample it normally. 441 | float4 texTP( sampler2D tex, float4 tillingOffset, float3 worldPos, float3 objPos, float3 worldNormal, float3 objNormal, float falloff, float2 uv) 442 | { 443 | if(_TextureSampleMode != 0) 444 | { 445 | worldPos = lerp(worldPos, objPos, _TextureSampleMode - 1); 446 | worldNormal = lerp(worldNormal, objNormal, _TextureSampleMode - 1); 447 | 448 | float3 projNormal = pow(abs(worldNormal),falloff); 449 | projNormal /= projNormal.x + projNormal.y + projNormal.z; 450 | float3 nsign = sign(worldNormal); 451 | float4 xNorm; float4 yNorm; float4 zNorm; 452 | xNorm = tex2D( tex, tillingOffset.xy * worldPos.zy * float2( nsign.x, 1.0 ) + tillingOffset.zw); 453 | yNorm = tex2D( tex, tillingOffset.xy * worldPos.xz * float2( nsign.y, 1.0 ) + tillingOffset.zw); 454 | zNorm = tex2D( tex, tillingOffset.xy * worldPos.xy * float2( -nsign.z, 1.0 ) + tillingOffset.zw); 455 | 456 | return xNorm * projNormal.x + yNorm * projNormal.y + zNorm * projNormal.z; 457 | } 458 | else{ 459 | return tex2D(tex, uv * tillingOffset.xy + tillingOffset.zw); 460 | } 461 | } 462 | 463 | inline float Dither8x8Bayer(int x, int y) 464 | { 465 | const float dither[ 64 ] = { 466 | 1, 49, 13, 61, 4, 52, 16, 64, 467 | 33, 17, 45, 29, 36, 20, 48, 32, 468 | 9, 57, 5, 53, 12, 60, 8, 56, 469 | 41, 25, 37, 21, 44, 28, 40, 24, 470 | 3, 51, 15, 63, 2, 50, 14, 62, 471 | 35, 19, 47, 31, 34, 18, 46, 30, 472 | 11, 59, 7, 55, 10, 58, 6, 54, 473 | 43, 27, 39, 23, 42, 26, 38, 22}; 474 | int r = y * 8 + x; 475 | return dither[r] / 64; 476 | } 477 | 478 | float getDither(float2 screenPos) 479 | { 480 | float dither = Dither8x8Bayer(fmod(screenPos.x, 8), fmod(screenPos.y, 8)); 481 | return dither; 482 | } 483 | 484 | void doAlpha(inout float alpha, float4 diffuse, float4 screenPos) 485 | { 486 | alpha = 1; 487 | #if defined(ALPHATEST) 488 | clip(diffuse.a - _Cutoff); 489 | #endif 490 | 491 | #if defined(DITHERED) 492 | float2 screenUV = getScreenUVs(screenPos); 493 | float dither = getDither(screenUV); 494 | clip(diffuse.a - dither); 495 | #endif 496 | 497 | #if defined(TRANSPARENT) || defined(ALPHATOCOVERAGE) 498 | alpha = diffuse.a; //should be maintex * color 499 | #endif 500 | } -------------------------------------------------------------------------------- /XSShaderTemplates/Templates/Shared/LightingFunctions.cginc.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 316df3fdf38d1ea498db19ef7524ac75 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: [] 6 | nonModifiableTextures: [] 7 | userData: 8 | assetBundleName: 9 | assetBundleVariant: 10 | -------------------------------------------------------------------------------- /XSShaderTemplates/Templates/Shared/Properties.txt: -------------------------------------------------------------------------------- 1 | [Header(MAIN)] 2 | [Enum(Unity Default, 0, Non Linear, 1)]_LightProbeMethod("Light Probe Sampling", Int) = 0 3 | [Enum(UVs, 0, Triplanar World, 1, Triplanar Object, 2)]_TextureSampleMode("Texture Mode", Int) = 0 4 | _TriplanarFalloff("Triplanar Blend", Range(0.5,1)) = 1 5 | _MainTex ("Main Texture", 2D) = "white" {} 6 | _Color ("Color", Color) = (1,1,1,1) 7 | //#CUTOUT!_Cutoff ("Alpha Cutoff", Range(0,1)) = 0.5 8 | 9 | [Space(16)] 10 | [Header(NORMALS)] 11 | _BumpMap("Normal Map", 2D) = "bump" {} 12 | _BumpScale("Normal Scale", Range(-1,1)) = 1 13 | 14 | [Space(16)] 15 | [Header(METALLIC)] 16 | _MetallicGlossMap("Metallic Map", 2D) = "white" {} 17 | [Gamma] _Metallic("Metallic", Range(0,1)) = 0 18 | _Glossiness("Smoothness", Range(0,1)) = 0 19 | _Reflectance("Reflectance", Range(0,1)) = 0.5 20 | _Anisotropy("Anisotropy", Range(-1,1)) = 0 21 | 22 | [Space(16)] 23 | [Header(OCCLUSION)] 24 | _OcclusionMap("Occlusion Map", 2D) = "white" {} 25 | _OcclusionColor("Occlusion Color", Color) = (0,0,0,1) 26 | 27 | [Space(16)] 28 | [Header(SUBSURFACE)] 29 | [Enum(Off, 0, Estimate, 1)]_SubsurfaceMethod("Subsurface Scattering Method", Int) = 0 30 | _CurvatureThicknessMap("Curvature Thickness Map", 2D) = "gray" {} 31 | _SubsurfaceColorMap("Subsurface Color Map", 2D) = "white" {} 32 | _SubsurfaceScatteringColor("Subsurface Color", Color) = (1,1,1,1) 33 | _SubsurfaceInheritDiffuse("Subsurface Inherit Diffuse", Range(0,1)) = 0 34 | _TransmissionNormalDistortion("Transmission Distortion", Range(0,3)) = 1 35 | _TransmissionPower("Transmission Power", Range(0,3)) = 1 36 | _TransmissionScale("Transmission Scale", Range(0,3)) = 0.1 37 | 38 | [Space(16)] 39 | [Header(EMISSION)] 40 | _EmissionMap("Emission Map", 2D) = "white" {} 41 | [HDR]_EmissionColor("Emission Color", Color) = (0,0,0,1) 42 | 43 | [Space(16)] 44 | [Header(CLEARCOAT)] 45 | _ClearcoatMap("Clearcoat Map", 2D) = "white" {} 46 | _Clearcoat("Clearcoat", Range(0,1)) = 0 47 | _ClearcoatGlossiness("Clearcoat Smoothness", Range(0,1)) = 0.5 48 | _ClearcoatAnisotropy("Clearcoat Anisotropy", Range(-1,1)) = 0 49 | 50 | //#GEOM![Space(16)] 51 | //#GEOM![Header(GEOMETRY SETTINGS)] 52 | //#GEOM!_VertexOffset("Face Offset", float) = 0 53 | 54 | //#TESS![Space(16)] 55 | //#TESS![Header(GEOMETRYTESSELLATION SETTINGS)] 56 | //#TESS![Enum(Uniform, 0, Edge Length, 1, Distance, 2)]_TessellationMode("Tessellation Mode", Int) = 1 57 | //#TESS!_TessellationUniform("Tessellation Factor", Range(0,1)) = 0.05 58 | //#TESS!_TessClose("Tessellation Close", Float) = 10 59 | //#TESS!_TessFar("Tessellation Far", Float) = 50 60 | 61 | [Space(16)] 62 | [Header(LIGHTMAPPING HACKS)] 63 | _SpecularLMOcclusion("Specular Occlusion", Range(0,1)) = 0 64 | _SpecLMOcclusionAdjust("Spec Occlusion Sensitiviy", Range(0,1)) = 0.2 65 | _LMStrength("Lightmap Strength", Range(0,1)) = 1 66 | _RTLMStrength("Realtime Lightmap Strength", Range(0,1)) = 1 -------------------------------------------------------------------------------- /XSShaderTemplates/Templates/Shared/Properties.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: a5f23bd9db267924d9bb64d8e8ce6492 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /XSShaderTemplates/Templates/TessellatedGeometry_Lit.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 715b6de0c7944d249b4c32a7b12a0cde 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /XSShaderTemplates/Templates/TessellatedGeometry_Lit/TessellatedGeometry_Lit.txt: -------------------------------------------------------------------------------- 1 | Shader "Template/Tessellated" 2 | { 3 | Properties 4 | { 5 | $PROPERTIES#TESS#GEOM 6 | } 7 | 8 | SubShader 9 | { 10 | $TAGS 11 | $BLENDMODE 12 | 13 | Pass 14 | { 15 | Tags{"LightMode"="ForwardBase"} 16 | 17 | CGPROGRAM 18 | #include "UnityCG.cginc" 19 | #include "AutoLight.cginc" 20 | #include "Lighting.cginc" 21 | #pragma vertex vert 22 | #pragma hull hull 23 | #pragma domain domain 24 | #pragma geometry geom 25 | #pragma fragment frag 26 | #pragma multi_compile _ VERTEXLIGHT_ON 27 | #pragma multi_compile_fwdbase 28 | #define GEOMETRY 29 | $BLENDDEFINE 30 | 31 | #ifndef UNITY_PASS_FORWARDBASE 32 | #define UNITY_PASS_FORWARDBASE 33 | #endif 34 | 35 | #pragma target 4.6 36 | 37 | struct vertexInput { 38 | float4 vertex : POSITION; 39 | float2 uv : TEXCOORD0; 40 | float2 uv1 : TEXCOORD1; 41 | float2 uv2 : TEXCOORD2; 42 | float3 normal : NORMAL; 43 | float4 tangent : TANGENT; 44 | }; 45 | 46 | struct vertexOutput { 47 | float4 vertex : POSITION; 48 | float2 uv : TEXCOORD0; 49 | float2 uv1 : TEXCOORD1; 50 | float2 uv2 : TEXCOORD2; 51 | float3 normal : NORMAL; 52 | float4 tangent : TANGENT; 53 | }; 54 | 55 | struct g2f { 56 | float4 pos : SV_POSITION; 57 | float2 uv : TEXCOORD0; 58 | float2 uv1 : TEXCOORD1; 59 | float2 uv2 : TEXCOORD2; 60 | float3 btn[3] : TEXCOORD3; //2 3; 61 | float4 worldPos : TEXCOORD6; 62 | float3 objPos : TEXCOORD7; 63 | float3 objNormal : TEXCOORD8; 64 | float4 screenPos : TEXCOORD9; 65 | SHADOW_COORDS(10) 66 | }; 67 | 68 | #include "Defines.cginc" 69 | #include "LightingFunctions.cginc" 70 | #include "LightingBRDF.cginc" 71 | #include "VertFragTessGeom.cginc" 72 | ENDCG 73 | } 74 | 75 | Pass 76 | { 77 | Tags{"LightMode"="ForwardAdd"} 78 | Blend One One 79 | ZWrite Off 80 | CGPROGRAM 81 | #include "UnityCG.cginc" 82 | #include "AutoLight.cginc" 83 | #include "Lighting.cginc" 84 | #pragma vertex vert 85 | #pragma hull hull 86 | #pragma domain domain 87 | #pragma geometry geom 88 | #pragma fragment frag 89 | #pragma multi_compile_fwdadd_fullshadows 90 | #define GEOMETRY 91 | $BLENDDEFINE 92 | 93 | #ifndef UNITY_PASS_FORWARDADD 94 | #define UNITY_PASS_FORWARDADD 95 | #endif 96 | 97 | #pragma target 4.6 98 | 99 | struct vertexInput { 100 | float4 vertex : POSITION; 101 | float2 uv : TEXCOORD0; 102 | float3 normal : NORMAL; 103 | float4 tangent : TANGENT; 104 | }; 105 | 106 | struct vertexOutput { 107 | float4 vertex : POSITION; 108 | float2 uv : TEXCOORD0; 109 | float3 normal : NORMAL; 110 | float4 tangent : TANGENT; 111 | }; 112 | 113 | struct g2f { 114 | float4 pos : SV_POSITION; 115 | float2 uv : TEXCOORD0; 116 | float3 btn[3] : TEXCOORD1; //2 3; 117 | float4 worldPos : TEXCOORD4; 118 | float3 objPos : TEXCOORD5; 119 | float3 objNormal : TEXCOORD6; 120 | float4 screenPos : TEXCOORD7; 121 | SHADOW_COORDS(8) 122 | }; 123 | 124 | #include "Defines.cginc" 125 | #include "LightingFunctions.cginc" 126 | #include "LightingBRDF.cginc" 127 | #include "VertFragTessGeom.cginc" 128 | ENDCG 129 | } 130 | 131 | Pass 132 | { 133 | Tags{"LightMode"="ShadowCaster"} 134 | CGPROGRAM 135 | #include "UnityCG.cginc" 136 | #include "AutoLight.cginc" 137 | #include "Lighting.cginc" 138 | #pragma vertex vert 139 | #pragma hull hull 140 | #pragma domain domain 141 | #pragma geometry geom 142 | #pragma fragment frag 143 | #pragma multi_compile_shadowcaster 144 | $BLENDDEFINE 145 | 146 | #ifndef UNITY_PASS_SHADOWCASTER 147 | #define UNITY_PASS_SHADOWCASTER 148 | #endif 149 | 150 | #pragma target 4.6 151 | 152 | struct vertexInput { 153 | float4 vertex : POSITION; 154 | float2 uv : TEXCOORD0; 155 | float3 normal : NORMAL; 156 | float4 tangent : TANGENT; 157 | }; 158 | 159 | struct vertexOutput { 160 | float4 vertex : POSITION; 161 | float2 uv : TEXCOORD0; 162 | float3 normal : NORMAL; 163 | float4 tangent : TANGENT; 164 | }; 165 | 166 | struct g2f { 167 | float4 pos : SV_POSITION; 168 | float2 uv : TEXCOORD0; 169 | float3 btn[3] : TEXCOORD1; //2 3; 170 | float4 worldPos : TEXCOORD4; 171 | float3 objPos : TEXCOORD5; 172 | float3 objNormal : TEXCOORD6; 173 | float4 screenPos : TEXCOORD7; 174 | }; 175 | 176 | #include "Defines.cginc" 177 | #include "LightingFunctions.cginc" 178 | #include "VertFragTessGeom.cginc" 179 | ENDCG 180 | } 181 | } 182 | } 183 | -------------------------------------------------------------------------------- /XSShaderTemplates/Templates/TessellatedGeometry_Lit/TessellatedGeometry_Lit.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: dcf6fab605b762d4fa594cbec6238166 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /XSShaderTemplates/Templates/TessellatedGeometry_Lit/Tessellation.cginc: -------------------------------------------------------------------------------- 1 | // Tessellation programs based on this article by Catlike Coding: 2 | // https://catlikecoding.com/unity/tutorials/advanced-rendering/tessellation/ 3 | 4 | float UnityDistanceFromPlane (float3 pos, float4 plane) 5 | { 6 | float d = dot (float4(pos,1.0f), plane); 7 | return d; 8 | } 9 | 10 | // Returns true if triangle with given 3 world positions is outside of camera's view frustum. 11 | // cullEps is distance outside of frustum that is still considered to be inside (i.e. max displacement) 12 | bool UnityWorldViewFrustumCull (float3 wpos0, float3 wpos1, float3 wpos2, float cullEps) 13 | { 14 | float4 planeTest; 15 | 16 | // left 17 | planeTest.x = (( UnityDistanceFromPlane(wpos0, unity_CameraWorldClipPlanes[0]) > -cullEps) ? 1.0f : 0.0f ) + 18 | (( UnityDistanceFromPlane(wpos1, unity_CameraWorldClipPlanes[0]) > -cullEps) ? 1.0f : 0.0f ) + 19 | (( UnityDistanceFromPlane(wpos2, unity_CameraWorldClipPlanes[0]) > -cullEps) ? 1.0f : 0.0f ); 20 | // right 21 | planeTest.y = (( UnityDistanceFromPlane(wpos0, unity_CameraWorldClipPlanes[1]) > -cullEps) ? 1.0f : 0.0f ) + 22 | (( UnityDistanceFromPlane(wpos1, unity_CameraWorldClipPlanes[1]) > -cullEps) ? 1.0f : 0.0f ) + 23 | (( UnityDistanceFromPlane(wpos2, unity_CameraWorldClipPlanes[1]) > -cullEps) ? 1.0f : 0.0f ); 24 | // top 25 | planeTest.z = (( UnityDistanceFromPlane(wpos0, unity_CameraWorldClipPlanes[2]) > -cullEps) ? 1.0f : 0.0f ) + 26 | (( UnityDistanceFromPlane(wpos1, unity_CameraWorldClipPlanes[2]) > -cullEps) ? 1.0f : 0.0f ) + 27 | (( UnityDistanceFromPlane(wpos2, unity_CameraWorldClipPlanes[2]) > -cullEps) ? 1.0f : 0.0f ); 28 | // bottom 29 | planeTest.w = (( UnityDistanceFromPlane(wpos0, unity_CameraWorldClipPlanes[3]) > -cullEps) ? 1.0f : 0.0f ) + 30 | (( UnityDistanceFromPlane(wpos1, unity_CameraWorldClipPlanes[3]) > -cullEps) ? 1.0f : 0.0f ) + 31 | (( UnityDistanceFromPlane(wpos2, unity_CameraWorldClipPlanes[3]) > -cullEps) ? 1.0f : 0.0f ); 32 | 33 | // has to pass all 4 plane tests to be visible 34 | return !all (planeTest); 35 | } 36 | 37 | struct TessellationFactors 38 | { 39 | float edge[3] : SV_TessFactor; 40 | float inside : SV_InsideTessFactor; 41 | }; 42 | 43 | vertexInput vert(vertexInput v) 44 | { 45 | return v; 46 | } 47 | 48 | vertexOutput tessVert(vertexInput v) 49 | { 50 | return v; 51 | } 52 | 53 | float UnityCalcDistanceTessFactor (float4 vertex, float minDist, float maxDist, float tess) 54 | { 55 | float3 wpos = vertex.xyz; 56 | float dist = distance (wpos, _WorldSpaceCameraPos); 57 | float f = clamp(1.0 - (dist - minDist) / (maxDist - minDist), 0.01, 1.0) * tess; 58 | return f; 59 | } 60 | 61 | float4 UnityCalcTriEdgeTessFactors (float3 triVertexFactors) 62 | { 63 | float4 tess; 64 | tess.x = 0.5 * (triVertexFactors.y + triVertexFactors.z); 65 | tess.y = 0.5 * (triVertexFactors.x + triVertexFactors.z); 66 | tess.z = 0.5 * (triVertexFactors.x + triVertexFactors.y); 67 | tess.w = (triVertexFactors.x + triVertexFactors.y + triVertexFactors.z) / 3.0f; 68 | return tess; 69 | } 70 | 71 | // Distance based tessellation: 72 | // Tessellation level is "tess" before "minDist" from camera, and linearly decreases to 1 73 | // up to "maxDist" from camera. 74 | float4 UnityDistanceBasedTess (float4 v0, float4 v1, float4 v2, float minDist, float maxDist, float tess) 75 | { 76 | float3 f; 77 | f.x = UnityCalcDistanceTessFactor (v0,minDist,maxDist,tess); 78 | f.y = UnityCalcDistanceTessFactor (v1,minDist,maxDist,tess); 79 | f.z = UnityCalcDistanceTessFactor (v2,minDist,maxDist,tess); 80 | 81 | return UnityCalcTriEdgeTessFactors (f); 82 | } 83 | 84 | float TessEdgeFactor(float3 p0, float3 p1) 85 | { 86 | float edgeLength = distance(p0, p1); 87 | 88 | float3 edgeCenter = (p0 + p1) * 0.5; 89 | float viewDistance = distance(edgeCenter, _WorldSpaceCameraPos); 90 | float tessFactor = lerp(1, 0, _TessellationUniform) * 50; 91 | return edgeLength * _ScreenParams.y / (tessFactor * viewDistance) ; 92 | } 93 | 94 | TessellationFactors patchConstantFunction (InputPatch patch) 95 | { 96 | TessellationFactors f; 97 | float4 p0 = mul(unity_ObjectToWorld, patch[0].vertex); 98 | float4 p1 = mul(unity_ObjectToWorld, patch[1].vertex); 99 | float4 p2 = mul(unity_ObjectToWorld, patch[2].vertex); 100 | float bias = 0; 101 | 102 | 103 | if(UnityWorldViewFrustumCull(p0, p1, p2, bias)) 104 | { 105 | f.edge[0] = f.edge[1] = f.edge[2] = f.inside = 0; 106 | } 107 | else 108 | { 109 | if(_TessellationMode == 1) 110 | { 111 | f.edge[0] = TessEdgeFactor(p1, p2); 112 | f.edge[1] = TessEdgeFactor(p2, p0); 113 | f.edge[2] = TessEdgeFactor(p0, p1); 114 | f.inside = 115 | (TessEdgeFactor(p1, p2) + 116 | TessEdgeFactor(p2, p0) + 117 | TessEdgeFactor(p0, p1)) * (1 / 3.0); 118 | } 119 | else if(_TessellationMode == 0) 120 | { 121 | _TessellationUniform *= 50; 122 | f.edge[0] = _TessellationUniform; 123 | f.edge[1] = _TessellationUniform; 124 | f.edge[2] = _TessellationUniform; 125 | f.inside = _TessellationUniform; 126 | } 127 | else 128 | { 129 | _TessellationUniform *= 50; 130 | float4 distanceTess = UnityDistanceBasedTess(p0, p1, p2, _TessClose, _TessFar, _TessellationUniform); 131 | f.edge[0] = distanceTess; 132 | f.edge[1] = distanceTess; 133 | f.edge[2] = distanceTess; 134 | f.inside = distanceTess; 135 | } 136 | } 137 | return f; 138 | } 139 | 140 | [UNITY_domain("tri")] 141 | [UNITY_outputcontrolpoints(3)] 142 | [UNITY_outputtopology("triangle_cw")] 143 | [UNITY_partitioning("fractional_odd")] 144 | //[UNITY_partitioning("fractional_even")] 145 | //[UNITY_partitioning("pow2")] 146 | //[UNITY_partitioning("integer")] 147 | [UNITY_patchconstantfunc("patchConstantFunction")] 148 | vertexInput hull (InputPatch patch, uint id : SV_OutputControlPointID) 149 | { 150 | return patch[id]; 151 | } 152 | 153 | [UNITY_domain("tri")] 154 | vertexOutput domain(TessellationFactors factors, OutputPatch patch, float3 barycentricCoordinates : SV_DomainLocation) 155 | { 156 | vertexInput v; 157 | 158 | #define DOMAIN_INTERPOLATE(fieldName) v.fieldName = \ 159 | patch[0].fieldName * barycentricCoordinates.x + \ 160 | patch[1].fieldName * barycentricCoordinates.y + \ 161 | patch[2].fieldName * barycentricCoordinates.z; 162 | 163 | DOMAIN_INTERPOLATE(vertex) 164 | DOMAIN_INTERPOLATE(uv) 165 | #if defined(UNITY_PASS_FORWARDBASE) 166 | DOMAIN_INTERPOLATE(uv1) 167 | DOMAIN_INTERPOLATE(uv2) 168 | #endif 169 | DOMAIN_INTERPOLATE(normal) 170 | DOMAIN_INTERPOLATE(tangent) 171 | 172 | return tessVert(v); 173 | } -------------------------------------------------------------------------------- /XSShaderTemplates/Templates/TessellatedGeometry_Lit/Tessellation.cginc.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 159693caba6709f41ac6581ef553a138 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: [] 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /XSShaderTemplates/Templates/TessellatedGeometry_Lit/VertFragTessGeom.cginc: -------------------------------------------------------------------------------- 1 | #include "Tessellation.cginc" 2 | 3 | //This file contains the vertex, fragment, and Geometry functions for both the ForwardBase and Forward Add pass. 4 | #if defined(SHADOWS_CUBE) && !defined(SHADOWS_CUBE_IN_DEPTH_TEX) 5 | #define V2F_SHADOW_CASTER_NOPOS float3 vec : TEXCOORD0; 6 | #define TRANSFER_SHADOW_CASTER_NOPOS_GEOMETRY(o,opos) o.vec = mul(unity_ObjectToWorld, v[i].vertex).xyz - _LightPositionRange.xyz; opos = o.pos; 7 | #else 8 | #define V2F_SHADOW_CASTER_NOPOS 9 | #define TRANSFER_SHADOW_CASTER_NOPOS_GEOMETRY(o, opos, vertexPosition, vertexNormal) \ 10 | opos = UnityClipSpaceShadowCasterPos(vertexPosition, vertexNormal); \ 11 | opos = UnityApplyLinearShadowBias(opos); 12 | #endif 13 | 14 | [maxvertexcount(3)] 15 | void geom(triangle vertexOutput v[3], inout TriangleStream tristream) 16 | { 17 | g2f o = (g2f)0; 18 | 19 | for (int i = 0; i < 3; i++) 20 | { 21 | o.pos = UnityObjectToClipPos(v[i].vertex); 22 | o.uv = v[i].uv; 23 | #if defined(UNITY_PASS_FORWARDBASE) 24 | o.uv1 = v[i].uv1; 25 | o.uv2 = v[i].uv2; 26 | #endif 27 | 28 | float3 worldNormal = UnityObjectToWorldNormal(v[i].normal); 29 | float3 tangent = UnityObjectToWorldDir(v[i].tangent); 30 | float3 bitangent = cross(tangent, worldNormal) * v[i].tangent.w; 31 | o.btn[0] = bitangent; 32 | o.btn[1] = tangent; 33 | o.btn[2] = worldNormal; 34 | o.worldPos = mul(unity_ObjectToWorld, v[i].vertex); 35 | o.objPos = v[i].vertex; 36 | o.objNormal = v[i].normal; 37 | o.screenPos = ComputeScreenPos(o.pos); 38 | 39 | //Only pass needed things through for shadow caster 40 | #if !defined(UNITY_PASS_SHADOWCASTER) 41 | UNITY_TRANSFER_SHADOW(o, o.uv); 42 | #else 43 | TRANSFER_SHADOW_CASTER_NOPOS_GEOMETRY(o, o.pos, v[i].vertex, v[i].normal); 44 | #endif 45 | 46 | tristream.Append(o); 47 | } 48 | tristream.RestartStrip(); 49 | } 50 | 51 | fixed4 frag (g2f i) : SV_Target 52 | { 53 | //Return only this if in the shadowcaster 54 | #if defined(UNITY_PASS_SHADOWCASTER) 55 | float4 albedo = texTP(_MainTex, _MainTex_ST, i.worldPos, i.objPos, i.btn[2], i.objNormal, _TriplanarFalloff, i.uv) * _Color; 56 | float alpha; 57 | doAlpha(alpha, albedo.a, i.screenPos); 58 | SHADOW_CASTER_FRAGMENT(i); 59 | #else 60 | return CustomStandardLightingBRDF(i); 61 | #endif 62 | } -------------------------------------------------------------------------------- /XSShaderTemplates/Templates/TessellatedGeometry_Lit/VertFragTessGeom.cginc.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: ed1916e20ee12154b90673d644b98183 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: [] 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /XSShaderTemplates/Templates/Tessellated_Lit.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: af827abfe76ed8543815d2eb2d5121a4 3 | folderAsset: yes 4 | DefaultImporter: 5 | externalObjects: {} 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /XSShaderTemplates/Templates/Tessellated_Lit/Tessellated_Lit.txt: -------------------------------------------------------------------------------- 1 | Shader "Template/Tessellated" 2 | { 3 | Properties 4 | { 5 | $PROPERTIES#TESS 6 | } 7 | 8 | SubShader 9 | { 10 | $TAGS 11 | $BLENDMODE 12 | 13 | Pass 14 | { 15 | Tags{"LightMode"="ForwardBase"} 16 | 17 | CGPROGRAM 18 | #include "UnityCG.cginc" 19 | #include "AutoLight.cginc" 20 | #include "Lighting.cginc" 21 | #pragma vertex vert 22 | #pragma hull hull 23 | #pragma domain domain 24 | #pragma fragment frag 25 | #pragma multi_compile _ VERTEXLIGHT_ON 26 | #pragma multi_compile_fwdbase 27 | #define TESSELLATION 28 | $BLENDDEFINE 29 | 30 | #ifndef UNITY_PASS_FORWARDBASE 31 | #define UNITY_PASS_FORWARDBASE 32 | #endif 33 | 34 | #pragma target 4.6 35 | 36 | struct vertexInput { 37 | float4 vertex : POSITION; 38 | float2 uv : TEXCOORD0; 39 | float2 uv1 : TEXCOORD1; 40 | float2 uv2 : TEXCOORD2; 41 | float3 normal : NORMAL; 42 | float4 tangent : TANGENT; 43 | }; 44 | 45 | struct vertexOutput { 46 | float4 pos : SV_POSITION; 47 | float2 uv : TEXCOORD0; 48 | float2 uv1 : TEXCOORD1; 49 | float2 uv2 : TEXCOORD2; 50 | float3 btn[3] : TEXCOORD3; //2 3; 51 | float4 worldPos : TEXCOORD6; 52 | float3 objPos : TEXCOORD7; 53 | float3 objNormal : TEXCOORD8; 54 | float4 screenPos : TEXCOORD9; 55 | SHADOW_COORDS(10) 56 | }; 57 | 58 | #include "Defines.cginc" 59 | #include "LightingFunctions.cginc" 60 | #include "LightingBRDF.cginc" 61 | #include "VertFragTess.cginc" 62 | ENDCG 63 | } 64 | 65 | Pass 66 | { 67 | Tags{"LightMode"="ForwardAdd"} 68 | Blend One One 69 | ZWrite Off 70 | CGPROGRAM 71 | #include "UnityCG.cginc" 72 | #include "AutoLight.cginc" 73 | #include "Lighting.cginc" 74 | #pragma vertex vert 75 | #pragma hull hull 76 | #pragma domain domain 77 | #pragma fragment frag 78 | #pragma multi_compile_fwdadd_fullshadows 79 | #define TESSELLATION 80 | $BLENDDEFINE 81 | 82 | #ifndef UNITY_PASS_FORWARDADD 83 | #define UNITY_PASS_FORWARDADD 84 | #endif 85 | 86 | #pragma target 4.6 87 | 88 | struct vertexInput { 89 | float4 vertex : POSITION; 90 | float2 uv : TEXCOORD0; 91 | float3 normal : NORMAL; 92 | float4 tangent : TANGENT; 93 | }; 94 | 95 | struct vertexOutput { 96 | float4 pos : SV_POSITION; 97 | float2 uv : TEXCOORD0; 98 | float3 btn[3] : TEXCOORD1; //2 3; 99 | float4 worldPos : TEXCOORD4; 100 | float3 objPos : TEXCOORD5; 101 | float3 objNormal : TEXCOORD6; 102 | float4 screenPos : TEXCOORD7; 103 | SHADOW_COORDS(8) 104 | }; 105 | 106 | #include "Defines.cginc" 107 | #include "LightingFunctions.cginc" 108 | #include "LightingBRDF.cginc" 109 | #include "VertFragTess.cginc" 110 | ENDCG 111 | } 112 | 113 | Pass 114 | { 115 | Tags{"LightMode"="ShadowCaster"} 116 | CGPROGRAM 117 | #include "UnityCG.cginc" 118 | #include "AutoLight.cginc" 119 | #include "Lighting.cginc" 120 | #pragma vertex vert 121 | #pragma hull hull 122 | #pragma domain domain 123 | #pragma fragment frag 124 | #pragma multi_compile_shadowcaster 125 | $BLENDDEFINE 126 | 127 | #ifndef UNITY_PASS_SHADOWCASTER 128 | #define UNITY_PASS_SHADOWCASTER 129 | #endif 130 | 131 | #pragma target 4.6 132 | 133 | struct vertexInput { 134 | float4 vertex : POSITION; 135 | float2 uv : TEXCOORD0; 136 | float3 normal : NORMAL; 137 | float4 tangent : TANGENT; 138 | }; 139 | 140 | struct vertexOutput { 141 | float4 pos : SV_POSITION; 142 | float2 uv : TEXCOORD0; 143 | float3 btn[3] : TEXCOORD1; //2 3; 144 | float4 worldPos : TEXCOORD4; 145 | float3 objPos : TEXCOORD5; 146 | float3 objNormal : TEXCOORD6; 147 | float4 screenPos : TEXCOORD7; 148 | }; 149 | 150 | #include "Defines.cginc" 151 | #include "LightingFunctions.cginc" 152 | #include "VertFragTess.cginc" 153 | ENDCG 154 | } 155 | } 156 | } 157 | -------------------------------------------------------------------------------- /XSShaderTemplates/Templates/Tessellated_Lit/Tessellated_Lit.txt.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 7d60faf01061188469662f2493cc157e 3 | TextScriptImporter: 4 | externalObjects: {} 5 | userData: 6 | assetBundleName: 7 | assetBundleVariant: 8 | -------------------------------------------------------------------------------- /XSShaderTemplates/Templates/Tessellated_Lit/Tessellation.cginc: -------------------------------------------------------------------------------- 1 | // Tessellation programs based on this article by Catlike Coding: 2 | // https://catlikecoding.com/unity/tutorials/advanced-rendering/tessellation/ 3 | 4 | float UnityDistanceFromPlane (float3 pos, float4 plane) 5 | { 6 | float d = dot (float4(pos,1.0f), plane); 7 | return d; 8 | } 9 | 10 | // Returns true if triangle with given 3 world positions is outside of camera's view frustum. 11 | // cullEps is distance outside of frustum that is still considered to be inside (i.e. max displacement) 12 | bool UnityWorldViewFrustumCull (float3 wpos0, float3 wpos1, float3 wpos2, float cullEps) 13 | { 14 | float4 planeTest; 15 | 16 | // left 17 | planeTest.x = (( UnityDistanceFromPlane(wpos0, unity_CameraWorldClipPlanes[0]) > -cullEps) ? 1.0f : 0.0f ) + 18 | (( UnityDistanceFromPlane(wpos1, unity_CameraWorldClipPlanes[0]) > -cullEps) ? 1.0f : 0.0f ) + 19 | (( UnityDistanceFromPlane(wpos2, unity_CameraWorldClipPlanes[0]) > -cullEps) ? 1.0f : 0.0f ); 20 | // right 21 | planeTest.y = (( UnityDistanceFromPlane(wpos0, unity_CameraWorldClipPlanes[1]) > -cullEps) ? 1.0f : 0.0f ) + 22 | (( UnityDistanceFromPlane(wpos1, unity_CameraWorldClipPlanes[1]) > -cullEps) ? 1.0f : 0.0f ) + 23 | (( UnityDistanceFromPlane(wpos2, unity_CameraWorldClipPlanes[1]) > -cullEps) ? 1.0f : 0.0f ); 24 | // top 25 | planeTest.z = (( UnityDistanceFromPlane(wpos0, unity_CameraWorldClipPlanes[2]) > -cullEps) ? 1.0f : 0.0f ) + 26 | (( UnityDistanceFromPlane(wpos1, unity_CameraWorldClipPlanes[2]) > -cullEps) ? 1.0f : 0.0f ) + 27 | (( UnityDistanceFromPlane(wpos2, unity_CameraWorldClipPlanes[2]) > -cullEps) ? 1.0f : 0.0f ); 28 | // bottom 29 | planeTest.w = (( UnityDistanceFromPlane(wpos0, unity_CameraWorldClipPlanes[3]) > -cullEps) ? 1.0f : 0.0f ) + 30 | (( UnityDistanceFromPlane(wpos1, unity_CameraWorldClipPlanes[3]) > -cullEps) ? 1.0f : 0.0f ) + 31 | (( UnityDistanceFromPlane(wpos2, unity_CameraWorldClipPlanes[3]) > -cullEps) ? 1.0f : 0.0f ); 32 | 33 | // has to pass all 4 plane tests to be visible 34 | return !all (planeTest); 35 | } 36 | 37 | struct TessellationFactors 38 | { 39 | float edge[3] : SV_TessFactor; 40 | float inside : SV_InsideTessFactor; 41 | }; 42 | 43 | vertexInput vert(vertexInput v) 44 | { 45 | return v; 46 | } 47 | 48 | 49 | vertexOutput tessVert(vertexInput v) 50 | { 51 | vertexOutput o = (vertexOutput)0; 52 | o.pos = UnityObjectToClipPos(v.vertex); 53 | o.uv = TRANSFORM_TEX(v.uv, _MainTex); 54 | 55 | #if defined(UNITY_PASS_FORWARDBASE) 56 | o.uv1 = v.uv1; 57 | o.uv2 = v.uv2; 58 | #endif 59 | float3 worldNormal = UnityObjectToWorldNormal(v.normal); 60 | float3 tangent = UnityObjectToWorldDir(v.tangent); 61 | float3 bitangent = cross(tangent, worldNormal) * v.tangent.w; 62 | 63 | o.btn[0] = bitangent; 64 | o.btn[1] = tangent; 65 | o.btn[2] = worldNormal; 66 | o.worldPos = mul(unity_ObjectToWorld, v.vertex); 67 | o.objPos = v.vertex; 68 | o.objNormal = v.normal; 69 | o.screenPos = ComputeScreenPos(o.pos); 70 | 71 | //Only pass needed things through for shadow caster 72 | #if !defined(UNITY_PASS_SHADOWCASTER) 73 | UNITY_TRANSFER_SHADOW(o, o.uv); 74 | #else 75 | TRANSFER_SHADOW_CASTER_NOPOS(o, o.pos); 76 | #endif 77 | 78 | return o; 79 | } 80 | 81 | float UnityCalcDistanceTessFactor (float4 vertex, float minDist, float maxDist, float tess) 82 | { 83 | float3 wpos = vertex.xyz; 84 | float dist = distance (wpos, _WorldSpaceCameraPos); 85 | float f = clamp(1.0 - (dist - minDist) / (maxDist - minDist), 0.01, 1.0) * tess; 86 | return f; 87 | } 88 | 89 | float4 UnityCalcTriEdgeTessFactors (float3 triVertexFactors) 90 | { 91 | float4 tess; 92 | tess.x = 0.5 * (triVertexFactors.y + triVertexFactors.z); 93 | tess.y = 0.5 * (triVertexFactors.x + triVertexFactors.z); 94 | tess.z = 0.5 * (triVertexFactors.x + triVertexFactors.y); 95 | tess.w = (triVertexFactors.x + triVertexFactors.y + triVertexFactors.z) / 3.0f; 96 | return tess; 97 | } 98 | 99 | // Distance based tessellation: 100 | // Tessellation level is "tess" before "minDist" from camera, and linearly decreases to 1 101 | // up to "maxDist" from camera. 102 | float4 UnityDistanceBasedTess (float4 v0, float4 v1, float4 v2, float minDist, float maxDist, float tess) 103 | { 104 | float3 f; 105 | f.x = UnityCalcDistanceTessFactor (v0,minDist,maxDist,tess); 106 | f.y = UnityCalcDistanceTessFactor (v1,minDist,maxDist,tess); 107 | f.z = UnityCalcDistanceTessFactor (v2,minDist,maxDist,tess); 108 | 109 | return UnityCalcTriEdgeTessFactors (f); 110 | } 111 | 112 | 113 | float TessEdgeFactor(float3 p0, float3 p1) 114 | { 115 | float edgeLength = distance(p0, p1); 116 | 117 | float3 edgeCenter = (p0 + p1) * 0.5; 118 | float viewDistance = distance(edgeCenter, _WorldSpaceCameraPos); 119 | float tessFactor = lerp(1, 0, _TessellationUniform) * 50; 120 | return edgeLength * _ScreenParams.y / (tessFactor * viewDistance) ; 121 | } 122 | 123 | TessellationFactors patchConstantFunction (InputPatch patch) 124 | { 125 | TessellationFactors f; 126 | float4 p0 = mul(unity_ObjectToWorld, patch[0].vertex); 127 | float4 p1 = mul(unity_ObjectToWorld, patch[1].vertex); 128 | float4 p2 = mul(unity_ObjectToWorld, patch[2].vertex); 129 | float bias = 0; 130 | 131 | 132 | if(UnityWorldViewFrustumCull(p0, p1, p2, bias)) 133 | { 134 | f.edge[0] = f.edge[1] = f.edge[2] = f.inside = 0; 135 | } 136 | else 137 | { 138 | if(_TessellationMode == 1) 139 | { 140 | f.edge[0] = TessEdgeFactor(p1, p2); 141 | f.edge[1] = TessEdgeFactor(p2, p0); 142 | f.edge[2] = TessEdgeFactor(p0, p1); 143 | f.inside = 144 | (TessEdgeFactor(p1, p2) + 145 | TessEdgeFactor(p2, p0) + 146 | TessEdgeFactor(p0, p1)) * (1 / 3.0); 147 | } 148 | else if(_TessellationMode == 0) 149 | { 150 | _TessellationUniform *= 50; 151 | f.edge[0] = _TessellationUniform; 152 | f.edge[1] = _TessellationUniform; 153 | f.edge[2] = _TessellationUniform; 154 | f.inside = _TessellationUniform; 155 | } 156 | else 157 | { 158 | _TessellationUniform *= 50; 159 | float4 distanceTess = UnityDistanceBasedTess(p0, p1, p2, _TessClose, _TessFar, _TessellationUniform); 160 | f.edge[0] = distanceTess; 161 | f.edge[1] = distanceTess; 162 | f.edge[2] = distanceTess; 163 | f.inside = distanceTess; 164 | } 165 | } 166 | 167 | 168 | return f; 169 | } 170 | 171 | [UNITY_domain("tri")] 172 | [UNITY_outputcontrolpoints(3)] 173 | [UNITY_outputtopology("triangle_cw")] 174 | [UNITY_partitioning("fractional_odd")] 175 | //[UNITY_partitioning("integer")] 176 | [UNITY_patchconstantfunc("patchConstantFunction")] 177 | vertexInput hull (InputPatch patch, uint id : SV_OutputControlPointID) 178 | { 179 | return patch[id]; 180 | } 181 | 182 | [UNITY_domain("tri")] 183 | vertexOutput domain(TessellationFactors factors, OutputPatch patch, float3 barycentricCoordinates : SV_DomainLocation) 184 | { 185 | vertexInput v; 186 | 187 | #define DOMAIN_INTERPOLATE(fieldName) v.fieldName = \ 188 | patch[0].fieldName * barycentricCoordinates.x + \ 189 | patch[1].fieldName * barycentricCoordinates.y + \ 190 | patch[2].fieldName * barycentricCoordinates.z; 191 | 192 | DOMAIN_INTERPOLATE(vertex) 193 | DOMAIN_INTERPOLATE(uv) 194 | #if defined(UNITY_PASS_FORWARDBASE) 195 | DOMAIN_INTERPOLATE(uv1) 196 | DOMAIN_INTERPOLATE(uv2) 197 | #endif 198 | DOMAIN_INTERPOLATE(normal) 199 | DOMAIN_INTERPOLATE(tangent) 200 | // #if !defined(UNITY_PASS_SHADOWCASTER) 201 | // DOMAIN_INTERPOLATE(objPos) 202 | // DOMAIN_INTERPOLATE(objNormal) 203 | // #endif 204 | 205 | return tessVert(v); 206 | } -------------------------------------------------------------------------------- /XSShaderTemplates/Templates/Tessellated_Lit/Tessellation.cginc.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: aa26512b43f8e9a4c9477990fe090a6e 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: [] 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | -------------------------------------------------------------------------------- /XSShaderTemplates/Templates/Tessellated_Lit/VertFragTess.cginc: -------------------------------------------------------------------------------- 1 | #include "Tessellation.cginc" 2 | 3 | //This file contains the vertex, fragment, and Geometry functions for both the ForwardBase and Forward Add pass. 4 | #if defined(SHADOWS_CUBE) && !defined(SHADOWS_CUBE_IN_DEPTH_TEX) 5 | #define V2F_SHADOW_CASTER_NOPOS float3 vec : TEXCOORD0; 6 | #define TRANSFER_SHADOW_CASTER_NOPOS_GEOMETRY(o,opos) o.vec = mul(unity_ObjectToWorld, v[i].vertex).xyz - _LightPositionRange.xyz; opos = o.pos; 7 | #else 8 | #define V2F_SHADOW_CASTER_NOPOS 9 | #define TRANSFER_SHADOW_CASTER_NOPOS_GEOMETRY(o,opos) \ 10 | opos = UnityClipSpaceShadowCasterPos(v[i].vertex, v[i].normal); \ 11 | opos = UnityApplyLinearShadowBias(opos); 12 | #endif 13 | 14 | 15 | fixed4 frag (vertexOutput i) : SV_Target 16 | { 17 | //Return only this if in the shadowcaster 18 | #if defined(UNITY_PASS_SHADOWCASTER) 19 | float4 albedo = texTP(_MainTex, _MainTex_ST, i.worldPos, i.objPos, i.btn[2], i.objNormal, _TriplanarFalloff, i.uv) * _Color; 20 | float alpha; 21 | doAlpha(alpha, albedo.a, i.screenPos); 22 | SHADOW_CASTER_FRAGMENT(i); 23 | #else 24 | return CustomStandardLightingBRDF(i); 25 | #endif 26 | } -------------------------------------------------------------------------------- /XSShaderTemplates/Templates/Tessellated_Lit/VertFragTess.cginc.meta: -------------------------------------------------------------------------------- 1 | fileFormatVersion: 2 2 | guid: 6439dc9a6f39b9f45bbc9a283623a456 3 | ShaderImporter: 4 | externalObjects: {} 5 | defaultTextures: [] 6 | userData: 7 | assetBundleName: 8 | assetBundleVariant: 9 | --------------------------------------------------------------------------------