summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authoryum <yum.food.vr@gmail.com>2025-08-06 16:42:42 -0700
committeryum <yum.food.vr@gmail.com>2025-08-06 16:42:42 -0700
commit99d161288bfe2d10c331c97e6b7571f9c884e912 (patch)
tree6ef130c4801de52f697c8d6996d9c4b0fb5f3964
initial commit
-rw-r--r--3ner.cginc166
-rw-r--r--3ner.shader267
-rw-r--r--LightVolumes.cginc503
-rw-r--r--UnityImageBasedLightingMinimal.cginc73
-rw-r--r--UnityStandardCoreMinimal.cginc72
-rw-r--r--brdf.cginc58
-rw-r--r--features.cginc76
-rw-r--r--filamented.cginc355
-rw-r--r--filtering.cginc255
-rw-r--r--globals.cginc115
-rw-r--r--interpolators.cginc29
-rw-r--r--lighting.cginc140
-rw-r--r--lysenko.cginc38
-rw-r--r--math.cginc26
-rw-r--r--pbr.cginc34
-rw-r--r--pbr_utils.cginc20
-rw-r--r--sampling.cginc1042
17 files changed, 3269 insertions, 0 deletions
diff --git a/3ner.cginc b/3ner.cginc
new file mode 100644
index 0000000..bfaeded
--- /dev/null
+++ b/3ner.cginc
@@ -0,0 +1,166 @@
+#ifndef __3NER_INC
+#define __3NER_INC
+
+#define INCLUDE_UNITY_STANDARD_BRDF_DEPRECATED
+#include "UnityStandardBRDF.cginc"
+#include "UnityDeprecated.cginc"
+#include "UnityCG.cginc"
+#include "UnityLightingCommon.cginc"
+#include "AutoLight.cginc"
+
+#include "brdf.cginc"
+#include "pbr.cginc"
+#include "lighting.cginc"
+#include "globals.cginc"
+#include "interpolators.cginc"
+
+v2f vert(appdata v) {
+ v2f o;
+ UNITY_SETUP_INSTANCE_ID(v);
+ UNITY_INITIALIZE_OUTPUT(v2f, o);
+ UNITY_TRANSFER_INSTANCE_ID(v, o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+
+#if defined(_TESSELLATION)
+ o.tpos = v.vertex;
+#endif
+ o.pos = UnityObjectToClipPos(v.vertex);
+ o.uv0 = v.uv0;
+ o.objPos = v.vertex;
+ o.worldPos = mul(unity_ObjectToWorld, v.vertex);
+ o.eyeVec.xyz = o.worldPos.xyz - _WorldSpaceCameraPos;
+
+ UNITY_TRANSFER_LIGHTING(o, v.uv1);
+ UNITY_TRANSFER_FOG_COMBINED_WITH_EYE_VEC(o, o.pos);
+ TRANSFER_SHADOW(o);
+#if defined(SHADOW_CASTER_PASS)
+ TRANSFER_SHADOW_CASTER_NORMALOFFSET(o);
+#endif
+
+ return o;
+}
+
+struct tess_factors {
+ float edge[3] : SV_TessFactor;
+ float inside : SV_InsideTessFactor;
+};
+
+bool cullPatch(float4 p0, float4 p1, float4 p2, float bias) {
+ return
+ (p0.x < -p0.w - bias && p1.x < -p1.w - bias && p2.x < -p2.w - bias) ||
+ (p0.x > p0.w + bias && p1.x > p1.w + bias && p2.x > p2.w + bias) ||
+ (p0.y < -p0.w - bias && p1.y < -p1.w - bias && p2.y < -p2.w - bias) ||
+ (p0.y > p0.w + bias && p1.y > p1.w + bias && p2.y > p2.w + bias) ||
+ (p0.z < -p0.w - bias && p1.z < -p1.w - bias && p2.z < -p2.w - bias) ||
+ (p0.z > p0.w + bias && p1.z > p1.w + bias && p2.z > p2.w + bias);
+}
+
+// Replaces the existing patch_constant function
+tess_factors patch_constant(InputPatch<v2f, 3> patch) {
+ tess_factors f;
+
+#if defined(_TESSELLATION)
+ float edgeLength = _Tessellation_Factor;
+
+ float3 p0_world = mul(unity_ObjectToWorld, float4(patch[0].objPos, 1));
+ float3 p1_world = mul(unity_ObjectToWorld, float4(patch[1].objPos, 1));
+ float3 p2_world = mul(unity_ObjectToWorld, float4(patch[2].objPos, 1));
+
+ float3 v0 = p0_world - _WorldSpaceCameraPos;
+ float3 v1 = p1_world - _WorldSpaceCameraPos;
+ float3 v2 = p2_world - _WorldSpaceCameraPos;
+
+ // Angular size drops with inverse distance
+ float s0 = rsqrt(dot(v0, v0));
+ float s1 = rsqrt(dot(v1, v1));
+ float s2 = rsqrt(dot(v2, v2));
+
+ float s01 = (s0 + s1) * 0.5f;
+ float s12 = (s1 + s2) * 0.5f;
+ float s20 = (s2 + s0) * 0.5f;
+
+ float k = _Tessellation_Falloff_Factor;
+ f.edge[2] = min(_Tessellation_Factor, k * _Tessellation_Factor * s01);
+ f.edge[0] = min(_Tessellation_Factor, k * _Tessellation_Factor * s12);
+ f.edge[1] = min(_Tessellation_Factor, k * _Tessellation_Factor * s20);
+
+ f.inside = (f.edge[0] + f.edge[1] + f.edge[2]) * 0.333333f;
+
+ // Early exit if tessellation is minimal
+ [branch]
+ if (f.inside <= 1.5) {
+ return f;
+ }
+#else
+ f.edge[0] = 1;
+ f.edge[1] = 1;
+ f.edge[2] = 1;
+ f.inside = 1;
+#endif
+
+#if defined(_TESSELLATION) && defined(_TESSELLATION_HEIGHTMAPS)
+ {
+ float4 p0 = patch[0].pos;
+ float4 p1 = patch[1].pos;
+ float4 p2 = patch[2].pos;
+ if (cullPatch(p0, p1, p2, _Tessellation_Frustum_Culling_Bias)) {
+ f.edge[0] = 1;
+ f.edge[1] = 1;
+ f.edge[2] = 1;
+ f.inside = 1;
+ }
+ }
+#endif
+
+ return f;
+}
+
+[UNITY_domain("tri")]
+[UNITY_outputcontrolpoints(3)]
+[UNITY_outputtopology("triangle_cw")]
+[UNITY_partitioning("fractional_odd")]
+[UNITY_patchconstantfunc("patch_constant")]
+v2f hull(
+ InputPatch<v2f, 3> patch,
+ uint id : SV_OutputControlPointID)
+{
+ return patch[id];
+}
+
+[UNITY_domain("tri")]
+v2f domain(
+ tess_factors factors,
+ OutputPatch<v2f, 3> patch,
+ float3 baryc : SV_DomainLocation)
+{
+ v2f o = (v2f) 0;
+#define DOMAIN_INTERP(fieldName) \
+ patch[0].fieldName * baryc.x + \
+ patch[1].fieldName * baryc.y + \
+ patch[2].fieldName * baryc.z
+
+ o.uv0 = DOMAIN_INTERP(uv0);
+#if defined(_TESSELLATION)
+ o.objPos = DOMAIN_INTERP(tpos);
+#else
+ o.objPos = DOMAIN_INTERP(objPos);
+#endif
+
+ o.worldPos = mul(unity_ObjectToWorld, float4(o.objPos, 1));
+ o.pos = UnityObjectToClipPos(o.objPos);
+ o.eyeVec.xyz = o.worldPos - _WorldSpaceCameraPos;
+
+ UNITY_TRANSFER_INSTANCE_ID(patch[0], o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+ return o;
+}
+
+float4 frag(v2f i) : SV_Target {
+ Pbr pbr = getPbr(i);
+ LightData light_data;
+ GetLighting(i, pbr, light_data);
+ return brdf(pbr, light_data);
+}
+
+#endif // __3NER_INC
+
diff --git a/3ner.shader b/3ner.shader
new file mode 100644
index 0000000..00602df
--- /dev/null
+++ b/3ner.shader
@@ -0,0 +1,267 @@
+Shader "yum_food/3ner"
+{
+ // Certain parts of the Properties below are derived from Poiyomi's toon
+ // shader. The license is available in this repository at the top of
+ // poi.cginc. C.
+ Properties
+ {
+ [HideInInspector] shader_master_label("<color=#de719bff>2ner</color>", Float) = 0
+ [HideInInspector] shader_is_using_thry_editor("", Float) = 0
+ [HideInInspector] shader_presets("ThryPresetsExample", Float) = 0
+ [HideInInspector] shader_properties_label_file("ThryLabelExample", Float) = 0
+
+ //ifex _ShaderOptimizerEnabled==0
+ [HideInInspector] _ForgotToLockMaterial(";;YOU_FORGOT_TO_LOCK_THE_MATERIAL;", Int) = 0
+ //endex
+ [ThryShaderOptimizerLockButton] _ShaderOptimizerEnabled("", Int) = 0
+
+ [ThryWideEnum(Opaque, 0, Cutout, 1, TransClipping, 9, Fade, 2, Transparent, 3, Additive, 4, Soft Additive, 5, Multiplicative, 6, 2x Multiplicative, 7)]_Mode("Rendering Preset--{on_value_actions:[
+ {value:0,actions:[{type:SET_PROPERTY,data:render_queue=2000},{type:SET_PROPERTY,data:_AlphaForceOpaque=1}, {type:SET_PROPERTY,data:render_type=Opaque}, {type:SET_PROPERTY,data:_BlendOp=0}, {type:SET_PROPERTY,data:_BlendOpAlpha=4}, {type:SET_PROPERTY,data:_Cutoff=0}, {type:SET_PROPERTY,data:_SrcBlend=1}, {type:SET_PROPERTY,data:_DstBlend=0}, {type:SET_PROPERTY,data:_SrcBlendAlpha=1}, {type:SET_PROPERTY,data:_DstBlendAlpha=1}, {type:SET_PROPERTY,data:_AddSrcBlend=1}, {type:SET_PROPERTY,data:_AddDstBlend=1}, {type:SET_PROPERTY,data:_AddSrcBlendAlpha=0}, {type:SET_PROPERTY,data:_AddDstBlendAlpha=1}, {type:SET_PROPERTY,data:_AlphaToCoverage=0}, {type:SET_PROPERTY,data:_ZWrite=1}, {type:SET_PROPERTY,data:_ZTest=4}, {type:SET_PROPERTY,data:_AlphaPremultiply=0}, {type:SET_PROPERTY,data:_OutlineSrcBlend=1}, {type:SET_PROPERTY,data:_OutlineDstBlend=0}, {type:SET_PROPERTY,data:_OutlineSrcBlendAlpha=1}, {type:SET_PROPERTY,data:_OutlineDstBlendAlpha=0}, {type:SET_PROPERTY,data:_OutlineBlendOp=0}, {type:SET_PROPERTY,data:_OutlineBlendOpAlpha=4}]},
+ {value:1,actions:[{type:SET_PROPERTY,data:render_queue=2450},{type:SET_PROPERTY,data:_AlphaForceOpaque=0}, {type:SET_PROPERTY,data:render_type=TransparentCutout}, {type:SET_PROPERTY,data:_BlendOp=0}, {type:SET_PROPERTY,data:_BlendOpAlpha=4}, {type:SET_PROPERTY,data:_Cutoff=.5}, {type:SET_PROPERTY,data:_SrcBlend=1}, {type:SET_PROPERTY,data:_DstBlend=0}, {type:SET_PROPERTY,data:_SrcBlendAlpha=1}, {type:SET_PROPERTY,data:_DstBlendAlpha=1}, {type:SET_PROPERTY,data:_AddSrcBlend=1}, {type:SET_PROPERTY,data:_AddDstBlend=1}, {type:SET_PROPERTY,data:_AddSrcBlendAlpha=0}, {type:SET_PROPERTY,data:_AddDstBlendAlpha=1}, {type:SET_PROPERTY,data:_AlphaToCoverage=0}, {type:SET_PROPERTY,data:_ZWrite=1}, {type:SET_PROPERTY,data:_ZTest=4}, {type:SET_PROPERTY,data:_AlphaPremultiply=0}, {type:SET_PROPERTY,data:_OutlineSrcBlend=1}, {type:SET_PROPERTY,data:_OutlineDstBlend=0}, {type:SET_PROPERTY,data:_OutlineSrcBlendAlpha=1}, {type:SET_PROPERTY,data:_OutlineDstBlendAlpha=1}, {type:SET_PROPERTY,data:_OutlineBlendOp=0}, {type:SET_PROPERTY,data:_OutlineBlendOpAlpha=4}]},
+ {value:9,actions:[{type:SET_PROPERTY,data:render_queue=2460},{type:SET_PROPERTY,data:_AlphaForceOpaque=0}, {type:SET_PROPERTY,data:render_type=TransparentCutout}, {type:SET_PROPERTY,data:_BlendOp=0}, {type:SET_PROPERTY,data:_BlendOpAlpha=4}, {type:SET_PROPERTY,data:_Cutoff=0.01}, {type:SET_PROPERTY,data:_SrcBlend=5}, {type:SET_PROPERTY,data:_DstBlend=10}, {type:SET_PROPERTY,data:_SrcBlendAlpha=1}, {type:SET_PROPERTY,data:_DstBlendAlpha=1}, {type:SET_PROPERTY,data:_AddSrcBlend=5}, {type:SET_PROPERTY,data:_AddDstBlend=1}, {type:SET_PROPERTY,data:_AddSrcBlendAlpha=0}, {type:SET_PROPERTY,data:_AddDstBlendAlpha=1}, {type:SET_PROPERTY,data:_AlphaToCoverage=0}, {type:SET_PROPERTY,data:_ZWrite=1}, {type:SET_PROPERTY,data:_ZTest=4}, {type:SET_PROPERTY,data:_AlphaPremultiply=0}, {type:SET_PROPERTY,data:_OutlineSrcBlend=5}, {type:SET_PROPERTY,data:_OutlineDstBlend=10}, {type:SET_PROPERTY,data:_OutlineSrcBlendAlpha=1}, {type:SET_PROPERTY,data:_OutlineDstBlendAlpha=1}, {type:SET_PROPERTY,data:_OutlineBlendOp=0}, {type:SET_PROPERTY,data:_OutlineBlendOpAlpha=4}]},
+ {value:2,actions:[{type:SET_PROPERTY,data:render_queue=3000},{type:SET_PROPERTY,data:_AlphaForceOpaque=0}, {type:SET_PROPERTY,data:render_type=Transparent}, {type:SET_PROPERTY,data:_BlendOp=0}, {type:SET_PROPERTY,data:_BlendOpAlpha=4}, {type:SET_PROPERTY,data:_Cutoff=0.002}, {type:SET_PROPERTY,data:_SrcBlend=5}, {type:SET_PROPERTY,data:_DstBlend=10}, {type:SET_PROPERTY,data:_SrcBlendAlpha=1}, {type:SET_PROPERTY,data:_DstBlendAlpha=1}, {type:SET_PROPERTY,data:_AddSrcBlend=5}, {type:SET_PROPERTY,data:_AddDstBlend=1}, {type:SET_PROPERTY,data:_AddSrcBlendAlpha=0}, {type:SET_PROPERTY,data:_AddDstBlendAlpha=1}, {type:SET_PROPERTY,data:_AlphaToCoverage=0}, {type:SET_PROPERTY,data:_ZWrite=0}, {type:SET_PROPERTY,data:_ZTest=4}, {type:SET_PROPERTY,data:_AlphaPremultiply=0}, {type:SET_PROPERTY,data:_OutlineSrcBlend=5}, {type:SET_PROPERTY,data:_OutlineDstBlend=10}, {type:SET_PROPERTY,data:_OutlineSrcBlendAlpha=1}, {type:SET_PROPERTY,data:_OutlineDstBlendAlpha=1}, {type:SET_PROPERTY,data:_OutlineBlendOp=0}, {type:SET_PROPERTY,data:_OutlineBlendOpAlpha=4}]},
+ {value:3,actions:[{type:SET_PROPERTY,data:render_queue=3000},{type:SET_PROPERTY,data:_AlphaForceOpaque=0}, {type:SET_PROPERTY,data:render_type=Transparent}, {type:SET_PROPERTY,data:_BlendOp=0}, {type:SET_PROPERTY,data:_BlendOpAlpha=4}, {type:SET_PROPERTY,data:_Cutoff=0}, {type:SET_PROPERTY,data:_SrcBlend=1}, {type:SET_PROPERTY,data:_DstBlend=10}, {type:SET_PROPERTY,data:_SrcBlendAlpha=1}, {type:SET_PROPERTY,data:_DstBlendAlpha=1}, {type:SET_PROPERTY,data:_AddSrcBlend=1}, {type:SET_PROPERTY,data:_AddDstBlend=1}, {type:SET_PROPERTY,data:_AddSrcBlendAlpha=0}, {type:SET_PROPERTY,data:_AddDstBlendAlpha=1}, {type:SET_PROPERTY,data:_AlphaToCoverage=0}, {type:SET_PROPERTY,data:_ZWrite=0}, {type:SET_PROPERTY,data:_ZTest=4}, {type:SET_PROPERTY,data:_AlphaPremultiply=1}, {type:SET_PROPERTY,data:_OutlineSrcBlend=1}, {type:SET_PROPERTY,data:_OutlineDstBlend=10}, {type:SET_PROPERTY,data:_OutlineSrcBlendAlpha=1}, {type:SET_PROPERTY,data:_OutlineDstBlendAlpha=1}, {type:SET_PROPERTY,data:_OutlineBlendOp=0}, {type:SET_PROPERTY,data:_OutlineBlendOpAlpha=4}]},
+ {value:4,actions:[{type:SET_PROPERTY,data:render_queue=3000},{type:SET_PROPERTY,data:_AlphaForceOpaque=0}, {type:SET_PROPERTY,data:render_type=Transparent}, {type:SET_PROPERTY,data:_BlendOp=0}, {type:SET_PROPERTY,data:_BlendOpAlpha=4}, {type:SET_PROPERTY,data:_Cutoff=0}, {type:SET_PROPERTY,data:_SrcBlend=1}, {type:SET_PROPERTY,data:_DstBlend=1}, {type:SET_PROPERTY,data:_SrcBlendAlpha=1}, {type:SET_PROPERTY,data:_DstBlendAlpha=1}, {type:SET_PROPERTY,data:_AddSrcBlend=1}, {type:SET_PROPERTY,data:_AddDstBlend=1}, {type:SET_PROPERTY,data:_AddSrcBlendAlpha=0}, {type:SET_PROPERTY,data:_AddDstBlendAlpha=1}, {type:SET_PROPERTY,data:_AlphaToCoverage=0}, {type:SET_PROPERTY,data:_ZWrite=0}, {type:SET_PROPERTY,data:_ZTest=4}, {type:SET_PROPERTY,data:_AlphaPremultiply=0}, {type:SET_PROPERTY,data:_OutlineSrcBlend=1}, {type:SET_PROPERTY,data:_OutlineDstBlend=1}, {type:SET_PROPERTY,data:_OutlineSrcBlendAlpha=1}, {type:SET_PROPERTY,data:_OutlineDstBlendAlpha=1}, {type:SET_PROPERTY,data:_OutlineBlendOp=0}, {type:SET_PROPERTY,data:_OutlineBlendOpAlpha=4}]},
+ {value:5,actions:[{type:SET_PROPERTY,data:render_queue=3000},{type:SET_PROPERTY,data:_AlphaForceOpaque=0}, {type:SET_PROPERTY,data:render_type=Transparent}, {type:SET_PROPERTY,data:_BlendOp=0}, {type:SET_PROPERTY,data:_BlendOpAlpha=4}, {type:SET_PROPERTY,data:_Cutoff=0}, {type:SET_PROPERTY,data:_SrcBlend=4}, {type:SET_PROPERTY,data:_DstBlend=1}, {type:SET_PROPERTY,data:_SrcBlendAlpha=1}, {type:SET_PROPERTY,data:_DstBlendAlpha=1}, {type:SET_PROPERTY,data:_AddSrcBlend=4}, {type:SET_PROPERTY,data:_AddDstBlend=1}, {type:SET_PROPERTY,data:_AddSrcBlendAlpha=0}, {type:SET_PROPERTY,data:_AddDstBlendAlpha=1}, {type:SET_PROPERTY,data:_AlphaToCoverage=0}, {type:SET_PROPERTY,data:_ZWrite=0}, {type:SET_PROPERTY,data:_ZTest=4}, {type:SET_PROPERTY,data:_AlphaPremultiply=0}, {type:SET_PROPERTY,data:_OutlineSrcBlend=4}, {type:SET_PROPERTY,data:_OutlineDstBlend=1}, {type:SET_PROPERTY,data:_OutlineSrcBlendAlpha=1}, {type:SET_PROPERTY,data:_OutlineDstBlendAlpha=1}, {type:SET_PROPERTY,data:_OutlineBlendOp=0}, {type:SET_PROPERTY,data:_OutlineBlendOpAlpha=4}]},
+ {value:6,actions:[{type:SET_PROPERTY,data:render_queue=3000},{type:SET_PROPERTY,data:_AlphaForceOpaque=0}, {type:SET_PROPERTY,data:render_type=Transparent}, {type:SET_PROPERTY,data:_BlendOp=0}, {type:SET_PROPERTY,data:_BlendOpAlpha=4}, {type:SET_PROPERTY,data:_Cutoff=0}, {type:SET_PROPERTY,data:_SrcBlend=2}, {type:SET_PROPERTY,data:_DstBlend=0}, {type:SET_PROPERTY,data:_SrcBlendAlpha=1}, {type:SET_PROPERTY,data:_DstBlendAlpha=1}, {type:SET_PROPERTY,data:_AddSrcBlend=2}, {type:SET_PROPERTY,data:_AddDstBlend=1}, {type:SET_PROPERTY,data:_AddSrcBlendAlpha=0}, {type:SET_PROPERTY,data:_AddDstBlendAlpha=1}, {type:SET_PROPERTY,data:_AlphaToCoverage=0}, {type:SET_PROPERTY,data:_ZWrite=0}, {type:SET_PROPERTY,data:_ZTest=4}, {type:SET_PROPERTY,data:_AlphaPremultiply=0}, {type:SET_PROPERTY,data:_OutlineSrcBlend=2}, {type:SET_PROPERTY,data:_OutlineDstBlend=0}, {type:SET_PROPERTY,data:_OutlineSrcBlendAlpha=1}, {type:SET_PROPERTY,data:_OutlineDstBlendAlpha=1}, {type:SET_PROPERTY,data:_OutlineBlendOp=0}, {type:SET_PROPERTY,data:_OutlineBlendOpAlpha=4}]},
+ {value:7,actions:[{type:SET_PROPERTY,data:render_queue=3000},{type:SET_PROPERTY,data:_AlphaForceOpaque=0}, {type:SET_PROPERTY,data:render_type=Transparent}, {type:SET_PROPERTY,data:_BlendOp=0}, {type:SET_PROPERTY,data:_BlendOpAlpha=4}, {type:SET_PROPERTY,data:_Cutoff=0}, {type:SET_PROPERTY,data:_SrcBlend=2}, {type:SET_PROPERTY,data:_DstBlend=3}, {type:SET_PROPERTY,data:_SrcBlendAlpha=1}, {type:SET_PROPERTY,data:_DstBlendAlpha=1}, {type:SET_PROPERTY,data:_AddSrcBlend=2}, {type:SET_PROPERTY,data:_AddDstBlend=1}, {type:SET_PROPERTY,data:_AddSrcBlendAlpha=0}, {type:SET_PROPERTY,data:_AddDstBlendAlpha=1}, {type:SET_PROPERTY,data:_AlphaToCoverage=0}, {type:SET_PROPERTY,data:_ZWrite=0}, {type:SET_PROPERTY,data:_ZTest=4}, {type:SET_PROPERTY,data:_AlphaPremultiply=0}, {type:SET_PROPERTY,data:_OutlineSrcBlend=2}, {type:SET_PROPERTY,data:_OutlineDstBlend=3}, {type:SET_PROPERTY,data:_OutlineSrcBlendAlpha=1}, {type:SET_PROPERTY,data:_OutlineDstBlendAlpha=1}, {type:SET_PROPERTY,data:_OutlineBlendOp=0}, {type:SET_PROPERTY,data:_OutlineBlendOpAlpha=4}]}
+ }]}]}", Int) = 0
+
+ [HideInInspector] m_mainOptions("Main", Float) = 0
+ _Color("Tint", Color) = (1, 1, 1, 1)
+ _Metallic("Metallic", Range(0, 1)) = 0
+ _Smoothness("Smoothness", Range(0, 1)) = 0
+
+ //ifex _Sea_FX_Enabled==0
+ [HideInInspector] m_start_Sea_FX("Sea FX", Float) = 0
+ [ThryToggle(_SEA_FX)] _Sea_FX_Enabled("Enable", Float) = 0
+
+ [HideInInspector] m_start_Sea_FX_Heightmaps("Heightmaps", Float) = 0
+ //ifex _Sea_FX_Heightmaps_Y_0_Enabled==0
+ [ThryToggle(_SEA_FX_HEIGHTMAPS_Y_0)] _Sea_FX_Heightmaps_Y_0_Enabled("Enable (Y 0)", Float) = 0
+ _Sea_FX_Heightmaps_Y_0("Y 0", 2D) = "black" {}
+ //endex
+ //ifex _Sea_FX_Heightmaps_Y_1_Enabled==0
+ [ThryToggle(_SEA_FX_HEIGHTMAPS_Y_1)] _Sea_FX_Heightmaps_Y_1_Enabled("Enable (Y 1)", Float) = 0
+ _Sea_FX_Heightmaps_Y_1("Y 1", 2D) = "black" {}
+ //endex
+ //ifex _Sea_FX_Heightmaps_Y_2_Enabled==0
+ [ThryToggle(_SEA_FX_HEIGHTMAPS_Y_2)] _Sea_FX_Heightmaps_Y_2_Enabled("Enable (Y 2)", Float) = 0
+ _Sea_FX_Heightmaps_Y_2("Y 2", 2D) = "black" {}
+ //endex
+ //ifex _Sea_FX_Heightmaps_Y_3_Enabled==0
+ [ThryToggle(_SEA_FX_HEIGHTMAPS_Y_3)] _Sea_FX_Heightmaps_Y_3_Enabled("Enable (Y 3)", Float) = 0
+ _Sea_FX_Heightmaps_Y_3("Y 3", 2D) = "black" {}
+ //endex
+ //ifex _Sea_FX_Heightmaps_XZ_0_Enabled==0
+ [ThryToggle(_SEA_FX_HEIGHTMAPS_XZ_0)] _Sea_FX_Heightmaps_XZ_0_Enabled("Enable (XZ 0)", Float) = 0
+ _Sea_FX_Heightmaps_XZ_0("XZ 0", 2D) = "black" {}
+ //endex
+ //ifex _Sea_FX_Heightmaps_XZ_1_Enabled==0
+ [ThryToggle(_SEA_FX_HEIGHTMAPS_XZ_1)] _Sea_FX_Heightmaps_XZ_1_Enabled("Enable (XZ 1)", Float) = 0
+ _Sea_FX_Heightmaps_XZ_1("XZ 1", 2D) = "black" {}
+ //endex
+ //ifex _Sea_FX_Heightmaps_XZ_2_Enabled==0
+ [ThryToggle(_SEA_FX_HEIGHTMAPS_XZ_2)] _Sea_FX_Heightmaps_XZ_2_Enabled("Enable (XZ 2)", Float) = 0
+ _Sea_FX_Heightmaps_XZ_2("XZ 2", 2D) = "black" {}
+ //endex
+ //ifex _Sea_FX_Heightmaps_XZ_3_Enabled==0
+ [ThryToggle(_SEA_FX_HEIGHTMAPS_XZ_3)] _Sea_FX_Heightmaps_XZ_3_Enabled("Enable (XZ 3)", Float) = 0
+ _Sea_FX_Heightmaps_XZ_3("XZ 3", 2D) = "black" {}
+ //endex
+ [HideInInspector] m_end_Sea_FX_Heightmaps("Heightmaps", Float) = 0
+
+ [HideInInspector] m_start_Sea_FX_Derivatives("Derivatives", Float) = 0
+ _Sea_FX_Derivatives_SS_Filtering_Factor("SS filtering factor", Range(0, 50)) = 15
+ //ifex _Sea_FX_Vertical_Derivatives_0_Enabled==0
+ [HideInInspector] m_start_Sea_FX_Vertical_Derivatives_0("Vertical derivatives 0", Float) = 0
+ [ThryToggle(_SEA_FX_VERTICAL_DERIVATIVES_0)] _Sea_FX_Vertical_Derivatives_0_Enabled("Enable", Float) = 0
+ _Sea_FX_Vertical_Derivatives_0("Vertical derivatives 0", 2D) = "black" {}
+ [HideInInspector] m_end_Sea_FX_Vertical_Derivatives_0("Vertical derivatives 0", Float) = 0
+ //endex
+ //ifex _Sea_FX_Horizontal_Derivatives_0_Enabled==0
+ [HideInInspector] m_start_Sea_FX_Horizontal_Derivatives_0("Horizontal derivatives 0", Float) = 0
+ [ThryToggle(_SEA_FX_HORIZONTAL_DERIVATIVES_0)] _Sea_FX_Horizontal_Derivatives_0_Enabled("Enable", Float) = 0
+ _Sea_FX_Horizontal_Derivatives_0("Horizontal derivatives 0", 2D) = "black" {}
+ [HideInInspector] m_end_Sea_FX_Horizontal_Derivatives_0("Horizontal derivatives 0", Float) = 0
+ //endex
+ //ifex _Sea_FX_Vertical_Derivatives_1_Enabled==0
+ [HideInInspector] m_start_Sea_FX_Vertical_Derivatives_1("Vertical derivatives 1", Float) = 0
+ [ThryToggle(_SEA_FX_VERTICAL_DERIVATIVES_1)] _Sea_FX_Vertical_Derivatives_1_Enabled("Enable", Float) = 0
+ _Sea_FX_Vertical_Derivatives_1("Vertical derivatives 1", 2D) = "black" {}
+ [HideInInspector] m_end_Sea_FX_Vertical_Derivatives_1("Vertical derivatives 1", Float) = 0
+ //endex
+ //ifex _Sea_FX_Horizontal_Derivatives_1_Enabled==0
+ [HideInInspector] m_start_Sea_FX_Horizontal_Derivatives_1("Horizontal derivatives 1", Float) = 0
+ [ThryToggle(_SEA_FX_HORIZONTAL_DERIVATIVES_1)] _Sea_FX_Horizontal_Derivatives_1_Enabled("Enable", Float) = 0
+ _Sea_FX_Horizontal_Derivatives_1("Horizontal derivatives 1", 2D) = "black" {}
+ [HideInInspector] m_end_Sea_FX_Horizontal_Derivatives_1("Horizontal derivatives 1", Float) = 0
+ //endex
+ //ifex _Sea_FX_Vertical_Derivatives_2_Enabled==0
+ [HideInInspector] m_start_Sea_FX_Vertical_Derivatives_2("Vertical derivatives 2", Float) = 0
+ [ThryToggle(_SEA_FX_VERTICAL_DERIVATIVES_2)] _Sea_FX_Vertical_Derivatives_2_Enabled("Enable", Float) = 0
+ _Sea_FX_Vertical_Derivatives_2("Vertical derivatives 2", 2D) = "black" {}
+ [HideInInspector] m_end_Sea_FX_Vertical_Derivatives_2("Vertical derivatives 2", Float) = 0
+ //endex
+ //ifex _Sea_FX_Horizontal_Derivatives_2_Enabled==0
+ [HideInInspector] m_start_Sea_FX_Horizontal_Derivatives_2("Horizontal derivatives 2", Float) = 0
+ [ThryToggle(_SEA_FX_HORIZONTAL_DERIVATIVES_2)] _Sea_FX_Horizontal_Derivatives_2_Enabled("Enable", Float) = 0
+ _Sea_FX_Horizontal_Derivatives_2("Horizontal derivatives 2", 2D) = "black" {}
+ [HideInInspector] m_end_Sea_FX_Horizontal_Derivatives_2("Horizontal derivatives 2", Float) = 0
+ //endex
+ //ifex _Sea_FX_Vertical_Derivatives_3_Enabled==0
+ [HideInInspector] m_start_Sea_FX_Vertical_Derivatives_3("Vertical derivatives 3", Float) = 0
+ [ThryToggle(_SEA_FX_VERTICAL_DERIVATIVES_3)] _Sea_FX_Vertical_Derivatives_3_Enabled("Enable", Float) = 0
+ _Sea_FX_Vertical_Derivatives_3("Vertical derivatives 3", 2D) = "black" {}
+ [HideInInspector] m_end_Sea_FX_Vertical_Derivatives_3("Vertical derivatives 3", Float) = 0
+ //endex
+ //ifex _Sea_FX_Horizontal_Derivatives_3_Enabled==0
+ [HideInInspector] m_start_Sea_FX_Horizontal_Derivatives_3("Horizontal derivatives 3", Float) = 0
+ [ThryToggle(_SEA_FX_HORIZONTAL_DERIVATIVES_3)] _Sea_FX_Horizontal_Derivatives_3_Enabled("Enable", Float) = 0
+ _Sea_FX_Horizontal_Derivatives_3("Horizontal derivatives 3", 2D) = "black" {}
+ [HideInInspector] m_end_Sea_FX_Horizontal_Derivatives_3("Horizontal derivatives 3", Float) = 0
+ //endex
+ [HideInInspector] m_end_Sea_FX_Derivatives("Derivatives", Float) = 0
+
+ //ifex _Gradient_Normals_Enabled==0
+ [HideInInspector] m_start_Gradient_Normals("Gradient Normals", Float) = 0
+ [ThryToggle(_GRADIENT_NORMALS)] _Gradient_Normals_Enabled("Enable", Float) = 0
+ [HideInInspector] m_end_Gradient_Normals("Gradient Normals", Float) = 0
+ //endex
+
+ //ifex _Sea_Foam_Enabled==0
+ [HideInInspector] m_start_Sea_Foam("Sea foam", Float) = 0
+ [ThryToggle(_SEA_FOAM)] _Sea_Foam_Enabled("Enable", Float) = 0
+ _Sea_Foam_Color("Color", Color) = (1, 1, 1, 1)
+ _Sea_Foam_Roughness("Roughness", Range(0, 1)) = 0.85
+ _Sea_Foam_Bias("Bias", Range(-5, 5)) = 0
+ [HideInInspector] m_end_Sea_Foam("Sea foam", Float) = 0
+ //endex
+
+ //ifex _Sea_SSS_Enabled==0
+ [HideInInspector] m_start_Sea_SSS("Sea SSS", Float) = 0
+ [ThryToggle(_SEA_SSS)] _Sea_SSS_Enabled("Enable", Float) = 0
+ _Sea_SSS_Color("Color", Color) = (0.5, 0.9, 1, 1)
+ _Sea_SSS_Bias("Bias", Range(-.5, .5)) = 0
+ _Sea_SSS_Factor("Factor", Range(0, 10)) = 1
+ _Sea_SSS_X_Amount("X_Amount", Range(0, 1)) = 0
+ _Sea_SSS_Power("Power", Range(0, 10)) = 1
+ _Sea_SSS_LoV_Wrap("LoV wrap", Range(0, 1)) = 0.8
+ [HideInInspector] m_end_Sea_SSS("Sea SSS", Float) = 0
+ //endex
+ [HideInInspector] m_end_Sea_FX("Sea FX", Float) = 0
+ //endex
+
+ //ifex _Tessellation_Enabled==0
+ [HideInInspector] m_start_Tessellation("Tessellation", Float) = 0
+ [ThryToggle(_TESSELLATION)] _Tessellation_Enabled("Enable", Float) = 0
+ _Tessellation_Factor("Factor", Range(1, 64)) = 1
+ _Tessellation_Frustum_Culling_Bias("Frustum culling bias", Float) = 35
+ _Tessellation_Falloff_Factor("Falloff factor", Float) = 50
+ // Shit for thry
+ [HideInInspector] Tessellation_Enabled("Enabled", Float) = 1
+ [HideInInspector] Tessellation_EnabledForwardBase("Enabled (ForwardBase)", Float) = 1
+ [HideInInspector] Tessellation_EnabledForwardAdd("Enabled (ForwardAdd)", Float) = 1
+ [HideInInspector] Tessellation_EnabledShadowCaster("Enabled (ShadowCaster)", Float) = 1
+ [HideInInspector] m_end_Tessellation("Tessellation", Float) = 0
+ //endex
+
+
+ [HideInInspector] m_start_Rendering_Options("Rendering Options", Float) = 0
+
+ [Enum(UnityEngine.Rendering.CullMode)] _Cull("Cull", Float) = 2
+ [Enum(UnityEngine.Rendering.CompareFunction)] _ZTest("ZTest", Float) = 4
+ [Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend("Source Blend", Float) = 1
+ [Enum(UnityEngine.Rendering.BlendMode)] _DstBlend("Destination Blend", Float) = 0
+ [Enum(Off, 0, On, 1)] _ZWrite("ZWrite", Int) = 1
+
+ [HideInInspector] m_start_blending ("Blending--{button_help:{text:Tutorial,action:{type:URL,data:https://www.poiyomi.com/rendering/blending},hover:Documentation}}", Float) = 0
+ [DoNotAnimate][Enum(Thry.BlendOp)]_BlendOp ("RGB Blend Op", Int) = 0
+ [DoNotAnimate][Enum(UnityEngine.Rendering.BlendMode)] _SrcBlend ("RGB Source Blend", Int) = 1
+ [DoNotAnimate][Enum(UnityEngine.Rendering.BlendMode)] _DstBlend ("RGB Destination Blend", Int) = 0
+ [DoNotAnimate][Space][ThryHeaderLabel(Additive Blending, 13)]
+ [DoNotAnimate][Enum(Thry.BlendOp)]_AddBlendOp ("RGB Blend Op", Int) = 4
+ [DoNotAnimate][Enum(UnityEngine.Rendering.BlendMode)] _AddSrcBlend ("RGB Source Blend", Int) = 1
+ [DoNotAnimate][Enum(UnityEngine.Rendering.BlendMode)] _AddDstBlend ("RGB Destination Blend", Int) = 1
+ [DoNotAnimate][HideInInspector] m_start_alphaBlending ("Advanced Alpha Blending", Float) = 0
+ [DoNotAnimate][Enum(Thry.BlendOp)]_BlendOpAlpha ("Alpha Blend Op", Int) = 0
+ [DoNotAnimate][Enum(UnityEngine.Rendering.BlendMode)] _SrcBlendAlpha ("Alpha Source Blend", Int) = 1
+ [DoNotAnimate][Enum(UnityEngine.Rendering.BlendMode)] _DstBlendAlpha ("Alpha Destination Blend", Int) = 10
+ [DoNotAnimate][Space][ThryHeaderLabel(Additive Blending, 13)]
+ [DoNotAnimate][Enum(Thry.BlendOp)]_AddBlendOpAlpha ("Alpha Blend Op", Int) = 4
+ [DoNotAnimate][Enum(UnityEngine.Rendering.BlendMode)] _AddSrcBlendAlpha ("Alpha Source Blend", Int) = 0
+ [DoNotAnimate][Enum(UnityEngine.Rendering.BlendMode)] _AddDstBlendAlpha ("Alpha Destination Blend", Int) = 1
+ [DoNotAnimate][HideInInspector] m_end_alphaBlending ("Advanced Alpha Blending", Float) = 0
+ [HideInInspector] m_end_blending ("Blending", Float) = 0
+
+ [HideInInspector] m_start_BRDF("BRDF", Float) = 0
+ _BRDF_Specular_Min_Denom("Specular minimum denominator", Float) = 0.000001
+ _Specular_AA_Variance("Specular AA Variance", Float) = 0.15
+ _Specular_AA_Threshold("Specular AA Threshold", Float) = 0.25
+ [HideInInspector] m_end_BRDF("BRDF", Float) = 0
+
+ [HideInInspector] m_end_Rendering_Options("Rendering Options", Float) = 0
+ }
+
+ SubShader {
+ Tags { "RenderType" = "Opaque" "Queue" = "Geometry" "VRCFallback" = "Standard" "DisableBatching" = "True" }
+
+ Pass {
+ Name "FORWARD"
+ Tags { "LightMode" = "ForwardBase" }
+ BlendOp [_BlendOp], [_BlendOpAlpha]
+ Blend [_SrcBlend] [_DstBlend], [_SrcBlendAlpha] [_DstBlendAlpha]
+ Cull [_Cull]
+ ZWrite [_ZWrite]
+ ZTest [_ZTest]
+
+ CGPROGRAM
+ #pragma target 5.0
+ #pragma multi_compile_fwdbase
+ #pragma multi_compile_fullshadows
+ #pragma multi_compile_instancing
+ #pragma multi_compile_fog
+ #pragma vertex vert
+ //ifex _Tessellation_Enabled==0
+ #pragma hull hull
+ #pragma domain domain
+ //endex
+ #pragma fragment frag
+
+ #define FORWARD_BASE_PASS
+
+ #include "3ner.cginc"
+ ENDCG
+ }
+ Pass {
+ Name "ADDITIVE"
+ Tags { "LightMode" = "ForwardAdd" }
+ Fog { Color (0,0,0,0) }
+ Cull [_Cull]
+ ZWrite Off
+ ZTest [_ZTest]
+ BlendOp [_AddBlendOp], [_AddBlendOpAlpha]
+ Blend [_AddSrcBlend] [_AddDstBlend], [_AddSrcBlendAlpha] [_AddDstBlendAlpha]
+
+ CGPROGRAM
+ #pragma target 5.0
+ #pragma multi_compile_fwdadd_fullshadows
+ #pragma multi_compile_instancing
+ #pragma multi_compile_fog
+ #pragma vertex vert
+ //ifex _Tessellation_Enabled==0
+ #pragma hull hull
+ #pragma domain domain
+ //endex
+ #pragma fragment frag
+
+
+ #define FORWARD_ADD_PASS
+
+ #include "3ner.cginc"
+ ENDCG
+ }
+ }
+ CustomEditor "Thry.ShaderEditor"
+}
+
diff --git a/LightVolumes.cginc b/LightVolumes.cginc
new file mode 100644
index 0000000..d10a190
--- /dev/null
+++ b/LightVolumes.cginc
@@ -0,0 +1,503 @@
+/*
+MIT License
+
+Copyright (c) 2025 RED_SIM
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+*/
+
+#ifndef VRC_LIGHT_VOLUMES_INCLUDED
+#define VRC_LIGHT_VOLUMES_INCLUDED
+
+// Are Light Volumes enabled on scene?
+uniform float _UdonLightVolumeEnabled;
+
+// All volumes count in scene
+uniform float _UdonLightVolumeCount;
+
+// Additive volumes max overdraw count
+uniform float _UdonLightVolumeAdditiveMaxOverdraw;
+
+// Additive volumes count
+uniform float _UdonLightVolumeAdditiveCount;
+
+// Should volumes be blended with lightprobes?
+uniform float _UdonLightVolumeProbesBlend;
+
+// Should volumes be with sharp edges when not blending with each other
+uniform float _UdonLightVolumeSharpBounds;
+
+// Main 3D Texture atlas
+uniform sampler3D _UdonLightVolume;
+
+// World to Local (-0.5, 0.5) UVW Matrix
+uniform float4x4 _UdonLightVolumeInvWorldMatrix[32];
+
+// L1 SH components rotation (relative to baked rotation)
+uniform float3 _UdonLightVolumeRotation[64];
+
+// Value that is needed to smoothly blend volumes ( BoundsScale / edgeSmooth )
+uniform float3 _UdonLightVolumeInvLocalEdgeSmooth[32];
+
+// AABB Bounds of islands on the 3D Texture atlas
+uniform float3 _UdonLightVolumeUvw[192];
+
+// Color multiplier (RGB) | If we actually need to rotate L1 components at all (A)
+uniform float4 _UdonLightVolumeColor[32];
+
+// Rotates vector by Matrix 2x3
+float3 LV_MultiplyVectorByMatrix2x3(float3 v, float3 r0, float3 r1) {
+ float3 r2 = cross(r0, r1);
+ return float3(dot(v, r0), dot(v, r1), dot(v, r2));
+}
+
+// Checks if local UVW point is in bounds from -0.5 to +0.5
+bool LV_PointLocalAABB(float3 localUVW){
+ return all(abs(localUVW) <= 0.5);
+}
+
+// Calculates local UVW using volume ID
+float3 LV_LocalFromVolume(uint volumeID, float3 worldPos) {
+ return mul(_UdonLightVolumeInvWorldMatrix[volumeID], float4(worldPos, 1.0)).xyz;
+}
+
+// Samples 3 SH textures and packing them into L1 channels
+void LV_SampleLightVolumeTex(float3 uvw0, float3 uvw1, float3 uvw2, out float3 L0, out float3 L1r, out float3 L1g, out float3 L1b) {
+ // Sampling 3D Atlas
+ float4 tex0 = tex3Dlod(_UdonLightVolume, float4(uvw0, 0));
+ float4 tex1 = tex3Dlod(_UdonLightVolume, float4(uvw1, 0));
+ float4 tex2 = tex3Dlod(_UdonLightVolume, float4(uvw2, 0));
+ // Packing final data
+ L0 = tex0.rgb;
+ L1r = float3(tex1.r, tex2.r, tex0.a);
+ L1g = float3(tex1.g, tex2.g, tex1.a);
+ L1b = float3(tex1.b, tex2.b, tex2.a);
+}
+
+// Bounds mask for a volume rotated in world space, using local UVW
+float LV_BoundsMask(float3 localUVW, float3 invLocalEdgeSmooth) {
+ float3 distToMin = (localUVW + 0.5) * invLocalEdgeSmooth;
+ float3 distToMax = (0.5 - localUVW) * invLocalEdgeSmooth;
+ float3 fade = saturate(min(distToMin, distToMax));
+ return fade.x * fade.y * fade.z;
+}
+
+// Default light probes SH components
+void LV_SampleLightProbe(out float3 L0, out float3 L1r, out float3 L1g, out float3 L1b) {
+ L0 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);
+ L1r = unity_SHAr.xyz;
+ L1g = unity_SHAg.xyz;
+ L1b = unity_SHAb.xyz;
+}
+
+// Default light probes L0 only
+float3 LV_SampleLightProbe_L0() {
+ return float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);
+}
+
+// Linear single SH L1 channel evaluation
+float LV_EvaluateSH(float L0, float3 L1, float3 n) {
+ return L0 + dot(L1, n);
+}
+
+// Samples a Volume with ID and Local UVW
+void LV_SampleVolume(uint id, float3 localUVW, out float3 L0, out float3 L1r, out float3 L1g, out float3 L1b) {
+
+ // Additive UVW
+ uint uvwID = id * 6;
+ float3 uvwMin0 = _UdonLightVolumeUvw[uvwID].xyz;
+ float3 uvwScaled = saturate(localUVW + 0.5) * (_UdonLightVolumeUvw[uvwID + 1].xyz - uvwMin0);
+ float3 uvw0 = uvwMin0 + uvwScaled;
+ float3 uvw1 = _UdonLightVolumeUvw[uvwID + 2].xyz + uvwScaled;
+ float3 uvw2 = _UdonLightVolumeUvw[uvwID + 4].xyz + uvwScaled;
+
+ // Sample additive
+ LV_SampleLightVolumeTex(uvw0, uvw1, uvw2, L0, L1r, L1g, L1b);
+
+ // Color correction
+ float4 color = _UdonLightVolumeColor[id];
+ L0 = L0 * color.rgb;
+ L1r = L1r * color.r;
+ L1g = L1g * color.g;
+ L1b = L1b * color.b;
+
+ // Rotate if needed
+ if (color.a != 0) {
+ int id2 = id * 2;
+ float3 r0 = _UdonLightVolumeRotation[id2];
+ float3 r1 = _UdonLightVolumeRotation[id2 + 1];
+ L1r = LV_MultiplyVectorByMatrix2x3(L1r, r0, r1);
+ L1g = LV_MultiplyVectorByMatrix2x3(L1g, r0, r1);
+ L1b = LV_MultiplyVectorByMatrix2x3(L1b, r0, r1);
+ }
+
+}
+
+// Samples a Volume with ID and Local UVW, but L0 component only
+float3 LV_SampleVolume_L0(uint id, float3 localUVW) {
+ uint uvwID = id * 6;
+ float3 uvwMin0 = _UdonLightVolumeUvw[uvwID].xyz;
+ float3 uvw0 = saturate(localUVW + 0.5) * (_UdonLightVolumeUvw[uvwID + 1].xyz - uvwMin0) + uvwMin0;
+ return tex3Dlod(_UdonLightVolume, float4(uvw0, 0)).rgb * _UdonLightVolumeColor[id].rgb;
+}
+
+// Forms specular based on roughness
+float LV_DistributionGGX(float NoH, float roughness) {
+ float f = (roughness - 1) * ((roughness + 1) * (NoH * NoH)) + 1;
+ return (roughness * roughness) / ((float) 3.141592653589793f * f * f);
+}
+
+// Faster normalize
+float3 LV_Normalize(float3 v) {
+ return rsqrt(dot(v, v)) * v;
+}
+
+// Calculates speculars for light volumes or any SH L1 data
+float3 LightVolumeSpecular(float3 f0, float smoothness, float3 worldNormal, float3 viewDir, float3 L0, float3 L1r, float3 L1g, float3 L1b) {
+
+ float3 specColor = max(float3(dot(reflect(-L1r, worldNormal), viewDir), dot(reflect(-L1g, worldNormal), viewDir), dot(reflect(-L1b, worldNormal), viewDir)), 0);
+
+ float3 rDir = LV_Normalize(LV_Normalize(L1r) + viewDir);
+ float3 gDir = LV_Normalize(LV_Normalize(L1g) + viewDir);
+ float3 bDir = LV_Normalize(LV_Normalize(L1b) + viewDir);
+
+ float rNh = saturate(dot(worldNormal, rDir));
+ float gNh = saturate(dot(worldNormal, gDir));
+ float bNh = saturate(dot(worldNormal, bDir));
+
+ float roughness = 1 - smoothness;
+ float roughExp = roughness * roughness;
+
+ float rSpec = LV_DistributionGGX(rNh, roughExp);
+ float gSpec = LV_DistributionGGX(gNh, roughExp);
+ float bSpec = LV_DistributionGGX(bNh, roughExp);
+
+ float3 specs = (rSpec + gSpec + bSpec) * f0;
+ float3 coloredSpecs = specs * specColor;
+
+ float3 a = coloredSpecs + specs * L0;
+ float3 b = coloredSpecs * 4;
+
+ return max(lerp(a, b, smoothness), 0.0);
+
+}
+
+float3 LightVolumeSpecular(float3 albedo, float smoothness, float metallic, float3 worldNormal, float3 viewDir, float3 L0, float3 L1r, float3 L1g, float3 L1b) {
+
+ float3 specularf0 = lerp(0.04f, albedo, metallic);
+ return LightVolumeSpecular(specularf0, smoothness, worldNormal, viewDir, L0, L1r, L1g, L1b);
+}
+
+// Calculates speculars for light volumes or any SH L1 data, but simplified, with only one dominant direction
+float3 LightVolumeSpecularDominant(float3 f0, float smoothness, float3 worldNormal, float3 viewDir, float3 L0, float3 L1r, float3 L1g, float3 L1b) {
+
+ float3 dominantDir = L1r + L1g + L1b;
+ float3 dir = LV_Normalize(LV_Normalize(dominantDir) + viewDir);
+ float nh = saturate(dot(worldNormal, dir));
+
+ float roughness = 1 - smoothness;
+ float roughExp = roughness * roughness;
+
+ float spec = LV_DistributionGGX(nh, roughExp);
+
+ return max(spec * L0 * f0, 0.0) * 2;
+
+}
+
+float3 LightVolumeSpecularDominant(float3 albedo, float smoothness, float metallic, float3 worldNormal, float3 viewDir, float3 L0, float3 L1r, float3 L1g, float3 L1b) {
+
+ float3 specularf0 = lerp(0.04f, albedo, metallic);
+ return LightVolumeSpecularDominant(specularf0, smoothness, worldNormal, viewDir, L0, L1r, L1g, L1b);
+}
+
+// Calculate Light Volume Color based on all SH components provided and the world normal
+float3 LightVolumeEvaluate(float3 worldNormal, float3 L0, float3 L1r, float3 L1g, float3 L1b) {
+ return float3(LV_EvaluateSH(L0.r, L1r, worldNormal), LV_EvaluateSH(L0.g, L1g, worldNormal), LV_EvaluateSH(L0.b, L1b, worldNormal));
+}
+
+// Calculates SH components based on the world position
+void LightVolumeSH(float3 worldPos, out float3 L0, out float3 L1r, out float3 L1g, out float3 L1b) {
+
+ // Initializing output variables
+ L0 = float3(0, 0, 0);
+ L1r = float3(0, 0, 0);
+ L1g = float3(0, 0, 0);
+ L1b = float3(0, 0, 0);
+
+ // Fallback to default light probes if Light Volume are not enabled
+ if (!_UdonLightVolumeEnabled || _UdonLightVolumeCount == 0) {
+ LV_SampleLightProbe(L0, L1r, L1g, L1b);
+ return;
+ }
+
+ uint volumeID_A = -1; // Main, dominant volume ID
+ uint volumeID_B = -1; // Secondary volume ID to blend main with
+
+ float3 localUVW = float3(0, 0, 0); // Last local UVW to use in disabled Light Probes mode
+ float3 localUVW_A = float3(0, 0, 0); // Main local UVW for Y Axis and Free rotations
+ float3 localUVW_B = float3(0, 0, 0); // Secondary local UVW
+
+ // Are A and B volumes NOT found?
+ bool isNoA = true;
+ bool isNoB = true;
+
+ // Additive volumes variables
+ uint addVolumesCount = 0;
+ float3 L0_, L1r_, L1g_, L1b_;
+
+ // Iterating through all light volumes with simplified algorithm requiring Light Volumes to be sorted by weight in descending order
+ [loop]
+ for (uint id = 0; id < (uint) _UdonLightVolumeCount; id++) {
+ localUVW = LV_LocalFromVolume(id, worldPos);
+ if (LV_PointLocalAABB(localUVW)) { // Intersection test
+ if (id < (uint) _UdonLightVolumeAdditiveCount) { // Sampling additive volumes
+ if (addVolumesCount < (uint) _UdonLightVolumeAdditiveMaxOverdraw) {
+ LV_SampleVolume(id, localUVW, L0_, L1r_, L1g_, L1b_);
+ L0 += L0_;
+ L1r += L1r_;
+ L1g += L1g_;
+ L1b += L1b_;
+ addVolumesCount++;
+ }
+ } else if (isNoA) { // First, searching for volume A
+ volumeID_A = id;
+ localUVW_A = localUVW;
+ isNoA = false;
+ } else { // Next, searching for volume B if A found
+ volumeID_B = id;
+ localUVW_B = localUVW;
+ isNoB = false;
+ break;
+ }
+ }
+ }
+
+ // Volume A SH components and mask to blend volume sides
+ float3 L0_A = float3(1, 1, 1);
+ float3 L1r_A = float3(0, 0, 0);
+ float3 L1g_A = float3(0, 0, 0);
+ float3 L1b_A = float3(0, 0, 0);
+
+ // If no volumes found, using Light Probes as fallback
+ if (isNoA && _UdonLightVolumeProbesBlend) {
+ LV_SampleLightProbe(L0_, L1r_, L1g_, L1b_);
+ L0 += L0_;
+ L1r += L1r_;
+ L1g += L1g_;
+ L1b += L1b_;
+ return;
+ }
+
+ // Fallback to lowest weight light volume if outside of every volume
+ localUVW_A = isNoA ? localUVW : localUVW_A;
+ volumeID_A = isNoA ? _UdonLightVolumeCount - 1 : volumeID_A;
+
+ // Sampling Light Volume A
+ LV_SampleVolume(volumeID_A, localUVW_A, L0_A, L1r_A, L1g_A, L1b_A);
+
+ float mask = LV_BoundsMask(localUVW_A, _UdonLightVolumeInvLocalEdgeSmooth[volumeID_A]);
+ if (mask == 1 || isNoA || (_UdonLightVolumeSharpBounds && isNoB)) { // Returning SH A result if it's the center of mask or out of bounds
+ L0 += L0_A;
+ L1r += L1r_A;
+ L1g += L1g_A;
+ L1b += L1b_A;
+ return;
+ }
+
+ // Volume B SH components
+ float3 L0_B = float3(1, 1, 1);
+ float3 L1r_B = float3(0, 0, 0);
+ float3 L1g_B = float3(0, 0, 0);
+ float3 L1b_B = float3(0, 0, 0);
+
+ if (isNoB && _UdonLightVolumeProbesBlend) { // No Volume found and light volumes blending enabled
+
+ // Sample Light Probes B
+ LV_SampleLightProbe(L0_B, L1r_B, L1g_B, L1b_B);
+
+ } else { // Blending Volume A and Volume B
+
+ // If no volume b found, use last one found to fallback
+ localUVW_B = isNoB ? localUVW : localUVW_B;
+ volumeID_B = isNoB ? _UdonLightVolumeCount - 1 : volumeID_B;
+
+ // Sampling Light Volume B
+ LV_SampleVolume(volumeID_B, localUVW_B, L0_B, L1r_B, L1g_B, L1b_B);
+
+ }
+
+ // Lerping SH components
+ L0 += lerp(L0_B, L0_A, mask);
+ L1r += lerp(L1r_B, L1r_A, mask);
+ L1g += lerp(L1g_B, L1g_A, mask);
+ L1b += lerp(L1b_B, L1b_A, mask);
+
+}
+
+// Calculates SH components based on the world position but for additive volumes only
+void LightVolumeAdditiveSH(float3 worldPos, out float3 L0, out float3 L1r, out float3 L1g, out float3 L1b) {
+
+ // Initializing output variables
+ L0 = float3(0, 0, 0);
+ L1r = float3(0, 0, 0);
+ L1g = float3(0, 0, 0);
+ L1b = float3(0, 0, 0);
+
+ if (!_UdonLightVolumeEnabled || _UdonLightVolumeAdditiveCount == 0) return;
+
+ // Additive volumes variables
+ float3 localUVW = float3(0, 0, 0);
+ float3 L0_, L1r_, L1g_, L1b_;
+
+ // Max additive volumes to sample
+ uint count = min((uint) _UdonLightVolumeAdditiveCount, (uint) _UdonLightVolumeAdditiveMaxOverdraw);
+
+ // Iterating through all light volumes with simplified algorithm requiring Light Volumes to be sorted by weight in descending order
+ [loop]
+ for (uint id = 0; id < count; id++) {
+ localUVW = LV_LocalFromVolume(id, worldPos);
+ //Intersection test
+ if (LV_PointLocalAABB(localUVW)) {
+ LV_SampleVolume(id, localUVW, L0_, L1r_, L1g_, L1b_);
+ L0 += L0_;
+ L1r += L1r_;
+ L1g += L1g_;
+ L1b += L1b_;
+ }
+ }
+
+}
+
+// Calculates L0 components based on the world position
+float3 LightVolumeSH_L0(float3 worldPos) {
+
+ // Fallback to default light probes if Light Volume are not enabled
+ if (!_UdonLightVolumeEnabled || _UdonLightVolumeCount == 0) {
+ return LV_SampleLightProbe_L0();
+ }
+
+ float3 L0 = float3(0, 0, 0);
+
+ uint volumeID_A = -1; // Main, dominant volume ID
+ uint volumeID_B = -1; // Secondary volume ID to blend main with
+
+ float3 localUVW = float3(0, 0, 0); // Last local UVW to use in disabled Light Probes mode
+ float3 localUVW_A = float3(0, 0, 0); // Main local UVW for Y Axis and Free rotations
+ float3 localUVW_B = float3(0, 0, 0); // Secondary local UVW
+
+ // Are A and B volumes NOT found?
+ bool isNoA = true;
+ bool isNoB = true;
+
+ // Additive volumes variables
+ uint addVolumesCount = 0;
+
+ // Iterating through all light volumes with simplified algorithm requiring Light Volumes to be sorted by weight in descending order
+ [loop]
+ for (uint id = 0; id < (uint) _UdonLightVolumeCount; id++) {
+ localUVW = LV_LocalFromVolume(id, worldPos);
+ if (LV_PointLocalAABB(localUVW)) { // Intersection test
+ if (id < (uint) _UdonLightVolumeAdditiveCount) { // Sampling additive volumes
+ if (addVolumesCount < (uint) _UdonLightVolumeAdditiveMaxOverdraw) {
+ L0 += LV_SampleVolume_L0(id, localUVW);
+ addVolumesCount++;
+ }
+ } else if (isNoA) { // First, searching for volume A
+ volumeID_A = id;
+ localUVW_A = localUVW;
+ isNoA = false;
+ } else { // Next, searching for volume B if A found
+ volumeID_B = id;
+ localUVW_B = localUVW;
+ isNoB = false;
+ break;
+ }
+ }
+ }
+
+ // If no volumes found, using Light Probes as fallback
+ if (isNoA && _UdonLightVolumeProbesBlend) {
+ return L0 + LV_SampleLightProbe_L0();
+ }
+
+ // Fallback to lowest weight light volume if outside of every volume
+ localUVW_A = isNoA ? localUVW : localUVW_A;
+ volumeID_A = isNoA ? _UdonLightVolumeCount - 1 : volumeID_A;
+
+ // Sampling Light Volume A
+ float3 L0_A = LV_SampleVolume_L0(volumeID_A, localUVW_A);
+
+ float mask = LV_BoundsMask(localUVW_A, _UdonLightVolumeInvLocalEdgeSmooth[volumeID_A]);
+ if (mask == 1 || isNoA || (_UdonLightVolumeSharpBounds && isNoB)) { // Returning SH A result if it's the center of mask or out of bounds
+ return L0 + L0_A;
+ }
+
+ // Volume B L0
+ float3 L0_B = float3(1, 1, 1);
+
+ if (isNoB && _UdonLightVolumeProbesBlend) { // No Volume found and light volumes blending enabled
+
+ // Sample Light Probes B
+ L0_B = LV_SampleLightProbe_L0();
+
+ } else { // Blending Volume A and Volume B
+
+ // If no volume b found, use last one found to fallback
+ localUVW_B = isNoB ? localUVW : localUVW_B;
+ volumeID_B = isNoB ? _UdonLightVolumeCount - 1 : volumeID_B;
+
+ // Sampling Light Volume B
+ L0_B = LV_SampleVolume_L0(volumeID_B, localUVW_B);
+
+ }
+
+ // Lerping L0
+ return L0 + lerp(L0_B, L0_A, mask);
+
+}
+
+// Calculates L0 component based on the world position but for additive volumes only
+float3 LightVolumeAdditiveSH_L0(float3 worldPos) {
+
+ // Initializing output variables
+ float3 L0 = float3(0, 0, 0);
+
+ if (!_UdonLightVolumeEnabled || _UdonLightVolumeAdditiveCount == 0) return L0;
+
+ // Additive volumes variables
+ float3 localUVW = float3(0, 0, 0);
+
+ // Max additive volumes to sample
+ uint count = min((uint) _UdonLightVolumeAdditiveCount, (uint) _UdonLightVolumeAdditiveMaxOverdraw);
+
+ // Iterating through all light volumes with simplified algorithm requiring Light Volumes to be sorted by weight in descending order
+ [loop]
+ for (uint id = 0; id < count; id++) {
+ localUVW = LV_LocalFromVolume(id, worldPos);
+ //Intersection test
+ if (LV_PointLocalAABB(localUVW)) {
+ L0 += LV_SampleVolume_L0(id, localUVW);
+ }
+ }
+
+ return L0;
+
+}
+
+#endif
diff --git a/UnityImageBasedLightingMinimal.cginc b/UnityImageBasedLightingMinimal.cginc
new file mode 100644
index 0000000..fb8b8f3
--- /dev/null
+++ b/UnityImageBasedLightingMinimal.cginc
@@ -0,0 +1,73 @@
+// Unity built-in shader source. Copyright (c) 2016 Unity Technologies. MIT license (see license.txt)
+
+#ifndef UNITY_IMAGE_BASED_LIGHTING_INCLUDED
+#define UNITY_IMAGE_BASED_LIGHTING_INCLUDED
+
+#include "pbr_utils.cginc"
+#include "UnityStandardUtils.cginc"
+
+// ----------------------------------------------------------------------------
+// GlossyEnvironment - Function to integrate the specular lighting with default sky or reflection probes
+// ----------------------------------------------------------------------------
+struct Unity_GlossyEnvironmentData
+{
+ // - Deferred case have one cubemap
+ // - Forward case can have two blended cubemap (unusual should be deprecated).
+
+ // Surface properties use for cubemap integration
+ half roughness; // CAUTION: This is perceptualRoughness but because of compatibility this name can't be change :(
+ half3 reflUVW;
+};
+
+// ----------------------------------------------------------------------------
+
+Unity_GlossyEnvironmentData UnityGlossyEnvironmentSetup(half Smoothness, half3 worldViewDir, half3 Normal, half3 fresnel0)
+{
+ Unity_GlossyEnvironmentData g;
+
+ g.roughness /* perceptualRoughness */ = smoothnessToPerceptualRoughness(Smoothness);
+ g.reflUVW = reflect(-worldViewDir, Normal);
+
+ return g;
+}
+
+// ----------------------------------------------------------------------------
+half perceptualRoughnessToMipmapLevel(half perceptualRoughness)
+{
+ return perceptualRoughness * UNITY_SPECCUBE_LOD_STEPS;
+}
+
+// ----------------------------------------------------------------------------
+half mipmapLevelToPerceptualRoughness(half mipmapLevel)
+{
+ return mipmapLevel / UNITY_SPECCUBE_LOD_STEPS;
+}
+
+// ----------------------------------------------------------------------------
+half3 Unity_GlossyEnvironment (UNITY_ARGS_TEXCUBE(tex), half4 hdr, Unity_GlossyEnvironmentData glossIn)
+{
+ half perceptualRoughness = glossIn.roughness /* perceptualRoughness */ ;
+
+// TODO: CAUTION: remap from Morten may work only with offline convolution, see impact with runtime convolution!
+// For now disabled
+#if 0
+ float m = PerceptualRoughnessToRoughness(perceptualRoughness); // m is the real roughness parameter
+ const float fEps = 1.192092896e-07F; // smallest such that 1.0+FLT_EPSILON != 1.0 (+1e-4h is NOT good here. is visibly very wrong)
+ float n = (2.0/max(fEps, m*m))-2.0; // remap to spec power. See eq. 21 in --> https://dl.dropboxusercontent.com/u/55891920/papers/mm_brdf.pdf
+
+ n /= 4; // remap from n_dot_h formulatino to n_dot_r. See section "Pre-convolved Cube Maps vs Path Tracers" --> https://s3.amazonaws.com/docs.knaldtech.com/knald/1.0.0/lys_power_drops.html
+
+ perceptualRoughness = pow( 2/(n+2), 0.25); // remap back to square root of real roughness (0.25 include both the sqrt root of the conversion and sqrt for going from roughness to perceptualRoughness)
+#else
+ // MM: came up with a surprisingly close approximation to what the #if 0'ed out code above does.
+ perceptualRoughness = perceptualRoughness*(1.7 - 0.7*perceptualRoughness);
+#endif
+
+
+ half mip = perceptualRoughnessToMipmapLevel(perceptualRoughness);
+ half3 R = glossIn.reflUVW;
+ half4 rgbm = UNITY_SAMPLE_TEXCUBE_LOD(tex, R, mip);
+
+ return DecodeHDR(rgbm, hdr);
+}
+#endif // UNITY_IMAGE_BASED_LIGHTING_INCLUDED \ No newline at end of file
diff --git a/UnityStandardCoreMinimal.cginc b/UnityStandardCoreMinimal.cginc
new file mode 100644
index 0000000..8f2135d
--- /dev/null
+++ b/UnityStandardCoreMinimal.cginc
@@ -0,0 +1,72 @@
+#ifndef __UNITY_STANDARD_CORE_MINIMAL_INC
+#define __UNITY_STANDARD_CORE_MINIMAL_INC
+
+#include "filtering.cginc"
+#include "UnityShadowLibrary.cginc"
+
+// Now add the SampleShadowMaskBicubic function
+fixed4 SampleShadowMaskBicubic(float2 uv)
+{
+ #if defined(UNITY_SHADOWMASK) && defined(SHADER_API_D3D11)
+ float width, height;
+ unity_ShadowMask.GetDimensions(width, height);
+ float4 unity_ShadowMask_TexelSize = float4(width, height, 1.0/width, 1.0/height);
+
+ return SampleTexture2DBicubicFilter(unity_ShadowMask, sampler_unity_ShadowMask,
+ uv, unity_ShadowMask_TexelSize);
+ #else
+ // Fallback to regular sampling
+ return UNITY_SAMPLE_TEX2D(unity_ShadowMask, uv);
+ #endif
+}
+
+fixed UnitySampleBakedOcclusionBicubic(float2 lightmapUV, float3 worldPos)
+{
+ #if defined (SHADOWS_SHADOWMASK)
+ #if defined(LIGHTMAP_ON)
+ fixed4 rawOcclusionMask = SampleShadowMaskBicubic(lightmapUV.xy);
+ #else
+ fixed4 rawOcclusionMask = fixed4(1.0, 1.0, 1.0, 1.0);
+ #if UNITY_LIGHT_PROBE_PROXY_VOLUME
+ if (unity_ProbeVolumeParams.x == 1.0)
+ rawOcclusionMask = LPPV_SampleProbeOcclusion(worldPos);
+ else
+ rawOcclusionMask = SampleShadowMaskBicubic(lightmapUV.xy);
+ #else
+ rawOcclusionMask = SampleShadowMaskBicubic(lightmapUV.xy);
+ #endif
+ #endif
+ return saturate(dot(rawOcclusionMask, unity_OcclusionMaskSelector));
+
+ #else
+
+ //In forward dynamic objects can only get baked occlusion from LPPV, light probe occlusion is done on the CPU by attenuating the light color.
+ fixed atten = 1.0f;
+ #if defined(UNITY_INSTANCING_ENABLED) && defined(UNITY_USE_SHCOEFFS_ARRAYS)
+ // ...unless we are doing instancing, and the attenuation is packed into SHC array's .w component.
+ atten = unity_SHC.w;
+ #endif
+
+ #if UNITY_LIGHT_PROBE_PROXY_VOLUME && !defined(LIGHTMAP_ON) && !UNITY_STANDARD_SIMPLE
+ fixed4 rawOcclusionMask = atten.xxxx;
+ if (unity_ProbeVolumeParams.x == 1.0)
+ rawOcclusionMask = LPPV_SampleProbeOcclusion(worldPos);
+ return saturate(dot(rawOcclusionMask, unity_OcclusionMaskSelector));
+ #endif
+
+ return atten;
+ #endif
+}
+
+void GetBakedAttenuation(inout float atten, float2 lightmapUV, float3 worldPos)
+{
+ // Base pass with Lightmap support is responsible for handling ShadowMask / blending here for performance reason
+ #if defined(HANDLE_SHADOWS_BLENDING_IN_GI)
+ half bakedAtten = UnitySampleBakedOcclusionBicubic(lightmapUV.xy, worldPos);
+ float zDist = dot(_WorldSpaceCameraPos - worldPos, UNITY_MATRIX_V[2].xyz);
+ float fadeDist = UnityComputeShadowFadeDistance(worldPos, zDist);
+ atten = UnityMixRealtimeAndBakedShadows(atten, bakedAtten, UnityComputeShadowFade(fadeDist));
+ #endif
+}
+
+#endif // __UNITY_STANDARD_CORE_MINIMAL_INC
diff --git a/brdf.cginc b/brdf.cginc
new file mode 100644
index 0000000..d36d82b
--- /dev/null
+++ b/brdf.cginc
@@ -0,0 +1,58 @@
+#ifndef __BRDF_INC
+#define __BRDF_INC
+
+#include "pbr.cginc"
+#include "lighting.cginc"
+#include "lysenko.cginc"
+#include "math.cginc"
+
+float fresnel(float LoH) {
+ // Schlick's approximation
+ float n1 = 1.0;
+ float n2 = 1.33;
+ float r0 = (n1 - n2) / (n1 + n2);
+ r0 = r0 * r0;
+
+ float term = 1.0 - LoH;
+ float term2 = term * term;
+ float term5 = term2 * term2 * term;
+ return r0 + (1.0 - r0) * term5;
+}
+
+float4 brdf(Pbr pbr, LightData data) {
+ float3 specular = 0;
+ float3 diffuse = 0;
+
+ // Direct
+ if (true) {
+ float F = fresnel(data.direct.LoH);
+ float D = D_GGX(pbr.roughness, data.direct.NoH, data.direct.H);
+ float V = V_SmithGGXCorrelated_Fast(pbr.roughness, data.common.NoV, data.direct.NoL);
+
+ float denom = 4.0f * data.common.NoV * data.direct.NoL;
+ float FDV = denom > _BRDF_Specular_Min_Denom ? F * D * V / denom : 0.0f;
+ specular += FDV * data.direct.color * data.direct.NoL;
+
+ float Fd = Fd_OrenNayar(pbr.roughness, data.common.NoV, data.direct.NoL, data.direct.LoV);
+ float3 remainder = (1.0f - F);
+ diffuse += (Fd / PI) * remainder * pbr.albedo.xyz * data.direct.color;
+ remainder *= (1.0f - (Fd / PI) * pbr.albedo);
+ }
+
+ // Indirect
+ if (true) {
+ float F = fresnel(data.indirect.LoH);
+
+ specular += F * data.indirect.specular;
+
+ float Fd = 1.0 / PI;
+ float3 remainder = (1.0f - F);
+ diffuse += Fd * remainder * pbr.albedo.xyz * data.indirect.diffuse;
+ remainder *= (1.0f - Fd * pbr.albedo);
+ }
+
+ return float4(diffuse + specular, 1);
+}
+
+#endif // __BRDF_INC
+
diff --git a/features.cginc b/features.cginc
new file mode 100644
index 0000000..cffb33e
--- /dev/null
+++ b/features.cginc
@@ -0,0 +1,76 @@
+#ifndef __FEATURES_INC
+#define __FEATURES_INC
+
+//ifex _Gradient_Normals_Enabled==0
+#pragma shader_feature_local _GRADIENT_NORMALS
+//endex
+
+//ifex _Sea_FX_Enabled==0
+#pragma shader_feature_local _SEA_FX
+//endex
+
+//ifex _Sea_FX_Heightmaps_Y_0_Enabled==0
+#pragma shader_feature_local _SEA_FX_HEIGHTMAPS_Y_0
+//endex
+//ifex _Sea_FX_Heightmaps_Y_1_Enabled==0
+#pragma shader_feature_local _SEA_FX_HEIGHTMAPS_Y_1
+//endex
+//ifex _Sea_FX_Heightmaps_Y_2_Enabled==0
+#pragma shader_feature_local _SEA_FX_HEIGHTMAPS_Y_2
+//endex
+//ifex _Sea_FX_Heightmaps_Y_3_Enabled==0
+#pragma shader_feature_local _SEA_FX_HEIGHTMAPS_Y_3
+//endex
+//ifex _Sea_FX_Heightmaps_XZ_0_Enabled==0
+#pragma shader_feature_local _SEA_FX_HEIGHTMAPS_XZ_0
+//endex
+//ifex _Sea_FX_Heightmaps_XZ_1_Enabled==0
+#pragma shader_feature_local _SEA_FX_HEIGHTMAPS_XZ_1
+//endex
+//ifex _Sea_FX_Heightmaps_XZ_2_Enabled==0
+#pragma shader_feature_local _SEA_FX_HEIGHTMAPS_XZ_2
+//endex
+//ifex _Sea_FX_Heightmaps_XZ_3_Enabled==0
+#pragma shader_feature_local _SEA_FX_HEIGHTMAPS_XZ_3
+//endex
+
+//ifex _Sea_FX_Vertical_Derivatives_0_Enabled==0
+#pragma shader_feature_local _SEA_FX_VERTICAL_DERIVATIVES_0
+//endex
+//ifex _Sea_FX_Horizontal_Derivatives_0_Enabled==0
+#pragma shader_feature_local _SEA_FX_HORIZONTAL_DERIVATIVES_0
+//endex
+//ifex _Sea_FX_Vertical_Derivatives_1_Enabled==0
+#pragma shader_feature_local _SEA_FX_VERTICAL_DERIVATIVES_1
+//endex
+//ifex _Sea_FX_Horizontal_Derivatives_1_Enabled==0
+#pragma shader_feature_local _SEA_FX_HORIZONTAL_DERIVATIVES_1
+//endex
+//ifex _Sea_FX_Vertical_Derivatives_2_Enabled==0
+#pragma shader_feature_local _SEA_FX_VERTICAL_DERIVATIVES_2
+//endex
+//ifex _Sea_FX_Horizontal_Derivatives_2_Enabled==0
+#pragma shader_feature_local _SEA_FX_HORIZONTAL_DERIVATIVES_2
+//endex
+//ifex _Sea_FX_Vertical_Derivatives_3_Enabled==0
+#pragma shader_feature_local _SEA_FX_VERTICAL_DERIVATIVES_3
+//endex
+//ifex _Sea_FX_Horizontal_Derivatives_3_Enabled==0
+#pragma shader_feature_local _SEA_FX_HORIZONTAL_DERIVATIVES_3
+//endex
+
+//ifex _Sea_Foam_Enabled==0
+#pragma shader_feature_local _SEA_FOAM
+//endex
+
+//ifex _Sea_SSS_Enabled==0
+#pragma shader_feature_local _SEA_SSS
+//endex
+
+//ifex _Tessellation_Enabled==0
+#pragma shader_feature_local _TESSELLATION
+#pragma shader_feature_local _TESSELLATION_HEIGHTMAP_WORLD_SPACE
+#pragma shader_feature_local _TESSELLATION_HEIGHTMAP_DIRECTION_CONTROL
+//endex
+
+#endif // __FEATURES_INC
diff --git a/filamented.cginc b/filamented.cginc
new file mode 100644
index 0000000..0e27bbc
--- /dev/null
+++ b/filamented.cginc
@@ -0,0 +1,355 @@
+#ifndef __FILAMENTED_INC
+#define __FILAMENTED_INC
+
+#include "globals.cginc"
+#include "math.cginc"
+
+/*
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+*/
+
+#include "UnityCG.cginc"
+#include "UnityImageBasedLightingMinimal.cginc"
+
+#define MIN_PERCEPTUAL_ROUGHNESS 0.045f
+#define MIN_ROUGHNESS 0.002025f
+
+float D_GGX(float roughness, float NoH, const float3 h) {
+ // Walter et al. 2007, "Microfacet Models for Refraction through Rough Surfaces"
+
+ // In mediump, there are two problems computing 1.0 - NoH^2
+ // 1) 1.0 - NoH^2 suffers floating point cancellation when NoH^2 is close to 1 (highlights)
+ // 2) NoH doesn't have enough precision around 1.0
+ // Both problem can be fixed by computing 1-NoH^2 in highp and providing NoH in highp as well
+
+ // However, we can do better using Lagrange's identity:
+ // ||a x b||^2 = ||a||^2 ||b||^2 - (a . b)^2
+ // since N and H are unit vectors: ||N x H||^2 = 1.0 - NoH^2
+ // This computes 1.0 - NoH^2 directly (which is close to zero in the highlights and has
+ // enough precision).
+ // Overall this yields better performance, keeping all computations in mediump
+ // Not available without reworking to pass NxH to the function
+ float oneMinusNoHSquared = 1.0 - NoH * NoH;
+ float a = NoH * roughness;
+ float k = roughness / (oneMinusNoHSquared + a * a);
+ float d = k * k * (1.0 / PI);
+ return d;
+}
+
+float V_SmithGGXCorrelated_Fast(float roughness, float NoV, float NoL) {
+ // Hammon 2017, "PBR Diffuse Lighting for GGX+Smith Microsurfaces"
+ float v = 0.5 / lerp(2.0 * NoL * NoV, NoL + NoV, roughness);
+ return v;
+}
+
+float normalFiltering(float perceptualRoughness, const float3 worldNormal) {
+ // Kaplanyan 2016, "Stable specular highlights"
+ // Tokuyoshi 2017, "Error Reduction and Simplification for Shading Anti-Aliasing"
+ // Tokuyoshi and Kaplanyan 2019, "Improved Geometric Specular Antialiasing"
+
+ // This implementation is meant for deferred rendering in the original paper but
+ // we use it in forward rendering as well (as discussed in Tokuyoshi and Kaplanyan
+ // 2019). The main reason is that the forward version requires an expensive transform
+ // of the half vector by the tangent frame for every light. This is therefore an
+ // approximation but it works well enough for our needs and provides an improvement
+ // over our original implementation based on Vlachos 2015, "Advanced VR Rendering".
+
+ float3 du = ddx(worldNormal);
+ float3 dv = ddy(worldNormal);
+
+ float variance = _Specular_AA_Variance * (dot(du, du) + dot(dv, dv));
+
+ float roughness = perceptualRoughnessToRoughness(perceptualRoughness);
+ float kernelRoughness = min(2.0 * variance, _Specular_AA_Threshold);
+ float squareRoughness = saturate(roughness * roughness + kernelRoughness);
+
+ return roughnessToPerceptualRoughness(sqrt(squareRoughness));
+}
+
+half3 Unity_GlossyEnvironment_local (UNITY_ARGS_TEXCUBE(tex), half4 hdr, Unity_GlossyEnvironmentData glossIn)
+{
+ half perceptualRoughness = glossIn.roughness /* perceptualRoughness */ ;
+
+ // Workaround for issue where objects are blurrier than they should be
+ // due to specular AA.
+ float roughnessAdjustment = 1-perceptualRoughness;
+ roughnessAdjustment = MIN_PERCEPTUAL_ROUGHNESS * roughnessAdjustment * roughnessAdjustment;
+ perceptualRoughness = perceptualRoughness - roughnessAdjustment;
+
+ // Unity derivation
+ perceptualRoughness = perceptualRoughness*(1.7 - 0.7 * perceptualRoughness);
+ // Filament derivation
+ // perceptualRoughness = perceptualRoughness * (2.0 - perceptualRoughness);
+ half mip = perceptualRoughnessToMipmapLevel(perceptualRoughness);
+ half3 R = glossIn.reflUVW;
+ half4 rgbm = UNITY_SAMPLE_TEXCUBE_LOD(tex, R, mip);
+
+ return DecodeHDR(rgbm, hdr);
+}
+
+UnityGIInput InitialiseUnityGIInput(float3 worldPos, float3 view_dir)
+{
+ UnityGIInput d;
+ d.worldPos = worldPos;
+ d.worldViewDir = view_dir;
+ d.probeHDR[0] = unity_SpecCube0_HDR;
+ d.probeHDR[1] = unity_SpecCube1_HDR;
+ #if defined(UNITY_SPECCUBE_BLENDING) || defined(UNITY_SPECCUBE_BOX_PROJECTION)
+ d.boxMin[0] = unity_SpecCube0_BoxMin; // .w holds lerp value for blending
+ #endif
+ #ifdef UNITY_SPECCUBE_BOX_PROJECTION
+ d.boxMax[0] = unity_SpecCube0_BoxMax;
+ d.probePosition[0] = unity_SpecCube0_ProbePosition;
+ d.boxMax[1] = unity_SpecCube1_BoxMax;
+ d.boxMin[1] = unity_SpecCube1_BoxMin;
+ d.probePosition[1] = unity_SpecCube1_ProbePosition;
+ #endif
+ return d;
+}
+
+inline half3 UnityGI_prefilteredRadiance(const UnityGIInput data, const float perceptualRoughness, const float3 r)
+{
+ half3 specular;
+
+ Unity_GlossyEnvironmentData glossIn = (Unity_GlossyEnvironmentData)0;
+ glossIn.roughness = perceptualRoughness;
+ glossIn.reflUVW = r;
+
+ #ifdef UNITY_SPECCUBE_BOX_PROJECTION
+ // we will tweak reflUVW in glossIn directly (as we pass it to Unity_GlossyEnvironment twice for probe0 and probe1), so keep original to pass into BoxProjectedCubemapDirection
+ half3 originalReflUVW = glossIn.reflUVW;
+ glossIn.reflUVW = BoxProjectedCubemapDirection (originalReflUVW, data.worldPos, data.probePosition[0], data.boxMin[0], data.boxMax[0]);
+ #endif
+
+ #ifdef _GLOSSYREFLECTIONS_OFF
+ specular = unity_IndirectSpecColor.rgb;
+ #else
+ half3 env0 = Unity_GlossyEnvironment_local (UNITY_PASS_TEXCUBE(unity_SpecCube0), data.probeHDR[0], glossIn);
+ #ifdef UNITY_SPECCUBE_BLENDING
+ const float kBlendFactor = 0.99999;
+ float blendLerp = data.boxMin[0].w;
+ UNITY_BRANCH
+ if (blendLerp < kBlendFactor)
+ {
+ #ifdef UNITY_SPECCUBE_BOX_PROJECTION
+ glossIn.reflUVW = BoxProjectedCubemapDirection (originalReflUVW, data.worldPos, data.probePosition[1], data.boxMin[1], data.boxMax[1]);
+ #endif
+
+ half3 env1 = Unity_GlossyEnvironment_local (UNITY_PASS_TEXCUBE_SAMPLER(unity_SpecCube1,unity_SpecCube0), data.probeHDR[1], glossIn);
+ specular = lerp(env1, env0, blendLerp);
+ }
+ else
+ {
+ specular = env0;
+ }
+ #else
+ specular = env0;
+ #endif
+ #endif
+
+ return specular;
+}
+
+#endif // __FILAMENTED_INC
diff --git a/filtering.cginc b/filtering.cginc
new file mode 100644
index 0000000..18fcad3
--- /dev/null
+++ b/filtering.cginc
@@ -0,0 +1,255 @@
+#ifndef __FILTERING_INC
+#define __FILTERING_INC
+
+#include "sampling.cginc"
+
+/*
+
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+ TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+ 1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+ 2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+ 3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+ 4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+ 5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+ 6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+ 7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+ 8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+ 9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+ END OF TERMS AND CONDITIONS
+
+ APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+ Copyright [yyyy] [name of copyright owner]
+
+ Licensed under the Apache License, Version 2.0 (the "License");
+ you may not use this file except in compliance with the License.
+ You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+ Unless required by applicable law or agreed to in writing, software
+ distributed under the License is distributed on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ See the License for the specific language governing permissions and
+ limitations under the License.
+
+*/
+
+float4 cubic(float v)
+{
+ float4 n = float4(1.0, 2.0, 3.0, 4.0) - v;
+ float4 s = n * n * n;
+ float x = s.x;
+ float y = s.y - 4.0 * s.x;
+ float z = s.z - 4.0 * s.y + 6.0 * s.x;
+ float w = 6.0 - x - y - z;
+ return float4(x, y, z, w);
+}
+
+
+// Unity's SampleTexture2DBicubic doesn't exist in 2018, which is our target here.
+// So this is a similar function with tweaks to have similar semantics.
+
+float4 SampleTexture2DBicubicFilter(TEXTURE2D_PARAM(tex, smp), float2 coord, float4 texSize)
+{
+ coord = coord * texSize.xy - 0.5;
+ float fx = frac(coord.x);
+ float fy = frac(coord.y);
+ coord.x -= fx;
+ coord.y -= fy;
+
+ float4 xcubic = cubic(fx);
+ float4 ycubic = cubic(fy);
+
+ float4 c = float4(coord.x - 0.5, coord.x + 1.5, coord.y - 0.5, coord.y + 1.5);
+ float4 s = float4(xcubic.x + xcubic.y, xcubic.z + xcubic.w, ycubic.x + ycubic.y, ycubic.z + ycubic.w);
+ float4 offset = c + float4(xcubic.y, xcubic.w, ycubic.y, ycubic.w) / s;
+
+ float4 sample0 = SAMPLE_TEXTURE2D(tex, smp, float2(offset.x, offset.z) * texSize.zw);
+ float4 sample1 = SAMPLE_TEXTURE2D(tex, smp, float2(offset.y, offset.z) * texSize.zw);
+ float4 sample2 = SAMPLE_TEXTURE2D(tex, smp, float2(offset.x, offset.w) * texSize.zw);
+ float4 sample3 = SAMPLE_TEXTURE2D(tex, smp, float2(offset.y, offset.w) * texSize.zw);
+
+ float sx = s.x / (s.x + s.y);
+ float sy = s.z / (s.z + s.w);
+
+ return lerp(
+ lerp(sample3, sample2, sx),
+ lerp(sample1, sample0, sx), sy);
+}
+
+#endif // __FILTERING_INC \ No newline at end of file
diff --git a/globals.cginc b/globals.cginc
new file mode 100644
index 0000000..2ce282b
--- /dev/null
+++ b/globals.cginc
@@ -0,0 +1,115 @@
+#ifndef __GLOBALS_INC
+#define __GLOBALS_INC
+
+#include "features.cginc"
+
+SamplerState point_repeat_s;
+SamplerState linear_repeat_s;
+SamplerState bilinear_repeat_s;
+SamplerState linear_clamp_s;
+SamplerState trilinear_repeat_s;
+
+float4 _Color;
+int _Mode;
+
+float _Smoothness;
+float _Metallic;
+
+float _Specular_AA_Variance;
+float _Specular_AA_Threshold;
+float _BRDF_Specular_Min_Denom;
+
+#if defined(_SEA_FX)
+float _Sea_FX_Derivatives_SS_Filtering_Factor;
+#endif
+
+#if defined(_SEA_FX_HEIGHTMAPS_Y_0)
+texture2D _Sea_FX_Heightmaps_Y_0;
+float4 _Sea_FX_Heightmaps_Y_0_ST;
+#endif
+#if defined(_SEA_FX_HEIGHTMAPS_Y_1)
+texture2D _Sea_FX_Heightmaps_Y_1;
+float4 _Sea_FX_Heightmaps_Y_1_ST;
+#endif
+#if defined(_SEA_FX_HEIGHTMAPS_Y_2)
+texture2D _Sea_FX_Heightmaps_Y_2;
+float4 _Sea_FX_Heightmaps_Y_2_ST;
+#endif
+#if defined(_SEA_FX_HEIGHTMAPS_Y_3)
+texture2D _Sea_FX_Heightmaps_Y_3;
+float4 _Sea_FX_Heightmaps_Y_3_ST;
+#endif
+
+#if defined(_SEA_FX_HEIGHTMAPS_XZ_0)
+texture2D _Sea_FX_Heightmaps_XZ_0;
+float4 _Sea_FX_Heightmaps_XZ_0_ST;
+#endif
+#if defined(_SEA_FX_HEIGHTMAPS_XZ_1)
+texture2D _Sea_FX_Heightmaps_XZ_1;
+float4 _Sea_FX_Heightmaps_XZ_1_ST;
+#endif
+#if defined(_SEA_FX_HEIGHTMAPS_XZ_2)
+texture2D _Sea_FX_Heightmaps_XZ_2;
+float4 _Sea_FX_Heightmaps_XZ_2_ST;
+#endif
+#if defined(_SEA_FX_HEIGHTMAPS_XZ_3)
+texture2D _Sea_FX_Heightmaps_XZ_3;
+float4 _Sea_FX_Heightmaps_XZ_3_ST;
+#endif
+
+#if defined(_SEA_FX_VERTICAL_DERIVATIVES_0)
+texture2D _Sea_FX_Vertical_Derivatives_0;
+float4 _Sea_FX_Vertical_Derivatives_0_ST;
+#endif
+#if defined(_SEA_FX_HORIZONTAL_DERIVATIVES_0)
+texture2D _Sea_FX_Horizontal_Derivatives_0;
+float4 _Sea_FX_Horizontal_Derivatives_0_ST;
+#endif
+#if defined(_SEA_FX_VERTICAL_DERIVATIVES_1)
+texture2D _Sea_FX_Vertical_Derivatives_1;
+float4 _Sea_FX_Vertical_Derivatives_1_ST;
+#endif
+#if defined(_SEA_FX_HORIZONTAL_DERIVATIVES_1)
+texture2D _Sea_FX_Horizontal_Derivatives_1;
+float4 _Sea_FX_Horizontal_Derivatives_1_ST;
+#endif
+#if defined(_SEA_FX_VERTICAL_DERIVATIVES_2)
+texture2D _Sea_FX_Vertical_Derivatives_2;
+float4 _Sea_FX_Vertical_Derivatives_2_ST;
+#endif
+#if defined(_SEA_FX_HORIZONTAL_DERIVATIVES_2)
+texture2D _Sea_FX_Horizontal_Derivatives_2;
+float4 _Sea_FX_Horizontal_Derivatives_2_ST;
+#endif
+#if defined(_SEA_FX_VERTICAL_DERIVATIVES_3)
+texture2D _Sea_FX_Vertical_Derivatives_3;
+float4 _Sea_FX_Vertical_Derivatives_3_ST;
+#endif
+#if defined(_SEA_FX_HORIZONTAL_DERIVATIVES_3)
+texture2D _Sea_FX_Horizontal_Derivatives_3;
+float4 _Sea_FX_Horizontal_Derivatives_3_ST;
+#endif
+
+#if defined(_SEA_FOAM)
+float4 _Sea_Foam_Color;
+float _Sea_Foam_Roughness;
+float _Sea_Foam_Bias;
+#endif
+
+#if defined(_SEA_SSS)
+float4 _Sea_SSS_Color;
+float _Sea_SSS_X_Amount;
+float _Sea_SSS_Bias;
+float _Sea_SSS_Factor;
+float _Sea_SSS_Power;
+float _Sea_SSS_LoV_Wrap;
+#endif
+
+#if defined(_TESSELLATION)
+float _Tessellation_Factor;
+float _Tessellation_Frustum_Culling_Bias;
+float _Tessellation_Falloff_Factor;
+#endif // _TESSELLATION
+
+
+#endif // __GLOBALS_INC
diff --git a/interpolators.cginc b/interpolators.cginc
new file mode 100644
index 0000000..94f2613
--- /dev/null
+++ b/interpolators.cginc
@@ -0,0 +1,29 @@
+#ifndef __INTERPOLATORS_INC
+#define __INTERPOLATORS_INC
+
+#include "AutoLight.cginc"
+
+struct appdata {
+ float4 vertex : POSITION;
+ float2 uv0 : TEXCOORD0;
+ float4 color : COLOR; // vertex color
+
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+};
+
+struct v2f {
+#if defined(_TESSELLATION)
+ float4 tpos : INTERNALTESSPOS;
+#endif
+ linear noperspective centroid float4 pos : SV_POSITION;
+ float2 uv0 : TEXCOORD0;
+ float3 objPos : TEXCOORD1;
+ float3 worldPos : TEXCOORD2;
+ float4 eyeVec : TEXCOORD3; // eyeVec.xyz | fogCoord
+ UNITY_LIGHTING_COORDS(4,5)
+
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ UNITY_VERTEX_OUTPUT_STEREO
+};
+
+#endif // __INTERPOLATORS_INC
diff --git a/lighting.cginc b/lighting.cginc
new file mode 100644
index 0000000..db3c4ff
--- /dev/null
+++ b/lighting.cginc
@@ -0,0 +1,140 @@
+#ifndef __LIGHTING_INC
+#define __LIGHTING_INC
+
+#include "UnityCG.cginc"
+#include "AutoLight.cginc"
+#include "UnityPBSLighting.cginc"
+#include "UnityLightingCommon.cginc"
+#include "UnityStandardCoreMinimal.cginc"
+
+#include "features.cginc"
+#include "filamented.cginc"
+#include "interpolators.cginc"
+#include "LightVolumes.cginc"
+#include "pbr.cginc"
+
+struct LightCommon {
+ float3 V;
+ float3 N;
+ float NoV;
+};
+
+struct LightDirect {
+ float3 dir;
+
+ float3 H;
+ float NoH;
+ float NoL;
+ float LoH;
+ float LoV;
+ float double_LoV;
+
+ float3 color;
+};
+
+struct LightIndirect {
+ float3 dir;
+
+ float3 H;
+ float NoH;
+ float NoL;
+ float LoH;
+ float LoV;
+ float double_LoV;
+
+ float3 specular;
+ float3 diffuse;
+
+ float3 L00;
+ float3 L01r;
+ float3 L01g;
+ float3 L01b;
+};
+
+struct LightData {
+ LightCommon common;
+ LightDirect direct;
+ LightIndirect indirect;
+};
+
+float3 getDirectLightDirection(v2f i) {
+#if defined(POINT) || defined(POINT_COOKIE) || defined(SPOT)
+ return normalize((_WorldSpaceLightPos0 - i.worldPos).xyz);
+#else
+ return _WorldSpaceLightPos0;
+#endif
+}
+
+float getShadowAttenuation(v2f i)
+{
+ UNITY_LIGHT_ATTENUATION(attenuation, i, i.worldPos);
+ return attenuation;
+}
+
+float4 getDirectLightColorIntensity() {
+ // Properly separate light color from intensity like filamented
+ if (_LightColor0.w <= 0) return float4(0, 0, 0, 0);
+ _LightColor0 += 1e-6f;
+ return float4(_LightColor0.xyz / _LightColor0.w, _LightColor0.w);
+}
+
+float3 getIndirectSpecular(v2f i, Pbr pbr, float3 view_dir, float3 reflect_dir) {
+ UnityGIInput data = InitialiseUnityGIInput(i.worldPos, view_dir);
+ float3 env_refl = UnityGI_prefilteredRadiance(data, pbr.roughness_perceptual, reflect_dir);
+ return env_refl;
+}
+
+float3 yumSH9(float4 n, float3 worldPos, inout LightIndirect light) {
+ LightVolumeSH(worldPos, light.L00, light.L01r, light.L01g, light.L01b);
+ return light.L00 + float3(
+ dot(light.L01r, n.xyz),
+ dot(light.L01g, n.xyz),
+ dot(light.L01b, n.xyz));
+}
+
+float4 getIndirectDiffuse(v2f i, Pbr pbr, inout LightIndirect light) {
+ float4 diffuse = 0;
+#if defined(FORWARD_BASE_PASS)
+ diffuse.xyz += max(0, yumSH9(float4(pbr.normal, 0), i.worldPos, light));
+#endif
+ return diffuse;
+}
+
+void GetLighting(v2f i, Pbr pbr, out LightData data) {
+ data = (LightData) 0;
+
+ float3 view_dir = normalize(i.eyeVec.xyz);
+
+ data.common.V = -view_dir;
+ data.common.N = pbr.normal;
+ data.common.NoV = saturate(dot(pbr.normal, data.common.V));
+
+ // Direct lighting
+ data.direct.dir = getDirectLightDirection(i);
+ data.direct.H = normalize(data.common.V + data.direct.dir);
+ data.direct.NoL = saturate(dot(pbr.normal, data.direct.dir));
+ data.direct.NoH = saturate(dot(pbr.normal, data.direct.H));
+ data.direct.LoH = saturate(dot(data.direct.dir, data.direct.H));
+ float direct_LoV = dot(data.direct.dir, data.common.V);
+ data.direct.LoV = saturate(direct_LoV);
+ data.direct.double_LoV = saturate(2.0f * direct_LoV * direct_LoV - 1.0f);
+
+ float4 lightColorIntensity = getDirectLightColorIntensity();
+ data.direct.color = lightColorIntensity.rgb * lightColorIntensity.w;
+
+ // Indirect lighting
+ data.indirect.dir = -reflect(data.common.V, pbr.normal);
+ data.indirect.H = normalize(data.common.V + data.indirect.dir);
+ data.indirect.NoL = saturate(dot(pbr.normal, data.indirect.dir));
+ data.indirect.NoH = saturate(dot(pbr.normal, data.indirect.H));
+ data.indirect.LoH = saturate(dot(data.indirect.dir, data.indirect.H));
+ float indirect_LoV = dot(data.direct.dir, data.common.V);
+ data.indirect.LoV = saturate(indirect_LoV);
+ data.indirect.double_LoV = saturate(2.0f * indirect_LoV * indirect_LoV - 1.0f);
+
+ data.indirect.diffuse = getIndirectDiffuse(i, pbr, data.indirect);
+ data.indirect.specular = getIndirectSpecular(i, pbr, view_dir, data.indirect.dir);
+}
+
+#endif // __LIGHTING_INC
+
diff --git a/lysenko.cginc b/lysenko.cginc
new file mode 100644
index 0000000..3026caf
--- /dev/null
+++ b/lysenko.cginc
@@ -0,0 +1,38 @@
+#ifndef __LYSENKO_INC
+#define __LYSENKO_INC
+
+/*
+The MIT License (MIT)
+
+Copyright (c) 2014 Mikola Lysenko
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+ */
+float Fd_OrenNayar(float roughness, float NoV, float NoL, float LoV) {
+ float s = LoV - NoL * NoV;
+ float t = lerp(1.0f, max(NoL, NoV), step(0.0f, s));
+ float sigma2 = roughness * roughness;
+ float A = 1.0f + sigma2 * rcp(sigma2 + 0.13f) + 0.5f / (sigma2 + 0.33f);
+ float B = 0.45f * sigma2 / (sigma2 + 0.09f);
+
+ return max(0.0f, NoL * (A + B * s / t));
+}
+
+#endif // __LYSENKO_INC
+
diff --git a/math.cginc b/math.cginc
new file mode 100644
index 0000000..4b91209
--- /dev/null
+++ b/math.cginc
@@ -0,0 +1,26 @@
+#ifndef __MATH_INC
+#define __MATH_INC
+
+#define PI 3.14159265358979f
+#define RCP_PI (1.0f / PI)
+
+// Wrap a dot product. Assume it's already clamped.
+// At k=0, you get standard lambertian shading.
+// At k=0.5, you get half-lambertian shading.
+// At k=1.0, you get flat shading.
+// k must be on [0, 1].
+// Energy preserving, within some small bound.
+float wrapDotProduct(float XoY, float k) {
+ float lambertian = XoY;
+ float half_lambertian = pow(max(1e-4, (XoY + 0.5f) / (1.0f + 0.5f)), 2);
+ float flat = RCP_PI;
+
+ if (k < 0.5) {
+ return lerp(lambertian, half_lambertian, k * 2.0f);
+ } else {
+ return lerp(half_lambertian, flat, k * 2.0f - 1.0f);
+ }
+}
+
+#endif // __MATH_INC
+
diff --git a/pbr.cginc b/pbr.cginc
new file mode 100644
index 0000000..6e37942
--- /dev/null
+++ b/pbr.cginc
@@ -0,0 +1,34 @@
+#ifndef __PBR_INC
+#define __PBR_INC
+
+#include "filamented.cginc"
+#include "globals.cginc"
+#include "interpolators.cginc"
+
+struct Pbr {
+ float4 albedo;
+ float3 normal;
+ float smoothness;
+ float roughness_perceptual;
+ float roughness;
+ float metallic;
+};
+
+// TODO consider normal filtering like filamented
+void propagateSmoothness(inout Pbr pbr) {
+ pbr.roughness_perceptual = max(MIN_PERCEPTUAL_ROUGHNESS, 1.0f - pbr.smoothness);
+ pbr.roughness = max(MIN_ROUGHNESS, pbr.roughness_perceptual * pbr.roughness_perceptual);
+}
+
+Pbr getPbr(v2f i) {
+ Pbr pbr = (Pbr) 0;
+ pbr.normal = float3(0, 1, 0);
+ pbr.albedo = _Color;
+ pbr.smoothness = _Smoothness;
+ propagateSmoothness(pbr);
+
+ pbr.metallic = _Metallic;
+ return pbr;
+}
+
+#endif // __PBR_INC
diff --git a/pbr_utils.cginc b/pbr_utils.cginc
new file mode 100644
index 0000000..c8c10cc
--- /dev/null
+++ b/pbr_utils.cginc
@@ -0,0 +1,20 @@
+#ifndef __PBR_UTILS_INC
+#define __PBR_UTILS_INC
+
+float perceptualRoughnessToRoughness(float perceptualRoughness) {
+ return perceptualRoughness * perceptualRoughness;
+}
+
+float roughnessToPerceptualRoughness(float roughness) {
+ return sqrt(roughness);
+}
+
+float smoothnessToPerceptualRoughness(float smoothness) {
+ return 1.0f - smoothness;
+}
+
+float smoothnessToRoughness(float smoothness) {
+ return perceptualRoughnessToRoughness(smoothnessToPerceptualRoughness(smoothness));
+}
+
+#endif // __PBR_UTILS_INC
diff --git a/sampling.cginc b/sampling.cginc
new file mode 100644
index 0000000..01d385f
--- /dev/null
+++ b/sampling.cginc
@@ -0,0 +1,1042 @@
+#ifndef __SAMPLING_INC
+#define __SAMPLING_INC
+
+// From https://github.com/orels1/orels-Unity-Shaders
+// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
+// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+// Credit to Jason Booth for digging this all up
+// This originally comes from CoreRP, see Jason's comment below
+
+// If your looking in here and thinking WTF, yeah, I know. These are taken from the SRPs, to allow us to use the same
+// texturing library they use. However, since they are not included in the standard pipeline by default, there is no
+// way to include them in and they have to be inlined, since someone could copy this shader onto another machine without
+// Better Shaders installed. Unfortunate, but I'd rather do this and have a nice library for texture sampling instead
+// of the patchy one Unity provides being inlined/emulated in HDRP/URP. Strangely, PSSL and XBoxOne libraries are not
+// included in the standard SRP code, but they are in tons of Unity own projects on the web, so I grabbed them from there.
+
+#if defined(SHADER_API_XBOXONE)
+
+// Initialize arbitrary structure with zero values.
+// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0
+#define ZERO_INITIALIZE(type, name) name = (type)0;
+#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }
+
+// Texture util abstraction
+
+#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)
+
+// Texture abstraction
+
+#define TEXTURE2D(textureName) Texture2D textureName
+#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName
+#define TEXTURECUBE(textureName) TextureCube textureName
+#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName
+#define TEXTURE3D(textureName) Texture3D textureName
+
+#define TEXTURE2D_FLOAT(textureName) TEXTURE2D(textureName)
+#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURE2D_ARRAY(textureName)
+#define TEXTURECUBE_FLOAT(textureName) TEXTURECUBE(textureName)
+#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_ARRAY(textureName)
+#define TEXTURE3D_FLOAT(textureName) TEXTURE3D(textureName)
+
+#define TEXTURE2D_HALF(textureName) TEXTURE2D(textureName)
+#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURE2D_ARRAY(textureName)
+#define TEXTURECUBE_HALF(textureName) TEXTURECUBE(textureName)
+#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_ARRAY(textureName)
+#define TEXTURE3D_HALF(textureName) TEXTURE3D(textureName)
+
+#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)
+#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)
+#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)
+#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)
+
+#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName
+#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName
+#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName
+
+#define SAMPLER(samplerName) SamplerState samplerName
+#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName
+
+#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)
+#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)
+#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)
+#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)
+#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)
+
+#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)
+#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)
+#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)
+#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)
+
+#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName
+
+#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
+
+#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)
+#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)
+#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)
+#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)
+#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))
+#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)
+#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)
+#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)
+#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)
+#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)
+#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)
+#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))
+#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)
+#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)
+#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)
+#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)
+
+#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)
+#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)
+#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)
+#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)
+
+#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))
+#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))
+#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)
+#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))
+#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)
+#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))
+#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))
+#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))
+
+#define PLATFORM_SUPPORT_GATHER
+#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)
+#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))
+#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)
+#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))
+#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)
+#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)
+#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)
+#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)
+
+#elif defined(SHADER_API_PSSL)
+
+// Initialize arbitrary structure with zero values.
+// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0
+#define ZERO_INITIALIZE(type, name) name = (type)0;
+#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }
+
+// Texture util abstraction
+
+#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.GetLOD(samplerName, coord2)
+
+// Texture abstraction
+
+#define TEXTURE2D(textureName) Texture2D textureName
+#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName
+#define TEXTURECUBE(textureName) TextureCube textureName
+#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName
+#define TEXTURE3D(textureName) Texture3D textureName
+
+#define TEXTURE2D_FLOAT(textureName) TEXTURE2D(textureName)
+#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURE2D_ARRAY(textureName)
+#define TEXTURECUBE_FLOAT(textureName) TEXTURECUBE(textureName)
+#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_ARRAY(textureName)
+#define TEXTURE3D_FLOAT(textureName) TEXTURE3D(textureName)
+
+#define TEXTURE2D_HALF(textureName) TEXTURE2D(textureName)
+#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURE2D_ARRAY(textureName)
+#define TEXTURECUBE_HALF(textureName) TEXTURECUBE(textureName)
+#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_ARRAY(textureName)
+#define TEXTURE3D_HALF(textureName) TEXTURE3D(textureName)
+
+#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)
+#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)
+#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)
+#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)
+
+#define RW_TEXTURE2D(type, textureName) RW_Texture2D<type> textureName
+#define RW_TEXTURE2D_ARRAY(type, textureName) RW_Texture2D_Array<type> textureName
+#define RW_TEXTURE3D(type, textureName) RW_Texture3D<type> textureName
+
+#define SAMPLER(samplerName) SamplerState samplerName
+#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName
+
+#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)
+#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)
+#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)
+#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)
+#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)
+
+#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)
+#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)
+#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)
+#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)
+
+#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName
+
+#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
+
+#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)
+#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)
+#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)
+#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)
+#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))
+#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)
+#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)
+#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)
+#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)
+#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)
+#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)
+#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))
+#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)
+#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)
+#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)
+#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)
+
+#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)
+#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)
+#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)
+#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)
+
+#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))
+#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))
+#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)
+#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))
+#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)
+#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))
+#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))
+#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))
+
+#define PLATFORM_SUPPORT_GATHER
+#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)
+#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))
+#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)
+#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))
+#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)
+#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)
+#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)
+#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)
+
+#elif defined(SHADER_API_D3D11)
+
+// Initialize arbitrary structure with zero values.
+// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0
+#define ZERO_INITIALIZE(type, name) name = (type)0;
+#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }
+
+// Texture util abstraction
+
+#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)
+
+// Texture abstraction
+
+#define TEXTURE2D(textureName) Texture2D textureName
+#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName
+#define TEXTURECUBE(textureName) TextureCube textureName
+#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName
+#define TEXTURE3D(textureName) Texture3D textureName
+
+#define TEXTURE2D_FLOAT(textureName) TEXTURE2D(textureName)
+#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURE2D_ARRAY(textureName)
+#define TEXTURECUBE_FLOAT(textureName) TEXTURECUBE(textureName)
+#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_ARRAY(textureName)
+#define TEXTURE3D_FLOAT(textureName) TEXTURE3D(textureName)
+
+#define TEXTURE2D_HALF(textureName) TEXTURE2D(textureName)
+#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURE2D_ARRAY(textureName)
+#define TEXTURECUBE_HALF(textureName) TEXTURECUBE(textureName)
+#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_ARRAY(textureName)
+#define TEXTURE3D_HALF(textureName) TEXTURE3D(textureName)
+
+#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)
+#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)
+#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)
+#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)
+
+#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName
+#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName
+#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName
+
+#define SAMPLER(samplerName) SamplerState samplerName
+#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName
+
+#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)
+#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)
+#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)
+#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)
+#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)
+
+#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)
+#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)
+#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)
+#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)
+
+#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName
+
+#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
+
+#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)
+#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)
+#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)
+#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)
+#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))
+#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)
+#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)
+#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)
+#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)
+#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)
+#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)
+#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))
+#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)
+#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)
+#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)
+#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)
+
+#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)
+#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)
+#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)
+#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)
+
+#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))
+#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))
+#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)
+#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))
+#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)
+#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))
+#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))
+#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))
+
+#define PLATFORM_SUPPORT_GATHER
+#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)
+#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))
+#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)
+#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))
+#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)
+#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)
+#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)
+#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)
+
+#elif defined(SHADER_API_METAL)
+
+// Initialize arbitrary structure with zero values.
+// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0
+#define ZERO_INITIALIZE(type, name) name = (type)0;
+#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }
+
+// Texture util abstraction
+
+#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)
+
+// Texture abstraction
+
+#define TEXTURE2D(textureName) Texture2D textureName
+#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName
+#define TEXTURECUBE(textureName) TextureCube textureName
+#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName
+#define TEXTURE3D(textureName) Texture3D textureName
+
+#define TEXTURE2D_FLOAT(textureName) Texture2D_float textureName
+#define TEXTURE2D_ARRAY_FLOAT(textureName) Texture2DArray textureName // no support to _float on Array, it's being added
+#define TEXTURECUBE_FLOAT(textureName) TextureCube_float textureName
+#define TEXTURECUBE_ARRAY_FLOAT(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added
+#define TEXTURE3D_FLOAT(textureName) Texture3D_float textureName
+
+#define TEXTURE2D_HALF(textureName) Texture2D_half textureName
+#define TEXTURE2D_ARRAY_HALF(textureName) Texture2DArray textureName // no support to _float on Array, it's being added
+#define TEXTURECUBE_HALF(textureName) TextureCube_half textureName
+#define TEXTURECUBE_ARRAY_HALF(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added
+#define TEXTURE3D_HALF(textureName) Texture3D_half textureName
+
+#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)
+#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)
+#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)
+#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)
+
+#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName
+#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName
+#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName
+
+#define SAMPLER(samplerName) SamplerState samplerName
+#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName
+
+#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)
+#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)
+#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)
+#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)
+#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)
+
+#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)
+#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)
+#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)
+#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)
+
+#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName
+
+#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
+
+#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)
+#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)
+#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)
+#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)
+#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))
+#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)
+#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)
+#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)
+#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)
+#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)
+#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)
+#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))
+#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)
+#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)
+#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)
+#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)
+
+#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)
+#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)
+#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)
+#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)
+
+#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))
+#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))
+#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)
+#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))
+#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)
+#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))
+#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))
+#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))
+
+#define PLATFORM_SUPPORT_GATHER
+#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)
+#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))
+#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)
+#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))
+#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)
+#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)
+#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)
+#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)
+
+#elif defined(SHADER_API_VULKAN)
+// This file assume SHADER_API_VULKAN is defined
+// TODO: This is a straight copy from D3D11.hlsl. Go through all this stuff and adjust where needed.
+
+// Initialize arbitrary structure with zero values.
+// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0
+#define ZERO_INITIALIZE(type, name) name = (type)0;
+#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }
+
+// Texture util abstraction
+
+#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)
+
+// Texture abstraction
+
+#define TEXTURE2D(textureName) Texture2D textureName
+#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName
+#define TEXTURECUBE(textureName) TextureCube textureName
+#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName
+#define TEXTURE3D(textureName) Texture3D textureName
+
+#define TEXTURE2D_FLOAT(textureName) Texture2D_float textureName
+#define TEXTURE2D_ARRAY_FLOAT(textureName) Texture2DArray textureName // no support to _float on Array, it's being added
+#define TEXTURECUBE_FLOAT(textureName) TextureCube_float textureName
+#define TEXTURECUBE_ARRAY_FLOAT(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added
+#define TEXTURE3D_FLOAT(textureName) Texture3D_float textureName
+
+#define TEXTURE2D_HALF(textureName) Texture2D_half textureName
+#define TEXTURE2D_ARRAY_HALF(textureName) Texture2DArray textureName // no support to _float on Array, it's being added
+#define TEXTURECUBE_HALF(textureName) TextureCube_half textureName
+#define TEXTURECUBE_ARRAY_HALF(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added
+#define TEXTURE3D_HALF(textureName) Texture3D_half textureName
+
+#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)
+#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)
+#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)
+#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)
+
+#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName
+#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName
+#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName
+
+#define SAMPLER(samplerName) SamplerState samplerName
+#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName
+
+#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)
+#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)
+#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)
+#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)
+#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)
+
+#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)
+#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)
+#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)
+#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)
+
+#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName
+
+#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
+
+#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)
+#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)
+#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)
+#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)
+#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))
+#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)
+#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)
+#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)
+#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)
+#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)
+#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)
+#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))
+#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)
+#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)
+#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)
+#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)
+
+#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)
+#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)
+#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)
+#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)
+
+#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))
+#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))
+#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)
+#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))
+#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)
+#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))
+#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))
+#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))
+
+#define PLATFORM_SUPPORT_GATHER
+#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)
+#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))
+#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)
+#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))
+#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)
+#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)
+#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)
+#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)
+
+#elif defined(SHADER_API_SWITCH)
+// This file assume SHADER_API_SWITCH is defined
+
+// Initialize arbitrary structure with zero values.
+// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0
+#define ZERO_INITIALIZE(type, name) name = (type)0;
+#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }
+
+// Texture util abstraction
+
+#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)
+
+// Texture abstraction
+
+#define TEXTURE2D(textureName) Texture2D textureName
+#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName
+#define TEXTURECUBE(textureName) TextureCube textureName
+#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName
+#define TEXTURE3D(textureName) Texture3D textureName
+
+#define TEXTURE2D_FLOAT(textureName) Texture2D_float textureName
+#define TEXTURE2D_ARRAY_FLOAT(textureName) Texture2DArray textureName // no support to _float on Array, it's being added
+#define TEXTURECUBE_FLOAT(textureName) TextureCube_float textureName
+#define TEXTURECUBE_ARRAY_FLOAT(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added
+#define TEXTURE3D_FLOAT(textureName) Texture3D_float textureName
+
+#define TEXTURE2D_HALF(textureName) Texture2D_half textureName
+#define TEXTURE2D_ARRAY_HALF(textureName) Texture2DArray textureName // no support to _float on Array, it's being added
+#define TEXTURECUBE_HALF(textureName) TextureCube_half textureName
+#define TEXTURECUBE_ARRAY_HALF(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added
+#define TEXTURE3D_HALF(textureName) Texture3D_half textureName
+
+#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)
+#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)
+#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)
+#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)
+
+#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName
+#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName
+#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName
+
+#define SAMPLER(samplerName) SamplerState samplerName
+#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName
+
+#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)
+#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)
+#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)
+#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)
+#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)
+
+#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)
+#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)
+#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)
+#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)
+
+#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName
+
+#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
+
+#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)
+#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)
+#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)
+#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, dpdx, dpdy) textureName.SampleGrad(samplerName, coord2, dpdx, dpdy)
+#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))
+#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)
+#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)
+#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)
+#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)
+#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)
+#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)
+#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))
+#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)
+#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) textureName.SampleBias(samplerName, float4(coord3, index), bias)
+#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)
+#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)
+
+#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)
+#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)
+#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)
+#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)
+
+#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))
+#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))
+#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)
+#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))
+#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))
+#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))
+#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))
+
+#define PLATFORM_SUPPORT_GATHER
+#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)
+#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))
+#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)
+#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))
+#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)
+#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)
+#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)
+#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)
+
+#elif defined(SHADER_API_GLCORE)
+
+// OpenGL 4.1 SM 5.0 https://docs.unity3d.com/Manual/SL-ShaderCompileTargets.html
+#if (SHADER_TARGET >= 46)
+#define OPENGL4_1_SM5 1
+#else
+#define OPENGL4_1_SM5 0
+#endif
+
+// Initialize arbitrary structure with zero values.
+// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0
+#define ZERO_INITIALIZE(type, name) name = (type)0;
+#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }
+
+// Texture util abstraction
+
+#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)
+
+// Texture abstraction
+
+#define TEXTURE2D(textureName) Texture2D textureName
+#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName
+#define TEXTURECUBE(textureName) TextureCube textureName
+#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName
+#define TEXTURE3D(textureName) Texture3D textureName
+
+#define TEXTURE2D_FLOAT(textureName) TEXTURE2D(textureName)
+#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURE2D_ARRAY(textureName)
+#define TEXTURECUBE_FLOAT(textureName) TEXTURECUBE(textureName)
+#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_ARRAY(textureName)
+#define TEXTURE3D_FLOAT(textureName) TEXTURE3D(textureName)
+
+#define TEXTURE2D_HALF(textureName) TEXTURE2D(textureName)
+#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURE2D_ARRAY(textureName)
+#define TEXTURECUBE_HALF(textureName) TEXTURECUBE(textureName)
+#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_ARRAY(textureName)
+#define TEXTURE3D_HALF(textureName) TEXTURE3D(textureName)
+
+#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)
+#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)
+#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)
+#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)
+
+#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName
+#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName
+#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName
+
+#define SAMPLER(samplerName) SamplerState samplerName
+#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName
+
+#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)
+#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)
+#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)
+#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)
+#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)
+
+#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)
+#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)
+#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)
+#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)
+
+#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName
+
+#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
+
+#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)
+#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)
+#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)
+#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, ddx, ddy) textureName.SampleGrad(samplerName, coord2, ddx, ddy)
+#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))
+#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)
+#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)
+#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)
+#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)
+#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)
+#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)
+#ifdef UNITY_NO_CUBEMAP_ARRAY
+#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY)
+#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_LOD)
+#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, bias) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_LOD)
+#else
+#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))
+#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)
+#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias)textureName.SampleBias(samplerName, float4(coord3, index), bias)
+#endif
+#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)
+#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)
+
+#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)
+#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)
+#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)
+#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)
+
+#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))
+#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))
+#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)
+#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))
+#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)
+#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))
+
+#if OPENGL4_1_SM5
+#define PLATFORM_SUPPORT_GATHER
+#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)
+#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))
+#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)
+#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))
+#else
+#define GATHER_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D)
+#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D_ARRAY)
+#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE)
+#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE_ARRAY)
+#endif
+
+#elif defined(SHADER_API_GLES3)
+
+// GLES 3.1 + AEP shader feature https://docs.unity3d.com/Manual/SL-ShaderCompileTargets.html
+#if (SHADER_TARGET >= 40)
+#define GLES3_1_AEP 1
+#else
+#define GLES3_1_AEP 0
+#endif
+
+// Initialize arbitrary structure with zero values.
+// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0
+#define ZERO_INITIALIZE(type, name) name = (type)0;
+#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }
+
+// Texture util abstraction
+
+#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) textureName.CalculateLevelOfDetail(samplerName, coord2)
+
+// Texture abstraction
+
+#define TEXTURE2D(textureName) Texture2D textureName
+#define TEXTURE2D_ARRAY(textureName) Texture2DArray textureName
+#define TEXTURECUBE(textureName) TextureCube textureName
+#define TEXTURECUBE_ARRAY(textureName) TextureCubeArray textureName
+#define TEXTURE3D(textureName) Texture3D textureName
+
+#define TEXTURE2D_FLOAT(textureName) Texture2D_float textureName
+#define TEXTURE2D_ARRAY_FLOAT(textureName) Texture2DArray textureName // no support to _float on Array, it's being added
+#define TEXTURECUBE_FLOAT(textureName) TextureCube_float textureName
+#define TEXTURECUBE_ARRAY_FLOAT(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added
+#define TEXTURE3D_FLOAT(textureName) Texture3D_float textureName
+
+#define TEXTURE2D_HALF(textureName) Texture2D_half textureName
+#define TEXTURE2D_ARRAY_HALF(textureName) Texture2DArray textureName // no support to _float on Array, it's being added
+#define TEXTURECUBE_HALF(textureName) TextureCube_half textureName
+#define TEXTURECUBE_ARRAY_HALF(textureName) TextureCubeArray textureName // no support to _float on Array, it's being added
+#define TEXTURE3D_HALF(textureName) Texture3D_half textureName
+
+#define TEXTURE2D_SHADOW(textureName) TEXTURE2D(textureName)
+#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURE2D_ARRAY(textureName)
+#define TEXTURECUBE_SHADOW(textureName) TEXTURECUBE(textureName)
+#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_ARRAY(textureName)
+
+#if GLES3_1_AEP
+#define RW_TEXTURE2D(type, textureName) RWTexture2D<type> textureName
+#define RW_TEXTURE2D_ARRAY(type, textureName) RWTexture2DArray<type> textureName
+#define RW_TEXTURE3D(type, textureName) RWTexture3D<type> textureName
+#else
+#define RW_TEXTURE2D(type, textureName) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture2D)
+#define RW_TEXTURE2D_ARRAY(type, textureName) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture2DArray)
+#define RW_TEXTURE3D(type, textureName) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture3D)
+#endif
+
+#define SAMPLER(samplerName) SamplerState samplerName
+#define SAMPLER_CMP(samplerName) SamplerComparisonState samplerName
+
+#define TEXTURE2D_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER(samplerName)
+#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER(samplerName)
+#define TEXTURECUBE_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER(samplerName)
+#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER(samplerName)
+#define TEXTURE3D_PARAM(textureName, samplerName) TEXTURE3D(textureName), SAMPLER(samplerName)
+
+#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) TEXTURE2D(textureName), SAMPLER_CMP(samplerName)
+#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURE2D_ARRAY(textureName), SAMPLER_CMP(samplerName)
+#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE(textureName), SAMPLER_CMP(samplerName)
+#define TEXTURECUBE_ARRAY_SHADOW_PARAM(textureName, samplerName) TEXTURECUBE_ARRAY(textureName), SAMPLER_CMP(samplerName)
+
+#define TEXTURE2D_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURECUBE_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURE3D_ARGS(textureName, samplerName) textureName, samplerName
+
+#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
+#define TEXTURECUBE_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName, samplerName
+
+#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) textureName.Sample(samplerName, coord2)
+#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) textureName.SampleLevel(samplerName, coord2, lod)
+#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) textureName.SampleBias(samplerName, coord2, bias)
+#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, ddx, ddy) textureName.SampleGrad(samplerName, coord2, ddx, ddy)
+#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Sample(samplerName, float3(coord2, index))
+#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) textureName.SampleLevel(samplerName, float3(coord2, index), lod)
+#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) textureName.SampleBias(samplerName, float3(coord2, index), bias)
+#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) textureName.SampleGrad(samplerName, float3(coord2, index), dpdx, dpdy)
+#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)
+#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)
+#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) textureName.SampleBias(samplerName, coord3, bias)
+
+#ifdef UNITY_NO_CUBEMAP_ARRAY
+#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY)
+#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_LOD)
+#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias)ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_BIAS)
+#else
+#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Sample(samplerName, float4(coord3, index))
+#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) textureName.SampleLevel(samplerName, float4(coord3, index), lod)
+#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias)textureName.SampleBias(samplerName, float4(coord3, index), bias)
+#endif
+
+#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) textureName.Sample(samplerName, coord3)
+#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) textureName.SampleLevel(samplerName, coord3, lod)
+
+#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) textureName.SampleCmpLevelZero(samplerName, (coord3).xy, (coord3).z)
+#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) textureName.SampleCmpLevelZero(samplerName, float3((coord3).xy, index), (coord3).z)
+#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) textureName.SampleCmpLevelZero(samplerName, (coord4).xyz, (coord4).w)
+#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) textureName.SampleCmpLevelZero(samplerName, float4((coord4).xyz, index), (coord4).w)
+
+#define LOAD_TEXTURE2D(textureName, unCoord2) textureName.Load(int3(unCoord2, 0))
+#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) textureName.Load(int3(unCoord2, lod))
+#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) textureName.Load(unCoord2, sampleIndex)
+#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) textureName.Load(int4(unCoord2, index, 0))
+#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) textureName.Load(int3(unCoord2, index), sampleIndex)
+#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) textureName.Load(int4(unCoord2, index, lod))
+#define LOAD_TEXTURE3D(textureName, unCoord3) textureName.Load(int4(unCoord3, 0))
+#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) textureName.Load(int4(unCoord3, lod))
+
+#if GLES3_1_AEP
+#define PLATFORM_SUPPORT_GATHER
+#define GATHER_TEXTURE2D(textureName, samplerName, coord2) textureName.Gather(samplerName, coord2)
+#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) textureName.Gather(samplerName, float3(coord2, index))
+#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) textureName.Gather(samplerName, coord3)
+#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) textureName.Gather(samplerName, float4(coord3, index))
+#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherRed(samplerName, coord2)
+#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherGreen(samplerName, coord2)
+#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherBlue(samplerName, coord2)
+#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) textureName.GatherAlpha(samplerName, coord2)
+#else
+#define GATHER_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D)
+#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D_ARRAY)
+#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE)
+#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE_ARRAY)
+#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_RED_TEXTURE2D)
+#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_GREEN_TEXTURE2D)
+#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_BLUE_TEXTURE2D)
+#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_ALPHA_TEXTURE2D)
+#endif
+
+#elif defined(SHADER_API_GLES)
+
+#define uint int
+
+#define rcp(x) 1.0 / (x)
+#define ddx_fine ddx
+#define ddy_fine ddy
+#define asfloat
+#define asuint(x) asint(x)
+#define f32tof16
+#define f16tof32
+
+#define ERROR_ON_UNSUPPORTED_FUNCTION(funcName) #error #funcName is not supported on GLES 2.0
+
+// Initialize arbitrary structure with zero values.
+// Do not exist on some platform, in this case we need to have a standard name that call a function that will initialize all parameters to 0
+#define ZERO_INITIALIZE(type, name) name = (type)0;
+#define ZERO_INITIALIZE_ARRAY(type, name, arraySize) { for (int arrayIndex = 0; arrayIndex < arraySize; arrayIndex++) { name[arrayIndex] = (type)0; } }
+
+// Texture util abstraction
+
+#define CALCULATE_TEXTURE2D_LOD(textureName, samplerName, coord2) #error calculate Level of Detail not supported in GLES2
+
+// Texture abstraction
+
+#define TEXTURE2D(textureName) sampler2D textureName
+#define TEXTURE2D_ARRAY(textureName) samplerCUBE textureName // No support to texture2DArray
+#define TEXTURECUBE(textureName) samplerCUBE textureName
+#define TEXTURECUBE_ARRAY(textureName) samplerCUBE textureName // No supoport to textureCubeArray and can't emulate with texture2DArray
+#define TEXTURE3D(textureName) sampler3D textureName
+
+#define TEXTURE2D_FLOAT(textureName) sampler2D_float textureName
+#define TEXTURE2D_ARRAY_FLOAT(textureName) TEXTURECUBE_FLOAT(textureName) // No support to texture2DArray
+#define TEXTURECUBE_FLOAT(textureName) samplerCUBE_float textureName
+#define TEXTURECUBE_ARRAY_FLOAT(textureName) TEXTURECUBE_FLOAT(textureName) // No support to textureCubeArray
+#define TEXTURE3D_FLOAT(textureName) sampler3D_float textureName
+
+#define TEXTURE2D_HALF(textureName) sampler2D_half textureName
+#define TEXTURE2D_ARRAY_HALF(textureName) TEXTURECUBE_HALF(textureName) // No support to texture2DArray
+#define TEXTURECUBE_HALF(textureName) samplerCUBE_half textureName
+#define TEXTURECUBE_ARRAY_HALF(textureName) TEXTURECUBE_HALF(textureName) // No support to textureCubeArray
+#define TEXTURE3D_HALF(textureName) sampler3D_half textureName
+
+#define TEXTURE2D_SHADOW(textureName) SHADOW2D_TEXTURE_AND_SAMPLER textureName
+#define TEXTURE2D_ARRAY_SHADOW(textureName) TEXTURECUBE_SHADOW(textureName) // No support to texture array
+#define TEXTURECUBE_SHADOW(textureName) SHADOWCUBE_TEXTURE_AND_SAMPLER textureName
+#define TEXTURECUBE_ARRAY_SHADOW(textureName) TEXTURECUBE_SHADOW(textureName) // No support to texture array
+
+#define RW_TEXTURE2D(type, textureNam) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture2D)
+#define RW_TEXTURE2D_ARRAY(type, textureName) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture2DArray)
+#define RW_TEXTURE3D(type, textureNam) ERROR_ON_UNSUPPORTED_FUNCTION(RWTexture3D)
+
+#define SAMPLER(samplerName)
+#define SAMPLER_CMP(samplerName)
+
+#define TEXTURE2D_PARAM(textureName, samplerName) sampler2D textureName
+#define TEXTURE2D_ARRAY_PARAM(textureName, samplerName) samplerCUBE textureName
+#define TEXTURECUBE_PARAM(textureName, samplerName) samplerCUBE textureName
+#define TEXTURECUBE_ARRAY_PARAM(textureName, samplerName) samplerCUBE textureName
+#define TEXTURE3D_PARAM(textureName, samplerName) sampler3D textureName
+#define TEXTURE2D_SHADOW_PARAM(textureName, samplerName) SHADOW2D_TEXTURE_AND_SAMPLER textureName
+#define TEXTURE2D_ARRAY_SHADOW_PARAM(textureName, samplerName) SHADOWCUBE_TEXTURE_AND_SAMPLER textureName
+#define TEXTURECUBE_SHADOW_PARAM(textureName, samplerName) SHADOWCUBE_TEXTURE_AND_SAMPLER textureName
+
+#define TEXTURE2D_ARGS(textureName, samplerName) textureName
+#define TEXTURE2D_ARRAY_ARGS(textureName, samplerName) textureName
+#define TEXTURECUBE_ARGS(textureName, samplerName) textureName
+#define TEXTURECUBE_ARRAY_ARGS(textureName, samplerName) textureName
+#define TEXTURE3D_ARGS(textureName, samplerName) textureName
+#define TEXTURE2D_SHADOW_ARGS(textureName, samplerName) textureName
+#define TEXTURE2D_ARRAY_SHADOW_ARGS(textureName, samplerName) textureName
+#define TEXTURECUBE_SHADOW_ARGS(textureName, samplerName) textureName
+
+#define SAMPLE_TEXTURE2D(textureName, samplerName, coord2) tex2D(textureName, coord2)
+
+#if (SHADER_TARGET >= 30)
+#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) tex2Dlod(textureName, float4(coord2, 0, lod))
+#else
+// No lod support. Very poor approximation with bias.
+#define SAMPLE_TEXTURE2D_LOD(textureName, samplerName, coord2, lod) SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, lod)
+#endif
+
+#define SAMPLE_TEXTURE2D_BIAS(textureName, samplerName, coord2, bias) tex2Dbias(textureName, float4(coord2, 0, bias))
+#define SAMPLE_TEXTURE2D_GRAD(textureName, samplerName, coord2, ddx, ddy) SAMPLE_TEXTURE2D(textureName, samplerName, coord2)
+#define SAMPLE_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE2D_ARRAY)
+#define SAMPLE_TEXTURE2D_ARRAY_LOD(textureName, samplerName, coord2, index, lod) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE2D_ARRAY_LOD)
+#define SAMPLE_TEXTURE2D_ARRAY_BIAS(textureName, samplerName, coord2, index, bias) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE2D_ARRAY_BIAS)
+#define SAMPLE_TEXTURE2D_ARRAY_GRAD(textureName, samplerName, coord2, index, dpdx, dpdy) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE2D_ARRAY_GRAD)
+#define SAMPLE_TEXTURECUBE(textureName, samplerName, coord3) texCUBE(textureName, coord3)
+// No lod support. Very poor approximation with bias.
+#define SAMPLE_TEXTURECUBE_LOD(textureName, samplerName, coord3, lod) SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, lod)
+#define SAMPLE_TEXTURECUBE_BIAS(textureName, samplerName, coord3, bias) texCUBEbias(textureName, float4(coord3, bias))
+#define SAMPLE_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY)
+#define SAMPLE_TEXTURECUBE_ARRAY_LOD(textureName, samplerName, coord3, index, lod) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_LOD)
+#define SAMPLE_TEXTURECUBE_ARRAY_BIAS(textureName, samplerName, coord3, index, bias) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_BIAS)
+#define SAMPLE_TEXTURE3D(textureName, samplerName, coord3) tex3D(textureName, coord3)
+#define SAMPLE_TEXTURE3D_LOD(textureName, samplerName, coord3, lod) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE3D_LOD)
+
+#define SAMPLE_TEXTURE2D_SHADOW(textureName, samplerName, coord3) SHADOW2D_SAMPLE(textureName, samplerName, coord3)
+#define SAMPLE_TEXTURE2D_ARRAY_SHADOW(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURE2D_ARRAY_SHADOW)
+#define SAMPLE_TEXTURECUBE_SHADOW(textureName, samplerName, coord4) SHADOWCUBE_SAMPLE(textureName, samplerName, coord4)
+#define SAMPLE_TEXTURECUBE_ARRAY_SHADOW(textureName, samplerName, coord4, index) ERROR_ON_UNSUPPORTED_FUNCTION(SAMPLE_TEXTURECUBE_ARRAY_SHADOW)
+
+// Not supported. Can't define as error because shader library is calling these functions.
+#define LOAD_TEXTURE2D(textureName, unCoord2) half4(0, 0, 0, 0)
+#define LOAD_TEXTURE2D_LOD(textureName, unCoord2, lod) half4(0, 0, 0, 0)
+#define LOAD_TEXTURE2D_MSAA(textureName, unCoord2, sampleIndex) half4(0, 0, 0, 0)
+#define LOAD_TEXTURE2D_ARRAY(textureName, unCoord2, index) half4(0, 0, 0, 0)
+#define LOAD_TEXTURE2D_ARRAY_MSAA(textureName, unCoord2, index, sampleIndex) half4(0, 0, 0, 0)
+#define LOAD_TEXTURE2D_ARRAY_LOD(textureName, unCoord2, index, lod) half4(0, 0, 0, 0)
+#define LOAD_TEXTURE3D(textureName, unCoord3) ERROR_ON_UNSUPPORTED_FUNCTION(LOAD_TEXTURE3D)
+#define LOAD_TEXTURE3D_LOD(textureName, unCoord3, lod) ERROR_ON_UNSUPPORTED_FUNCTION(LOAD_TEXTURE3D_LOD)
+
+// Gather not supported. Fallback to regular texture sampling.
+#define GATHER_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D)
+#define GATHER_TEXTURE2D_ARRAY(textureName, samplerName, coord2, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURE2D_ARRAY)
+#define GATHER_TEXTURECUBE(textureName, samplerName, coord3) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE)
+#define GATHER_TEXTURECUBE_ARRAY(textureName, samplerName, coord3, index) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_TEXTURECUBE_ARRAY)
+#define GATHER_RED_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_RED_TEXTURE2D)
+#define GATHER_GREEN_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_GREEN_TEXTURE2D)
+#define GATHER_BLUE_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_BLUE_TEXTURE2D)
+#define GATHER_ALPHA_TEXTURE2D(textureName, samplerName, coord2) ERROR_ON_UNSUPPORTED_FUNCTION(GATHER_ALPHA_TEXTURE2D)
+
+#else
+#error unsupported shader api
+#endif
+
+#endif // __SAMPLING_INC \ No newline at end of file