Search code examples
scenekitmetalmetalkit

Metal / Scenekit - Repeating texture on sampler


not sure why but I am not able to repeat the texture when using customer fragment shader

Here is my fragment

fragment float4 bFragment( VertexOut vertexOut [[stage_in]],
                           texture2d<float, access::sample> textureInput [[texture(0)]],)
    {
constexpr sampler sampler2d(coord::normalized, address::repeat, filter::linear, address::repeat);

float4 outputColor;
outputColor = textureInput.sample(sampler2d, vertexOut.texCoord);

return float4(outputColor.x , outputColor.y , outputColor.z , 1.0);

}

Here is how I pass the texture:

let imageProperty = SCNMaterialProperty(contents: texture)
imageProperty.wrapS  = .repeat
imageProperty.wrapT  = .repeat
imageProperty.contentsTransform = SCNMatrix4MakeScale(screenRatio * numberOfRepetitionsOnX, numberOfRepetitionsOnX , 1)
node.geometry!.firstMaterial!.setValue(imageProperty, forKey: "textureInput")

Image is NOT repeated, just clamped to the object, no matter the size of the texture.

If I use the same settings with NO customer shader:

let myMaterial = SCNMaterial()
myMaterial.lightingModel = .constant
myMaterial.diffuse.contents = texture 
myMaterial.diffuse.wrapS = .repeat
myMaterial.diffuse.wrapT = .repeat
myMaterial.diffuse.contentsTransform = SCNMatrix4MakeScale(screenRatio * numberOfRepetitionsOnX, numberOfRepetitionsOnX , 1)
node.geometry!.firstMaterial! = myMaterial

Texture correctly repeated

Questions:

  • What I have to change in order to be effective contentsTransform value also when using the sampler in custom fragment shader?
  • If that is not possible, what is the easiest way to achieve that? (Scaling, repeating.redrawing the texture is not an option)

Thanks.


Solution

  • When using SCNProgram the contentsTransform property of SCNMaterialProperty has no effect (because support is implemented in SceneKit's built-in vertex and fragment shaders).

    You will need to pass the 2D matrix to the custom SCNProgram shaders and manually transform the texture coordinates there.