summaryrefslogtreecommitdiffstats
path: root/3ner.cginc
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 /3ner.cginc
initial commit
Diffstat (limited to '3ner.cginc')
-rw-r--r--3ner.cginc166
1 files changed, 166 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
+