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

WebGLRenderer WebGL2.0 initial support with GLSL 1 to 3 runtime conversion #13717

Merged
merged 41 commits into from
Jul 12, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
d1d38c9
WebGLRenderer WebGL2.0 basic support
takahirox Mar 28, 2018
63839ee
Minor clean up
takahirox Mar 28, 2018
b17356f
Add internalFormat conversion function to WebGLTextures
takahirox Mar 28, 2018
24e0ec4
Update setupFrameBufferTexture()
takahirox Mar 28, 2018
b3af65a
Skip GLSL conversion if material is RawShaderMaterial
takahirox Mar 28, 2018
b1f0db4
Ignore EXT_frag_depth for WebGL 2.0
takahirox Mar 28, 2018
a04bea6
Ignore EXT_shader_texture_lod for WebGL 2.0
takahirox Mar 28, 2018
5392545
Update instancing for WebGL 2.0
takahirox Mar 28, 2018
2b0dac6
Clean up WebGLUtils
takahirox Mar 28, 2018
cf3ff01
Clean up WebGLProgram
takahirox Mar 28, 2018
32cb672
Add .isGLSL3 to ShaderMaterial
takahirox Mar 28, 2018
2456569
Clean up WebGLTextures
takahirox Mar 28, 2018
6065f4f
Update EXT_blend_minmax handling for WebGL 2.0
takahirox Mar 28, 2018
f02117f
Update WebGLUtils for WebGL 2.0 UNSIGNED_INT_24_8
takahirox Mar 28, 2018
c1ff8fc
Update internalFormat for WebGL2.0
takahirox Mar 28, 2018
7a4dc58
Add WebGL_draw_buffers as built-in extensionn for WebGL2.0 to WebGLEx…
takahirox Mar 28, 2018
fd7ced8
Clean up WebGLProgram
takahirox Mar 28, 2018
949623b
Add webgl2 option to WebGLRenderer
takahirox Mar 28, 2018
89c1738
Update WebGLTextures for gl.RGB
takahirox Mar 29, 2018
42831e8
Update getInternalFormat() in WebGLTextures
takahirox Mar 29, 2018
51dad3f
Fix HalfFloatType bug in WebGLUtils
takahirox Mar 29, 2018
e11ed2b
Clean up WebGLUtils
takahirox Mar 29, 2018
ddc4893
Enable webgl2_sandbox example
takahirox Mar 30, 2018
4ec384f
Remove trailing space
takahirox Mar 30, 2018
b53cec2
Do not force POT texture for WebGL2
takahirox Mar 30, 2018
5219c0f
Save isWebGL2 to WebGL context object
takahirox Mar 31, 2018
3f0dfd9
Add webgl2 to Detector
takahirox Mar 31, 2018
062d7db
Remove .isGLSL3 property from ShaderMaterial and determine GLSL3 shad…
takahirox Apr 1, 2018
8ca782f
Rename webgl2 with autoWebgl2
takahirox Apr 4, 2018
325d8e9
Add webgl2 option to WebGLRenderer
takahirox Apr 4, 2018
3cdf35b
Combine webgl2 and autoWebgl2 options to webglVersion
takahirox Apr 4, 2018
dc11ded
Revert the change of WebGLRenderer.setRenderTarget
takahirox Apr 4, 2018
bdbc68b
Revert the change of setupFrameBufferTexture in WebGLTextures
takahirox Apr 4, 2018
46ee5b6
Remove workaround from WebGLExtensions and add if ( gl.isWebGL2 ) ins…
takahirox Apr 4, 2018
ab65cb7
Merge remote-tracking branch 'upstream/dev' into WebGLRendererWebGL2.0
takahirox May 2, 2018
acee27d
Remove webglVersion option from WebGLRenderer constructor
takahirox May 8, 2018
f696296
Revert "Remove webglVersion option from WebGLRenderer constructor"
takahirox May 8, 2018
d177df5
Revert "Enable webgl2_sandbox example"
takahirox May 8, 2018
158fc6c
Update webgl2_sandbox example
takahirox May 8, 2018
fda6fac
Remove webglVersion option from WebGLRenderer constructor.
takahirox May 8, 2018
a18d1a2
Merge branch 'dev' into WebGLRendererWebGL2.0
takahirox May 10, 2018
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions examples/js/Detector.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,19 @@ var Detector = {

}

} )(),
webgl2: ( function () {

try {

var canvas = document.createElement( 'canvas' ); return !! ( window.WebGL2RenderingContext && ( canvas.getContext( 'webgl2' ) ) );

} catch ( e ) {

return false;

}

} )(),
workers: !! window.Worker,
fileapi: window.File && window.FileReader && window.FileList && window.Blob,
Expand Down
7 changes: 5 additions & 2 deletions examples/webgl2_sandbox.html
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
import { Mesh } from '../src/objects/Mesh.js';
import { Fog } from '../src/scenes/Fog.js';
import { Scene } from '../src/scenes/Scene.js';
import { WebGL2Renderer } from '../src/renderers/WebGL2Renderer.js';
import { WebGLRenderer } from '../src/renderers/WebGLRenderer.js';

//

Expand Down Expand Up @@ -89,7 +89,10 @@

}

renderer = new WebGL2Renderer();
var canvas = document.createElement( 'canvas' );
var context = canvas.getContext( 'webgl2' );

renderer = new WebGLRenderer( { canvas: canvas, context: context } );
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
Expand Down
28 changes: 18 additions & 10 deletions src/renderers/WebGLRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -208,6 +208,8 @@ function WebGLRenderer( parameters ) {

}

_gl.isWebGL2 = typeof WebGL2RenderingContext !== 'undefined' && _gl instanceof WebGL2RenderingContext;
Copy link
Collaborator

@fernandojsg fernandojsg Apr 3, 2018

Choose a reason for hiding this comment

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

I wouldn't pollute the webgl context. What about adding a isWebGL2 attribute on the WebGLRenderer itself?

Copy link
Collaborator

Choose a reason for hiding this comment

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

I think the problem is that certain modules of the renderer like WebGLBufferRenderer do not have a reference to the renderer but to the raw WebGL context instead. If we add isWebGL2 to WebGLRenderer, we need to pass it to the respective modules.

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yeah I was thinking about it too, in any case the change will be small, just replacing the WebGLcontext parameter by WebGLRenderer and access the context from the renderer inside the module. Not strong opinion either, but If we pollute the webgl context, should we open the door to practices like babylon's #13717 (comment) ?
I guess @mrdoob should decide here :)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yup, I was gonna comment the same thing about no reference to WebGLRenderer from some modules. I don't prefer passing WebGLRenderer instance to such modules instead of WebGLContext because I don't wanna let them have dependency with WebGLRenderer.

And also, tbh I don't really wanna pollute WebGLContext object. So... .isWebGL2( gl ) function in utils.js? Not strong preference tho.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

What do you think? @mrdoob


// Some experimental-webgl implementations do not have getShaderPrecisionFormat

if ( _gl.getShaderPrecisionFormat === undefined ) {
Expand Down Expand Up @@ -238,14 +240,20 @@ function WebGLRenderer( parameters ) {
function initGLContext() {

extensions = new WebGLExtensions( _gl );
extensions.get( 'WEBGL_depth_texture' );
extensions.get( 'OES_texture_float' );

if ( ! _gl.isWebGL2 ) {

extensions.get( 'WEBGL_depth_texture' );
extensions.get( 'OES_texture_float' );
extensions.get( 'OES_texture_half_float' );
extensions.get( 'OES_texture_half_float_linear' );
extensions.get( 'OES_standard_derivatives' );
extensions.get( 'OES_element_index_uint' );
extensions.get( 'ANGLE_instanced_arrays' );

}

extensions.get( 'OES_texture_float_linear' );
extensions.get( 'OES_texture_half_float' );
extensions.get( 'OES_texture_half_float_linear' );
extensions.get( 'OES_standard_derivatives' );
extensions.get( 'OES_element_index_uint' );
extensions.get( 'ANGLE_instanced_arrays' );

utils = new WebGLUtils( _gl, extensions );

Expand Down Expand Up @@ -837,7 +845,7 @@ function WebGLRenderer( parameters ) {

function setupVertexAttributes( material, program, geometry ) {

if ( geometry && geometry.isInstancedBufferGeometry ) {
if ( geometry && geometry.isInstancedBufferGeometry & ! _gl.isWebGL2 ) {

if ( extensions.get( 'ANGLE_instanced_arrays' ) === null ) {

Expand Down Expand Up @@ -2526,8 +2534,8 @@ function WebGLRenderer( parameters ) {
}

if ( textureType !== UnsignedByteType && utils.convert( textureType ) !== _gl.getParameter( _gl.IMPLEMENTATION_COLOR_READ_TYPE ) && // IE11, Edge and Chrome Mac < 52 (#9513)
! ( textureType === FloatType && ( extensions.get( 'OES_texture_float' ) || extensions.get( 'WEBGL_color_buffer_float' ) ) ) && // Chrome Mac >= 52 and Firefox
! ( textureType === HalfFloatType && extensions.get( 'EXT_color_buffer_half_float' ) ) ) {
! ( textureType === FloatType && ( _gl.isWebGL2 || extensions.get( 'OES_texture_float' ) || extensions.get( 'WEBGL_color_buffer_float' ) ) ) && // Chrome Mac >= 52 and Firefox
! ( textureType === HalfFloatType && ( _gl.isWebGL2 ? extensions.get( 'EXT_color_buffer_float' ) : extensions.get( 'EXT_color_buffer_half_float' ) ) ) ) {

console.error( 'THREE.WebGLRenderer.readRenderTargetPixels: renderTarget is not in UnsignedByteType or implementation defined type.' );
return;
Expand Down
20 changes: 15 additions & 5 deletions src/renderers/webgl/WebGLBufferRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,16 +22,26 @@ function WebGLBufferRenderer( gl, extensions, info ) {

function renderInstances( geometry, start, count ) {

var extension = extensions.get( 'ANGLE_instanced_arrays' );
var extension;

if ( extension === null ) {
if ( gl.isWebGL2 ) {

console.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
return;
extension = gl;

} else {

extension = extensions.get( 'ANGLE_instanced_arrays' );

if ( extension === null ) {

console.error( 'THREE.WebGLBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
return;

}

}

extension.drawArraysInstancedANGLE( mode, start, count, geometry.maxInstancedCount );
extension[ gl.isWebGL2 ? 'drawArraysInstanced' : 'drawArraysInstancedANGLE' ]( mode, start, count, geometry.maxInstancedCount );

info.update( count, mode, geometry.maxInstancedCount );

Expand Down
2 changes: 1 addition & 1 deletion src/renderers/webgl/WebGLCapabilities.js
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,7 @@ function WebGLCapabilities( gl, extensions, parameters ) {
var maxFragmentUniforms = gl.getParameter( gl.MAX_FRAGMENT_UNIFORM_VECTORS );

var vertexTextures = maxVertexTextures > 0;
var floatFragmentTextures = !! extensions.get( 'OES_texture_float' );
var floatFragmentTextures = gl.isWebGL2 || !! extensions.get( 'OES_texture_float' );
var floatVertexTextures = vertexTextures && floatFragmentTextures;

return {
Expand Down
20 changes: 15 additions & 5 deletions src/renderers/webgl/WebGLIndexedBufferRenderer.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,26 @@ function WebGLIndexedBufferRenderer( gl, extensions, info ) {

function renderInstances( geometry, start, count ) {

var extension = extensions.get( 'ANGLE_instanced_arrays' );
var extension;

if ( extension === null ) {
if ( gl.isWebGL2 ) {

console.error( 'THREE.WebGLIndexedBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
return;
extension = gl;

} else {

var extension = extensions.get( 'ANGLE_instanced_arrays' );

if ( extension === null ) {

console.error( 'THREE.WebGLIndexedBufferRenderer: using THREE.InstancedBufferGeometry but hardware does not support extension ANGLE_instanced_arrays.' );
return;

}

}

extension.drawElementsInstancedANGLE( mode, count, type, start * bytesPerElement, geometry.maxInstancedCount );
extension[ gl.isWebGL2 ? 'drawElementsInstanced' : 'drawElementsInstancedANGLE' ]( mode, count, type, start * bytesPerElement, geometry.maxInstancedCount );

info.update( count, mode, geometry.maxInstancedCount );

Expand Down
52 changes: 48 additions & 4 deletions src/renderers/webgl/WebGLProgram.js
Original file line number Diff line number Diff line change
Expand Up @@ -285,7 +285,7 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters

//

var customExtensions = generateExtensions( material.extensions, parameters, extensions );
var customExtensions = gl.isWebGL2 ? '' : generateExtensions( material.extensions, parameters, extensions );

var customDefines = generateDefines( defines );

Expand Down Expand Up @@ -372,7 +372,7 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters
parameters.sizeAttenuation ? '#define USE_SIZEATTENUATION' : '',

parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
parameters.logarithmicDepthBuffer && extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',
parameters.logarithmicDepthBuffer && ( gl.isWebGL2 || extensions.get( 'EXT_frag_depth' ) ) ? '#define USE_LOGDEPTHBUF_EXT' : '',

'uniform mat4 modelMatrix;',
'uniform mat4 modelViewMatrix;',
Expand Down Expand Up @@ -476,9 +476,9 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters
parameters.physicallyCorrectLights ? '#define PHYSICALLY_CORRECT_LIGHTS' : '',

parameters.logarithmicDepthBuffer ? '#define USE_LOGDEPTHBUF' : '',
parameters.logarithmicDepthBuffer && extensions.get( 'EXT_frag_depth' ) ? '#define USE_LOGDEPTHBUF_EXT' : '',
parameters.logarithmicDepthBuffer && ( gl.isWebGL2 || extensions.get( 'EXT_frag_depth' ) ) ? '#define USE_LOGDEPTHBUF_EXT' : '',

parameters.envMap && extensions.get( 'EXT_shader_texture_lod' ) ? '#define TEXTURE_LOD_EXT' : '',
parameters.envMap && ( gl.isWebGL2 || extensions.get( 'EXT_shader_texture_lod' ) ) ? '#define TEXTURE_LOD_EXT' : '',

'uniform mat4 viewMatrix;',
'uniform vec3 cameraPosition;',
Expand Down Expand Up @@ -514,6 +514,50 @@ function WebGLProgram( renderer, extensions, code, material, shader, parameters
vertexShader = unrollLoops( vertexShader );
fragmentShader = unrollLoops( fragmentShader );

if ( gl.isWebGL2 && ! material.isRawShaderMaterial ) {

var isGLSL3ShaderMaterial = false;

var versionRegex = /^\s*#version\s+300\s+es\s*\n/;

if ( material.isShaderMaterial &&
vertexShader.match( versionRegex ) !== null &&
fragmentShader.match( versionRegex ) !== null ) {

isGLSL3ShaderMaterial = true;

vertexShader = vertexShader.replace( versionRegex, '' );
fragmentShader = fragmentShader.replace( versionRegex, '' );

}

// GLSL 3.0 conversion
prefixVertex = [
'#version 300 es\n',
'#define attribute in',
'#define varying out',
'#define texture2D texture'
].join( '\n' ) + '\n' + prefixVertex;

prefixFragment = [
'#version 300 es\n',
'#define varying in',
isGLSL3ShaderMaterial ? '' : 'out highp vec4 pc_fragColor;',
isGLSL3ShaderMaterial ? '' : '#define gl_FragColor pc_fragColor',
'#define gl_FragDepthEXT gl_FragDepth',
'#define texture2D texture',
'#define textureCube texture',
'#define texture2DProj textureProj',
'#define texture2DLodEXT textureLod',
'#define texture2DProjLodEXT textureProjLod',
'#define textureCubeLodEXT textureLod',
'#define texture2DGradEXT textureGrad',
'#define texture2DProjGradEXT textureProjGrad',
'#define textureCubeGradEXT textureGrad'
].join( '\n' ) + '\n' + prefixFragment;

}

var vertexGlsl = prefixVertex + vertexShader;
var fragmentGlsl = prefixFragment + fragmentShader;

Expand Down
4 changes: 2 additions & 2 deletions src/renderers/webgl/WebGLState.js
Original file line number Diff line number Diff line change
Expand Up @@ -434,9 +434,9 @@ function WebGLState( gl, extensions, utils ) {

if ( attributeDivisors[ attribute ] !== meshPerAttribute ) {

var extension = extensions.get( 'ANGLE_instanced_arrays' );
var extension = gl.isWebGL2 ? gl : extensions.get( 'ANGLE_instanced_arrays' );

extension.vertexAttribDivisorANGLE( attribute, meshPerAttribute );
extension[ gl.isWebGL2 ? 'vertexAttribDivisor' : 'vertexAttribDivisorANGLE' ]( attribute, meshPerAttribute );
attributeDivisors[ attribute ] = meshPerAttribute;

}
Expand Down
Loading