1
0
mirror of https://github.com/godotengine/godot.git synced 2025-11-05 12:10:55 +00:00

Fix Octahedral/Split Stream Options

Update mesh_surface_get_format_stride and
mesh_surface_make_offsets_from_format to return an array of offsets and
an array of strides in order to support vertex stream splitting

Update _get_array_from_surface to also support vertex stream splitting

Add a condition on split stream usage to ensure it does not get used on
dynamic meshes

Handle case when Tangent is compressed but Normal is not compressed

Make stream splitting option require a restart in the settings

Update SoftBody and Sprite3D to support and use strides and offsets
returned by updated visual_server functions

Update Sprite3D to use the dynamic mesh flag
This commit is contained in:
Omar El Sheikh
2021-08-16 20:41:43 -04:00
parent 4032d26dd5
commit a63028e172
9 changed files with 150 additions and 67 deletions

View File

@@ -844,17 +844,24 @@ Error VisualServer::_surface_set_data(Array p_arrays, uint32_t p_format, uint32_
uint32_t VisualServer::mesh_surface_get_format_offset(uint32_t p_format, int p_vertex_len, int p_index_len, int p_array_index) const {
uint32_t offsets[ARRAY_MAX];
mesh_surface_make_offsets_from_format(p_format, p_vertex_len, p_index_len, offsets);
uint32_t strides[ARRAY_MAX];
mesh_surface_make_offsets_from_format(p_format, p_vertex_len, p_index_len, offsets, strides);
return offsets[p_array_index];
}
uint32_t VisualServer::mesh_surface_get_format_stride(uint32_t p_format, int p_vertex_len, int p_index_len) const {
uint32_t VisualServer::mesh_surface_get_format_stride(uint32_t p_format, int p_vertex_len, int p_index_len, int p_array_index) const {
uint32_t offsets[ARRAY_MAX];
return mesh_surface_make_offsets_from_format(p_format, p_vertex_len, p_index_len, offsets);
uint32_t strides[ARRAY_MAX];
mesh_surface_make_offsets_from_format(p_format, p_vertex_len, p_index_len, offsets, strides);
return strides[p_array_index];
}
uint32_t VisualServer::mesh_surface_make_offsets_from_format(uint32_t p_format, int p_vertex_len, int p_index_len, uint32_t *r_offsets) const {
int total_elem_size = 0;
void VisualServer::mesh_surface_make_offsets_from_format(uint32_t p_format, int p_vertex_len, int p_index_len, uint32_t *r_offsets, uint32_t *r_strides) const {
bool use_split_stream = GLOBAL_GET("rendering/mesh_storage/split_stream") && !(p_format & VS::ARRAY_FLAG_USE_DYNAMIC_UPDATE);
int attributes_base_offset = 0;
int attributes_stride = 0;
int positions_stride = 0;
for (int i = 0; i < VS::ARRAY_MAX; i++) {
r_offsets[i] = 0; //reset
@@ -883,6 +890,14 @@ uint32_t VisualServer::mesh_surface_make_offsets_from_format(uint32_t p_format,
elem_size = 8;
}
r_offsets[i] = 0;
positions_stride = elem_size;
if (use_split_stream) {
attributes_base_offset = elem_size * p_vertex_len;
} else {
attributes_base_offset = elem_size;
}
} break;
case VS::ARRAY_NORMAL: {
if (p_format & ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION) {
@@ -901,12 +916,14 @@ uint32_t VisualServer::mesh_surface_make_offsets_from_format(uint32_t p_format,
elem_size = sizeof(float) * 3;
}
}
r_offsets[i] = attributes_base_offset + attributes_stride;
attributes_stride += elem_size;
} break;
case VS::ARRAY_TANGENT: {
if (p_format & ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION) {
if (p_format & ARRAY_COMPRESS_TANGENT) {
if (p_format & ARRAY_COMPRESS_TANGENT && (p_format & ARRAY_FORMAT_NORMAL) && (p_format & ARRAY_COMPRESS_NORMAL)) {
elem_size = sizeof(uint8_t) * 2;
} else {
elem_size = sizeof(uint16_t) * 2;
@@ -918,6 +935,8 @@ uint32_t VisualServer::mesh_surface_make_offsets_from_format(uint32_t p_format,
elem_size = sizeof(float) * 4;
}
}
r_offsets[i] = attributes_base_offset + attributes_stride;
attributes_stride += elem_size;
} break;
case VS::ARRAY_COLOR: {
@@ -926,6 +945,9 @@ uint32_t VisualServer::mesh_surface_make_offsets_from_format(uint32_t p_format,
} else {
elem_size = sizeof(float) * 4;
}
r_offsets[i] = attributes_base_offset + attributes_stride;
attributes_stride += elem_size;
} break;
case VS::ARRAY_TEX_UV: {
if (p_format & ARRAY_COMPRESS_TEX_UV) {
@@ -933,6 +955,8 @@ uint32_t VisualServer::mesh_surface_make_offsets_from_format(uint32_t p_format,
} else {
elem_size = sizeof(float) * 2;
}
r_offsets[i] = attributes_base_offset + attributes_stride;
attributes_stride += elem_size;
} break;
@@ -942,6 +966,8 @@ uint32_t VisualServer::mesh_surface_make_offsets_from_format(uint32_t p_format,
} else {
elem_size = sizeof(float) * 2;
}
r_offsets[i] = attributes_base_offset + attributes_stride;
attributes_stride += elem_size;
} break;
case VS::ARRAY_WEIGHTS: {
@@ -950,6 +976,8 @@ uint32_t VisualServer::mesh_surface_make_offsets_from_format(uint32_t p_format,
} else {
elem_size = sizeof(float) * 4;
}
r_offsets[i] = attributes_base_offset + attributes_stride;
attributes_stride += elem_size;
} break;
case VS::ARRAY_BONES: {
@@ -958,6 +986,8 @@ uint32_t VisualServer::mesh_surface_make_offsets_from_format(uint32_t p_format,
} else {
elem_size = sizeof(uint32_t);
}
r_offsets[i] = attributes_base_offset + attributes_stride;
attributes_stride += elem_size;
} break;
case VS::ARRAY_INDEX: {
@@ -976,21 +1006,28 @@ uint32_t VisualServer::mesh_surface_make_offsets_from_format(uint32_t p_format,
continue;
}
default: {
ERR_FAIL_V(0);
ERR_FAIL();
}
}
r_offsets[i] = total_elem_size;
total_elem_size += elem_size;
}
return total_elem_size;
if (use_split_stream) {
r_strides[VS::ARRAY_VERTEX] = positions_stride;
for (int i = 1; i < VS::ARRAY_MAX - 1; i++) {
r_strides[i] = attributes_stride;
}
} else {
for (int i = 0; i < VS::ARRAY_MAX - 1; i++) {
r_strides[i] = positions_stride + attributes_stride;
}
}
}
void VisualServer::mesh_add_surface_from_arrays(RID p_mesh, PrimitiveType p_primitive, const Array &p_arrays, const Array &p_blend_shapes, uint32_t p_compress_format) {
ERR_FAIL_INDEX(p_primitive, VS::PRIMITIVE_MAX);
ERR_FAIL_COND(p_arrays.size() != VS::ARRAY_MAX);
bool use_split_stream = GLOBAL_GET("rendering/mesh_storage/split_stream");
bool use_split_stream = GLOBAL_GET("rendering/mesh_storage/split_stream") && !(p_compress_format & VS::ARRAY_FLAG_USE_DYNAMIC_UPDATE);
uint32_t format = 0;
@@ -1116,7 +1153,7 @@ void VisualServer::mesh_add_surface_from_arrays(RID p_mesh, PrimitiveType p_prim
case VS::ARRAY_TANGENT: {
if (p_compress_format & ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION) {
if (p_compress_format & ARRAY_COMPRESS_TANGENT) {
if (p_compress_format & ARRAY_COMPRESS_TANGENT && (format & ARRAY_FORMAT_NORMAL) && (p_compress_format & ARRAY_COMPRESS_NORMAL)) {
elem_size = sizeof(uint8_t) * 2;
} else {
elem_size = sizeof(uint16_t) * 2;
@@ -1266,9 +1303,14 @@ void VisualServer::mesh_add_surface_from_arrays(RID p_mesh, PrimitiveType p_prim
}
Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_t> p_vertex_data, int p_vertex_len, PoolVector<uint8_t> p_index_data, int p_index_len) const {
uint32_t offsets[ARRAY_MAX];
bool use_split_stream = GLOBAL_GET("rendering/mesh_storage/split_stream") && !(p_format & VS::ARRAY_FLAG_USE_DYNAMIC_UPDATE);
int total_elem_size = 0;
uint32_t offsets[ARRAY_MAX];
uint32_t strides[VS::ARRAY_MAX];
int attributes_base_offset = 0;
int attributes_stride = 0;
int positions_stride = 0;
for (int i = 0; i < VS::ARRAY_MAX; i++) {
offsets[i] = 0; //reset
@@ -1278,7 +1320,6 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
}
int elem_size = 0;
switch (i) {
case VS::ARRAY_VERTEX: {
if (p_format & ARRAY_FLAG_USE_2D_VERTICES) {
@@ -1297,6 +1338,14 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
elem_size = 8;
}
offsets[i] = 0;
positions_stride = elem_size;
if (use_split_stream) {
attributes_base_offset = elem_size * p_vertex_len;
} else {
attributes_base_offset = elem_size;
}
} break;
case VS::ARRAY_NORMAL: {
if (p_format & ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION) {
@@ -1315,12 +1364,14 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
elem_size = sizeof(float) * 3;
}
}
offsets[i] = attributes_base_offset + attributes_stride;
attributes_stride += elem_size;
} break;
case VS::ARRAY_TANGENT: {
if (p_format & ARRAY_FLAG_USE_OCTAHEDRAL_COMPRESSION) {
if (p_format & ARRAY_COMPRESS_TANGENT) {
if (p_format & ARRAY_COMPRESS_TANGENT && (p_format & ARRAY_FORMAT_NORMAL) && (p_format & ARRAY_COMPRESS_NORMAL)) {
elem_size = sizeof(uint8_t) * 2;
} else {
elem_size = sizeof(uint16_t) * 2;
@@ -1332,6 +1383,8 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
elem_size = sizeof(float) * 4;
}
}
offsets[i] = attributes_base_offset + attributes_stride;
attributes_stride += elem_size;
} break;
case VS::ARRAY_COLOR: {
@@ -1340,6 +1393,9 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
} else {
elem_size = sizeof(float) * 4;
}
offsets[i] = attributes_base_offset + attributes_stride;
attributes_stride += elem_size;
} break;
case VS::ARRAY_TEX_UV: {
if (p_format & ARRAY_COMPRESS_TEX_UV) {
@@ -1347,6 +1403,8 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
} else {
elem_size = sizeof(float) * 2;
}
offsets[i] = attributes_base_offset + attributes_stride;
attributes_stride += elem_size;
} break;
@@ -1356,6 +1414,8 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
} else {
elem_size = sizeof(float) * 2;
}
offsets[i] = attributes_base_offset + attributes_stride;
attributes_stride += elem_size;
} break;
case VS::ARRAY_WEIGHTS: {
@@ -1364,6 +1424,8 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
} else {
elem_size = sizeof(float) * 4;
}
offsets[i] = attributes_base_offset + attributes_stride;
attributes_stride += elem_size;
} break;
case VS::ARRAY_BONES: {
@@ -1372,6 +1434,8 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
} else {
elem_size = sizeof(uint32_t);
}
offsets[i] = attributes_base_offset + attributes_stride;
attributes_stride += elem_size;
} break;
case VS::ARRAY_INDEX: {
@@ -1393,9 +1457,17 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
ERR_FAIL_V(Array());
}
}
}
offsets[i] = total_elem_size;
total_elem_size += elem_size;
if (use_split_stream) {
strides[VS::ARRAY_VERTEX] = positions_stride;
for (int i = 1; i < VS::ARRAY_MAX - 1; i++) {
strides[i] = attributes_stride;
}
} else {
for (int i = 0; i < VS::ARRAY_MAX - 1; i++) {
strides[i] = positions_stride + attributes_stride;
}
}
Array ret;
@@ -1418,14 +1490,14 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
PoolVector<Vector2>::Write w = arr_2d.write();
for (int j = 0; j < p_vertex_len; j++) {
const uint16_t *v = (const uint16_t *)&r[j * total_elem_size + offsets[i]];
const uint16_t *v = (const uint16_t *)&r[j * strides[i] + offsets[i]];
w[j] = Vector2(Math::halfptr_to_float(&v[0]), Math::halfptr_to_float(&v[1]));
}
} else {
PoolVector<Vector2>::Write w = arr_2d.write();
for (int j = 0; j < p_vertex_len; j++) {
const float *v = (const float *)&r[j * total_elem_size + offsets[i]];
const float *v = (const float *)&r[j * strides[i] + offsets[i]];
w[j] = Vector2(v[0], v[1]);
}
}
@@ -1439,14 +1511,14 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
PoolVector<Vector3>::Write w = arr_3d.write();
for (int j = 0; j < p_vertex_len; j++) {
const uint16_t *v = (const uint16_t *)&r[j * total_elem_size + offsets[i]];
const uint16_t *v = (const uint16_t *)&r[j * strides[i] + offsets[i]];
w[j] = Vector3(Math::halfptr_to_float(&v[0]), Math::halfptr_to_float(&v[1]), Math::halfptr_to_float(&v[2]));
}
} else {
PoolVector<Vector3>::Write w = arr_3d.write();
for (int j = 0; j < p_vertex_len; j++) {
const float *v = (const float *)&r[j * total_elem_size + offsets[i]];
const float *v = (const float *)&r[j * strides[i] + offsets[i]];
w[j] = Vector3(v[0], v[1], v[2]);
}
}
@@ -1464,7 +1536,7 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
PoolVector<Vector3>::Write w = arr.write();
for (int j = 0; j < p_vertex_len; j++) {
const int8_t *n = (const int8_t *)&r[j * total_elem_size + offsets[i]];
const int8_t *n = (const int8_t *)&r[j * strides[i] + offsets[i]];
Vector2 enc(n[0] / 127.0f, n[1] / 127.0f);
w[j] = oct_to_norm(enc);
@@ -1473,7 +1545,7 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
PoolVector<Vector3>::Write w = arr.write();
for (int j = 0; j < p_vertex_len; j++) {
const int16_t *n = (const int16_t *)&r[j * total_elem_size + offsets[i]];
const int16_t *n = (const int16_t *)&r[j * strides[i] + offsets[i]];
Vector2 enc(n[0] / 32767.0f, n[1] / 32767.0f);
w[j] = oct_to_norm(enc);
@@ -1485,14 +1557,14 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
const float multiplier = 1.f / 127.f;
for (int j = 0; j < p_vertex_len; j++) {
const int8_t *v = (const int8_t *)&r[j * total_elem_size + offsets[i]];
const int8_t *v = (const int8_t *)&r[j * strides[i] + offsets[i]];
w[j] = Vector3(float(v[0]) * multiplier, float(v[1]) * multiplier, float(v[2]) * multiplier);
}
} else {
PoolVector<Vector3>::Write w = arr.write();
for (int j = 0; j < p_vertex_len; j++) {
const float *v = (const float *)&r[j * total_elem_size + offsets[i]];
const float *v = (const float *)&r[j * strides[i] + offsets[i]];
w[j] = Vector3(v[0], v[1], v[2]);
}
}
@@ -1511,7 +1583,7 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
PoolVector<float>::Write w = arr.write();
for (int j = 0; j < p_vertex_len; j++) {
const int8_t *t = (const int8_t *)&r[j * total_elem_size + offsets[i]];
const int8_t *t = (const int8_t *)&r[j * strides[i] + offsets[i]];
Vector2 enc(t[0] / 127.0f, t[1] / 127.0f);
Vector3 dec = oct_to_tangent(enc, &w[j * 4 + 3]);
@@ -1523,7 +1595,7 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
PoolVector<float>::Write w = arr.write();
for (int j = 0; j < p_vertex_len; j++) {
const int16_t *t = (const int16_t *)&r[j * total_elem_size + offsets[i]];
const int16_t *t = (const int16_t *)&r[j * strides[i] + offsets[i]];
Vector2 enc(t[0] / 32767.0f, t[1] / 32767.0f);
Vector3 dec = oct_to_tangent(enc, &w[j * 4 + 3]);
@@ -1537,7 +1609,7 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
PoolVector<float>::Write w = arr.write();
for (int j = 0; j < p_vertex_len; j++) {
const int8_t *v = (const int8_t *)&r[j * total_elem_size + offsets[i]];
const int8_t *v = (const int8_t *)&r[j * strides[i] + offsets[i]];
for (int k = 0; k < 4; k++) {
w[j * 4 + k] = float(v[k] / 127.0);
}
@@ -1546,7 +1618,7 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
PoolVector<float>::Write w = arr.write();
for (int j = 0; j < p_vertex_len; j++) {
const float *v = (const float *)&r[j * total_elem_size + offsets[i]];
const float *v = (const float *)&r[j * strides[i] + offsets[i]];
for (int k = 0; k < 4; k++) {
w[j * 4 + k] = v[k];
}
@@ -1565,14 +1637,14 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
PoolVector<Color>::Write w = arr.write();
for (int j = 0; j < p_vertex_len; j++) {
const uint8_t *v = (const uint8_t *)&r[j * total_elem_size + offsets[i]];
const uint8_t *v = (const uint8_t *)&r[j * strides[i] + offsets[i]];
w[j] = Color(float(v[0] / 255.0), float(v[1] / 255.0), float(v[2] / 255.0), float(v[3] / 255.0));
}
} else {
PoolVector<Color>::Write w = arr.write();
for (int j = 0; j < p_vertex_len; j++) {
const float *v = (const float *)&r[j * total_elem_size + offsets[i]];
const float *v = (const float *)&r[j * strides[i] + offsets[i]];
w[j] = Color(v[0], v[1], v[2], v[3]);
}
}
@@ -1587,14 +1659,14 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
PoolVector<Vector2>::Write w = arr.write();
for (int j = 0; j < p_vertex_len; j++) {
const uint16_t *v = (const uint16_t *)&r[j * total_elem_size + offsets[i]];
const uint16_t *v = (const uint16_t *)&r[j * strides[i] + offsets[i]];
w[j] = Vector2(Math::halfptr_to_float(&v[0]), Math::halfptr_to_float(&v[1]));
}
} else {
PoolVector<Vector2>::Write w = arr.write();
for (int j = 0; j < p_vertex_len; j++) {
const float *v = (const float *)&r[j * total_elem_size + offsets[i]];
const float *v = (const float *)&r[j * strides[i] + offsets[i]];
w[j] = Vector2(v[0], v[1]);
}
}
@@ -1610,14 +1682,14 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
PoolVector<Vector2>::Write w = arr.write();
for (int j = 0; j < p_vertex_len; j++) {
const uint16_t *v = (const uint16_t *)&r[j * total_elem_size + offsets[i]];
const uint16_t *v = (const uint16_t *)&r[j * strides[i] + offsets[i]];
w[j] = Vector2(Math::halfptr_to_float(&v[0]), Math::halfptr_to_float(&v[1]));
}
} else {
PoolVector<Vector2>::Write w = arr.write();
for (int j = 0; j < p_vertex_len; j++) {
const float *v = (const float *)&r[j * total_elem_size + offsets[i]];
const float *v = (const float *)&r[j * strides[i] + offsets[i]];
w[j] = Vector2(v[0], v[1]);
}
}
@@ -1632,7 +1704,7 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
PoolVector<float>::Write w = arr.write();
for (int j = 0; j < p_vertex_len; j++) {
const uint16_t *v = (const uint16_t *)&r[j * total_elem_size + offsets[i]];
const uint16_t *v = (const uint16_t *)&r[j * strides[i] + offsets[i]];
for (int k = 0; k < 4; k++) {
w[j * 4 + k] = float(v[k] / 65535.0);
}
@@ -1641,7 +1713,7 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
PoolVector<float>::Write w = arr.write();
for (int j = 0; j < p_vertex_len; j++) {
const float *v = (const float *)&r[j * total_elem_size + offsets[i]];
const float *v = (const float *)&r[j * strides[i] + offsets[i]];
for (int k = 0; k < 4; k++) {
w[j * 4 + k] = v[k];
}
@@ -1658,7 +1730,7 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
PoolVector<int>::Write w = arr.write();
for (int j = 0; j < p_vertex_len; j++) {
const uint16_t *v = (const uint16_t *)&r[j * total_elem_size + offsets[i]];
const uint16_t *v = (const uint16_t *)&r[j * strides[i] + offsets[i]];
for (int k = 0; k < 4; k++) {
w[j * 4 + k] = v[k];
}
@@ -1667,7 +1739,7 @@ Array VisualServer::_get_array_from_surface(uint32_t p_format, PoolVector<uint8_
PoolVector<int>::Write w = arr.write();
for (int j = 0; j < p_vertex_len; j++) {
const uint8_t *v = (const uint8_t *)&r[j * total_elem_size + offsets[i]];
const uint8_t *v = (const uint8_t *)&r[j * strides[i] + offsets[i]];
for (int k = 0; k < 4; k++) {
w[j * 4 + k] = v[k];
}
@@ -1809,7 +1881,7 @@ void VisualServer::_bind_methods() {
ClassDB::bind_method(D_METHOD("mesh_create"), &VisualServer::mesh_create);
ClassDB::bind_method(D_METHOD("mesh_surface_get_format_offset", "format", "vertex_len", "index_len", "array_index"), &VisualServer::mesh_surface_get_format_offset);
ClassDB::bind_method(D_METHOD("mesh_surface_get_format_stride", "format", "vertex_len", "index_len"), &VisualServer::mesh_surface_get_format_stride);
ClassDB::bind_method(D_METHOD("mesh_surface_get_format_stride", "format", "vertex_len", "index_len", "array_index"), &VisualServer::mesh_surface_get_format_stride);
ClassDB::bind_method(D_METHOD("mesh_add_surface_from_arrays", "mesh", "primitive", "arrays", "blend_shapes", "compress_format"), &VisualServer::mesh_add_surface_from_arrays, DEFVAL(Array()), DEFVAL(ARRAY_COMPRESS_DEFAULT));
ClassDB::bind_method(D_METHOD("mesh_set_blend_shape_count", "mesh", "amount"), &VisualServer::mesh_set_blend_shape_count);
ClassDB::bind_method(D_METHOD("mesh_get_blend_shape_count", "mesh"), &VisualServer::mesh_get_blend_shape_count);
@@ -2560,7 +2632,7 @@ VisualServer::VisualServer() {
GLOBAL_DEF("rendering/quality/shading/force_blinn_over_ggx", false);
GLOBAL_DEF("rendering/quality/shading/force_blinn_over_ggx.mobile", true);
GLOBAL_DEF("rendering/mesh_storage/split_stream", false);
GLOBAL_DEF_RST("rendering/mesh_storage/split_stream", false);
GLOBAL_DEF("rendering/quality/depth_prepass/enable", true);
GLOBAL_DEF("rendering/quality/depth_prepass/disable_for_vendors", "PowerVR,Mali,Adreno,Apple");