MetaCore/build_filament/shaders/minified/surface_getters.vs

259 lines
8.8 KiB
GLSL

#if CLIENT_MATERIAL_API_LEVEL < UNSTABLE_MATERIAL_API_LEVEL
mat4 getWorldFromModelMatrix() {
return object_uniforms_worldFromModelMatrix;
}
mat3 getWorldFromModelNormalMatrix() {
return object_uniforms_worldFromModelNormalMatrix;
}
#endif
float getObjectUserData() {
return object_uniforms_userData;
}
#if MATERIAL_FEATURE_LEVEL > 0
int getVertexIndex() {
#if defined(TARGET_METAL_ENVIRONMENT) || defined(TARGET_VULKAN_ENVIRONMENT) || defined(TARGET_WEBGPU_ENVIRONMENT)
return gl_VertexIndex;
#else
return gl_VertexID;
#endif
}
#endif
#if defined(VARIANT_HAS_SKINNING_OR_MORPHING)
#define MAX_SKINNING_BUFFER_WIDTH 2048u
vec3 mulBoneNormal(vec3 n, uint j) {
highp mat3 cof;
highp float a = bonesUniforms.bones[j].transform[0][0];
highp float b = bonesUniforms.bones[j].transform[0][1];
highp float c = bonesUniforms.bones[j].transform[0][2];
highp float d = bonesUniforms.bones[j].transform[1][0];
highp float e = bonesUniforms.bones[j].transform[1][1];
highp float f = bonesUniforms.bones[j].transform[1][2];
highp float g = bonesUniforms.bones[j].transform[2][0];
highp float h = bonesUniforms.bones[j].transform[2][1];
highp float i = bonesUniforms.bones[j].transform[2][2];
cof[0] = bonesUniforms.bones[j].cof0;
cof[1].xyz = vec3(
bonesUniforms.bones[j].cof1x,
a * i - c * g,
c * d - a * f);
cof[2].xyz = vec3(
d * h - e * g,
b * g - a * h,
a * e - b * d);
return normalize(cof * n);
}
vec3 mulBoneVertex(vec3 v, uint i) {
highp mat4x3 m = transpose(bonesUniforms.bones[i].transform);
return v.x * m[0].xyz + (v.y * m[1].xyz + (v.z * m[2].xyz + m[3].xyz));
}
void skinPosition(inout vec3 p, const uvec4 ids, const vec4 weights) {
if (weights.w >= 0.0) {
p = weights.x * mulBoneVertex(p, uint(ids.x))
+ weights.y * mulBoneVertex(p, uint(ids.y))
+ weights.z * mulBoneVertex(p, uint(ids.z))
+ weights.w * mulBoneVertex(p, uint(ids.w));
return;
}
vec3 posSum = weights.x * mulBoneVertex(p, uint(ids.x));
posSum += weights.y * mulBoneVertex(p, uint(ids.y));
posSum += weights.z * mulBoneVertex(p, uint(ids.z));
uint pairIndex = uint(-weights.w - 1.);
uint pairStop = pairIndex + uint(ids.w - 3u);
for (uint i = pairIndex; i < pairStop; ++i) {
ivec2 texcoord = ivec2(i % MAX_SKINNING_BUFFER_WIDTH, i / MAX_SKINNING_BUFFER_WIDTH);
vec2 indexWeight = texelFetch(sampler1_indicesAndWeights, texcoord, 0).rg;
posSum += mulBoneVertex(p, uint(indexWeight.r)) * indexWeight.g;
}
p = posSum;
}
void skinNormal(inout vec3 n, const uvec4 ids, const vec4 weights) {
if (weights.w >= 0.0) {
n = weights.x * mulBoneNormal(n, uint(ids.x))
+ weights.y * mulBoneNormal(n, uint(ids.y))
+ weights.z * mulBoneNormal(n, uint(ids.z))
+ weights.w * mulBoneNormal(n, uint(ids.w));
return;
}
vec3 normSum = weights.x * mulBoneNormal(n, uint(ids.x));
normSum += weights.y * mulBoneNormal(n, uint(ids.y));
normSum += weights.z * mulBoneNormal(n, uint(ids.z));
uint pairIndex = uint(-weights.w - 1.);
uint pairStop = pairIndex + uint(ids.w - 3u);
for (uint i = pairIndex; i < pairStop; i = i + 1u) {
ivec2 texcoord = ivec2(i % MAX_SKINNING_BUFFER_WIDTH, i / MAX_SKINNING_BUFFER_WIDTH);
vec2 indexWeight = texelFetch(sampler1_indicesAndWeights, texcoord, 0).rg;
normSum += mulBoneNormal(n, uint(indexWeight.r)) * indexWeight.g;
}
n = normSum;
}
void skinNormalTangent(inout vec3 n, inout vec3 t, const uvec4 ids, const vec4 weights) {
if (weights.w >= 0.0) {
n = weights.x * mulBoneNormal(n, uint(ids.x))
+ weights.y * mulBoneNormal(n, uint(ids.y))
+ weights.z * mulBoneNormal(n, uint(ids.z))
+ weights.w * mulBoneNormal(n, uint(ids.w));
t = weights.x * mulBoneNormal(t, uint(ids.x))
+ weights.y * mulBoneNormal(t, uint(ids.y))
+ weights.z * mulBoneNormal(t, uint(ids.z))
+ weights.w * mulBoneNormal(t, uint(ids.w));
return;
}
vec3 normSum = weights.x * mulBoneNormal(n, uint(ids.x));
normSum += weights.y * mulBoneNormal(n, uint(ids.y)) ;
normSum += weights.z * mulBoneNormal(n, uint(ids.z));
vec3 tangSum = weights.x * mulBoneNormal(t, uint(ids.x));
tangSum += weights.y * mulBoneNormal(t, uint(ids.y));
tangSum += weights.z * mulBoneNormal(t, uint(ids.z));
uint pairIndex = uint(-weights.w - 1.);
uint pairStop = pairIndex + uint(ids.w - 3u);
for (uint i = pairIndex; i < pairStop; i = i + 1u) {
ivec2 texcoord = ivec2(i % MAX_SKINNING_BUFFER_WIDTH, i / MAX_SKINNING_BUFFER_WIDTH);
vec2 indexWeight = texelFetch(sampler1_indicesAndWeights, texcoord, 0).rg;
normSum += mulBoneNormal(n, uint(indexWeight.r)) * indexWeight.g;
tangSum += mulBoneNormal(t, uint(indexWeight.r)) * indexWeight.g;
}
n = normSum;
t = tangSum;
}
#define MAX_MORPH_TARGET_BUFFER_WIDTH 2048
#if CLIENT_MATERIAL_API_LEVEL >= UNSTABLE_MATERIAL_API_LEVEL
void morphData2(inout vec2 v, highp sampler2DArray data) {
int index = getVertexIndex() + pushConstants.morphingBufferOffset;
ivec3 texcoord = ivec3(index % MAX_MORPH_TARGET_BUFFER_WIDTH, index / MAX_MORPH_TARGET_BUFFER_WIDTH, 0);
int c = object_uniforms_morphTargetCount;
for (int i = 0; i < c; ++i) {
float w = morphingUniforms.weights[i][0];
if (w != 0.0) {
texcoord.z = i;
v += w * texelFetch(data, texcoord, 0).xy;
}
}
}
void morphData3(inout vec3 v, highp sampler2DArray data) {
int index = getVertexIndex() + pushConstants.morphingBufferOffset;
ivec3 texcoord = ivec3(index % MAX_MORPH_TARGET_BUFFER_WIDTH, index / MAX_MORPH_TARGET_BUFFER_WIDTH, 0);
int c = object_uniforms_morphTargetCount;
for (int i = 0; i < c; ++i) {
float w = morphingUniforms.weights[i][0];
if (w != 0.0) {
texcoord.z = i;
v += w * texelFetch(data, texcoord, 0).xyz;
}
}
}
void morphData4(inout vec4 v, highp sampler2DArray data) {
int index = getVertexIndex() + pushConstants.morphingBufferOffset;
ivec3 texcoord = ivec3(index % MAX_MORPH_TARGET_BUFFER_WIDTH, index / MAX_MORPH_TARGET_BUFFER_WIDTH, 0);
int c = object_uniforms_morphTargetCount;
for (int i = 0; i < c; ++i) {
float w = morphingUniforms.weights[i][0];
if (w != 0.0) {
texcoord.z = i;
v += w * texelFetch(data, texcoord, 0);
}
}
}
void morphPosition(inout vec4 p) {
morphData4(p, sampler1_positions);
}
#else
void morphPosition(inout vec4 p) {
int index = getVertexIndex() + pushConstants.morphingBufferOffset;
ivec3 texcoord = ivec3(index % MAX_MORPH_TARGET_BUFFER_WIDTH, index / MAX_MORPH_TARGET_BUFFER_WIDTH, 0);
int c = object_uniforms_morphTargetCount;
for (int i = 0; i < c; ++i) {
float w = morphingUniforms.weights[i][0];
if (w != 0.0) {
texcoord.z = i;
p += w * texelFetch(sampler1_positions, texcoord, 0);
}
}
}
#endif
void morphNormal(inout vec3 n) {
vec3 baseNormal = n;
int index = getVertexIndex() + pushConstants.morphingBufferOffset;
ivec3 texcoord = ivec3(index % MAX_MORPH_TARGET_BUFFER_WIDTH, index / MAX_MORPH_TARGET_BUFFER_WIDTH, 0);
int c = object_uniforms_morphTargetCount;
for (int i = 0; i < c; ++i) {
float w = morphingUniforms.weights[i][0];
if (w != 0.0) {
texcoord.z = i;
ivec4 tangent = texelFetch(sampler1_tangents, texcoord, 0);
vec3 normal;
toTangentFrame(float4(tangent) * (1.0 / 32767.0), normal);
n += w * (normal - baseNormal);
}
}
}
#endif
vec4 getPosition() {
vec4 pos = mesh_position;
#if defined(VARIANT_HAS_SKINNING_OR_MORPHING)
if ((object_uniforms_flagsChannels & FILAMENT_OBJECT_MORPHING_POSITION_BIT) != 0) {
#if defined(LEGACY_MORPHING)
pos += morphingUniforms.weights[0] * mesh_custom0;
pos += morphingUniforms.weights[1] * mesh_custom1;
pos += morphingUniforms.weights[2] * mesh_custom2;
pos += morphingUniforms.weights[3] * mesh_custom3;
#else
morphPosition(pos);
#endif
}
if ((object_uniforms_flagsChannels & FILAMENT_OBJECT_SKINNING_ENABLED_BIT) != 0) {
skinPosition(pos.xyz, mesh_bone_indices, mesh_bone_weights);
}
#endif
return pos;
}
#if defined(HAS_ATTRIBUTE_CUSTOM0)
vec4 getCustom0() { return mesh_custom0; }
#endif
#if defined(HAS_ATTRIBUTE_CUSTOM1)
vec4 getCustom1() { return mesh_custom1; }
#endif
#if defined(HAS_ATTRIBUTE_CUSTOM2)
vec4 getCustom2() { return mesh_custom2; }
#endif
#if defined(HAS_ATTRIBUTE_CUSTOM3)
vec4 getCustom3() { return mesh_custom3; }
#endif
#if defined(HAS_ATTRIBUTE_CUSTOM4)
vec4 getCustom4() { return mesh_custom4; }
#endif
#if defined(HAS_ATTRIBUTE_CUSTOM5)
vec4 getCustom5() { return mesh_custom5; }
#endif
#if defined(HAS_ATTRIBUTE_CUSTOM6)
vec4 getCustom6() { return mesh_custom6; }
#endif
#if defined(HAS_ATTRIBUTE_CUSTOM7)
vec4 getCustom7() { return mesh_custom7; }
#endif
vec4 computeWorldPosition() {
#if defined(VERTEX_DOMAIN_OBJECT)
mat4 transform = getWorldFromModelMatrix();
vec3 position = getPosition().xyz;
return mulMat4x4Float3(transform, position);
#elif defined(VERTEX_DOMAIN_WORLD)
return vec4(getPosition().xyz, 1.0);
#elif defined(VERTEX_DOMAIN_VIEW)
mat4 transform = getWorldFromViewMatrix();
vec3 position = getPosition().xyz;
return mulMat4x4Float3(transform, position);
#elif defined(VERTEX_DOMAIN_DEVICE)
mat4 transform = getWorldFromClipMatrix();
vec4 p = getPosition();
p.z = p.z * -0.5 + 0.5;
vec4 position = transform * p;
const highp float ALMOST_ZERO_FLT = 1.08420217249e-19;
if (abs(position.w) < ALMOST_ZERO_FLT) {
position.w = position.w < 0.0 ? -ALMOST_ZERO_FLT : ALMOST_ZERO_FLT;
}
return position * (1.0 / position.w);
#else
#error Unknown Vertex Domain
#endif
}