소스 검색

Merge pull request #30987 from clayjohn/GLES2-light-negative

Implement negative for OmniLights and SpotLights in GLES2
Rémi Verschelde 6 년 전
부모
커밋
7464074cb8
2개의 변경된 파일9개의 추가작업 그리고 4개의 파일을 삭제
  1. 8 3
      drivers/gles2/rasterizer_scene_gles2.cpp
  2. 1 1
      drivers/gles2/rasterizer_scene_gles2.h

+ 8 - 3
drivers/gles2/rasterizer_scene_gles2.cpp

@@ -1910,14 +1910,14 @@ void RasterizerSceneGLES2::_setup_light_type(LightInstance *p_light, ShadowAtlas
 	}
 	}
 }
 }
 
 
-void RasterizerSceneGLES2::_setup_light(LightInstance *light, ShadowAtlas *shadow_atlas, const Transform &p_view_transform) {
+void RasterizerSceneGLES2::_setup_light(LightInstance *light, ShadowAtlas *shadow_atlas, const Transform &p_view_transform, bool accum_pass) {
 
 
 	RasterizerStorageGLES2::Light *light_ptr = light->light_ptr;
 	RasterizerStorageGLES2::Light *light_ptr = light->light_ptr;
 
 
 	//common parameters
 	//common parameters
 	float energy = light_ptr->param[VS::LIGHT_PARAM_ENERGY];
 	float energy = light_ptr->param[VS::LIGHT_PARAM_ENERGY];
 	float specular = light_ptr->param[VS::LIGHT_PARAM_SPECULAR];
 	float specular = light_ptr->param[VS::LIGHT_PARAM_SPECULAR];
-	float sign = light_ptr->negative ? -1 : 1;
+	float sign = (light_ptr->negative && !accum_pass) ? -1 : 1; //inverse color for base pass lights only
 
 
 	state.scene_shader.set_uniform(SceneShaderGLES2::LIGHT_SPECULAR, specular);
 	state.scene_shader.set_uniform(SceneShaderGLES2::LIGHT_SPECULAR, specular);
 	Color color = light_ptr->color * sign * energy * Math_PI;
 	Color color = light_ptr->color * sign * energy * Math_PI;
@@ -2310,6 +2310,11 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
 
 
 			if (accum_pass) { //accum pass force pass
 			if (accum_pass) { //accum pass force pass
 				blend_mode = RasterizerStorageGLES2::Shader::Spatial::BLEND_MODE_ADD;
 				blend_mode = RasterizerStorageGLES2::Shader::Spatial::BLEND_MODE_ADD;
+				if (rebind_light && light && light->light_ptr->negative) {
+					glBlendEquation(GL_FUNC_REVERSE_SUBTRACT);
+					glBlendFunc(GL_SRC_ALPHA, GL_ONE);
+					blend_mode = RasterizerStorageGLES2::Shader::Spatial::BLEND_MODE_SUB;
+				}
 			}
 			}
 
 
 			if (prev_blend_mode != blend_mode) {
 			if (prev_blend_mode != blend_mode) {
@@ -2553,7 +2558,7 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
 		}
 		}
 
 
 		if (rebind_light && light) {
 		if (rebind_light && light) {
-			_setup_light(light, shadow_atlas, p_view_transform);
+			_setup_light(light, shadow_atlas, p_view_transform, accum_pass);
 		}
 		}
 
 
 		if (rebind_reflection && (refprobe_1 || refprobe_2)) {
 		if (rebind_reflection && (refprobe_1 || refprobe_2)) {

+ 1 - 1
drivers/gles2/rasterizer_scene_gles2.h

@@ -694,7 +694,7 @@ public:
 	_FORCE_INLINE_ bool _setup_material(RasterizerStorageGLES2::Material *p_material, bool p_alpha_pass, Size2i p_skeleton_tex_size = Size2i(0, 0));
 	_FORCE_INLINE_ bool _setup_material(RasterizerStorageGLES2::Material *p_material, bool p_alpha_pass, Size2i p_skeleton_tex_size = Size2i(0, 0));
 	_FORCE_INLINE_ void _setup_geometry(RenderList::Element *p_element, RasterizerStorageGLES2::Skeleton *p_skeleton);
 	_FORCE_INLINE_ void _setup_geometry(RenderList::Element *p_element, RasterizerStorageGLES2::Skeleton *p_skeleton);
 	_FORCE_INLINE_ void _setup_light_type(LightInstance *p_light, ShadowAtlas *shadow_atlas);
 	_FORCE_INLINE_ void _setup_light_type(LightInstance *p_light, ShadowAtlas *shadow_atlas);
-	_FORCE_INLINE_ void _setup_light(LightInstance *p_light, ShadowAtlas *shadow_atlas, const Transform &p_view_transform);
+	_FORCE_INLINE_ void _setup_light(LightInstance *p_light, ShadowAtlas *shadow_atlas, const Transform &p_view_transform, bool accum_pass);
 	_FORCE_INLINE_ void _setup_refprobes(ReflectionProbeInstance *p_refprobe1, ReflectionProbeInstance *p_refprobe2, const Transform &p_view_transform, Environment *p_env);
 	_FORCE_INLINE_ void _setup_refprobes(ReflectionProbeInstance *p_refprobe1, ReflectionProbeInstance *p_refprobe2, const Transform &p_view_transform, Environment *p_env);
 	_FORCE_INLINE_ void _render_geometry(RenderList::Element *p_element);
 	_FORCE_INLINE_ void _render_geometry(RenderList::Element *p_element);