Java 在处理过程中更改聚光灯方向

Java 在处理过程中更改聚光灯方向,java,glsl,processing,shader,Java,Glsl,Processing,Shader,我尝试在场景顶部使用处理实现两个聚光灯,它们会随着时间的推移改变各自的方向。我尝试使用默认的聚光灯(r、g、b、x、y、z、nx、ny、nz、角度、浓度)方法创建聚光灯,并尝试更改nx、ny和nz变量以更改灯光方向。然而,该方法似乎没有考虑这3个变量。这是我正在使用的glsl precision mediump float; varying vec3 normalInterp; varying vec3 vertPos; uniform int lightCount; uniform v

我尝试在场景顶部使用
处理
实现两个聚光灯,它们会随着时间的推移改变各自的方向。我尝试使用默认的
聚光灯(r、g、b、x、y、z、nx、ny、nz、角度、浓度)
方法创建聚光灯,并尝试更改
nx
ny
nz
变量以更改灯光方向。然而,该方法似乎没有考虑这3个变量。这是我正在使用的glsl

precision mediump float;

varying vec3 normalInterp;
varying vec3 vertPos;



uniform int lightCount;
uniform vec4 lightPosition[8];
uniform vec3 lightNormal[8];


//ambient
const vec3 ambientColor = vec3(0.1, 0, 0);
//diffuse
const vec3 diffuseColor = vec3(0.5, 0.0, 0.0);
//specular
const vec3 specColor = vec3(1.0, 1.0, 1.0);
//specular reflection parameter
const float n = 30.0;
//Depth cueing
//not implemented

void main() {

  float lightR = 0.0;
  float lightG = 0.0;
  float lightB = 0.0;

  for (int i = 0; i < lightCount; i++)
  {
   vec3 normal = normalize(normalInterp);
   vec3 lightDir = normalize(lightPosition[i] - vertPos);

   //diffuse
   float diffuse = max(dot(lightDir,normal), 0.0);

   //specular
   float specular = 0.0;
   if(diffuse > 0.0) {
      vec3 viewDir = normalize(-vertPos);
      vec3 reflectDir = reflect(-lightDir, normal);
      float specAngle = max(dot(reflectDir, viewDir), 0.0);
      specular = pow(specAngle, n);
  }

  //Note: can add in depth cueing here
  vec3 colorLinear = ambientColor +
                     diffuse * diffuseColor +
                     specular * specColor;

  lightR += colorLinear.x;
  lightG += colorLinear.y;
  lightB += colorLinear.z;

  }

  gl_FragColor = vec4(lightR,lightG,lightB, 1.0);
}
precision mediump float;
可变vec3-normalInterp;
可变vec3垂直位置;
均匀整数光计数;
均匀vec4光位[8];
均匀vec3光法线[8];
//环境的
const vec3 ambientColor=vec3(0.1,0,0);
//漫
常数vec3 diffuseColor=vec3(0.5,0.0,0.0);
//镜面反射
常量vec3 specColor=vec3(1.0,1.0,1.0);
//镜面反射参数
常数浮点n=30.0;
//深度提示
//未实施
void main(){
浮子灯r=0.0;
浮点数g=0.0;
浮点数b=0.0;
对于(int i=0;i0.0){
vec3 viewDir=标准化(-vertPos);
vec3 reflectDir=反射(-lightDir,正常);
float specAngle=最大值(点(反射方向、视图方向),0.0);
镜面反射=功率(镜面反射角,n);
}
//注意:可以在此添加深度提示
vec3 colorLinear=环境颜色+
漫反射*漫反射颜色+
镜面反射*镜面反射颜色;
lightR+=colorLinear.x;
lightG+=彩色线性.y;
lightB+=colorLinear.z;
}
gl_FragColor=vec4(lightR,lightG,lightB,1.0);
}

着色器程序中有一个简单的问题。首先是打字错误。它必须是
lightPosition
而不是
lightPosition
。但这不是唯一的问题

lightPosition[i]
的类型是
vec4
vertPos
的类型是
vec3
。当从
lightPosition[i]
中减去
vertPos
时,会导致错误

您必须从
lightPosition[i]
构建
vec3

vec3 lightDir=normalize(lightposition[i]-vertPos)

vec3-lightDir=normalize(vec3(lightPosition[i])-vertPos);
或者您必须获得x、y和z分量表
lightPosition[i]
(请参阅):

vec3-lightDir=normalize(lightPosition[i].xyz-vertPos);
两种解决方案都会导致相同的结果


当然,灯光位置必须相对于对象进行设置。注意:调用时,灯光位置和方向由当前模型视图矩阵变换

请参见示例:

顶点着色器

uniformmat4模型视图;
一致mat4变换;
一致mat3正规矩阵;
属性向量4位置;
属性向量4颜色;
属性向量3正常;
可变vec3-normalInterp;
可变vec3垂直位置;
不同的颜色;
void main(){
gl_位置=变换*位置;
vertPos=vec3(模型视图*位置);
normalInterp=规格化(normalMatrix*normal);
}
片段着色器

precision mediump float;
可变vec3-normalInterp;
可变vec3垂直位置;
均匀整数光计数;
均匀vec4光位[8];
均匀vec3光法线[8];
均匀vec3光漫反射[8];
均匀vec3光反射[8];
均匀vec2光点[8];
const vec3 ambientColor=vec3(0.2);
常数vec3 diffuseColor=vec3(1.0);
常量vec3 specColor=vec3(1.0);
常数浮点n=30.0;
void main(){
vec3-lightColor=vec3(0.0,0.0,0.0);
对于(int i=0;i0.0){
vec3 viewDir=标准化(-vertPos);
vec3 reflectDir=反射(-lightDir,正常);
float specAngle=最大值(点(反射方向、视图方向),0.0);
浮动镜面反射=功率(镜面反射角,n);
lightColor+=镜面反射*镜面反射[i]*镜面反射颜色;
}
}
gl_FragColor=vec4(lightColor.rgb,1.0);
}
代码

PShader-lightShader;
无效设置(){
尺寸(800600,P3D);
lightShader=loadShader(“fragment.glsl”、“vertex.glsl”);
}
浮动ry=0.0;
作废提款(){
背景(0);
着色器(lightShader);
平移(宽度/2.0,高度/2.0);
聚光灯(255,0,0,0500500,0,-1,-1,PI/25,2);
聚光灯(0,0,255,500,0,500,-1,0,-1,PI/25,2);
rotateY(ry);
rotateX(-0.5);
ry+=0.02;
仰泳();
盒子(200);
}

对不起。它应该是lightPosition。当我复制代码时,我被遗漏了。这仍然不能解决glsl无法为聚光灯(r、g、b、x、y、z、nx、ny、nz、角度、浓度)接收nx、ny和nz变量的问题。@KelonEe你期望什么<代码>lightNormal
从未在着色器程序中使用。是。我尝试在中使用lightnormal,但它仍然不会改变灯光方向。问题的状态是什么?问题解决了吗?