#version 310 es #extension GL_EXT_tessellation_shader : require layout(quads, cw, fractional_even_spacing) in; layout(binding = 1, std140) uniform UBO { mat4 uMVP; vec4 uScale; vec2 uInvScale; vec3 uCamPos; vec2 uPatchSize; vec2 uInvHeightmapSize; } _31; layout(binding = 0) uniform mediump sampler2D uHeightmapDisplacement; in patch vec2 vOutPatchPosBase; in patch vec4 vPatchLods; out vec4 vGradNormalTex; out vec3 vWorld; vec2 lerp_vertex(vec2 tess_coord) { return (vOutPatchPosBase + (tess_coord * _31.uPatchSize)); } mediump vec2 lod_factor(vec2 tess_coord) { mediump vec2 x = mix(vPatchLods.yx, vPatchLods.zw, vec2(tess_coord.x)); mediump float level = mix(x.x, x.y, tess_coord.y); mediump float floor_level = floor(level); mediump float fract_level = (level - floor_level); return vec2(floor_level, fract_level); } mediump vec3 sample_height_displacement(vec2 uv, vec2 off, mediump vec2 lod) { return mix(textureLod(uHeightmapDisplacement, (uv + (off * 0.5)), lod.x).xyz, textureLod(uHeightmapDisplacement, (uv + (off * 1.0)), (lod.x + 1.0)).xyz, vec3(lod.y)); } void main() { vec2 tess_coord = gl_TessCoord.xy; vec2 param = tess_coord; vec2 pos = lerp_vertex(param); vec2 param_1 = tess_coord; mediump vec2 lod = lod_factor(param_1); vec2 tex = (pos * _31.uInvHeightmapSize); pos = (pos * _31.uScale.xy); mediump float delta_mod = exp2(lod.x); vec2 off = (_31.uInvHeightmapSize * delta_mod); vGradNormalTex = vec4((tex + (_31.uInvHeightmapSize * 0.5)), (tex * _31.uScale.zw)); vec2 param_2 = tex; vec2 param_3 = off; vec2 param_4 = lod; vec3 height_displacement = sample_height_displacement(param_2, param_3, param_4); pos = (pos + height_displacement.yz); vWorld = vec3(pos.x, height_displacement.x, pos.y); gl_Position = (_31.uMVP * vec4(vWorld, 1.0)); }