运用纹理立方,不同的纹理在立方体的每一个面 [英] applying texture to Cube, different texture on each face of cube

查看:271
本文介绍了运用纹理立方,不同的纹理在立方体的每一个面的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图用samplerCube和textureCube着色器多维数据集应用不同的质感。

I'm trying to apply different texture on cube with shaders using samplerCube and textureCube.

但我不能够获得立方体只有单一颜色的脸绘制纹理出现。

But I'm not able to get texture drawn on faces of cube only single color is appearing.

输出的截图

下面是我的着色器code:

Below is my shader code:

顶点着色器

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);
    }

创建立方体贴图code

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];
    }

我无法明白的地方,我会犯错。

I'm not able to understand where I'm making mistake.

如果你想看到完整的code。

If you want see full code.

解决方案:

用于相同的立方体绘制坐标纹理坐标

Used same cube drawing co-ordinates for texture co-ordinates

感谢名单全部

code链接

推荐答案

但现在的问题是解决了,我想提出为什么使用不同的坐标实际上帮助解释(因为这是上述失踪)。

although the question is now solved, i would like to offer an explanation for why using a different coordinates actually helped (because that is missing above).

当我第一次实现立方体贴图,我有这个同样的错误,因为立方体贴图是如何工作的误解。立方体地图内部是一组6个2D纹理,安排在立方体的六个面。从数学的角度来看,它定义了一个查找函数,其中参数是3D 方向并输出RGBA颜色。

When i first implemented cube-mapping, i had this same error, because of misconception of how cube maps worked. Cube-map is internally a set of 6 2D textures, arranged on a six faces of a cube. From a mathematical point of view, it defines a lookup function, where argument is 3D direction and output is RGBA color.

这是重要的,因为在上述的例子中,参数查找正常。正常的是一个方向,这是正确的。但在正常也是横跨立方体的整个面常数(当计算平滑着色风格法线除外,这是不是这种情况)。如果(输入到查找)的正常是恒定的,这当然是指输出(彩色)必须恒定为好。我的这种误解是,我假设的OpenGL会在一定程度兼顾的位置和方向,但就是遗憾的是情况并非如此。

This is important, because in the example above, the argument to the lookup was normal. Normal is a direction, which is correct. But the normal is also constant across the entire face of the cube (except when smooth shading style normals are calculated, which was not the case). If the normal (input to the lookup) is constant, that means of course the output (color) must be constant as well. My misconception in this was that i assumed that OpenGL would somehow take into account both position and direction, but that is unfortunately not the case.

在该特定情况下Interersting的是,人们可以使用立方体(位置)或立方体(位置+方向),并且将得到相当类似的结果。这是因为立方体地图的另一重要特性,那就是输入方向首先被归一化(变更长度为1,而不改变它的方向)读出彩的纹理之前。这是用在一些老显卡来计算快速矢量归,采用特殊的立方体贴图(因为计算着色器平方根比纹理查找慢)。

Interersting thing in this particular case is, one can either use cubeMap(position) or cubeMap(position + direction), and will get quite similar result. It is because of another important property of cube maps, and that is the input direction is first normalized (changed length to 1, without changing it's direction) before reading color out of the texture. This was used on older graphics cards to calculate fast vector normalization, using a special cube map texture (because calculating square root in shader was slower than texture lookup).

有关立方体最后一个思想 - 立方体地图不是一个立方体的每一面分配不同纹理的正确途径。它适用于简单的情况下,但它是很难让它实用,例如在游戏中,因为我)上的一个立方体不同质地的组合的数量很可能需要不必要的大量纹理和II),因为这样一来,纹理重复不能使用的

One last thought about cubes - cube-map is not the correct way of assigning different texture to each face of a cube. It works for a simple cases, but it would be hard to make it practical, e.g. in a game, because I) the number of combinations of different textures on one cube would probably require unnecessarily lot of textures and II) because this way, texture repeat can not be used.

这篇关于运用纹理立方,不同的纹理在立方体的每一个面的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆