Difference between revisions of "Decalery manual"
Line 36: | Line 36: | ||
<hr> | <hr> | ||
+ | === DecalManager === | ||
+ | DecalManager manages the creation and reuse of [[Decalery_manual#DecalSpawner|DecalSpawners]]. | ||
− | + | <hr> | |
+ | === DecalSpawner === | ||
+ | DecalSpawner class is the main building block that manages pools of decals using identical settings and materials. For example, in a shooter, a single DecalSpawner for bullet holes can be used by all guns of all characters. | ||
+ | Internally DecalSpawner will create lower-level ''DecalUtils.Group'' objects for every combination of shader variant / lightmap index / parent transform. | ||
Properties: | Properties: | ||
Line 52: | Line 57: | ||
*** '''{{code|<nowiki>Shader src</nowiki>}} | *** '''{{code|<nowiki>Shader src</nowiki>}} | ||
*** '''{{code|<nowiki>Shader dest</nowiki>}}'''If receiver has shader ''src'', decal will use shader ''dest''.<br><br> | *** '''{{code|<nowiki>Shader dest</nowiki>}}'''If receiver has shader ''src'', decal will use shader ''dest''.<br><br> | ||
− | |||
− | |||
− | |||
− | |||
− | + | Methods: | |
− | + | <br> | |
− | '''{{code|<nowiki>Init(int maxTrisTotal, int maxTrisInDecal, DecalUtils.Mode preferredMode, bool preferDrawIndirect, int preferredShaderPass)</nowiki>}}''' | + | *'''{{code|<nowiki>Init(int maxTrisTotal, int maxTrisInDecal, DecalUtils.Mode preferredMode, bool preferDrawIndirect, int preferredShaderPass)</nowiki>}}'''Initializes the spawner using its properties. Must be called only once.<br> |
− | Initializes | + | ** '''{{code|<nowiki>int maxTrisTotal</nowiki>}}'''Maximum amount of triangles used in a single ''DecalUtils.Group'' spawned. Decal triangle count depends on receiver geometry detail and decal size. Older decals will disappear when new decals are added above the limit.<br> |
− | + | ** '''{{code|<nowiki>int maxTrisInDecal</nowiki>}}'''Maximum allowed triangle count for one decal. Similarly, it depends on receiver geometry detail and decal size. While this number can be set to ''maxTrisTotal'' for safety, using a lower realistic value will reduce processing time.<br> | |
− | + | ** '''{{code|<nowiki>DecalUtils.Mode preferredMode</nowiki>}}'''Preferred decal generation mode. Possible values are:<br> | |
− | + | *** '''{{code|<nowiki>DecalUtils.Mode.CPU</nowiki>}}'''Generation is done on the CPU, similar to how the DecalGroup component works. This is the slowest, but also the most platform-compatible option. Requires receiver meshes to have [https://docs.unity3d.com/Manual/FBXImporter-Model.html Read/Write Enabled].<br> | |
− | ''' | + | *** '''{{code|<nowiki>DecalUtils.Mode.GPU</nowiki>}}'''Generation is done on the GPU. This option requires hardware support for Unordered Access Views and Geometry Shaders (i.e. sm5_0). Receivers do '''not''' need to have ''Read/Write Enabled''. |
+ | ** '''{{code|<nowiki>bool preferDrawIndirect</nowiki>}}'''Are these decals supposed to be rendered with [https://docs.unity3d.com/ScriptReference/Rendering.CommandBuffer.DrawProceduralIndirect.html DrawProceduralIndirect]? Such decals do not require costly VRAM->RAM->VRAM memory transfers, as the generated buffer is used directly by the drawing shader. Shader must be aware of this method.<br> | ||
+ | ** '''{{code|<nowiki>int preferredShaderPass</nowiki>}}'''Shader pass used by indirect-drawing shaders. If the pass is not present in the shader, it will be clamped to the highest available value.<br> | ||
+ | {{note|Currently, skinned meshes only support CPU generation mode. DecalSpawner will automatically fallback to CPU when used on skinned meshes.}}<br> |
Revision as of 18:58, 27 November 2023
(Draft)
Components
Decal Group
Represents a decal projector, defined by the MeshFilter/MeshRenderer on the same object. Decal shape can be anything from a simple quad, to a complex shape, such as e.g. a corner, a ring around another object, etc. MeshRenderer should be normally disabled after the decal is projected.
Settings:
- Receiver selection mode: defines how the decal-receiving objects are selected. Possible options:
- Manual: receivers are selected by hand. This is the most precise and predictable method. Objects can be chosen via both the standard Unity selector or by pressing the "Pick in Scene" button and directly clicking receivers in the scene. To the side of every added object there are X and M buttons:
- Pressing X will remove the receiver from the list.
- Pressing M will show a material field which will be used instead of the decal's own material only for the selected receiver. This is useful when, for example, the same decal is applied to a dry and a wet surface, where different shaders might be desirable.
- Box Intersection: receivers are chosen by overlapping a box with nearby colliders.
- Box scale: scales the selection box. Final box size is affected both by decal mesh bounds, Forward/Backward distance and Box scale.
- Raycast from vertices: receivers are chosen by performing a physics raycast from every vertex of the decal's mesh, in the inverse normal direction. As with the previous option, it only picks up objects having colliders.
- Manual: receivers are selected by hand. This is the most precise and predictable method. Objects can be chosen via both the standard Unity selector or by pressing the "Pick in Scene" button and directly clicking receivers in the scene. To the side of every added object there are X and M buttons:
- Forward distance: decal projection distance (inside).
- Backward distance: decal projection distance (outside).
- Angle clip: maximum allowed angle between each decal triangle and projector triangle. The value is from -1 (-180) to 1 (180). This is to prevent texture stretching on surfaces parallel to the projection.
- Angle fade: fades vertex color/alpha to 0 as the projection approaches Angle clip value.
- Layer mask: a simple layer mask to filter out receiving objects.
- Generate tangents: does decal geometry need per-vertex tangents generated? Tangents are required for normal-mapping, parallax and other effects.
- Link to parent: if enabled, decal meshes will be parented to their receivers.
- Optimize: performs vertex welding and vertex order optimization.
Buttons:
- Live Preview: when enabled, decal will be rebuilt interactively, as it is transformed, or its settings are tweaked.
- Update: (re)builds the decal geometry once.
- Remove: removes previously generated decal geometry.
Runtime API
Decals can be created at runtime. While it is possible to directly use the DecalGroup component, it is not recommended for performance reasons. Decalery has a special fast mode of generating and rendering simple quad-like and trail-like decals at runtime. The architecture is as follows:
DecalManager
DecalManager manages the creation and reuse of DecalSpawners.
DecalSpawner
DecalSpawner class is the main building block that manages pools of decals using identical settings and materials. For example, in a shooter, a single DecalSpawner for bullet holes can be used by all guns of all characters. Internally DecalSpawner will create lower-level DecalUtils.Group objects for every combination of shader variant / lightmap index / parent transform.
Properties:
- InitData initDataMain spawner settings. InitData class contains following members:
- Material materialBase material used by all spawned decals. Use shaders made specifically for decals (offsetting position to camera to prevent Z-fighting).
- bool isTrailIs this decal a trail (e.g. a tire track)? Trails connect edge-to-edge instead of being separated quads. Trails also have a unique continuous UV generation style.
- float trailIntervalIf isTrail is enabled, controls interval between trail edges (smaller interval = rounder trails).
- float trailVScaleIf isTrail is enabled, controls vertical texture coordinate tiling.
- bool tangentsShould decals have tangents (do they need normal mapping)?
- bool inheritMaterialPropertyBlocksShould these decals inherit MaterialPropertyBlocks from receivers?
- bool useShaderReplacementUse shader replacement feature? (see next)
- ShaderReplacement[] shaderReplacementAllows optionally overriding decal shader based on the receiver's shader. Can be used when applying decals to e.g. special surfaces with vertex deformation. ShaderReplacement structure contains following members
- Shader src
- Shader destIf receiver has shader src, decal will use shader dest.
Methods:
- Init(int maxTrisTotal, int maxTrisInDecal, DecalUtils.Mode preferredMode, bool preferDrawIndirect, int preferredShaderPass)Initializes the spawner using its properties. Must be called only once.
- int maxTrisTotalMaximum amount of triangles used in a single DecalUtils.Group spawned. Decal triangle count depends on receiver geometry detail and decal size. Older decals will disappear when new decals are added above the limit.
- int maxTrisInDecalMaximum allowed triangle count for one decal. Similarly, it depends on receiver geometry detail and decal size. While this number can be set to maxTrisTotal for safety, using a lower realistic value will reduce processing time.
- DecalUtils.Mode preferredModePreferred decal generation mode. Possible values are:
- DecalUtils.Mode.CPUGeneration is done on the CPU, similar to how the DecalGroup component works. This is the slowest, but also the most platform-compatible option. Requires receiver meshes to have Read/Write Enabled.
- DecalUtils.Mode.GPUGeneration is done on the GPU. This option requires hardware support for Unordered Access Views and Geometry Shaders (i.e. sm5_0). Receivers do not need to have Read/Write Enabled.
- bool preferDrawIndirectAre these decals supposed to be rendered with DrawProceduralIndirect? Such decals do not require costly VRAM->RAM->VRAM memory transfers, as the generated buffer is used directly by the drawing shader. Shader must be aware of this method.
- int preferredShaderPassShader pass used by indirect-drawing shaders. If the pass is not present in the shader, it will be clamped to the highest available value.