Implemented FOG support in GLES2.
This commit is contained in:
parent
723e2e9654
commit
11f088279d
3 changed files with 160 additions and 8 deletions
|
@ -742,20 +742,38 @@ void RasterizerSceneGLES2::environment_set_adjustment(RID p_env, bool p_enable,
|
|||
}
|
||||
|
||||
void RasterizerSceneGLES2::environment_set_fog(RID p_env, bool p_enable, const Color &p_color, const Color &p_sun_color, float p_sun_amount) {
|
||||
|
||||
Environment *env = environment_owner.getornull(p_env);
|
||||
ERR_FAIL_COND(!env);
|
||||
|
||||
env->fog_enabled = p_enable;
|
||||
env->fog_color = p_color;
|
||||
env->fog_sun_color = p_sun_color;
|
||||
env->fog_sun_amount = p_sun_amount;
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES2::environment_set_fog_depth(RID p_env, bool p_enable, float p_depth_begin, float p_depth_curve, bool p_transmit, float p_transmit_curve) {
|
||||
|
||||
Environment *env = environment_owner.getornull(p_env);
|
||||
ERR_FAIL_COND(!env);
|
||||
|
||||
env->fog_depth_enabled = p_enable;
|
||||
env->fog_depth_begin = p_depth_begin;
|
||||
env->fog_depth_curve = p_depth_curve;
|
||||
env->fog_transmit_enabled = p_transmit;
|
||||
env->fog_transmit_curve = p_transmit_curve;
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES2::environment_set_fog_height(RID p_env, bool p_enable, float p_min_height, float p_max_height, float p_height_curve) {
|
||||
|
||||
Environment *env = environment_owner.getornull(p_env);
|
||||
ERR_FAIL_COND(!env);
|
||||
}
|
||||
|
||||
env->fog_height_enabled = p_enable;
|
||||
env->fog_height_min = p_min_height;
|
||||
env->fog_height_max = p_max_height;
|
||||
env->fog_height_curve = p_height_curve;
|
||||
}
|
||||
bool RasterizerSceneGLES2::is_environment(RID p_env) {
|
||||
return environment_owner.owns(p_env);
|
||||
}
|
||||
|
@ -2031,6 +2049,15 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
|
|||
glDisable(GL_BLEND);
|
||||
}
|
||||
|
||||
float fog_max_distance = 0;
|
||||
bool using_fog = false;
|
||||
if (p_env && !p_shadow && p_env->fog_enabled && (p_env->fog_depth_enabled || p_env->fog_height_enabled)) {
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::FOG_DEPTH_ENABLED, p_env->fog_depth_enabled);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::FOG_HEIGHT_ENABLED, p_env->fog_height_enabled);
|
||||
fog_max_distance = p_projection.get_z_far();
|
||||
using_fog = true;
|
||||
}
|
||||
|
||||
RasterizerStorageGLES2::Texture *prev_lightmap = NULL;
|
||||
float lightmap_energy = 1.0;
|
||||
bool prev_use_lightmap_capture = false;
|
||||
|
@ -2268,10 +2295,34 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
|
|||
rebind_light = true;
|
||||
rebind_reflection = true;
|
||||
rebind_lightmap = true;
|
||||
|
||||
if (using_fog) {
|
||||
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::FOG_COLOR_BASE, p_env->fog_color);
|
||||
Color sun_color_amount = p_env->fog_sun_color;
|
||||
sun_color_amount.a = p_env->fog_sun_amount;
|
||||
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::FOG_SUN_COLOR_AMOUNT, sun_color_amount);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::FOG_TRANSMIT_ENABLED, p_env->fog_transmit_enabled);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::FOG_TRANSMIT_CURVE, p_env->fog_transmit_curve);
|
||||
|
||||
if (p_env->fog_depth_enabled) {
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::FOG_DEPTH_BEGIN, p_env->fog_depth_begin);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::FOG_DEPTH_CURVE, p_env->fog_depth_curve);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::FOG_MAX_DISTANCE, fog_max_distance);
|
||||
}
|
||||
|
||||
if (p_env->fog_height_enabled) {
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::FOG_HEIGHT_MIN, p_env->fog_height_min);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::FOG_HEIGHT_MAX, p_env->fog_height_max);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::FOG_HEIGHT_MAX, p_env->fog_height_max);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::FOG_HEIGHT_CURVE, p_env->fog_height_curve);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::CAMERA_MATRIX, view_transform_inverse);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::CAMERA_INVERSE_MATRIX, p_view_transform);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::CAMERA_MATRIX, p_view_transform);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::CAMERA_INVERSE_MATRIX, view_transform_inverse);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::PROJECTION_MATRIX, p_projection);
|
||||
state.scene_shader.set_uniform(SceneShaderGLES2::PROJECTION_INVERSE_MATRIX, projection_inverse);
|
||||
|
||||
|
@ -2328,6 +2379,8 @@ void RasterizerSceneGLES2::_render_render_list(RenderList::Element **p_elements,
|
|||
state.scene_shader.set_conditional(SceneShaderGLES2::USE_REFLECTION_PROBE2, false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::USE_LIGHTMAP, false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::USE_LIGHTMAP_CAPTURE, false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::FOG_DEPTH_ENABLED, false);
|
||||
state.scene_shader.set_conditional(SceneShaderGLES2::FOG_HEIGHT_ENABLED, false);
|
||||
}
|
||||
|
||||
void RasterizerSceneGLES2::_draw_sky(RasterizerStorageGLES2::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_custom_fov, float p_energy) {
|
||||
|
|
|
@ -353,6 +353,21 @@ public:
|
|||
|
||||
int canvas_max_layer;
|
||||
|
||||
bool fog_enabled;
|
||||
Color fog_color;
|
||||
Color fog_sun_color;
|
||||
float fog_sun_amount;
|
||||
|
||||
bool fog_depth_enabled;
|
||||
float fog_depth_begin;
|
||||
float fog_depth_curve;
|
||||
bool fog_transmit_enabled;
|
||||
float fog_transmit_curve;
|
||||
bool fog_height_enabled;
|
||||
float fog_height_min;
|
||||
float fog_height_max;
|
||||
float fog_height_curve;
|
||||
|
||||
Environment() {
|
||||
bg_mode = VS::ENV_BG_CLEAR_COLOR;
|
||||
sky_custom_fov = 0.0;
|
||||
|
@ -361,6 +376,24 @@ public:
|
|||
ambient_energy = 1.0;
|
||||
ambient_sky_contribution = 0.0;
|
||||
canvas_max_layer = 0;
|
||||
|
||||
fog_enabled = false;
|
||||
fog_color = Color(0.5, 0.5, 0.5);
|
||||
fog_sun_color = Color(0.8, 0.8, 0.0);
|
||||
fog_sun_amount = 0;
|
||||
|
||||
fog_depth_enabled = true;
|
||||
|
||||
fog_depth_begin = 10;
|
||||
fog_depth_curve = 1;
|
||||
|
||||
fog_transmit_enabled = true;
|
||||
fog_transmit_curve = 1;
|
||||
|
||||
fog_height_enabled = false;
|
||||
fog_height_min = 0;
|
||||
fog_height_max = 100;
|
||||
fog_height_curve = 1;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -379,7 +379,7 @@ void main() {
|
|||
|
||||
#endif
|
||||
|
||||
mat4 modelview = camera_matrix * world_matrix;
|
||||
mat4 modelview = camera_inverse_matrix * world_matrix;
|
||||
float roughness = 1.0;
|
||||
|
||||
#define world_transform world_matrix
|
||||
|
@ -406,11 +406,11 @@ VERTEX_SHADER_CODE
|
|||
#endif
|
||||
|
||||
#if !defined(SKIP_TRANSFORM_USED) && defined(VERTEX_WORLD_COORDS_USED)
|
||||
vertex = camera_matrix * vertex;
|
||||
normal = normalize((camera_matrix * vec4(normal, 0.0)).xyz);
|
||||
vertex = camera_inverse_matrix * vertex;
|
||||
normal = normalize((camera_inverse_matrix * vec4(normal, 0.0)).xyz);
|
||||
#if defined(ENABLE_TANGENT_INTERP) || defined(ENABLE_NORMALMAP)
|
||||
tangent = normalize((camera_matrix * vec4(tangent, 0.0)).xyz);
|
||||
binormal = normalize((camera_matrix * vec4(binormal, 0.0)).xyz);
|
||||
tangent = normalize((camera_inverse_matrix * vec4(tangent, 0.0)).xyz);
|
||||
binormal = normalize((camera_inverse_matrix * vec4(binormal, 0.0)).xyz);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
@ -816,6 +816,8 @@ uniform float ambient_energy;
|
|||
varying highp vec3 diffuse_interp;
|
||||
varying highp vec3 specular_interp;
|
||||
|
||||
uniform vec3 light_direction; //may be used by fog, so leave here
|
||||
|
||||
#else
|
||||
//done in fragment
|
||||
// general for all lights
|
||||
|
@ -1296,6 +1298,30 @@ float sample_shadow(
|
|||
|
||||
#endif
|
||||
|
||||
#if defined(FOG_DEPTH_ENABLED) || defined(FOG_HEIGHT_ENABLED)
|
||||
|
||||
uniform mediump vec4 fog_color_base;
|
||||
#ifdef LIGHT_MODE_DIRECTIONAL
|
||||
uniform mediump vec4 fog_sun_color_amount;
|
||||
#endif
|
||||
|
||||
uniform bool fog_transmit_enabled;
|
||||
uniform mediump float fog_transmit_curve;
|
||||
|
||||
#ifdef FOG_DEPTH_ENABLED
|
||||
uniform highp float fog_depth_begin;
|
||||
uniform mediump float fog_depth_curve;
|
||||
uniform mediump float fog_max_distance;
|
||||
#endif
|
||||
|
||||
#ifdef FOG_HEIGHT_ENABLED
|
||||
uniform highp float fog_height_min;
|
||||
uniform highp float fog_height_max;
|
||||
uniform mediump float fog_height_curve;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
void main() {
|
||||
|
||||
#ifdef RENDER_DEPTH_DUAL_PARABOLOID
|
||||
|
@ -1926,5 +1952,45 @@ FRAGMENT_SHADER_CODE
|
|||
|
||||
#endif //unshaded
|
||||
|
||||
//apply fog
|
||||
#if defined(FOG_DEPTH_ENABLED) || defined(FOG_HEIGHT_ENABLED)
|
||||
|
||||
float fog_amount = 0.0;
|
||||
|
||||
#ifdef LIGHT_MODE_DIRECTIONAL
|
||||
|
||||
vec3 fog_color = mix(fog_color_base.rgb, fog_sun_color_amount.rgb, fog_sun_color_amount.a * pow(max(dot(eye_position, light_direction), 0.0), 8.0));
|
||||
#else
|
||||
vec3 fog_color = fog_color_base.rgb;
|
||||
#endif
|
||||
|
||||
#ifdef FOG_DEPTH_ENABLED
|
||||
|
||||
{
|
||||
|
||||
float fog_z = smoothstep(fog_depth_begin, fog_max_distance, length(vertex));
|
||||
|
||||
fog_amount = pow(fog_z, fog_depth_curve);
|
||||
|
||||
if (fog_transmit_enabled) {
|
||||
vec3 total_light = gl_FragColor.rgb;
|
||||
float transmit = pow(fog_z, fog_transmit_curve);
|
||||
fog_color = mix(max(total_light, fog_color), fog_color, transmit);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef FOG_HEIGHT_ENABLED
|
||||
{
|
||||
float y = (camera_matrix * vec4(vertex, 1.0)).y;
|
||||
fog_amount = max(fog_amount, pow(smoothstep(fog_height_min, fog_height_max, y), fog_height_curve));
|
||||
}
|
||||
#endif
|
||||
|
||||
gl_FragColor.rgb = mix(gl_FragColor.rgb,fog_color,fog_amount);
|
||||
|
||||
|
||||
#endif // defined(FOG_DEPTH_ENABLED) || defined(FOG_HEIGHT_ENABLED)
|
||||
|
||||
#endif // not RENDER_DEPTH
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue