A. Claesson
A. Claesson

Reputation: 559

SCNShadable in SceneKit pass float array to shader modifier

I am using SCNShadable's shader modifiers in SceneKit. I want to pass an array of float vectors (float3's).

In the SCNShadable docs, under the section "Providing Custom Inputs to a Shader Modifier", the following table is presented with data type conversions:

To pass a value to the shader, one must wrap the value in one of the specified types. It does not seem as array types are supported, but only NSValue,NSNumber or SCMaterialProperty types.

In the shader, you also need to define the type which you pass. As an example, I might wish to define something like:

uniform vec3 points[100];

Is it really not possible to pass a float array to initialize this uniform?

Otherwise, I thought that maybe it would be possible to store a float3 array as a texture in the SCNMaterialProperty type and pass this. However, I am unsure about how I might access the individual float3 values in the shader then.

Here are other similar questions I saw that might be relevant:

SceneKit shader modifiers with GLSL arrays

Is it possible to pass a float array to an iOS SceneKit vertex shader modifier?

Upvotes: 2

Views: 489

Answers (2)

Matt Bierner
Matt Bierner

Reputation: 65223

This is currently poorly documented but here's what worked for me.

You can pass the values over using a MTLBuffer. To do this, first in your shader modifier, defined your buffer argument. This should be a pointer to the buffer type (in this case I have a buffer of float values):

geometry.firstMaterial?.shaderModifiers = [
    .geometry:
        """
        #pragma arguments
        float* buffer;

        #pragma body
        // Shader body
        """
]

SCNShadable.h suggests that device const float* should work but I found that adding the device qualifier causes a shader compile error.

Then set the buffer on your material:

geometry.firstMaterial?.setValue(myBuffer, forKey: "buffer")

Using this approach, I am able to pass an MTLBuffer of any type of data to the shaderModifiers

Upvotes: 1

mnuages
mnuages

Reputation: 13462

the online documentation is not up to date. The SCNShadable.h header also mentions NSData and id <MTLBuffer> that can both be used for arrays.

GLSL        | Metal Shading Language | Objective-C                           |
------------┼------------------------┼---------------------------------------┤
-           | device const T*        | MTLBuffer                             | Feature introduced in macOS 10.13, iOS 11.0 and tvOS 11.0
-           | struct {...}           | NSData                                | The entire struct can be set using NSData but it is also possible to set individual members using the member's name as a key and a value compatible with the member's type

Upvotes: 4

Related Questions