问题
I'm using SceneKit to generate some custom geometry. This is working fine, but I'm struggling to find a way to include custom vertex attributes. Specifically, I'm looking to include an additional SCNVector3 per vertex.
I've found plenty of examples which make use of shaderModifiers to include GLSL/Metal code that relies upon custom uniform values, but haven't come across a way of including vertex attributes. Is this possible with SceneKit, or is my thinking backwards?
回答1:
there doesn't seem to be a way to access custom geometry sources in shader modifiers. That said, if your data fits into a float4
you can pass that data through SCNGeometrySourceSemanticColor
.
The Fox sample code uses the same technique to animate blades of grass. The displacement amount is baked into grayscale vertex colors as shown in the picture below.
Finally the following shader modifier reads the value of _geometry.color
and makes sure to reset it to pure white so that the stored data doesn't affect the final color of the object.
float offset = _geometry.color.x * (sin(1.2 * u_time + (_geometry.position.x+ _geometry.position.z)*4.0) + 0.5) * 0.02;
_geometry.position.x += offset;
_geometry.color.xyz = vec3(1.0);
回答2:
To make custom geometry, you use SCNGeometrySource objects to provide the vertex position, normal, and texture coordinate attributes using a buffer or Data
object full of values, then pass your geometry sources to the SCNGeometry
init(sources:elements:) initializer.
When you create an SCNGeometrySource
, you associate it with a "semantic" which is analogous to the GL/Metal vertex attribute. To create a custom vertex attribute, just give it a custom semantic. (In ObjC, SCNGeometrySourceSemantic
is just a typedef for NSString
, so you can provide your own string name. In Swift, SCNGeometrySource.Semantic
is an enum-like struct that you can extend create new members with String
raw values.)
To use your custom vertex attribute in a custom shader program, use setSemantic(_:forSymbol:options:) for GL shaders and (I think) handleBinding(ofBufferNamed:frequency:handler:) for Metal shaders.
来源:https://stackoverflow.com/questions/39669053/custom-vertex-attributes-in-scenekit