diff options
author | Juan Linietsky <reduzio@gmail.com> | 2017-07-08 12:34:05 -0300 |
---|---|---|
committer | Juan Linietsky <reduzio@gmail.com> | 2017-07-08 12:36:15 -0300 |
commit | f4c8c552f956094e1bb8787de79476f57dd6a7b6 (patch) | |
tree | 4ed1eb9e7d0a9401db6eaaadf257d8e73e03b499 /drivers/gles3 | |
parent | 0067982f5ece3145c00e2f4c0bc092d1ec28c8b3 (diff) |
Added triplanar mapping, toon mode, and more specular modes for materials. Added multipass support for materials.
Diffstat (limited to 'drivers/gles3')
-rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.cpp | 18 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_scene_gles3.h | 2 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.cpp | 22 | ||||
-rw-r--r-- | drivers/gles3/rasterizer_storage_gles3.h | 3 | ||||
-rw-r--r-- | drivers/gles3/shader_compiler_gles3.cpp | 5 | ||||
-rw-r--r-- | drivers/gles3/shaders/cubemap_filter.glsl | 4 | ||||
-rw-r--r-- | drivers/gles3/shaders/scene.glsl | 36 |
7 files changed, 84 insertions, 6 deletions
diff --git a/drivers/gles3/rasterizer_scene_gles3.cpp b/drivers/gles3/rasterizer_scene_gles3.cpp index 3b3ce73264..ce8ff2ff9e 100644 --- a/drivers/gles3/rasterizer_scene_gles3.cpp +++ b/drivers/gles3/rasterizer_scene_gles3.cpp @@ -1879,6 +1879,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ glBindBufferBase(GL_UNIFORM_BUFFER, 0, state.scene_ubo); //bind globals ubo + bool use_radiance_map = false; if (!p_shadow && !p_directional_add) { glBindBufferBase(GL_UNIFORM_BUFFER, 2, state.env_radiance_ubo); //bind environment radiance info @@ -1892,6 +1893,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ state.scene_shader.set_conditional(SceneShaderGLES3::USE_RADIANCE_MAP, true); state.scene_shader.set_conditional(SceneShaderGLES3::USE_RADIANCE_MAP_ARRAY, storage->config.use_texture_array_environment); + use_radiance_map = true; } else { state.scene_shader.set_conditional(SceneShaderGLES3::USE_RADIANCE_MAP, false); state.scene_shader.set_conditional(SceneShaderGLES3::USE_RADIANCE_MAP_ARRAY, false); @@ -1966,6 +1968,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ state.scene_shader.set_conditional(SceneShaderGLES3::SHADOW_MODE_PCF_5, false); state.scene_shader.set_conditional(SceneShaderGLES3::SHADOW_MODE_PCF_13, false); state.scene_shader.set_conditional(SceneShaderGLES3::USE_GI_PROBES, false); + state.scene_shader.set_conditional(SceneShaderGLES3::USE_RADIANCE_MAP, false); //state.scene_shader.set_conditional(SceneShaderGLES3::SHADELESS,true); } else { @@ -1981,6 +1984,7 @@ void RasterizerSceneGLES3::_render_list(RenderList::Element **p_elements, int p_ state.scene_shader.set_conditional(SceneShaderGLES3::LIGHT_USE_PSSM_BLEND, false); state.scene_shader.set_conditional(SceneShaderGLES3::SHADOW_MODE_PCF_5, shadow_filter_mode == SHADOW_FILTER_PCF5); state.scene_shader.set_conditional(SceneShaderGLES3::SHADOW_MODE_PCF_13, shadow_filter_mode == SHADOW_FILTER_PCF13); + state.scene_shader.set_conditional(SceneShaderGLES3::USE_RADIANCE_MAP, use_radiance_map); if (p_directional_add || (directional_light && (e->sort_key & SORT_KEY_NO_DIRECTIONAL_FLAG) == 0)) { state.scene_shader.set_conditional(SceneShaderGLES3::USE_LIGHT_DIRECTIONAL, true); @@ -2163,7 +2167,19 @@ void RasterizerSceneGLES3::_add_geometry(RasterizerStorageGLES3::Geometry *p_geo ERR_FAIL_COND(!m); - bool has_base_alpha = (m->shader->spatial.uses_alpha || m->shader->spatial.uses_screen_texture); + _add_geometry_with_material(p_geometry, p_instance, p_owner, m, p_shadow); + + while (m->next_pass.is_valid()) { + m = storage->material_owner.getornull(m->next_pass); + if (!m) + break; + _add_geometry_with_material(p_geometry, p_instance, p_owner, m, p_shadow); + } +} + +void RasterizerSceneGLES3::_add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *m, bool p_shadow) { + + bool has_base_alpha = (m->shader->spatial.uses_alpha || m->shader->spatial.uses_screen_texture || m->shader->spatial.unshaded); bool has_blend_alpha = m->shader->spatial.blend_mode != RasterizerStorageGLES3::Shader::Spatial::BLEND_MODE_MIX || m->shader->spatial.ontop; bool has_alpha = has_base_alpha || has_blend_alpha; bool shadow = false; diff --git a/drivers/gles3/rasterizer_scene_gles3.h b/drivers/gles3/rasterizer_scene_gles3.h index 5f0db446a9..69213bf49e 100644 --- a/drivers/gles3/rasterizer_scene_gles3.h +++ b/drivers/gles3/rasterizer_scene_gles3.h @@ -769,6 +769,8 @@ public: _FORCE_INLINE_ void _add_geometry(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, int p_material, bool p_shadow); + _FORCE_INLINE_ void _add_geometry_with_material(RasterizerStorageGLES3::Geometry *p_geometry, InstanceBase *p_instance, RasterizerStorageGLES3::GeometryOwner *p_owner, RasterizerStorageGLES3::Material *p_material, bool p_shadow); + void _draw_sky(RasterizerStorageGLES3::Sky *p_sky, const CameraMatrix &p_projection, const Transform &p_transform, bool p_vflip, float p_scale, float p_energy); void _setup_environment(Environment *env, const CameraMatrix &p_cam_projection, const Transform &p_cam_transform); diff --git a/drivers/gles3/rasterizer_storage_gles3.cpp b/drivers/gles3/rasterizer_storage_gles3.cpp index 036ff58719..14fb36f3b0 100644 --- a/drivers/gles3/rasterizer_storage_gles3.cpp +++ b/drivers/gles3/rasterizer_storage_gles3.cpp @@ -1870,6 +1870,14 @@ void RasterizerStorageGLES3::material_set_line_width(RID p_material, float p_wid material->line_width = p_width; } +void RasterizerStorageGLES3::material_set_next_pass(RID p_material, RID p_next_material) { + + Material *material = material_owner.get(p_material); + ERR_FAIL_COND(!material); + + material->next_pass = p_next_material; +} + bool RasterizerStorageGLES3::material_is_animated(RID p_material) { Material *material = material_owner.get(p_material); @@ -1878,7 +1886,11 @@ bool RasterizerStorageGLES3::material_is_animated(RID p_material) { _update_material(material); } - return material->is_animated_cache; + bool animated = material->is_animated_cache; + if (!animated && material->next_pass.is_valid()) { + animated = material_is_animated(material->next_pass); + } + return animated; } bool RasterizerStorageGLES3::material_casts_shadows(RID p_material) { @@ -1888,7 +1900,13 @@ bool RasterizerStorageGLES3::material_casts_shadows(RID p_material) { _update_material(material); } - return material->can_cast_shadow_cache; + bool casts_shadows = material->can_cast_shadow_cache; + + if (!casts_shadows && material->next_pass.is_valid()) { + casts_shadows = material_casts_shadows(material->next_pass); + } + + return casts_shadows; } void RasterizerStorageGLES3::material_add_instance_owner(RID p_material, RasterizerScene::InstanceBase *p_instance) { diff --git a/drivers/gles3/rasterizer_storage_gles3.h b/drivers/gles3/rasterizer_storage_gles3.h index d317d27656..183db534ac 100644 --- a/drivers/gles3/rasterizer_storage_gles3.h +++ b/drivers/gles3/rasterizer_storage_gles3.h @@ -496,6 +496,8 @@ public: Vector<RID> textures; float line_width; + RID next_pass; + uint32_t index; uint64_t last_pass; @@ -533,6 +535,7 @@ public: virtual Variant material_get_param(RID p_material, const StringName &p_param) const; virtual void material_set_line_width(RID p_material, float p_width); + virtual void material_set_next_pass(RID p_material, RID p_next_material); virtual bool material_is_animated(RID p_material); virtual bool material_casts_shadows(RID p_material); diff --git a/drivers/gles3/shader_compiler_gles3.cpp b/drivers/gles3/shader_compiler_gles3.cpp index 0bcfaf1839..54cbc07f59 100644 --- a/drivers/gles3/shader_compiler_gles3.cpp +++ b/drivers/gles3/shader_compiler_gles3.cpp @@ -791,6 +791,11 @@ ShaderCompilerGLES3::ShaderCompilerGLES3() { actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_burley"] = "#define DIFFUSE_BURLEY\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_oren_nayar"] = "#define DIFFUSE_OREN_NAYAR\n"; actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_half_lambert"] = "#define DIFFUSE_HALF_LAMBERT\n"; + actions[VS::SHADER_SPATIAL].render_mode_defines["diffuse_toon"] = "#define DIFFUSE_TOON\n"; + + actions[VS::SHADER_SPATIAL].render_mode_defines["specular_blinn"] = "#define SPECULAR_BLINN\n"; + actions[VS::SHADER_SPATIAL].render_mode_defines["specular_phong"] = "#define SPECULAR_PHONG\n"; + actions[VS::SHADER_SPATIAL].render_mode_defines["specular_toon"] = "#define SPECULAR_TOON\n"; /* PARTICLES SHADER */ diff --git a/drivers/gles3/shaders/cubemap_filter.glsl b/drivers/gles3/shaders/cubemap_filter.glsl index 10a803cafe..393ef2892a 100644 --- a/drivers/gles3/shaders/cubemap_filter.glsl +++ b/drivers/gles3/shaders/cubemap_filter.glsl @@ -204,7 +204,9 @@ vec4 textureDualParaboloidArray(vec3 normal) { vec3 norm = normalize(normal); norm.xy/=1.0+abs(norm.z); norm.xy=norm.xy * vec2(0.5,0.25) + vec2(0.5,0.25); - norm.y+=max(0.0,sign(-norm.z))*0.5; + if (norm.z<0) { + norm.y=0.5-norm.y+0.5; + } return textureLod(source_dual_paraboloid_array, vec3(norm.xy, float(source_array_index) ), 0.0); } diff --git a/drivers/gles3/shaders/scene.glsl b/drivers/gles3/shaders/scene.glsl index cea963503f..545c7b2605 100644 --- a/drivers/gles3/shaders/scene.glsl +++ b/drivers/gles3/shaders/scene.glsl @@ -775,6 +775,10 @@ LIGHT_SHADER_CODE diffuse += diffuse_color * max(0.0, NdotL) * (A + vec3(B) * s / t) / M_PI; } +#elif defined(DIFFUSE_TOON) + + diffuse += smoothstep(-roughness,roughness,dot(N,L)) * light_color * diffuse_color; + #elif defined(DIFFUSE_BURLEY) { @@ -805,6 +809,34 @@ LIGHT_SHADER_CODE if (roughness > 0.0) { + + // D + +#if defined(SPECULAR_BLINN) + + vec3 H = normalize(V + L); + float dotNH = max(dot(N,H), 0.0 ); + float intensity = pow( dotNH, (1.0-roughness) * 256.0); + specular += light_color * intensity; + +#elif defined(SPECULAR_PHONG) + + vec3 R = normalize(-reflect(L,N)); + float dotNV = max(0.0,dot(R,V)); + float intensity = pow( dotNV, (1.0-roughness) * 256.0); + specular += light_color * intensity; + +#elif defined(SPECULAR_TOON) + + vec3 R = normalize(-reflect(L,N)); + float dotNV = dot(R,V); + float mid = 1.0-roughness; + float intensity = smoothstep(mid-roughness*0.5,mid+roughness*0.5,dotNV); + diffuse += light_color * intensity; //write to diffuse, as in toon shading you generally want no reflection + + +#else + // shlick+ggx as default float alpha = roughness * roughness; vec3 H = normalize(V + L); @@ -812,7 +844,6 @@ LIGHT_SHADER_CODE float dotNH = max(dot(N,H), 0.0 ); float dotLH = max(dot(L,H), 0.0 ); - // D #if defined(LIGHT_USE_ANISOTROPY) float aspect = sqrt(1.0-anisotropy*0.9); @@ -844,6 +875,7 @@ LIGHT_SHADER_CODE float speci = dotNL * D * F * vis; specular += speci * light_color * specular_blob_intensity; +#endif #if defined(LIGHT_USE_CLEARCOAT) float Dr = GTR1(dotNH, mix(.1,.001,clearcoat_gloss)); @@ -1686,7 +1718,7 @@ FRAGMENT_SHADER_CODE float ndotv = clamp(dot(normal,eye_vec),0.0,1.0); //energy conservation - vec3 dielectric = vec3(0.034) * 0.5 * 2.0; + vec3 dielectric = vec3(0.034) * specular * 2.0; vec3 f0 = mix(dielectric, albedo, metallic); const vec4 c0 = vec4(-1.0, -0.0275, -0.572, 0.022); const vec4 c1 = vec4( 1.0, 0.0425, 1.04, -0.04); |