summaryrefslogtreecommitdiff
path: root/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes
diff options
context:
space:
mode:
Diffstat (limited to 'VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes')
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_FunctionsArtistic.cginc369
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_FunctionsArtistic.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiAlphaToCoverage.cginc32
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiAlphaToCoverage.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiAudioLink.cginc128
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiAudioLink.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBRDF.cginc254
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBRDF.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBackFace.cginc49
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBackFace.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBlackLight.cginc56
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBlackLight.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBlending.cginc385
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBlending.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBulge.cginc41
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBulge.cginc.meta8
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiClearCoat.cginc327
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiClearCoat.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiData.cginc260
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiData.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDebug.cginc107
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDebug.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDecal.cginc331
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDecal.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDefines.cginc7
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDefines.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDepthColor.cginc129
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDepthColor.cginc.meta8
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDissolve.cginc237
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDissolve.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDithering.cginc34
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDithering.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiEmission.cginc341
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiEmission.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiEnvironmentalRimLighting.cginc48
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiEnvironmentalRimLighting.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiFlipbook.cginc221
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiFlipbook.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiFrag.cginc422
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiFrag.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiGlitter.cginc274
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiGlitter.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiGrab.cginc125
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiGrab.cginc.meta8
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiHelpers.cginc336
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiHelpers.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiHologram.cginc44
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiHologram.cginc.meta8
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiIridescence.cginc104
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiIridescence.cginc.meta8
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiLighting.cginc981
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiLighting.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMSDF.cginc243
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMSDF.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMacros.cginc40
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMacros.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMainTex.cginc192
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMainTex.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMatcap.cginc160
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMatcap.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMath.cginc100
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMath.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMetal.cginc130
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMetal.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMirror.cginc81
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMirror.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiOutlineFrag.cginc117
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiOutlineFrag.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiOutlineVert.cginc144
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiOutlineVert.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPanosphere.cginc80
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPanosphere.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiParallax.cginc166
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiParallax.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPass.cginc252
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPass.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPassOutline.cginc34
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPassOutline.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPassShadow.cginc46
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPassShadow.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPathing.cginc150
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPathing.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPenetration.cginc214
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPenetration.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiRGBMask.cginc191
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiRGBMask.cginc.meta8
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiRandom.cginc41
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiRandom.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiRimLighting.cginc99
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiRimLighting.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiShadowFrag.cginc143
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiShadowFrag.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiShadowIncludes.cginc44
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiShadowIncludes.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiShadowVert.cginc86
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiShadowVert.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiSpawnInFrag.cginc58
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiSpawnInFrag.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiSpawnInVert.cginc40
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiSpawnInVert.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiSpecular.cginc505
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiSpecular.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiSubsurfaceScattering.cginc75
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiSubsurfaceScattering.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiTessellation.cginc117
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiTessellation.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiUVDistortion.cginc74
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiUVDistortion.cginc.meta8
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiV2F.cginc35
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiV2F.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiVert.cginc145
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiVert.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiVertexManipulations.cginc102
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiVertexManipulations.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiVideo.cginc297
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiVideo.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiVoronoi.cginc312
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiVoronoi.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiWireframe.cginc111
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiWireframe.cginc.meta8
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_Poicludes.cginc172
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_Poicludes.cginc.meta9
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/Notes.txt7
-rw-r--r--VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/Notes.txt.meta7
124 files changed, 10993 insertions, 0 deletions
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_FunctionsArtistic.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_FunctionsArtistic.cginc
new file mode 100644
index 00000000..8d98417c
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_FunctionsArtistic.cginc
@@ -0,0 +1,369 @@
+#ifndef POI_FUNCTIONS_ARTISTIC
+ #define POI_FUNCTIONS_ARTISTIC
+
+ // Based on unity shader graph code
+
+ // * Adjustments * //
+
+ /*
+ * Channel Mixer
+ *
+ * Controls the amount each of the channels of input In contribute to each of the channels of output Out. The slider
+ * parameters on the node control the contribution of each of the input channels. The toggle button parameters control
+ * which of the output channels is currently being edited. Slider controls for editing the contribution of each input
+ * channnel range between -2 and 2.
+ */
+ void poiChannelMixer(float3 In, float3 _ChannelMixer_Red, float3 _ChannelMixer_Green, float3 _ChannelMixer_Blue, out float3 Out)
+ {
+ Out = float3(dot(In, _ChannelMixer_Red), dot(In, _ChannelMixer_Green), dot(In, _ChannelMixer_Blue));
+ }
+
+ /*
+ * Contrast
+ *
+ * Adjusts the contrast of input In by the amount of input Contrast. A Contrast value of 1 will return the input
+ * unaltered. A Contrast value of 0 will return the midpoint of the input
+ */
+ void poiContrast(float3 In, float Contrast, out float3 Out)
+ {
+ float midpoint = pow(0.5, 2.2);
+ Out = (In - midpoint) * Contrast + midpoint;
+ }
+
+
+ /*
+ * Invert Colors
+ *
+ * Inverts the colors of input In on a per channel basis. This Node assumes all input values are in the range 0 - 1.
+ */
+ void poiInvertColors(float4 In, float4 InvertColors, out float4 Out)
+ {
+ Out = abs(InvertColors - In);
+ }
+
+ /*
+ * Replace Color
+ *
+ * Replaces values in input In equal to input From to the value of input To. Input Range can be used to define a
+ * wider range of values around input From to replace. Input Fuzziness can be used to soften the edges around the
+ * selection similar to anti-aliasing.
+ */
+ void poiReplaceColor(float3 In, float3 From, float3 To, float Range, float Fuzziness, out float3 Out)
+ {
+ float Distance = distance(From, In);
+ Out = lerp(To, In, saturate((Distance - Range) / max(Fuzziness, 0.00001)));
+ }
+
+ /*
+ * Saturation
+ *
+ * Adjusts the saturation of input In by the amount of input Saturation. A Saturation value of 1 will return the input
+ * unaltered. A Saturation value of 0 will return the input completely desaturated.
+ */
+ void poiSaturation(float3 In, float Saturation, out float3 Out)
+ {
+ float luma = dot(In, float3(0.2126729, 0.7151522, 0.0721750));
+ Out = luma.xxx + Saturation.xxx * (In - luma.xxx);
+ }
+
+ /*
+ * Dither Node
+ *
+ * Dither is an intentional form of noise used to randomize quantization error. It is used to prevent large-scale
+ * patterns such as color banding in images. The Dither node applies dithering in screen-space to ensure a uniform
+ * distribution of the pattern. This can be adjusted by connecting another node to input Screen Position.
+ *
+ * This Node is commonly used as an input to Alpha Clip Threshold on a Master Node to give the appearance of
+ * transparency to an opaque object. This is useful for creating objects that appear to be transparent but have
+ * the advantages of rendering as opaque, such as writing depth and/or being rendered in deferred.
+ */
+ void poiDither(float4 In, float4 ScreenPosition, out float4 Out)
+ {
+ float2 uv = ScreenPosition.xy * _ScreenParams.xy;
+ float DITHER_THRESHOLDS[16] = {
+ 1.0 / 17.0, 9.0 / 17.0, 3.0 / 17.0, 11.0 / 17.0,
+ 13.0 / 17.0, 5.0 / 17.0, 15.0 / 17.0, 7.0 / 17.0,
+ 4.0 / 17.0, 12.0 / 17.0, 2.0 / 17.0, 10.0 / 17.0,
+ 16.0 / 17.0, 8.0 / 17.0, 14.0 / 17.0, 6.0 / 17.0
+ };
+ uint index = (uint(uv.x) % 4) * 4 + uint(uv.y) % 4;
+ Out = In - DITHER_THRESHOLDS[index];
+ }
+
+ /*
+ * Color Mask
+ *
+ * Creates a mask from values in input In equal to input Mask Color. Input Range can be used to define a wider
+ * range of values around input Mask Color to create the mask. Colors within this range will return 1,
+ * otherwise the node will return 0. Input Fuzziness can be used to soften the edges around the selection
+ * similar to anti-aliasing.
+ */
+ void poiColorMask(float3 In, float3 MaskColor, float Range, float Fuzziness, out float4 Out)
+ {
+ float Distance = distance(MaskColor, In);
+ Out = saturate(1 - (Distance - Range) / max(Fuzziness, 0.00001));
+ }
+
+ float3 hueShift(float3 color, float Offset)
+ {
+ float4 K = float4(0.0, -1.0 / 3.0, 2.0 / 3.0, -1.0);
+ float4 P = lerp(float4(color.bg, K.wz), float4(color.gb, K.xy), step(color.b, color.g));
+ float4 Q = lerp(float4(P.xyw, color.r), float4(color.r, P.yzx), step(P.x, color.r));
+ float D = Q.x - min(Q.w, Q.y);
+ float E = 0.0000000001;
+ float3 hsv = float3(abs(Q.z + (Q.w - Q.y) / (6.0 * D + E)), D / (Q.x + E), Q.x);
+
+ float hue = hsv.x + Offset;
+ hsv.x = frac(hue);
+
+ float4 K2 = float4(1.0, 2.0 / 3.0, 1.0 / 3.0, 3.0);
+ float3 P2 = abs(frac(hsv.xxx + K2.xyz) * 6.0 - K2.www);
+ return hsv.z * lerp(K2.xxx, saturate(P2 - K2.xxx), hsv.y);
+ }
+
+ static const float Epsilon = 1e-10;
+ // The weights of RGB contributions to luminance.
+ // Should sum to unity.
+ static const float3 HCYwts = float3(0.299, 0.587, 0.114);
+ static const float HCLgamma = 3;
+ static const float HCLy0 = 100;
+ static const float HCLmaxL = 0.530454533953517; // == exp(HCLgamma / HCLy0) - 0.5
+ static const float3 wref = float3(1.0, 1.0, 1.0);
+ #define TAU 6.28318531
+
+ float3 HUEtoRGB(in float H)
+ {
+ float R = abs(H * 6 - 3) - 1;
+ float G = 2 - abs(H * 6 - 2);
+ float B = 2 - abs(H * 6 - 4);
+ return saturate(float3(R, G, B));
+ }
+
+ float3 RGBtoHCV(in float3 RGB)
+ {
+ // Based on work by Sam Hocevar and Emil Persson
+ float4 P = (RGB.g < RGB.b) ? float4(RGB.bg, -1.0, 2.0 / 3.0): float4(RGB.gb, 0.0, -1.0 / 3.0);
+ float4 Q = (RGB.r < P.x) ? float4(P.xyw, RGB.r): float4(RGB.r, P.yzx);
+ float C = Q.x - min(Q.w, Q.y);
+ float H = abs((Q.w - Q.y) / (6 * C + Epsilon) + Q.z);
+ return float3(H, C, Q.x);
+ }
+
+ float3 HSVtoRGB(in float3 HSV)
+ {
+ float3 RGB = HUEtoRGB(HSV.x);
+ return((RGB - 1) * HSV.y + 1) * HSV.z;
+ }
+
+ float3 RGBtoHSV(in float3 RGB)
+ {
+ float3 HCV = RGBtoHCV(RGB);
+ float S = HCV.y / (HCV.z + Epsilon);
+ return float3(HCV.x, S, HCV.z);
+ }
+
+ float3 HSLtoRGB(in float3 HSL)
+ {
+ float3 RGB = HUEtoRGB(HSL.x);
+ float C = (1 - abs(2 * HSL.z - 1)) * HSL.y;
+ return(RGB - 0.5) * C + HSL.z;
+ }
+
+ float3 RGBtoHSL(in float3 RGB)
+ {
+ float3 HCV = RGBtoHCV(RGB);
+ float L = HCV.z - HCV.y * 0.5;
+ float S = HCV.y / (1 - abs(L * 2 - 1) + Epsilon);
+ return float3(HCV.x, S, L);
+ }
+
+ float3 HCYtoRGB(in float3 HCY)
+ {
+
+
+ float3 RGB = HUEtoRGB(HCY.x);
+ float Z = dot(RGB, HCYwts);
+ if (HCY.z < Z)
+ {
+ HCY.y *= HCY.z / Z;
+ }
+ else if(Z < 1)
+ {
+ HCY.y *= (1 - HCY.z) / (1 - Z);
+ }
+ return(RGB - Z) * HCY.y + HCY.z;
+ }
+
+ float3 RGBtoHCY(in float3 RGB)
+ {
+ // Corrected by David Schaeffer
+ float3 HCV = RGBtoHCV(RGB);
+ float Y = dot(RGB, HCYwts);
+ float Z = dot(HUEtoRGB(HCV.x), HCYwts);
+ if (Y < Z)
+ {
+ HCV.y *= Z / (Epsilon + Y);
+ }
+ else
+ {
+ HCV.y *= (1 - Z) / (Epsilon + 1 - Y);
+ }
+ return float3(HCV.x, HCV.y, Y);
+ }
+
+ float3 HCLtoRGB(in float3 HCL)
+ {
+ float3 RGB = 0;
+ if(HCL.z != 0)
+ {
+ float H = HCL.x;
+ float C = HCL.y;
+ float L = HCL.z * HCLmaxL;
+ float Q = exp((1 - C / (2 * L)) * (HCLgamma / HCLy0));
+ float U = (2 * L - C) / (2 * Q - 1);
+ float V = C / Q;
+ float A = (H + min(frac(2 * H) / 4, frac(-2 * H) / 8)) * pi * 2;
+ float T;
+ H *= 6;
+ if(H <= 0.999)
+ {
+ T = tan(A);
+ RGB.r = 1;
+ RGB.g = T / (1 + T);
+ }
+ else if(H <= 1.001)
+ {
+ RGB.r = 1;
+ RGB.g = 1;
+ }
+ else if(H <= 2)
+ {
+ T = tan(A);
+ RGB.r = (1 + T) / T;
+ RGB.g = 1;
+ }
+ else if(H <= 3)
+ {
+ T = tan(A);
+ RGB.g = 1;
+ RGB.b = 1 + T;
+ }
+ else if(H <= 3.999)
+ {
+ T = tan(A);
+ RGB.g = 1 / (1 + T);
+ RGB.b = 1;
+ }
+ else if(H <= 4.001)
+ {
+ RGB.g = 0;
+ RGB.b = 1;
+ }
+ else if(H <= 5)
+ {
+ T = tan(A);
+ RGB.r = -1 / T;
+ RGB.b = 1;
+ }
+ else
+ {
+ T = tan(A);
+ RGB.r = 1;
+ RGB.b = -T;
+ }
+ RGB = RGB * V + U;
+ }
+ return RGB;
+ }
+
+ float3 RGBtoHCL(in float3 RGB)
+ {
+ float3 HCL;
+ float H = 0;
+ float U = min(RGB.r, min(RGB.g, RGB.b));
+ float V = max(RGB.r, max(RGB.g, RGB.b));
+ float Q = HCLgamma / HCLy0;
+ HCL.y = V - U;
+ if(HCL.y != 0)
+ {
+ H = atan2(RGB.g - RGB.b, RGB.r - RGB.g) / pi;
+ Q *= U / V;
+ }
+ Q = exp(Q);
+ HCL.x = frac(H / 2 - min(frac(H), frac(-H)) / 6);
+ HCL.y *= Q;
+ HCL.z = lerp(-U, V, Q) / (HCLmaxL * 2);
+ return HCL;
+ }
+
+ //HSL MODIFT
+ float3 ModifyViaHSL(float3 color, float3 HSLMod)
+ {
+ float3 colorHSL = RGBtoHSL(color);
+ colorHSL.r = frac(colorHSL.r + HSLMod.r);
+ colorHSL.g = saturate(colorHSL.g + HSLMod.g);
+ colorHSL.b = saturate(colorHSL.b + HSLMod.b);
+ return HSLtoRGB(colorHSL);
+ }
+
+ float3 poiSaturation(float3 In, float Saturation)
+ {
+ float luma = dot(In, float3(0.2126729, 0.7151522, 0.0721750));
+ return luma.xxx + Saturation.xxx * (In - luma.xxx);
+ }
+ // LCH
+ float xyzF(float t)
+ {
+ return lerp(pow(t, 1. / 3.), 7.787037 * t + 0.139731, step(t, 0.00885645));
+ }
+ float xyzR(float t)
+ {
+ return lerp(t * t * t, 0.1284185 * (t - 0.139731), step(t, 0.20689655));
+ }
+ float3 rgb2lch(in float3 c)
+ {
+ c = mul(float3x3(0.4124, 0.3576, 0.1805,
+ 0.2126, 0.7152, 0.0722,
+ 0.0193, 0.1192, 0.9505), c);
+ c.x = xyzF(c.x / wref.x);
+ c.y = xyzF(c.y / wref.y);
+ c.z = xyzF(c.z / wref.z);
+ float3 lab = float3(max(0., 116.0 * c.y - 16.0), 500.0 * (c.x - c.y), 200.0 * (c.y - c.z));
+ return float3(lab.x, length(float2(lab.y, lab.z)), atan2(lab.z, lab.y));
+ }
+
+ float3 lch2rgb(in float3 c)
+ {
+ c = float3(c.x, cos(c.z) * c.y, sin(c.z) * c.y);
+
+ float lg = 1. / 116. * (c.x + 16.);
+ float3 xyz = float3(wref.x * xyzR(lg + 0.002 * c.y),
+ wref.y * xyzR(lg),
+ wref.z * xyzR(lg - 0.005 * c.z));
+
+ float3 rgb = mul(float3x3(3.2406, -1.5372, -0.4986,
+ - 0.9689, 1.8758, 0.0415,
+ 0.0557, -0.2040, 1.0570), xyz);
+
+ return rgb;
+ }
+
+ //cheaply lerp around a circle
+ float lerpAng(in float a, in float b, in float x)
+ {
+ float ang = fmod(fmod((a - b), TAU) + pi * 3., TAU) - pi;
+ return ang * x + b;
+ }
+
+ //Linear interpolation between two colors in Lch space
+ float3 lerpLch(in float3 a, in float3 b, in float x)
+ {
+ float hue = lerpAng(a.z, b.z, x);
+ return float3(lerp(b.xy, a.xy, x), hue);
+ }
+
+ float3 poiExpensiveColorBlend(float3 col1, float3 col2, float alpha)
+ {
+ return lch2rgb(lerpLch(rgb2lch(col1), rgb2lch(col2), alpha));
+ }
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_FunctionsArtistic.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_FunctionsArtistic.cginc.meta
new file mode 100644
index 00000000..cfdb6a63
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_FunctionsArtistic.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 2e376fd109ce87a41b889d93e88c6639
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiAlphaToCoverage.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiAlphaToCoverage.cginc
new file mode 100644
index 00000000..3abae393
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiAlphaToCoverage.cginc
@@ -0,0 +1,32 @@
+#ifndef POI_ALPHA_TO_COVERAGE
+ #define POI_ALPHA_TO_COVERAGE
+
+ half _MainMipScale;
+ float _MainAlphaToCoverage;
+
+ float CalcMipLevel(float2 texture_coord)
+ {
+ float2 dx = ddx(texture_coord);
+ float2 dy = ddy(texture_coord);
+ float delta_max_sqr = max(dot(dx, dx), dot(dy, dy));
+
+ return 0.5 * log2(delta_max_sqr);
+ }
+
+ void ApplyAlphaToCoverage(inout float4 finalColor)
+ {
+ // Force Model Opacity to 1 if desired
+ UNITY_BRANCH
+ if (_Mode == 1)
+ {
+ UNITY_BRANCH
+ if(_MainAlphaToCoverage)
+ {
+ // rescale alpha by mip level
+ finalColor.a *= 1 + max(0, CalcMipLevel(poiMesh.uv[0] * _MainTex_TexelSize.zw)) * _MainMipScale;
+ // rescale alpha by partial derivative
+ finalColor.a = (finalColor.a - _Cutoff) / max(fwidth(finalColor.a), 0.0001) + _Cutoff;
+ }
+ }
+ }
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiAlphaToCoverage.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiAlphaToCoverage.cginc.meta
new file mode 100644
index 00000000..d513e5dd
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiAlphaToCoverage.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 89ff22574b0f92e49a4b10267d737637
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiAudioLink.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiAudioLink.cginc
new file mode 100644
index 00000000..ed847502
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiAudioLink.cginc
@@ -0,0 +1,128 @@
+#ifndef POI_AUDIOLINK
+#define POI_AUDIOLINK
+
+UNITY_DECLARE_TEX2D(_AudioTexture);
+float4 _AudioTexture_ST;
+fixed _AudioLinkDelay;
+fixed _AudioLinkAveraging;
+fixed _AudioLinkAverageRange;
+
+// Debug
+fixed _EnableAudioLinkDebug;
+fixed _AudioLinkDebugTreble;
+fixed _AudioLinkDebugHighMid;
+fixed _AudioLinkDebugLowMid;
+fixed _AudioLinkDebugBass;
+fixed _AudioLinkDebugAnimate;
+fixed _AudioLinkTextureVisualization;
+fixed _AudioLinkAnimToggle;
+
+void AudioTextureExists()
+{
+ half testw = 0;
+ half testh = 0;
+ _AudioTexture.GetDimensions(testw, testh);
+ poiMods.audioLinkTextureExists = testw >= 32;
+ poiMods.audioLinkTextureExists *= _AudioLinkAnimToggle;
+ switch(testw)
+ {
+ case 32: // V1
+ poiMods.audioLinkVersion = 1;
+ break;
+ case 128: // V2
+ poiMods.audioLinkVersion = 2;
+ break;
+ default:
+ poiMods.audioLinkVersion = 1;
+ break;
+ }
+}
+
+float getBandAtTime(float band, fixed time, fixed width)
+{
+ float versionUvMultiplier = 1;
+
+ if (poiMods.audioLinkVersion == 2)
+ {
+ versionUvMultiplier = 0.0625;
+ }
+ return UNITY_SAMPLE_TEX2D(_AudioTexture, float2(time * width, (band * .25 + .125) * versionUvMultiplier)).r;
+}
+
+void initAudioBands()
+{
+ AudioTextureExists();
+
+ float versionUvMultiplier = 1;
+
+ if (poiMods.audioLinkVersion == 2)
+ {
+ versionUvMultiplier = 0.0625;
+ }
+
+ if (poiMods.audioLinkTextureExists)
+ {
+ poiMods.audioLink.x = UNITY_SAMPLE_TEX2D(_AudioTexture, float2(_AudioLinkDelay, .125 * versionUvMultiplier));
+ poiMods.audioLink.y = UNITY_SAMPLE_TEX2D(_AudioTexture, float2(_AudioLinkDelay, .375 * versionUvMultiplier));
+ poiMods.audioLink.z = UNITY_SAMPLE_TEX2D(_AudioTexture, float2(_AudioLinkDelay, .625 * versionUvMultiplier));
+ poiMods.audioLink.w = UNITY_SAMPLE_TEX2D(_AudioTexture, float2(_AudioLinkDelay, .875 * versionUvMultiplier));
+
+ UNITY_BRANCH
+ if (_AudioLinkAveraging)
+ {
+ float uv = saturate(_AudioLinkDelay + _AudioLinkAverageRange * .25);
+ poiMods.audioLink.x += UNITY_SAMPLE_TEX2D(_AudioTexture, float2(uv, .125 * versionUvMultiplier));
+ poiMods.audioLink.y += UNITY_SAMPLE_TEX2D(_AudioTexture, float2(uv, .375 * versionUvMultiplier));
+ poiMods.audioLink.z += UNITY_SAMPLE_TEX2D(_AudioTexture, float2(uv, .625 * versionUvMultiplier));
+ poiMods.audioLink.w += UNITY_SAMPLE_TEX2D(_AudioTexture, float2(uv, .875 * versionUvMultiplier));
+
+ uv = saturate(_AudioLinkDelay + _AudioLinkAverageRange * .5);
+ poiMods.audioLink.x += UNITY_SAMPLE_TEX2D(_AudioTexture, float2(uv, .125 * versionUvMultiplier));
+ poiMods.audioLink.y += UNITY_SAMPLE_TEX2D(_AudioTexture, float2(uv, .375 * versionUvMultiplier));
+ poiMods.audioLink.z += UNITY_SAMPLE_TEX2D(_AudioTexture, float2(uv, .625 * versionUvMultiplier));
+ poiMods.audioLink.w += UNITY_SAMPLE_TEX2D(_AudioTexture, float2(uv, .875 * versionUvMultiplier));
+
+ uv = saturate(_AudioLinkDelay + _AudioLinkAverageRange * .75);
+ poiMods.audioLink.x += UNITY_SAMPLE_TEX2D(_AudioTexture, float2(uv, .125 * versionUvMultiplier));
+ poiMods.audioLink.y += UNITY_SAMPLE_TEX2D(_AudioTexture, float2(uv, .375 * versionUvMultiplier));
+ poiMods.audioLink.z += UNITY_SAMPLE_TEX2D(_AudioTexture, float2(uv, .625 * versionUvMultiplier));
+ poiMods.audioLink.w += UNITY_SAMPLE_TEX2D(_AudioTexture, float2(uv, .875 * versionUvMultiplier));
+
+ uv = saturate(_AudioLinkDelay + _AudioLinkAverageRange);
+ poiMods.audioLink.x += UNITY_SAMPLE_TEX2D(_AudioTexture, float2(uv, .125 * versionUvMultiplier));
+ poiMods.audioLink.y += UNITY_SAMPLE_TEX2D(_AudioTexture, float2(uv, .375 * versionUvMultiplier));
+ poiMods.audioLink.z += UNITY_SAMPLE_TEX2D(_AudioTexture, float2(uv, .625 * versionUvMultiplier));
+ poiMods.audioLink.w += UNITY_SAMPLE_TEX2D(_AudioTexture, float2(uv, .875 * versionUvMultiplier));
+
+ poiMods.audioLink /= 5;
+ }
+ }
+
+ #ifndef OPTIMIZER_ENABLED
+ UNITY_BRANCH
+ if (_EnableAudioLinkDebug)
+ {
+ poiMods.audioLink.x = _AudioLinkDebugBass;
+ poiMods.audioLink.y = _AudioLinkDebugLowMid;
+ poiMods.audioLink.z = _AudioLinkDebugHighMid;
+ poiMods.audioLink.w = _AudioLinkDebugTreble;
+
+ if (_AudioLinkDebugAnimate)
+ {
+ poiMods.audioLink.x *= (sin(_Time.w * 3.1) + 1) * .5;
+ poiMods.audioLink.y *= (sin(_Time.w * 3.2) + 1) * .5;
+ poiMods.audioLink.z *= (sin(_Time.w * 3.3) + 1) * .5;
+ poiMods.audioLink.w *= (sin(_Time.w * 3) + 1) * .5;
+ }
+ poiMods.audioLinkTextureExists = 1;
+ }
+
+ UNITY_BRANCH
+ if (_AudioLinkTextureVisualization)
+ {
+ poiMods.audioLinkTexture = UNITY_SAMPLE_TEX2D(_AudioTexture, poiMesh.uv[0]);
+ }
+ #endif
+}
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiAudioLink.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiAudioLink.cginc.meta
new file mode 100644
index 00000000..426cf89c
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiAudioLink.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: b4f547d93a614ad4d86c09ba02a0ba8d
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBRDF.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBRDF.cginc
new file mode 100644
index 00000000..5dade8c0
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBRDF.cginc
@@ -0,0 +1,254 @@
+#ifndef POI_BRDF
+#define POI_BRDF
+
+/*
+* MIT License
+*
+* Copyright (c) 2020 Xiexe
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all
+* copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*/
+
+#if defined(PROP_BRDFMETALLICGLOSSMAP) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_BRDFMetallicGlossMap);
+#endif
+#if defined(PROP_BRDFSPECULARMAP) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_BRDFSpecularMap);
+#endif
+#if defined(PROP_BRDFMETALLICMAP) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_BRDFMetallicMap);
+#endif
+
+samplerCUBE _BRDFFallback;
+
+float _BRDFMetallic;
+float _BRDFGlossiness;
+float _BRDFReflectance;
+float _BRDFAnisotropy;
+float _BRDFReflectionsEnabled;
+float _BRDFSpecularEnabled;
+float _BRDFInvertGlossiness;
+float _BRDFForceFallback;
+float _BRDFMetallicSpecIgnoresBaseColor;
+
+bool DoesReflectionProbeExist()
+{
+ float4 envSample = UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0, poiCam.reflectionDir, UNITY_SPECCUBE_LOD_STEPS);
+ bool probeExists = !(unity_SpecCube0_HDR.a == 0 && envSample.a == 0);
+ return probeExists && !_BRDFForceFallback;
+}
+
+float getGeometricSpecularAA(float3 normal)
+{
+ float3 vNormalWsDdx = ddx(normal.xyz);
+ float3 vNormalWsDdy = ddy(normal.xyz);
+ float flGeometricRoughnessFactor = pow(saturate(max(dot(vNormalWsDdx.xyz, vNormalWsDdx.xyz), dot(vNormalWsDdy.xyz, vNormalWsDdy.xyz))), 0.333);
+ return max(0, flGeometricRoughnessFactor);
+}
+
+float3 getAnisotropicReflectionVector(float3 viewDir, float3 bitangent, float3 tangent, float3 normal, float roughness, float anisotropy)
+{
+ float3 anisotropicDirection = anisotropy >= 0.0 ? bitangent : tangent;
+ float3 anisotropicTangent = cross(anisotropicDirection, viewDir);
+ float3 anisotropicNormal = cross(anisotropicTangent, anisotropicDirection);
+ float bendFactor = abs(anisotropy) * saturate(5.0 * roughness);
+ float3 bentNormal = normalize(lerp(normal, anisotropicNormal, bendFactor));
+ return reflect(-viewDir, bentNormal);
+}
+
+float3 F_Schlick(float u, float3 f0)
+{
+ return f0 + (1.0 - f0) * pow(1.0 - u, 5.0);
+}
+
+float3 F_Schlick(const float3 f0, float f90, float VoH)
+{
+ // Schlick 1994, "An Inexpensive BRDF Model for Physically-Based Rendering"
+ float pow5 = 1.0 - VoH;
+ pow5 = pow5 * pow5 * pow5 * pow5 * pow5;
+ return f0 + (f90 - f0) * pow5;
+}
+
+float D_GGX(float NoH, float roughness)
+{
+ float a2 = roughness * roughness;
+ float f = (NoH * a2 - NoH) * NoH + 1.0;
+ return a2 / (UNITY_PI * f * f);
+}
+
+float V_SmithGGXCorrelated(float NoV, float NoL, float a)
+{
+ float a2 = a * a;
+ float GGXL = NoV * sqrt((-NoL * a2 + NoL) * NoL + a2);
+ float GGXV = NoL * sqrt((-NoV * a2 + NoV) * NoV + a2);
+ return 0.5 / (GGXV + GGXL);
+}
+
+float D_GGX_Anisotropic(float NoH, const float3 h, const float3 t, const float3 b, float at, float ab)
+{
+ 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 / UNITY_PI);
+}
+
+float3 getBoxProjection(float3 direction, float3 position, float4 cubemapPosition, float3 boxMin, float3 boxMax)
+{
+ // #if defined(UNITY_SPECCUBE_BOX_PROJECTION) // For some reason this doesn't work?
+ if (cubemapPosition.w > 0)
+ {
+ float3 factors = ((direction > 0 ? boxMax : boxMin) - position) / direction;
+ float scalar = min(min(factors.x, factors.y), factors.z);
+ direction = direction * scalar + (position - cubemapPosition.xyz);
+ }
+ // #endif
+ return direction;
+}
+
+float3 getDirectSpecular(float roughness, float ndh, float vdn, float ndl, float ldh, float3 f0, float3 halfVector, float3 tangent, float3 bitangent, float anisotropy)
+{
+ #if !defined(LIGHTMAP_ON)
+ float rough = max(roughness * roughness, 0.0045);
+ float Dn = D_GGX(ndh, rough);
+ float3 F = F_Schlick(ldh, f0);
+ float V = V_SmithGGXCorrelated(vdn, ndl, rough);
+ float3 directSpecularNonAniso = max(0, (Dn * V) * F);
+
+ anisotropy *= saturate(5.0 * roughness);
+ float at = max(rough * (1.0 + anisotropy), 0.001);
+ float ab = max(rough * (1.0 - anisotropy), 0.001);
+ float D = D_GGX_Anisotropic(ndh, halfVector, tangent, bitangent, at, ab);
+ float3 directSpecularAniso = max(0, (D * V) * F);
+
+ return lerp(directSpecularNonAniso, directSpecularAniso, saturate(abs(_BRDFAnisotropy * 100))) * 3; // * 100 to prevent blending, blend because otherwise tangents are fucked on lightmapped object
+ #else
+ return 0;
+ #endif
+}
+
+float3 getIndirectSpecular(float metallic, float roughness, float3 reflDir, float3 worldPos, float3 lightmap, float3 normal)
+{
+ float3 spec = float3(0, 0, 0);
+ #if defined(UNITY_PASS_FORWARDBASE)
+ float3 indirectSpecular;
+ Unity_GlossyEnvironmentData envData;
+ envData.roughness = roughness;
+ envData.reflUVW = getBoxProjection(
+ reflDir, worldPos,
+ unity_SpecCube0_ProbePosition,
+ unity_SpecCube0_BoxMin.xyz, unity_SpecCube0_BoxMax.xyz
+ );
+ float3 probe0 = Unity_GlossyEnvironment(UNITY_PASS_TEXCUBE(unity_SpecCube0), unity_SpecCube0_HDR, envData);
+ float interpolator = unity_SpecCube0_BoxMin.w;
+ UNITY_BRANCH
+ if (interpolator < 0.99999)
+ {
+ envData.reflUVW = getBoxProjection(
+ reflDir, worldPos,
+ unity_SpecCube1_ProbePosition,
+ unity_SpecCube1_BoxMin.xyz, unity_SpecCube1_BoxMax.xyz
+ );
+ float3 probe1 = Unity_GlossyEnvironment(UNITY_PASS_TEXCUBE_SAMPLER(unity_SpecCube1, unity_SpecCube0), unity_SpecCube0_HDR, envData);
+ indirectSpecular = lerp(probe1, probe0, interpolator);
+ }
+ else
+ {
+ indirectSpecular = probe0;
+ }
+
+ if (!DoesReflectionProbeExist())
+ {
+ indirectSpecular = texCUBElod(_BRDFFallback, float4(reflDir, roughness * UNITY_SPECCUBE_LOD_STEPS)).rgb * poiLight.finalLighting;
+ }
+
+ float horizon = min(1 + dot(reflDir, normal), 1);
+ indirectSpecular *= horizon * horizon;
+
+ spec = indirectSpecular;
+ #if defined(LIGHTMAP_ON)
+ float specMultiplier = max(0, lerp(1, pow(length(lightmap), _SpecLMOcclusionAdjust), _SpecularLMOcclusion));
+ spec *= specMultiplier;
+ #endif
+ #endif
+ return spec;
+}
+
+void poiBRDF(inout float4 finalColor, const float4 finalColorBeforeLighting)
+{
+ float4 ret = float4(1, 0, 0, 1);
+ #if defined(PROP_BRDFMETALLICGLOSSMAP) || !defined(OPTIMIZER_ENABLED)
+ float4 metallicGlossMap = POI2D_SAMPLER_PAN(_BRDFMetallicGlossMap, _MainTex, poiMesh.uv[_BRDFMetallicGlossMapUV], _BRDFMetallicGlossMapPan);
+ #else
+ float4 metallicGlossMap = 1;
+ #endif
+ #if defined(PROP_BRDFSPECULARMAP) || !defined(OPTIMIZER_ENABLED)
+ float4 spcularTintMask = POI2D_SAMPLER_PAN(_BRDFSpecularMap, _MainTex, poiMesh.uv[_BRDFSpecularMapUV], _BRDFSpecularMapPan);
+ #else
+ float4 spcularTintMask = 1;
+ #endif
+ #if defined(PROP_BRDFMETALLICMAP) || !defined(OPTIMIZER_ENABLED)
+ float4 metallicTintMask = POI2D_SAMPLER_PAN(_BRDFMetallicMap, _MainTex, poiMesh.uv[_BRDFMetallicMapUV], _BRDFMetallicMapPan);
+ #else
+ float4 metallicTintMask = 1;
+ #endif
+ UNITY_BRANCH
+ if (_BRDFInvertGlossiness == 1)
+ {
+ metallicGlossMap.a = 1 - metallicGlossMap.a;
+ }
+
+ float metallic = metallicGlossMap.r * _BRDFMetallic;
+ float reflectance = metallicGlossMap.g * _BRDFReflectance;
+ float roughness = max(1 - (_BRDFGlossiness * metallicGlossMap.a), getGeometricSpecularAA(poiMesh.normals[1]));
+ finalColor.rgb *= lerp(1, 1 - metallic, _BRDFReflectionsEnabled);
+
+ float3 reflViewDir = getAnisotropicReflectionVector(poiCam.viewDir, poiMesh.binormal, poiMesh.tangent.xyz, poiMesh.normals[1], roughness, _BRDFAnisotropy);
+ float3 reflLightDir = reflect(poiLight.direction, poiMesh.normals[1]);
+
+ #if defined(FORWARD_BASE_PASS) || defined(POI_META_PASS)
+ float attenuation = poiMax(poiLight.rampedLightMap);
+ #endif
+ #ifdef FORWARD_ADD_PASS
+ float attenuation = saturate(poiLight.nDotL);
+ #endif
+
+
+ float3 f0 = 0.16 * reflectance * reflectance * (1.0 - metallic) + lerp(finalColorBeforeLighting.rgb * metallic, 1, _BRDFMetallicSpecIgnoresBaseColor);
+ float3 fresnel = lerp(F_Schlick(poiLight.nDotV, f0), f0, metallic); //Kill fresnel on metallics, it looks bad.
+ float3 directSpecular = getDirectSpecular(roughness, saturate(poiLight.nDotH), max(poiLight.nDotV, 0.000001), attenuation, saturate(poiLight.lDotH), f0, poiLight.halfDir, poiMesh.tangent.xyz, poiMesh.binormal, _BRDFAnisotropy) * poiLight.attenuation * attenuation * poiLight.color;
+ directSpecular = min(directSpecular, poiLight.color);
+
+ float3 vDirectSpecular = 0;
+ #ifdef VERTEXLIGHT_ON
+ for (int index = 0; index < 4; index++)
+ {
+ float3 v0directSpecular = getDirectSpecular(roughness, saturate(poiLight.vDotNH[index]), max(poiLight.nDotV, 0.000001), attenuation, saturate(poiLight.lDotH), f0, poiLight.vHalfDir[index], poiMesh.tangent, poiMesh.binormal, _BRDFAnisotropy) * poiLight.attenuation * poiLight.vAttenuationDotNL[index] * poiLight.vColor[index];
+ vDirectSpecular += min(v0directSpecular, poiLight.vColor[index]);
+ }
+ #endif
+
+ float3 indirectSpecular = getIndirectSpecular(metallic, roughness, reflViewDir, poiMesh.worldPos, /*directDiffuse*/ finalColor.rgb, poiMesh.normals[1]) * lerp(fresnel, f0, roughness);
+ float3 specular = indirectSpecular * _BRDFReflectionsEnabled * metallicTintMask.a * metallicTintMask.rgb * poiLight.occlusion + (directSpecular + vDirectSpecular) * _BRDFSpecularEnabled * spcularTintMask.a * spcularTintMask.rgb;
+ finalColor.rgb += specular;
+}
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBRDF.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBRDF.cginc.meta
new file mode 100644
index 00000000..709d8c6c
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBRDF.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 0543f339ffab97d418a5577bd4cd049c
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBackFace.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBackFace.cginc
new file mode 100644
index 00000000..57294263
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBackFace.cginc
@@ -0,0 +1,49 @@
+#ifndef POI_BACKFACE
+#define POI_BACKFACE
+
+float _BackFaceEnabled;
+float _BackFaceTextureUV;
+float _BackFaceDetailIntensity;
+float _BackFaceEmissionStrength;
+float2 _BackFacePanning;
+float _BackFaceHueShift;
+float4 _BackFaceColor;
+float _BackFaceReplaceAlpha;
+
+#if defined(PROP_BACKFACETEXTURE) || !defined(OPTIMIZER_ENABLED)
+ UNITY_DECLARE_TEX2D_NOSAMPLER(_BackFaceTexture); float4 _BackFaceTexture_ST;
+#endif
+
+float3 BackFaceColor;
+void applyBackFaceTexture(inout float backFaceDetailIntensity, inout float mixedHueShift, inout float4 albedo, inout float3 backFaceEmission)
+{
+ backFaceEmission = 0;
+ BackFaceColor = 0;
+ UNITY_BRANCH
+ if (_BackFaceEnabled)
+ {
+ if (!poiMesh.isFrontFace)
+ {
+ #if defined(PROP_BACKFACETEXTURE) || !defined(OPTIMIZER_ENABLED)
+ float4 backFaceTex = POI2D_SAMPLER_PAN(_BackFaceTexture, _MainTex, poiMesh.uv[_BackFaceTextureUV], _BackFacePanning) * _BackFaceColor;
+ #else
+ float4 backFaceTex = _BackFaceColor;
+ #endif
+
+ albedo.rgb = backFaceTex.rgb;
+
+ UNITY_BRANCH
+ if (_BackFaceReplaceAlpha)
+ {
+ albedo.a = backFaceTex.a;
+ }
+
+ backFaceDetailIntensity = _BackFaceDetailIntensity;
+ BackFaceColor = albedo.rgb;
+ mixedHueShift = _BackFaceHueShift;
+ backFaceEmission = BackFaceColor * _BackFaceEmissionStrength;
+ }
+ }
+}
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBackFace.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBackFace.cginc.meta
new file mode 100644
index 00000000..7e580bcc
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBackFace.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 9ee086be5141bcb458615f8ad9f54d79
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBlackLight.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBlackLight.cginc
new file mode 100644
index 00000000..0ae60087
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBlackLight.cginc
@@ -0,0 +1,56 @@
+#ifndef POI_BLACKLIGHT
+ #define POI_BLACKLIGHT
+
+ float4 _BlackLightMaskStart;
+ float4 _BlackLightMaskEnd;
+ float4 _BlackLightMaskKeys;
+ float _BlackLightMaskDebug;
+ float _BlackLightMaskDissolve;
+ float _BlackLightAdjustDissolve;
+ float _BlackLightMaskMetallic;
+ float _BlackLightMaskClearCoat;
+ float _BlackLightMaskMatcap;
+ float _BlackLightMaskMatcap2;
+ float _BlackLightMaskEmission;
+ float _BlackLightMaskEmission2;
+ float _BlackLightMaskFlipbook;
+ float _BlackLightMaskPanosphere;
+ float _BlackLightMaskIridescence;
+ float _BlackLightMove;
+
+ half _BlackLightMaskGlitter;
+
+ half4 blackLightMask;
+
+ void createBlackLightMask()
+ {
+ blackLightMask = 0;
+ #ifdef VERTEXLIGHT_ON
+
+ for (int lightIndex = 0; lightIndex < 4; lightIndex ++)
+ {
+ float3 lightPos = float3(unity_4LightPosX0[lightIndex], unity_4LightPosY0[lightIndex], unity_4LightPosZ0[lightIndex]);
+ if (!distance(unity_LightColor[lightIndex].rgb, float3(0, 0, 0)))
+ {
+ for (int maskIndex = 0; maskIndex < 4; maskIndex ++)
+ {
+ float4 comparison = _BlackLightMaskKeys;
+ if(unity_LightColor[lightIndex].a == comparison[maskIndex])
+ {
+ blackLightMask[maskIndex] = max(blackLightMask[maskIndex], smoothstep(_BlackLightMaskEnd[maskIndex], _BlackLightMaskStart[maskIndex], distance(poiMesh.worldPos, lightPos)));
+ }
+ }
+ }
+ }
+ #endif
+ }
+#endif
+
+/*
+#ifdef POI_BLACKLIGHT
+ if (_BlackLightMaskDissolve != 4)
+ {
+ blackLightMask[mask];
+ }
+#endif
+*/ \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBlackLight.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBlackLight.cginc.meta
new file mode 100644
index 00000000..bd162897
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBlackLight.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 49ee29e0fa0a33c48a51991dc965e8eb
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBlending.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBlending.cginc
new file mode 100644
index 00000000..1016ae12
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBlending.cginc
@@ -0,0 +1,385 @@
+#ifndef POI_BLENDING
+ #define POI_BLENDING
+
+ /*
+ 0: Zero float4(0.0, 0.0, 0.0, 0.0),
+ 1: One float4(1.0, 1.0, 1.0, 1.0),
+ 2: DstColor destinationColor,
+ 3: SrcColor sourceColor,
+ 4: OneMinusDstColor float4(1.0, 1.0, 1.0, 1.0) - destinationColor,
+ 5: SrcAlpha sourceColor.aaaa,
+ 6: OneMinusSrcColor float4(1.0, 1.0, 1.0, 1.0) - sourceColor,
+ 7: DstAlpha destinationColor.aaaa,
+ 8: OneMinusDstAlpha float4(1.0, 1.0, 1.0, 1.0) - destinationColor.,
+ 9: SrcAlphaSaturate saturate(sourceColor.aaaa),
+ 10: OneMinusSrcAlpha float4(1.0, 1.0, 1.0, 1.0) - sourceColor.aaaa,
+ */
+
+ float4 poiBlend(const float sourceFactor, const float4 sourceColor, const float destinationFactor, const float4 destinationColor, const float4 blendFactor)
+ {
+ float4 sA = 1 - blendFactor;
+ const float4 blendData[11] = {
+ float4(0.0, 0.0, 0.0, 0.0),
+ float4(1.0, 1.0, 1.0, 1.0),
+ destinationColor,
+ sourceColor,
+ float4(1.0, 1.0, 1.0, 1.0) - destinationColor,
+ sA,
+ float4(1.0, 1.0, 1.0, 1.0) - sourceColor,
+ sA,
+ float4(1.0, 1.0, 1.0, 1.0) - sA,
+ saturate(sourceColor.aaaa),
+ 1 - sA,
+ };
+
+ return lerp(blendData[sourceFactor] * sourceColor + blendData[destinationFactor] * destinationColor, sourceColor, sA);
+ }
+
+ // Average
+ float3 blendAverage(float3 base, float3 blend)
+ {
+ return(base + blend) / 2.0;
+ }
+
+ // Color burn
+ float blendColorBurn(float base, float blend)
+ {
+ return(blend == 0.0)?blend: max((1.0 - ((1.0 - base) / blend)), 0.0);
+ }
+
+ float3 blendColorBurn(float3 base, float3 blend)
+ {
+ return float3(blendColorBurn(base.r, blend.r), blendColorBurn(base.g, blend.g), blendColorBurn(base.b, blend.b));
+ }
+
+ // Color Dodge
+ float blendColorDodge(float base, float blend)
+ {
+ return(blend == 1.0)?blend: min(base / (1.0 - blend), 1.0);
+ }
+
+ float3 blendColorDodge(float3 base, float3 blend)
+ {
+ return float3(blendColorDodge(base.r, blend.r), blendColorDodge(base.g, blend.g), blendColorDodge(base.b, blend.b));
+ }
+
+ // Darken
+ float blendDarken(float base, float blend)
+ {
+ return min(blend, base);
+ }
+
+ float3 blendDarken(float3 base, float3 blend)
+ {
+ return float3(blendDarken(base.r, blend.r), blendDarken(base.g, blend.g), blendDarken(base.b, blend.b));
+ }
+
+ // Exclusion
+ float3 blendExclusion(float3 base, float3 blend)
+ {
+ return base + blend - 2.0 * base * blend;
+ }
+
+ // Reflect
+ float blendReflect(float base, float blend)
+ {
+ return(blend == 1.0)?blend: min(base * base / (1.0 - blend), 1.0);
+ }
+
+ float3 blendReflect(float3 base, float3 blend)
+ {
+ return float3(blendReflect(base.r, blend.r), blendReflect(base.g, blend.g), blendReflect(base.b, blend.b));
+ }
+
+ // Glow
+ float3 blendGlow(float3 base, float3 blend)
+ {
+ return blendReflect(blend, base);
+ }
+
+ // Overlay
+ float blendOverlay(float base, float blend)
+ {
+ return base < 0.5?(2.0 * base * blend): (1.0 - 2.0 * (1.0 - base) * (1.0 - blend));
+ }
+
+ float3 blendOverlay(float3 base, float3 blend)
+ {
+ return float3(blendOverlay(base.r, blend.r), blendOverlay(base.g, blend.g), blendOverlay(base.b, blend.b));
+ }
+
+ // Hard Light
+ float3 blendHardLight(float3 base, float3 blend)
+ {
+ return blendOverlay(blend, base);
+ }
+
+ // Vivid light
+ float blendVividLight(float base, float blend)
+ {
+ return(blend < 0.5)?blendColorBurn(base, (2.0 * blend)): blendColorDodge(base, (2.0 * (blend - 0.5)));
+ }
+
+ float3 blendVividLight(float3 base, float3 blend)
+ {
+ return float3(blendVividLight(base.r, blend.r), blendVividLight(base.g, blend.g), blendVividLight(base.b, blend.b));
+ }
+
+ // Hard mix
+ float blendHardMix(float base, float blend)
+ {
+ return(blendVividLight(base, blend) < 0.5)?0.0: 1.0;
+ }
+
+ float3 blendHardMix(float3 base, float3 blend)
+ {
+ return float3(blendHardMix(base.r, blend.r), blendHardMix(base.g, blend.g), blendHardMix(base.b, blend.b));
+ }
+
+ // Lighten
+ float blendLighten(float base, float blend)
+ {
+ return max(blend, base);
+ }
+
+ float3 blendLighten(float3 base, float3 blend)
+ {
+ return float3(blendLighten(base.r, blend.r), blendLighten(base.g, blend.g), blendLighten(base.b, blend.b));
+ }
+
+ // Linear Burn
+ float blendLinearBurn(float base, float blend)
+ {
+ // Note : Same implementation as BlendSubtractf
+ return max(base + blend - 1.0, 0.0);
+ }
+
+ float3 blendLinearBurn(float3 base, float3 blend)
+ {
+ // Note : Same implementation as BlendSubtract
+ return max(base + blend - float3(1.0, 1.0, 1.0), float3(0.0, 0.0, 0.0));
+ }
+
+ // Linear Dodge
+ float blendLinearDodge(float base, float blend)
+ {
+ // Note : Same implementation as BlendAddf
+ return min(base + blend, 1.0);
+ }
+
+ float3 blendLinearDodge(float3 base, float3 blend)
+ {
+ // Note : Same implementation as BlendAdd
+ return min(base + blend, float3(1.0, 1.0, 1.0));
+ }
+
+ // Linear light
+ float blendLinearLight(float base, float blend)
+ {
+ return blend < 0.5?blendLinearBurn(base, (2.0 * blend)): blendLinearDodge(base, (2.0 * (blend - 0.5)));
+ }
+
+ float3 blendLinearLight(float3 base, float3 blend)
+ {
+ return float3(blendLinearLight(base.r, blend.r), blendLinearLight(base.g, blend.g), blendLinearLight(base.b, blend.b));
+ }
+
+ // Multiply
+ float3 blendMultiply(float3 base, float3 blend)
+ {
+ return base * blend;
+ }
+
+ // Negation
+ float3 blendNegation(float3 base, float3 blend)
+ {
+ return float3(1.0, 1.0, 1.0) - abs(float3(1.0, 1.0, 1.0) - base - blend);
+ }
+
+ // Normal
+ float3 blendNormal(float3 base, float3 blend)
+ {
+ return blend;
+ }
+
+ // Phoenix
+ float3 blendPhoenix(float3 base, float3 blend)
+ {
+ return min(base, blend) - max(base, blend) + float3(1.0, 1.0, 1.0);
+ }
+
+ // Pin light
+ float blendPinLight(float base, float blend)
+ {
+ return(blend < 0.5)?blendDarken(base, (2.0 * blend)): blendLighten(base, (2.0 * (blend - 0.5)));
+ }
+
+ float3 blendPinLight(float3 base, float3 blend)
+ {
+ return float3(blendPinLight(base.r, blend.r), blendPinLight(base.g, blend.g), blendPinLight(base.b, blend.b));
+ }
+
+ // Screen
+ float blendScreen(float base, float blend)
+ {
+ return 1.0 - ((1.0 - base) * (1.0 - blend));
+ }
+
+ float3 blendScreen(float3 base, float3 blend)
+ {
+ return float3(blendScreen(base.r, blend.r), blendScreen(base.g, blend.g), blendScreen(base.b, blend.b));
+ }
+
+ // Soft Light
+ float blendSoftLight(float base, float blend)
+ {
+ return(blend < 0.5)?(2.0 * base * blend + base * base * (1.0 - 2.0 * blend)): (sqrt(base) * (2.0 * blend - 1.0) + 2.0 * base * (1.0 - blend));
+ }
+
+ float3 blendSoftLight(float3 base, float3 blend)
+ {
+ return float3(blendSoftLight(base.r, blend.r), blendSoftLight(base.g, blend.g), blendSoftLight(base.b, blend.b));
+ }
+
+ // Subtract
+ float blendSubtract(float base, float blend)
+ {
+ return max(base - blend, 0.0);
+ }
+
+ float3 blendSubtract(float3 base, float3 blend)
+ {
+ return max(base - blend, 0.0);
+ }
+
+ // Difference
+ float blendDifference(float base, float blend)
+ {
+ return abs(base - blend);
+ }
+
+ float3 blendDifference(float3 base, float3 blend)
+ {
+ return abs(base - blend);
+ }
+
+ // Divide
+ float blendDivide(float base, float blend)
+ {
+ return base / max(blend, 0.0001);
+ }
+
+ float3 blendDivide(float3 base, float3 blend)
+ {
+ return base / max(blend, 0.0001);
+ }
+
+ float3 customBlend(float3 base, float3 blend, float blendType)
+ {
+ float3 ret = 0;
+ switch(blendType)
+ {
+ case 0:
+ {
+ ret = blendNormal(base, blend);
+ break;
+ }
+ case 1:
+ {
+ ret = blendDarken(base, blend);
+ break;
+ }
+ case 2:
+ {
+ ret = blendMultiply(base, blend);
+ break;
+ }
+ case 3:
+ {
+ ret = blendColorBurn(base, blend);
+ break;
+ }
+ case 4:
+ {
+ ret = blendLinearBurn(base, blend);
+ break;
+ }
+ case 5:
+ {
+ ret = blendLighten(base, blend);
+ break;
+ }
+ case 6:
+ {
+ ret = blendScreen(base, blend);
+ break;
+ }
+ case 7:
+ {
+ ret = blendColorDodge(base, blend);
+ break;
+ }
+ case 8:
+ {
+ ret = blendLinearDodge(base, blend);
+ break;
+ }
+ case 9:
+ {
+ ret = blendOverlay(base, blend);
+ break;
+ }
+ case 10:
+ {
+ ret = blendSoftLight(base, blend);
+ break;
+ }
+ case 11:
+ {
+ ret = blendHardLight(base, blend);
+ break;
+ }
+ case 12:
+ {
+ ret = blendVividLight(base, blend);
+ break;
+ }
+ case 13:
+ {
+ ret = blendLinearLight(base, blend);
+ break;
+ }
+ case 14:
+ {
+ ret = blendPinLight(base, blend);
+ break;
+ }
+ case 15:
+ {
+ ret = blendHardMix(base, blend);
+ break;
+ }
+ case 16:
+ {
+ ret = blendDifference(base, blend);
+ break;
+ }
+ case 17:
+ {
+ ret = blendExclusion(base, blend);
+ break;
+ }
+ case 18:
+ {
+ ret = blendSubtract(base, blend);
+ break;
+ }
+ case 19:
+ {
+ ret = blendDivide(base, blend);
+ break;
+ }
+ }
+ return ret;
+ }
+#endif
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBlending.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBlending.cginc.meta
new file mode 100644
index 00000000..ab596bdf
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBlending.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 9f7b9815516b9bd45afc0657803fde91
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBulge.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBulge.cginc
new file mode 100644
index 00000000..09e44d6f
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBulge.cginc
@@ -0,0 +1,41 @@
+#ifndef POI_BULGE
+ #define POI_BULGE
+
+ float _BuldgeFadeLength;
+ float _BuldgeHeight;
+
+ #if defined(PROP_BULGEMASK) || !defined(OPTIMIZER_ENABLED)
+ sampler2D _BulgeMask;
+ #endif
+
+ void bulgyWolgy(inout v2f o)
+ {
+ float depth = DecodeFloatRG(tex2Dlod(_CameraDepthTexture, float4(o.grabPos.xy / o.grabPos.w, 0, 0)));
+ #if defined(PROP_BULGEMASK) || !defined(OPTIMIZER_ENABLED)
+ float bulgeMask = tex2Dlod(_BulgeMask, float4(o.uv0.xy, 0, 0));
+ #else
+ float bulgeMask = 1.0;
+ #endif
+
+ depth = Linear01Depth(depth);
+
+ float intersect = 0;
+ if (depth != 1)
+ {
+ float diff = distance(depth, Linear01Depth(o.pos.z / o.pos.w));
+ if(diff > 0)
+ {
+ intersect = 1 - smoothstep(0, _ProjectionParams.w * _BuldgeFadeLength, diff);
+ }
+ }
+ float4 offset = intersect * _BuldgeHeight * float4(o.normal, 0);
+
+ offset = IsInMirror() ? 0: offset;
+ offset *= bulgeMask;
+
+ o.worldPos = mul(unity_ObjectToWorld, o.localPos) + offset;
+ o.localPos = mul(unity_WorldToObject, o.worldPos);
+ o.pos = UnityObjectToClipPos(o.localPos);
+ }
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBulge.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBulge.cginc.meta
new file mode 100644
index 00000000..bf1b19f9
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiBulge.cginc.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: c49023d4328abbe4dbce068a8f1ded2d
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiClearCoat.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiClearCoat.cginc
new file mode 100644
index 00000000..77f4954d
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiClearCoat.cginc
@@ -0,0 +1,327 @@
+#ifndef POI_CLEARCOAT
+#define POI_CLEARCOAT
+
+float _Clearcoat;
+float _ClearcoatGlossiness;
+float _ClearcoatAnisotropy;
+float _ClearcoatForceFallback;
+float _ClearcoatEnableReflections;
+float _ClearcoatEnableSpecular;
+float _ClearcoatInvertSmoothness;
+#if defined(PROP_CLEARCOATMAP) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_ClearcoatMap);
+#endif
+
+samplerCUBE _ClearcoatFallback;
+/*
+samplerCUBE _ClearCoatCubeMap;
+float _ClearCoatSampleWorld;
+float _ClearcoatInvertSmoothness;
+float _Clearcoat;
+float3 _ClearCoatTint;
+float _ClearCoatNormalToUse;
+float _ClearCoatForceLighting;
+float lighty_clear_boy_uwu_var;
+
+#if defined(PROP_CLEARCOATSMOOTHNESSMAP) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_ClearCoatSmoothnessMap);
+#endif
+
+float3 CalculateClearCoatEnvironmentalReflections()
+{
+ float3 reflectionColor;
+
+ #if defined(PROP_CLEARCOATSMOOTHNESSMAP) || !defined(OPTIMIZER_ENABLED)
+ float smoothnessMap = (POI2D_SAMPLER_PAN(_ClearCoatSmoothnessMap, _MainTex, poiMesh.uv[_ClearCoatSmoothnessMapUV], _ClearCoatSmoothnessMapPan));
+ #else
+ float smoothnessMap = 1.0;
+ #endif
+
+ if (_ClearcoatInvertSmoothness == 1)
+ {
+ smoothnessMap = 1 - smoothnessMap;
+ }
+ smoothnessMap *= _ClearCoatSmoothness;
+ float roughness = 1 - smoothnessMap;
+
+ lighty_clear_boy_uwu_var = 0;
+
+ float3 reflectedDir = _ClearCoatNormalToUse == 0 ? poiCam.vertexReflectionDir: poiCam.reflectionDir;
+
+ float4 envSample = UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0, reflectedDir, roughness * UNITY_SPECCUBE_LOD_STEPS);
+ bool no_probe = unity_SpecCube0_HDR.a == 0 && envSample.a == 0;
+
+ UNITY_BRANCH
+ if(_ClearCoatSampleWorld == 0 && no_probe == 0)
+ {
+
+ Unity_GlossyEnvironmentData envData;
+ envData.roughness = roughness;
+ envData.reflUVW = BoxProjection(
+ reflectedDir, poiMesh.worldPos.xyz,
+ unity_SpecCube0_ProbePosition,
+ unity_SpecCube0_BoxMin, unity_SpecCube0_BoxMax
+ );
+ float3 probe0 = Unity_GlossyEnvironment(
+ UNITY_PASS_TEXCUBE(unity_SpecCube0), unity_SpecCube0_HDR, envData
+ );
+ envData.reflUVW = BoxProjection(
+ reflectedDir, poiMesh.worldPos.xyz,
+ unity_SpecCube1_ProbePosition,
+ unity_SpecCube1_BoxMin, unity_SpecCube1_BoxMax
+ );
+
+ float interpolator = unity_SpecCube0_BoxMin.w;
+ UNITY_BRANCH
+ if(interpolator < 0.99999)
+ {
+ float3 probe1 = Unity_GlossyEnvironment(
+ UNITY_PASS_TEXCUBE_SAMPLER(unity_SpecCube1, unity_SpecCube0),
+ unity_SpecCube0_HDR, envData
+ );
+ reflectionColor = lerp(probe1, probe0, interpolator);
+ }
+ else
+ {
+ reflectionColor = probe0;
+ }
+ }
+ else
+ {
+ lighty_clear_boy_uwu_var = 1;
+ reflectionColor = texCUBElod(_ClearCoatCubeMap, float4(reflectedDir, roughness * UNITY_SPECCUBE_LOD_STEPS));
+ }
+
+ if(_ClearCoatForceLighting)
+ {
+ lighty_clear_boy_uwu_var = 1;
+ }
+
+ return reflectionColor * _ClearCoatTint;
+}
+
+void calculateAndApplyClearCoat(inout float4 finalColor)
+{
+ #if defined(PROP_CLEARCOATMASK) || !defined(OPTIMIZER_ENABLED)
+ half clearCoatMap = POI2D_SAMPLER_PAN(_ClearcoatMap, _MainTex, poiMesh.uv[_ClearCoatMaskUV], _ClearCoatMaskPan);
+ #else
+ half clearCoatMap = 1;
+ #endif
+
+ #ifdef POI_BLACKLIGHT
+ if(_BlackLightMaskClearCoat != 4)
+ {
+ clearCoatMap *= blackLightMask[_BlackLightMaskClearCoat];
+ }
+ #endif
+
+ half3 reflectionColor = CalculateClearCoatEnvironmentalReflections();
+
+ float NormalDotView = abs(dot(_Clearcoat, _ClearCoatNormalToUse == 0 ? poiLight.N0DotV: poiLight.nDotV).r);
+ #ifdef POI_LIGHTING
+ finalColor.rgb = lerp(finalColor.rgb, reflectionColor * lerp(1, poiLight.finalLighting, lighty_clear_boy_uwu_var), clearCoatMap * _Clearcoat * clamp(FresnelTerm(_Clearcoat, NormalDotView), 0, 1));
+ //finalColor.rgb += reflectionColor;
+ //finalColor.rgb = finalColor.rgb * (1- (reflectionColor.r + reflectionColor.g + reflectionColor.b)/3) + reflectionColor * clearCoatMap * lerp(1, poiLight.finalLighting, lighty_clear_boy_uwu_var);
+ #else
+ finalColor.rgb = lerp(finalColor.rgb, reflectionColor, clearCoatMap * _Clearcoat * clamp(FresnelTerm(_Clearcoat, NormalDotView), 0, 1));
+ #endif
+}
+*/
+
+bool clearcoatDoesReflectionProbeExist()
+{
+ float4 envSample = UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0, poiCam.reflectionDir, UNITY_SPECCUBE_LOD_STEPS);
+ bool probeExists = !(unity_SpecCube0_HDR.a == 0 && envSample.a == 0);
+ return probeExists && !_ClearcoatForceFallback;
+}
+
+float3 clearcoatF_Schlick(float u, float3 f0)
+{
+ return f0 + (1.0 - f0) * pow(1.0 - u, 5.0);
+}
+
+float4 getClearcoatSmoothness(float4 clearcoatMap)
+{
+ float roughness = 1 - (_ClearcoatGlossiness * clearcoatMap.a);
+ roughness = clamp(roughness, 0.0045, 1.0);
+ roughness = roughness * roughness;
+
+ float reflectivity = _Clearcoat * clearcoatMap.r;
+ return float4(reflectivity, 0, 0, roughness);
+}
+
+float getGeometricClearCoatSpecularAA(float3 normal)
+{
+ float3 vNormalWsDdx = ddx(normal.xyz);
+ float3 vNormalWsDdy = ddy(normal.xyz);
+ float flGeometricRoughnessFactor = pow(saturate(max(dot(vNormalWsDdx.xyz, vNormalWsDdx.xyz), dot(vNormalWsDdy.xyz, vNormalWsDdy.xyz))), 0.333);
+ return max(0, flGeometricRoughnessFactor);
+}
+
+float3 getClearcoatAnisotropicReflectionVector(float3 viewDir, float3 bitangent, float3 tangent, float3 normal, float roughness, float anisotropy)
+{
+ //_Anisotropy = lerp(-0.2, 0.2, sin(_Time.y / 20)); //This is pretty fun
+ float3 anisotropicDirection = anisotropy >= 0.0 ? bitangent: tangent;
+ float3 anisotropicTangent = cross(anisotropicDirection, viewDir);
+ float3 anisotropicNormal = cross(anisotropicTangent, anisotropicDirection);
+ float bendFactor = abs(anisotropy) * saturate(5.0 * roughness);
+ float3 bentNormal = normalize(lerp(normal, anisotropicNormal, bendFactor));
+ return reflect(-viewDir, bentNormal);
+}
+
+float D_GGXClearcoat(float NoH, float roughness)
+{
+ float a2 = roughness * roughness;
+ float f = (NoH * a2 - NoH) * NoH + 1.0;
+ return a2 / (UNITY_PI * f * f);
+}
+
+float D_GGXClearcoat_Anisotropic(float NoH, const float3 h, const float3 t, const float3 b, float at, float ab)
+{
+ 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 / UNITY_PI);
+}
+
+float V_SmithGGXClearcoatCorrelated(float NoV, float NoL, float a)
+{
+ float a2 = a * a;
+ float GGXL = NoV * sqrt((-NoL * a2 + NoL) * NoL + a2);
+ float GGXV = NoL * sqrt((-NoV * a2 + NoV) * NoV + a2);
+ return 0.5 / (GGXV + GGXL);
+}
+
+float3 getClearcoatDirectSpecular(float roughness, float ndh, float vdn, float ndl, float ldh, float3 f0, float3 halfVector, float3 tangent, float3 bitangent, float anisotropy)
+{
+ #if !defined(LIGHTMAP_ON)
+ float rough = max(roughness * roughness, 0.0045);
+ float Dn = D_GGXClearcoat(ndh, rough);
+ float3 F = clearcoatF_Schlick(ldh, f0);
+ float V = V_SmithGGXClearcoatCorrelated(vdn, ndl, rough);
+ float3 directSpecularNonAniso = max(0, (Dn * V) * F);
+
+ anisotropy *= saturate(5.0 * roughness);
+ float at = max(rough * (1.0 + anisotropy), 0.001);
+ float ab = max(rough * (1.0 - anisotropy), 0.001);
+ float D = D_GGXClearcoat_Anisotropic(ndh, halfVector, tangent, bitangent, at, ab);
+ float3 directSpecularAniso = max(0, (D * V) * F);
+
+ return lerp(directSpecularNonAniso, directSpecularAniso, saturate(abs(_ClearcoatAnisotropy * 100))) * 3; // * 100 to prevent blending, blend because otherwise tangents are fucked on lightmapped object
+ #else
+ return 0;
+ #endif
+}
+
+float3 getClearCoatBoxProjection(float3 direction, float3 position, float4 cubemapPosition, float3 boxMin, float3 boxMax)
+{
+ // #if defined(UNITY_SPECCUBE_BOX_PROJECTION) // For some reason this doesn't work?
+ if (cubemapPosition.w > 0)
+ {
+ float3 factors = ((direction > 0 ? boxMax: boxMin) - position) / direction;
+ float scalar = min(min(factors.x, factors.y), factors.z);
+ direction = direction * scalar + (position - cubemapPosition.xyz);
+ }
+ // #endif
+ return direction;
+}
+
+float3 getClearcoatIndirectSpecular(float metallic, float roughness, float3 reflDir, float3 worldPos, float3 lightmap, float3 normal)
+{
+ float3 spec = float3(0, 0, 0);
+ #if defined(UNITY_PASS_FORWARDBASE)
+ float3 indirectSpecular;
+ Unity_GlossyEnvironmentData envData;
+ envData.roughness = roughness;
+ envData.reflUVW = getClearCoatBoxProjection(
+ reflDir, worldPos,
+ unity_SpecCube0_ProbePosition,
+ unity_SpecCube0_BoxMin.xyz, unity_SpecCube0_BoxMax.xyz
+ );
+ float3 probe0 = Unity_GlossyEnvironment(UNITY_PASS_TEXCUBE(unity_SpecCube0), unity_SpecCube0_HDR, envData);
+ float interpolator = unity_SpecCube0_BoxMin.w;
+ UNITY_BRANCH
+ if (interpolator < 0.99999)
+ {
+ envData.reflUVW = getClearCoatBoxProjection(
+ reflDir, worldPos,
+ unity_SpecCube1_ProbePosition,
+ unity_SpecCube1_BoxMin.xyz, unity_SpecCube1_BoxMax.xyz
+ );
+ float3 probe1 = Unity_GlossyEnvironment(UNITY_PASS_TEXCUBE_SAMPLER(unity_SpecCube1, unity_SpecCube0), unity_SpecCube0_HDR, envData);
+ indirectSpecular = lerp(probe1, probe0, interpolator);
+ }
+ else
+ {
+ indirectSpecular = probe0;
+ }
+
+ if (!clearcoatDoesReflectionProbeExist())
+ {
+ indirectSpecular = texCUBElod(_ClearcoatFallback, float4(envData.reflUVW, roughness * UNITY_SPECCUBE_LOD_STEPS)).rgb * poiLight.finalLighting;
+ }
+
+ float horizon = min(1 + dot(reflDir, normal), 1);
+ indirectSpecular *= horizon * horizon;
+
+ spec = indirectSpecular;
+ #if defined(LIGHTMAP_ON)
+ float specMultiplier = max(0, lerp(1, pow(length(lightmap), _SpecLMOcclusionAdjust), _SpecularLMOcclusion));
+ spec *= specMultiplier;
+ #endif
+ #endif
+ return spec;
+}
+
+void calculateAndApplyClearCoat(inout float4 finalColor)
+{
+ #if defined(PROP_CLEARCOATMAP) || !defined(OPTIMIZER_ENABLED)
+ float4 clearCoatMap = POI2D_SAMPLER_PAN(_ClearcoatMap, _MainTex, poiMesh.uv[_ClearcoatMapUV], _ClearcoatMapPan);
+ #else
+ float4 clearCoatMap = 1;
+ #endif
+
+ float4 clearcoatReflectivitySmoothness = getClearcoatSmoothness(clearCoatMap);
+ float clearcoatReflectivity = clearcoatReflectivitySmoothness.r;
+ float clearcoatRoughness = clearcoatReflectivitySmoothness.a;
+ UNITY_BRANCH
+ if (_ClearcoatInvertSmoothness)
+ {
+ clearcoatRoughness = 1 - clearcoatRoughness;
+ }
+ float3 creflViewDir = getClearcoatAnisotropicReflectionVector(poiCam.viewDir, poiMesh.binormal, poiMesh.tangent.xyz, poiMesh.normals[0], clearcoatRoughness, _ClearcoatAnisotropy);
+ float cndl = saturate(dot(poiLight.direction, poiMesh.normals[0]));
+ float cvdn = abs(dot(poiCam.viewDir, poiMesh.normals[0]));
+ float cndh = saturate(dot(poiMesh.normals[0], poiLight.halfDir));
+
+ float3 clearcoatf0 = 0.16 * clearcoatReflectivity * clearcoatReflectivity;
+ float3 clearcoatFresnel = clearcoatF_Schlick(cvdn, clearcoatf0);
+
+ #if defined(FORWARD_BASE_PASS) || defined(POI_META_PASS)
+ float attenuation = poiLight.rampedLightMap;
+ #endif
+ #ifdef FORWARD_ADD_PASS
+ float attenuation = saturate(poiLight.nDotL);
+ #endif
+
+ float3 vDirectSpecular = 0;
+ #ifdef VERTEXLIGHT_ON
+ for (int index = 0; index < 4; index++)
+ {
+ float vcndh = saturate(dot(poiMesh.normals[0], poiLight.vHalfDir[index]));
+ float vcndl = saturate(dot(poiLight.vDirection[index], poiMesh.normals[0]));
+ float3 v0directSpecular = getClearcoatDirectSpecular(clearcoatRoughness, vcndh, max(cvdn, 0.000001), vcndl, saturate(poiLight.vDotLH[index]), clearcoatf0, poiLight.halfDir, poiMesh.tangent, poiMesh.binormal, _ClearcoatAnisotropy) * poiLight.vAttenuation * vcndl * poiLight.vColor[index];
+ vDirectSpecular += v0directSpecular;
+ }
+ #endif
+
+ float3 clearcoatDirectSpecular = getClearcoatDirectSpecular(clearcoatRoughness, cndh, max(cvdn, 0.000001), attenuation, saturate(poiLight.lDotH), clearcoatf0, poiLight.halfDir, poiMesh.tangent, poiMesh.binormal, _ClearcoatAnisotropy) * poiLight.attenuation * attenuation * poiLight.color;
+ float3 clearcoatIndirectSpecular = getClearcoatIndirectSpecular(0, clearcoatRoughness, creflViewDir, poiMesh.worldPos, finalColor, poiMesh.normals[0]);
+ float3 clearcoat = ((clearcoatDirectSpecular + vDirectSpecular) * clearCoatMap.g * _ClearcoatEnableSpecular + clearcoatIndirectSpecular * clearCoatMap.b * _ClearcoatEnableReflections) * clearcoatReflectivity * clearcoatFresnel;
+ finalColor.rgb += clearcoat;
+}
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiClearCoat.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiClearCoat.cginc.meta
new file mode 100644
index 00000000..895de4d7
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiClearCoat.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 05e2de0df0c3a8147a1f7989db8ebd19
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiData.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiData.cginc
new file mode 100644
index 00000000..816c7a7c
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiData.cginc
@@ -0,0 +1,260 @@
+#ifndef POI_DATA
+#define POI_DATA
+
+float _ParallaxBias;
+float _LightingAdditiveLimitIntensity;
+float _LightingAdditiveMaxIntensity;
+POI_TEXTURE_NOSAMPLER(_BumpMap);
+#ifdef FINALPASS
+ #if defined(PROP_DETAILMASK) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_DetailMask);
+ #endif
+ #if defined(PROP_DETAILNORMALMAP) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_DetailNormalMap);
+ #endif
+ float _DetailNormalMapScale;
+#endif
+float _BumpScale;
+
+void calculateAttenuation(v2f i)
+{
+ #ifdef FORWARD_ADD_PASS
+ #if defined(POINT) || defined(SPOT)
+ POI_LIGHT_ATTENUATION(attenuation, shadow, i, i.worldPos.xyz)
+ poiLight.additiveShadow = shadow;
+ #else
+ UNITY_LIGHT_ATTENUATION(attenuation, i, i.worldPos.xyz)
+ poiLight.additiveShadow == 0;
+ #endif
+ #else
+ UNITY_LIGHT_ATTENUATION(attenuation, i, i.worldPos.xyz)
+ // fix for rare bug where light atten is 0 when there is no directional light in the scene
+ #ifdef FORWARD_BASE_PASS
+ if (all(_LightColor0.rgb == 0.0))
+ {
+ attenuation = 1.0;
+ }
+ #endif
+ #endif
+ poiLight.attenuation = attenuation;
+}
+
+void calculateVertexLightingData(in v2f i)
+{
+ #ifdef VERTEXLIGHT_ON
+ float4 toLightX = unity_4LightPosX0 - i.worldPos.x;
+ float4 toLightY = unity_4LightPosY0 - i.worldPos.y;
+ float4 toLightZ = unity_4LightPosZ0 - i.worldPos.z;
+ float4 lengthSq = 0;
+ lengthSq += toLightX * toLightX;
+ lengthSq += toLightY * toLightY;
+ lengthSq += toLightZ * toLightZ;
+
+ float4 lightAttenSq = unity_4LightAtten0;
+ float4 atten = 1.0 / (1.0 + lengthSq * lightAttenSq);
+ float4 vLightWeight = saturate(1 - (lengthSq * lightAttenSq / 25));
+ poiLight.vAttenuation = min(atten, vLightWeight * vLightWeight);
+
+ poiLight.vDotNL = 0;
+ poiLight.vDotNL += toLightX * poiMesh.normals[1].x;
+ poiLight.vDotNL += toLightY * poiMesh.normals[1].y;
+ poiLight.vDotNL += toLightZ * poiMesh.normals[1].z;
+
+ float4 corr = rsqrt(lengthSq);
+ poiLight.vDotNL = max(0, poiLight.vDotNL * corr);
+ poiLight.vAttenuationDotNL = poiLight.vAttenuation * poiLight.vDotNL;
+
+ for (int index = 0; index < 4; index++)
+ {
+ poiLight.vPosition[index] = float3(unity_4LightPosX0[index], unity_4LightPosY0[index], unity_4LightPosZ0[index]);
+
+ float3 vertexToLightSource = poiLight.vPosition[index] - poiMesh.worldPos;
+ poiLight.vDirection[index] = normalize(vertexToLightSource);
+ //poiLight.vAttenuationDotNL[index] = 1.0 / (1.0 + unity_4LightAtten0[index] * poiLight.vDotNL[index]);
+ poiLight.vColor[index] = unity_LightColor[index].rgb;
+ UNITY_BRANCH
+ if (_LightingAdditiveLimitIntensity == 1)
+ {
+ float intensity = max(0.001, (0.299 * poiLight.vColor[index].r + 0.587 * poiLight.vColor[index].g + 0.114 * poiLight.vColor[index].b));
+ poiLight.vColor[index] = min(poiLight.vColor[index], poiLight.vColor[index] / (intensity / _LightingAdditiveMaxIntensity));
+ }
+ poiLight.vHalfDir[index] = Unity_SafeNormalize(poiLight.vDirection[index] + poiCam.viewDir);
+ poiLight.vDotNL[index] = dot(poiMesh.normals[1], -poiLight.vDirection[index]);
+ poiLight.vCorrectedDotNL[index] = .5 * (poiLight.vDotNL[index] + 1);
+ poiLight.vDotLH[index] = saturate(dot(poiLight.vDirection[index], poiLight.vHalfDir[index]));
+
+ poiLight.vDotNH[index] = saturate(dot(poiMesh.normals[1], poiLight.vHalfDir[index]));
+ }
+ #endif
+}
+
+void calculateLightingData(in v2f i)
+{
+ poiLight.occlusion = 1;
+ #ifdef FORWARD_BASE_PASS
+ //poiLight.color = saturate(_LightColor0.rgb) + saturate(ShadeSH9(normalize(unity_SHAr + unity_SHAg + unity_SHAb)));
+ float3 magic = max(ShadeSH9(normalize(unity_SHAr + unity_SHAg + unity_SHAb)), 0);
+ float3 normalLight = _LightColor0.rgb;
+ poiLight.color = magic + normalLight;
+ #else
+ #ifdef FORWARD_ADD_PASS
+ poiLight.color = _LightColor0.rgb;
+
+ UNITY_BRANCH
+ if (_LightingAdditiveLimitIntensity == 1)
+ {
+ float additiveLightIntensity = max(0.001, (0.299 * poiLight.color.r + 0.587 * poiLight.color.g + 0.114 * poiLight.color.b));
+ poiLight.color = min(poiLight.color, poiLight.color / (additiveLightIntensity / _LightingAdditiveMaxIntensity));
+ }
+ #endif
+ #endif
+
+ #ifdef FORWARD_BASE_PASS
+ poiLight.direction = normalize(_WorldSpaceLightPos0.xyz + unity_SHAr.xyz + unity_SHAg.xyz + unity_SHAb.xyz);
+ #else
+ #if defined(POINT) || defined(SPOT)
+ poiLight.direction = normalize(_WorldSpaceLightPos0.xyz - i.worldPos.xyz);
+ #else
+ poiLight.direction = _WorldSpaceLightPos0.xyz;
+ #endif
+ #endif
+
+ poiLight.halfDir = normalize(poiLight.direction + poiCam.viewDir);
+
+ poiLight.dotNH = saturate(dot(poiMesh.normals[1], poiLight.halfDir));
+ poiLight.dotLH = saturate(dot(poiLight.direction, poiLight.halfDir));
+
+ poiLight.nDotV = dot(poiMesh.normals[1], poiCam.viewDir);
+ poiLight.N0DotV = dot(poiMesh.normals[0], poiCam.viewDir);
+ poiLight.nDotL = dot(poiMesh.normals[1], poiLight.direction);
+ poiLight.nDotH = dot(poiMesh.normals[1], poiLight.halfDir);
+ poiLight.lDotv = dot(poiLight.direction, poiCam.viewDir);
+ poiLight.lDotH = dot(poiLight.direction, poiLight.halfDir);
+}
+
+void initPoiMods()
+{
+ poiMods.audioLink = float4(0, 0, 0, 0);
+ poiMods.globalMasks = float4(0, 0, 0, 0);
+ #ifdef POI_AUDIOLINK
+ initAudioBands();
+ #endif
+}
+
+void InitializeMeshData(inout v2f i, uint facing)
+{
+ poiMesh.isFrontFace = facing;
+ poiMesh.normals[0] = i.normal;
+ poiMesh.binormal.rgb = i.binormal;
+ poiMesh.tangent = i.tangent;
+
+ #ifndef OUTLINE
+ if (!poiMesh.isFrontFace)
+ {
+ poiMesh.normals[0] *= -1;
+ poiMesh.tangent *= -1;
+ poiMesh.binormal *= -1;
+ }
+ #endif
+
+ poiMesh.worldPos = i.worldPos.xyz;
+ poiMesh.localPos = i.localPos.xyz;
+ poiMesh.barycentricCoordinates = i.barycentricCoordinates;
+ poiMesh.uv[0] = i.uv0.xy;
+ poiMesh.uv[1] = i.uv0.zw;
+ poiMesh.uv[2] = i.uv1.xy;
+ poiMesh.uv[3] = i.uv1.zw;
+
+ initPoiMods();
+
+ #ifdef POI_UV_DISTORTION
+ poiMesh.uv[4] = calculateDistortionUV(i.uv0.xy);
+ #else
+ poiMesh.uv[4] = poiMesh.uv[0];
+ #endif
+
+ poiMesh.vertexColor = i.vertexColor;
+ #if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)
+ poiMesh.lightmapUV = i.lightmapUV;
+ #endif
+ poiMesh.modelPos = i.modelPos;
+
+ #ifdef FUR
+ poiMesh.furAlpha = i.furAlpha;
+ #endif
+}
+
+void initializeCamera(v2f i)
+{
+ poiCam.viewDir = normalize(_WorldSpaceCameraPos - i.worldPos.xyz);
+ poiCam.forwardDir = getCameraForward();
+ poiCam.worldPos = _WorldSpaceCameraPos;
+ poiCam.distanceToModel = distance(poiMesh.modelPos, poiCam.worldPos);
+ poiCam.distanceToVert = distance(poiMesh.worldPos, poiCam.worldPos);
+ poiCam.grabPos = i.grabPos;
+ poiCam.screenUV = calcScreenUVs(i.grabPos);
+ poiCam.clipPos = i.pos;
+ #if defined(GRAIN)
+ poiCam.worldDirection = i.worldDirection;
+ #endif
+
+ poiCam.tangentViewDir = normalize(i.tangentViewDir);
+ poiCam.decalTangentViewDir = poiCam.tangentViewDir;
+ poiCam.tangentViewDir.xy /= (poiCam.tangentViewDir.z + _ParallaxBias);
+}
+
+void calculateTangentData()
+{
+ poiTData.tangentTransform = float3x3(poiMesh.tangent.xyz, poiMesh.binormal, poiMesh.normals[0]);
+ poiTData.tangentToWorld = transpose(float3x3(poiMesh.tangent.xyz, poiMesh.binormal, poiMesh.normals[0]));
+}
+
+void CalculateReflectionData()
+{
+ #if defined(_METALLICGLOSSMAP) || defined(_COLORCOLOR_ON)
+ poiCam.reflectionDir = reflect(-poiCam.viewDir, poiMesh.normals[1]);
+ poiCam.vertexReflectionDir = reflect(-poiCam.viewDir, poiMesh.normals[0]);
+ #endif
+}
+
+void calculateNormals(inout half3 detailMask)
+{
+ half3 mainNormal = UnpackScaleNormal(POI2D_SAMPLER_PAN(_BumpMap, _MainTex, poiMesh.uv[_BumpMapUV], _BumpMapPan), _BumpScale);
+
+ #ifdef FINALPASS
+ #if defined(PROP_DETAILMASK) || !defined(OPTIMIZER_ENABLED)
+ detailMask = POI2D_SAMPLER_PAN(_DetailMask, _MainTex, poiMesh.uv[_DetailMaskUV], _DetailMaskPan).rgb;
+ #else
+ detailMask = 1;
+ #endif
+ UNITY_BRANCH
+ if (_DetailNormalMapScale > 0)
+ {
+ #if defined(PROP_DETAILNORMALMAP) || !defined(OPTIMIZER_ENABLED)
+ half3 detailNormal = UnpackScaleNormal(POI2D_SAMPLER_PAN(_DetailNormalMap, _MainTex, poiMesh.uv[_DetailNormalMapUV], _DetailNormalMapPan), _DetailNormalMapScale * detailMask.g);
+ poiMesh.tangentSpaceNormal = BlendNormals(mainNormal, detailNormal);
+ #else
+ poiMesh.tangentSpaceNormal = mainNormal;
+ #endif
+ }
+ else
+ {
+ poiMesh.tangentSpaceNormal = mainNormal;
+ }
+ #else
+ poiMesh.tangentSpaceNormal = mainNormal;
+ #endif
+
+ #ifdef POI_RGBMASK
+ calculateRGBNormals(poiMesh.tangentSpaceNormal);
+ #endif
+
+ poiMesh.normals[1] = normalize(
+ poiMesh.tangentSpaceNormal.x * poiMesh.tangent.xyz +
+ poiMesh.tangentSpaceNormal.y * poiMesh.binormal +
+ poiMesh.tangentSpaceNormal.z * poiMesh.normals[0]
+ );
+
+ poiCam.viewDotNormal = abs(dot(poiCam.viewDir, poiMesh.normals[1]));
+}
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiData.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiData.cginc.meta
new file mode 100644
index 00000000..3d82995e
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiData.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 221d9e3fa8c8639449704bdb192dbc4f
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDebug.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDebug.cginc
new file mode 100644
index 00000000..961b5fb7
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDebug.cginc
@@ -0,0 +1,107 @@
+#ifndef POI_DEBUG
+ #define POI_DEBUG
+
+ float _DebugEnabled;
+ float _DebugMeshData;
+ float _DebugLightingData;
+ float _DebugCameraData;
+
+ void displayDebugInfo(inout float4 finalColor)
+ {
+ UNITY_BRANCH
+ if (_DebugEnabled != 0)
+ {
+ //Mesh Data
+ if (_DebugMeshData == 1)
+ {
+ finalColor.rgb = poiMesh.normals[0];
+ return;
+ }
+ else if(_DebugMeshData == 2)
+ {
+ finalColor.rgb = poiMesh.normals[1];
+ return;
+ }
+ else if(_DebugMeshData == 3)
+ {
+ finalColor.rgb = poiMesh.tangent;
+ return;
+ }
+ else if(_DebugMeshData == 4)
+ {
+ finalColor.rgb = poiMesh.binormal;
+ return;
+ }
+ else if(_DebugMeshData == 5)
+ {
+ finalColor.rgb = poiMesh.localPos;
+ return;
+ }
+
+ #ifdef POI_LIGHTING
+ if(_DebugLightingData == 1)
+ {
+ finalColor.rgb = poiLight.attenuation;
+ return;
+ }
+ else if(_DebugLightingData == 2)
+ {
+ finalColor.rgb = poiLight.directLighting;
+ return;
+ }
+ else if(_DebugLightingData == 3)
+ {
+ finalColor.rgb = poiLight.indirectLighting;
+ return;
+ }
+ else if(_DebugLightingData == 4)
+ {
+ finalColor.rgb = poiLight.lightMap;
+ return;
+ }
+ else if(_DebugLightingData == 5)
+ {
+ finalColor.rgb = poiLight.rampedLightMap;
+ return;
+ }
+ else if(_DebugLightingData == 6)
+ {
+ finalColor.rgb = poiLight.finalLighting;
+ return;
+ }
+ else if(_DebugLightingData == 7)
+ {
+ finalColor.rgb = poiLight.nDotL;
+ return;
+ }
+ #endif
+
+ if(_DebugCameraData == 1)
+ {
+ finalColor.rgb = poiCam.viewDir;
+ return;
+ }
+ else if(_DebugCameraData == 2)
+ {
+ finalColor.rgb = poiCam.tangentViewDir;
+ return;
+ }
+ else if(_DebugCameraData == 3)
+ {
+ finalColor.rgb = poiCam.forwardDir;
+ return;
+ }
+ else if(_DebugCameraData == 4)
+ {
+ finalColor.rgb = poiCam.worldPos;
+ return;
+ }
+ else if(_DebugCameraData == 5)
+ {
+ finalColor.rgb = poiCam.viewDotNormal;
+ return;
+ }
+ }
+ }
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDebug.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDebug.cginc.meta
new file mode 100644
index 00000000..40d0b923
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDebug.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 1cc16395659ad2b4b886b2caaeb83829
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDecal.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDecal.cginc
new file mode 100644
index 00000000..5e1b64ef
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDecal.cginc
@@ -0,0 +1,331 @@
+#ifndef POI_DECAL
+#define POI_DECAL
+
+
+#if defined(PROP_DECALMASK) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_DecalMask);
+#endif
+
+#if defined(PROP_DECALTEXTURE) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_DecalTexture);
+#else
+ float2 _DecalTextureUV;
+#endif
+float4 _DecalColor;
+fixed _DecalTiled;
+float _DecalBlendType;
+half _DecalRotation;
+half2 _DecalScale;
+half2 _DecalPosition;
+half _DecalRotationSpeed;
+float _DecalEmissionStrength;
+float _DecalBlendAlpha;
+float _DecalHueShiftEnabled;
+float _DecalHueShift;
+float _DecalHueShiftSpeed;
+
+// Audio Link
+half _AudioLinkDecal0ScaleBand;
+float4 _AudioLinkDecal0Scale;
+half _AudioLinkDecal0RotationBand;
+float2 _AudioLinkDecal0Rotation;
+half _AudioLinkDecal0AlphaBand;
+float2 _AudioLinkDecal0Alpha;
+half _AudioLinkDecal0EmissionBand;
+float2 _AudioLinkDecal0Emission;
+
+half _AudioLinkDecal1ScaleBand;
+float4 _AudioLinkDecal1Scale;
+half _AudioLinkDecal1RotationBand;
+float2 _AudioLinkDecal1Rotation;
+half _AudioLinkDecal1AlphaBand;
+float2 _AudioLinkDecal1Alpha;
+half _AudioLinkDecal1EmissionBand;
+float2 _AudioLinkDecal1Emission;
+
+half _AudioLinkDecal2ScaleBand;
+float4 _AudioLinkDecal2Scale;
+half _AudioLinkDecal2RotationBand;
+float2 _AudioLinkDecal2Rotation;
+half _AudioLinkDecal2AlphaBand;
+float2 _AudioLinkDecal2Alpha;
+half _AudioLinkDecal2EmissionBand;
+float2 _AudioLinkDecal2Emission;
+
+half _AudioLinkDecal3ScaleBand;
+float4 _AudioLinkDecal3Scale;
+half _AudioLinkDecal3RotationBand;
+float2 _AudioLinkDecal3Rotation;
+half _AudioLinkDecal3AlphaBand;
+float2 _AudioLinkDecal3Alpha;
+half _AudioLinkDecal3EmissionBand;
+float2 _AudioLinkDecal3Emission;
+
+#ifdef GEOM_TYPE_BRANCH_DETAIL
+ #if defined(PROP_DECALTEXTURE1) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_DecalTexture1);
+ #else
+ float2 _DecalTexture1UV;
+ #endif
+ float4 _DecalColor1;
+ fixed _DecalTiled1;
+ float _DecalBlendType1;
+ half _DecalRotation1;
+ half2 _DecalScale1;
+ half2 _DecalPosition1;
+ half _DecalRotationSpeed1;
+ float _DecalEmissionStrength1;
+ float _DecalBlendAlpha1;
+ float _DecalHueShiftEnabled1;
+ float _DecalHueShift1;
+ float _DecalHueShiftSpeed1;
+#endif
+
+#ifdef GEOM_TYPE_FROND
+ #if defined(PROP_DECALTEXTURE2) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_DecalTexture2);
+ #else
+ float2 _DecalTexture2UV;
+ #endif
+ float4 _DecalColor2;
+ fixed _DecalTiled2;
+ float _DecalBlendType2;
+ half _DecalRotation2;
+ half2 _DecalScale2;
+ half2 _DecalPosition2;
+ half _DecalRotationSpeed2;
+ float _DecalEmissionStrength2;
+ float _DecalBlendAlpha2;
+ float _DecalHueShiftEnabled2;
+ float _DecalHueShift2;
+ float _DecalHueShiftSpeed2;
+#endif
+
+#ifdef DEPTH_OF_FIELD_COC_VIEW
+ #if defined(PROP_DECALTEXTURE3) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_DecalTexture3);
+ #else
+ float2 _DecalTexture3UV;
+ #endif
+ float4 _DecalColor3;
+ fixed _DecalTiled3;
+ float _DecalBlendType3;
+ half _DecalRotation3;
+ half2 _DecalScale3;
+ half2 _DecalPosition3;
+ half _DecalRotationSpeed3;
+ float _DecalEmissionStrength3;
+ float _DecalBlendAlpha3;
+ float _DecalHueShiftEnabled3;
+ float _DecalHueShift3;
+ float _DecalHueShiftSpeed3;
+#endif
+
+// Parallax
+float _Decal0Depth;
+float _Decal1Depth;
+float _Decal2Depth;
+float _Decal3Depth;
+
+float2 calcParallax(float height)
+{
+ return((height * - 1) + 1) * (poiCam.decalTangentViewDir.xy / poiCam.decalTangentViewDir.z);
+}
+
+
+float2 decalUV(float uvNumber, float2 position, half rotation, half rotationSpeed, half2 scale, float depth)
+{
+ float2 uv = poiMesh.uv[uvNumber] + calcParallax(depth + 1);
+ float2 decalCenter = position;
+ float theta = radians(rotation + _Time.z * rotationSpeed);
+ float cs = cos(theta);
+ float sn = sin(theta);
+ uv = float2((uv.x - decalCenter.x) * cs - (uv.y - decalCenter.y) * sn + decalCenter.x, (uv.x - decalCenter.x) * sn + (uv.y - decalCenter.y) * cs + decalCenter.y);
+ uv = remap(uv, float2(0, 0) - scale / 2 + position, scale / 2 + position, float2(0, 0), float2(1, 1));
+ return uv;
+}
+
+inline float3 decalHueShift(float enabled, float3 color, float shift, float shiftSpeed)
+{
+ UNITY_BRANCH
+ if (enabled)
+ {
+ color = hueShift(color, shift + _Time.x * shiftSpeed);
+ }
+ return color;
+}
+
+inline float applyTilingClipping(float enabled, float2 uv)
+{
+ float ret = 1;
+ UNITY_BRANCH
+ if (!enabled)
+ {
+ if (uv.x > 1 || uv.y > 1 || uv.x < 0 || uv.y < 0)
+ {
+ ret = 0;
+ }
+ }
+ return ret;
+}
+
+void applyDecals(inout float4 albedo, inout float3 decalEmission)
+{
+
+ #if defined(PROP_DECALMASK) || !defined(OPTIMIZER_ENABLED)
+ float4 decalMask = POI2D_SAMPLER_PAN(_DecalMask, _MainTex, poiMesh.uv[_DecalMaskUV], _DecalMaskPan);
+ #else
+ float4 decalMask = 1;
+ #endif
+
+ float4 decalColor = 1;
+ float2 uv = 0;
+
+ // Decal 0
+ float2 decalScale = float2(1, 1);
+ float decalRotation = 0;
+ decalScale = _DecalScale;
+ #if defined(PROP_DECALTEXTURE) || !defined(OPTIMIZER_ENABLED)
+ #ifdef POI_AUDIOLINK
+ UNITY_BRANCH
+ if (poiMods.audioLinkTextureExists)
+ {
+ decalScale += lerp(_AudioLinkDecal0Scale.xy, _AudioLinkDecal0Scale.zw, poiMods.audioLink[_AudioLinkDecal0ScaleBand]);
+ decalRotation += lerp(_AudioLinkDecal0Rotation.x, _AudioLinkDecal0Rotation.y, poiMods.audioLink[_AudioLinkDecal0RotationBand]);
+ }
+ #endif
+ uv = decalUV(_DecalTextureUV, _DecalPosition, _DecalRotation + decalRotation, _DecalRotationSpeed, decalScale, _Decal0Depth);
+ decalColor = POI2D_SAMPLER_PAN(_DecalTexture, _MainTex, uv, _DecalTexturePan) * _DecalColor;
+ #else
+ uv = decalUV(_DecalTextureUV, _DecalPosition, _DecalRotation + decalRotation, _DecalRotationSpeed, decalScale, _Decal0Depth);
+ decalColor = _DecalColor;
+ #endif
+ decalColor.rgb = decalHueShift(_DecalHueShiftEnabled, decalColor.rgb, _DecalHueShift, _DecalHueShiftSpeed);
+ decalColor.a *= applyTilingClipping(_DecalTiled, uv) * decalMask.r;
+
+ float audioLinkDecalAlpha0 = 0;
+ #ifdef POI_AUDIOLINK
+ audioLinkDecalAlpha0 = lerp(_AudioLinkDecal0Alpha.x, _AudioLinkDecal0Alpha.y, poiMods.audioLink[_AudioLinkDecal0AlphaBand]) * poiMods.audioLinkTextureExists;
+ #endif
+
+ albedo.rgb = lerp(albedo.rgb, customBlend(albedo.rgb, decalColor.rgb, _DecalBlendType), decalColor.a * saturate(_DecalBlendAlpha + audioLinkDecalAlpha0));
+
+ float audioLinkDecalEmission0 = 0;
+ #ifdef POI_AUDIOLINK
+ audioLinkDecalEmission0 = lerp(_AudioLinkDecal0Emission.x, _AudioLinkDecal0Emission.y, poiMods.audioLink[_AudioLinkDecal0EmissionBand]) * poiMods.audioLinkTextureExists;
+ #endif
+
+ decalEmission += decalColor.rgb * decalColor.a * max(_DecalEmissionStrength + audioLinkDecalEmission0, 0);
+ #ifdef GEOM_TYPE_BRANCH_DETAIL
+ // Decal 1
+ decalScale = _DecalScale1;
+ decalRotation = 0;
+ #if defined(PROP_DECALTEXTURE1) || !defined(OPTIMIZER_ENABLED)
+ #ifdef POI_AUDIOLINK
+ UNITY_BRANCH
+ if (poiMods.audioLinkTextureExists)
+ {
+ decalScale += lerp(_AudioLinkDecal1Scale.xy, _AudioLinkDecal1Scale.zw, poiMods.audioLink[_AudioLinkDecal1ScaleBand]);
+ decalRotation += lerp(_AudioLinkDecal1Rotation.x, _AudioLinkDecal1Rotation.y, poiMods.audioLink[_AudioLinkDecal1RotationBand]);
+ }
+ #endif
+ uv = decalUV(_DecalTexture1UV, _DecalPosition1, _DecalRotation1 + decalRotation, _DecalRotationSpeed1, decalScale, _Decal1Depth);
+ decalColor = POI2D_SAMPLER_PAN(_DecalTexture1, _MainTex, uv, _DecalTexture1Pan) * _DecalColor1;
+ #else
+ uv = decalUV(_DecalTexture1UV, _DecalPosition1, _DecalRotation1 + decalRotation, _DecalRotationSpeed1, decalScale, _Decal1Depth);
+ decalColor = _DecalColor1;
+ #endif
+ decalColor.rgb = decalHueShift(_DecalHueShiftEnabled1, decalColor.rgb, _DecalHueShift1, _DecalHueShiftSpeed1);
+ decalColor.a *= applyTilingClipping(_DecalTiled1, uv) * decalMask.g;
+
+ float audioLinkDecalAlpha1 = 0;
+ #ifdef POI_AUDIOLINK
+ audioLinkDecalAlpha1 = lerp(_AudioLinkDecal1Alpha.x, _AudioLinkDecal1Alpha.y, poiMods.audioLink[_AudioLinkDecal1AlphaBand]) * poiMods.audioLinkTextureExists;
+ #endif
+
+ albedo.rgb = lerp(albedo.rgb, customBlend(albedo.rgb, decalColor.rgb, _DecalBlendType1), decalColor.a * saturate(_DecalBlendAlpha1 + audioLinkDecalAlpha1));
+
+ float audioLinkDecalEmission1 = 0;
+ #ifdef POI_AUDIOLINK
+ audioLinkDecalEmission1 = lerp(_AudioLinkDecal1Emission.x, _AudioLinkDecal1Emission.y, poiMods.audioLink[_AudioLinkDecal1EmissionBand]) * poiMods.audioLinkTextureExists;
+ #endif
+
+ decalEmission += decalColor.rgb * decalColor.a * max(_DecalEmissionStrength1 + audioLinkDecalEmission1, 0);
+ #endif
+ #ifdef GEOM_TYPE_FROND
+ // Decal 2
+ decalScale = _DecalScale2;
+ decalRotation = 0;
+ #if defined(PROP_DECALTEXTURE2) || !defined(OPTIMIZER_ENABLED)
+ #ifdef POI_AUDIOLINK
+ UNITY_BRANCH
+ if (poiMods.audioLinkTextureExists)
+ {
+ decalScale += lerp(_AudioLinkDecal2Scale.xy, _AudioLinkDecal2Scale.zw, poiMods.audioLink[_AudioLinkDecal2ScaleBand]);
+ decalRotation += lerp(_AudioLinkDecal2Rotation.x, _AudioLinkDecal2Rotation.y, poiMods.audioLink[_AudioLinkDecal2RotationBand]);
+ }
+ #endif
+ uv = decalUV(_DecalTexture2UV, _DecalPosition2, _DecalRotation2 + decalRotation, _DecalRotationSpeed2, decalScale, _Decal2Depth);
+ decalColor = POI2D_SAMPLER_PAN(_DecalTexture2, _MainTex, uv, _DecalTexture2Pan) * _DecalColor2;
+ #else
+ uv = decalUV(_DecalTexture2UV, _DecalPosition2, _DecalRotation2 + decalRotation, _DecalRotationSpeed2, decalScale, _Decal2Depth);
+ decalColor = _DecalColor2;
+ #endif
+ decalColor.rgb = decalHueShift(_DecalHueShiftEnabled2, decalColor.rgb, _DecalHueShift2, _DecalHueShiftSpeed2);
+ decalColor.a *= applyTilingClipping(_DecalTiled2, uv) * decalMask.b;
+
+ float audioLinkDecalAlpha2 = 0;
+ #ifdef POI_AUDIOLINK
+ audioLinkDecalAlpha2 = lerp(_AudioLinkDecal2Alpha.x, _AudioLinkDecal2Alpha.y, poiMods.audioLink[_AudioLinkDecal2AlphaBand]) * poiMods.audioLinkTextureExists;
+ #endif
+
+ albedo.rgb = lerp(albedo.rgb, customBlend(albedo.rgb, decalColor.rgb, _DecalBlendType2), decalColor.a * saturate(_DecalBlendAlpha2 + audioLinkDecalAlpha2));
+
+ float audioLinkDecalEmission2 = 0;
+ #ifdef POI_AUDIOLINK
+ audioLinkDecalEmission2 = lerp(_AudioLinkDecal2Emission.x, _AudioLinkDecal2Emission.y, poiMods.audioLink[_AudioLinkDecal2EmissionBand]) * poiMods.audioLinkTextureExists;
+ #endif
+
+ decalEmission += decalColor.rgb * decalColor.a * max(_DecalEmissionStrength2 + audioLinkDecalEmission2, 0);
+ #endif
+ #ifdef DEPTH_OF_FIELD_COC_VIEW
+ // Decal 3
+ decalScale = _DecalScale3;
+ decalRotation = 0;
+ #if defined(PROP_DECALTEXTURE3) || !defined(OPTIMIZER_ENABLED)
+ #ifdef POI_AUDIOLINK
+ UNITY_BRANCH
+ if (poiMods.audioLinkTextureExists)
+ {
+ decalScale += lerp(_AudioLinkDecal3Scale.xy, _AudioLinkDecal3Scale.zw, poiMods.audioLink[_AudioLinkDecal3ScaleBand]);
+ decalRotation += lerp(_AudioLinkDecal3Rotation.x, _AudioLinkDecal3Rotation.y, poiMods.audioLink[_AudioLinkDecal3RotationBand]);
+ }
+ #endif
+ uv = decalUV(_DecalTexture3UV, _DecalPosition3, _DecalRotation3 + decalRotation, _DecalRotationSpeed3, decalScale, _Decal3Depth);
+ decalColor = POI2D_SAMPLER_PAN(_DecalTexture3, _MainTex, uv, _DecalTexture3Pan) * _DecalColor3;
+ #else
+ uv = decalUV(_DecalTexture3UV, _DecalPosition3, _DecalRotation3 + decalRotation, _DecalRotationSpeed3, decalScale, _Decal3Depth);
+ decalColor = _DecalColor3;
+ #endif
+ decalColor.rgb = decalHueShift(_DecalHueShiftEnabled3, decalColor.rgb, _DecalHueShift3, _DecalHueShiftSpeed3);
+ decalColor.a *= applyTilingClipping(_DecalTiled3, uv) * decalMask.a;
+
+ float audioLinkDecalAlpha3 = 0;
+ #ifdef POI_AUDIOLINK
+ audioLinkDecalAlpha3 = lerp(_AudioLinkDecal3Alpha.x, _AudioLinkDecal3Alpha.y, poiMods.audioLink[_AudioLinkDecal3AlphaBand]) * poiMods.audioLinkTextureExists;
+ #endif
+
+ albedo.rgb = lerp(albedo.rgb, customBlend(albedo.rgb, decalColor.rgb, _DecalBlendType3), decalColor.a * saturate(_DecalBlendAlpha3 + audioLinkDecalAlpha3));
+
+ float audioLinkDecalEmission3 = 0;
+ #ifdef POI_AUDIOLINK
+ audioLinkDecalEmission3 = lerp(_AudioLinkDecal3Emission.x, _AudioLinkDecal3Emission.y, poiMods.audioLink[_AudioLinkDecal3EmissionBand]) * poiMods.audioLinkTextureExists;
+ #endif
+
+ decalEmission += decalColor.rgb * decalColor.a * max(_DecalEmissionStrength3 + audioLinkDecalEmission3, 0);
+ #endif
+
+ albedo = saturate(albedo);
+}
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDecal.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDecal.cginc.meta
new file mode 100644
index 00000000..f49f4460
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDecal.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 664de60cb14b4194ba278cf1f8d8cec5
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDefines.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDefines.cginc
new file mode 100644
index 00000000..0c789440
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDefines.cginc
@@ -0,0 +1,7 @@
+#ifndef POI_DEFINES
+ #define POI_DEFINES
+
+ #define DielectricSpec float4(0.04, 0.04, 0.04, 1.0 - 0.04)
+ #define pi float(3.14159265359)
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDefines.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDefines.cginc.meta
new file mode 100644
index 00000000..7d163c12
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDefines.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 7c4268f3614d17d49ba4a6865bd104de
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDepthColor.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDepthColor.cginc
new file mode 100644
index 00000000..6e1f834d
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDepthColor.cginc
@@ -0,0 +1,129 @@
+#ifndef POI_DEPTH_COLOR
+ #define POI_DEPTH_COLOR
+
+ float4 _DepthGlowColor;
+ float _DepthGlowEmission;
+ float _FadeLength;
+ float _DepthAlphaMin;
+ float _DepthAlphaMax;
+ float _DepthGradientTextureUV;
+ float _DepthGradientBlend;
+
+ #if defined(PROP_DEPTHGRADIENT) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_DepthGradient);
+ #endif
+ #if defined(PROP_DEPTHMASK) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_DepthMask);
+ #endif
+
+ /*
+ void applyDepthColor(inout float4 finalColor, inout float3 depthTouchEmission, inout float3 finalEmission, float4 worldDirection, float4 clipPos)
+ {
+ float3 touchEmission = 0;
+ if (!IsInMirror())
+ {
+ float fadeLength = _FadeLength;
+ fadeLength *= 0.01;
+ float depth = DecodeFloatRG(tex2Dproj(_CameraDepthTexture, worldDirection));
+ depth = Linear01Depth(depth);
+ if(depth != 1)
+ {
+ float diff = distance(depth, Linear01Depth(clipPos.z));
+ float intersect = 0;
+ if(diff > 0)
+ {
+ intersect = clamp(1 - smoothstep(0, _ProjectionParams.w * fadeLength, diff), 0, 1);
+ }
+ half4 depthGradient = UNITY_SAMPLE_TEX2D_SAMPLER(_DepthGradient, _MainTex, intersect);
+ half3 depthMask = UNITY_SAMPLE_TEX2D_SAMPLER(_DepthMask, _MainTex, poiMesh.uv[0]);
+ half3 depthColor = depthGradient.rgb * _DepthGlowColor.rgb;
+ finalColor.rgb = lerp(finalColor.rgb, depthColor, intersect * depthMask);
+ finalColor.a *= lerp(_DepthAlphaMax, _DepthAlphaMin, intersect);
+ touchEmission = depthColor * _DepthGlowEmission * intersect * depthMask;
+ }
+ }
+ depthTouchEmission = touchEmission;
+ }
+ */
+
+ inline float CorrectedLinearEyeDepth(float z, float B)
+ {
+ return 1.0 / (z / PM._34 + B);
+ }
+
+ void applyDepthColor(inout float4 finalColor, inout float3 depthTouchEmission, inout float3 finalEmission, in float4 worldDirection)
+ {
+ float3 touchEmission = 0;
+ float fadeLength = _FadeLength;
+ fadeLength *= 0.01;
+
+ float perspectiveDivide = 1.0f / poiCam.clipPos.w;
+ float4 direction = worldDirection * perspectiveDivide;
+ float2 screenPos = poiCam.grabPos.xy * perspectiveDivide;
+ float z = SAMPLE_DEPTH_TEXTURE(_CameraDepthTexture, screenPos);
+
+ #if UNITY_REVERSED_Z
+ if (z == 0)
+ #else
+ if(z == 1)
+ #endif
+ return;
+
+ float depth = CorrectedLinearEyeDepth(z, direction.w);
+ float3 worldpos = direction * depth + _WorldSpaceCameraPos.xyz;
+ /*
+ finalColor.rgb = frac(worldpos);
+ return;
+ */
+
+ float diff = distance(worldpos, poiMesh.worldPos);
+ float intersect = 0;
+ intersect = clamp(1 - smoothstep(0, fadeLength, diff), 0, 1);
+ #if defined(PROP_DEPTHMASK) || !defined(OPTIMIZER_ENABLED)
+ half3 depthMask = POI2D_SAMPLER_PAN(_DepthMask, _MainTex, poiMesh.uv[_DepthMaskUV], _DepthMaskPan);
+ #else
+ half3 depthMask = 1;
+ #endif
+
+ half4 depthGradient = 0;
+ half3 depthColor = 0;
+
+ UNITY_BRANCH
+ if (_DepthGradientTextureUV == 0)
+ {
+ #if defined(PROP_DEPTHGRADIENT) || !defined(OPTIMIZER_ENABLED)
+ depthGradient = POI2D_SAMPLER_PAN(_DepthGradient, _MainTex, float2(intersect, intersect), _DepthGradientPan);
+ #else
+ depthGradient = 1;
+ #endif
+ depthColor = depthGradient.rgb * _DepthGlowColor.rgb;
+ }
+ else
+ {
+ #if defined(PROP_DEPTHGRADIENT) || !defined(OPTIMIZER_ENABLED)
+ depthGradient = POI2D_SAMPLER_PAN(_DepthGradient, _MainTex, poiMesh.uv[_DepthGradientUV], _DepthGradientPan);
+ #else
+ depthGradient = 1;
+ #endif
+ depthColor = depthGradient.rgb * _DepthGlowColor.rgb * intersect;
+ }
+
+ UNITY_BRANCH
+ if(_DepthGradientBlend == 0) // rpelace
+ {
+ finalColor.rgb = lerp(finalColor.rgb, depthColor, intersect * depthMask);
+ }
+ else if (_DepthGradientBlend == 1) // add
+ {
+ finalColor.rgb += depthColor * intersect * depthMask;
+ }
+ else if (_DepthGradientBlend == 2) // multiply
+ {
+ finalColor.rgb *= lerp(1, depthColor, intersect * depthMask);
+ }
+ finalColor.a *= lerp(_DepthAlphaMax, _DepthAlphaMin, intersect * depthMask);
+ touchEmission = depthColor * _DepthGlowEmission * intersect * depthMask;
+
+ depthTouchEmission = touchEmission;
+ }
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDepthColor.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDepthColor.cginc.meta
new file mode 100644
index 00000000..72f55fc6
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDepthColor.cginc.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 051133829be575149906a0cbe6572012
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDissolve.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDissolve.cginc
new file mode 100644
index 00000000..ee46ba87
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDissolve.cginc
@@ -0,0 +1,237 @@
+#ifndef POI_DISSOLVE
+#define POI_DISSOLVE
+
+float _DissolveType;
+float _DissolveEdgeWidth;
+float4 _DissolveEdgeColor;
+sampler2D _DissolveEdgeGradient; float4 _DissolveEdgeGradient_ST;
+float _DissolveEdgeEmission;
+float4 _DissolveTextureColor;
+
+#if defined(PROP_DISSOLVETOTEXTURE) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_DissolveToTexture);
+#endif
+
+#if defined(PROP_DISSOLVENOISETEXTURE) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_DissolveNoiseTexture);
+#endif
+
+#if defined(PROP_DISSOLVEDETAILNOISE) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_DissolveDetailNoise);
+#endif
+
+#if defined(PROP_DISSOLVEMASK) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_DissolveMask);
+#endif
+
+float _DissolveMaskInvert;
+float _DissolveAlpha;
+float _ContinuousDissolve;
+float _DissolveDetailStrength;
+float _DissolveEdgeHardness;
+float _DissolveInvertNoise;
+float _DissolveInvertDetailNoise;
+float _DissolveToEmissionStrength;
+
+// Point to Point
+float _DissolveP2PWorldLocal;
+float _DissolveP2PEdgeLength;
+float4 _DissolveStartPoint;
+float4 _DissolveEndPoint;
+
+// World Dissolve
+float _DissolveWorldShape;
+float4 _DissolveShapePosition;
+float4 _DissolveShapeRotation;
+float _DissolveShapeScale;
+float _DissolveInvertShape;
+float _DissolveShapeEdgeLength;
+
+float _DissolveAlpha0;
+float _DissolveAlpha1;
+float _DissolveAlpha2;
+float _DissolveAlpha3;
+float _DissolveAlpha4;
+float _DissolveAlpha5;
+float _DissolveAlpha6;
+float _DissolveAlpha7;
+float _DissolveAlpha8;
+float _DissolveAlpha9;
+// Masking
+float _DissolveEmissionSide;
+float _DissolveEmission1Side;
+float _DissolveUseVertexColors;
+
+// Audio Link
+#ifdef POI_AUDIOLINK
+ fixed _EnableDissolveAudioLink;
+ half _AudioLinkDissolveAlphaBand;
+ float2 _AudioLinkDissolveAlpha;
+ half _AudioLinkDissolveDetailBand;
+ float2 _AudioLinkDissolveDetail;
+#endif
+
+float4 edgeColor;
+float edgeAlpha;
+float dissolveAlpha;
+float4 dissolveToTexture;
+
+float _DissolveHueShiftEnabled;
+float _DissolveHueShiftSpeed;
+float _DissolveHueShift;
+float _DissolveEdgeHueShiftEnabled;
+float _DissolveEdgeHueShiftSpeed;
+float _DissolveEdgeHueShift;
+void calculateDissolve(inout float4 albedo, inout float3 dissolveEmission)
+{
+ #if defined(PROP_DISSOLVEMASK) || !defined(OPTIMIZER_ENABLED)
+ float dissolveMask = POI2D_SAMPLER_PAN(_DissolveMask, _MainTex, poiMesh.uv[_DissolveMaskUV], _DissolveMaskPan).r;
+ #else
+ float dissolveMask = 1;
+ #endif
+ UNITY_BRANCH
+ if (_DissolveUseVertexColors)
+ {
+ // Vertex Color Imprecision hype
+ dissolveMask = ceil(poiMesh.vertexColor.g * 100000) / 100000;
+ }
+
+ #if defined(PROP_DISSOLVETOTEXTURE) || !defined(OPTIMIZER_ENABLED)
+ dissolveToTexture = POI2D_SAMPLER_PAN(_DissolveToTexture, _MainTex, poiMesh.uv[_DissolveToTextureUV], _DissolveToTexturePan) * _DissolveTextureColor;
+ #else
+ dissolveToTexture = _DissolveTextureColor;
+ #endif
+
+ #if defined(PROP_DISSOLVENOISETEXTURE) || !defined(OPTIMIZER_ENABLED)
+ float dissolveNoiseTexture = POI2D_SAMPLER_PAN(_DissolveNoiseTexture, _MainTex, poiMesh.uv[_DissolveNoiseTextureUV], _DissolveNoiseTexturePan).r;
+ #else
+ float dissolveNoiseTexture = 1;
+ #endif
+
+ float da = _DissolveAlpha
+ + _DissolveAlpha0
+ + _DissolveAlpha1
+ + _DissolveAlpha2
+ + _DissolveAlpha3
+ + _DissolveAlpha4
+ + _DissolveAlpha5
+ + _DissolveAlpha6
+ + _DissolveAlpha7
+ + _DissolveAlpha8
+ + _DissolveAlpha9;
+ float dds = _DissolveDetailStrength;
+
+ #ifdef POI_AUDIOLINK
+ UNITY_BRANCH
+ if (_EnableDissolveAudioLink && poiMods.audioLinkTextureExists)
+ {
+ da += lerp(_AudioLinkDissolveAlpha.x, _AudioLinkDissolveAlpha.y, poiMods.audioLink[_AudioLinkDissolveAlphaBand]);
+ dds += lerp(_AudioLinkDissolveDetail.x, _AudioLinkDissolveDetail.y, poiMods.audioLink[_AudioLinkDissolveDetailBand]);
+ }
+ #endif
+
+ da = saturate(da);
+ dds = saturate(dds);
+
+ #ifdef POI_BLACKLIGHT
+ if (_BlackLightMaskDissolve != 4)
+ {
+ dissolveMask *= blackLightMask[_BlackLightMaskDissolve];
+ }
+ #endif
+
+ if (_DissolveMaskInvert)
+ {
+ dissolveMask = 1 - dissolveMask;
+ }
+ #if defined(PROP_DISSOLVEDETAILNOISE) || !defined(OPTIMIZER_ENABLED)
+ float dissolveDetailNoise = POI2D_SAMPLER_PAN(_DissolveDetailNoise, _MainTex, poiMesh.uv[_DissolveDetailNoiseUV], _DissolveDetailNoisePan);
+ #else
+ float dissolveDetailNoise = 0;
+ #endif
+ if (_DissolveInvertNoise)
+ {
+ dissolveNoiseTexture = 1 - dissolveNoiseTexture;
+ }
+ if (_DissolveInvertDetailNoise)
+ {
+ dissolveDetailNoise = 1 - dissolveDetailNoise;
+ }
+ if (_ContinuousDissolve != 0)
+ {
+ da = sin(_Time.y * _ContinuousDissolve) * .5 + .5;
+ }
+ da *= dissolveMask;
+ dissolveAlpha = da;
+ edgeAlpha = 0;
+
+ UNITY_BRANCH
+ if (_DissolveType == 1) // Basic
+
+ {
+ da = remap(da, 0, 1, -_DissolveEdgeWidth, 1);
+ dissolveAlpha = da;
+ //Adjust detail strength to avoid artifacts
+ dds *= smoothstep(1, .99, da);
+ float noise = saturate(dissolveNoiseTexture - dissolveDetailNoise * dds);
+
+ noise = saturate(noise + 0.001);
+ //noise = remap(noise, 0, 1, _DissolveEdgeWidth, 1 - _DissolveEdgeWidth);
+ dissolveAlpha = dissolveAlpha >= noise;
+ edgeAlpha = remapClamped(noise, da + _DissolveEdgeWidth, da, 0, 1) * (1 - dissolveAlpha);
+ }
+ else if (_DissolveType == 2) // Point to Point
+
+ {
+ float3 direction;
+ float3 currentPos;
+ float distanceTo = 0;
+ direction = normalize(_DissolveEndPoint - _DissolveStartPoint);
+ currentPos = lerp(_DissolveStartPoint, _DissolveEndPoint, dissolveAlpha);
+
+ UNITY_BRANCH
+ if (_DissolveP2PWorldLocal != 1)
+ {
+ float3 pos = _DissolveP2PWorldLocal == 0 ? poiMesh.localPos.rgb: poiMesh.vertexColor.rgb;
+ distanceTo = dot(pos - currentPos, direction) - dissolveDetailNoise * dds;
+ edgeAlpha = smoothstep(_DissolveP2PEdgeLength + .00001, 0, distanceTo);
+ dissolveAlpha = step(distanceTo, 0);
+ edgeAlpha *= 1 - dissolveAlpha;
+ }
+ else
+ {
+ distanceTo = dot(poiMesh.worldPos - currentPos, direction) - dissolveDetailNoise * dds;
+ edgeAlpha = smoothstep(_DissolveP2PEdgeLength + .00001, 0, distanceTo);
+ dissolveAlpha = step(distanceTo, 0);
+ edgeAlpha *= 1 - dissolveAlpha;
+ }
+ }
+
+ #ifndef POI_SHADOW
+ UNITY_BRANCH
+ if (_DissolveHueShiftEnabled)
+ {
+ dissolveToTexture.rgb = hueShift(dissolveToTexture.rgb, _DissolveHueShift + _Time.x * _DissolveHueShiftSpeed);
+ }
+ #endif
+ albedo = lerp(albedo, dissolveToTexture, dissolveAlpha * .999999);
+
+ UNITY_BRANCH
+ if (_DissolveEdgeWidth)
+ {
+ edgeColor = tex2D(_DissolveEdgeGradient, TRANSFORM_TEX(float2(edgeAlpha, edgeAlpha), _DissolveEdgeGradient)) * _DissolveEdgeColor;
+ #ifndef POI_SHADOW
+ UNITY_BRANCH
+ if (_DissolveEdgeHueShiftEnabled)
+ {
+ edgeColor.rgb = hueShift(edgeColor.rgb, _DissolveEdgeHueShift + _Time.x * _DissolveEdgeHueShiftSpeed);
+ }
+ #endif
+ albedo.rgb = lerp(albedo.rgb, edgeColor.rgb, smoothstep(0, 1 - _DissolveEdgeHardness * .99999999999, edgeAlpha));
+ }
+
+ dissolveEmission = lerp(0, dissolveToTexture * _DissolveToEmissionStrength, dissolveAlpha) + lerp(0, edgeColor.rgb * _DissolveEdgeEmission, smoothstep(0, 1 - _DissolveEdgeHardness * .99999999999, edgeAlpha));
+}
+
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDissolve.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDissolve.cginc.meta
new file mode 100644
index 00000000..a4fbdf2d
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDissolve.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: e737055de48f98a4587f09a286ede08f
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDithering.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDithering.cginc
new file mode 100644
index 00000000..1540b5eb
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDithering.cginc
@@ -0,0 +1,34 @@
+#ifndef POI_DITHERING
+ #define POI_DITHERING
+ fixed _DitheringEnabled;
+ fixed _DitherGradient;
+
+ half calcDither(half2 grabPos)
+ {
+ half dither = Dither8x8Bayer(fmod(grabPos.x, 8), fmod(grabPos.y, 8));
+ return dither;
+ }
+
+ #ifndef POI_SHADOW
+ void applyDithering(inout float4 finalColor)
+ {
+ UNITY_BRANCH
+ if (_DitheringEnabled)
+ {
+ half dither = calcDither(poiCam.screenUV.xy);
+ finalColor.a = finalColor.a - (dither * (1 - finalColor.a) * _DitherGradient);
+ }
+ }
+ #else
+ void applyShadowDithering(inout float alpha, float2 screenUV)
+ {
+ UNITY_BRANCH
+ if(_DitheringEnabled)
+ {
+ half dither = calcDither(screenUV);
+ alpha = alpha - (dither * (1 - alpha) * _DitherGradient);
+ }
+ }
+ #endif
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDithering.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDithering.cginc.meta
new file mode 100644
index 00000000..da58503e
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiDithering.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 07d19319226672d40891a9cf8095bb1d
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiEmission.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiEmission.cginc
new file mode 100644
index 00000000..9beafd3c
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiEmission.cginc
@@ -0,0 +1,341 @@
+#ifndef POI_EMISSION
+#define POI_EMISSION
+
+float4 _EmissionColor;
+#if defined(PROP_EMISSIONMAP) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_EmissionMap);
+#endif
+#if defined(PROP_EMISSIONMASK) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_EmissionMask);
+#endif
+#if defined(PROP_EMISSIONSCROLLINGCURVE) || !defined(OPTIMIZER_ENABLED)
+ UNITY_DECLARE_TEX2D_NOSAMPLER(_EmissionScrollingCurve); float4 _EmissionScrollingCurve_ST;
+#endif
+float _EmissionBaseColorAsMap;
+float _EmissionStrength;
+float _EnableEmission;
+float _EmissionHueShift;
+float4 _EmissiveScroll_Direction;
+float _EmissiveScroll_Width;
+float _EmissiveScroll_Velocity;
+float _EmissiveScroll_Interval;
+float _EmissionBlinkingEnabled;
+float _EmissiveBlink_Min;
+float _EmissiveBlink_Max;
+float _EmissiveBlink_Velocity;
+float _ScrollingEmission;
+float _EnableGITDEmission;
+float _GITDEMinEmissionMultiplier;
+float _GITDEMaxEmissionMultiplier;
+float _GITDEMinLight;
+float _GITDEMaxLight;
+float _GITDEWorldOrMesh;
+float _EmissionCenterOutEnabled;
+float _EmissionCenterOutSpeed;
+float _EmissionHueShiftEnabled;
+float _EmissionBlinkingOffset;
+float _EmissionScrollingOffset;
+float _EmissionHueShiftSpeed;
+float _EmissionHueShiftSpeed1;
+
+float4 _EmissionColor1;
+#ifdef EFFECT_HUE_VARIATION
+ #if defined(PROP_EMISSIONMAP1) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_EmissionMap1);
+ #endif
+ #if defined(PROP_EMISSIONMASK1) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_EmissionMask1);
+ #endif
+ #if defined(PROP_EMISSIONSCROLLINGCURVE1) || !defined(OPTIMIZER_ENABLED)
+ UNITY_DECLARE_TEX2D_NOSAMPLER(_EmissionScrollingCurve1); float4 _EmissionScrollingCurve1_ST;
+ #endif
+#endif
+float _EmissionBaseColorAsMap1;
+float _EmissionStrength1;
+float _EnableEmission1;
+float _EmissionHueShift1;
+float4 _EmissiveScroll_Direction1;
+float _EmissiveScroll_Width1;
+float _EmissiveScroll_Velocity1;
+float _EmissiveScroll_Interval1;
+float _EmissionBlinkingEnabled1;
+float _EmissiveBlink_Min1;
+float _EmissiveBlink_Max1;
+float _EmissiveBlink_Velocity1;
+float _ScrollingEmission1;
+float _EnableGITDEmission1;
+float _GITDEMinEmissionMultiplier1;
+float _GITDEMaxEmissionMultiplier1;
+float _GITDEMinLight1;
+float _GITDEMaxLight1;
+float _GITDEWorldOrMesh1;
+float _EmissionCenterOutEnabled1;
+float _EmissionCenterOutSpeed1;
+float _EmissionHueShiftEnabled1;
+float _EmissionBlinkingOffset1;
+float _EmissionScrollingOffset1;
+
+float _EmissionReplace;
+
+float _EmissionScrollingVertexColor;
+float _EmissionScrollingVertexColor1;
+
+float _EmissionScrollingUseCurve;
+float _EmissionScrollingUseCurve1;
+
+#ifdef POI_AUDIOLINK
+ half _EnableEmissionStrengthAudioLink;
+ half _AudioLinkEmissionStrengthBand;
+ half _EnableEmissionCenterOutAudioLink;
+ half _AudioLinkEmissionCenterOutBand;
+ float2 _AudioLinkAddEmission;
+ half _AudioLinkAddEmissionBand;
+ float2 _EmissionCenterOutAddAudioLink;
+ half _AudioLinkEmissionCenterOutAddBand;
+
+ half _EnableEmission1StrengthAudioLink;
+ half _AudioLinkEmission1StrengthBand;
+ half _EnableEmission1CenterOutAudioLink;
+ half _AudioLinkEmission1CenterOutBand;
+ float2 _AudioLinkAddEmission1;
+ half _AudioLinkAddEmission1Band;
+ float2 _EmissionCenterOutAddAudioLink1;
+ half _AudioLinkEmission1CenterOutAddBand;
+
+ fixed _EmissionCenterOutAudioLinkWidth;
+ fixed _EmissionCenterOutAddAudioLinkwidth;
+ fixed _Emission1CenterOutAudioLinkWidth;
+ fixed _Emission1CenterOutAddAudioLinkwidth;
+#endif
+
+float calculateGlowInTheDark(in float minLight, in float maxLight, in float minEmissionMultiplier, in float maxEmissionMultiplier, in float enabled, in float worldOrMesh)
+{
+ float glowInTheDarkMultiplier = 1;
+ UNITY_BRANCH
+ if (enabled)
+ {
+ #ifdef POI_LIGHTING
+ float3 lightValue = worldOrMesh ? calculateluminance(poiLight.finalLighting.rgb): calculateluminance(poiLight.directLighting.rgb);
+ float gitdeAlpha = saturate(inverseLerp(minLight, maxLight, lightValue));
+ glowInTheDarkMultiplier = lerp(minEmissionMultiplier, maxEmissionMultiplier, gitdeAlpha);
+ #endif
+ }
+ return glowInTheDarkMultiplier;
+}
+
+float calculateScrollingEmission(in float3 direction, in float velocity, in float interval, in float scrollWidth, float offset, float3 position)
+{
+ float phase = 0;
+ phase = dot(position, direction);
+ phase -= (_Time.y + offset) * velocity;
+ phase /= interval;
+ phase -= floor(phase);
+ phase = saturate(phase);
+ return(pow(phase, scrollWidth) + pow(1 - phase, scrollWidth * 4)) * 0.5;
+}
+
+float calculateBlinkingEmission(in float blinkMin, in float blinkMax, in float blinkVelocity, float offset)
+{
+ float amplitude = (blinkMax - blinkMin) * 0.5f;
+ float base = blinkMin + amplitude;
+ return sin((_Time.y + offset) * blinkVelocity) * amplitude + base;
+}
+
+float3 calculateEmissionNew(in float3 baseColor, inout float4 finalColor)
+{
+ // First Emission
+ float3 emission0 = 0;
+ float emissionStrength0 = _EmissionStrength;
+ float3 emissionColor0 = 0;
+
+ #ifdef POI_AUDIOLINK
+ UNITY_BRANCH
+ if (poiMods.audioLinkTextureExists)
+ {
+ UNITY_BRANCH
+ if (_EnableEmissionStrengthAudioLink)
+ {
+ emissionStrength0 *= poiMods.audioLink[_AudioLinkEmissionStrengthBand];
+ }
+ UNITY_BRANCH
+ if (_EnableEmissionCenterOutAudioLink)
+ {
+ emissionStrength0 *= getBandAtTime(_AudioLinkEmissionCenterOutBand, saturate(1 - poiLight.nDotV), _EmissionCenterOutAudioLinkWidth);
+ }
+ emissionStrength0 += lerp(_EmissionCenterOutAddAudioLink.x, _EmissionCenterOutAddAudioLink.y, getBandAtTime(_AudioLinkEmissionCenterOutAddBand, saturate(1 - poiLight.nDotV), _EmissionCenterOutAddAudioLinkwidth));
+ emissionStrength0 += lerp(_AudioLinkAddEmission.x, _AudioLinkAddEmission.y, poiMods.audioLink[_AudioLinkAddEmissionBand]);
+ emissionStrength0 = max(emissionStrength0, 0);
+ }
+ #endif
+
+ float glowInTheDarkMultiplier0 = calculateGlowInTheDark(_GITDEMinLight, _GITDEMaxLight, _GITDEMinEmissionMultiplier, _GITDEMaxEmissionMultiplier, _EnableGITDEmission, _GITDEWorldOrMesh);
+
+ #if defined(PROP_EMISSIONMAP) || !defined(OPTIMIZER_ENABLED)
+ UNITY_BRANCH
+ if (!_EmissionCenterOutEnabled)
+ {
+ emissionColor0 = POI2D_SAMPLER_PAN(_EmissionMap, _MainTex, poiMesh.uv[_EmissionMapUV], _EmissionMapPan).rgb * lerp(1, baseColor, _EmissionBaseColorAsMap).rgb * _EmissionColor.rgb;
+ }
+ else
+ {
+ emissionColor0 = UNITY_SAMPLE_TEX2D_SAMPLER(_EmissionMap, _MainTex, ((.5 + poiLight.nDotV * .5) * _EmissionMap_ST.xy) + _Time.x * _EmissionCenterOutSpeed).rgb * lerp(1, baseColor, _EmissionBaseColorAsMap).rgb * _EmissionColor.rgb;
+ }
+ #else
+ emissionColor0 = lerp(1, baseColor, _EmissionBaseColorAsMap).rgb * _EmissionColor.rgb;
+ #endif
+
+ UNITY_BRANCH
+ if (_ScrollingEmission)
+ {
+ float3 pos = poiMesh.localPos;
+ UNITY_BRANCH
+ if (_EmissionScrollingVertexColor)
+ {
+ pos = poiMesh.vertexColor.rgb;
+ }
+
+ UNITY_BRANCH
+ if (_EmissionScrollingUseCurve)
+ {
+ #if defined(PROP_EMISSIONSCROLLINGCURVE) || !defined(OPTIMIZER_ENABLED)
+ emissionStrength0 *= UNITY_SAMPLE_TEX2D_SAMPLER(_EmissionScrollingCurve, _MainTex, TRANSFORM_TEX(poiMesh.uv[_EmissionMapUV], _EmissionScrollingCurve) + (dot(pos, _EmissiveScroll_Direction.xyz) * _EmissiveScroll_Interval) + _Time.x * _EmissiveScroll_Velocity).r;
+ #endif
+ }
+ else
+ {
+ emissionStrength0 *= calculateScrollingEmission(_EmissiveScroll_Direction.xyz, _EmissiveScroll_Velocity, _EmissiveScroll_Interval, _EmissiveScroll_Width, _EmissionScrollingOffset, pos);
+ }
+ }
+
+ UNITY_BRANCH
+ if (_EmissionBlinkingEnabled)
+ {
+ emissionStrength0 *= calculateBlinkingEmission(_EmissiveBlink_Min, _EmissiveBlink_Max, _EmissiveBlink_Velocity, _EmissionBlinkingOffset);
+ }
+
+ emissionColor0 = hueShift(emissionColor0, frac(_EmissionHueShift + _EmissionHueShiftSpeed * _Time.x) * _EmissionHueShiftEnabled);
+
+ #if defined(PROP_EMISSIONMASK) || !defined(OPTIMIZER_ENABLED)
+ float emissionMask0 = UNITY_SAMPLE_TEX2D_SAMPLER(_EmissionMask, _MainTex, TRANSFORM_TEX(poiMesh.uv[_EmissionMaskUV], _EmissionMask) + _Time.x * _EmissionMaskPan).r;
+ #else
+ float emissionMask0 = 1;
+ #endif
+
+ #ifdef POI_BLACKLIGHT
+ if (_BlackLightMaskEmission != 4)
+ {
+ emissionMask0 *= blackLightMask[_BlackLightMaskEmission];
+ }
+ #endif
+
+ emissionStrength0 *= glowInTheDarkMultiplier0 * emissionMask0;
+ emission0 = emissionStrength0 * emissionColor0;
+
+ #ifdef POI_DISSOLVE
+ UNITY_BRANCH
+ if (_DissolveEmissionSide != 2)
+ {
+ emission0 *= lerp(1 - dissolveAlpha, dissolveAlpha, _DissolveEmissionSide);
+ }
+ #endif
+
+ // Second Emission
+ float3 emission1 = 0;
+ float emissionStrength1 = 0;
+ float3 emissionColor1 = 0;
+
+ #ifdef EFFECT_HUE_VARIATION
+ emissionStrength1 = _EmissionStrength1;
+
+ #ifdef POI_AUDIOLINK
+ UNITY_BRANCH
+ if (poiMods.audioLinkTextureExists)
+ {
+ UNITY_BRANCH
+ if (_EnableEmission1StrengthAudioLink)
+ {
+ emissionStrength1 *= poiMods.audioLink[_AudioLinkEmission1StrengthBand];
+ }
+ UNITY_BRANCH
+ if (_EnableEmission1CenterOutAudioLink)
+ {
+ emissionStrength1 *= getBandAtTime(_AudioLinkEmission1CenterOutBand, saturate(1 - poiLight.nDotV), _Emission1CenterOutAudioLinkWidth);
+ }
+ emissionStrength1 += lerp(_EmissionCenterOutAddAudioLink1.x, _EmissionCenterOutAddAudioLink1.y, getBandAtTime(_AudioLinkEmission1CenterOutAddBand, saturate(1 - poiLight.nDotV), _Emission1CenterOutAddAudioLinkwidth));
+ emissionStrength1 += lerp(_AudioLinkAddEmission1.x, _AudioLinkAddEmission1.y, poiMods.audioLink[_AudioLinkAddEmission1Band]);
+ emissionStrength1 = max(emissionStrength1, 0);
+ }
+ #endif
+
+ float glowInTheDarkMultiplier1 = calculateGlowInTheDark(_GITDEMinLight1, _GITDEMaxLight1, _GITDEMinEmissionMultiplier1, _GITDEMaxEmissionMultiplier1, _EnableGITDEmission1, _GITDEWorldOrMesh1);
+ #if defined(PROP_EMISSIONMAP1) || !defined(OPTIMIZER_ENABLED)
+
+ UNITY_BRANCH
+ if (!_EmissionCenterOutEnabled1)
+ {
+ emissionColor1 = POI2D_SAMPLER_PAN(_EmissionMap1, _MainTex, poiMesh.uv[_EmissionMap1UV], _EmissionMap1Pan) * lerp(1, baseColor, _EmissionBaseColorAsMap1).rgb * _EmissionColor1.rgb;
+ }
+ else
+ {
+ emissionColor1 = UNITY_SAMPLE_TEX2D_SAMPLER(_EmissionMap1, _MainTex, ((.5 + poiLight.nDotV * .5) * _EmissionMap1_ST.xy) + _Time.x * _EmissionCenterOutSpeed1).rgb * lerp(1, baseColor, _EmissionBaseColorAsMap1).rgb * _EmissionColor1.rgb;
+ }
+ #else
+ emissionColor1 = lerp(1, baseColor, _EmissionBaseColorAsMap1).rgb * _EmissionColor1.rgb;;
+ #endif
+ UNITY_BRANCH
+ if (_ScrollingEmission1)
+ {
+ float3 pos1 = poiMesh.localPos;
+ UNITY_BRANCH
+ if (_EmissionScrollingVertexColor1)
+ {
+ pos1 = poiMesh.vertexColor.rgb;
+ }
+
+ UNITY_BRANCH
+ if (_EmissionScrollingUseCurve1)
+ {
+ #if defined(PROP_EMISSIONSCROLLINGCURVE1) || !defined(OPTIMIZER_ENABLED)
+ emissionStrength1 *= UNITY_SAMPLE_TEX2D_SAMPLER(_EmissionScrollingCurve1, _MainTex, TRANSFORM_TEX(poiMesh.uv[_EmissionMap1UV], _EmissionScrollingCurve1) + (dot(pos1, _EmissiveScroll_Direction1) * _EmissiveScroll_Interval1) + _Time.x * _EmissiveScroll_Velocity1);
+ #endif
+ }
+ else
+ {
+ emissionStrength1 *= calculateScrollingEmission(_EmissiveScroll_Direction1, _EmissiveScroll_Velocity1, _EmissiveScroll_Interval1, _EmissiveScroll_Width1, _EmissionScrollingOffset1, pos1);
+ }
+ }
+ UNITY_BRANCH
+ if (_EmissionBlinkingEnabled1)
+ {
+ emissionStrength1 *= calculateBlinkingEmission(_EmissiveBlink_Min1, _EmissiveBlink_Max1, _EmissiveBlink_Velocity1, _EmissionBlinkingOffset1);
+ }
+
+ emissionColor1 = hueShift(emissionColor1, frac(_EmissionHueShift1 + _EmissionHueShiftSpeed1 * _Time.x) * _EmissionHueShiftEnabled1);
+ #if defined(PROP_EMISSIONMASK1) || !defined(OPTIMIZER_ENABLED)
+ float emissionMask1 = UNITY_SAMPLE_TEX2D_SAMPLER(_EmissionMask1, _MainTex, TRANSFORM_TEX(poiMesh.uv[_EmissionMask1UV], _EmissionMask1) + _Time.x * _EmissionMask1Pan);
+ #else
+ float emissionMask1 = 1;
+ #endif
+
+ #ifdef POI_BLACKLIGHT
+ if (_BlackLightMaskEmission2 != 4)
+ {
+ emissionMask1 *= blackLightMask[_BlackLightMaskEmission2];
+ }
+ #endif
+ emissionStrength1 *= glowInTheDarkMultiplier1 * emissionMask1;
+ emission1 = emissionStrength1 * emissionColor1;
+
+ #ifdef POI_DISSOLVE
+ if (_DissolveEmission1Side != 2)
+ {
+ emission1 *= lerp(1 - dissolveAlpha, dissolveAlpha, _DissolveEmission1Side);
+ }
+ #endif
+ #endif
+ finalColor.rgb = lerp(finalColor.rgb, saturate(emissionColor0 + emissionColor1), saturate(emissionStrength0 + emissionStrength1) * _EmissionReplace * poiMax(emission0 + emission1));
+
+ return emission0 + emission1;
+}
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiEmission.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiEmission.cginc.meta
new file mode 100644
index 00000000..db647b30
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiEmission.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: fb39e9f722d93614d8bb1b9b708f60e6
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiEnvironmentalRimLighting.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiEnvironmentalRimLighting.cginc
new file mode 100644
index 00000000..92ed124a
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiEnvironmentalRimLighting.cginc
@@ -0,0 +1,48 @@
+#ifndef POI_ENVIRONMENTAL_RIM
+ #define POI_ENVIRONMENTAL_RIM
+
+ //enviro rim
+ float _EnableEnvironmentalRim;
+ float _RimEnviroBlur;
+ float _RimEnviroMinBrightness;
+ float _RimEnviroWidth;
+ float _RimEnviroSharpness;
+ float _RimEnviroIntensity;
+ #if defined(PROP_RIMENVIROMASK) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_RimEnviroMask);
+ #endif
+
+ float3 calculateEnvironmentalRimLighting(in float4 albedo)
+ {
+ float enviroRimAlpha = saturate(1 - smoothstep(min(_RimEnviroSharpness, _RimEnviroWidth), _RimEnviroWidth, poiCam.viewDotNormal));
+ _RimEnviroBlur *= 1.7 - 0.7 * _RimEnviroBlur;
+
+ float3 enviroRimColor = 0;
+ float interpolator = unity_SpecCube0_BoxMin.w;
+ UNITY_BRANCH
+ if (interpolator < 0.99999)
+ {
+ //Probe 1
+ float4 reflectionData0 = UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0, poiMesh.normals[1], _RimEnviroBlur * UNITY_SPECCUBE_LOD_STEPS);
+ float3 reflectionColor0 = DecodeHDR(reflectionData0, unity_SpecCube0_HDR);
+
+ //Probe 2
+ float4 reflectionData1 = UNITY_SAMPLE_TEXCUBE_SAMPLER_LOD(unity_SpecCube1, unity_SpecCube0, poiMesh.normals[1], _RimEnviroBlur * UNITY_SPECCUBE_LOD_STEPS);
+ float3 reflectionColor1 = DecodeHDR(reflectionData1, unity_SpecCube1_HDR);
+
+ enviroRimColor = lerp(reflectionColor1, reflectionColor0, interpolator);
+ }
+ else
+ {
+ float4 reflectionData = UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0, poiMesh.normals[1], _RimEnviroBlur * UNITY_SPECCUBE_LOD_STEPS);
+ enviroRimColor = DecodeHDR(reflectionData, unity_SpecCube0_HDR);
+ }
+ #if defined(PROP_RIMENVIROMASK) || !defined(OPTIMIZER_ENABLED)
+ half enviroMask = poiMax(POI2D_SAMPLER_PAN(_RimEnviroMask, _MainTex, poiMesh.uv[_RimEnviroMaskUV], _RimEnviroMaskPan).rgb);
+ #else
+ half enviroMask = 1;
+ #endif
+ return lerp(0, max(0, (enviroRimColor - _RimEnviroMinBrightness) * albedo.rgb), enviroRimAlpha).rgb * enviroMask * _RimEnviroIntensity;
+ }
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiEnvironmentalRimLighting.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiEnvironmentalRimLighting.cginc.meta
new file mode 100644
index 00000000..2fab05f3
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiEnvironmentalRimLighting.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: a1c11292ccd8b1d41887e0f69e6695dd
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiFlipbook.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiFlipbook.cginc
new file mode 100644
index 00000000..f600ced0
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiFlipbook.cginc
@@ -0,0 +1,221 @@
+#ifndef POI_FLIPBOOK
+#define POI_FLIPBOOK
+
+#if defined(PROP_FLIPBOOKTEXARRAY) || !defined(OPTIMIZER_ENABLED)
+ UNITY_DECLARE_TEX2DARRAY(_FlipbookTexArray); float4 _FlipbookTexArray_ST;
+#endif
+#if defined(PROP_FLIPBOOKMASK) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_FlipbookMask);
+#endif
+
+float4 _FlipbookColor;
+float _FlipbookFPS;
+float _FlipbookTotalFrames;
+float4 _FlipbookScaleOffset;
+float _FlipbookTiled;
+float _FlipbookCurrentFrame;
+float _FlipbookEmissionStrength;
+float _FlipbookRotation;
+float _EnableFlipbook;
+float _FlipbookTexArrayUV;
+float _FlipbookAlphaControlsFinalAlpha;
+float _FlipbookRotationSpeed;
+float _FlipbookIntensityControlsAlpha;
+float _FlipbookColorReplaces;
+float2 _FlipbookTexArrayPan;
+
+// blending
+float _FlipbookReplace;
+float _FlipbookMultiply;
+float _FlipbookAdd;
+
+// anim
+float _FlipbookMovementType;
+float4 _FlipbookStartEndOffset;
+float _FlipbookMovementSpeed;
+
+// Crossfade
+float _FlipbookCrossfadeEnabled;
+float2 _FlipbookCrossfadeRange;
+
+float _FlipbookHueShiftEnabled;
+float _FlipbookHueShiftSpeed;
+float _FlipbookHueShift;
+// Global
+float4 flipBookPixel;
+float4 flipBookPixelMultiply;
+float flipBookMask;
+
+// Audio Link
+half _AudioLinkFlipbookScaleBand;
+half4 _AudioLinkFlipbookScale;
+half _AudioLinkFlipbookAlphaBand;
+half2 _AudioLinkFlipbookAlpha;
+half _AudioLinkFlipbookEmissionBand;
+half2 _AudioLinkFlipbookEmission;
+half _AudioLinkFlipbookFrameBand;
+half2 _AudioLinkFlipbookFrame;
+
+#ifndef POI_SHADOW
+
+ void applyFlipbook(inout float4 finalColor, inout float3 flipbookEmission)
+ {
+
+ #if defined(PROP_FLIPBOOKMASK) || !defined(OPTIMIZER_ENABLED)
+ flipBookMask = POI2D_SAMPLER_PAN(_FlipbookMask, _MainTex, poiMesh.uv[_FlipbookMaskUV], _FlipbookMaskPan).r;
+ #else
+ flipBookMask = 1;
+ #endif
+ float4 flipbookScaleOffset = _FlipbookScaleOffset;
+
+ #ifdef POI_AUDIOLINK
+ flipbookScaleOffset.xy += lerp(_AudioLinkFlipbookScale.xy, _AudioLinkFlipbookScale.zw, poiMods.audioLink[_AudioLinkFlipbookScaleBand]);
+ #endif
+
+ flipbookScaleOffset.xy = 1 - flipbookScaleOffset.xy;
+ float2 uv = frac(poiMesh.uv[_FlipbookTexArrayUV]);
+ float theta = radians(_FlipbookRotation + _Time.z * _FlipbookRotationSpeed);
+ float cs = cos(theta);
+ float sn = sin(theta);
+ float2 spriteCenter = flipbookScaleOffset.zw + .5;
+ // 2d rotation
+ uv = float2((uv.x - spriteCenter.x) * cs - (uv.y - spriteCenter.y) * sn + spriteCenter.x, (uv.x - spriteCenter.x) * sn + (uv.y - spriteCenter.y) * cs + spriteCenter.y);
+
+ float2 newUV = remap(uv, float2(0, 0) + flipbookScaleOffset.xy / 2 + flipbookScaleOffset.zw, float2(1, 1) - flipbookScaleOffset.xy / 2 + flipbookScaleOffset.zw, float2(0, 0), float2(1, 1));
+
+ UNITY_BRANCH
+ if (_FlipbookTiled == 0)
+ {
+ if (max(newUV.x, newUV.y) > 1 || min(newUV.x, newUV.y) < 0)
+ {
+ flipBookPixel = 0;
+ return;
+ }
+ }
+ #if defined(PROP_FLIPBOOKTEXARRAY) || !defined(OPTIMIZER_ENABLED)
+ float currentFrame = fmod(_FlipbookCurrentFrame, _FlipbookTotalFrames);
+ if (_FlipbookCurrentFrame < 0)
+ {
+ currentFrame = (_Time.y / (1 / _FlipbookFPS)) % _FlipbookTotalFrames;
+ }
+ #ifdef POI_AUDIOLINK
+ currentFrame += lerp(_AudioLinkFlipbookFrame.x, _AudioLinkFlipbookFrame.y, poiMods.audioLink[_AudioLinkFlipbookFrameBand]);
+ #endif
+ flipBookPixel = UNITY_SAMPLE_TEX2DARRAY(_FlipbookTexArray, float3(TRANSFORM_TEX(newUV, _FlipbookTexArray) + _Time.x * _FlipbookTexArrayPan, floor(currentFrame)));
+ UNITY_BRANCH
+ if (_FlipbookCrossfadeEnabled)
+ {
+ float4 flipbookNextPixel = UNITY_SAMPLE_TEX2DARRAY(_FlipbookTexArray, float3(TRANSFORM_TEX(newUV, _FlipbookTexArray) + _Time.x * _FlipbookTexArrayPan, floor((currentFrame + 1) % _FlipbookTotalFrames)));
+ flipBookPixel = lerp(flipBookPixel, flipbookNextPixel, smoothstep(_FlipbookCrossfadeRange.x, _FlipbookCrossfadeRange.y, frac(currentFrame)));
+ }
+ #else
+ flipBookPixel = 1;
+ #endif
+
+ UNITY_BRANCH
+ if (_FlipbookIntensityControlsAlpha)
+ {
+ flipBookPixel.a = poiMax(flipBookPixel.rgb);
+ }
+ UNITY_BRANCH
+ if (_FlipbookColorReplaces)
+ {
+ flipBookPixel.rgb = _FlipbookColor.rgb;
+ }
+ else
+ {
+ flipBookPixel.rgb *= _FlipbookColor.rgb;
+ }
+
+ #ifdef POI_BLACKLIGHT
+ UNITY_BRANCH
+ if (_BlackLightMaskFlipbook != 4)
+ {
+ flipBookMask *= blackLightMask[_BlackLightMaskFlipbook];
+ }
+ #endif
+
+ UNITY_BRANCH
+ if (_FlipbookHueShiftEnabled)
+ {
+ flipBookPixel.rgb = hueShift(flipBookPixel.rgb, _FlipbookHueShift + _Time.x * _FlipbookHueShiftSpeed);
+ }
+ half flipbookAlpha = 1;
+ #ifdef POI_AUDIOLINK
+ flipbookAlpha = saturate(lerp(_AudioLinkFlipbookAlpha.x, _AudioLinkFlipbookAlpha.y, poiMods.audioLink[_AudioLinkFlipbookAlphaBand]));
+ #endif
+
+ finalColor.rgb = lerp(finalColor.rgb, flipBookPixel.rgb, flipBookPixel.a * _FlipbookColor.a * _FlipbookReplace * flipBookMask * flipbookAlpha);
+ finalColor.rgb = finalColor + flipBookPixel.rgb * _FlipbookAdd * flipBookMask * flipbookAlpha;
+ finalColor.rgb = finalColor * lerp(1, flipBookPixel.rgb, flipBookPixel.a * _FlipbookColor.a * flipBookMask * _FlipbookMultiply * flipbookAlpha);
+
+ UNITY_BRANCH
+ if (_FlipbookAlphaControlsFinalAlpha)
+ {
+ finalColor.a = lerp(finalColor.a, flipBookPixel.a * _FlipbookColor.a, flipBookMask);
+ }
+ float flipbookEmissionStrength = _FlipbookEmissionStrength;
+ #ifdef POI_AUDIOLINK
+ flipbookEmissionStrength += max(lerp(_AudioLinkFlipbookEmission.x, _AudioLinkFlipbookEmission.y, poiMods.audioLink[_AudioLinkFlipbookEmissionBand]), 0);
+ #endif
+ flipbookEmission = lerp(0, flipBookPixel.rgb * flipbookEmissionStrength, flipBookPixel.a * _FlipbookColor.a * flipBookMask * flipbookAlpha);
+ }
+
+#else
+
+ float applyFlipbookAlphaToShadow(float2 uv)
+ {
+ UNITY_BRANCH
+ if (_FlipbookAlphaControlsFinalAlpha)
+ {
+ float flipbookShadowAlpha = 0;
+
+ float4 flipbookScaleOffset = _FlipbookScaleOffset;
+ flipbookScaleOffset.xy = 1 - flipbookScaleOffset.xy;
+ float theta = radians(_FlipbookRotation);
+
+ float cs = cos(theta);
+ float sn = sin(theta);
+ float2 spriteCenter = flipbookScaleOffset.zw + .5;
+ uv = float2((uv.x - spriteCenter.x) * cs - (uv.y - spriteCenter.y) * sn + spriteCenter.x, (uv.x - spriteCenter.x) * sn + (uv.y - spriteCenter.y) * cs + spriteCenter.y);
+
+ float2 newUV = remap(uv, float2(0, 0) + flipbookScaleOffset.xy / 2 + flipbookScaleOffset.zw, float2(1, 1) - flipbookScaleOffset.xy / 2 + flipbookScaleOffset.zw, float2(0, 0), float2(1, 1));
+
+ #if defined(PROP_FLIPBOOKTEXARRAY) || !defined(OPTIMIZER_ENABLED)
+ float currentFrame = fmod(_FlipbookCurrentFrame, _FlipbookTotalFrames);
+ if (_FlipbookCurrentFrame < 0)
+ {
+ currentFrame = (_Time.y / (1 / _FlipbookFPS)) % _FlipbookTotalFrames;
+ }
+
+ half4 flipbookColor = UNITY_SAMPLE_TEX2DARRAY(_FlipbookTexArray, float3(TRANSFORM_TEX(newUV, _FlipbookTexArray) + _Time.x * _FlipbookTexArrayPan, floor(currentFrame)));
+ UNITY_BRANCH
+ if (_FlipbookCrossfadeEnabled)
+ {
+ float4 flipbookNextPixel = UNITY_SAMPLE_TEX2DARRAY(_FlipbookTexArray, float3(TRANSFORM_TEX(newUV, _FlipbookTexArray) + _Time.x * _FlipbookTexArrayPan, floor((currentFrame + 1) % _FlipbookTotalFrames)));
+ flipbookColor = lerp(flipbookColor, flipbookNextPixel, smoothstep(_FlipbookCrossfadeRange.x, _FlipbookCrossfadeRange.y, frac(currentFrame)));
+ }
+ #else
+ half4 flipbookColor = 1;
+ #endif
+
+ if (_FlipbookIntensityControlsAlpha)
+ {
+ flipbookColor.a = poiMax(flipbookColor.rgb);
+ }
+
+ UNITY_BRANCH
+ if (_FlipbookTiled == 0)
+ {
+ if (max(newUV.x, newUV.y) > 1 || min(newUV.x, newUV.y) < 0)
+ {
+ flipbookColor.a = 0;
+ }
+ }
+ return flipbookColor.a * _FlipbookColor.a;
+ }
+ return 1;
+ }
+
+#endif
+#endif
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiFlipbook.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiFlipbook.cginc.meta
new file mode 100644
index 00000000..c3c259f1
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiFlipbook.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 87a9dab4f8128cd41bf38bac18075b14
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiFrag.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiFrag.cginc
new file mode 100644
index 00000000..a852d5f0
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiFrag.cginc
@@ -0,0 +1,422 @@
+#ifndef POIFRAG
+#define POIFRAG
+
+float _MainEmissionStrength;
+float _IgnoreFog;
+half _GIEmissionMultiplier;
+float _IridescenceTime;
+float _AlphaToMask;
+float _ForceOpaque;
+float _commentIfZero_EnableGrabpass;
+float _AlphaPremultiply;
+float2 _MainTexPan;
+float _MainTextureUV;
+float _LightingAdditiveEnable;
+
+// Post Processing
+float _PPLightingMultiplier;
+float _PPEmissionMultiplier;
+
+float4 frag(v2f i, uint facing: SV_IsFrontFace): SV_Target
+{
+ #ifdef FORWARD_ADD_PASS
+ #if !defined(POI_LIGHTING)
+ return 0;
+ #endif
+ UNITY_BRANCH
+ if (_LightingAdditiveEnable == 0)
+ {
+ return 0;
+ }
+ #endif
+ UNITY_SETUP_INSTANCE_ID(i);
+ // Color
+ float4 albedo = 1;
+ float4 finalColor = 1;
+
+ // Lighting
+ float bakedCubemap = 0; // Whether or not metallic should run before or after lighting multiplication
+ float3 finalSpecular0 = 0;
+ float3 finalSpecular1 = 0;
+ float3 finalSSS = 0;
+ fixed lightingAlpha = 1;
+ float3 finalEnvironmentalRim = 0;
+
+ // Emissions
+ float3 finalEmission = 0;
+ float3 finalLighting = 1;
+ float3 emissionLighting = 1;
+ float3 IridescenceEmission = 0;
+ float3 spawnInEmission = 0;
+ float3 voronoiEmission = 0;
+ float3 matcapEmission = 0;
+ float3 depthTouchEmission = 0;
+ float3 decalEmission = 0;
+ float3 glitterEmission = 0;
+ float3 panosphereEmission = 0;
+ float3 backFaceEmission = 0;
+ float3 dissolveEmission = 0;
+ float3 rimLightEmission = 0;
+ float3 flipbookEmission = 0;
+ float3 textOverlayEmission = 0;
+ float3 videoEmission = 0;
+ float3 pathEmission = 0;
+ /**********************************************************************
+ Initialize the base data that's needed everywhere else in the shader
+ **********************************************************************/
+ calculateAttenuation(i);
+ InitializeMeshData(i, facing);
+ initializeCamera(i);
+ calculateTangentData();
+
+
+ #ifdef POI_BLACKLIGHT
+ createBlackLightMask();
+ UNITY_BRANCH
+ if (_BlackLightMaskDebug)
+ {
+ return float4(blackLightMask.rgb, 1);
+ }
+ #endif
+
+ // This has to happen in the initializbecause it alters UV data globally
+ #ifdef POI_PARALLAX
+ calculateandApplyParallax();
+ #endif
+
+ // Basically every texture relies on the maintex sampler to function and that's why this is here.
+ float4 mainTexture = UNITY_SAMPLE_TEX2D(_MainTex, TRANSFORM_TEX(poiMesh.uv[_MainTextureUV], _MainTex) + _Time.x * _MainTexPan);
+ half3 detailMask = 1;
+ calculateNormals(detailMask);
+
+ //return float4(poiMesh.binormal.xyz, 1);
+ calculateVertexLightingData(i);
+ /**********************************************************************
+ Calculate Light Maps
+ **********************************************************************/
+ #ifdef POI_DATA
+ calculateLightingData(i);
+ #endif
+ #ifdef POI_LIGHTING
+ calculateBasePassLightMaps();
+ #endif
+
+ /**********************************************************************
+ Calculate Color Data
+ **********************************************************************/
+
+ initTextureData(albedo, mainTexture, backFaceEmission, dissolveEmission, detailMask);
+
+ #ifdef POI_PATHING
+ applyPathing(albedo, pathEmission);
+ #endif
+
+ #ifdef POI_DECAL
+ applyDecals(albedo, decalEmission);
+ #endif
+
+
+ #ifdef POI_IRIDESCENCE
+ UNITY_BRANCH
+ if (_IridescenceTime == 0)
+ {
+ applyIridescence(albedo, IridescenceEmission);
+ }
+ #endif
+
+ #ifdef POI_VORONOI
+ applyVoronoi(albedo, voronoiEmission);
+ #endif
+
+ #ifdef POI_MSDF
+ ApplyTextOverlayColor(albedo, textOverlayEmission);
+ #endif
+
+ #ifdef POI_ENVIRONMENTAL_RIM
+ finalEnvironmentalRim = calculateEnvironmentalRimLighting(albedo);
+ #endif
+
+ #if defined(POI_METAL) || defined(POI_CLEARCOAT)
+ CalculateReflectionData();
+ #endif
+
+ #ifdef POI_DATA
+ distanceFade(albedo);
+ #endif
+
+ #ifdef POI_RANDOM
+ albedo.a *= i.angleAlpha;
+ #endif
+
+ #ifdef MATCAP
+ applyMatcap(albedo, matcapEmission);
+ #endif
+
+ #ifdef PANOSPHERE
+ applyPanosphereColor(albedo, panosphereEmission);
+ #endif
+
+ #ifdef POI_FLIPBOOK
+ applyFlipbook(albedo, flipbookEmission);
+ #endif
+
+ #ifdef POI_GLITTER
+ applyGlitter(albedo, glitterEmission);
+ #endif
+
+ #ifdef POI_RIM
+ applyRimLighting(albedo, rimLightEmission);
+ #endif
+
+ #ifdef POI_DEPTH_COLOR
+ applyDepthColor(albedo, depthTouchEmission, finalEmission, i.worldDirection);
+ #endif
+
+ #ifdef POI_IRIDESCENCE
+ UNITY_BRANCH
+ if (_IridescenceTime == 1)
+ {
+ applyIridescence(albedo, IridescenceEmission);
+ }
+ #endif
+
+ #ifdef POI_VIDEO
+ applyScreenEffect(albedo, videoEmission);
+ #endif
+
+ applySpawnIn(albedo, spawnInEmission, poiMesh.uv[0], poiMesh.localPos);
+
+ /**********************************************************************
+ Handle a few alpha options
+ **********************************************************************/
+ UNITY_BRANCH
+ if (_Mode == 1)
+ {
+ UNITY_BRANCH
+ if (_AlphaToMask == 0)
+ {
+ applyDithering(albedo);
+ }
+ }
+
+ albedo.a = max(_ForceOpaque, albedo.a);
+
+ UNITY_BRANCH
+ if (_Mode == 0)
+ {
+ albedo.a = 1;
+ }
+
+ UNITY_BRANCH
+ if (_Mode >= 1)
+ {
+ clip(albedo.a - _Cutoff);
+ }
+
+ UNITY_BRANCH
+ if (_AlphaPremultiply)
+ {
+ albedo.rgb *= saturate(albedo.a + 0.0000000001);
+ }
+
+ /**********************************************************************
+ Lighting Time :)
+ **********************************************************************/
+
+ #ifdef POI_LIGHTING
+ finalLighting = calculateFinalLighting(albedo.rgb, finalColor);
+ finalLighting = max(finalLighting *= _PPLightingMultiplier, 0);
+
+ if (!_LightingUncapped)
+ {
+ finalLighting = saturate(finalLighting);
+ }
+
+ #ifdef SUBSURFACE
+ finalSSS = calculateSubsurfaceScattering();
+ //finalSSS = calculateSubsurfaceScattering(albedo);
+ #endif
+ #endif
+
+ float4 finalColorBeforeLighting = albedo;
+ finalColor = finalColorBeforeLighting;
+
+ #ifdef POI_SPECULAR
+ finalSpecular0 = calculateSpecular(finalColorBeforeLighting);
+ #endif
+ #ifdef POI_PARALLAX
+ calculateAndApplyInternalParallax(finalColor);
+ #endif
+
+ #ifdef POI_ALPHA_TO_COVERAGE
+ ApplyAlphaToCoverage(finalColor);
+ #endif
+
+ UNITY_BRANCH
+ if (_Mode == 1)
+ {
+ UNITY_BRANCH
+ if (_AlphaToMask == 1)
+ {
+ applyDithering(finalColor);
+ }
+ }
+
+
+ #ifdef POI_METAL
+ calculateMetallicness();
+ bool probeExists = shouldMetalHappenBeforeLighting();
+ UNITY_BRANCH
+ if (!probeExists)
+ {
+ ApplyMetallicsFake(finalColor, albedo);
+ }
+ #endif
+
+
+ #ifdef POI_LIGHTING
+ emissionLighting = finalLighting;
+ #if defined(FORWARD_ADD_PASS) && defined(POI_METAL)
+ finalLighting *= 1 - metalicMap;
+ #endif
+ applyLighting(finalColor, finalLighting);
+ #endif
+
+ #ifdef POI_BRDF
+ poiBRDF(finalColor, finalColorBeforeLighting);
+ #endif
+
+ #ifdef POI_METAL
+ UNITY_BRANCH
+ if (probeExists)
+ {
+ ApplyMetallics(finalColor, albedo);
+ }
+ #endif
+
+ finalColor.rgb += finalSpecular0 + finalEnvironmentalRim + finalSSS;
+
+ #ifdef FORWARD_BASE_PASS
+ #ifdef POI_CLEARCOAT
+ calculateAndApplyClearCoat(finalColor);
+ #endif
+ #endif
+
+ finalColor.a = saturate(finalColor.a);
+
+ /**********************************************************************
+ Add Up all the emission values :D
+ **********************************************************************/
+ //#if defined(FORWARD_BASE_PASS) || defined(POI_META_PASS)
+ finalEmission += finalColorBeforeLighting.rgb * _MainEmissionStrength * albedo.a;
+ finalEmission += wireframeEmission;
+ finalEmission += IridescenceEmission;
+ finalEmission += spawnInEmission;
+ finalEmission += voronoiEmission;
+ finalEmission += matcapEmission;
+ finalEmission += depthTouchEmission;
+ finalEmission += decalEmission;
+ finalEmission += glitterEmission;
+ finalEmission += panosphereEmission;
+ finalEmission += backFaceEmission;
+ finalEmission += rimLightEmission;
+ finalEmission += flipbookEmission;
+ finalEmission += videoEmission;
+ finalEmission += textOverlayEmission;
+ finalEmission += dissolveEmission;
+ finalEmission += pathEmission;
+ #ifdef POI_EMISSION
+ finalEmission += calculateEmissionNew(finalColorBeforeLighting.rgb, finalColor);
+ #endif
+
+ finalEmission = max(finalEmission * _PPEmissionMultiplier, 0);
+
+ //#endif
+ // Compensate for HDR lights
+ #if defined(FORWARD_ADD_PASS)
+ finalEmission *= emissionLighting; // TODO: add in vertex lights
+ #else
+ finalEmission *= max(1, emissionLighting);
+ #endif
+
+ /**********************************************************************
+ Meta Pass Hype :D
+ **********************************************************************/
+ #ifdef POI_META_PASS
+ UnityMetaInput meta;
+ UNITY_INITIALIZE_OUTPUT(UnityMetaInput, meta);
+ meta.Emission = finalEmission * _GIEmissionMultiplier;
+ meta.Albedo = saturate(finalColor.rgb);
+ #ifdef POI_SPECULAR
+ meta.SpecularColor = poiLight.color.rgb * _SpecularTint.rgb * lerp(1, albedo.rgb, _SpecularMetallic) * _SpecularTint.a;
+ #else
+ meta.SpecularColor = poiLight.color.rgb * albedo.rgb;
+ #endif
+ return UnityMetaFragment(meta);
+ #endif
+
+ /**********************************************************************
+ Apply Emission to finalColor
+ **********************************************************************/
+ finalColor.rgb += finalEmission;
+
+ /**********************************************************************
+ Grabpass features
+ **********************************************************************/
+
+ UNITY_BRANCH
+ if (_commentIfZero_EnableGrabpass)
+ {
+ applyGrabEffects(finalColor);
+ }
+
+ /**********************************************************************
+ Unity Fog
+ **********************************************************************/
+ #ifdef FORWARD_BASE_PASS
+ UNITY_BRANCH
+ if (_IgnoreFog == 0)
+ {
+ UNITY_APPLY_FOG(i.fogCoord, finalColor);
+ }
+ #endif
+
+ #ifdef FORWARD_ADD_PASS
+ if (_Mode > 0)
+ {
+ finalColor.rgb *= finalColor.a;
+ }
+ #endif
+
+ UNITY_BRANCH
+ if (_Mode == 0)
+ {
+ finalColor.a = 1;
+ }
+
+ #ifdef FORWARD_ADD_PASS
+ //finalColor.rgb = smoothstep(_LightingAdditiveGradientStart, _LightingAdditiveGradientEnd, 1 - (.5 * poiLight.nDotL + .5));
+ #endif
+
+ #ifdef POI_DEBUG
+ displayDebugInfo(finalColor);
+ #endif
+
+ #ifdef POI_AUDIOLINK
+ UNITY_BRANCH
+ if (_AudioLinkTextureVisualization)
+ {
+ finalColor = poiMods.audioLinkTexture;
+ }
+ #endif
+
+ #ifdef FORWARD_ADD_PASS
+ #if defined(_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A) && defined(DIRECTIONAL)
+ return finalColor + albedo * 0.00001;;
+ #endif
+ #endif
+
+ //finalColor.rgb = frac(finalColor.rgb);
+ return finalColor + mainTexture * 0.00001;
+}
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiFrag.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiFrag.cginc.meta
new file mode 100644
index 00000000..1469bed5
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiFrag.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 60cd78e9ddf39f8488c9f5574a8a5a7b
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiGlitter.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiGlitter.cginc
new file mode 100644
index 00000000..fead7309
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiGlitter.cginc
@@ -0,0 +1,274 @@
+#ifndef POI_GLITTER
+ #define POI_GLITTER
+
+ half3 _GlitterColor;
+ float2 _GlitterPan;
+ half _GlitterSpeed;
+ half _GlitterBrightness;
+ float _GlitterFrequency;
+ float _GlitterJitter;
+ half _GlitterSize;
+ half _GlitterContrast;
+ half _GlitterAngleRange;
+ half _GlitterMinBrightness;
+ half _GlitterBias;
+ float _GlitterRandomColors;
+ float2 _GlitterMinMaxSaturation;
+ float2 _GlitterMinMaxBrightness;
+ fixed _GlitterUseSurfaceColor;
+ float _GlitterBlendType;
+ float _GlitterMode;
+ float _GlitterShape;
+ float _GlitterCenterSize;
+ float _glitterFrequencyLinearEmissive;
+ float _GlitterJaggyFix;
+ float _GlitterRandomRotation;
+ float _GlitterTextureRotation;
+ float4 _GlitterMinMaxSize;
+ float _GlitterRandomSize;
+ float2 _GlitterUVPanning;
+
+ float _GlitterHueShiftEnabled;
+ float _GlitterHueShiftSpeed;
+ float _GlitterHueShift;
+ float _GlitterHideInShadow;
+
+ #if defined(PROP_GLITTERMASK) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_GlitterMask);
+ #endif
+ #if defined(PROP_GLITTERCOLORMAP) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_GlitterColorMap);
+ #endif
+ #if defined(PROP_GLITTERTEXTURE) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_GlitterTexture);
+ #endif
+
+ float3 randomFloat3(float2 Seed, float maximum)
+ {
+ return(.5 + float3(
+ frac(sin(dot(Seed.xy, float2(12.9898, 78.233))) * 43758.5453),
+ frac(sin(dot(Seed.yx, float2(12.9898, 78.233))) * 43758.5453),
+ frac(sin(dot(float2(Seed), float2(12.9898, 78.233))) * 43758.5453)
+ ) * .5) * (maximum);
+ }
+
+ float3 randomFloat3Range(float2 Seed, float Range)
+ {
+ return(float3(
+ frac(sin(dot(Seed.xy, float2(12.9898, 78.233))) * 43758.5453),
+ frac(sin(dot(Seed.yx, float2(12.9898, 78.233))) * 43758.5453),
+ frac(sin(dot(float2(Seed.x * Seed.y, Seed.y + Seed.x), float2(12.9898, 78.233))) * 43758.5453)
+ ) * 2 - 1) * Range;
+ }
+
+ float3 randomFloat3WiggleRange(float2 Seed, float Range)
+ {
+ float3 rando = (float3(
+ frac(sin(dot(Seed.xy, float2(12.9898, 78.233))) * 43758.5453),
+ frac(sin(dot(Seed.yx, float2(12.9898, 78.233))) * 43758.5453),
+ frac(sin(dot(float2(Seed.x * Seed.y, Seed.y + Seed.x), float2(12.9898, 78.233))) * 43758.5453)
+ ) * 2 - 1);
+ float speed = 1 + _GlitterSpeed;
+ return float3(sin((_Time.x + rando.x * pi) * speed), sin((_Time.x + rando.y * pi) * speed), sin((_Time.x + rando.z * pi) * speed)) * Range;
+ }
+
+ void Unity_RandomRange_float(float2 Seed, float Min, float Max, out float Out)
+ {
+ float randomno = frac(sin(dot(Seed, float2(12.9898, 78.233))) * 43758.5453);
+ Out = lerp(Min, Max, randomno);
+ }
+
+ float3 RandomColorFromPoint(float2 rando)
+ {
+ fixed hue = random2(rando.x + rando.y).x;
+ fixed saturation = lerp(_GlitterMinMaxSaturation.x, _GlitterMinMaxSaturation.y, rando.x);
+ fixed value = lerp(_GlitterMinMaxBrightness.x, _GlitterMinMaxBrightness.y, rando.y);
+ float3 hsv = float3(hue, saturation, value);
+ return HSVtoRGB(hsv);
+ }
+
+ void applyGlitter(inout float4 albedo, inout float3 glitterEmission)
+ {
+
+
+ // Scale
+ float2 st = frac(poiMesh.uv[0] + _GlitterUVPanning.xy * _Time.x) * _GlitterFrequency;
+
+ // Tile the space
+ float2 i_st = floor(st);
+ float2 f_st = frac(st);
+
+ float m_dist = 10.; // minimun distance
+ float2 m_point = 0; // minimum point
+ float2 randoPoint = 0;
+ float2 dank;
+ for (int j = -1; j <= 1; j ++)
+ {
+ for (int i = -1; i <= 1; i ++)
+ {
+ float2 neighbor = float2(i, j);
+ float2 pos = random2(i_st + neighbor);
+ float2 rando = pos;
+ pos = 0.5 + 0.5 * sin(_GlitterJitter * 6.2831 * pos);
+ float2 diff = neighbor + pos - f_st;
+ float dist = length(diff);
+
+ if (dist < m_dist)
+ {
+ dank = diff;
+ m_dist = dist;
+ m_point = pos;
+ randoPoint = rando;
+ }
+ }
+ }
+
+ float randomFromPoint = random(randoPoint);
+
+ float size = _GlitterSize;
+ UNITY_BRANCH
+ if(_GlitterRandomSize)
+ {
+ size = remapClamped(randomFromPoint, 0, 1, _GlitterMinMaxSize.x, _GlitterMinMaxSize.y);
+ }
+
+
+ // Assign a color using the closest point position
+ //color += dot(m_point, float2(.3, .6));
+
+ // Add distance field to closest point center
+ // color.g = m_dist;
+
+ // Show isolines
+ //color -= abs(sin(40.0 * m_dist)) * 0.07;
+
+ // Draw cell center
+ half glitterAlpha = 1;
+ switch(_GlitterShape)
+ {
+ case 0: //circle
+ glitterAlpha = (1. - step(size, m_dist));
+ break;
+ case 1: //sqaure
+ float jaggyFix = pow(poiCam.distanceToVert, 2) * _GlitterJaggyFix;
+
+ UNITY_BRANCH
+ if (_GlitterRandomRotation == 1 || _GlitterTextureRotation != 0)
+ {
+ float2 center = float2(0, 0);
+ float randomBoy = 0;
+ UNITY_BRANCH
+ if(_GlitterRandomRotation)
+ {
+ randomBoy = random(randoPoint);
+ }
+ float theta = radians((randomBoy + _Time.x * _GlitterTextureRotation) * 360);
+ float cs = cos(theta);
+ float sn = sin(theta);
+ dank = float2((dank.x - center.x) * cs - (dank.y - center.y) * sn + center.x, (dank.x - center.x) * sn + (dank.y - center.y) * cs + center.y);
+ glitterAlpha = (1. - smoothstep(size - .1 * jaggyFix, size, abs(dank.x))) * (1. - smoothstep(size - .1 * jaggyFix, size, abs(dank.y)));
+ }
+ else
+ {
+ glitterAlpha = (1. - smoothstep(size - .1 * jaggyFix, size, abs(dank.x))) * (1. - smoothstep(size - .1 * jaggyFix, size, abs(dank.y)));
+ }
+ break;
+ }
+
+ float3 finalGlitter = 0;
+
+ switch(_GlitterMode)
+ {
+ case 0:
+ float3 randomRotation = 0;
+ UNITY_BRANCH
+ if(_GlitterSpeed > 0)
+ {
+ randomRotation = randomFloat3WiggleRange(randoPoint, _GlitterAngleRange);
+ }
+ else
+ {
+ randomRotation = randomFloat3Range(randoPoint, _GlitterAngleRange);
+ }
+ float3 norm = poiMesh.normals[0];
+
+ float3 glitterReflectionDirection = normalize(mul(poiRotationMatrixFromAngles(randomRotation), norm));
+ finalGlitter = lerp(0, _GlitterMinBrightness * glitterAlpha, glitterAlpha) + max(pow(saturate(dot(lerp(glitterReflectionDirection, poiCam.viewDir, _GlitterBias), poiCam.viewDir)), _GlitterContrast), 0);
+ finalGlitter *= glitterAlpha;
+ break;
+ case 1:
+ float offset = random(randoPoint);
+ float brightness = sin((_Time.x + offset) * _GlitterSpeed) * _glitterFrequencyLinearEmissive - (_glitterFrequencyLinearEmissive - 1);
+ finalGlitter = max(_GlitterMinBrightness * glitterAlpha, brightness * glitterAlpha * smoothstep(0, 1, 1 - m_dist * _GlitterCenterSize * 10));
+ break;
+ }
+
+
+ half3 glitterColor = _GlitterColor;
+ glitterColor *= lerp(1, albedo, _GlitterUseSurfaceColor);
+ #if defined(PROP_GLITTERCOLORMAP) || !defined(OPTIMIZER_ENABLED)
+ glitterColor *= POI2D_SAMPLER_PAN(_GlitterColorMap, _MainTex, poiMesh.uv[_GlitterColorMapUV], _GlitterColorMapPan).rgb;
+ #endif
+ float2 uv = remapClamped(dank, -size, size, 0, 1);
+ UNITY_BRANCH
+ if(_GlitterRandomRotation == 1 || _GlitterTextureRotation != 0 && !_GlitterShape)
+ {
+ float2 fakeUVCenter = float2(.5, .5);
+ float randomBoy = 0;
+ UNITY_BRANCH
+ if(_GlitterRandomRotation)
+ {
+ randomBoy = random(randoPoint);
+ }
+ float theta = radians((randomBoy + _Time.x * _GlitterTextureRotation) * 360);
+ float cs = cos(theta);
+ float sn = sin(theta);
+ uv = float2((uv.x - fakeUVCenter.x) * cs - (uv.y - fakeUVCenter.y) * sn + fakeUVCenter.x, (uv.x - fakeUVCenter.x) * sn + (uv.y - fakeUVCenter.y) * cs + fakeUVCenter.y);
+ }
+
+ #if defined(PROP_GLITTERTEXTURE) || !defined(OPTIMIZER_ENABLED)
+ float4 glitterTexture = POI2D_SAMPLER_PAN(_GlitterTexture, _MainTex, uv, _GlitterTexturePan);
+ #else
+ float4 glitterTexture = 1;
+ #endif
+ //float4 glitterTexture = _GlitterTexture.SampleGrad(sampler_MainTex, frac(uv), ddx(uv), ddy(uv));
+ glitterColor *= glitterTexture.rgb;
+ #if defined(PROP_GLITTERMASK) || !defined(OPTIMIZER_ENABLED)
+ float glitterMask = POI2D_SAMPLER_PAN(_GlitterMask, _MainTex, poiMesh.uv[_GlitterMaskUV], _GlitterMaskPan);
+ #else
+ float glitterMask = 1;
+ #endif
+
+ glitterMask *= lerp(1, poiLight.rampedLightMap, _GlitterHideInShadow);
+
+ #ifdef POI_BLACKLIGHT
+ if (_BlackLightMaskGlitter != 4)
+ {
+ glitterMask *= blackLightMask[_BlackLightMaskGlitter];
+ }
+ #endif
+
+ if(_GlitterRandomColors)
+ {
+ glitterColor *= RandomColorFromPoint(random2(randoPoint.x + randoPoint.y));
+ }
+
+ UNITY_BRANCH
+ if(_GlitterHueShiftEnabled)
+ {
+ glitterColor.rgb = hueShift(glitterColor.rgb, _GlitterHueShift + _Time.x * _GlitterHueShiftSpeed);
+ }
+
+ UNITY_BRANCH
+ if(_GlitterBlendType == 1)
+ {
+ albedo.rgb = lerp(albedo.rgb, finalGlitter * glitterColor * _GlitterBrightness, finalGlitter * glitterTexture.a * glitterMask);
+ glitterEmission = finalGlitter * glitterColor * max(0, (_GlitterBrightness - 1) * glitterTexture.a) * glitterMask;
+ }
+ else
+ {
+ glitterEmission = finalGlitter * glitterColor * _GlitterBrightness * glitterTexture.a * glitterMask;
+ }
+ }
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiGlitter.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiGlitter.cginc.meta
new file mode 100644
index 00000000..3138813f
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiGlitter.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 951e19b6f0892c246b81926ee196e733
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiGrab.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiGrab.cginc
new file mode 100644
index 00000000..d8a3d424
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiGrab.cginc
@@ -0,0 +1,125 @@
+#ifndef POI_GRAB
+ #define POI_GRAB
+
+ float _RefractionIndex;
+ float _RefractionOpacity;
+ float _RefractionChromaticAberattion;
+ float _RefractionEnabled;
+ float _GrabSrcBlend;
+ float _GrabDstBlend;
+ float _GrabPassUseAlpha;
+ float _GrabPassBlendFactor;
+ float _GrabBlurDistance;
+ float _GrabBlurQuality;
+ float _GrabBlurDirections;
+ POI_TEXTURE_NOSAMPLER(_GrabPassBlendMap);
+
+ float4 blur(float2 uv)
+ {
+ float two_pi = 6.28318530718;
+
+ float2 radius = _GrabBlurDistance / _ScreenParams.xy * 100; // Arbitrary constant to match old blur
+ float quality = floor(_GrabBlurQuality);
+ float directions = floor(_GrabBlurDirections);
+
+ // Pixel colour
+ float4 color = tex2D(_PoiGrab, uv);
+
+ float deltaAngle = two_pi / directions;
+ float deltaQuality = 1.0 / quality;
+ for (int i = 0; i < directions; i ++)
+ {
+ for (int j = 0; j < quality; j ++)
+ {
+ float angle = deltaAngle * i + j;
+ float offset = deltaQuality * (j + 1);
+ color += tex2D(_PoiGrab, uv + float2(cos(angle), sin(angle)) * radius * offset);
+ }
+ }
+
+ // Output to screen
+ color /= quality * directions + 1;
+ return color;
+ }
+
+ inline float4 Refraction(float indexOfRefraction, float chromaticAberration, float2 projectedGrabPos)
+ {
+ float4 refractionColor;
+ float3 worldViewDir = normalize(UnityWorldSpaceViewDir(poiMesh.worldPos));
+ float3 refractionOffset = ((((indexOfRefraction - 1.0) * mul(UNITY_MATRIX_V, float4(poiMesh.normals[1], 0.0)).xyz) * (1.0 / (poiCam.grabPos.z + 1.0))) * (1.0 - dot(poiMesh.normals[1], worldViewDir)));
+ float2 cameraRefraction = float2(refractionOffset.x, - (refractionOffset.y * _ProjectionParams.x));
+
+ UNITY_BRANCH
+ if (_RefractionChromaticAberattion > 0)
+ {
+ float4 redAlpha = tex2D(_PoiGrab, (projectedGrabPos + cameraRefraction));
+ float green = tex2D(_PoiGrab, (projectedGrabPos + (cameraRefraction * (1.0 - chromaticAberration)))).g;
+ float blue = tex2D(_PoiGrab, (projectedGrabPos + (cameraRefraction * (1.0 + chromaticAberration)))).b;
+ refractionColor = float4(redAlpha.r, green, blue, redAlpha.a);
+ }
+ else
+ {
+ float2 refractedGrab = projectedGrabPos + cameraRefraction;
+
+ #ifdef CHROMATIC_ABERRATION_LOW
+ refractionColor = blur(refractedGrab);
+ #else
+ refractionColor = tex2D(_PoiGrab, (refractedGrab));
+ #endif
+ }
+ return refractionColor;
+ }
+
+ void calculateRefraction(float2 projectedGrabPos, inout float4 finalColor)
+ {
+ float3 refraction = 1;
+ UNITY_BRANCH
+ if(_RefractionEnabled == 1)
+ {
+ refraction = Refraction(_RefractionIndex, _RefractionChromaticAberattion, projectedGrabPos).rgb;
+ }
+ else
+ {
+ #ifdef CHROMATIC_ABERRATION_LOW
+ refraction = blur(projectedGrabPos);
+ #else
+ refraction = tex2Dproj(_PoiGrab, poiCam.grabPos).rgb;
+ #endif
+ }
+
+ float blendFactor = _GrabPassBlendFactor * POI2D_SAMPLER_PAN(_GrabPassBlendMap, _MainTex, poiMesh.uv[_GrabPassBlendMapUV], _GrabPassBlendMapPan).r;
+ UNITY_BRANCH
+ if(_GrabPassUseAlpha)
+ {
+ finalColor = poiBlend(_GrabSrcBlend, finalColor, _GrabDstBlend, float4(refraction, 1), blendFactor * (1 - finalColor.a));
+ finalColor.a = 1;
+ }
+ else
+ {
+ finalColor = poiBlend(_GrabSrcBlend, finalColor, _GrabDstBlend, float4(refraction, 1), blendFactor);
+ }
+ }
+
+ float2 calculateGrabPosition()
+ {
+ float4 grabPos = poiCam.grabPos;
+ #if UNITY_UV_STARTS_AT_TOP
+ float scale = -1.0;
+ #else
+ float scale = 1.0;
+ #endif
+ float halfPosW = grabPos.w * 0.5;
+ grabPos.y = (grabPos.y - halfPosW) * _ProjectionParams.x * scale + halfPosW;
+ #if SHADER_API_D3D9 || SHADER_API_D3D11
+ grabPos.w += 0.00000000001;
+ #endif
+ return(grabPos / grabPos.w).xy;
+ }
+
+ void applyGrabEffects(inout float4 finalColor)
+ {
+ float2 projectedGrabPos = calculateGrabPosition();
+ calculateRefraction(projectedGrabPos, finalColor);
+ }
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiGrab.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiGrab.cginc.meta
new file mode 100644
index 00000000..d01d8517
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiGrab.cginc.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 31b4450700d5cc244853b4488e455231
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiHelpers.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiHelpers.cginc
new file mode 100644
index 00000000..e71e6ef3
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiHelpers.cginc
@@ -0,0 +1,336 @@
+#ifndef POI_HELPER
+#define POI_HELPER
+
+#ifndef pi
+ #define pi float(3.14159265359)
+#endif
+
+float linearSin(float x)
+{
+ return pow(min(cos(pi * x / 2.0), 1.0 - abs(x)), 1.0);
+}
+
+float random(float2 p)
+{
+ return frac(sin(dot(p, float2(12.9898, 78.2383))) * 43758.5453123);
+}
+
+float2 random2(float2 p)
+{
+ return frac(sin(float2(dot(p, float2(127.1, 311.7)), dot(p, float2(269.5, 183.3)))) * 43758.5453);
+}
+
+float3 random3(float3 p)
+{
+ return frac(sin(float3(dot(p, float3(127.1, 311.7, 248.6)), dot(p, float3(269.5, 183.3, 423.3)), dot(p, float3(248.3, 315.9, 184.2)))) * 43758.5453);
+}
+
+float3 mod(float3 x, float y)
+{
+ return x - y * floor(x / y);
+}
+float2 mod(float2 x, float y)
+{
+ return x - y * floor(x / y);
+}
+
+//1/7
+#define K 0.142857142857
+//3/7
+#define Ko 0.428571428571
+
+// Permutation polynomial: (34x^2 + x) mod 289
+float3 Permutation(float3 x)
+{
+ return mod((34.0 * x + 1.0) * x, 289.0);
+}
+
+bool IsInMirror()
+{
+ return unity_CameraProjection[2][0] != 0.f || unity_CameraProjection[2][1] != 0.f;
+}
+
+float3 BoxProjection(float3 direction, float3 position, float4 cubemapPosition, float3 boxMin, float3 boxMax)
+{
+ #if UNITY_SPECCUBE_BOX_PROJECTION
+ UNITY_BRANCH
+ if (cubemapPosition.w > 0)
+ {
+ float3 factors = ((direction > 0 ? boxMax : boxMin) - position) / direction;
+ float scalar = min(min(factors.x, factors.y), factors.z);
+ direction = direction * scalar + (position - cubemapPosition.xyz);
+ }
+ #endif
+ return direction;
+}
+
+// Camera
+float3 getCameraPosition()
+{
+ #ifdef USING_STEREO_MATRICES
+ return lerp(unity_StereoWorldSpaceCameraPos[0], unity_StereoWorldSpaceCameraPos[1], 0.5);
+ #endif
+ return _WorldSpaceCameraPos;
+}
+
+float3 getCameraForward()
+{
+ #if UNITY_SINGLE_PASS_STEREO
+ float3 p1 = mul(unity_StereoCameraToWorld[0], float4(0, 0, 1, 1));
+ float3 p2 = mul(unity_StereoCameraToWorld[0], float4(0, 0, 0, 1));
+ #else
+ float3 p1 = mul(unity_CameraToWorld, float4(0, 0, 1, 1)).xyz;
+ float3 p2 = mul(unity_CameraToWorld, float4(0, 0, 0, 1)).xyz;
+ #endif
+ return normalize(p2 - p1);
+}
+
+float3 grayscale_vector_node()
+{
+ return float3(0, 0.3823529, 0.01845836);
+}
+
+float3 grayscale_for_light()
+{
+ return float3(0.298912, 0.586611, 0.114478);
+}
+
+//Math Operators
+
+float remap(float x, float minOld, float maxOld, float minNew, float maxNew)
+{
+ return minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld);
+}
+
+float2 remap(float2 x, float2 minOld, float2 maxOld, float2 minNew, float2 maxNew)
+{
+ return minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld);
+}
+
+float3 remap(float3 x, float3 minOld, float3 maxOld, float3 minNew, float3 maxNew)
+{
+ return minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld);
+}
+
+float4 remap(float4 x, float4 minOld, float4 maxOld, float4 minNew, float4 maxNew)
+{
+ return minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld);
+}
+
+float remapClamped(float x, float minOld, float maxOld, float minNew, float maxNew)
+{
+ return clamp(minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld), minNew, maxNew);
+}
+
+float2 remapClamped(float2 x, float2 minOld, float2 maxOld, float2 minNew, float2 maxNew)
+{
+ return clamp(minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld), minNew, maxNew);
+}
+
+float3 remapClamped(float3 x, float3 minOld, float3 maxOld, float3 minNew, float3 maxNew)
+{
+ return clamp(minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld), minNew, maxNew);
+}
+
+float4 remapClamped(float4 x, float4 minOld, float4 maxOld, float4 minNew, float4 maxNew)
+{
+ return clamp(minNew + (x - minOld) * (maxNew - minNew) / (maxOld - minOld), minNew, maxNew);
+}
+
+float poiMax(float2 i)
+{
+ return max(i.x, i.y);
+}
+
+float poiMax(float3 i)
+{
+ return max(max(i.x, i.y), i.z);
+}
+
+float poiMax(float4 i)
+{
+ return max(max(max(i.x, i.y), i.z), i.w);
+}
+
+float4x4 poiAngleAxisRotationMatrix(float angle, float3 axis)
+{
+ axis = normalize(axis);
+ float s = sin(angle);
+ float c = cos(angle);
+ float oc = 1.0 - c;
+
+ return float4x4(oc * axis.x * axis.x + c, oc * axis.x * axis.y - axis.z * s, oc * axis.z * axis.x + axis.y * s, 0.0,
+ oc * axis.x * axis.y + axis.z * s, oc * axis.y * axis.y + c, oc * axis.y * axis.z - axis.x * s, 0.0,
+ oc * axis.z * axis.x - axis.y * s, oc * axis.y * axis.z + axis.x * s, oc * axis.z * axis.z + c, 0.0,
+ 0.0, 0.0, 0.0, 1.0);
+}
+
+float4x4 poiRotationMatrixFromAngles(float x, float y, float z)
+{
+ float angleX = radians(x);
+ float c = cos(angleX);
+ float s = sin(angleX);
+ float4x4 rotateXMatrix = float4x4(1, 0, 0, 0,
+ 0, c, -s, 0,
+ 0, s, c, 0,
+ 0, 0, 0, 1);
+
+ float angleY = radians(y);
+ c = cos(angleY);
+ s = sin(angleY);
+ float4x4 rotateYMatrix = float4x4(c, 0, s, 0,
+ 0, 1, 0, 0,
+ - s, 0, c, 0,
+ 0, 0, 0, 1);
+
+ float angleZ = radians(z);
+ c = cos(angleZ);
+ s = sin(angleZ);
+ float4x4 rotateZMatrix = float4x4(c, -s, 0, 0,
+ s, c, 0, 0,
+ 0, 0, 1, 0,
+ 0, 0, 0, 1);
+
+ return mul(mul(rotateXMatrix, rotateYMatrix), rotateZMatrix);
+}
+
+float4x4 poiRotationMatrixFromAngles(float3 angles)
+{
+ float angleX = radians(angles.x);
+ float c = cos(angleX);
+ float s = sin(angleX);
+ float4x4 rotateXMatrix = float4x4(1, 0, 0, 0,
+ 0, c, -s, 0,
+ 0, s, c, 0,
+ 0, 0, 0, 1);
+
+ float angleY = radians(angles.y);
+ c = cos(angleY);
+ s = sin(angleY);
+ float4x4 rotateYMatrix = float4x4(c, 0, s, 0,
+ 0, 1, 0, 0,
+ - s, 0, c, 0,
+ 0, 0, 0, 1);
+
+ float angleZ = radians(angles.z);
+ c = cos(angleZ);
+ s = sin(angleZ);
+ float4x4 rotateZMatrix = float4x4(c, -s, 0, 0,
+ s, c, 0, 0,
+ 0, 0, 1, 0,
+ 0, 0, 0, 1);
+
+ return mul(mul(rotateXMatrix, rotateYMatrix), rotateZMatrix);
+}
+
+#endif
+
+half2 calcScreenUVs(half4 grabPos)
+{
+ half2 uv = grabPos.xy / (grabPos.w + 0.0000000001);
+ #if UNITY_SINGLE_PASS_STEREO
+ uv.xy *= half2(_ScreenParams.x * 2, _ScreenParams.y);
+ #else
+ uv.xy *= _ScreenParams.xy;
+ #endif
+
+ return uv;
+}
+
+float inverseLerp(float A, float B, float T)
+{
+ return(T - A) / (B - A);
+}
+
+float inverseLerp2(float2 a, float2 b, float2 value)
+{
+ float2 AB = b - a;
+ float2 AV = value - a;
+ return dot(AV, AB) / dot(AB, AB);
+}
+
+float inverseLerp3(float3 a, float3 b, float3 value)
+{
+ float3 AB = b - a;
+ float3 AV = value - a;
+ return dot(AV, AB) / dot(AB, AB);
+}
+
+float inverseLerp4(float4 a, float4 b, float4 value)
+{
+ float4 AB = b - a;
+ float4 AV = value - a;
+ return dot(AV, AB) / dot(AB, AB);
+}
+
+// Dithering
+inline half Dither8x8Bayer(int x, int y)
+{
+ const half dither[ 64 ] = {
+ 1, 49, 13, 61, 4, 52, 16, 64,
+ 33, 17, 45, 29, 36, 20, 48, 32,
+ 9, 57, 5, 53, 12, 60, 8, 56,
+ 41, 25, 37, 21, 44, 28, 40, 24,
+ 3, 51, 15, 63, 2, 50, 14, 62,
+ 35, 19, 47, 31, 34, 18, 46, 30,
+ 11, 59, 7, 55, 10, 58, 6, 54,
+ 43, 27, 39, 23, 42, 26, 38, 22
+ };
+ int r = y * 8 + x;
+ return dither[r] / 64;
+}
+
+// UV Manipulation
+float2 TransformUV(half2 offset, half rotation, half2 scale, float2 uv)
+{
+ float theta = radians(rotation);
+ scale = 1 - scale;
+ float cs = cos(theta);
+ float sn = sin(theta);
+ float2 centerPoint = offset + .5;
+ uv = float2((uv.x - centerPoint.x) * cs - (uv.y - centerPoint.y) * sn + centerPoint.x, (uv.x - centerPoint.x) * sn + (uv.y - centerPoint.y) * cs + centerPoint.y);
+
+ return remap(uv, float2(0, 0) + offset + (scale * .5), float2(1, 1) + offset - (scale * .5), float2(0, 0), float2(1, 1));
+}
+
+bool isVR()
+{
+ // USING_STEREO_MATRICES
+ #if UNITY_SINGLE_PASS_STEREO
+ return true;
+ #else
+ return false;
+ #endif
+}
+
+bool isVRHandCamera()
+{
+ return !isVR() && abs(UNITY_MATRIX_V[0].y) > 0.0000005;
+}
+
+bool isDesktop()
+{
+ return !isVRHandCamera();
+}
+
+bool isVRHandCameraPreview()
+{
+ return isVRHandCamera() && _ScreenParams.y == 720;
+}
+
+bool isVRHandCameraPicture()
+{
+ return isVRHandCamera() && _ScreenParams.y == 1080;
+}
+
+bool isPanorama()
+{
+ // Crude method
+ // FOV=90=camproj=[1][1]
+ return unity_CameraProjection[1][1] == 1 && _ScreenParams.x == 1075 && _ScreenParams.y == 1025;
+}
+
+float calculateluminance(float3 color)
+{
+ return color.r * 0.299 + color.g * 0.587 + color.b * 0.114;
+} \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiHelpers.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiHelpers.cginc.meta
new file mode 100644
index 00000000..233c26f9
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiHelpers.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: fb03052ea8dc42740b104275ae961ae0
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiHologram.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiHologram.cginc
new file mode 100644
index 00000000..af9e781d
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiHologram.cginc
@@ -0,0 +1,44 @@
+#ifndef POI_HOLOGRAM
+#define POI_HOLOGRAM
+
+#if defined(PROP_HOLOALPHAMAP) || !defined(OPTIMIZER_ENABLED)
+ UNITY_DECLARE_TEX2D_NOSAMPLER(_HoloAlphaMap); float4 _HoloAlphaMap_ST;
+#endif
+float _HoloCoordinateSpace; // 0 World, 1 Local, 2 UV
+float3 _HoloDirection;
+float _HoloScrollSpeed;
+float _HoloLineDensity;
+
+fixed _HoloFresnelAlpha;
+fixed _HoloRimSharpness;
+fixed _HoloRimWidth;
+
+void ApplyHoloAlpha(inout float4 color)
+{
+ float uv = 0;
+ UNITY_BRANCH
+ if (_HoloCoordinateSpace == 0)
+ {
+ uv = dot(normalize(_HoloDirection), poiMesh.worldPos * _HoloLineDensity) + _Time.x * _HoloScrollSpeed;
+ }
+ UNITY_BRANCH
+ if (_HoloCoordinateSpace == 1)
+ {
+ uv = dot(normalize(_HoloDirection), poiMesh.localPos * _HoloLineDensity) + _Time.x * _HoloScrollSpeed;
+ }
+ UNITY_BRANCH
+ if (_HoloCoordinateSpace == 2)
+ {
+ uv = dot(_HoloDirection, poiMesh.uv[0] * _HoloLineDensity) + _Time.x * _HoloScrollSpeed;
+ }
+ float holoRim = saturate(1 - smoothstep(min(_HoloRimSharpness, _HoloRimWidth), _HoloRimWidth, poiCam.viewDotNormal));
+ holoRim = abs(lerp(1, holoRim, _HoloFresnelAlpha));
+ #if defined(PROP_HOLOALPHAMAP) || !defined(OPTIMIZER_ENABLED)
+ fixed holoAlpha = UNITY_SAMPLE_TEX2D_SAMPLER(_HoloAlphaMap, _MainTex, uv).r;
+ #else
+ fixed holoAlpha = 1;
+ #endif
+ color.a *= holoAlpha * holoRim;
+}
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiHologram.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiHologram.cginc.meta
new file mode 100644
index 00000000..f342f3b6
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiHologram.cginc.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: ea5f0a88cd7909642be3bb003cd6c291
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiIridescence.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiIridescence.cginc
new file mode 100644
index 00000000..053a4d48
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiIridescence.cginc
@@ -0,0 +1,104 @@
+#ifndef POI_IRIDESCENCE
+#define POI_IRIDESCENCE
+#if defined(PROP_IRIDESCENCERAMP) || !defined(OPTIMIZER_ENABLED)
+ UNITY_DECLARE_TEX2D_NOSAMPLER(_IridescenceRamp); float4 _IridescenceRamp_ST;
+#endif
+#if defined(PROP_IRIDESCENCEMASK) || !defined(OPTIMIZER_ENABLED)
+ UNITY_DECLARE_TEX2D_NOSAMPLER(_IridescenceMask); float4 _IridescenceMask_ST;
+#endif
+#if defined(PROP_IRIDESCENCENORMALMAP) || !defined(OPTIMIZER_ENABLED)
+ UNITY_DECLARE_TEX2D_NOSAMPLER(_IridescenceNormalMap); float4 _IridescenceNormalMap_ST;
+#endif
+float _IridescenceNormalUV;
+float _IridescenceMaskUV;
+float _IridescenceNormalSelection;
+float _IridescenceNormalIntensity;
+float _IridescenceNormalToggle;
+float _IridescenceIntensity;
+fixed _IridescenceAddBlend;
+fixed _IridescenceReplaceBlend;
+fixed _IridescenceMultiplyBlend;
+float _IridescenceEmissionStrength;
+float _IridescencePanSpeed;
+half _IridescenceOffset;
+
+half _IridescenceHueShiftEnabled;
+half _IridescenceHueShiftSpeed;
+half _IridescenceHueShift;
+
+#ifdef POI_AUDIOLINK
+ half _IridescenceAudioLinkEmissionBand;
+ half2 _IridescenceAudioLinkEmission;
+#endif
+
+//global
+#if defined(PROP_IRIDESCENCENORMALMAP) || !defined(OPTIMIZER_ENABLED)
+ float3 calculateNormal(float3 baseNormal)
+ {
+
+ float3 normal = UnpackScaleNormal(UNITY_SAMPLE_TEX2D_SAMPLER(_IridescenceNormalMap, _MainTex, TRANSFORM_TEX(poiMesh.uv[_IridescenceNormalUV], _IridescenceNormalMap)), _IridescenceNormalIntensity);
+ return normalize(
+ normal.x * poiMesh.tangent +
+ normal.y * poiMesh.binormal +
+ normal.z * baseNormal
+ );
+ }
+#endif
+
+void applyIridescence(inout float4 albedo, inout float3 IridescenceEmission)
+{
+ float3 normal = poiMesh.normals[_IridescenceNormalSelection];
+
+ #if defined(PROP_IRIDESCENCENORMALMAP) || !defined(OPTIMIZER_ENABLED)
+ // Use custom normal map
+ UNITY_BRANCH
+ if (_IridescenceNormalToggle)
+ {
+ normal = calculateNormal(normal);
+ }
+ #endif
+
+ float ndotv = abs(dot(normal, poiCam.viewDir)) + _Time.x * _IridescencePanSpeed + _IridescenceOffset;
+
+ #if defined(PROP_IRIDESCENCERAMP) || !defined(OPTIMIZER_ENABLED)
+ float4 iridescenceColor = UNITY_SAMPLE_TEX2D_SAMPLER(_IridescenceRamp, _MainTex, ndotv);
+ #else
+ float4 iridescenceColor = 1;
+ #endif
+
+ #if defined(PROP_IRIDESCENCEMASK) || !defined(OPTIMIZER_ENABLED)
+ float4 iridescenceMask = UNITY_SAMPLE_TEX2D_SAMPLER(_IridescenceMask, _MainTex, TRANSFORM_TEX(poiMesh.uv[_IridescenceMaskUV], _IridescenceMask));
+ #else
+ float4 iridescenceMask = 1;
+ #endif
+ #ifdef POI_BLACKLIGHT
+ if (_BlackLightMaskIridescence != 4)
+ {
+ iridescenceMask *= blackLightMask[_BlackLightMaskIridescence];
+ }
+ #endif
+
+ UNITY_BRANCH
+ if (_IridescenceHueShiftEnabled)
+ {
+ iridescenceColor.rgb = hueShift(iridescenceColor.rgb, _IridescenceHueShift + _Time.x * _IridescenceHueShiftSpeed);
+ }
+
+ albedo.rgb = lerp(albedo.rgb, saturate(iridescenceColor.rgb * _IridescenceIntensity), iridescenceColor.a * _IridescenceReplaceBlend * iridescenceMask);
+ albedo.rgb += saturate(iridescenceColor.rgb * _IridescenceIntensity * iridescenceColor.a * _IridescenceAddBlend * iridescenceMask);
+ albedo.rgb *= saturate(lerp(1, iridescenceColor.rgb * _IridescenceIntensity, iridescenceColor.a * _IridescenceMultiplyBlend * iridescenceMask));
+
+ half emissionStrength = _IridescenceEmissionStrength;
+
+ #ifdef POI_AUDIOLINK
+ UNITY_BRANCH
+ if (poiMods.audioLinkTextureExists)
+ {
+ emissionStrength += lerp(_IridescenceAudioLinkEmission.x, _IridescenceAudioLinkEmission.y, poiMods.audioLink[_IridescenceAudioLinkEmissionBand]);
+ }
+ #endif
+
+ IridescenceEmission = saturate(iridescenceColor.rgb * _IridescenceIntensity) * iridescenceColor.a * iridescenceMask * emissionStrength;
+}
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiIridescence.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiIridescence.cginc.meta
new file mode 100644
index 00000000..db93f998
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiIridescence.cginc.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 72605619fbb558a40926b8b605114f53
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiLighting.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiLighting.cginc
new file mode 100644
index 00000000..87e3719e
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiLighting.cginc
@@ -0,0 +1,981 @@
+
+#ifndef POI_LIGHTING
+#define POI_LIGHTING
+
+float _LightingRampType;
+float _LightingIgnoreAmbientColor;
+float _UseShadowTexture;
+float _LightingEnableAO;
+float _LightingDetailShadowsEnabled;
+
+float _LightingOnlyUnityShadows;
+float _LightingMode;
+float _ForceLightDirection;
+float _ShadowStrength;
+float _OutlineShadowStrength;
+float _ShadowOffset;
+float3 _LightDirection;
+float _ForceShadowStrength;
+float _CastedShadowSmoothing;
+float _AttenuationMultiplier;
+float _EnableLighting;
+float _LightingControlledUseLightColor;
+fixed _LightingStandardSmoothness;
+fixed _LightingStandardControlsToon;
+fixed _LightingMinLightBrightness;
+float _LightingUseShadowRamp;
+float _LightingMinShadowBrightnessRatio;
+fixed _LightingMonochromatic;
+
+fixed _LightingGradientStart;
+fixed _LightingGradientEnd;
+float3 _LightingShadowColor;
+float _AOStrength;
+fixed _LightingDetailStrength;
+fixed _LightingAdditiveDetailStrength;
+fixed _LightingNoIndirectMultiplier;
+fixed _LightingNoIndirectThreshold;
+float _LightingUncapped;
+
+float _LightingDirectColorMode;
+float _LightingIndirectColorMode;
+float _LightingAdditiveType;
+fixed _LightingAdditiveGradientStart;
+fixed _LightingAdditiveGradientEnd;
+fixed _LightingAdditivePassthrough;
+float _LightingDirectAdjustment;
+float _LightingIndirect;
+// HSL JUNK
+float _LightingEnableHSL;
+float _LightingShadowHue;
+float _LightingShadowSaturation;
+float _LightingShadowLightness;
+float _LightingHSLIntensity;
+// UTS Style Shade Mapping
+float4 _1st_ShadeColor;
+float _Use_BaseAs1st;
+float4 _2nd_ShadeColor;
+float _Use_1stAs2nd;
+float _BaseColor_Step;
+float _BaseShade_Feather;
+float _ShadeColor_Step;
+float _1st2nd_Shades_Feather;
+float _Use_1stShadeMapAlpha_As_ShadowMask;
+float _1stShadeMapMask_Inverse;
+float _Tweak_1stShadingGradeMapLevel;
+float _Use_2ndShadeMapAlpha_As_ShadowMask;
+float _2ndShadeMapMask_Inverse;
+float _Tweak_2ndShadingGradeMapLevel;
+// Skin
+float _SkinScatteringProperties;
+float _SssWeight;
+float _SssMaskCutoff ;
+float _SssBias;
+float _SssScale;
+float _SssBumpBlur;
+float4 _SssTransmissionAbsorption;
+float4 _SssColorBleedAoWeights;
+/*
+UNITY_DECLARE_TEX2D_NOSAMPLER(_ToonRamp3);
+half _LightingShadowStrength3;
+half _ShadowOffset3;
+*/
+
+half4 shadowStrength;
+sampler2D _SkinLUT;
+UNITY_DECLARE_TEX2D(_ToonRamp);
+POI_TEXTURE_NOSAMPLER(_1st_ShadeMap);
+POI_TEXTURE_NOSAMPLER(_2nd_ShadeMap);
+POI_TEXTURE_NOSAMPLER(_LightingDetailShadows);
+POI_TEXTURE_NOSAMPLER(_LightingAOTex);
+POI_TEXTURE_NOSAMPLER(_LightingShadowMask);
+
+float3 directLighting;
+float3 indirectLighting;
+/*
+* DJLs code starts here
+*/
+float _LightingWrappedWrap;
+float _LightingWrappedNormalization;
+
+// Green’s model with adjustable energy
+// http://blog.stevemcauley.com/2011/12/03/energy-conserving-wrapped-diffuse/
+// Modified for adjustable conservation ratio and over-wrap to directionless
+float RTWrapFunc(in float dt, in float w, in float norm)
+{
+ float cw = saturate(w);
+
+ float o = (dt + cw) / ((1.0 + cw) * (1.0 + cw * norm));
+ float flt = 1.0 - 0.85 * norm;
+ if (w > 1.0)
+ {
+ o = lerp(o, flt, w - 1.0);
+ }
+ return o;
+}
+float3 GreenWrapSH(float fA) // Greens unoptimized and non-normalized
+
+{
+ float fAs = saturate(fA);
+ float4 t = float4(fA + 1, fAs - 1, fA - 2, fAs + 1); // DJL edit: allow wrapping to L0-only at w=2
+ return float3(t.x, -t.z * t.x / 3, 0.25 * t.y * t.y * t.w);
+}
+float3 GreenWrapSHOpt(float fW) // optimised and normalized https://blog.selfshadow.com/2012/01/07/righting-wrap-part-2/
+
+{
+ const float4 t0 = float4(0.0, 1.0 / 4.0, -1.0 / 3.0, -1.0 / 2.0);
+ const float4 t1 = float4(1.0, 2.0 / 3.0, 1.0 / 4.0, 0.0);
+ float3 fWs = float3(fW, fW, saturate(fW)); // DJL edit: allow wrapping to L0-only at w=2
+
+ float3 r;
+ r.xyz = t0.xxy * fWs + t0.xzw;
+ r.xyz = r.xyz * fWs + t1.xyz;
+ return r;
+}
+float3 ShadeSH9_wrapped(float3 normal, float wrap)
+{
+ float3 x0, x1, x2;
+ float3 conv = lerp(GreenWrapSH(wrap), GreenWrapSHOpt(wrap), _LightingWrappedNormalization); // Should try optimizing this...
+ conv *= float3(1, 1.5, 4); // Undo pre-applied cosine convolution by using the inverse
+
+ // Constant (L0)
+ x0 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w);
+ // Remove pre-applied constant part from L(2,0) to apply correct convolution
+ float3 L2_0 = float3(unity_SHBr.z, unity_SHBg.z, unity_SHBb.z) / - 3.0;
+ x0 -= L2_0;
+
+ // Linear (L1) polynomial terms
+ x1.r = dot(unity_SHAr.xyz, normal);
+ x1.g = dot(unity_SHAg.xyz, normal);
+ x1.b = dot(unity_SHAb.xyz, normal);
+
+ // 4 of the quadratic (L2) polynomials
+ float4 vB = normal.xyzz * normal.yzzx;
+ x2.r = dot(unity_SHBr, vB);
+ x2.g = dot(unity_SHBg, vB);
+ x2.b = dot(unity_SHBb, vB);
+
+ // Final (5th) quadratic (L2) polynomial
+ float vC = normal.x * normal.x - normal.y * normal.y;
+ x2 += unity_SHC.rgb * vC;
+ // Move back the constant part of L(2,0)
+ x2 += L2_0;
+
+ return x0 * conv.x + x1 * conv.y + x2 * conv.z;
+}
+
+/*
+* MIT License
+*
+* Copyright (c) 2018 s-ilent
+*
+* Permission is hereby granted, free of charge, to any person obtaining a copy
+* of this software and associated documentation files (the "Software"), to deal
+* in the Software without restriction, including without limitation the rights
+* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+* copies of the Software, and to permit persons to whom the Software is
+* furnished to do so, subject to the following conditions:
+*
+* The above copyright notice and this permission notice shall be included in all
+* copies or substantial portions of the Software.
+*
+* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+* SOFTWARE.
+*/
+
+/*
+* Silent's code starts here
+*/
+
+float shEvaluateDiffuseL1Geomerics_local(float L0, float3 L1, float3 n)
+{
+ // average energy
+ float R0 = max(0, L0);
+
+ // avg direction of incoming light
+ float3 R1 = 0.5f * L1;
+
+ // directional brightness
+ float lenR1 = length(R1);
+
+ // linear angle between normal and direction 0-1
+ //float q = 0.5f * (1.0f + dot(R1 / lenR1, n));
+ //float q = dot(R1 / lenR1, n) * 0.5 + 0.5;
+ float q = dot(normalize(R1), n) * 0.5 + 0.5;
+ q = saturate(q); // Thanks to ScruffyRuffles for the bug identity.
+
+ // power for q
+ // lerps from 1 (linear) to 3 (cubic) based on directionality
+ float p = 1.0f + 2.0f * lenR1 / R0;
+
+ // dynamic range constant
+ // should vary between 4 (highly directional) and 0 (ambient)
+ float a = (1.0f - lenR1 / R0) / (1.0f + lenR1 / R0);
+
+ return R0 * (a + (1.0f - a) * (p + 1.0f) * pow(q, p));
+}
+
+half3 BetterSH9(half4 normal)
+{
+ float3 indirect;
+ float3 L0 = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w) + float3(unity_SHBr.z, unity_SHBg.z, unity_SHBb.z) / 3.0;
+ indirect.r = shEvaluateDiffuseL1Geomerics_local(L0.r, unity_SHAr.xyz, normal.xyz);
+ indirect.g = shEvaluateDiffuseL1Geomerics_local(L0.g, unity_SHAg.xyz, normal.xyz);
+ indirect.b = shEvaluateDiffuseL1Geomerics_local(L0.b, unity_SHAb.xyz, normal.xyz);
+ indirect = max(0, indirect);
+ indirect += SHEvalLinearL2(normal);
+ return indirect;
+}
+
+float3 BetterSH9(float3 normal)
+{
+ return BetterSH9(float4(normal, 1));
+}
+
+/*
+* Standard stuff starts here
+*/
+UnityLight CreateLight(float3 normal, fixed detailShadowMap)
+{
+ UnityLight light;
+ light.dir = poiLight.direction;
+ light.color = saturate(_LightColor0.rgb * lerp(1, poiLight.attenuation, _AttenuationMultiplier) * detailShadowMap);
+ light.ndotl = DotClamped(normal, poiLight.direction);
+ return light;
+}
+
+float FadeShadows(float attenuation)
+{
+ #if HANDLE_SHADOWS_BLENDING_IN_GI || ADDITIONAL_MASKED_DIRECTIONAL_SHADOWS
+ // UNITY_LIGHT_ATTENUATION doesn't fade shadows for us.
+
+ #if ADDITIONAL_MASKED_DIRECTIONAL_SHADOWS
+ attenuation = lerp(1, poiLight.attenuation, _AttenuationMultiplier);
+ #endif
+
+ float viewZ = dot(_WorldSpaceCameraPos - poiMesh.worldPos, UNITY_MATRIX_V[2].xyz);
+ float shadowFadeDistance = UnityComputeShadowFadeDistance(poiMesh.worldPos, viewZ);
+ float shadowFade = UnityComputeShadowFade(shadowFadeDistance);
+ float bakedAttenuation = UnitySampleBakedOcclusion(poiMesh.lightmapUV.xy, poiMesh.worldPos);
+ attenuation = UnityMixRealtimeAndBakedShadows(
+ attenuation, bakedAttenuation, shadowFade
+ );
+ #endif
+
+ return attenuation;
+}
+
+void ApplySubtractiveLighting(inout UnityIndirect indirectLight)
+{
+ #if SUBTRACTIVE_LIGHTING
+ poiLight.attenuation = FadeShadows(lerp(1, poiLight.attenuation, _AttenuationMultiplier));
+
+ float ndotl = saturate(dot(i.normal, _WorldSpaceLightPos0.xyz));
+ float3 shadowedLightEstimate = ndotl * (1 - poiLight.attenuation) * _LightColor0.rgb;
+ float3 subtractedLight = indirectLight.diffuse - shadowedLightEstimate;
+ subtractedLight = max(subtractedLight, unity_ShadowColor.rgb);
+ subtractedLight = lerp(subtractedLight, indirectLight.diffuse, _LightShadowData.x);
+ indirectLight.diffuse = min(subtractedLight, indirectLight.diffuse);
+ #endif
+}
+
+float3 weightedBlend(float3 layer1, float3 layer2, float2 weights)
+{
+ return(weights.x * layer1 + weights.y * layer2) / (weights.x + weights.y);
+}
+
+UnityIndirect CreateIndirectLight(float3 normal)
+{
+ UnityIndirect indirectLight;
+ indirectLight.diffuse = 0;
+ indirectLight.specular = 0;
+
+ #if defined(FORWARD_BASE_PASS)
+ #if defined(LIGHTMAP_ON)
+ indirectLight.diffuse = DecodeLightmap(UNITY_SAMPLE_TEX2D(unity_Lightmap, poiMesh.lightmapUV.xy));
+
+ #if defined(DIRLIGHTMAP_COMBINED)
+ float4 lightmapDirection = UNITY_SAMPLE_TEX2D_SAMPLER(
+ unity_LightmapInd, unity_Lightmap, poiMesh.lightmapUV.xy
+ );
+ indirectLight.diffuse = DecodeDirectionalLightmap(
+ indirectLight.diffuse, lightmapDirection, normal
+ );
+ #endif
+ ApplySubtractiveLighting(indirectLight);
+ #endif
+
+ #if defined(DYNAMICLIGHTMAP_ON)
+ float3 dynamicLightDiffuse = DecodeRealtimeLightmap(
+ UNITY_SAMPLE_TEX2D(unity_DynamicLightmap, poiMesh.lightmapUV.zw)
+ );
+
+ #if defined(DIRLIGHTMAP_COMBINED)
+ float4 dynamicLightmapDirection = UNITY_SAMPLE_TEX2D_SAMPLER(
+ unity_DynamicDirectionality, unity_DynamicLightmap,
+ poiMesh.lightmapUV.zw
+ );
+ indirectLight.diffuse += DecodeDirectionalLightmap(
+ dynamicLightDiffuse, dynamicLightmapDirection, normal
+ );
+ #else
+ indirectLight.diffuse += dynamicLightDiffuse;
+ #endif
+ #endif
+
+ #if !defined(LIGHTMAP_ON) && !defined(DYNAMICLIGHTMAP_ON)
+ #if UNITY_LIGHT_PROBE_PROXY_VOLUME
+ if (unity_ProbeVolumeParams.x == 1)
+ {
+ indirectLight.diffuse = SHEvalLinearL0L1_SampleProbeVolume(
+ float4(normal, 1), poiMesh.worldPos
+ );
+ indirectLight.diffuse = max(0, indirectLight.diffuse);
+ #if defined(UNITY_COLORSPACE_GAMMA)
+ indirectLight.diffuse = LinearToGammaSpace(indirectLight.diffuse);
+ #endif
+ }
+ else
+ {
+ indirectLight.diffuse += max(0, ShadeSH9(float4(normal, 1)));
+ }
+ #else
+ indirectLight.diffuse += max(0, ShadeSH9(float4(normal, 1)));
+ #endif
+ #endif
+
+ float3 reflectionDir = reflect(-poiCam.viewDir, normal);
+ Unity_GlossyEnvironmentData envData;
+ envData.roughness = 1 - _LightingStandardSmoothness;
+ envData.reflUVW = BoxProjection(
+ reflectionDir, poiMesh.worldPos.xyz,
+ unity_SpecCube0_ProbePosition,
+ unity_SpecCube0_BoxMin.xyz, unity_SpecCube0_BoxMax.xyz
+ );
+ float3 probe0 = Unity_GlossyEnvironment(
+ UNITY_PASS_TEXCUBE(unity_SpecCube0), unity_SpecCube0_HDR, envData
+ );
+ envData.reflUVW = BoxProjection(
+ reflectionDir, poiMesh.worldPos.xyz,
+ unity_SpecCube1_ProbePosition,
+ unity_SpecCube1_BoxMin.xyz, unity_SpecCube1_BoxMax.xyz
+ );
+ #if UNITY_SPECCUBE_BLENDING
+ float interpolator = unity_SpecCube0_BoxMin.w;
+ UNITY_BRANCH
+ if (interpolator < 0.99999)
+ {
+ float3 probe1 = Unity_GlossyEnvironment(
+ UNITY_PASS_TEXCUBE_SAMPLER(unity_SpecCube1, unity_SpecCube0),
+ unity_SpecCube0_HDR, envData
+ );
+ indirectLight.specular = lerp(probe1, probe0, interpolator);
+ }
+ else
+ {
+ indirectLight.specular = probe0;
+ }
+ #else
+ indirectLight.specular = probe0;
+ #endif
+ float occlusion = 1;
+ UNITY_BRANCH
+ if (_LightingEnableAO)
+ {
+ occlusion = lerp(1, POI2D_SAMPLER_PAN(_LightingAOTex, _MainTex, poiMesh.uv[_LightingAOTexUV], _LightingAOTexPan).r, _AOStrength);
+ }
+
+ indirectLight.diffuse *= occlusion;
+ indirectLight.diffuse = max(indirectLight.diffuse, _LightingMinLightBrightness);
+ indirectLight.specular *= occlusion;
+ #endif
+
+ return indirectLight;
+}
+
+/*
+* Poiyomi's cool as heck code starts here :smug:
+*/
+
+half PoiDiffuse(half NdotV, half NdotL, half LdotH)
+{
+ half fd90 = 0.5 + 2 * LdotH * LdotH * SmoothnessToPerceptualRoughness(.5);
+ // Two schlick fresnel term
+ half lightScatter = (1 + (fd90 - 1) * Pow5(1 - NdotL));
+ half viewScatter = (1 + (fd90 - 1) * Pow5(1 - NdotV));
+
+ return lightScatter * viewScatter;
+}
+
+float3 ShadeSH9Indirect()
+{
+ return ShadeSH9(half4(0.0, -1.0, 0.0, 1.0));
+}
+
+float3 ShadeSH9Direct()
+{
+ return ShadeSH9(half4(0.0, 1.0, 0.0, 1.0));
+}
+
+float3 ShadeSH9Normal(float3 normalDirection)
+{
+ return ShadeSH9(half4(normalDirection, 1.0));
+}
+
+half3 GetSHLength()
+{
+ half3 x, x1;
+ x.r = length(unity_SHAr);
+ x.g = length(unity_SHAg);
+ x.b = length(unity_SHAb);
+ x1.r = length(unity_SHBr);
+ x1.g = length(unity_SHBg);
+ x1.b = length(unity_SHBb);
+ return x + x1;
+}
+half3 GetSHDirectionL1()
+{
+ //float3 grayscale = float3(.3, .59, .11);
+ float3 grayscale = float3(.33333, .33333, .33333);
+ half3 r = Unity_SafeNormalize(half3(unity_SHAr.x, unity_SHAr.y, unity_SHAr.z));
+ half3 g = Unity_SafeNormalize(half3(unity_SHAg.x, unity_SHAg.y, unity_SHAg.z));
+ half3 b = Unity_SafeNormalize(half3(unity_SHAb.x, unity_SHAb.y, unity_SHAb.z));
+ return Unity_SafeNormalize(grayscale.r * r + grayscale.g * g + grayscale.b * b);
+}
+float3 GetSHDirectionL1_()
+{
+ // For efficiency, we only get the direction from L1.
+ // Because getting it from L2 would be too hard!
+ return Unity_SafeNormalize((unity_SHAr.xyz + unity_SHAg.xyz + unity_SHAb.xyz));
+}
+// Returns the value from SH in the lighting direction with the
+// brightest intensity.
+half3 GetSHMaxL1()
+{
+ float3 maxDirection = GetSHDirectionL1();
+ return ShadeSH9_wrapped(maxDirection, 0);
+}
+
+
+float3 calculateRealisticLighting(float4 colorToLight, fixed detailShadowMap)
+{
+ return UNITY_BRDF_PBS(1, 0, 0, _LightingStandardSmoothness, poiMesh.normals[1], poiCam.viewDir, CreateLight(poiMesh.normals[1], detailShadowMap), CreateIndirectLight(poiMesh.normals[1])).xyz;
+}
+
+void calculateBasePassLightMaps()
+{
+ #if defined(FORWARD_BASE_PASS) || defined(POI_META_PASS)
+ float AOMap = 1;
+ float AOStrength = 0;
+ float3 lightColor = poiLight.color;
+ /*
+ * Generate Basic Light Maps
+ */
+
+ bool lightExists = false;
+ if (any(_LightColor0.rgb >= 0.002))
+ {
+ lightExists = true;
+ }
+ #ifndef OUTLINE
+ UNITY_BRANCH
+ if (_LightingEnableAO)
+ {
+ AOMap = POI2D_SAMPLER_PAN(_LightingAOTex, _MainTex, poiMesh.uv[_LightingAOTexUV], _LightingAOTexPan).r;
+ AOStrength = _AOStrength;
+ poiLight.occlusion = lerp(1, AOMap, AOStrength);
+ }
+ #ifdef FORWARD_BASE_PASS
+ //poiLight.color = saturate(_LightColor0.rgb) + saturate(ShadeSH9(normalize(unity_SHAr + unity_SHAg + unity_SHAb)));
+ if (lightExists)
+ {
+ lightColor = _LightColor0.rgb + BetterSH9(float4(0, 0, 0, 1));
+ }
+ else
+ {
+ lightColor = BetterSH9(normalize(unity_SHAr + unity_SHAg + unity_SHAb));
+ }
+
+ //lightColor = magic * magiratio + normalLight * normaRatio;
+ //lightColor = magic + normalLight;
+ #endif
+ #endif
+
+ float3 grayscale_vector = float3(.33333, .33333, .33333);
+ float3 ShadeSH9Plus = GetSHLength();
+ float3 ShadeSH9Minus = float3(unity_SHAr.w, unity_SHAg.w, unity_SHAb.w) + float3(unity_SHBr.z, unity_SHBg.z, unity_SHBb.z) / 3.0;
+
+ shadowStrength = 1;
+ #ifndef OUTLINE
+ shadowStrength = POI2D_SAMPLER_PAN(_LightingShadowMask, _MainTex, poiMesh.uv[_LightingShadowMaskUV], _LightingShadowMaskPan) * _ShadowStrength;
+ #else
+ shadowStrength = _OutlineShadowStrength;
+ #endif
+
+ float bw_lightColor = dot(lightColor, grayscale_vector);
+ float bw_directLighting = (((poiLight.nDotL * 0.5 + 0.5) * bw_lightColor * lerp(1, poiLight.attenuation, _AttenuationMultiplier)) + dot(ShadeSH9Normal(poiMesh.normals[1]), grayscale_vector));
+ float bw_bottomIndirectLighting = dot(ShadeSH9Minus, grayscale_vector);
+ float bw_topIndirectLighting = dot(ShadeSH9Plus, grayscale_vector);
+ float lightDifference = ((bw_topIndirectLighting + bw_lightColor) - bw_bottomIndirectLighting);
+
+ fixed detailShadow = 1;
+ UNITY_BRANCH
+ if (_LightingDetailShadowsEnabled)
+ {
+ detailShadow = lerp(1, POI2D_SAMPLER_PAN(_LightingDetailShadows, _MainTex, poiMesh.uv[_LightingDetailShadowsUV], _LightingDetailShadowsPan), _LightingDetailStrength).r;
+ }
+ UNITY_BRANCH
+ if (_LightingOnlyUnityShadows)
+ {
+ poiLight.lightMap = poiLight.attenuation;
+ }
+ else
+ {
+ poiLight.lightMap = smoothstep(0, lightDifference, bw_directLighting - bw_bottomIndirectLighting);
+ }
+ poiLight.lightMap *= detailShadow;
+
+ /*
+ * Decide on light colors
+ */
+
+ indirectLighting = 0;
+ directLighting = 0;
+
+
+
+ UNITY_BRANCH
+ if (_LightingIndirectColorMode == 1)
+ {
+ indirectLighting = BetterSH9(float4(poiMesh.normals[1], 1));
+ }
+ else
+ {
+ indirectLighting = ShadeSH9Minus;
+ }
+
+ poiLight.directLighting = lightColor;
+ poiLight.indirectLighting = indirectLighting;
+
+
+ UNITY_BRANCH
+ if (_LightingDirectColorMode == 0)
+ {
+ float3 magic = max(BetterSH9(normalize(unity_SHAr + unity_SHAg + unity_SHAb)), 0);
+ float3 normalLight = _LightColor0.rgb + BetterSH9(float4(0, 0, 0, 1));
+
+ float magiLumi = calculateluminance(magic);
+ float normaLumi = calculateluminance(normalLight);
+ float maginormalumi = magiLumi + normaLumi;
+
+ float magiratio = magiLumi / maginormalumi;
+ float normaRatio = normaLumi / maginormalumi;
+
+ float target = calculateluminance(magic * magiratio + normalLight * normaRatio);
+ float3 properLightColor = magic * poiLight.occlusion + normalLight;
+ float properLuminance = calculateluminance(magic + normalLight);
+ directLighting = properLightColor * max(0.0001, (target / properLuminance));
+ }
+ else
+ {
+ if (lightExists)
+ {
+ directLighting = _LightColor0.rgb + BetterSH9(float4(0, 0, 0, 1)) * poiLight.occlusion;
+ }
+ else
+ {
+ directLighting = max(BetterSH9(normalize(unity_SHAr + unity_SHAg + unity_SHAb)), 0);
+ }
+ }
+
+ UNITY_BRANCH
+ if (!_LightingUncapped)
+ {
+ float directluminance = calculateluminance(directLighting);
+ float indirectluminance = calculateluminance(indirectLighting);
+ directLighting = min(directLighting, directLighting / max(0.0001, (directluminance / 1)));
+ indirectLighting = min(indirectLighting, indirectLighting / max(0.0001, (indirectluminance / 1)));
+ }
+
+ directLighting = lerp(directLighting, dot(directLighting, float3(0.299, 0.587, 0.114)), _LightingMonochromatic);
+ indirectLighting = lerp(indirectLighting, dot(indirectLighting, float3(0.299, 0.587, 0.114)), _LightingMonochromatic);
+
+
+ if (max(max(indirectLighting.x, indirectLighting.y), indirectLighting.z) <= _LightingNoIndirectThreshold && max(max(directLighting.x, directLighting.y), directLighting.z) >= 0)
+ {
+ indirectLighting = directLighting * _LightingNoIndirectMultiplier;
+ }
+
+
+ UNITY_BRANCH
+ if (_LightingMinShadowBrightnessRatio)
+ {
+ float directluminance = clamp(directLighting.r * 0.299 + directLighting.g * 0.587 + directLighting.b * 0.114, 0, 1);
+ if (directluminance > 0)
+ {
+ indirectLighting = max(0.001, indirectLighting);
+ }
+ float indirectluminance = clamp(indirectLighting.r * 0.299 + indirectLighting.g * 0.587 + indirectLighting.b * 0.114, 0, 1);
+ float targetluminance = directluminance * _LightingMinShadowBrightnessRatio;
+ if (indirectluminance < targetluminance)
+ {
+ indirectLighting = indirectLighting / max(0.0001, indirectluminance / targetluminance);
+ }
+ }
+
+ poiLight.rampedLightMap = 1 - smoothstep(0, .5, 1 - poiLight.lightMap);
+ poiLight.finalLighting = directLighting;
+
+ indirectLighting = max(indirectLighting,0);
+ directLighting = max(directLighting,0);
+
+ /*
+ * Create Gradiant Maps
+ */
+ switch(_LightingRampType)
+ {
+ case 0: // Ramp Texture
+
+ {
+ poiLight.rampedLightMap = lerp(1, UNITY_SAMPLE_TEX2D(_ToonRamp, poiLight.lightMap + _ShadowOffset).rgb, shadowStrength.r);
+ UNITY_BRANCH
+ if (_LightingIgnoreAmbientColor)
+ {
+ poiLight.finalLighting = lerp(poiLight.rampedLightMap * directLighting * poiLight.occlusion, directLighting, poiLight.rampedLightMap);
+ }
+ else
+ {
+ poiLight.finalLighting = lerp(indirectLighting * poiLight.occlusion, directLighting, poiLight.rampedLightMap);
+
+ }
+ }
+ break;
+ case 1: // Math Gradient
+
+ {
+ poiLight.rampedLightMap = saturate(1 - smoothstep(_LightingGradientStart - .000001, _LightingGradientEnd, 1 - poiLight.lightMap));
+ float3 shadowColor = _LightingShadowColor;
+ UNITY_BRANCH
+ if (_UseShadowTexture)
+ {
+ shadowColor = 1;
+ }
+ UNITY_BRANCH
+ if (_LightingIgnoreAmbientColor)
+ {
+ poiLight.finalLighting = lerp((directLighting * shadowColor * poiLight.occlusion), (directLighting), saturate(poiLight.rampedLightMap + 1 - _ShadowStrength));
+ }
+ else
+ {
+ poiLight.finalLighting = lerp((indirectLighting * shadowColor * poiLight.occlusion), (directLighting), saturate(poiLight.rampedLightMap + 1 - _ShadowStrength));
+ }
+ }
+ break;
+ case 2:
+ {
+ poiLight.rampedLightMap = saturate(1 - smoothstep(0, .5, 1 - poiLight.lightMap));
+ poiLight.finalLighting = directLighting;
+ }
+ break;
+ }
+
+ // DJL stuff
+ if (_LightingMode == 2) // Wrapped
+
+ {
+ float wrap = _LightingWrappedWrap;
+
+ float3 directcolor = (_LightColor0.rgb) * saturate(RTWrapFunc(poiLight.nDotL, wrap, _LightingWrappedNormalization));
+ float directatten = lerp(1, poiLight.attenuation, _AttenuationMultiplier);
+
+ uint normalsindex = _LightingIndirectColorMode > 0 ? 1: 0;
+ // if (_LightingIndirectColorMode == 1)
+ // {
+ // surfnormals = poiMesh.normals[1];
+ // }
+ // else
+ // {
+ // surfnormals = poiMesh.normals[0];
+ // }
+ float3 envlight = ShadeSH9_wrapped(poiMesh.normals[normalsindex], wrap);
+ envlight *= poiLight.occlusion;
+
+ poiLight.directLighting = directcolor * detailShadow * directatten;
+ poiLight.indirectLighting = envlight;
+
+
+ float3 ShadeSH9Plus_2 = GetSHMaxL1();
+ float bw_topDirectLighting_2 = dot(_LightColor0.rgb, grayscale_vector);
+ float bw_directLighting = dot(poiLight.directLighting, grayscale_vector);
+ float bw_indirectLighting = dot(poiLight.indirectLighting, grayscale_vector);
+ float bw_topIndirectLighting = dot(ShadeSH9Plus_2, grayscale_vector);
+
+ //poiLight.lightMap = saturate(dot(poiLight.indirectLighting + poiLight.directLighting, grayscale_vector));
+ poiLight.lightMap = smoothstep(0, bw_topIndirectLighting + bw_topDirectLighting_2, bw_indirectLighting + bw_directLighting);
+
+ poiLight.rampedLightMap = 1;
+ UNITY_BRANCH
+ if (_LightingRampType == 0) // Ramp Texture
+
+ {
+ poiLight.rampedLightMap = lerp(1, UNITY_SAMPLE_TEX2D(_ToonRamp, poiLight.lightMap + _ShadowOffset).rgb, shadowStrength.r);
+ }
+ else if (_LightingRampType == 1) // Math Gradient
+
+ {
+ poiLight.rampedLightMap = lerp(_LightingShadowColor * lerp(poiLight.indirectLighting, 1, _LightingIgnoreAmbientColor), float3(1, 1, 1), saturate(1 - smoothstep(_LightingGradientStart - .000001, _LightingGradientEnd, 1 - poiLight.lightMap)));
+ poiLight.rampedLightMap = lerp(float3(1, 1, 1), poiLight.rampedLightMap, shadowStrength.r);
+ }
+
+ poiLight.finalLighting = (poiLight.indirectLighting + poiLight.directLighting) * saturate(poiLight.rampedLightMap + 1 - _ShadowStrength);
+ }
+
+ if (!_LightingUncapped)
+ {
+ poiLight.finalLighting = saturate(poiLight.finalLighting);
+ }
+ //poiLight.finalLighting *= .8;
+ #endif
+ }
+
+ /*
+ void applyShadowTexture(inout float4 albedo)
+ {
+ UNITY_BRANCH
+ if (_UseShadowTexture && _LightingRampType == 1)
+ {
+ albedo.rgb = lerp(albedo.rgb, POI2D_SAMPLER_PAN(_LightingShadowTexture, _MainTex, poiMesh.uv[_LightingShadowTextureUV], _LightingShadowTexturePan) * _LightingShadowColor, (1 - poiLight.rampedLightMap) * shadowStrength);
+ }
+ }
+ */
+
+ float3 calculateNonImportantLighting(float attenuation, float attenuationDotNL, float3 albedo, float3 lightColor, half dotNL, half correctedDotNL)
+ {
+ fixed detailShadow = 1;
+ UNITY_BRANCH
+ if (_LightingDetailShadowsEnabled)
+ {
+ detailShadow = lerp(1, POI2D_SAMPLER_PAN(_LightingDetailShadows, _MainTex, poiMesh.uv[_LightingDetailShadowsUV], _LightingDetailShadowsPan), _LightingAdditiveDetailStrength).r;
+ }
+ UNITY_BRANCH
+ if (_LightingAdditiveType == 0)
+ {
+ return lightColor * attenuationDotNL * detailShadow; // Realistic
+ }
+ else if (_LightingAdditiveType == 1) // Toon
+
+ {
+ return lerp(lightColor * attenuation, lightColor * _LightingAdditivePassthrough * attenuation, smoothstep(_LightingAdditiveGradientStart, _LightingAdditiveGradientEnd, dotNL)) * detailShadow;
+ }
+ else //if(_LightingAdditiveType == 2) // Wrapped
+
+ {
+ float uv = saturate(RTWrapFunc(-dotNL, _LightingWrappedWrap, _LightingWrappedNormalization)) * detailShadow;
+
+ poiLight.rampedLightMap = 1;
+ if (_LightingRampType == 1) // Math Gradient
+ poiLight.rampedLightMap = lerp(_LightingShadowColor, float3(1, 1, 1), saturate(1 - smoothstep(_LightingGradientStart - .000001, _LightingGradientEnd, 1 - uv)));
+ // TODO: ramp texture or full shade/tint map for atlasing
+
+ return lightColor * poiLight.rampedLightMap * saturate(attenuation * uv);
+ }
+ }
+
+ void applyShadeMaps(inout float4 albedo)
+ {
+ UNITY_BRANCH
+ if (_LightingRampType == 2)
+ {
+ float3 baseColor = albedo.rgb;
+
+ float MainColorFeatherStep = _BaseColor_Step - _BaseShade_Feather;
+ float firstColorFeatherStep = _ShadeColor_Step - _1st2nd_Shades_Feather;
+
+ #if defined(PROP_1ST_SHADEMAP) || !defined(OPTIMIZER_ENABLED)
+ float4 firstShadeMap = POI2D_SAMPLER_PAN(_1st_ShadeMap, _MainTex, poiMesh.uv[_1st_ShadeMapUV], _1st_ShadeMapPan);
+ #else
+ float4 firstShadeMap = float4(1, 1, 1, 1);
+ #endif
+ firstShadeMap = lerp(firstShadeMap, albedo, _Use_BaseAs1st);
+
+ #if defined(PROP_2ND_SHADEMAP) || !defined(OPTIMIZER_ENABLED)
+ float4 secondShadeMap = POI2D_SAMPLER_PAN(_2nd_ShadeMap, _MainTex, poiMesh.uv[_2nd_ShadeMapUV], _2nd_ShadeMapPan);
+ #else
+ float4 secondShadeMap = float4(1, 1, 1, 1);
+ #endif
+ secondShadeMap = lerp(secondShadeMap, firstShadeMap, _Use_1stAs2nd);
+
+ firstShadeMap.rgb *= _1st_ShadeColor.rgb; //* lighColor
+ secondShadeMap.rgb *= _2nd_ShadeColor.rgb; //* LightColor;
+
+ float shadowMask = 1;
+ shadowMask *= _Use_1stShadeMapAlpha_As_ShadowMask ?(_1stShadeMapMask_Inverse ?(1.0 - firstShadeMap.a): firstShadeMap.a): 1;
+ shadowMask *= _Use_2ndShadeMapAlpha_As_ShadowMask ?(_2ndShadeMapMask_Inverse ?(1.0 - secondShadeMap.a): secondShadeMap.a): 1;
+
+ float mainShadowMask = saturate(1 - ((poiLight.lightMap) - MainColorFeatherStep) / (_BaseColor_Step - MainColorFeatherStep) * (shadowMask));
+ float firstSecondShadowMask = saturate(1 - ((poiLight.lightMap) - firstColorFeatherStep) / (_ShadeColor_Step - firstColorFeatherStep) * (shadowMask));
+
+ #if defined(PROP_LIGHTINGSHADOWMASK) || !defined(OPTIMIZER_ENABLED)
+ float removeShadow = POI2D_SAMPLER_PAN(_LightingShadowMask, _MainTex, poiMesh.uv[_LightingShadowMaskUV], _LightingShadowMaskPan).r;
+ #else
+ float removeShadow = 1;
+ #endif
+ mainShadowMask *= removeShadow;
+ firstSecondShadowMask *= removeShadow;
+
+ albedo.rgb = lerp(albedo.rgb, lerp(firstShadeMap.rgb, secondShadeMap.rgb, firstSecondShadowMask), mainShadowMask);
+ }
+ }
+
+ float3 calculateFinalLighting(inout float3 albedo, float4 finalColor)
+ {
+ float3 finalLighting = 1;
+ // Additive Lighting
+ #ifdef FORWARD_ADD_PASS
+ fixed detailShadow = 1;
+ UNITY_BRANCH
+ if (_LightingDetailShadowsEnabled)
+ {
+ detailShadow = lerp(1, POI2D_SAMPLER_PAN(_LightingDetailShadows, _MainTex, poiMesh.uv[_LightingDetailShadowsUV], _LightingDetailShadowsPan), _LightingAdditiveDetailStrength).r;
+ }
+ UNITY_BRANCH
+ if (_LightingAdditiveType == 0) // Realistic
+
+ {
+ finalLighting = poiLight.color * poiLight.attenuation * max(0, poiLight.nDotL) * detailShadow * poiLight.additiveShadow;
+ }
+ else if (_LightingAdditiveType == 1) // Toon
+
+ {
+ #if defined(POINT) || defined(SPOT)
+ finalLighting = lerp(poiLight.color * max(poiLight.additiveShadow, _LightingAdditivePassthrough), poiLight.color * _LightingAdditivePassthrough, smoothstep(_LightingAdditiveGradientStart, _LightingAdditiveGradientEnd, 1 - (.5 * poiLight.nDotL + .5))) * poiLight.attenuation * detailShadow;
+ #else
+ finalLighting = lerp(poiLight.color * max(poiLight.attenuation, _LightingAdditivePassthrough), poiLight.color * _LightingAdditivePassthrough, smoothstep(_LightingAdditiveGradientStart, _LightingAdditiveGradientEnd, 1 - (.5 * poiLight.nDotL + .5))) * detailShadow;
+ #endif
+ }
+ else //if(_LightingAdditiveType == 2) // Wrapped
+
+ {
+ float uv = saturate(RTWrapFunc(poiLight.nDotL, _LightingWrappedWrap, _LightingWrappedNormalization)) * detailShadow;
+
+ poiLight.rampedLightMap = 1;
+ UNITY_BRANCH
+ if (_LightingRampType == 1) // Math Gradient
+ poiLight.rampedLightMap = lerp(_LightingShadowColor, float3(1, 1, 1), saturate(1 - smoothstep(_LightingGradientStart - .000001, _LightingGradientEnd, 1 - uv)));
+ // TODO: ramp texture or full shade/tint map for atlasing
+ //poiLight.rampedLightMap = lerp(1, UNITY_SAMPLE_TEX2D(_ToonRamp, float2(uv + _ShadowOffset, 1)), shadowStrength.r);
+
+ float shadowatten = max(poiLight.additiveShadow, _LightingAdditivePassthrough);
+ return poiLight.color * poiLight.rampedLightMap * saturate(poiLight.attenuation * uv * shadowatten);
+ }
+ #endif
+
+ // Base and Meta Lighting
+ #if defined(FORWARD_BASE_PASS) || defined(POI_META_PASS)
+ #ifdef VERTEXLIGHT_ON
+ poiLight.vFinalLighting = 0;
+
+ for (int index = 0; index < 4; index++)
+ {
+ poiLight.vFinalLighting += calculateNonImportantLighting(poiLight.vAttenuation[index], poiLight.vAttenuationDotNL[index], albedo, poiLight.vColor[index], poiLight.vDotNL[index], poiLight.vCorrectedDotNL[index]);
+ }
+ #endif
+
+ switch(_LightingMode)
+ {
+ case 0: // Toon Lighting
+ case 2: // or wrapped
+
+ {
+ // HSL Shading
+ UNITY_BRANCH
+ if (_LightingEnableHSL)
+ {
+ float3 HSLMod = float3(_LightingShadowHue * 2 - 1, _LightingShadowSaturation * 2 - 1, _LightingShadowLightness * 2 - 1) * (1 - poiLight.rampedLightMap);
+ albedo = lerp(albedo.rgb, ModifyViaHSL(albedo.rgb, HSLMod), _LightingHSLIntensity);
+ }
+
+ // Normal Shading
+ UNITY_BRANCH
+ if (_LightingMinLightBrightness > 0)
+ {
+ poiLight.finalLighting = max(0.001, poiLight.finalLighting);
+ float finalluminance = calculateluminance(poiLight.finalLighting);
+ finalLighting = max(poiLight.finalLighting, poiLight.finalLighting / max(0.0001, (finalluminance / _LightingMinLightBrightness)));
+ poiLight.finalLighting = finalLighting;
+ }
+ else
+ {
+ finalLighting = poiLight.finalLighting;
+ }
+ }
+ break;
+ case 1: // realistic
+
+ {
+ fixed detailShadow = 1;
+ UNITY_BRANCH
+ if (_LightingDetailShadowsEnabled)
+ {
+ detailShadow = lerp(1, POI2D_SAMPLER_PAN(_LightingDetailShadows, _MainTex, poiMesh.uv[_LightingDetailShadowsUV], _LightingDetailShadowsPan), _LightingDetailStrength).r;
+ }
+
+ float3 realisticLighting = calculateRealisticLighting(finalColor, detailShadow).rgb;
+ finalLighting = lerp(realisticLighting, dot(realisticLighting, float3(0.299, 0.587, 0.114)), _LightingMonochromatic);
+ }
+ break;
+ case 3: // Skin
+
+ {
+ float subsurfaceShadowWeight = 0.0h;
+ float3 ambientNormalWorld = poiMesh.normals[1];//aTangentToWorld(s, s.blurredNormalTangent);
+
+ // Scattering mask.
+ float subsurface = 1;
+ float skinScatteringMask = _SssWeight * saturate(1.0h / _SssMaskCutoff * subsurface);
+ float skinScattering = saturate(subsurface * _SssScale * 2 + _SssBias);
+
+ // Skin subsurface depth absorption tint.
+ // cf http://www.crytek.com/download/2014_03_25_CRYENGINE_GDC_Schultz.pdf pg 35
+ half3 absorption = exp((1.0h - subsurface) * _SssTransmissionAbsorption.rgb);
+
+ // Albedo scale for absorption assumes ~0.5 luminance for Caucasian skin.
+ absorption *= saturate(finalColor.rgb * unity_ColorSpaceDouble.rgb);
+
+ // Blurred normals for indirect diffuse and direct scattering.
+ ambientNormalWorld = normalize(lerp(poiMesh.normals[1], ambientNormalWorld, _SssBumpBlur));
+
+ float ndlBlur = dot(poiMesh.normals[1], poiLight.direction) * 0.5h + 0.5h;
+ float lumi = dot(poiLight.color, half3(0.2126h, 0.7152h, 0.0722h));
+ float4 sssLookupUv = float4(ndlBlur, skinScattering * lumi, 0.0f, 0.0f);
+ half3 sss = poiLight.lightMap * poiLight.attenuation * tex2Dlod(_SkinLUT, sssLookupUv).rgb;
+ finalLighting = min(lerp(indirectLighting * _LightingShadowColor, _LightingShadowColor, _LightingIgnoreAmbientColor) + (sss * directLighting), directLighting);
+ }
+ break;
+ case 4:
+ {
+ finalLighting = directLighting;
+ }
+ break;
+ }
+ #endif
+ return finalLighting;
+ }
+
+
+ void applyLighting(inout float4 finalColor, float3 finalLighting)
+ {
+ #ifdef VERTEXLIGHT_ON
+ finalColor.rgb *= finalLighting + poiLight.vFinalLighting;
+ #else
+ //finalColor.rgb = blendSoftLight(finalColor.rgb, finalLighting);
+ //finalColor.rgb *= saturate(poiLight.directLighting);
+ finalColor.rgb *= finalLighting;
+ #endif
+ }
+ #endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiLighting.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiLighting.cginc.meta
new file mode 100644
index 00000000..7c935bd7
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiLighting.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: be833b6d97385124b8b1cbbcf36275b6
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMSDF.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMSDF.cginc
new file mode 100644
index 00000000..6339aab5
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMSDF.cginc
@@ -0,0 +1,243 @@
+#ifndef POI_MSDF
+ #define POI_MSDF
+
+ sampler2D _TextGlyphs;
+ float4 _TextGlyphs_ST;
+ float4 _TextGlyphs_TexelSize;
+ float _TextFPSUV;
+ float _TextTimeUV;
+ float _TextPositionUV;
+ float _TextPixelRange;
+
+ float _TextFPSEnabled;
+ float _TextPositionEnabled;
+ float _TextTimeEnabled;
+
+
+ float4 _TextFPSColor;
+ half _TextFPSEmissionStrength;
+ fixed4 _TextFPSPadding;
+ half2 _TextFPSOffset;
+ half2 _TextFPSScale;
+ half _TextFPSRotation;
+
+ fixed _TextPositionVertical;
+ float4 _TextPositionColor;
+ half _TextPositionEmissionStrength;
+ fixed4 _TextPositionPadding;
+ half2 _TextPositionOffset;
+ half2 _TextPositionScale;
+ half _TextPositionRotation;
+
+ float4 _TextTimeColor;
+ half _TextTimeEmissionStrength;
+ fixed4 _TextTimePadding;
+ half2 _TextTimeOffset;
+ half2 _TextTimeScale;
+ half _TextTimeRotation;
+
+ #define glyphWidth 0.0625
+
+ #define ASCII_LEFT_PARENTHESIS 40
+ #define ASCII_RIGHT_PARENTHESIS 41
+ #define ASCII_POSITIVE 43
+ #define ASCII_PERIOD 46
+ #define ASCII_NEGATIVE 45
+ #define ASCII_COMMA 44
+ #define ASCII_E 69
+ #define ASCII_F 70
+ #define ASCII_I 73
+ #define ASCII_M 77
+ #define ASCII_O 79
+ #define ASCII_P 80
+ #define ASCII_S 83
+ #define ASCII_T 54
+ #define ASCII_SEMICOLON 58
+
+ float3 globalTextEmission;
+
+ half2 getAsciiCoordinate(float index)
+ {
+ return half2((index - 1) / 16, 1 - ((floor(index / 16 - glyphWidth)) / 16));
+ }
+
+ float median(float r, float g, float b)
+ {
+ return max(min(r, g), min(max(r, g), b));
+ }
+
+ void ApplyPositionText(inout float4 albedo, float2 uv)
+ {
+ float3 cameraPos = clamp(getCameraPosition(), -999, 999);
+ float3 absCameraPos = abs(cameraPos);
+ float totalCharacters = 20;
+ float positionArray[20];
+ positionArray[0] = cameraPos.x >= 0 ? ASCII_NEGATIVE: ASCII_POSITIVE;
+ positionArray[1] = floor((absCameraPos.x * .01) % 10) + 48;
+ positionArray[2] = floor((absCameraPos.x * .1) % 10) + 48;
+ positionArray[3] = floor(absCameraPos.x % 10) + 48;
+ positionArray[4] = ASCII_PERIOD;
+ positionArray[5] = floor((absCameraPos.x * 10) % 10) + 48;
+ positionArray[6] = ASCII_COMMA;
+ positionArray[7] = cameraPos.y >= 0 ? ASCII_NEGATIVE: ASCII_POSITIVE;
+ positionArray[8] = floor((absCameraPos.y * .01) % 10) + 48;
+ positionArray[9] = floor((absCameraPos.y * .1) % 10) + 48;
+ positionArray[10] = floor(absCameraPos.y % 10) + 48;
+ positionArray[11] = ASCII_PERIOD;
+ positionArray[12] = floor((absCameraPos.y * 10) % 10) + 48;
+ positionArray[13] = ASCII_COMMA;
+ positionArray[14] = cameraPos.z >= 0 ? ASCII_NEGATIVE: ASCII_POSITIVE;
+ positionArray[15] = floor((absCameraPos.z * .01) % 10) + 48;
+ positionArray[16] = floor((absCameraPos.z * .1) % 10) + 48;
+ positionArray[17] = floor(absCameraPos.z % 10) + 48;
+ positionArray[18] = ASCII_PERIOD;
+ positionArray[19] = floor((absCameraPos.z * 10) % 10) + 48;
+
+ uv = TransformUV(_TextPositionOffset, _TextPositionRotation, _TextPositionScale, uv);
+
+ if (uv.x > 1 || uv.x < 0 || uv.y > 1 || uv.y < 0)
+ {
+ return;
+ }
+
+ float currentCharacter = floor(uv.x * totalCharacters);
+ half2 glyphPos = getAsciiCoordinate(positionArray[currentCharacter]);
+
+ float2 startUV = float2(1 / totalCharacters * currentCharacter, 0);
+ float2 endUV = float2(1 / totalCharacters * (currentCharacter + 1), 1);
+
+ fixed4 textPositionPadding = _TextPositionPadding;
+ textPositionPadding *= 1 / totalCharacters;
+ uv = remapClamped(uv, startUV, endUV, float2(glyphPos.x + textPositionPadding.x, glyphPos.y - glyphWidth + textPositionPadding.y), float2(glyphPos.x + glyphWidth - textPositionPadding.z, glyphPos.y - textPositionPadding.w));
+
+ if (uv.x > glyphPos.x + glyphWidth - textPositionPadding.z - .001 || uv.x < glyphPos.x + textPositionPadding.x + .001 || uv.y > glyphPos.y - textPositionPadding.w - .001 || uv.y < glyphPos.y - glyphWidth + textPositionPadding.y + .001)
+ {
+ return;
+ }
+
+ float3 samp = tex2D(_TextGlyphs, TRANSFORM_TEX(uv, _TextGlyphs)).rgb;
+ float2 msdfUnit = _TextPixelRange / _TextGlyphs_TexelSize.zw;
+ float sigDist = median(samp.r, samp.g, samp.b) - 0.5;
+ sigDist *= max(dot(msdfUnit, 0.5 / fwidth(uv)), 1);
+ float opacity = clamp(sigDist + 0.5, 0, 1);
+ albedo.rgb = lerp(albedo.rgb, _TextPositionColor.rgb, opacity * _TextPositionColor.a);
+ globalTextEmission += _TextPositionColor.rgb * opacity * _TextPositionEmissionStrength;
+ }
+
+ void ApplyTimeText(inout float4 albedo, float2 uv)
+ {
+ float instanceTime = _Time.y;
+ float hours = instanceTime / 3600;
+ float minutes = (instanceTime / 60) % 60;
+ float seconds = instanceTime % 60;
+ float totalCharacters = 8;
+ float timeArray[8];
+ timeArray[0] = floor((hours * .1) % 10) + 48;
+ timeArray[1] = floor(hours % 10) + 48;
+ timeArray[2] = ASCII_SEMICOLON;
+ timeArray[3] = floor((minutes * .1) % 10) + 48;
+ timeArray[4] = floor(minutes % 10) + 48;
+ timeArray[5] = ASCII_SEMICOLON;
+ timeArray[6] = floor((seconds * .1) % 10) + 48;
+ timeArray[7] = floor(seconds % 10) + 48;
+
+ uv = TransformUV(_TextTimeOffset, _TextTimeRotation, _TextTimeScale, uv);
+
+ if(uv.x > 1 || uv.x < 0 || uv.y > 1 || uv.y < 0)
+ {
+ return;
+ }
+
+ float currentCharacter = floor(uv.x * totalCharacters);
+ half2 glyphPos = getAsciiCoordinate(timeArray[currentCharacter]);
+ // 0.1428571 = 1/7 = 1 / totalCharacters
+ float startUV = 1 / totalCharacters * currentCharacter;
+ float endUV = 1 / totalCharacters * (currentCharacter + 1);
+ fixed4 textTimePadding = _TextTimePadding;
+ textTimePadding *= 1 / totalCharacters;
+ uv = remapClamped(uv, float2(startUV, 0), float2(endUV, 1), float2(glyphPos.x + textTimePadding.x, glyphPos.y - glyphWidth + textTimePadding.y), float2(glyphPos.x + glyphWidth - textTimePadding.z, glyphPos.y - textTimePadding.w));
+
+ if (uv.x > glyphPos.x + glyphWidth - textTimePadding.z - .001 || uv.x < glyphPos.x + textTimePadding.x + .001 || uv.y > glyphPos.y - textTimePadding.w - .001 || uv.y < glyphPos.y - glyphWidth + textTimePadding.y + .001)
+ {
+ return;
+ }
+
+ float3 samp = tex2D(_TextGlyphs, TRANSFORM_TEX(uv, _TextGlyphs)).rgb;
+ float2 msdfUnit = _TextPixelRange / _TextGlyphs_TexelSize.zw;
+ float sigDist = median(samp.r, samp.g, samp.b) - 0.5;
+ sigDist *= max(dot(msdfUnit, 0.5 / fwidth(uv)), 1);
+ float opacity = clamp(sigDist + 0.5, 0, 1);
+ albedo.rgb = lerp(albedo.rgb, _TextTimeColor.rgb, opacity * _TextTimeColor.a);
+ globalTextEmission += _TextTimeColor.rgb * opacity * _TextTimeEmissionStrength;
+ }
+
+ void ApplyFPSText(inout float4 albedo, float2 uv)
+ {
+ float smoothDeltaTime = clamp(unity_DeltaTime.w, 0, 999);
+ float totalCharacters = 7;
+ float fpsArray[7];
+ fpsArray[0] = ASCII_F;
+ fpsArray[1] = ASCII_P;
+ fpsArray[2] = ASCII_S;
+ fpsArray[3] = ASCII_SEMICOLON;
+ fpsArray[4] = floor((smoothDeltaTime * .01) % 10) + 48;
+ fpsArray[5] = floor((smoothDeltaTime * .1) % 10) + 48;
+ fpsArray[6] = floor(smoothDeltaTime % 10) + 48;
+
+ uv = TransformUV(_TextFPSOffset, _TextFPSRotation, _TextFPSScale, uv);
+
+ if(uv.x > 1 || uv.x < 0 || uv.y > 1 || uv.y < 0)
+ {
+ return;
+ }
+
+ float currentCharacter = floor(uv.x * totalCharacters);
+ half2 glyphPos = getAsciiCoordinate(fpsArray[currentCharacter]);
+ // 0.1428571 = 1/7 = 1 / totalCharacters
+ float startUV = 1 / totalCharacters * currentCharacter;
+ float endUV = 1 / totalCharacters * (currentCharacter + 1);
+
+ fixed4 textFPSPadding = _TextFPSPadding;
+ textFPSPadding *= 1 / totalCharacters;
+ uv = remapClamped(uv, float2(startUV, 0), float2(endUV, 1), float2(glyphPos.x + textFPSPadding.x, glyphPos.y - glyphWidth + textFPSPadding.y), float2(glyphPos.x + glyphWidth - textFPSPadding.z, glyphPos.y - textFPSPadding.w));
+
+ if (uv.x > glyphPos.x + glyphWidth - textFPSPadding.z - .001 || uv.x < glyphPos.x + textFPSPadding.x + .001 || uv.y > glyphPos.y - textFPSPadding.w - .001 || uv.y < glyphPos.y - glyphWidth + textFPSPadding.y + .001)
+ {
+ return;
+ }
+
+ float3 samp = tex2D(_TextGlyphs, TRANSFORM_TEX(uv, _TextGlyphs)).rgb;
+ float2 msdfUnit = _TextPixelRange / _TextGlyphs_TexelSize.zw;
+ float sigDist = median(samp.r, samp.g, samp.b) - 0.5;
+ sigDist *= max(dot(msdfUnit, 0.5 / fwidth(uv)), 1);
+ float opacity = clamp(sigDist + 0.5, 0, 1);
+ albedo.rgb = lerp(albedo.rgb, _TextFPSColor.rgb, opacity * _TextFPSColor.a);
+ globalTextEmission += _TextFPSColor.rgb * opacity * _TextFPSEmissionStrength;
+ }
+
+ void ApplyTextOverlayColor(inout float4 albedo, inout float3 textOverlayEmission)
+ {
+ globalTextEmission = 0;
+ half positionalOpacity = 0;
+ #ifdef EFFECT_BUMP
+ UNITY_BRANCH
+ if(_TextFPSEnabled)
+ {
+ ApplyFPSText(albedo, poiMesh.uv[_TextFPSUV]);
+ }
+ UNITY_BRANCH
+ if(_TextPositionEnabled)
+ {
+ ApplyPositionText(albedo, poiMesh.uv[_TextPositionUV]);
+ }
+ UNITY_BRANCH
+ if(_TextTimeEnabled)
+ {
+ ApplyTimeText(albedo, poiMesh.uv[_TextTimeUV]);
+ }
+
+ textOverlayEmission = globalTextEmission;
+ #endif
+ }
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMSDF.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMSDF.cginc.meta
new file mode 100644
index 00000000..7f40f268
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMSDF.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 39347a84f5d044c4d917618f2cad9661
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMacros.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMacros.cginc
new file mode 100644
index 00000000..60897dea
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMacros.cginc
@@ -0,0 +1,40 @@
+#ifndef POI_MACROS
+ #define POI_MACROS
+
+ #define POI_TEXTURE_NOSAMPLER(tex) Texture2D tex; float4 tex##_ST; float2 tex##Pan; uint tex##UV
+ #define POI_TEXTURE(tex) UNITY_DECLARE_TEX2D(tex##); float4 tex##_ST; float2 tex##Pan; uint tex##UV
+ #define POI_NORMAL_NOSAMPLER(tex) Texture2D tex; float4 tex##_ST; float2 tex##Pan; uint tex##UV; float tex##Scale
+
+ #define POI2D_SAMPLER_PAN(tex, texSampler, uv, pan) (UNITY_SAMPLE_TEX2D_SAMPLER(tex, texSampler, TRANSFORM_TEX(uv, tex) + _Time.x * pan))
+ #define POI2D_SAMPLER(tex, texSampler, uv) (UNITY_SAMPLE_TEX2D_SAMPLER(tex, texSampler, TRANSFORM_TEX(uv, tex)))
+ #define POI2D_PAN(tex, uv, pan) (tex2D(tex, TRANSFORM_TEX(uv, tex) + _Time.x * pan))
+ #define POI2D(tex, uv) (tex2D(tex, TRANSFORM_TEX(uv, tex)))
+ #define POI_SAMPLE_TEX2D(tex, uv) (UNITY_SAMPLE_TEX2D(tex, TRANSFORM_TEX(uv, tex)))
+ #define POI_SAMPLE_TEX2D_PAN(tex, uv, pan) (UNITY_SAMPLE_TEX2D(tex, TRANSFORM_TEX(uv, tex) + _Time.x * pan))
+
+ #ifdef POINT
+ # define POI_LIGHT_ATTENUATION(destName, shadow, input, worldPos) \
+ unityShadowCoord3 lightCoord = mul(unity_WorldToLight, unityShadowCoord4(worldPos, 1)).xyz; \
+ fixed shadow = UNITY_SHADOW_ATTENUATION(input, worldPos); \
+ fixed destName = tex2D(_LightTexture0, dot(lightCoord, lightCoord).rr).r;
+ #endif
+
+ #ifdef SPOT
+ #if !defined(UNITY_HALF_PRECISION_FRAGMENT_SHADER_REGISTERS)
+ #define DECLARE_LIGHT_COORD(input, worldPos) unityShadowCoord4 lightCoord = mul(unity_WorldToLight, unityShadowCoord4(worldPos, 1))
+ #else
+ #define DECLARE_LIGHT_COORD(input, worldPos) unityShadowCoord4 lightCoord = input._LightCoord
+ #endif
+ # define POI_LIGHT_ATTENUATION(destName, shadow, input, worldPos) \
+ DECLARE_LIGHT_COORD(input, worldPos); \
+ fixed shadow = UNITY_SHADOW_ATTENUATION(input, worldPos); \
+ fixed destName = (lightCoord.z > 0) * UnitySpotCookie(lightCoord) * UnitySpotAttenuate(lightCoord.xyz);
+ #endif
+
+ #if defined(UNITY_COMPILER_HLSL)
+ #define PoiInitStruct(type,name) name = (type)0;
+ #else
+ #define PoiInitStruct(type,name)
+ #endif
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMacros.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMacros.cginc.meta
new file mode 100644
index 00000000..a9486762
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMacros.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 6e064571b72c98948b7726439d667d07
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMainTex.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMainTex.cginc
new file mode 100644
index 00000000..6c01d499
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMainTex.cginc
@@ -0,0 +1,192 @@
+#ifndef POI_MAINTEXTURE
+#define POI_MAINTEXTURE
+
+
+#if defined(PROP_CLIPPINGMASK) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_ClippingMask);
+#endif
+#if defined(PROP_MAINFADETEXTURE) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_MainFadeTexture);
+#endif
+
+float _Inverse_Clipping;
+float4 _Color;
+float _MainVertexColoring;
+float _MainVertexColoringLinearSpace;
+float _MainUseVertexColorAlpha;
+float _Saturation;
+float _MainDistanceFadeMin;
+float _MainDistanceFadeMax;
+half _MainMinAlpha;
+half _MainMaxAlpha;
+float _MainHueShift;
+float _MainFadeType;
+#ifdef COLOR_GRADING_HDR
+ #if defined(PROP_MAINCOLORADJUSTTEXTURE) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_MainColorAdjustTexture);
+ #endif
+ float _MainHueShiftToggle;
+ float _MainHueShiftSpeed;
+ float _MainHueShiftReplace;
+ float _MainSaturationShift;
+ float _MainBrightness;
+#endif
+
+#ifdef FINALPASS
+ #if defined(PROP_DETAILTEX) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_DetailTex);
+ #endif
+ half _DetailTexIntensity;
+ half3 _DetailTint;
+ float _DetailBrightness;
+#endif
+//globals
+float alphaMask;
+half3 diffColor;
+
+#include "CGI_PoiBackFace.cginc"
+
+float3 wireframeEmission;
+
+inline FragmentCommonData SpecularSetup(float4 i_tex, inout float4 albedo)
+{
+ half4 specGloss = 0;
+ half3 specColor = specGloss.rgb;
+ half smoothness = specGloss.a;
+
+ half oneMinusReflectivity;
+ diffColor = EnergyConservationBetweenDiffuseAndSpecular(albedo.rgb, specColor, /*out*/ oneMinusReflectivity);
+
+ FragmentCommonData o = (FragmentCommonData)0;
+ o.diffColor = diffColor;
+ o.specColor = specColor;
+ o.oneMinusReflectivity = oneMinusReflectivity;
+ o.smoothness = smoothness;
+ return o;
+}
+
+inline FragmentCommonData FragmentSetup(float4 i_tex, half3 i_viewDirForParallax, float3 i_posWorld, inout float4 albedo)
+{
+ i_tex = i_tex;
+
+ FragmentCommonData o = SpecularSetup(i_tex, albedo);
+ o.normalWorld = float3(0, 0, 0);
+ o.eyeVec = poiCam.viewDir;
+ o.posWorld = i_posWorld;
+
+ // NOTE: shader relies on pre-multiply alpha-blend (_SrcBlend = One, _DstBlend = OneMinusSrcAlpha)
+ o.diffColor = PreMultiplyAlpha(o.diffColor, 1, o.oneMinusReflectivity, /*out*/ o.alpha);
+ return o;
+}
+
+void initTextureData(inout float4 albedo, inout float4 mainTexture, inout float3 backFaceEmission, inout float3 dissolveEmission, in half3 detailMask)
+{
+ dissolveEmission = 0;
+
+ #if (defined(FORWARD_BASE_PASS) || defined(FORWARD_ADD_PASS))
+ #ifdef POI_MIRROR
+ applyMirrorTexture(mainTexture);
+ #endif
+ #endif
+ #if defined(PROP_CLIPPINGMASK) || !defined(OPTIMIZER_ENABLED)
+ alphaMask = POI2D_SAMPLER_PAN(_ClippingMask, _MainTex, poiMesh.uv[_ClippingMaskUV], _ClippingMaskPan).r;
+ #else
+ alphaMask = 1;
+ #endif
+ UNITY_BRANCH
+ if (_Inverse_Clipping)
+ {
+ alphaMask = 1 - alphaMask;
+ }
+ mainTexture.a *= alphaMask;
+
+ #ifndef POI_SHADOW
+ float3 vertexColor = poiMesh.vertexColor.rgb;
+ UNITY_BRANCH
+ if(_MainVertexColoringLinearSpace)
+ {
+ vertexColor = GammaToLinearSpace(poiMesh.vertexColor.rgb);
+ }
+
+ albedo = float4(mainTexture.rgb * max(_Color.rgb, float3(0.000000001, 0.000000001, 0.000000001)) * lerp(1, vertexColor, _MainVertexColoring), mainTexture.a * max(_Color.a, 0.0000001));
+
+ #if defined(POI_LIGHTING) && defined(FORWARD_BASE_PASS)
+ applyShadeMaps(albedo);
+ #endif
+
+ albedo *= lerp(1, poiMesh.vertexColor.a, _MainUseVertexColorAlpha);
+ #ifdef POI_RGBMASK
+ albedo.rgb = calculateRGBMask(albedo.rgb);
+ #endif
+
+ albedo.a = saturate(_AlphaMod + albedo.a);
+
+ wireframeEmission = 0;
+ #ifdef POI_WIREFRAME
+ applyWireframe(wireframeEmission, albedo);
+ #endif
+ float backFaceDetailIntensity = 1;
+
+ float mixedHueShift = _MainHueShift;
+ applyBackFaceTexture(backFaceDetailIntensity, mixedHueShift, albedo, backFaceEmission);
+
+ #ifdef POI_FUR
+ calculateFur();
+ #endif
+
+ #ifdef COLOR_GRADING_HDR
+ #if defined(PROP_MAINCOLORADJUSTTEXTURE) || !defined(OPTIMIZER_ENABLED)
+ float4 hueShiftAlpha = POI2D_SAMPLER_PAN(_MainColorAdjustTexture, _MainTex, poiMesh.uv[_MainColorAdjustTextureUV], _MainColorAdjustTexturePan);
+ #else
+ float4 hueShiftAlpha = 1;
+ #endif
+
+ if (_MainHueShiftReplace)
+ {
+ albedo.rgb = lerp(albedo.rgb, hueShift(albedo.rgb, mixedHueShift + _MainHueShiftSpeed * _Time.x), hueShiftAlpha.r);
+ }
+ else
+ {
+ albedo.rgb = hueShift(albedo.rgb, frac((mixedHueShift - (1 - hueShiftAlpha.r) + _MainHueShiftSpeed * _Time.x)));
+ }
+
+ albedo.rgb = lerp(albedo.rgb, dot(albedo.rgb, float3(0.3, 0.59, 0.11)), -_Saturation * hueShiftAlpha.b);
+ albedo.rgb = saturate(albedo.rgb + _MainBrightness * hueShiftAlpha.g);
+ #endif
+ #ifdef FINALPASS
+ #if defined(PROP_DETAILTEX) || !defined(OPTIMIZER_ENABLED)
+ half3 detailTexture = POI2D_SAMPLER_PAN(_DetailTex, _MainTex, poiMesh.uv[_DetailTexUV], _DetailTexPan).rgb * _DetailTint.rgb;
+ #else
+ half3 detailTexture = 0.21763764082 * _DetailTint.rgb;
+ #endif
+ albedo.rgb *= LerpWhiteTo(detailTexture * _DetailBrightness * unity_ColorSpaceDouble.rgb, detailMask.r * _DetailTexIntensity * backFaceDetailIntensity);
+ #endif
+ albedo.rgb = saturate(albedo.rgb);
+
+ #ifdef POI_HOLOGRAM
+ ApplyHoloAlpha(albedo);
+ #endif
+
+ s = FragmentSetup(float4(poiMesh.uv[0], 1, 1), poiCam.viewDir, poiMesh.worldPos, albedo);
+ #endif
+
+ #ifdef DISTORT
+ calculateDissolve(albedo, dissolveEmission);
+ #endif
+}
+
+void distanceFade(inout float4 albedo)
+{
+ #if defined(PROP_MAINFADETEXTURE) || !defined(OPTIMIZER_ENABLED)
+ half fadeMap = POI2D_SAMPLER_PAN(_MainFadeTexture, _MainTex, poiMesh.uv[_MainFadeTextureUV], _MainFadeTexturePan).r;
+ #else
+ half fadeMap = 1;
+ #endif
+ if (fadeMap)
+ {
+ float fadeDistance = _MainFadeType ? poiCam.distanceToVert : poiCam.distanceToModel;
+ half fadeValue = lerp(_MainMinAlpha, _MainMaxAlpha, smoothstep(_MainDistanceFadeMin, _MainDistanceFadeMax, fadeDistance));
+ albedo.a *= fadeValue;
+ }
+}
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMainTex.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMainTex.cginc.meta
new file mode 100644
index 00000000..7684dca0
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMainTex.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 543c4fafdae39c64ebbb99654c35c4b6
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMatcap.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMatcap.cginc
new file mode 100644
index 00000000..5d7d0f73
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMatcap.cginc
@@ -0,0 +1,160 @@
+#ifndef MATCAP
+ #define MATCAP
+
+ #if defined(PROP_MATCAP) || !defined(OPTIMIZER_ENABLED)
+ UNITY_DECLARE_TEX2D_NOSAMPLER(_Matcap); float4 _Matcap_ST;
+ #endif
+ #if defined(PROP_MATCAPMASK) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_MatcapMask);
+ #endif
+ float _MatcapMaskInvert;
+ float _MatcapBorder;
+ float4 _MatcapColor;
+ float _MatcapIntensity;
+ float _MatcapReplace;
+ float _MatcapMultiply;
+ float _MatcapAdd;
+ float _MatcapEnable;
+ float _MatcapLightMask;
+ float _MatcapEmissionStrength;
+ float _MatcapNormal;
+ float _MatcapHueShiftEnabled;
+ float _MatcapHueShiftSpeed;
+ float _MatcapHueShift;
+
+ #ifdef COLOR_GRADING_HDR_3D
+ #if defined(PROP_MATCAP2) || !defined(OPTIMIZER_ENABLED)
+ UNITY_DECLARE_TEX2D_NOSAMPLER(_Matcap2);float4 _Matcap2_ST;
+ #endif
+ #if defined(PROP_MATCAP2MASK) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_Matcap2Mask);
+ #endif
+ float _Matcap2MaskInvert;
+ float _Matcap2Border;
+ float4 _Matcap2Color;
+ float _Matcap2Intensity;
+ float _Matcap2Replace;
+ float _Matcap2Multiply;
+ float _Matcap2Add;
+ float _Matcap2Enable;
+ float _Matcap2LightMask;
+ float _Matcap2EmissionStrength;
+ float _Matcap2Normal;
+ float _Matcap2HueShiftEnabled;
+ float _Matcap2HueShiftSpeed;
+ float _Matcap2HueShift;
+ #endif
+
+ void blendMatcap(inout float4 finalColor, float add, float multiply, float replace, float4 matcapColor, float matcapMask, inout float3 matcapEmission, float emissionStrength
+ #ifdef POI_LIGHTING
+ , float matcapLightMask
+ #endif
+ #ifdef POI_BLACKLIGHT
+ , uint blackLightMaskIndex
+ #endif
+ )
+ {
+ #ifdef POI_LIGHTING
+ if (matcapLightMask)
+ {
+ matcapMask *= lerp(1, poiLight.rampedLightMap, matcapLightMask);
+ }
+ #endif
+ #ifdef POI_BLACKLIGHT
+ if(blackLightMaskIndex != 4)
+ {
+ matcapMask *= blackLightMask[blackLightMaskIndex];
+ }
+ #endif
+
+ finalColor.rgb = lerp(finalColor.rgb, matcapColor.rgb, replace * matcapMask * matcapColor.a * .999999);
+ finalColor.rgb *= lerp(1, matcapColor.rgb, multiply * matcapMask * matcapColor.a);
+ finalColor.rgb += matcapColor.rgb * add * matcapMask * matcapColor.a;
+ matcapEmission += matcapColor.rgb * emissionStrength * matcapMask * matcapColor.a;
+ }
+
+ void applyMatcap(inout float4 finalColor, inout float3 matcapEmission)
+ {
+ float4 matcap = 0;
+ float matcapMask = 0;
+ float4 matcap2 = 0;
+ float matcap2Mask = 0;
+
+ // Both matcaps use the same coordinates
+ half3 worldViewUp = normalize(half3(0, 1, 0) - poiCam.viewDir * dot(poiCam.viewDir, half3(0, 1, 0)));
+ half3 worldViewRight = normalize(cross(poiCam.viewDir, worldViewUp));
+
+ // Matcap 1
+ half2 matcapUV = half2(dot(worldViewRight, poiMesh.normals[_MatcapNormal]), dot(worldViewUp, poiMesh.normals[_MatcapNormal])) * _MatcapBorder + 0.5;
+
+ #if defined(PROP_MATCAP) || !defined(OPTIMIZER_ENABLED)
+ matcap = UNITY_SAMPLE_TEX2D_SAMPLER(_Matcap, _MainTex, TRANSFORM_TEX(matcapUV, _Matcap)) * _MatcapColor;
+ #else
+ matcap = _MatcapColor;
+ #endif
+
+ matcap.rgb *= _MatcapIntensity;
+ #if defined(PROP_MATCAPMASK) || !defined(OPTIMIZER_ENABLED)
+ matcapMask = POI2D_SAMPLER_PAN(_MatcapMask, _MainTex, poiMesh.uv[_MatcapMaskUV], _MatcapMaskPan);
+ #else
+ matcapMask = 1;
+ #endif
+
+ if (_MatcapMaskInvert)
+ {
+ matcapMask = 1 - matcapMask;
+ }
+
+ UNITY_BRANCH
+ if(_MatcapHueShiftEnabled)
+ {
+ matcap.rgb = hueShift(matcap.rgb, _MatcapHueShift + _Time.x * _MatcapHueShiftSpeed);
+ }
+
+ blendMatcap(finalColor, _MatcapAdd, _MatcapMultiply, _MatcapReplace, matcap, matcapMask, matcapEmission, _MatcapEmissionStrength
+ #ifdef POI_LIGHTING
+ , _MatcapLightMask
+ #endif
+ #ifdef POI_BLACKLIGHT
+ , _BlackLightMaskMatcap
+ #endif
+ );
+
+
+ // Matcap 2
+ #ifdef COLOR_GRADING_HDR_3D
+ half2 matcapUV2 = half2(dot(worldViewRight, poiMesh.normals[_Matcap2Normal]), dot(worldViewUp, poiMesh.normals[_Matcap2Normal])) * _Matcap2Border + 0.5;
+ #if defined(PROP_MATCAP2) || !defined(OPTIMIZER_ENABLED)
+ matcap2 = UNITY_SAMPLE_TEX2D_SAMPLER(_Matcap2, _MainTex, TRANSFORM_TEX(matcapUV2, _Matcap2)) * _Matcap2Color;
+ #else
+ matcap2 = _Matcap2Color;
+ #endif
+ matcap2.rgb *= _Matcap2Intensity;
+ #if defined(PROP_MATCAP2MASK) || !defined(OPTIMIZER_ENABLED)
+ matcap2Mask = POI2D_SAMPLER_PAN(_Matcap2Mask, _MainTex, poiMesh.uv[_Matcap2MaskUV], _Matcap2MaskPan);
+ #else
+ matcap2Mask = 1;
+ #endif
+ if (_Matcap2MaskInvert)
+ {
+ matcap2Mask = 1 - matcap2Mask;
+ }
+
+ UNITY_BRANCH
+ if(_Matcap2HueShiftEnabled)
+ {
+ matcap2.rgb = hueShift(matcap2.rgb, _Matcap2HueShift + _Time.x * _Matcap2HueShiftSpeed);
+ }
+
+ blendMatcap(finalColor, _Matcap2Add, _Matcap2Multiply, _Matcap2Replace, matcap2, matcap2Mask, matcapEmission, _Matcap2EmissionStrength
+ #ifdef POI_LIGHTING
+ , _Matcap2LightMask
+ #endif
+ #ifdef POI_BLACKLIGHT
+ , _BlackLightMaskMatcap2
+ #endif
+ );
+ #endif
+ }
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMatcap.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMatcap.cginc.meta
new file mode 100644
index 00000000..34077054
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMatcap.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: ea56da5c525e5e441bf82593f3151cac
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMath.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMath.cginc
new file mode 100644
index 00000000..e81ff2d5
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMath.cginc
@@ -0,0 +1,100 @@
+/*
+MIT License
+
+Copyright (c) 2019 wraikny
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
+
+VertexTransformShader is dependent on:
+*/
+
+#ifndef POI_MATH
+#define POI_MATH
+
+#ifndef pi
+ #define pi float(3.14159265359)
+#endif
+
+float4 quaternion_conjugate(float4 v)
+{
+ return float4(
+ v.x, -v.yzw
+ );
+}
+
+float4 quaternion_mul(float4 v1, float4 v2)
+{
+ float4 result1 = (v1.x * v2 + v1 * v2.x);
+
+ float4 result2 = float4(
+ - dot(v1.yzw, v2.yzw),
+ cross(v1.yzw, v2.yzw)
+ );
+
+ return float4(result1 + result2);
+}
+
+// angle : radians
+float4 get_quaternion_from_angle(float3 axis, float angle)
+{
+ return float4(
+ cos(angle / 2.0),
+ normalize(axis) * sin(angle / 2.0)
+ );
+}
+
+float4 quaternion_from_vector(float3 inVec)
+{
+ return float4(0.0, inVec);
+}
+
+float degree_to_radius(float degree)
+{
+ return(
+ degree / 180.0 * pi
+ );
+}
+
+float3 rotate_with_quaternion(float3 inVec, float3 rotation)
+{
+ float4 qx = get_quaternion_from_angle(float3(1, 0, 0), degree_to_radius(rotation.x));
+ float4 qy = get_quaternion_from_angle(float3(0, 1, 0), degree_to_radius(rotation.y));
+ float4 qz = get_quaternion_from_angle(float3(0, 0, 1), degree_to_radius(rotation.z));
+
+ #define MUL3(A, B, C) quaternion_mul(quaternion_mul((A), (B)), (C))
+ float4 quaternion = normalize(MUL3(qx, qy, qz));
+ float4 conjugate = quaternion_conjugate(quaternion);
+
+ float4 inVecQ = quaternion_from_vector(inVec);
+
+ float3 rotated = (
+ MUL3(quaternion, inVecQ, conjugate)
+ ).yzw;
+
+ return rotated;
+}
+
+float4 transform(float4 input, float4 pos, float4 rotation, float4 scale)
+{
+ input.rgb *= (scale.xyz * scale.w);
+ input = float4(rotate_with_quaternion(input.xyz, rotation.xyz/* * rotation.w*/) + (pos.xyz/* * pos.w*/), input.w);
+ return input;
+}
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMath.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMath.cginc.meta
new file mode 100644
index 00000000..e5c6ac94
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMath.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 382dd34f82ef0a742b5bb3e691f224f6
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMetal.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMetal.cginc
new file mode 100644
index 00000000..ed6b64ed
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMetal.cginc
@@ -0,0 +1,130 @@
+#ifndef POI_METAL
+ #define POI_METAL
+
+ samplerCUBE _CubeMap;
+ float _SampleWorld;
+ POI_TEXTURE_NOSAMPLER(_MetallicMask);
+ POI_TEXTURE_NOSAMPLER(_SmoothnessMask);
+ float _Metallic;
+ float _InvertSmoothness;
+ float _Smoothness;
+ float _EnableMetallic;
+ float3 _MetalReflectionTint;
+ POI_TEXTURE_NOSAMPLER(_MetallicTintMap);
+
+ float3 finalreflections;
+ float metalicMap;
+ float3 reflection;
+ float roughness;
+ float lighty_boy_uwu_var;
+
+ bool shouldMetalHappenBeforeLighting()
+ {
+ float4 envSample = UNITY_SAMPLE_TEXCUBE_LOD(unity_SpecCube0, poiCam.reflectionDir, roughness * UNITY_SPECCUBE_LOD_STEPS);
+ bool probeExists = !(unity_SpecCube0_HDR.a == 0 && envSample.a == 0);
+ return probeExists && !_SampleWorld;
+ }
+
+ float3 fresnelRelflection(in float4 albedo)
+ {
+ half3 dotNV = 1 - abs(poiLight.nDotV);
+ half f = dotNV * dotNV * dotNV * dotNV;
+ //f *= i_sold.fresnel;
+ return lerp(lerp(DielectricSpec.rgb, albedo.rgb, metalicMap), saturate(1 - roughness + metalicMap), f);
+ }
+
+ void calculateMetallicness()
+ {
+ metalicMap = POI2D_SAMPLER_PAN(_MetallicMask, _MainTex, poiMesh.uv[_MetallicMaskUV], _MetallicMaskPan) * _Metallic;
+ }
+
+ void ApplyMetallics(inout float4 finalColor, in float4 albedo)
+ {
+ #ifdef FORWARD_BASE_PASS
+ float smoothnessMap = (POI2D_SAMPLER_PAN(_SmoothnessMask, _MainTex, poiMesh.uv[_SmoothnessMaskUV], _SmoothnessMaskPan));
+
+ #ifdef POI_BLACKLIGHT
+ if (_BlackLightMaskMetallic != 4)
+ {
+ metalicMap *= blackLightMask[_BlackLightMaskMetallic];
+ smoothnessMap *= blackLightMask[_BlackLightMaskMetallic];
+ }
+ #endif
+
+ if(_InvertSmoothness == 1)
+ {
+ smoothnessMap = 1 - smoothnessMap;
+ }
+ smoothnessMap *= _Smoothness;
+ roughness = 1 - smoothnessMap;
+
+
+ Unity_GlossyEnvironmentData envData;
+ envData.roughness = roughness;
+ envData.reflUVW = BoxProjection(
+ poiCam.reflectionDir, poiMesh.worldPos.xyz,
+ unity_SpecCube0_ProbePosition,
+ unity_SpecCube0_BoxMin, unity_SpecCube0_BoxMax
+ );
+ float3 probe0 = Unity_GlossyEnvironment(
+ UNITY_PASS_TEXCUBE(unity_SpecCube0), unity_SpecCube0_HDR, envData
+ );
+ envData.reflUVW = BoxProjection(
+ poiCam.reflectionDir, poiMesh.worldPos.xyz,
+ unity_SpecCube1_ProbePosition,
+ unity_SpecCube1_BoxMin, unity_SpecCube1_BoxMax
+ );
+
+ float interpolator = unity_SpecCube0_BoxMin.w;
+ UNITY_BRANCH
+ if(interpolator < 0.99999)
+ {
+ float3 probe1 = Unity_GlossyEnvironment(
+ UNITY_PASS_TEXCUBE_SAMPLER(unity_SpecCube1, unity_SpecCube0),
+ unity_SpecCube0_HDR, envData
+ );
+ reflection = lerp(probe1, probe0, interpolator);
+ }
+ else
+ {
+ reflection = probe0;
+ }
+
+ float reflecty_lighty_boy_uwu_var_2 = 1.0 / (roughness * roughness + 1.0);
+
+ half4 tintMap = POI2D_SAMPLER_PAN(_MetallicTintMap, _MainTex, poiMesh.uv[_MetallicTintMapUV], _MetallicTintMapPan);
+ finalColor.rgb *= (1 - metalicMap * tintMap.a);
+ finalColor.rgb += reflecty_lighty_boy_uwu_var_2 * reflection.rgb * fresnelRelflection(albedo) * _MetalReflectionTint * tintMap.rgb * tintMap.a;
+ #endif
+ }
+
+ void ApplyMetallicsFake(inout float4 finalColor, in float4 albedo)
+ {
+ #ifdef FORWARD_BASE_PASS
+ metalicMap = POI2D_SAMPLER_PAN(_MetallicMask, _MainTex, poiMesh.uv[_MetallicMaskUV], _MetallicMaskPan) * _Metallic;
+ float smoothnessMap = (POI2D_SAMPLER_PAN(_SmoothnessMask, _MainTex, poiMesh.uv[_SmoothnessMaskUV], _SmoothnessMaskPan));
+
+ #ifdef POI_BLACKLIGHT
+ if(_BlackLightMaskMetallic != 4)
+ {
+ metalicMap *= blackLightMask[_BlackLightMaskMetallic];
+ smoothnessMap *= blackLightMask[_BlackLightMaskMetallic];
+ }
+ #endif
+
+ if(_InvertSmoothness == 1)
+ {
+ smoothnessMap = 1 - smoothnessMap;
+ }
+ smoothnessMap *= _Smoothness;
+ roughness = 1 - smoothnessMap;
+
+ reflection = texCUBElod(_CubeMap, float4(poiCam.reflectionDir, roughness * UNITY_SPECCUBE_LOD_STEPS));
+
+ float reflecty_lighty_boy_uwu_var_2 = 1.0 / (roughness * roughness + 1.0);
+ half4 tintMap = POI2D_SAMPLER_PAN(_MetallicTintMap, _MainTex, poiMesh.uv[_MetallicTintMapUV], _MetallicTintMapPan);
+ finalColor.rgb *= (1 - metalicMap * tintMap.a);
+ finalColor.rgb += reflecty_lighty_boy_uwu_var_2 * reflection.rgb * fresnelRelflection(albedo) * _MetalReflectionTint * tintMap.rgb * tintMap.a;
+ #endif
+ }
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMetal.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMetal.cginc.meta
new file mode 100644
index 00000000..22f650ab
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMetal.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: ef435eef1f3062442a396ae471e4c023
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMirror.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMirror.cginc
new file mode 100644
index 00000000..b2edec92
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMirror.cginc
@@ -0,0 +1,81 @@
+#ifndef POI_MIRROR
+ #define POI_MIRROR
+
+ float _Mirror;
+ float _EnableMirrorTexture;
+ #if defined(PROP_MIRRORTEXTURE) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_MirrorTexture);
+ #endif
+
+
+ void applyMirrorRenderVert(inout float4 vertex)
+ {
+ UNITY_BRANCH
+ if (_Mirror != 0)
+ {
+ bool inMirror = IsInMirror();
+ if(_Mirror == 1 && inMirror)
+ {
+ return;
+ }
+ if(_Mirror == 1 && !inMirror)
+ {
+ vertex = -1;
+ return;
+ }
+ if(_Mirror == 2 && inMirror)
+ {
+ vertex = -1;
+ return;
+ }
+ if(_Mirror == 2 && !inMirror)
+ {
+ return;
+ }
+ }
+ }
+
+ void applyMirrorRenderFrag()
+ {
+ UNITY_BRANCH
+ if(_Mirror != 0)
+ {
+ bool inMirror = IsInMirror();
+ if(_Mirror == 1 && inMirror)
+ {
+ return;
+ }
+ if(_Mirror == 1 && !inMirror)
+ {
+ clip(-1);
+ return;
+ }
+ if(_Mirror == 2 && inMirror)
+ {
+ clip(-1);
+ return;
+ }
+ if(_Mirror == 2 && !inMirror)
+ {
+ return;
+ }
+ }
+ }
+
+ #if(defined(FORWARD_BASE_PASS) || defined(FORWARD_ADD_PASS))
+ void applyMirrorTexture(inout float4 mainTexture)
+ {
+ UNITY_BRANCH
+ if(_EnableMirrorTexture)
+ {
+ if(IsInMirror())
+ {
+ #if defined(PROP_MIRRORTEXTURE) || !defined(OPTIMIZER_ENABLED)
+ mainTexture = POI2D_SAMPLER_PAN(_MirrorTexture, _MainTex, poiMesh.uv[_MirrorTextureUV], _MirrorTexturePan);
+ #endif
+ }
+ }
+ }
+ #endif
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMirror.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMirror.cginc.meta
new file mode 100644
index 00000000..790d2641
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiMirror.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 6a90225807e1d2943a87f41b64493968
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiOutlineFrag.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiOutlineFrag.cginc
new file mode 100644
index 00000000..1db932e5
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiOutlineFrag.cginc
@@ -0,0 +1,117 @@
+float _OutlineRimLightBlend;
+float _OutlineLit;
+float _OutlineTintMix;
+float2 _MainTexPan;
+float _MainTextureUV;
+half _OutlineHueOffset;
+half _OutlineHueShift;
+half _OutlineHueOffsetSpeed;
+
+float4 frag(v2f i, uint facing: SV_IsFrontFace): COLOR
+{
+ float4 finalColor = 1;
+ UNITY_BRANCH
+ if (_commentIfZero_EnableOutlinePass)
+ {
+ UNITY_SETUP_INSTANCE_ID(i);
+
+ float3 finalEmission = 0;
+ float4 albedo = 1;
+
+ poiMesh.uv[0] = i.uv0.xy;
+ poiMesh.uv[1] = i.uv0.zw;
+ poiMesh.uv[2] = i.uv1.xy;
+ poiMesh.uv[3] = i.uv1.zw;
+
+ calculateAttenuation(i);
+ InitializeMeshData(i, facing);
+ initializeCamera(i);
+ calculateTangentData();
+
+ float4 mainTexture = UNITY_SAMPLE_TEX2D(_MainTex, TRANSFORM_TEX(poiMesh.uv[_MainTextureUV], _MainTex) + _Time.x * _MainTexPan);
+ half3 detailMask = 1;
+ calculateNormals(detailMask);
+
+ #ifdef POI_DATA
+ calculateLightingData(i);
+ #endif
+ #ifdef POI_LIGHTING
+ calculateBasePassLightMaps();
+ #endif
+
+ float3 uselessData0;
+ float3 uselessData1;
+ initTextureData(albedo, mainTexture, uselessData0, uselessData1, detailMask);
+
+
+ fixed4 col = mainTexture;
+ float alphaMultiplier = smoothstep(_OutlineFadeDistance.x, _OutlineFadeDistance.y, distance(getCameraPosition(), i.worldPos));
+ float OutlineMask = tex2D(_OutlineMask, TRANSFORM_TEX(poiMesh.uv[_OutlineMaskUV], _OutlineMask) + _Time.x * _OutlineMaskPan).r;
+ clip(OutlineMask * _LineWidth - 0.001);
+
+ col = col * 0.00000000001 + tex2D(_OutlineTexture, TRANSFORM_TEX(poiMesh.uv[_OutlineTextureUV], _OutlineTexture) + _Time.x * _OutlineTexturePan);
+ col.a *= albedo.a;
+ col.a *= alphaMultiplier;
+
+ #ifdef POI_RANDOM
+ col.a *= i.angleAlpha;
+ #endif
+
+ poiCam.screenUV = calcScreenUVs(i.grabPos);
+ col.a *= _LineColor.a;
+
+ UNITY_BRANCH
+ if (_Mode == 1)
+ {
+ applyDithering(col);
+ }
+
+ clip(col.a - _Cutoff);
+
+ #ifdef POI_MIRROR
+ applyMirrorRenderFrag();
+ #endif
+
+ UNITY_BRANCH
+ if (_OutlineMode == 1)
+ {
+ #ifdef POI_MIRROR
+ applyMirrorTexture(mainTexture);
+ #endif
+ col.rgb = mainTexture.rgb;
+ }
+ else if (_OutlineMode == 2)
+ {
+ col.rgb = lerp(col.rgb, poiLight.color, _OutlineRimLightBlend);
+ }
+ col.rgb *= _LineColor.rgb;
+
+ if (_OutlineMode == 1)
+ {
+ col.rgb = lerp(col.rgb, mainTexture.rgb, _OutlineTintMix);
+ }
+
+ finalColor = col;
+
+ // Hue shift
+ UNITY_BRANCH
+ if (_OutlineHueShift)
+ {
+ finalColor.rgb = hueShift(finalColor.rgb, _OutlineHueOffset + _OutlineHueOffsetSpeed * _Time.x);
+ }
+
+ #ifdef POI_LIGHTING
+ UNITY_BRANCH
+ if (_OutlineLit)
+ {
+ finalColor.rgb *= calculateFinalLighting(finalColor.rgb, finalColor);
+ }
+ #endif
+ finalColor.rgb += (col.rgb * _OutlineEmission);
+}
+else
+{
+ clip(-1);
+}
+return finalColor;
+} \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiOutlineFrag.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiOutlineFrag.cginc.meta
new file mode 100644
index 00000000..c0544bc2
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiOutlineFrag.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 7db374de8ad35a74e8b931bcef6e3ba8
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiOutlineVert.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiOutlineVert.cginc
new file mode 100644
index 00000000..55fb800d
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiOutlineVert.cginc
@@ -0,0 +1,144 @@
+#ifndef OutlineVert
+#define OutlineVert
+
+#include "CGI_PoiV2F.cginc"
+
+float _OutlineMode;
+float4 _OutlinePersonaDirection;
+float4 _OutlineDropShadowOffset;
+float _OutlineUseVertexColors;
+float _OutlineFixedSize;
+float _commentIfZero_EnableOutlinePass;
+float _OutlinesMaxDistance;
+
+sampler2D _OutlineMask; float4 _OutlineMask_ST; float2 _OutlineMaskPan; float _OutlineMaskUV;
+
+float _VertexManipulationHeightUV;
+
+float3 CreateBinormal(half3 normal, half3 tangent, half tangentSign)
+{
+ half sign = tangentSign * unity_WorldTransformParams.w;
+ return cross(normal, tangent) * sign;
+}
+
+v2f vert(appdata v)
+{
+
+ UNITY_SETUP_INSTANCE_ID(v);
+ v2f o;
+
+ #ifdef AUTO_EXPOSURE
+ applyLocalVertexTransformation(v.normal, v.tangent, v.vertex);
+ #endif
+
+ UNITY_INITIALIZE_OUTPUT(v2f, o);
+ UNITY_TRANSFER_INSTANCE_ID(v, o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+
+ #ifdef RALIV_PENETRATION
+ applyRalivDynamicOrifaceSystem(v);
+ #endif
+
+ o.uv0.xy = v.uv0.xy;
+ o.uv0.zw = v.uv1.xy;
+ o.uv1.xy = v.uv2.xy;
+ o.uv1.zw = v.uv3.xy;
+
+ float2 uvArray[4];
+ uvArray[0] = o.uv0.xy;
+ uvArray[1] = o.uv0.zw;
+ uvArray[2] = o.uv1.xy;
+ uvArray[3] = o.uv1.zw;
+
+ float2 uvToUse = uvArray[_VertexManipulationHeightUV];
+
+ #ifdef POI_MIRROR
+ applyMirrorRenderVert(v.vertex);
+ #endif
+
+ o.uv0.xy = v.uv0 + _OutlineGlobalPan.xy * _Time.y;
+ float outlineMask = 1;
+
+ outlineMask = poiMax(tex2Dlod(_OutlineMask, float4(TRANSFORM_TEX(uvArray[_OutlineMaskUV], _OutlineMask) + _Time.x * _OutlineMaskPan, 0, 0)).rgb);
+ UNITY_BRANCH
+ if (_OutlineUseVertexColors == 2)
+ {
+ outlineMask *= v.color.r;
+ }
+
+ UNITY_BRANCH
+ if (_OutlineUseVertexColors != 1)
+ {
+ o.normal = UnityObjectToWorldNormal(v.normal);
+ }
+ else
+ {
+ o.normal = UnityObjectToWorldNormal(v.color);
+ }
+
+ float4 localPos = v.vertex;
+
+ #ifdef RALIV_PENETRATION
+ applyRalivDynamicPenetrationSystem(localPos.rgb, o.normal.rgb, v);
+ #endif
+ o.tangent = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w);
+ o.binormal.rgb = CreateBinormal(o.normal.xyz, o.tangent.xyz, o.tangent.w);
+
+
+ half offsetMultiplier = 1;
+ half distanceOffset = 1;
+ UNITY_BRANCH
+ if (_OutlineFixedSize)
+ {
+ distanceOffset *= min(distance(_WorldSpaceCameraPos, mul(unity_ObjectToWorld, localPos).xyz), _OutlinesMaxDistance);
+ }
+
+ float3 offset = o.normal * (_LineWidth * _commentIfZero_EnableOutlinePass / 100) * outlineMask * distanceOffset;
+
+ UNITY_BRANCH
+ if (_OutlineMode == 2)
+ {
+ float3 lightDirection = poiLight.direction = normalize(_WorldSpaceLightPos0 + unity_SHAr.xyz + unity_SHAg.xyz + unity_SHAb.xyz);
+ offsetMultiplier = saturate(dot(lightDirection, o.normal));
+ offset *= offsetMultiplier;
+ offset *= distanceOffset;
+ }
+ else if (_OutlineMode == 3)
+ {
+ half3 viewNormal = mul((float3x3)UNITY_MATRIX_V, o.normal);
+ offsetMultiplier = saturate(dot(viewNormal.xy, normalize(_OutlinePersonaDirection.xy)));
+
+ offset *= offsetMultiplier;
+ offset *= distanceOffset;
+ }
+ else if (_OutlineMode == 4)
+ {
+ offset = mul((float3x3)transpose(UNITY_MATRIX_V), _OutlineDropShadowOffset);
+ offset *= distanceOffset;
+ }
+
+ o.worldPos = mul(unity_ObjectToWorld, localPos) + float4(offset, 0);
+ o.modelPos = mul(unity_ObjectToWorld, float4(0, 0, 0, 1));
+
+ #ifdef AUTO_EXPOSURE
+ applyWorldVertexTransformation(o.worldPos, o.localPos, o.normal, uvToUse);
+ #endif
+
+ #ifdef AUTO_EXPOSURE
+ applyVertexRounding(o.worldPos, o.localPos);
+ #endif
+
+ o.pos = UnityWorldToClipPos(o.worldPos);
+ o.grabPos = ComputeGrabScreenPos(o.pos);
+ o.angleAlpha = 1;
+ #ifdef POI_RANDOM
+ o.angleAlpha = ApplyAngleBasedRendering(o.modelPos, o.worldPos);
+ #endif
+
+
+ UNITY_TRANSFER_SHADOW(o, o.uv0);
+ UNITY_TRANSFER_FOG(o, o.pos);
+ return o;
+}
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiOutlineVert.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiOutlineVert.cginc.meta
new file mode 100644
index 00000000..9de9fef6
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiOutlineVert.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 3ffaf29d05947a14fa6c536ce06612d5
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPanosphere.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPanosphere.cginc
new file mode 100644
index 00000000..7986c320
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPanosphere.cginc
@@ -0,0 +1,80 @@
+#ifndef PANOSPHERE
+ #define PANOSPHERE
+
+ float _PanoEmission;
+ float _PanoBlend;
+ float4 _PanosphereColor;
+ float3 _PanospherePan;
+ float _PanoToggle;
+ float _PanoCubeMapToggle;
+ float _PanoInfiniteStereoToggle;
+
+ float3 panoColor;
+ float panoMask;
+
+ #if defined(PROP_PANOSPHERETEXTURE) || !defined(OPTIMIZER_ENABLED)
+ sampler2D _PanosphereTexture; float4 _PanosphereTexture_ST;
+ #endif
+ #if defined(PROP_PANOCUBEMAP) || !defined(OPTIMIZER_ENABLED)
+ samplerCUBE _PanoCubeMap; half4 _PanoCubeMap_HDR;
+ #endif
+ #if defined(PROP_PANOMASK) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_PanoMask);
+ #endif
+
+ float2 projectIt(float3 coords)
+ {
+ float3 normalizedCoords = normalize(coords);
+ float latitude = acos(normalizedCoords.y);
+ float longitude = atan2(normalizedCoords.z, normalizedCoords.x);
+ float2 sphereCoords = float2(longitude + _Time.y * _PanospherePan.x, latitude + _Time.y * _PanospherePan.y) * float2(1.0 / UNITY_PI, 1.0 / UNITY_PI);
+ sphereCoords = float2(1.0, 1.0) - sphereCoords;
+ return(sphereCoords + float4(0, 1 - unity_StereoEyeIndex, 1, 1.0).xy) * float4(0, 1 - unity_StereoEyeIndex, 1, 1.0).zw;
+ }
+
+ void applyPanosphereColor(inout float4 albedo, inout float3 panosphereEmission)
+ {
+ #if defined(PROP_PANOMASK) || !defined(OPTIMIZER_ENABLED)
+ panoMask = POI2D_SAMPLER_PAN(_PanoMask, _MainTex, poiMesh.uv[_PanoMaskUV], _PanoMaskPan);
+ #else
+ panoMask = 1;
+ #endif
+ #ifdef POI_BLACKLIGHT
+ if (_BlackLightMaskPanosphere != 4)
+ {
+ panoMask *= blackLightMask[_BlackLightMaskPanosphere];
+ }
+ #endif
+
+ UNITY_BRANCH
+ if(_PanoCubeMapToggle)
+ {
+ #if defined(PROP_PANOCUBEMAP) || !defined(OPTIMIZER_ENABLED)
+ float3 cubeUV = mul(poiRotationMatrixFromAngles(_PanospherePan.xyz * _Time.y), float4(-poiCam.viewDir, 1));
+ half4 cubemap = texCUBE(_PanoCubeMap, cubeUV);
+ panoColor = DecodeHDR(cubemap, _PanoCubeMap_HDR) * _PanosphereColor.rgb;
+ #else
+ panoColor = _PanosphereColor.rgb;
+ #endif
+ }
+ else
+ {
+ float2 uv = projectIt(normalize(lerp(getCameraPosition().xyz, poiCam.worldPos.xyz, _PanoInfiniteStereoToggle) - poiMesh.worldPos.xyz) * - 1);
+
+ float2 ddxuv = ddx(uv);
+ float2 ddyuv = ddy(uv);
+ if(any(fwidth(uv) > .5))
+ {
+ ddxuv = ddyuv = 0.001;
+ }
+ #if defined(PROP_PANOSPHERETEXTURE) || !defined(OPTIMIZER_ENABLED)
+ panoColor = tex2D(_PanosphereTexture, TRANSFORM_TEX(uv, _PanosphereTexture), ddxuv, ddyuv).rgb * _PanosphereColor.rgb;
+ #else
+ panoColor = _PanosphereColor.rgb;
+ #endif
+ }
+ panosphereEmission = panoColor * _PanoBlend * panoMask * _PanoEmission;
+ albedo.rgb = lerp(albedo.rgb, panoColor, _PanoBlend * .9999999 * panoMask);
+ }
+
+#endif
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPanosphere.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPanosphere.cginc.meta
new file mode 100644
index 00000000..aaebe97b
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPanosphere.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 1181a36e0475df340b0a8d40fc95f05b
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiParallax.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiParallax.cginc
new file mode 100644
index 00000000..db2f9da4
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiParallax.cginc
@@ -0,0 +1,166 @@
+#ifndef POI_PARALLAX
+ #define POI_PARALLAX
+
+ #if defined(PROP_PARALLAXHEIGHTMAP) || !defined(OPTIMIZER_ENABLED)
+ UNITY_DECLARE_TEX2D_NOSAMPLER(_ParallaxHeightMap); float4 _ParallaxHeightMap_ST;
+ #endif
+ #if defined(PROP_PARALLAXHEIGHTMAPMASK) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_ParallaxHeightMapMask);
+ #endif
+ float2 _ParallaxHeightMapPan;
+ float _ParallaxStrength;
+ float _ParallaxHeightMapEnabled;
+ float _ParallaxUV;
+
+ //Internal
+ float _ParallaxInternalMapEnabled;
+ #if defined(PROP_PARALLAXINTERNALMAP) || !defined(OPTIMIZER_ENABLED)
+ UNITY_DECLARE_TEX2D_NOSAMPLER(_ParallaxInternalMap); float4 _ParallaxInternalMap_ST;
+ #endif
+ #if defined(PROP_PARALLAXINTERNALMAPMASK) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_ParallaxInternalMapMask);
+ #endif
+ float _ParallaxInternalIterations;
+ float _ParallaxInternalMinDepth;
+ float _ParallaxInternalMaxDepth;
+ float _ParallaxInternalMinFade;
+ float _ParallaxInternalMaxFade;
+ float4 _ParallaxInternalMinColor;
+ float4 _ParallaxInternalMaxColor;
+ float4 _ParallaxInternalPanSpeed;
+ float4 _ParallaxInternalPanDepthSpeed;
+ float _ParallaxInternalHeightmapMode;
+ float _ParallaxInternalHeightFromAlpha;
+
+ float GetParallaxHeight(float2 uv)
+ {
+ #if defined(PROP_PARALLAXHEIGHTMAP) || !defined(OPTIMIZER_ENABLED)
+ return clamp(UNITY_SAMPLE_TEX2D_SAMPLER(_ParallaxHeightMap, _MainTex, TRANSFORM_TEX(uv, _ParallaxHeightMap) + _Time.x * _ParallaxHeightMapPan).g, 0, .99999);
+ #else
+ return 0;
+ #endif
+ }
+ /*
+ float2 ParallaxOffset(float2 viewDir)
+ {
+ float height = GetParallaxHeight();
+ height -= 0.5;
+ height *= _ParallaxStrength;
+ return viewDir * height;
+ }
+ */
+ float2 ParallaxRaymarching(float2 viewDir)
+ {
+ float2 uvOffset = 0;
+ float stepSize = 0.1;
+ float2 uvDelta = viewDir * (stepSize * _ParallaxStrength);
+
+ float stepHeight = 1;
+ float surfaceHeight = GetParallaxHeight(poiMesh.uv[_ParallaxUV]);
+
+
+ float2 prevUVOffset = uvOffset;
+ float prevStepHeight = stepHeight;
+ float prevSurfaceHeight = surfaceHeight;
+
+ for (int i = 1; i < 10 && stepHeight > surfaceHeight; i ++)
+ {
+ prevUVOffset = uvOffset;
+ prevStepHeight = stepHeight;
+ prevSurfaceHeight = surfaceHeight;
+
+ uvOffset -= uvDelta;
+ stepHeight -= stepSize;
+ surfaceHeight = GetParallaxHeight(poiMesh.uv[_ParallaxUV] + uvOffset);
+ }
+
+ float prevDifference = prevStepHeight - prevSurfaceHeight;
+ float difference = surfaceHeight - stepHeight;
+ float t = prevDifference / (prevDifference + difference);
+ uvOffset = prevUVOffset -uvDelta * t;
+ #if defined(PROP_PARALLAXHEIGHTMAPMASK) || !defined(OPTIMIZER_ENABLED)
+ return uvOffset *= POI2D_SAMPLER_PAN(_ParallaxHeightMapMask, _MainTex, poiMesh.uv[_ParallaxHeightMapMaskUV], _ParallaxHeightMapMaskPan).r;
+ #else
+ return uvOffset;
+ #endif
+ }
+
+ void calculateandApplyParallax()
+ {
+ UNITY_BRANCH
+ if (_ParallaxHeightMapEnabled)
+ {
+ float2 parallaxOffset = ParallaxRaymarching(poiCam.tangentViewDir.xy);
+ UNITY_BRANCH
+ if(_ParallaxUV == 0)
+ {
+ poiMesh.uv[0] += parallaxOffset;
+ }
+ UNITY_BRANCH
+ if(_ParallaxUV == 1)
+ {
+ poiMesh.uv[1] += parallaxOffset;
+ }
+ UNITY_BRANCH
+ if(_ParallaxUV == 2)
+ {
+ poiMesh.uv[2] += parallaxOffset;
+ }
+ UNITY_BRANCH
+ if(_ParallaxUV == 3)
+ {
+ poiMesh.uv[3] += parallaxOffset;
+ }
+ }
+ }
+
+ void calculateAndApplyInternalParallax(inout float4 finalColor)
+ {
+ #if defined(_PARALLAXMAP)
+ UNITY_BRANCH
+ if(_ParallaxInternalMapEnabled)
+ {
+ float3 parallax = 0;
+
+ for (int j = _ParallaxInternalIterations; j > 0; j --)
+ {
+ float ratio = (float)j / _ParallaxInternalIterations;
+ float2 parallaxOffset = _Time.y * (_ParallaxInternalPanSpeed + (1 - ratio) * _ParallaxInternalPanDepthSpeed);
+ float fade = lerp(_ParallaxInternalMinFade, _ParallaxInternalMaxFade, ratio);
+ #if defined(PROP_PARALLAXINTERNALMAP) || !defined(OPTIMIZER_ENABLED)
+ float4 parallaxColor = UNITY_SAMPLE_TEX2D_SAMPLER(_ParallaxInternalMap, _MainTex, TRANSFORM_TEX(poiMesh.uv[0], _ParallaxInternalMap) + lerp(_ParallaxInternalMinDepth, _ParallaxInternalMaxDepth, ratio) * - poiCam.tangentViewDir.xy + parallaxOffset);
+ #else
+ float4 parallaxColor = 0;
+ #endif
+ float3 parallaxTint = lerp(_ParallaxInternalMinColor, _ParallaxInternalMaxColor, ratio);
+ float parallaxHeight;
+ if(_ParallaxInternalHeightFromAlpha)
+ {
+ parallaxTint *= parallaxColor.rgb;
+ parallaxHeight = parallaxColor.a;
+ }
+ else
+ {
+ parallaxHeight = parallaxColor.r;
+ }
+ //float parallaxColor *= lerp(_ParallaxInternalMinColor, _ParallaxInternalMaxColor, 1 - ratio);
+ UNITY_BRANCH
+ if (_ParallaxInternalHeightmapMode == 1)
+ {
+ parallax = lerp(parallax, parallaxTint * fade, parallaxHeight >= 1 - ratio);
+ }
+ else
+ {
+ parallax += parallaxTint * parallaxHeight * fade;
+ }
+ }
+ //parallax /= _ParallaxInternalIterations;
+ #if defined(PROP_PARALLAXINTERNALMAPMASK) || !defined(OPTIMIZER_ENABLED)
+ finalColor.rgb += parallax * POI2D_SAMPLER_PAN(_ParallaxInternalMapMask, _MainTex, poiMesh.uv[_ParallaxInternalMapMaskUV], _ParallaxInternalMapMaskPan).r;
+ #else
+ finalColor.rgb += parallax;
+ #endif
+ }
+ #endif
+ }
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiParallax.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiParallax.cginc.meta
new file mode 100644
index 00000000..dfdd10cc
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiParallax.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 3737980e09be8994e929a4a8aca17fd4
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPass.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPass.cginc
new file mode 100644
index 00000000..8b22cdd0
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPass.cginc
@@ -0,0 +1,252 @@
+/*
+USED---------------------------------------------
+"_PARALLAXMAP"
+"_REQUIRE_UV2"
+"_SUNDISK_NONE"
+"_DETAIL_MULX2"
+"_GLOSSYREFLECTIONS_OFF"
+"_METALLICGLOSSMAP"
+"_COLORADDSUBDIFF_ON"
+"_SPECGLOSSMAP"
+"_TERRAIN_NORMAL_MAP"
+"_SUNDISK_SIMPLE"
+"_EMISSION"
+"_COLORCOLOR_ON"
+"_COLOROVERLAY_ON"
+"_ALPHAMODULATE_ON"
+"_SUNDISK_HIGH_QUALITY"
+"_MAPPING_6_FRAMES_LAYOUT"
+"_NORMALMAP
+"EFFECT_BUMP"
+"BLOOM"
+"BLOOM_LOW"
+"GRAIN"
+"DEPTH_OF_FIELD"
+"USER_LUT"
+"CHROMATIC_ABERRATION_LOW"
+"BLOOM_LENS_DIRT"
+"_FADING_ON"
+"CHROMATIC_ABERRATION"
+"DISTORT"
+"GEOM_TYPE_BRANCH"
+"_SPECULARHIGHLIGHTS_OFF"
+"_SMOOTHNESS_TEXTURE_ALBEDO_CHANNEL_A"
+"EFFECT_HUE_VARIATION"
+"GEOM_TYPE_LEAF"
+"GEOM_TYPE_MESH"
+"FINALPASS"
+"AUTO_EXPOSURE
+"VIGNETTE"
+"VIGNETTE_MASKED"
+"COLOR_GRADING_HDR"
+"COLOR_GRADING_HDR_3D"
+"DITHERING"
+"VIGNETTE_CLASSIC"
+"GEOM_TYPE_BRANCH_DETAIL"
+"GEOM_TYPE_FROND"
+"DEPTH_OF_FIELD_COC_VIEW"
+"COLOR_GRADING_LOG_VIEW"
+"TONEMAPPING_CUSTOM"
+
+UNUSED-------------------------------------------
+"_ALPHABLEND_ON"
+"_ALPHAPREMULTIPLY_ON"
+"_ALPHATEST_ON"
+"PIXELSNAP_ON"
+"TONEMAPPING_FILMIC"
+"TONEMAPPING_NEUTRAL"
+"TONEMAPPING_ACES"
+"COLOR_GRADING"
+
+DO NOT USE -----------------------------------------
+"BILLBOARD_FACE_CAMERA_POS"
+SOFTPARTICLES_ON
+*/
+
+
+#ifndef POI_PASS
+#define POI_PASS
+
+#include "UnityCG.cginc"
+#include "Lighting.cginc"
+#include "UnityPBSLighting.cginc"
+#include "AutoLight.cginc"
+#include "UnityShaderVariables.cginc"
+
+#ifdef POI_META_PASS
+ #include "UnityMetaPass.cginc"
+#endif
+
+//#pragma warning (default : 3206) // implicit truncation
+
+#include "CGI_PoiMacros.cginc"
+#include "CGI_PoiDefines.cginc"
+#include "CGI_FunctionsArtistic.cginc"
+
+#include "CGI_Poicludes.cginc"
+#include "CGI_PoiHelpers.cginc"
+#include "CGI_PoiBlending.cginc"
+
+#ifdef _SUNDISK_NONE
+ #include "CGI_PoiRandom.cginc"
+#endif
+
+#ifdef _REQUIRE_UV2
+ #include "CGI_PoiMirror.cginc"
+#endif
+
+#include "CGI_PoiPenetration.cginc"
+#include "CGI_PoiVertexManipulations.cginc"
+
+#include "CGI_PoiSpawnInVert.cginc"
+
+#include "CGI_PoiV2F.cginc"
+
+#ifdef BLOOM_LOW
+ #include "CGI_PoiBulge.cginc"
+#endif
+
+#include "CGI_PoiVert.cginc"
+
+#ifdef TESSELATION
+ #include "CGI_PoiTessellation.cginc"
+#endif
+
+#include "CGI_PoiDithering.cginc"
+
+#ifdef _PARALLAXMAP
+ #include "CGI_PoiParallax.cginc"
+#endif
+
+#ifdef COLOR_GRADING_LOG_VIEW
+ #include "CGI_PoiAudioLink.cginc"
+#endif
+
+#ifdef USER_LUT
+ #include "CGI_PoiUVDistortion.cginc"
+#endif
+
+#ifdef VIGNETTE
+ #include "CGI_PoiRGBMask.cginc"
+#endif
+
+#include "CGI_PoiData.cginc"
+
+#ifdef _SPECULARHIGHLIGHTS_OFF
+ #include "CGI_PoiBlackLight.cginc"
+#endif
+
+#include "CGI_PoiSpawnInFrag.cginc"
+
+#ifdef WIREFRAME
+ #include "CGI_PoiWireframe.cginc"
+#endif
+
+#ifdef DISTORT
+ #include "CGI_PoiDissolve.cginc"
+#endif
+
+#ifdef DEPTH_OF_FIELD
+ #include "CGI_PoiHologram.cginc"
+#endif
+
+#ifdef BLOOM_LENS_DIRT
+ #include "CGI_PoiIridescence.cginc"
+#endif
+
+
+#ifdef FUR
+ //#include "CGI_PoiFur.cginc"
+ //#include "CGI_PoiGeomFur.cginc"
+#endif
+
+#ifdef VIGNETTE_MASKED
+ #include "CGI_PoiLighting.cginc"
+#endif
+
+#include "CGI_PoiMainTex.cginc"
+
+#ifdef TONEMAPPING_CUSTOM
+ #include "CGI_PoiPathing.cginc"
+#endif
+
+#ifdef GEOM_TYPE_BRANCH
+ #include "CGI_PoiDecal.cginc"
+#endif
+
+#ifdef CHROMATIC_ABERRATION
+ #include "CGI_PoiVoronoi.cginc"
+#endif
+
+#ifdef _DETAIL_MULX2
+ #include "CGI_PoiPanosphere.cginc"
+#endif
+
+#ifdef EFFECT_BUMP
+ #include "CGI_PoiMSDF.cginc"
+#endif
+
+#ifdef GRAIN
+ #include "CGI_PoiDepthColor.cginc"
+#endif
+
+
+#ifdef _SUNDISK_HIGH_QUALITY
+ #include "CGI_PoiFlipbook.cginc"
+#endif
+
+#ifdef _GLOSSYREFLECTIONS_OFF
+ #include "CGI_PoiRimLighting.cginc"
+#endif
+
+#ifdef _MAPPING_6_FRAMES_LAYOUT
+ #include "CGI_PoiEnvironmentalRimLighting.cginc"
+#endif
+
+#ifdef VIGNETTE_CLASSIC
+ #include "CGI_PoiBRDF.cginc"
+#endif
+
+#ifdef _METALLICGLOSSMAP
+ #include "CGI_PoiMetal.cginc"
+#endif
+
+#ifdef _COLORADDSUBDIFF_ON
+ #include "CGI_PoiMatcap.cginc"
+#endif
+
+#ifdef _SPECGLOSSMAP
+ #include "CGI_PoiSpecular.cginc"
+#endif
+
+#ifdef BLOOM
+ #include "CGI_PoiVideo.cginc"
+#endif
+
+#ifdef _TERRAIN_NORMAL_MAP
+ #include "CGI_PoiSubsurfaceScattering.cginc"
+#endif
+
+#include "CGI_PoiBlending.cginc"
+#include "CGI_PoiGrab.cginc"
+
+#ifdef _SUNDISK_SIMPLE
+ #include "CGI_PoiGlitter.cginc"
+#endif
+
+#ifdef _EMISSION
+ #include "CGI_PoiEmission.cginc"
+#endif
+
+#ifdef _COLORCOLOR_ON
+ #include "CGI_PoiClearCoat.cginc"
+#endif
+
+#include "CGI_PoiAlphaToCoverage.cginc"
+
+#ifdef _COLOROVERLAY_ON
+ #include "CGI_PoiDebug.cginc"
+#endif
+#include "CGI_PoiFrag.cginc"
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPass.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPass.cginc.meta
new file mode 100644
index 00000000..e829717d
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPass.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: fa1dff6cd1c9b9f4891de1a7c880523d
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPassOutline.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPassOutline.cginc
new file mode 100644
index 00000000..f8504d25
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPassOutline.cginc
@@ -0,0 +1,34 @@
+#ifndef POI_PASS_OUTLINE
+#define POI_PASS_OUTLINE
+
+#include "UnityCG.cginc"
+#include "Lighting.cginc"
+#include "UnityPBSLighting.cginc"
+#include "AutoLight.cginc"
+#include "CGI_PoiMacros.cginc"
+#include "CGI_PoiDefines.cginc"
+#include "CGI_FunctionsArtistic.cginc"
+#include "CGI_Poicludes.cginc"
+#include "CGI_PoiHelpers.cginc"
+#include "CGI_PoiBlending.cginc"
+#include "CGI_PoiPenetration.cginc"
+#include "CGI_PoiVertexManipulations.cginc"
+#include "CGI_PoiOutlineVert.cginc"
+#ifdef TESSELATION
+ #include "CGI_PoiTessellation.cginc"
+#endif
+#ifdef _REQUIRE_UV2
+ #include "CGI_PoiMirror.cginc"
+#endif
+#ifdef DISTORT
+ #include "CGI_PoiDissolve.cginc"
+#endif
+#include "CGI_PoiLighting.cginc"
+#include "CGI_PoiMainTex.cginc"
+#include "CGI_PoiData.cginc"
+#include "CGI_PoiDithering.cginc"
+#ifdef _COLOROVERLAY_ON
+ #include "CGI_PoiDebug.cginc"
+#endif
+#include "CGI_PoiOutlineFrag.cginc"
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPassOutline.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPassOutline.cginc.meta
new file mode 100644
index 00000000..b3bd3e2a
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPassOutline.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 0fe97530a72193b4faea2c5e3dd997a6
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPassShadow.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPassShadow.cginc
new file mode 100644
index 00000000..9e5c4fea
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPassShadow.cginc
@@ -0,0 +1,46 @@
+#ifndef POI_PASS_SHADOW
+ #define POI_PASS_SHADOW
+
+ #pragma multi_compile_shadowcaster
+ #include "UnityCG.cginc"
+ #include "UnityShaderVariables.cginc"
+ #include "UnityCG.cginc"
+ #include "Lighting.cginc"
+ #include "UnityPBSLighting.cginc"
+ #include "AutoLight.cginc"
+
+ #include "CGI_PoiMacros.cginc"
+ #include "CGI_PoiDefines.cginc"
+
+ #include "CGI_Poicludes.cginc"
+ #include "CGI_PoiShadowIncludes.cginc"
+ #include "CGI_PoiHelpers.cginc"
+ #include "CGI_PoiMirror.cginc"
+ #include "CGI_PoiSpawnInFrag.cginc"
+
+ #include "CGI_PoiV2F.cginc"
+ #include "CGI_PoiData.cginc"
+
+ #ifdef WIREFRAME
+ #include "CGI_PoiWireframe.cginc"
+ #endif
+
+ #ifdef _SUNDISK_HIGH_QUALITY
+ #include "CGI_PoiFlipbook.cginc"
+ #endif
+
+ #ifdef _SUNDISK_NONE
+ #include "CGI_PoiRandom.cginc"
+ #endif
+ #include "CGI_PoiDithering.cginc"
+ #ifdef DISTORT
+ #include "CGI_PoiDissolve.cginc"
+ #endif
+ #include "CGI_PoiPenetration.cginc"
+ #include "CGI_PoiVertexManipulations.cginc"
+
+ #include "CGI_PoiSpawnInVert.cginc"
+ #include "CGI_PoiShadowVert.cginc"
+ #include "CGI_PoiShadowFrag.cginc"
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPassShadow.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPassShadow.cginc.meta
new file mode 100644
index 00000000..239a4e9a
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPassShadow.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 94f93700d2c2f3946ba884cd83881c8e
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPathing.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPathing.cginc
new file mode 100644
index 00000000..b35f402e
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPathing.cginc
@@ -0,0 +1,150 @@
+#ifndef POI_PATHING
+#define POI_PATHING
+
+// Fill, 0, Path, 1, Loop, 2
+half _PathTypeR;
+half _PathTypeG;
+half _PathTypeB;
+half3 _PathWidth;
+float3 _PathTime;
+float3 _PathOffset;
+float3 _PathSpeed;
+float4 _PathColorR;
+float4 _PathColorG;
+float4 _PathColorB;
+float3 _PathEmissionStrength;
+float3 _PathSoftness;
+float3 _PathSegments;
+float3 _PathAlpha;
+
+#ifdef POI_AUDIOLINK
+ // Time Offset
+ half _AudioLinkPathTimeOffsetBandR;
+ half2 _AudioLinkPathTimeOffsetR;
+ half _AudioLinkPathTimeOffsetBandG;
+ half2 _AudioLinkPathTimeOffsetG;
+ half _AudioLinkPathTimeOffsetBandB;
+ half2 _AudioLinkPathTimeOffsetB;
+
+ // Emission Offset
+ half _AudioLinkPathEmissionAddBandR;
+ half2 _AudioLinkPathEmissionAddR;
+ half _AudioLinkPathEmissionAddBandG;
+ half2 _AudioLinkPathEmissionAddG;
+ half _AudioLinkPathEmissionAddBandB;
+ half2 _AudioLinkPathEmissionAddB;
+
+ // Length Offset
+ half _AudioLinkPathWidthOffsetBandR;
+ half2 _AudioLinkPathWidthOffsetR;
+ half _AudioLinkPathWidthOffsetBandG;
+ half2 _AudioLinkPathWidthOffsetG;
+ half _AudioLinkPathWidthOffsetBandB;
+ half2 _AudioLinkPathWidthOffsetB;
+#endif
+
+#if defined(PROP_PATHINGMAP) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_PathingMap);
+#endif
+#if defined(PROP_PATHINGCOLORMAP) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_PathingColorMap);
+#endif
+
+void applyPathing(inout float4 albedo, inout float3 pathEmission)
+{
+ #if defined(PROP_PATHINGMAP) || !defined(OPTIMIZER_ENABLED)
+ float4 path = POI2D_SAMPLER_PAN(_PathingMap, _MainTex, poiMesh.uv[_PathingMapUV], _PathingMapPan);
+ #else
+ float4 path = float4(0,0,0,0);
+ return;
+ #endif
+
+ #if defined(PROP_PATHINGCOLORMAP) || !defined(OPTIMIZER_ENABLED)
+ float4 pathColorMap = POI2D_SAMPLER_PAN(_PathingColorMap, _MainTex, poiMesh.uv[_PathingColorMapUV], _PathingColorMapPan);
+ #else
+ float4 pathColorMap = float4(1, 1, 1, 1);
+ #endif
+
+ float3 pathAudioLinkEmission = 0;
+ float3 pathTime = 0;
+ float3 pathAlpha[3] = {
+ float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0), float3(0.0, 0.0, 0.0)
+ };
+
+
+ #ifdef POI_AUDIOLINK
+ half pathAudioLinkPathTimeOffsetBand[3] = {_AudioLinkPathTimeOffsetBandR, _AudioLinkPathTimeOffsetBandG, _AudioLinkPathTimeOffsetBandB};
+ half2 pathAudioLinkTimeOffset[3] = {_AudioLinkPathTimeOffsetR.xy, _AudioLinkPathTimeOffsetG.xy, _AudioLinkPathTimeOffsetB.xy};
+ half pathAudioLinkPathWidthOffsetBand[3] = {_AudioLinkPathWidthOffsetBandR, _AudioLinkPathWidthOffsetBandG, _AudioLinkPathWidthOffsetBandB};
+ half2 pathAudioLinkWidthOffset[3] = {_AudioLinkPathWidthOffsetR.xy, _AudioLinkPathWidthOffsetG.xy, _AudioLinkPathWidthOffsetB.xy};
+
+ UNITY_BRANCH
+ if (poiMods.audioLinkTextureExists)
+ {
+ // Emission
+ pathAudioLinkEmission.r = lerp(_AudioLinkPathEmissionAddR.x, _AudioLinkPathEmissionAddR.y, poiMods.audioLink[_AudioLinkPathEmissionAddBandR]);
+ pathAudioLinkEmission.g = lerp(_AudioLinkPathEmissionAddG.x, _AudioLinkPathEmissionAddG.y, poiMods.audioLink[_AudioLinkPathEmissionAddBandG]);
+ pathAudioLinkEmission.b = lerp(_AudioLinkPathEmissionAddB.x, _AudioLinkPathEmissionAddB.y, poiMods.audioLink[_AudioLinkPathEmissionAddBandB]);
+ }
+ #endif
+
+ [unroll]
+ for (int index = 0; index < 3; index++)
+ {
+ pathTime[index] = _PathTime[index] != -999.0f ? frac(_PathTime[index] + _PathOffset[index]): frac(_Time.x * _PathSpeed[index] + _PathOffset[index]);
+
+ #ifdef POI_AUDIOLINK
+ UNITY_BRANCH
+ if (poiMods.audioLinkTextureExists)
+ {
+ pathTime[index] += lerp(pathAudioLinkTimeOffset[index].x, pathAudioLinkTimeOffset[index].y, poiMods.audioLink[pathAudioLinkPathTimeOffsetBand[index]]);
+ }
+ #endif
+
+ if (_PathSegments[index])
+ {
+ float pathSegments = abs(_PathSegments[index]);
+ pathTime = (ceil(pathTime * pathSegments) - .5) / pathSegments;
+ }
+
+ if (path[index])
+ {
+ // Cutting it in half because it goes out in both directions for now
+ half pathWidth = _PathWidth[index] * .5;
+ #ifdef POI_AUDIOLINK
+ UNITY_BRANCH
+ if (poiMods.audioLinkTextureExists)
+ {
+ pathWidth += lerp(pathAudioLinkWidthOffset[index].x, pathAudioLinkWidthOffset[index].y, poiMods.audioLink[pathAudioLinkPathWidthOffsetBand[index]]);
+ }
+ #endif
+
+
+ //fill
+ pathAlpha[index].x = pathTime[index] > path[index];
+ //path
+ pathAlpha[index].y = saturate((1 - abs(lerp(-pathWidth, 1 + pathWidth, pathTime[index]) - path[index])) - (1 - pathWidth)) * (1 / pathWidth);
+ //loop
+ pathAlpha[index].z = saturate((1 - distance(pathTime[index], path[index])) - (1 - pathWidth)) * (1 / pathWidth);
+ pathAlpha[index].z += saturate(distance(pathTime[index], path[index]) - (1 - pathWidth)) * (1 / pathWidth);
+ pathAlpha[index] = smoothstep(0, _PathSoftness[index] + .00001, pathAlpha[index]);
+ }
+ }
+
+ // Emission
+ pathEmission = 0;
+ pathEmission += pathAlpha[0][_PathTypeR] * _PathColorR.rgb * (_PathEmissionStrength[0] + pathAudioLinkEmission.r);
+ pathEmission += pathAlpha[1][_PathTypeG] * _PathColorG.rgb * (_PathEmissionStrength[1] + pathAudioLinkEmission.g);
+ pathEmission += pathAlpha[2][_PathTypeB] * _PathColorB.rgb * (_PathEmissionStrength[2] + pathAudioLinkEmission.b);
+ pathEmission *= pathColorMap.rgb * pathColorMap.a * path.a;
+
+ float3 colorReplace = 0;
+ colorReplace = pathAlpha[0][_PathTypeR] * _PathColorR.rgb * pathColorMap.rgb;
+ albedo.rgb = lerp(albedo.rgb, colorReplace + albedo.rgb * 0.00001, pathColorMap.a * path.a * _PathColorR.a * pathAlpha[0][_PathTypeR]);
+ colorReplace = pathAlpha[1][_PathTypeG] * _PathColorG.rgb * pathColorMap.rgb;
+ albedo.rgb = lerp(albedo.rgb, colorReplace + albedo.rgb * 0.00001, pathColorMap.a * path.a * _PathColorG.a * pathAlpha[1][_PathTypeG]);
+ colorReplace = pathAlpha[2][_PathTypeB] * _PathColorB.rgb * pathColorMap.rgb;
+ albedo.rgb = lerp(albedo.rgb, colorReplace + albedo.rgb * 0.00001, pathColorMap.a * path.a * _PathColorB.a * pathAlpha[2][_PathTypeB]);
+}
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPathing.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPathing.cginc.meta
new file mode 100644
index 00000000..e0413910
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPathing.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 3649a270ab312624fb813bdd56cf2373
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPenetration.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPenetration.cginc
new file mode 100644
index 00000000..b05186f5
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPenetration.cginc
@@ -0,0 +1,214 @@
+#ifndef RALIV_PENETRATION
+ #define RALIV_PENETRATION
+
+ float _PenetratorEnabled;
+ float _squeeze;
+ float _SqueezeDist;
+ float _BulgeOffset;
+ float _BulgePower;
+ float _Length;
+ float _EntranceStiffness;
+ float _Curvature;
+ float _ReCurvature;
+ float _WriggleSpeed;
+ float _Wriggle;
+ float _OrificeChannel;
+ float __dirty;
+
+ float _OrifaceEnabled;
+ sampler2D _OrificeData;
+ float _EntryOpenDuration;
+ float _Shape1Depth;
+ float _Shape1Duration;
+ float _Shape2Depth;
+ float _Shape2Duration;
+ float _Shape3Depth;
+ float _Shape3Duration;
+ float _BlendshapePower;
+ float _BlendshapeBadScaleFix;
+
+ void GetBestLights(float Channel, inout int orificeType, inout float3 orificePositionTracker, inout float3 orificeNormalTracker, inout float3 penetratorPositionTracker, inout float penetratorLength)
+ {
+ float ID = step(0.5, Channel);
+ float baseID = (ID * 0.02);
+ float holeID = (baseID + 0.01);
+ float ringID = (baseID + 0.02);
+ float normalID = (0.05 + (ID * 0.01));
+ float penetratorID = (0.09 + (ID * - 0.01));
+ float4 orificeWorld;
+ float4 orificeNormalWorld;
+ float4 penetratorWorld;
+ float penetratorDist = 100;
+ for (int i = 0; i < 4; i ++)
+ {
+ float range = (0.005 * sqrt(1000000 - unity_4LightAtten0[i])) / sqrt(unity_4LightAtten0[i]);
+ if (length(unity_LightColor[i].rgb) < 0.01)
+ {
+ if(abs(fmod(range, 0.1) - holeID) < 0.005)
+ {
+ orificeType = 0;
+ orificeWorld = float4(unity_4LightPosX0[i], unity_4LightPosY0[i], unity_4LightPosZ0[i], 1);
+ orificePositionTracker = mul(unity_WorldToObject, orificeWorld).xyz;
+ }
+ if(abs(fmod(range, 0.1) - ringID) < 0.005)
+ {
+ orificeType = 1;
+ orificeWorld = float4(unity_4LightPosX0[i], unity_4LightPosY0[i], unity_4LightPosZ0[i], 1);
+ orificePositionTracker = mul(unity_WorldToObject, orificeWorld).xyz;
+ }
+ if(abs(fmod(range, 0.1) - normalID) < 0.005)
+ {
+ orificeNormalWorld = float4(unity_4LightPosX0[i], unity_4LightPosY0[i], unity_4LightPosZ0[i], 1);
+ orificeNormalTracker = mul(unity_WorldToObject, orificeNormalWorld).xyz;
+ }
+ if(abs(fmod(range, 0.1) - penetratorID) < 0.005)
+ {
+ float3 tempPenetratorPositionTracker = penetratorPositionTracker;
+ penetratorWorld = float4(unity_4LightPosX0[i], unity_4LightPosY0[i], unity_4LightPosZ0[i], 1);
+ penetratorPositionTracker = mul(unity_WorldToObject, penetratorWorld).xyz;
+ if(length(penetratorPositionTracker) > length(tempPenetratorPositionTracker))
+ {
+ penetratorPositionTracker = tempPenetratorPositionTracker;
+ }
+ else
+ {
+ penetratorLength = unity_LightColor[i].a;
+ }
+ }
+ }
+ }
+ }
+
+ #ifdef POI_SHADOW
+ void applyRalivDynamicPenetrationSystem(inout float3 VertexPosition, inout float3 VertexNormal, inout VertexInputShadow v)
+ #else
+ void applyRalivDynamicPenetrationSystem(inout float3 VertexPosition, inout float3 VertexNormal, inout appdata v)
+ #endif
+ {
+ UNITY_BRANCH
+ if(_PenetratorEnabled)
+ {
+ float orificeChannel=0;
+ float orificeType = 0;
+ float3 orificePositionTracker = float3(0,0,100);
+ float3 orificeNormalTracker = float3(0,0,99);
+ float3 penetratorPositionTracker = float3(0,0,1);
+ float3 penetratorNormalTracker = float3(0,0,1);
+ float pl=0;
+ GetBestLights(orificeChannel, orificeType, orificePositionTracker, orificeNormalTracker, penetratorNormalTracker, pl);
+ float3 orificeNormal = normalize( lerp( ( orificePositionTracker - orificeNormalTracker ) , orificePositionTracker , max( _EntranceStiffness , 0.01 )) );
+ float behind = smoothstep(-_Length*0.5, _Length*0.2, orificePositionTracker.z);
+ //orificePositionTracker.xy = behind * orificePositionTracker.xy;
+ //orificeNormal.xy = behind * orificeNormal.xy;
+ orificePositionTracker.z=(abs(orificePositionTracker.z+(_Length*0.2))-(_Length*0.2))*(1+step(orificePositionTracker.z,0)*2);
+ orificePositionTracker.z=smoothstep(-_Length*0.2, _Length*0.2, orificePositionTracker.z) * orificePositionTracker.z;
+ float distanceToOrifice = length( orificePositionTracker );
+ float3 PhysicsNormal = normalize(penetratorNormalTracker.xyz);
+ float enterFactor = smoothstep( _Length , _Length+0.05 , distanceToOrifice);
+ float wriggleTimeY = _Time.y * _WriggleSpeed;
+ float curvatureMod = ( _Length * ( ( cos( wriggleTimeY ) * _Wriggle ) + _Curvature ) );
+ float wriggleTimeX = _Time.y * ( _WriggleSpeed * 0.79 );
+ float3 finalOrificeNormal = normalize( lerp( orificeNormal , ( PhysicsNormal + ( ( float3(0,1,0) * ( curvatureMod + ( _Length * ( _ReCurvature + ( ( sin( wriggleTimeY ) * 0.3 ) * _Wriggle ) ) * 2.0 ) ) ) + ( float3(0.5,0,0) * ( cos( wriggleTimeX ) * _Wriggle ) ) ) ) , enterFactor) );
+ float3 finalOrificePosition = lerp( orificePositionTracker , ( ( normalize(penetratorNormalTracker) * _Length ) + ( float3(0,0.2,0) * ( sin( ( wriggleTimeY + UNITY_PI ) ) * _Wriggle ) * _Length ) + ( float3(0.2,0,0) * _Length * ( sin( ( wriggleTimeX + UNITY_PI ) ) * _Wriggle ) ) ) , enterFactor);
+ float finalOrificeDistance = length( finalOrificePosition );
+ float3 bezierBasePosition = float3(0,0,0);
+ float bezierDistanceThird = ( finalOrificeDistance / 3.0 );
+ float3 curvatureOffset = lerp( float3( 0,0,0 ) , ( float3(0,1,0) * ( curvatureMod * -0.2 ) ) , saturate( ( distanceToOrifice / _Length ) ));
+ float3 bezierBaseNormal = ( ( bezierDistanceThird * float3(0,0,1) ) + curvatureOffset );
+ float3 bezierOrificeNormal = ( finalOrificePosition - ( bezierDistanceThird * finalOrificeNormal ) );
+ float3 bezierOrificePosition = finalOrificePosition;
+ float vertexBaseTipPosition = ( VertexPosition.z / finalOrificeDistance );
+
+ float3 sphereifyDistance = ( VertexPosition.xyz - float3(0,0, distanceToOrifice) );
+ float3 sphereifyNormal = normalize( sphereifyDistance );
+ float sphereifyFactor = smoothstep( 0.01 , -0.01 , distanceToOrifice - VertexPosition.z);
+ sphereifyFactor *= 1-orificeType;
+ VertexPosition.xyz = lerp( VertexPosition.xyz , ( float3(0,0, distanceToOrifice) + ( min( length( sphereifyDistance ) , _squeeze ) * sphereifyNormal ) ) , sphereifyFactor);
+
+ float squeezeFactor = smoothstep( 0.0 , _SqueezeDist , VertexPosition.z - distanceToOrifice);
+ squeezeFactor = max( squeezeFactor , smoothstep( 0.0 , _SqueezeDist , distanceToOrifice - VertexPosition.z));
+ squeezeFactor = 1- (1-squeezeFactor) * smoothstep(0,0.01,VertexPosition.z) * behind * (1-enterFactor);
+ VertexPosition.xy = lerp( ( normalize(VertexPosition.xy) * min( length( VertexPosition.xy ) , _squeeze ) ) , VertexPosition.xy , squeezeFactor);
+
+ float bulgeFactor = 1-smoothstep( 0.0 , _BulgeOffset , abs( ( finalOrificeDistance - VertexPosition.z ) ));
+ float bulgeFactorBaseClip = smoothstep( 0.0 , 0.05 , VertexPosition.z);
+ VertexPosition.xy *= lerp( 1.0 , ( 1.0 + _BulgePower ) , ( bulgeFactor * bulgeFactorBaseClip * behind * (1-enterFactor)));
+
+ float t = saturate(vertexBaseTipPosition);
+ float oneMinusT = 1 - t;
+ float3 bezierPoint = oneMinusT * oneMinusT * oneMinusT * bezierBasePosition + 3 * oneMinusT * oneMinusT * t * bezierBaseNormal + 3 * oneMinusT * t * t * bezierOrificeNormal + t * t * t * bezierOrificePosition;
+ float3 straightLine = (float3(0.0 , 0.0 , VertexPosition.z));
+ float baseFactor = smoothstep( 0.05 , -0.05 , VertexPosition.z);
+ bezierPoint = lerp( bezierPoint , straightLine , baseFactor);
+ bezierPoint = lerp( ( ( finalOrificeNormal * ( VertexPosition.z - finalOrificeDistance ) ) + finalOrificePosition ) , bezierPoint , step( vertexBaseTipPosition , 1.0 ));
+ float3 bezierDerivitive = 3 * oneMinusT * oneMinusT * (bezierBaseNormal - bezierBasePosition) + 6 * oneMinusT * t * (bezierOrificeNormal - bezierBaseNormal) + 3 * t * t * (bezierOrificePosition - bezierOrificeNormal);
+ bezierDerivitive = normalize( lerp( bezierDerivitive , float3(0,0,1) , baseFactor) );
+ float bezierUpness = dot( bezierDerivitive , float3( 0,1,0 ) );
+ float3 bezierUp = lerp( float3(0,1,0) , float3( 0,0,-1 ) , saturate( bezierUpness ));
+ float bezierDownness = dot( bezierDerivitive , float3( 0,-1,0 ) );
+ bezierUp = normalize( lerp( bezierUp , float3( 0,0,1 ) , saturate( bezierDownness )) );
+ float3 bezierSpaceX = normalize( cross( bezierDerivitive , bezierUp ) );
+ float3 bezierSpaceY = normalize( cross( bezierDerivitive , -bezierSpaceX ) );
+ float3 bezierSpaceVertexOffset = ( ( VertexPosition.y * bezierSpaceY ) + ( VertexPosition.x * -bezierSpaceX ) );
+ float3 bezierSpaceVertexOffsetNormal = normalize( bezierSpaceVertexOffset );
+ float distanceFromTip = ( finalOrificeDistance - VertexPosition.z );
+
+ float3 bezierSpaceVertexOffsetFinal = lerp( bezierSpaceVertexOffset , bezierSpaceVertexOffset , enterFactor);
+ float3 bezierConstructedVertex = ( bezierPoint + bezierSpaceVertexOffsetFinal );
+
+ VertexNormal = normalize( ( ( -bezierSpaceX * VertexNormal.x ) + ( bezierSpaceY * VertexNormal.y ) + ( bezierDerivitive * VertexNormal.z ) ) );
+ VertexPosition.xyz = bezierConstructedVertex;
+ }
+ }
+
+ float3 getBlendOffset(float blendSampleIndex, float activationDepth, float activationSmooth, int vertexID, float penetrationDepth, float3 normal, float3 tangent, float3 binormal)
+ {
+ float blendTextureSize = 1024;
+ float2 blendSampleUV = (float2(((fmod((float)vertexID, blendTextureSize) + 0.5) / (blendTextureSize)), (((floor((vertexID / (blendTextureSize))) + 0.5) / (blendTextureSize)) + blendSampleIndex / 8)));
+ float3 sampledBlend = tex2Dlod(_OrificeData, float4(blendSampleUV, 0, 0.0)).rgb;
+ float blendActivation = smoothstep((activationDepth), (activationDepth + activationSmooth), penetrationDepth);
+ blendActivation = -cos(blendActivation * 3.1416) * 0.5 + 0.5;
+ float3 blendOffset = ((sampledBlend - float3(1, 1, 1)) * (blendActivation) * _BlendshapePower * _BlendshapeBadScaleFix);
+ return((blendOffset.x * normal) + (blendOffset.y * tangent) + (blendOffset.z * binormal));
+ }
+
+ #ifdef POI_SHADOW
+ void applyRalivDynamicOrifaceSystem(inout VertexInputShadow v)
+ #else
+ void applyRalivDynamicOrifaceSystem(inout appdata v)
+ #endif
+ {
+ UNITY_BRANCH
+ if (_OrifaceEnabled)
+ {
+ float penetratorLength = 0.1;
+ float penetratorDistance;
+ float3 orificePositionTracker = float3(0, 0, -100);
+ float3 orificeNormalTracker = float3(0, 0, -99);
+ float3 penetratorPositionTracker = float3(0, 0, 100);
+ float orificeType = 0;
+
+ GetBestLights(_OrificeChannel, orificeType, orificePositionTracker, orificeNormalTracker, penetratorPositionTracker, penetratorLength);
+ penetratorDistance = distance(orificePositionTracker, penetratorPositionTracker);
+
+ float penetrationDepth = (penetratorLength - penetratorDistance);
+
+ float3 normal = normalize(v.normal);
+ float3 tangent = normalize(v.tangent.xyz);
+ float3 binormal = normalize(cross(normal, tangent));
+
+ v.vertex.xyz += getBlendOffset(0, 0, _EntryOpenDuration, v.vertexId, penetrationDepth, normal, tangent, binormal);
+ v.vertex.xyz += getBlendOffset(2, _Shape1Depth, _Shape1Duration, v.vertexId, penetrationDepth, normal, tangent, binormal);
+ v.vertex.xyz += getBlendOffset(4, _Shape2Depth, _Shape2Duration, v.vertexId, penetrationDepth, normal, tangent, binormal);
+ v.vertex.xyz += getBlendOffset(6, _Shape3Depth, _Shape3Duration, v.vertexId, penetrationDepth, normal, tangent, binormal);
+ v.vertex.w = 1;
+
+ v.normal += getBlendOffset(1, 0, _EntryOpenDuration, v.vertexId, penetrationDepth, normal, tangent, binormal);
+ v.normal += getBlendOffset(3, _Shape1Depth, _Shape1Duration, v.vertexId, penetrationDepth, normal, tangent, binormal);
+ v.normal += getBlendOffset(5, _Shape2Depth, _Shape2Duration, v.vertexId, penetrationDepth, normal, tangent, binormal);
+ v.normal += getBlendOffset(7, _Shape3Depth, _Shape3Duration, v.vertexId, penetrationDepth, normal, tangent, binormal);
+ v.normal = normalize(v.normal);
+ }
+ }
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPenetration.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPenetration.cginc.meta
new file mode 100644
index 00000000..d25df48e
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiPenetration.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 4c432851cf0d1dd44b21e0713429604a
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiRGBMask.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiRGBMask.cginc
new file mode 100644
index 00000000..7a92e7b7
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiRGBMask.cginc
@@ -0,0 +1,191 @@
+#ifndef POI_RGBMASK
+ #define POI_RGBMASK
+ #if defined(PROP_RGBMASK) || !defined(OPTIMIZER_ENABLED)
+ UNITY_DECLARE_TEX2D_NOSAMPLER(_RGBMask); float4 _RGBMask_ST;
+ #endif
+ #if defined(PROP_REDTEXURE) || !defined(OPTIMIZER_ENABLED)
+ UNITY_DECLARE_TEX2D_NOSAMPLER(_RedTexure); float4 _RedTexure_ST;
+ #endif
+ #if defined(PROP_GREENTEXTURE) || !defined(OPTIMIZER_ENABLED)
+ UNITY_DECLARE_TEX2D_NOSAMPLER(_GreenTexture); float4 _GreenTexture_ST;
+ #endif
+ #if defined(PROP_BLUETEXTURE) || !defined(OPTIMIZER_ENABLED)
+ UNITY_DECLARE_TEX2D_NOSAMPLER(_BlueTexture); float4 _BlueTexture_ST;
+ #endif
+ #if defined(PROP_ALPHATEXTURE) || !defined(OPTIMIZER_ENABLED)
+ UNITY_DECLARE_TEX2D_NOSAMPLER(_AlphaTexture); float4 _AlphaTexture_ST;
+ #endif
+
+ #ifdef GEOM_TYPE_MESH
+ #if defined(PROP_RGBNORMALR) || !defined(OPTIMIZER_ENABLED)
+ #endif
+ #if defined(PROP_RGBNORMALG) || !defined(OPTIMIZER_ENABLED)
+ #endif
+ #if defined(PROP_RGBNORMALB) || !defined(OPTIMIZER_ENABLED)
+ #endif
+ POI_NORMAL_NOSAMPLER(_RgbNormalR);
+ POI_NORMAL_NOSAMPLER(_RgbNormalG);
+ POI_NORMAL_NOSAMPLER(_RgbNormalB);
+ POI_NORMAL_NOSAMPLER(_RgbNormalA);
+ float _RgbNormalsEnabled;
+ #endif
+
+ float4 _RedColor;
+ float4 _GreenColor;
+ float4 _BlueColor;
+ float4 _AlphaColor;
+
+ float2 _RGBMaskPanning;
+ float2 _RGBRedPanning;
+ float2 _RGBGreenPanning;
+ float2 _RGBBluePanning;
+ float2 _RGBAlphaPanning;
+
+ float _RGBBlendMultiplicative;
+
+ float _RGBMaskUV;
+ float _RGBRed_UV;
+ float _RGBGreen_UV;
+ float _RGBBlue_UV;
+ float _RGBAlpha_UV;
+ float _RGBUseVertexColors;
+ float _RGBNormalBlend;
+
+ static float4 rgbMask;
+
+ void calculateRGBNormals(inout half3 mainTangentSpaceNormal)
+ {
+ #ifdef GEOM_TYPE_MESH
+ #ifndef RGB_MASK_TEXTURE
+ #define RGB_MASK_TEXTURE
+ UNITY_BRANCH
+ if (_RGBUseVertexColors)
+ {
+ rgbMask = poiMesh.vertexColor;
+ }
+ else
+ {
+ #if defined(PROP_RGBMASK) || !defined(OPTIMIZER_ENABLED)
+ rgbMask = POI2D_SAMPLER_PAN(_RGBMask, _MainTex, poiMesh.uv[_RGBMaskUV], _RGBMaskPanning);
+ #else
+ rgbMask = 1;
+ #endif
+ }
+ #endif
+
+ UNITY_BRANCH
+ if(_RgbNormalsEnabled)
+ {
+ UNITY_BRANCH
+ if(_RGBNormalBlend == 0)
+ {
+ UNITY_BRANCH
+ if(_RgbNormalRScale > 0)
+ {
+ half3 normalToBlendWith = UnpackScaleNormal(POI2D_SAMPLER_PAN(_RgbNormalR, _MainTex, poiMesh.uv[_RgbNormalRUV], _RgbNormalRPan), _RgbNormalRScale);
+ mainTangentSpaceNormal = lerp(mainTangentSpaceNormal, normalToBlendWith, rgbMask.r);
+ }
+
+ UNITY_BRANCH
+ if(_RgbNormalGScale > 0)
+ {
+ half3 normalToBlendWith = UnpackScaleNormal(POI2D_SAMPLER_PAN(_RgbNormalG, _MainTex, poiMesh.uv[_RgbNormalGUV], _RgbNormalGPan), _RgbNormalGScale);
+ mainTangentSpaceNormal = lerp(mainTangentSpaceNormal, normalToBlendWith, rgbMask.g);
+ }
+
+ UNITY_BRANCH
+ if(_RgbNormalBScale > 0)
+ {
+ half3 normalToBlendWith = UnpackScaleNormal(POI2D_SAMPLER_PAN(_RgbNormalB, _MainTex, poiMesh.uv[_RgbNormalBUV], _RgbNormalBPan), _RgbNormalBScale);
+ mainTangentSpaceNormal = lerp(mainTangentSpaceNormal, normalToBlendWith, rgbMask.b);
+ }
+
+ UNITY_BRANCH
+ if(_RgbNormalAScale > 0)
+ {
+ half3 normalToBlendWith = UnpackScaleNormal(POI2D_SAMPLER_PAN(_RgbNormalA, _MainTex, poiMesh.uv[_RgbNormalAUV], _RgbNormalAPan), _RgbNormalAScale);
+ mainTangentSpaceNormal = lerp(mainTangentSpaceNormal, normalToBlendWith, rgbMask.a);
+ }
+
+ return;
+ }
+ else
+ {
+ half3 newNormal = UnpackScaleNormal(POI2D_SAMPLER_PAN(_RgbNormalR, _MainTex, poiMesh.uv[_RgbNormalRUV], _RgbNormalRPan), _RgbNormalRScale * rgbMask.r);
+ half3 normalToBlendWith = UnpackScaleNormal(POI2D_SAMPLER_PAN(_RgbNormalG, _MainTex, poiMesh.uv[_RgbNormalGUV], _RgbNormalGPan), _RgbNormalGScale * rgbMask.g);
+ newNormal = BlendNormals(newNormal, normalToBlendWith);
+ normalToBlendWith = UnpackScaleNormal(POI2D_SAMPLER_PAN(_RgbNormalB, _MainTex, poiMesh.uv[_RgbNormalBUV], _RgbNormalBPan), _RgbNormalBScale * rgbMask.b);
+ newNormal = BlendNormals(newNormal, normalToBlendWith);
+ normalToBlendWith = UnpackScaleNormal(POI2D_SAMPLER_PAN(_RgbNormalA, _MainTex, poiMesh.uv[_RgbNormalAUV], _RgbNormalAPan), _RgbNormalAScale * rgbMask.a);
+ newNormal = BlendNormals(newNormal, normalToBlendWith);
+ mainTangentSpaceNormal = BlendNormals(newNormal, mainTangentSpaceNormal);
+ return;
+ }
+ }
+ #endif
+ }
+
+ float3 calculateRGBMask(float3 baseColor)
+ {
+ //If RGB normals are in use this data will already exist
+ #ifndef RGB_MASK_TEXTURE
+ #define RGB_MASK_TEXTURE
+
+ UNITY_BRANCH
+ if (_RGBUseVertexColors)
+ {
+ rgbMask = poiMesh.vertexColor;
+ }
+ else
+ {
+ #if defined(PROP_RGBMASK) || !defined(OPTIMIZER_ENABLED)
+ rgbMask = POI2D_SAMPLER_PAN(_RGBMask, _MainTex, poiMesh.uv[_RGBMaskUV], _RGBMaskPanning);
+ #else
+ rgbMask = 1;
+ #endif
+ }
+ #endif
+ #if defined(PROP_REDTEXURE) || !defined(OPTIMIZER_ENABLED)
+ float4 red = POI2D_SAMPLER_PAN(_RedTexure, _MainTex, poiMesh.uv[_RGBRed_UV], _RGBRedPanning);
+ #else
+ float4 red = 1;
+ #endif
+ #if defined(PROP_GREENTEXTURE) || !defined(OPTIMIZER_ENABLED)
+ float4 green = POI2D_SAMPLER_PAN(_GreenTexture, _MainTex, poiMesh.uv[_RGBGreen_UV], _RGBGreenPanning);
+ #else
+ float4 green = 1;
+ #endif
+ #if defined(PROP_BLUETEXTURE) || !defined(OPTIMIZER_ENABLED)
+ float4 blue = POI2D_SAMPLER_PAN(_BlueTexture, _MainTex, poiMesh.uv[_RGBBlue_UV], _RGBBluePanning);
+ #else
+ float4 blue = 1;
+ #endif
+ #if defined(PROP_ALPHATEXTURE) || !defined(OPTIMIZER_ENABLED)
+ float4 alpha = POI2D_SAMPLER_PAN(_AlphaTexture, _MainTex, poiMesh.uv[_RGBAlpha_UV], _RGBAlphaPanning);
+ #else
+ float4 alpha = 1;
+ #endif
+
+ UNITY_BRANCH
+ if(_RGBBlendMultiplicative)
+ {
+ float3 RGBColor = 1;
+ RGBColor = lerp(RGBColor, red.rgb * _RedColor.rgb, rgbMask.r * red.a * _RedColor.a);
+ RGBColor = lerp(RGBColor, green.rgb * _GreenColor.rgb, rgbMask.g * green.a * _GreenColor.a);
+ RGBColor = lerp(RGBColor, blue.rgb * _BlueColor.rgb, rgbMask.b * blue.a * _BlueColor.a);
+ RGBColor = lerp(RGBColor, alpha.rgb * _AlphaColor.rgb, rgbMask.a * alpha.a * _AlphaColor.a);
+
+ baseColor *= RGBColor;
+ }
+ else
+ {
+ baseColor = lerp(baseColor, red.rgb * _RedColor.rgb, rgbMask.r * red.a * _RedColor.a);
+ baseColor = lerp(baseColor, green.rgb * _GreenColor.rgb, rgbMask.g * green.a * _GreenColor.a);
+ baseColor = lerp(baseColor, blue.rgb * _BlueColor.rgb, rgbMask.b * blue.a * _BlueColor.a);
+ baseColor = lerp(baseColor, alpha.rgb * _AlphaColor.rgb, rgbMask.a * alpha.a * _AlphaColor.a);
+ }
+
+ return baseColor;
+ }
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiRGBMask.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiRGBMask.cginc.meta
new file mode 100644
index 00000000..9c49f636
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiRGBMask.cginc.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 5a887d6c0dfbbba48a780737a0351a55
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiRandom.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiRandom.cginc
new file mode 100644
index 00000000..7870c853
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiRandom.cginc
@@ -0,0 +1,41 @@
+#ifndef POI_RANDOM
+ #define POI_RANDOM
+
+ float _EnableRandom;
+ float m_start_Angle;
+ float _AngleType;
+ float3 _AngleForwardDirection;
+ float _CameraAngleMin;
+ float _CameraAngleMax;
+ float _ModelAngleMin;
+ float _ModelAngleMax;
+ float _AngleMinAlpha;
+ float _AngleCompareTo;
+
+ float ApplyAngleBasedRendering(float3 modelPos, float3 worldPos)
+ {
+ half cameraAngleMin = _CameraAngleMin / 180;
+ half cameraAngleMax = _CameraAngleMax / 180;
+ half modelAngleMin = _ModelAngleMin / 180;
+ half modelAngleMax = _ModelAngleMax / 180;
+ float3 pos = _AngleCompareTo == 0 ? modelPos : worldPos;
+ half3 cameraToModelDirection = normalize(pos - getCameraPosition());
+ half3 modelForwardDirection = normalize(mul(unity_ObjectToWorld, normalize(_AngleForwardDirection)));
+ half cameraLookAtModel = remapClamped(.5 * dot(cameraToModelDirection, getCameraForward()) + .5, cameraAngleMax, cameraAngleMin, 0, 1);
+ half modelLookAtCamera = remapClamped(.5 * dot(-cameraToModelDirection, modelForwardDirection) + .5, modelAngleMax, modelAngleMin, 0, 1);
+ if (_AngleType == 0)
+ {
+ return max(cameraLookAtModel, _AngleMinAlpha);
+ }
+ else if(_AngleType == 1)
+ {
+ return max(modelLookAtCamera, _AngleMinAlpha);
+ }
+ else if(_AngleType == 2)
+ {
+ return max(cameraLookAtModel * modelLookAtCamera, _AngleMinAlpha);
+ }
+ return 1;
+ }
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiRandom.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiRandom.cginc.meta
new file mode 100644
index 00000000..945d4847
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiRandom.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: b6260b56386a2b743a6bc537a3307cc7
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiRimLighting.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiRimLighting.cginc
new file mode 100644
index 00000000..dd0b9fac
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiRimLighting.cginc
@@ -0,0 +1,99 @@
+#ifndef POI_RIM
+#define POI_RIM
+
+float4 _RimLightColor;
+float _RimLightingInvert;
+float _RimWidth;
+float _RimStrength;
+float _RimSharpness;
+float _RimLightColorBias;
+float _ShadowMix;
+float _ShadowMixThreshold;
+float _ShadowMixWidthMod;
+float _EnableRimLighting;
+float _RimBrighten;
+float _RimLightNormal;
+float _RimHueShiftEnabled;
+float _RimHueShiftSpeed;
+float _RimHueShift;
+
+#ifdef POI_AUDIOLINK
+ half _AudioLinkRimWidthBand;
+ float2 _AudioLinkRimWidthAdd;
+ half _AudioLinkRimEmissionBand;
+ float2 _AudioLinkRimEmissionAdd;
+ half _AudioLinkRimBrightnessBand;
+ float2 _AudioLinkRimBrightnessAdd;
+#endif
+
+#if defined(PROP_RIMTEX) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_RimTex);
+#endif
+#if defined(PROP_RIMMASK) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_RimMask);
+#endif
+#if defined(PROP_RIMWIDTHNOISETEXTURE) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_RimWidthNoiseTexture);
+#endif
+
+float _RimWidthNoiseStrength;
+
+float4 rimColor = float4(0, 0, 0, 0);
+float rim = 0;
+
+void applyRimLighting(inout float4 albedo, inout float3 rimLightEmission)
+{
+ #if defined(PROP_RIMWIDTHNOISETEXTURE) || !defined(OPTIMIZER_ENABLED)
+ float rimNoise = POI2D_SAMPLER_PAN(_RimWidthNoiseTexture, _MainTex, poiMesh.uv[_RimWidthNoiseTextureUV], _RimWidthNoiseTexturePan);
+ #else
+ float rimNoise = 0;
+ #endif
+ rimNoise = (rimNoise - .5) * _RimWidthNoiseStrength;
+
+ float viewDotNormal = saturate(abs(dot(poiCam.viewDir, poiMesh.normals[_RimLightNormal])));
+
+ UNITY_BRANCH
+ if (_RimLightingInvert)
+ {
+ viewDotNormal = 1 - viewDotNormal;
+ }
+ float rimStrength = _RimStrength;
+ float rimBrighten = _RimBrighten;
+
+ float rimWidth = lerp( - .05, 1, _RimWidth);
+ #ifdef POI_AUDIOLINK
+ UNITY_BRANCH
+ if (poiMods.audioLinkTextureExists)
+ {
+ rimWidth = clamp(rimWidth + lerp(_AudioLinkRimWidthAdd.x, _AudioLinkRimWidthAdd.y, poiMods.audioLink[_AudioLinkRimWidthBand]), - .05, 1);
+ rimStrength += lerp(_AudioLinkRimEmissionAdd.x, _AudioLinkRimEmissionAdd.y, poiMods.audioLink[_AudioLinkRimEmissionBand]);
+ rimBrighten += lerp(_AudioLinkRimBrightnessAdd.x, _AudioLinkRimBrightnessAdd.y, poiMods.audioLink[_AudioLinkRimBrightnessBand]);
+ }
+ #endif
+
+ rimWidth -= rimNoise;
+ #if defined(PROP_RIMMASK) || !defined(OPTIMIZER_ENABLED)
+ float rimMask = POI2D_SAMPLER_PAN(_RimMask, _MainTex, poiMesh.uv[_RimMaskUV], _RimMaskPan);
+ #else
+ float rimMask = 1;
+ #endif
+
+ #if defined(PROP_RIMTEX) || !defined(OPTIMIZER_ENABLED)
+ rimColor = POI2D_SAMPLER_PAN(_RimTex, _MainTex, poiMesh.uv[_RimTexUV], _RimTexPan) * _RimLightColor;
+ #else
+ rimColor = _RimLightColor;
+ #endif
+
+ UNITY_BRANCH
+ if (_RimHueShiftEnabled)
+ {
+ rimColor.rgb = hueShift(rimColor.rgb, _RimHueShift + _Time.x * _RimHueShiftSpeed);
+ }
+
+ rimWidth = max(lerp(rimWidth, rimWidth * lerp(0, 1, poiLight.lightMap - _ShadowMixThreshold) * _ShadowMixWidthMod, _ShadowMix), 0);
+ rim = 1 - smoothstep(min(_RimSharpness, rimWidth), rimWidth, viewDotNormal);
+ rim *= _RimLightColor.a * rimColor.a * rimMask;
+ rimLightEmission = rim * lerp(albedo, rimColor, _RimLightColorBias) * rimStrength;
+ albedo.rgb = lerp(albedo.rgb, lerp(albedo.rgb, rimColor, _RimLightColorBias) + lerp(albedo.rgb, rimColor, _RimLightColorBias) * rimBrighten, rim);
+}
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiRimLighting.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiRimLighting.cginc.meta
new file mode 100644
index 00000000..8fcf8327
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiRimLighting.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: a87bd1004a9f61d4da9d5159ced4fcc8
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiShadowFrag.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiShadowFrag.cginc
new file mode 100644
index 00000000..8e6499fa
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiShadowFrag.cginc
@@ -0,0 +1,143 @@
+#ifndef SHADOW_FRAG
+#define SHADOW_FRAG
+
+float2 _MainDistanceFade;
+float _ForceOpaque;
+float _MainShadowClipMod;
+float2 _ClippingMaskPan;
+float _ClippingMaskUV;
+sampler3D _DitherMaskLOD;
+float2 _MainTexPan;
+float _MainTextureUV;
+float _Inverse_Clipping;
+float _MainDistanceFadeMin;
+float _MainDistanceFadeMax;
+half _MainMinAlpha;
+half _MainMaxAlpha;
+
+#if defined(PROP_MAINFADETEXTURE) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_MainFadeTexture);
+#endif
+
+float distanceFade()
+{
+ #if defined(PROP_MAINFADETEXTURE) || !defined(OPTIMIZER_ENABLED)
+ half fadeMap = POI2D_SAMPLER_PAN(_MainFadeTexture, _MainTex, poiMesh.uv[_MainFadeTextureUV], _MainFadeTexturePan).r;
+ #else
+ half fadeMap = 1;
+ #endif
+
+ return lerp(_MainMinAlpha, _MainMaxAlpha, smoothstep(_MainDistanceFadeMin, _MainDistanceFadeMax, distance(poiMesh.worldPos, poiCam.worldPos)));
+}
+
+half4 fragShadowCaster(
+ #if !defined(V2F_SHADOW_CASTER_NOPOS_IS_EMPTY) || defined(UNITY_STANDARD_USE_SHADOW_UVS)
+ V2FShadow i, uint facing: SV_IsFrontFace
+ #endif
+ ): SV_Target
+ {
+ poiMesh.uv[0] = i.uv;
+ poiMesh.uv[1] = i.uv1;
+ poiMesh.uv[2] = i.uv2;
+ poiMesh.uv[3] = i.uv3;
+
+ // Basically every texture relies on the maintex sampler to function and that's why this is here.
+ float4 mainTexture = UNITY_SAMPLE_TEX2D(_MainTex, TRANSFORM_TEX(poiMesh.uv[_MainTextureUV], _MainTex) + _Time.x * _MainTexPan);
+
+
+ //Possible Bug with clip
+ float clipValue = clamp(_Cutoff + _MainShadowClipMod, - .001, 1.001);
+
+ poiMesh.vertexColor = saturate(i.vertexColor);
+ poiMesh.worldPos = i.worldPos;
+ poiMesh.localPos = i.localPos;
+ poiCam.worldPos = _WorldSpaceCameraPos;
+
+ #ifdef POI_MIRROR
+ applyMirrorRenderFrag();
+ #endif
+
+ #if defined(UNITY_STANDARD_USE_SHADOW_UVS)
+
+ half4 alpha = mainTexture;
+
+ #if defined(PROP_MIRRORTEXTURE) || !defined(OPTIMIZER_ENABLED)
+ UNITY_BRANCH
+ if (_EnableMirrorTexture)
+ {
+ if (IsInMirror())
+ {
+ alpha.a = UNITY_SAMPLE_TEX2D_SAMPLER(_MirrorTexture, _MainTex, TRANSFORM_TEX(i.uv, _MirrorTexture)).a;
+ }
+ }
+ #endif
+
+ alpha.a *= distanceFade();
+ half alphaMask = POI2D_PAN(_ClippingMask, poiMesh.uv[_ClippingMaskUV], _ClippingMaskPan);
+ UNITY_BRANCH
+ if (_Inverse_Clipping)
+ {
+ alphaMask = 1 - alphaMask;
+ }
+ alpha.a *= alphaMask;
+ alpha.a *= _Color.a + .0001;
+ alpha.a += _AlphaMod;
+ alpha.a = saturate(alpha.a);
+
+ UNITY_BRANCH
+ if (_Mode == 0)
+ {
+ alpha.a = 1;
+ }
+
+ UNITY_BRANCH
+ if (_Mode == 1)
+ {
+ applyShadowDithering(alpha.a, calcScreenUVs(i.grabPos).xy);
+ }
+
+ #ifdef POI_DISSOLVE
+ float3 fakeEmission = 1;
+ calculateDissolve(alpha, fakeEmission);
+ #endif
+ UNITY_BRANCH
+ if (_Mode == 1)
+ {
+ clip(alpha.a - 0.001);
+ }
+
+ /*
+ return poiMesh.vertexColor.g;
+
+ #ifdef POI_RANDOM
+ alpha.a *= i.angleAlpha;
+ #endif
+
+ UNITY_BRANCH
+ if(_Mode >= 1)
+ {
+ applySpawnInShadow(uv[0], i.localPos);
+
+ #if defined(POI_FLIPBOOK)
+ alpha.a *= applyFlipbookAlphaToShadow(uv[_FlipbookTexArrayUV]);
+ #endif
+ }
+ */
+ UNITY_BRANCH
+ if (_Mode == 1)
+ {
+ clip(alpha.a - clipValue);
+ }
+
+ UNITY_BRANCH
+ if (_Mode > 1)
+ {
+ float dither = tex3D(_DitherMaskLOD, float3(i.pos.xy * .25, alpha.a * 0.9375)).a;
+ clip(dither - 0.01);
+ }
+
+ #endif
+ SHADOW_CASTER_FRAGMENT(i)
+ }
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiShadowFrag.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiShadowFrag.cginc.meta
new file mode 100644
index 00000000..217949d3
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiShadowFrag.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 6f029ac6c95637345af7f9fa039b835d
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiShadowIncludes.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiShadowIncludes.cginc
new file mode 100644
index 00000000..583b0e75
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiShadowIncludes.cginc
@@ -0,0 +1,44 @@
+#ifndef SHADOW_INCLUDES
+ #define SHADOW_INCLUDES
+
+ #define UNITY_STANDARD_USE_SHADOW_UVS 1
+
+ float4 _Color;
+ sampler2D _ClippingMask; float4 _ClippingMask_ST;
+
+ struct VertexInputShadow
+ {
+ float4 vertex: POSITION;
+ float3 normal: NORMAL;
+ float4 tangent: TANGENT;
+ float4 color: COLOR;
+ float2 uv0: TEXCOORD0;
+ float2 uv1: TEXCOORD1;
+ float2 uv2: TEXCOORD2;
+ float2 uv3: TEXCOORD3;
+ uint vertexId : SV_VertexID;
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ };
+
+ #if !defined(V2F_SHADOW_CASTER_NOPOS_IS_EMPTY) || defined(UNITY_STANDARD_USE_SHADOW_UVS)
+ struct V2FShadow
+ {
+ V2F_SHADOW_CASTER_NOPOS
+ float4 pos: SV_POSITION;
+ float2 uv: TEXCOORD1;
+ float2 uv1: TEXCOORD2;
+ float2 uv2: TEXCOORD3;
+ float2 uv3: TEXCOORD4;
+ float3 modelPos: TEXCOORD5;
+ float4 worldPos: TEXCOORD6;
+ float4 localPos: TEXCOORD7;
+ float3 angleAlpha: TEXCOORD8;
+ float4 grabPos: TEXCOORD9;
+ fixed3 barycentricCoordinates: TEXCOORD10;
+ float4 vertexColor: TEXCOORD11;
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ UNITY_VERTEX_OUTPUT_STEREO
+ };
+ #endif
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiShadowIncludes.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiShadowIncludes.cginc.meta
new file mode 100644
index 00000000..e32bb288
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiShadowIncludes.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 388afdf5d08890a498d21c55347c0a2c
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiShadowVert.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiShadowVert.cginc
new file mode 100644
index 00000000..b7d8328c
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiShadowVert.cginc
@@ -0,0 +1,86 @@
+float _EnableTouchGlow;
+float _EnableBulge;
+float _VertexManipulationHeightUV;
+
+V2FShadow vertShadowCaster(VertexInputShadow v)
+{
+ V2FShadow o;
+ UNITY_SETUP_INSTANCE_ID(v);
+ #ifdef RALIV_PENETRATION
+ applyRalivDynamicOrifaceSystem(v);
+ #endif
+ #ifdef AUTO_EXPOSURE
+ applyLocalVertexTransformation(v.normal, v.vertex);
+ #endif
+
+ UNITY_INITIALIZE_OUTPUT(V2FShadow, o);
+ UNITY_TRANSFER_INSTANCE_ID(v, o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+
+ o.localPos = v.vertex;
+ o.worldPos = mul(unity_ObjectToWorld, o.localPos);
+
+ #ifdef RALIV_PENETRATION
+ applyRalivDynamicPenetrationSystem(o.localPos.rgb, v.normal.rgb, v);
+ #endif
+
+ o.modelPos = mul(unity_ObjectToWorld, float4(0, 0, 0, 1));
+ o.uv = v.uv0;
+ o.uv1 = v.uv1;
+ o.uv2 = v.uv2;
+ o.uv3 = v.uv3;
+
+
+ float2 uvToUse = 0;
+ UNITY_BRANCH
+ if (_VertexManipulationHeightUV == 0)
+ {
+ uvToUse = v.uv0.xy;
+ }
+ UNITY_BRANCH
+ if(_VertexManipulationHeightUV == 1)
+ {
+ uvToUse = v.uv1.xy;
+ }
+ UNITY_BRANCH
+ if(_VertexManipulationHeightUV == 2)
+ {
+ uvToUse = v.uv2.xy;
+ }
+ UNITY_BRANCH
+ if(_VertexManipulationHeightUV == 3)
+ {
+ uvToUse = v.uv3.xy;
+ }
+ #ifdef AUTO_EXPOSURE
+ applyWorldVertexTransformation(o.worldPos, o.localPos, v.normal, uvToUse);
+ #endif
+ applyVertexGlitching(o.worldPos, o.localPos);
+ applySpawnInVert(o.worldPos, o.localPos, v.uv0.xy);
+ #ifdef AUTO_EXPOSURE
+ applyVertexRounding(o.worldPos, o.localPos);
+ #endif
+ o.pos = UnityObjectToClipPos(o.localPos);
+ o.grabPos = ComputeGrabScreenPos(o.pos);
+ o.modelPos = mul(unity_ObjectToWorld, float4(0, 0, 0, 1));
+ o.vertexColor = v.color;
+
+ UNITY_BRANCH
+ if(_EnableTouchGlow || _EnableBulge)
+ {
+ o.pos = UnityObjectToClipPos(float3(0, 0, -5));
+ o.localPos.xyz = float3(0, 0, -5);
+ o.worldPos = mul(unity_ObjectToWorld, o.localPos);
+ }
+
+ o.angleAlpha = 1;
+ #ifdef POI_RANDOM
+ o.angleAlpha = ApplyAngleBasedRendering(o.modelPos, o.worldPos);
+ #endif
+
+
+ o.pos = UnityClipSpaceShadowCasterPos(o.localPos, v.normal);
+ o.pos = UnityApplyLinearShadowBias(o.pos);
+
+ return o;
+} \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiShadowVert.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiShadowVert.cginc.meta
new file mode 100644
index 00000000..2b45031c
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiShadowVert.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 85240e87020438747a5fa50f428e5cdf
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiSpawnInFrag.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiSpawnInFrag.cginc
new file mode 100644
index 00000000..12bea5f7
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiSpawnInFrag.cginc
@@ -0,0 +1,58 @@
+#ifndef POI_SPAWN_IN_FRAG
+ #define POI_SPAWN_FRAG
+
+ #ifndef SPAWN_IN_VARIABLES
+ #define SPAWN_IN_VARIABLES
+
+ float3 _SpawnInGradientStart;
+ float3 _SpawnInGradientFinish;
+ fixed _SpawnInAlpha;
+ fixed _SpawnInNoiseIntensity;
+ float3 _SpawnInEmissionColor;
+ float _SpawnInEmissionOffset;
+ float _SpawnInVertOffset;
+ float _SpawnInVertOffsetOffset;
+ float _EnableScifiSpawnIn;
+ #endif
+
+ UNITY_DECLARE_TEX2D_NOSAMPLER(_SpawnInNoise); float4 _SpawnInNoise_ST;
+
+ float calculateGradientValueFrag(float3 start, float3 finish, float3 localPos)
+ {
+ return inverseLerp3(start, finish, localPos);
+ }
+
+ void applySpawnIn(inout float4 finalColor, inout float3 spawnInEmission, float2 uv, float3 localPos)
+ {
+ UNITY_BRANCH
+ if (_EnableScifiSpawnIn)
+ {
+ float noise = UNITY_SAMPLE_TEX2D_SAMPLER(_SpawnInNoise, _MainTex, TRANSFORM_TEX(uv, _SpawnInNoise)).r * _SpawnInAlpha * _SpawnInNoiseIntensity;
+ float gradient = calculateGradientValueFrag(_SpawnInGradientStart, _SpawnInGradientFinish, localPos);
+ float inverseGradient = 1 - gradient;
+ float alpha = gradient - _SpawnInAlpha - noise;
+ spawnInEmission = saturate(inverseGradient + _SpawnInAlpha + _SpawnInEmissionOffset +noise - 1) * _SpawnInEmissionColor;
+ UNITY_BRANCH
+ if(_Mode >= 1)
+ {
+ clip(ceil(alpha) - 0.001);
+ }
+ }
+ }
+
+ void applySpawnInShadow(float2 uv, float3 localPos)
+ {
+ UNITY_BRANCH
+ if(_EnableScifiSpawnIn)
+ {
+ float noise = UNITY_SAMPLE_TEX2D_SAMPLER(_SpawnInNoise, _MainTex, TRANSFORM_TEX(uv, _SpawnInNoise)).r * _SpawnInAlpha * _SpawnInNoiseIntensity;
+ float gradient = calculateGradientValueFrag(_SpawnInGradientStart, _SpawnInGradientFinish, localPos);
+ float alpha = gradient - _SpawnInAlpha - noise + length(_SpawnInVertOffset);
+ UNITY_BRANCH
+ if(_Mode >= 1)
+ {
+ clip(ceil(alpha) - 0.001);
+ }
+ }
+ }
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiSpawnInFrag.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiSpawnInFrag.cginc.meta
new file mode 100644
index 00000000..97aa08c5
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiSpawnInFrag.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 7913db65c40101341a2f9d4c1b15f96d
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiSpawnInVert.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiSpawnInVert.cginc
new file mode 100644
index 00000000..01ced3fb
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiSpawnInVert.cginc
@@ -0,0 +1,40 @@
+#ifndef POI_SPAWN_IN_FRAG
+ #define POI_SPAWN_FRAG
+
+ #ifndef SPAWN_IN_VARIABLES
+ #define SPAWN_IN_VARIABLES
+
+ float3 _SpawnInGradientStart;
+ float3 _SpawnInGradientFinish;
+ fixed _SpawnInAlpha;
+ fixed _SpawnInNoiseIntensity;
+ float3 _SpawnInEmissionColor;
+ float _SpawnInEmissionOffset;
+ float _SpawnInVertOffset;
+ float _SpawnInVertOffsetOffset;
+ float _EnableScifiSpawnIn;
+
+ #endif
+ //sampler2D _SpawnInNoiseVert; float4 _SpawnInNoiseVert_ST;
+
+ float calculateGradientValueVert(float3 start, float3 finish, float3 localPos)
+ {
+ return inverseLerp3(start, finish, localPos);
+ }
+
+ void applySpawnInVert(inout float4 worldPos, inout float4 localPos, float2 uv)
+ {
+ UNITY_BRANCH
+ if (_EnableScifiSpawnIn)
+ {
+ float noise = 0;
+ float gradient = calculateGradientValueVert(_SpawnInGradientStart, _SpawnInGradientFinish, localPos.xyz);
+ float inverseGradient = 1 - gradient;
+ float alpha = gradient - _SpawnInAlpha - noise;
+ worldPos.xyz += saturate(inverseGradient + _SpawnInAlpha + _SpawnInVertOffsetOffset -1) * float3(0, _SpawnInVertOffset, 0);
+ localPos.xyz = mul(unity_WorldToObject, worldPos).xyz;
+ }
+ //float noise = tex2Dlod(_SpawnInNoise, float4(TRANSFORM_TEX(uv, _SpawnInNoise))).r * _SpawnInAlpha * _SpawnInNoiseIntensity;
+ }
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiSpawnInVert.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiSpawnInVert.cginc.meta
new file mode 100644
index 00000000..e6fcfee7
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiSpawnInVert.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 73fa7e501ae5f2643ac34be3ad11b72a
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiSpecular.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiSpecular.cginc
new file mode 100644
index 00000000..e205f1bf
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiSpecular.cginc
@@ -0,0 +1,505 @@
+#ifndef POI_SPECULAR
+#define POI_SPECULAR
+float _SpecWhatTangent;
+float _SpecularType;
+float _SmoothnessFrom;
+POI_TEXTURE_NOSAMPLER(_SpecularMetallicMap);
+POI_TEXTURE_NOSAMPLER(_SpecularMap);
+fixed _CenterOutSpecColor;
+POI_TEXTURE_NOSAMPLER(_SpecularAnisoJitterMicro);
+float _SpecularAnisoJitterMirrored;
+POI_TEXTURE_NOSAMPLER(_SpecularAnisoJitterMacro);
+POI_TEXTURE_NOSAMPLER(_SpecularAnisoFakeUV);
+POI_TEXTURE_NOSAMPLER(_AnisoTangentMap);
+POI_TEXTURE_NOSAMPLER(_SpecularMask);
+float _SpecularAnisoJitterMicroMultiplier;
+float _SpecularAnisoJitterMacroMultiplier;
+float4 _SpecularTint;
+float _SpecularSmoothness;
+float _Spec1Offset;
+float _Spec1JitterStrength;
+float _Spec2Smoothness;
+float _Spec2Offset;
+float _Spec2JitterStrength;
+float _AnisoUseTangentMap;
+float _AnisoSpec1Alpha;
+float _AnisoSpec2Alpha;
+float _SpecularInvertSmoothness;
+half _SpecularMetallic;
+float _SpecularNormal;
+float _SpecularNormal1;
+float _SpecularMaxBrightness;
+// Toon
+fixed _SpecularToonStart;
+fixed _SpecularToonEnd;
+half4 _SpecularToonInnerOuter;
+
+#ifdef DITHERING
+ float _EnableSpecular1;
+ float _SpecWhatTangent1;
+ float _SpecularType1;
+ float _SmoothnessFrom1;
+ POI_TEXTURE_NOSAMPLER(_SpecularMetallicMap1);
+ POI_TEXTURE_NOSAMPLER(_SpecularMap1);
+ POI_TEXTURE_NOSAMPLER(_SpecularAnisoJitterMicro1);
+ POI_TEXTURE_NOSAMPLER(_SpecularAnisoJitterMacro1);
+ float _SpecularAnisoJitterMirrored1;
+ POI_TEXTURE_NOSAMPLER(_AnisoTangentMap1);
+ POI_TEXTURE_NOSAMPLER(_SpecularMask1);
+ float _SpecularAnisoJitterMicroMultiplier1;
+ float _SpecularAnisoJitterMacroMultiplier1;
+ float4 _SpecularTint1;
+ float _SpecularSmoothness1;
+ float _Spec1Offset1;
+ float _Spec1JitterStrength1;
+ float _Spec2Smoothness1;
+ float _Spec2Offset1;
+ float _Spec2JitterStrength1;
+ float _AnisoUseTangentMap1;
+ float _AnisoSpec1Alpha1;
+ float _AnisoSpec2Alpha1;
+ float _SpecularInvertSmoothness1;
+ half _SpecularMetallic1;
+ float _SpecularMaxBrightness1;
+ // Toon
+ half4 _SpecularToonInnerOuter1;
+ fixed _SpecularToonStart1;
+ fixed _SpecularToonEnd1;
+#endif
+UnityIndirect ZeroIndirect()
+{
+ UnityIndirect ind;
+ ind.diffuse = 0;
+ ind.specular = 0;
+ return ind;
+}
+
+// From unity just putting it here in case I want to mod it
+half4 poiRealisticSpecular(half3 diffColor, half3 specColor, half oneMinusReflectivity, half smoothness,
+float3 normal, float3 halfDir,
+UnityLight light, UnityIndirect gi)
+{
+ float perceptualRoughness = SmoothnessToPerceptualRoughness(smoothness);
+ #define UNITY_HANDLE_CORRECTLY_NEGATIVE_NDOTV 0
+
+ #if UNITY_HANDLE_CORRECTLY_NEGATIVE_NDOTV
+ half shiftAmount = dot(normal, poiCam.viewDir);
+ normal = shiftAmount < 0.0f ? normal + poiCam.viewDir * (-shiftAmount + 1e-5f): normal;
+ float nv = saturate(dot(normal, poiCam.viewDir));
+ #else
+ half nv = abs(dot(normal, poiCam.viewDir));
+ #endif
+
+ float nl = saturate(dot(normal, light.dir));
+ float nh = saturate(dot(normal, halfDir));
+
+ half lv = saturate(dot(light.dir, poiCam.viewDir));
+ half lh = saturate(dot(light.dir, halfDir));
+
+ half diffuseTerm = DisneyDiffuse(nv, nl, lh, perceptualRoughness) * nl;
+
+ float roughness = PerceptualRoughnessToRoughness(perceptualRoughness);
+
+ roughness = max(roughness, 0.002);
+ float V = SmithJointGGXVisibilityTerm(nl, nv, roughness);
+ float D = GGXTerm(nh, roughness);
+
+ float specularTerm = V * D * UNITY_PI;
+
+ #ifdef UNITY_COLORSPACE_GAMMA
+ specularTerm = sqrt(max(1e-4h, specularTerm));
+ #endif
+
+ specularTerm = max(0, specularTerm * nl);
+ #if defined(_POI_SPECULARHIGHLIGHTS_OFF)
+ specularTerm = 0.0;
+ #endif
+
+ half surfaceReduction;
+ #ifdef UNITY_COLORSPACE_GAMMA
+ surfaceReduction = 1.0 - 0.28 * roughness * perceptualRoughness;
+ #else
+ surfaceReduction = 1.0 / (roughness * roughness + 1.0);
+ #endif
+
+ specularTerm *= any(specColor) ? 1.0: 0.0;
+
+ half grazingTerm = saturate(smoothness + (1 - oneMinusReflectivity));
+ half3 color = diffColor * (gi.diffuse + light.color * diffuseTerm)
+ + specularTerm * light.color * FresnelTerm(specColor, lh)
+ + surfaceReduction * gi.specular * FresnelLerp(specColor, grazingTerm, nv);
+
+ return half4(color, 1);
+}
+
+half3 calculateRealisticSpecular(float4 albedo, float2 uv, float4 specularTint, float specularSmoothness, float invertSmoothness, float mixAlbedoWithTint, float4 specularMap, float3 specularLight, float3 normal, float attenuation, float3 lightDirection, float nDotL, float3 halfDir)
+{
+ half oneMinusReflectivity;
+ half3 finalSpecular;
+ UnityLight unityLight;
+ unityLight.color = specularLight;
+ unityLight.dir = lightDirection;
+ unityLight.ndotl = nDotL;
+
+ UNITY_BRANCH
+ if (_SmoothnessFrom == 0)
+ {
+ half3 diffColor = EnergyConservationBetweenDiffuseAndSpecular(albedo, specularMap.rgb * specularTint.rgb, /*out*/ oneMinusReflectivity);
+ finalSpecular = poiRealisticSpecular(diffColor, specularMap.rgb, oneMinusReflectivity, specularMap.a * specularSmoothness * lerp(1, -1, invertSmoothness), normal, halfDir, unityLight, ZeroIndirect());
+ }
+ else
+ {
+ half3 diffColor = EnergyConservationBetweenDiffuseAndSpecular(albedo, specularTint.rgb, /*out*/ oneMinusReflectivity);
+ float smoothness = max(max(specularMap.r, specularMap.g), specularMap.b);
+ finalSpecular = poiRealisticSpecular(diffColor, 1, oneMinusReflectivity, smoothness * specularSmoothness * lerp(1, -1, invertSmoothness), normal, halfDir, unityLight, ZeroIndirect());
+ }
+ finalSpecular *= lerp(1, albedo.rgb, mixAlbedoWithTint);
+ return finalSpecular;
+}
+
+half3 calculateToonSpecular(float4 albedo, float2 uv, float2 specularToonInnerOuter, float specularMixAlbedoIntoTint, float smoothnessFrom, float4 specularMap, float3 specularLight, float3 normal, float3 halfDir, float attenuation)
+{
+ half3 finalSpecular = smoothstep(1 - specularToonInnerOuter.y, 1 - specularToonInnerOuter.x, dot(halfDir, normal)) * specularLight;
+ UNITY_BRANCH
+ if (smoothnessFrom == 0)
+ {
+ finalSpecular.rgb *= specularMap.rgb * lerp(1, albedo.rgb, specularMixAlbedoIntoTint);
+ finalSpecular *= specularMap.a;
+ }
+ else
+ {
+ finalSpecular *= specularMap.r * lerp(1, albedo.rgb, specularMixAlbedoIntoTint);
+ }
+ return finalSpecular;
+}
+
+float3 strandSpecular(float TdotL, float TdotV, float specPower, float nDotL)
+{
+ #ifdef FORWARD_ADD_PASS
+ nDotL *= poiLight.attenuation * poiLight.additiveShadow;
+ #endif
+ float Specular = saturate(nDotL) * pow(saturate(sqrt(1.0 - (TdotL * TdotL)) * sqrt(1.0 - (TdotV * TdotV)) - TdotL * TdotV), specPower);
+ half normalization = sqrt((specPower + 1) * ((specPower) + 1)) / (8 * pi);
+ Specular *= normalization;
+ return Specular;
+}
+
+half3 AnisotropicSpecular(
+ float specWhatTangent, float anisoUseTangentMap, float specularSmoothness, float spec2Smoothness,
+ float anisoSpec1Alpha, float anisoSpec2Alpha, float4 specularTint, float specularMixAlbedoIntoTint, float4 specularMap, float3 specularLight, float3 lightDirection, float3 halfDir, float nDotL, float jitter, float4 packedTangentMap, in float4 albedo)
+{
+ float3 tangentOrBinormal = specWhatTangent ? poiMesh.tangent: poiMesh.binormal;
+
+
+ float3 normalLocalAniso = lerp(float3(0, 0, 1), UnpackNormal(packedTangentMap), anisoUseTangentMap);
+ normalLocalAniso = BlendNormals(normalLocalAniso, poiMesh.tangentSpaceNormal);
+ //float3 normalDirection = normalize(mul(poiMesh.normals[_SpecularNormal], poiTData.tangentTransform));
+ float3 normalDirectionAniso = Unity_SafeNormalize(mul(normalLocalAniso, poiTData.tangentTransform));
+ float3 tangentDirection = mul(poiTData.tangentTransform, tangentOrBinormal).xyz;
+ float3 viewReflectDirectionAniso = reflect(-poiCam.viewDir, normalDirectionAniso); // possible bad negation
+ float3 tangentDirectionMap = mul(poiTData.tangentToWorld, float3(normalLocalAniso.rg, 0.0)).xyz;
+ tangentDirectionMap = normalize(lerp(tangentOrBinormal, tangentDirectionMap, anisoUseTangentMap));
+
+ tangentDirectionMap += _Spec1Offset +jitter;
+
+ float TdotL = dot(lightDirection, tangentDirectionMap);
+ float TdotV = dot(poiCam.viewDir, tangentDirectionMap);
+ float TdotH = dot(halfDir, tangentDirectionMap);
+ half specPower = RoughnessToSpecPower(1.0 - specularSmoothness * specularMap.a);
+ half spec2Power = RoughnessToSpecPower(1.0 - spec2Smoothness * specularMap.a);
+ half Specular = 0;
+
+ float3 spec = strandSpecular(TdotL, TdotV, specPower, nDotL) * anisoSpec1Alpha;
+ float3 spec2 = strandSpecular(TdotL, TdotV, spec2Power, nDotL) * anisoSpec2Alpha;
+
+ return max(spec, spec2) * specularMap.rgb * specularTint.a * specularLight * lerp(1, albedo.rgb, specularMixAlbedoIntoTint);
+}
+
+inline float3 toonAnisoSpecular(float specWhatTangent, float anisoUseTangentMap, float3 lightDirection, float halfDir, float4 specularMap, float nDotL, fixed gradientStart, fixed gradientEnd, float4 specColor, float4 finalColor, fixed metallic, float jitter, float mirrored, float4 packedTangentMap)
+{
+ float3 tangentOrBinormal = specWhatTangent ? poiMesh.tangent: poiMesh.binormal;
+
+ float3 normalLocalAniso = lerp(float3(0, 0, 1), UnpackNormal(packedTangentMap), anisoUseTangentMap);
+ normalLocalAniso = BlendNormals(normalLocalAniso, poiMesh.tangentSpaceNormal);
+ //float3 normalDirection = normalize(mul(poiMesh.normals[_SpecularNormal], poiTData.tangentTransform));
+ float3 normalDirectionAniso = Unity_SafeNormalize(mul(normalLocalAniso, poiTData.tangentTransform));
+ float3 tangentDirection = mul(poiTData.tangentTransform, tangentOrBinormal).xyz;
+ float3 viewReflectDirectionAniso = reflect(-poiCam.viewDir, normalDirectionAniso); // possible bad negation
+ float3 tangentDirectionMap = mul(poiTData.tangentToWorld, float3(normalLocalAniso.rg, 0.0)).xyz;
+ tangentDirectionMap = normalize(lerp(tangentOrBinormal, tangentDirectionMap, anisoUseTangentMap));
+
+ if (!mirrored)
+ {
+ tangentDirectionMap += jitter;
+ }
+
+ float TdotL = dot(lightDirection, tangentDirectionMap);
+ float TdotV = dot(poiCam.viewDir, tangentDirectionMap);
+ float TdotH = dot(halfDir, tangentDirectionMap);
+
+ float specular = saturate(sqrt(1.0 - (TdotL * TdotL)) * sqrt(1.0 - (TdotV * TdotV)) - TdotL * TdotV);
+
+ fixed smoothAlpha = specular;
+ if (mirrored)
+ {
+ smoothAlpha = max(specular - jitter, 0);
+ }
+
+ specular = smoothstep(gradientStart, gradientEnd, smoothAlpha);
+
+ /*
+ UNITY_BRANCH
+ if(_CenterOutSpecColor)
+ {
+ specularMap = POI2D_SAMPLER_PAN(_SpecularMap, _MainTex, clamp(float2(specular, specular), 0.01, .99), _SpecularMapPan);
+ }
+ */
+
+ #ifdef FORWARD_ADD_PASS
+ nDotL *= poiLight.attenuation * poiLight.additiveShadow;
+ #endif
+
+ return saturate(nDotL) * specular * poiLight.color * specColor * specularMap.rgb * lerp(1, finalColor, metallic) * specularMap.a;
+}
+
+inline float SpecularHQ(half roughness, half dotNH, half dotLH)
+{
+ roughness = saturate(roughness);
+ roughness = max((roughness * roughness), 0.002);
+ half roughnessX2 = roughness * roughness;
+
+ half denom = dotNH * dotNH * (roughnessX2 - 1.0) + 1.0f;
+ half D = roughnessX2 / (3.14159 * denom * denom);
+
+ half k = roughness / 2.0f;
+ half k2 = k * k;
+ half invK2 = 1.0f - k2;
+
+ half vis = rcp(dotLH * dotLH * invK2 + k2);
+
+ float specTerm = vis * D;
+
+ return specTerm;
+}
+
+float3 calculateNewSpecular(in float3 specularMap, uint colorFrom, in float4 albedo, in float3 specularTint, in float specularMetallic, in float specularSmoothness, in half dotNH, in half dotLH, in float3 lightColor, in float attenuation)
+{
+ float3 specColor = specularTint;
+ float metallic = specularMetallic;
+ float roughness = 1 - specularSmoothness;
+ float perceptualRoughness = roughness;
+ //float reflectInverse = DielectricSpec.a - metallic * DielectricSpec.a;
+ //float reflectivity = 1.0h - reflectInverse;
+ float3 specMapColor = lerp(specularMap, 1, colorFrom);
+ float3 specularColor = lerp(DielectricSpec.rgb * specMapColor, lerp(specularMap, albedo.rgb, colorFrom), metallic);
+ //albedo.rgb *= reflectInverse;
+ return clamp(specularColor * lightColor * attenuation * specularTint * SpecularHQ(perceptualRoughness, dotNH, dotLH), 0, lightColor * specularTint);
+}
+
+float3 calculateSpecular(in float4 albedo)
+{
+ half3 finalSpecular = 0;
+ half3 finalSpecular1 = 0;
+ float4 realisticAlbedo = albedo;
+ float4 realisticAlbedo1 = albedo;
+ float4 specularMap = POI2D_SAMPLER_PAN(_SpecularMap, _MainTex, poiMesh.uv[_SpecularMapUV], _SpecularMapPan);
+ half metallic = POI2D_SAMPLER_PAN(_SpecularMetallicMap, _MainTex, poiMesh.uv[_SpecularMetallicMapUV], _SpecularMetallicMapPan).r * _SpecularMetallic;
+ half specularMask = POI2D_SAMPLER_PAN(_SpecularMask, _MainTex, poiMesh.uv[_SpecularMaskUV], _SpecularMaskPan).r;
+ float attenuation = saturate(poiLight.nDotL);
+
+ float3 specularLightColor = poiLight.color;
+ UNITY_BRANCH
+ if (_SpecularMaxBrightness)
+ {
+ specularLightColor = clamp(poiLight.color, 0, _SpecularMaxBrightness);
+ }
+
+ #ifdef FORWARD_ADD_PASS
+ attenuation *= poiLight.attenuation * poiLight.additiveShadow;
+ #endif
+
+ #ifdef POI_LIGHTING
+ UNITY_BRANCH
+ if (_LightingMode == 0 && _LightingRampType == 1)
+ {
+ attenuation = poiLight.rampedLightMap;
+ }
+ #endif
+
+ UNITY_BRANCH
+ if (_SpecularType == 1) // Realistic
+
+ {
+ if (_SmoothnessFrom == 1)
+ {
+ specularMap.a = specularMap.r;
+ specularMap.rgb = 1;
+ }
+
+ if (_SpecularInvertSmoothness)
+ {
+ specularMap.a = 1 - specularMap.a;
+ }
+
+ finalSpecular += calculateNewSpecular(specularMap.rgb, _SmoothnessFrom, realisticAlbedo, _SpecularTint, metallic, _SpecularSmoothness * specularMap.a, poiLight.dotNH, poiLight.dotLH, specularLightColor, attenuation);
+ }
+
+ UNITY_BRANCH
+ if (_SpecularType == 4)
+ {
+ float jitter = 0;
+ float microJitter = POI2D_SAMPLER_PAN(_SpecularAnisoJitterMicro, _MainTex, float2(poiMesh.uv[_SpecularAnisoJitterMicroUV]), _SpecularAnisoJitterMicroPan).r;
+ fixed jitterOffset = (1 - _SpecularAnisoJitterMirrored) * .5;
+ jitter += (POI2D_SAMPLER_PAN(_SpecularAnisoJitterMicro, _MainTex, float2(poiMesh.uv[_SpecularAnisoJitterMicroUV]), _SpecularAnisoJitterMicroPan).r - jitterOffset) * _SpecularAnisoJitterMicroMultiplier;
+ jitter += (POI2D_SAMPLER_PAN(_SpecularAnisoJitterMacro, _MainTex, float2(poiMesh.uv[_SpecularAnisoJitterMacroUV]), _SpecularAnisoJitterMacroPan).r - jitterOffset) * _SpecularAnisoJitterMacroMultiplier;
+ jitter += _Spec1Offset;
+
+ float4 packedTangentMap = POI2D_SAMPLER_PAN(_AnisoTangentMap, _MainTex, poiMesh.uv[_AnisoTangentMapUV], _AnisoTangentMapPan);
+
+ finalSpecular += toonAnisoSpecular(_SpecWhatTangent, _AnisoUseTangentMap, poiLight.direction, poiLight.halfDir, specularMap, poiLight.nDotL, _SpecularToonStart, _SpecularToonEnd, _SpecularTint, albedo, metallic, jitter, _SpecularAnisoJitterMirrored, packedTangentMap);
+ finalSpecular *= attenuation;
+ }
+
+ #ifdef FORWARD_BASE_PASS
+ UNITY_BRANCH
+ if (_SpecularType == 2) // Toon
+
+ {
+ finalSpecular += calculateToonSpecular(albedo, poiMesh.uv[0], _SpecularToonInnerOuter, metallic, _SmoothnessFrom, specularMap, specularLightColor, poiMesh.normals[_SpecularNormal], poiLight.halfDir, poiLight.attenuation);
+ finalSpecular *= _SpecularTint;
+ }
+ UNITY_BRANCH
+ if (_SpecularType == 3) // anisotropic
+
+ {
+ float jitter = 0;
+ float microJitter = POI2D_SAMPLER_PAN(_SpecularAnisoJitterMicro, _MainTex, float2(poiMesh.uv[_SpecularAnisoJitterMicroUV]), _SpecularAnisoJitterMicroPan).r;
+ fixed jitterOffset = (1 - _SpecularAnisoJitterMirrored) * .5;
+ jitter += (POI2D_SAMPLER_PAN(_SpecularAnisoJitterMicro, _MainTex, float2(poiMesh.uv[_SpecularAnisoJitterMicroUV]), _SpecularAnisoJitterMicroPan).r - jitterOffset) * _SpecularAnisoJitterMicroMultiplier;
+ jitter += (POI2D_SAMPLER_PAN(_SpecularAnisoJitterMacro, _MainTex, float2(poiMesh.uv[_SpecularAnisoJitterMacroUV]), _SpecularAnisoJitterMacroPan).r - jitterOffset) * _SpecularAnisoJitterMacroMultiplier;
+ jitter += _Spec1Offset;
+
+ float4 packedTangentMap = POI2D_SAMPLER_PAN(_AnisoTangentMap, _MainTex, poiMesh.uv[_AnisoTangentMapUV], _AnisoTangentMapPan);
+
+ finalSpecular += AnisotropicSpecular(_SpecWhatTangent, _AnisoUseTangentMap, _SpecularSmoothness, _Spec2Smoothness, _AnisoSpec1Alpha, _AnisoSpec2Alpha, _SpecularTint, metallic, specularMap, specularLightColor, poiLight.direction, poiLight.halfDir, poiLight.nDotL, jitter, packedTangentMap, albedo);
+ finalSpecular *= _SpecularTint;
+ finalSpecular *= attenuation;
+ }
+ #endif
+
+ #ifdef VERTEXLIGHT_ON
+ // Non Important Lights
+ for (int index = 0; index < 4; index++)
+ {
+ UNITY_BRANCH
+ if (_SpecularType == 1) // Realistic
+
+ {
+ finalSpecular += calculateNewSpecular(specularMap.rgb, _SmoothnessFrom, realisticAlbedo, _SpecularTint, metallic, _SpecularSmoothness * specularMap.a, poiLight.vDotNH[index], poiLight.vDotLH[index], poiLight.vColor[index], poiLight.vAttenuationDotNL[index]);
+ }
+ }
+ #endif
+
+ finalSpecular *= _SpecularTint.a;
+ finalSpecular = finalSpecular.rgb;
+ finalSpecular *= specularMask;
+
+ #ifdef DITHERING
+ UNITY_BRANCH
+ if (_SpecularMaxBrightness)
+ {
+ specularLightColor = clamp(poiLight.color, 0, _SpecularMaxBrightness1);
+ }
+ float4 specularMap1 = POI2D_SAMPLER_PAN(_SpecularMap1, _MainTex, poiMesh.uv[_SpecularMap1UV], _SpecularMap1Pan);
+ half specularMask1 = POI2D_SAMPLER_PAN(_SpecularMask1, _MainTex, poiMesh.uv[_SpecularMask1UV], _SpecularMask1Pan).r;
+ half metallic1 = POI2D_SAMPLER_PAN(_SpecularMetallicMap1, _MainTex, poiMesh.uv[_SpecularMetallicMap1UV], _SpecularMetallicMap1Pan).r * _SpecularMetallic1;
+ UNITY_BRANCH
+ if (_SpecularType1 == 1) // Realistic
+
+ {
+ UNITY_BRANCH
+ if (_SmoothnessFrom1 == 1)
+ {
+ specularMap1.a = specularMap1.r;
+ specularMap1.rgb = 1;
+ }
+ else
+ {
+ realisticAlbedo1.rgb = specularMap1.rgb;
+ }
+
+ UNITY_BRANCH
+ if (_SpecularInvertSmoothness1)
+ {
+ specularMap1.a = 1 - specularMap1.a;
+ }
+
+ finalSpecular1 = calculateNewSpecular(specularMap1.rgb, _SmoothnessFrom1, realisticAlbedo1, _SpecularTint1, metallic1, _SpecularSmoothness1 * specularMap1.a, poiLight.dotNH, poiLight.dotLH, specularLightColor, attenuation);
+ }
+
+ UNITY_BRANCH
+ if (_SpecularType1 == 4)
+ {
+ float jitter = 0;
+ float microJitter = POI2D_SAMPLER_PAN(_SpecularAnisoJitterMicro1, _MainTex, float2(poiMesh.uv[_SpecularAnisoJitterMicro1UV]), _SpecularAnisoJitterMicro1Pan).r;
+ fixed jitterOffset = (1 - _SpecularAnisoJitterMirrored1) * .5;
+ jitter += (POI2D_SAMPLER_PAN(_SpecularAnisoJitterMicro1, _MainTex, float2(poiMesh.uv[_SpecularAnisoJitterMicro1UV]), _SpecularAnisoJitterMicro1Pan).r - jitterOffset) * _SpecularAnisoJitterMicroMultiplier1;
+ jitter += (POI2D_SAMPLER_PAN(_SpecularAnisoJitterMacro1, _MainTex, float2(poiMesh.uv[_SpecularAnisoJitterMacro1UV]), _SpecularAnisoJitterMacro1Pan).r - jitterOffset) * _SpecularAnisoJitterMacroMultiplier1;
+ jitter += _Spec1Offset1;
+
+ float4 packedTangentMap = POI2D_SAMPLER_PAN(_AnisoTangentMap1, _MainTex, poiMesh.uv[_AnisoTangentMap1UV], _AnisoTangentMap1Pan);
+
+ finalSpecular1 += toonAnisoSpecular(_SpecWhatTangent1, _AnisoUseTangentMap1, poiLight.direction, poiLight.halfDir, specularMap1, poiLight.nDotL, _SpecularToonStart1, _SpecularToonEnd1, _SpecularTint1, albedo, metallic1, jitter, _SpecularAnisoJitterMirrored1, packedTangentMap);
+ finalSpecular1 *= poiLight.attenuation;
+ }
+
+ UNITY_BRANCH
+ if (_SpecularType1 == 2) // Toon
+
+ {
+ finalSpecular1 = calculateToonSpecular(albedo, poiMesh.uv[0], _SpecularToonInnerOuter1, metallic1, _SmoothnessFrom1, specularMap1, specularLightColor, poiMesh.normals[_SpecularNormal1], poiLight.halfDir, poiLight.attenuation);
+ finalSpecular1 *= _SpecularTint1;
+ }
+ UNITY_BRANCH
+ if (_SpecularType1 == 3) // anisotropic
+
+ {
+ float jitter = 0;
+ float microJitter = POI2D_SAMPLER_PAN(_SpecularAnisoJitterMicro1, _MainTex, float2(poiMesh.uv[_SpecularAnisoJitterMicro1UV]), _SpecularAnisoJitterMicro1Pan).r;
+ fixed jitterOffset = (1 - _SpecularAnisoJitterMirrored1) * .5;
+ jitter += (POI2D_SAMPLER_PAN(_SpecularAnisoJitterMicro1, _MainTex, float2(poiMesh.uv[_SpecularAnisoJitterMicro1UV]), _SpecularAnisoJitterMicro1Pan).r - jitterOffset) * _SpecularAnisoJitterMicroMultiplier1;
+ jitter += (POI2D_SAMPLER_PAN(_SpecularAnisoJitterMacro1, _MainTex, float2(poiMesh.uv[_SpecularAnisoJitterMacro1UV]), _SpecularAnisoJitterMacro1Pan).r - jitterOffset) * _SpecularAnisoJitterMacroMultiplier1;
+ jitter += _Spec1Offset1;
+
+ float4 packedTangentMap = POI2D_SAMPLER_PAN(_AnisoTangentMap1, _MainTex, poiMesh.uv[_AnisoTangentMap1UV], _AnisoTangentMap1Pan);
+
+ finalSpecular1 = AnisotropicSpecular(_SpecWhatTangent1, _AnisoUseTangentMap1, _SpecularSmoothness1, _Spec2Smoothness1, _AnisoSpec1Alpha1, _AnisoSpec2Alpha1, _SpecularTint1, metallic1, specularMap1, specularLightColor, poiLight.direction, poiLight.halfDir, poiLight.nDotL, jitter, packedTangentMap, albedo);
+ finalSpecular1 *= _SpecularTint1;
+ finalSpecular1 *= poiLight.attenuation;
+ }
+
+ #ifdef FORWARD_BASE_PASS
+ // Non Important Lights
+ #ifdef VERTEXLIGHT_ON
+ for (int index = 0; index < 4; index++)
+ {
+ UNITY_BRANCH
+ if (_SpecularType == 1) // Realistic
+
+ {
+ finalSpecular1 += calculateNewSpecular(specularMap1.rgb, _SmoothnessFrom1, realisticAlbedo1, _SpecularTint1, metallic1, _SpecularSmoothness1 * specularMap1.a, poiLight.vDotNH[index], poiLight.vDotLH[index], poiLight.vColor[index], poiLight.vAttenuationDotNL[index]);
+ }
+ }
+ #endif
+ #endif
+
+ finalSpecular1 *= _SpecularTint1.a;
+ finalSpecular1 = finalSpecular1.rgb;
+ finalSpecular1 *= specularMask1;
+
+ #endif
+
+ return finalSpecular + finalSpecular1;
+}
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiSpecular.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiSpecular.cginc.meta
new file mode 100644
index 00000000..99ab9d9b
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiSpecular.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: da46d1a0fb2f8cc48a64a10aabc5df20
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiSubsurfaceScattering.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiSubsurfaceScattering.cginc
new file mode 100644
index 00000000..5878059b
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiSubsurfaceScattering.cginc
@@ -0,0 +1,75 @@
+#ifndef SUBSURFACE
+ #define SUBSURFACE
+ /*
+ float _SSSThickness;
+ half4 _SSSColor;
+ float _SSSPointLightDirectionality;
+ float _SSSNormalOffset;
+ float _SSSStrength;
+ float _SSSExponent;
+ float _SSSNDotL;
+ float _SSSConstant;
+
+ #if defined(PROP_SSSTHICKNESSMAP) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_SSSThicknessMap);
+ #endif
+
+ half3 calculateSubsurfaceScattering(const float4 albedo)
+ {
+ #if defined(PROP_SSSTHICKNESSMAP) || !defined(OPTIMIZER_ENABLED)
+ float thicknessMap = 1 - POI2D_SAMPLER_PAN(_SSSThicknessMap, _MainTex, poiMesh.uv[_SSSThicknessMapUV], _SSSThicknessMapPan);
+ #else
+ float thicknessMap = 1;
+ #endif
+
+ half4 translucencyColor = _SSSColor;
+ float3 lightDir = poiLight.direction;
+
+ #ifdef FORWARD_BASE_PASS
+ half tLitDot = saturate(dot((poiLight.direction + poiMesh.normals[1] * _SSSNormalOffset), -poiCam.viewDir));
+ #else
+ float3 lightDirectional = normalize(_WorldSpaceLightPos0.xyz - poiCam.worldPos);
+ lightDir = normalize(lerp(poiLight.direction, lightDirectional, _SSSPointLightDirectionality));
+ half tLitDot = saturate(dot((poiLight.direction + poiMesh.normals[1] * _SSSNormalOffset), -poiCam.viewDir));
+ #endif
+
+ tLitDot = exp2(-_SSSExponent * (1 - tLitDot)) * _SSSStrength;
+ float NDotL = abs(dot(poiLight.direction, poiMesh.normals[1]));
+ tLitDot *= lerp(1, NDotL, _SSSNDotL);
+
+ half translucencyOcclusion = lerp(1, thicknessMap, _SSSThickness);
+ half translucencyAtten = (tLitDot + _SSSConstant * (NDotL + 0.1)) * translucencyOcclusion;
+
+ return translucencyAtten * albedo.rgb * translucencyColor.rgb * poiLight.lightMap * poiLight.color;
+ }
+ */
+
+ float _SSSThicknessMod;
+ float _SSSSCale;
+ float _SSSPower;
+ float _SSSDistortion;
+ float4 _SSSColor;
+ float _EnableSSS;
+
+ #if defined(PROP_SSSTHICKNESSMAP) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_SSSThicknessMap);
+ #endif
+
+ float3 calculateSubsurfaceScattering()
+ {
+ #if defined(PROP_SSSTHICKNESSMAP) || !defined(OPTIMIZER_ENABLED)
+ float SSS = 1 - POI2D_SAMPLER_PAN(_SSSThicknessMap, _MainTex, poiMesh.uv[_SSSThicknessMapUV], _SSSThicknessMapPan);
+ #else
+ float SSS = 1;
+ #endif
+ half3 vLTLight = poiLight.direction + poiMesh.normals[0] * _SSSDistortion;
+ half flTDot = pow(saturate(dot(poiCam.viewDir, -vLTLight)), _SSSPower) * _SSSSCale;
+ #ifdef FORWARD_BASE_PASS
+ half3 fLT = (flTDot) * saturate(SSS + - 1 * _SSSThicknessMod);
+ #else
+ half3 fLT = poiLight.attenuation * (flTDot) * saturate(SSS + - 1 * _SSSThicknessMod);
+ #endif
+
+ return fLT * poiLight.color * _SSSColor * poiLight.attenuation;
+ }
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiSubsurfaceScattering.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiSubsurfaceScattering.cginc.meta
new file mode 100644
index 00000000..f2f00eaf
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiSubsurfaceScattering.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: c86cb17bac1d3ae469535ac16b47fcf9
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiTessellation.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiTessellation.cginc
new file mode 100644
index 00000000..a35f940f
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiTessellation.cginc
@@ -0,0 +1,117 @@
+#ifndef POI_TESSELLATION
+ #define POI_TESSELLATION
+
+ float _TessellationPhongStrength;
+ float _TessellationEdgeLength;
+ float _TessellationExtrusionAmount;
+ float _TessellationUniform;
+
+ struct TessellationControlPoint
+ {
+ float4 vertex: INTERNALTESSPOS;
+ float3 normal: NORMAL;
+ float4 tangent: TANGENT;
+ float4 color: COLOR;
+ float2 uv0: TEXCOORD0;
+ float2 uv1: TEXCOORD1;
+ float2 uv2: TEXCOORD2;
+ float2 uv3: TEXCOORD3;
+ };
+
+ struct TessellationFactors
+ {
+ float edge[3]: SV_TessFactor;
+ float inside: SV_InsideTessFactor;
+ };
+
+ TessellationControlPoint poiTessellationVert(appdata v)
+ {
+ TessellationControlPoint p;
+ p.vertex = v.vertex;
+ p.normal = v.normal;
+ p.tangent = v.tangent;
+ p.color = v.color;
+ p.uv0 = v.uv0;
+ p.uv1 = v.uv1;
+ p.uv2 = v.uv2;
+ p.uv3 = v.uv3;
+ return p;
+ }
+
+ float TessellationEdgeFactor(float3 p0, float3 p1)
+ {
+ #ifndef _FADING_ON
+ float edgeLength = distance(p0, p1);
+
+ float3 edgeCenter = (p0 + p1) * 0.5;
+ float viewDistance = distance(edgeCenter, _WorldSpaceCameraPos);
+
+ return edgeLength * _ScreenParams.y /
+ (_TessellationEdgeLength * viewDistance);
+ #else
+ return _TessellationUniform;
+ #endif
+ }
+
+ TessellationFactors poiPatchConst(
+ InputPatch < TessellationControlPoint, 3 > patch
+ )
+ {
+
+ TessellationFactors f;
+ float3 p0 = mul(unity_ObjectToWorld, patch[0].vertex).xyz;
+ float3 p1 = mul(unity_ObjectToWorld, patch[1].vertex).xyz;
+ float3 p2 = mul(unity_ObjectToWorld, patch[2].vertex).xyz;
+ f.edge[0] = TessellationEdgeFactor(p1, p2);
+ f.edge[1] = TessellationEdgeFactor(p2, p0);
+ f.edge[2] = TessellationEdgeFactor(p0, p1);
+ f.inside = (TessellationEdgeFactor(p1, p2) +
+ TessellationEdgeFactor(p2, p0) +
+ TessellationEdgeFactor(p0, p1)) * (1 / 3.0);
+ return f;
+ }
+
+ [UNITY_domain("tri")]
+ [UNITY_outputcontrolpoints(3)]
+ [UNITY_outputtopology("triangle_cw")]
+ [UNITY_partitioning("fractional_odd")]
+ [UNITY_patchconstantfunc("poiPatchConst")]
+ TessellationControlPoint poiHull(
+ InputPatch < TessellationControlPoint, 3 > patch,
+ uint id: SV_OutputControlPointID
+ )
+ {
+ return patch[id];
+ }
+
+ [UNITY_domain("tri")]
+ v2f poiDomain(
+ TessellationFactors factors,
+ OutputPatch < TessellationControlPoint, 3 > patch,
+ float3 barycentricCoordinates: SV_DomainLocation
+ )
+ {
+ appdata data;
+
+ #define MY_DOMAIN_PROGRAM_INTERPOLATE(fieldName) data.fieldName = patch[0].fieldName * barycentricCoordinates.x + patch[1].fieldName * barycentricCoordinates.y + patch[2].fieldName * barycentricCoordinates.z;
+
+ MY_DOMAIN_PROGRAM_INTERPOLATE(vertex)
+ float3 pp[3];
+ for (int i = 0; i < 3; ++ i)
+ {
+ pp[i] = data.vertex.xyz - patch[i].normal * (dot(data.vertex.xyz, patch[i].normal) - dot(patch[i].vertex.xyz, patch[i].normal));
+ }
+ data.vertex.xyz = _TessellationPhongStrength * (pp[0] * barycentricCoordinates.x + pp[1] * barycentricCoordinates.y + pp[2] * barycentricCoordinates.z) + (1.0f - _TessellationPhongStrength) * data.vertex.xyz;
+ MY_DOMAIN_PROGRAM_INTERPOLATE(normal)
+ data.vertex.xyz += data.normal.xyz * _TessellationExtrusionAmount;
+ MY_DOMAIN_PROGRAM_INTERPOLATE(tangent)
+ MY_DOMAIN_PROGRAM_INTERPOLATE(color)
+ MY_DOMAIN_PROGRAM_INTERPOLATE(uv0)
+ MY_DOMAIN_PROGRAM_INTERPOLATE(uv1)
+ MY_DOMAIN_PROGRAM_INTERPOLATE(uv2)
+ MY_DOMAIN_PROGRAM_INTERPOLATE(uv3)
+
+ return vert(data);
+ }
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiTessellation.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiTessellation.cginc.meta
new file mode 100644
index 00000000..4ddeb912
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiTessellation.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: cb923a9217d969d40a045da0c480df7e
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiUVDistortion.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiUVDistortion.cginc
new file mode 100644
index 00000000..9a3d5455
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiUVDistortion.cginc
@@ -0,0 +1,74 @@
+#ifndef POI_UV_DISTORTION
+#define POI_UV_DISTORTION
+
+#if defined(PROP_DISTORTIONFLOWTEXTURE) || !defined(OPTIMIZER_ENABLED)
+ UNITY_DECLARE_TEX2D_NOSAMPLER(_DistortionFlowTexture); float4 _DistortionFlowTexture_ST;
+#endif
+#if defined(PROP_DISTORTIONFLOWTEXTURE1) || !defined(OPTIMIZER_ENABLED)
+ UNITY_DECLARE_TEX2D_NOSAMPLER(_DistortionFlowTexture1); float4 _DistortionFlowTexture1_ST;
+#endif
+#if defined(PROP_DISTORTIONMASK) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_DistortionMask);
+#endif
+
+half _DistortionStrength;
+half _DistortionStrength1;
+half2 _DistortionSpeed;
+half2 _DistortionSpeed1;
+
+#ifdef POI_AUDIOLINK
+ half _EnableDistortionAudioLink;
+ half2 _DistortionStrengthAudioLink;
+ half _DistortionStrengthAudioLinkBand;
+ half2 _DistortionStrength1AudioLink;
+ half _DistortionStrength1AudioLinkBand;
+
+#endif
+
+float2 getTorusUv(float2 uv)
+{
+ // translated to hlsl from https://www.shadertoy.com/view/Md3Bz7
+ // http://web.cs.ucdavis.edu/~amenta/s12/findnorm.pdf
+ float phi = 6.28318530718f * uv.x;
+ float theta = 6.28318530718f * uv.y;
+ float3 c = cos(float3(phi, phi + 1.57079632679f, theta));
+ float2 result = float2(c.x * c.z, -c.y * c.z);
+ return result * 0.5 + 0.5;
+}
+
+float2 calculateDistortionUV(float2 uv)
+{
+ #if defined(PROP_DISTORTIONFLOWTEXTURE) || !defined(OPTIMIZER_ENABLED)
+ float4 flowVector = UNITY_SAMPLE_TEX2D_SAMPLER(_DistortionFlowTexture, _MainTex, TRANSFORM_TEX(poiMesh.uv[0], _DistortionFlowTexture) + _Time.x * _DistortionSpeed) * 2 - 1;
+ #else
+ float4 flowVector = 0;
+ #endif
+ #if defined(PROP_DISTORTIONFLOWTEXTURE1) || !defined(OPTIMIZER_ENABLED)
+ float4 flowVector1 = UNITY_SAMPLE_TEX2D_SAMPLER(_DistortionFlowTexture1, _MainTex, TRANSFORM_TEX(poiMesh.uv[0], _DistortionFlowTexture1) + _Time.x * _DistortionSpeed1) * 2 - 1;
+ #else
+ float4 flowVector1 = 0;
+ #endif
+ #if defined(PROP_DISTORTIONMASK) || !defined(OPTIMIZER_ENABLED)
+ half distortionMask = POI2D_SAMPLER_PAN(_DistortionMask, _MainTex, poiMesh.uv[_DistortionMaskUV], _DistortionMaskPan).r;
+ #else
+ half distortionMask = 1;
+ #endif
+
+ half distortionStrength = _DistortionStrength;
+ half distortionStrength1 = _DistortionStrength1;
+
+ #ifdef POI_AUDIOLINK
+ UNITY_BRANCH
+ if (poiMods.audioLinkTextureExists && _EnableDistortionAudioLink)
+ {
+ distortionStrength += lerp(_DistortionStrengthAudioLink.x, _DistortionStrengthAudioLink.y, poiMods.audioLink[_DistortionStrengthAudioLinkBand]);
+ distortionStrength1 += lerp(_DistortionStrength1AudioLink.x, _DistortionStrength1AudioLink.y, poiMods.audioLink[_DistortionStrength1AudioLinkBand]);
+ }
+ #endif
+
+ flowVector *= distortionStrength;
+ flowVector1 *= distortionStrength1;
+ return uv + ((flowVector.xy + flowVector1.xy) / 2) * distortionMask;
+}
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiUVDistortion.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiUVDistortion.cginc.meta
new file mode 100644
index 00000000..e949dffd
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiUVDistortion.cginc.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: b781c7822eb79cd4d94941b850ec86fd
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiV2F.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiV2F.cginc
new file mode 100644
index 00000000..b4ab59ff
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiV2F.cginc
@@ -0,0 +1,35 @@
+#ifndef POI_V2F
+ #define POI_V2F
+
+ struct v2f
+ {
+ float4 pos: SV_POSITION;
+ float4 uv0: TEXCOORD0;
+ float4 uv1: TEXCOORD1;
+ float3 normal: TEXCOORD2;
+ float3 tangentViewDir: TEXCOORD3;
+ float4 tangent: TEXCOORD4;
+ float4 binormal: TEXCOORD5;
+ float4 worldPos: TEXCOORD6;
+ float4 localPos: TEXCOORD7;
+ float4 grabPos: TEXCOORD8;
+ float3 barycentricCoordinates: TEXCOORD9;
+ #if defined(GRAIN)
+ float4 worldDirection: TEXCOORD10;
+ #endif
+ #if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)
+ float4 lightmapUV: TEXCOORD11;
+ #endif
+ float3 modelPos: TEXCOORD12;
+ float angleAlpha: TEXCOORD13;
+ float4 vertexColor: TEXCOORD14;
+ #ifdef FUR
+ float furAlpha: TEXCOORD15;
+ #endif
+ UNITY_SHADOW_COORDS(16)
+ UNITY_FOG_COORDS(17)
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+ UNITY_VERTEX_OUTPUT_STEREO
+ };
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiV2F.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiV2F.cginc.meta
new file mode 100644
index 00000000..b99520d2
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiV2F.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: ef2c28e0e6cae3d49989341119faa165
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiVert.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiVert.cginc
new file mode 100644
index 00000000..63cde28b
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiVert.cginc
@@ -0,0 +1,145 @@
+#ifndef POI_VERT
+#define POI_VERT
+
+float _VertexManipulationHeightUV;
+float _VertexUnwrap;
+
+#define PM UNITY_MATRIX_P
+
+inline float4 CalculateFrustumCorrection()
+{
+ float x1 = -PM._31 / (PM._11 * PM._34);
+ float x2 = -PM._32 / (PM._22 * PM._34);
+ return float4(x1, x2, 0, PM._33 / PM._34 + x1 * PM._13 + x2 * PM._23);
+}
+
+float3 CreateBinormal(half3 normal, half3 tangent, half tangentSign)
+{
+ half sign = tangentSign * unity_WorldTransformParams.w;
+ return cross(normal, tangent) * sign;
+}
+
+v2f vert(appdata v)
+{
+ UNITY_SETUP_INSTANCE_ID(v);
+ v2f o;
+
+ #ifdef _COLOROVERLAY_ON
+ v.vertex.xyz = lerp(v.vertex.xyz, float3(v.uv0.x - .5, v.uv0.y - .5, 0), _VertexUnwrap);
+ #endif
+
+ #ifdef RALIV_PENETRATION
+ applyRalivDynamicOrifaceSystem(v);
+ #endif
+
+ #ifdef AUTO_EXPOSURE
+ applyLocalVertexTransformation(v.normal, v.tangent, v.vertex);
+ #endif
+
+
+ UNITY_INITIALIZE_OUTPUT(v2f, o);
+ UNITY_TRANSFER_INSTANCE_ID(v, o);
+ UNITY_INITIALIZE_VERTEX_OUTPUT_STEREO(o);
+
+
+ #ifdef _REQUIRE_UV2 //POI_MIRROR
+ applyMirrorRenderVert(v.vertex);
+ #endif
+
+ TANGENT_SPACE_ROTATION;
+ o.localPos = v.vertex;
+ o.worldPos = mul(unity_ObjectToWorld, o.localPos);
+ o.normal = UnityObjectToWorldNormal(v.normal);
+
+ #ifdef RALIV_PENETRATION
+ applyRalivDynamicPenetrationSystem(o.localPos.rgb, o.normal.rgb, v);
+ #endif
+
+ //o.localPos.x *= -1;
+ //o.localPos.xz += sin(o.localPos.y * 100 + _Time.y * 5) * .0025;
+
+ float2 uvToUse = 0;
+ UNITY_BRANCH
+ if (_VertexManipulationHeightUV == 0)
+ {
+ uvToUse = v.uv0.xy;
+ }
+ UNITY_BRANCH
+ if (_VertexManipulationHeightUV == 1)
+ {
+ uvToUse = v.uv1.xy;
+ }
+ UNITY_BRANCH
+ if (_VertexManipulationHeightUV == 2)
+ {
+ uvToUse = v.uv2.xy;
+ }
+ UNITY_BRANCH
+ if (_VertexManipulationHeightUV == 3)
+ {
+ uvToUse = v.uv3.xy;
+ }
+ #ifdef AUTO_EXPOSURE
+ applyWorldVertexTransformation(o.worldPos, o.localPos, o.normal, uvToUse);
+ #endif
+ applyVertexGlitching(o.worldPos, o.localPos);
+ applySpawnInVert(o.worldPos, o.localPos, v.uv0.xy);
+ #ifdef AUTO_EXPOSURE
+ applyVertexRounding(o.worldPos, o.localPos);
+ #endif
+ o.pos = UnityObjectToClipPos(o.localPos);
+ o.grabPos = ComputeGrabScreenPos(o.pos);
+ o.uv0.xy = v.uv0.xy;
+ o.uv0.zw = v.uv1.xy;
+ o.uv1.xy = v.uv2.xy;
+ o.uv1.zw = v.uv3.xy;
+ o.vertexColor = v.color;
+ o.modelPos = mul(unity_ObjectToWorld, float4(0, 0, 0, 1)).xyz;
+ o.tangent = float4(UnityObjectToWorldDir(v.tangent.xyz), v.tangent.w);
+
+ o.binormal.rgb = CreateBinormal(o.normal.xyz, o.tangent.xyz, o.tangent.w);
+
+ #ifdef POI_BULGE
+ bulgyWolgy(o);
+ #endif
+
+
+ o.angleAlpha = 1;
+ #ifdef _SUNDISK_NONE //POI_RANDOM
+ o.angleAlpha = ApplyAngleBasedRendering(o.modelPos, o.worldPos);
+ #endif
+
+ #if defined(LIGHTMAP_ON)
+ o.lightmapUV.xy = v.uv1.xy * unity_LightmapST.xy + unity_LightmapST.zw;
+ #endif
+ #ifdef DYNAMICLIGHTMAP_ON
+ o.lightmapUV.zw = v.uv2.xy * unity_DynamicLightmapST.xy + unity_DynamicLightmapST.zw;
+ #endif
+
+ UNITY_TRANSFER_SHADOW(o, o.uv0.xy);
+ UNITY_TRANSFER_FOG(o, o.pos);
+
+ v.tangent.xyz = normalize(v.tangent.xyz);
+ v.normal = normalize(v.normal);
+ float3x3 objectToTangent = float3x3(
+ v.tangent.xyz,
+ cross(v.normal, v.tangent.xyz) * v.tangent.w,
+ v.normal
+ );
+ o.tangentViewDir = mul(objectToTangent, ObjSpaceViewDir(v.vertex));
+
+ #ifdef POI_META_PASS
+ o.pos = UnityMetaVertexPosition(v.vertex, v.uv1.xy, v.uv2.xy, unity_LightmapST, unity_DynamicLightmapST);
+ #endif
+
+ #if defined(GRAIN)
+ float4 worldDirection;
+
+ worldDirection.xyz = o.worldPos.xyz - _WorldSpaceCameraPos;
+ worldDirection.w = dot(o.pos, CalculateFrustumCorrection());
+ o.worldDirection = worldDirection;
+ #endif
+
+ return o;
+}
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiVert.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiVert.cginc.meta
new file mode 100644
index 00000000..200d2fcc
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiVert.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: c608d4e6f9b40dc4a854fca20604e6b6
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiVertexManipulations.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiVertexManipulations.cginc
new file mode 100644
index 00000000..cf586808
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiVertexManipulations.cginc
@@ -0,0 +1,102 @@
+#ifndef POI_VERTEX_MANIPULATION
+ #define POI_VERTEX_MANIPULATION
+
+ #include "CGI_PoiMath.cginc"
+
+ float4 _VertexManipulationLocalTranslation;
+ float4 _VertexManipulationLocalRotation;
+ float4 _VertexManipulationLocalScale;
+ float4 _VertexManipulationWorldTranslation;
+
+ float _VertexManipulationHeight;
+ float _VertexManipulationHeightBias;
+ #if defined(PROP_VERTEXMANIPULATIONHEIGHTMASK) || !defined(OPTIMIZER_ENABLED)
+ sampler2D _VertexManipulationHeightMask; float4 _VertexManipulationHeightMask_ST;
+ #endif
+ float2 _VertexManipulationHeightPan;
+
+
+ //Vertex Glitching
+ float _EnableVertexGlitch;
+ float _VertexGlitchThreshold;
+ float _VertexGlitchFrequency;
+ float _VertexGlitchStrength;
+ // Rounding
+ float _VertexRoundingDivision;
+ float _VertexRoundingEnabled;
+
+ void applyLocalVertexTransformation(inout float3 normal, inout float4 tangent, inout float4 vertex)
+ {
+ normal = rotate_with_quaternion(normal, _VertexManipulationLocalRotation.xyz);
+ tangent.xyz = rotate_with_quaternion(tangent.xyz, _VertexManipulationLocalRotation.xyz);
+ vertex = transform(vertex, _VertexManipulationLocalTranslation, _VertexManipulationLocalRotation, _VertexManipulationLocalScale);
+
+ //vertex = float4(vertex.x + sin(_Time.y*1.5 + vertex.y * 50) * .75 * smoothstep( .3, -1, vertex.y), vertex.y, vertex.z + cos(_Time.y*1.5 + vertex.y * 50) * .75 * smoothstep( .3, -1, vertex.y), 1);
+ }
+
+ void applyLocalVertexTransformation(inout float3 normal, inout float4 vertex)
+ {
+ normal = rotate_with_quaternion(normal, _VertexManipulationLocalRotation.xyz);
+ vertex = transform(vertex, _VertexManipulationLocalTranslation, _VertexManipulationLocalRotation, _VertexManipulationLocalScale);
+
+ //vertex = float4(vertex.x + sin(_Time.y*1.5 + vertex.y * 50) * .75 * smoothstep( .3, -1, vertex.y), vertex.y, vertex.z + cos(_Time.y*1.5 + vertex.y * 50) * .75 * smoothstep( .3, -1, vertex.y), 1);
+ }
+
+ void applyWorldVertexTransformation(inout float4 worldPos, inout float4 localPos, inout float3 worldNormal, float2 uv)
+ {
+ #if defined(PROP_VERTEXMANIPULATIONHEIGHTMASK) || !defined(OPTIMIZER_ENABLED)
+ float3 heightOffset = (tex2Dlod(_VertexManipulationHeightMask, float4(TRANSFORM_TEX(uv, _VertexManipulationHeightMask) + _VertexManipulationHeightPan * _Time.x, 0, 0)).r - _VertexManipulationHeightBias) * _VertexManipulationHeight * worldNormal;
+ #else
+ float3 heightOffset = _VertexManipulationHeight * worldNormal;
+ #endif
+ worldPos.rgb += _VertexManipulationWorldTranslation.xyz/* * _VertexManipulationWorldTranslation.w*/ + heightOffset;
+ localPos.xyz = mul(unity_WorldToObject, worldPos).xyz;
+ }
+
+ void applyWorldVertexTransformationShadow(inout float4 worldPos, inout float4 localPos, float3 worldNormal, float2 uv)
+ {
+ #if defined(PROP_VERTEXMANIPULATIONHEIGHTMASK) || !defined(OPTIMIZER_ENABLED)
+ float3 heightOffset = (tex2Dlod(_VertexManipulationHeightMask, float4(TRANSFORM_TEX(uv, _VertexManipulationHeightMask) + _VertexManipulationHeightPan * _Time.x, 0, 0)).r - _VertexManipulationHeightBias) * _VertexManipulationHeight * worldNormal;
+ #else
+ float3 heightOffset = _VertexManipulationHeight * worldNormal;
+ #endif
+ worldPos.rgb += _VertexManipulationWorldTranslation.xyz/* * _VertexManipulationWorldTranslation.w*/ + heightOffset;
+ localPos.xyz = mul(unity_WorldToObject, worldPos).xyz;
+ }
+
+ void applyVertexRounding(inout float4 worldPos, inout float4 localPos)
+ {
+ UNITY_BRANCH
+ if (_VertexRoundingEnabled)
+ {
+ worldPos.xyz = (ceil(worldPos.xyz * _VertexRoundingDivision) / _VertexRoundingDivision) - 1 / _VertexRoundingDivision * .5;
+ localPos = mul(unity_WorldToObject, worldPos);
+ }
+ }
+
+ void applyVertexGlitching(inout float4 worldPos, inout float4 localPos)
+ {
+ UNITY_BRANCH
+ if(_EnableVertexGlitch)
+ {
+ float3 forward = getCameraPosition() - mul(unity_ObjectToWorld, float4(0, 0, 0, 1)).xyz;
+ forward.y = 0;
+ forward = normalize(forward);
+ float3 glitchDirection = normalize(cross(float3(0, 1, 0), forward));
+ float glitchAmount = frac(sin(dot(_Time.xy + worldPos.y, float2(12.9898, 78.233))) * 43758.5453123) * 2 - 1;
+ /*
+ float uvl = worldPos.y * _VertexGlitchDensity + _Time.x * _VertexGlitchMapPanSpeed;
+ float uvr = worldPos.y * _VertexGlitchDensity - _Time.x * _VertexGlitchMapPanSpeed;
+ float glitchAmountLeft = tex2Dlod(_VertexGlitchMap, float4(uvl, uvl, 0, 0)).r;
+ float glitchAmountRight = -tex2Dlod(_VertexGlitchMap, float4(uvr, uvr, 0, 0)).r;
+ float glitchAmount = glitchAmountLeft + glitchAmountRight;
+ */
+ float time = _Time.y * _VertexGlitchFrequency;
+ float randomGlitch = (sin(time) + sin(2.2 * time + 5.52) + sin(2.9 * time + 0.93) + sin(4.6 * time + 8.94)) / 4;
+ worldPos.xyz += glitchAmount * glitchDirection * (_VertexGlitchStrength * .01) * step(_VertexGlitchThreshold, randomGlitch);
+ localPos = mul(unity_WorldToObject, worldPos);
+ }
+ }
+
+#endif
+// \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiVertexManipulations.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiVertexManipulations.cginc.meta
new file mode 100644
index 00000000..b0ae7b8d
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiVertexManipulations.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: 8f221171da2883d41ab5a08dd1de9779
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiVideo.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiVideo.cginc
new file mode 100644
index 00000000..2e4625e1
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiVideo.cginc
@@ -0,0 +1,297 @@
+#ifndef POI_VIDEO
+ #define POI_VIDEO
+
+ #if defined(PROP_VIDEOPIXELTEXTURE) || !defined(OPTIMIZER_ENABLED)
+ UNITY_DECLARE_TEX2D_NOSAMPLER(_VideoPixelTexture); float4 _VideoPixelTexture_ST;
+ #endif
+ #if defined(PROP_VIDEOMASKTEXTURE) || !defined(OPTIMIZER_ENABLED)
+ UNITY_DECLARE_TEX2D_NOSAMPLER(_VideoMaskTexture); float4 _VideoMaskTexture_ST;
+ #endif
+ #if defined(PROP_VIDEOGAMEBOYRAMP) || !defined(OPTIMIZER_ENABLED)
+ sampler2D _VideoGameboyRamp;
+ #endif
+ #if defined(PROP_VIDEODEBUGTEXTURE) || !defined(OPTIMIZER_ENABLED)
+ UNITY_DECLARE_TEX2D_NOSAMPLER(_VideoDebugTexture); float4 _VideoDebugTexture_ST;
+ #endif
+
+ float _VideoUVNumber;
+ float _VideoType;
+ float3 pixels;
+ float2 _VideoResolution;
+ half _VideoBacklight;
+ half _VideoCRTRefreshRate;
+ half _VideoCRTPixelEnergizedTime;
+ half _VideoEnableVideoPlayer;
+ half _VideoRepeatVideoTexture;
+ half _VideoPixelateToResolution;
+ float2 _VideoMaskPanning;
+ float _VideoEmissionEnabled;
+ // Video Settings
+ half _VideoSaturation;
+ half _VideoContrast;
+ float2 _VideoTiling;
+ float2 _VideoOffset;
+ float2 _VideoPanning;
+
+ //Debug
+ half _VideoEnableDebug;
+
+
+
+ sampler2D _VRChat_VideoPlayer;
+ float4 _VRChat_VideoPlayer_TexelSize;
+
+ float4 globalVideoPlayerColor;
+ float3 globalColorToDisplayOnScreen;
+ float globalVideoOn;
+
+ float3 applyBacklight(float3 albedo, half backlightStrength)
+ {
+ return max(backlightStrength, albedo.rgb);
+ }
+
+ float3 applyViewAngleTN(float3 albedo)
+ {
+ float3 reflectionVector = normalize(reflect(poiCam.viewDir.rgb, poiMesh.normals[1].rgb));
+ float upwardShift = dot(reflectionVector, poiMesh.binormal);
+ upwardShift = pow(upwardShift, 1);
+ float sideShift = dot(reflectionVector, poiMesh.tangent);
+ sideShift *= pow(sideShift, 3);
+ #if !UNITY_COLORSPACE_GAMMA
+ albedo = LinearToGammaSpace(albedo);
+ #endif
+ albedo = saturate(lerp(half3(0.5, 0.5, 0.5), albedo, upwardShift + 1));
+ #if !UNITY_COLORSPACE_GAMMA
+ albedo = GammaToLinearSpace(albedo);
+ #endif
+ albedo = (lerp(albedo, albedo.gbr, sideShift));
+ return albedo;
+ }
+
+ float calculateCRTPixelBrightness()
+ {
+ float totalPixels = _VideoResolution.x * _VideoResolution.y;
+ float2 uvPixel = float2((floor((1 - poiMesh.uv[_VideoUVNumber].y) * _VideoResolution.y)) / _VideoResolution.y, (floor(poiMesh.uv[_VideoUVNumber].x * _VideoResolution.x)) / _VideoResolution.x);
+ float currentPixelNumber = _VideoResolution.x * (_VideoResolution.y * uvPixel.x) + _VideoResolution.y * uvPixel.y;
+ float currentPixelAlpha = currentPixelNumber / totalPixels;
+ half electronBeamAlpha = frac(_Time.y * _VideoCRTRefreshRate);
+ float electronBeamPixelNumber = totalPixels * electronBeamAlpha;
+
+ float DistanceInPixelsFromCurrentElectronBeamPixel = 0;
+ if (electronBeamPixelNumber >= currentPixelNumber)
+ {
+ DistanceInPixelsFromCurrentElectronBeamPixel = electronBeamPixelNumber - currentPixelNumber;
+ }
+ else
+ {
+ DistanceInPixelsFromCurrentElectronBeamPixel = electronBeamPixelNumber + (totalPixels - currentPixelNumber);
+ }
+ float CRTFrameTime = 1 / _VideoCRTRefreshRate;
+ float timeSincecurrentPixelWasHitByElectronBeam = (DistanceInPixelsFromCurrentElectronBeamPixel / totalPixels);
+
+ return saturate(_VideoCRTPixelEnergizedTime - timeSincecurrentPixelWasHitByElectronBeam);
+ }
+
+ void applyContrastSettings(inout float3 pixel)
+ {
+ #if !UNITY_COLORSPACE_GAMMA
+ pixel = LinearToGammaSpace(pixel);
+ #endif
+ pixel = saturate(lerp(half3(0.5, 0.5, 0.5), pixel, _VideoContrast + 1));
+ #if !UNITY_COLORSPACE_GAMMA
+ pixel = GammaToLinearSpace(pixel);
+ #endif
+ }
+
+ void applySaturationSettings(inout float3 pixel)
+ {
+ pixel = lerp(pixel.rgb, dot(pixel.rgb, float3(0.3, 0.59, 0.11)), -_VideoSaturation);
+ }
+
+ void applyVideoSettings(inout float3 pixel)
+ {
+ applySaturationSettings(pixel);
+ applyContrastSettings(pixel);
+ }
+
+ void calculateLCD(inout float4 albedo)
+ {
+ UNITY_BRANCH
+ if(_VideoEnableVideoPlayer == 0)
+ {
+ globalColorToDisplayOnScreen = albedo;
+ }
+ globalColorToDisplayOnScreen = applyBacklight(globalColorToDisplayOnScreen, _VideoBacklight * .01);
+ applyVideoSettings(globalColorToDisplayOnScreen);
+ albedo.rgb = globalColorToDisplayOnScreen * pixels * _VideoBacklight + albedo * .000001;
+ }
+ void calculateTN(inout float4 albedo)
+ {
+ if(_VideoEnableVideoPlayer == 0)
+ {
+ globalColorToDisplayOnScreen = albedo;
+ }
+ globalColorToDisplayOnScreen = applyBacklight(globalColorToDisplayOnScreen, _VideoBacklight * .01);
+ globalColorToDisplayOnScreen = applyViewAngleTN(globalColorToDisplayOnScreen);
+ applyVideoSettings(globalColorToDisplayOnScreen);
+ albedo.rgb = globalColorToDisplayOnScreen * pixels * _VideoBacklight + albedo * .000001;
+ }
+ void calculateCRT(inout float4 albedo)
+ {
+ UNITY_BRANCH
+ if(_VideoEnableVideoPlayer == 0)
+ {
+ globalColorToDisplayOnScreen = albedo;
+ }
+ float brightness = calculateCRTPixelBrightness();
+ applyVideoSettings(globalColorToDisplayOnScreen);
+ albedo.rgb = globalColorToDisplayOnScreen * pixels * brightness * _VideoBacklight + albedo * .000001;
+ }
+ void calculateOLED(inout float4 albedo)
+ {
+ UNITY_BRANCH
+ if(_VideoEnableVideoPlayer == 0)
+ {
+ globalColorToDisplayOnScreen = albedo;
+ }
+ applyVideoSettings(globalColorToDisplayOnScreen);
+ albedo.rgb = globalColorToDisplayOnScreen * pixels * _VideoBacklight + albedo * .000001;
+ }
+ void calculateGameboy(inout float4 albedo)
+ {
+ UNITY_BRANCH
+ if(_VideoEnableVideoPlayer == 0)
+ {
+ globalColorToDisplayOnScreen = albedo;
+ }
+ applyVideoSettings(globalColorToDisplayOnScreen);
+ half brightness = saturate((globalColorToDisplayOnScreen.r + globalColorToDisplayOnScreen.g + globalColorToDisplayOnScreen.b) * .3333333);
+ #if defined(PROP_VIDEOGAMEBOYRAMP) || !defined(OPTIMIZER_ENABLED)
+ albedo.rgb = tex2D(_VideoGameboyRamp, brightness);
+ #endif
+ }
+ void calculateProjector(inout float4 albedo)
+ {
+ UNITY_BRANCH
+ if(_VideoEnableVideoPlayer == 0)
+ {
+ globalColorToDisplayOnScreen = albedo;
+ }
+ applyVideoSettings(globalColorToDisplayOnScreen);
+
+ float3 projectorColor = albedo * globalColorToDisplayOnScreen * _VideoBacklight;
+ albedo.r = clamp(projectorColor.r, albedo.r, 1000);
+ albedo.g = clamp(projectorColor.g, albedo.g, 1000);
+ albedo.b = clamp(projectorColor.b, albedo.b, 1000);
+ }
+
+ void applyScreenEffect(inout float4 albedo, inout float3 videoEmission)
+ {
+ float4 albedoBeforeScreen = albedo;
+ #if defined(PROP_VIDEOPIXELTEXTURE) || !defined(OPTIMIZER_ENABLED)
+ pixels = UNITY_SAMPLE_TEX2D_SAMPLER(_VideoPixelTexture, _MainTex, TRANSFORM_TEX(poiMesh.uv[_VideoUVNumber], _VideoPixelTexture) * _VideoResolution);
+ #else
+ pixels = 1;
+ #endif
+ globalVideoOn = 0;
+ UNITY_BRANCH
+ if(_VideoEnableVideoPlayer == 1)
+ {
+ float4 videoTexture = 0;
+ UNITY_BRANCH
+ if(_VideoPixelateToResolution)
+ {
+ UNITY_BRANCH
+ if(_VideoEnableDebug)
+ {
+ #if defined(PROP_VIDEODEBUGTEXTURE) || !defined(OPTIMIZER_ENABLED)
+ videoTexture = UNITY_SAMPLE_TEX2D_SAMPLER(_VideoDebugTexture, _MainTex, round(TRANSFORM_TEX(poiMesh.uv[_VideoUVNumber], _VideoDebugTexture) * _VideoResolution + .5) / _VideoResolution);
+ #else
+ videoTexture = 1;
+ #endif
+ }
+ else
+ {
+ videoTexture = tex2D(_VRChat_VideoPlayer, round(poiMesh.uv[_VideoUVNumber] * _VideoResolution + .5) / _VideoResolution);
+ }
+ }
+ else
+ {
+ UNITY_BRANCH
+ if(_VideoEnableDebug)
+ {
+ #if defined(PROP_VIDEODEBUGTEXTURE) || !defined(OPTIMIZER_ENABLED)
+ videoTexture = UNITY_SAMPLE_TEX2D_SAMPLER(_VideoDebugTexture, _MainTex, TRANSFORM_TEX(poiMesh.uv[_VideoUVNumber], _VideoDebugTexture) * _VideoTiling + _VideoOffset);
+ #else
+ videoTexture = 1;
+ #endif
+ }
+ else
+ {
+ videoTexture = tex2D(_VRChat_VideoPlayer, ((poiMesh.uv[_VideoUVNumber] + _Time.x * _VideoPanning) * _VideoTiling) + _VideoOffset);
+ }
+ }
+ if(videoTexture.a == 1)
+ {
+ globalColorToDisplayOnScreen = videoTexture.rgb;
+ globalVideoOn = 1;
+ }
+ }
+
+ UNITY_BRANCH
+ if(_VideoRepeatVideoTexture == 1)
+ {
+ if(poiMesh.uv[_VideoUVNumber].x > 1 || poiMesh.uv[_VideoUVNumber].x < 0 || poiMesh.uv[_VideoUVNumber].y > 1 || poiMesh.uv[_VideoUVNumber].y < 0)
+ {
+ return;
+ }
+ }
+
+ switch(_VideoType)
+ {
+ case 0: // LCD
+ {
+ calculateLCD(albedo);
+ break;
+ }
+ case 1: // TN
+ {
+ calculateTN(albedo);
+ break;
+ }
+ case 2: // CRT
+ {
+ calculateCRT(albedo);
+ break;
+ }
+ case 3: // OLED
+ {
+ calculateOLED(albedo);
+ break;
+ }
+ case 4: // Gameboy
+ {
+ calculateGameboy(albedo);
+ break;
+ }
+ case 5: // Projector
+ {
+ calculateProjector(albedo);
+ break;
+ }
+ }
+ #if defined(PROP_VIDEOMASKTEXTURE) || !defined(OPTIMIZER_ENABLED)
+ float screenMask = UNITY_SAMPLE_TEX2D_SAMPLER(_VideoMaskTexture, _MainTex, TRANSFORM_TEX(poiMesh.uv[_VideoUVNumber], _VideoMaskTexture) + _Time.x * _VideoMaskPanning);
+ #else
+ float screenMask = 1;
+ #endif
+
+ albedo = lerp(albedoBeforeScreen, albedo, screenMask);
+ UNITY_BRANCH
+ if (_VideoEmissionEnabled)
+ {
+ videoEmission = albedo.rgb * screenMask;
+ }
+ }
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiVideo.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiVideo.cginc.meta
new file mode 100644
index 00000000..34b51bfb
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiVideo.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: ff77987a6a6483746ae074933182b0e0
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiVoronoi.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiVoronoi.cginc
new file mode 100644
index 00000000..92cb1a5a
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiVoronoi.cginc
@@ -0,0 +1,312 @@
+#ifndef POI_VORONOI
+ #define POI_VORONOI
+
+ float _VoronoiSpace;
+ float _VoronoiBlend;
+ float _VoronoiType;
+ float4 _VoronoiColor0;
+ float _VoronoiEmission0;
+ float4 _VoronoiColor1;
+ float _VoronoiEmission1;
+ float2 _VoronoiGradient;
+ float _VoronoiScale;
+ float3 _VoronoiSpeed;
+ float _VoronoiEnableRandomCellColor;
+ float2 _VoronoiRandomMinMaxSaturation;
+ float2 _VoronoiRandomMinMaxBrightness;
+ float3 randomPoint;
+ float _VoronoiEffectsMaterialAlpha;
+
+ #if defined(PROP_VORONOIMASK) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_VoronoiMask);
+ #endif
+ #if defined(PROP_VORONOINOISE) || !defined(OPTIMIZER_ENABLED)
+ POI_TEXTURE_NOSAMPLER(_VoronoiNoise);
+ #endif
+ float _VoronoiNoiseIntensity;
+
+ float2 inoise(float3 P, float jitter)
+ {
+ float3 Pi = mod(floor(P), 289.0);
+ float3 Pf = frac(P);
+ float3 oi = float3(-1.0, 0.0, 1.0);
+ float3 of = float3(-0.5, 0.5, 1.5);
+ float3 px = Permutation(Pi.x + oi);
+ float3 py = Permutation(Pi.y + oi);
+
+ float3 p, ox, oy, oz, dx, dy, dz;
+ float2 F = 1e6;
+
+ for (int i = 0; i < 3; i ++)
+ {
+ for (int j = 0; j < 3; j ++)
+ {
+ p = Permutation(px[i] + py[j] + Pi.z + oi); // pij1, pij2, pij3
+
+ ox = frac(p * K) - Ko;
+ oy = mod(floor(p * K), 7.0) * K - Ko;
+
+ p = Permutation(p);
+
+ oz = frac(p * K) - Ko;
+
+ dx = Pf.x - of[i] + jitter * ox;
+ dy = Pf.y - of[j] + jitter * oy;
+ dz = Pf.z - of + jitter * oz;
+
+ float3 d = dx * dx + dy * dy + dz * dz; // dij1, dij2 and dij3, squared
+
+ //Find lowest and second lowest distances
+ for (int n = 0; n < 3; n ++)
+ {
+ if (d[n] < F[0])
+ {
+ F[1] = F[0];
+ F[0] = d[n];
+ randomPoint = p;
+ }
+ else if(d[n] < F[1])
+ {
+ F[1] = d[n];
+ }
+ }
+ }
+ }
+
+ return F;
+ }
+
+ float voronoi2D(in float2 x, float scale, float2 speed)
+ {
+ x *= scale;
+ x += speed * _Time.x;
+ float2 n = floor(x);
+ float2 f = frac(x);
+
+ // first pass: regular voronoi
+ float2 mg, mr;
+ float md = 8.0;
+ for (int j = -1; j <= 1; j ++)
+ {
+ for (int i = -1; i <= 1; i ++)
+ {
+ float2 g = float2(float(i), float(j));
+ float2 o = random2(n + g);
+ float2 currentPoint = o;
+
+ float2 r = g + o - f;
+ float d = dot(r, r);
+
+ if (d < md)
+ {
+ md = d;
+ mr = r;
+ mg = g;
+ randomPoint.xy = currentPoint;
+ }
+ }
+ }
+
+ // second pass: distance to borders
+ md = 8.0;
+ for (int r = -2; r <= 2; r ++)
+ {
+ for (int q = -2; q <= 2; q ++)
+ {
+ float2 g = mg + float2(float(q), float(r));
+ float2 o = random2(n + g);
+
+ float2 r = g + o - f;
+
+ if (dot(mr - r, mr - r) > 0.00001)
+ {
+ md = min(md, dot(0.5 * (mr + r), normalize(r - mr)));
+ }
+ }
+ }
+ return md;
+ }
+
+ float voronoi3D(in float3 x, float scale, float3 speed)
+ {
+ x *= scale;
+ x += speed * _Time.x;
+ float3 n = floor(x);
+ float3 f = frac(x);
+
+ // first pass: regular voronoi
+ float3 mg, mr;
+ float md = 8.0;
+ for (int j = -1; j <= 1; j ++)
+ {
+ for (int i = -1; i <= 1; i ++)
+ {
+ for (int h = -1; h <= 1; h ++)
+ {
+ float3 g = float3(float(h), float(i), float(j));
+ float3 o = random3(n + g);
+ float3 currentPoint = o;
+
+ float3 r = g + o - f;
+ float d = dot(r, r);
+
+ if (d < md)
+ {
+ md = d;
+ mr = r;
+ mg = g;
+ randomPoint = currentPoint;
+ }
+ }
+ }
+ }
+
+ // second pass: distance to borders
+ md = 8.0;
+ for (int r = -2; r <= 2; r ++)
+ {
+ for (int q = -2; q <= 2; q ++)
+ {
+ for (int p = -2; p <= 2; p ++)
+ {
+ float3 g = mg + float3(float(p), float(q), float(r));
+ float3 o = random3(n + g);
+
+ float3 r = g + o - f;
+
+ if (dot(mr - r, mr - r) > 0.00001)
+ {
+ md = min(md, dot(0.5 * (mr + r), normalize(r - mr)));
+ }
+ }
+ }
+ }
+ return md;
+ }
+
+
+
+ // fracal sum, range -1.0 - 1.0
+ float VoronoiNoise_Octaves(float3 p, float scale, float3 speed, int octaveNumber, float octaveScale, float octaveAttenuation, float jitter, float time)
+ {
+ float freq = scale;
+ float weight = 1.0f;
+ float sum = 0;
+ for (int i = 0; i < octaveNumber; i ++)
+ {
+ float2 F = inoise(p * freq + time * speed, jitter) * weight;
+
+ sum += sqrt(F[0]);
+
+ freq *= octaveScale;
+ weight *= 1.0f - octaveAttenuation;
+ }
+ return sum;
+ }
+
+ float VoronoiNoiseDiff_Octaves(float3 p, float scale, float3 speed, int octaveNumber, float octaveScale, float octaveAttenuation, float jitter, float time)
+ {
+ float freq = scale;
+ float weight = 1.0f;
+ float sum = 0;
+ for (int i = 0; i < octaveNumber; i ++)
+ {
+ float2 F = inoise(p * freq + time * speed, jitter) * weight;
+
+ sum += sqrt(F[1]) - sqrt(F[0]);
+
+ freq *= octaveScale;
+ weight *= 1.0f - octaveAttenuation;
+ }
+ return sum;
+ }
+
+ void applyVoronoi(inout float4 finalColor, inout float3 VoronoiEmission)
+ {
+ float voronoiOctaveNumber = 1;
+ float voronoiOctaveScale = 1;
+ float voronoiOctaveAttenuation = 1;
+ randomPoint = 0;
+ float4 voronoiColor1 = _VoronoiColor1;
+
+ float voronoi = 0;
+
+ float3 position = 0;
+
+ UNITY_BRANCH
+ if (_VoronoiSpace == 0)
+ {
+ position = poiMesh.localPos;
+ }
+ UNITY_BRANCH
+ if(_VoronoiSpace == 1)
+ {
+ position = poiMesh.worldPos;
+ }
+ UNITY_BRANCH
+ if(_VoronoiSpace == 2)
+ {
+ position = float3(poiMesh.uv[0].x, poiMesh.uv[0].y, 0);
+ }
+ #if defined(PROP_VORONOIMASK) || !defined(OPTIMIZER_ENABLED)
+ float mask = POI2D_SAMPLER_PAN(_VoronoiMask, _MainTex, poiMesh.uv[_VoronoiMaskUV], _VoronoiMaskPan).r;
+ #else
+ float mask = 1;
+ #endif
+ #if defined(PROP_VORONOINOISE) || !defined(OPTIMIZER_ENABLED)
+ float edgeNoise = POI2D_SAMPLER_PAN(_VoronoiNoise, _MainTex, poiMesh.uv[_VoronoiNoiseUV], _VoronoiNoisePan).r * _VoronoiNoiseIntensity;
+ #else
+ float edgeNoise = 0;
+ #endif
+ UNITY_BRANCH
+ if(_VoronoiType == 0) // Basic
+ {
+ voronoi = voronoi2D(position.xy, _VoronoiScale, _VoronoiSpeed);
+ }
+ UNITY_BRANCH
+ if (_VoronoiType == 1) // Diff
+ {
+ voronoi = VoronoiNoiseDiff_Octaves(position, _VoronoiScale, _VoronoiSpeed, voronoiOctaveNumber, voronoiOctaveScale, voronoiOctaveAttenuation, 1, _Time.x);
+ }
+ UNITY_BRANCH
+ if (_VoronoiType == 2) // Fixed Border
+ {
+ voronoi = voronoi3D(position, _VoronoiScale, _VoronoiSpeed);
+ // isolines
+ //color = c.x * (0.5 + 0.5 * sin(64.0 * c.x)) * 1.0;
+ }
+
+ if (_VoronoiEnableRandomCellColor == 1)
+ {
+ float3 rando = random3(randomPoint);
+ fixed hue = rando.x;
+ fixed saturation = lerp(_VoronoiRandomMinMaxSaturation.x, _VoronoiRandomMinMaxSaturation.y, rando.y);
+ fixed value = lerp(_VoronoiRandomMinMaxBrightness.x, _VoronoiRandomMinMaxBrightness.y, rando.z);
+ float3 hsv = float3(hue, saturation, value);
+
+ voronoiColor1.rgb = HSVtoRGB(hsv);
+ }
+
+ float2 voronoiGradient = _VoronoiGradient;
+ voronoiGradient.xy += edgeNoise;
+ float ramp = smoothstep(voronoiGradient.x, voronoiGradient.y, voronoi);
+
+ UNITY_BRANCH
+ if(_VoronoiBlend == 0)
+ {
+ float4 voronoiColor = lerp(_VoronoiColor0, voronoiColor1, ramp);
+ UNITY_BRANCH
+ if(_VoronoiEffectsMaterialAlpha)
+ {
+ finalColor.rgba = lerp(finalColor, voronoiColor, min(mask, 0.99999));
+ }
+ else
+ {
+ finalColor.rgb = lerp(finalColor.rgb, voronoiColor.rgb, min(mask * voronoiColor.a, 0.99999));
+ }
+ }
+ float4 voronoiEmissionColor = lerp(_VoronoiColor0 * _VoronoiEmission0, voronoiColor1 * _VoronoiEmission1, ramp);
+ VoronoiEmission = voronoiEmissionColor.rgb * mask * voronoiEmissionColor.a;
+ }
+
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiVoronoi.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiVoronoi.cginc.meta
new file mode 100644
index 00000000..59241830
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiVoronoi.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: e434761b466d9634bb3659a0b8ec52b8
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiWireframe.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiWireframe.cginc
new file mode 100644
index 00000000..1f56e6e6
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiWireframe.cginc
@@ -0,0 +1,111 @@
+#ifndef POI_WIREFRAME
+ #define POI_WIREFRAME
+
+ UNITY_DECLARE_TEX2D_NOSAMPLER(_WireframeTexture); float4 _WireframeTexture_ST;
+ float2 _WireframeTexturePan;
+ float _WireframeSmoothing;
+ float _WireframeThickness;
+ float4 _WireframeColor;
+ float _WireframeAlpha;
+ float _WireframeEnable;
+ float _WireframeWaveEnabled;
+ float _WireframeWaveDensity;
+ float _WireframeWaveSpeed;
+ float _WireframeEdgeOpacity;
+ float _WireframeFaceOpacity;
+ half _WireframeEmissionAlpha;
+ float _WireframeEmissionStrength;
+ float _WireframeQuad;
+ float _WireframeUV;
+
+ #ifndef POI_SHADOW
+ void applyWireframe(inout float3 wireframeEmission, inout float4 albedo)
+ {
+ UNITY_BRANCH
+ if (_WireframeEnable)
+ {
+ float4 colorMap = UNITY_SAMPLE_TEX2D_SAMPLER(_WireframeTexture, _MainTex, TRANSFORM_TEX(poiMesh.uv[_WireframeUV], _WireframeTexture) + _Time.x * _WireframeTexturePan);
+ float size = _WireframeThickness;
+ half3 width = abs(ddx(poiMesh.barycentricCoordinates)) + abs(ddy(poiMesh.barycentricCoordinates));
+ half3 eF = smoothstep(0, width * size, poiMesh.barycentricCoordinates);
+ half minBary = size > 0 ? min(min(eF.x, eF.y), eF.z): 1;
+
+ float4 wireframeColor = _WireframeColor * colorMap;
+
+ albedo.a *= lerp(_WireframeEdgeOpacity, _WireframeFaceOpacity, minBary);
+ albedo.rgb = lerp(lerp(albedo.rgb, wireframeColor.rgb, wireframeColor.a), albedo.rgb, minBary);
+ wireframeEmission = wireframeColor.rgb * _WireframeEmissionStrength * (1 - minBary) * _WireframeColor.a;
+ }
+ }
+
+ [maxvertexcount(3)]
+ void wireframeGeom(triangle v2f IN[3], inout TriangleStream < v2f > tristream)
+ {
+ UNITY_BRANCH
+ if(_WireframeQuad)
+ {
+ float e1 = length(IN[0].localPos - IN[1].localPos);
+ float e2 = length(IN[1].localPos - IN[2].localPos);
+ float e3 = length(IN[2].localPos - IN[0].localPos);
+
+ float3 quad = 0;
+ if(e1 > e2 && e1 > e3)
+ quad.y = 1.;
+ else if(e2 > e3 && e2 > e1)
+ quad.x = 1;
+ else
+ quad.z = 1;
+
+ IN[0].barycentricCoordinates = fixed3(1, 0, 0) + quad;
+ IN[1].barycentricCoordinates = fixed3(0, 0, 1) + quad;
+ IN[2].barycentricCoordinates = fixed3(0, 1, 0) + quad;
+ }
+ else
+ {
+ IN[0].barycentricCoordinates = fixed3(1, 0, 0);
+ IN[1].barycentricCoordinates = fixed3(0, 1, 0);
+ IN[2].barycentricCoordinates = fixed3(0, 0, 1);
+ }
+
+
+
+ tristream.Append(IN[0]);
+ tristream.Append(IN[1]);
+ tristream.Append(IN[2]);
+ }
+ #else
+
+ float applyShadowWireframe(float2 uv, float3 barycentricCoordinates, float3 normal, float3 worldPos)
+ {
+ UNITY_BRANCH
+ if(_WireframeEnable)
+ {
+ float wireframeFadeAlpha = _WireframeAlpha;
+ float3 finalWireframeColor = 0;
+
+ float3 barys;
+ barys.xy = barycentricCoordinates;
+ barys.z = 1 - barys.x - barys.y;
+ float3 deltas = fwidth(barys);
+ float3 smoothing = deltas * _WireframeSmoothing;
+ float wireframeThickness = _WireframeThickness;
+ float3 thickness = deltas * wireframeThickness;
+ barys = smoothstep(thickness, thickness + smoothing, barys);
+ float minBary = min(barys.x, min(barys.y, barys.z));
+
+ return lerp(_WireframeEdgeOpacity, _WireframeFaceOpacity, minBary);
+ }
+ }
+
+ [maxvertexcount(3)]
+ void wireframeGeom(triangle V2FShadow IN[3], inout TriangleStream < V2FShadow > tristream)
+ {
+ IN[0].barycentricCoordinates = fixed3(1, 0, 0);
+ IN[1].barycentricCoordinates = fixed3(0, 1, 0);
+ IN[2].barycentricCoordinates = fixed3(0, 0, 1);
+ tristream.Append(IN[0]);
+ tristream.Append(IN[1]);
+ tristream.Append(IN[2]);
+ }
+ #endif
+#endif \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiWireframe.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiWireframe.cginc.meta
new file mode 100644
index 00000000..6a7b4507
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_PoiWireframe.cginc.meta
@@ -0,0 +1,8 @@
+fileFormatVersion: 2
+guid: 65110f189ab785a48b0a0d99d987ea15
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_Poicludes.cginc b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_Poicludes.cginc
new file mode 100644
index 00000000..4ae8cc7d
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_Poicludes.cginc
@@ -0,0 +1,172 @@
+#ifndef POICLUDES
+#define POICLUDES
+
+UNITY_DECLARE_TEX2D(_MainTex); float4 _MainTex_ST; float4 _MainTex_TexelSize;
+float _SpecularLMOcclusion;
+float _SpecLMOcclusionAdjust;
+sampler2D _PoiGrab;
+sampler2D _CameraDepthTexture;
+float _Cutoff;
+float _AlphaMod;
+
+//Structs
+struct appdata
+{
+ float4 vertex : POSITION;
+ float3 normal : NORMAL;
+ float4 tangent : TANGENT;
+ float4 color : COLOR;
+ float2 uv0 : TEXCOORD0;
+ float2 uv1 : TEXCOORD1;
+ float2 uv2 : TEXCOORD2;
+ float2 uv3 : TEXCOORD3;
+ uint vertexId : SV_VertexID;
+ UNITY_VERTEX_INPUT_INSTANCE_ID
+};
+
+#ifdef OUTLINE
+ float _LineWidth;
+ float _OutlineEmission;
+ float4 _LineColor;
+ sampler2D _OutlineTexture; float4 _OutlineTexture_ST; float2 _OutlineTexturePan; float _OutlineTextureUV;
+ float4 _OutlineFadeDistance;
+ float4 _OutlineGlobalPan;
+#endif
+
+struct PoiLighting
+{
+ half3 direction;
+ half3 color;
+ fixed attenuation;
+ #ifdef FORWARD_ADD_PASS
+ fixed additiveShadow;
+ #endif
+ half3 directLighting;
+ half3 indirectLighting;
+ half lightMap;
+ float3 rampedLightMap;
+ half3 finalLighting;
+ half3 halfDir;
+ half nDotL;
+ half nDotH;
+ half lDotv;
+ half lDotH;
+ half nDotV;
+ half N0DotV;
+ half diffuseTerm;
+ half occlusion;
+ half dotNH;
+ half dotLH;
+
+ #ifdef VERTEXLIGHT_ON
+ // Non Important Lights
+ float4 vDotNL;
+ float3 vColor[4];
+ float4 vCorrectedDotNL;
+ float4 vAttenuation;
+ float4 vAttenuationDotNL;
+ float3 vPosition[4];
+ float3 vDirection[4];
+ float3 vFinalLighting;
+ float3 vHalfDir[4];
+ half4 vDotNH;
+ half4 vDotLH;
+
+
+ #endif
+};
+
+struct PoiCamera
+{
+ half3 viewDir;
+ half3 tangentViewDir;
+ half3 decalTangentViewDir;
+ half3 forwardDir;
+ half3 worldPos;
+ float viewDotNormal;
+ float distanceToModel;
+ float distanceToVert;
+ float3 reflectionDir;
+ float3 vertexReflectionDir;
+ float2 screenUV;
+ float4 clipPos;
+ #if defined(GRAIN)
+ float4 worldDirection;
+ #endif
+ float4 grabPos;
+};
+
+struct PoiMesh
+{
+ float3 normals[2];
+ float4 tangent;
+ float3 binormal;
+ float3 localPos;
+ float3 worldPos;
+ float3 modelPos;
+ float3 tangentSpaceNormal;
+ float2 uv[5];
+ float4 vertexColor;
+ fixed3 barycentricCoordinates;
+ #if defined(LIGHTMAP_ON) || defined(DYNAMICLIGHTMAP_ON)
+ float4 lightmapUV;
+ #endif
+ float isFrontFace;
+ #ifdef FUR
+ float furAlpha;
+ #endif
+};
+
+struct PoiTangentData
+{
+ float3x3 tangentTransform;
+ float3x3 tangentToWorld;
+};
+
+struct FragmentCommonData
+{
+ half3 diffColor, specColor;
+ // Note: smoothness & oneMinusReflectivity for optimization purposes, mostly for DX9 SM2.0 level.
+ // Most of the math is being done on these (1-x) values, and that saves a few precious ALU slots.
+ half oneMinusReflectivity, smoothness;
+ float3 normalWorld;
+ float3 eyeVec;
+ half alpha;
+ float3 posWorld;
+
+ #if UNITY_STANDARD_SIMPLE
+ half3 reflUVW;
+ #endif
+
+ #if UNITY_STANDARD_SIMPLE
+ half3 tangentSpaceNormal;
+ #endif
+};
+
+struct Debug
+{
+ float debug1;
+ float2 debug2;
+ float3 debug3;
+ float4 debug4;
+};
+
+struct PoiMods
+{
+ float4 audioLink;
+ fixed audioLinkTextureExists;
+ float4 globalMasks;
+ float audioLinkVersion;
+ float4 audioLinkTexture;
+};
+
+static Debug debug;
+static PoiLighting poiLight;
+static PoiCamera poiCam;
+static PoiMesh poiMesh;
+static PoiMods poiMods;
+static UnityGI gi;
+static FragmentCommonData s;
+static PoiTangentData poiTData;
+
+#endif
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_Poicludes.cginc.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_Poicludes.cginc.meta
new file mode 100644
index 00000000..f1877049
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/CGI_Poicludes.cginc.meta
@@ -0,0 +1,9 @@
+fileFormatVersion: 2
+guid: d0e3e8cd70bfa154ab69be067aba0d59
+ShaderImporter:
+ externalObjects: {}
+ defaultTextures: []
+ nonModifiableTextures: []
+ userData:
+ assetBundleName:
+ assetBundleVariant:
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/Notes.txt b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/Notes.txt
new file mode 100644
index 00000000..ec2c5bfd
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/Notes.txt
@@ -0,0 +1,7 @@
+// Transforms 2D UV by scale/bias property
+#define TRANSFORM_TEX(tex,name) (tex.xy * name##_ST.xy + name##_ST.zw)
+
+[HideInInspector][Vector2]Pan ("Panning", Vector) = (0, 0, 0, 0)
+ [HideInInspector][Enum(UV0, 0, UV1, 1, UV2, 2, UV3, 3, distorteduv0, 4)] UV ("UV", Int) = 0
+
+:=--{reference_properties:[Pan, UV]} \ No newline at end of file
diff --git a/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/Notes.txt.meta b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/Notes.txt.meta
new file mode 100644
index 00000000..53bab679
--- /dev/null
+++ b/VRCSDK3AvatarsLegacy/Assets/_PoiyomiShaders/Shaders/Pro/Includes/Notes.txt.meta
@@ -0,0 +1,7 @@
+fileFormatVersion: 2
+guid: 572baf09485ff2d4b9e074da2bba81bb
+TextScriptImporter:
+ externalObjects: {}
+ userData:
+ assetBundleName:
+ assetBundleVariant: