let properFrameCount = 0;
"precision mediump float;" +
"precision mediump int;" +
"uniform mat4 uViewMatrix;" +
"uniform bool uUseLighting;" +
"uniform int uAmbientLightCount;" +
"uniform vec3 uAmbientColor[5];" +
"uniform int uDirectionalLightCount;" +
"uniform vec3 uLightingDirection[5];" +
"uniform vec3 uDirectionalDiffuseColors[5];" +
"uniform vec3 uDirectionalSpecularColors[5];" +
"const float specularFactor = 2.0;" +
"const float diffuseFactor = 0.73;" +
"float _lambertDiffuse(vec3 lightDirection, vec3 surfaceNormal){" +
" return max(0.0, dot(-lightDirection, surfaceNormal));" +
"LightResult _light(vec3 viewDirection, vec3 normal, vec3 lightVector){" +
" vec3 lightDir = normalize(lightVector);" +
" lr.diffuse = _lambertDiffuse(lightDir, normal);" +
"void totalLight(vec3 modelPosition, vec3 normal, out vec3 totalDiffuse, out vec3 totalSpecular){" +
" totalSpecular = vec3(0.0);" +
" totalDiffuse = vec3(1.0);" +
" totalDiffuse = vec3(0.0);" +
" vec3 viewDirection = normalize(-modelPosition);" +
" for(int j = 0; j < 5; j++){" +
" if(j < uDirectionalLightCount){" +
" vec3 lightVector = (uViewMatrix * vec4(uLightingDirection[j], 0.0)).xyz;" +
" vec3 lightColor = uDirectionalDiffuseColors[j];" +
" vec3 specularColor = uDirectionalSpecularColors[j];" +
" LightResult result = _light(viewDirection, normal, lightVector);" +
" totalDiffuse += result.diffuse * lightColor;" +
" totalSpecular += result.specular * lightColor * specularColor;" +
"attribute vec3 aPosition;" +
"attribute vec3 aNormal;" +
"attribute vec2 aTexCoord;" +
"attribute vec4 aMaterialColor;" +
"attribute vec4 aMyAttr1;" +
"attribute vec4 aMyAttr2;" +
"uniform mat4 uModelViewMatrix;" +
"uniform mat4 uProjectionMatrix;" +
"uniform mat3 uNormalMatrix;" +
"varying highp vec2 vVertTexCoord;" +
"varying vec3 vDiffuseColor;" +
"varying vec3 vSpecularColor;" +
"varying vec4 vVertexColor;" +
"varying vec4 vMyAttr1;" +
"varying vec4 vMyAttr2;" +
" vMyAttr1 = aMyAttr1;" +
" vMyAttr2 = aMyAttr2;" +
" vec4 viewModelPosition = uModelViewMatrix * vec4(p, 1.0);" +
" gl_Position = uProjectionMatrix * viewModelPosition;" +
" vec3 vertexNormal = normalize(uNormalMatrix * aNormal);" +
" vVertTexCoord = aTexCoord;" +
" vVertexColor = aMaterialColor;" +
" totalLight(viewModelPosition.xyz, vertexNormal, vDiffuseColor, vSpecularColor);" +
" for(int i = 0; i < 5; i++){" +
" if (i < uAmbientLightCount){" +
" vDiffuseColor += uAmbientColor[i];" +
"precision mediump float;" +
"uniform vec4 uMaterialColor;" +
"uniform sampler2D uSampler;" +
"uniform bool isTexture;" +
"uniform bool uEmissive;" +
"uniform int uPatternId;" +
"varying highp vec2 vVertTexCoord;" +
"varying vec3 vDiffuseColor;" +
"varying vec3 vSpecularColor;" +
"varying vec4 vVertexColor;" +
"varying vec4 vMyAttr1;" +
"varying vec4 vMyAttr2;" +
"vec3 getRGB(float h, float s, float b){" +
" vec3 c = vec3(h, s, b);" +
" vec3 rgb = clamp(abs(mod(c.x * 6.0 + vec3(0.0, 4.0, 2.0), 6.0) - 3.0) - 1.0, 0.0, 1.0);" +
" rgb = rgb * rgb * (3.0 - 2.0 * rgb);" +
" return c.z * mix(vec3(1.0), rgb, c.y);" +
" vec4 col = vVertexColor;" +
" if(uPatternId == 0){" +
" }else if(uPatternId == 1){" +
" }else if(uPatternId == 2){" +
" col = 0.5 * (vMyAttr1 + vMyAttr2);" +
" col.rgb = col.rgb * vDiffuseColor + vSpecularColor;" +
let _gl = createCanvas(600, 600, WEBGL);
myFillShader = createShader(vsFill, fsFill);
gl.enable(gl.DEPTH_TEST);
bg = createGraphics(600, 600);
bgImage = createGraphics(600, 600);
bgImage.colorMode(HSB, 100);
for(let i = 0; i < 200; i++){
bgImage.fill(55 + i/10, 100 - i/2, 100);
bgImage.rect(0, i * 3, 600, 3);
_gl.retainedMode.buffers.fill.push(new p5.RenderBuffer(4, "myAttr1", "myAttr1dst", "aMyAttr1", _gl));
_gl.retainedMode.buffers.fill.push(new p5.RenderBuffer(4, "myAttr2", "myAttr2dst", "aMyAttr2", _gl));
const patternId = Math.floor((frameCount % 360) / 120);
gl.disable(gl.DEPTH_TEST);
directionalLight(255, 255, 255, 0, 0, 1);
directionalLight(255, 255 ,255, 0, 0, -1);
rotateX(properFrameCount * PI / 120);
gl.enable(gl.DEPTH_TEST);
myFillShader.setUniform("uPatternId", patternId);
bg.textAlign(CENTER, CENTER);
const _txt = ["vMyAttr1 only", "vMyAttr2 only", "0.5 * (vMyAttr1 + vMyAttr2)"];
bg.text(_txt[patternId], 300, 100);
function myRect(sizeX, sizeY, detailX, detailY){
const gId = `myPlane|${detailX}|${detailY}`;
if(!this._renderer.geometryInHash(gId)){
const geom = new p5.Geometry();
for(let i = 0; i < detailX; i++){
for(let j = 0; j < detailY; j++){
const x1 = -0.5 + i / detailX;
const y1 = -0.5 + j / detailY;
const x2 = -0.5 + (i+1) / detailX;
const y2 = -0.5 + (j+1) / detailY;
geom.vertices.push(v.set(x1, y1, 0).copy());
geom.vertices.push(v.set(x1, y2, 0).copy());
geom.vertices.push(v.set(x2, y1, 0).copy());
geom.vertices.push(v.set(x2, y2, 0).copy());
geom.vertexColors.push(i / detailX, j / detailY, 1.0, 1.0);
geom.vertexColors.push(i / detailX, j / detailY, 1.0, 1.0);
geom.vertexColors.push(i / detailX, j / detailY, 1.0, 1.0);
geom.vertexColors.push(i / detailX, j / detailY, 1.0, 1.0);
geom.myAttr1.push(1.0, i / detailX, j / detailY, 1.0);
geom.myAttr1.push(1.0, i / detailX, j / detailY, 1.0);
geom.myAttr1.push(1.0, i / detailX, j / detailY, 1.0);
geom.myAttr1.push(1.0, i / detailX, j / detailY, 1.0);
geom.myAttr2.push(i / detailX, 1.0, j / detailY, 1.0);
geom.myAttr2.push(i / detailX, 1.0, j / detailY, 1.0);
geom.myAttr2.push(i / detailX, 1.0, j / detailY, 1.0);
geom.myAttr2.push(i / detailX, 1.0, j / detailY, 1.0);
geom.faces.push([index, index + 1, index + 2]);
geom.faces.push([index + 2, index + 1, index + 3]);
geom._makeTriangleEdges()._edgesToVertices();
this._renderer.createBuffers(gId, geom);
this._renderer.drawBuffersScaled(gId, sizeX, sizeY, 1);