0

Blender で作成され、.obj ファイルにエクスポートされたモデルがあります。頂点のテクスチャと法線の座標を読み取るパーサーを作成しました。画面に収まるようにモードのサイズを縮小するために、すべての座標をプログラムに適用できる定数で割っています (これは一時的な措置です)。これは、機能しない照明を除いて正常に機能します。色を付ける必要があるときに、黒い 3D オブジェクトが残っています。Web で調べたところ、これは法線の長さが 1 でないためではないでしょうか? これが正しい場合、座標が画面に収まるようにスケーリングし、照明が機能するようにするにはどうすればよいですか?

頂点シェーダー

//
//  Created by Jake Cunningham on 13/10/2012.
//  Copyright (c) 2012 Jake Cunningham. All rights reserved.
//

attribute vec4 position;
attribute vec3 normal;

varying lowp vec4 colorVarying;

uniform mat4 modelViewProjectionMatrix;
uniform mat3 normalMatrix;

attribute vec2 TextCo;
varying vec2 textCoOut;

void main()
{
vec3 eyeNormal = normalize(normalMatrix * normal);
vec3 lightPosition = vec3(0.0, 0.0, 1.0);
vec4 diffuseColor = vec4(0.4, 0.4, 1.0, 1.0);

float nDotVP = max(0.0, dot(eyeNormal, normalize(lightPosition)));

colorVarying = diffuseColor * nDotVP;

gl_Position = modelViewProjectionMatrix * position;
textCoOut = TextCo;
}

フラグメント シェーダー:

//  Created by Jake Cunningham on 13/10/2012.
//  Copyright (c) 2012 Jake Cunningham. All rights reserved.
//

varying lowp vec4 colorVarying;

varying lowp vec2 textCoOut;
uniform sampler2D texture;

void main()
{
gl_FragColor = colorVarying * texture2D(texture, textCoOut);

}

ビューコントローラーからのコード。

glEnable(GL_DEPTH_TEST);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);


glGenVertexArraysOES(1, &_vertexArray);
glBindVertexArrayOES(_vertexArray);

glGenBuffers(1, &_vertexBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _vertexBuffer);
glBufferData(GL_ARRAY_BUFFER, loader.currentCountOfVerticies * sizeof(GLfloat) * 3, arrayOfVerticies, GL_STATIC_DRAW);

glEnableVertexAttribArray(GLKVertexAttribPosition);
glVertexAttribPointer(GLKVertexAttribPosition, 3, GL_FLOAT, GL_FALSE, 12, BUFFER_OFFSET(0));

glGenVertexArraysOES(1, &_normalArray);
glBindVertexArrayOES(_normalArray);

glGenBuffers(1, &_normalBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _normalBuffer);
glBufferData(GLKVertexAttribNormal, loader.currentCountOfNormals  * sizeof(GLfloat) * 3,loader.arrayOfNormals , GL_STATIC_DRAW);

glEnableVertexAttribArray(GLKVertexAttribNormal);
glVertexAttribPointer(GLKVertexAttribNormal, 3, GL_FLOAT, GL_FALSE, 12, BUFFER_OFFSET(0));

glGenVertexArraysOES(1, &_textureArray);
glBindVertexArrayOES(_textureArray);

glGenBuffers(1, &_textureBuffer);
glBindBuffer(GL_ARRAY_BUFFER, _textureBuffer);
glBufferData(GL_ARRAY_BUFFER, loader.currentCountOfTextureCoordinates * sizeof(GLfloat) * 2, loader.arrayOftextureCoOrdinates, GL_STATIC_DRAW);

glEnableVertexAttribArray(GLKVertexAttribTexCoord0);
glVertexAttribPointer(GLKVertexAttribTexCoord0, 2, GL_FLOAT, GL_FALSE, 8, BUFFER_OFFSET(0));


glBindVertexArrayOES(0);
4

1 に答える 1

1

シェーダーを使用している場合はnormalize()、GLSL コード内で頂点と法線に対して操作を使用できます。

また、モデルのスケーリング、中央揃え、正規化を行うobj2opengl スクリプトを見て、OBJ ファイルを iOS 実装の準備が整ったヘッダー ファイルに変換することもできます。また、そのスクリプトをmtl2openglに拡張して、MTL ファイルのサポートを組み込み、もう少し軽量にしました (Xcode の例も使用)。

于 2012-12-31T12:28:35.620 に答える