247 lines
9.4 KiB
GLSL
247 lines
9.4 KiB
GLSL
/************************************************************************************
|
|
Copyright : Copyright (c) Facebook Technologies, LLC and its affiliates. All rights reserved.
|
|
|
|
Your use of this SDK or tool is subject to the Oculus SDK License Agreement, available at
|
|
https://developer.oculus.com/licenses/oculussdk/
|
|
|
|
Unless required by applicable law or agreed to in writing, the Utilities SDK distributed
|
|
under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
|
|
ANY KIND, either express or implied. See the License for the specific language governing
|
|
permissions and limitations under the License.
|
|
************************************************************************************/
|
|
|
|
Shader "Interaction/OculusHand"
|
|
{
|
|
Properties
|
|
{
|
|
[Header(General)]
|
|
_ColorTop("Color Top", Color) = (0.1960784, 0.2039215, 0.2117647, 1)
|
|
_ColorBottom("Color Bottom", Color) = (0.1215686, 0.1254902, 0.1294117, 1)
|
|
_Opacity("Opacity", Range( 0 , 1)) = 0.8
|
|
|
|
[Header(Fresnel)]
|
|
_FresnelPower("FresnelPower", Range( 0 , 5)) = 0.16
|
|
|
|
[Header(Outline)]
|
|
_OutlineColor("Outline Color", Color) = (0.5377358,0.5377358,0.5377358,1)
|
|
_OutlineWidth("Outline Width", Range( 0 , 0.005)) = 0.00134
|
|
_OutlineOpacity("Outline Opacity", Range( 0 , 1)) = 0.4
|
|
_OutlineIntensity("Outline Intensity", Range( 0 , 1)) = 1
|
|
_OutlinePinchRange("Outline Pinch Range", Float) = 0.15
|
|
_OutlineGlowIntensity("Outline Glow Intensity", Range( 0 , 1)) = 0
|
|
_OutlineGlowColor("Outline Glow Color", Color) = (1,1,1,1)
|
|
_OutlineSphereHardness("Outline Sphere Hardness", Range( 0 , 1)) = 0.3
|
|
|
|
[Header(Pinch)]
|
|
_PinchPosition("Pinch Position", Vector) = (0,0,0,0)
|
|
_PinchRange("Pinch Range", Float) = 0.03
|
|
_PinchIntensity("Pinch Intensity", Range( 0 , 1)) = 0
|
|
_PinchColor("Pinch Color", Color) = (0.95,0.95,0.95,1)
|
|
|
|
[Header(Wrist)]
|
|
_WristLocalOffset("Wrist Local Offset", Vector) = (0,0,0,0)
|
|
_WristRange("Wrist Range", Float) = 0.06
|
|
_WristScale("Wrist Scale", Float) = 1.0
|
|
|
|
[Header(Finger Glow)]
|
|
_FingerGlowMask("Finger Glow Mask", 2D) = "white" {}
|
|
_FingerGlowColor("Finger Glow Color", Color) = (1,1,1,1)
|
|
|
|
[HideInInspector] _texcoord( "", 2D ) = "white" {}
|
|
}
|
|
|
|
SubShader
|
|
{
|
|
Tags
|
|
{
|
|
"Queue" = "Transparent" "RenderType" = "Transparent" "IgnoreProjector" = "True"
|
|
}
|
|
LOD 200
|
|
|
|
//==============================================================================
|
|
// Depth Pass
|
|
//==============================================================================
|
|
|
|
Pass
|
|
{
|
|
ZWrite On
|
|
Cull Off
|
|
ColorMask 0
|
|
}
|
|
|
|
|
|
//==============================================================================
|
|
// Outline Pass
|
|
//==============================================================================
|
|
|
|
Tags
|
|
{
|
|
"RenderType" = "Transparent" "Queue" = "Transparent+0"
|
|
}
|
|
Cull Front
|
|
Blend SrcAlpha OneMinusSrcAlpha
|
|
|
|
CGPROGRAM
|
|
#pragma target 3.0
|
|
#pragma surface outlineSurf Outline nofog keepalpha noshadow noambient novertexlights nolightmap nodynlightmap nodirlightmap nometa noforwardadd vertex:outlineVertexDataFunc
|
|
|
|
void outlineVertexDataFunc(inout appdata_full v, out Input o) {
|
|
UNITY_INITIALIZE_OUTPUT(Input, o);
|
|
v.vertex.xyz += v.normal * _OutlineWidth; // Outline
|
|
}
|
|
|
|
inline half4 LightingOutline(SurfaceOutput s, half3 lightDir, half atten) {
|
|
return half4(0, 0, 0, s.Alpha);
|
|
}
|
|
|
|
void outlineSurf(Input i, inout SurfaceOutput o) {
|
|
// Sphere mask
|
|
float3 mask = ((i.worldPos - _PinchPosition) / _OutlinePinchRange);
|
|
float dotValue = clamp(dot(mask, mask), 0.0, 1.0);
|
|
float sphereMask = pow(dotValue, _OutlineSphereHardness);
|
|
|
|
// Compute outline color
|
|
float3 outlineGlow = saturate(1.0 - sphereMask) * _OutlineGlowIntensity *
|
|
_OutlineGlowColor.rgb;
|
|
|
|
// Wrist
|
|
float3 wristPosition = mul(unity_ObjectToWorld, _WristLocalOffset).xyz;
|
|
float wristSphere = length(wristPosition - i.worldPos);
|
|
float wristRangeScaled = _WristRange * _WristScale;
|
|
float wristSphereStep = smoothstep(wristRangeScaled * 0.333, wristRangeScaled, wristSphere);
|
|
|
|
// Output
|
|
o.Emission = (_OutlineColor.rgb * _OutlineIntensity) + outlineGlow;
|
|
o.Alpha = _OutlineOpacity * wristSphereStep;
|
|
if (o.Alpha < 0.1)
|
|
{
|
|
discard;
|
|
}
|
|
}
|
|
ENDCG
|
|
|
|
//==============================================================================
|
|
// Fesnel / Color / Alpha Pass
|
|
//==============================================================================
|
|
|
|
Tags
|
|
{
|
|
"RenderType" = "MaskedOutline" "Queue" = "Transparent+0" "IgnoreProjector" = "True" "IsEmissive" = "true"
|
|
}
|
|
Cull Back
|
|
Blend SrcAlpha OneMinusSrcAlpha
|
|
|
|
CGINCLUDE
|
|
#include "UnityPBSLighting.cginc"
|
|
#include "Lighting.cginc"
|
|
#pragma target 3.0
|
|
|
|
struct Input {
|
|
float3 worldPos;
|
|
float3 worldNormal;
|
|
float2 uv_FingerGlowMask;
|
|
};
|
|
|
|
// General
|
|
uniform float4 _ColorTop;
|
|
uniform float4 _ColorBottom;
|
|
uniform float _Opacity;
|
|
uniform float _FresnelPower;
|
|
|
|
// Outline
|
|
uniform float _OutlineWidth;
|
|
uniform float _OutlineIntensity;
|
|
uniform float4 _OutlineColor;
|
|
uniform float _OutlinePinchRange;
|
|
uniform float _OutlineSphereHardness;
|
|
uniform float _OutlineGlowIntensity;
|
|
uniform float4 _OutlineGlowColor;
|
|
uniform float _OutlineOpacity;
|
|
|
|
// Pinch
|
|
uniform float _PinchRange;
|
|
uniform float3 _PinchPosition;
|
|
uniform float _PinchIntensity;
|
|
uniform float4 _PinchColor;
|
|
|
|
// Wrist
|
|
uniform float4 _WristLocalOffset;
|
|
uniform float _WristRange;
|
|
uniform float _WristScale;
|
|
|
|
// Finger Glow
|
|
uniform sampler2D _FingerGlowMask;
|
|
uniform float4 _FingerGlowColor;
|
|
uniform float _ThumbGlowValue;
|
|
uniform float _IndexGlowValue;
|
|
uniform float _MiddleGlowValue;
|
|
uniform float _RingGlowValue;
|
|
uniform float _PinkyGlowValue;
|
|
|
|
void vertexDataFunc(inout appdata_full v, out Input o) {
|
|
UNITY_INITIALIZE_OUTPUT(Input, o);
|
|
}
|
|
|
|
inline half4 LightingUnlit(SurfaceOutput s, half3 lightDir, half atten) {
|
|
return half4(0, 0, 0, s.Alpha);
|
|
}
|
|
|
|
void surf(Input i, inout SurfaceOutput o) {
|
|
float3 wristPosition = mul(unity_ObjectToWorld, _WristLocalOffset).xyz;
|
|
float3 worldViewDir = normalize(UnityWorldSpaceViewDir(i.worldPos));
|
|
|
|
// Fresnel + color
|
|
float fresnelNdot = dot(i.worldNormal, worldViewDir);
|
|
float fresnel = 1.0 * pow(1.0 - fresnelNdot, _FresnelPower);
|
|
float4 color = lerp(_ColorTop, _ColorBottom, fresnel);
|
|
|
|
// Pinch sphere
|
|
float pinchSphere = length(_PinchPosition - i.worldPos);
|
|
float pinchSphereStep = smoothstep(_PinchRange - 0.01, _PinchRange, pinchSphere);
|
|
float4 pinchColor = float4(
|
|
saturate((1.0 - pinchSphereStep) * _PinchIntensity * _PinchColor.rgb),
|
|
0.0);
|
|
|
|
// Wrist fade
|
|
//
|
|
// Visually this means that at approx 33% of the sphere range we want full transparency (map to 0)
|
|
// to 100% of our sphere range to be opaque.
|
|
float wristSphere = length(wristPosition - i.worldPos);
|
|
float wristRangeScaled = _WristRange * _WristScale;
|
|
float wristSphereStep = smoothstep(wristRangeScaled * 0.333, wristRangeScaled, wristSphere);
|
|
|
|
// Finger glows
|
|
//
|
|
// the value is packed into a texture where each pixel has two bytes (red and green channels):
|
|
//
|
|
// the red channel is used to mask each glow area, currently every finger,
|
|
// with the thumb being the 1st bit and pinky the 5th bit (6-8 currently unused).
|
|
//
|
|
// the green channel is used to indicate the intensity of the glow. This works only because the glow maps
|
|
// between fingers do not overlap.
|
|
|
|
float3 glowMaskPixelColor = tex2D(_FingerGlowMask, i.uv_FingerGlowMask);
|
|
int glowMaskR = glowMaskPixelColor.r * 255;
|
|
float glowIntensity = saturate(
|
|
glowMaskPixelColor.g *
|
|
((glowMaskR & 0x1) * _ThumbGlowValue +
|
|
((glowMaskR >> 1) & 0x1) * _IndexGlowValue +
|
|
((glowMaskR >> 2) & 0x1) * _MiddleGlowValue +
|
|
((glowMaskR >> 3) & 0x1) * _RingGlowValue +
|
|
((glowMaskR >> 4) & 0x1) * _PinkyGlowValue));
|
|
|
|
float4 glowColor = glowIntensity * _FingerGlowColor;
|
|
|
|
// Emission + Opacity
|
|
o.Emission = saturate(color + pinchColor + glowColor).rgb;
|
|
o.Alpha = _Opacity * wristSphereStep;
|
|
}
|
|
ENDCG
|
|
|
|
CGPROGRAM
|
|
#pragma surface surf Unlit keepalpha vertex:vertexDataFunc
|
|
ENDCG
|
|
}
|
|
Fallback "Diffuse"
|
|
}
|