diff options
| -rw-r--r-- | 2ner.cginc | 1200 | ||||
| -rw-r--r-- | 2ner.shader | 42 | ||||
| -rw-r--r-- | UnityStandardMeta.cginc | 3 | ||||
| -rw-r--r-- | data.cginc | 3 | ||||
| -rw-r--r-- | features.cginc | 4 | ||||
| -rw-r--r-- | filamented.cginc | 21 | ||||
| -rw-r--r-- | globals.cginc | 4 | ||||
| -rw-r--r-- | interpolators.cginc | 2 | ||||
| -rw-r--r-- | yum_brdf.cginc | 27 | ||||
| -rw-r--r-- | yum_lighting.cginc | 9 | ||||
| -rw-r--r-- | yum_pbr.cginc | 4 |
11 files changed, 692 insertions, 627 deletions
@@ -1,600 +1,600 @@ -#ifndef __2NER_INC
-#define __2NER_INC
-
-#define HANDLE_SHADOWS_BLENDING_IN_GI
-
-#include "UnityStandardCoreMinimal.cginc"
-#include "UnityCG.cginc"
-#include "UnityLightingCommon.cginc"
-#include "AutoLight.cginc"
-
-#include "custom30.cginc"
-#include "eyes.cginc"
-#include "face_me.cginc"
-#include "false_color_visualization.cginc"
-#include "features.cginc"
-#include "fog.cginc"
-#include "globals.cginc"
-#include "harnack_tracing.cginc"
-#include "interpolators.cginc"
-#include "letter_grid.cginc"
-#include "matcaps.cginc"
-#include "math.cginc"
-#include "poi.cginc"
-#include "shatter_wave.cginc"
-#include "ssao.cginc"
-#include "ssfd.cginc"
-#include "tessellation.cginc"
-#include "trochoid.cginc"
-#include "unigram_letter_grid.cginc"
-#include "vertex_domain_warping.cginc"
-#include "yum_brdf.cginc"
-#include "yum_pbr.cginc"
-#include "yum_lighting.cginc"
-
-v2f vert(appdata v) {
-#if defined(OUTLINE_PASS) && !defined(_OUTLINES)
- // The outline pass will be entirely elided when locked. This just lets us
- // hide outlines when not locked.
- return (v2f) (0.0/0.0);
-#endif
-#if defined(_RAYMARCHED_FOG) && !defined(FORWARD_BASE_PASS)
- return (v2f) (0.0/0.0);
-#endif
-#if defined(DEPTH_PREPASS) && !defined(_DEPTH_PREPASS)
- return (v2f) (0.0/0.0);
-#endif
-#if defined(EXTRA_STENCIL_COLOR_PASS) && !defined(_EXTRA_STENCIL_COLOR_PASS)
- return (v2f) (0.0/0.0);
-#endif
-#if defined(MASKED_STENCIL1_PASS)
-#if !defined(_MASKED_STENCIL1)
- return (v2f) (0.0/0.0);
-#endif
- float masked_stencil1_mask = _Masked_Stencil1_Mask.SampleLevel(linear_repeat_s, v.uv0, 0);
- [branch]
- if (masked_stencil1_mask < 0.5) {
- return (v2f) (0.0/0.0);
- }
-#endif
-#if defined(MASKED_STENCIL2_PASS)
-#if !defined(_MASKED_STENCIL2)
- return (v2f) (0.0/0.0);
-#endif
- float masked_stencil2_mask = _Masked_Stencil2_Mask.SampleLevel(linear_repeat_s, v.uv0, 0);
- [branch]
- if (masked_stencil2_mask < 0.5) {
- return (v2f) (0.0/0.0);
- }
-#endif
-#if defined(MASKED_STENCIL3_PASS)
-#if !defined(_MASKED_STENCIL3)
- return (v2f) (0.0/0.0);
-#endif
- float masked_stencil3_mask = _Masked_Stencil3_Mask.SampleLevel(linear_repeat_s, v.uv0, 0);
- [branch]
- if (masked_stencil3_mask < 0.5) {
- return (v2f) (0.0/0.0);
- }
-#endif
-#if defined(MASKED_STENCIL4_PASS)
-#if !defined(_MASKED_STENCIL4)
- return (v2f) (0.0/0.0);
-#endif
- float masked_stencil4_mask = _Masked_Stencil4_Mask.SampleLevel(linear_repeat_s, v.uv0, 0);
- [branch]
- if (masked_stencil4_mask < 0.5) {
- return (v2f) (0.0/0.0);
- }
-#endif
-#if defined(EXTRA_STENCIL_COLOR_PASS) && !defined(_EXTRA_STENCIL_COLOR_PASS)
- return (v2f) (0.0/0.0);
-#endif
-#if defined(FORWARD_ADD_PASS) & defined(_UNLIT)
- return (v2f) (0.0/0.0);
-#endif
-
- 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(_SPHERIZE)
- {
- float3 tgt_normal = normalize(o.objPos.xyz);
- float3 tgt_tangent = normalize(float3(tgt_normal.y, -tgt_normal.x, 0));
- float3 tgt_pos = tgt_normal * _Spherize_Radius;
- v.normal = normalize(lerp(v.normal, tgt_normal, _Spherize_Strength));
- v.vertex.xyz = lerp(v.vertex.xyz, tgt_pos, _Spherize_Strength);
- }
-#endif
-#if !defined(_TESSELLATION) && defined(_SHATTER_WAVE)
- shatterWaveVert(v.vertex.xyz, v.normal, v.tangent);
-#endif
-
-#if defined(_VERTEX_DOMAIN_WARPING)
- v.vertex.xyz = domainWarpVertexPosition(v.vertex.xyz);
-#endif
-
-#if defined(_TROCHOID)
- o.orig_pos = v.vertex.xyz;
- v.vertex.xyz = trochoid_map(v.vertex.xyz);
-#endif
-
-#if defined(OUTLINE_PASS)
- [branch]
- if (!_Outlines_Enabled_Dynamic) {
- return (v2f) (0.0/0.0);
- }
-#if defined(_OUTLINE_MASK)
- float thickness = _Outline_Mask.SampleLevel(linear_repeat_s, v.uv0, 0);
- thickness = (_Outline_Mask_Invert == 0 ? thickness : 1 - thickness);
-#else
- float thickness = 1;
-#endif
- v.vertex.xyz += _Outline_Width * v.normal * thickness;
- v.normal *= -1;
- v.tangent *= -1;
-#endif // OUTLINE_PASS
-
-#if defined(_FACE_ME)
- face_me(v);
-#endif
-
-#if defined(_FOCAL_LENGTH_CONTROL)
- [branch]
- if (_Focal_Length_Enabled_Dynamic) {
- float4 fl_worldPos_unscaled = mul(unity_ObjectToWorld, v.vertex);
- float4 fl_viewPos_unscaled = mul(UNITY_MATRIX_V, fl_worldPos_unscaled);
-
- float4 fl_objPos = float4(v.vertex.xyz * _Focal_Length_Multiplier, v.vertex.w);
- float4 fl_worldPos = mul(unity_ObjectToWorld, fl_objPos);
- float4 fl_viewPos = mul(UNITY_MATRIX_V, fl_worldPos);
- fl_viewPos.xy /= _Focal_Length_Multiplier;
-
- float2 fl_compensation = fl_viewPos_unscaled.xy - fl_viewPos.xy;
- fl_viewPos.xy += fl_compensation;
-
- o.pos = mul(UNITY_MATRIX_P, fl_viewPos);
- } else {
- o.pos = UnityObjectToClipPos(v.vertex);
- }
-#else
- o.pos = UnityObjectToClipPos(v.vertex);
-#endif
-
-#if defined(_TESSELLATION)
- o.tpos = v.vertex;
-#endif
- o.uv01.xy = v.uv0;
-#if defined(LIGHTMAP_ON)
- o.uv01.zw = v.uv1 * unity_LightmapST.xy + unity_LightmapST.zw;
-#else
- o.uv01.zw = v.uv1;
-#endif
- o.uv23.xy = v.uv2;
- o.uv23.zw = v.uv3;
-#if defined(_MIRROR_UVS_IN_MIRROR)
- [branch]
- if (isInMirror()) {
- o.uv01.x = 1.0 - o.uv01.x;
- o.uv01.z = 1.0 - o.uv01.z;
- o.uv23.x = 1.0 - o.uv23.x;
- o.uv23.z = 1.0 - o.uv23.z;
- }
-#endif
- o.objPos = v.vertex;
-
- // These are used to convert normals from tangent space to world space.
- o.normal = v.normal;
- o.tangent = v.tangent.xyz;
-
- 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
-
-#if defined(V2F_COLOR)
- // Vertex color
- o.color = v.color;
-#endif
-
- // Calculate vertex lights
- #ifdef VERTEXLIGHT_ON
- float3 worldPos = mul(unity_ObjectToWorld, v.vertex);
- #if defined(_WRAPPED_LIGHTING)
- o.vertexLight = Shade4PointLightsWrapped(
- unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0,
- unity_LightColor[0].rgb, unity_LightColor[1].rgb, unity_LightColor[2].rgb, unity_LightColor[3].rgb,
- unity_4LightAtten0, worldPos, o.normal, _Wrap_NoL_Diffuse_Strength);
- #else
- o.vertexLight = Shade4PointLights(
- unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0,
- unity_LightColor[0].rgb, unity_LightColor[1].rgb, unity_LightColor[2].rgb, unity_LightColor[3].rgb,
- unity_4LightAtten0, worldPos, o.normal);
- #endif
- #else
- o.vertexLight = 0;
- #endif
-
- return o;
-}
-
-//ifex _Fur_Enabled==0
-[maxvertexcount(30)]
-void geom(triangle v2f input[3], inout TriangleStream<v2f> stream) {
-#if defined(_FUR)
-#if defined(_FUR_MASK)
- float fur_mask = _Fur_Mask.SampleLevel(bilinear_repeat_s, input[0].uv01.xy * _Fur_Mask_ST.xy, 0);
-#else
- float fur_mask = 1;
-#endif
-
- stream.Append(input[0]);
- stream.Append(input[1]);
- stream.Append(input[2]);
- stream.RestartStrip();
-
- [branch]
- if (fur_mask < 0.5) {
- return;
- }
-
- float3 gravDirObj = normalize(mul(unity_WorldToObject, float3(0, -1, 0)));
-
- // Compute gravity direction minus component that would compress this shell.
- // Could compute average normal but this is probably good enough.
- float3 gravDirNoRegress = gravDirObj - min(0, input[0].normal * dot(gravDirObj, input[0].normal));
-
- float3 worldPos = mul(unity_ObjectToWorld, input[0].objPos).xyz;
- float radius = length(_WorldSpaceCameraPos - worldPos);
- uint fur_layers = lerp(_Fur_Layers - 3, 5, saturate((radius - _Fur_Min_Dist) / (_Fur_Max_Dist - _Fur_Min_Dist)));
-
- [loop]
- for (uint layer = 0; layer < fur_layers; layer++) {
- float t = (float) layer / (float) max(fur_layers - 4, 1);
-
- float offset = t * _Fur_Thickness;
-
- v2f o = input[layer % 3];
- float3 normal_ws = UnityObjectToWorldNormal(o.normal);
-
- float3 dir = lerp(o.normal, gravDirNoRegress, t * t * _Fur_Gravity_Strength);
-
- o.objPos.xyz += dir * offset;
-
- float3 worldPos = mul(unity_ObjectToWorld, o.objPos).xyz;
- o.pos = UnityWorldToClipPos(worldPos);
- o.vertexLight.w = t;
- stream.Append(o);
- }
-#else
- stream.Append(input[0]);
- stream.Append(input[1]);
- stream.Append(input[2]);
- stream.RestartStrip();
-#endif // _FUR
-}
-//endex
-
-float4 frag(v2f i, uint facing : SV_IsFrontFace
-#if defined(_HARNACK_TRACING) || defined(_SHATTER_WAVE) || defined(_VERTEX_DOMAIN_WARPING) || (defined(_CUSTOM30) && !defined(_DEPTH_PREPASS)) || defined(_RAYMARCHED_FOG) || defined(_TESSELLATION_HEIGHTMAP)
- , out float depth : SV_DepthLessEqual
-#endif
-) : SV_Target {
-
- UNITY_APPLY_DITHER_CROSSFADE(i.pos.xy);
- UNITY_SETUP_INSTANCE_ID(i);
- UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i);
-
-#if defined(_CUSTOM30) && defined(_DEPTH_PREPASS) && !defined(FORWARD_BASE_PASS)
- return 0;
-#endif
-
- i.normal *= facing ? 1 : -1;
- i.normal = UnityObjectToWorldNormal(i.normal);
- i.tangent = UnityObjectToWorldNormal(i.tangent);
-
- // Not necessarily normalized after interpolation
- i.normal = normalize(i.normal);
- i.tangent = normalize(i.tangent);
-
- f2f f = (f2f) 0;
- f.worldPos = mul(unity_ObjectToWorld, i.objPos);
- f.binormal = cross(i.tangent, i.normal);
- f.eyeVec = f.worldPos - _WorldSpaceCameraPos;
- f.viewDir = normalize(f.eyeVec);
- f.tbn = float3x3(
- i.tangent,
- f.binormal,
- i.normal
- );
-
-#if defined(_RAYMARCHED_FOG)
- {
- // Many fields are overspecified as .rgb or .xyz. This is because thry's
- // shader locker will inline those fields (incorrectly) as float4. Unity's
- // shader compiler doesn't like that, demanding exact type correspondence.
- // Overspecifying gets around the issue.
-
- FogParams fog_params = {
- _Raymarched_Fog_Color.rgb,
- _Raymarched_Fog_Direct_Light_Intensity,
- _Raymarched_Fog_Indirect_Light_Intensity,
- _Raymarched_Fog_Steps,
- _Raymarched_Fog_Y_Cutoff,
- _Raymarched_Fog_Dithering_Noise,
- _Raymarched_Fog_Dithering_Noise_TexelSize,
- _Raymarched_Fog_Density_Noise,
- _Raymarched_Fog_Density_Noise_Scale,
- _Raymarched_Fog_Velocity.xyz,
- _Raymarched_Fog_Mean_Free_Path,
- _Raymarched_Fog_Albedo,
- _Raymarched_Fog_G,
- _Raymarched_Fog_Height_Scale,
- _Raymarched_Fog_Height_Offset,
- _Raymarched_Fog_Turbulence,
- _Raymarched_Fog_Step_Size,
- _Raymarched_Fog_Step_Growth,
- #if defined(_RAYMARCHED_FOG_EMITTER_TEXTURE)
- _Raymarched_Fog_Emitter_Texture,
- _Raymarched_Fog_Emitter_Texture_TexelSize,
- _Raymarched_Fog_Emitter_Texture_World_Pos.xyz,
- normalize(_Raymarched_Fog_Emitter_Texture_World_Normal).xyz,
- normalize(_Raymarched_Fog_Emitter_Texture_World_Tangent).xyz,
- normalize(cross(_Raymarched_Fog_Emitter_Texture_World_Normal, _Raymarched_Fog_Emitter_Texture_World_Tangent)).xyz,
- _Raymarched_Fog_Emitter_Texture_World_Scale.xy,
- 1.0f / _Raymarched_Fog_Emitter_Texture_World_Scale.xy,
- _Raymarched_Fog_Emitter_Texture_Luminance,
- _Raymarched_Fog_Emitter_Texture_Intensity,
- #endif
- #if defined(_RAYMARCHED_FOG_EMITTER_TEXTURE_WARPING)
- _Raymarched_Fog_Emitter_Texture_Warping_Octaves,
- _Raymarched_Fog_Emitter_Texture_Warping_Strength,
- _Raymarched_Fog_Emitter_Texture_Warping_Scale,
- _Raymarched_Fog_Emitter_Texture_Warping_Speed,
- #endif
- #if defined(_RAYMARCHED_FOG_DENSITY_EXPONENT)
- _Raymarched_Fog_Density_Exponent,
- #endif
- };
- FogResult fog_result = raymarched_fog(i, f, fog_params);
- depth = fog_result.depth;
- return fog_result.color;
- }
-#endif
-
-#if defined(_SHATTER_WAVE) || defined(_SCREEN_SPACE_NORMALS)
- calcNormalInScreenSpace(i.normal, i.objPos);
- i.normal = UnityObjectToWorldNormal(i.normal);
-#endif
-
-#if defined(_SHATTER_WAVE) || defined(_VERTEX_DOMAIN_WARPING) || defined(_TESSELLATION_HEIGHTMAP)
- {
- [branch]
- if (
- false
-#if defined(_SHATTER_WAVE)
- || any(_Shatter_Wave_Amplitude > 1E-4)
-#endif
-#if defined(_VERTEX_DOMAIN_WARPING)
- || _Vertex_Domain_Warping_Octaves > 0.1
-#endif
-#if defined(_TESSELLATION_HEIGHTMAP_0)
- || _Tessellation_Heightmap_0_Scale > 1E-4
-#endif
-#if defined(_TESSELLATION_HEIGHTMAP_1)
- || _Tessellation_Heightmap_1_Scale > 1E-4
-#endif
-#if defined(_TESSELLATION_HEIGHTMAP_2)
- || _Tessellation_Heightmap_2_Scale > 1E-4
-#endif
-#if defined(_TESSELLATION_HEIGHTMAP_3)
- || _Tessellation_Heightmap_3_Scale > 1E-4
-#endif
-#if defined(_TESSELLATION_HEIGHTMAP_4)
- || _Tessellation_Heightmap_4_Scale > 1E-4
-#endif
-#if defined(_TESSELLATION_HEIGHTMAP_5)
- || _Tessellation_Heightmap_5_Scale > 1E-4
-#endif
-#if defined(_TESSELLATION_HEIGHTMAP_6)
- || _Tessellation_Heightmap_6_Scale > 1E-4
-#endif
-#if defined(_TESSELLATION_HEIGHTMAP_7)
- || _Tessellation_Heightmap_7_Scale > 1E-4
-#endif
- ) {
- float4 clip_pos = UnityObjectToClipPos(i.objPos);
- depth = clip_pos.z / clip_pos.w;
- } else {
- // Perspective division takes place before the fragment shader, so we
- // don't have to divide again.
- depth = i.pos.z;
- }
- }
-#endif
-
-#if defined(_EYE_EFFECT_00)
- EyeEffectOutput eye_effect_00 = EyeEffect_00(i);
- i.uv01.xy = eye_effect_00.uv;
-#endif
-
-#if defined(_CUSTOM30)
-#if defined(FORWARD_BASE_PASS) || (!defined(_DEPTH_PREPASS) && defined(SHADOW_CASTER_PASS))
-#if defined(_CUSTOM30_BASICCUBE)
- Custom30Output c30_out = BasicCube(i);
-#elif defined(_CUSTOM30_BASICWEDGE)
- Custom30Output c30_out = BasicWedge(i);
-#elif defined(_CUSTOM30_BASICPLATFORM)
- Custom30Output c30_out = BasicPlatform(i);
-#elif defined(_CUSTOM30_RAINBOW)
- Custom30Output c30_out = Rainbow(i);
-#else
- Custom30Output c30_out = (Custom30Output) 0;
-#endif
- i.normal = c30_out.normal;
- float4 c30_clipPos = UnityObjectToClipPos(i.objPos);
- float4 c30_screenPos = ComputeScreenPos(c30_clipPos);
- i.pos = c30_screenPos;
-#if !defined(_DEPTH_PREPASS)
- depth = c30_out.depth;
-#endif
-#endif
-#endif
-
- float ssao = 1;
-#if defined(_SSAO)
- float2 debug;
- ssao = get_ssao(i, f, debug);
-#endif
- YumPbr pbr = GetYumPbr(i, f);
- pbr.albedo.rgb *= ssao;
-
-#if defined(META_PASS)
-#if defined(_EMISSION)
- return pbr.emission;
-#else
- return 0;
-#endif
-#endif
-
-#if defined(_TROCHOID)
- float3 normal_obj = trochoid_normal(i.orig_pos);
-
- // We need tangents that are perpendicular to the new normal.
- // A common way to generate them is to cross with a fixed "up" vector.
- float3 tangent_obj = normalize(cross(normal_obj, float3(0, 1, 0)));
- float3 binormal_obj = cross(normal_obj, tangent_obj);
-
- i.normal = UnityObjectToWorldNormal(normal_obj);
- i.tangent = float4(normalize(mul((float3x3)unity_ObjectToWorld, tangent_obj)), 1);
- i.binormal = normalize(mul((float3x3)unity_ObjectToWorld, binormal_obj));
- i.normal *= facing ? 1 : -1;
-
- float theta = 1 - atan2(i.orig_pos.y, i.orig_pos.x) / PI;
- float3 color = _Trochoid_Color_Ramp.SampleLevel(linear_clamp_s, float2(theta, 0.5), 0).rgb;
- pbr.albedo.xyz = color;
-#endif
-
-#if defined(_HARNACK_TRACING)
- HarnackTracingOutput harnack_output = HarnackTracing(i);
- pbr.albedo = float4(1, 1, 1, 0.2);
- pbr.smoothness = 0.95;
- pbr.roughness_perceptual = 0.05;
- pbr.roughness = pbr.roughness_perceptual * pbr.roughness_perceptual;
- pbr.metallic = 0;
-#endif
-
-#if defined(_SSFD)
- float ssfd_mask = ssfd(i.uv01.xy, _SSFD_Scale, _SSFD_Max_Fwidth, 0, _SSFD_Noise);
- pbr.albedo *= (ssfd_mask > _SSFD_Threshold);
-#endif
-
-#if defined(OUTLINE_PASS)
- pbr.smoothness = 0;
- pbr.roughness = 1;
- pbr.roughness_perceptual = 1;
- pbr.metallic = 0;
-#endif
-
-#if defined(_EYE_EFFECT_00)
- pbr.normal = eye_effect_00.normal;
-#endif
-
-#if defined(_LETTER_GRID)
- LetterGridOutput letter_grid_output = LetterGrid(i);
- pbr.albedo.rgb = lerp(pbr.albedo.rgb, letter_grid_output.albedo, letter_grid_output.albedo.a);
- pbr.metallic = lerp(pbr.metallic, letter_grid_output.metallic, letter_grid_output.albedo.a);
- pbr.roughness = lerp(pbr.roughness, letter_grid_output.roughness, letter_grid_output.albedo.a);
-#endif
-
-#if defined(_UNIGRAM_LETTER_GRID)
- UnigramLetterGridOutput unigram_letter_grid_output = UnigramLetterGrid(i, facing);
- pbr.albedo.rgb = lerp(pbr.albedo.rgb, unigram_letter_grid_output.albedo,
- unigram_letter_grid_output.albedo.a);
- pbr.metallic = lerp(pbr.metallic, unigram_letter_grid_output.metallic,
- unigram_letter_grid_output.albedo.a);
- pbr.roughness = lerp(pbr.roughness, unigram_letter_grid_output.roughness,
- unigram_letter_grid_output.albedo.a);
-#endif
-
- [branch]
- if (_Mode == 1) {
- clip(pbr.albedo.a - _Clip);
- pbr.albedo.a = 1;
- }
-
-#if defined(EXTRA_STENCIL_COLOR_PASS) && defined(_EXTRA_STENCIL_COLOR_PASS)
- pbr.albedo = _ExtraStencilColor;
-#endif
-
-#if defined(FORWARD_BASE_PASS) || defined(FORWARD_ADD_PASS) || defined(OUTLINE_PASS) || defined(EXTRA_STENCIL_COLOR_PASS)
- YumLighting l = GetYumLighting(i, f, pbr);
-
-#if defined(FORWARD_BASE_PASS) || defined(FORWARD_ADD_PASS)
- applyMatcapsAndRimLighting(i, f, pbr, l);
- l.diffuse = max(0, l.diffuse);
- l.specular = max(0, l.specular);
-#endif
-
- pbr.albedo.rgb = visualizeInFalseColor(pbr.albedo.rgb);
- pbr.albedo.rgb = applyQuasiShadows(pbr.albedo.rgb, l);
-
-#if defined(_UNLIT)
- float4 lit = pbr.albedo;
-#else
- float4 lit = YumBRDF(i, f, l, pbr);
-#endif
-
-#if defined(_HARNACK_TRACING)
- pbr.albedo = harnack_output.color;
- pbr.smoothness = 0;
- pbr.roughness = 1;
- pbr.roughness_perceptual = 1;
- pbr.metallic = 0;
- pbr.normal = harnack_output.normal;
- l.NoL = saturate(dot(pbr.normal, l.dir));
- l.NoL_wrapped_s = l.NoL;
- l.NoL_wrapped_d = l.NoL;
- float4 harnack_lit = YumBRDF(i, l, pbr);
- //lit = alphaBlend(harnack_lit, lit);
- lit = harnack_lit;
- {
- float4 clip_pos = mul(UNITY_MATRIX_VP, float4(harnack_output.worldPos, 1.0));
- depth = clip_pos.z / clip_pos.w;
- }
-#endif
-
-#if defined(_EMISSION) || (defined(_GLITTER) && defined(FORWARD_BASE_PASS)) || defined(OUTLINE_PASS)
- lit.rgb += pbr.emission;
-#endif
-#if defined(_LETTER_GRID)
- lit.rgb += letter_grid_output.emission * letter_grid_output.albedo.a;
-#endif
-#if defined(_UNIGRAM_LETTER_GRID)
- lit.rgb += unigram_letter_grid_output.emission * unigram_letter_grid_output.albedo.a;
-#endif
-
- UNITY_EXTRACT_FOG_FROM_EYE_VEC(i);
- UNITY_APPLY_FOG(_unity_fogCoord, lit.rgb);
-
- return lit;
-#elif defined(SHADOW_CASTER_PASS)
- // Apply dithering for LOD if needed
- #ifdef LOD_FADE_CROSSFADE
- UnityApplyDitherCrossFade(i.pos.xy);
- #endif
-
- // Output proper shadow data
- SHADOW_CASTER_FRAGMENT(i)
-#elif defined(MASKED_STENCIL1_PASS) || defined(MASKED_STENCIL2_PASS) || defined(MASKED_STENCIL3_PASS) || defined(MASKED_STENCIL4_PASS) || defined(DEPTH_PREPASS)
- return 0;
-#endif
-}
-
-#endif // __2NER_INC
+#ifndef __2NER_INC +#define __2NER_INC + +#define HANDLE_SHADOWS_BLENDING_IN_GI + +#include "UnityCG.cginc" +#include "UnityStandardCoreMinimal.cginc" +#include "UnityLightingCommon.cginc" +#include "AutoLight.cginc" + +#include "custom30.cginc" +#include "eyes.cginc" +#include "face_me.cginc" +#include "false_color_visualization.cginc" +#include "features.cginc" +#include "fog.cginc" +#include "globals.cginc" +#include "harnack_tracing.cginc" +#include "interpolators.cginc" +#include "letter_grid.cginc" +#include "matcaps.cginc" +#include "math.cginc" +#include "poi.cginc" +#include "shatter_wave.cginc" +#include "ssao.cginc" +#include "ssfd.cginc" +#include "tessellation.cginc" +#include "trochoid.cginc" +#include "unigram_letter_grid.cginc" +#include "vertex_domain_warping.cginc" +#include "yum_brdf.cginc" +#include "yum_pbr.cginc" +#include "yum_lighting.cginc" + +v2f vert(appdata v) { +#if defined(OUTLINE_PASS) && !defined(_OUTLINES) + // The outline pass will be entirely elided when locked. This just lets us + // hide outlines when not locked. + return (v2f) (0.0/0.0); +#endif +#if defined(_RAYMARCHED_FOG) && !defined(FORWARD_BASE_PASS) + return (v2f) (0.0/0.0); +#endif +#if defined(DEPTH_PREPASS) && !defined(_DEPTH_PREPASS) + return (v2f) (0.0/0.0); +#endif +#if defined(EXTRA_STENCIL_COLOR_PASS) && !defined(_EXTRA_STENCIL_COLOR_PASS) + return (v2f) (0.0/0.0); +#endif +#if defined(MASKED_STENCIL1_PASS) +#if !defined(_MASKED_STENCIL1) + return (v2f) (0.0/0.0); +#endif + float masked_stencil1_mask = _Masked_Stencil1_Mask.SampleLevel(linear_repeat_s, v.uv0, 0); + [branch] + if (masked_stencil1_mask < 0.5) { + return (v2f) (0.0/0.0); + } +#endif +#if defined(MASKED_STENCIL2_PASS) +#if !defined(_MASKED_STENCIL2) + return (v2f) (0.0/0.0); +#endif + float masked_stencil2_mask = _Masked_Stencil2_Mask.SampleLevel(linear_repeat_s, v.uv0, 0); + [branch] + if (masked_stencil2_mask < 0.5) { + return (v2f) (0.0/0.0); + } +#endif +#if defined(MASKED_STENCIL3_PASS) +#if !defined(_MASKED_STENCIL3) + return (v2f) (0.0/0.0); +#endif + float masked_stencil3_mask = _Masked_Stencil3_Mask.SampleLevel(linear_repeat_s, v.uv0, 0); + [branch] + if (masked_stencil3_mask < 0.5) { + return (v2f) (0.0/0.0); + } +#endif +#if defined(MASKED_STENCIL4_PASS) +#if !defined(_MASKED_STENCIL4) + return (v2f) (0.0/0.0); +#endif + float masked_stencil4_mask = _Masked_Stencil4_Mask.SampleLevel(linear_repeat_s, v.uv0, 0); + [branch] + if (masked_stencil4_mask < 0.5) { + return (v2f) (0.0/0.0); + } +#endif +#if defined(EXTRA_STENCIL_COLOR_PASS) && !defined(_EXTRA_STENCIL_COLOR_PASS) + return (v2f) (0.0/0.0); +#endif +#if defined(FORWARD_ADD_PASS) & defined(_UNLIT) + return (v2f) (0.0/0.0); +#endif + + 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(_SPHERIZE) + { + float3 tgt_normal = normalize(o.objPos.xyz); + float3 tgt_tangent = normalize(float3(tgt_normal.y, -tgt_normal.x, 0)); + float3 tgt_pos = tgt_normal * _Spherize_Radius; + v.normal = normalize(lerp(v.normal, tgt_normal, _Spherize_Strength)); + v.vertex.xyz = lerp(v.vertex.xyz, tgt_pos, _Spherize_Strength); + } +#endif +#if !defined(_TESSELLATION) && defined(_SHATTER_WAVE) + shatterWaveVert(v.vertex.xyz, v.normal, v.tangent); +#endif + +#if defined(_VERTEX_DOMAIN_WARPING) + v.vertex.xyz = domainWarpVertexPosition(v.vertex.xyz); +#endif + +#if defined(_TROCHOID) + o.orig_pos = v.vertex.xyz; + v.vertex.xyz = trochoid_map(v.vertex.xyz); +#endif + +#if defined(OUTLINE_PASS) + [branch] + if (!_Outlines_Enabled_Dynamic) { + return (v2f) (0.0/0.0); + } +#if defined(_OUTLINE_MASK) + float thickness = _Outline_Mask.SampleLevel(linear_repeat_s, v.uv0, 0); + thickness = (_Outline_Mask_Invert == 0 ? thickness : 1 - thickness); +#else + float thickness = 1; +#endif + v.vertex.xyz += _Outline_Width * v.normal * thickness; + v.normal *= -1; + v.tangent *= -1; +#endif // OUTLINE_PASS + +#if defined(_FACE_ME) + face_me(v); +#endif + +#if defined(_FOCAL_LENGTH_CONTROL) + [branch] + if (_Focal_Length_Enabled_Dynamic) { + float4 fl_worldPos_unscaled = mul(unity_ObjectToWorld, v.vertex); + float4 fl_viewPos_unscaled = mul(UNITY_MATRIX_V, fl_worldPos_unscaled); + + float4 fl_objPos = float4(v.vertex.xyz * _Focal_Length_Multiplier, v.vertex.w); + float4 fl_worldPos = mul(unity_ObjectToWorld, fl_objPos); + float4 fl_viewPos = mul(UNITY_MATRIX_V, fl_worldPos); + fl_viewPos.xy /= _Focal_Length_Multiplier; + + float2 fl_compensation = fl_viewPos_unscaled.xy - fl_viewPos.xy; + fl_viewPos.xy += fl_compensation; + + o.pos = mul(UNITY_MATRIX_P, fl_viewPos); + } else { + o.pos = UnityObjectToClipPos(v.vertex); + } +#else + o.pos = UnityObjectToClipPos(v.vertex); +#endif + +#if defined(_TESSELLATION) + o.tpos = v.vertex; +#endif + o.uv01.xy = v.uv0; +#if defined(LIGHTMAP_ON) + o.uv01.zw = v.uv1 * unity_LightmapST.xy + unity_LightmapST.zw; +#else + o.uv01.zw = v.uv1; +#endif + o.uv23.xy = v.uv2; + o.uv23.zw = v.uv3; +#if defined(_MIRROR_UVS_IN_MIRROR) + [branch] + if (isInMirror()) { + o.uv01.x = 1.0 - o.uv01.x; + o.uv01.z = 1.0 - o.uv01.z; + o.uv23.x = 1.0 - o.uv23.x; + o.uv23.z = 1.0 - o.uv23.z; + } +#endif + o.objPos = v.vertex; + + // These are used to convert normals from tangent space to world space. + o.normal = v.normal; + o.tangent = v.tangent; + + 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 + +#if defined(V2F_COLOR) + // Vertex color + o.color = v.color; +#endif + + // Calculate vertex lights + #ifdef VERTEXLIGHT_ON + float3 worldPos = mul(unity_ObjectToWorld, v.vertex); + #if defined(_WRAPPED_LIGHTING) + o.vertexLight = Shade4PointLightsWrapped( + unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0, + unity_LightColor[0].rgb, unity_LightColor[1].rgb, unity_LightColor[2].rgb, unity_LightColor[3].rgb, + unity_4LightAtten0, worldPos, o.normal, _Wrap_NoL_Diffuse_Strength); + #else + o.vertexLight = Shade4PointLights( + unity_4LightPosX0, unity_4LightPosY0, unity_4LightPosZ0, + unity_LightColor[0].rgb, unity_LightColor[1].rgb, unity_LightColor[2].rgb, unity_LightColor[3].rgb, + unity_4LightAtten0, worldPos, o.normal); + #endif + #else + o.vertexLight = 0; + #endif + + return o; +} + +//ifex _Fur_Enabled==0 +[maxvertexcount(30)] +void geom(triangle v2f input[3], inout TriangleStream<v2f> stream) { +#if defined(_FUR) +#if defined(_FUR_MASK) + float fur_mask = _Fur_Mask.SampleLevel(bilinear_repeat_s, input[0].uv01.xy * _Fur_Mask_ST.xy, 0); +#else + float fur_mask = 1; +#endif + + stream.Append(input[0]); + stream.Append(input[1]); + stream.Append(input[2]); + stream.RestartStrip(); + + [branch] + if (fur_mask < 0.5) { + return; + } + + float3 gravDirObj = normalize(mul(unity_WorldToObject, float3(0, -1, 0))); + + // Compute gravity direction minus component that would compress this shell. + // Could compute average normal but this is probably good enough. + float3 gravDirNoRegress = gravDirObj - min(0, input[0].normal * dot(gravDirObj, input[0].normal)); + + float3 worldPos = mul(unity_ObjectToWorld, input[0].objPos).xyz; + float radius = length(_WorldSpaceCameraPos - worldPos); + uint fur_layers = lerp(_Fur_Layers - 3, 5, saturate((radius - _Fur_Min_Dist) / (_Fur_Max_Dist - _Fur_Min_Dist))); + + [loop] + for (uint layer = 0; layer < fur_layers; layer++) { + float t = (float) layer / (float) max(fur_layers - 4, 1); + + float offset = t * _Fur_Thickness; + + v2f o = input[layer % 3]; + float3 normal_ws = UnityObjectToWorldNormal(o.normal); + + float3 dir = lerp(o.normal, gravDirNoRegress, t * t * _Fur_Gravity_Strength); + + o.objPos.xyz += dir * offset; + + float3 worldPos = mul(unity_ObjectToWorld, o.objPos).xyz; + o.pos = UnityWorldToClipPos(worldPos); + o.vertexLight.w = t; + stream.Append(o); + } +#else + stream.Append(input[0]); + stream.Append(input[1]); + stream.Append(input[2]); + stream.RestartStrip(); +#endif // _FUR +} +//endex + +float4 frag(v2f i, uint facing : SV_IsFrontFace +#if defined(_HARNACK_TRACING) || defined(_SHATTER_WAVE) || defined(_VERTEX_DOMAIN_WARPING) || (defined(_CUSTOM30) && !defined(_DEPTH_PREPASS)) || defined(_RAYMARCHED_FOG) || defined(_TESSELLATION_HEIGHTMAP) + , out float depth : SV_DepthLessEqual +#endif +) : SV_Target { + + UNITY_APPLY_DITHER_CROSSFADE(i.pos.xy); + UNITY_SETUP_INSTANCE_ID(i); + UNITY_SETUP_STEREO_EYE_INDEX_POST_VERTEX(i); + +#if defined(_CUSTOM30) && defined(_DEPTH_PREPASS) && !defined(FORWARD_BASE_PASS) + return 0; +#endif + + i.normal *= facing ? 1 : -1; + i.normal = UnityObjectToWorldNormal(i.normal); + i.tangent.xyz = UnityObjectToWorldNormal(i.tangent.xyz); + + // Not necessarily normalized after interpolation + i.normal = normalize(i.normal); + i.tangent.xyz = normalize(i.tangent.xyz); + + f2f f = (f2f) 0; + f.worldPos = mul(unity_ObjectToWorld, i.objPos); + f.binormal = cross(i.normal, i.tangent.xyz) * i.tangent.w; + f.eyeVec = f.worldPos - _WorldSpaceCameraPos; + f.viewDir = normalize(f.eyeVec); + f.tbn = float3x3( + i.tangent.xyz, + f.binormal, + i.normal + ); + +#if defined(_RAYMARCHED_FOG) + { + // Many fields are overspecified as .rgb or .xyz. This is because thry's + // shader locker will inline those fields (incorrectly) as float4. Unity's + // shader compiler doesn't like that, demanding exact type correspondence. + // Overspecifying gets around the issue. + + FogParams fog_params = { + _Raymarched_Fog_Color.rgb, + _Raymarched_Fog_Direct_Light_Intensity, + _Raymarched_Fog_Indirect_Light_Intensity, + _Raymarched_Fog_Steps, + _Raymarched_Fog_Y_Cutoff, + _Raymarched_Fog_Dithering_Noise, + _Raymarched_Fog_Dithering_Noise_TexelSize, + _Raymarched_Fog_Density_Noise, + _Raymarched_Fog_Density_Noise_Scale, + _Raymarched_Fog_Velocity.xyz, + _Raymarched_Fog_Mean_Free_Path, + _Raymarched_Fog_Albedo, + _Raymarched_Fog_G, + _Raymarched_Fog_Height_Scale, + _Raymarched_Fog_Height_Offset, + _Raymarched_Fog_Turbulence, + _Raymarched_Fog_Step_Size, + _Raymarched_Fog_Step_Growth, + #if defined(_RAYMARCHED_FOG_EMITTER_TEXTURE) + _Raymarched_Fog_Emitter_Texture, + _Raymarched_Fog_Emitter_Texture_TexelSize, + _Raymarched_Fog_Emitter_Texture_World_Pos.xyz, + normalize(_Raymarched_Fog_Emitter_Texture_World_Normal).xyz, + normalize(_Raymarched_Fog_Emitter_Texture_World_Tangent).xyz, + normalize(cross(_Raymarched_Fog_Emitter_Texture_World_Normal, _Raymarched_Fog_Emitter_Texture_World_Tangent)).xyz, + _Raymarched_Fog_Emitter_Texture_World_Scale.xy, + 1.0f / _Raymarched_Fog_Emitter_Texture_World_Scale.xy, + _Raymarched_Fog_Emitter_Texture_Luminance, + _Raymarched_Fog_Emitter_Texture_Intensity, + #endif + #if defined(_RAYMARCHED_FOG_EMITTER_TEXTURE_WARPING) + _Raymarched_Fog_Emitter_Texture_Warping_Octaves, + _Raymarched_Fog_Emitter_Texture_Warping_Strength, + _Raymarched_Fog_Emitter_Texture_Warping_Scale, + _Raymarched_Fog_Emitter_Texture_Warping_Speed, + #endif + #if defined(_RAYMARCHED_FOG_DENSITY_EXPONENT) + _Raymarched_Fog_Density_Exponent, + #endif + }; + FogResult fog_result = raymarched_fog(i, f, fog_params); + depth = fog_result.depth; + return fog_result.color; + } +#endif + +#if defined(_SHATTER_WAVE) || defined(_SCREEN_SPACE_NORMALS) + calcNormalInScreenSpace(i.normal, i.objPos); + i.normal = UnityObjectToWorldNormal(i.normal); +#endif + +#if defined(_SHATTER_WAVE) || defined(_VERTEX_DOMAIN_WARPING) || defined(_TESSELLATION_HEIGHTMAP) + { + [branch] + if ( + false +#if defined(_SHATTER_WAVE) + || any(_Shatter_Wave_Amplitude > 1E-4) +#endif +#if defined(_VERTEX_DOMAIN_WARPING) + || _Vertex_Domain_Warping_Octaves > 0.1 +#endif +#if defined(_TESSELLATION_HEIGHTMAP_0) + || _Tessellation_Heightmap_0_Scale > 1E-4 +#endif +#if defined(_TESSELLATION_HEIGHTMAP_1) + || _Tessellation_Heightmap_1_Scale > 1E-4 +#endif +#if defined(_TESSELLATION_HEIGHTMAP_2) + || _Tessellation_Heightmap_2_Scale > 1E-4 +#endif +#if defined(_TESSELLATION_HEIGHTMAP_3) + || _Tessellation_Heightmap_3_Scale > 1E-4 +#endif +#if defined(_TESSELLATION_HEIGHTMAP_4) + || _Tessellation_Heightmap_4_Scale > 1E-4 +#endif +#if defined(_TESSELLATION_HEIGHTMAP_5) + || _Tessellation_Heightmap_5_Scale > 1E-4 +#endif +#if defined(_TESSELLATION_HEIGHTMAP_6) + || _Tessellation_Heightmap_6_Scale > 1E-4 +#endif +#if defined(_TESSELLATION_HEIGHTMAP_7) + || _Tessellation_Heightmap_7_Scale > 1E-4 +#endif + ) { + float4 clip_pos = UnityObjectToClipPos(i.objPos); + depth = clip_pos.z / clip_pos.w; + } else { + // Perspective division takes place before the fragment shader, so we + // don't have to divide again. + depth = i.pos.z; + } + } +#endif + +#if defined(_EYE_EFFECT_00) + EyeEffectOutput eye_effect_00 = EyeEffect_00(i); + i.uv01.xy = eye_effect_00.uv; +#endif + +#if defined(_CUSTOM30) +#if defined(FORWARD_BASE_PASS) || (!defined(_DEPTH_PREPASS) && defined(SHADOW_CASTER_PASS)) +#if defined(_CUSTOM30_BASICCUBE) + Custom30Output c30_out = BasicCube(i); +#elif defined(_CUSTOM30_BASICWEDGE) + Custom30Output c30_out = BasicWedge(i); +#elif defined(_CUSTOM30_BASICPLATFORM) + Custom30Output c30_out = BasicPlatform(i); +#elif defined(_CUSTOM30_RAINBOW) + Custom30Output c30_out = Rainbow(i); +#else + Custom30Output c30_out = (Custom30Output) 0; +#endif + i.normal = c30_out.normal; + float4 c30_clipPos = UnityObjectToClipPos(i.objPos); + float4 c30_screenPos = ComputeScreenPos(c30_clipPos); + i.pos = c30_screenPos; +#if !defined(_DEPTH_PREPASS) + depth = c30_out.depth; +#endif +#endif +#endif + + float ssao = 1; +#if defined(_SSAO) + float2 debug; + ssao = get_ssao(i, f, debug); +#endif + YumPbr pbr = GetYumPbr(i, f); + pbr.albedo.rgb *= ssao; + +#if defined(META_PASS) +#if defined(_EMISSION) + return pbr.emission; +#else + return 0; +#endif +#endif + +#if defined(_TROCHOID) + float3 normal_obj = trochoid_normal(i.orig_pos); + + // We need tangents that are perpendicular to the new normal. + // A common way to generate them is to cross with a fixed "up" vector. + float3 tangent_obj = normalize(cross(normal_obj, float3(0, 1, 0))); + float3 binormal_obj = cross(normal_obj, tangent_obj); + + i.normal = UnityObjectToWorldNormal(normal_obj); + i.tangent = float4(normalize(mul((float3x3)unity_ObjectToWorld, tangent_obj)), 1); + i.binormal = normalize(mul((float3x3)unity_ObjectToWorld, binormal_obj)); + i.normal *= facing ? 1 : -1; + + float theta = 1 - atan2(i.orig_pos.y, i.orig_pos.x) / PI; + float3 color = _Trochoid_Color_Ramp.SampleLevel(linear_clamp_s, float2(theta, 0.5), 0).rgb; + pbr.albedo.xyz = color; +#endif + +#if defined(_HARNACK_TRACING) + HarnackTracingOutput harnack_output = HarnackTracing(i); + pbr.albedo = float4(1, 1, 1, 0.2); + pbr.smoothness = 0.95; + pbr.roughness_perceptual = 0.05; + pbr.roughness = pbr.roughness_perceptual * pbr.roughness_perceptual; + pbr.metallic = 0; +#endif + +#if defined(_SSFD) + float ssfd_mask = ssfd(i.uv01.xy, _SSFD_Scale, _SSFD_Max_Fwidth, 0, _SSFD_Noise); + pbr.albedo *= (ssfd_mask > _SSFD_Threshold); +#endif + +#if defined(OUTLINE_PASS) + pbr.smoothness = 0; + pbr.roughness = 1; + pbr.roughness_perceptual = 1; + pbr.metallic = 0; +#endif + +#if defined(_EYE_EFFECT_00) + pbr.normal = eye_effect_00.normal; +#endif + +#if defined(_LETTER_GRID) + LetterGridOutput letter_grid_output = LetterGrid(i); + pbr.albedo.rgb = lerp(pbr.albedo.rgb, letter_grid_output.albedo, letter_grid_output.albedo.a); + pbr.metallic = lerp(pbr.metallic, letter_grid_output.metallic, letter_grid_output.albedo.a); + pbr.roughness = lerp(pbr.roughness, letter_grid_output.roughness, letter_grid_output.albedo.a); +#endif + +#if defined(_UNIGRAM_LETTER_GRID) + UnigramLetterGridOutput unigram_letter_grid_output = UnigramLetterGrid(i, facing); + pbr.albedo.rgb = lerp(pbr.albedo.rgb, unigram_letter_grid_output.albedo, + unigram_letter_grid_output.albedo.a); + pbr.metallic = lerp(pbr.metallic, unigram_letter_grid_output.metallic, + unigram_letter_grid_output.albedo.a); + pbr.roughness = lerp(pbr.roughness, unigram_letter_grid_output.roughness, + unigram_letter_grid_output.albedo.a); +#endif + + [branch] + if (_Mode == 1) { + clip(pbr.albedo.a - _Clip); + pbr.albedo.a = 1; + } + +#if defined(EXTRA_STENCIL_COLOR_PASS) && defined(_EXTRA_STENCIL_COLOR_PASS) + pbr.albedo = _ExtraStencilColor; +#endif + +#if defined(FORWARD_BASE_PASS) || defined(FORWARD_ADD_PASS) || defined(OUTLINE_PASS) || defined(EXTRA_STENCIL_COLOR_PASS) + YumLighting l = GetYumLighting(i, f, pbr); + +#if defined(FORWARD_BASE_PASS) || defined(FORWARD_ADD_PASS) + applyMatcapsAndRimLighting(i, f, pbr, l); + l.diffuse = max(0, l.diffuse); + l.specular = max(0, l.specular); +#endif + + pbr.albedo.rgb = visualizeInFalseColor(pbr.albedo.rgb); + pbr.albedo.rgb = applyQuasiShadows(pbr.albedo.rgb, l); + +#if defined(_UNLIT) + float4 lit = pbr.albedo; +#else + float4 lit = YumBRDF(i, f, l, pbr); +#endif + +#if defined(_HARNACK_TRACING) + pbr.albedo = harnack_output.color; + pbr.smoothness = 0; + pbr.roughness = 1; + pbr.roughness_perceptual = 1; + pbr.metallic = 0; + pbr.normal = harnack_output.normal; + l.NoL = saturate(dot(pbr.normal, l.dir)); + l.NoL_wrapped_s = l.NoL; + l.NoL_wrapped_d = l.NoL; + float4 harnack_lit = YumBRDF(i, l, pbr); + //lit = alphaBlend(harnack_lit, lit); + lit = harnack_lit; + { + float4 clip_pos = mul(UNITY_MATRIX_VP, float4(harnack_output.worldPos, 1.0)); + depth = clip_pos.z / clip_pos.w; + } +#endif + +#if defined(_EMISSION) || (defined(_GLITTER) && defined(FORWARD_BASE_PASS)) || defined(OUTLINE_PASS) + lit.rgb += pbr.emission; +#endif +#if defined(_LETTER_GRID) + lit.rgb += letter_grid_output.emission * letter_grid_output.albedo.a; +#endif +#if defined(_UNIGRAM_LETTER_GRID) + lit.rgb += unigram_letter_grid_output.emission * unigram_letter_grid_output.albedo.a; +#endif + + UNITY_EXTRACT_FOG_FROM_EYE_VEC(i); + UNITY_APPLY_FOG(_unity_fogCoord, lit.rgb); + + return lit; +#elif defined(SHADOW_CASTER_PASS) + // Apply dithering for LOD if needed + #ifdef LOD_FADE_CROSSFADE + UnityApplyDitherCrossFade(i.pos.xy); + #endif + + // Output proper shadow data + SHADOW_CASTER_FRAGMENT(i) +#elif defined(MASKED_STENCIL1_PASS) || defined(MASKED_STENCIL2_PASS) || defined(MASKED_STENCIL3_PASS) || defined(MASKED_STENCIL4_PASS) || defined(DEPTH_PREPASS) + return 0; +#endif +} + +#endif // __2NER_INC diff --git a/2ner.shader b/2ner.shader index ae966d1..0ea5b2c 100644 --- a/2ner.shader +++ b/2ner.shader @@ -72,24 +72,32 @@ Shader "yum_food/2ner" //endex //ifex _Metallics_Enabled==0 - [HideInInspector] m_reflectionOptions("Reflections", Float) = 0 - [HideInInspector] m_start_Metallic("Metallics", Float) = 0 - [ThryToggle(_METALLICS)]_Metallics_Enabled("Enable", Float) = 0 - _Metallic("Metallic", Range(0, 1)) = 0 - _Smoothness("Smoothness", Range(0, 1)) = 0 - _MetallicGlossMap("Metallic gloss map", 2D) = "white" {} - [HideInInspector] m_end_Metallic("Metallics", Float) = 0 - //endex + [HideInInspector] m_start_Reflections("Reflections", Float) = 0 + [HideInInspector] m_start_Metallic("Metallics", Float) = 0 + [ThryToggle(_METALLICS)]_Metallics_Enabled("Enable", Float) = 0 + _Metallic("Metallic", Range(0, 1)) = 0 + _Smoothness("Smoothness", Range(0, 1)) = 0 + _MetallicGlossMap("Metallic gloss map", 2D) = "white" {} + [HideInInspector] m_end_Metallic("Metallics", Float) = 0 + //endex - //ifex _Clearcoat_Enabled==0 - [HideInInspector] m_start_Clearcoat("Clearcoat", Float) = 0 - [ThryToggle(_CLEARCOAT)]_Clearcoat_Enabled("Enable", Float) = 0 - [ThryToggle(_CLEARCOAT_GEOMETRIC_NORMALS)]_Clearcoat_Geometric_Normals_Enabled("Use geometric normals", Float) = 1 - _Clearcoat_Mask("Mask", 2D) = "white" {} - _Clearcoat_Strength("Strength", Range(0, 10)) = 1 - _Clearcoat_Roughness("Roughness", Range(0.089, 1)) = 0.089 - [HideInInspector] m_end_Clearcoat("Clearcoat", Float) = 0 - //endex + //ifex _Clearcoat_Enabled==0 + [HideInInspector] m_start_Clearcoat("Clearcoat", Float) = 0 + [ThryToggle(_CLEARCOAT)]_Clearcoat_Enabled("Enable", Float) = 0 + [ThryToggle(_CLEARCOAT_GEOMETRIC_NORMALS)]_Clearcoat_Geometric_Normals_Enabled("Use geometric normals", Float) = 1 + _Clearcoat_Mask("Mask", 2D) = "white" {} + _Clearcoat_Strength("Strength", Range(0, 10)) = 1 + _Clearcoat_Roughness("Roughness", Range(0.089, 1)) = 0.089 + [HideInInspector] m_end_Clearcoat("Clearcoat", Float) = 0 + //endex + + //ifex _Anisotropy_Enabled==0 + [HideInInspector] m_start_Anisotropy("Anisotropy", Float) = 0 + [ThryToggle(_ANISOTROPY)]_Anisotropy_Enabled("Enable", Float) = 0 + _Anisotropy_Strength("Strength", Range(-1, 1)) = 0 + [HideInInspector] m_end_Anisotropy("Anisotropy", Float) = 0 + //endex + [HideInInspector] m_end_Reflections("Reflections", Float) = 0 [HideInInspector] m_gimmicks("Gimmicks", Float) = 0 //ifex _Outlines_Enabled==0 diff --git a/UnityStandardMeta.cginc b/UnityStandardMeta.cginc index 60eedc9..95fe193 100644 --- a/UnityStandardMeta.cginc +++ b/UnityStandardMeta.cginc @@ -101,7 +101,6 @@ float4 frag_meta (v2f_meta i) : SV_Target v2f pbr_input; pbr_input.uv01 = i.uv01; pbr_input.uv23 = i.uv23; - pbr_input.worldPos = i.worldPos; pbr_input.objPos = float4(i.objPos, 1.0); pbr_input.normal = i.normal; pbr_input.tangent = i.tangent; @@ -114,7 +113,7 @@ float4 frag_meta (v2f_meta i) : SV_Target f.eyeVec = i.worldPos - _WorldSpaceCameraPos; f.viewDir = normalize(f.eyeVec); - YumPbr pbr = GetYumPbr(pbr_input, f, tangentToWorld); + YumPbr pbr = GetYumPbr(pbr_input, f); #if defined(_CUSTOM30) #if defined(_CUSTOM30_BASICCUBE) @@ -10,6 +10,9 @@ struct YumPbr { float roughness_perceptual; float metallic; float ao; +#if defined(_ANISOTROPY) + float3 binormal; +#endif }; #endif // __DATA_INC diff --git a/features.cginc b/features.cginc index ab45306..12a89a0 100644 --- a/features.cginc +++ b/features.cginc @@ -63,6 +63,10 @@ #pragma shader_feature_local _CLEARCOAT_GEOMETRIC_NORMALS //endex +//ifex _Anisotropy_Enabled==0 +#pragma shader_feature_local _ANISOTROPY +//endex + //ifex _Metallics_Enabled==0 #pragma shader_feature_local _METALLICS //endex diff --git a/filamented.cginc b/filamented.cginc index b66baf2..ecf697f 100644 --- a/filamented.cginc +++ b/filamented.cginc @@ -889,6 +889,19 @@ float D_GGX(float roughness, float NoH, const float3 h) { return d; } +// t = tangent vector, b = bitangent vector +float D_GGX_Anisotropic(float at, float ab, float NoH, + const float3 h, + const float3 t, const float3 b) { + float ToH = dot(t, h); + float BoH = dot(b, h); + float a2 = at * ab; + float3 v = float3(ab * ToH, at * BoH, a2 * NoH); + float v2 = dot(v, v); + float w2 = a2 / v2; + return a2 * w2 * w2 * (1.0 / PI); +} + float F_Schlick(float f0, float VoH) { return f0 + (1.0 - f0) * pow5(1.0 - VoH); } @@ -935,6 +948,14 @@ float V_SmithGGXCorrelated_Fast(float roughness, float NoV, float NoL) { return v; } +float V_SmithGGXCorrelated_Anisotropic(float at, float ab, float ToV, float BoV, + float ToL, float BoL, float NoV, float NoL) { + float lambdaV = NoL * length(float3(at * ToV, ab * BoV, NoV)); + float lambdaL = NoV * length(float3(at * ToL, ab * BoL, NoL)); + float v = 0.5 / (lambdaV + lambdaL); + return saturate(v); +} + float perceptualRoughnessToRoughness(float perceptualRoughness) { return perceptualRoughness * perceptualRoughness; } diff --git a/globals.cginc b/globals.cginc index d374c2d..e6e7423 100644 --- a/globals.cginc +++ b/globals.cginc @@ -132,6 +132,10 @@ float _Clearcoat_Strength; float _Clearcoat_Roughness;
#endif
+#if defined(_ANISOTROPY)
+float _Anisotropy_Strength;
+#endif
+
#if defined(OUTLINE_PASS)
float _Outlines_Enabled_Dynamic;
float4 _Outline_Color;
diff --git a/interpolators.cginc b/interpolators.cginc index 6a632d1..89fae91 100644 --- a/interpolators.cginc +++ b/interpolators.cginc @@ -25,7 +25,7 @@ struct v2f { float4 uv23 : TEXCOORD1; // just one more uv slot bro please
float4 objPos : TEXCOORD2;
float3 normal : TEXCOORD3;
- float3 tangent : TEXCOORD4;
+ float4 tangent : TEXCOORD4;
float4 vertexLight : TEXCOORD5; // vertexLight.xyz | furLayer
UNITY_LIGHTING_COORDS(6,7)
diff --git a/yum_brdf.cginc b/yum_brdf.cginc index 347c31d..a12e667 100644 --- a/yum_brdf.cginc +++ b/yum_brdf.cginc @@ -33,8 +33,8 @@ float V_Cloth(float NoV, float NoL) { return 1.0 / (4.0 * (NoL + NoV - NoL * NoV)); } -float3 specularLobe(YumPbr pbr, float3 f0, - float3 h, float LoH, float NoH, float NoV, float NoL) +float3 specularLobe(v2f i, f2f f, YumPbr pbr, YumLighting light, + float3 f0, float3 h, float LoH, float NoH, float NoV, float NoL) { #if defined(_MATERIAL_TYPE_CLOTH) float D = D_Charlie(pbr.roughness, NoH); @@ -49,10 +49,25 @@ float3 specularLobe(YumPbr pbr, float3 f0, float f90 = saturate(dot(f0, (50.0 * 0.33))); const float3 F = F_Schlick(f0, f90, LoH); #endif - // Normal distribution function + +#if defined(_ANISOTROPY) + float anisotropy = _Anisotropy_Strength; + // Walter et al. 2007, "Microfacet Models for Refraction through Rough Surfaces" + float3 b = pbr.binormal; + float3 t = i.tangent.xyz; + float at = max(pbr.roughness * (1.0 + anisotropy), 0.001); + float ab = max(pbr.roughness * (1.0 - anisotropy), 0.001); + float D = D_GGX_Anisotropic(at, ab, NoH, h, t, b); + float ToV = dot(t, light.view_dir); + float BoV = dot(b, light.view_dir); + float ToL = dot(t, light.dir); + float BoL = dot(b, light.dir); + float V = V_SmithGGXCorrelated_Anisotropic(at, ab, + ToV, BoV, ToL, BoL, NoV, NoL); +#else float D = D_GGX(pbr.roughness, NoH, h); - // Geometric shadowing float V = V_SmithGGXCorrelated_Fast(pbr.roughness, NoV, NoL); +#endif return (D * V) * F; #endif } @@ -118,7 +133,7 @@ float4 YumBRDF(v2f i, f2f f, const YumLighting light, YumPbr pbr) { #endif // Cloth specular BRDF - multiply by PI to match Unity intensities - float3 Fr = specularLobe(pbr, float3(0.04, 0.04, 0.04), h, LoH, NoH, NoV, NoL_wrapped_s) * PI * light.attenuation; + float3 Fr = specularLobe(i, f, pbr, light, float3(0.04, 0.04, 0.04), h, LoH, NoH, NoV, NoL_wrapped_s) * PI * light.attenuation; #if defined(_MATERIAL_TYPE_CLOTH_SUBSURFACE) // No need to multiply by NoL when using subsurface scattering @@ -163,7 +178,7 @@ float4 YumBRDF(v2f i, f2f f, const YumLighting light, YumPbr pbr) { Fd *= light.attenuation * pbr.ao * remainder; // Multiply by PI to match Unity intensities (same as Filament's implementation) - float3 Fr = specularLobe(pbr, f0, h, LoH, NoH, NoV, NoL_wrapped_s) * PI * light.attenuation * remainder; + float3 Fr = specularLobe(i, f, pbr, light, f0, h, LoH, NoH, NoV, NoL_wrapped_s) * PI * light.attenuation * remainder; // Apply energy compensation to specular term float3 color = Fd * NoL_wrapped_d + Fr * energy_compensation * NoL_wrapped_s; diff --git a/yum_lighting.cginc b/yum_lighting.cginc index 7f2d922..a1bef47 100644 --- a/yum_lighting.cginc +++ b/yum_lighting.cginc @@ -166,7 +166,14 @@ float GetLodRoughness(float roughness) { } float3 getIndirectSpecular(v2f i, f2f f, YumPbr pbr, float3 view_dir, float diffuse_luminance) { +#if defined(_ANISOTROPY) + float3 aniso_tangent = cross(view_dir, pbr.binormal); + float3 aniso_normal = -normalize(cross(aniso_tangent, pbr.binormal)); + float3 refl_normal = normalize(lerp(pbr.normal, aniso_normal, _Anisotropy_Strength)); + float3 reflect_dir = reflect(-view_dir, refl_normal); +#else float3 reflect_dir = reflect(-view_dir, pbr.normal); +#endif UnityGIInput data; data.worldPos = f.worldPos; @@ -349,7 +356,7 @@ YumLighting GetYumLighting(v2f i, f2f f, YumPbr pbr) { light.attenuation = getShadowAttenuation(i, f); float3 tangentNormal = mul(f.tbn, pbr.normal); - float3x3 tangentToWorld = float3x3(i.tangent, f.binormal, i.normal); + float3x3 tangentToWorld = float3x3(i.tangent.xyz, f.binormal, i.normal); // Use Bakery-aware irradiance function #if defined(LIGHTMAP_ON) diff --git a/yum_pbr.cginc b/yum_pbr.cginc index 6049b35..2b746d5 100644 --- a/yum_pbr.cginc +++ b/yum_pbr.cginc @@ -327,6 +327,10 @@ YumPbr GetYumPbr(v2f i, f2f f) { result.emission += glitter_albedo.rgb * glitter_albedo.a * _Glitter_Emission; #endif +#if defined(_ANISOTROPY) + result.binormal = normalize(cross(result.normal, i.tangent.xyz) * i.tangent.w); +#endif + return result; } |
