diff options
| author | yum <yum.food.vr@gmail.com> | 2026-02-25 18:48:24 -0800 |
|---|---|---|
| committer | yum <yum.food.vr@gmail.com> | 2026-02-25 18:48:24 -0800 |
| commit | 0e0584159c47c0229e1ba2120dcc782c7250d09f (patch) | |
| tree | a8fd6b7eaf357ed76f072b4baf748f2cdb830400 /matcap.cginc | |
| parent | e299d8bbb242f6a2bb59d07f7dd1354eb018fedf (diff) | |
add matcap & rim lighting backend code
Diffstat (limited to 'matcap.cginc')
| -rw-r--r-- | matcap.cginc | 107 |
1 files changed, 107 insertions, 0 deletions
diff --git a/matcap.cginc b/matcap.cginc new file mode 100644 index 0000000..3b9fb15 --- /dev/null +++ b/matcap.cginc @@ -0,0 +1,107 @@ +#ifndef __MATCAPS_INC +#define __MATCAPS_INC + +#include "globals.cginc" +#include "lighting.cginc" +#include "pbr.cginc" +#include "texture_utils.cginc" + +#if defined(_MATCAP0) || defined(_RIM_LIGHTING0) +float2 getMatcapUV(v2f i, Pbr pbr) { + const float3 cam_normal = normalize(mul(UNITY_MATRIX_V, float4(pbr.normal, 0))); + const float3 cam_view_dir = normalize(mul(UNITY_MATRIX_V, float4(-i.eyeVec, 0))); + const float3 cam_refl = -reflect(cam_view_dir, cam_normal); + float m = 2.0 * sqrt( + cam_refl.x * cam_refl.x + + cam_refl.y * cam_refl.y + + (cam_refl.z + 1) * (cam_refl.z + 1)); + return cam_refl.xy / m + 0.5; +} + +void applyMatcapImpl(inout float3 color, float3 sample, uint mode, float mask) +{ + [forcecase] + switch(mode) { + case MATCAP_MODE_REPLACE: + color.rgb = lerp(color.rgb, sample, mask); + break; + case MATCAP_MODE_ADD: + color.rgb += lerp(0, sample, mask); + break; + case MATCAP_MODE_MULTIPLY: + color.rgb *= lerp(1, sample, mask); + break; + case MATCAP_MODE_SUBTRACT: + color.rgb -= lerp(0, sample, mask); + break; + case MATCAP_MODE_ADD_PRODUCT: + color.rgb += lerp(0, sample * color.rgb, mask); + break; + default: + break; + } +} + +void applyMatcap(inout Pbr pbr, float3 sample, uint mode, float mask) +{ + applyMatcapImpl(pbr.albedo.rgb, sample, mode, mask); +} + +float2 quantizeMatcapUV(float2 muv, float muv_r, float steps) { + float muv_r_q = floor(muv_r * steps) / steps; + const float epsilon = 1e-4f; + return muv_r_q * (muv / max(epsilon, muv_r)); +} +#endif // _MATCAP0 || _RIM_LIGHTING0 + +void applyMatcapsAndRimLighting(v2f i, inout Pbr pbr, inout Lighting light_data) { +#if defined(_MATCAP0) || defined(_RIM_LIGHTING0) + float2 muv = getMatcapUV(i, pbr); + float2 muv_centered = muv * 2 - 1; + float muv_r = length(muv_centered); +#endif + +#if defined(_MATCAP0) +#if defined(_MATCAP0_QUANTIZATION) + float2 m0uv = quantizeMatcapUV(muv, muv_r, _Matcap0_Quantization_Steps); +#else + float2 m0uv = muv; +#endif + float3 m0 = _Matcap0.Sample(linear_repeat_s, m0uv); + m0 = _Matcap0_Invert ? 1 - m0 : m0; + m0 *= _Matcap0_Strength; +#if defined(_MATCAP0_MASK) + float m0_mask = _Matcap0_Mask.Sample(linear_repeat_s, UV_SCOFF(i, _Matcap0_Mask_ST, /*which_channel=*/0)); +#else + float m0_mask = 1; +#endif + applyMatcap(pbr, m0, _Matcap0_Mode, m0_mask); +#endif // _MATCAP0 + +#if defined(_RIM_LIGHTING0) + // 1 at rim center, 0 outside blur radius. + float rl0_inner = smoothstep( + _Rim_Lighting0_Center - _Rim_Lighting0_Blur, + _Rim_Lighting0_Center, + muv_r); + float rl0_outer = 1 - smoothstep( + _Rim_Lighting0_Center, + _Rim_Lighting0_Center + _Rim_Lighting0_Blur, + muv_r); + float rl0_dist = rl0_inner * rl0_outer; +#if defined(_RIM_LIGHTING0_QUANTIZATION) + rl0_dist = floor(rl0_dist * _Rim_Lighting0_Quantization_Steps) / _Rim_Lighting0_Quantization_Steps; +#endif + float3 rl0 = _Rim_Lighting0_Color * rl0_dist; +#if defined(_RIM_LIGHTING0_MASK) + float rl0_mask = _Rim_Lighting0_Mask.Sample(linear_repeat_s, UV_SCOFF(i, _Rim_Lighting0_Mask_ST, /*which_channel=*/0)); +#else + float rl0_mask = 1; +#endif + applyMatcap(pbr, rl0, _Rim_Lighting0_Mode, rl0_mask); +#endif // _RIM_LIGHTING0 + +} + +#endif + |
