@animech-public/playcanvas
Version:
PlayCanvas WebGL game engine
148 lines (121 loc) • 4.4 kB
JavaScript
var transformVS = /* glsl */`
uniform vec4 uScreenSize;
uniform float projectionFlipY;
uniform vec4 morph_weights_a;
uniform vec4 morph_weights_b;
uniform vec4 morph_tex_params;
ivec2 getTextureMorphCoords() {
// turn morph_vertex_id into int grid coordinates
ivec2 textureSize = ivec2(morph_tex_params.xy);
int morphGridV = int(morph_vertex_id / textureSize.x);
int morphGridU = int(morph_vertex_id - (morphGridV * textureSize.x));
morphGridV = textureSize.y - morphGridV - 1;
return ivec2(morphGridU, morphGridV);
}
vec2 getTextureMorphCoords() {
vec2 textureSize = morph_tex_params.xy;
vec2 invTextureSize = morph_tex_params.zw;
// turn morph_vertex_id into int grid coordinates
float morphGridV = floor(morph_vertex_id * invTextureSize.x);
float morphGridU = morph_vertex_id - (morphGridV * textureSize.x);
// convert grid coordinates to uv coordinates with half pixel offset
return vec2(morphGridU, morphGridV) * invTextureSize + (0.5 * invTextureSize);
}
uniform highp sampler2D morphPositionTex;
mat4 getModelMatrix() {
return getBoneMatrix(vertex_boneIndices);
return matrix_model * getSkinMatrix(vertex_boneIndices, vertex_boneWeights);
return mat4(instance_line1, instance_line2, instance_line3, instance_line4);
return matrix_model;
}
vec4 getPosition() {
dModelMatrix = getModelMatrix();
vec3 localPos = vertex_position;
// outer and inner vertices are at the same position, scale both
localPos.xz *= outerScale;
// offset inner vertices inside
// (original vertices must be in [-1;1] range)
vec2 positiveUnitOffset = clamp(vertex_position.xz, vec2(0.0), vec2(1.0));
vec2 negativeUnitOffset = clamp(-vertex_position.xz, vec2(0.0), vec2(1.0));
localPos.xz += (-positiveUnitOffset * innerOffset.xy + negativeUnitOffset * innerOffset.zw) * vertex_texCoord0.xy;
vTiledUv = (localPos.xz - outerScale + innerOffset.xy) * -0.5 + 1.0; // uv = local pos - inner corner
localPos.xz *= -0.5; // move from -1;1 to -0.5;0.5
localPos = localPos.xzy;
localPos.xyz += morph_weights_a[0] * morph_pos0;
localPos.xyz += morph_weights_a[1] * morph_pos1;
localPos.xyz += morph_weights_a[2] * morph_pos2;
localPos.xyz += morph_weights_a[3] * morph_pos3;
localPos.xyz += morph_weights_b[0] * morph_pos4;
localPos.xyz += morph_weights_b[1] * morph_pos5;
localPos.xyz += morph_weights_b[2] * morph_pos6;
localPos.xyz += morph_weights_b[3] * morph_pos7;
ivec2 morphUV = getTextureMorphCoords();
vec3 morphPos = texelFetch(morphPositionTex, ivec2(morphUV), 0).xyz;
vec2 morphUV = getTextureMorphCoords();
vec3 morphPos = texture2D(morphPositionTex, morphUV).xyz;
localPos += morphPos;
vec4 posW = dModelMatrix * vec4(localPos, 1.0);
posW.zw = vec2(0.0, 1.0);
dPositionW = posW.xyz;
vec4 screenPos;
screenPos = vec4(vertex_texCoord1.xy * 2.0 - 1.0, 0.5, 1);
screenPos.y *= -1.0;
screenPos = posW;
screenPos.y *= projectionFlipY;
screenPos = matrix_viewProjection * posW;
// snap vertex to a pixel boundary
screenPos.xy = (screenPos.xy * 0.5) + 0.5;
screenPos.xy *= uScreenSize.xy;
screenPos.xy = floor(screenPos.xy);
screenPos.xy *= uScreenSize.zw;
screenPos.xy = (screenPos.xy * 2.0) - 1.0;
return screenPos;
}
vec3 getWorldPosition() {
return dPositionW;
}
`;
export { transformVS as default };