summaryrefslogtreecommitdiffstats
path: root/matcaps.cginc
blob: 78f2cce1b91ae8451a93565639395723cc926248 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
#ifndef __MATCAPS_INC
#define __MATCAPS_INC

#include "features.cginc"
#include "globals.cginc"
#include "interpolators.cginc"
#include "yum_pbr.cginc"

#if defined(_MATCAP0) || defined(_RIM_LIGHTING0)
float2 getMatcapUV(v2f i, inout YumPbr 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.xyz, 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 applyMatcap(inout YumPbr pbr, float3 sample, uint mode, float mask)
{
  [forcecase]
  switch(mode) {
    case MATCAP_MODE_REPLACE:
      pbr.albedo.rgb = lerp(pbr.albedo.rgb, sample, mask);
      break;
    case MATCAP_MODE_ADD:
      pbr.albedo.rgb += lerp(0, sample, mask);
      break;
    case MATCAP_MODE_MULTIPLY:
      pbr.albedo.rgb *= lerp(1, sample, mask);
      break;
    case MATCAP_MODE_SUBTRACT:
      pbr.albedo.rgb -= lerp(0, sample, mask);
      break;
    case MATCAP_MODE_ADD_PRODUCT:
      pbr.albedo.rgb += lerp(0, sample * pbr.albedo.rgb, mask);
      break;
    default:
      break;
  }
}
#endif

float getAngleAttenuation(float2 muv, float2 target_vector, float power) {
  muv = muv * 2 - 1;
  float NoL = dot(muv, target_vector);
  NoL =  halfLambertianNoL(NoL);
  return pow(NoL, power);
}

void applyMatcapsAndRimLighting(v2f i, inout YumPbr pbr) {
#if defined(_MATCAP0) || defined(_RIM_LIGHTING0) || defined(_RIM_LIGHTING1)
  float2 muv = getMatcapUV(i, pbr);
#endif
#if defined(_MATCAP0)
  float3 m0 = _Matcap0.Sample(linear_repeat_s, muv);
  m0 = lerp(m0, 1 - m0, _Matcap0_Invert);
  m0 *= _Matcap0_Strength;
#if defined(_MATCAP0_MASK)
  float m0_mask = _Matcap0_Mask.Sample(linear_repeat_s, i.uv01.xy);
#else
  float m0_mask = 1;
#endif
  applyMatcap(pbr, m0, _Matcap0_Mode, m0_mask);
#endif
#if defined(_RIM_LIGHTING0) || defined(_RIM_LIGHTING1)
  float rl_radius = length(muv - 0.5);
#endif
#if defined(_RIM_LIGHTING0)
  float rl0_dist = exp2(-_Rim_Lighting0_Power * abs(rl_radius - _Rim_Lighting0_Center));
  float3 rl0 = _Rim_Lighting0_Color * _Rim_Lighting0_Brightness * rl0_dist;
#if defined(_RIM_LIGHTING0_MASK)
  float rl0_mask = _Rim_Lighting0_Mask.Sample(linear_repeat_s, i.uv01.xy);
#else
  float rl0_mask = 1;
#endif
#if defined(_RIM_LIGHTING0_ANGLE_LIMIT)
  rl0 *= getAngleAttenuation(muv, _Rim_Lighting0_Angle_Limit_Target_Vector,
      _Rim_Lighting0_Angle_Limit_Power);
#endif
#if defined(_RIM_LIGHTING0_QUANTIZATION)
  rl0 = floor(rl0 * _Rim_Lighting0_Quantization_Steps) / _Rim_Lighting0_Quantization_Steps;
#endif
  applyMatcap(pbr, rl0, _Rim_Lighting0_Mode, rl0_mask);
#endif
#if defined(_RIM_LIGHTING1)
  float rl1_dist = exp2(-_Rim_Lighting1_Power * abs(rl_radius - _Rim_Lighting1_Center));
  float3 rl1 = _Rim_Lighting1_Color * _Rim_Lighting1_Brightness * rl1_dist;
#if defined(_RIM_LIGHTING1_MASK)
  float rl1_mask = _Rim_Lighting1_Mask.Sample(linear_repeat_s, i.uv01.xy);
#else
  float rl1_mask = 1;
#endif
#if defined(_RIM_LIGHTING1_ANGLE_LIMIT)
  rl1 *= getAngleAttenuation(muv, _Rim_Lighting1_Angle_Limit_Target_Vector,
      _Rim_Lighting1_Angle_Limit_Power);
#endif
#if defined(_RIM_LIGHTING1_QUANTIZATION)
  rl1 = floor(rl1 * _Rim_Lighting1_Quantization_Steps) / _Rim_Lighting1_Quantization_Steps;
#endif
  applyMatcap(pbr, rl1, _Rim_Lighting1_Mode, rl1_mask);
#endif
}

#endif