You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 

133 lines
3.8 KiB

#include "Packages/com.unity.render-pipelines.core/ShaderLibrary/Common.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/ShaderLibrary/ShaderVariables.hlsl"
#include "Packages/com.unity.render-pipelines.high-definition/Runtime/PostProcessing/Shaders/PostProcessDefines.hlsl"
#pragma only_renderers d3d11 playstation xboxone xboxseries vulkan metal switch switch2
#pragma kernel KMain
#pragma multi_compile GENERIC UNITDISTANCE
#pragma multi_compile _ ENABLE_ALPHA
TEXTURE2D_X(_InputTexture);
RW_TEXTURE2D_X(CTYPE, _OutputTexture);
SAMPLER(sampler_LinearClamp);
CBUFFER_START(cb0)
float4 _Params;
CBUFFER_END
#define GROUP_SIZE 8
// Back-ported & adapted from the work of the Stockholm demo team - thanks Lasse
float2 Panini_UnitDistance(float2 view_pos)
{
// Given
// S----------- E--X-------
// | ` . /,´
// |-- --- Q
// 1 | ,´/ `
// | ,´ / ´
// | ,´ / `
// | ,´ / .
// O` / .
// | / `
// | / ´
// 1 | / ´
// | / ´
// |/_ . ´
// P
//
// Have E
// Want to find X
//
// First apply tangent-secant theorem to find Q
// PE*QE = SE*SE
// QE = PE-PQ
// PQ = PE-(SE*SE)/PE
// Q = E*(PQ/PE)
// Then project Q to find X
const float d = 1.0;
const float view_dist = 2.0;
const float view_dist_sq = 4.0;
float view_hyp = sqrt(view_pos.x * view_pos.x + view_dist_sq);
float cyl_hyp = view_hyp - (view_pos.x * view_pos.x) / view_hyp;
float cyl_hyp_frac = cyl_hyp / view_hyp;
float cyl_dist = view_dist * cyl_hyp_frac;
float2 cyl_pos = view_pos * cyl_hyp_frac;
return cyl_pos / (cyl_dist - d);
}
float2 Panini_Generic(float2 view_pos, float d)
{
// Given
// S----------- E--X-------
// | ` ~. /,´
// |-- --- Q
// | ,/ `
// 1 | ,´/ `
// | ,´ / ´
// | ,´ / ´
// |,` / ,
// O /
// | / ,
// d | /
// | / ,
// |/ .
// P
// | ´
// | , ´
// +- ´
//
// Have E
// Want to find X
//
// First compute line-circle intersection to find Q
// Then project Q to find X
float view_dist = 1.0 + d;
float view_hyp_sq = view_pos.x * view_pos.x + view_dist * view_dist;
float isect_D = view_pos.x * d;
float isect_discrim = view_hyp_sq - isect_D * isect_D;
float cyl_dist_minus_d = (-isect_D * view_pos.x + view_dist * sqrt(isect_discrim)) / view_hyp_sq;
float cyl_dist = cyl_dist_minus_d + d;
float2 cyl_pos = view_pos * (cyl_dist / view_dist);
return cyl_pos / (cyl_dist - d);
}
[numthreads(GROUP_SIZE, GROUP_SIZE, 1)]
void KMain(uint3 dispatchThreadId : SV_DispatchThreadID)
{
UNITY_XR_ASSIGN_VIEW_INDEX(dispatchThreadId.z);
PositionInputs posInputs = GetPositionInput(float2(dispatchThreadId.xy), _PostProcessScreenSize.zw, uint2(GROUP_SIZE, GROUP_SIZE));
float2 uv = posInputs.positionNDC;
#if GENERIC
float2 proj_pos = Panini_Generic((2.0 * uv - 1.0) * _Params.xy * _Params.w, _Params.z);
#else // UNITDISTANCE
float2 proj_pos = Panini_UnitDistance((2.0 * uv - 1.0) * _Params.xy * _Params.w);
#endif
float2 proj_ndc = proj_pos / _Params.xy;
float2 coords = proj_ndc * 0.5 + 0.5;
if (any(coords < 0.0) || any(coords > 1.0))
{
_OutputTexture[COORD_TEXTURE2D_X(posInputs.positionSS)] = 0.0;
}
else
{
CTYPE smp = SAMPLE_TEXTURE2D_X_LOD(_InputTexture, sampler_LinearClamp, ClampAndScaleUVForBilinearPostProcessTexture(coords), 0.0).CTYPE_SWIZZLE;
_OutputTexture[COORD_TEXTURE2D_X(posInputs.positionSS)] = smp;
}
}