如何将SCNTechnique首遍渲染的颜色、深度缓冲区传入SCNProgram?
实现方案
你可以通过以下步骤完成需求,不需要在SCNTechnique中硬编码着色器,直接复用节点绑定的SCNProgram即可:
1. 调整SCNTechnique配置
首先删除pass_object下的metalVertexShader和metalFragmentShader配置项,保留inputs、outputs、includeCategoryMask等配置,同时在Technique根层级补充缓冲区目标定义:
... <key>targets</key> <dict> <key>COLOR</key> <dict> <key>type</key> <string>color</string> <key>format</key> <string>rgba16float</string> <key>size</key> <string>viewport</string> </dict> <key>DEPTH</key> <dict> <key>type</key> <string>depth</string> <key>format</key> <string>depth32float</string> <key>size</key> <string>viewport</string> </dict> </dict> <key>passes</key> <dict> <key>pass_scene</key> <dict> <key>draw</key> <string>DRAW_SCENE</string> <key>excludeCategoryMask</key> <string>自定义节点的分类掩码位</string> <key>outputs</key> <dict> <key>color</key> <string>COLOR</string> <key>depth</key> <string>DEPTH</string> </dict> </dict> <key>pass_object</key> <dict> <key>draw</key> <string>DRAW_SCENE</string> <key>includeCategoryMask</key> <string>自定义节点的分类掩码位</string> <key>inputs</key> <dict> <key>colorBuffer</key> <string>COLOR</string> <key>depthBuffer</key> <string>DEPTH</string> </dict> <key>outputs</key> <dict> <key>color</key> <string>COLOR</string> </dict> <!-- 移除此处的metal着色器声明 --> </dict> </dict> <key>sequence</key> <array> <string>pass_scene</string> <string>pass_object</string> </array> ...
2. 匹配SCNProgram着色器参数
SceneKit执行pass_object时,会自动将当前pass定义的inputs参数绑定到当前渲染节点所用SCNProgram的着色器中,你只需要保证着色器内的参数名和inputs的key完全一致即可。
以Metal着色器为例,片段着色器可以直接声明对应纹理参数:
#include <SceneKit/SceneKit.h> using namespace metal; struct VertexOutput { float4 position [[position]]; // 其他自定义顶点输出参数 }; fragment float4 customFragmentShader( VertexOutput in [[stage_in]], texture2d<float, access::sample> colorBuffer [[texture(0)]], texture2d<float, access::sample> depthBuffer [[texture(1)]], constant SCNSceneBuffer& scn_frame [[buffer(0)]] ) { // 用屏幕坐标转换UV采样第一遍渲染结果 constexpr sampler s(coord::normalized, filter::linear); float2 uv = float2( in.position.x / scn_frame.viewport.z, 1.0 - in.position.y / scn_frame.viewport.w ); float4 sceneColor = colorBuffer.sample(s, uv); float sceneDepth = depthBuffer.sample(s, uv).r; // 此处添加你的自定义渲染逻辑 return sceneColor; }
3. 绑定SCNProgram到目标节点
正常创建SCNProgram实例,关联你自定义的顶点、片段着色器函数,然后赋值给目标节点几何材质的program属性即可。
注意事项
- 确保自定义节点的
categoryBitMask和两个pass的掩码配置匹配,第一遍排除、第二遍仅包含该节点,避免重复渲染 - 缓冲区格式可根据你的需求调整,如不需要浮点精度可替换为
rgba8Unorm等格式
内容的提问来源于stack exchange,提问作者Nick
相关产品推荐
相关产品推荐

