Skip to content

Commit

Permalink
Increase the maximum number of lights to 4 for Mesa vc4
Browse files Browse the repository at this point in the history
Testing on the latest Raspbian release shows that the open-source Mesa driver can handle 4 lights on all P3D examples without tripping up during register allocation. Still an issue with 8 lights, so leave it at 4 for now, and re-test with 6 next time around.
  • Loading branch information
gohai committed Mar 16, 2018
1 parent 6750501 commit 5af7a59
Show file tree
Hide file tree
Showing 5 changed files with 324 additions and 6 deletions.
8 changes: 6 additions & 2 deletions core/src/processing/opengl/PGraphicsOpenGL.java
Original file line number Diff line number Diff line change
Expand Up @@ -6895,8 +6895,12 @@ protected void getGLParameters() {

// overwrite the default shaders with vendor specific versions
// if needed
if (OPENGL_RENDERER.equals("VideoCore IV HW") || // Broadcom's binary driver for Raspberry Pi
OPENGL_RENDERER.contains("VC4")) { // Mesa driver for same hardware
if (OPENGL_RENDERER.equals("VideoCore IV HW")) { // Broadcom's binary driver for Raspberry Pi
defLightShaderVertURL =
PGraphicsOpenGL.class.getResource("/processing/opengl/shaders/LightVert-brcm.glsl");
defTexlightShaderVertURL =
PGraphicsOpenGL.class.getResource("/processing/opengl/shaders/TexLightVert-brcm.glsl");
} else if (OPENGL_RENDERER.contains("VC4")) { // Mesa driver for same hardware
defLightShaderVertURL =
PGraphicsOpenGL.class.getResource("/processing/opengl/shaders/LightVert-vc4.glsl");
defTexlightShaderVertURL =
Expand Down
154 changes: 154 additions & 0 deletions core/src/processing/opengl/shaders/LightVert-brcm.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
/*
Part of the Processing project - http://processing.org
Copyright (c) 2012-15 The Processing Foundation
Copyright (c) 2004-12 Ben Fry and Casey Reas
Copyright (c) 2001-04 Massachusetts Institute of Technology
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation, version 2.1.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
*/

uniform mat4 modelviewMatrix;
uniform mat4 transformMatrix;
uniform mat3 normalMatrix;

uniform int lightCount;
uniform vec4 lightPosition[8];
uniform vec3 lightNormal[8];
uniform vec3 lightAmbient[8];
uniform vec3 lightDiffuse[8];
uniform vec3 lightSpecular[8];
uniform vec3 lightFalloff[8];
uniform vec2 lightSpot[8];

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

attribute vec4 ambient;
attribute vec4 specular;
attribute vec4 emissive;
attribute float shininess;

varying vec4 vertColor;
varying vec4 backVertColor;

const float zero_float = 0.0;
const float one_float = 1.0;
const vec3 zero_vec3 = vec3(0.0);
const vec3 minus_one_vec3 = vec3(0.0-1.0);

float falloffFactor(vec3 lightPos, vec3 vertPos, vec3 coeff) {
vec3 lpv = lightPos - vertPos;
vec3 dist = vec3(one_float);
dist.z = dot(lpv, lpv);
dist.y = sqrt(dist.z);
return one_float / dot(dist, coeff);
}

float spotFactor(vec3 lightPos, vec3 vertPos, vec3 lightNorm, float minCos, float spotExp) {
vec3 lpv = normalize(lightPos - vertPos);
vec3 nln = minus_one_vec3 * lightNorm;
float spotCos = dot(nln, lpv);
return spotCos <= minCos ? zero_float : pow(spotCos, spotExp);
}

float lambertFactor(vec3 lightDir, vec3 vecNormal) {
return max(zero_float, dot(lightDir, vecNormal));
}

float blinnPhongFactor(vec3 lightDir, vec3 vertPos, vec3 vecNormal, float shine) {
vec3 np = normalize(vertPos);
vec3 ldp = normalize(lightDir - np);
return pow(max(zero_float, dot(ldp, vecNormal)), shine);
}

void main() {
// Vertex in clip coordinates
gl_Position = transformMatrix * position;

// Vertex in eye coordinates
vec3 ecVertex = vec3(modelviewMatrix * position);

// Normal vector in eye coordinates
vec3 ecNormal = normalize(normalMatrix * normal);
vec3 ecNormalInv = ecNormal * minus_one_vec3;

// Light calculations
vec3 totalAmbient = vec3(0, 0, 0);

vec3 totalFrontDiffuse = vec3(0, 0, 0);
vec3 totalFrontSpecular = vec3(0, 0, 0);

vec3 totalBackDiffuse = vec3(0, 0, 0);
vec3 totalBackSpecular = vec3(0, 0, 0);

// prevent register allocation failure by limiting ourselves to
// two lights for now
for (int i = 0; i < 2; i++) {
if (lightCount == i) break;

vec3 lightPos = lightPosition[i].xyz;
bool isDir = lightPosition[i].w < one_float;
float spotCos = lightSpot[i].x;
float spotExp = lightSpot[i].y;

vec3 lightDir;
float falloff;
float spotf;

if (isDir) {
falloff = one_float;
lightDir = minus_one_vec3 * lightNormal[i];
} else {
falloff = falloffFactor(lightPos, ecVertex, lightFalloff[i]);
lightDir = normalize(lightPos - ecVertex);
}

spotf = spotExp > zero_float ? spotFactor(lightPos, ecVertex, lightNormal[i],
spotCos, spotExp)
: one_float;

if (any(greaterThan(lightAmbient[i], zero_vec3))) {
totalAmbient += lightAmbient[i] * falloff;
}

if (any(greaterThan(lightDiffuse[i], zero_vec3))) {
totalFrontDiffuse += lightDiffuse[i] * falloff * spotf *
lambertFactor(lightDir, ecNormal);
totalBackDiffuse += lightDiffuse[i] * falloff * spotf *
lambertFactor(lightDir, ecNormalInv);
}

if (any(greaterThan(lightSpecular[i], zero_vec3))) {
totalFrontSpecular += lightSpecular[i] * falloff * spotf *
blinnPhongFactor(lightDir, ecVertex, ecNormal, shininess);
totalBackSpecular += lightSpecular[i] * falloff * spotf *
blinnPhongFactor(lightDir, ecVertex, ecNormalInv, shininess);
}
}

// Calculating final color as result of all lights (plus emissive term).
// Transparency is determined exclusively by the diffuse component.
vertColor = vec4(totalAmbient, 0) * ambient +
vec4(totalFrontDiffuse, 1) * color +
vec4(totalFrontSpecular, 0) * specular +
vec4(emissive.rgb, 0);

backVertColor = vec4(totalAmbient, 0) * ambient +
vec4(totalBackDiffuse, 1) * color +
vec4(totalBackSpecular, 0) * specular +
vec4(emissive.rgb, 0);
}
4 changes: 2 additions & 2 deletions core/src/processing/opengl/shaders/LightVert-vc4.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@ void main() {
vec3 totalBackSpecular = vec3(0, 0, 0);

// prevent register allocation failure by limiting ourselves to
// two lights for now
for (int i = 0; i < 2; i++) {
// four lights for now
for (int i = 0; i < 4; i++) {
if (lightCount == i) break;

vec3 lightPos = lightPosition[i].xyz;
Expand Down
160 changes: 160 additions & 0 deletions core/src/processing/opengl/shaders/TexLightVert-brcm.glsl
Original file line number Diff line number Diff line change
@@ -0,0 +1,160 @@
/*
Part of the Processing project - http://processing.org
Copyright (c) 2012-15 The Processing Foundation
Copyright (c) 2004-12 Ben Fry and Casey Reas
Copyright (c) 2001-04 Massachusetts Institute of Technology
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation, version 2.1.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General
Public License along with this library; if not, write to the
Free Software Foundation, Inc., 59 Temple Place, Suite 330,
Boston, MA 02111-1307 USA
*/

uniform mat4 modelviewMatrix;
uniform mat4 transformMatrix;
uniform mat3 normalMatrix;
uniform mat4 texMatrix;

uniform int lightCount;
uniform vec4 lightPosition[8];
uniform vec3 lightNormal[8];
uniform vec3 lightAmbient[8];
uniform vec3 lightDiffuse[8];
uniform vec3 lightSpecular[8];
uniform vec3 lightFalloff[8];
uniform vec2 lightSpot[8];

attribute vec4 position;
attribute vec4 color;
attribute vec3 normal;
attribute vec2 texCoord;

attribute vec4 ambient;
attribute vec4 specular;
attribute vec4 emissive;
attribute float shininess;

varying vec4 vertColor;
varying vec4 backVertColor;
varying vec4 vertTexCoord;

const float zero_float = 0.0;
const float one_float = 1.0;
const vec3 zero_vec3 = vec3(0.0);
const vec3 minus_one_vec3 = vec3(0.0-1.0);

float falloffFactor(vec3 lightPos, vec3 vertPos, vec3 coeff) {
vec3 lpv = lightPos - vertPos;
vec3 dist = vec3(one_float);
dist.z = dot(lpv, lpv);
dist.y = sqrt(dist.z);
return one_float / dot(dist, coeff);
}

float spotFactor(vec3 lightPos, vec3 vertPos, vec3 lightNorm, float minCos, float spotExp) {
vec3 lpv = normalize(lightPos - vertPos);
vec3 nln = minus_one_vec3 * lightNorm;
float spotCos = dot(nln, lpv);
return spotCos <= minCos ? zero_float : pow(spotCos, spotExp);
}

float lambertFactor(vec3 lightDir, vec3 vecNormal) {
return max(zero_float, dot(lightDir, vecNormal));
}

float blinnPhongFactor(vec3 lightDir, vec3 vertPos, vec3 vecNormal, float shine) {
vec3 np = normalize(vertPos);
vec3 ldp = normalize(lightDir - np);
return pow(max(zero_float, dot(ldp, vecNormal)), shine);
}

void main() {
// Vertex in clip coordinates
gl_Position = transformMatrix * position;

// Vertex in eye coordinates
vec3 ecVertex = vec3(modelviewMatrix * position);

// Normal vector in eye coordinates
vec3 ecNormal = normalize(normalMatrix * normal);
vec3 ecNormalInv = ecNormal * minus_one_vec3;

// Light calculations
vec3 totalAmbient = vec3(0, 0, 0);

vec3 totalFrontDiffuse = vec3(0, 0, 0);
vec3 totalFrontSpecular = vec3(0, 0, 0);

vec3 totalBackDiffuse = vec3(0, 0, 0);
vec3 totalBackSpecular = vec3(0, 0, 0);

// prevent register allocation failure by limiting ourselves to
// two lights for now
for (int i = 0; i < 2; i++) {
if (lightCount == i) break;

vec3 lightPos = lightPosition[i].xyz;
bool isDir = lightPosition[i].w < one_float;
float spotCos = lightSpot[i].x;
float spotExp = lightSpot[i].y;

vec3 lightDir;
float falloff;
float spotf;

if (isDir) {
falloff = one_float;
lightDir = minus_one_vec3 * lightNormal[i];
} else {
falloff = falloffFactor(lightPos, ecVertex, lightFalloff[i]);
lightDir = normalize(lightPos - ecVertex);
}

spotf = spotExp > zero_float ? spotFactor(lightPos, ecVertex, lightNormal[i],
spotCos, spotExp)
: one_float;

if (any(greaterThan(lightAmbient[i], zero_vec3))) {
totalAmbient += lightAmbient[i] * falloff;
}

if (any(greaterThan(lightDiffuse[i], zero_vec3))) {
totalFrontDiffuse += lightDiffuse[i] * falloff * spotf *
lambertFactor(lightDir, ecNormal);
totalBackDiffuse += lightDiffuse[i] * falloff * spotf *
lambertFactor(lightDir, ecNormalInv);
}

if (any(greaterThan(lightSpecular[i], zero_vec3))) {
totalFrontSpecular += lightSpecular[i] * falloff * spotf *
blinnPhongFactor(lightDir, ecVertex, ecNormal, shininess);
totalBackSpecular += lightSpecular[i] * falloff * spotf *
blinnPhongFactor(lightDir, ecVertex, ecNormalInv, shininess);
}
}

// Calculating final color as result of all lights (plus emissive term).
// Transparency is determined exclusively by the diffuse component.
vertColor = vec4(totalAmbient, 0) * ambient +
vec4(totalFrontDiffuse, 1) * color +
vec4(totalFrontSpecular, 0) * specular +
vec4(emissive.rgb, 0);

backVertColor = vec4(totalAmbient, 0) * ambient +
vec4(totalBackDiffuse, 1) * color +
vec4(totalBackSpecular, 0) * specular +
vec4(emissive.rgb, 0);

// Calculating texture coordinates, with r and q set both to one
vertTexCoord = texMatrix * vec4(texCoord, 1.0, 1.0);
}
4 changes: 2 additions & 2 deletions core/src/processing/opengl/shaders/TexLightVert-vc4.glsl
Original file line number Diff line number Diff line change
Expand Up @@ -99,8 +99,8 @@ void main() {
vec3 totalBackSpecular = vec3(0, 0, 0);

// prevent register allocation failure by limiting ourselves to
// two lights for now
for (int i = 0; i < 2; i++) {
// four lights for now
for (int i = 0; i < 4; i++) {
if (lightCount == i) break;

vec3 lightPos = lightPosition[i].xyz;
Expand Down

0 comments on commit 5af7a59

Please sign in to comment.