1
This repository has been archived on 2025-03-15. You can view files and clone it, but cannot push or open issues or pull requests.

100 lines
3.1 KiB
HLSL
Raw Permalink Normal View History

2025-03-15 20:02:21 +01:00
// 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