在OpenGL ES中,將值傳入Shader的方式主要有以下幾種:
1. Uniform變量
- 用途:用于傳遞在繪制過程中不變的常量數據,如變換矩陣、顏色等。
- 步驟:
- 在Shader中聲明Uniform變量:
uniform mat4 uMVPMatrix; // 例如一個模型視圖投影矩陣 uniform vec4 uColor; // 例如一個顏色值
- 在C/C++代碼中獲取Uniform變量的位置:
GLint uMVPMatrixLocation = glGetUniformLocation(program, "uMVPMatrix"); GLint uColorLocation = glGetUniformLocation(program, "uColor");
- 使用
glUniform*
系列函數將數據傳入Shader:glUniformMatrix4fv(uMVPMatrixLocation, 1, GL_FALSE, mvpMatrix); glUniform4f(uColorLocation, r, g, b, a);
- 在Shader中聲明Uniform變量:
2. Attribute變量
- 用途:用于傳遞每個頂點不同的數據,如頂點位置、法線、紋理坐標等。
- 步驟:
- 在Shader中聲明Attribute變量:
attribute vec4 aPosition; // 頂點位置 attribute vec2 aTexCoord; // 紋理坐標
- 在C/C++代碼中獲取Attribute變量的位置:
GLint aPositionLocation = glGetAttribLocation(program, "aPosition"); GLint aTexCoordLocation = glGetAttribLocation(program, "aTexCoord");
- 使用
glVertexAttribPointer
指定數據格式和位置:glVertexAttribPointer(aPositionLocation, 3, GL_FLOAT, GL_FALSE, stride, vertexData); glVertexAttribPointer(aTexCoordLocation, 2, GL_FLOAT, GL_FALSE, stride, texCoordData);
- 啟用Attribute變量:
glEnableVertexAttribArray(aPositionLocation); glEnableVertexAttribArray(aTexCoordLocation);
- 在Shader中聲明Attribute變量:
3. Texture(紋理)
- 用途:用于傳遞紋理數據,通常用于貼圖。
- 步驟:
- 在Shader中聲明Sampler變量:
uniform sampler2D uTexture; // 2D紋理
- 在C/C++代碼中綁定紋理并傳入Shader:
glActiveTexture(GL_TEXTURE0); // 激活紋理單元0 glBindTexture(GL_TEXTURE_2D, textureId); // 綁定紋理 GLint uTextureLocation = glGetUniformLocation(program, "uTexture"); glUniform1i(uTextureLocation, 0); // 將紋理單元0傳入Shader
- 在Shader中聲明Sampler變量:
4. Varying變量
- 用途:用于在Vertex Shader和Fragment Shader之間傳遞插值數據,如顏色、紋理坐標等。
- 步驟:
- 在Vertex Shader中聲明Varying變量并賦值:
varying vec2 vTexCoord; void main() {vTexCoord = aTexCoord; // 從Attribute變量傳入gl_Position = uMVPMatrix * aPosition; }
- 在Fragment Shader中聲明相同的Varying變量并使用:
varying vec2 vTexCoord; void main() {gl_FragColor = texture2D(uTexture, vTexCoord); // 使用插值后的紋理坐標 }
- 在Vertex Shader中聲明Varying變量并賦值:
5. Shader Storage Buffer Object (SSBO)
- 用途:用于傳遞大量數據,通常用于計算Shader或復雜的數據結構。
- 步驟:
- 在Shader中聲明SSBO:
layout(std430, binding = 0) buffer MyBuffer {vec4 data[]; };
- 在C/C++代碼中創建并綁定SSBO:
GLuint ssbo; glGenBuffers(1, &ssbo); glBindBuffer(GL_SHADER_STORAGE_BUFFER, ssbo); glBufferData(GL_SHADER_STORAGE_BUFFER, size, data, GL_DYNAMIC_DRAW); glBindBufferBase(GL_SHADER_STORAGE_BUFFER, 0, ssbo);
- 在Shader中聲明SSBO:
6. Uniform Buffer Object (UBO)
- 用途:用于在多個Shader之間共享Uniform數據。
- 步驟:
- 在Shader中聲明UBO:
layout(std140) uniform MyUBO {mat4 uMVPMatrix;vec4 uColor; };
- 在C/C++代碼中創建并綁定UBO:
GLuint ubo; glGenBuffers(1, &ubo); glBindBuffer(GL_UNIFORM_BUFFER, ubo); glBufferData(GL_UNIFORM_BUFFER, size, data, GL_STATIC_DRAW); glBindBufferBase(GL_UNIFORM_BUFFER, 0, ubo);
- 在Shader中聲明UBO:
總結
- Uniform:用于傳遞常量數據。
- Attribute:用于傳遞頂點數據。
- Texture:用于傳遞紋理數據。
- Varying:用于在Vertex和Fragment Shader之間傳遞插值數據。
- SSBO:用于傳遞大量數據。
- UBO:用于在多個Shader之間共享Uniform數據。
根據具體需求選擇合適的方式將數據傳入Shader。