#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); }