Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Modify the lightingShader to allow per-vertex coloring #5938

Merged
merged 14 commits into from
Jan 9, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/webgl/p5.RendererGL.Immediate.js
Original file line number Diff line number Diff line change
Expand Up @@ -368,6 +368,7 @@ p5.RendererGL.prototype._tesselateShape = function() {
*/
p5.RendererGL.prototype._drawImmediateFill = function() {
const gl = this.GL;
this._useVertexColor = (this.immediateMode.geometry.vertexColors.length > 0);
const shader = this._getImmediateFillShader();

this._setFillUniforms(shader);
Expand Down
1 change: 1 addition & 0 deletions src/webgl/p5.RendererGL.Retained.js
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,7 @@ p5.RendererGL.prototype.drawBuffers = function(gId) {
}

if (this._doFill) {
this._useVertexColor = (geometry.model.vertexColors.length > 0);
const fillShader = this._getRetainedFillShader();
this._setFillUniforms(fillShader);
for (const buff of this.retainedMode.buffers.fill) {
Expand Down
2 changes: 2 additions & 0 deletions src/webgl/p5.RendererGL.js
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,7 @@ p5.RendererGL = function(elt, pInst, isMainCanvas, attr) {
this._useShininess = 1;

this._useLineColor = false;
this._useVertexColor = false;

this._tint = [255, 255, 255, 255];

Expand Down Expand Up @@ -1270,6 +1271,7 @@ p5.RendererGL.prototype._setFillUniforms = function(fillShader) {
fillShader.bindShader();

// TODO: optimize
fillShader.setUniform('uUseVertexColor', this._useVertexColor);
fillShader.setUniform('uMaterialColor', this.curFillColor);
fillShader.setUniform('isTexture', !!this._tex);
if (this._tex) {
Expand Down
4 changes: 2 additions & 2 deletions src/webgl/shaders/basic.frag
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
precision mediump float;
uniform vec4 uMaterialColor;
varying vec4 vColor;
void main(void) {
gl_FragColor = vec4(uMaterialColor.rgb, 1.) * uMaterialColor.a;
gl_FragColor = vec4(vColor.rgb, 1.) * vColor.a;
}
7 changes: 7 additions & 0 deletions src/webgl/shaders/light.vert
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,19 @@
attribute vec3 aPosition;
attribute vec3 aNormal;
attribute vec2 aTexCoord;
attribute vec4 aVertexColor;

uniform mat4 uModelViewMatrix;
uniform mat4 uProjectionMatrix;
uniform mat3 uNormalMatrix;

uniform bool uUseVertexColor;
uniform vec4 uMaterialColor;

varying highp vec2 vVertTexCoord;
varying vec3 vDiffuseColor;
varying vec3 vSpecularColor;
varying vec4 vColor;

void main(void) {

Expand All @@ -27,4 +32,6 @@ void main(void) {
vDiffuseColor += uAmbientColor[i];
}
}

vColor = (uUseVertexColor ? aVertexColor : uMaterialColor);
}
6 changes: 3 additions & 3 deletions src/webgl/shaders/light_texture.frag
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
precision highp float;

uniform vec4 uMaterialColor;
uniform vec4 uTint;
uniform sampler2D uSampler;
uniform bool isTexture;
Expand All @@ -9,13 +8,14 @@ uniform bool uEmissive;
varying highp vec2 vVertTexCoord;
varying vec3 vDiffuseColor;
varying vec3 vSpecularColor;
varying vec4 vColor;

void main(void) {
if(uEmissive && !isTexture) {
gl_FragColor = uMaterialColor;
gl_FragColor = vColor;
}
else {
vec4 baseColor = isTexture ? texture2D(uSampler, vVertTexCoord) * (uTint / vec4(255, 255, 255, 255)) : uMaterialColor;
vec4 baseColor = isTexture ? texture2D(uSampler, vVertTexCoord) * (uTint / vec4(255, 255, 255, 255)) : vColor;
gl_FragColor = vec4(gl_FragColor.rgb * vDiffuseColor + vSpecularColor, 1.) * baseColor.a;
}
}
6 changes: 6 additions & 0 deletions src/webgl/shaders/normal.vert
Original file line number Diff line number Diff line change
@@ -1,17 +1,23 @@
attribute vec3 aPosition;
attribute vec3 aNormal;
attribute vec2 aTexCoord;
attribute vec4 aVertexColor;

uniform mat4 uModelViewMatrix;
uniform mat4 uProjectionMatrix;
uniform mat3 uNormalMatrix;

uniform vec4 uMaterialColor;
uniform bool uUseVertexColor;

varying vec3 vVertexNormal;
varying highp vec2 vVertTexCoord;
varying vec4 vColor;

void main(void) {
vec4 positionVec4 = vec4(aPosition, 1.0);
gl_Position = uProjectionMatrix * uModelViewMatrix * positionVec4;
vVertexNormal = normalize(vec3( uNormalMatrix * aNormal ));
vVertTexCoord = aTexCoord;
vColor = (uUseVertexColor ? aVertexColor : uMaterialColor);
}
4 changes: 2 additions & 2 deletions src/webgl/shaders/phong.frag
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ uniform vec4 uSpecularMatColor;
uniform vec4 uAmbientMatColor;
uniform vec4 uEmissiveMatColor;

uniform vec4 uMaterialColor;
uniform vec4 uTint;
uniform sampler2D uSampler;
uniform bool isTexture;
Expand All @@ -15,6 +14,7 @@ varying vec3 vNormal;
varying vec2 vTexCoord;
varying vec3 vViewPosition;
varying vec3 vAmbientColor;
varying vec4 vColor;

void main(void) {

Expand All @@ -24,7 +24,7 @@ void main(void) {

// Calculating final color as result of all lights (plus emissive term).

vec4 baseColor = isTexture ? texture2D(uSampler, vTexCoord) * (uTint / vec4(255, 255, 255, 255)) : uMaterialColor;
vec4 baseColor = isTexture ? texture2D(uSampler, vTexCoord) * (uTint / vec4(255, 255, 255, 255)) : vColor;
gl_FragColor = vec4(diffuse * baseColor.rgb +
vAmbientColor * uAmbientMatColor.rgb +
specular * uSpecularMatColor.rgb +
Expand Down
7 changes: 7 additions & 0 deletions src/webgl/shaders/phong.vert
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ precision highp int;
attribute vec3 aPosition;
attribute vec3 aNormal;
attribute vec2 aTexCoord;
attribute vec4 aVertexColor;

uniform vec3 uAmbientColor[5];

Expand All @@ -12,10 +13,14 @@ uniform mat4 uProjectionMatrix;
uniform mat3 uNormalMatrix;
uniform int uAmbientLightCount;

uniform bool uUseVertexColor;
uniform vec4 uMaterialColor;

varying vec3 vNormal;
varying vec2 vTexCoord;
varying vec3 vViewPosition;
varying vec3 vAmbientColor;
varying vec4 vColor;

void main(void) {

Expand All @@ -35,4 +40,6 @@ void main(void) {
vAmbientColor += uAmbientColor[i];
}
}

vColor = (uUseVertexColor ? aVertexColor : uMaterialColor);
}
141 changes: 141 additions & 0 deletions test/unit/webgl/p5.RendererGL.js
Original file line number Diff line number Diff line change
Expand Up @@ -1109,6 +1109,147 @@ suite('p5.RendererGL', function() {
});
});

suite('interpolation of vertex colors', function(){
test('immediate mode uses vertex colors (noLight)', function(done) {
const renderer = myp5.createCanvas(256, 256, myp5.WEBGL);

// upper color: (200, 0, 0, 255);
// lower color: (0, 0, 200, 255);
// expected center color: (100, 0, 100, 255);

myp5.beginShape();
myp5.fill(200, 0, 0);
myp5.vertex(-128, -128);
myp5.fill(200, 0, 0);
myp5.vertex(128, -128);
myp5.fill(0, 0, 200);
myp5.vertex(128, 128);
myp5.fill(0, 0, 200);
myp5.vertex(-128, 128);
myp5.endShape(myp5.CLOSE);

assert.equal(renderer._useVertexColor, true);
assert.deepEqual(myp5.get(128, 128), [100, 0, 100, 255]);
done();
});

test('immediate mode uses vertex colors (light)', function(done) {
const renderer = myp5.createCanvas(256, 256, myp5.WEBGL);

myp5.directionalLight(255, 255, 255, 0, 0, -1);
// diffuseFactor:0.73
// so, expected color is (73, 0, 73, 255).

myp5.beginShape();
myp5.fill(200, 0, 0);
myp5.vertex(-128, -128);
myp5.fill(200, 0, 0);
myp5.vertex(128, -128);
myp5.fill(0, 0, 200);
myp5.vertex(128, 128);
myp5.fill(0, 0, 200);
myp5.vertex(-128, 128);
myp5.endShape(myp5.CLOSE);

assert.equal(renderer._useVertexColor, true);
assert.deepEqual(myp5.get(128, 128), [73, 0, 73, 255]);
done();
});

test('geom without vertex colors use curFillCol (noLight)', function(done) {
const renderer = myp5.createCanvas(256, 256, myp5.WEBGL);

// expected center color is curFillColor.

myp5.fill(200, 0, 200);
myp5.rectMode(myp5.CENTER);
myp5.rect(0, 0, myp5.width, myp5.height);

assert.equal(renderer._useVertexColor, false);
assert.deepEqual(myp5.get(128, 128), [200, 0, 200, 255]);
done();
});

test('geom without vertex colors use curFillCol (light)', function(done) {
const renderer = myp5.createCanvas(256, 256, myp5.WEBGL);

myp5.directionalLight(255, 255, 255, 0, 0, -1);
// diffuseFactor:0.73
// so, expected color is (146, 0, 146, 255).

myp5.fill(200, 0, 200);
myp5.rectMode(myp5.CENTER);
myp5.rect(0, 0, myp5.width, myp5.height);

assert.equal(renderer._useVertexColor, false);
assert.deepEqual(myp5.get(128, 128), [146, 0, 146, 255]);
done();
});

test('geom with vertex colors use their color (noLight)', function(done) {
const renderer = myp5.createCanvas(256, 256, myp5.WEBGL);

// upper color: (200, 0, 0, 255);
// lower color: (0, 0, 200, 255);
// expected center color: (100, 0, 100, 255);

const myGeom = new p5.Geometry(1, 1, function() {
this.gid = 'vertexColorTestWithNoLights';
this.vertices.push(myp5.createVector(-128, -128));
this.vertices.push(myp5.createVector(128, -128));
this.vertices.push(myp5.createVector(128, 128));
this.vertices.push(myp5.createVector(-128, 128));
this.faces.push([0, 1, 2]);
this.faces.push([0, 2, 3]);
this.vertexColors.push(
200/255, 0, 0, 1,
200/255, 0, 0, 1,
0, 0, 200/255, 1,
0, 0, 200/255, 1
);
this.computeNormals();
});

myp5.noStroke();
myp5.model(myGeom);

assert.equal(renderer._useVertexColor, true);
assert.deepEqual(myp5.get(128, 128), [100, 0, 100, 255]);
done();
});

test('geom with vertex colors use their color (light)', function(done) {
const renderer = myp5.createCanvas(256, 256, myp5.WEBGL);

const myGeom = new p5.Geometry(1, 1, function() {
this.gid = 'vertexColorTestWithLighs';
this.vertices.push(myp5.createVector(-128, -128));
this.vertices.push(myp5.createVector(128, -128));
this.vertices.push(myp5.createVector(128, 128));
this.vertices.push(myp5.createVector(-128, 128));
this.faces.push([0, 1, 2]);
this.faces.push([0, 2, 3]);
this.vertexColors.push(
200/255, 0, 0, 1,
200/255, 0, 0, 1,
0, 0, 200/255, 1,
0, 0, 200/255, 1
);
this.computeNormals();
});

myp5.directionalLight(255, 255, 255, 0, 0, -1);
// diffuseFactor:0.73
// so, expected color is (73, 0, 73, 255).
myp5.noStroke();
myp5.model(myGeom);

assert.equal(renderer._useVertexColor, true);
assert.deepEqual(myp5.get(128, 128), [73, 0, 73, 255]);
done();
});
});

suite('setAttributes', function() {
test('It leaves a reference to the correct canvas', function(done) {
const renderer = myp5.createCanvas(10, 10, myp5.WEBGL);
Expand Down