diff options
| author | yum <yum.food.vr@gmail.com> | 2025-08-06 16:42:42 -0700 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2025-08-06 16:42:42 -0700 |
| commit | 99d161288bfe2d10c331c97e6b7571f9c884e912 (patch) | |
| tree | 6ef130c4801de52f697c8d6996d9c4b0fb5f3964 /3ner.cginc | |
initial commit
Diffstat (limited to '3ner.cginc')
| -rw-r--r-- | 3ner.cginc | 166 |
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 + |
