【问题标题】:Perlin noise shaderPerlin 噪声着色器
【发布时间】:2014-01-21 09:10:25
【问题描述】:

我正在尝试为我的一个应用程序创建动画背景。

基本上,我希望我的活动将animated Perlin or Simplex noise 显示为背景。为了降低能耗,我正在尝试使用 OpenGL 做所有事情。不幸的是,我对 OpenGL 知之甚少。

我从Displaying Graphics with OpenGL ES 开始,它奏效了。然后我尝试替换 Square 的绘图代码和顶点/片段着色器,但最终出现运行时异常。

我正在尝试使用以下顶点着色器:

uniform mat4 uMVPMatrix;
attribute vec4 vPosition;

void main()
{
    gl_Position = uMVPMatrix * vPosition;
}

片段着色器从Ashima Arts略有改变:

float snoise(vec3 v) { 
  // ..
}


uniform float time; // Used for texture animation

void main( void )
{
  vec3 v_texCoord3D = gl_Position.xyz; 

  vec3 uvw = v_texCoord3D + 0.1*vec3(snoise(v_texCoord3D + vec3(0.0, 0.0, time)),
    snoise(v_texCoord3D + vec3(43.0, 17.0, time)),
    snoise(v_texCoord3D + vec3(-17.0, -43.0, time)));
  // Six components of noise in a fractal sum
  float n = snoise(uvw - vec3(0.0, 0.0, time));
  n += 0.5 * snoise(uvw * 2.0 - vec3(0.0, 0.0, time*1.4)); 
  n += 0.25 * snoise(uvw * 4.0 - vec3(0.0, 0.0, time*2.0)); 
  n += 0.125 * snoise(uvw * 8.0 - vec3(0.0, 0.0, time*2.8)); 
  n += 0.0625 * snoise(uvw * 16.0 - vec3(0.0, 0.0, time*4.0)); 
  n += 0.03125 * snoise(uvw * 32.0 - vec3(0.0, 0.0, time*5.6)); 
  n = n * 0.7;
  // A "hot" colormap - cheesy but effective 
  gl_FragColor = vec4(vec3(1.0, 0.5, 0.0) + vec3(n, n, n), 1.0);
}

绘制函数:

public void draw(float[] mvpMatrix)
{
    GLES20.glUseProgram(m_program);

    int positionHandle = GLES20.glGetAttribLocation(m_program, "vPosition");
    GLES20.glEnableVertexAttribArray(positionHandle);

    int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex
    GLES20.glVertexAttribPointer(positionHandle, COORDS_PER_VERTEX, GLES20.GL_FLOAT, false, vertexStride, m_vertexBuffer);

    int timeHandle = GLES20.glGetUniformLocation(m_program, "time");
    GLES20.glUniform1f(timeHandle, time);

    int mvpMatrixHandle = GLES20.glGetUniformLocation(m_program, "uMVPMatrix");
    BackgroundRenderer.checkGlError("glGetUniformLocation");

    GLES20.glUniformMatrix4fv(mvpMatrixHandle, 1, false, mvpMatrix, 0);
    BackgroundRenderer.checkGlError("glUniformMatrix4fv");

    GLES20.glDrawElements(GLES20.GL_TRIANGLES, drawOrder.length, GLES20.GL_UNSIGNED_SHORT, m_drawListBuffer);

    GLES20.glDisableVertexAttribArray(positionHandle);
}

不幸的是,我得到的只是

java.lang.RuntimeException: glGetUniformLocation: glError 1282

在这条线上加注

int mvpMatrixHandle = GLES20.glGetUniformLocation(m_program, "uMVPMatrix");

我应该如何更改我的代码?

【问题讨论】:

  • 一方面,检查 GLSL 编译/链接日志。如果是 raise GL_INVALID_OPERATION (0x0502
  • 这可能是一个很长的镜头,因为它已经很旧了,但我正在寻找你已经做过的同样的事情,我想知道你是否可以将你的最终代码抛出一个要点。我觉得有些东西不见了

标签: android opengl-es opengl-es-2.0 shader glsurfaceview


【解决方案1】:

这里有几个问题:

  1. 您从未检查过着色器编译日志,如果您检查过,您会发现片段着色器无法编译。
  2. 您只在一次调用后检查glGetError (...),因此您认为int mvpMatrixHandle = GLES20.glGetUniformLocation(m_program, "uMVPMatrix"); 是您的GL_INVALID_OPERATION 的来源,而实际上glUseProgram (...) 是您函数中触发它的第一行代码。

我已经更正了您的顶点和片段着色器,以便它们能够编译...您不能在片段着色器中使用gl_Position,这就是您的着色器无法编译并且您的程序没有链接的原因。

修改的顶点着色器:

uniform   mat4 uMVPMatrix;
attribute vec4 vPosition;
varying   vec4 vtx_pos;

void main()
{
    gl_Position = uMVPMatrix * vPosition;
    vtx_pos     = gl_Position;
}

修改片段着色器:

varying vec4  vtx_pos;
uniform float time; // Used for texture animation

float snoise(vec3 v) { 
  // ..
}

void main( void )
{
  vec3 v_texCoord3D = vtx_pos.xyz; 

  vec3 uvw = v_texCoord3D + 0.1*vec3(snoise(v_texCoord3D + vec3(0.0, 0.0, time)),
    snoise(v_texCoord3D + vec3(43.0, 17.0, time)),
    snoise(v_texCoord3D + vec3(-17.0, -43.0, time)));
  // Six components of noise in a fractal sum
  float n = snoise(uvw - vec3(0.0, 0.0, time));
  n += 0.5 * snoise(uvw * 2.0 - vec3(0.0, 0.0, time*1.4)); 
  n += 0.25 * snoise(uvw * 4.0 - vec3(0.0, 0.0, time*2.0)); 
  n += 0.125 * snoise(uvw * 8.0 - vec3(0.0, 0.0, time*2.8)); 
  n += 0.0625 * snoise(uvw * 16.0 - vec3(0.0, 0.0, time*4.0)); 
  n += 0.03125 * snoise(uvw * 32.0 - vec3(0.0, 0.0, time*5.6)); 
  n = n * 0.7;
  // A "hot" colormap - cheesy but effective 
  gl_FragColor = vec4(vec3(1.0, 0.5, 0.0) + vec3(n, n, n), 1.0);
}

【讨论】:

  • 感谢您的回答。它有很大帮助。另外,我将precision mediump float; 放入片段着色器中,因为着色器编译器抱怨ERROR: 0:25: 'vec3' : No precision defined for this type
猜你喜欢
  • 2017-09-26
  • 2013-05-21
  • 2020-04-17
  • 2014-02-15
  • 2020-06-06
  • 2011-09-20
  • 1970-01-01
  • 1970-01-01
  • 2021-06-30
相关资源
最近更新 更多