GLES2 refactors
This commit unhacks some parts of the 3D rendering. Most notably: - possibility to use negative texture units (no longer weird manual index allocation for user samplers) - refactoring of light code, now sorts in a different way, should yield better performance - fixes a crash while saving (because of "Illegal instruction" execution) when using a decent compiler (clang, it's clang. Thanks GCC for not telling me about UB).
This commit is contained in:
parent
6ffd2d3529
commit
73fe08be2e
|
@ -349,7 +349,7 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
|
|||
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_UV_ATTRIBUTE, false);
|
||||
if (state.canvas_shader.bind()) {
|
||||
_set_uniforms();
|
||||
state.canvas_shader.use_material((void *)p_material, 2);
|
||||
state.canvas_shader.use_material((void *)p_material);
|
||||
}
|
||||
|
||||
_bind_canvas_texture(RID(), RID());
|
||||
|
@ -393,7 +393,7 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
|
|||
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_UV_ATTRIBUTE, false);
|
||||
if (state.canvas_shader.bind()) {
|
||||
_set_uniforms();
|
||||
state.canvas_shader.use_material((void *)p_material, 2);
|
||||
state.canvas_shader.use_material((void *)p_material);
|
||||
}
|
||||
|
||||
RasterizerStorageGLES2::Texture *tex = _bind_canvas_texture(r->texture, r->normal_map);
|
||||
|
@ -476,7 +476,7 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
|
|||
state.canvas_shader.set_conditional(CanvasShaderGLES2::USE_UV_ATTRIBUTE, true);
|
||||
if (state.canvas_shader.bind()) {
|
||||
_set_uniforms();
|
||||
state.canvas_shader.use_material((void *)p_material, 2);
|
||||
state.canvas_shader.use_material((void *)p_material);
|
||||
}
|
||||
|
||||
glDisableVertexAttribArray(VS::ARRAY_COLOR);
|
||||
|
@ -642,7 +642,7 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
|
|||
|
||||
if (state.canvas_shader.bind()) {
|
||||
_set_uniforms();
|
||||
state.canvas_shader.use_material((void *)p_material, 2);
|
||||
state.canvas_shader.use_material((void *)p_material);
|
||||
}
|
||||
|
||||
static const int num_points = 32;
|
||||
|
@ -673,7 +673,7 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
|
|||
|
||||
if (state.canvas_shader.bind()) {
|
||||
_set_uniforms();
|
||||
state.canvas_shader.use_material((void *)p_material, 2);
|
||||
state.canvas_shader.use_material((void *)p_material);
|
||||
}
|
||||
|
||||
RasterizerStorageGLES2::Texture *texture = _bind_canvas_texture(polygon->texture, polygon->normal_map);
|
||||
|
@ -694,7 +694,7 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
|
|||
|
||||
if (state.canvas_shader.bind()) {
|
||||
_set_uniforms();
|
||||
state.canvas_shader.use_material((void *)p_material, 2);
|
||||
state.canvas_shader.use_material((void *)p_material);
|
||||
}
|
||||
|
||||
_bind_canvas_texture(RID(), RID());
|
||||
|
@ -727,7 +727,7 @@ void RasterizerCanvasGLES2::_canvas_item_render_commands(Item *p_item, Item *cur
|
|||
|
||||
if (state.canvas_shader.bind()) {
|
||||
_set_uniforms();
|
||||
state.canvas_shader.use_material((void *)p_material, 2);
|
||||
state.canvas_shader.use_material((void *)p_material);
|
||||
}
|
||||
|
||||
ERR_CONTINUE(primitive->points.size() < 1);
|
||||
|
@ -926,7 +926,7 @@ void RasterizerCanvasGLES2::canvas_render_items(Item *p_item_list, int p_z, cons
|
|||
state.canvas_shader.set_custom_shader(0);
|
||||
state.canvas_shader.bind();
|
||||
}
|
||||
state.canvas_shader.use_material((void *)material_ptr, 2);
|
||||
state.canvas_shader.use_material((void *)material_ptr);
|
||||
|
||||
shader_cache = shader_ptr;
|
||||
|
||||
|
|
|
@ -35,6 +35,8 @@
|
|||
#include "rasterizer_canvas_gles2.h"
|
||||
#include "servers/visual/visual_server_raster.h"
|
||||
|
||||
#include "vmap.h"
|
||||
|
||||
#ifndef GLES_OVER_GL
|
||||
#define glClearDepth glClearDepthf
|
||||
#endif
|
||||
|
@ -827,7 +829,7 @@ static const GLenum gl_primitive[] = {
|
|||
GL_TRIANGLE_FAN
|
||||
};
|
||||
|
||||
void RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_material, bool p_use_radiance_map, bool p_reverse_cull, bool p_shadow_atlas, bool p_skeleton_tex, Size2i p_skeleton_tex_size) {
|
||||
void RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_material, bool p_reverse_cull, Size2i p_skeleton_tex_size) {
|
||||
|
||||
// material parameters
|
||||
|
||||
|
@ -864,25 +866,11 @@ void RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_m
|
|||
|
||||
ShaderLanguage::ShaderNode::Uniform::Hint *texture_hints = p_material->shader->texture_hints.ptrw();
|
||||
|
||||
int num_default_tex = p_use_radiance_map ? 1 : 0;
|
||||
|
||||
if (p_material->shader->spatial.uses_screen_texture) {
|
||||
num_default_tex = MIN(num_default_tex, 2);
|
||||
}
|
||||
|
||||
if (p_shadow_atlas) {
|
||||
num_default_tex = MIN(num_default_tex, 3);
|
||||
}
|
||||
|
||||
if (p_skeleton_tex) {
|
||||
num_default_tex = MIN(num_default_tex, 4);
|
||||
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::SKELETON_TEXTURE_SIZE, p_skeleton_tex_size);
|
||||
}
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::SKELETON_TEXTURE_SIZE, p_skeleton_tex_size);
|
||||
|
||||
for (int i = 0; i < tc; i++) {
|
||||
|
||||
glActiveTexture(GL_TEXTURE0 + num_default_tex + i);
|
||||
glActiveTexture(GL_TEXTURE0 + i);
|
||||
|
||||
RasterizerStorageGLES2::Texture *t = storage->texture_owner.getornull(textures[i].second);
|
||||
|
||||
|
@ -911,7 +899,7 @@ void RasterizerSceneGLES2::_setup_material(RasterizerStorageGLES2::Material *p_m
|
|||
|
||||
glBindTexture(t->target, t->tex_id);
|
||||
}
|
||||
state.scene_shader.use_material((void *)p_material, num_default_tex);
|
||||
state.scene_shader.use_material((void *)p_material);
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES2::_setup_geometry(RenderList::Element *p_element, RasterizerStorageGLES2::Skeleton *p_skeleton) {
|
||||
|
@ -1279,7 +1267,7 @@ void RasterizerSceneGLES2::_render_geometry(RenderList::Element *p_element) {
|
|||
}
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements, int p_element_count, const RID *p_light_cull_result, int p_light_cull_count, const Transform &p_view_transform, const CameraMatrix &p_projection, RID p_shadow_atlas, Environment *p_env, GLuint p_base_env, float p_shadow_bias, float p_shadow_normal_bias, bool p_reverse_cull, bool p_alpha_pass, bool p_shadow, bool p_directional_add, bool p_directional_shadows) {
|
||||
void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements, int p_element_count, const RID *p_directional_lights, int p_directional_light_count, const Transform &p_view_transform, const CameraMatrix &p_projection, RID p_shadow_atlas, Environment *p_env, GLuint p_base_env, float p_shadow_bias, float p_shadow_normal_bias, bool p_reverse_cull, bool p_alpha_pass, bool p_shadow, bool p_directional_add) {
|
||||
|
||||
ShadowAtlas *shadow_atlas = shadow_atlas_owner.getornull(p_shadow_atlas);
|
||||
|
||||
|
@ -1289,6 +1277,8 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
|
|||
|
||||
bool use_radiance_map = false;
|
||||
|
||||
VMap<RID, Vector<RenderList::Element *> > lit_objects;
|
||||
|
||||
for (int i = 0; i < p_element_count; i++) {
|
||||
RenderList::Element *e = p_elements[i];
|
||||
|
||||
|
@ -1297,7 +1287,7 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
|
|||
RasterizerStorageGLES2::Skeleton *skeleton = storage->skeleton_owner.getornull(e->instance->skeleton);
|
||||
|
||||
if (p_base_env) {
|
||||
glActiveTexture(GL_TEXTURE0);
|
||||
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 2);
|
||||
glBindTexture(GL_TEXTURE_CUBE_MAP, p_base_env);
|
||||
use_radiance_map = true;
|
||||
}
|
||||
|
@ -1315,7 +1305,7 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
|
|||
|
||||
_setup_geometry(e, skeleton);
|
||||
|
||||
_setup_material(material, use_radiance_map, p_reverse_cull, false, skeleton ? (skeleton->tex_id != 0) : 0, Size2i(skeleton ? skeleton->size * 3 : 0, 0));
|
||||
_setup_material(material, p_reverse_cull, Size2i(skeleton ? skeleton->size * 3 : 0, 0));
|
||||
|
||||
if (use_radiance_map) {
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::RADIANCE_INVERSE_XFORM, p_view_transform);
|
||||
|
@ -1404,66 +1394,88 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
|
|||
|
||||
_render_geometry(e);
|
||||
|
||||
// render lights
|
||||
|
||||
if (material->shader->spatial.unshaded)
|
||||
continue;
|
||||
|
||||
if (p_shadow)
|
||||
continue;
|
||||
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_PASS, true);
|
||||
for (int light = 0; light < e->instance->light_instances.size(); light++) {
|
||||
|
||||
state.scene_shader.bind();
|
||||
RID light_instance = e->instance->light_instances[light];
|
||||
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
lit_objects[light_instance].push_back(e);
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
bool has_shadow_atlas = shadow_atlas != NULL;
|
||||
_setup_material(material, false, p_reverse_cull, has_shadow_atlas, skeleton ? (skeleton->tex_id != 0) : 0, Size2i(skeleton ? skeleton->size * 3 : 0, 0));
|
||||
if (p_shadow) {
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::USE_RADIANCE_MAP, false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_USE_PSSM4, false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_USE_PSSM2, false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_USE_PSSM_BLEND, false);
|
||||
return;
|
||||
}
|
||||
|
||||
if (has_shadow_atlas) {
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
glBindTexture(GL_TEXTURE_2D, shadow_atlas->depth);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_PASS, true);
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
glBlendEquation(GL_FUNC_ADD);
|
||||
glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
|
||||
for (int lo = 0; lo < lit_objects.size(); lo++) {
|
||||
|
||||
RID key = lit_objects.getk(lo);
|
||||
|
||||
LightInstance *light = light_instance_owner.getornull(key);
|
||||
RasterizerStorageGLES2::Light *light_ptr = light->light_ptr;
|
||||
|
||||
const Vector<RenderList::Element *> &list = lit_objects.getv(lo);
|
||||
|
||||
for (int i = 0; i < list.size(); i++) {
|
||||
|
||||
RenderList::Element *e = list[i];
|
||||
RasterizerStorageGLES2::Material *material = e->material;
|
||||
|
||||
RasterizerStorageGLES2::Skeleton *skeleton = storage->skeleton_owner.getornull(e->instance->skeleton);
|
||||
|
||||
{
|
||||
_setup_geometry(e, skeleton);
|
||||
|
||||
_setup_material(material, p_reverse_cull, Size2i(skeleton ? skeleton->size * 3 : 0, 0));
|
||||
if (shadow_atlas != NULL) {
|
||||
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 4);
|
||||
glBindTexture(GL_TEXTURE_2D, shadow_atlas->depth);
|
||||
}
|
||||
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::CAMERA_MATRIX, p_view_transform.inverse());
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::CAMERA_INVERSE_MATRIX, p_view_transform);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::PROJECTION_MATRIX, p_projection);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::PROJECTION_INVERSE_MATRIX, p_projection.inverse());
|
||||
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::TIME, storage->frame.time[0]);
|
||||
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::SCREEN_PIXEL_SIZE, screen_pixel_size);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::NORMAL_MULT, 1.0); // TODO mirror?
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::WORLD_TRANSFORM, e->instance->transform);
|
||||
}
|
||||
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::CAMERA_MATRIX, p_view_transform.inverse());
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::CAMERA_INVERSE_MATRIX, p_view_transform);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::PROJECTION_MATRIX, p_projection);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::PROJECTION_INVERSE_MATRIX, p_projection.inverse());
|
||||
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::TIME, storage->frame.time[0]);
|
||||
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::SCREEN_PIXEL_SIZE, screen_pixel_size);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::NORMAL_MULT, 1.0); // TODO mirror?
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::WORLD_TRANSFORM, e->instance->transform);
|
||||
}
|
||||
|
||||
for (int j = 0; j < e->instance->light_instances.size(); j++) {
|
||||
RID light_rid = e->instance->light_instances[j];
|
||||
LightInstance *light = light_instance_owner.get(light_rid);
|
||||
|
||||
switch (light->light_ptr->type) {
|
||||
case VS::LIGHT_DIRECTIONAL: {
|
||||
continue;
|
||||
} break;
|
||||
|
||||
switch (light_ptr->type) {
|
||||
case VS::LIGHT_OMNI: {
|
||||
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::LIGHT_TYPE, (int)1);
|
||||
|
||||
Vector3 position = p_view_transform.inverse().xform(light->transform.origin);
|
||||
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::LIGHT_POSITION, position);
|
||||
|
||||
float range = light->light_ptr->param[VS::LIGHT_PARAM_RANGE];
|
||||
float range = light_ptr->param[VS::LIGHT_PARAM_RANGE];
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::LIGHT_RANGE, range);
|
||||
|
||||
Color attenuation = Color(0.0, 0.0, 0.0, 0.0);
|
||||
attenuation.a = light->light_ptr->param[VS::LIGHT_PARAM_ATTENUATION];
|
||||
attenuation.a = light_ptr->param[VS::LIGHT_PARAM_ATTENUATION];
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::LIGHT_ATTENUATION, attenuation);
|
||||
|
||||
if (light->light_ptr->shadow && shadow_atlas->shadow_owners.has(light->self)) {
|
||||
if (light_ptr->shadow && shadow_atlas->shadow_owners.has(light->self)) {
|
||||
|
||||
uint32_t key = shadow_atlas->shadow_owners[light->self];
|
||||
|
||||
|
@ -1516,10 +1528,10 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
|
|||
Vector3 direction = p_view_transform.inverse().basis.xform(light->transform.basis.xform(Vector3(0, 0, -1))).normalized();
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::LIGHT_DIRECTION, direction);
|
||||
Color attenuation = Color(0.0, 0.0, 0.0, 0.0);
|
||||
attenuation.a = light->light_ptr->param[VS::LIGHT_PARAM_ATTENUATION];
|
||||
float range = light->light_ptr->param[VS::LIGHT_PARAM_RANGE];
|
||||
float spot_attenuation = light->light_ptr->param[VS::LIGHT_PARAM_SPOT_ATTENUATION];
|
||||
float angle = light->light_ptr->param[VS::LIGHT_PARAM_SPOT_ANGLE];
|
||||
attenuation.a = light_ptr->param[VS::LIGHT_PARAM_ATTENUATION];
|
||||
float range = light_ptr->param[VS::LIGHT_PARAM_RANGE];
|
||||
float spot_attenuation = light_ptr->param[VS::LIGHT_PARAM_SPOT_ATTENUATION];
|
||||
float angle = light_ptr->param[VS::LIGHT_PARAM_SPOT_ANGLE];
|
||||
angle = Math::cos(Math::deg2rad(angle));
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::LIGHT_ATTENUATION, attenuation);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::LIGHT_SPOT_ATTENUATION, spot_attenuation);
|
||||
|
@ -1576,9 +1588,7 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
|
|||
|
||||
} break;
|
||||
|
||||
default: {
|
||||
print_line("wat.");
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
float energy = light->light_ptr->param[VS::LIGHT_PARAM_ENERGY];
|
||||
|
@ -1590,62 +1600,57 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
|
|||
|
||||
_render_geometry(e);
|
||||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j < p_light_cull_count; j++) {
|
||||
RID light_rid = p_light_cull_result[j];
|
||||
for (int dl = 0; dl < p_directional_light_count; dl++) {
|
||||
RID light_rid = p_directional_lights[dl];
|
||||
LightInstance *light = light_instance_owner.getornull(light_rid);
|
||||
RasterizerStorageGLES2::Light *light_ptr = light->light_ptr;
|
||||
|
||||
LightInstance *light = light_instance_owner.getornull(light_rid);
|
||||
switch (light_ptr->directional_shadow_mode) {
|
||||
case VS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL: {
|
||||
} break;
|
||||
case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS: {
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_USE_PSSM2, true);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_USE_PSSM_BLEND, light_ptr->directional_blend_splits);
|
||||
} break;
|
||||
|
||||
RasterizerStorageGLES2::Light *light_ptr = light->light_ptr;
|
||||
case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS: {
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_USE_PSSM4, true);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_USE_PSSM_BLEND, light_ptr->directional_blend_splits);
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
switch (light_ptr->type) {
|
||||
case VS::LIGHT_DIRECTIONAL: {
|
||||
for (int i = 0; i < p_element_count; i++) {
|
||||
|
||||
switch (light_ptr->directional_shadow_mode) {
|
||||
case VS::LIGHT_DIRECTIONAL_SHADOW_ORTHOGONAL: {
|
||||
} break;
|
||||
case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_2_SPLITS: {
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_USE_PSSM2, true);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_USE_PSSM_BLEND, light_ptr->directional_blend_splits);
|
||||
} break;
|
||||
RenderList::Element *e = p_elements[i];
|
||||
RasterizerStorageGLES2::Material *material = e->material;
|
||||
RasterizerStorageGLES2::Skeleton *skeleton = storage->skeleton_owner.getornull(e->instance->skeleton);
|
||||
|
||||
case VS::LIGHT_DIRECTIONAL_SHADOW_PARALLEL_4_SPLITS: {
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_USE_PSSM4, true);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_USE_PSSM_BLEND, light_ptr->directional_blend_splits);
|
||||
} break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
{
|
||||
_setup_material(material, p_reverse_cull, Size2i(skeleton ? skeleton->size * 3 : 0, 0));
|
||||
|
||||
{
|
||||
_setup_material(material, false, p_reverse_cull, false, skeleton ? (skeleton->tex_id != 0) : 0, Size2i(skeleton ? skeleton->size * 3 : 0, 0));
|
||||
if (directional_shadow.depth) {
|
||||
glActiveTexture(GL_TEXTURE0 + storage->config.max_texture_image_units - 4); // TODO move into base pass
|
||||
glBindTexture(GL_TEXTURE_2D, directional_shadow.depth);
|
||||
}
|
||||
|
||||
if (directional_shadow.depth) {
|
||||
glActiveTexture(GL_TEXTURE3);
|
||||
glBindTexture(GL_TEXTURE_2D, directional_shadow.depth);
|
||||
}
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::CAMERA_MATRIX, p_view_transform.inverse());
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::CAMERA_INVERSE_MATRIX, p_view_transform);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::PROJECTION_MATRIX, p_projection);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::PROJECTION_INVERSE_MATRIX, p_projection.inverse());
|
||||
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::CAMERA_MATRIX, p_view_transform.inverse());
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::CAMERA_INVERSE_MATRIX, p_view_transform);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::PROJECTION_MATRIX, p_projection);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::PROJECTION_INVERSE_MATRIX, p_projection.inverse());
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::TIME, storage->frame.time[0]);
|
||||
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::TIME, storage->frame.time[0]);
|
||||
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::SCREEN_PIXEL_SIZE, screen_pixel_size);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::NORMAL_MULT, 1.0); // TODO mirror?
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::WORLD_TRANSFORM, e->instance->transform);
|
||||
}
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::LIGHT_TYPE, (int)0);
|
||||
Vector3 direction = p_view_transform.inverse().basis.xform(light->transform.basis.xform(Vector3(0, 0, -1))).normalized();
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::LIGHT_DIRECTION, direction);
|
||||
|
||||
} break;
|
||||
|
||||
default: {
|
||||
continue;
|
||||
} break;
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::SCREEN_PIXEL_SIZE, screen_pixel_size);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::NORMAL_MULT, 1.0); // TODO mirror?
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::WORLD_TRANSFORM, e->instance->transform);
|
||||
}
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::LIGHT_TYPE, (int)0);
|
||||
Vector3 direction = p_view_transform.inverse().basis.xform(light->transform.basis.xform(Vector3(0, 0, -1))).normalized();
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::LIGHT_DIRECTION, direction);
|
||||
|
||||
float energy = light_ptr->param[VS::LIGHT_PARAM_ENERGY];
|
||||
float specular = light_ptr->param[VS::LIGHT_PARAM_SPECULAR];
|
||||
|
@ -1753,10 +1758,10 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
|
|||
|
||||
_render_geometry(e);
|
||||
}
|
||||
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_PASS, false);
|
||||
}
|
||||
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_PASS, false);
|
||||
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::USE_RADIANCE_MAP, false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_USE_PSSM4, false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::LIGHT_USE_PSSM2, false);
|
||||
|
@ -1911,9 +1916,21 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
|
|||
}
|
||||
}
|
||||
|
||||
Vector<RID> directional_lights;
|
||||
|
||||
for (int i = 0; i < p_light_cull_count; i++) {
|
||||
RID light_rid = p_light_cull_result[i];
|
||||
|
||||
LightInstance *light = light_instance_owner.getornull(light_rid);
|
||||
|
||||
if (light->light_ptr->type == VS::LIGHT_DIRECTIONAL) {
|
||||
directional_lights.push_back(light_rid);
|
||||
}
|
||||
}
|
||||
|
||||
// render opaque things first
|
||||
render_list.sort_by_key(false);
|
||||
_render_render_list(render_list.elements, render_list.element_count, p_light_cull_result, p_light_cull_count, p_cam_transform, p_cam_projection, p_shadow_atlas, env, env_radiance_tex, 0.0, 0.0, false, false, false, false, false);
|
||||
_render_render_list(render_list.elements, render_list.element_count, directional_lights.ptr(), directional_lights.size(), p_cam_transform, p_cam_projection, p_shadow_atlas, env, env_radiance_tex, 0.0, 0.0, false, false, false, false);
|
||||
|
||||
// alpha pass
|
||||
|
||||
|
@ -1921,7 +1938,7 @@ void RasterizerSceneGLES2::render_scene(const Transform &p_cam_transform, const
|
|||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
render_list.sort_by_key(true);
|
||||
_render_render_list(&render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, p_light_cull_result, p_light_cull_count, p_cam_transform, p_cam_projection, p_shadow_atlas, env, env_radiance_tex, 0.0, 0.0, false, true, false, false, false);
|
||||
_render_render_list(&render_list.elements[render_list.max_elements - render_list.alpha_element_count], render_list.alpha_element_count, directional_lights.ptr(), directional_lights.size(), p_cam_transform, p_cam_projection, p_shadow_atlas, env, env_radiance_tex, 0.0, 0.0, false, true, false, false);
|
||||
|
||||
glDepthMask(GL_FALSE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
|
@ -2136,7 +2153,7 @@ void RasterizerSceneGLES2::render_shadow(RID p_light, RID p_shadow_atlas, int p_
|
|||
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::RENDER_DEPTH, true);
|
||||
|
||||
_render_render_list(render_list.elements, render_list.element_count, NULL, 0, light_transform, light_projection, RID(), NULL, 0, bias, normal_bias, false, false, true, false, false);
|
||||
_render_render_list(render_list.elements, render_list.element_count, NULL, 0, light_transform, light_projection, RID(), NULL, 0, bias, normal_bias, false, false, true, false);
|
||||
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::RENDER_DEPTH, false);
|
||||
|
||||
|
|
|
@ -545,11 +545,23 @@ public:
|
|||
void _add_geometry_with_material(RasterizerStorageGLES2::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES2::GeometryOwner *p_owner, RasterizerStorageGLES2::Material *p_material, bool p_depth_pass, bool p_shadow_pass);
|
||||
|
||||
void _fill_render_list(InstanceBase **p_cull_result, int p_cull_count, bool p_depth_pass, bool p_shadow_pass);
|
||||
void _render_render_list(RenderList::Element **p_elements, int p_element_count, const RID *p_light_cull_result, int p_light_cull_count, const Transform &p_view_transform, const CameraMatrix &p_projection, RID p_shadow_atlas, Environment *p_env, GLuint p_base_env, float p_shadow_bias, float p_shadow_normal_bias, bool p_reverse_cull, bool p_alpha_pass, bool p_shadow, bool p_directional_add, bool p_directional_shadows);
|
||||
void _render_render_list(RenderList::Element **p_elements, int p_element_count,
|
||||
const RID *p_directional_lights, int p_directional_light_count,
|
||||
const Transform &p_view_transform,
|
||||
const CameraMatrix &p_projection,
|
||||
RID p_shadow_atlas,
|
||||
Environment *p_env,
|
||||
GLuint p_base_env,
|
||||
float p_shadow_bias,
|
||||
float p_shadow_normal_bias,
|
||||
bool p_reverse_cull,
|
||||
bool p_alpha_pass,
|
||||
bool p_shadow,
|
||||
bool p_directional_add);
|
||||
|
||||
void _draw_sky(RasterizerStorageGLES2::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_custom_fov, float p_energy);
|
||||
|
||||
void _setup_material(RasterizerStorageGLES2::Material *p_material, bool p_use_radiance_map, bool p_reverse_cull, bool p_shadow_atlas = false, bool p_skeleton_tex = false, Size2i p_skeleton_tex_size = Size2i(0, 0));
|
||||
void _setup_material(RasterizerStorageGLES2::Material *p_material, bool p_reverse_cull, Size2i p_skeleton_tex_size = Size2i(0, 0));
|
||||
void _setup_geometry(RenderList::Element *p_element, RasterizerStorageGLES2::Skeleton *p_skeleton);
|
||||
void _render_geometry(RenderList::Element *p_element);
|
||||
|
||||
|
|
|
@ -567,7 +567,7 @@ Ref<Image> RasterizerStorageGLES2::texture_get_data(RID p_texture, int p_layer)
|
|||
ERR_FAIL_COND_V(!texture->active, Ref<Image>());
|
||||
ERR_FAIL_COND_V(texture->data_size == 0 && !texture->render_target, Ref<Image>());
|
||||
|
||||
if (!texture->images[p_layer].is_null()) {
|
||||
if (texture->type == VS::TEXTURE_TYPE_CUBEMAP && p_layer < 6 && p_layer >= 0 && !texture->images[p_layer].is_null()) {
|
||||
return texture->images[p_layer];
|
||||
}
|
||||
#ifdef GLES_OVER_GL
|
||||
|
@ -594,9 +594,13 @@ Ref<Image> RasterizerStorageGLES2::texture_get_data(RID p_texture, int p_layer)
|
|||
ofs = Image::get_image_data_size(texture->alloc_width, texture->alloc_height, texture->format, i - 1);
|
||||
}
|
||||
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
|
||||
glGetTexImage(texture->target, i, texture->gl_format_cache, texture->gl_type_cache, &wb[ofs]);
|
||||
if (texture->compressed) {
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 4);
|
||||
glGetCompressedTexImage(texture->target, i, &wb[ofs]);
|
||||
} else {
|
||||
glPixelStorei(GL_PACK_ALIGNMENT, 1);
|
||||
glGetTexImage(texture->target, i, texture->gl_format_cache, texture->gl_type_cache, &wb[ofs]);
|
||||
}
|
||||
}
|
||||
|
||||
wb = PoolVector<uint8_t>::Write();
|
||||
|
@ -3961,7 +3965,7 @@ void RasterizerStorageGLES2::initialize() {
|
|||
frame.clear_request = false;
|
||||
// config.keep_original_textures = false;
|
||||
|
||||
glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &config.max_texture_image_units);
|
||||
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &config.max_texture_image_units);
|
||||
glGetIntegerv(GL_MAX_TEXTURE_SIZE, &config.max_texture_size);
|
||||
|
||||
shaders.copy.init();
|
||||
|
|
|
@ -527,8 +527,13 @@ ShaderGLES2::Version *ShaderGLES2::get_current_version() {
|
|||
|
||||
for (int i = 0; i < texunit_pair_count; i++) {
|
||||
GLint loc = glGetUniformLocation(v.id, texunit_pairs[i].name);
|
||||
if (loc >= 0)
|
||||
glUniform1i(loc, texunit_pairs[i].index);
|
||||
if (loc >= 0) {
|
||||
if (texunit_pairs[i].index < 0) {
|
||||
glUniform1i(loc, max_image_units + texunit_pairs[i].index);
|
||||
} else {
|
||||
glUniform1i(loc, texunit_pairs[i].index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cc) {
|
||||
|
@ -643,6 +648,8 @@ void ShaderGLES2::setup(
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
glGetIntegerv(GL_MAX_COMBINED_TEXTURE_IMAGE_UNITS, &max_image_units);
|
||||
}
|
||||
|
||||
void ShaderGLES2::finish() {
|
||||
|
@ -717,7 +724,7 @@ void ShaderGLES2::free_custom_shader(uint32_t p_code_id) {
|
|||
custom_code_map.erase(p_code_id);
|
||||
}
|
||||
|
||||
void ShaderGLES2::use_material(void *p_material, int p_num_predef_textures) {
|
||||
void ShaderGLES2::use_material(void *p_material) {
|
||||
RasterizerStorageGLES2::Material *material = (RasterizerStorageGLES2::Material *)p_material;
|
||||
|
||||
if (!material) {
|
||||
|
@ -906,20 +913,58 @@ void ShaderGLES2::use_material(void *p_material, int p_num_predef_textures) {
|
|||
case ShaderLanguage::TYPE_MAT2: {
|
||||
Transform2D val = V->get();
|
||||
|
||||
// TODO
|
||||
if (value.second.size() < 4) {
|
||||
value.second.resize(4);
|
||||
}
|
||||
|
||||
value.second.write[0].real = val.elements[0][0];
|
||||
value.second.write[1].real = val.elements[0][1];
|
||||
value.second.write[2].real = val.elements[1][0];
|
||||
value.second.write[3].real = val.elements[1][1];
|
||||
|
||||
} break;
|
||||
|
||||
case ShaderLanguage::TYPE_MAT3: {
|
||||
Basis val = V->get();
|
||||
|
||||
// TODO
|
||||
if (value.second.size() < 9) {
|
||||
value.second.resize(9);
|
||||
}
|
||||
|
||||
value.second.write[0].real = val.elements[0][0];
|
||||
value.second.write[1].real = val.elements[0][1];
|
||||
value.second.write[2].real = val.elements[0][2];
|
||||
value.second.write[3].real = val.elements[1][0];
|
||||
value.second.write[4].real = val.elements[1][1];
|
||||
value.second.write[5].real = val.elements[1][2];
|
||||
value.second.write[6].real = val.elements[2][0];
|
||||
value.second.write[7].real = val.elements[2][1];
|
||||
value.second.write[8].real = val.elements[2][2];
|
||||
} break;
|
||||
|
||||
case ShaderLanguage::TYPE_MAT4: {
|
||||
Transform val = V->get();
|
||||
|
||||
// TODO
|
||||
if (value.second.size() < 16) {
|
||||
value.second.resize(16);
|
||||
}
|
||||
|
||||
value.second.write[0].real = val.basis.elements[0][0];
|
||||
value.second.write[0].real = val.basis.elements[0][1];
|
||||
value.second.write[0].real = val.basis.elements[0][2];
|
||||
value.second.write[0].real = 0;
|
||||
value.second.write[0].real = val.basis.elements[1][0];
|
||||
value.second.write[0].real = val.basis.elements[1][1];
|
||||
value.second.write[0].real = val.basis.elements[1][2];
|
||||
value.second.write[0].real = 0;
|
||||
value.second.write[0].real = val.basis.elements[2][0];
|
||||
value.second.write[0].real = val.basis.elements[2][1];
|
||||
value.second.write[0].real = val.basis.elements[2][2];
|
||||
value.second.write[0].real = 0;
|
||||
value.second.write[0].real = val.origin[0];
|
||||
value.second.write[0].real = val.origin[1];
|
||||
value.second.write[0].real = val.origin[2];
|
||||
value.second.write[0].real = 1;
|
||||
} break;
|
||||
|
||||
case ShaderLanguage::TYPE_SAMPLER2D: {
|
||||
|
@ -1034,7 +1079,7 @@ void ShaderGLES2::use_material(void *p_material, int p_num_predef_textures) {
|
|||
Pair<ShaderLanguage::DataType, Vector<ShaderLanguage::ConstantNode::Value> > value;
|
||||
value.first = ShaderLanguage::TYPE_INT;
|
||||
value.second.resize(1);
|
||||
value.second.write[0].sint = p_num_predef_textures + i;
|
||||
value.second.write[0].sint = i;
|
||||
|
||||
// GLint location = get_uniform_location(textures[i].first);
|
||||
|
||||
|
|
|
@ -465,7 +465,7 @@ public:
|
|||
|
||||
// this void* is actually a RasterizerStorageGLES2::Material, but C++ doesn't
|
||||
// like forward declared nested classes.
|
||||
void use_material(void *p_material, int p_num_predef_textures);
|
||||
void use_material(void *p_material);
|
||||
|
||||
uint32_t get_version() const { return new_conditional_version.version; }
|
||||
|
||||
|
|
|
@ -48,7 +48,7 @@ attribute highp vec4 bone_transform_row_2; // attrib:11
|
|||
attribute vec4 bone_ids; // attrib:6
|
||||
attribute highp vec4 bone_weights; // attrib:7
|
||||
|
||||
uniform highp sampler2D bone_transforms; // texunit:4
|
||||
uniform highp sampler2D bone_transforms; // texunit:-1
|
||||
uniform ivec2 skeleton_texture_size;
|
||||
|
||||
#endif
|
||||
|
@ -294,17 +294,17 @@ uniform highp float time;
|
|||
uniform vec2 screen_pixel_size;
|
||||
#endif
|
||||
|
||||
uniform highp sampler2D depth_buffer; //texunit:1
|
||||
uniform highp sampler2D depth_buffer; //texunit:-5
|
||||
|
||||
#if defined(SCREEN_TEXTURE_USED)
|
||||
uniform highp sampler2D screen_texture; //texunit:2
|
||||
uniform highp sampler2D screen_texture; //texunit:-6
|
||||
#endif
|
||||
|
||||
#ifdef USE_RADIANCE_MAP
|
||||
|
||||
#define RADIANCE_MAX_LOD 6.0
|
||||
|
||||
uniform samplerCube radiance_map; // texunit:0
|
||||
uniform samplerCube radiance_map; // texunit:-2
|
||||
|
||||
uniform mat4 radiance_inverse_xform;
|
||||
|
||||
|
@ -345,7 +345,7 @@ uniform float light_spot_angle;
|
|||
|
||||
|
||||
// shadows
|
||||
uniform highp sampler2D light_shadow_atlas; //texunit:3
|
||||
uniform highp sampler2D light_shadow_atlas; //texunit:-4
|
||||
uniform float light_has_shadow;
|
||||
|
||||
uniform mat4 light_shadow_matrix;
|
||||
|
@ -353,7 +353,7 @@ uniform vec4 light_clamp;
|
|||
|
||||
// directional shadow
|
||||
|
||||
uniform highp sampler2D light_directional_shadow; // texunit:3
|
||||
uniform highp sampler2D light_directional_shadow; // texunit:-4
|
||||
uniform vec4 light_split_offsets;
|
||||
|
||||
uniform mat4 light_shadow_matrix1;
|
||||
|
@ -439,11 +439,10 @@ void light_compute(vec3 N,
|
|||
{
|
||||
// calculate specular reflection
|
||||
|
||||
vec3 R = normalize(-reflect(L,N));
|
||||
float cRdotV = max(dot(R, V), 0.0);
|
||||
float blob_intensity = pow(cRdotV, (1.0 - roughness) * 256.0);
|
||||
specular_light += light_color * attenuation * blob_intensity * specular_blob_intensity;
|
||||
|
||||
vec3 R = normalize(-reflect(L,N));
|
||||
float cRdotV = max(dot(R, V), 0.0);
|
||||
float blob_intensity = pow(cRdotV, (1.0 - roughness) * 256.0);
|
||||
specular_light += light_color * attenuation * blob_intensity * specular_blob_intensity;
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -808,7 +807,6 @@ FRAGMENT_SHADER_CODE
|
|||
anisotropy,
|
||||
diffuse_light,
|
||||
specular_light);
|
||||
|
||||
}
|
||||
|
||||
gl_FragColor = vec4(ambient_light + diffuse_light + specular_light, alpha);
|
||||
|
|
Loading…
Reference in New Issue