Assignment for RMIT Mixed Reality in 2020
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

318 lines
9.0 KiB

  1. #ifndef AVATAR_UTIL_CG_INCLUDED
  2. #define AVATAR_UTIL_CG_INCLUDED
  3. #include "UnityCG.cginc"
  4. #define SAMPLE_MODE_COLOR 0
  5. #define SAMPLE_MODE_TEXTURE 1
  6. #define SAMPLE_MODE_TEXTURE_SINGLE_CHANNEL 2
  7. #define SAMPLE_MODE_PARALLAX 3
  8. #define SAMPLE_MODE_RSRM 4
  9. #define MASK_TYPE_NONE 0
  10. #define MASK_TYPE_POSITIONAL 1
  11. #define MASK_TYPE_REFLECTION 2
  12. #define MASK_TYPE_FRESNEL 3
  13. #define MASK_TYPE_PULSE 4
  14. #define BLEND_MODE_ADD 0
  15. #define BLEND_MODE_MULTIPLY 1
  16. #ifdef LAYERS_1
  17. #define LAYER_COUNT 1
  18. #elif LAYERS_2
  19. #define LAYER_COUNT 2
  20. #elif LAYERS_3
  21. #define LAYER_COUNT 3
  22. #elif LAYERS_4
  23. #define LAYER_COUNT 4
  24. #elif LAYERS_5
  25. #define LAYER_COUNT 5
  26. #elif LAYERS_6
  27. #define LAYER_COUNT 6
  28. #elif LAYERS_7
  29. #define LAYER_COUNT 7
  30. #elif LAYERS_8
  31. #define LAYER_COUNT 8
  32. #endif
  33. #define DECLARE_LAYER_UNIFORMS(index) \
  34. int _LayerSampleMode##index; \
  35. int _LayerBlendMode##index; \
  36. int _LayerMaskType##index; \
  37. fixed4 _LayerColor##index; \
  38. sampler2D _LayerSurface##index; \
  39. float4 _LayerSurface##index##_ST; \
  40. float4 _LayerSampleParameters##index; \
  41. float4 _LayerMaskParameters##index; \
  42. float4 _LayerMaskAxis##index;
  43. DECLARE_LAYER_UNIFORMS(0)
  44. DECLARE_LAYER_UNIFORMS(1)
  45. DECLARE_LAYER_UNIFORMS(2)
  46. DECLARE_LAYER_UNIFORMS(3)
  47. DECLARE_LAYER_UNIFORMS(4)
  48. DECLARE_LAYER_UNIFORMS(5)
  49. DECLARE_LAYER_UNIFORMS(6)
  50. DECLARE_LAYER_UNIFORMS(7)
  51. struct VertexOutput
  52. {
  53. float4 pos : SV_POSITION;
  54. float2 texcoord : TEXCOORD0;
  55. float3 worldPos : TEXCOORD1;
  56. float3 worldNormal : TEXCOORD2;
  57. float3 viewDir : TEXCOORD3;
  58. float4 vertColor : COLOR;
  59. #if NORMAL_MAP_ON || PARALLAX_ON
  60. float3 worldTangent : TANGENT;
  61. float3 worldBitangent : TEXCOORD5;
  62. #endif
  63. };
  64. float _Alpha;
  65. int _BaseMaskType;
  66. float4 _BaseMaskParameters;
  67. float4 _BaseMaskAxis;
  68. fixed4 _DarkMultiplier;
  69. fixed4 _BaseColor;
  70. sampler2D _AlphaMask;
  71. float4 _AlphaMask_ST;
  72. sampler2D _AlphaMask2;
  73. float4 _AlphaMask2_ST;
  74. sampler2D _NormalMap;
  75. float4 _NormalMap_ST;
  76. sampler2D _ParallaxMap;
  77. float4 _ParallaxMap_ST;
  78. sampler2D _RoughnessMap;
  79. float4 _RoughnessMap_ST;
  80. float4x4 _ProjectorWorldToLocal;
  81. VertexOutput vert(appdata_full v)
  82. {
  83. VertexOutput o;
  84. UNITY_INITIALIZE_OUTPUT(VertexOutput, o);
  85. o.texcoord = v.texcoord.xy;
  86. o.worldPos = mul(unity_ObjectToWorld, v.vertex);
  87. o.vertColor = v.color;
  88. o.viewDir = normalize(_WorldSpaceCameraPos.xyz - o.worldPos);
  89. o.worldNormal = normalize(mul(unity_ObjectToWorld, float4(v.normal, 0.0)).xyz);
  90. #if NORMAL_MAP_ON || PARALLAX_ON
  91. o.worldTangent = normalize(mul(unity_ObjectToWorld, float4(v.tangent.xyz, 0.0)).xyz);
  92. o.worldBitangent = normalize(cross(o.worldNormal, o.worldTangent) * v.tangent.w);
  93. #endif
  94. o.pos = UnityObjectToClipPos(v.vertex);
  95. return o;
  96. }
  97. #ifndef NORMAL_MAP_ON
  98. #define COMPUTE_NORMAL IN.worldNormal
  99. #else
  100. #define COMPUTE_NORMAL normalize(mul(lerp(float3(0, 0, 1), surfaceNormal, normalMapStrength), tangentTransform))
  101. #endif
  102. float3 ComputeColor(
  103. VertexOutput IN,
  104. float2 uv,
  105. #if PARALLAX_ON || NORMAL_MAP_ON
  106. float3x3 tangentTransform,
  107. #endif
  108. #ifdef NORMAL_MAP_ON
  109. float3 surfaceNormal,
  110. #endif
  111. sampler2D surface,
  112. float4 surface_ST,
  113. fixed4 color,
  114. int sampleMode,
  115. float4 sampleParameters
  116. ) {
  117. if (sampleMode == SAMPLE_MODE_TEXTURE) {
  118. float2 panning = _Time.g * sampleParameters.xy;
  119. return tex2D(surface, (uv + panning) * surface_ST.xy + surface_ST.zw).rgb * color.rgb;
  120. }
  121. else if (sampleMode == SAMPLE_MODE_TEXTURE_SINGLE_CHANNEL) {
  122. float4 channelMask = sampleParameters;
  123. float4 channels = tex2D(surface, uv * surface_ST.xy + surface_ST.zw);
  124. return dot(channels, channelMask) * color.rgb;
  125. }
  126. #ifdef PARALLAX_ON
  127. else if (sampleMode == SAMPLE_MODE_PARALLAX) {
  128. float parallaxMinHeight = sampleParameters.x;
  129. float parallaxMaxHeight = sampleParameters.y;
  130. float parallaxValue = tex2D(_ParallaxMap, TRANSFORM_TEX(uv, _ParallaxMap)).r;
  131. float scaledHeight = lerp(parallaxMinHeight, parallaxMaxHeight, parallaxValue);
  132. float2 parallaxUV = mul(tangentTransform, IN.viewDir).xy * scaledHeight;
  133. return tex2D(surface, (uv * surface_ST.xy + surface_ST.zw) + parallaxUV).rgb * color.rgb;
  134. }
  135. #endif
  136. else if (sampleMode == SAMPLE_MODE_RSRM) {
  137. float roughnessMin = sampleParameters.x;
  138. float roughnessMax = sampleParameters.y;
  139. #ifdef ROUGHNESS_ON
  140. float roughnessValue = tex2D(_RoughnessMap, TRANSFORM_TEX(uv, _RoughnessMap)).r;
  141. float scaledRoughness = lerp(roughnessMin, roughnessMax, roughnessValue);
  142. #else
  143. float scaledRoughness = roughnessMin;
  144. #endif
  145. #ifdef NORMAL_MAP_ON
  146. float normalMapStrength = sampleParameters.z;
  147. #endif
  148. float3 viewReflect = reflect(-IN.viewDir, COMPUTE_NORMAL);
  149. float viewAngle = viewReflect.y * 0.5 + 0.5;
  150. return tex2D(surface, float2(scaledRoughness, viewAngle)).rgb * color.rgb;
  151. }
  152. return color.rgb;
  153. }
  154. float ComputeMask(
  155. VertexOutput IN,
  156. #ifdef NORMAL_MAP_ON
  157. float3x3 tangentTransform,
  158. float3 surfaceNormal,
  159. #endif
  160. int maskType,
  161. float4 layerParameters,
  162. float3 maskAxis
  163. ) {
  164. if (maskType == MASK_TYPE_POSITIONAL) {
  165. float centerDistance = layerParameters.x;
  166. float fadeAbove = layerParameters.y;
  167. float fadeBelow = layerParameters.z;
  168. float3 objPos = mul(unity_WorldToObject, float4(IN.worldPos, 1.0)).xyz;
  169. float d = dot(objPos, maskAxis);
  170. if (d > centerDistance) {
  171. return saturate(1.0 - (d - centerDistance) / fadeAbove);
  172. }
  173. else {
  174. return saturate(1.0 - (centerDistance - d) / fadeBelow);
  175. }
  176. }
  177. else if (maskType == MASK_TYPE_REFLECTION) {
  178. float fadeStart = layerParameters.x;
  179. float fadeEnd = layerParameters.y;
  180. #ifdef NORMAL_MAP_ON
  181. float normalMapStrength = layerParameters.z;
  182. #endif
  183. float power = layerParameters.w;
  184. float3 viewReflect = reflect(-IN.viewDir, COMPUTE_NORMAL);
  185. float d = max(0.0, dot(viewReflect, maskAxis));
  186. return saturate(1.0 - (d - fadeStart) / (fadeEnd - fadeStart));
  187. }
  188. else if (maskType == MASK_TYPE_FRESNEL) {
  189. float power = layerParameters.x;
  190. float fadeStart = layerParameters.y;
  191. float fadeEnd = layerParameters.z;
  192. #ifdef NORMAL_MAP_ON
  193. float normalMapStrength = layerParameters.w;
  194. #endif
  195. float d = saturate(1.0 - max(0.0, dot(IN.viewDir, COMPUTE_NORMAL)));
  196. float p = pow(d, power);
  197. return saturate(lerp(fadeStart, fadeEnd, p));
  198. }
  199. else if (maskType == MASK_TYPE_PULSE) {
  200. float distance = layerParameters.x;
  201. float speed = layerParameters.y;
  202. float power = layerParameters.z;
  203. float3 objPos = mul(unity_WorldToObject, float4(IN.worldPos, 1.0)).xyz;
  204. float d = dot(objPos, maskAxis);
  205. float theta = 6.2831 * frac((d - _Time.g * speed) / distance);
  206. return saturate(pow((sin(theta) * 0.5 + 0.5), power));
  207. }
  208. else {
  209. return 1.0;
  210. }
  211. }
  212. float3 ComputeBlend(float3 source, float3 blend, float mask, int blendMode) {
  213. if (blendMode == BLEND_MODE_MULTIPLY) {
  214. return source * (blend * mask);
  215. }
  216. else {
  217. return source + (blend * mask);
  218. }
  219. }
  220. float4 ComputeSurface(VertexOutput IN)
  221. {
  222. #if PROJECTOR_ON
  223. float3 projectorPos = mul(_ProjectorWorldToLocal, float4(IN.worldPos, 1.0)).xyz;
  224. if (abs(projectorPos.x) > 1.0 || abs(projectorPos.y) > 1.0 || abs(projectorPos.z) > 1.0)
  225. {
  226. discard;
  227. }
  228. float2 uv = projectorPos.xy * 0.5 + 0.5;
  229. #else
  230. float2 uv = IN.texcoord.xy;
  231. #endif
  232. fixed4 c = _BaseColor;
  233. IN.worldNormal = normalize(IN.worldNormal);
  234. #if PARALLAX_ON || NORMAL_MAP_ON
  235. float3x3 tangentTransform = float3x3(IN.worldTangent, IN.worldBitangent, IN.worldNormal);
  236. #endif
  237. #ifdef NORMAL_MAP_ON
  238. float3 surfaceNormal = UnpackNormal(tex2D(_NormalMap, TRANSFORM_TEX(uv, _NormalMap)));
  239. #endif
  240. #if PARALLAX_ON || NORMAL_MAP_ON
  241. #ifndef NORMAL_MAP_ON
  242. #define COLOR_INPUTS IN, uv, tangentTransform
  243. #define MASK_INPUTS IN
  244. #else
  245. #define COLOR_INPUTS IN, uv, tangentTransform, surfaceNormal
  246. #define MASK_INPUTS IN, tangentTransform, surfaceNormal
  247. #endif
  248. #else
  249. #define COLOR_INPUTS IN, uv
  250. #define MASK_INPUTS IN
  251. #endif
  252. #define LAYER_COLOR(index) ComputeColor(COLOR_INPUTS, _LayerSurface##index, _LayerSurface##index##_ST, _LayerColor##index, _LayerSampleMode##index, _LayerSampleParameters##index)
  253. #define LAYER_MASK(index) ComputeMask(MASK_INPUTS, _LayerMaskType##index, _LayerMaskParameters##index, _LayerMaskAxis##index##.xyz)
  254. #define LAYER_BLEND(index, c) ComputeBlend(c, LAYER_COLOR(index), LAYER_MASK(index), _LayerBlendMode##index)
  255. c.rgb = LAYER_BLEND(0, c.rgb);
  256. #if LAYER_COUNT > 1
  257. c.rgb = LAYER_BLEND(1, c.rgb);
  258. #endif
  259. #if LAYER_COUNT > 2
  260. c.rgb = LAYER_BLEND(2, c.rgb);
  261. #endif
  262. #if LAYER_COUNT > 3
  263. c.rgb = LAYER_BLEND(3, c.rgb);
  264. #endif
  265. #if LAYER_COUNT > 4
  266. c.rgb = LAYER_BLEND(4, c.rgb);
  267. #endif
  268. #if LAYER_COUNT > 5
  269. c.rgb = LAYER_BLEND(5, c.rgb);
  270. #endif
  271. #if LAYER_COUNT > 6
  272. c.rgb = LAYER_BLEND(6, c.rgb);
  273. #endif
  274. #if LAYER_COUNT > 7
  275. c.rgb = LAYER_BLEND(7, c.rgb);
  276. #endif
  277. #ifdef VERTALPHA_ON
  278. float scaledValue = IN.vertColor.a * 2.0;
  279. float alpha0weight = max(0.0, 1.0 - scaledValue);
  280. float alpha2weight = max(0.0, scaledValue - 1.0);
  281. float alpha1weight = 1.0 - alpha0weight - alpha2weight;
  282. c.a = _Alpha * c.a * (tex2D(_AlphaMask, TRANSFORM_TEX(uv, _AlphaMask)).r * alpha1weight + tex2D(_AlphaMask2, TRANSFORM_TEX(uv, _AlphaMask2)).r * alpha2weight + alpha0weight) * ComputeMask(MASK_INPUTS, _BaseMaskType, _BaseMaskParameters, _BaseMaskAxis);
  283. #else
  284. c.a = _Alpha * c.a * tex2D(_AlphaMask, TRANSFORM_TEX(uv, _AlphaMask)).r * IN.vertColor.a * ComputeMask(MASK_INPUTS, _BaseMaskType, _BaseMaskParameters, _BaseMaskAxis);
  285. #endif
  286. c.rgb = lerp(c.rgb, c.rgb * _DarkMultiplier, IN.vertColor.r);
  287. return c;
  288. }
  289. #endif