diff --git a/resources/shaders/flat_texture_attr.vs b/resources/shaders/flat_texture_attr.vs index bdd675052..e59a99da3 100644 --- a/resources/shaders/flat_texture_attr.vs +++ b/resources/shaders/flat_texture_attr.vs @@ -1,24 +1,15 @@ #version 110 -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ attribute vec3 v_position; attribute vec2 v_tex_coord; uniform mat4 view_model_matrix; uniform mat4 projection_matrix; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ varying vec2 tex_coord; void main() { -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ tex_coord = v_tex_coord; gl_Position = projection_matrix * view_model_matrix * vec4(v_position, 1.0); -// gl_Position = vec4(v_position, 1.0); - - -// gl_Position = ftransform(); -// tex_coord = gl_MultiTexCoord0.xy; -//@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ } diff --git a/resources/shaders/gouraud.fs b/resources/shaders/gouraud.fs index b9e860d10..511faf4c0 100644 --- a/resources/shaders/gouraud.fs +++ b/resources/shaders/gouraud.fs @@ -40,7 +40,6 @@ varying vec2 intensity; uniform PrintVolumeDetection print_volume; -varying vec4 model_pos; varying vec4 world_pos; varying float world_normal_z; varying vec3 eye_normal; diff --git a/resources/shaders/gouraud.vs b/resources/shaders/gouraud.vs index 79d7a63c0..c8b3d7b33 100644 --- a/resources/shaders/gouraud.vs +++ b/resources/shaders/gouraud.vs @@ -38,7 +38,6 @@ varying vec2 intensity; varying vec3 clipping_planes_dots; -varying vec4 model_pos; varying vec4 world_pos; varying float world_normal_z; varying vec3 eye_normal; @@ -60,7 +59,6 @@ void main() NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0); intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; - model_pos = gl_Vertex; // Point in homogenous coordinates. world_pos = volume_world_matrix * gl_Vertex; diff --git a/resources/shaders/gouraud_attr.vs b/resources/shaders/gouraud_attr.vs new file mode 100644 index 000000000..87e524c14 --- /dev/null +++ b/resources/shaders/gouraud_attr.vs @@ -0,0 +1,77 @@ +#version 110 + +#define INTENSITY_CORRECTION 0.6 + +// normalized values for (-0.6/1.31, 0.6/1.31, 1./1.31) +const vec3 LIGHT_TOP_DIR = vec3(-0.4574957, 0.4574957, 0.7624929); +#define LIGHT_TOP_DIFFUSE (0.8 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SPECULAR (0.125 * INTENSITY_CORRECTION) +#define LIGHT_TOP_SHININESS 20.0 + +// normalized values for (1./1.43, 0.2/1.43, 1./1.43) +const vec3 LIGHT_FRONT_DIR = vec3(0.6985074, 0.1397015, 0.6985074); +#define LIGHT_FRONT_DIFFUSE (0.3 * INTENSITY_CORRECTION) +//#define LIGHT_FRONT_SPECULAR (0.0 * INTENSITY_CORRECTION) +//#define LIGHT_FRONT_SHININESS 5.0 + +#define INTENSITY_AMBIENT 0.3 + +const vec3 ZERO = vec3(0.0, 0.0, 0.0); + +struct SlopeDetection +{ + bool actived; + float normal_z; + mat3 volume_world_normal_matrix; +}; + +attribute vec3 v_position; +attribute vec3 v_normal; + +uniform mat4 view_model_matrix; +uniform mat4 projection_matrix; +uniform mat3 normal_matrix; +uniform mat4 volume_world_matrix; +uniform SlopeDetection slope; + +// Clipping plane, x = min z, y = max z. Used by the FFF and SLA previews to clip with a top / bottom plane. +uniform vec2 z_range; +// Clipping plane - general orientation. Used by the SLA gizmo. +uniform vec4 clipping_plane; + +// x = diffuse, y = specular; +varying vec2 intensity; + +varying vec3 clipping_planes_dots; + +varying vec4 world_pos; +varying float world_normal_z; +varying vec3 eye_normal; + +void main() +{ + // First transform the normal into camera space and normalize the result. + eye_normal = normalize(normal_matrix * v_normal); + + // Compute the cos of the angle between the normal and lights direction. The light is directional so the direction is constant for every vertex. + // Since these two are normalized the cosine is the dot product. We also need to clamp the result to the [0,1] range. + float NdotL = max(dot(eye_normal, LIGHT_TOP_DIR), 0.0); + + intensity.x = INTENSITY_AMBIENT + NdotL * LIGHT_TOP_DIFFUSE; + vec4 position = view_model_matrix * vec4(v_position, 1.0); + intensity.y = LIGHT_TOP_SPECULAR * pow(max(dot(-normalize(position.xyz), reflect(-LIGHT_TOP_DIR, eye_normal)), 0.0), LIGHT_TOP_SHININESS); + + // Perform the same lighting calculation for the 2nd light source (no specular applied). + NdotL = max(dot(eye_normal, LIGHT_FRONT_DIR), 0.0); + intensity.x += NdotL * LIGHT_FRONT_DIFFUSE; + + // Point in homogenous coordinates. + world_pos = volume_world_matrix * vec4(v_position, 1.0); + + // z component of normal vector in world coordinate used for slope shading + world_normal_z = slope.actived ? (normalize(slope.volume_world_normal_matrix * v_normal)).z : 0.0; + + gl_Position = projection_matrix * position; + // Fill in the scalars for fragment shader clipping. Fragments with any of these components lower than zero are discarded. + clipping_planes_dots = vec3(dot(world_pos, clipping_plane), world_pos.z - z_range.x, z_range.y - world_pos.z); +} diff --git a/src/slic3r/GUI/3DScene.cpp b/src/slic3r/GUI/3DScene.cpp index 31639c065..9269458df 100644 --- a/src/slic3r/GUI/3DScene.cpp +++ b/src/slic3r/GUI/3DScene.cpp @@ -1097,7 +1097,7 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab #if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES GLShaderProgram* sink_shader = GUI::wxGetApp().get_shader("flat_attr"); GLShaderProgram* edges_shader = GUI::wxGetApp().get_shader("flat_attr"); - bool use_attributes = boost::algorithm::iends_with(shader->get_name(), "_attr"); + assert(boost::algorithm::iends_with(shader->get_name(), "_attr")); #else GLShaderProgram* sink_shader = GUI::wxGetApp().get_shader("flat"); GLShaderProgram* edges_shader = GUI::wxGetApp().get_shader("flat"); @@ -1140,14 +1140,10 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab shader->start_using(); #endif // ENABLE_GLBEGIN_GLEND_REMOVAL -#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES - if (!use_attributes) { -#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES +#if !ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES glsafe(::glEnableClientState(GL_VERTEX_ARRAY)); glsafe(::glEnableClientState(GL_NORMAL_ARRAY)); -#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES - } -#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES +#endif // !ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES #if ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL if (!volume.first->model.is_initialized()) @@ -1176,12 +1172,10 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab volume.first->model.set_color(volume.first->render_color); #endif // ENABLE_GLINDEXEDVERTEXARRAY_REMOVAL #if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES - if (use_attributes) { - const Transform3d matrix = view_matrix * volume.first->world_matrix(); - shader->set_uniform("view_model_matrix", matrix); - shader->set_uniform("projection_matrix", projection_matrix); - shader->set_uniform("normal_matrix", (Matrix3d)matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); - } + const Transform3d matrix = view_matrix * volume.first->world_matrix(); + shader->set_uniform("view_model_matrix", matrix); + shader->set_uniform("projection_matrix", projection_matrix); + shader->set_uniform("normal_matrix", (Matrix3d)matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); #endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES volume.first->render(); @@ -1193,14 +1187,10 @@ void GLVolumeCollection::render(GLVolumeCollection::ERenderType type, bool disab glsafe(::glBindBuffer(GL_ARRAY_BUFFER, 0)); glsafe(::glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0)); -#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES - if (!use_attributes) { -#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES - glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); - glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); -#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES - } -#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES +#if !ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + glsafe(::glDisableClientState(GL_VERTEX_ARRAY)); + glsafe(::glDisableClientState(GL_NORMAL_ARRAY)); +#endif // !ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES } if (m_show_sinking_contours) { diff --git a/src/slic3r/GUI/GLCanvas3D.cpp b/src/slic3r/GUI/GLCanvas3D.cpp index b3bcf379d..5cf8c0619 100644 --- a/src/slic3r/GUI/GLCanvas3D.cpp +++ b/src/slic3r/GUI/GLCanvas3D.cpp @@ -5523,7 +5523,11 @@ void GLCanvas3D::_render_objects(GLVolumeCollection::ERenderType type) m_volumes.set_show_non_manifold_edges(!m_gizmos.is_hiding_instances() && m_gizmos.get_current_type() != GLGizmosManager::Simplify); #endif // ENABLE_SHOW_NON_MANIFOLD_EDGES +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + GLShaderProgram* shader = wxGetApp().get_shader("gouraud_attr"); +#else GLShaderProgram* shader = wxGetApp().get_shader("gouraud"); +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES if (shader != nullptr) { shader->start_using(); diff --git a/src/slic3r/GUI/GLShadersManager.cpp b/src/slic3r/GUI/GLShadersManager.cpp index fb9a9cecf..091e59818 100644 --- a/src/slic3r/GUI/GLShadersManager.cpp +++ b/src/slic3r/GUI/GLShadersManager.cpp @@ -86,7 +86,11 @@ std::pair GLShadersManager::init() valid &= append_shader("toolpaths_lines", { "toolpaths_lines.vs", "toolpaths_lines.fs" }); #endif // !ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES // used to render objects in 3d editor +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + valid &= append_shader("gouraud_attr", { "gouraud_attr.vs", "gouraud.fs" } +#else valid &= append_shader("gouraud", { "gouraud.vs", "gouraud.fs" } +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES #if ENABLE_ENVIRONMENT_MAP , { "ENABLE_ENVIRONMENT_MAP"sv } #endif // ENABLE_ENVIRONMENT_MAP diff --git a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp index a6d970dc9..7910c6eb1 100644 --- a/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp +++ b/src/slic3r/GUI/Gizmos/GLGizmoPainterBase.cpp @@ -80,7 +80,11 @@ GLGizmoPainterBase::ClippingPlaneDataWrapper GLGizmoPainterBase::get_clipping_pl void GLGizmoPainterBase::render_triangles(const Selection& selection) const { +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + auto* shader = wxGetApp().get_shader("gouraud_attr"); +#else auto* shader = wxGetApp().get_shader("gouraud"); +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES if (! shader) return; shader->start_using(); @@ -105,8 +109,16 @@ void GLGizmoPainterBase::render_triangles(const Selection& selection) const if (is_left_handed) glsafe(::glFrontFace(GL_CW)); +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + const Camera& camera = wxGetApp().plater()->get_camera(); + const Transform3d matrix = camera.get_view_matrix() * trafo_matrix; + shader->set_uniform("view_model_matrix", matrix); + shader->set_uniform("projection_matrix", camera.get_projection_matrix()); + shader->set_uniform("normal_matrix", (Matrix3d)matrix.matrix().block(0, 0, 3, 3).inverse().transpose()); +#else glsafe(::glPushMatrix()); glsafe(::glMultMatrixd(trafo_matrix.data())); +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES // For printers with multiple extruders, it is necessary to pass trafo_matrix // to the shader input variable print_box.volume_world_matrix before @@ -116,7 +128,9 @@ void GLGizmoPainterBase::render_triangles(const Selection& selection) const m_triangle_selectors[mesh_id]->render(m_imgui); +#if !ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES glsafe(::glPopMatrix()); +#endif // !ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES if (is_left_handed) glsafe(::glFrontFace(GL_CCW)); } @@ -907,7 +921,11 @@ void TriangleSelectorGUI::render(ImGuiWrapper* imgui) auto* shader = wxGetApp().get_current_shader(); if (! shader) return; +#if ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES + assert(shader->get_name() == "gouraud_attr"); +#else assert(shader->get_name() == "gouraud"); +#endif // ENABLE_GLBEGIN_GLEND_SHADERS_ATTRIBUTES ScopeGuard guard([shader]() { if (shader) shader->set_uniform("offset_depth_buffer", false);}); shader->set_uniform("offset_depth_buffer", true); for (auto iva : {std::make_pair(&m_iva_enforcers, enforcers_color),