java - 使用处理实现用于聚光的 GLSL 着色器

标签 java opengl glsl processing

我目前的情况是将 Gouraud 和 Phong 简单着色器与点光源结合使用。但是,相反,我想介绍多个 SPOTLIGHT 来源。但我不确定应该对新的碎片和顶点着色器进行哪些更改。

这是我当前的 GLSL 程序:

片段.glsl

#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif

varying vec4 col;

void main() {
  gl_FragColor = col;
}

顶点.glsl

#define PROCESSING_LIGHT_SHADER

uniform mat4 modelview;
uniform mat4 transform;
uniform mat3 normalMatrix;

uniform vec4 lightPosition;

attribute vec4 vertex;
attribute vec4 color;
attribute vec3 normal;

varying vec4 col;

void main(){

  gl_Position = transform*vertex;
  vec3 vertexCamera = vec3(modelview * vertex);

  vec3 transformedNormal = normalize(normalMatrix * normal);
  vec3 dir = normalize(lightPosition.xyz - vertexCamera);

  float light = max(0.0, dot(dir, transformedNormal));
  col = vec4(light, light, light, 1)*color;
} 

最佳答案

在处理过程中,您最多可以使用 8 个光源。要访问光源,您必须声明 Uniform具有数组类型,如 Processing Light shaders tutorial 中所述:

uniform vec4 lightPosition[8];

在应用程序中设置多个光源(如2个):

pointLight(255, 255, 255, width/2, height, 200);
pointLight(255, 255, 255, width, height/2, 200);

迭代 (2) 个光源并对着色器程序中的光求和。例如:

void main() {
    gl_Position = transform * position;
    vec3 ecPosition = vec3(modelview * position);
    vec3 ecNormal = normalize(normalMatrix * normal);

    vertColor = vec4(0.0);
    for (int i=0; i < 2; ++i)
    {
        vec3 direction = normalize(lightPosition[i].xyz - ecPosition);
        float intensity = max(0.0, dot(direction, ecNormal)); 
        vertColor += vec4(intensity, intensity, intensity, 1) * color;
    }
}
<小时/>

绿色和红色点光源的示例:

应用程序

PShape can;
float angle;

PShader lightShader;

void setup() {
  size(640, 360, P3D);
  can = createCan(100, 200, 32);
  lightShader = loadShader("lightfrag.glsl", "lightvert.glsl");
}

void draw() {
  background(0);

  shader(lightShader);

  pointLight(0, 255, 0, width/2, height, 200);
  pointLight(255, 0, 0, width, height/2, 200);

  translate(width/2, height/2);
  rotateY(angle);
  shape(can);
  angle += 0.01;
}

PShape createCan(float r, float h, int detail) {
  textureMode(NORMAL);
  PShape sh = createShape();
  sh.beginShape(QUAD_STRIP);
  sh.noStroke();
  for (int i = 0; i <= detail; i++) {
    float angle = TWO_PI / detail;
    float x = sin(i * angle);
    float z = cos(i * angle);
    float u = float(i) / detail;
    sh.normal(x, 0, z);
    sh.vertex(x * r, -h/2, z * r, u, 0);
    sh.vertex(x * r, +h/2, z * r, u, 1);
  }
  sh.endShape();
  return sh;
}

顶点着色器

uniform mat4 modelview;
uniform mat4 transform;
uniform mat3 normalMatrix;

uniform vec4 lightPosition[8];
uniform vec3 lightDiffuse[8];

attribute vec4 position;
attribute vec4 color;
attribute vec3 normal;

varying vec4 vertColor;

void main() {
    gl_Position = transform * position;
    vec3 ecPosition = vec3(modelview * position);
    vec3 ecNormal = normalize(normalMatrix * normal);

    vertColor = vec4(0.0);
    for (int i=0; i < 2; ++i)
    {
        vec3 direction = normalize(lightPosition[i].xyz - ecPosition);
        float intensity = max(0.0, dot(direction, ecNormal));
        vertColor += vec4(intensity * lightDiffuse[i], 1.0) * color;
    }
}

片段着色器

#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif

varying vec4 vertColor;

void main() {
    gl_FragColor = vertColor;
}

关于java - 使用处理实现用于聚光的 GLSL 着色器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59426737/

相关文章:

java - 尝试使用 jogl 加载并初始化着色器

c++ - 延迟渲染的特殊情况

glsl - webGL 中的平面着色

c - opengl 不显示 renderFunction 的输出

java - 在动画背景中更改按钮背景?

java - 为什么不推荐使用 (javax.servlet.)SingleThreadModel?

java - 将 JPA 与 Hibernate 实现一起使用 : entityManager. 删除 - 不工作

c++ - 如何只使用一次 gluPerspective?

opengl-es - 你可以用 GLSL ES 中的整数做什么?

java - Java 中的可嵌入分布式版本控制系统?