Pass nil texture to metal fragment shader

Hello everyone, I am studying apply metal to scenekit.

I want to pass nil texture to fragment shader. But I don't know how...

This code is for pass texture named volume to fragment shader using scntechnique.

swift code

if let path = Bundle.main.path(
      forResource: "volumerendering-metal",
      ofType: "plist")
    {
      if let dico1 = NSDictionary(contentsOfFile: path) {
        let dico = dico1 as! [String: AnyObject]
        let technique = SCNTechnique(dictionary: dico)
         
        let screenSize = NSValue(
          cgSize: view.frame.size.applying(CGAffineTransform(scaleX: 2.0, y: 2.0)))
        technique?.setValue(screenSize,
                  forKeyPath: "screen_size")
         
        technique?.setValue(nil, forKey: "volume")
       // or? 
       // technique?.setObject(nil, forKeyedSubscript: "volume" as NSCopying)
         
        scnView.technique = technique
      }
    }

property list file

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
	<key>passes</key>
	<dict>
		<key>pass_backface</key>
		<dict>
			<key>metalVertexShader</key>
			<string>backface_vertex</string>
			<key>metalFragmentShader</key>
			<string>backface_fragment</string>
			<key>program</key>
			<string>doesntexist</string>
			<key>depthStates</key>
			<dict>
				<key>clear</key>
				<true/>
			</dict>
			<key>colorStates</key>
			<dict>
				<key>clear</key>
				<true/>
				<key>clearColor</key>
				<string>sceneBackground</string>
			</dict>
			<key>cullMode</key>
			<string>front</string>
			<key>includeCategoryMask</key>
			<string>2</string>
			<key>draw</key>
			<string>DRAW_NODE</string>
			<key>inputs</key>
			<dict>
				<key>aPos</key>
				<string>vertex-symbol</string>
			</dict>
			<key>outputs</key>
			<dict>
				<key>color</key>
				<string>backface</string>
			</dict>
		</dict>
		<key>pass_mip</key>
		<dict>
			<key>colorStates</key>
			<dict>
				<key>clear</key>
				<true/>
				<key>clearColor</key>
				<string>sceneBackground</string>
			</dict>
			<key>depthStates</key>
			<dict>
				<key>clear</key>
				<true/>
			</dict>
			<key>metalVertexShader</key>
			<string>mip_vertex</string>
			<key>metalFragmentShader</key>
			<string>mip_fragment</string>
			<key>program</key>
			<string>doesntexist</string>
			<key>cullMode</key>
			<string>back</string>
			<key>includeCategoryMask</key>
			<string>2</string>
			<key>draw</key>
			<string>DRAW_NODE</string>
			<key>inputs</key>
			<dict>
				<key>aPos</key>
				<string>vertex-symbol</string>
				<key>viewport</key>
				<string>screen_size</string>
				<key>backface</key>
				<string>backface</string>
				<key>volume</key>
				<string>volume</string>
			</dict>
			<key>outputs</key>
			<dict>
				<key>color</key>
				<string>COLOR</string>
				<key>depth</key>
				<string>DEPTH</string>
			</dict>
		</dict>
	</dict>
	<key>sequence</key>
	<array>
		<string>pass_backface</string>
		<string>pass_mip</string>
	</array>
	<key>targets</key>
	<dict>
		<key>backface</key>
		<dict>
			<key>type</key>
			<string>color</string>
		</dict>
	</dict>
	<key>symbols</key>
	<dict>
		<key>vertex-symbol</key>
		<dict>
			<key>semantic</key>
			<string>vertex</string>
		</dict>
		<key>screen_size</key>
		<dict>
			<key>type</key>
			<string>vec2</string>
		</dict>
		<key>volume</key>
		<dict>
			<key>type</key>
			<string>sampler3D</string>
		</dict>
	</dict>
</dict>
</plist>

shader code

fragment float4 mip_fragment
(
  VertexOutput in [[stage_in]]
  , texture2d<float, access::sample> backface [[texture(0)]]
  , texture2d<float, access::sample> volume [[texture(1)]]
)
{
  ...  
  if (is_null_texture(volume)) return float4(1, 0, 0, 0);
  else return float4(0, 1, 0, 0);
}

I want to get red object but green object.... Because I want to set 3d texture at runtime. So before set it want to be nil, because error occurred. (https://developer.apple.com/forums/thread/688841)

I’m not an expert on SceneKit, but why do you have volume as type sampler3D in your plist, and volume as a texture2D in your shader? If you want it to be a texture3D, it should probably be set to that in your shader and plist.

Yes,

this shader code is right.

fragment float4 mip_fragment
(
  VertexOutput in [[stage_in]]
  , texture2d<float, access::sample> backface [[texture(0)]]
  , texture3d<float, access::sample> volume [[texture(1)]]
)
{
  ...  
  if (is_null_texture(volume)) return float4(1, 0, 0, 0);
  else return float4(0, 1, 0, 0);
}

And I check now, is_null_texture makes same error like volume.sample function.

https://bitbucket.org/skia_wonki/metal-volume-rendering/src/master/

This is full source of question.

Pass nil texture to metal fragment shader
 
 
Q