Применение текстуры к кубу, различные текстуры на каждой грани куба

Я пытаюсь применить различные текстуры на кубе с шейдерами, используя samplerCube и textureCube.

Но я не могу получить текстуру, нарисованную на гранях куба, появляется только один цвет.

Скриншоты вывода

Ниже мой шейдерный код:

Vertex Shader

String strVShader = "attribute vec4 a_position;" + "uniform mat4 u_VPMatrix;" + "attribute vec3 a_normal;" + "varying vec3 v_normal;" + "void main()" + "{" + "gl_Position = u_VPMatrix * a_position;" + "v_normal = a_normal;" + "}"; 

Фрагментный шейдер

 String strFShader = "precision mediump float;" + "uniform samplerCube u_texId;" + "varying vec3 v_normal;" + "void main()" + "{" + "gl_FragColor = textureCube(u_texId, v_normal);" + "}"; 

Определение куба

 float[] cube = { 2,2,2, -2,2,2, -2,-2,2, 2,-2,2, //0-1-2-3 front 2,2,2, 2,-2,2, 2,-2,-2, 2,2,-2,//0-3-4-5 right 2,-2,-2, -2,-2,-2, -2,2,-2, 2,2,-2,//4-7-6-5 back -2,2,2, -2,2,-2, -2,-2,-2, -2,-2,2,//1-6-7-2 left 2,2,2, 2,2,-2, -2,2,-2, -2,2,2, //top 2,-2,2, -2,-2,2, -2,-2,-2, 2,-2,-2,//bottom }; short[] indeces = {0,1,2, 0,2,3, 4,5,6, 4,6,7, 8,9,10, 8,10,11, 12,13,14, 12,14,15, 16,17,18, 16,18,19, 20,21,22, 20,22,23, }; float[] normals = { 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, //front 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, // right 0, 0,-1, 0, 0,-1, 0, 0,-1, 0, 0,-1, //back -1, 0, 0, -1, 0, 0, -1, 0, 0, -1, 0, 0, // left 0, 1, 0, 0, 1, 0, 0, 1, 0, 0, 1, 0, // top 0,-1, 0, 0,-1, 0, 0,-1, 0, 0,-1, 0, // bottom }; 

OnDrawFrame

 public void onDrawFrame(GL10 arg0) { GLES20.glClear(GLES20.GL_COLOR_BUFFER_BIT | GLES20.GL_DEPTH_BUFFER_BIT); GLES20.glUseProgram(iProgId); cubeBuffer.position(0); GLES20.glVertexAttribPointer(iPosition, 3, GLES20.GL_FLOAT, false, 0, cubeBuffer); GLES20.glEnableVertexAttribArray(iPosition); GLES20.glVertexAttribPointer(iNormal, 3, GLES20.GL_FLOAT, false, 0, normBuffer); GLES20.glEnableVertexAttribArray(iNormal); GLES20.glActiveTexture(GLES20.GL_TEXTURE0); GLES20.glBindTexture(GLES20.GL_TEXTURE_CUBE_MAP, iTexId); GLES20.glUniform1i(iTexLoc, 0); Matrix.setIdentityM(m_fIdentity, 0); Matrix.rotateM(m_fIdentity, 0, -xAngle, 0, 1, 0); Matrix.rotateM(m_fIdentity, 0, -yAngle, 1, 0, 0); Matrix.multiplyMM(m_fVPMatrix, 0, m_fViewMatrix, 0, m_fIdentity, 0); Matrix.multiplyMM(m_fVPMatrix, 0, m_fProjMatrix, 0, m_fVPMatrix, 0); GLES20.glUniformMatrix4fv(iVPMatrix, 1, false, m_fVPMatrix, 0); GLES20.glDrawElements(GLES20.GL_TRIANGLES, 36, GLES20.GL_UNSIGNED_SHORT, indexBuffer); } 

Создание кода карты Cube

 public int CreateCubeTexture() { ByteBuffer fcbuffer = null; int[] cubeTex = new int[1]; GLES20.glGenTextures(1, cubeTex, 0); GLES20.glBindTexture(GLES20.GL_TEXTURE_CUBE_MAP,cubeTex[0]); GLES20.glTexParameteri(GLES20.GL_TEXTURE_CUBE_MAP, GLES20.GL_TEXTURE_MIN_FILTER, GLES20.GL_NEAREST); GLES20.glTexParameteri(GLES20.GL_TEXTURE_CUBE_MAP, GLES20.GL_TEXTURE_MAG_FILTER, GLES20.GL_NEAREST); GLES20.glTexParameteri(GLES20.GL_TEXTURE_CUBE_MAP, GLES20.GL_TEXTURE_WRAP_S, GLES20.GL_CLAMP_TO_EDGE); GLES20.glTexParameteri(GLES20.GL_TEXTURE_CUBE_MAP, GLES20.GL_TEXTURE_WRAP_T, GLES20.GL_CLAMP_TO_EDGE); Bitmap img = null; img = BitmapFactory.decodeResource(curView.getResources(), R.raw.brick1); fcbuffer = ByteBuffer.allocateDirect(img.getHeight() * img.getWidth() * 4); img.copyPixelsToBuffer(fcbuffer); fcbuffer.position(0); Log.d("alpha",""+img.hasAlpha()); GLES20.glTexImage2D(GLES20.GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GLES20.GL_RGBA, img.getWidth(),img.getHeight() , 0,GLES20.GL_RGBA ,GLES20.GL_UNSIGNED_BYTE, fcbuffer); fcbuffer = null; img.recycle(); img = BitmapFactory.decodeResource(curView.getResources(), R.raw.brick2); fcbuffer = ByteBuffer.allocateDirect(img.getHeight() * img.getWidth() * 4); img.copyPixelsToBuffer(fcbuffer); fcbuffer.position(0); GLES20.glTexImage2D(GLES20.GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GLES20.GL_RGBA, img.getWidth(),img.getHeight(), 0,GLES20.GL_RGBA ,GLES20.GL_UNSIGNED_BYTE, fcbuffer); fcbuffer = null; img.recycle(); img = BitmapFactory.decodeResource(curView.getResources(), R.raw.brick3); fcbuffer = ByteBuffer.allocateDirect(img.getHeight() * img.getWidth() * 4); img.copyPixelsToBuffer(fcbuffer); fcbuffer.position(0); GLES20.glTexImage2D(GLES20.GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GLES20.GL_RGBA, img.getWidth(),img.getHeight(), 0,GLES20.GL_RGBA ,GLES20.GL_UNSIGNED_BYTE, fcbuffer); fcbuffer = null; img.recycle(); img = BitmapFactory.decodeResource(curView.getResources(), R.raw.brick4); fcbuffer = ByteBuffer.allocateDirect(img.getHeight() * img.getWidth() * 4); img.copyPixelsToBuffer(fcbuffer); fcbuffer.position(0); GLES20.glTexImage2D(GLES20.GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GLES20.GL_RGBA, img.getWidth(),img.getHeight(), 0,GLES20.GL_RGBA ,GLES20.GL_UNSIGNED_BYTE, fcbuffer); fcbuffer = null; img.recycle(); img = BitmapFactory.decodeResource(curView.getResources(), R.raw.brick5); fcbuffer = ByteBuffer.allocateDirect(img.getHeight() * img.getWidth() * 4); img.copyPixelsToBuffer(fcbuffer); fcbuffer.position(0); GLES20.glTexImage2D(GLES20.GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GLES20.GL_RGBA,img.getWidth(),img.getHeight(), 0,GLES20.GL_RGBA ,GLES20.GL_UNSIGNED_BYTE, fcbuffer); fcbuffer = null; img.recycle(); img = BitmapFactory.decodeResource(curView.getResources(), R.raw.brick6); fcbuffer = ByteBuffer.allocateDirect(img.getHeight() * img.getWidth() * 4); img.copyPixelsToBuffer(fcbuffer); fcbuffer.position(0); GLES20.glTexImage2D(GLES20.GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GLES20.GL_RGBA, img.getWidth(),img.getHeight(), 0,GLES20.GL_RGBA ,GLES20.GL_UNSIGNED_BYTE, fcbuffer); fcbuffer = null; img.recycle(); GLES20.glGenerateMipmap(GLES20.GL_TEXTURE_CUBE_MAP); return cubeTex[0]; } 

Я не могу понять, где я ошибаюсь.

Если вы хотите увидеть полный код.

Решение:

Используются одинаковые координаты чертежа куба для координат текстуры

Thanx all

Ссылка CODE

Хотя вопрос теперь решен, я хотел бы предложить объяснение, почему использование других координат фактически помогло (потому что этого не хватает выше).

Когда я впервые реализовал отображение куба, у меня была такая же ошибка из-за неправильного представления о том, как работают карты кубов. Cube-map – это внутренний набор из 6 2D-текстур, расположенных на шести гранях куба. С математической точки зрения он определяет функцию поиска, где аргумент – трехмерное направление, а выход – цвет RGBA.

Это важно, потому что в приведенном выше примере аргумент поиска был нормальным. Нормальное – это правильное направление. Но нормаль также постоянна на всей поверхности куба (за исключением случаев, когда вычисляются нормали гладких оттенков штрихов, чего не было). Если нормальный (вход для поиска) является постоянным, это означает, конечно, что вывод (цвет) также должен быть постоянным. Мое заблуждение в том, что я предположил, что OpenGL каким-то образом учитывает как положение, так и направление , но это, к сожалению, не так.

В этом конкретном случае это может быть либо использование cubeMap (position), либо cubeMap (позиция + направление), и результат будет очень похожим. Это из-за другого важного свойства кубических карт, и это направление ввода сначала нормализуется (изменяется длина до 1, не меняя его направление), прежде чем читать цвет из текстуры. Это использовалось на более старых графических картах для расчета быстрой векторной нормализации, используя специальную текстуру карты куба (поскольку вычисление квадратного корня в шейдере было медленнее, чем поиск текстуры).

Последняя мысль о кубах – кубическая карта – не правильный способ присвоения каждой текстуры каждой текстуре куба. Он работает для простых случаев, но было бы трудно сделать его практичным, например, в игре, потому что я) количество комбинаций разных текстур на одном кубе, вероятно, потребует излишне много текстур и II), потому что таким образом текстура Повтор не может быть использован.

Вам необходимо добавить devDeptSet.dll в приложение и применить его к вашему объекту:

 string brickMatName = "Wall bricks"; viewportLayout1.Materials.Add(brickMatName, new Material(devDept.DataSet.DataSet.GetBricks()));