Skip to content

Commit

Permalink
Merge pull request #3820 from sanketsingh24/feature-emissive
Browse files Browse the repository at this point in the history
Feature implementation: emissiveMaterial()
  • Loading branch information
aferriss authored Jul 3, 2019
2 parents 39532e1 + bd8fa47 commit 23b7b18
Show file tree
Hide file tree
Showing 9 changed files with 145 additions and 6 deletions.
3 changes: 2 additions & 1 deletion developer_docs/webgl_mode_architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ Provides flat shading of objects, based on the current fill color.
#### Light Shader (for lighting AND textures)
Accounts for:
* Lighting parameters set by `ambientLight()`, `directionalLight()`, and `pointLight()`
* Material parameters set by `ambientMaterial()`, and `specularMaterial()`
* Material parameters set by `ambientMaterial()`, `emissiveMaterial()` and `specularMaterial()`
* Texture parameters, set by `texture()`

#### Normal Shader
Expand Down Expand Up @@ -133,6 +133,7 @@ The normal shader is set when `normalMaterial()` is in use. It uses the surface
|`uniform vec3 uPointLightLocation[8];`| |x | | | |
|`uniform vec3 uPointLightColor[8];` | |x | | | |
|`uniform bool uSpecular;` | |x | | | |
|`uniform bool uEmissive;` | |x | | | |
|`uniform int uShininess;` | |x | | | |
|`uniform bool uUseLighting;` | |x | | | |
|`uniform float uConstantAttenuation;` | |x | | | |
Expand Down
56 changes: 56 additions & 0 deletions src/webgl/material.js
Original file line number Diff line number Diff line change
Expand Up @@ -312,6 +312,7 @@ p5.prototype.normalMaterial = function() {
p5._validateParameters('normalMaterial', arguments);
this._renderer.drawMode = constants.FILL;
this._renderer._useSpecularMaterial = false;
this._renderer._useEmissiveMaterial = false;
this._renderer._useNormalMaterial = true;
this._renderer.curFillColor = [1, 1, 1, 1];
this._renderer._setProperty('_doFill', true);
Expand Down Expand Up @@ -412,6 +413,7 @@ p5.prototype.texture = function(tex) {

this._renderer.drawMode = constants.TEXTURE;
this._renderer._useSpecularMaterial = false;
this._renderer._useEmissiveMaterial = false;
this._renderer._useNormalMaterial = false;
this._renderer._tex = tex;
this._renderer._setProperty('_doFill', true);
Expand Down Expand Up @@ -616,6 +618,59 @@ p5.prototype.ambientMaterial = function(v1, v2, v3, a) {
var color = p5.prototype.color.apply(this, arguments);
this._renderer.curFillColor = color._array;
this._renderer._useSpecularMaterial = false;
this._renderer._useEmissiveMaterial = false;
this._renderer._useNormalMaterial = false;
this._renderer._enableLighting = true;
this._renderer._tex = null;

return this;
};

/**
* Sets the emissive color of the material used for geometry drawn to
* the screen. This is a misnomer in the sense that the material does not
* actually emit light that effects surrounding polygons. Instead,
* it gives the appearance that the object is glowing. An emissive material
* will display at full strength even if there is no light for it to reflect.
* @method emissiveMaterial
* @param {Number} v1 gray value, red or hue value
* (depending on the current color mode),
* @param {Number} [v2] green or saturation value
* @param {Number} [v3] blue or brightness value
* @param {Number} [a] opacity
* @chainable
* @example
* <div>
* <code>
* function setup() {
* createCanvas(100, 100, WEBGL);
* }
* function draw() {
* background(0);
* noStroke();
* ambientLight(0);
* emissiveMaterial(130, 230, 0);
* sphere(40);
* }
* </code>
* </div>
*
* @alt
* radiating light source from top right of canvas
*/
/**
* @method emissiveMaterial
* @param {Number[]|String|p5.Color} color color, color Array, or CSS color string
* @chainable
*/
p5.prototype.emissiveMaterial = function(v1, v2, v3, a) {
this._assert3d('emissiveMaterial');
p5._validateParameters('emissiveMaterial', arguments);

var color = p5.prototype.color.apply(this, arguments);
this._renderer.curFillColor = color._array;
this._renderer._useSpecularMaterial = false;
this._renderer._useEmissiveMaterial = true;
this._renderer._useNormalMaterial = false;
this._renderer._enableLighting = true;
this._renderer._tex = null;
Expand Down Expand Up @@ -667,6 +722,7 @@ p5.prototype.specularMaterial = function(v1, v2, v3, a) {
var color = p5.prototype.color.apply(this, arguments);
this._renderer.curFillColor = color._array;
this._renderer._useSpecularMaterial = true;
this._renderer._useEmissiveMaterial = false;
this._renderer._useNormalMaterial = false;
this._renderer._enableLighting = true;
this._renderer._tex = null;
Expand Down
3 changes: 3 additions & 0 deletions src/webgl/p5.RendererGL.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ p5.RendererGL = function(elt, pInst, isMainCanvas, attr) {
this.blendExt = this.GL.getExtension('EXT_blend_minmax');

this._useSpecularMaterial = false;
this._useEmissiveMaterial = false;
this._useNormalMaterial = false;
this._useShininess = 1;

Expand Down Expand Up @@ -901,6 +902,7 @@ p5.RendererGL.prototype.push = function() {
properties.curFillColor = this.curFillColor;

properties._useSpecularMaterial = this._useSpecularMaterial;
properties._useEmissiveMaterial = this._useEmissiveMaterial;
properties._useShininess = this._useShininess;

properties.constantAttenuation = this.constantAttenuation;
Expand Down Expand Up @@ -1139,6 +1141,7 @@ p5.RendererGL.prototype._setFillUniforms = function(fillShader) {
fillShader.setUniform('uTint', this._tint);

fillShader.setUniform('uSpecular', this._useSpecularMaterial);
fillShader.setUniform('uEmissive', this._useEmissiveMaterial);
fillShader.setUniform('uShininess', this._useShininess);

fillShader.setUniform('uUseLighting', this._enableLighting);
Expand Down
10 changes: 8 additions & 2 deletions src/webgl/shaders/light_texture.frag
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,18 @@ uniform vec4 uMaterialColor;
uniform vec4 uTint;
uniform sampler2D uSampler;
uniform bool isTexture;
uniform bool uEmissive;

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

void main(void) {
gl_FragColor = isTexture ? texture2D(uSampler, vVertTexCoord) * (uTint / vec4(255, 255, 255, 255)) : uMaterialColor;
gl_FragColor.rgb = gl_FragColor.rgb * vDiffuseColor + vSpecularColor;
if(uEmissive && !isTexture) {
gl_FragColor = uMaterialColor;
}
else {
gl_FragColor = isTexture ? texture2D(uSampler, vVertTexCoord) * (uTint / vec4(255, 255, 255, 255)) : uMaterialColor;
gl_FragColor.rgb = gl_FragColor.rgb * vDiffuseColor + vSpecularColor;
}
}
10 changes: 8 additions & 2 deletions src/webgl/shaders/phong.frag
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
uniform vec4 uMaterialColor;
uniform sampler2D uSampler;
uniform bool isTexture;
uniform bool uEmissive;

varying vec3 vNormal;
varying vec2 vTexCoord;
Expand All @@ -15,6 +16,11 @@ void main(void) {
vec3 specular;
totalLight(vViewPosition, normalize(vNormal), diffuse, specular);

gl_FragColor = isTexture ? texture2D(uSampler, vTexCoord) : uMaterialColor;
gl_FragColor.rgb = gl_FragColor.rgb * (diffuse + vAmbientColor) + specular;
if(uEmissive && !isTexture) {
gl_FragColor = uMaterialColor;
}
else {
gl_FragColor = isTexture ? texture2D(uSampler, vTexCoord) : uMaterialColor;
gl_FragColor.rgb = gl_FragColor.rgb * (diffuse + vAmbientColor) + specular;
}
}
17 changes: 17 additions & 0 deletions test/manual-test-examples/webgl/material/emissive/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<!DOCTYPE html>
<html>

<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title></title>
<link rel="stylesheet" href="../../../styles.css">
<script language="javascript" type="text/javascript" src="../../../../../lib/p5.js"></script>
<script language="javascript" type="text/javascript" src="sketch.js"></script>
<script src="../../stats.js"></script>
</head>

<body>
</body>

</html>
32 changes: 32 additions & 0 deletions test/manual-test-examples/webgl/material/emissive/sketch.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
function setup() {
createCanvas(windowWidth, windowHeight, WEBGL);
// setAttributes('perPixelLighting', true);
}

function draw() {
background(0);

var locY = mouseY - height / 2;
var locX = mouseX - width / 2;

ambientLight(100);
pointLight(200, 200, 200, locX, locY, 0);

translate(-200, 0, 0);
push();
ambientMaterial(250);
rotateZ(frameCount * 0.02);
rotateX(frameCount * 0.02);
rotateY(frameCount * 0.02);
torus(80, 20, 64, 64);
pop();

translate(400, 0, 0);
push();
emissiveMaterial(200, 0, 0);
rotateZ(frameCount * 0.02);
rotateX(frameCount * 0.02);
rotateY(frameCount * 0.02);
torus(81, 20, 64, 64);
pop();
}
3 changes: 2 additions & 1 deletion test/unit/core/rendering.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,8 @@ suite('Rendering', function() {
'ambientLight', 'directionalLight', 'pointLight', 'lights',
'model',
'createShader', 'shader',
'normalMaterial', 'texture', 'ambientMaterial', 'specularMaterial', 'shininess', 'lightFalloff',
'normalMaterial', 'texture', 'ambientMaterial', 'emissiveMaterial', 'specularMaterial',
'shininess', 'lightFalloff',
'plane', 'box', 'sphere', 'cylinder', 'cone', 'ellipsoid', 'torus',
];

Expand Down
17 changes: 17 additions & 0 deletions test/unit/webgl/p5.Shader.js
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ suite('p5.Shader', function() {
'uMaterialColor',
'uSampler',
'isTexture',
'uEmissive',
'uConstantAttenuation',
'uLinearAttenuation',
'uQuadraticAttenuation'
Expand Down Expand Up @@ -211,6 +212,22 @@ suite('p5.Shader', function() {
'after call to specularMaterial()'
);
});
test('Light shader set after emissiveMaterial()', function() {
var lightShader = myp5._renderer._getLightShader();
myp5.emissiveMaterial(128);
var selectedRetainedShader = myp5._renderer._getRetainedFillShader();
var selectedImmediateShader = myp5._renderer._getImmediateFillShader();
assert(
lightShader === selectedRetainedShader,
"_renderer's retain mode shader was not light shader " +
'after call to emissiveMaterial()'
);
assert(
lightShader === selectedImmediateShader,
"_renderer's immediate mode shader was not light shader " +
'after call to emissiveMaterial()'
);
});

test('Able to setUniform empty arrays', function() {
myp5.shader(myp5._renderer._getLightShader());
Expand Down

0 comments on commit 23b7b18

Please sign in to comment.