【问题标题】:SceneKit shader not workingSceneKit 着色器不工作
【发布时间】:2015-02-17 21:28:19
【问题描述】:

我正在尝试在 iOS 8 上使用 SceneKit 中的着色器。 这是我的代码:

let sphere = SCNSphere(radius: 6)
    sphere.segmentCount = 100
    sphere.firstMaterial?.diffuse.contents = UIImage(named: "noise.png")
    sphere.firstMaterial?.diffuse.wrapS = SCNWrapMode.Repeat
    sphere.firstMaterial?.diffuse.wrapT = SCNWrapMode.Repeat
    sphere.firstMaterial?.reflective.contents = UIImage(named: "envmap3")
    sphere.firstMaterial?.fresnelExponent = 1.3

    let sphereNode = SCNNode(geometry: sphere)
    sphereNode.position = SCNVector3(x: 0, y: 0, z: -20)

    let surfaceModifier = NSString(contentsOfFile: NSBundle.mainBundle().pathForResource("carPaint", ofType: "shader")!, encoding: NSUTF8StringEncoding, error: nil)
    sphere.firstMaterial?.shaderModifiers = [SCNShaderModifierEntryPointSurface: surfaceModifier!]

    scene.rootNode.addChildNode(sphereNode)

代码来自 WWDC 2013 SceneKit Demo,我将其翻译成 Swift

这是该演示的 carPaint.shader 文件中相应的着色器代码:

float flakeSize = 0.2;
float flakeIntensity = 0.7;

vec3 paintColor0 = vec3(0.9, 0.4, 0.3);
vec3 paintColor1 = vec3(0.9, 0.75, 0.2);
vec3 flakeColor = vec3(flakeIntensity, flakeIntensity, flakeIntensity);

vec3 rnd =  texture2D(u_diffuseTexture, _surface.diffuseTexcoord * vec2(1.0 / flakeSize)).rgb;
rnd = normalize(2 * rnd - 1.0);

vec3 nrm1 = normalize(0.05 * rnd + 0.95 * _surface.normal);
vec3 nrm2 = normalize(0.3 * rnd + 0.4 * _surface.normal);

float fresnel1 = clamp(dot(nrm1, _surface.view), 0.0, 1.0);
float fresnel2 = clamp(dot(nrm2, _surface.view), 0.0, 1.0);

vec3 col = mix(paintColor0, paintColor1, fresnel1);
col += pow(fresnel2, 106.0) * flakeColor;

_surface.normal = nrm1;
_surface.diffuse = vec4(col, 1.0);
_surface.emission = (_surface.reflective * _surface.reflective) * 2.0;
_surface.reflective = vec4(0.0);

这是控制台输出: http://pastebin.com/JAbJSrxg

应用没有崩溃,但着色器不工作,球体颜色设置为粉红色。

所以我的问题是,我怎样才能让它工作?我认为我做得对,但显然我做得不对。

谢谢

【问题讨论】:

    标签: iphone xcode ios8 shader scenekit


    【解决方案1】:

    您发布的控制台日志显示着色器的这一行有错误:

    rnd = normalize(2 * rnd - 1.0);
    

    由 OpenGL ES 2.0 使用的 GLSL ES 1.0,即 SceneKit 在 iOS 上使用的,不支持整数类型。所以它在抱怨那条线上的文字2。您可以通过将其设为浮点文字 2.0 来解决此问题。

    如果此着色器源在您从中提取的示例代码项目中未更改,您可能需要report a bug。该着色器代码在桌面 OpenGL 上工作,但它应该被编写以便它也可以在 iOS 上工作。

    【讨论】:

    • GLSL ES 也不支持统一初始化。所以你可以这样写:float flakeSize = 0.2; float flakeIntensity = 0.7;
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2023-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多