137 lines
No EOL
3.6 KiB
Text
137 lines
No EOL
3.6 KiB
Text
Shader "Distortion"
|
|
{
|
|
Properties
|
|
{
|
|
_Refraction ("Refraction", Range (0.00, 100.0)) = 1.0
|
|
_Power ("Power", Range (1.00, 10.0)) = 1.0
|
|
_AlphaPower ("Vertex Alpha Power", Range (1.00, 10.0)) = 1.0
|
|
_BumpMap( "Normal Map", 2D ) = "bump" {}
|
|
|
|
_Cull ( "Face Culling", Int ) = 2
|
|
}
|
|
|
|
SubShader
|
|
{
|
|
Tags { "Queue" = "Transparent+1" }
|
|
|
|
GrabPass
|
|
{
|
|
"_GrabTexture"
|
|
}
|
|
|
|
Pass
|
|
{
|
|
Cull [_Cull]
|
|
|
|
CGPROGRAM
|
|
#pragma target 3.0
|
|
#pragma vertex vert
|
|
#pragma fragment frag
|
|
#include "UnityCG.cginc"
|
|
#include "UnityLightingCommon.cginc"
|
|
#include "UnityStandardUtils.cginc"
|
|
#include "UnityStandardInput.cginc"
|
|
|
|
// From Valve's Lab Renderer, Copyright (c) Valve Corporation, All rights reserved.
|
|
float3 Vec3TsToWs( float3 vVectorTs, float3 vNormalWs, float3 vTangentUWs, float3 vTangentVWs )
|
|
{
|
|
float3 vVectorWs;
|
|
vVectorWs.xyz = vVectorTs.x * vTangentUWs.xyz;
|
|
vVectorWs.xyz += vVectorTs.y * vTangentVWs.xyz;
|
|
vVectorWs.xyz += vVectorTs.z * vNormalWs.xyz;
|
|
return vVectorWs.xyz; // Return without normalizing
|
|
}
|
|
|
|
// From Valve's Lab Renderer, Copyright (c) Valve Corporation, All rights reserved.
|
|
float3 Vec3TsToWsNormalized( float3 vVectorTs, float3 vNormalWs, float3 vTangentUWs, float3 vTangentVWs )
|
|
{
|
|
return normalize( Vec3TsToWs( vVectorTs.xyz, vNormalWs.xyz, vTangentUWs.xyz, vTangentVWs.xyz ) );
|
|
}
|
|
|
|
struct VS_INPUT
|
|
{
|
|
float4 vPosition : POSITION;
|
|
float3 vNormal : NORMAL;
|
|
float2 vTexcoord0 : TEXCOORD0;
|
|
float4 vTangentUOs_flTangentVSign : TANGENT;
|
|
float4 vColor : COLOR;
|
|
};
|
|
|
|
struct PS_INPUT
|
|
{
|
|
float4 vGrabPos : TEXCOORD0;
|
|
float4 vPos : SV_POSITION;
|
|
float4 vColor : COLOR;
|
|
float2 vTexCoord0 : TEXCOORD1;
|
|
float3 vNormalWs : TEXCOORD2;
|
|
float3 vTangentUWs : TEXCOORD3;
|
|
float3 vTangentVWs : TEXCOORD4;
|
|
};
|
|
|
|
PS_INPUT vert(VS_INPUT i)
|
|
{
|
|
PS_INPUT o;
|
|
|
|
// Clip space position
|
|
o.vPos = UnityObjectToClipPos(i.vPosition);
|
|
|
|
// Grab position
|
|
o.vGrabPos = ComputeGrabScreenPos(o.vPos);
|
|
|
|
// World space normal
|
|
o.vNormalWs = UnityObjectToWorldNormal(i.vNormal);
|
|
|
|
// Tangent
|
|
o.vTangentUWs.xyz = UnityObjectToWorldDir( i.vTangentUOs_flTangentVSign.xyz ); // World space tangentU
|
|
o.vTangentVWs.xyz = cross( o.vNormalWs.xyz, o.vTangentUWs.xyz ) * i.vTangentUOs_flTangentVSign.w;
|
|
|
|
// Texture coordinates
|
|
o.vTexCoord0.xy = i.vTexcoord0.xy;
|
|
|
|
// Color
|
|
o.vColor = i.vColor;
|
|
|
|
return o;
|
|
}
|
|
|
|
sampler2D _GrabTexture;
|
|
float _Refraction;
|
|
float _Power;
|
|
float _AlphaPower;
|
|
|
|
float4 frag(PS_INPUT i) : SV_Target
|
|
{
|
|
// Tangent space normals
|
|
float3 vNormalTs = UnpackScaleNormal( tex2D( _BumpMap, i.vTexCoord0.xy ), 1 );
|
|
|
|
// Tangent space -> World space
|
|
float3 vNormalWs = Vec3TsToWsNormalized( vNormalTs.xyz, i.vNormalWs.xyz, i.vTangentUWs.xyz, i.vTangentVWs.xyz );
|
|
|
|
// World space -> View space
|
|
float3 vNormalVs = normalize(mul((float3x3)UNITY_MATRIX_V, vNormalWs));
|
|
|
|
// Calculate offset
|
|
float2 offset = vNormalVs.xy * _Refraction;
|
|
offset *= pow(length(vNormalVs.xy), _Power);
|
|
|
|
// Scale to pixel size
|
|
offset /= float2(_ScreenParams.x, _ScreenParams.y);
|
|
|
|
// Scale with screen depth
|
|
offset /= i.vPos.z;
|
|
|
|
// Scale with vertex alpha
|
|
offset *= pow(i.vColor.a, _AlphaPower);
|
|
|
|
// Sample grab texture
|
|
float4 vDistortColor = tex2Dproj(_GrabTexture, i.vGrabPos + float4(offset, 0.0, 0.0));
|
|
|
|
// Debug normals
|
|
// return float4(vNormalVs * 0.5 + 0.5, 1);
|
|
|
|
return vDistortColor;
|
|
}
|
|
ENDCG
|
|
}
|
|
}
|
|
} |