FSHo><      í  #version 430
out vec4 bgfx_FragColor;
#define gl_FragColor bgfx_FragColor
#define texture2DLod       textureLod
#define texture2DGrad      textureGrad
#define texture2DProjLod   textureProjLod
#define texture2DProjGrad  textureProjGrad
#define textureCubeLod     textureLod
#define textureCubeGrad    textureGrad
#define texture3D          texture
#define texture2DLofOffset textureLodOffset
#define attribute in
#define varying in
#define bgfxShadow2D(_sampler, _coord)     vec4_splat(texture(_sampler, _coord))
#define bgfxShadow2DProj(_sampler, _coord) vec4_splat(textureProj(_sampler, _coord))
varying vec2 v_texcoord0;
vec3 instMul(vec3 _vec, mat3 _mtx) { return ( (_vec) * (_mtx) ); }
vec3 instMul(mat3 _mtx, vec3 _vec) { return ( (_mtx) * (_vec) ); }
vec4 instMul(vec4 _vec, mat4 _mtx) { return ( (_vec) * (_mtx) ); }
vec4 instMul(mat4 _mtx, vec4 _vec) { return ( (_mtx) * (_vec) ); }
float rcp(float _a) { return 1.0/_a; }
vec2 rcp(vec2 _a) { return vec2(1.0)/_a; }
vec3 rcp(vec3 _a) { return vec3(1.0)/_a; }
vec4 rcp(vec4 _a) { return vec4(1.0)/_a; }
vec2 vec2_splat(float _x) { return vec2(_x, _x); }
vec3 vec3_splat(float _x) { return vec3(_x, _x, _x); }
vec4 vec4_splat(float _x) { return vec4(_x, _x, _x, _x); }
mat4 mtxFromRows(vec4 _0, vec4 _1, vec4 _2, vec4 _3)
{
return transpose(mat4(_0, _1, _2, _3) );
}
mat4 mtxFromCols(vec4 _0, vec4 _1, vec4 _2, vec4 _3)
{
return mat4(_0, _1, _2, _3);
}
mat3 mtxFromRows(vec3 _0, vec3 _1, vec3 _2)
{
return transpose(mat3(_0, _1, _2) );
}
mat3 mtxFromCols(vec3 _0, vec3 _1, vec3 _2)
{
return mat3(_0, _1, _2);
}
uniform vec4 u_viewRect;
uniform vec4 u_viewTexel;
uniform mat4 u_view;
uniform mat4 u_invView;
uniform mat4 u_proj;
uniform mat4 u_invProj;
uniform mat4 u_viewProj;
uniform mat4 u_invViewProj;
uniform mat4 u_model[32];
uniform mat4 u_modelView;
uniform mat4 u_modelViewProj;
uniform vec4 u_alphaRef4;
mat4x3 mtxFromRows(vec4 _0, vec4 _1, vec4 _2)
{
return transpose(mat3x4(_0, _1, _2) );
}
vec4 mtxGetRow(mat4x3 _0, uint row)
{
return vec4(_0[0][row], _0[1][row], _0[2][row], _0[3][row]);
}
vec4 mtxGetRow(mat4 _0, uint row)
{
return vec4(_0[0][row], _0[1][row], _0[2][row], _0[3][row]);
}
vec4 mtxGetColumn(mat4 _0, uint column)
{
return vec4(_0[column]);
}
float mtxGetElement(mat4 _0, uint column, uint row)
{
return _0[column][row];
}
uint findMSB_(uint x)
{
uint i;
uint mask;
uint res = -1;
for (i = 0; i < 32; i++)
{
mask = 0x80000000 >> i;
if ((x & mask) != 0)
{
res = 31 - i;
break;
}
}
return res;
}
uint parentKey(in uint key)
{
return (key >> 1u);
}
void childrenKeys(in uint key, out uint children[2])
{
children[0] = (key << 1u) | 0u;
children[1] = (key << 1u) | 1u;
}
bool isRootKey(in uint key)
{
return (key == 1u);
}
bool isLeafKey(in uint key)
{
return findMSB_(key) == 31;
}
bool isChildZeroKey(in uint key)
{
return ((key & 1u) == 0u);
}
vec3 berp(in vec3 v[3], in vec2 u)
{
return v[0] + u.x * (v[1] - v[0]) + u.y * (v[2] - v[0]);
}
vec4 berp(in vec4 v[3], in vec2 u)
{
return v[0] + u.x * (v[1] - v[0]) + u.y * (v[2] - v[0]);
}
mat3 bitToXform(in uint bit)
{
float b = float(bit);
float c = 1.0f - b;
vec3 c1 = vec3(0.0f, c , b );
vec3 c2 = vec3(0.5f, b , 0.0f);
vec3 c3 = vec3(0.5f, 0.0f, c );
return mtxFromCols(c1, c2, c3);
}
mat3 keyToXform(in uint key)
{
vec3 c1 = vec3(1.0f, 0.0f, 0.0f);
vec3 c2 = vec3(0.0f, 1.0f, 0.0f);
vec3 c3 = vec3(0.0f, 0.0f, 1.0f);
mat3 xf = mtxFromCols(c1, c2, c3);
while (key > 1u) {
xf = ( (xf) * (bitToXform(key & 1u)) );
key = key >> 1u;
}
return xf;
}
mat3 keyToXform(in uint key, out mat3 xfp)
{
xfp = keyToXform(parentKey(key));
return keyToXform(key);
}
void subd(in uint key, in vec4 v_in[3], out vec4 v_out[3])
{
mat3 xf = keyToXform(key);
mat4x3 m = mtxFromRows(v_in[0], v_in[1], v_in[2]);
mat4x3 v = ( (xf) * (m) );
v_out[0] = mtxGetRow(v, 0);
v_out[1] = mtxGetRow(v, 1);
v_out[2] = mtxGetRow(v, 2);
}
void subd(in uint key, in vec4 v_in[3], out vec4 v_out[3], out vec4 v_out_p[3])
{
mat3 xfp; mat3 xf = keyToXform(key, xfp);
mat4x3 m = mtxFromRows(v_in[0], v_in[1], v_in[2]);
mat4x3 v = ( (xf) * (m) );
mat4x3 vp = ( (xfp) * (m) );
v_out[0] = mtxGetRow(v, 0);
v_out[1] = mtxGetRow(v, 1);
v_out[2] = mtxGetRow(v, 2);
v_out_p[0] = mtxGetRow(vp, 0);
v_out_p[1] = mtxGetRow(vp, 1);
v_out_p[2] = mtxGetRow(vp, 2);
}
uniform vec4 u_params[2];
layout(std430, binding=4) buffer u_AtomicCounterBufferBuffer { uint u_AtomicCounterBuffer[]; };
layout(std430, binding=1) buffer u_SubdBufferOutBuffer { uint u_SubdBufferOut[]; };
uniform sampler2D u_DmapSampler;
uniform sampler2D u_SmapSampler;
float dmap(vec2 pos)
{
return (texture2DLod(u_DmapSampler, pos * 0.5 + 0.5, 0).x) * u_params[0].x;
}
float distanceToLod(float z, float lodFactor)
{
return -2.0 * log2(clamp(z * lodFactor, 0.0f, 1.0f));
}
float computeLod(vec3 c)
{
c.z += dmap(mtxGetColumn(u_invView, 3).xy);
vec3 cxf = ( (u_modelView) * (vec4(c.x, c.y, c.z, 1)) ).xyz;
float z = length(cxf);
return distanceToLod(z, u_params[0].y);
}
float computeLod(in vec4 v[3])
{
vec3 c = (v[1].xyz + v[2].xyz) / 2.0;
return computeLod(c);
}
float computeLod(in vec3 v[3])
{
vec3 c = (v[1].xyz + v[2].xyz) / 2.0;
return computeLod(c);
}
void writeKey(uint primID, uint key)
{
uint idx = 0;
idx = atomicAdd(u_AtomicCounterBuffer[0], 2);
u_SubdBufferOut[idx] = primID;
u_SubdBufferOut[idx+1] = key;
}
void updateSubdBuffer(
uint primID
, uint key
, uint targetLod
, uint parentLod
, bool isVisible
)
{
uint keyLod = findMSB_(key);
if ( keyLod < targetLod && !isLeafKey(key) && isVisible)
{
uint children[2]; childrenKeys(key, children);
writeKey(primID, children[0]);
writeKey(primID, children[1]);
}
else if ( keyLod < (parentLod + 1) && isVisible)
{
writeKey(primID, key);
}
else
{
if ( isRootKey(key))
{
writeKey(primID, key);
}
else if ( isChildZeroKey(key)) {
writeKey(primID, parentKey(key));
}
}
}
void updateSubdBuffer(uint primID, uint key, uint targetLod, uint parentLod)
{
updateSubdBuffer(primID, key, targetLod, parentLod, true);
}
void main()
{
vec2 s = texture2D(u_SmapSampler, v_texcoord0).rg * u_params[0].x;
vec3 n = normalize(vec3(-s, 1));
float d = clamp(n.z, 0.0, 1.0) / 3.14159;
vec3 r = vec3(d, d, d);
gl_FragColor = vec4(r, 1);
}
 