Last active
November 15, 2022 13:48
-
-
Save Fewes/7d0918c9822bb8e696bb0b1da4b8d3be to your computer and use it in GitHub Desktop.
Distortion shader for Unity. Supports a normal map.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Shader "Distortion" | |
{ | |
Properties | |
{ | |
_Refraction ("Refraction", Range (0.00, 10.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 | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Thank you :)