Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Passing values between SCNShadable entry points

In an OpenGL program you typical declare something like this in a vertex shader

varying bool aBooleanVariable;

and then read the value in the fragment shader. How do you do this within the framework of an SCNShadable entry point? For example from SCNShaderModifierEntryPointGeometry to SCNShaderModifierEntryPointFragment.

Receiving the argument seems to be defined by using the pragma arguments, I provide my test SCNShaderModifierEntryPointFragment to illustrate.

#pragma arguments
bool clipFragment

#pragma body

if (clipFragment) {
    discard_fragment();
}

However, the arguments pragma doesn't work for outputting the value in the SCNShaderModifierEntryPointGeometry entry point.

I found an article that suggests that it can be done with GLSL syntax, but I was trying to find the Metal way and I wasn't even able to reproduce the result.

like image 975
Cameron Lowell Palmer Avatar asked May 31 '16 12:05

Cameron Lowell Palmer


Video Answer


1 Answers

I had a similar problem and managed to figure out the solution. I'm not sure how far back this works, but it works on XCode 9 with iOS 11. Here's an example of looking up a custom cubemap texture using a varying float3 for the coordinate.

The geometry modifier:

#include <metal_stdlib>

#pragma varyings
float3 cubemapCoord;

#pragma body
out.cubemapCoord = _geometry.normal;

The surface modifier:

#include <metal_stdlib>

#pragma arguments
texturecube<float> texture;

#pragma body
constexpr sampler s(filter::linear, mip_filter::linear);
_surface.diffuse = texture.sample(s, in.cubemapCoord);

And the Swift code for assigning the material:

do {
    let loader = MTKTextureLoader.init(device: MTLCreateSystemDefaultDevice()!)
    let url = Bundle.main.url(forResource: "cubemap", withExtension: "pvr", subdirectory: "art.scnassets")!
    let texture = try loader.newTexture(URL: url, options: nil)
    let materialProperty = SCNMaterialProperty.init(contents: texture)
    geometry.setValue(materialProperty, forKey: "texture")
} catch {
    print(error.localizedDescription)
}
like image 74
John Stephen Avatar answered Sep 20 '22 01:09

John Stephen