Skip to content

Commit 420bac4

Browse files
committed
Make metalness be editable too
1 parent 22addb5 commit 420bac4

File tree

4 files changed

+66
-24
lines changed

4 files changed

+66
-24
lines changed

src/webgl/material.js

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -904,7 +904,8 @@ p5.prototype.shader = function (s) {
904904
* - `vec3 ambientMaterial`, the color of the pixel when affected by ambient light
905905
* - `vec3 specularMaterial`, the color of the pixel when reflecting specular highlights
906906
* - `vec3 emissiveMaterial`, the light color emitted by the pixel
907-
* - `float shininess`, a number representing how sharp specular reflections should be
907+
* - `float shininess`, a number representing how sharp specular reflections should be, from 1 to infinity
908+
* - `float metalness`, a number representing how mirrorlike the material should be, between 0 and 1
908909
The struct can be modified and returned.
909910
* - `vec4 combineColors`: Take in a `ColorComponents` struct containing all the different components of light, and combining them into
910911
* a single final color. The struct contains:
@@ -995,6 +996,46 @@ p5.prototype.shader = function (s) {
995996
* <div modernizr='webgl'>
996997
* <code>
997998
* let myShader;
999+
* let environment;
1000+
*
1001+
* function preload() {
1002+
* environment = loadImage('assets/outdoor_spheremap.jpg');
1003+
* }
1004+
*
1005+
* function setup() {
1006+
* createCanvas(200, 200, WEBGL);
1007+
* myShader = materialShader().modify({
1008+
* 'Inputs getPixelInputs': `(Inputs inputs) {
1009+
* float factor =
1010+
* sin(
1011+
* inputs.texCoord.x * ${TWO_PI} +
1012+
* inputs.texCoord.y * ${TWO_PI}
1013+
* ) * 0.4 + 0.5;
1014+
* inputs.shininess = mix(1., 100., factor);
1015+
* inputs.metalness = factor;
1016+
* return inputs;
1017+
* }`
1018+
* });
1019+
* }
1020+
*
1021+
* function draw() {
1022+
* panorama(environment);
1023+
* ambientLight(100);
1024+
* imageLight(environment);
1025+
* rotateY(millis() * 0.001);
1026+
* shader(myShader);
1027+
* noStroke();
1028+
* fill(255);
1029+
* specularMaterial(150);
1030+
* sphere(50);
1031+
* }
1032+
* </code>
1033+
* </div>
1034+
*
1035+
* @example
1036+
* <div modernizr='webgl'>
1037+
* <code>
1038+
* let myShader;
9981039
*
9991040
* function setup() {
10001041
* createCanvas(200, 200, WEBGL);

src/webgl/p5.RendererGL.js

Lines changed: 3 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1727,7 +1727,7 @@ p5.RendererGL = class RendererGL extends p5.Renderer {
17271727
sphereMapping
17281728
);
17291729
}
1730-
this.uNMatrix.inverseTranspose(this.uMVMatrix);
1730+
this.uNMatrix.inverseTranspose(this.uViewMatrix);
17311731
this.uNMatrix.invert3x3(this.uNMatrix);
17321732
this.sphereMapping.setUniform('uFovY', this._curCamera.cameraFOV);
17331733
this.sphereMapping.setUniform('uAspect', this._curCamera.aspectRatio);
@@ -2246,7 +2246,7 @@ p5.RendererGL = class RendererGL extends p5.Renderer {
22462246
fillShader.setUniform('uSpecular', this._useSpecularMaterial);
22472247
fillShader.setUniform('uEmissive', this._useEmissiveMaterial);
22482248
fillShader.setUniform('uShininess', this._useShininess);
2249-
fillShader.setUniform('metallic', this._useMetalness);
2249+
fillShader.setUniform('uMetallic', this._useMetalness);
22502250

22512251
this._setImageLightUniforms(fillShader);
22522252

@@ -2319,14 +2319,7 @@ p5.RendererGL = class RendererGL extends p5.Renderer {
23192319
let diffusedLight = this.getDiffusedTexture(this.activeImageLight);
23202320
shader.setUniform('environmentMapDiffused', diffusedLight);
23212321
let specularLight = this.getSpecularTexture(this.activeImageLight);
2322-
// In p5js the range of shininess is >= 1,
2323-
// Therefore roughness range will be ([0,1]*8)*20 or [0, 160]
2324-
// The factor of 8 is because currently the getSpecularTexture
2325-
// only calculated 8 different levels of roughness
2326-
// The factor of 20 is just to spread up this range so that,
2327-
// [1, max] of shininess is converted to [0,160] of roughness
2328-
let roughness = 20 / this._useShininess;
2329-
shader.setUniform('levelOfDetail', roughness * 8);
2322+
23302323
shader.setUniform('environmentMapSpecular', specularLight);
23312324
}
23322325
}

src/webgl/shaders/lighting.glsl

Lines changed: 18 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ uniform vec3 uSpotLightDirection[5];
3030

3131
uniform bool uSpecular;
3232
uniform float uShininess;
33-
uniform float metallic;
33+
uniform float uMetallic;
3434

3535
uniform float uConstantAttenuation;
3636
uniform float uLinearAttenuation;
@@ -43,8 +43,6 @@ uniform bool uUseImageLight;
4343
uniform sampler2D environmentMapDiffused;
4444
// texture for use in calculateImageSpecular
4545
uniform sampler2D environmentMapSpecular;
46-
// roughness for use in calculateImageSpecular
47-
uniform float levelOfDetail;
4846

4947
const float specularFactor = 2.0;
5048
const float diffuseFactor = 0.73;
@@ -68,7 +66,7 @@ float _lambertDiffuse(vec3 lightDirection, vec3 surfaceNormal) {
6866
return max(0.0, dot(-lightDirection, surfaceNormal));
6967
}
7068

71-
LightResult _light(vec3 viewDirection, vec3 normal, vec3 lightVector, float shininess) {
69+
LightResult _light(vec3 viewDirection, vec3 normal, vec3 lightVector, float shininess, float metallic) {
7270

7371
vec3 lightDir = normalize(lightVector);
7472

@@ -109,7 +107,7 @@ vec2 mapTextureToNormal( vec3 v ){
109107
}
110108

111109

112-
vec3 calculateImageDiffuse( vec3 vNormal, vec3 vViewPosition ){
110+
vec3 calculateImageDiffuse(vec3 vNormal, vec3 vViewPosition, float metallic){
113111
// make 2 seperate builds
114112
vec3 worldCameraPosition = vec3(0.0, 0.0, 0.0); // hardcoded world camera position
115113
vec3 worldNormal = normalize(vNormal * uCameraRotation);
@@ -120,14 +118,21 @@ vec3 calculateImageDiffuse( vec3 vNormal, vec3 vViewPosition ){
120118
return mix(smoothstep(vec3(0.0), vec3(1.0), texture.xyz), vec3(0.0), metallic);
121119
}
122120

123-
vec3 calculateImageSpecular( vec3 vNormal, vec3 vViewPosition ){
121+
vec3 calculateImageSpecular(vec3 vNormal, vec3 vViewPosition, float shininess, float metallic){
124122
vec3 worldCameraPosition = vec3(0.0, 0.0, 0.0);
125123
vec3 worldNormal = normalize(vNormal);
126124
vec3 lightDirection = normalize( vViewPosition - worldCameraPosition );
127125
vec3 R = reflect(lightDirection, worldNormal) * uCameraRotation;
128126
vec2 newTexCoor = mapTextureToNormal( R );
129127
#ifdef WEBGL2
130-
vec4 outColor = textureLod(environmentMapSpecular, newTexCoor, levelOfDetail);
128+
// In p5js the range of shininess is >= 1,
129+
// Therefore roughness range will be ([0,1]*8)*20 or [0, 160]
130+
// The factor of 8 is because currently the getSpecularTexture
131+
// only calculated 8 different levels of roughness
132+
// The factor of 20 is just to spread up this range so that,
133+
// [1, max] of shininess is converted to [0,160] of roughness
134+
float roughness = 20. / shininess;
135+
vec4 outColor = textureLod(environmentMapSpecular, newTexCoor, roughness * 8.);
131136
#else
132137
vec4 outColor = TEXTURE(environmentMapSpecular, newTexCoor);
133138
#endif
@@ -144,6 +149,7 @@ void totalLight(
144149
vec3 modelPosition,
145150
vec3 normal,
146151
float shininess,
152+
float metallic,
147153
out vec3 totalDiffuse,
148154
out vec3 totalSpecular
149155
) {
@@ -164,7 +170,7 @@ void totalLight(
164170
vec3 lightVector = (uViewMatrix * vec4(uLightingDirection[j], 0.0)).xyz;
165171
vec3 lightColor = uDirectionalDiffuseColors[j];
166172
vec3 specularColor = uDirectionalSpecularColors[j];
167-
LightResult result = _light(viewDirection, normal, lightVector, shininess);
173+
LightResult result = _light(viewDirection, normal, lightVector, shininess, metallic);
168174
totalDiffuse += result.diffuse * lightColor;
169175
totalSpecular += result.specular * lightColor * specularColor;
170176
}
@@ -178,7 +184,7 @@ void totalLight(
178184
vec3 lightColor = lightFalloff * uPointLightDiffuseColors[j];
179185
vec3 specularColor = lightFalloff * uPointLightSpecularColors[j];
180186

181-
LightResult result = _light(viewDirection, normal, lightVector, shininess);
187+
LightResult result = _light(viewDirection, normal, lightVector, shininess, metallic);
182188
totalDiffuse += result.diffuse * lightColor;
183189
totalSpecular += result.specular * lightColor * specularColor;
184190
}
@@ -204,16 +210,16 @@ void totalLight(
204210
vec3 lightColor = uSpotLightDiffuseColors[j];
205211
vec3 specularColor = uSpotLightSpecularColors[j];
206212

207-
LightResult result = _light(viewDirection, normal, lightVector, shininess);
213+
LightResult result = _light(viewDirection, normal, lightVector, shininess, metallic);
208214

209215
totalDiffuse += result.diffuse * lightColor * lightFalloff;
210216
totalSpecular += result.specular * lightColor * specularColor * lightFalloff;
211217
}
212218
}
213219

214220
if( uUseImageLight ){
215-
totalDiffuse += calculateImageDiffuse(normal, modelPosition);
216-
totalSpecular += calculateImageSpecular(normal, modelPosition);
221+
totalDiffuse += calculateImageDiffuse(normal, modelPosition, metallic);
222+
totalSpecular += calculateImageSpecular(normal, modelPosition, shininess, metallic);
217223
}
218224

219225
totalDiffuse *= diffuseFactor;

src/webgl/shaders/phong.frag

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@ struct Inputs {
3636
vec3 emissiveMaterial;
3737
vec4 color;
3838
float shininess;
39+
float metalness;
3940
};
4041

4142
void main(void) {
@@ -54,14 +55,15 @@ void main(void) {
5455
// channels by alpha to convert it to premultiplied alpha.
5556
: vec4(vColor.rgb * vColor.a, vColor.a);
5657
inputs.shininess = uShininess;
58+
inputs.metalness = uMetallic;
5759
inputs.ambientMaterial = uHasSetAmbient ? uAmbientMatColor.rgb : inputs.color.rgb;
5860
inputs.specularMaterial = uSpecularMatColor.rgb;
5961
inputs.emissiveMaterial = uEmissiveMatColor.rgb;
6062
inputs = HOOK_getPixelInputs(inputs);
6163

6264
vec3 diffuse;
6365
vec3 specular;
64-
totalLight(vViewPosition, inputs.normal, inputs.shininess, diffuse, specular);
66+
totalLight(vViewPosition, inputs.normal, inputs.shininess, inputs.metalness, diffuse, specular);
6567

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

0 commit comments

Comments
 (0)