本文介绍了SceneKit着色器不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm trying to work with shaders in SceneKit on iOS 8.Here is my code:

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演示,我将其翻译为Swift

The code is from the WWDC 2013 SceneKit Demo and I translated it into Swift

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

This here is the corresponding shader code from the carPaint.shader file of that demo:

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

该应用程序不会崩溃,但着色器无法正常工作,并且球体颜色设置为粉红色.

The app does not crash but the shader is not working and the sphere color is set to pink.

所以我的问题是,如何使它正常工作?我认为我做得对,但显然我做得不对.

So my question is, how can I get this to work? I think I'm doing it right but obviously I'm doing it not right.

谢谢

推荐答案

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

The console log you posted says there's an error on this line of the shader:

rnd = normalize(2 * rnd - 1.0);

GLSL ES 1.0(由SceneKit在iOS上使用的OpenGL ES 2.0使用)不支持整数类型.因此,它抱怨该行上的文字2.您可以通过将其设置为浮点文字2.0来解决此问题.

GLSL ES 1.0, which is used by OpenGL ES 2.0, which is what SceneKit uses on iOS, doesn't support integer types. So it's complaining about the literal 2 on that line. You can fix this by making it a floating point literal 2.0.

如果此着色器源与您从中提取的示例代码项目相同,则可能要报告错误.该着色器代码可在桌面OpenGL上运行,但应进行编写,使其也可在iOS上运行.

If this shader source is unchanged from the sample code project you pulled it from, you might want to report a bug. That shader code works on desktop OpenGL, but it ought to be written so that it works on iOS too.

这篇关于SceneKit着色器不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-31 10:16