Pārlūkot izejas kodu

doc: Update p3cull's README

Sam Edwards 7 gadi atpakaļ
vecāks
revīzija
a00715c363
1 mainītis faili ar 170 papildinājumiem un 3 dzēšanām
  1. 170 3
      panda/src/cull/README.md

+ 170 - 3
panda/src/cull/README.md

@@ -1,3 +1,170 @@
-This package contains the Cull Traverser.  The cull traversal collects
-all state changes specified, and removes unnecessary state change
-requests.  Also does all the depth sorting for proper alphaing.
+p3cull: Panda3D's cull traverser
+================================
+
+Overview
+--------
+
+### What is "culling"?
+
+In the 3D graphics world, "culling" refers to the process of determining
+objects that are hidden from view or are otherwise guaranteed not to contribute
+meaningfully to the scene. These objects are then skipped in the rendering step
+to save on valuable rendering time.
+
+Panda3D uses the term "cull" in a slightly different sense. In particular, it
+refers to the whole process of preparing a complex, non-linear and arbitrarily
+deep scenegraph for rendering by the graphics backend, which needs a list of
+objects to render one at a time. This involves, roughly:
+
+1. Determining all *visible* objects, given a viewpoint, a scenegraph, and a
+   bitmask indicating which objects should be shown.
+2. *Composing* (combining) the state of each object, as inherited from its
+   ancestors in the scenegraph.
+3. Deciding the order in which the objects are to be sent for rendering.
+
+Note that this processs should not be confused with "back-face culling," which
+is where triangles that face away from the screen are assumed to be on the
+opposite side of of an object and therefore not visible. Back-face culling is
+performed at render-time and therefore does not reduce the total number of
+objects being sent to the backend.
+
+### Determining visible objects
+
+Panda3D's primary culling mode is called "viewing frustum culling," where a
+given viewpoint (Camera and Lens, in Panda3D terms) is represented as a
+bounding volume, typically a frustum - a chopped-off pyramid. As the theory
+goes, whenever a volume represents completely and precisely the visible portion
+of a space, any object that does not intersect with the volume must not be
+visible and can therefore be ignored during that frame.
+
+Every object also has a bounding volume, which is a geometric approximation of
+its actual shape. This approximation is computed to be as small as possible,
+while staying computationally simple and guaranteeing that the volume
+encompasses the entire object and its children. In other words, it's better to
+err on the side of being too large.
+
+When Panda3D performs cull traversals, it walks the scenegraph in a depth-first
+search order, visiting each node, and testing for intersections between the
+view volume and the node's bounding volume. These intersections usually fall
+into one of three categories:
+1. No intersection: The node is culled, and none of its children are
+   considered.
+2. Some: A partial intersection means the node is considered visible, but
+   further tests against children are necessary. (This can be overridden by the
+   `set_final` flag; see PandaNode.)
+3. All: If the node's bounding volume is completely enclosed within the viewing
+   volume, then no part of it is *not* visible. All children are assumed to
+   pass the intersection test as well.
+
+Panda3D supports the "portal culling" and "occlusion culling" paradigms as well.
+In portal culling, visual chokepoints in the scene (e.g. narrow doorways) are
+represented by a rectangular "portal" into a different area of the scene. If
+the portal is culled, every object on the opposite side of the portal is also
+culled. If the portal is not culled, the portal clips the frustum and culling
+continues across the portal. In occlusion culling, rectangular "occluders"
+(sometimes called "antiportals") are placed in the scene; however, objects
+using the occluder are _only_ culled if they are completely enclosed within the
+occluder's clipped view frustrum (since the view frustrum, as clipped by the
+occluder, represents the region blocked by the occluder -
+that is, the "shadow" of the camera - which cannot be seen)
+
+Normally, this would be enough, but Panda3D also offers the option of hiding
+nodes, either from every camera or selectively on a camera-by-camera basis
+(this is useful in implementing certain graphical effects such as shadows). To
+do this, Panda3D gives every node and camera a special bitmask called a
+DrawMask, with the rule being that an object can only be seen by a camera if
+they share bits in common. If not, the node simply fails the cull test and
+isn't sent for rendering.
+
+### Composing state
+
+Each node can have state - either in the form of a transform, and/or rendering
+effects/attributes - applied to it. These attributes apply both to the node
+and to all children of that node. (See the [pgraph](../pgraph) component for
+more details.)
+
+For every object that passes the visibility test, its render state is fully
+composed, starting with the initial state set on the camera (see
+`Camera::set_initial_state`), then the root of the scenegraph, and then every
+ancestor of the object in top-down order, with lower nodes taking precedence
+over higher nodes.
+
+The transform state is composed similarly, but it begins with the *inverse* of
+the camera's transform.
+
+The result is a series of CullableObjects, which typically represent a Geom
+(see [gobj](../gobj)) each. These are the atomic unit of rendering during
+Panda3D's render pass, and as such are independent of one another.
+
+These CullableObjects are sent to a CullHandler, which is responsible for
+collecting CullableObjects for rendering.
+
+### Deciding rendering order
+
+Before each CullableObject can be submitted for rendering on the graphics
+backend, Panda3D needs to determine the best order in which to draw them.
+Panda3D typically takes into account:
+
+1. Specific requests from the user. Some graphical effects, for example, may
+   require that objects are rendered in a particular order.
+2. Specific orderings based on the kind of the object. Transparent objects must
+   be rendered in back-to-front order after the rest of the scene for alpha
+   blending to work properly, for instance.
+3. Grouping objects by similarity of render state to minimize the number of
+   times the graphics hardware must change state. Each change of state involves
+   some performance cost, sometimes even a full stall of the graphics pipeline,
+   and so grouping similar objects together helps keep framerates high.
+
+To do this, Panda3D's BinCullHandler groups all CullableObjects into CullBins,
+which are responsible for determining the coarse and fine rendering order of
+objects. For more on how CullBins work, see the Panda3D manual page
+[How to Control Render Order](https://www.panda3d.org/manual/index.php/How_to_Control_Render_Order).
+
+The BinCullHandler produces a CullResult, which is a series of CullableObjects
+(again, typically Geoms) ready to be submitted to the GraphicsStateGuardian for
+rendering.
+
+Classes
+-------
+
+* **SceneSetup** describes one rendering pass, including the camera, scene,
+  lens, DisplayRegion, and GraphicsStateGuardian involved.
+* **CullTraverser** takes the parameters from SceneSetup and traverses the
+  scene in a depth-first order, searching for visible geometry, which is passed
+  to a CullHandler object.
+* **CullableObject** is a container for any visible geometry that has passed
+  the cull test and its associated (composed) state. Typically, this is a Geom,
+  a RenderState, and a TransformState.
+* **CullHandler** is an abstract interface for accepting CullableObjects which
+  have passed the cull test.
+* **DrawCullHandler** is a kind of CullHandler that immediately passes the
+  objects on to the GraphicsStateGuardian. See also
+  `GraphicsThreadingModel::set_cull_sorting`
+* **BinCullHandler** is a kind of CullHandler that "bins" the
+  CullableObjects - sorting them into an optimal rendering order.
+* **CullBin** is a base class for any class that sorts CullableObjects in some
+  order.
+* **CullBinStateSorted** is a CullBin that sorts the CullableObjects in such a
+  way as to minimize state transitions, which are expensive on pipelined
+  graphics hardware.
+* **CullBinFixed** is a CullBin that sorts the CullableObjects in an
+  application-specified order, specified in the CullBinAttrib.
+* **CullBinBackToFront** is a CullBin that sorts the CullableObjects in
+  back-to-front order, which is useful for transparent operation.
+* **CullBinFrontToBack** is a CullBin that sorts front-to-back.
+* **CullBinUnsorted** is a CullBin that doesn't try to sort geometry in any
+  meaningful way.
+* **CullBinManager** is a global object that maintains a list of the named
+  CullBins in the application, and keeps track of their global ordering.
+* **CullBinAttrib** is a RenderAttrib that allows the application to specify a
+  CullBin for its geometry to be categorized into.
+
+Configuration
+-------------
+
+* `cull-bin bin_name sort type` defines a new CullBin by name.
+
+Build-time flags
+----------------
+
+None affect this component.