-
-
Notifications
You must be signed in to change notification settings - Fork 3.7k
Addresses issue #6587 #6665
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
base: main
Are you sure you want to change the base?
Addresses issue #6587 #6665
Changes from 6 commits
227fe69
8e2d05c
317d915
917de2f
5139c0a
45e33d5
1d54fad
1ff8702
6cd7856
4401ebd
37751d9
93b8b50
66dc0dc
cffda69
751b16a
29e7a14
7981fdc
e7cd392
f30af0e
d51c4a8
38bcaab
2558755
773198a
bbc7c72
ffd9097
cc77e7e
518b0f0
c124738
38e6e84
a585ef5
f118a3b
2da03d1
5961be8
4515c09
be6d27f
6dc9916
3133e80
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -9,7 +9,7 @@ import './p5.Matrix'; | |
| import './p5.Framebuffer'; | ||
| import { readFileSync } from 'fs'; | ||
| import { join } from 'path'; | ||
| import { MipmapTexture } from './p5.Texture'; | ||
| import { CubemapTexture, MipmapTexture } from './p5.Texture'; | ||
|
|
||
| const STROKE_CAP_ENUM = {}; | ||
| const STROKE_JOIN_ENUM = {}; | ||
|
|
@@ -40,6 +40,14 @@ const webgl2CompatibilityShader = readFileSync( | |
| join(__dirname, '/shaders/webgl2Compatibility.glsl'), | ||
| 'utf-8' | ||
| ); | ||
| const cubemapFragmentShader=readFileSync( | ||
| join(__dirname,'/shaders/cubeFragment.glsl'), | ||
| 'utf8' | ||
| ); | ||
| const cubemapVertexShader=readFileSync( | ||
| join(__dirname,'/shaders/cubeVertex.glsl'), | ||
| 'utf8' | ||
| ); | ||
|
|
||
| const defaultShaders = { | ||
| immediateVert: readFileSync( | ||
|
|
@@ -1902,6 +1910,8 @@ p5.RendererGL = class RendererGL extends p5.Renderer { | |
| let smallWidth = 200; | ||
| let width = smallWidth; | ||
| let height = Math.floor(smallWidth * (input.height / input.width)); | ||
| let cubemapTexture; | ||
| const faces = []; | ||
| newFramebuffer = this._pInst.createFramebuffer({ | ||
| width, height, density: 1 | ||
| }); | ||
|
|
@@ -1913,23 +1923,49 @@ p5.RendererGL = class RendererGL extends p5.Renderer { | |
| defaultShaders.imageLightDiffusedFrag | ||
| ); | ||
| } | ||
| // Create a shader for cubemap conversion | ||
| const cubemapShader = this._pInst.createShader( | ||
| cubemapVertexShader, | ||
| cubemapFragmentShader); | ||
|
|
||
| // Render each face of the cubemap | ||
| for (let i = 0; i < 6; ++i) { | ||
| newFramebuffer.draw(() => { | ||
| cubemapShader.use(); | ||
| cubemapShader.setUniform('equirectangularMap', input); | ||
| cubemapShader.setUniform('projection', captureProjection); | ||
| cubemapShader.setUniform('view', captureViews[i]); | ||
|
|
||
| this._pInst.noStroke(); | ||
| this._pInst.rectMode(constants.CENTER); | ||
| this._pInst.noLights(); | ||
| this._pInst.rect(0, 0, width, height); | ||
|
|
||
| // Capture the rendered face and store it in the faces array | ||
| faces[i] = this._pInst.get(0, 0, width, height); | ||
|
||
| }); | ||
| } | ||
| // Use the diffusedShader for rendering | ||
| newFramebuffer.draw(() => { | ||
|
||
| this._pInst.shader(this.diffusedShader); | ||
| this.diffusedShader.setUniform('environmentMap', input); | ||
| this._pInst.noStroke(); | ||
| this._pInst.rectMode(constants.CENTER); | ||
| this._pInst.noLights(); | ||
| this._pInst.rect(0, 0, width, height); | ||
| // Render the cubemap using the stored faces | ||
| for (let i = 0; i < 6; ++i) { | ||
| this._pInst.image(faces[i], 0, 0, width, height); | ||
| } | ||
| }); | ||
| this.diffusedTextures.set(input, newFramebuffer); | ||
| return newFramebuffer; | ||
| // Initialize CubemapTexture class with faces | ||
| cubemapTexture=new CubemapTexture(this._pInst,faces, {}); | ||
| cubemapTexture.init(faces); | ||
| this.diffusedTextures.set(input, cubemapTexture); | ||
| return cubemapTexture; | ||
| } | ||
|
|
||
| /* | ||
| * used in imageLight, | ||
| * To create a texture from the input non blurry image, if it doesn't already exist | ||
| * Creating 8 different levels of textures according to different | ||
| * sizes and atoring them in `levels` array | ||
| * sizes and storing them in `levels` array | ||
| * Creating a new Mipmap texture with that `levels` array | ||
| * Storing the texture for input image in map called `specularTextures` | ||
| * maps the input p5.Image to a p5.MipmapTexture | ||
|
|
@@ -2087,7 +2123,7 @@ p5.RendererGL = class RendererGL extends p5.Renderer { | |
| // this.activeImageLight has image as a key | ||
| // look up the texture from the diffusedTexture map | ||
| let diffusedLight = this.getDiffusedTexture(this.activeImageLight); | ||
| shader.setUniform('environmentMapDiffused', diffusedLight); | ||
| shader.setUniform('environmentMapDiffusedCubemap', diffusedLight); | ||
|
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am not sure but I feel diffusedLight is also a sampler2D texture, could it be passed as a uniform with samplerCube texture?
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Here, diffusedLight is obtained from
Collaborator
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oooh...sorry. I overlooked this, previously we had diffusedLight with |
||
| let specularLight = this.getSpecularTexture(this.activeImageLight); | ||
| // In p5js the range of shininess is >= 1, | ||
| // Therefore roughness range will be ([0,1]*8)*20 or [0, 160] | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -510,12 +510,64 @@ export function checkWebGLCapabilities({ GL, webglVersion }) { | |
| : gl.getExtension('OES_texture_half_float'); | ||
| const supportsHalfFloatLinear = supportsHalfFloat && | ||
| gl.getExtension('OES_texture_half_float_linear'); | ||
| const supportsCubemap = gl.getExtension('OES_texture_cube_map'); | ||
|
||
| return { | ||
| float: supportsFloat, | ||
| floatLinear: supportsFloatLinear, | ||
| halfFloat: supportsHalfFloat, | ||
| halfFloatLinear: supportsHalfFloatLinear | ||
| halfFloatLinear: supportsHalfFloatLinear, | ||
| cubemap: supportsCubemap | ||
| }; | ||
| } | ||
|
|
||
| export class CubemapTexture extends p5.Texture { | ||
| constructor(renderer, faces, settings) { | ||
| super(renderer, faces, settings); | ||
| } | ||
|
|
||
| glFilter(_filter) { | ||
| const gl = this._renderer.GL; | ||
| // TODO: Support other filters if needed | ||
| return gl.LINEAR; | ||
| } | ||
|
|
||
| _getTextureDataFromSource() { | ||
| return this.src; | ||
| } | ||
|
|
||
| init(faces) { | ||
| const gl = this._renderer.GL; | ||
| this.glTex = gl.createTexture(); | ||
|
|
||
| this.bindTexture(); | ||
| for (let faceIndex = 0; faceIndex < faces.length; faceIndex++) { | ||
| // Set up each face of the cubemap | ||
| gl.texImage2D( | ||
| gl.TEXTURE_CUBE_MAP_POSITIVE_X + faceIndex, | ||
| 0, | ||
| this.glFormat, | ||
| this.glFormat, | ||
| this.glDataType, | ||
| faces[faceIndex] | ||
| ); | ||
| } | ||
|
|
||
| // Set parameters for the cubemap | ||
| gl.texParameteri(gl.TEXTURE_CUBE_MAP | ||
| , gl.TEXTURE_MAG_FILTER, this.glMagFilter); | ||
| gl.texParameteri(gl.TEXTURE_CUBE_MAP | ||
| , gl.TEXTURE_MIN_FILTER, this.glMinFilter); | ||
| gl.texParameteri(gl.TEXTURE_CUBE_MAP | ||
| , gl.TEXTURE_WRAP_S, this.glWrapS); | ||
| gl.texParameteri(gl.TEXTURE_CUBE_MAP | ||
| , gl.TEXTURE_WRAP_T, this.glWrapT); | ||
|
|
||
| this.unbindTexture(); | ||
| } | ||
|
|
||
| update() { | ||
| // Custom update logic, if needed | ||
| } | ||
| } | ||
|
|
||
| export default p5.Texture; | ||
| Original file line number | Diff line number | Diff line change | ||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,23 @@ | ||||||||||||||||
| #version 330 core | ||||||||||||||||
|
||||||||||||||||
| for (const key in defaultShaders) { | |
| defaultShaders[key] = webgl2CompatibilityShader + defaultShaders[key]; | |
| } |
...and by adding an appropriate prefix for the vertex/fragment shaders like this:
p5.js/src/webgl/p5.RendererGL.js
Lines 1745 to 1748 in bda63ff
| this._defaultLightShader = new p5.Shader( | |
| this, | |
| this._webGL2CompatibilityPrefix('vert', 'highp') + | |
| defaultShaders.lightVert, |
To make this file use it, it would involve taking out the #version (that's added by the prefix we add), and replacing out and in with the macros OUT and IN which get #defined to the appropriate keyword depending on what WebGL version is being used. It also means not explicitly declaring out vec4 FragColor and instead using OUT_COLOR, which we also automatically add a definition for.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Might be worth adding a comment mentioning https://learnopengl.com/PBR/IBL/Diffuse-irradiance as a source so that we can refer back to it in the future
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,13 @@ | ||
| #version 330 core | ||
| layout (location = 0) in vec3 aPos; | ||
|
|
||
| out vec3 localPos; | ||
|
|
||
| uniform mat4 projection; | ||
| uniform mat4 view; | ||
|
|
||
| void main() | ||
| { | ||
| localPos = aPos; | ||
| gl_Position = projection * view * vec4(localPos, 1.0); | ||
| } |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -39,7 +39,7 @@ uniform float uQuadraticAttenuation; | |
| // boolean to initiate the calculateImageDiffuse and calculateImageSpecular | ||
| uniform bool uUseImageLight; | ||
| // texture for use in calculateImageDiffuse | ||
| uniform sampler2D environmentMapDiffused; | ||
| uniform sampler2D environmentMapDiffusedCubemap; | ||
|
||
| // texture for use in calculateImageSpecular | ||
| uniform sampler2D environmentMapSpecular; | ||
| // roughness for use in calculateImageSpecular | ||
|
|
@@ -111,7 +111,7 @@ vec3 calculateImageDiffuse( vec3 vNormal, vec3 vViewPosition ){ | |
| vec3 worldCameraPosition = vec3(0.0, 0.0, 0.0); // hardcoded world camera position | ||
| vec3 worldNormal = normalize(vNormal); | ||
| vec2 newTexCoor = mapTextureToNormal( worldNormal ); | ||
| vec4 texture = TEXTURE( environmentMapDiffused, newTexCoor ); | ||
| vec4 texture = textureCube( environmentMapDiffusedCubemap, newTexCoor ); | ||
|
||
| // this is to make the darker sections more dark | ||
| // png and jpg usually flatten the brightness so it is to reverse that | ||
| return smoothstep(vec3(0.0), vec3(0.8), texture.xyz); | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just above this, we create and cache a shader so that we only ever need one copy. Can we add that caching here too?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I have applied caching mechanism to possibly all the shaders. I am not sure whether this aligns with what you were suggesting through this @davepagurek .PLease have a look into the changes I've made.
Thanks.!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we don't want to wrap all the existing shader sources in a caching function, since those are just the sources for one part of a shader (e.g. just the vertex or fragment source, and often not the full source either, since we need to add a prefix to it.) A caching function would be good for this
createShadercall (since you're still creating a new shader every time this line is hit, currently.) A few lines up,this.diffusedShaderalready does caching, but can be refactored to use the same caching system you use here if you're factoring that out into a common pattern.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
oh actually I see that you've added that in
_getCubemapShader. I think rather than making a new shader here, we can just useconst cubemapShader = this._getCubemapShader()instead.