converted skeletons from uniform to texture

This commit is contained in:
Juan Linietsky 2017-03-12 13:08:56 -03:00
parent b043f0e77d
commit 6d15e15732
4 changed files with 189 additions and 141 deletions

View File

@ -1528,7 +1528,7 @@ void RasterizerSceneGLES3::_setup_light(RenderList::Element *e, const Transform
GIProbeInstance *gipi = gi_probe_instance_owner.getptr(ridp[0]); GIProbeInstance *gipi = gi_probe_instance_owner.getptr(ridp[0]);
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 6); glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 10);
glBindTexture(GL_TEXTURE_3D, gipi->tex_cache); glBindTexture(GL_TEXTURE_3D, gipi->tex_cache);
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_XFORM1, gipi->transform_to_data * p_view_transform); state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_XFORM1, gipi->transform_to_data * p_view_transform);
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_BOUNDS1, gipi->bounds); state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_BOUNDS1, gipi->bounds);
@ -1540,7 +1540,7 @@ void RasterizerSceneGLES3::_setup_light(RenderList::Element *e, const Transform
GIProbeInstance *gipi2 = gi_probe_instance_owner.getptr(ridp[1]); GIProbeInstance *gipi2 = gi_probe_instance_owner.getptr(ridp[1]);
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 7); glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 11);
glBindTexture(GL_TEXTURE_3D, gipi2->tex_cache); glBindTexture(GL_TEXTURE_3D, gipi2->tex_cache);
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_XFORM2, gipi2->transform_to_data * p_view_transform); state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_XFORM2, gipi2->transform_to_data * p_view_transform);
state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_BOUNDS2, gipi2->bounds); state.scene_shader.set_uniform(SceneShaderGLES3::GI_PROBE_BOUNDS2, gipi2->bounds);
@ -1804,24 +1804,26 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
} }
} }
if ((prev_base_type == VS::INSTANCE_MULTIMESH) != (e->instance->base_type == VS::INSTANCE_MULTIMESH)) {
state.scene_shader.set_conditional(SceneShaderGLES3::USE_INSTANCING, e->instance->base_type == VS::INSTANCE_MULTIMESH);
rebind = true;
}
if (prev_skeleton != skeleton) { if (prev_skeleton != skeleton) {
if (prev_skeleton.is_valid() != skeleton.is_valid()) { if (prev_skeleton.is_valid() != skeleton.is_valid()) {
state.scene_shader.set_conditional(SceneShaderGLES3::USE_SKELETON, skeleton.is_valid()); state.scene_shader.set_conditional(SceneShaderGLES3::USE_SKELETON, skeleton.is_valid());
rebind = true; rebind = true;
} }
if (skeleton.is_valid()) { if (skeleton.is_valid()) {
RasterizerStorageGLES3::Skeleton *sk = storage->skeleton_owner.getornull(skeleton); RasterizerStorageGLES3::Skeleton *sk = storage->skeleton_owner.getornull(skeleton);
if (sk->size) { glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 6);
glBindBufferBase(GL_UNIFORM_BUFFER, 7, sk->ubo); glBindTexture(GL_TEXTURE_2D,sk->texture);
}
} }
} }
if ((prev_base_type == VS::INSTANCE_MULTIMESH) != (e->instance->base_type == VS::INSTANCE_MULTIMESH)) {
state.scene_shader.set_conditional(SceneShaderGLES3::USE_INSTANCING, e->instance->base_type == VS::INSTANCE_MULTIMESH);
rebind = true;
}
if (material != prev_material || rebind) { if (material != prev_material || rebind) {
storage->info.render_material_switch_count++; storage->info.render_material_switch_count++;
@ -1833,6 +1835,8 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_
} }
} }
if (!(e->sort_key & RenderList::SORT_KEY_UNSHADED_FLAG) && !p_directional_add && !p_shadow) { if (!(e->sort_key & RenderList::SORT_KEY_UNSHADED_FLAG) && !p_directional_add && !p_shadow) {
_setup_light(e, p_view_transform); _setup_light(e, p_view_transform);
} }
@ -3567,7 +3571,7 @@ void RasterizerSceneGLES3::render_scene(const Transform &p_cam_transform, const
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0); glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0); glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
//bind depth for read //bind depth for read
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 8); glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 9);
glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->depth); glBindTexture(GL_TEXTURE_2D, storage->frame.current_rt->depth);
} }

View File

@ -3038,7 +3038,7 @@ Rect3 RasterizerStorageGLES3::mesh_get_aabb(RID p_mesh, RID p_skeleton) const {
int sbs = sk->size; int sbs = sk->size;
ERR_CONTINUE(bs > sbs); ERR_CONTINUE(bs > sbs);
float *skb = sk->bones.ptr(); const float *texture = sk->skel_texture.ptr();
bool first = true; bool first = true;
if (sk->use_2d) { if (sk->use_2d) {
@ -3047,16 +3047,18 @@ Rect3 RasterizerStorageGLES3::mesh_get_aabb(RID p_mesh, RID p_skeleton) const {
if (!skused[j]) if (!skused[j])
continue; continue;
float *dataptr = &skb[8 * j];
int base_ofs = ((j / 256) * 256) * 2 * 4 + (j % 256) * 4;
Transform mtx; Transform mtx;
mtx.basis.elements[0][0] = dataptr[0]; mtx.basis[0].x=texture[base_ofs+0];
mtx.basis.elements[0][1] = dataptr[1]; mtx.basis[0].y=texture[base_ofs+1];
mtx.origin[0] = dataptr[3]; mtx.origin.x=texture[base_ofs+3];
mtx.basis.elements[1][0] = dataptr[4]; base_ofs+=256*4;
mtx.basis.elements[1][1] = dataptr[5]; mtx.basis[1].x=texture[base_ofs+0];
mtx.origin[1] = dataptr[7]; mtx.basis[1].y=texture[base_ofs+1];
mtx.origin.y=texture[base_ofs+3];
Rect3 baabb = mtx.xform(skbones[j]); Rect3 baabb = mtx.xform(skbones[j]);
if (first) { if (first) {
@ -3072,21 +3074,24 @@ Rect3 RasterizerStorageGLES3::mesh_get_aabb(RID p_mesh, RID p_skeleton) const {
if (!skused[j]) if (!skused[j])
continue; continue;
float *dataptr = &skb[12 * j]; int base_ofs = ((j / 256) * 256) * 3 * 4 + (j % 256) * 4;
Transform mtx; Transform mtx;
mtx.basis.elements[0][0] = dataptr[0];
mtx.basis.elements[0][1] = dataptr[1]; mtx.basis[0].x=texture[base_ofs+0];
mtx.basis.elements[0][2] = dataptr[2]; mtx.basis[0].y=texture[base_ofs+1];
mtx.origin.x = dataptr[3]; mtx.basis[0].z=texture[base_ofs+2];
mtx.basis.elements[1][0] = dataptr[4]; mtx.origin.x=texture[base_ofs+3];
mtx.basis.elements[1][1] = dataptr[5]; base_ofs+=256*4;
mtx.basis.elements[1][2] = dataptr[6]; mtx.basis[1].x=texture[base_ofs+0];
mtx.origin.y = dataptr[7]; mtx.basis[1].y=texture[base_ofs+1];
mtx.basis.elements[2][0] = dataptr[8]; mtx.basis[1].z=texture[base_ofs+2];
mtx.basis.elements[2][1] = dataptr[9]; mtx.origin.y=texture[base_ofs+3];
mtx.basis.elements[2][2] = dataptr[10]; base_ofs+=256*4;
mtx.origin.z = dataptr[11]; mtx.basis[2].x=texture[base_ofs+0];
mtx.basis[2].y=texture[base_ofs+1];
mtx.basis[2].z=texture[base_ofs+2];
mtx.origin.z=texture[base_ofs+3];
Rect3 baabb = mtx.xform(skbones[j]); Rect3 baabb = mtx.xform(skbones[j]);
if (first) { if (first) {
@ -3921,6 +3926,9 @@ RID RasterizerStorageGLES3::immediate_get_material(RID p_immediate) const {
RID RasterizerStorageGLES3::skeleton_create() { RID RasterizerStorageGLES3::skeleton_create() {
Skeleton *skeleton = memnew(Skeleton); Skeleton *skeleton = memnew(Skeleton);
glGenTextures(1,&skeleton->texture);
return skeleton_owner.make_rid(skeleton); return skeleton_owner.make_rid(skeleton);
} }
@ -3933,49 +3941,28 @@ void RasterizerStorageGLES3::skeleton_allocate(RID p_skeleton, int p_bones, bool
if (skeleton->size == p_bones && skeleton->use_2d == p_2d_skeleton) if (skeleton->size == p_bones && skeleton->use_2d == p_2d_skeleton)
return; return;
if (skeleton->ubo) { skeleton->size=p_bones;
glDeleteBuffers(1, &skeleton->ubo); skeleton->use_2d=p_2d_skeleton;
skeleton->ubo = 0;
}
skeleton->size = p_bones; int height = p_bones/256;
if (p_2d_skeleton) { if (p_bones%256)
skeleton->bones.resize(p_bones * 8); height++;
for (int i = 0; i < skeleton->bones.size(); i += 8) {
skeleton->bones[i + 0] = 1;
skeleton->bones[i + 1] = 0;
skeleton->bones[i + 2] = 0;
skeleton->bones[i + 3] = 0;
skeleton->bones[i + 4] = 0;
skeleton->bones[i + 5] = 1;
skeleton->bones[i + 6] = 0;
skeleton->bones[i + 7] = 0;
}
glActiveTexture(GL_TEXTURE0);
glBindTexture(GL_TEXTURE_2D,skeleton->texture);
if (skeleton->use_2d) {
skeleton->skel_texture.resize(256*height*2*4);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 256, height*2, 0, GL_RGBA, GL_FLOAT, NULL);
} else { } else {
skeleton->bones.resize(p_bones * 12); skeleton->skel_texture.resize(256*height*3*4);
for (int i = 0; i < skeleton->bones.size(); i += 12) { glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F, 256, height*3, 0, GL_RGBA, GL_FLOAT, NULL);
skeleton->bones[i + 0] = 1;
skeleton->bones[i + 1] = 0;
skeleton->bones[i + 2] = 0;
skeleton->bones[i + 3] = 0;
skeleton->bones[i + 4] = 0;
skeleton->bones[i + 5] = 1;
skeleton->bones[i + 6] = 0;
skeleton->bones[i + 7] = 0;
skeleton->bones[i + 8] = 0;
skeleton->bones[i + 9] = 0;
skeleton->bones[i + 10] = 1;
skeleton->bones[i + 11] = 0;
}
} }
if (p_bones) { glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glGenBuffers(1, &skeleton->ubo); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glBindBuffer(GL_UNIFORM_BUFFER, skeleton->ubo); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glBufferData(GL_UNIFORM_BUFFER, skeleton->bones.size() * sizeof(float), NULL, GL_DYNAMIC_DRAW); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glBindBuffer(GL_UNIFORM_BUFFER, 0);
}
if (!skeleton->update_list.in_list()) { if (!skeleton->update_list.in_list()) {
skeleton_update_list.add(&skeleton->update_list); skeleton_update_list.add(&skeleton->update_list);
@ -3997,19 +3984,25 @@ void RasterizerStorageGLES3::skeleton_bone_set_transform(RID p_skeleton, int p_b
ERR_FAIL_INDEX(p_bone, skeleton->size); ERR_FAIL_INDEX(p_bone, skeleton->size);
ERR_FAIL_COND(skeleton->use_2d); ERR_FAIL_COND(skeleton->use_2d);
float *bones = skeleton->bones.ptr(); float *texture = skeleton->skel_texture.ptr();
bones[p_bone * 12 + 0] = p_transform.basis.elements[0][0];
bones[p_bone * 12 + 1] = p_transform.basis.elements[0][1]; int base_ofs = ((p_bone / 256) * 256) * 3 * 4 + (p_bone % 256) * 4;
bones[p_bone * 12 + 2] = p_transform.basis.elements[0][2];
bones[p_bone * 12 + 3] = p_transform.origin.x; texture[base_ofs+0]=p_transform.basis[0].x;
bones[p_bone * 12 + 4] = p_transform.basis.elements[1][0]; texture[base_ofs+1]=p_transform.basis[0].y;
bones[p_bone * 12 + 5] = p_transform.basis.elements[1][1]; texture[base_ofs+2]=p_transform.basis[0].z;
bones[p_bone * 12 + 6] = p_transform.basis.elements[1][2]; texture[base_ofs+3]=p_transform.origin.x;
bones[p_bone * 12 + 7] = p_transform.origin.y; base_ofs+=256*4;
bones[p_bone * 12 + 8] = p_transform.basis.elements[2][0]; texture[base_ofs+0]=p_transform.basis[1].x;
bones[p_bone * 12 + 9] = p_transform.basis.elements[2][1]; texture[base_ofs+1]=p_transform.basis[1].y;
bones[p_bone * 12 + 10] = p_transform.basis.elements[2][2]; texture[base_ofs+2]=p_transform.basis[1].z;
bones[p_bone * 12 + 11] = p_transform.origin.z; texture[base_ofs+3]=p_transform.origin.y;
base_ofs+=256*4;
texture[base_ofs+0]=p_transform.basis[2].x;
texture[base_ofs+1]=p_transform.basis[2].y;
texture[base_ofs+2]=p_transform.basis[2].z;
texture[base_ofs+3]=p_transform.origin.z;
if (!skeleton->update_list.in_list()) { if (!skeleton->update_list.in_list()) {
skeleton_update_list.add(&skeleton->update_list); skeleton_update_list.add(&skeleton->update_list);
@ -4024,22 +4017,30 @@ Transform RasterizerStorageGLES3::skeleton_bone_get_transform(RID p_skeleton, in
ERR_FAIL_INDEX_V(p_bone, skeleton->size, Transform()); ERR_FAIL_INDEX_V(p_bone, skeleton->size, Transform());
ERR_FAIL_COND_V(skeleton->use_2d, Transform()); ERR_FAIL_COND_V(skeleton->use_2d, Transform());
float *bones = skeleton->bones.ptr(); const float *texture = skeleton->skel_texture.ptr();
Transform mtx;
mtx.basis.elements[0][0] = bones[p_bone * 12 + 0]; Transform ret;
mtx.basis.elements[0][1] = bones[p_bone * 12 + 1];
mtx.basis.elements[0][2] = bones[p_bone * 12 + 2]; int base_ofs = ((p_bone / 256) * 256) * 3 * 4 + (p_bone % 256) * 4;
mtx.origin.x = bones[p_bone * 12 + 3];
mtx.basis.elements[1][0] = bones[p_bone * 12 + 4]; ret.basis[0].x=texture[base_ofs+0];
mtx.basis.elements[1][1] = bones[p_bone * 12 + 5]; ret.basis[0].y=texture[base_ofs+1];
mtx.basis.elements[1][2] = bones[p_bone * 12 + 6]; ret.basis[0].z=texture[base_ofs+2];
mtx.origin.y = bones[p_bone * 12 + 7]; ret.origin.x=texture[base_ofs+3];
mtx.basis.elements[2][0] = bones[p_bone * 12 + 8]; base_ofs+=256*4;
mtx.basis.elements[2][1] = bones[p_bone * 12 + 9]; ret.basis[1].x=texture[base_ofs+0];
mtx.basis.elements[2][2] = bones[p_bone * 12 + 10]; ret.basis[1].y=texture[base_ofs+1];
mtx.origin.z = bones[p_bone * 12 + 11]; ret.basis[1].z=texture[base_ofs+2];
ret.origin.y=texture[base_ofs+3];
base_ofs+=256*4;
ret.basis[2].x=texture[base_ofs+0];
ret.basis[2].y=texture[base_ofs+1];
ret.basis[2].z=texture[base_ofs+2];
ret.origin.z=texture[base_ofs+3];
return ret;
return mtx;
} }
void RasterizerStorageGLES3::skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) { void RasterizerStorageGLES3::skeleton_bone_set_transform_2d(RID p_skeleton, int p_bone, const Transform2D &p_transform) {
@ -4049,15 +4050,20 @@ void RasterizerStorageGLES3::skeleton_bone_set_transform_2d(RID p_skeleton, int
ERR_FAIL_INDEX(p_bone, skeleton->size); ERR_FAIL_INDEX(p_bone, skeleton->size);
ERR_FAIL_COND(!skeleton->use_2d); ERR_FAIL_COND(!skeleton->use_2d);
float *bones = skeleton->bones.ptr(); float *texture = skeleton->skel_texture.ptr();
bones[p_bone * 12 + 0] = p_transform.elements[0][0];
bones[p_bone * 12 + 1] = p_transform.elements[1][0]; int base_ofs = ((p_bone / 256) * 256) * 2 * 4 + (p_bone % 256) * 4;
bones[p_bone * 12 + 2] = 0;
bones[p_bone * 12 + 3] = p_transform.elements[2][0]; texture[base_ofs+0]=p_transform[0][0];
bones[p_bone * 12 + 4] = p_transform.elements[0][1]; texture[base_ofs+1]=p_transform[1][0];
bones[p_bone * 12 + 5] = p_transform.elements[1][1]; texture[base_ofs+2]=0;
bones[p_bone * 12 + 6] = 0; texture[base_ofs+3]=p_transform[2][0];
bones[p_bone * 12 + 7] = p_transform.elements[2][1]; base_ofs+=256*4;
texture[base_ofs+0]=p_transform[0][1];
texture[base_ofs+1]=p_transform[1][1];
texture[base_ofs+2]=0;
texture[base_ofs+3]=p_transform[2][1];
if (!skeleton->update_list.in_list()) { if (!skeleton->update_list.in_list()) {
skeleton_update_list.add(&skeleton->update_list); skeleton_update_list.add(&skeleton->update_list);
@ -4071,28 +4077,41 @@ Transform2D RasterizerStorageGLES3::skeleton_bone_get_transform_2d(RID p_skeleto
ERR_FAIL_INDEX_V(p_bone, skeleton->size, Transform2D()); ERR_FAIL_INDEX_V(p_bone, skeleton->size, Transform2D());
ERR_FAIL_COND_V(!skeleton->use_2d, Transform2D()); ERR_FAIL_COND_V(!skeleton->use_2d, Transform2D());
Transform2D mtx; const float *texture = skeleton->skel_texture.ptr();
float *bones = skeleton->bones.ptr(); Transform2D ret;
mtx.elements[0][0] = bones[p_bone * 12 + 0];
mtx.elements[1][0] = bones[p_bone * 12 + 1];
mtx.elements[2][0] = bones[p_bone * 12 + 3];
mtx.elements[0][1] = bones[p_bone * 12 + 4];
mtx.elements[1][1] = bones[p_bone * 12 + 5];
mtx.elements[2][1] = bones[p_bone * 12 + 7];
return mtx; int base_ofs = ((p_bone / 256) * 256) * 2 * 4 + (p_bone % 256) * 4;
ret[0][0]=texture[base_ofs+0];
ret[1][0]=texture[base_ofs+1];
ret[2][0]=texture[base_ofs+3];
base_ofs+=256*4;
ret[0][1]=texture[base_ofs+0];
ret[1][1]=texture[base_ofs+1];
ret[2][1]=texture[base_ofs+3];
return ret;
} }
void RasterizerStorageGLES3::update_dirty_skeletons() { void RasterizerStorageGLES3::update_dirty_skeletons() {
glActiveTexture(GL_TEXTURE0);
while (skeleton_update_list.first()) { while (skeleton_update_list.first()) {
Skeleton *skeleton = skeleton_update_list.first()->self(); Skeleton *skeleton = skeleton_update_list.first()->self();
if (skeleton->size) { if (skeleton->size) {
glBindBuffer(GL_UNIFORM_BUFFER, skeleton->ubo);
glBufferSubData(GL_UNIFORM_BUFFER, 0, skeleton->bones.size() * sizeof(float), skeleton->bones.ptr());
glBindBuffer(GL_UNIFORM_BUFFER, 0);
int height = skeleton->size/256;
if (skeleton->size%256)
height++;
glBindTexture(GL_TEXTURE_2D,skeleton->texture);
glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 256,height*(skeleton->use_2d?2:3), GL_RGBA, GL_FLOAT, skeleton->skel_texture.ptr());
} }
for (Set<RasterizerScene::InstanceBase *>::Element *E = skeleton->instances.front(); E; E = E->next()) { for (Set<RasterizerScene::InstanceBase *>::Element *E = skeleton->instances.front(); E; E = E->next()) {
@ -5957,6 +5976,8 @@ bool RasterizerStorageGLES3::free(RID p_rid) {
} }
skeleton_allocate(p_rid, 0, false); skeleton_allocate(p_rid, 0, false);
glDeleteTextures(1,&skeleton->texture);
skeleton_owner.free(p_rid); skeleton_owner.free(p_rid);
memdelete(skeleton); memdelete(skeleton);

View File

@ -769,18 +769,19 @@ public:
/* SKELETON API */ /* SKELETON API */
struct Skeleton : RID_Data { struct Skeleton : RID_Data {
int size;
bool use_2d; bool use_2d;
Vector<float> bones; //4x3 or 4x2 depending on what is needed int size;
GLuint ubo; Vector<float> skel_texture;
GLuint texture;
SelfList<Skeleton> update_list; SelfList<Skeleton> update_list;
Set<RasterizerScene::InstanceBase *> instances; //instances using skeleton Set<RasterizerScene::InstanceBase *> instances; //instances using skeleton
Skeleton() Skeleton()
: update_list(this) { : update_list(this) {
size = 0; size=0;
use_2d = false; use_2d = false;
ubo = 0; texture = 0;
} }
}; };

View File

@ -146,13 +146,10 @@ out highp float dp_clip;
#endif #endif
#define SKELETON_TEXTURE_WIDTH 256
#ifdef USE_SKELETON #ifdef USE_SKELETON
uniform highp sampler2D skeleton_texture; //texunit:-6
layout(std140) uniform SkeletonData { //ubo:7
mat3x4 skeleton[MAX_SKELETON_BONES];
};
#endif #endif
out highp vec4 position_interp; out highp vec4 position_interp;
@ -173,15 +170,41 @@ void main() {
color_interp = color_attrib; color_interp = color_attrib;
#endif #endif
#ifdef USE_SKELETON #ifdef USE_SKELETON
{ {
//skeleton transform //skeleton transform
highp mat3x4 m=skeleton[bone_indices.x]*bone_weights.x; ivec2 tex_ofs = ivec2( bone_indices.x%256, (bone_indices.x/256)*3 );
m+=skeleton[bone_indices.y]*bone_weights.y; highp mat3x4 m = mat3x4(
m+=skeleton[bone_indices.z]*bone_weights.z; texelFetch(skeleton_texture,tex_ofs,0),
m+=skeleton[bone_indices.w]*bone_weights.w; texelFetch(skeleton_texture,tex_ofs+ivec2(0,1),0),
texelFetch(skeleton_texture,tex_ofs+ivec2(0,2),0)
) * bone_weights.x;
tex_ofs = ivec2( bone_indices.y%256, (bone_indices.y/256)*3 );
m+= mat3x4(
texelFetch(skeleton_texture,tex_ofs,0),
texelFetch(skeleton_texture,tex_ofs+ivec2(0,1),0),
texelFetch(skeleton_texture,tex_ofs+ivec2(0,2),0)
) * bone_weights.y;
tex_ofs = ivec2( bone_indices.z%256, (bone_indices.z/256)*3 );
m+= mat3x4(
texelFetch(skeleton_texture,tex_ofs,0),
texelFetch(skeleton_texture,tex_ofs+ivec2(0,1),0),
texelFetch(skeleton_texture,tex_ofs+ivec2(0,2),0)
) * bone_weights.z;
tex_ofs = ivec2( bone_indices.w%256, (bone_indices.w/256)*3 );
m+= mat3x4(
texelFetch(skeleton_texture,tex_ofs,0),
texelFetch(skeleton_texture,tex_ofs+ivec2(0,1),0),
texelFetch(skeleton_texture,tex_ofs+ivec2(0,2),0)
) * bone_weights.w;
vertex.xyz = vertex * m; vertex.xyz = vertex * m;
@ -190,8 +213,7 @@ void main() {
tangent.xyz = vec4(tangent.xyz,0.0) * mn; tangent.xyz = vec4(tangent.xyz,0.0) * mn;
#endif #endif
} }
#endif // USE_SKELETON1 #endif
#ifdef USE_INSTANCING #ifdef USE_INSTANCING
@ -493,7 +515,7 @@ layout(location=0) out vec4 frag_color;
#endif #endif
in highp vec4 position_interp; in highp vec4 position_interp;
uniform highp sampler2D depth_buffer; //texunit:-8 uniform highp sampler2D depth_buffer; //texunit:-9
float contact_shadow_compute(vec3 pos, vec3 dir, float max_distance) { float contact_shadow_compute(vec3 pos, vec3 dir, float max_distance) {
@ -926,7 +948,7 @@ void reflection_process(int idx, vec3 vertex, vec3 normal,vec3 binormal, vec3 ta
#ifdef USE_GI_PROBES #ifdef USE_GI_PROBES
uniform mediump sampler3D gi_probe1; //texunit:-6 uniform mediump sampler3D gi_probe1; //texunit:-11
uniform highp mat4 gi_probe_xform1; uniform highp mat4 gi_probe_xform1;
uniform highp vec3 gi_probe_bounds1; uniform highp vec3 gi_probe_bounds1;
uniform highp vec3 gi_probe_cell_size1; uniform highp vec3 gi_probe_cell_size1;
@ -934,7 +956,7 @@ uniform highp float gi_probe_multiplier1;
uniform highp float gi_probe_bias1; uniform highp float gi_probe_bias1;
uniform bool gi_probe_blend_ambient1; uniform bool gi_probe_blend_ambient1;
uniform mediump sampler3D gi_probe2; //texunit:-7 uniform mediump sampler3D gi_probe2; //texunit:-10
uniform highp mat4 gi_probe_xform2; uniform highp mat4 gi_probe_xform2;
uniform highp vec3 gi_probe_bounds2; uniform highp vec3 gi_probe_bounds2;
uniform highp vec3 gi_probe_cell_size2; uniform highp vec3 gi_probe_cell_size2;