如何在SceneKit中创建动画纹理? “默认程序回退”错误

时间:2015-04-05 22:04:59

标签: ios glsl shader scenekit

我想在SceneKit中使用动画纹理,我发现这个Using shader modifiers to animate texture in SceneKit leads to jittery textures over time,但是我的错误代码相同:

  

C3DResourceManagerMakeProgramResident无法编译程序 - 默认程序的回退

我尝试使用另一个文件作为着色器(新文件> Empty>名为animated.shader),然后使用此代码,但我遇到了同样的错误:

let fireImage = UIImage(contentsOfFile: "art.scnassets/torch.png")
myMaterial = SCNMaterial()
myMaterial.diffuse.contents = fireImage
myMaterial.diffuse.wrapS = SCNWrapMode.Repeat
myMaterial.diffuse.wrapT = SCNWrapMode.Repeat

myMaterial.shaderModifiers = [ SCNShaderModifierEntryPointGeometry : "uniform float u_time; _geometry.texcoords[0] = vec2((_geometry.texcoords[0].x+floor(u_time*30.0))/24.0, (_geometry.texcoords[0].y+floor(u_time*30.0/24.0))/1.0);" ]
plane.materials = [myMaterial]

//OR :

let url = NSBundle.mainBundle().pathForResource("animated", ofType: "shader")
let str = String(contentsOfFile: url!, encoding: NSUTF8StringEncoding , error: nil)
let nstr = NSString(string: str!)
myMaterial.shaderModifiers = [ SCNShaderModifierEntryPointFragment: nstr ]
plane.materials = [myMaterial]

我尝试使用一个简单的着色器,在文档中给出了Apple,确保它有效。所以问题来自我正在使用的代码。

我在这里发现了第二个代码(wiki unity):link,我稍微改了一下,使用glsl代替unityscript

uniform float u_time;
float numTileX = 24;
float numTileY = 1;
float fps = 30;

float indexA = u_time * fps;
float index = index % (numTileX * numTileY);
float uIndex = index % numTileX;
float vIndex = index / numTileY;

_geometry.texcoords[0] = vec2( (_geometry.texcoords[0].x + uIndex) , (_geometry.texcoords[0].y + vIndex) );

编辑:以下是错误:

错误:

SceneKit: error, failed to link program: ERROR: 0:66: '%' does not operate on 'int' and 'int'
ERROR: 0:67: Use of undeclared identifier 'index'
ERROR: 0:68: Use of undeclared identifier 'index'
ERROR: 0:69: Use of undeclared identifier '_geometry'

新代码:

int numTileX = 24;
int numTileY = 1;

float fps = 30.0;
float indexA = u_time * fps;
int indexI = int(indexA);
int total = int(numTileX * numTileY);

int index = indexI % total;
float uIndex = index % numTileX;
float vIndex = index / numTileY;

_geometry.texcoords[0] = vec2( (_geometry.texcoords[0].x + uIndex) , (_geometry.texcoords[0].y + vIndex) );

你知道如何解决这个问题吗?

由于

1 个答案:

答案 0 :(得分:2)

如果不了解有关着色器编译错误的更多信息,很难判断该着色器代码是否存在更多错误,但是您获得的错误意味着着色器程序无法编译。

通过查看着色器代码,我认为我发现了两个错误:

  1. Scene Kit已经声明了当前时间的统一float u_time;,以秒为单位,可在所有入口点使用。此外,u_a_v_前缀由Scene Kit保留,不应用于着色器修改器中的自定义变量。

  2. GLSL对类型转换非常挑剔。将整数类型分配给float变量 not 导致转换(就像在C中一样),而是类型错误。

  3. 这意味着,例如:

    float numTileX = 24;
    

    是类型错误,应重新定义为:

    float numTileX = 24.0;
    

    同样的事情适用于混合整数和浮动类型的算法。