Closed Shfty closed 1 year ago
Generalizing operators over distance function I/O seems to be the most immediate solution, implementing new rust-gpu-bridge
traits as needed to cover the various shading lang functions.
Longer-term, a way to split blanket impls out from specific impls is probably wise - i.e. an extra marker type param that can be generalized over in a consuming trait.
The blanket / specific approach didn't work out, as the result would require the user to know blanket / specific impl details while specifying their SDF type in order to write the correct marker parameter.
However, this is progressing - field functions and operators are now standardized around implementing position / normal / uv, with tangent and color as wrapper-derived attributes.
In addition, support function (i.e. vector to nearest surface) has been added as a free-standing wrapper-first attribute. This fits nicely as a reference implementation for third-party attributes, since avoiding manual impl_passthrough_op!
across the entire existing set is preferable.
The next step is to try and figure out a cons-based approach to evaluating several attributes from one function call, i.e.
let (normal, tangent, uv, color) = sdf.evaluate(
(
Normal<Vec3>::default(),
Tangent<Vec3>::default(),
Uv,
Color
),
pos
);
Where the Attr
parameter is a type that implements Cons
, which produces an Attribute
type that also implements Uncons
for automatic denesting before return.
However, a prior attempt at this was unsuccesful due to blanket impl conflicts. Will need to revisit, and possibly devise a solution around re-encoding Operator
via cons cell (i.e. <(OpType, SdfType) as Operator>
).
The free-standing attribute approach may be viable for cons evaulation.
This is now functional by way of a blanket cons implementation over FieldFunction
. However, this comes at the cost of Operator
extensibility; each of its impls are now manual over a concrete attribute type, which may prevent downstream crates from doing the same for a custom attribute.
As with FieldCons
, the elegant way to solve this seems to be the introduction of extension traits; implementing FieldFunction
as before (i.e. with no cons ability) and creating an extension trait to cover the cons list impl in a separate method.
Should also be able to use an indirection trait to reflect evaluate<T>()
/ evaluate_cons<T>()
onto FieldFunction
types, allowing the attribute generic to be specified in the function position and removing the need for a concrete attribute parameter.
Done; the trait machinery has been split into single and plural variants, with an extra layer of API traits to move the Attr
generic into function position.
Normals are supported by the
SignedDistanceField
trait and have some local impls, as well as the normal approximation adapters, but these are currently inaccessible in practical terms since none of the other operators or adapters implement any attribute other than distance.Need to create passthrough impls for all related types -
Operator
, adapters, etc.Worth ruminating on how this might be extended, since it will require one explicit impl for each
SignedDistanceField
implementor for each attribute type - seems like a lot of work for users to extend.