我目前正在学习如何使用scenekit,并且遇到透明对象的问题。我写了一个着色器,以便在看到面部时增加透明度,当我选择白色背景时,一切都按预期工作...... transparency with white background
但是当我选择黑色背景时,对象的行为就好像它完全不透明transparency with black background
这是我的视图控制器代码
import Cocoa
import SceneKit
import SceneKit.ModelIO
struct shaderSettings {
var Color: vector_float4
var minTransparency: Float
}
class ViewController: NSViewController {
var scnView: SCNView!
var scnScene: SCNScene!
override func viewDidLoad() {
super.viewDidLoad()
scnView = self.view as! SCNView
scnScene = SCNScene()
scnView.scene = scnScene
scnView.allowsCameraControl = true
scnView.backgroundColor = NSColor.black
//load mesh
let url = URL(fileURLWithPath: "monkey.obj")
let monkey = MDLAsset(url: url).object(at: 0)
let node = SCNNode(mdlObject: monkey)
node.name = "monkey"
//use metal shader
let program = SCNProgram();
program.vertexFunctionName = "vert";
program.fragmentFunctionName = "frag";
program.isOpaque = false
//setup material
var s = shaderSettings(Color: vector_float4(1, 0, 0, 1) ,minTransparency: 0.3)
let mat = SCNMaterial();
mat.program = program;
mat.setValue(NSData(bytes: &s, length: MemoryLayout<shaderSettings>.stride), forKey: "s")
mat.blendMode = SCNBlendMode.alpha
mat.writesToDepthBuffer = false
mat.readsFromDepthBuffer = false
mat.cullMode = SCNCullMode.back
//create node
node.geometry!.firstMaterial = mat
scnScene.rootNode.addChildNode(node)
}
override func viewDidDisappear() {
//quit when window closes
exit(0)
}
}
而且,虽然我不认为这里有问题,但这是我的着色器程序
#include <metal_stdlib>
using namespace metal;
#include <metal_geometric>
#include <metal_common>
#include <SceneKit/scn_metal>
struct settings {
float4 Color;
float minTransparency;
};
typedef struct {
float4 pos [[ attribute(SCNVertexSemanticPosition) ]];
float4 norm [[ attribute(SCNVertexSemanticNormal) ]];
} Input;
typedef struct {
float4 pos [[position]];
float3 camDir;
float3 norm;
} v2f;
struct nodeBuffer {
float4x4 modelViewProjectionTransform;
float4x4 modelViewTransform;
float4x4 normalTransform;
};
vertex v2f vert(Input in [[ stage_in ]],
constant SCNSceneBuffer& scn_frame [[buffer(0)]],
constant nodeBuffer& scn_node [[buffer(1)]]) {
v2f o;
o.pos = scn_node.modelViewProjectionTransform * in.pos;
o.norm = normalize(float3(scn_node.normalTransform * in.norm));
o.camDir = normalize(float3(scn_node.modelViewTransform*in.pos));
return o;
}
fragment half4 frag(v2f in [[stage_in]], constant settings& s [[buffer(2)]]) {
float nDotCam = abs(dot(float3(in.norm), float3(-in.camDir)));
half4 col;
col.rgb = half3(s.Color.rgb);
col.a = half(mix(s.Color.a, s.minTransparency, nDotCam));
return col;
}
谢谢你的时间!