SPIRV-Cross/reference/shaders/tesc/water_tess.tesc
Hans-Kristian Arntzen 36a0b63f28 Fix various corner cases with expression dependencies.
There was a potential problem if variables were invalidated and SPIR-V
read expressions which depended on other expression which in turn depended on the
invalidated variable.

Also fixes issue where variables were considered immutable if they were
forwardable. This allowed some incorrect optimizations to slip through.
2016-07-12 14:50:23 +02:00

119 lines
3.7 KiB
GLSL

#version 310 es
#extension GL_EXT_tessellation_shader : require
layout(vertices = 1) out;
layout(std140) uniform UBO
{
vec4 uScale;
vec3 uCamPos;
vec2 uPatchSize;
vec2 uMaxTessLevel;
float uDistanceMod;
vec4 uFrustum[6];
} _41;
out patch vec2 vOutPatchPosBase;
out patch vec4 vPatchLods;
in vec2 vPatchPosBase[32];
bool frustum_cull(vec2 p0)
{
vec2 min_xz = ((p0 - vec2(10.0)) * _41.uScale.xy);
vec2 max_xz = (((p0 + _41.uPatchSize) + vec2(10.0)) * _41.uScale.xy);
vec3 bb_min = vec3(min_xz.x, -10.0, min_xz.y);
vec3 bb_max = vec3(max_xz.x, 10.0, max_xz.y);
vec3 center = ((bb_min + bb_max) * 0.5);
float radius = (0.5 * length((bb_max - bb_min)));
vec3 f0 = vec3(dot(_41.uFrustum[0], vec4(center, 1.0)), dot(_41.uFrustum[1], vec4(center, 1.0)), dot(_41.uFrustum[2], vec4(center, 1.0)));
vec3 f1 = vec3(dot(_41.uFrustum[3], vec4(center, 1.0)), dot(_41.uFrustum[4], vec4(center, 1.0)), dot(_41.uFrustum[5], vec4(center, 1.0)));
vec3 _199 = f0;
bool _205 = any(lessThanEqual(_199, vec3((-radius))));
bool _215;
if ((!_205))
{
_215 = any(lessThanEqual(f1, vec3((-radius))));
}
else
{
_215 = _205;
}
return (!_215);
}
float lod_factor(vec2 pos_)
{
vec2 pos = (pos_ * _41.uScale.xy);
vec3 dist_to_cam = (_41.uCamPos - vec3(pos.x, 0.0, pos.y));
float level = log2(((length(dist_to_cam) + 9.9999997473787516355514526367188e-05) * _41.uDistanceMod));
return clamp(level, 0.0, _41.uMaxTessLevel.x);
}
vec4 tess_level(vec4 lod)
{
return (exp2((-lod)) * _41.uMaxTessLevel.y);
}
float tess_level(float lod)
{
return (_41.uMaxTessLevel.y * exp2((-lod)));
}
void compute_tess_levels(vec2 p0)
{
vOutPatchPosBase = p0;
vec2 param = (p0 + (vec2(-0.5) * _41.uPatchSize));
float l00 = lod_factor(param);
vec2 param_1 = (p0 + (vec2(0.5, -0.5) * _41.uPatchSize));
float l10 = lod_factor(param_1);
vec2 param_2 = (p0 + (vec2(1.5, -0.5) * _41.uPatchSize));
float l20 = lod_factor(param_2);
vec2 param_3 = (p0 + (vec2(-0.5, 0.5) * _41.uPatchSize));
float l01 = lod_factor(param_3);
vec2 param_4 = (p0 + (vec2(0.5) * _41.uPatchSize));
float l11 = lod_factor(param_4);
vec2 param_5 = (p0 + (vec2(1.5, 0.5) * _41.uPatchSize));
float l21 = lod_factor(param_5);
vec2 param_6 = (p0 + (vec2(-0.5, 1.5) * _41.uPatchSize));
float l02 = lod_factor(param_6);
vec2 param_7 = (p0 + (vec2(0.5, 1.5) * _41.uPatchSize));
float l12 = lod_factor(param_7);
vec2 param_8 = (p0 + (vec2(1.5) * _41.uPatchSize));
float l22 = lod_factor(param_8);
vec4 lods = vec4(dot(vec4(l01, l11, l02, l12), vec4(0.25)), dot(vec4(l00, l10, l01, l11), vec4(0.25)), dot(vec4(l10, l20, l11, l21), vec4(0.25)), dot(vec4(l11, l21, l12, l22), vec4(0.25)));
vPatchLods = lods;
vec4 outer_lods = min(lods, lods.yzwx);
vec4 param_9 = outer_lods;
vec4 levels = tess_level(param_9);
gl_TessLevelOuter[0] = levels.x;
gl_TessLevelOuter[1] = levels.y;
gl_TessLevelOuter[2] = levels.z;
gl_TessLevelOuter[3] = levels.w;
float min_lod = min(min(lods.x, lods.y), min(lods.z, lods.w));
float param_10 = min(min_lod, l11);
float inner = tess_level(param_10);
gl_TessLevelInner[0] = inner;
gl_TessLevelInner[1] = inner;
}
void main()
{
vec2 p0 = vPatchPosBase[0];
vec2 param = p0;
vec2 param_1;
if ((!frustum_cull(param)))
{
gl_TessLevelOuter[0] = -1.0;
gl_TessLevelOuter[1] = -1.0;
gl_TessLevelOuter[2] = -1.0;
gl_TessLevelOuter[3] = -1.0;
gl_TessLevelInner[0] = -1.0;
gl_TessLevelInner[1] = -1.0;
}
else
{
param_1 = p0;
compute_tess_levels(param_1);
}
}