저는 높이 맵 텍스처에 따라 평면의 지오메트리를 대체하는 SceneKit 셰이더 수정 자 (지오메트리 진입 점용)를 만드는 초기 단계에 있습니다. 계획은 지형을 만드는 데 사용하는 것입니다.
iOS (편집 : iOS 시뮬레이터)에서는 셰이더가 정상적으로 작동하지만이 경고를 콘솔에 출력합니다.
SceneKit : 오류, 코드없는 수정자는 유효하지 않습니다.
그러나 OS X 용으로 빌드 할 때 셰이더에 치명적인 오류가 발생하고 지형 지오메트리가 분홍색 직사각형으로 표시됩니다.
이것은 지오메트리 셰이더 수정 자입니다.
uniform sampler2D displacementMap;
const float intensity = 7.5;
# pragma body
vec4 displace = texture2D(displacementMap, _geometry.texcoords[0]);
_geometry.position.z += displace.r * intensity;
이것이 셰이더가 지오메트리에 연결되는 방식입니다. terrainScene
높이 맵이며, 확산 내용과 displacementMap
셰이더 수정 자의 사용자 정의 샘플러 값에 모두 배치됩니다 .
//displacement shader
let mat = SCNMaterial()
mat.diffuse.contents = terrainScene
var displacementShader: String?
guard let path = NSBundle.mainBundle().pathForResource("DisplaceGeometry", ofType: "shader") else {return}
do {
displacementShader = try String(contentsOfFile: path, encoding: NSUTF8StringEncoding)
} catch {
return
}
mat.shaderModifiers = [SCNShaderModifierEntryPointGeometry: displacementShader!]
let noiseProperty = SCNMaterialProperty(contents: terrainScene!)
mat.setValue(noiseProperty, forKey: "displacementMap")
//geometry
let plane = SCNPlane(width: 80, height: 80)
plane.widthSegmentCount = 40
plane.heightSegmentCount = 40
plane.materials = [mat]
다음은 OS X 오류 메시지의 시작입니다.
SceneKit: error, modifier without code is invalid
2016-06-11 10:58:32.054 EndlessTerrainOSX[16923:5292387] SceneKit: error, Invalid shader modifier : no code provided
2016-06-11 10:58:32.640 EndlessTerrainOSX[16923:5292387] FATAL ERROR : failed loading compiling shader:
그리고 오류의 끝 :
UserInfo={NSLocalizedDescription=Compilation failed:
<program source>:343:8: error: global variables must have a constant address space qualifier
float4 displace = displacementMap.sample(displacementMapSampler, _geometry.texcoords[0]);
^
<program source>:343:19: error: use of undeclared identifier 'displacementMap'
float4 displace = displacementMap.sample(displacementMapSampler, _geometry.texcoords[0]);
^
<program source>:343:42: error: use of undeclared identifier 'displacementMapSampler'
float4 displace = displacementMap.sample(displacementMapSampler, _geometry.texcoords[0]);
^
<program source>:344:1: error: unknown type name '_geometry'
_geometry.position.z += displace.r * intensity;
^
<program source>:344:10: error: cannot use dot operator on a type
_geometry.position.z += displace.r * intensity;
^
}
2016-06-11 10:58:32.646 EndlessTerrainOSX[16923:5292387] Shaders without a vertex function are not allowed
iOS에 표시되는 이유를 아는 사람이 있지만 OS X에서는 실패합니까?
iOS 대 OSX 문제는 아니지만 OpenGL과 다른 Metal을 사용하는 한 장치와 관련이있을 수 있습니다.
오류 메시지의 코드는 Metal이며 SceneKit이 코드를 GLSL에서 Metal로 변환했음을 나타냅니다. 내 경험상 이것은 100 % 작동하지 않습니다. 귀하의 경우 가장 간단한 해결책은 SCNView
OpenGL을 만들 때 옵션 을 전달 하여 강제 로 OpenGL을 사용 하도록하는 것입니다 . 이것도 Interface Builder에 드롭 다운이 있다고 생각합니다.
Metal을 계속 사용하고 싶은데 그 이유가 있다면 계속 읽으십시오.
셰이더 수정자가 셰이더의 전체 내용을 컴파일하지 못하면 stdout에 덤프되어 디버깅 프로세스에 정말 도움이됩니다. 343 행까지 스크롤하면 SceneKit이 정점 셰이더 앞에float4 displace = displacementMap.sample(...);
메서드 를 포함했음을 알 수 있습니다. 함수 외부에서 정의된다는 것은 전역 변수라는 것을 의미하므로 constant
주소 공간 수정자가 필요 하지만 이것은 전혀 원하는 것이 아닙니다 ...이 경우 GLSL에서 Metal 로의 변환이 예상대로 작동하지 않았습니다.
#pragma arguments
지시문 이 누락되었다는 점에 유의하십시오 . 이것은 균일 한 정의 위에 포함되어야합니다 ( "Shader Modifier Snippet 작성" 참조 ). 도움이 될 수 있습니다. 내 경험상 메탈 기반 셰이더 수정 자에 텍스처를 전달하는 데 어려움을 겪을 것이라고 생각합니다. 나는 그것을 시도하고, 실패하고, SCNProgram
대신 썼다 . OpenGL을 강제하도록 제안하십시오.
이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.
침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제
몇 마디 만하겠습니다