为什么当我使用SCNTechnique时,我的场景摄像机只显示黑屏?

时间:2019-03-07 13:59:43

标签: ios swift shader scenekit scntechnique

所以我正在将SceneKit与iOS 12(Swift 4.2)一起使用,我想向相机添加旋转/凹凸变形。我在这里(Fish Eye Wide-angle with a Scene Kit Camera: Possible?)找到了类似的东西,据说会产生桶形失真。但是当我尝试将其添加到项目中时,场景只是变黑,并且在控制台中出现错误

  

2019-03-07 13:35:14.982232 + 0000 TestingSCN [551:66202] [framework] CUIThemeStore:未注册ID = 0的主题

     

2019-03-07 13:35:15.064859 + 0000 TestingSCN [551:66202] [framework] CUIThemeStore:未注册ID = 0的主题

     

2019-03-07 13:35:15.097517 + 0000 TestingSCN [551:66270] [framework] CUIThemeStore:未注册ID = 0的主题

     

2019-03-07 13:35:15.118445 + 0000 TestingSCN [551:66270] [SceneKit]错误:如果没有程序,则无法使用默认值呈现

现在,该方法基本上是使用JSON词典文件定义技术以及GLSL顶点和片段着色器文件。然后在我的主要swift文件中,将该技术添加到相机中。这是我使用的代码: bucket.json(位于art.scnassets中)

{
    "passes" : {
        "barrel" : {
            "outputs" : {
                "color" : "COLOR"
            },
            "inputs" : {
                "colorSampler" : "COLOR",
                "noiseSampler" : "noiseSymbol",
                "a_position" : "a_position-symbol"
            },
            "program" : "art.scnassets/barrel",
            "draw" : "DRAW_QUAD"
        }
    },
    "sequence" : [
        "barrel"
    ],
    "symbols" : {
        "a_position-symbol" : {
        "semantic" : "vertex"
        },
        "noiseSymbol" : {
            "image" : "noise.png",
            "type" : "sampler2D"
        },
        "barrelPower" : {
            "type" : "float"
        }
    }
}

barrel.fsh

uniform sampler2D colorSampler;
const float PI = 3.1415926535;
uniform float barrelPower;
varying vec2 uv;
vec2 Distort(vec2 p)
{
    float theta  = atan(p.y, p.x);
    float radius = length(p);
    radius = pow(radius, barrelPower);
    p.x = radius * cos(theta);
    p.y = radius * sin(theta);
    return 0.5 * (p + 1.0);
}
void main() {
    vec2 rg = 2.0 * uv.xy - 1.0;
    vec2 uv2;
    float d = length(xy);
    if (d < 1.0){
        uv2 = Distort(xy);
    } else {
        uv2 = uv.xy;
    }
    gl_FragColor = texture2D(colorSampler, uv2);
}

barrel.vsh

attribute vec4 a_position;
varying vec2 uv;

void main() {
    gl_Position = a_position;
    uv = a_position.xy;
}

GameViewController.swift(在viewDidLoad中)

let url: URL = Bundle.main.url(forResource: "art.scnassets/barrel", withExtension: "json")!

do {
    let jsonData = try Data(contentsOf: url)
    let jsonObject = try JSONSerialization.jsonObject(with: jsonData, options:JSONSerialization.ReadingOptions(rawValue: 0))
    guard let dictionary = jsonObject as? Dictionary<String, Any> else {
        print("Not a Dictionary")
        return
    }
    var technique: SCNTechnique? = nil
    technique = SCNTechnique(dictionary: dictionary)
    technique?.setValue(NSNumber(value: 0.5), forKey: "barrelPower")
    cameraNode.camera?.technique = technique
}
catch let error as NSError {
    print("Found an error - \(error)")
}

我并不是着色器专家,我知道写一个SCNProgram或其他东西可能更好,但是我不知道从哪里开始。 任何帮助表示赞赏:)

1 个答案:

答案 0 :(得分:0)

您可以尝试

    let scnView = self.view as! SCNView
    scnView.technique = technique

正在使用(“ draw”:“ DRAW_QUAD”)渲染渲染对象的纹理。

还有一个编译器错误:

 float d = length(xy);  // `xy` is not defined