SCNTechnique: Accessing A Node's Textures in DRAW_SCENE Pass

Is there any way to access the Textures of a material for a Node in a SCNTechnique DRAW_SCENE pass?

I am implementing a custom SCNTechnique. This is primarily for practice with different rendering techniques, so performance is not my goal.

Ideally, if I had full control of the pipeline I (think I) could attach multiple targets and get the albedo, normal, depth in a single pass.

Right now, I am attempting to implement SSAO and (eventually) Deferred Lighting with SCNTechniques.

My SSAO passes will eventually look like the following:

  1. Render Albedo to Texture, Depth to Texture
  2. Render Normal to Texture
  3. Compute Occlusion, combine with Albedo

Right now I am attempting to debug, and am doing the following:

  1. (attempting to) Render Albedo to Texture
  2. Render Normal to Texture
  3. Combining the two for visual confirmation

My Technique has the following definition:

"passes": [

			"albedoPass": [

				"draw": "DRAW_SCENE",

				"metalVertexShader": "albedoVertex",

				"metalFragmentShader": "albedoFragment",

				"outputs": [

					"color": "AlbedoMap",

				],

				"colorStates": [

					"clear": "1",

				],

				"depthStates": [

					"clear": "1",

				],

			],

			"normalPass": [

				"draw": "DRAW_SCENE",

				"metalVertexShader": "normalsVertex",

				"metalFragmentShader": "normalsFragment",

				"inputs": [

				],

				"outputs": [

					"color": "ViewSpaceNormalMap",

				],

				"colorStates": [

					"clear": "1",

				],

				"depthStates": [

					"clear": "1",

				],

			],

			"showNormal": [

				"draw": "DRAW_QUAD",

				"metalVertexShader": "normalsResultVertex",

				"metalFragmentShader": "normalsResultFragment",

				"inputs": [

					"quadOverlayPosition": "quadOverlayPosition-Symbol",

					"viewSpaceNormalMapTexture": "ViewSpaceNormalMap",

					"albedoMapTexture": "AlbedoMap",

				],

				"outputs": [

					"color": "COLOR",

				],

				"colorStates": [

					"clear": "1",

				],

			]

		],

		"sequence": [

			"albedoPass",

			"normalPass",

			"showNormalPass",

		],

		"targets": [

			"AlbedoMap": [

				"type": "color",

			],

			"ViewSpaceNormalMap": [

				"type": "color",

			],

		],

		"symbols": [

			"quadOverlayPosition-Symbol": [

				"semantic": "vertex",

			],

		],

	]

For the albedo pass, would it be possible to acquire the diffuse material in the fragment/vertex shader given to the pass? Like so:

#include <metal_stdlib>

using namespace metal;

#include <SceneKit/scn_metal>



struct VertexIn {

	float3 position  [[attribute(SCNVertexSemanticPosition)]];

	float2 uv [[attribute(SCNVertexSemanticTexcoord0)]];

};



struct VertexOut {

	float4 position [[position]];

	float2 uv;

};

struct NodeBuffer {

	float4x4 modelTransform;

	float4x4 inverseModelTransform;

	float4x4 modelViewTransform;

	float4x4 inverseModelViewTransform;

	float4x4 normalTransform; // Inverse transpose of modelViewTransform

	float4x4 modelViewProjectionTransform;

	float4x4 inverseModelViewProjectionTransform;

	float2x3 boundingBox;

	float2x3 worldBoundingBox;

};



vertex VertexOut albedoVertex(VertexIn in [[ stage_in ]], constant SCNSceneBuffer& scn_frame [[buffer(0)]], constant NodeBuffer& scn_node [[buffer(1)]]) {

	VertexOut out;

	out.position = scn_node.modelViewProjectionTransform * float4(in.position, 1.0);

	out.uv = in.uv;

	return out;

}



fragment float4 albedoFragment(VertexOut out [[ stage_in ]], texture2d<float, access::sample> diffuse [[texture(0)]]) {

	constexpr sampler textureSampler(coord::normalized, filter::linear, address::repeat);

	float4 color = diffuse.sample(textureSampler, out.uv);

	return color;
}

Any help would be appreciated, thanks!

Answered by Apple Designer in 680461022

Hi, No I don't think there's any way from a custom program to retrieve the original material parameters as it completely replaces the material. So I don't think it's possible to turn SceneKit into a deferred renderer using SCNTechnique.

Did you end up finding a way to do this @pprovins? I’m also trying to access per-node uniforms in a DRAW_SCENE pass with custom shaders.

it’s simple enough to bind a global uniform with symbols, but I can’t find any details on how to do it per node.

Accepted Answer

Hi, No I don't think there's any way from a custom program to retrieve the original material parameters as it completely replaces the material. So I don't think it's possible to turn SceneKit into a deferred renderer using SCNTechnique.

@nickfromnelson unfortunately I did not find a way to include textures while using DRAW_SCENE. The closest I can get is to move all lighting to a separate tree and give the scene an ambient light with white color for "albedo pass", then bring the other lighting information back in another pass by setting custom buffers and symbols. Unfortunately, all information apart from the diffuse texture color is lost.

SCNTechnique: Accessing A Node's Textures in DRAW_SCENE Pass
 
 
Q