100 lines
3.1 KiB
HLSL
100 lines
3.1 KiB
HLSL
// Upgrade NOTE: replaced 'mul(UNITY_MATRIX_MVP,*)' with 'UnityObjectToClipPos(*)'
|
|
|
|
// Upgrade NOTE: replaced '_World2Object' with 'unity_WorldToObject'
|
|
|
|
// Copyright 2015 Google Inc. All rights reserved.
|
|
//
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// 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.
|
|
|
|
|
|
// To use in a surface shader, add the following text to the code:
|
|
//
|
|
// #pragma surface ... vertex:vert <-- add "vertex:vert" to this line
|
|
// #pragma multi_compile __ GVR_DISTORTION <-- copy the next 5 lines
|
|
// #include "GvrDistortion.cginc"
|
|
// void vert (inout appdata_base v) {
|
|
// v.vertex = undistortSurface(v.vertex);
|
|
// }
|
|
|
|
// To use in a vertex shader, modify it as follows:
|
|
//
|
|
// #pragma multi_compile __ GVR_DISTORTION <-- add these 2 lines
|
|
// #include "GvrDistortion.cginc"
|
|
//
|
|
// v2f vert (appdata_blah v) {
|
|
// v2f o;
|
|
// o.vertex = undistortVertex(v.vertex); <-- replace "mul(UNITY_MATRIX_MVP, v.vertex)"
|
|
// ...
|
|
// return o;
|
|
// }
|
|
|
|
#if defined(GVR_DISTORTION)
|
|
|
|
float4x4 _Undistortion;
|
|
float _MaxRadSq;
|
|
float _NearClip;
|
|
float4x4 _RealProjection;
|
|
float4x4 _FixProjection;
|
|
|
|
float distortionFactor(float rSquared) {
|
|
float ret = 0.0;
|
|
ret = rSquared * (ret + _Undistortion[1][1]);
|
|
ret = rSquared * (ret + _Undistortion[0][1]);
|
|
ret = rSquared * (ret + _Undistortion[3][0]);
|
|
ret = rSquared * (ret + _Undistortion[2][0]);
|
|
ret = rSquared * (ret + _Undistortion[1][0]);
|
|
ret = rSquared * (ret + _Undistortion[0][0]);
|
|
return ret + 1.0;
|
|
}
|
|
|
|
// Convert point from world space to undistorted camera space.
|
|
float4 undistort(float4 pos) {
|
|
// Go to camera space.
|
|
pos = mul(UNITY_MATRIX_MV, pos);
|
|
if (pos.z <= -_NearClip) { // Reminder: Forward is -Z.
|
|
// Undistort the point's coordinates in XY.
|
|
float r2 = clamp(dot(pos.xy, pos.xy) / (pos.z*pos.z), 0, _MaxRadSq);
|
|
pos.xy *= distortionFactor(r2);
|
|
}
|
|
return pos;
|
|
}
|
|
|
|
// Multiply by no-lens projection matrix after undistortion.
|
|
float4 undistortVertex(float4 pos) {
|
|
return mul(_RealProjection, undistort(pos));
|
|
}
|
|
|
|
// Surface shader hides away the MVP multiplication, so we have
|
|
// to multiply by _FixProjection = inverse(VP)*_RealProjection
|
|
// and then by inverse(M), in order to cancel it out and leave our
|
|
// own transform in place.
|
|
float4 undistortSurface(float4 pos) {
|
|
float4 proj = mul(_FixProjection, undistort(pos));
|
|
return mul(unity_WorldToObject, proj);
|
|
}
|
|
|
|
#else
|
|
// Distortion disabled.
|
|
|
|
// Just do the standard MVP transform.
|
|
float4 undistortVertex(float4 pos) {
|
|
return UnityObjectToClipPos(pos);
|
|
}
|
|
|
|
// Surface shader hides away the MVP multiplication, so just return pos.
|
|
float4 undistortSurface(float4 pos) {
|
|
return pos;
|
|
}
|
|
|
|
#endif
|