मैं SceneKit
में गड़बड़ करने की कोशिश कर रहा हूं और खुद को सिखाता हूं। असल में, मैं 3 आयताकार पक्षों और 1 ढलान वाली स्लाइड के साथ एक ट्रैक्टर बना रहा हूं।कस्टम शेडर एससीएनप्रोग्राम आईओएस 9 सीनेट
मैं चाहता हूं कि सतह पर फैलाएं और विकृत हो जाएं।
कुछ सामान ऑनलाइन पढ़ना, ऐसा लगता है कि मुझे प्रभाव प्राप्त करने के लिए कस्टम वर्टेक्स और खंड शेडर्स के साथ SCNProgram
बनाना होगा। लेकिन, मुझे सतह पर फैलाने के लिए बनावट प्रतीत नहीं हो रही है। कृपया मदद की ज़रूरत है। (मैं ग्राफिक्स प्रोग्रामिंग के लिए नया हूं इसलिए इसे खुद को सिखाने की कोशिश कर रहा हूं)।
मेरे स्विफ्ट कोड ज्यामिति और बनावट बनाने के लिए इसका इस प्रकार है:
func geometryCreate() -> SCNNode {
let verticesPosition = [
SCNVector3Make(0.0, 0.0, 0.0),
SCNVector3Make(5.0, 0.0, 0.0),
SCNVector3Make(5.0, 5.0, 0.0),
SCNVector3Make(0.0, 3.0, 0.0)
]
let textureCord = [CGPoint (x: 0.0,y: 0.0), CGPoint(x: 1.0,y: 0.0), CGPoint(x: 1.0,y: 1.0), CGPoint(x: 0.0,y: 1.0)]
let indices: [CInt] = [
0, 2, 3,
0, 1, 2
]
let vertexSource = SCNGeometrySource(vertices: verticesPosition, count: 4)
let srcTex = SCNGeometrySource(textureCoordinates: textureCord, count: 4)
let date = NSData(bytes: indices, length: sizeof(CInt) * indices.count)
let scngeometry = SCNGeometryElement(data: date, primitiveType: SCNGeometryPrimitiveType.Triangles, primitiveCount: 2, bytesPerIndex: sizeof(CInt))
let geometry = SCNGeometry(sources: [vertexSource,srcTex], elements: [scngeometry])
let program = SCNProgram()
if let filepath = NSBundle.mainBundle().pathForResource("vertexshadertry", ofType: "vert") {
do {
let contents = try NSString(contentsOfFile: filepath, encoding: NSUTF8StringEncoding) as String
program.vertexShader = contents
} catch {
print("**** happened loading vertex shader")
}
}
if let fragmentShaderPath = NSBundle.mainBundle().pathForResource("fragshadertry", ofType:"frag")
{
do {
let fragmentShaderAsAString = try NSString(contentsOfFile: fragmentShaderPath, encoding: NSUTF8StringEncoding)
program.fragmentShader = fragmentShaderAsAString as String
} catch {
print("**** happened loading frag shader")
}
}
program.setSemantic(SCNGeometrySourceSemanticVertex, forSymbol: "position", options: nil)
program.setSemantic(SCNGeometrySourceSemanticTexcoord, forSymbol: "textureCoordinate", options: nil)
program.setSemantic(SCNModelViewProjectionTransform, forSymbol: "modelViewProjection", options: nil)
do {
let texture = try GLKTextureLoader.textureWithCGImage(UIImage(named: "stripes")!.CGImage!, options: nil)
geometry.firstMaterial?.handleBindingOfSymbol("yourTexture", usingBlock: { (programId:UInt32, location:UInt32, node:SCNNode!, renderer:SCNRenderer!) -> Void in
glTexParameterf(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_WRAP_S), Float(GL_CLAMP_TO_EDGE))
glTexParameterf(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_WRAP_T), Float(GL_CLAMP_TO_EDGE))
glTexParameterf(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MAG_FILTER), Float(GL_LINEAR))
glTexParameterf(GLenum(GL_TEXTURE_2D), GLenum(GL_TEXTURE_MIN_FILTER), Float(GL_LINEAR))
glBindTexture(GLenum(GL_TEXTURE_2D), texture.name)
})
} catch {
print("Texture not loaded")
}
geometry.firstMaterial?.program = program
let scnnode = SCNNode(geometry: geometry)
return scnnode
}
मेरे वर्टेक्स शेडर है:
attribute vec4 position;
attribute vec2 textureCoordinate;
uniform mat4 modelViewProjection;
varying highp vec2 pos;
varying vec2 texCoord;
void main() {
texCoord = vec2(textureCoordinate.s, 1.0 - textureCoordinate.t) ;
gl_Position = modelViewProjection * position;
pos = vec2(position.x, 1.0 - position.y);
}
मेरे टुकड़ा शेडर है:
precision highp float;
uniform sampler2D yourTexture;
varying highp vec2 texCoord;
varying highp vec2 pos;
void main() {
gl_FragColor = texture2D(yourTexture, vec2(pos.x, pos.y));
}
मैं बस सतह पर फैले नीचे बाईं ओर बनावट बना नहीं लग रहा है। क्या आप मदद कर सकतें है?
कुछ मैनुअल शीर्ष और frag शेडर करतब दिखाने करना, मैं परिणाम प्राप्त कर सकते हैं लेकिन यह बहुत असजीला लगता है और मैं बहुत यकीन है कि यह इस तरह विशिष्ट कोड लिखने नहीं होना चाहिए हूँ।
attribute vec4 position;
attribute vec2 textureCoordinate;
uniform mat4 modelViewProjection;
varying highp vec2 pos;
varying vec2 texCoord;
void main() {
// Pass along to the fragment shader
texCoord = vec2(textureCoordinate.s, 1.0 - textureCoordinate.t) ;
// output the projected position
gl_Position = modelViewProjection * position;
pos = vec2(position.x, position.y);
}
टुकड़ा शेडर में किए गए परिवर्तन (जहां 0.4 ट्रैक्टर के शीर्ष की ढलान):
precision highp float;
uniform sampler2D yourTexture;
varying highp vec2 texCoord;
varying highp vec2 pos;
void main() {
gl_FragColor = texture2D(yourTexture, vec2(pos.x/5.0, 1.0 - pos.y/(3.0+0.4*pos.x)));
// gl_FragColor = vec4 (0.0, pos.y/5.0, 0.0, 1.0);
}
कौन सा मुझे देता है मैं वास्तव में क्या देख रहा हूँ, लेकिन यह काम करने के बहुत गलत तरीके से लगता है ।
संपादित करें: मैं texCoord
रूप texCoord के बजाय pos
चर का उपयोग कर रहा मुझे नरक परिणाम जो मैं वास्तव में समझ में नहीं कर सकते, क्योंकि :(अजीब दे रहा है
अगर मैं संशोधित करने के लिए था मेरी। टुकड़ा शेडर के रूप में:
:precision highp float;
uniform sampler2D yourTexture;
varying highp vec2 texCoord;
varying highp vec2 pos;
void main() {
// gl_FragColor = texture2D(yourTexture, vec2(pos.x/5.0, 1.0 - pos.y/(3.0+0.4*pos.x)));
gl_FragColor = texture2D(yourTexture, texCoord);
// gl_FragColor = vec4 (0.0, pos.y/5.0, 0.0, 1.0);
}
मैं नीचे तस्वीर की तरह कुछ मिलता है
जो मुझसे कहता है कि मेरे बनावट में कुछ गड़बड़ है परिभाषा को निर्देशित करता है लेकिन मुझे पता नहीं लगा सकता कि क्या?
EDIT2: ठीक प्रगति।
let uvSource = SCNGeometrySource(data: uvData,
semantic: SCNGeometrySourceSemanticTexcoord,
vectorCount: textureCord.count,
floatComponents: true,
componentsPerVector: 3,
bytesPerComponent: sizeof(Float),
dataOffset: 0,
dataStride: sizeof(vector_float2))
अब जब मैं अपने frag शेडर में texCoord का उपयोग यह मुझे इस तरह एक परिणाम देता है::
एक जवाब है कि लॉक एक संबंधित धागा मैं अपने uvs नए सिरे से परिभाषित पर दिया नीचे विधि का उपयोग कर के आधार परयह ऊपर की बनावट में घुमावदार विकृतियों के रूप में महान नहीं है। लेकिन इसकी प्रगति।किसी भी विचार से मैं इस विशाल प्रश्न में तस्वीर 2 की तरह कैसे सुगम हो सकता हूं?
कृपया मदद करते हैं।
अच्छा काम @AdiTheExplorer। विरूपण को रोकने के लिए आपको 0,1.6 (3/5) पर होने के बजाय, शीर्ष बाएं बनावट समन्वय को समायोजित करने की आवश्यकता है। एफडब्ल्यूआईडब्ल्यू, मुझे नहीं लगता कि आपके पास बनावट निर्देशांक उत्पन्न करने के लिए कोड के साथ क्या गलत है, लेकिन स्पष्ट रूप से कुछ इसके साथ बिल्कुल सही नहीं था। – lock
धन्यवाद @lock। लेकिन मैं वास्तव में यह चाहता हूं कि यह थ्रेड में तस्वीर 2 में विकृत हो जाए ताकि यह वक्र बनावट में जा सके? जहां यह 2 त्रिकोणों में समान रूप से विकृत हो रहा है। आप रास्ते से एक बड़ी मदद कर चुके हैं। इसके बिना इसे नहीं किया जा सका :) – AdiTheExplorer
पर्याप्त मेला। उस स्थिति में यह शायद शीर्ष दाएं समन्वय है जिसे आप ट्विक करना चाहते हैं, जिससे यह y समन्वय कम हो जाएगा। यह संभवतः आपको चित्र 2 में दिखाई देने वाली विरूपण नहीं देगा, यह एक रचनात्मक समीकरण है जिसे आपने बनावट निर्देशांक की गणना के लिए प्राप्त किया है। आप शायद यूवी के उपयोग से इसे दोहराना कर सकते हैं, अब वे ठीक हैं ('gl_FragColor = texture2D (yourTexture, vec2 (texCoord.x, texCoord.y/(0.4 * texCoord.x));' शायद ...)। लेकिन, आम तौर पर आपकी बनावट छवि में मानक शेडर्स के उपयोग की इजाजत देकर विरूपण होता है। – lock