diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx index 426597b83e..6638903594 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.cxx +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.cxx @@ -52,6 +52,7 @@ #include "alphaTestAttrib.h" #include "clipPlaneAttrib.h" #include "cullFaceAttrib.h" +#include "depthBiasAttrib.h" #include "depthOffsetAttrib.h" #include "depthWriteAttrib.h" #include "fogAttrib.h" @@ -156,6 +157,13 @@ null_glBlendColor(GLclampf, GLclampf, GLclampf, GLclampf) { } #endif +#ifndef OPENGLES_1 +static void APIENTRY +null_glPolygonOffsetClamp(GLfloat factor, GLfloat units, GLfloat clamp) { + glPolygonOffset(factor, units); +} +#endif + #ifndef OPENGLES_1 // We have a default shader that will be applied when there isn't any shader // applied (e.g. if it failed to compile). We need this because OpenGL ES @@ -626,6 +634,7 @@ reset() { _inv_state_mask.clear_bit(ColorAttrib::get_class_slot()); _inv_state_mask.clear_bit(ColorScaleAttrib::get_class_slot()); _inv_state_mask.clear_bit(CullFaceAttrib::get_class_slot()); + _inv_state_mask.clear_bit(DepthBiasAttrib::get_class_slot()); _inv_state_mask.clear_bit(DepthOffsetAttrib::get_class_slot()); _inv_state_mask.clear_bit(DepthTestAttrib::get_class_slot()); _inv_state_mask.clear_bit(DepthWriteAttrib::get_class_slot()); @@ -3365,6 +3374,21 @@ reset() { _has_attrib_depth_range = false; } +#ifndef OPENGLES_1 +#ifndef OPENGLES + if (is_at_least_gl_version(4, 6) || has_extension("GL_ARB_polygon_offset_clamp")) { + _glPolygonOffsetClamp = (PFNGLPOLYGONOFFSETCLAMPEXTPROC)get_extension_func("glPolygonOffsetClamp"); + } + else +#endif + if (has_extension("GL_EXT_polygon_offset_clamp")) { + _glPolygonOffsetClamp = (PFNGLPOLYGONOFFSETCLAMPEXTPROC)get_extension_func("glPolygonOffsetClampEXT"); + } + else { + _glPolygonOffsetClamp = null_glPolygonOffsetClamp; + } +#endif + // Set up all the enableddisabled flags to GL's known initial values: // everything off. _multisample_mode = 0; @@ -8173,19 +8197,34 @@ do_issue_fog() { * */ void CLP(GraphicsStateGuardian):: -do_issue_depth_offset() { - const DepthOffsetAttrib *target_depth_offset = (const DepthOffsetAttrib *) - _target_rs->get_attrib_def(DepthOffsetAttrib::get_class_slot()); - +do_issue_depth_bias() { + const DepthOffsetAttrib *target_depth_offset; + _target_rs->get_attrib_def(target_depth_offset); int offset = target_depth_offset->get_offset(); - if (offset != 0) { + const DepthBiasAttrib *target_depth_bias; + if (_target_rs->get_attrib(target_depth_bias)) { + GLfloat slope_factor = target_depth_bias->get_slope_factor(); + GLfloat constant_factor = target_depth_bias->get_constant_factor(); + + slope_factor -= offset; + constant_factor -= offset; + +#ifndef OPENGLES_1 + GLfloat clamp = target_depth_bias->get_clamp(); + _glPolygonOffsetClamp(slope_factor, constant_factor, clamp); +#else + glPolygonOffset(slope_factor, constant_factor); +#endif + enable_polygon_offset(true); + } + else if (offset != 0) { // The relationship between these two parameters is a little unclear and // poorly explained in the GL man pages. glPolygonOffset((GLfloat) -offset, (GLfloat) -offset); enable_polygon_offset(true); - - } else { + } + else { enable_polygon_offset(false); } @@ -11785,11 +11824,15 @@ set_state_and_transform(const RenderState *target, _state_mask.set_bit(cull_face_slot); } + int depth_bias_slot = DepthBiasAttrib::get_class_slot(); int depth_offset_slot = DepthOffsetAttrib::get_class_slot(); - if (_target_rs->get_attrib(depth_offset_slot) != _state_rs->get_attrib(depth_offset_slot) || + if (_target_rs->get_attrib(depth_bias_slot) != _state_rs->get_attrib(depth_bias_slot) || + _target_rs->get_attrib(depth_offset_slot) != _state_rs->get_attrib(depth_offset_slot) || + !_state_mask.get_bit(depth_bias_slot) || !_state_mask.get_bit(depth_offset_slot)) { // PStatGPUTimer timer(this, _draw_set_state_depth_offset_pcollector); - do_issue_depth_offset(); + do_issue_depth_bias(); + _state_mask.set_bit(depth_bias_slot); _state_mask.set_bit(depth_offset_slot); } diff --git a/panda/src/glstuff/glGraphicsStateGuardian_src.h b/panda/src/glstuff/glGraphicsStateGuardian_src.h index 656ee40e5b..1bc31174c8 100644 --- a/panda/src/glstuff/glGraphicsStateGuardian_src.h +++ b/panda/src/glstuff/glGraphicsStateGuardian_src.h @@ -454,7 +454,7 @@ protected: #ifdef SUPPORT_FIXED_FUNCTION void do_issue_fog(); #endif - void do_issue_depth_offset(); + void do_issue_depth_bias(); void do_issue_shade_model(); #ifndef OPENGLES_1 void do_issue_shader(); @@ -772,6 +772,9 @@ public: bool _use_remapped_depth_range; PFNGLDEPTHRANGEDNVPROC _glDepthRangedNV; #endif +#ifndef OPENGLES_1 + PFNGLPOLYGONOFFSETCLAMPEXTPROC _glPolygonOffsetClamp; +#endif bool _supports_point_parameters; PFNGLPOINTPARAMETERFVPROC _glPointParameterfv; diff --git a/panda/src/pgraph/CMakeLists.txt b/panda/src/pgraph/CMakeLists.txt index 2eb4d98a06..85c041f01b 100644 --- a/panda/src/pgraph/CMakeLists.txt +++ b/panda/src/pgraph/CMakeLists.txt @@ -29,6 +29,7 @@ set(P3PGRAPH_HEADERS cullTraverserData.I cullTraverserData.h cullableObject.I cullableObject.h decalEffect.I decalEffect.h + depthBiasAttrib.I depthBiasAttrib.h depthOffsetAttrib.I depthOffsetAttrib.h depthTestAttrib.I depthTestAttrib.h depthWriteAttrib.I depthWriteAttrib.h @@ -131,6 +132,7 @@ set(P3PGRAPH_SOURCES cullTraverserData.cxx cullableObject.cxx decalEffect.cxx + depthBiasAttrib.cxx depthOffsetAttrib.cxx depthTestAttrib.cxx depthWriteAttrib.cxx diff --git a/panda/src/pgraph/config_pgraph.cxx b/panda/src/pgraph/config_pgraph.cxx index d13e6e8c95..406f8fa41a 100644 --- a/panda/src/pgraph/config_pgraph.cxx +++ b/panda/src/pgraph/config_pgraph.cxx @@ -33,6 +33,7 @@ #include "cullTraverser.h" #include "cullableObject.h" #include "decalEffect.h" +#include "depthBiasAttrib.h" #include "depthOffsetAttrib.h" #include "depthTestAttrib.h" #include "depthWriteAttrib.h" @@ -416,6 +417,7 @@ init_libpgraph() { CullTraverser::init_type(); CullableObject::init_type(); DecalEffect::init_type(); + DepthBiasAttrib::init_type(); DepthOffsetAttrib::init_type(); DepthTestAttrib::init_type(); DepthWriteAttrib::init_type(); @@ -489,6 +491,7 @@ init_libpgraph() { CullBinAttrib::register_with_read_factory(); CullFaceAttrib::register_with_read_factory(); DecalEffect::register_with_read_factory(); + DepthBiasAttrib::register_with_read_factory(); DepthOffsetAttrib::register_with_read_factory(); DepthTestAttrib::register_with_read_factory(); DepthWriteAttrib::register_with_read_factory(); diff --git a/panda/src/pgraph/depthBiasAttrib.I b/panda/src/pgraph/depthBiasAttrib.I new file mode 100644 index 0000000000..6a73641c8e --- /dev/null +++ b/panda/src/pgraph/depthBiasAttrib.I @@ -0,0 +1,49 @@ +/** + * PANDA 3D SOFTWARE + * Copyright (c) Carnegie Mellon University. All rights reserved. + * + * All use of this software is subject to the terms of the revised BSD + * license. You should have received a copy of this license along + * with this source code in a file named "LICENSE." + * + * @file depthBiasAttrib.I + * @author rdb + * @date 2021-08-24 + */ + +/** + * Use DepthBiasAttrib::make() to construct a new DepthBiasAttrib object. + */ +INLINE DepthBiasAttrib:: +DepthBiasAttrib(PN_stdfloat slope_factor, PN_stdfloat constant_factor, + PN_stdfloat clamp) : + _slope_factor(slope_factor), + _constant_factor(constant_factor), + _clamp(clamp) +{ +} + +/** + * Returns the slope factor. + */ +INLINE PN_stdfloat DepthBiasAttrib:: +get_slope_factor() const { + return _slope_factor; +} + +/** + * Returns the constant factor. + */ +INLINE PN_stdfloat DepthBiasAttrib:: +get_constant_factor() const { + return _constant_factor; +} + +/** + * Returns the maximum (or minimum, if negative) value of the bias. If zero, + * no clamping is performed. + */ +INLINE PN_stdfloat DepthBiasAttrib:: +get_clamp() const { + return _clamp; +} diff --git a/panda/src/pgraph/depthBiasAttrib.cxx b/panda/src/pgraph/depthBiasAttrib.cxx new file mode 100644 index 0000000000..4a5e8273de --- /dev/null +++ b/panda/src/pgraph/depthBiasAttrib.cxx @@ -0,0 +1,180 @@ +/** + * PANDA 3D SOFTWARE + * Copyright (c) Carnegie Mellon University. All rights reserved. + * + * All use of this software is subject to the terms of the revised BSD + * license. You should have received a copy of this license along + * with this source code in a file named "LICENSE." + * + * @file depthBiasAttrib.cxx + * @author rdb + * @date 2021-08-24 + */ + +#include "depthBiasAttrib.h" +#include "graphicsStateGuardianBase.h" +#include "dcast.h" +#include "bamReader.h" +#include "bamWriter.h" +#include "datagram.h" +#include "datagramIterator.h" + +TypeHandle DepthBiasAttrib::_type_handle; +int DepthBiasAttrib::_attrib_slot; + +/** + * Constructs a new DepthBiasAttrib object that indicates the slope factor, + * constant factor, and an optional clamping value. + */ +CPT(RenderAttrib) DepthBiasAttrib:: +make(PN_stdfloat slope_factor, PN_stdfloat constant_factor, PN_stdfloat clamp) { + DepthBiasAttrib *attrib = new DepthBiasAttrib(slope_factor, constant_factor, clamp); + return return_new(attrib); +} + +/** + * Returns a RenderAttrib that corresponds to whatever the standard default + * properties for render attributes of this type ought to be. + */ +CPT(RenderAttrib) DepthBiasAttrib:: +make_default() { + return return_new(new DepthBiasAttrib(0, 0, 0)); +} + +/** + * + */ +void DepthBiasAttrib:: +output(std::ostream &out) const { + out << get_type() << ":(" << get_slope_factor() << ", " << get_constant_factor() + << ", " << get_clamp() << ")"; +} + +/** + * Intended to be overridden by derived DepthBiasAttrib types to return a + * unique number indicating whether this DepthBiasAttrib is equivalent to + * the other one. + * + * This should return 0 if the two DepthBiasAttrib objects are equivalent, a + * number less than zero if this one should be sorted before the other one, + * and a number greater than zero otherwise. + * + * This will only be called with two DepthBiasAttrib objects whose + * get_type() functions return the same. + */ +int DepthBiasAttrib:: +compare_to_impl(const RenderAttrib *other) const { + const DepthBiasAttrib *ta = (const DepthBiasAttrib *)other; + + if (_slope_factor != ta->_slope_factor) { + return _slope_factor < ta->_slope_factor ? -1 : 1; + } + if (_constant_factor != ta->_constant_factor) { + return _constant_factor < ta->_constant_factor ? -1 : 1; + } + if (_clamp != ta->_clamp) { + return _clamp < ta->_clamp ? -1 : 1; + } + return 0; +} + +/** + * Intended to be overridden by derived RenderAttrib types to return a unique + * hash for these particular properties. RenderAttribs that compare the same + * with compare_to_impl(), above, should return the same hash; RenderAttribs + * that compare differently should return a different hash. + */ +size_t DepthBiasAttrib:: +get_hash_impl() const { + size_t hash = 0; + hash = float_hash().add_hash(hash, _slope_factor); + hash = float_hash().add_hash(hash, _constant_factor); + hash = float_hash().add_hash(hash, _clamp); + return hash; +} + +/** + * Intended to be overridden by derived RenderAttrib types to specify how two + * consecutive RenderAttrib objects of the same type interact. + * + * This should return the result of applying the other RenderAttrib to a node + * in the scene graph below this RenderAttrib, which was already applied. In + * most cases, the result is the same as the other RenderAttrib (that is, a + * subsequent RenderAttrib completely replaces the preceding one). On the + * other hand, some kinds of RenderAttrib (for instance, ColorTransformAttrib) + * might combine in meaningful ways. + */ +CPT(RenderAttrib) DepthBiasAttrib:: +compose_impl(const RenderAttrib *other) const { + const DepthBiasAttrib *ba = (const DepthBiasAttrib *)other; + + return return_new(new DepthBiasAttrib(ba->_slope_factor + _slope_factor, + ba->_constant_factor + _constant_factor, + ba->_clamp)); +} + +/** + * Intended to be overridden by derived RenderAttrib types to specify how two + * consecutive RenderAttrib objects of the same type interact. + * + * See invert_compose() and compose_impl(). + */ +CPT(RenderAttrib) DepthBiasAttrib:: +invert_compose_impl(const RenderAttrib *other) const { + const DepthBiasAttrib *ba = (const DepthBiasAttrib *)other; + + return return_new(new DepthBiasAttrib(ba->_slope_factor - _slope_factor, + ba->_constant_factor - _constant_factor, + ba->_clamp)); +} + +/** + * Tells the BamReader how to create objects of type DepthBiasAttrib. + */ +void DepthBiasAttrib:: +register_with_read_factory() { + BamReader::get_factory()->register_factory(get_class_type(), make_from_bam); +} + +/** + * Writes the contents of this object to the datagram for shipping out to a + * Bam file. + */ +void DepthBiasAttrib:: +write_datagram(BamWriter *manager, Datagram &dg) { + RenderAttrib::write_datagram(manager, dg); + + dg.add_stdfloat(_slope_factor); + dg.add_stdfloat(_constant_factor); + dg.add_stdfloat(_clamp); +} + +/** + * This function is called by the BamReader's factory when a new object of + * type DepthBiasAttrib is encountered in the Bam file. It should create + * the DepthBiasAttrib and extract its information from the file. + */ +TypedWritable *DepthBiasAttrib:: +make_from_bam(const FactoryParams ¶ms) { + DepthBiasAttrib *attrib = new DepthBiasAttrib(0, 0, 0); + DatagramIterator scan; + BamReader *manager; + + parse_params(params, scan, manager); + attrib->fillin(scan, manager); + + return attrib; +} + +/** + * This internal function is called by make_from_bam to read in all of the + * relevant data from the BamFile for the new DepthBiasAttrib. + */ +void DepthBiasAttrib:: +fillin(DatagramIterator &scan, BamReader *manager) { + RenderAttrib::fillin(scan, manager); + + _slope_factor = scan.get_stdfloat(); + _constant_factor = scan.get_stdfloat(); + _clamp = scan.get_stdfloat(); +} diff --git a/panda/src/pgraph/depthBiasAttrib.h b/panda/src/pgraph/depthBiasAttrib.h new file mode 100644 index 0000000000..75fcdd3dc9 --- /dev/null +++ b/panda/src/pgraph/depthBiasAttrib.h @@ -0,0 +1,115 @@ +/** + * PANDA 3D SOFTWARE + * Copyright (c) Carnegie Mellon University. All rights reserved. + * + * All use of this software is subject to the terms of the revised BSD + * license. You should have received a copy of this license along + * with this source code in a file named "LICENSE." + * + * @file depthBiasAttrib.h + * @author rdb + * @date 2021-08-24 + */ + +#ifndef DEPTHBIASATTRIB_H +#define DEPTHBIASATTRIB_H + +#include "pandabase.h" + +#include "renderAttrib.h" +#include "luse.h" + +class FactoryParams; + +/** + * This is a special kind of attribute that instructs the graphics driver to + * apply an offset or bias to the generated depth values for rendered + * polygons, before they are written to the depth buffer. + * + * This class replaces the old DepthOffsetAttrib, which had a more limited + * parameterization. The differences are: + * - The sign of the factor parameter was inverted. + * - The slope and constant factors are specified separately. + * - The factors are specified as floating-point instead of integer. + * - There is a new clamp parameter. + * + * Nested DepthBiasAttrib values accumulate; that is, a DepthBiasAttrib + * with a value of 1 beneath another DepthBiasAttrib with a value of 2 + * presents a net offset of 3. (A DepthBiasAttrib will not, however, + * combine with any other DepthBiasAttribs with a lower override parameter.) + */ +class EXPCL_PANDA_PGRAPH DepthBiasAttrib : public RenderAttrib { +private: + INLINE DepthBiasAttrib(PN_stdfloat slope_factor, PN_stdfloat constant_factor, + PN_stdfloat clamp = 0); + +PUBLISHED: + static CPT(RenderAttrib) make(PN_stdfloat slope_factor, PN_stdfloat constant_factor, + PN_stdfloat clamp = 0); + static CPT(RenderAttrib) make_default(); + +public: + INLINE PN_stdfloat get_slope_factor() const; + INLINE PN_stdfloat get_constant_factor() const; + INLINE PN_stdfloat get_clamp() const; + +PUBLISHED: + MAKE_PROPERTY(slope_factor, get_slope_factor); + MAKE_PROPERTY(constant_factor, get_constant_factor); + MAKE_PROPERTY(clamp, get_clamp); + +public: + virtual void output(std::ostream &out) const; + +protected: + virtual int compare_to_impl(const RenderAttrib *other) const; + virtual size_t get_hash_impl() const; + virtual CPT(RenderAttrib) compose_impl(const RenderAttrib *other) const; + virtual CPT(RenderAttrib) invert_compose_impl(const RenderAttrib *other) const; + +private: + PN_stdfloat _slope_factor; + PN_stdfloat _constant_factor; + PN_stdfloat _clamp; + +PUBLISHED: + static int get_class_slot() { + return _attrib_slot; + } + virtual int get_slot() const { + return get_class_slot(); + } + MAKE_PROPERTY(class_slot, get_class_slot); + +public: + static void register_with_read_factory(); + virtual void write_datagram(BamWriter *manager, Datagram &dg); + +protected: + static TypedWritable *make_from_bam(const FactoryParams ¶ms); + void fillin(DatagramIterator &scan, BamReader *manager); + +public: + static TypeHandle get_class_type() { + return _type_handle; + } + static void init_type() { + RenderAttrib::init_type(); + register_type(_type_handle, "DepthBiasAttrib", + RenderAttrib::get_class_type()); + _attrib_slot = register_slot(_type_handle, 100, + new DepthBiasAttrib(0, 0, 0)); + } + virtual TypeHandle get_type() const { + return get_class_type(); + } + virtual TypeHandle force_init_type() {init_type(); return get_class_type();} + +private: + static TypeHandle _type_handle; + static int _attrib_slot; +}; + +#include "depthBiasAttrib.I" + +#endif diff --git a/panda/src/pgraph/depthOffsetAttrib.h b/panda/src/pgraph/depthOffsetAttrib.h index 54fef347d5..6f868cec88 100644 --- a/panda/src/pgraph/depthOffsetAttrib.h +++ b/panda/src/pgraph/depthOffsetAttrib.h @@ -46,6 +46,8 @@ class FactoryParams; * Also, and only tangentially related, the DepthOffsetAttrib can be used to * constrain the Z output value to a subset of the usual [0, 1] range (or * reversing its direction) by specifying a new min_value and max_value. + * + * @deprecated See DepthBiasAttrib and DisplayRegion::set_depth_range() instead. */ class EXPCL_PANDA_PGRAPH DepthOffsetAttrib : public RenderAttrib { private: diff --git a/panda/src/pgraph/nodePath.cxx b/panda/src/pgraph/nodePath.cxx index 5c7dbbbdaf..c6ea2bff6b 100644 --- a/panda/src/pgraph/nodePath.cxx +++ b/panda/src/pgraph/nodePath.cxx @@ -34,9 +34,10 @@ #include "renderModeAttrib.h" #include "cullFaceAttrib.h" #include "alphaTestAttrib.h" +#include "depthBiasAttrib.h" +#include "depthOffsetAttrib.h" #include "depthTestAttrib.h" #include "depthWriteAttrib.h" -#include "depthOffsetAttrib.h" #include "shaderAttrib.h" #include "billboardEffect.h" #include "compassEffect.h" @@ -4684,6 +4685,8 @@ get_depth_write() const { * bias is always an integer number, and each integer increment represents the * smallest possible increment in Z that is sufficient to completely resolve * two coplanar polygons. Positive numbers are closer towards the camera. + * + * @deprecated See set_depth_bias() instead, which provides more controls. */ void NodePath:: set_depth_offset(int bias, int priority) { @@ -4730,6 +4733,40 @@ get_depth_offset() const { return 0; } +/** + * This instructs the graphics driver to apply an offset or bias to the + * generated depth values for rendered polygons, before they are written to + * the depth buffer. This can be used to shift polygons forward slightly, to + * resolve depth conflicts, or self-shadowing artifacts on thin objects. + * Positive numbers are further away from the camera. + */ +void NodePath:: +set_depth_bias(PN_stdfloat slope_factor, PN_stdfloat constant_factor, PN_stdfloat clamp, int priority) { + nassertv_always(!is_empty()); + node()->set_attrib(DepthBiasAttrib::make(slope_factor, constant_factor, clamp), priority); +} + +/** + * Completely removes any depth-bias adjustment that may have been set on + * this node via set_depth_bias(). + */ +void NodePath:: +clear_depth_bias() { + nassertv_always(!is_empty()); + node()->clear_attrib(DepthBiasAttrib::get_class_slot()); +} + +/** + * Returns true if a depth-bias adjustment has been explicitly set on this + * particular node via set_depth_bias(). If this returns true, then + * get_depth_bias() may be called to determine which has been set. + */ +bool NodePath:: +has_depth_bias() const { + nassertr_always(!is_empty(), false); + return node()->has_attrib(DepthBiasAttrib::get_class_slot()); +} + /** * Performs a billboard-type rotate to the indicated camera node, one time * only, and leaves the object rotated. This is similar in principle to diff --git a/panda/src/pgraph/nodePath.h b/panda/src/pgraph/nodePath.h index 187129d30c..66bf5eb9ae 100644 --- a/panda/src/pgraph/nodePath.h +++ b/panda/src/pgraph/nodePath.h @@ -811,6 +811,11 @@ PUBLISHED: bool has_depth_offset() const; int get_depth_offset() const; + void set_depth_bias(PN_stdfloat slope_factor, PN_stdfloat constant_factor, + PN_stdfloat clamp = 0.0, int priority = 0); + void clear_depth_bias(); + bool has_depth_bias() const; + void do_billboard_axis(const NodePath &camera, PN_stdfloat offset); void do_billboard_point_eye(const NodePath &camera, PN_stdfloat offset); void do_billboard_point_world(const NodePath &camera, PN_stdfloat offset); diff --git a/panda/src/pgraph/p3pgraph_composite2.cxx b/panda/src/pgraph/p3pgraph_composite2.cxx index 88dc14b398..139ee34c63 100644 --- a/panda/src/pgraph/p3pgraph_composite2.cxx +++ b/panda/src/pgraph/p3pgraph_composite2.cxx @@ -9,6 +9,7 @@ #include "cullTraverserData.cxx" #include "cullableObject.cxx" #include "decalEffect.cxx" +#include "depthBiasAttrib.cxx" #include "depthOffsetAttrib.cxx" #include "depthTestAttrib.cxx" #include "depthWriteAttrib.cxx" diff --git a/tests/display/test_depth_buffer.py b/tests/display/test_depth_buffer.py index b1352fac14..947287428a 100644 --- a/tests/display/test_depth_buffer.py +++ b/tests/display/test_depth_buffer.py @@ -179,3 +179,43 @@ def test_depth_range(depth_region): assert z == pytest.approx(0.25, rel=0.01) finally: depth_region.set_depth_range(0, 1) + + +def test_depth_bias(depth_region): + # Without depth bias + z_ref = render_depth_pixel(depth_region, 5, near=1, far=10) + + # With constant positive depth bias + state = core.RenderState.make(core.DepthBiasAttrib.make(0, 1)) + z = render_depth_pixel(depth_region, 5, near=1, far=10, state=state) + assert z > z_ref + + # With constant negative depth bias + state = core.RenderState.make(core.DepthBiasAttrib.make(0, -1)) + z = render_depth_pixel(depth_region, 5, near=1, far=10, state=state) + assert z < z_ref + + # With slope-scaled depth bias (our quad has no slope) + state = core.RenderState.make(core.DepthBiasAttrib.make(10, 0)) + z = render_depth_pixel(depth_region, 5, near=1, far=10, state=state) + assert z == z_ref + + # Same, but negative + state = core.RenderState.make(core.DepthBiasAttrib.make(-10, 0)) + z = render_depth_pixel(depth_region, 5, near=1, far=10, state=state) + assert z == z_ref + + +def test_depth_offset(depth_region): + # Without depth offset + z_ref = render_depth_pixel(depth_region, 5, near=1, far=10) + + # With constant positive depth offset + state = core.RenderState.make(core.DepthOffsetAttrib.make(1)) + z = render_depth_pixel(depth_region, 5, near=1, far=10, state=state) + assert z < z_ref + + # With constant negative depth offset + state = core.RenderState.make(core.DepthOffsetAttrib.make(-1)) + z = render_depth_pixel(depth_region, 5, near=1, far=10, state=state) + assert z > z_ref