Переглянути джерело

fragDepth ext support, better ext availablitity handling

Alexander Rose 6 роки тому
батько
коміт
126ef26a34
3 змінених файлів з 61 додано та 16 видалено
  1. 41 14
      src/mol-gl/shader-code.ts
  2. 7 0
      src/mol-gl/webgl/compat.ts
  3. 13 2
      src/mol-gl/webgl/context.ts

+ 41 - 14
src/mol-gl/shader-code.ts

@@ -14,39 +14,50 @@ export type DefineValues = { [k: string]: ValueCell<DefineType> }
 
 const shaderCodeId = idFactory()
 
+export interface ShaderExtensions {
+    readonly standardDerivatives: boolean
+    readonly fragDepth: boolean
+}
+
 export interface ShaderCode {
-    id: number
-    vert: string
-    frag: string
+    readonly id: number
+    readonly vert: string
+    readonly frag: string
+    readonly extensions: ShaderExtensions
 }
 
-export function ShaderCode(vert: string, frag: string): ShaderCode {
-    return { id: shaderCodeId(), vert, frag }
+export function ShaderCode(vert: string, frag: string, extensions: ShaderExtensions): ShaderCode {
+    return { id: shaderCodeId(), vert, frag, extensions }
 }
 
 export const PointsShaderCode = ShaderCode(
     require('mol-gl/shader/points.vert'),
-    require('mol-gl/shader/points.frag')
+    require('mol-gl/shader/points.frag'),
+    { standardDerivatives: false, fragDepth: false }
 )
 
 export const LinesShaderCode = ShaderCode(
     require('mol-gl/shader/lines.vert'),
-    require('mol-gl/shader/lines.frag')
+    require('mol-gl/shader/lines.frag'),
+    { standardDerivatives: false, fragDepth: false }
 )
 
 export const MeshShaderCode = ShaderCode(
     require('mol-gl/shader/mesh.vert'),
-    require('mol-gl/shader/mesh.frag')
+    require('mol-gl/shader/mesh.frag'),
+    { standardDerivatives: true, fragDepth: false }
 )
 
 export const GaussianDensityShaderCode = ShaderCode(
     require('mol-gl/shader/gaussian-density.vert'),
-    require('mol-gl/shader/gaussian-density.frag')
+    require('mol-gl/shader/gaussian-density.frag'),
+    { standardDerivatives: false, fragDepth: false }
 )
 
 export const DirectVolumeShaderCode = ShaderCode(
     require('mol-gl/shader/direct-volume.vert'),
-    require('mol-gl/shader/direct-volume.frag')
+    require('mol-gl/shader/direct-volume.frag'),
+    { standardDerivatives: false, fragDepth: true }
 )
 
 export type ShaderDefines = {
@@ -74,8 +85,20 @@ function getDefinesCode (defines: ShaderDefines) {
     return lines.join('\n') + '\n'
 }
 
-const glsl100FragPrefix = `#extension GL_OES_standard_derivatives : enable
-`
+function getGlsl100FragPrefix(ctx: Context, extensions: ShaderExtensions) {
+    const prefix: string[] = []
+    if (extensions.standardDerivatives) {
+        prefix.push('#extension GL_OES_standard_derivatives : enable')
+        prefix.push('#define enabledStandardDerivatives')
+    }
+    if (extensions.fragDepth) {
+        if (ctx.extensions.fragDepth) {
+            prefix.push('#extension GL_EXT_frag_depth : enable')
+            prefix.push('#define enabledFragDepth')
+        }
+    }
+    return prefix.join('\n') + '\n'
+}
 
 const glsl300VertPrefix = `#version 300 es
 #define attribute in
@@ -89,16 +112,20 @@ layout(location = 0) out highp vec4 out_FragColor;
 #define gl_FragColor out_FragColor
 #define gl_FragDepthEXT gl_FragDepth
 #define texture2D texture
+
+#define enabledStandardDerivatives
+#define enabledFragDepth
 `
 
 export function addShaderDefines(ctx: Context, defines: ShaderDefines, shaders: ShaderCode): ShaderCode {
     const { isWebGL2 } = ctx
     const header = getDefinesCode(defines)
     const vertPrefix = isWebGL2 ? glsl300VertPrefix : ''
-    const fragPrefix = isWebGL2 ? glsl300FragPrefix : glsl100FragPrefix
+    const fragPrefix = isWebGL2 ? glsl300FragPrefix : getGlsl100FragPrefix(ctx, shaders.extensions)
     return {
         id: shaderCodeId(),
         vert: `${vertPrefix}${header}${shaders.vert}`,
-        frag: `${fragPrefix}${header}${shaders.frag}`
+        frag: `${fragPrefix}${header}${shaders.frag}`,
+        extensions: shaders.extensions
     }
 }

+ 7 - 0
src/mol-gl/webgl/compat.ts

@@ -121,4 +121,11 @@ export function getBlendMinMax(gl: GLRenderingContext): COMPAT_blend_minmax | nu
         if (ext === null) return null
         return { MIN: ext.MIN_EXT, MAX: ext.MAX_EXT }
     }
+}
+
+export interface COMPAT_frag_depth {
+}
+
+export function getFragDepth(gl: GLRenderingContext): COMPAT_frag_depth | null {
+    return isWebGL2(gl) ? {} : gl.getExtension('EXT_frag_depth')
 }

+ 13 - 2
src/mol-gl/webgl/context.ts

@@ -6,7 +6,7 @@
 
 import { createProgramCache, ProgramCache } from './program'
 import { createShaderCache, ShaderCache } from './shader'
-import { GLRenderingContext, COMPAT_instanced_arrays, COMPAT_standard_derivatives, COMPAT_vertex_array_object, getInstancedArrays, getStandardDerivatives, getVertexArrayObject, isWebGL2, COMPAT_element_index_uint, getElementIndexUint, COMPAT_texture_float, getTextureFloat, COMPAT_texture_float_linear, getTextureFloatLinear, COMPAT_blend_minmax, getBlendMinMax } from './compat';
+import { GLRenderingContext, COMPAT_instanced_arrays, COMPAT_standard_derivatives, COMPAT_vertex_array_object, getInstancedArrays, getStandardDerivatives, getVertexArrayObject, isWebGL2, COMPAT_element_index_uint, getElementIndexUint, COMPAT_texture_float, getTextureFloat, COMPAT_texture_float_linear, getTextureFloatLinear, COMPAT_blend_minmax, getBlendMinMax, getFragDepth, COMPAT_frag_depth } from './compat';
 
 export function getGLContext(canvas: HTMLCanvasElement, contextAttributes?: WebGLContextAttributes): GLRenderingContext | null {
     function getContext(contextId: 'webgl' | 'experimental-webgl' | 'webgl2') {
@@ -105,6 +105,7 @@ type Extensions = {
     textureFloatLinear: COMPAT_texture_float_linear
     elementIndexUint: COMPAT_element_index_uint | null
     vertexArrayObject: COMPAT_vertex_array_object | null
+    fragDepth: COMPAT_frag_depth | null
 }
 
 /** A WebGL context object, including the rendering context, resource caches and counts */
@@ -165,6 +166,10 @@ export function createContext(gl: GLRenderingContext): Context {
     if (vertexArrayObject === null) {
         console.log('Could not find support for "vertex_array_object"')
     }
+    const fragDepth = getFragDepth(gl)
+    if (fragDepth === null) {
+        console.log('Could not find support for "frag_depth"')
+    }
 
     const shaderCache = createShaderCache()
     const programCache = createProgramCache()
@@ -172,6 +177,11 @@ export function createContext(gl: GLRenderingContext): Context {
     const parameters = {
         maxTextureSize: gl.getParameter(gl.MAX_TEXTURE_SIZE),
         maxDrawBuffers: isWebGL2(gl) ? gl.getParameter(gl.MAX_DRAW_BUFFERS) : 0,
+        maxVertexTextureImageUnits: gl.getParameter(gl.MAX_VERTEX_TEXTURE_IMAGE_UNITS),
+    }
+
+    if (parameters.maxVertexTextureImageUnits < 4) {
+        throw new Error('Need "MAX_VERTEX_TEXTURE_IMAGE_UNITS" >= 4')
     }
 
     return {
@@ -184,7 +194,8 @@ export function createContext(gl: GLRenderingContext): Context {
             textureFloat,
             textureFloatLinear,
             elementIndexUint,
-            vertexArrayObject
+            vertexArrayObject,
+            fragDepth
         },
         pixelRatio: getPixelRatio(),