mirror of
https://github.com/scratchfoundation/bgfx.git
synced 2024-11-29 11:05:36 -05:00
99 lines
4 KiB
Text
99 lines
4 KiB
Text
|
#version 300 es
|
||
|
|
||
|
// From rcupisz light shafts package, "Coords" shader.
|
||
|
// Is using vector equality, which was translating wrong to Metal
|
||
|
// at some point.
|
||
|
|
||
|
#define gl_FragColor _glesFragData[0]
|
||
|
#define gl_FragData _glesFragData
|
||
|
layout(location = 0) out mediump vec4 _glesFragData[4];
|
||
|
float xll_saturate_f( float x) {
|
||
|
return clamp( x, 0.0, 1.0);
|
||
|
}
|
||
|
vec4 xll_matrixindex_mf4x4_i (mat4 m, int i) { vec4 v; v.x=m[0][i]; v.y=m[1][i]; v.z=m[2][i]; v.w=m[3][i]; return v; }
|
||
|
struct posuv {
|
||
|
highp vec4 pos;
|
||
|
highp vec2 uv;
|
||
|
};
|
||
|
uniform highp vec4 _ZBufferParams;
|
||
|
uniform highp vec4 _LightPos;
|
||
|
uniform highp float _InterpolationStep;
|
||
|
uniform highp mat4 _FrustumRays;
|
||
|
uniform highp vec4 _CameraPosLocal;
|
||
|
uniform highp float _FrustumApex;
|
||
|
uniform highp vec4 _CoordTexDim;
|
||
|
uniform highp vec4 _ScreenTexDim;
|
||
|
uniform sampler2D _CameraDepthTexture;
|
||
|
|
||
|
highp vec2 GetEpipolarLineEntryPoint( in highp vec2 exit ) {
|
||
|
return _LightPos.xy;
|
||
|
}
|
||
|
|
||
|
bool Cube( in highp vec3 org, in highp vec3 dir, out highp float tnear, out highp float tfar ) {
|
||
|
highp vec3 invR = (1.0 / dir);
|
||
|
highp vec3 tbot = (invR * (-0.5 - org));
|
||
|
highp vec3 ttop = (invR * (0.5 - org));
|
||
|
highp vec3 tmin = min( ttop, tbot);
|
||
|
highp vec3 tmax = max( ttop, tbot);
|
||
|
highp vec2 t0 = max( tmin.xx, tmin.yz);
|
||
|
tnear = max( t0.x, t0.y);
|
||
|
t0 = min( tmax.xx, tmax.yz);
|
||
|
tfar = min( t0.x, t0.y);
|
||
|
return ((tnear < tfar) && (tfar > 0.0));
|
||
|
}
|
||
|
highp vec3 FrustumRay( in highp vec2 uv, out highp float rayLength ) {
|
||
|
highp vec3 ray0 = mix( xll_matrixindex_mf4x4_i (_FrustumRays, 0).xyz, xll_matrixindex_mf4x4_i (_FrustumRays, 1).xyz, vec3( uv.x));
|
||
|
highp vec3 ray1 = mix( xll_matrixindex_mf4x4_i (_FrustumRays, 3).xyz, xll_matrixindex_mf4x4_i (_FrustumRays, 2).xyz, vec3( uv.x));
|
||
|
highp vec3 ray = mix( ray0, ray1, vec3( uv.y));
|
||
|
rayLength = length(ray);
|
||
|
return (ray / rayLength);
|
||
|
}
|
||
|
bool IntersectVolume( in highp vec2 uv, out highp float near, out highp float far, out highp vec3 rayN, out highp float rayLength ) {
|
||
|
rayN = FrustumRay( uv, rayLength);
|
||
|
return Cube( _CameraPosLocal.xyz, rayN, near, far);
|
||
|
}
|
||
|
highp float Linear01Depth( in highp float z ) {
|
||
|
return (1.0 / ((_ZBufferParams.x * z) + _ZBufferParams.y));
|
||
|
}
|
||
|
void frag( in posuv i, out highp vec4 coord, out highp vec4 depth ) {
|
||
|
highp vec2 uv = i.uv;
|
||
|
highp float sampleOnEpipolarLine = (uv.x - (0.5 / _CoordTexDim.x));
|
||
|
highp float epipolarLine = xll_saturate_f((uv.y - (0.5 / _CoordTexDim.y)));
|
||
|
sampleOnEpipolarLine *= (_CoordTexDim.x / (_CoordTexDim.x - 1.0));
|
||
|
sampleOnEpipolarLine = xll_saturate_f(sampleOnEpipolarLine);
|
||
|
highp int edge = int(clamp( floor((epipolarLine * 4.0)), 0.0, 3.0));
|
||
|
highp float posOnEdge = fract((epipolarLine * 4.0));
|
||
|
highp float edgeCoord = (-1.0 + (2.0 * posOnEdge));
|
||
|
highp vec4 edgeX = vec4( -1.0, edgeCoord, 1.0, (-edgeCoord));
|
||
|
highp vec4 edgeY = vec4( (-edgeCoord), -1.0, edgeCoord, 1.0);
|
||
|
bvec4 edgeFlags = equal( ivec4( edge), ivec4( 0, 1, 2, 3));
|
||
|
highp vec2 exit = (-vec2( dot( edgeY, vec4(edgeFlags)), dot( edgeX, vec4(edgeFlags))));
|
||
|
highp vec2 entry = GetEpipolarLineEntryPoint( exit);
|
||
|
highp vec2 coordTemp = mix( entry, exit, vec2( sampleOnEpipolarLine));
|
||
|
coordTemp = ((coordTemp * 0.5) + 0.5);
|
||
|
coord = vec4( coordTemp.x, coordTemp.y, 0.0, 0.0);
|
||
|
coordTemp = ((floor((coordTemp * _ScreenTexDim.xy)) + 0.5) * _ScreenTexDim.zw);
|
||
|
depth = vec4( Linear01Depth( texture( _CameraDepthTexture, coordTemp).x));
|
||
|
highp float near;
|
||
|
highp float far;
|
||
|
highp float rayLength;
|
||
|
highp vec3 rayN;
|
||
|
if (((!IntersectVolume( coord.xy, near, far, rayN, rayLength)) || (depth.x < (near / rayLength)))){
|
||
|
depth *= -1.0;
|
||
|
}
|
||
|
else{
|
||
|
depth = min( depth, vec4( (far / rayLength)));
|
||
|
}
|
||
|
}
|
||
|
in highp vec2 xlv_TEXCOORD0;
|
||
|
void main() {
|
||
|
posuv xlt_i;
|
||
|
xlt_i.pos = vec4(0.0);
|
||
|
xlt_i.uv = vec2(xlv_TEXCOORD0);
|
||
|
highp vec4 xlt_coord;
|
||
|
highp vec4 xlt_depth;
|
||
|
frag( xlt_i, xlt_coord, xlt_depth);
|
||
|
gl_FragData[0] = vec4(xlt_coord);
|
||
|
gl_FragData[1] = vec4(xlt_depth);
|
||
|
}
|