e75add42c9
These are mapped to Metal's post-tessellation vertex functions. The semantic difference is much less here, so this change should be simpler than the previous one. There are still some hairy parts, though. In MSL, the array of control point data is represented by a special type, `patch_control_point<T>`, where `T` is a valid stage-input type. This object must be embedded inside the patch-level stage input. For this reason, I've added a new type to the type system to represent this. On Mac, the number of input control points to the function must be specified in the `patch()` attribute. This is optional on iOS. SPIRV-Cross takes this from the `OutputVertices` execution mode; the intent is that if it's not set in the shader itself, MoltenVK will set it from the tessellation control shader. If you're translating these offline, you'll have to update the control point count manually, since this number must match the number that is passed to the `drawPatches:...` family of methods. Fixes #120.
66 lines
1.8 KiB
GLSL
66 lines
1.8 KiB
GLSL
#version 310 es
|
|
#extension GL_EXT_tessellation_shader : require
|
|
precision highp int;
|
|
|
|
layout(cw, quads, fractional_even_spacing) in;
|
|
|
|
layout(location = 0) patch in vec2 vOutPatchPosBase;
|
|
layout(location = 1) patch in vec4 vPatchLods;
|
|
|
|
layout(binding = 1, std140) uniform UBO
|
|
{
|
|
mat4 uMVP;
|
|
vec4 uScale;
|
|
vec2 uInvScale;
|
|
vec3 uCamPos;
|
|
vec2 uPatchSize;
|
|
vec2 uInvHeightmapSize;
|
|
};
|
|
layout(binding = 0) uniform mediump sampler2D uHeightmapDisplacement;
|
|
|
|
layout(location = 0) highp out vec3 vWorld;
|
|
layout(location = 1) highp out vec4 vGradNormalTex;
|
|
|
|
vec2 lerp_vertex(vec2 tess_coord)
|
|
{
|
|
return vOutPatchPosBase + tess_coord * uPatchSize;
|
|
}
|
|
|
|
mediump vec2 lod_factor(vec2 tess_coord)
|
|
{
|
|
mediump vec2 x = mix(vPatchLods.yx, vPatchLods.zw, 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 + 0.5 * off, lod.x).xyz,
|
|
textureLod(uHeightmapDisplacement, uv + 1.0 * off, lod.x + 1.0).xyz,
|
|
lod.y);
|
|
}
|
|
|
|
void main()
|
|
{
|
|
vec2 tess_coord = gl_TessCoord.xy;
|
|
vec2 pos = lerp_vertex(tess_coord);
|
|
mediump vec2 lod = lod_factor(tess_coord);
|
|
|
|
vec2 tex = pos * uInvHeightmapSize.xy;
|
|
pos *= uScale.xy;
|
|
|
|
mediump float delta_mod = exp2(lod.x);
|
|
vec2 off = uInvHeightmapSize.xy * delta_mod;
|
|
|
|
vGradNormalTex = vec4(tex + 0.5 * uInvHeightmapSize.xy, tex * uScale.zw);
|
|
vec3 height_displacement = sample_height_displacement(tex, off, lod);
|
|
|
|
pos += height_displacement.yz;
|
|
vWorld = vec3(pos.x, height_displacement.x, pos.y);
|
|
gl_Position = uMVP * vec4(vWorld, 1.0);
|
|
}
|
|
|