From 9d2914b233da61e9c6b0043b2a5b522ee7002cec Mon Sep 17 00:00:00 2001 From: Perminder Singh Date: Tue, 13 Feb 2024 17:58:29 +0530 Subject: [PATCH 01/17] Sphere-Mapping --- src/webgl/light.js | 71 +++++++++++++++++++++++----- src/webgl/material.js | 35 +++++++++----- src/webgl/p5.RendererGL.js | 23 +++++++-- src/webgl/shaders/sphereMapping.frag | 32 +++++++++++++ 4 files changed, 134 insertions(+), 27 deletions(-) create mode 100644 src/webgl/shaders/sphereMapping.frag diff --git a/src/webgl/light.js b/src/webgl/light.js index 363d0772e5..e3b06b80ef 100644 --- a/src/webgl/light.js +++ b/src/webgl/light.js @@ -115,7 +115,7 @@ import p5 from '../core/main'; * @param {p5.Color} color color as a p5.Color * @chainable */ -p5.prototype.ambientLight = function(v1, v2, v3, a) { +p5.prototype.ambientLight = function (v1, v2, v3, a) { this._assert3d('ambientLight'); p5._validateParameters('ambientLight', arguments); const color = this.color(...arguments); @@ -229,7 +229,7 @@ p5.prototype.ambientLight = function(v1, v2, v3, a) { * @param {p5.Color} color color as a p5.Color * @chainable */ -p5.prototype.specularColor = function(v1, v2, v3) { +p5.prototype.specularColor = function (v1, v2, v3) { this._assert3d('specularColor'); p5._validateParameters('specularColor', arguments); const color = this.color(...arguments); @@ -327,7 +327,7 @@ p5.prototype.specularColor = function(v1, v2, v3) { * @param {p5.Vector} direction * @chainable */ -p5.prototype.directionalLight = function(v1, v2, v3, x, y, z) { +p5.prototype.directionalLight = function (v1, v2, v3, x, y, z) { this._assert3d('directionalLight'); p5._validateParameters('directionalLight', arguments); @@ -454,7 +454,7 @@ p5.prototype.directionalLight = function(v1, v2, v3, x, y, z) { * @param {p5.Vector} position * @chainable */ -p5.prototype.pointLight = function(v1, v2, v3, x, y, z) { +p5.prototype.pointLight = function (v1, v2, v3, x, y, z) { this._assert3d('pointLight'); p5._validateParameters('pointLight', arguments); @@ -592,13 +592,63 @@ p5.prototype.pointLight = function(v1, v2, v3, x, y, z) { * @alt * light with slider having a slider for varying roughness */ -p5.prototype.imageLight = function(img){ +p5.prototype.imageLight = function (img) { // activeImageLight property is checked by _setFillUniforms // for sending uniforms to the fillshader this._renderer.activeImageLight = img; this._renderer._enableLighting = true; }; +/** + * Creates a Panorama with given image. + * + * + * `panorama(img)` is a method designed to transform a standard + * image into a 360-degree view. It operates on the concept + * of sphere mapping, where the image is manipulated to + * resemble a sphere by adjusting camera angles. Utilizing + * this method, users can obtain a complete 360-degree view + * of a scene. + * + * Using Panorama is straightforward. Similar to calling a + * `background(color)`, users only need to call the `panorama(img)`, and + * beneath it, anything created will form a 360-degree scene. + * To enable 360-degree viewing, it is essential to invoke + * `orbitControl()`; otherwise, the method will not function as intended. + * @method panorama + * @param {p5.image} img + * @example + *
+ * + * let img; + * function preload() { + * img = loadImage('assets/outdoor_spheremap.jpg'); + * } + * function setup() { + * createCanvas(100 ,100 ,WEBGL); + * } + * function draw() { + * panorama(img); + * imageMode(CENTER); + * orbitControl(); + * noStroke(); + * push(); + * imageLight(img); + * specularMaterial('green'); + * shininess(200); + * metalness(100); + * sphere(25); + * pop(); + * } + * + *
+ * @alt + * The image transformed into a panoramic scene. + */ +p5.prototype.panorama = function (img) { + this.filter(this._renderer._getSphereMapping(img)); +}; + /** * Places an ambient and directional light in the scene. * The lights are set to ambientLight(128, 128, 128) and @@ -634,7 +684,7 @@ p5.prototype.imageLight = function(img){ * @alt * the light is partially ambient and partially directional */ -p5.prototype.lights = function() { +p5.prototype.lights = function () { this._assert3d('lights'); // Both specify gray by default. const grayColor = this.color('rgb(128,128,128)'); @@ -698,7 +748,7 @@ p5.prototype.lights = function() { * @alt * Two spheres with different falloff values show different intensity of light */ -p5.prototype.lightFalloff = function( +p5.prototype.lightFalloff = function ( constantAttenuation, linearAttenuation, quadraticAttenuation @@ -892,7 +942,7 @@ p5.prototype.lightFalloff = function( * @param {Number} [angle] * @param {Number} [concentration] */ -p5.prototype.spotLight = function( +p5.prototype.spotLight = function ( v1, v2, v3, @@ -1058,8 +1108,7 @@ p5.prototype.spotLight = function( default: console.warn( - `Sorry, input for spotlight() is not in prescribed format. Too ${ - length < 3 ? 'few' : 'many' + `Sorry, input for spotlight() is not in prescribed format. Too ${length < 3 ? 'few' : 'many' } arguments were provided` ); return this; @@ -1153,7 +1202,7 @@ p5.prototype.spotLight = function( * Three white spheres. Each appears as a different * color due to lighting. */ -p5.prototype.noLights = function(...args) { +p5.prototype.noLights = function (...args) { this._assert3d('noLights'); p5._validateParameters('noLights', args); diff --git a/src/webgl/material.js b/src/webgl/material.js index e94d148538..8a76e1d9e4 100644 --- a/src/webgl/material.js +++ b/src/webgl/material.js @@ -300,23 +300,32 @@ p5.prototype.createFilterShader = function (fragSrc) { } `; let defaultVertV2 = `#version 300 es - uniform mat4 uModelViewMatrix; - uniform mat4 uProjectionMatrix; + uniform mat4 uModelViewMatrix; + uniform mat4 uProjectionMatrix; - in vec3 aPosition; - in vec2 aTexCoord; - out vec2 vTexCoord; + in vec3 aPosition; + in vec2 aTexCoord; + in vec3 aNormal; - void main() { - // transferring texcoords for the frag shader - vTexCoord = aTexCoord; + out vec3 faNormal; + out vec3 vNormal; + out vec3 faPosition; + out vec2 vTexCoord; + out vec3 fvNormal; + + void main() { + // transferring vectors and texcoords for the frag shader + faNormal = aNormal; + fvNormal = vNormal; + faPosition = aPosition; + vTexCoord = aTexCoord; - // copy position with a fourth coordinate for projection (1.0 is normal) - vec4 positionVec4 = vec4(aPosition, 1.0); + // copy position with a fourth coordinate for projection (1.0 is normal) + vec4 positionVec4 = vec4(aPosition, 1.0); - // project to 3D space - gl_Position = uProjectionMatrix * uModelViewMatrix * positionVec4; - } + // project to 3D space + gl_Position = uProjectionMatrix * uModelViewMatrix * positionVec4; + } `; let vertSrc = fragSrc.includes('#version 300 es') ? defaultVertV2 : defaultVertV1; const shader = new p5.Shader(this._renderer, vertSrc, fragSrc); diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js index 7f1069bfd5..5d55192a4f 100644 --- a/src/webgl/p5.RendererGL.js +++ b/src/webgl/p5.RendererGL.js @@ -42,6 +42,10 @@ const webgl2CompatibilityShader = readFileSync( ); const defaultShaders = { + sphereMappingFrag: readFileSync( + join(__dirname, '/shaders/sphereMapping.frag'), + 'utf-8' + ), immediateVert: readFileSync( join(__dirname, '/shaders/immediate.vert'), 'utf-8' @@ -80,6 +84,7 @@ const defaultShaders = { imageLightDiffusedFrag: readFileSync(join(__dirname, '/shaders/imageLightDiffused.frag'), 'utf-8'), imageLightSpecularFrag: readFileSync(join(__dirname, '/shaders/imageLightSpecular.frag'), 'utf-8') }; +let sphereMapping = defaultShaders.sphereMappingFrag; for (const key in defaultShaders) { defaultShaders[key] = webgl2CompatibilityShader + defaultShaders[key]; } @@ -559,6 +564,7 @@ p5.RendererGL = class RendererGL extends p5.Renderer { this.executeRotateAndMove = false; this.specularShader = undefined; + this.sphereMapping = undefined; this.diffusedShader = undefined; this._defaultLightShader = undefined; this._defaultImmediateModeShader = undefined; @@ -1012,6 +1018,7 @@ p5.RendererGL = class RendererGL extends p5.Renderer { } filter(...args) { + this.uNMatrix.inverseTranspose(this.uMVMatrix); let fbo = this.getFilterLayer(); // use internal shader for filter constants BLUR, INVERT, etc @@ -1104,6 +1111,7 @@ p5.RendererGL = class RendererGL extends p5.Renderer { this._pInst.noStroke(); this._pInst.blendMode(constants.BLEND); this._pInst.shader(this.filterShader); + this.filterShader.setUniform('uNewNormalMatrix', this.uNMatrix.mat3); this.filterShader.setUniform('tex0', target); this.filterShader.setUniform('texelSize', texelSize); this.filterShader.setUniform('canvasSize', [target.width, target.height]); @@ -1613,6 +1621,7 @@ p5.RendererGL = class RendererGL extends p5.Renderer { properties.quadraticAttenuation = this.quadraticAttenuation; properties._enableLighting = this._enableLighting; + properties.sphereMapping = this.sphereMapping; properties._useNormalMaterial = this._useNormalMaterial; properties._tex = this._tex; properties.drawMode = this.drawMode; @@ -1676,6 +1685,14 @@ p5.RendererGL = class RendererGL extends p5.Renderer { return this._getImmediateStrokeShader(); } + _getSphereMapping(img) { + this.sphereMapping = this._pInst.createFilterShader( + sphereMapping + ); + this.sphereMapping.setUniform('uSampler', img); + return this.sphereMapping; + } + /* * selects which fill shader should be used based on renderer state, * for use with begin/endShape and immediate vertex mode. @@ -2141,9 +2158,9 @@ p5.RendererGL = class RendererGL extends p5.Renderer { } /* Binds a buffer to the drawing context - * when passed more than two arguments it also updates or initializes - * the data associated with the buffer - */ + * when passed more than two arguments it also updates or initializes + * the data associated with the buffer + */ _bindBuffer( buffer, target, diff --git a/src/webgl/shaders/sphereMapping.frag b/src/webgl/shaders/sphereMapping.frag new file mode 100644 index 0000000000..df1501b4ab --- /dev/null +++ b/src/webgl/shaders/sphereMapping.frag @@ -0,0 +1,32 @@ +#version 300 es +#define PI 3.141592 + +precision highp float; + +uniform sampler2D uSampler; +uniform mat3 uNewNormalMatrix; +uniform mat3 uCameraRotation; +uniform mat4 uNewModelViewMatrix; +uniform mat4 uModelViewMatrix; + +in vec2 vTexCoord; +in vec3 fvNormal; +in vec3 faNormal; +in vec3 faPosition; + +out vec4 fragColor; + +void main() { + vec4 viewModelPosition = uModelViewMatrix * vec4(faPosition, 1.0); + vec3 vViewPosition = viewModelPosition.xyz; + vec4 newTexColor = texture(uSampler, vTexCoord); + vec3 vGlobalNormal = uNewNormalMatrix * faNormal ; + vec3 n = reflect(vViewPosition.xyz , (vGlobalNormal.xyz)); + n = normalize(n); + vec2 suv; + suv.y = 0.5 + 0.5 * n.y; + suv.x = atan(n.z, n.x) / (2.0 * PI) + 0.5; + newTexColor = texture(uSampler, suv.xy); + vec4 baseColor = newTexColor; + fragColor = baseColor; +} \ No newline at end of file From 997db50f15c22f1e238759ba7b47d6b34bfb6973 Mon Sep 17 00:00:00 2001 From: Perminder Singh <127239756+perminder-17@users.noreply.github.com> Date: Tue, 13 Feb 2024 18:16:13 +0530 Subject: [PATCH 02/17] prettier fix --- src/webgl/light.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/webgl/light.js b/src/webgl/light.js index e3b06b80ef..5465f1b6ff 100644 --- a/src/webgl/light.js +++ b/src/webgl/light.js @@ -1108,7 +1108,8 @@ p5.prototype.spotLight = function ( default: console.warn( - `Sorry, input for spotlight() is not in prescribed format. Too ${length < 3 ? 'few' : 'many' + `Sorry, input for spotlight() is not in prescribed format. Too ${ + length < 3 ? 'few' : 'many' } arguments were provided` ); return this; From 71dc72355b132be77344c00611ac69ccdb44053c Mon Sep 17 00:00:00 2001 From: Perminder Singh <127239756+perminder-17@users.noreply.github.com> Date: Tue, 13 Feb 2024 21:19:35 +0530 Subject: [PATCH 03/17] fixes --- src/webgl/material.js | 45 ++++++++++++++++++++----------------------- 1 file changed, 21 insertions(+), 24 deletions(-) diff --git a/src/webgl/material.js b/src/webgl/material.js index 8a76e1d9e4..ea19e939b4 100644 --- a/src/webgl/material.js +++ b/src/webgl/material.js @@ -286,11 +286,17 @@ p5.prototype.createFilterShader = function (fragSrc) { // texcoords only come from p5 to vertex shader // so pass texcoords on to the fragment shader in a varying variable attribute vec2 aTexCoord; + attribute vec3 aNormal; + varying vec2 vTexCoord; + varying vec3 faNormal; + varying vec3 faPosition; void main() { - // transferring texcoords for the frag shader + // transferring vectors and texcoords for the frag shader vTexCoord = aTexCoord; + faNormal = aNormal; + faPosition = aPosition; // copy position with a fourth coordinate for projection (1.0 is normal) vec4 positionVec4 = vec4(aPosition, 1.0); @@ -300,32 +306,23 @@ p5.prototype.createFilterShader = function (fragSrc) { } `; let defaultVertV2 = `#version 300 es - uniform mat4 uModelViewMatrix; - uniform mat4 uProjectionMatrix; + uniform mat4 uModelViewMatrix; + uniform mat4 uProjectionMatrix; - in vec3 aPosition; - in vec2 aTexCoord; - in vec3 aNormal; + in vec3 aPosition; + in vec2 aTexCoord; + out vec2 vTexCoord; - out vec3 faNormal; - out vec3 vNormal; - out vec3 faPosition; - out vec2 vTexCoord; - out vec3 fvNormal; - - void main() { - // transferring vectors and texcoords for the frag shader - faNormal = aNormal; - fvNormal = vNormal; - faPosition = aPosition; - vTexCoord = aTexCoord; + void main() { + // transferring texcoords for the frag shader + vTexCoord = aTexCoord; - // copy position with a fourth coordinate for projection (1.0 is normal) - vec4 positionVec4 = vec4(aPosition, 1.0); + // copy position with a fourth coordinate for projection (1.0 is normal) + vec4 positionVec4 = vec4(aPosition, 1.0); - // project to 3D space - gl_Position = uProjectionMatrix * uModelViewMatrix * positionVec4; - } + // project to 3D space + gl_Position = uProjectionMatrix * uModelViewMatrix * positionVec4; + } `; let vertSrc = fragSrc.includes('#version 300 es') ? defaultVertV2 : defaultVertV1; const shader = new p5.Shader(this._renderer, vertSrc, fragSrc); @@ -1293,7 +1290,7 @@ p5.prototype.metalness = function (metallic) { * transparency internally, e.g. via vertex colors * @return {Number[]]} Normalized numbers array */ -p5.RendererGL.prototype._applyColorBlend = function(colors, hasTransparency) { +p5.RendererGL.prototype._applyColorBlend = function (colors, hasTransparency) { const gl = this.GL; const isTexture = this.drawMode === constants.TEXTURE; From 692ea248bb5efbfffaf03a4095adcfcc66dab92f Mon Sep 17 00:00:00 2001 From: Perminder Singh <127239756+perminder-17@users.noreply.github.com> Date: Tue, 13 Feb 2024 21:21:11 +0530 Subject: [PATCH 04/17] fixes --- src/webgl/shaders/sphereMapping.frag | 20 +++++++------------- 1 file changed, 7 insertions(+), 13 deletions(-) diff --git a/src/webgl/shaders/sphereMapping.frag b/src/webgl/shaders/sphereMapping.frag index df1501b4ab..aef025d521 100644 --- a/src/webgl/shaders/sphereMapping.frag +++ b/src/webgl/shaders/sphereMapping.frag @@ -1,32 +1,26 @@ -#version 300 es #define PI 3.141592 precision highp float; uniform sampler2D uSampler; uniform mat3 uNewNormalMatrix; -uniform mat3 uCameraRotation; -uniform mat4 uNewModelViewMatrix; uniform mat4 uModelViewMatrix; -in vec2 vTexCoord; -in vec3 fvNormal; -in vec3 faNormal; -in vec3 faPosition; - -out vec4 fragColor; +varying vec2 vTexCoord; +varying vec3 faNormal; +varying vec3 faPosition; void main() { vec4 viewModelPosition = uModelViewMatrix * vec4(faPosition, 1.0); vec3 vViewPosition = viewModelPosition.xyz; - vec4 newTexColor = texture(uSampler, vTexCoord); + vec4 newTexColor = texture2D(uSampler, vTexCoord); vec3 vGlobalNormal = uNewNormalMatrix * faNormal ; vec3 n = reflect(vViewPosition.xyz , (vGlobalNormal.xyz)); n = normalize(n); vec2 suv; suv.y = 0.5 + 0.5 * n.y; suv.x = atan(n.z, n.x) / (2.0 * PI) + 0.5; - newTexColor = texture(uSampler, suv.xy); + newTexColor = texture2D(uSampler, suv.xy); vec4 baseColor = newTexColor; - fragColor = baseColor; -} \ No newline at end of file + gl_FragColor = baseColor; +} From 71a32d58de87d4de72f56ae8a0ec8bc36983ea99 Mon Sep 17 00:00:00 2001 From: Perminder Singh <127239756+perminder-17@users.noreply.github.com> Date: Tue, 13 Feb 2024 21:22:37 +0530 Subject: [PATCH 05/17] fixes --- src/webgl/p5.RendererGL.js | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js index 5d55192a4f..c4d4461607 100644 --- a/src/webgl/p5.RendererGL.js +++ b/src/webgl/p5.RendererGL.js @@ -502,7 +502,7 @@ p5.RendererGL = class RendererGL extends p5.Renderer { this.curStrokeColor = this._cachedStrokeStyle = [0, 0, 0, 1]; this.curBlendMode = constants.BLEND; - this.preEraseBlend=undefined; + this.preEraseBlend = undefined; this._cachedBlendMode = undefined; if (this.webglVersion === constants.WEBGL2) { this.blendExt = this.GL; @@ -1018,7 +1018,6 @@ p5.RendererGL = class RendererGL extends p5.Renderer { } filter(...args) { - this.uNMatrix.inverseTranspose(this.uMVMatrix); let fbo = this.getFilterLayer(); // use internal shader for filter constants BLUR, INVERT, etc @@ -1111,7 +1110,6 @@ p5.RendererGL = class RendererGL extends p5.Renderer { this._pInst.noStroke(); this._pInst.blendMode(constants.BLEND); this._pInst.shader(this.filterShader); - this.filterShader.setUniform('uNewNormalMatrix', this.uNMatrix.mat3); this.filterShader.setUniform('tex0', target); this.filterShader.setUniform('texelSize', texelSize); this.filterShader.setUniform('canvasSize', [target.width, target.height]); @@ -1194,7 +1192,7 @@ p5.RendererGL = class RendererGL extends p5.Renderer { this.curFillColor = this._cachedFillStyle.slice(); this.curStrokeColor = this._cachedStrokeStyle.slice(); // Restore blend mode - this.curBlendMode=this.preEraseBlend; + this.curBlendMode = this.preEraseBlend; this.blendMode(this.preEraseBlend); // Ensure that _applyBlendMode() sets preEraseBlend back to the original blend mode this._isErasing = false; @@ -1621,7 +1619,6 @@ p5.RendererGL = class RendererGL extends p5.Renderer { properties.quadraticAttenuation = this.quadraticAttenuation; properties._enableLighting = this._enableLighting; - properties.sphereMapping = this.sphereMapping; properties._useNormalMaterial = this._useNormalMaterial; properties._tex = this._tex; properties.drawMode = this.drawMode; @@ -1686,9 +1683,13 @@ p5.RendererGL = class RendererGL extends p5.Renderer { } _getSphereMapping(img) { - this.sphereMapping = this._pInst.createFilterShader( - sphereMapping - ); + if (!this.sphereMapping) { + this.sphereMapping = this._pInst.createFilterShader( + sphereMapping + ); + } + this.uNMatrix.inverseTranspose(this.uMVMatrix); + this.sphereMapping.setUniform('uNewNormalMatrix', this.uNMatrix.mat3); this.sphereMapping.setUniform('uSampler', img); return this.sphereMapping; } From 9db3b2e58949e1578e27f2566b5dd6fd4aeddcc5 Mon Sep 17 00:00:00 2001 From: Perminder Singh <127239756+perminder-17@users.noreply.github.com> Date: Thu, 15 Feb 2024 14:15:37 +0530 Subject: [PATCH 06/17] fixes --- src/webgl/shaders/sphereMapping.frag | 32 +++++++++++++--------------- 1 file changed, 15 insertions(+), 17 deletions(-) diff --git a/src/webgl/shaders/sphereMapping.frag b/src/webgl/shaders/sphereMapping.frag index aef025d521..fb4d2b7dc3 100644 --- a/src/webgl/shaders/sphereMapping.frag +++ b/src/webgl/shaders/sphereMapping.frag @@ -1,26 +1,24 @@ #define PI 3.141592 precision highp float; - + uniform sampler2D uSampler; uniform mat3 uNewNormalMatrix; -uniform mat4 uModelViewMatrix; +uniform float uFovY; +uniform float uAspect; varying vec2 vTexCoord; -varying vec3 faNormal; -varying vec3 faPosition; - + void main() { - vec4 viewModelPosition = uModelViewMatrix * vec4(faPosition, 1.0); - vec3 vViewPosition = viewModelPosition.xyz; - vec4 newTexColor = texture2D(uSampler, vTexCoord); - vec3 vGlobalNormal = uNewNormalMatrix * faNormal ; - vec3 n = reflect(vViewPosition.xyz , (vGlobalNormal.xyz)); - n = normalize(n); - vec2 suv; - suv.y = 0.5 + 0.5 * n.y; - suv.x = atan(n.z, n.x) / (2.0 * PI) + 0.5; - newTexColor = texture2D(uSampler, suv.xy); - vec4 baseColor = newTexColor; - gl_FragColor = baseColor; + float uFovX = uFovY * uAspect; + vec4 newTexColor = texture2D(uSampler, vTexCoord); + float angleY = mix(-uFovY/2.0, uFovY/2.0, vTexCoord.y); + float angleX = mix(-uFovX/2.0, uFovX/2.0, vTexCoord.x); + vec3 rotatedNormal = vec3( angleX, angleY, 1.0 ); + rotatedNormal = uNewNormalMatrix * normalize(rotatedNormal); + vec2 suv; + suv.y = 0.5 + 0.5 * rotatedNormal.y; + suv.x = atan(rotatedNormal.z, rotatedNormal.x) / (2.0 * PI) + 0.5; + newTexColor = texture2D(uSampler, suv.xy); + gl_FragColor = newTexColor; } From bc9558ce7cdbd21f8bcb2bc908e99d9b533fd2da Mon Sep 17 00:00:00 2001 From: Perminder Singh <127239756+perminder-17@users.noreply.github.com> Date: Thu, 15 Feb 2024 14:16:25 +0530 Subject: [PATCH 07/17] fixes --- src/webgl/p5.RendererGL.js | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js index c4d4461607..188e686c72 100644 --- a/src/webgl/p5.RendererGL.js +++ b/src/webgl/p5.RendererGL.js @@ -1689,6 +1689,8 @@ p5.RendererGL = class RendererGL extends p5.Renderer { ); } this.uNMatrix.inverseTranspose(this.uMVMatrix); + this.sphereMapping.setUniform('uFovY', this._curCamera.cameraFOV); + this.sphereMapping.setUniform('uAspect', this._curCamera.aspectRatio); this.sphereMapping.setUniform('uNewNormalMatrix', this.uNMatrix.mat3); this.sphereMapping.setUniform('uSampler', img); return this.sphereMapping; From 2c61205730ad39256c6677ddc2e23536cad7d36d Mon Sep 17 00:00:00 2001 From: Perminder Singh <127239756+perminder-17@users.noreply.github.com> Date: Thu, 15 Feb 2024 14:18:57 +0530 Subject: [PATCH 08/17] fixes --- src/webgl/material.js | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/src/webgl/material.js b/src/webgl/material.js index ea19e939b4..e94d148538 100644 --- a/src/webgl/material.js +++ b/src/webgl/material.js @@ -286,17 +286,11 @@ p5.prototype.createFilterShader = function (fragSrc) { // texcoords only come from p5 to vertex shader // so pass texcoords on to the fragment shader in a varying variable attribute vec2 aTexCoord; - attribute vec3 aNormal; - varying vec2 vTexCoord; - varying vec3 faNormal; - varying vec3 faPosition; void main() { - // transferring vectors and texcoords for the frag shader + // transferring texcoords for the frag shader vTexCoord = aTexCoord; - faNormal = aNormal; - faPosition = aPosition; // copy position with a fourth coordinate for projection (1.0 is normal) vec4 positionVec4 = vec4(aPosition, 1.0); @@ -1290,7 +1284,7 @@ p5.prototype.metalness = function (metallic) { * transparency internally, e.g. via vertex colors * @return {Number[]]} Normalized numbers array */ -p5.RendererGL.prototype._applyColorBlend = function (colors, hasTransparency) { +p5.RendererGL.prototype._applyColorBlend = function(colors, hasTransparency) { const gl = this.GL; const isTexture = this.drawMode === constants.TEXTURE; From 88d251c25120ae7c251039ba1b067023b1ab21fa Mon Sep 17 00:00:00 2001 From: Perminder Singh <127239756+perminder-17@users.noreply.github.com> Date: Fri, 16 Feb 2024 22:11:11 +0530 Subject: [PATCH 09/17] fixes --- src/webgl/shaders/sphereMapping.frag | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/webgl/shaders/sphereMapping.frag b/src/webgl/shaders/sphereMapping.frag index fb4d2b7dc3..baed3b390a 100644 --- a/src/webgl/shaders/sphereMapping.frag +++ b/src/webgl/shaders/sphereMapping.frag @@ -12,12 +12,12 @@ varying vec2 vTexCoord; void main() { float uFovX = uFovY * uAspect; vec4 newTexColor = texture2D(uSampler, vTexCoord); - float angleY = mix(-uFovY/2.0, uFovY/2.0, vTexCoord.y); - float angleX = mix(-uFovX/2.0, uFovX/2.0, vTexCoord.x); + float angleY = mix(uFovY/2.0, -uFovY/2.0, vTexCoord.y); + float angleX = mix(uFovX/2.0, -uFovX/2.0, vTexCoord.x); vec3 rotatedNormal = vec3( angleX, angleY, 1.0 ); rotatedNormal = uNewNormalMatrix * normalize(rotatedNormal); vec2 suv; - suv.y = 0.5 + 0.5 * rotatedNormal.y; + suv.y = 0.5 + 0.5 * (-rotatedNormal.y); suv.x = atan(rotatedNormal.z, rotatedNormal.x) / (2.0 * PI) + 0.5; newTexColor = texture2D(uSampler, suv.xy); gl_FragColor = newTexColor; From 242aeddbc4b6d93fdb262f6b280d167a455978a9 Mon Sep 17 00:00:00 2001 From: Perminder Singh <127239756+perminder-17@users.noreply.github.com> Date: Fri, 16 Feb 2024 22:12:06 +0530 Subject: [PATCH 10/17] fixes --- src/webgl/p5.RendererGL.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js index 188e686c72..0e207da542 100644 --- a/src/webgl/p5.RendererGL.js +++ b/src/webgl/p5.RendererGL.js @@ -1689,6 +1689,7 @@ p5.RendererGL = class RendererGL extends p5.Renderer { ); } this.uNMatrix.inverseTranspose(this.uMVMatrix); + this.uNMatrix.invert3x3(this.uNMatrix); this.sphereMapping.setUniform('uFovY', this._curCamera.cameraFOV); this.sphereMapping.setUniform('uAspect', this._curCamera.aspectRatio); this.sphereMapping.setUniform('uNewNormalMatrix', this.uNMatrix.mat3); From ae6e257c5fcc12a56a7b52da984cf4841fc1950b Mon Sep 17 00:00:00 2001 From: Perminder Singh <127239756+perminder-17@users.noreply.github.com> Date: Fri, 16 Feb 2024 22:13:02 +0530 Subject: [PATCH 11/17] fixes --- src/webgl/light.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/webgl/light.js b/src/webgl/light.js index 5465f1b6ff..4edec74b9a 100644 --- a/src/webgl/light.js +++ b/src/webgl/light.js @@ -647,6 +647,7 @@ p5.prototype.imageLight = function (img) { */ p5.prototype.panorama = function (img) { this.filter(this._renderer._getSphereMapping(img)); + this.clearDepth(); }; /** From 3c491c46fcf9d79bf21d108fb051bc7cc90c4f78 Mon Sep 17 00:00:00 2001 From: Perminder Singh <127239756+perminder-17@users.noreply.github.com> Date: Wed, 21 Feb 2024 00:28:46 +0530 Subject: [PATCH 12/17] removed clearDepth for panorma --- src/webgl/light.js | 1 - 1 file changed, 1 deletion(-) diff --git a/src/webgl/light.js b/src/webgl/light.js index 4edec74b9a..5465f1b6ff 100644 --- a/src/webgl/light.js +++ b/src/webgl/light.js @@ -647,7 +647,6 @@ p5.prototype.imageLight = function (img) { */ p5.prototype.panorama = function (img) { this.filter(this._renderer._getSphereMapping(img)); - this.clearDepth(); }; /** From 30844cf301ac9340191a141be2c620efc032ec29 Mon Sep 17 00:00:00 2001 From: Perminder Singh <127239756+perminder-17@users.noreply.github.com> Date: Wed, 21 Feb 2024 00:31:39 +0530 Subject: [PATCH 13/17] clearDepth-all-filterShader --- src/webgl/p5.RendererGL.js | 1 + 1 file changed, 1 insertion(+) diff --git a/src/webgl/p5.RendererGL.js b/src/webgl/p5.RendererGL.js index 0e207da542..5dac06ad24 100644 --- a/src/webgl/p5.RendererGL.js +++ b/src/webgl/p5.RendererGL.js @@ -1133,6 +1133,7 @@ p5.RendererGL = class RendererGL extends p5.Renderer { this._pInst.resetMatrix(); this._pInst.image(fbo, -target.width / 2, -target.height / 2, target.width, target.height); + this._pInst.clearDepth(); this._pInst.pop(); this._pInst.pop(); } From 0117abdce46b1560688e41b886196e339613e939 Mon Sep 17 00:00:00 2001 From: Perminder Singh <127239756+perminder-17@users.noreply.github.com> Date: Wed, 21 Feb 2024 02:10:47 +0530 Subject: [PATCH 14/17] docs --- src/webgl/light.js | 25 +++++++++++-------------- 1 file changed, 11 insertions(+), 14 deletions(-) diff --git a/src/webgl/light.js b/src/webgl/light.js index 5465f1b6ff..1123c4fdc5 100644 --- a/src/webgl/light.js +++ b/src/webgl/light.js @@ -600,21 +600,18 @@ p5.prototype.imageLight = function (img) { }; /** - * Creates a Panorama with given image. + * The `panorama(img)` method adeptly transforms images such as + * maps usually in rectangular format, HDRIs into immersive + * 360-degree views. This is similar to calling `background(color)`; + * call `panorama(img)` before drawing your scene to create a 360-degree + * background from your image. It operates on the concept of sphere mapping, + * where the image is manipulated to resemble a sphere by adjusting + * camera angles. Using this method, a comprehensive 360-degree view of + * a scene can be obtained. + * + * To enable 360-degree viewing, either use orbitControl or try changing + * the orientation of the camera to see different parts of the background. * - * - * `panorama(img)` is a method designed to transform a standard - * image into a 360-degree view. It operates on the concept - * of sphere mapping, where the image is manipulated to - * resemble a sphere by adjusting camera angles. Utilizing - * this method, users can obtain a complete 360-degree view - * of a scene. - * - * Using Panorama is straightforward. Similar to calling a - * `background(color)`, users only need to call the `panorama(img)`, and - * beneath it, anything created will form a 360-degree scene. - * To enable 360-degree viewing, it is essential to invoke - * `orbitControl()`; otherwise, the method will not function as intended. * @method panorama * @param {p5.image} img * @example From 47e9a6ff3038a68fae6aff8e3adaadc81bf8a84e Mon Sep 17 00:00:00 2001 From: Perminder Singh <127239756+perminder-17@users.noreply.github.com> Date: Sat, 24 Feb 2024 23:18:28 +0530 Subject: [PATCH 15/17] docs Co-authored-by: Dave Pagurek --- src/webgl/light.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/webgl/light.js b/src/webgl/light.js index 1123c4fdc5..db1ba164e7 100644 --- a/src/webgl/light.js +++ b/src/webgl/light.js @@ -613,7 +613,7 @@ p5.prototype.imageLight = function (img) { * the orientation of the camera to see different parts of the background. * * @method panorama - * @param {p5.image} img + * @param {p5.Image} img A 360-degree image to use as a background panorama * @example *
* From 9741865d109dd5800b00a1212088b453aa6c4c66 Mon Sep 17 00:00:00 2001 From: Perminder Singh <127239756+perminder-17@users.noreply.github.com> Date: Sat, 24 Feb 2024 23:18:49 +0530 Subject: [PATCH 16/17] docs Co-authored-by: Dave Pagurek --- src/webgl/light.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/webgl/light.js b/src/webgl/light.js index db1ba164e7..2d1d3b1898 100644 --- a/src/webgl/light.js +++ b/src/webgl/light.js @@ -609,7 +609,7 @@ p5.prototype.imageLight = function (img) { * camera angles. Using this method, a comprehensive 360-degree view of * a scene can be obtained. * - * To enable 360-degree viewing, either use orbitControl or try changing + * To enable 360-degree viewing, either use `orbitControl()` or try changing * the orientation of the camera to see different parts of the background. * * @method panorama From a063911823f72be61fed56bf65e291e8d22e9c88 Mon Sep 17 00:00:00 2001 From: Perminder Singh <127239756+perminder-17@users.noreply.github.com> Date: Sat, 24 Feb 2024 23:20:18 +0530 Subject: [PATCH 17/17] docs --- src/webgl/light.js | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/webgl/light.js b/src/webgl/light.js index 2d1d3b1898..6729cc18bc 100644 --- a/src/webgl/light.js +++ b/src/webgl/light.js @@ -600,14 +600,14 @@ p5.prototype.imageLight = function (img) { }; /** - * The `panorama(img)` method adeptly transforms images such as - * maps usually in rectangular format, HDRIs into immersive - * 360-degree views. This is similar to calling `background(color)`; - * call `panorama(img)` before drawing your scene to create a 360-degree - * background from your image. It operates on the concept of sphere mapping, - * where the image is manipulated to resemble a sphere by adjusting - * camera angles. Using this method, a comprehensive 360-degree view of - * a scene can be obtained. + * The `panorama(img)` method transforms images containing + * 360-degree content, such as maps or HDRIs, into immersive + * 3D backgrounds that surround your scene. This is similar to calling + * `background(color)`; call `panorama(img)` before drawing your + * scene to create a 360-degree background from your image. It + * operates on the concept of sphere mapping, where the image is + * mapped onto an infinitely large sphere based on the angles of the + * camera. * * To enable 360-degree viewing, either use `orbitControl()` or try changing * the orientation of the camera to see different parts of the background.