Skip to content
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

Light texture #7060

Closed
wants to merge 6 commits into from
Closed

Light texture #7060

wants to merge 6 commits into from

Conversation

gero3
Copy link
Contributor

@gero3 gero3 commented Aug 27, 2015

This adds a texture to upload the lights to the gpu instead of using just uniforms as proposed in #7037.

Things that don't work correctly right now:

  • It constantly updates this now.
  • The texture probably doesn't have the correct properies for most usecases.
  • It only handles 128 lights without counting ambient light.

@bhouston
Copy link
Contributor

Here is an online version of the PR:

http://exocortex.github.io/three.js/pr7060/examples
http://exocortex.github.io/three.js/pr7060/examples/#webgl_lights_pointlights2

Seems very performance on my desktop.

@bhouston
Copy link
Contributor

Errors on Nexus 5:

THREE.WebGLRenderer: OES_texture_float_linear extension not supported.
three.min.js:610 THREE.WebGLProgram: gl.getProgramInfoLog() --From Vertex Shader:
--From Fragment Shader:
Link was successful.

three.min.js:588 WebGL: drawElements: texture bound to texture unit 1 is not renderable. It maybe non-power-of-2 and have incompatible texture filtering or is not 'texture complete'. Or the texture is Float or Half Float type with linear filtering while OES_float_linear or OES_half_float_linear extension is not enabled.
three.min.js:610 THREE.WebGLProgram: gl.getProgramInfoLog() --From Vertex Shader:
--From Fragment Shader:
Link was successful.

255three.min.js:586 WebGL: drawArrays: texture bound to texture unit 1 is not renderable. It maybe non-power-of-2 and have incompatible texture filtering or is not 'texture complete'. Or the texture is Float or Half Float type with linear filtering while OES_float_linear or OES_half_float_linear extension is not enabled.
three.min.js:586 WebGL: too many errors, no more errors will be reported to the console for this context.
three.min.js:610 THREE.WebGLProgram: gl.getProgramInfoLog() --From Vertex Shader:
--From Fragment Shader:
Link was successful.

The current version up on threejs.org works well though, so I think these are specific to the lightTexture. I'm using Remote Debugging in Chrome to get the above data.

@@ -66,6 +66,7 @@ THREE.UniformsLib = {

lights: {

"lightTexture" : { type: "t", value: new THREE.DataTexture( new Float32Array( 128 * 4 * 4 ), 4, 128, THREE.RGBAFormat, THREE.FloatType ) },
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think the data texture should be nearest for filtering and no anisotropy.

Thus something like:

new THREE.DataTexture( new Float32Array( 128 * 4 * 4 ), 4, 128,
    THREE.RGBAFormat, THREE.FloatType,
    undefined, undefined,
    THREE.NearestFilter,  THREE.NearestFilter, 0 )

I wonder why DataTextures do not default to nearest,
if they are data then interpolating doesn't make much sense.

@gero3
Copy link
Contributor Author

gero3 commented Aug 27, 2015

Errors on Nexus 5 should be fixed now because it returns to using unforms when there are no float textures.

I also improved the constructor of the texture with what you suggested.

@bhouston
Copy link
Contributor

@gero3, the Nexus 5 has float texture support. Here are the extensions I had:

image

One issue was with the DataTexture doing linear interpolation which requires the WEBGL_texture_float_linear extension which my Nexus 5 doesn't have.

It may also have required a power of 2 texture -- not sure about that.

@gero3
Copy link
Contributor Author

gero3 commented Aug 31, 2015

@bhouston a few questions:

  • Would this be activated by material or just by renderer??
  • How does lambert materials need to work with a light texture??

@bhouston
Copy link
Contributor

I think that uniforms are likely faster than data textures -- conjecture but I think it is probably right.

Thus we likely want to use uniforms when we can. Thus we could automatically turn on data textyres for lights once we hit a light limit. We could calculate the number of lights we think can reasonably fix into a shader and once we exceed that we switch to a light data texture approach?

We could actually hard code this limit to something reasonable to avoid having to do the tricky math of fixing out when it will switch over.

I think this is fairly cost free because we already recompile shaders when the number of lights change.

We could also have a flag that you can set somehow that forces a light data texture even if it isn't technically needed - which would be useful for testing.

@bhouston
Copy link
Contributor

How does lambert materials need to work with a light texture??

I guess we could support this by having a renderer flag that disables light textures no matter how many?

There are actually different limits to the number of uniforms for vertex and fragment , and the limit is usually higher on vertex. Thus data textures are not as useful for lambert because the limit is so high.

I guess I would prefer to not have to do both light textures and light uniforms.

But if we needed to have both, one could write a function called, isLightDataTextureNeeded() and isLightUniformsNeeded() and you could have some logic that determines if they are -- based on what is in the scene (# of lights and existance of a lambert material.) (For maximum generality, you could have booleans on a material that state on what type of lighting it supports and that forces behavior on the part of the renderer, but that seems complex.) For both light texture and light unfiroms one could have a shader define if they are present, and it is up to the shader itself to figure out if both defines are present, which it prefers to use - thus you can have lambert using uniforms and other fragment shaders using the data texture.

@bhouston
Copy link
Contributor

BTW in Clara.io we do not support Lambert shading and if we did, we would fake it with a fragment shader doing the lighting on a per pixel basis. It just isn't worth it for us to spend the time to support a vertex based lighting scheme -- too many special case exceptions for low quality results.

@gero3
Copy link
Contributor Author

gero3 commented Aug 31, 2015

Indeed, Lambert is actually not that important here since 256 vertex uniforms are the minimum. That is close to 60 lights normally.

@tschw
Copy link
Contributor

tschw commented Aug 31, 2015

Indeed, Lambert is actually not that important here since 256 vertex uniforms are the minimum. That is close to 60 lights normally.

Did you forget to switch off "Personal computers" when viewing webglstats.com? It appears that more and more phones only have 128 MAX_VERTEX_UNIFORM_VECTORS. With several matrices, maybe animation, plus some occupied by the implementation for its own use, it's not that plenty - just less of a catastrophic situation than in the fragment shader...

BTW in Clara.io we do not support Lambert shading and if we did, we would fake it with a fragment shader doing the lighting on a per pixel basis.

A "Lambertian reflector" describes a material that does not produce specular highlights. Lambert would be pleased and probably call it less of a fake than the Three.js implementation using Gouraud shading :-).

@bhouston
Copy link
Contributor

bhouston commented Aug 31, 2015 via email

@threejsworker
Copy link

The examples of this pullrequest are now built and visible in threejsworker. To view them, go to the following link:

http://threejsworker.com/viewpullrequest.html#7060

1 similar comment
@threejsworker
Copy link

The examples of this pullrequest are now built and visible in threejsworker. To view them, go to the following link:

http://threejsworker.com/viewpullrequest.html#7060

@mrdoob
Copy link
Owner

mrdoob commented Nov 5, 2015

Would you mind re-implementing this with the new/refactored lights code?

@bhouston bhouston mentioned this pull request Mar 25, 2016
12 tasks
@gero3 gero3 closed this Aug 19, 2016
@gero3 gero3 deleted the lightTexture branch August 19, 2016 08:38
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants