From 31afc465045bbe1dfefe98f1c8c32a04044973bb Mon Sep 17 00:00:00 2001 From: lindsay Date: Wed, 25 Sep 2024 23:31:30 +0200 Subject: [PATCH] WebGLRenderer refactorings + SAO --- packages/webglrenderer/src/Layer.ts | 3 + packages/webglrenderer/src/RENDER_PASSES.ts | 6 +- packages/webglrenderer/src/RenderContext.ts | 10 +- .../src/SAODepthLimitedBlurRenderer.ts | 332 +++++++++++++++ .../webglrenderer/src/SAOOcclusionRenderer.ts | 390 ++++++++++++++++++ .../src/WebGLRenderBufferManager.ts | 10 +- packages/webglrenderer/src/WebGLRenderer.ts | 161 +++++--- .../webglrenderer/src/WebGLRendererMesh.ts | 6 - .../webglrenderer/src/WebGLRendererModel.ts | 10 +- packages/webglrenderer/src/vbo/VBORenderer.ts | 299 +++++++------- .../webglrenderer/src/vbo/VBORendererSet.ts | 44 +- .../src/vbo/batching/VBOBatchingLayer.ts | 53 ++- .../vbo/batching/VBOBatchingRenderState.ts | 2 + ...s => VBOLinesBatchingDrawColorRenderer.ts} | 26 +- .../VBOLinesBatchingPickMeshRenderer.ts | 27 +- .../VBOLinesBatchingSilhouetteRenderer.ts | 26 +- .../lines/renderers/rendererFactory.ts | 6 +- ... => VBOPointsBatchingDrawColorRenderer.ts} | 21 +- .../VBOPointsBatchingPickMeshRenderer.ts | 147 ++----- .../VBOPointsBatchingSilhouetteRenderer.ts | 131 ++---- .../points/renderers/rendererFactory.ts | 6 +- ... VBOTrianglesBatchingDrawColorRenderer.ts} | 8 +- ...BOTrianglesBatchingDrawColorSAORenderer.ts | 51 +++ .../VBOTrianglesBatchingDrawDepthRenderer.ts | 46 +++ .../VBOTrianglesBatchingEdgesDrawRenderer.ts | 12 +- ...rianglesBatchingEdgesSilhouetteRenderer.ts | 14 +- .../VBOTrianglesBatchingPickMeshRenderer.ts | 14 +- .../VBOTrianglesBatchingSilhouetteRenderer.ts | 18 +- .../triangles/renderers/rendererFactory.ts | 17 +- .../src/vbo/instancing/VBOInstancingLayer.ts | 84 ++-- .../instancing/VBOInstancingRenderState.ts | 1 + ...=> VBOLinesInstancingDrawColorRenderer.ts} | 8 +- .../VBOLinesInstancingPickMeshRenderer.ts | 13 +- .../VBOLinesInstancingSilhouetteRenderer.ts | 18 +- .../lines/renderers/rendererFactory.ts | 6 +- ...BOTrianglesInstancingDrawColorRenderer.ts} | 10 +- ...TrianglesInstancingDrawColorSAORenderer.ts | 50 +++ ...VBOTrianglesInstancingDrawDepthRenderer.ts | 46 +++ ...VBOTrianglesInstancingEdgesDrawRenderer.ts | 12 +- ...anglesInstancingEdgesSilhouetteRenderer.ts | 14 +- .../VBOTrianglesInstancingPickMeshRenderer.ts | 14 +- ...BOTrianglesInstancingSilhouetteRenderer.ts | 14 +- .../triangles/renderers/rendererFactory.ts | 16 +- packages/webglutils/src/WebGLRenderBuffer.ts | 2 +- 44 files changed, 1569 insertions(+), 635 deletions(-) create mode 100644 packages/webglrenderer/src/SAODepthLimitedBlurRenderer.ts create mode 100644 packages/webglrenderer/src/SAOOcclusionRenderer.ts rename packages/webglrenderer/src/vbo/batching/lines/renderers/{VBOLinesBatchingDrawRenderer.ts => VBOLinesBatchingDrawColorRenderer.ts} (61%) rename packages/webglrenderer/src/vbo/batching/points/renderers/{VBOPointsBatchingDrawRenderer.ts => VBOPointsBatchingDrawColorRenderer.ts} (72%) rename packages/webglrenderer/src/vbo/batching/triangles/renderers/{VBOTrianglesBatchingDrawRenderer.ts => VBOTrianglesBatchingDrawColorRenderer.ts} (85%) create mode 100644 packages/webglrenderer/src/vbo/batching/triangles/renderers/VBOTrianglesBatchingDrawColorSAORenderer.ts create mode 100644 packages/webglrenderer/src/vbo/batching/triangles/renderers/VBOTrianglesBatchingDrawDepthRenderer.ts rename packages/webglrenderer/src/vbo/instancing/lines/renderers/{VBOLinesInstancingDrawRenderer.ts => VBOLinesInstancingDrawColorRenderer.ts} (85%) rename packages/webglrenderer/src/vbo/instancing/triangles/renderers/{VBOTrianglesInstancingDrawRenderer.ts => VBOTrianglesInstancingDrawColorRenderer.ts} (85%) create mode 100644 packages/webglrenderer/src/vbo/instancing/triangles/renderers/VBOTrianglesInstancingDrawColorSAORenderer.ts create mode 100644 packages/webglrenderer/src/vbo/instancing/triangles/renderers/VBOTrianglesInstancingDrawDepthRenderer.ts diff --git a/packages/webglrenderer/src/Layer.ts b/packages/webglrenderer/src/Layer.ts index 5dd12dd37..b22b9c932 100644 --- a/packages/webglrenderer/src/Layer.ts +++ b/packages/webglrenderer/src/Layer.ts @@ -17,6 +17,7 @@ export interface Layer { layerIndex: number; sortId: string; meshCounts: MeshCounts[]; + saoSupported: boolean; //--------------------------------------------------------- // Builder methods @@ -68,6 +69,8 @@ export interface Layer { drawColorOpaque() : void; + drawColorSAOOpaque(): void; + drawColorTranslucent(): void; drawDepth(): void; diff --git a/packages/webglrenderer/src/RENDER_PASSES.ts b/packages/webglrenderer/src/RENDER_PASSES.ts index 84159edff..b5197568a 100755 --- a/packages/webglrenderer/src/RENDER_PASSES.ts +++ b/packages/webglrenderer/src/RENDER_PASSES.ts @@ -8,10 +8,10 @@ export const RENDER_PASSES = { NOT_RENDERED: 0, - // Normal rendering - mutually exclusive modes + // Draw color, or draw depth or normals for post-effects - COLOR_OPAQUE: 1, - COLOR_TRANSPARENT: 2, + DRAW_OPAQUE: 1, + DRAW_TRANSPARENT: 2, // Accents silhouette rendering - mutually exclusive modes diff --git a/packages/webglrenderer/src/RenderContext.ts b/packages/webglrenderer/src/RenderContext.ts index baa790e74..a79c4fb25 100755 --- a/packages/webglrenderer/src/RenderContext.ts +++ b/packages/webglrenderer/src/RenderContext.ts @@ -41,11 +41,6 @@ export class RenderContext { */ public pbrEnabled: boolean; - /** - * Whether SAO is currently enabled during the current frame. - */ - public withSAO: boolean; - /** * Whether backfaces are currently enabled during the current frame. */ @@ -125,7 +120,7 @@ export class RenderContext { /** * The occlusion rendering texture. */ - public occlusionTexture: WebGLAbstractTexture | null; + public saoOcclusionTexture: WebGLAbstractTexture | null; public pickClipPos: FloatArrayParam; @@ -145,7 +140,6 @@ export class RenderContext { reset() { this.lastProgramId = -1; this.pbrEnabled = false; - this.withSAO = false; this.backfaces = false; this.frontface = true; this.textureUnit = 0; @@ -157,7 +151,7 @@ export class RenderContext { this.pickZFar = 5000; this.pickInvisible = false; this.lineWidth = 1; - this.occlusionTexture = null; + this.saoOcclusionTexture = null; } /** diff --git a/packages/webglrenderer/src/SAODepthLimitedBlurRenderer.ts b/packages/webglrenderer/src/SAODepthLimitedBlurRenderer.ts new file mode 100644 index 000000000..63d25d2d5 --- /dev/null +++ b/packages/webglrenderer/src/SAODepthLimitedBlurRenderer.ts @@ -0,0 +1,332 @@ +import {RenderContext} from "./RenderContext"; +import {WebGLArrayBuf, WebGLAttribute, WebGLProgram, WebGLRenderBuffer} from "@xeokit/webglutils"; +import {PerspectiveProjectionType} from "@xeokit/constants"; +import {View} from "@xeokit/viewer"; + +const blurStdDev = 4; +const blurDepthCutoff = 0.01; +const KERNEL_RADIUS = 16; + +const sampleOffsetsVert = new Float32Array(createSampleOffsets(KERNEL_RADIUS + 1, [0, 1])); +const sampleOffsetsHor = new Float32Array(createSampleOffsets(KERNEL_RADIUS + 1, [1, 0])); +const sampleWeights = new Float32Array(createSampleWeights(KERNEL_RADIUS + 1, blurStdDev)); + +const tempVec2a = new Float32Array(2); + +/** + * SAO implementation inspired from previous SAO work in THREE.js by ludobaka / ludobaka.github.io and bhouston + * @private + */ +export class SAODepthLimitedBlurRenderer { + + #renderContext: RenderContext; + #program: WebGLProgram; + #programError: boolean; + #aPosition: WebGLAttribute; + #aUV: WebGLAttribute; + #uDepthTexture: string; + #uOcclusionTexture: string; + #uViewport: WebGLUniformLocation; + #uCameraNear: WebGLUniformLocation; + #uCameraFar: WebGLUniformLocation; + #uCameraProjectionMatrix: WebGLUniformLocation; + #uCameraInverseProjectionMatrix: WebGLUniformLocation; + #uvBuf: WebGLArrayBuf; + #positionsBuf: WebGLArrayBuf; + #indicesBuf: WebGLArrayBuf; + #uDepthCutoff: WebGLUniformLocation; + #uSampleOffsets: WebGLUniformLocation; + #uSampleWeights: WebGLUniformLocation; + + constructor(params: { + renderContext: RenderContext + }) { + + this.#renderContext = params.renderContext; + + // The program + + this.#program = null; + this.#programError = false; + + // Variable locations + + this.#aPosition = null; + this.#aUV = null; + + this.#uDepthTexture = "uDepthTexture"; + this.#uOcclusionTexture = "uOcclusionTexture"; + + this.#uViewport = null; + this.#uCameraNear = null; + this.#uCameraFar = null; + this.#uCameraProjectionMatrix = null; + this.#uCameraInverseProjectionMatrix = null; + + // VBOs + + this.#uvBuf = null; + this.#positionsBuf = null; + this.#indicesBuf = null; + + this.init(); + } + + init() { + + const gl = this.#renderContext.gl; + + this.#program = new WebGLProgram(gl, { + + vertex: `#version 300 es + precision highp float; + precision highp int; + + in vec3 aPosition; + in vec2 aUV; + uniform vec2 uViewport; + out vec2 vUV; + out vec2 vInvSize; + void main () { + vUV = aUV; + vInvSize = 1.0 / uViewport; + gl_Position = vec4(aPosition, 1.0); + }`, + + fragment: + `#version 300 es + precision highp float; + precision highp int; + + #define PI 3.14159265359 + #define PI2 6.28318530718 + #define EPSILON 1e-6 + + #define KERNEL_RADIUS ${KERNEL_RADIUS} + + in vec2 vUV; + in vec2 vInvSize; + + uniform sampler2D uDepthTexture; + uniform sampler2D uOcclusionTexture; + + uniform float uCameraNear; + uniform float uCameraFar; + uniform float uDepthCutoff; + + uniform vec2 uSampleOffsets[ KERNEL_RADIUS + 1 ]; + uniform float uSampleWeights[ KERNEL_RADIUS + 1 ]; + + const float unpackDownscale = 255. / 256.; + + const vec3 packFactors = vec3( 256. * 256. * 256., 256. * 256., 256. ); + const vec4 unpackFactors = unpackDownscale / vec4( packFactors, 1. ); + + const float packUpscale = 256. / 255.; + + const float shiftRights = 1. / 256.; + + float unpackRGBAToFloat( const in vec4 v ) { + return dot( floor( v * 255.0 + 0.5 ) / 255.0, unpackFactors ); + } + + vec4 packFloatToRGBA( const in float v ) { + vec4 r = vec4( fract( v * packFactors ), v ); + r.yzw -= r.xyz * shiftRights; + return r * packUpscale; + } + + float viewZToOrthographicDepth( const in float viewZ) { + return ( viewZ + uCameraNear ) / ( uCameraNear - uCameraFar ); + } + + float orthographicDepthToViewZ( const in float linearClipZ) { + return linearClipZ * ( uCameraNear - uCameraFar ) - uCameraNear; + } + + float viewZToPerspectiveDepth( const in float viewZ) { + return (( uCameraNear + viewZ ) * uCameraFar ) / (( uCameraFar - uCameraNear ) * viewZ ); + } + + float perspectiveDepthToViewZ( const in float invClipZ) { + return ( uCameraNear * uCameraFar ) / ( ( uCameraFar - uCameraNear ) * invClipZ - uCameraFar ); + } + + float getDepth( const in vec2 screenPosition ) { + return vec4(texture(uDepthTexture, screenPosition)).r; + } + + float getViewZ( const in float depth ) { + return perspectiveDepthToViewZ( depth ); + } + + out vec4 outColor; + + void main() { + + float depth = getDepth( vUV ); + if( depth >= ( 1.0 - EPSILON ) ) { + discard; + } + + float centerViewZ = -getViewZ( depth ); + bool rBreak = false; + bool lBreak = false; + + float weightSum = uSampleWeights[0]; + float occlusionSum = unpackRGBAToFloat(texture( uOcclusionTexture, vUV )) * weightSum; + + for( int i = 1; i <= KERNEL_RADIUS; i ++ ) { + + float sampleWeight = uSampleWeights[i]; + vec2 sampleUVOffset = uSampleOffsets[i] * vInvSize; + + vec2 sampleUV = vUV + sampleUVOffset; + float viewZ = -getViewZ( getDepth( sampleUV ) ); + + if( abs( viewZ - centerViewZ ) > uDepthCutoff ) { + rBreak = true; + } + + if( ! rBreak ) { + occlusionSum += unpackRGBAToFloat(texture( uOcclusionTexture, sampleUV )) * sampleWeight; + weightSum += sampleWeight; + } + + sampleUV = vUV - sampleUVOffset; + viewZ = -getViewZ( getDepth( sampleUV ) ); + + if( abs( viewZ - centerViewZ ) > uDepthCutoff ) { + lBreak = true; + } + + if( ! lBreak ) { + occlusionSum += unpackRGBAToFloat(texture( uOcclusionTexture, sampleUV )) * sampleWeight; + weightSum += sampleWeight; + } + } + + outColor = packFloatToRGBA(occlusionSum / weightSum); + }` + }); + + if (this.#program.errors) { + console.error(this.#program.errors.join("\n")); + this.#programError = true; + return; + } + + const uv = new Float32Array([1, 1, 0, 1, 0, 0, 1, 0]); + const positions = new Float32Array([1, 1, 0, -1, 1, 0, -1, -1, 0, 1, -1, 0]); + + // Mitigation: if Uint8Array is used, the geometry is corrupted on OSX when using Chrome with data-textures + const indices = new Uint32Array([0, 1, 2, 0, 2, 3]); + + this.#positionsBuf = new WebGLArrayBuf(gl, gl.ARRAY_BUFFER, positions, positions.length, 3, gl.STATIC_DRAW); + this.#uvBuf = new WebGLArrayBuf(gl, gl.ARRAY_BUFFER, uv, uv.length, 2, gl.STATIC_DRAW); + this.#indicesBuf = new WebGLArrayBuf(gl, gl.ELEMENT_ARRAY_BUFFER, indices, indices.length, 1, gl.STATIC_DRAW); + + this.#program.bind(); + + this.#uViewport = this.#program.getLocation("uViewport"); + + this.#uCameraNear = this.#program.getLocation("uCameraNear"); + this.#uCameraFar = this.#program.getLocation("uCameraFar"); + + this.#uDepthCutoff = this.#program.getLocation("uDepthCutoff"); + + this.#uSampleOffsets = gl.getUniformLocation(this.#program.handle, "uSampleOffsets"); + this.#uSampleWeights = gl.getUniformLocation(this.#program.handle, "uSampleWeights"); + + this.#aPosition = this.#program.getAttribute("aPosition"); + this.#aUV = this.#program.getAttribute("aUV"); + } + + render(params : { + view: View, + depthRenderBuffer: WebGLRenderBuffer, + occlusionRenderBuffer: WebGLRenderBuffer, + direction: number + }) { + + if (this.#programError) { + return; + } + + const {view, depthRenderBuffer, occlusionRenderBuffer, direction} = params; + const gl = this.#renderContext.gl; + const program = this.#program; + const viewportWidth = gl.drawingBufferWidth; + const viewportHeight = gl.drawingBufferHeight; + const projection = view.camera.projectionType === PerspectiveProjectionType + ? view.camera.perspectiveProjection + : view.camera.orthoProjection; + const near = projection.near; + const far = projection.far; + + gl.viewport(0, 0, viewportWidth, viewportHeight); + gl.clearColor(0, 0, 0, 1); + gl.enable(gl.DEPTH_TEST); + gl.disable(gl.BLEND); + gl.frontFace(gl.CCW); + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); + + program.bind(); + + tempVec2a[0] = viewportWidth; + tempVec2a[1] = viewportHeight; + + gl.uniform2fv(this.#uViewport, tempVec2a); + gl.uniform1f(this.#uCameraNear, near); + gl.uniform1f(this.#uCameraFar, far); + + gl.uniform1f(this.#uDepthCutoff, blurDepthCutoff); + + if (direction === 0) {// Horizontal + gl.uniform2fv(this.#uSampleOffsets, sampleOffsetsHor); + } else { // Vertical + gl.uniform2fv(this.#uSampleOffsets, sampleOffsetsVert); + } + + gl.uniform1fv(this.#uSampleWeights, sampleWeights); + + const depthTexture = depthRenderBuffer.getDepthTexture(); + const saoOcclusionTexture = occlusionRenderBuffer.getTexture(); + + program.bindTexture(this.#uDepthTexture, depthTexture, 0); // TODO: use FrameCtx.textureUnit + program.bindTexture(this.#uOcclusionTexture, saoOcclusionTexture, 1); + + this.#aUV.bindArrayBuffer(this.#uvBuf); + this.#aPosition.bindArrayBuffer(this.#positionsBuf); + this.#indicesBuf.bind(); + + gl.drawElements(gl.TRIANGLES, this.#indicesBuf.numItems, this.#indicesBuf.itemType, 0); + } + + destroy() { + this.#program.destroy(); + } +} + +function createSampleWeights(kernelRadius: number, stdDev: number) { + const weights = []; + for (let i = 0; i <= kernelRadius; i++) { + weights.push(gaussian(i, stdDev)); + } + return weights; // TODO: Optimize +} + +function gaussian(x, stdDev) { + return Math.exp(-(x * x) / (2.0 * (stdDev * stdDev))) / (Math.sqrt(2.0 * Math.PI) * stdDev); +} + +function createSampleOffsets(kernelRadius: number, uvIncrement: number[]) { + const offsets = []; + for (let i = 0; i <= kernelRadius; i++) { + offsets.push(uvIncrement[0] * i); + offsets.push(uvIncrement[1] * i); + } + return offsets; +} + + diff --git a/packages/webglrenderer/src/SAOOcclusionRenderer.ts b/packages/webglrenderer/src/SAOOcclusionRenderer.ts new file mode 100644 index 000000000..f0d47dad4 --- /dev/null +++ b/packages/webglrenderer/src/SAOOcclusionRenderer.ts @@ -0,0 +1,390 @@ +import {WebGLArrayBuf, WebGLAttribute, WebGLProgram, WebGLRenderBuffer} from "@xeokit/webglutils"; +import {createMat4, createVec2, inverseMat4} from "@xeokit/matrix"; +import {RenderContext} from "./RenderContext"; +import {PerspectiveProjection, View} from "@xeokit/viewer"; +import {PerspectiveProjectionType} from "@xeokit/constants"; + +const tempVec2 = createVec2(); + +/** + * @private + */ +export class SAOOcclusionRenderer { + + #numSamples: number; + #program: WebGLProgram; + #programError: boolean; + #aPosition: WebGLAttribute; + #aUV: WebGLAttribute; + #uDepthTexture: string; + #uCameraNear: WebGLUniformLocation; + #uCameraFar: WebGLUniformLocation; + #uCameraProjectionMatrix: WebGLUniformLocation; + #uCameraInverseProjectionMatrix: WebGLUniformLocation; + #uScale: WebGLUniformLocation; + #uIntensity: WebGLUniformLocation; + #uBias: WebGLUniformLocation; + #uKernelRadius: WebGLUniformLocation; + #uMinResolution: WebGLUniformLocation; + #uRandomSeed: WebGLUniformLocation; + #uvBuf: WebGLArrayBuf; + #positionsBuf: WebGLArrayBuf; + #indicesBuf: WebGLArrayBuf; + #uPerspective: WebGLUniformLocation; + #uViewport: WebGLUniformLocation; + #dirty: boolean; + #renderContext: RenderContext; + + constructor(params: { + renderContext: RenderContext + }) { + + this.#renderContext = params.renderContext; + + this.#numSamples = null; + + // The program + + this.#program = null; + this.#programError = false; + + // Variable locations + + this.#aPosition = null; + this.#aUV = null; + + this.#uDepthTexture = "uDepthTexture"; + + this.#uCameraNear = null; + this.#uCameraFar = null; + this.#uCameraProjectionMatrix = null; + this.#uCameraInverseProjectionMatrix = null; + + this.#uScale = null; + this.#uIntensity = null; + this.#uBias = null; + this.#uKernelRadius = null; + this.#uMinResolution = null; + this.#uRandomSeed = null; + + // VBOs + + this.#uvBuf = null; + this.#positionsBuf = null; + this.#indicesBuf = null; + } + + render(params: { + depthRenderBuffer: WebGLRenderBuffer + view: View + }) { + + this.#build(); + + if (this.#programError) { + return; + } + + const {depthRenderBuffer, view} = params; + + const gl = this.#renderContext.gl; + + const program = this.#program; + const sao = view.sao; + const viewportWidth = gl.drawingBufferWidth; + const viewportHeight = gl.drawingBufferHeight; + const projection = view.camera.projectionType === PerspectiveProjectionType + ? view.camera.perspectiveProjection + : view.camera.orthoProjection; + const near = projection.near; + const far = projection.far; + const projectionMatrix = projection.projMatrix; + const inverseProjectionMatrix = projection.inverseProjMatrix; + const randomSeed = Math.random(); + const perspective = (view.camera.projectionType === PerspectiveProjectionType); + + tempVec2[0] = viewportWidth; + tempVec2[1] = viewportHeight; + + gl.viewport(0, 0, viewportWidth, viewportHeight); + gl.clearColor(0, 0, 0, 1); + gl.disable(gl.DEPTH_TEST); + gl.disable(gl.BLEND); + gl.frontFace(gl.CCW); + gl.clear(gl.COLOR_BUFFER_BIT); + + program.bind(); + + gl.uniform1f(this.#uCameraNear, near); + gl.uniform1f(this.#uCameraFar, far); + + gl.uniformMatrix4fv(this.#uCameraProjectionMatrix, false, projectionMatrix); + gl.uniformMatrix4fv(this.#uCameraInverseProjectionMatrix, false, inverseProjectionMatrix); + + gl.uniform1i(this.#uPerspective, perspective ? 1 : 0); + + gl.uniform1f(this.#uScale, sao.scale * (far / 5)); + gl.uniform1f(this.#uIntensity, sao.intensity); + gl.uniform1f(this.#uBias, sao.bias); + gl.uniform1f(this.#uKernelRadius, sao.kernelRadius); + gl.uniform1f(this.#uMinResolution, sao.minResolution); + gl.uniform2fv(this.#uViewport, tempVec2); + gl.uniform1f(this.#uRandomSeed, randomSeed); + + const depthTexture = depthRenderBuffer.getDepthTexture(); + + program.bindTexture(this.#uDepthTexture, depthTexture, 0); + + this.#aUV.bindArrayBuffer(this.#uvBuf); + this.#aPosition.bindArrayBuffer(this.#positionsBuf); + this.#indicesBuf.bind(); + + gl.drawElements(gl.TRIANGLES, this.#indicesBuf.numItems, this.#indicesBuf.itemType, 0); + } + + #build() { + + let dirty = false; + + const sao = this.#renderContext.view.sao; + + if (sao.numSamples !== this.#numSamples) { + this.#numSamples = Math.floor(sao.numSamples); + dirty = true; + } + + if (!dirty) { + return; + } + + const gl = this.#renderContext.gl; + + if (this.#program) { + this.#program.destroy(); + this.#program = null; + } + + this.#program = new WebGLProgram(gl, { + vertex: `#version 300 es + precision highp float; + precision highp int; + + in vec3 aPosition; + in vec2 aUV; + + out vec2 vUV; + + void main () { + gl_Position = vec4(aPosition, 1.0); + vUV = aUV; + }`, + + fragment: `#version 300 es + precision highp float; + precision highp int; + + #define NORMAL_TEXTURE 0 + #define PI 3.14159265359 + #define PI2 6.28318530718 + #define EPSILON 1e-6 + #define NUM_SAMPLES ${this.#numSamples} + #define NUM_RINGS 4 + + in vec2 vUV; + + uniform sampler2D uDepthTexture; + + uniform float uCameraNear; + uniform float uCameraFar; + uniform mat4 uProjectMatrix; + uniform mat4 uInverseProjectMatrix; + + uniform bool uPerspective; + + uniform float uScale; + uniform float uIntensity; + uniform float uBias; + uniform float uKernelRadius; + uniform float uMinResolution; + uniform vec2 uViewport; + uniform float uRandomSeed; + + float pow2( const in float x ) { return x*x; } + + highp float rand( const in vec2 uv ) { + const highp float a = 12.9898, b = 78.233, c = 43758.5453; + highp float dt = dot( uv.xy, vec2( a,b ) ), sn = mod( dt, PI ); + return fract(sin(sn) * c); + } + + vec3 packNormalToRGB( const in vec3 normal ) { + return normalize( normal ) * 0.5 + 0.5; + } + + vec3 unpackRGBToNormal( const in vec3 rgb ) { + return 2.0 * rgb.xyz - 1.0; + } + + const float packUpscale = 256. / 255.; + const float unpackDownScale = 255. / 256.; + + const vec3 packFactors = vec3( 256. * 256. * 256., 256. * 256., 256. ); + const vec4 unPackFactors = unpackDownScale / vec4( packFactors, 1. ); + + const float shiftRights = 1. / 256.; + + vec4 packFloatToRGBA( const in float v ) { + vec4 r = vec4( fract( v * packFactors ), v ); + r.yzw -= r.xyz * shiftRights; + return r * packUpscale; + } + + float unpackRGBAToFloat( const in vec4 v ) { + return dot( floor( v * 255.0 + 0.5 ) / 255.0, unPackFactors ); + } + + float perspectiveDepthToViewZ( const in float invClipZ, const in float near, const in float far ) { + return ( near * far ) / ( ( far - near ) * invClipZ - far ); + } + + float orthographicDepthToViewZ( const in float linearClipZ, const in float near, const in float far ) { + return linearClipZ * ( near - far ) - near; + } + + float getDepth( const in vec2 screenPosition ) { + return vec4(texture(uDepthTexture, screenPosition)).r; + } + + float getViewZ( const in float depth ) { + if (uPerspective) { + return perspectiveDepthToViewZ( depth, uCameraNear, uCameraFar ); + } else { + return orthographicDepthToViewZ( depth, uCameraNear, uCameraFar ); + } + } + + vec3 getViewPos( const in vec2 screenPos, const in float depth, const in float viewZ ) { + float clipW = uProjectMatrix[2][3] * viewZ + uProjectMatrix[3][3]; + vec4 clipPosition = vec4( ( vec3( screenPos, depth ) - 0.5 ) * 2.0, 1.0 ); + clipPosition *= clipW; + return ( uInverseProjectMatrix * clipPosition ).xyz; + } + + vec3 getViewNormal( const in vec3 viewPosition, const in vec2 screenPos ) { + return normalize( cross( dFdx( viewPosition ), dFdy( viewPosition ) ) ); + } + + float scaleDividedByCameraFar; + float minResolutionMultipliedByCameraFar; + + float getOcclusion( const in vec3 centerViewPosition, const in vec3 centerViewNormal, const in vec3 sampleViewPosition ) { + vec3 viewDelta = sampleViewPosition - centerViewPosition; + float viewDistance = length( viewDelta ); + float scaledScreenDistance = scaleDividedByCameraFar * viewDistance; + return max(0.0, (dot(centerViewNormal, viewDelta) - minResolutionMultipliedByCameraFar) / scaledScreenDistance - uBias) / (1.0 + pow2( scaledScreenDistance ) ); + } + + const float ANGLE_STEP = PI2 * float( NUM_RINGS ) / float( NUM_SAMPLES ); + const float INV_NUM_SAMPLES = 1.0 / float( NUM_SAMPLES ); + + float getAmbientOcclusion( const in vec3 centerViewPosition ) { + + scaleDividedByCameraFar = uScale / uCameraFar; + minResolutionMultipliedByCameraFar = uMinResolution * uCameraFar; + vec3 centerViewNormal = getViewNormal( centerViewPosition, vUV ); + + float angle = rand( vUV + uRandomSeed ) * PI2; + vec2 radius = vec2( uKernelRadius * INV_NUM_SAMPLES ) / uViewport; + vec2 radiusStep = radius; + + float occlusionSum = 0.0; + float weightSum = 0.0; + + for( int i = 0; i < NUM_SAMPLES; i ++ ) { + vec2 sampleUv = vUV + vec2( cos( angle ), sin( angle ) ) * radius; + radius += radiusStep; + angle += ANGLE_STEP; + + float sampleDepth = getDepth( sampleUv ); + if( sampleDepth >= ( 1.0 - EPSILON ) ) { + continue; + } + + float sampleViewZ = getViewZ( sampleDepth ); + vec3 sampleViewPosition = getViewPos( sampleUv, sampleDepth, sampleViewZ ); + occlusionSum += getOcclusion( centerViewPosition, centerViewNormal, sampleViewPosition ); + weightSum += 1.0; + } + + if( weightSum == 0.0 ) discard; + + return occlusionSum * ( uIntensity / weightSum ); + } + + out vec4 outColor; + + void main() { + + float centerDepth = getDepth( vUV ); + + if( centerDepth >= ( 1.0 - EPSILON ) ) { + discard; + } + + float centerViewZ = getViewZ( centerDepth ); + vec3 viewPosition = getViewPos( vUV, centerDepth, centerViewZ ); + + float ambientOcclusion = getAmbientOcclusion( viewPosition ); + + outColor = packFloatToRGBA( 1.0- ambientOcclusion ); + }` + }); + + if (this.#program.errors) { + console.error(this.#program.errors.join("\n")); + this.#programError = true; + return; + } + + const uv = new Float32Array([1, 1, 0, 1, 0, 0, 1, 0]); + const positions = new Float32Array([1, 1, 0, -1, 1, 0, -1, -1, 0, 1, -1, 0]); + + // Mitigation: if Uint8Array is used, the geometry is corrupted on OSX when using Chrome with data-textures + const indices = new Uint32Array([0, 1, 2, 0, 2, 3]); + + this.#positionsBuf = new WebGLArrayBuf(gl, gl.ARRAY_BUFFER, positions, positions.length, 3, gl.STATIC_DRAW); + this.#uvBuf = new WebGLArrayBuf(gl, gl.ARRAY_BUFFER, uv, uv.length, 2, gl.STATIC_DRAW); + this.#indicesBuf = new WebGLArrayBuf(gl, gl.ELEMENT_ARRAY_BUFFER, indices, indices.length, 1, gl.STATIC_DRAW); + + this.#program.bind(); + + this.#uCameraNear = this.#program.getLocation("uCameraNear"); + this.#uCameraFar = this.#program.getLocation("uCameraFar"); + + this.#uCameraProjectionMatrix = this.#program.getLocation("uProjectMatrix"); + this.#uCameraInverseProjectionMatrix = this.#program.getLocation("uInverseProjectMatrix"); + + this.#uPerspective = this.#program.getLocation("uPerspective"); + + this.#uScale = this.#program.getLocation("uScale"); + this.#uIntensity = this.#program.getLocation("uIntensity"); + this.#uBias = this.#program.getLocation("uBias"); + this.#uKernelRadius = this.#program.getLocation("uKernelRadius"); + this.#uMinResolution = this.#program.getLocation("uMinResolution"); + this.#uViewport = this.#program.getLocation("uViewport"); + this.#uRandomSeed = this.#program.getLocation("uRandomSeed"); + + this.#aPosition = this.#program.getAttribute("aPosition"); + this.#aUV = this.#program.getAttribute("aUV"); + + this.#dirty = false; + } + + destroy() { + if (this.#program) { + this.#program.destroy(); + this.#program = null; + } + } +} + diff --git a/packages/webglrenderer/src/WebGLRenderBufferManager.ts b/packages/webglrenderer/src/WebGLRenderBufferManager.ts index e43d8d8ae..d95a04278 100644 --- a/packages/webglrenderer/src/WebGLRenderBufferManager.ts +++ b/packages/webglrenderer/src/WebGLRenderBufferManager.ts @@ -13,18 +13,18 @@ export class WebGLRenderBufferManager { constructor(gl: WebGL2RenderingContext, webglCanvas: HTMLCanvasElement) { this.#gl = gl; - // this.#view = view; - this.#webglCanvas= webglCanvas; + // this.#view = view; + this.#webglCanvas = webglCanvas; this.#renderBuffersBasic = {}; this.#renderBuffersScaled = {}; } getRenderBuffer(id: string, options?: { depthTexture: boolean; - size: number[]; + size?: number[]; }) { - // const renderBuffers = this.#view.resolutionScale.enabled ? this.#renderBuffersBasic : this.#renderBuffersScaled; - const renderBuffers =this.#renderBuffersBasic; + // const renderBuffers = this.#view.resolutionScale.enabled ? this.#renderBuffersBasic : this.#renderBuffersScaled; + const renderBuffers = this.#renderBuffersBasic; let renderBuffer = renderBuffers[id]; if (!renderBuffer) { renderBuffer = new WebGLRenderBuffer(this.#webglCanvas, this.#gl, options); diff --git a/packages/webglrenderer/src/WebGLRenderer.ts b/packages/webglrenderer/src/WebGLRenderer.ts index e2164b70e..cbd0ddf41 100755 --- a/packages/webglrenderer/src/WebGLRenderer.ts +++ b/packages/webglrenderer/src/WebGLRenderer.ts @@ -17,6 +17,8 @@ import {Layer} from "./Layer"; import {WebGLRenderBufferManager} from "./WebGLRenderBufferManager"; import {PickParams, PickResult} from "@xeokit/viewer"; import {WebGLRendererMesh} from "./WebGLRendererMesh"; +import {SAOOcclusionRenderer} from "./SAOOcclusionRenderer"; +import {SAODepthLimitedBlurRenderer} from "./SAODepthLimitedBlurRenderer"; const ua = navigator.userAgent.match(/(opera|chrome|safari|firefox|msie|mobile)\/?\s*(\.?\d+(\.\d+)*)/i); const isSafari = (ua && ua[1].toLowerCase() === "safari"); @@ -101,6 +103,8 @@ export class WebGLRenderer implements Renderer { */ tileManager: WebGLTileManager | null; + #saoOcclusionRenderer: SAOOcclusionRenderer; + #saoDepthLimitedBlurRenderer: SAODepthLimitedBlurRenderer; #pickBufferManager: WebGLRenderBufferManager; @@ -282,6 +286,12 @@ export class WebGLRenderer implements Renderer { this.#viewer = viewer; this.#textureTranscoder.init(this.#viewer.capabilities); this.renderContext = new RenderContext(this.#viewer, this.#gl, this); + this.#saoOcclusionRenderer = new SAOOcclusionRenderer({ + renderContext: this.renderContext + }); + this.#saoDepthLimitedBlurRenderer = new SAODepthLimitedBlurRenderer({ + renderContext: this.renderContext + }); } /** @@ -565,7 +575,8 @@ export class WebGLRenderer implements Renderer { getSAOSupported(): boolean { - return isSafari && WEBGL_INFO.SUPPORTED_EXTENSIONS["OES_standard_derivatives"]; + return true; + //return isSafari && WEBGL_INFO.SUPPORTED_EXTENSIONS["OES_standard_derivatives"]; } /** @@ -662,6 +673,7 @@ export class WebGLRenderer implements Renderer { return (rendererView.imageDirty || this.#layerListDirty || this.#stateSortDirty); } + /** * Renders a frame for a View. * @@ -794,8 +806,8 @@ export class WebGLRenderer implements Renderer { return; } this.#activateExtensions(); - if (rendererView.saoEnabled && rendererView.view.sao.possible) { - this.#drawSAOBuffers(params); + if (rendererView.view.sao.enabled && rendererView.view.sao.possible) { + // this.#drawSAOBuffers(params); } this.#drawColor(params); } @@ -813,62 +825,101 @@ export class WebGLRenderer implements Renderer { } #drawSAOBuffers(params: { + viewIndex: number, clear: boolean; }) { - // const sao = this.#view.sao; - // const saoDepthRenderBuffer = this.#renderBufferManager.getRenderBuffer("saoDepth", { - // depthTexture: WEBGL_INFO.SUPPORTED_EXTENSIONS["WEBGL_depth_texture"] - // }); - // this.#saoDepthRenderBuffer.bind(); - // this.#saoDepthRenderBuffer.clear(); - // this.#drawDepth(params); - // this.#saoDepthRenderBuffer.unbind(); - // // Render occlusion buffer - // const occlusionRenderBuffer1 = this.#renderBufferManager.getRenderBuffer("saoOcclusion"); - // occlusionRenderBuffer1.bind(); - // occlusionRenderBuffer1.clear(); - // this.#saoOcclusionRenderer.render(saoDepthRenderBuffer); - // occlusionRenderBuffer1.unbind(); - // if (sao.blur) { - // // Horizontally blur occlusion buffer 1 into occlusion buffer 2 - // const occlusionRenderBuffer2 = this.#renderBufferManager.getRenderBuffer("saoOcclusion2"); - // occlusionRenderBuffer2.bind(); - // occlusionRenderBuffer2.clear(); - // this.#saoDepthLimitedBlurRenderer.render(saoDepthRenderBuffer, occlusionRenderBuffer1, 0); - // occlusionRenderBuffer2.unbind(); - // // Vertically blur occlusion buffer 2 back into occlusion buffer 1 - // occlusionRenderBuffer1.bind(); - // occlusionRenderBuffer1.clear(); - // this.#saoDepthLimitedBlurRenderer.render(saoDepthRenderBuffer, occlusionRenderBuffer2, 1); - // occlusionRenderBuffer1.unbind(); - // } + + const viewIndex = params.viewIndex; + const rendererView = this.#rendererViewsList[viewIndex]; + const view = rendererView.view; + const sao = view.sao; + + // Render depth buffer + + const depthRenderBuffer = rendererView.renderBufferManager.getRenderBuffer("saoDepth", { + depthTexture: WEBGL_INFO.SUPPORTED_EXTENSIONS["WEBGL_depth_texture"] + }); + depthRenderBuffer.bind(); + depthRenderBuffer.clear(); + this.#drawDepth(params); + depthRenderBuffer.unbind(); + + // Render occlusion buffer + + const occlusionRenderBuffer1 = rendererView.renderBufferManager.getRenderBuffer("saoOcclusion"); + occlusionRenderBuffer1.bind(); + occlusionRenderBuffer1.clear(); + + this.#saoOcclusionRenderer.render({ + view, + depthRenderBuffer + }); + occlusionRenderBuffer1.unbind(); + + if (sao.blur) { + + // Horizontally blur occlusion buffer 1 into occlusion buffer 2 + + const occlusionRenderBuffer2 = rendererView.renderBufferManager.getRenderBuffer("saoOcclusion2"); + occlusionRenderBuffer2.bind(); + occlusionRenderBuffer2.clear(); + + this.#saoDepthLimitedBlurRenderer.render({ + view, + depthRenderBuffer, + occlusionRenderBuffer: occlusionRenderBuffer1, + direction: 0 + }); + occlusionRenderBuffer2.unbind(); + + // Vertically blur occlusion buffer 2 back into occlusion buffer 1 + + occlusionRenderBuffer1.bind(); + occlusionRenderBuffer1.clear(); + + this.#saoDepthLimitedBlurRenderer.render({ + view, + depthRenderBuffer, + occlusionRenderBuffer: occlusionRenderBuffer2, + direction: 1 + }); + occlusionRenderBuffer1.unbind(); + } } #drawDepth(params: { viewIndex: number, - clear: boolean + clear: boolean; }) { - this.renderContext.reset(); - const gl = this.renderContext.gl; + const viewIndex = params.viewIndex; + const rendererView = this.#rendererViewsList[viewIndex]; + const view = rendererView.view; + const renderContext = this.renderContext; + const gl = renderContext.gl; + + renderContext.reset(); + renderContext.view = view; + gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); + gl.clearColor(0, 0, 0, 0); gl.enable(gl.DEPTH_TEST); gl.frontFace(gl.CCW); gl.enable(gl.CULL_FACE); gl.depthMask(true); + if (params.clear !== false) { gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); } - // for (let i = 0, len = this.#layerListPostCull.length; i < len; i++) { - // const layer = this.#layerListPostCull[i]; - // // if (layer.culled === true || layer.visible === false || !layer.drawDepth) { - // // continue; - // // } - // // if (layer.drawFlags.colorOpaque) { - // // // layer.drawDepth(this.renderContext); - // // } - // } + for (let i = 0, len = this.#layerList.length; i < len; i++) { + const layer = this.#layerList[i]; + const meshCounts = layer.meshCounts[viewIndex]; + if (meshCounts.numTransparent < meshCounts.numMeshes) { // Only draw opaque objects in depth pass + layer.drawDepth(); + } + } + // const numVertexAttribs = WEBGL_INFO.MAX_VERTEX_ATTRIBS; // Fixes https://github.com/xeokit/xeokit-sdk/issues/174 // for (let ii = 0; ii < numVertexAttribs; ii++) { // gl.disableVertexAttribArray(ii); @@ -905,7 +956,6 @@ export class WebGLRenderer implements Renderer { renderContext.reset(); renderContext.view = view; - renderContext.withSAO = false; renderContext.pbrEnabled = rendererView.pbrEnabled && !!view.qualityRender; gl.viewport(0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight); @@ -924,17 +974,13 @@ export class WebGLRenderer implements Renderer { renderContext.lineWidth = 1; - const saoPossible = view.sao.possible; + const drawWithSAO = rendererView.saoEnabled && view.sao.possible; - if (rendererView.saoEnabled && saoPossible) { - // const occlusionRenderBuffer1 = this.#renderBufferManager.getRenderBuffer("saoOcclusion", { - // depthTexture: false, - // size: [gl.drawingBufferWidth, gl.drawingBufferHeight] - // }); - // renderContext.occlusionTexture = occlusionRenderBuffer1 ? occlusionRenderBuffer1.getTexture() : null; + if (drawWithSAO) { + const saoOcclusionRenderBuffer = rendererView.renderBufferManager.getRenderBuffer("saoOcclusion"); + renderContext.saoOcclusionTexture = saoOcclusionRenderBuffer ? saoOcclusionRenderBuffer.getTexture() : null; } else { - renderContext.occlusionTexture = null; - + renderContext.saoOcclusionTexture = null; } if (params.clear !== false) { @@ -953,7 +999,11 @@ export class WebGLRenderer implements Renderer { } if (meshCounts.numTransparent < meshCounts.numMeshes) { - layer.drawColorOpaque(); + if (drawWithSAO && layer.saoSupported) { + normalDrawSAOBin.push(layer); + } else { + layer.drawColorOpaque(); + } } if (rendererView.transparentEnabled) { @@ -1022,9 +1072,8 @@ export class WebGLRenderer implements Renderer { // Render deferred bins if (normalDrawSAOBin.length > 0) { - renderContext.withSAO = true; for (let i = 0; i < normalDrawSAOBin.length; i++) { - normalDrawSAOBin[i].drawColorOpaque(); + normalDrawSAOBin[i].drawColorSAOOpaque(); } } @@ -1495,6 +1544,8 @@ export class WebGLRenderer implements Renderer { if (this.#viewer) { this.detachViewer(); } + this.#saoOcclusionRenderer.destroy(); + this.#saoDepthLimitedBlurRenderer.destroy(); this.#pickBufferManager.destroy(); this.#destroyed = true; this.onDestroyed.dispatch(this, true); diff --git a/packages/webglrenderer/src/WebGLRendererMesh.ts b/packages/webglrenderer/src/WebGLRendererMesh.ts index d9a4241aa..f1216de7e 100755 --- a/packages/webglrenderer/src/WebGLRendererMesh.ts +++ b/packages/webglrenderer/src/WebGLRendererMesh.ts @@ -94,12 +94,6 @@ export class WebGLRendererMesh implements RendererMesh, Pickable { } } - setMetallic(metallic: number): void { - } - - setRoughness(roughness: number): void { - } - setColor(color: FloatArrayParam) { const setOpacity = false; this.color[0] = color[0]; diff --git a/packages/webglrenderer/src/WebGLRendererModel.ts b/packages/webglrenderer/src/WebGLRendererModel.ts index 8172767a6..2b669bf0e 100755 --- a/packages/webglrenderer/src/WebGLRendererModel.ts +++ b/packages/webglrenderer/src/WebGLRendererModel.ts @@ -396,7 +396,13 @@ export class WebGLRendererModel extends Component implements RendererModel { const primitive = sceneGeometry.primitive; const instancing = sceneGeometry.numMeshes > 1; const origin = mesh.tile.origin; - const layerId = `VBO-${instancing ? "Instancing" : "Batching"}-${textureSetId}.${primitive}.${Math.round(origin[0])}.${Math.round(origin[1])}.${Math.round(origin[2])}`; + + const layerId = `VBO-${instancing ? "Instancing" : "Batching"} + .${textureSetId} + .${primitive} + .${Math.round(origin[0])}.${Math.round(origin[1])}.${Math.round(origin[2])} + .${instancing ? sceneGeometry.id : ""}`; + let layer = this.#currentLayers[layerId]; if (layer) { if (layer.canCreateLayerMesh(sceneGeometry)) { @@ -838,7 +844,7 @@ export class WebGLRendererModel extends Component implements RendererModel { if (this.destroyed) { return; } - // this.detachSceneModel(); + // this.detachSceneModel(); // this.#view.camera.onViewMatrix.unsubscribe(this.#onCameraViewMatrix); for (let layerId in this.#currentLayers) { if (this.#currentLayers.hasOwnProperty(layerId)) { diff --git a/packages/webglrenderer/src/vbo/VBORenderer.ts b/packages/webglrenderer/src/vbo/VBORenderer.ts index 0bf6d4932..4b1f12143 100644 --- a/packages/webglrenderer/src/vbo/VBORenderer.ts +++ b/packages/webglrenderer/src/vbo/VBORenderer.ts @@ -1,4 +1,4 @@ -import {WebGLAttribute, WebGLProgram} from "@xeokit/webglutils"; +import {WEBGL_INFO, WebGLAttribute, WebGLProgram} from "@xeokit/webglutils"; import {OrthoProjectionType} from "@xeokit/constants"; import {AmbientLight, DirLight, PointLight} from "@xeokit/viewer"; import {RenderContext} from "../RenderContext"; @@ -63,6 +63,7 @@ export abstract class VBORenderer { lightColor: WebGLUniformLocation[]; lightAttenuation: WebGLUniformLocation[]; lightAmbient: WebGLUniformLocation; + saoParams: WebGLUniformLocation; }; attributes: { @@ -79,6 +80,10 @@ export abstract class VBORenderer { modelMatrixCol2: WebGLAttribute; }; + samplers: { + saoOcclusionTexture: "saoOcclusionTexture"; + }; + constructor(renderContext: RenderContext, cfg: { edges: boolean } = {edges: false}) { this.renderContext = renderContext; this.#needRebuild = true; @@ -160,7 +165,8 @@ export abstract class VBORenderer { lightDir: [], lightPos: [], lightAttenuation: [], - lightAmbient: program.getLocation("lightAmbient") + lightAmbient: program.getLocation("lightAmbient"), + saoParams: program.getLocation("saoParams") }; const lights = view.lightsList; @@ -217,29 +223,24 @@ export abstract class VBORenderer { vertexHeader(src: string[]) { src.push('#version 300 es'); - src.push("// vertexHeader") src.push(`// ${this.constructor.name} vertex shader`); } vertexCommonDefs(src: string[]) { - src.push("// ------------------- vertexCommonDefs") src.push("in float flags;"); src.push("uniform int renderPass;"); - src.push(""); } vertexBatchingTransformDefs(src: string[]) { - src.push("// ------------------- vertexBatchingTransformDefs") + src.push("in vec3 position;"); src.push("uniform mat4 viewMatrix;"); src.push("uniform mat4 projMatrix;"); src.push("uniform mat4 worldMatrix;"); src.push("uniform vec3 positionsDecompressOffset;"); src.push("uniform vec3 positionsDecompressScale;"); - src.push("in vec3 position;"); } vertexInstancingTransformDefs(src: string[]) { - src.push("// ------------------- vertexInstancingTransformDefs") src.push("uniform mat4 viewMatrix;"); src.push("uniform mat4 projMatrix;"); src.push("uniform mat4 worldMatrix;"); @@ -251,18 +252,15 @@ export abstract class VBORenderer { src.push("in vec4 modelMatrixCol2;"); } - vertexPickMeshShadingDefs(src: string[]) { - src.push("// ------------------- vertexPickMeshShadingDefs") + vertexPickMeshDefs(src: string[]) { src.push("in vec4 pickColor;"); src.push("out vec4 vPickColor;"); - src.push("uniform vec2 drawingBufferSize;"); src.push("uniform vec2 pickClipPos;"); - - src.push("vec4 remapClipPos(vec4 clipPos) {"); + src.push("vec4 remapPickClipPos(vec4 clipPos) {"); src.push(" clipPos.xy /= clipPos.w;"); //if (viewportSize === 1) { - src.push(" clipPos.xy = (clipPos.xy - pickClipPos) * drawingBufferSize;"); + src.push(" clipPos.xy = (clipPos.xy - pickClipPos) * drawingBufferSize;"); // } else { // src.push(` clipPos.xy = (clipPos.xy - pickClipPos) * (drawingBufferSize / float(${viewportSize}));`); // } @@ -273,144 +271,162 @@ export abstract class VBORenderer { vertexSlicingDefs(src: string[]) { if (this.renderContext.view.getNumAllocatedSectionPlanes() > 0) { - src.push("// ------------------- vertexSlicingDefs") src.push("out vec4 vWorldPosition;"); src.push("out boolean vClippable;"); } } - vertexColorMainOpenBlock(src: string[]) { + vertexDrawMainOpen(src: string[]) { src.push("void main(void) {"); - src.push(` int colorFlag = int(flags) & 0xF;`); + src.push(` int colorFlag = (int(flags) & 0xF);`); src.push(` if (colorFlag != renderPass) {`); src.push(" gl_Position = vec4(2.0, 0.0, 0.0, 0.0);"); src.push(" } else {"); } - openVertexSilhouetteMain(src: string[]) { + vertexSilhouetteMainOpen(src: string[]) { src.push("void main(void) {"); - src.push(` if ((int(flags) >> 4 & 0xF) != renderPass) {`); + src.push(" int silhouetteFlag = (int(flags) >> 4 & 0xF);") + src.push(` if (silhouetteFlag != renderPass) {`); src.push(" gl_Position = vec4(2.0, 0.0, 0.0, 0.0);"); src.push(" } else {"); } - openVertexEdgesMain(src: string[]) { - src.push("void main(void) {"); - } - - openVertexPickMain(src: string[]) { + vertexPickMainOpen(src: string[]) { src.push("void main(void) {"); src.push(` int pickFlag = int(flags) >> 8 & 0xF;`); src.push(` if (pickFlag != renderPass) {`); src.push(" gl_Position = vec4(2.0, 0.0, 0.0, 0.0);"); + src.push(" } else {"); } - vertexColorMainCloseBlock(src: string[]) { - src.push(" }"); - src.push("}"); - } - - vertexPickMainCloseBlock(src: string[]) { + vertexMainClose(src: string[]) { src.push(" }"); src.push("}"); } vertexSlicingLogic(src: string[]) { if (this.renderContext.view.getNumAllocatedSectionPlanes() > 0) { - src.push(" // ------------------- vertexSlicingLogic") src.push(" vWorldPosition = worldPosition;"); src.push(" vClippable = (int(flags) >> 12 & 0xF) == 1;"); } } vertexDrawBatchingTransformLogic(src: string[]) { - src.push(" // ------------------- vertexDrawBatchingTransformLogic") src.push(" vec4 worldPosition = (vec4(positionsDecompressOffset + (positionsDecompressScale * position), 1.0)); "); src.push(" vec4 viewPosition = viewMatrix * worldPosition; "); src.push(" gl_Position = projMatrix * viewPosition;"); } + vertexDrawPointsBatchingTransformLogic(src: string[]) { + src.push(" vec4 worldPosition = (vec4(positionsDecompressOffset + (positionsDecompressScale * position), 1.0)); "); + src.push(" vec4 viewPosition = viewMatrix * worldPosition; "); + src.push(" vec4 clipPos = projMatrix * viewPosition;"); + src.push(" gl_Position = clipPos;"); + src.push(" clipPos.xy *= clipPos.w;"); + } + vertexPickBatchingTransformLogic(src: string[]) { - src.push(" // ------------------- vertexDrawBatchingTransformLogic") src.push(" vec4 worldPosition = (vec4(positionsDecompressOffset + (positionsDecompressScale * position), 1.0)); "); src.push(" vec4 viewPosition = viewMatrix * worldPosition; "); - src.push(" gl_Position = remapClipPos(projMatrix * viewPosition);"); + src.push(" gl_Position = remapPickClipPos(projMatrix * viewPosition);"); } vertexDrawInstancingTransformLogic(src: string[]) { - src.push(" // ------------------- vertexDrawInstancingTransformLogic") src.push(" vec4 worldPosition = (vec4(positionsDecompressOffset + (positionsDecompressScale * position), 1.0)); "); src.push(" vec4 viewPosition = viewMatrix * vec4(dot(worldPosition, modelMatrixCol0), dot(worldPosition, modelMatrixCol1), dot(worldPosition, modelMatrixCol2), 1.0); "); src.push(" gl_Position = projMatrix * viewPosition;"); } vertexPickInstancingTransformLogic(src: string[]) { - src.push(" // ------------------- vertexDrawInstancingTransformLogic") src.push(" vec4 worldPosition = (vec4(positionsDecompressOffset + (positionsDecompressScale * position), 1.0)); "); src.push(" vec4 viewPosition = viewMatrix * vec4(dot(worldPosition, modelMatrixCol0), dot(worldPosition, modelMatrixCol1), dot(worldPosition, modelMatrixCol2), 1.0); "); - src.push(" gl_Position = remapClipPos(projMatrix * viewPosition);"); + src.push(" gl_Position = remapPickClipPos(projMatrix * viewPosition);"); } vertexDrawLambertDefs(src: string[]) { - src.push(" // ------------------- vertexDrawLambertDefs") src.push(" in vec4 color;"); src.push(" out vec4 vColor;"); src.push(" out vec4 vViewPosition;"); } - vertexDrawLambertLogic(src: string[]) { // Depends on vertexDrawInstancingTransformLogic / vertexDrawBatchingTransformLogic - src.push(" // ------------------- vertexDrawLambertLogic") + vertexDrawLambertLogic(src: string[]) { src.push(" vColor = vec4(float(color.r) / 255.0, float(color.g) / 255.0, float(color.b) / 255.0, 1.0);"); src.push(" vViewPosition = viewPosition;"); } - vertexDrawSilhouetteDefs(src: string[]) { - src.push(" // ------------------- vertexDrawSilhouetteDefs") + vertexSilhouetteDefs(src: string[]) { src.push(" uniform vec4 silhouetteColor;"); src.push(" out vec4 vColor;"); } - vertexDrawSilhouetteLogic(src: string[]) { - src.push(" // ------------------- vertexDrawSilhouetteLogic") + vertexSilhouetteLogic(src: string[]) { src.push(" vColor = vec4(silhouetteColor.r, silhouetteColor.g, silhouetteColor.b, 0.5);"); } - vertexDrawFlatColorDefs(src: string[]) { - src.push(" // ------------------- vertexDrawFlatColorDefs") - src.push(" in vec4 color;"); - src.push(" out vec4 vColor;"); - } - vertexDrawFlatColorLogic(src: string[]) { - src.push(" // ------------------- vertexDrawFlatColorLogic") src.push(" vColor = vec4(float(color.r) / 255.0, float(color.g) / 255.0, float(color.b) / 255.0, 1.0);"); } - vertexDrawEdgesColorDefs(src: string[]) { - src.push(" // ------------------- vertexDrawEdgesColorDefs") + vertexDrawFlatColorDefs(src: string[]) { src.push(" in vec4 color;"); src.push(" out vec4 vColor;"); } vertexDrawEdgesColorLogic(src: string[]) { - src.push(" // ------------------- vertexDrawEdgesColorLogic") src.push(" vColor = vec4(float(color.r-200.0) / 255.0, float(color.g-200.0) / 255.0, float(color.b-200.0) / 255.0, 1.0);"); } - vertexDrawEdgesSilhouetteDefs(src: string[]) { - src.push(" // ------------------- vertexDrawEdgesSilhouetteDefs") - src.push(" uniform vec4 silhouetteColor;"); - src.push(" out vec4 vColor;"); + vertexPickMeshLogic(src: string[]) { + src.push(" vPickColor = vec4(float(pickColor.r) / 255.0, float(pickColor.g) / 255.0, float(pickColor.b) / 255.0, float(pickColor.a) / 255.0);"); } - vertexDrawEdgesSilhouetteLogic(src: string[]) { - src.push(" // ------------------- vertexDrawEdgesSilhouetteLogic") - src.push(" vColor = vec4(silhouetteColor.r, silhouetteColor.g, silhouetteColor.b, 0.5);"); + vertexPointsDrawDefs(src: string[]): void { + src.push("in vec4 color;"); + src.push("out vec4 vColor;"); } - vertexPickMeshShadingLogic(src: string[]) { - src.push(" // ------------------- vertexPickMeshShadingLogic") - src.push(" vPickColor = vec4(float(pickColor.r) / 255.0, float(pickColor.g) / 255.0, float(pickColor.b) / 255.0, float(pickColor.a) / 255.0);"); + vertexDrawPointsColorsLogic(src: string[]): void { + src.push("vColor = vec4(float(color.r) / 255.0, float(color.g) / 255.0, float(color.b) / 255.0, 1.0);"); + } + + vertexPointsGeometryDefs(src: string[]): void { + const pointsMaterial = this.renderContext.view.pointsMaterial; + if (pointsMaterial.perspectivePoints) { + src.push("uniform float nearPlaneHeight;"); + } + if (pointsMaterial.filterIntensity) { + src.push("uniform vec2 intensityRange;"); + } + src.push("uniform float pointSize;"); + } + + vertexPointsFilterLogicOpenBlock(src: string[]) { + const pointsMaterial = this.renderContext.view.pointsMaterial; + if (pointsMaterial.filterIntensity) { + src.push("float intensity = float(color.a) / 255.0;") + src.push("if (intensity < intensityRange[0] || intensity > intensityRange[1]) {"); + src.push(" gl_Position = vec4(2.0, 0.0, 0.0, 0.0);"); + src.push("} else {"); + } + } + + vertexPointsFilterLogicCloseBlock(src: string[]) { + const pointsMaterial = this.renderContext.view.pointsMaterial; + if (pointsMaterial.filterIntensity) { + src.push("}"); + } + } + + vertexPointsGeometryLogic(src: string[]) { + const pointsMaterial = this.renderContext.view.pointsMaterial; + // if (pointsMaterial.perspectivePoints) { + // src.push("gl_PointSize = (nearPlaneHeight * pointSize) / clipPos.w;"); + // src.push("gl_PointSize = max(gl_PointSize, " + Math.floor(pointsMaterial.minPerspectivePointSize) + ".0);"); + // src.push("gl_PointSize = min(gl_PointSize, " + Math.floor(pointsMaterial.maxPerspectivePointSize) + ".0);"); + // } else { + src.push("gl_PointSize = pointSize;"); + // } } fragmentHeader(src: string[]) { @@ -419,7 +435,6 @@ export abstract class VBORenderer { } fragmentPrecisionDefs(src: string[]) { - src.push("// ------------------- fragmentPrecisionDefs") src.push("#ifdef GL_FRAGMENT_PRECISION_HIGH"); src.push("precision highp float;"); src.push("precision highp int;"); @@ -429,11 +444,14 @@ export abstract class VBORenderer { src.push("#endif"); } + fragmentCommonDefs(src: string[]) { + src.push("vec4 color;"); + src.push("out vec4 outColor;"); + } + fragmentDrawLambertDefs(src: string[]) { - src.push("// ------------------- fragmentDrawLambertDefs") const view = this.renderContext.view; src.push("in vec4 vColor;"); - src.push("out vec4 outColor;"); src.push("in vec4 vViewPosition;"); src.push("uniform vec4 lightAmbient;"); src.push("uniform mat4 viewMatrix;"); @@ -453,7 +471,6 @@ export abstract class VBORenderer { } fragmentDrawLambertLogic(src: string[]) { - src.push("// ------------------- fragmentDrawLambertLogic") const view = this.renderContext.view; src.push("vec3 reflectedColor = vec3(0.0, 0.0, 0.0);"); src.push("vec3 viewLightDir = vec3(0.0, 0.0, -1.0);"); @@ -484,62 +501,66 @@ export abstract class VBORenderer { src.push("lambertian = max(dot(-viewNormal, viewLightDir), 0.0);"); src.push(`reflectedColor += lambertian * (lightColor${i}.rgb * lightColor${i}.a);`); } - src.push("outColor = vec4((lightAmbient.rgb * lightAmbient.a * vColor.rgb) + (reflectedColor * vColor.rgb), vColor.a);"); + src.push("color = vec4((lightAmbient.rgb * lightAmbient.a * vColor.rgb) + (reflectedColor * vColor.rgb), vColor.a);"); } - fragmentDrawSilhouetteDefs(src: string[]) { - src.push("// ------------------- fragmentDrawSilhouetteDefs") - src.push("in vec4 vColor;"); - src.push("out vec4 outColor;"); + fragmentDrawSAODefs(src: string[]) { + src.push("uniform sampler2D saoOcclusionTexture;"); + src.push("uniform vec4 saoParams;"); + src.push("const float saoUnpackDownScale = 255. / 256.;"); + src.push("const vec3 saoPackFactors = vec3( 256. * 256. * 256., 256. * 256., 256. );"); + src.push("const vec4 saoUnpackFactors = saoUnpackDownScale / vec4( saoPackFactors, 1. );"); + src.push("float saoUnpackRGBToFloat( const in vec4 v ) {"); + src.push(" return dot( v, saoUnpackFactors );"); + src.push("}"); } - fragmentDrawSilhouetteLogic(src: string[]) { - src.push("// ------------------- fragmentDrawSilhouetteLogic") - src.push("outColor = vColor;"); + fragmentSilhouetteDefs(src: string[]) { + src.push( + "in vec4 vColor;", + ); } fragmentDrawFlatColorDefs(src: string[]) { - src.push("// ------------------- fragmentDrawFlatColorDefs") src.push("in vec4 vColor;"); - src.push("out vec4 outColor;"); } fragmentDrawFlatColorLogic(src: string[]) { - src.push("// ------------------- fragmentDrawFlatColorLogic") - src.push("outColor = vColor;"); + src.push("color = vColor;"); } - fragmentDrawEdgesColorDefs(src: string[]) { - src.push("// ------------------- fragmentDrawEdgesColorDefs") - src.push("in vec4 vColor;"); - src.push("out vec4 outColor;"); + fragmentDrawSAOLogic(src: string[]) { + // Doing SAO blend in the main solid fill draw shader just so that edge lines can be drawn over the top + // TODO: Would be more efficient to defer this, then render lines later, using same depth buffer for Z-reject + src.push(" float saoViewportWidth = saoParams[0];"); + src.push(" float saoViewportHeight = saoParams[1];"); + src.push(" float saoBlendCutoff = saoParams[2];"); + src.push(" float saoBlendFactor = saoParams[3];"); + src.push(" vec2 saoUV = vec2(gl_FragCoord.x / saoViewportWidth, gl_FragCoord.y / saoViewportHeight);"); + src.push(" float saoAmbient = smoothstep(saoBlendCutoff, 1.0, saoUnpackRGBToFloat(texture(saoOcclusionTexture, saoUV))) * saoBlendFactor;"); + src.push(" color = vec4(color.rgb * saoAmbient, 1.0);"); } - fragmentDrawEdgesColorLogic(src: string[]) { - src.push("// ------------------- fragmentDrawEdgesColorLogic") - src.push("outColor = vColor;"); + fragmentDrawDepthDefs(src: string[]) { + src.push("in vec2 vHighPrecisionZW;"); } - fragmentDrawEdgesSilhouetteDefs(src: string[]) { - src.push("// ------------------- fragmentDrawEdgesSilhouetteDefs") - src.push("in vec4 vColor;"); - src.push("out vec4 outColor;"); + fragmentDrawDepthLogic(src: string[]) { + src.push("float depthFragCoordZ = 0.5 * vHighPrecisionZW[0] / vHighPrecisionZW[1] + 0.5;"); + src.push("color = vec4(vec3(1.0 - depthFragCoordZ), 1.0); "); } - fragmentDrawEdgesSilhouetteLogic(src: string[]) { - src.push("// ------------------- fragmentDrawEdgesSilhouetteLogic") - src.push("outColor = vColor;"); + fragmentSilhouetteLogic(src: string[]) { + src.push("color = vColor;"); } - fragmentPickMeshShadingDefs(src: string[]) { - src.push("// ------------------- fragmentDrawSilhouetteDefs") + fragmentPickMeshDefs(src: string[]) { src.push("in vec4 vPickColor;"); src.push("out vec4 outColor;"); } - fragmentPickMeshShadingLogic(src: string[]) { - src.push("// ------------------- fragmentDrawSilhouetteLogic") - src.push("outColor = vPickColor;"); + fragmentPickMeshLogic(src: string[]) { + src.push("color = vPickColor;"); } fragmentSlicingDefs(src: string[]) { @@ -547,7 +568,6 @@ export abstract class VBORenderer { if (numSectionPlanes === 0) { return; } - src.push("// ------------------- fragmentSlicingDefs") src.push("in vec4 vWorldPosition;"); src.push("in boolean vClippable;"); for (let i = 0; i < numSectionPlanes; i++) { @@ -562,7 +582,6 @@ export abstract class VBORenderer { if (numSectionPlanes === 0) { return; } - src.push("// ------------------- fragmentSlicingLogic") src.push(" if (vClippable) {"); src.push(" float dist = 0.0;"); for (let i = 0; i < numSectionPlanes; i++) { @@ -574,49 +593,6 @@ export abstract class VBORenderer { src.push(" }"); } - vertexDrawPointsColorsDefs(src: string[]): void { - src.push("in vec4 color;"); - src.push("out vec4 vColor;"); - } - - vertexDrawPointsColorsLogic(src: string[]): void { - src.push("vColor = vec4(float(color.r) / 255.0, float(color.g) / 255.0, float(color.b) / 255.0, 1.0);"); - } - - vertexPointsGeometryDefs(src: string[]): void { - const pointsMaterial = this.renderContext.view.pointsMaterial; - if (pointsMaterial.perspectivePoints) { - src.push("uniform float nearPlaneHeight;"); - } - if (pointsMaterial.filterIntensity) { - src.push("uniform vec2 intensityRange;"); - } - } - - vertexPointsFilterLogicOpenBlock(src: string[]) { - const pointsMaterial = this.renderContext.view.pointsMaterial; - if (pointsMaterial.filterIntensity) { - src.push("float intensity = float(color.a) / 255.0;") - src.push("if (intensity < intensityRange[0] || intensity > intensityRange[1]) {"); - src.push(" gl_Position = vec4(2.0, 0.0, 0.0, 0.0);"); - src.push("} else {"); - } - } - - vertexPointsFilterLogicCloseBlock(src: string[]) { - src.push("}"); - } - - vertexPointsGeometryLogic(src: string[]) { - const pointsMaterial = this.renderContext.view.pointsMaterial; - if (pointsMaterial.perspectivePoints) { - src.push("gl_PointSize = (nearPlaneHeight * pointSize) / clipPos.w;"); - src.push("gl_PointSize = max(gl_PointSize, " + Math.floor(pointsMaterial.minPerspectivePointSize) + ".0);"); - src.push("gl_PointSize = min(gl_PointSize, " + Math.floor(pointsMaterial.maxPerspectivePointSize) + ".0);"); - } else { - src.push("gl_PointSize = pointSize;"); - } - } fragmentPointsGeometryLogic(src: string[]): void { if (this.renderContext.view.pointsMaterial.roundPoints) { @@ -628,11 +604,16 @@ export abstract class VBORenderer { } } + fragmentCommonOutput(src: string[]) { + src.push("outColor = color;"); + } + bind(renderPass: number): boolean { const view = this.renderContext.view; const gl = this.renderContext.gl; const uniforms = this.uniforms; - this.renderContext.textureUnit = 0; + const renderContext = this.renderContext; + renderContext.textureUnit = 0; if (this.program && !this.getValid()) { this.program.destroy(); this.program = null; @@ -642,23 +623,23 @@ export abstract class VBORenderer { if (this.errors) { return false; } - this.renderContext.lastProgramId = -1; + renderContext.lastProgramId = -1; } if (!this.program) { return false; } - if (this.renderContext.lastProgramId === this.program.id) { + if (renderContext.lastProgramId === this.program.id) { return true; // Already bound } this.program.bind(); - this.renderContext.lastProgramId = this.program.id; + renderContext.lastProgramId = this.program.id; gl.uniform1i(uniforms.renderPass, renderPass); if (uniforms.projMatrix) { gl.uniformMatrix4fv(uniforms.projMatrix, false, (renderPass === RENDER_PASSES.PICK - ? this.renderContext.pickProjMatrix - : view.camera.projMatrix)); + ? renderContext.pickProjMatrix + : view.camera.projMatrix)); } if (uniforms.pointSize) { gl.uniform1f(uniforms.pointSize, view.pointsMaterial.pointSize); @@ -667,14 +648,14 @@ export abstract class VBORenderer { gl.uniform1f(uniforms.nearPlaneHeight, (view.camera.projectionType === OrthoProjectionType) ? 1.0 : (gl.drawingBufferHeight / (2 * Math.tan(0.5 * view.camera.perspectiveProjection.fov * Math.PI / 180.0)))); } if (uniforms.pickZNear) { - gl.uniform1f(uniforms.pickZNear, this.renderContext.pickZNear); - gl.uniform1f(uniforms.pickZFar, this.renderContext.pickZFar); + gl.uniform1f(uniforms.pickZNear, renderContext.pickZNear); + gl.uniform1f(uniforms.pickZFar, renderContext.pickZFar); } if (uniforms.drawingBufferSize) { gl.uniform2f(uniforms.drawingBufferSize, gl.drawingBufferWidth, gl.drawingBufferHeight); } if (uniforms.pickClipPos) { - gl.uniform2fv(uniforms.pickClipPos, this.renderContext.pickClipPos); + gl.uniform2fv(uniforms.pickClipPos, renderContext.pickClipPos); } if (uniforms.lightAmbient) { gl.uniform4fv(uniforms.lightAmbient, view.getAmbientColorAndIntensity()); @@ -728,6 +709,18 @@ export abstract class VBORenderer { } } } + const sao = view.sao; + const saoEnabled = sao.possible; + if (saoEnabled) { + if (this.uniforms.saoParams) { + gl.uniform4f(this.uniforms.saoParams, gl.drawingBufferWidth, gl.drawingBufferHeight, sao.blendCutoff, sao.blendFactor); + this.program.bindTexture( + this.samplers.saoOcclusionTexture, + renderContext.saoOcclusionTexture, + renderContext.textureUnit); + renderContext.textureUnit = (renderContext.textureUnit + 1) % WEBGL_INFO.MAX_TEXTURE_UNITS; + } + } return true; } diff --git a/packages/webglrenderer/src/vbo/VBORendererSet.ts b/packages/webglrenderer/src/vbo/VBORendererSet.ts index 0dc44ba55..0040f3c0e 100644 --- a/packages/webglrenderer/src/vbo/VBORendererSet.ts +++ b/packages/webglrenderer/src/vbo/VBORendererSet.ts @@ -12,6 +12,8 @@ export class VBORendererSet { renderStats: RenderStats; #colorRenderer: VBORenderer; + #colorSAORenderer: VBORenderer; + #drawDepthRenderer: VBORenderer; #silhouetteRenderer: VBORenderer; #pickMeshRenderer: VBORenderer; #pickDepthRenderer: VBORenderer; @@ -20,8 +22,6 @@ export class VBORendererSet { #snapRenderer: VBORenderer; #edgesColorRenderer: VBORenderer; #edgesSilhouetteRenderer: VBORenderer; - #depthRenderer: VBORenderer; - #normalsRenderer: VBORenderer; constructor(webglRenderer: WebGLRenderer) { this.renderContext = webglRenderer.renderContext; @@ -33,6 +33,14 @@ export class VBORendererSet { this.#colorRenderer.destroy(); this.#colorRenderer = null; } + if (this.#colorSAORenderer && (!this.#colorSAORenderer.getValid())) { + this.#colorSAORenderer.destroy(); + this.#colorSAORenderer = null; + } + if (this.#drawDepthRenderer && (!this.#drawDepthRenderer.getValid())) { + this.#drawDepthRenderer.destroy(); + this.#drawDepthRenderer = null; + } if (this.#silhouetteRenderer && (!this.#silhouetteRenderer.getValid())) { this.#silhouetteRenderer.destroy(); this.#silhouetteRenderer = null; @@ -69,7 +77,21 @@ export class VBORendererSet { get colorRenderer(): VBORenderer { if (!this.#colorRenderer) { - this.#colorRenderer = this.createDrawRenderer(); + this.#colorRenderer = this.createDrawColorRenderer(); + } + return this.#colorRenderer; + } + + get colorSAORenderer(): VBORenderer { + if (!this.#colorSAORenderer) { + this.#colorSAORenderer = this.createDrawColorSAORenderer(); + } + return this.#colorSAORenderer; + } + + get drawDepthRenderer(): VBORenderer { + if (!this.#colorRenderer) { + this.#colorRenderer = this.createDrawDepthRenderer(); } return this.#colorRenderer; } @@ -130,7 +152,15 @@ export class VBORendererSet { return this.#snapRenderer; } - protected createDrawRenderer(): VBORenderer { + protected createDrawColorRenderer(): VBORenderer { + return null; + } + + protected createDrawColorSAORenderer(): VBORenderer { + return null; + } + + protected createDrawDepthRenderer(): VBORenderer { return null; } @@ -170,6 +200,12 @@ export class VBORendererSet { if (this.#colorRenderer) { this.#colorRenderer.destroy(); } + if (this.#colorSAORenderer) { + this.#colorSAORenderer.destroy(); + } + if (this.#drawDepthRenderer) { + this.#drawDepthRenderer.destroy(); + } if (this.#silhouetteRenderer) { this.#silhouetteRenderer.destroy(); } diff --git a/packages/webglrenderer/src/vbo/batching/VBOBatchingLayer.ts b/packages/webglrenderer/src/vbo/batching/VBOBatchingLayer.ts index 67dd41a6b..facc94e5b 100644 --- a/packages/webglrenderer/src/vbo/batching/VBOBatchingLayer.ts +++ b/packages/webglrenderer/src/vbo/batching/VBOBatchingLayer.ts @@ -19,6 +19,7 @@ import {VBOBatchingLayerParams} from "./VBOBatchingLayerParams"; import {compressUVs, decompressPoint3WithAABB3, getUVBounds, quantizePositions3} from "@xeokit/compression"; import {VBORendererSet} from "../VBORendererSet"; +import {SolidPrimitive, SurfacePrimitive, TrianglesPrimitive} from "@xeokit/constants"; let numLayers = 0; @@ -37,6 +38,7 @@ export class VBOBatchingLayer implements Layer { meshCounts: MeshCounts[]; renderState: VBOBatchingRenderState; sortId: string; + saoSupported: boolean; #built: boolean; #aabb: FloatArrayParam; @@ -69,7 +71,7 @@ export class VBOBatchingLayer implements Layer { this.sortId = `VBOBatchingLayer-${vBOBatchingLayerParams.primitive}`; this.meshCounts = []; - for (let i =0, len = this.renderContext.viewer.viewList.length; i < len; i++) { + for (let i = 0, len = this.renderContext.viewer.viewList.length; i < len; i++) { this.meshCounts.push(new MeshCounts()); } @@ -273,17 +275,25 @@ export class VBOBatchingLayer implements Layer { renderState.uvBuf = new WebGLArrayBuf(gl, gl.ARRAY_BUFFER, buffer.uv, buffer.uv.length, 2, gl.STATIC_DRAW, notNormalized); } } - this.renderState.pbrSupported + + this.saoSupported + = (this.primitive === SolidPrimitive + || this.primitive === SurfacePrimitive + || this.primitive === TrianglesPrimitive); + + renderState.pbrSupported = !!renderState.metallicRoughnessBuf && !!renderState.uvBuf && !!renderState.normalsBuf && !!renderState.textureSet && !!renderState.textureSet.colorTexture && !!renderState.textureSet.metallicRoughnessTexture; - this.renderState.colorTextureSupported + + renderState.colorTextureSupported = !!renderState.uvBuf && !!renderState.textureSet && !!renderState.textureSet.colorTexture; + this.#buffer = null; this.#built = true; } @@ -491,9 +501,9 @@ export class VBOBatchingLayer implements Layer { colorFlag = RENDER_PASSES.NOT_RENDERED; } else { if (transparent) { - colorFlag = RENDER_PASSES.COLOR_TRANSPARENT; + colorFlag = RENDER_PASSES.DRAW_TRANSPARENT; } else { - colorFlag = RENDER_PASSES.COLOR_OPAQUE; + colorFlag = RENDER_PASSES.DRAW_OPAQUE; } } @@ -547,7 +557,20 @@ export class VBOBatchingLayer implements Layer { return; } if (this.#rendererSet.colorRenderer) { - this.#rendererSet.colorRenderer.renderVBOBatchingLayer(this, RENDER_PASSES.COLOR_OPAQUE); + this.#rendererSet.colorRenderer.renderVBOBatchingLayer(this, RENDER_PASSES.DRAW_OPAQUE); + } + } + + drawColorSAOOpaque() { + const viewIndex = this.renderContext.view.viewIndex; + if (this.meshCounts[viewIndex].numCulled === this.meshCounts[viewIndex].numMeshes || + this.meshCounts[viewIndex].numVisible === 0 || + this.meshCounts[viewIndex].numTransparent === this.meshCounts[viewIndex].numMeshes || + this.meshCounts[viewIndex].numXRayed === this.meshCounts[viewIndex].numMeshes) { + return; + } + if (this.#rendererSet.colorSAORenderer) { + this.#rendererSet.colorSAORenderer.renderVBOBatchingLayer(this, RENDER_PASSES.DRAW_OPAQUE); } } @@ -560,7 +583,7 @@ export class VBOBatchingLayer implements Layer { return; } if (this.#rendererSet.colorRenderer) { - this.#rendererSet.colorRenderer.renderVBOBatchingLayer(this, RENDER_PASSES.COLOR_TRANSPARENT); + this.#rendererSet.colorRenderer.renderVBOBatchingLayer(this, RENDER_PASSES.DRAW_TRANSPARENT); } } @@ -572,9 +595,9 @@ export class VBOBatchingLayer implements Layer { this.meshCounts[viewIndex].numXRayed === this.meshCounts[viewIndex].numMeshes) { return; } - // if (this.#rendererSet.depthRenderer) { - // this.#rendererSet.depthRenderer.renderVBOBatchingLayer(this, RENDER_PASSES.COLOR_OPAQUE); // Assume whatever post-effect uses depth (eg SAO) does not apply to transparent objects - // } + if (this.#rendererSet.drawDepthRenderer) { + this.#rendererSet.drawDepthRenderer.renderVBOBatchingLayer(this, RENDER_PASSES.DRAW_OPAQUE); // Assume whatever post-effect uses depth (eg SAO) does not apply to transparent objects + } } drawNormals() { @@ -586,7 +609,7 @@ export class VBOBatchingLayer implements Layer { return; } // if (this.#rendererSet.normalsRenderer) { - // this.#rendererSet.normalsRenderer.renderVBOBatchingLayer(this, RENDER_PASSES.COLOR_OPAQUE); // Assume whatever post-effect uses normals (eg SAO) does not apply to transparent objects + // this.#rendererSet.normalsRenderer.renderVBOBatchingLayer(this, RENDER_PASSES.DRAW_OPAQUE); // Assume whatever post-effect uses normals (eg SAO) does not apply to transparent objects // } } @@ -633,7 +656,7 @@ export class VBOBatchingLayer implements Layer { return; } if (this.#rendererSet.edgesColorRenderer) { - this.#rendererSet.edgesColorRenderer.renderVBOBatchingLayer(this, RENDER_PASSES.COLOR_OPAQUE); + this.#rendererSet.edgesColorRenderer.renderVBOBatchingLayer(this, RENDER_PASSES.DRAW_OPAQUE); } } @@ -645,7 +668,7 @@ export class VBOBatchingLayer implements Layer { return; } if (this.#rendererSet.edgesColorRenderer) { - this.#rendererSet.edgesColorRenderer.renderVBOBatchingLayer(this, RENDER_PASSES.COLOR_TRANSPARENT); + this.#rendererSet.edgesColorRenderer.renderVBOBatchingLayer(this, RENDER_PASSES.DRAW_TRANSPARENT); } } @@ -692,7 +715,7 @@ export class VBOBatchingLayer implements Layer { return; } if (this.#rendererSet.occlusionRenderer) { - this.#rendererSet.occlusionRenderer.renderVBOBatchingLayer(this, RENDER_PASSES.COLOR_OPAQUE); + this.#rendererSet.occlusionRenderer.renderVBOBatchingLayer(this, RENDER_PASSES.DRAW_OPAQUE); } } @@ -703,7 +726,7 @@ export class VBOBatchingLayer implements Layer { // return; // } // if (this.#rendererSet.shadowRenderer) { - // this.#rendererSet.shadowRenderer.render( this, RENDER_PASSES.COLOR_OPAQUE); + // this.#rendererSet.shadowRenderer.render( this, RENDER_PASSES.DRAW_OPAQUE); // } } diff --git a/packages/webglrenderer/src/vbo/batching/VBOBatchingRenderState.ts b/packages/webglrenderer/src/vbo/batching/VBOBatchingRenderState.ts index ebf5ea14c..53f099768 100644 --- a/packages/webglrenderer/src/vbo/batching/VBOBatchingRenderState.ts +++ b/packages/webglrenderer/src/vbo/batching/VBOBatchingRenderState.ts @@ -23,5 +23,7 @@ export interface VBOBatchingRenderState { origin: FloatArrayParam; positionsBuf: WebGLArrayBuf; indicesBuf: WebGLArrayBuf; + + saoSupported: boolean; pbrSupported: boolean; } diff --git a/packages/webglrenderer/src/vbo/batching/lines/renderers/VBOLinesBatchingDrawRenderer.ts b/packages/webglrenderer/src/vbo/batching/lines/renderers/VBOLinesBatchingDrawColorRenderer.ts similarity index 61% rename from packages/webglrenderer/src/vbo/batching/lines/renderers/VBOLinesBatchingDrawRenderer.ts rename to packages/webglrenderer/src/vbo/batching/lines/renderers/VBOLinesBatchingDrawColorRenderer.ts index 089903dc8..b3a5f41ee 100644 --- a/packages/webglrenderer/src/vbo/batching/lines/renderers/VBOLinesBatchingDrawRenderer.ts +++ b/packages/webglrenderer/src/vbo/batching/lines/renderers/VBOLinesBatchingDrawColorRenderer.ts @@ -4,39 +4,37 @@ import {VBOBatchingRenderer} from "../../VBOBatchingRenderer"; /** * @private */ -export class VBOLinesBatchingDrawRenderer extends VBOBatchingRenderer { +export class VBOLinesBatchingDrawColorRenderer extends VBOBatchingRenderer { getHash(): string { return this.slicingHash; } - buildVertexShader(src: string[]):void { + buildVertexShader(src: string[]): void { this.vertexHeader(src); this.vertexCommonDefs(src); this.vertexBatchingTransformDefs(src); this.vertexSlicingDefs(src); this.vertexDrawFlatColorDefs(src); - src.push("void main(void) {"); - // colorFlag = NOT_RENDERED | COLOR_OPAQUE | COLOR_TRANSPARENT - // renderPass = COLOR_OPAQUE - src.push(`if ((int(flags) & 0xF) != renderPass) {`); - src.push(" gl_Position = vec4(0.0, 0.0, 0.0, 0.0);"); // Cull vertex - src.push("} else {"); - this.vertexDrawBatchingTransformLogic(src); - this.vertexDrawFlatColorLogic(src); - this.vertexSlicingLogic(src); - src.push("}"); - src.push("}"); + this.vertexDrawMainOpen(src); + { + this.vertexDrawBatchingTransformLogic(src); + this.vertexDrawFlatColorLogic(src); + this.vertexSlicingLogic(src); + } + this.vertexMainClose(src); } - buildFragmentShader(src: string[]) :void{ + buildFragmentShader(src: string[]): void { this.fragmentHeader(src); this.fragmentPrecisionDefs(src); + this.fragmentCommonDefs(src); this.fragmentSlicingDefs(src); this.fragmentDrawFlatColorDefs(src); src.push("void main(void) {"); this.fragmentSlicingLogic(src); this.fragmentDrawFlatColorLogic(src); + this.fragmentCommonOutput(src); src.push("}"); } diff --git a/packages/webglrenderer/src/vbo/batching/lines/renderers/VBOLinesBatchingPickMeshRenderer.ts b/packages/webglrenderer/src/vbo/batching/lines/renderers/VBOLinesBatchingPickMeshRenderer.ts index 83ccdf57a..8aa426331 100644 --- a/packages/webglrenderer/src/vbo/batching/lines/renderers/VBOLinesBatchingPickMeshRenderer.ts +++ b/packages/webglrenderer/src/vbo/batching/lines/renderers/VBOLinesBatchingPickMeshRenderer.ts @@ -15,29 +15,26 @@ export class VBOLinesBatchingPickMeshRenderer extends VBOBatchingRenderer { this.vertexCommonDefs(src); this.vertexBatchingTransformDefs(src); this.vertexSlicingDefs(src); - this.vertexPickMeshShadingDefs(src); - src.push("void main(void) {"); - // colorFlag = NOT_RENDERED | COLOR_OPAQUE | COLOR_TRANSPARENT - // renderPass = COLOR_OPAQUE - src.push(`int colorFlag = int(flags) & 0xF;`); - src.push(`if (colorFlag != renderPass) {`); - src.push(" gl_Position = vec4(0.0, 0.0, 0.0, 0.0);"); // Cull vertex - src.push("} else {"); - this.vertexDrawBatchingTransformLogic(src); - this.vertexPickMeshShadingLogic(src); - this.vertexSlicingLogic(src); - src.push("}"); - src.push("}"); + this.vertexPickMeshDefs(src); + this.vertexPickMainOpen(src); + { + this.vertexDrawBatchingTransformLogic(src); + this.vertexPickMeshLogic(src); + this.vertexSlicingLogic(src); + } + this.vertexMainClose(src); } buildFragmentShader(src: string[]):void { this.fragmentHeader(src); this.fragmentPrecisionDefs(src); + this.fragmentCommonDefs(src); this.fragmentSlicingDefs(src); - this.fragmentPickMeshShadingDefs(src); + this.fragmentPickMeshDefs(src); src.push("void main(void) {"); this.fragmentSlicingLogic(src); - this.fragmentPickMeshShadingLogic(src); + this.fragmentPickMeshLogic(src); + this.fragmentCommonOutput(src); src.push("}"); } diff --git a/packages/webglrenderer/src/vbo/batching/lines/renderers/VBOLinesBatchingSilhouetteRenderer.ts b/packages/webglrenderer/src/vbo/batching/lines/renderers/VBOLinesBatchingSilhouetteRenderer.ts index fe43a5897..388ab96df 100644 --- a/packages/webglrenderer/src/vbo/batching/lines/renderers/VBOLinesBatchingSilhouetteRenderer.ts +++ b/packages/webglrenderer/src/vbo/batching/lines/renderers/VBOLinesBatchingSilhouetteRenderer.ts @@ -15,29 +15,27 @@ export class VBOLinesBatchingSilhouetteRenderer extends VBOBatchingRenderer { this.vertexCommonDefs(src); this.vertexBatchingTransformDefs(src); this.vertexSlicingDefs(src); - this.vertexDrawSilhouetteDefs(src); - src.push("void main(void) {"); - // colorFlag = NOT_RENDERED | COLOR_OPAQUE | COLOR_TRANSPARENT - // renderPass = COLOR_OPAQUE - src.push(`int colorFlag = int(flags) & 0xF;`); - src.push(`if (colorFlag != renderPass) {`); - src.push(" gl_Position = vec4(0.0, 0.0, 0.0, 0.0);"); // Cull vertex - src.push("} else {"); - this.vertexDrawBatchingTransformLogic(src); - this.vertexDrawSilhouetteLogic(src); - this.vertexSlicingLogic(src); - src.push("}"); + this.vertexSilhouetteDefs(src); + this.vertexSilhouetteMainOpen(src); + { + this.vertexDrawBatchingTransformLogic(src); + this.vertexSilhouetteLogic(src); + this.vertexSlicingLogic(src); + src.push("}"); + } src.push("}"); } buildFragmentShader(src: string[]):void { this.fragmentHeader(src); this.fragmentPrecisionDefs(src); + this.fragmentCommonDefs(src); this.fragmentSlicingDefs(src); - this.fragmentDrawSilhouetteDefs(src); + this.fragmentSilhouetteDefs(src); src.push("void main(void) {"); this.fragmentSlicingLogic(src); - this.fragmentDrawSilhouetteLogic(src); + this.fragmentSilhouetteLogic(src); + this.fragmentCommonOutput(src); src.push("}"); } diff --git a/packages/webglrenderer/src/vbo/batching/lines/renderers/rendererFactory.ts b/packages/webglrenderer/src/vbo/batching/lines/renderers/rendererFactory.ts index 98f6c54ec..fa6d272ba 100644 --- a/packages/webglrenderer/src/vbo/batching/lines/renderers/rendererFactory.ts +++ b/packages/webglrenderer/src/vbo/batching/lines/renderers/rendererFactory.ts @@ -1,6 +1,6 @@ import {WebGLRenderer} from "../../../../WebGLRenderer"; import {RendererSetFactory, VBORendererSet} from "../../../VBORendererSet"; -import {VBOLinesBatchingDrawRenderer} from "./VBOLinesBatchingDrawRenderer"; +import {VBOLinesBatchingDrawColorRenderer} from "./VBOLinesBatchingDrawColorRenderer"; import {VBORenderer} from "../../../VBORenderer"; import {VBOLinesBatchingPickMeshRenderer} from "./VBOLinesBatchingPickMeshRenderer"; import {VBOLinesBatchingSilhouetteRenderer} from "./VBOLinesBatchingSilhouetteRenderer"; @@ -10,8 +10,8 @@ import {VBOLinesBatchingSilhouetteRenderer} from "./VBOLinesBatchingSilhouetteRe */ class RendererFactory extends VBORendererSet { - createDrawRenderer(): VBORenderer { - return new VBOLinesBatchingDrawRenderer(this.renderContext); + createDrawColorRenderer(): VBORenderer { + return new VBOLinesBatchingDrawColorRenderer(this.renderContext); } createPickMeshRenderer(): VBORenderer { diff --git a/packages/webglrenderer/src/vbo/batching/points/renderers/VBOPointsBatchingDrawRenderer.ts b/packages/webglrenderer/src/vbo/batching/points/renderers/VBOPointsBatchingDrawColorRenderer.ts similarity index 72% rename from packages/webglrenderer/src/vbo/batching/points/renderers/VBOPointsBatchingDrawRenderer.ts rename to packages/webglrenderer/src/vbo/batching/points/renderers/VBOPointsBatchingDrawColorRenderer.ts index 8e1e2544d..f353b2ccc 100644 --- a/packages/webglrenderer/src/vbo/batching/points/renderers/VBOPointsBatchingDrawRenderer.ts +++ b/packages/webglrenderer/src/vbo/batching/points/renderers/VBOPointsBatchingDrawColorRenderer.ts @@ -4,7 +4,7 @@ import {VBOBatchingRenderer} from "../../VBOBatchingRenderer"; /** * @private */ -export class VBOPointsBatchingDrawRenderer extends VBOBatchingRenderer { +export class VBOPointsBatchingDrawColorRenderer extends VBOBatchingRenderer { getHash(): string { const view = this.renderContext.view; @@ -15,32 +15,37 @@ export class VBOPointsBatchingDrawRenderer extends VBOBatchingRenderer { buildVertexShader(src: string[]): void { this.vertexHeader(src); this.vertexCommonDefs(src); + this.vertexBatchingTransformDefs(src); this.vertexSlicingDefs(src); this.vertexPointsGeometryDefs(src); - this.vertexDrawPointsColorsDefs(src); - this.vertexColorMainOpenBlock(src); + this.vertexPointsDrawDefs(src); + this.vertexDrawMainOpen(src); { this.vertexPointsFilterLogicOpenBlock(src); { - this.vertexDrawBatchingTransformLogic(src); + this.vertexDrawPointsBatchingTransformLogic(src); this.vertexSlicingLogic(src); this.vertexDrawPointsColorsLogic(src); this.vertexPointsGeometryLogic(src); } this.vertexPointsFilterLogicCloseBlock(src); } - this.vertexColorMainCloseBlock(src); + this.vertexMainClose(src); } buildFragmentShader(src: string[]): void { this.fragmentHeader(src); this.fragmentPrecisionDefs(src); + this.fragmentCommonDefs(src); this.fragmentSlicingDefs(src); this.fragmentDrawFlatColorDefs(src); src.push("void main(void) {"); - this.fragmentPointsGeometryLogic(src); - this.fragmentSlicingLogic(src); - this.fragmentDrawFlatColorLogic(src); + { + this.fragmentPointsGeometryLogic(src); + this.fragmentSlicingLogic(src); + this.fragmentDrawFlatColorLogic(src); + this.fragmentCommonOutput(src); + } src.push("}"); } diff --git a/packages/webglrenderer/src/vbo/batching/points/renderers/VBOPointsBatchingPickMeshRenderer.ts b/packages/webglrenderer/src/vbo/batching/points/renderers/VBOPointsBatchingPickMeshRenderer.ts index fd9f4de33..197266fad 100644 --- a/packages/webglrenderer/src/vbo/batching/points/renderers/VBOPointsBatchingPickMeshRenderer.ts +++ b/packages/webglrenderer/src/vbo/batching/points/renderers/VBOPointsBatchingPickMeshRenderer.ts @@ -8,133 +8,50 @@ import {VBOBatchingRenderer} from "../../VBOBatchingRenderer"; export class VBOPointsBatchingPickMeshRenderer extends VBOBatchingRenderer { getHash(): string { - return ""; + const view = this.renderContext.view; + const pointsMaterial = view.pointsMaterial; + return `${pointsMaterial.perspectivePoints}-${pointsMaterial.filterIntensity}-${pointsMaterial.roundPoints}-${view.getSectionPlanesHash()}`; } - buildVertexShader(src: string[]) :void{ - const renderContext = this.renderContext; - const view = renderContext.view; - const clipping = view.getNumAllocatedSectionPlanes() > 0; - const pointsMaterial = view.pointsMaterial; + buildVertexShader(src: string[]): void { this.vertexHeader(src); this.vertexCommonDefs(src); + this.vertexBatchingTransformDefs(src); this.vertexSlicingDefs(src); - src.push("in vec4 pickColor;"); - src.push("uniform float pointSize;"); - if (pointsMaterial.perspectivePoints) { - src.push("uniform float nearPlaneHeight;"); - } - // if (view.logarithmicDepthBufferEnabled) { - // src.push("uniform float logDepthBufFC;"); - // src.push("out float vFragDepth;"); - // } - - src.push("out vec4 vPickColor;"); - src.push("void main(void) {"); - // pickFlag = NOT_RENDERED | PICK - // renderPass = PICK - src.push(`int pickFlag = int(flags) >> 12 & 0xF;`); - src.push(`if (pickFlag != renderPass) {`); - src.push(" gl_Position = vec4(0.0, 0.0, 0.0, 0.0);"); // Cull vertex - src.push(" } else {"); - src.push(" vec4 worldPosition = worldMatrix * (positionsDecodeMatrix * vec4(position, 1.0)); "); - src.push(" vec4 viewPosition = viewMatrix * worldPosition; "); - src.push(" vPickColor = vec4(float(pickColor.r) / 255.0, float(pickColor.g) / 255.0, float(pickColor.b) / 255.0, float(pickColor.a) / 255.0);"); - if (clipping) { - src.push(" vWorldPosition = worldPosition;"); - src.push(" vFlags = flags;"); - } - src.push("vec4 clipPos = projMatrix * viewPosition;"); - // if (view.logarithmicDepthBufferEnabled) { - // src.push("vFragDepth = 1.0 + clipPos.w;"); - // } - src.push("gl_Position = clipPos;"); - if (pointsMaterial.perspectivePoints) { - src.push("gl_PointSize = (nearPlaneHeight * pointSize) / clipPos.w;"); - src.push("gl_PointSize = max(gl_PointSize, " + Math.floor(pointsMaterial.minPerspectivePointSize) + ".0);"); - src.push("gl_PointSize = min(gl_PointSize, " + Math.floor(pointsMaterial.maxPerspectivePointSize) + ".0);"); - } else { - src.push("gl_PointSize = pointSize;"); + this.vertexPointsGeometryDefs(src); + this.vertexPointsDrawDefs(src); + this.vertexPickMainOpen(src); + { + this.vertexPointsFilterLogicOpenBlock(src); + { + this.vertexDrawPointsBatchingTransformLogic(src); + this.vertexSlicingLogic(src); + this.vertexDrawPointsColorsLogic(src); + this.vertexPointsGeometryLogic(src); + } + this.vertexPointsFilterLogicCloseBlock(src); } - src.push("gl_PointSize += 10.0;"); - src.push(" }"); - src.push("}"); + this.vertexMainClose(src); } - buildFragmentShader(src: string[]) :void{ - const renderContext = this.renderContext; - const view = renderContext.view; - const clipping = view.getNumAllocatedSectionPlanes() > 0; - src.push(`#version 300 es - // Points batching pick mesh vertex shader - #ifdef GL_FRAGMENT_PRECISION_HIGH - precision highp float; - precision highp int; - #else; - precision mediump float; - precision mediump int; - #endif`); - // if (view.logarithmicDepthBufferEnabled) { - // src.push("uniform float logDepthBufFC;"); - // src.push("in float vFragDepth;"); - // } - if (clipping) { - src.push("in vec4 vWorldPosition;"); - src.push("in float vFlags;"); - for (var i = 0; i < view.getNumAllocatedSectionPlanes(); i++) { - src.push("uniform bool sectionPlaneActive" + i + ";"); - src.push("uniform vec3 sectionPlanePos" + i + ";"); - src.push("uniform vec3 sectionPlaneDir" + i + ";"); - } - } - src.push("in vec4 vPickColor;"); - src.push("out vec4 outColor;"); + buildFragmentShader(src: string[]): void { + this.fragmentHeader(src); + this.fragmentPrecisionDefs(src); + this.fragmentCommonDefs(src); + this.fragmentSlicingDefs(src); + this.fragmentDrawFlatColorDefs(src); src.push("void main(void) {"); - if (view.pointsMaterial.roundPoints) { - src.push(" vec2 cxy = 2.0 * gl_PointCoord - 1.0;"); - src.push(" float r = dot(cxy, cxy);"); - src.push(" if (r > 1.0) {"); - src.push(" discard;"); - src.push(" }"); - } - if (clipping) { - src.push(" bool clippable = (int(vFlags) >> 16 & 0xF) == 1;"); - src.push(" if (clippable) {"); - src.push(" float dist = 0.0;"); - for (let i = 0; i < view.getNumAllocatedSectionPlanes(); i++) { - src.push(" if (sectionPlaneActive" + i + ") {"); - src.push(" dist += clamp(dot(-sectionPlaneDir" + i + ".xyz, vWorldPosition.xyz - sectionPlanePos" + i + ".xyz), 0.0, 1000.0);"); - src.push(" }"); - } - src.push(" if (dist > 0.0) { discard; }"); - src.push(" }"); + { + this.fragmentPointsGeometryLogic(src); + this.fragmentSlicingLogic(src); + this.fragmentDrawFlatColorLogic(src); + this.fragmentCommonOutput(src); } - // if (view.logarithmicDepthBufferEnabled) { - // src.push("gl_FragDepth = log2( vFragDepth ) * logDepthBufFC * 0.5;"); - // } - src.push(" outColor = vPickColor; "); src.push("}"); } - drawVBOBatchingLayerPrimitives(vboBatchingLayer: VBOBatchingLayer, renderPass: number) { - // this.bind(renderPass); - // const view = this.renderContext.view; - // const viewIndex = view.viewIndex; - // const gl = this.renderContext.gl; - // const attributes = this.attributes; - // const renderState = vboBatchingLayer.renderState; - // attributes.position.bindArrayBuffer(renderState.positionsBuf); - // if (attributes.pickColor) { - // attributes.pickColor.bindArrayBuffer(renderState.pickColorsBuf); - // } - // if (attributes.flags) { - // attributes.flags.bindArrayBuffer(renderState.flagsBufs[viewIndex]); - // } - // gl.uniform1i(this.uniforms.renderPass, renderPass); - // gl.uniformMatrix4fv(this.uniforms.positionsDecodeMatrix, false, renderState.positionsDecodeMatrix); - // - // gl.uniformMatrix4fv(this.uniforms.worldMatrix, false, vboBatchingLayer.rendererModel.worldMatrix); - // gl.uniformMatrix4fv(this.uniforms.viewMatrix, false, createRTCViewMat(this.renderContext.view.camera.viewMatrix, renderState.origin)); - // gl.drawArrays(gl.POINTS, 0, renderState.positionsBuf.numItems); + drawVBOBatchingLayerPrimitives(vboBatchingLayer: VBOBatchingLayer, renderPass: number): void { + const gl = this.renderContext.gl; + gl.drawArrays(gl.POINTS, 0, vboBatchingLayer.renderState.positionsBuf.numItems); } } diff --git a/packages/webglrenderer/src/vbo/batching/points/renderers/VBOPointsBatchingSilhouetteRenderer.ts b/packages/webglrenderer/src/vbo/batching/points/renderers/VBOPointsBatchingSilhouetteRenderer.ts index b54ec5a7b..611031615 100644 --- a/packages/webglrenderer/src/vbo/batching/points/renderers/VBOPointsBatchingSilhouetteRenderer.ts +++ b/packages/webglrenderer/src/vbo/batching/points/renderers/VBOPointsBatchingSilhouetteRenderer.ts @@ -1,6 +1,4 @@ import {VBOBatchingLayer} from "../../VBOBatchingLayer"; -import {RENDER_PASSES} from "../../../../RENDER_PASSES"; -import {createRTCViewMat} from "@xeokit/rtc"; import {VBOBatchingRenderer} from "../../VBOBatchingRenderer"; /** @@ -9,119 +7,50 @@ import {VBOBatchingRenderer} from "../../VBOBatchingRenderer"; export class VBOPointsBatchingSilhouetteRenderer extends VBOBatchingRenderer { getHash(): string { - return ""; + const view = this.renderContext.view; + const pointsMaterial = view.pointsMaterial; + return `${pointsMaterial.perspectivePoints}-${pointsMaterial.filterIntensity}-${pointsMaterial.roundPoints}-${view.getSectionPlanesHash()}`; } - buildVertexShader(src: string[]) :void{ - const renderContext = this.renderContext; - const view = renderContext.view; - const clipping = view.getNumAllocatedSectionPlanes() > 0; - const pointsMaterial = view.pointsMaterial; + buildVertexShader(src: string[]): void { this.vertexHeader(src); this.vertexCommonDefs(src); + this.vertexBatchingTransformDefs(src); this.vertexSlicingDefs(src); - src.push("uniform vec4 color;"); - src.push("uniform float pointSize;"); - if (pointsMaterial.perspectivePoints) { - src.push("uniform float nearPlaneHeight;"); - } - - src.push("void main(void) {"); - // silhouetteFlag = NOT_RENDERED | SILHOUETTE_HIGHLIGHTED | SILHOUETTE_SELECTED | SILHOUETTE_XRAYED - // renderPass = SILHOUETTE_HIGHLIGHTED | SILHOUETTE_SELECTED | | SILHOUETTE_XRAYED - src.push(`int silhouetteFlag = int(flags) >> 4 & 0xF;`); - src.push(`if (silhouetteFlag != renderPass) {`); - src.push(" gl_Position = vec4(0.0, 0.0, 0.0, 0.0);"); // Cull vertex - src.push("} else {"); - src.push("vec4 worldPosition = worldMatrix * (positionsDecodeMatrix * vec4(position, 1.0)); "); - src.push("vec4 viewPosition = viewMatrix * worldPosition; "); - if (clipping) { - src.push("vWorldPosition = worldPosition;"); - src.push("vFlags = flags;"); - } - src.push("vec4 clipPos = projMatrix * viewPosition;"); - // if (view.logarithmicDepthBufferEnabled) { - // src.push("vFragDepth = 1.0 + clipPos.w;"); - // } - src.push("gl_Position = clipPos;"); - if (pointsMaterial.perspectivePoints) { - src.push("gl_PointSize = (nearPlaneHeight * pointSize) / clipPos.w;"); - src.push("gl_PointSize = max(gl_PointSize, " + Math.floor(pointsMaterial.minPerspectivePointSize) + ".0);"); - src.push("gl_PointSize = min(gl_PointSize, " + Math.floor(pointsMaterial.maxPerspectivePointSize) + ".0);"); - } else { - src.push("gl_PointSize = pointSize;"); + this.vertexPointsGeometryDefs(src); + this.vertexSilhouetteDefs(src); + this.vertexSilhouetteMainOpen(src); + { + this.vertexPointsFilterLogicOpenBlock(src); + { + this.vertexDrawPointsBatchingTransformLogic(src); + this.vertexSlicingLogic(src); + this.vertexDrawPointsColorsLogic(src); + this.vertexPointsGeometryLogic(src); + } + this.vertexPointsFilterLogicCloseBlock(src); } - src.push("}"); - src.push("}"); + this.vertexMainClose(src); } - buildFragmentShader(src: string[]):void { - const renderContext = this.renderContext; - const view = renderContext.view; - const clipping = view.getNumAllocatedSectionPlanes() > 0; + buildFragmentShader(src: string[]): void { this.fragmentHeader(src); - src.push("#ifdef GL_FRAGMENT_PRECISION_HIGH"); - src.push("precision highp float;"); - src.push("precision highp int;"); - src.push("#else"); - src.push("precision mediump float;"); - src.push("precision mediump int;"); - src.push("#endif"); - if (clipping) { - src.push("in vec4 vWorldPosition;"); - src.push("in float vFlags;"); - for (let i = 0, len = view.getNumAllocatedSectionPlanes(); i < len; i++) { - src.push("uniform bool sectionPlaneActive" + i + ";"); - src.push("uniform vec3 sectionPlanePos" + i + ";"); - src.push("uniform vec3 sectionPlaneDir" + i + ";"); - } - } - src.push("uniform vec4 color;"); - src.push("out vec4 outColor;"); + this.fragmentPrecisionDefs(src); + this.fragmentCommonDefs(src); + this.fragmentSlicingDefs(src); + this.fragmentDrawFlatColorDefs(src); src.push("void main(void) {"); - if (view.pointsMaterial.roundPoints) { - src.push(" vec2 cxy = 2.0 * gl_PointCoord - 1.0;"); - src.push(" float r = dot(cxy, cxy);"); - src.push(" if (r > 1.0) {"); - src.push(" discard;"); - src.push(" }"); + { + this.fragmentPointsGeometryLogic(src); + this.fragmentSlicingLogic(src); + this.fragmentSilhouetteLogic(src); + this.fragmentCommonOutput(src); } - this.fragmentSlicingLogic(src); - src.push("outColor = color;"); src.push("}"); } drawVBOBatchingLayerPrimitives(vboBatchingLayer: VBOBatchingLayer, renderPass: number): void { - // this.bind(renderPass); - // const view = this.renderContext.view; - // const viewIndex = view.viewIndex; - // let material; - // if (renderPass === RENDER_PASSES.SILHOUETTE_XRAYED) { - // material = view.xrayMaterial; - // } else if (renderPass === RENDER_PASSES.SILHOUETTE_HIGHLIGHTED) { - // material = view.highlightMaterial; - // } else if (renderPass === RENDER_PASSES.SILHOUETTE_SELECTED) { - // material = view.selectedMaterial; - // } else { - // return; - // } - // const gl = this.renderContext.gl; - // const color = material.fillColor; - // const alpha = material.fillAlpha; - // gl.uniform4f(this.uniforms.silhouetteColor, color[0], color[1], color[2], alpha); - // const attributes = this.attributes; - // const renderState = vboBatchingLayer.renderState; - // attributes.position.bindArrayBuffer(renderState.positionsBuf); - // if (attributes.color) { - // attributes.color.bindArrayBuffer(renderState.colorsBuf[viewIndex]); - // } - // if (attributes.flags) { - // attributes.flags.bindArrayBuffer(renderState.flagsBufs[viewIndex]); - // } - // gl.uniform1i(this.uniforms.renderPass, renderPass); - // gl.uniformMatrix4fv(this.uniforms.positionsDecodeMatrix, false, renderState.positionsDecodeMatrix); - // gl.uniformMatrix4fv(this.uniforms.worldMatrix, false, vboBatchingLayer.rendererModel.worldMatrix); - // gl.uniformMatrix4fv(this.uniforms.viewMatrix, false, createRTCViewMat(this.renderContext.view.camera.viewMatrix, renderState.origin)); - // gl.drawArrays(gl.POINTS, 0, renderState.positionsBuf.numItems); + const gl = this.renderContext.gl; + gl.drawArrays(gl.POINTS, 0, vboBatchingLayer.renderState.positionsBuf.numItems); } } diff --git a/packages/webglrenderer/src/vbo/batching/points/renderers/rendererFactory.ts b/packages/webglrenderer/src/vbo/batching/points/renderers/rendererFactory.ts index 8b26c18ad..bb7655aa8 100644 --- a/packages/webglrenderer/src/vbo/batching/points/renderers/rendererFactory.ts +++ b/packages/webglrenderer/src/vbo/batching/points/renderers/rendererFactory.ts @@ -1,6 +1,6 @@ import {WebGLRenderer} from "../../../../WebGLRenderer"; import {VBOBatchingRenderer} from "../../VBOBatchingRenderer"; -import {VBOPointsBatchingDrawRenderer} from "./VBOPointsBatchingDrawRenderer"; +import {VBOPointsBatchingDrawColorRenderer} from "./VBOPointsBatchingDrawColorRenderer"; import {VBOPointsBatchingPickMeshRenderer} from "./VBOPointsBatchingPickMeshRenderer"; import {VBOPointsBatchingSilhouetteRenderer} from "./VBOPointsBatchingSilhouetteRenderer"; import {RendererSetFactory, VBORendererSet} from "../../../VBORendererSet"; @@ -12,8 +12,8 @@ import {VBORenderer} from "../../../VBORenderer"; */ class RendererFactory extends VBORendererSet { - createDrawRenderer(): VBOBatchingRenderer { - return new VBOPointsBatchingDrawRenderer(this.renderContext); + createDrawColorRenderer(): VBOBatchingRenderer { + return new VBOPointsBatchingDrawColorRenderer(this.renderContext); } createPickMeshRenderer(): VBORenderer { diff --git a/packages/webglrenderer/src/vbo/batching/triangles/renderers/VBOTrianglesBatchingDrawRenderer.ts b/packages/webglrenderer/src/vbo/batching/triangles/renderers/VBOTrianglesBatchingDrawColorRenderer.ts similarity index 85% rename from packages/webglrenderer/src/vbo/batching/triangles/renderers/VBOTrianglesBatchingDrawRenderer.ts rename to packages/webglrenderer/src/vbo/batching/triangles/renderers/VBOTrianglesBatchingDrawColorRenderer.ts index b112b4acd..43c0ad80f 100644 --- a/packages/webglrenderer/src/vbo/batching/triangles/renderers/VBOTrianglesBatchingDrawRenderer.ts +++ b/packages/webglrenderer/src/vbo/batching/triangles/renderers/VBOTrianglesBatchingDrawColorRenderer.ts @@ -4,7 +4,7 @@ import {VBOBatchingRenderer} from "../../VBOBatchingRenderer"; /** * @private */ -export class VBOTrianglesBatchingDrawRenderer extends VBOBatchingRenderer { +export class VBOTrianglesBatchingDrawColorRenderer extends VBOBatchingRenderer { getHash(): string { const view = this.renderContext.view; @@ -17,24 +17,26 @@ export class VBOTrianglesBatchingDrawRenderer extends VBOBatchingRenderer { this.vertexBatchingTransformDefs(src); this.vertexSlicingDefs(src); this.vertexDrawLambertDefs(src); - this.vertexColorMainOpenBlock(src); + this.vertexDrawMainOpen(src); { this.vertexDrawBatchingTransformLogic(src); this.vertexDrawLambertLogic(src); this.vertexSlicingLogic(src); } - this.vertexColorMainCloseBlock(src); + this.vertexMainClose(src); } buildFragmentShader(src: string[]) :void{ this.fragmentHeader(src); this.fragmentPrecisionDefs(src); + this.fragmentCommonDefs(src); this.fragmentSlicingDefs(src); this.fragmentDrawLambertDefs(src); src.push("void main(void) {"); { this.fragmentSlicingLogic(src); this.fragmentDrawLambertLogic(src); + this.fragmentCommonOutput(src); } src.push("}"); } diff --git a/packages/webglrenderer/src/vbo/batching/triangles/renderers/VBOTrianglesBatchingDrawColorSAORenderer.ts b/packages/webglrenderer/src/vbo/batching/triangles/renderers/VBOTrianglesBatchingDrawColorSAORenderer.ts new file mode 100644 index 000000000..77de265ea --- /dev/null +++ b/packages/webglrenderer/src/vbo/batching/triangles/renderers/VBOTrianglesBatchingDrawColorSAORenderer.ts @@ -0,0 +1,51 @@ +import {VBOBatchingLayer} from "../../VBOBatchingLayer"; +import {VBOBatchingRenderer} from "../../VBOBatchingRenderer"; + +/** + * @private + */ +export class VBOTrianglesBatchingDrawColorSAORenderer extends VBOBatchingRenderer { + + getHash(): string { + const view = this.renderContext.view; + return `${view.getLightsHash()}-${view.getSectionPlanesHash()}`; + } + + buildVertexShader(src: string[]):void { + this.vertexHeader(src); + this.vertexCommonDefs(src); + this.vertexBatchingTransformDefs(src); + this.vertexSlicingDefs(src); + this.vertexDrawLambertDefs(src); + this.vertexDrawMainOpen(src); + { + this.vertexDrawBatchingTransformLogic(src); + this.vertexDrawLambertLogic(src); + this.vertexSlicingLogic(src); + } + this.vertexMainClose(src); + } + + buildFragmentShader(src: string[]) :void{ + this.fragmentHeader(src); + this.fragmentPrecisionDefs(src); + this.fragmentCommonDefs(src); + this.fragmentSlicingDefs(src); + this.fragmentDrawLambertDefs(src); + this.fragmentDrawSAODefs(src); + src.push("void main(void) {"); + { + this.fragmentSlicingLogic(src); + this.fragmentDrawLambertLogic(src); + this.fragmentDrawSAOLogic(src); + this.fragmentCommonOutput(src); + } + src.push("}"); + } + + drawVBOBatchingLayerPrimitives(vboBatchingLayer: VBOBatchingLayer, renderPass: number): void { + const gl = this.renderContext.gl; + const renderState = vboBatchingLayer.renderState; + gl.drawElements(gl.TRIANGLES, renderState.indicesBuf.numItems, renderState.indicesBuf.itemType, 0); + } +} diff --git a/packages/webglrenderer/src/vbo/batching/triangles/renderers/VBOTrianglesBatchingDrawDepthRenderer.ts b/packages/webglrenderer/src/vbo/batching/triangles/renderers/VBOTrianglesBatchingDrawDepthRenderer.ts new file mode 100644 index 000000000..5f62932ed --- /dev/null +++ b/packages/webglrenderer/src/vbo/batching/triangles/renderers/VBOTrianglesBatchingDrawDepthRenderer.ts @@ -0,0 +1,46 @@ +import {VBOBatchingLayer} from "../../VBOBatchingLayer"; +import {VBOBatchingRenderer} from "../../VBOBatchingRenderer"; + +/** + * @private + */ +export class VBOTrianglesBatchingDrawDepthRenderer extends VBOBatchingRenderer { + + getHash(): string { + return `${this.slicingHash}`; + } + + buildVertexShader(src: string[]): void { + this.vertexHeader(src); + this.vertexCommonDefs(src); + this.vertexBatchingTransformDefs(src); + this.vertexSlicingDefs(src); + this.vertexDrawMainOpen(src); + { + this.vertexDrawBatchingTransformLogic(src); + this.vertexSlicingLogic(src); + } + this.vertexMainClose(src); + } + + buildFragmentShader(src: string[]): void { + this.fragmentHeader(src); + this.fragmentPrecisionDefs(src); + this.fragmentCommonDefs(src); + this.fragmentDrawDepthDefs(src); + this.fragmentSlicingDefs(src); + src.push("void main(void) {"); + { + this.fragmentSlicingLogic(src); + this.fragmentDrawDepthLogic(src); + this.fragmentCommonOutput(src); + } + src.push("}"); + } + + drawVBOBatchingLayerPrimitives(vboBatchingLayer: VBOBatchingLayer, renderPass: number): void { + const gl = this.renderContext.gl; + const renderState = vboBatchingLayer.renderState; + gl.drawElements(gl.TRIANGLES, renderState.indicesBuf.numItems, renderState.indicesBuf.itemType, 0); + } +} diff --git a/packages/webglrenderer/src/vbo/batching/triangles/renderers/VBOTrianglesBatchingEdgesDrawRenderer.ts b/packages/webglrenderer/src/vbo/batching/triangles/renderers/VBOTrianglesBatchingEdgesDrawRenderer.ts index 8a01bff52..e2b0dd79a 100644 --- a/packages/webglrenderer/src/vbo/batching/triangles/renderers/VBOTrianglesBatchingEdgesDrawRenderer.ts +++ b/packages/webglrenderer/src/vbo/batching/triangles/renderers/VBOTrianglesBatchingEdgesDrawRenderer.ts @@ -20,25 +20,27 @@ export class VBOTrianglesBatchingEdgesDrawRenderer extends VBOBatchingRenderer { this.vertexCommonDefs(src); this.vertexBatchingTransformDefs(src); this.vertexSlicingDefs(src); - this.vertexDrawEdgesColorDefs(src); - this.vertexColorMainOpenBlock(src); + this.vertexDrawFlatColorDefs(src); + this.vertexDrawMainOpen(src); { this.vertexDrawBatchingTransformLogic(src); this.vertexDrawEdgesColorLogic(src); this.vertexSlicingLogic(src); } - this.vertexColorMainCloseBlock(src); + this.vertexMainClose(src); } buildFragmentShader(src: string[]): void { this.fragmentHeader(src); this.fragmentPrecisionDefs(src); + this.fragmentCommonDefs(src); this.fragmentSlicingDefs(src); - this.fragmentDrawEdgesColorDefs(src); + this.fragmentDrawFlatColorDefs(src); src.push("void main(void) {"); { this.fragmentSlicingLogic(src); - this.fragmentDrawEdgesColorLogic(src); + this.fragmentDrawFlatColorLogic(src); + this.fragmentCommonOutput(src); } src.push("}"); } diff --git a/packages/webglrenderer/src/vbo/batching/triangles/renderers/VBOTrianglesBatchingEdgesSilhouetteRenderer.ts b/packages/webglrenderer/src/vbo/batching/triangles/renderers/VBOTrianglesBatchingEdgesSilhouetteRenderer.ts index e1933dd49..d905d62c9 100644 --- a/packages/webglrenderer/src/vbo/batching/triangles/renderers/VBOTrianglesBatchingEdgesSilhouetteRenderer.ts +++ b/packages/webglrenderer/src/vbo/batching/triangles/renderers/VBOTrianglesBatchingEdgesSilhouetteRenderer.ts @@ -20,25 +20,27 @@ export class VBOTrianglesBatchingEdgesSilhouetteRenderer extends VBOBatchingRend this.vertexCommonDefs(src); this.vertexBatchingTransformDefs(src); this.vertexSlicingDefs(src); - this.vertexDrawEdgesSilhouetteDefs(src); - this.openVertexSilhouetteMain(src); + this.vertexSilhouetteDefs(src); + this.vertexSilhouetteMainOpen(src); { this.vertexDrawBatchingTransformLogic(src); - this.vertexDrawEdgesSilhouetteLogic(src); + this.vertexSilhouetteLogic(src); this.vertexSlicingLogic(src); } - this.vertexColorMainCloseBlock(src); + this.vertexMainClose(src); } buildFragmentShader(src: string[]): void { this.fragmentHeader(src); this.fragmentPrecisionDefs(src); + this.fragmentCommonDefs(src); this.fragmentSlicingDefs(src); - this.fragmentDrawEdgesSilhouetteDefs(src); + this.fragmentSilhouetteDefs(src); src.push("void main(void) {"); { this.fragmentSlicingLogic(src); - this.fragmentDrawEdgesSilhouetteLogic(src); + this.fragmentSilhouetteLogic(src); + this.fragmentCommonOutput(src); } src.push("}"); } diff --git a/packages/webglrenderer/src/vbo/batching/triangles/renderers/VBOTrianglesBatchingPickMeshRenderer.ts b/packages/webglrenderer/src/vbo/batching/triangles/renderers/VBOTrianglesBatchingPickMeshRenderer.ts index a9b416791..7ce4744c2 100644 --- a/packages/webglrenderer/src/vbo/batching/triangles/renderers/VBOTrianglesBatchingPickMeshRenderer.ts +++ b/packages/webglrenderer/src/vbo/batching/triangles/renderers/VBOTrianglesBatchingPickMeshRenderer.ts @@ -15,25 +15,27 @@ export class VBOTrianglesBatchingPickMeshRenderer extends VBOBatchingRenderer { this.vertexCommonDefs(src); this.vertexBatchingTransformDefs(src); this.vertexSlicingDefs(src); - this.vertexPickMeshShadingDefs(src); - this.openVertexPickMain(src); + this.vertexPickMeshDefs(src); + this.vertexPickMainOpen(src); { this.vertexPickBatchingTransformLogic(src); - this.vertexPickMeshShadingLogic(src); + this.vertexPickMeshLogic(src); this.vertexSlicingLogic(src); } - this.vertexPickMainCloseBlock(src); + this.vertexMainClose(src); } buildFragmentShader(src: string[]):void { this.fragmentHeader(src); this.fragmentPrecisionDefs(src); + this.fragmentCommonDefs(src); this.fragmentSlicingDefs(src); - this.fragmentPickMeshShadingDefs(src); + this.fragmentPickMeshDefs(src); src.push("void main(void) {"); { this.fragmentSlicingLogic(src); - this.fragmentPickMeshShadingLogic(src); + this.fragmentPickMeshLogic(src); + this.fragmentCommonOutput(src); } src.push("}"); } diff --git a/packages/webglrenderer/src/vbo/batching/triangles/renderers/VBOTrianglesBatchingSilhouetteRenderer.ts b/packages/webglrenderer/src/vbo/batching/triangles/renderers/VBOTrianglesBatchingSilhouetteRenderer.ts index 1881d3b48..3241096fc 100644 --- a/packages/webglrenderer/src/vbo/batching/triangles/renderers/VBOTrianglesBatchingSilhouetteRenderer.ts +++ b/packages/webglrenderer/src/vbo/batching/triangles/renderers/VBOTrianglesBatchingSilhouetteRenderer.ts @@ -15,24 +15,28 @@ export class VBOTrianglesBatchingSilhouetteRenderer extends VBOBatchingRenderer this.vertexCommonDefs(src); this.vertexBatchingTransformDefs(src); this.vertexSlicingDefs(src); - this.vertexDrawSilhouetteDefs(src); - this.openVertexSilhouetteMain(src); + this.vertexSilhouetteDefs(src); + this.vertexSilhouetteMainOpen(src); { this.vertexDrawBatchingTransformLogic(src); - this.vertexDrawSilhouetteLogic(src); + this.vertexSilhouetteLogic(src); this.vertexSlicingLogic(src); } - this.vertexColorMainCloseBlock(src); + this.vertexMainClose(src); } buildFragmentShader(src: string[]): void { this.fragmentHeader(src); this.fragmentPrecisionDefs(src); + this.fragmentCommonDefs(src); this.fragmentSlicingDefs(src); - this.fragmentDrawSilhouetteDefs(src); + this.fragmentSilhouetteDefs(src); src.push("void main(void) {"); - this.fragmentSlicingLogic(src); - this.fragmentDrawSilhouetteLogic(src); + { + this.fragmentSlicingLogic(src); + this.fragmentSilhouetteLogic(src); + this.fragmentCommonOutput(src); + } src.push("}"); } diff --git a/packages/webglrenderer/src/vbo/batching/triangles/renderers/rendererFactory.ts b/packages/webglrenderer/src/vbo/batching/triangles/renderers/rendererFactory.ts index 5287a6208..c028c88ea 100644 --- a/packages/webglrenderer/src/vbo/batching/triangles/renderers/rendererFactory.ts +++ b/packages/webglrenderer/src/vbo/batching/triangles/renderers/rendererFactory.ts @@ -1,12 +1,13 @@ import {WebGLRenderer} from "../../../../WebGLRenderer"; import {RendererSetFactory, VBORendererSet} from "../../../VBORendererSet"; -import {VBOTrianglesBatchingDrawRenderer} from "./VBOTrianglesBatchingDrawRenderer"; +import {VBOTrianglesBatchingDrawColorRenderer} from "./VBOTrianglesBatchingDrawColorRenderer"; import {VBORenderer} from "../../../VBORenderer"; import {VBOTrianglesBatchingPickMeshRenderer} from "./VBOTrianglesBatchingPickMeshRenderer"; import {VBOTrianglesBatchingSilhouetteRenderer} from "./VBOTrianglesBatchingSilhouetteRenderer"; import {VBOTrianglesBatchingEdgesDrawRenderer} from "./VBOTrianglesBatchingEdgesDrawRenderer"; import {VBOTrianglesBatchingEdgesSilhouetteRenderer} from "./VBOTrianglesBatchingEdgesSilhouetteRenderer"; - +import {VBOTrianglesBatchingDrawDepthRenderer} from "./VBOTrianglesBatchingDrawDepthRenderer"; +import {VBOTrianglesBatchingDrawColorSAORenderer} from "./VBOTrianglesBatchingDrawColorSAORenderer"; /** @@ -14,8 +15,16 @@ import {VBOTrianglesBatchingEdgesSilhouetteRenderer} from "./VBOTrianglesBatchin */ class RendererFactory extends VBORendererSet { - createDrawRenderer(): VBORenderer { - return new VBOTrianglesBatchingDrawRenderer(this.renderContext); + createDrawColorRenderer(): VBORenderer { + return new VBOTrianglesBatchingDrawColorRenderer(this.renderContext); + } + + createDrawColorSAORenderer(): VBORenderer { + return new VBOTrianglesBatchingDrawColorSAORenderer(this.renderContext); + } + + createDrawDepthRenderer(): VBORenderer { + return new VBOTrianglesBatchingDrawDepthRenderer(this.renderContext); } createPickMeshRenderer(): VBORenderer { diff --git a/packages/webglrenderer/src/vbo/instancing/VBOInstancingLayer.ts b/packages/webglrenderer/src/vbo/instancing/VBOInstancingLayer.ts index 3d91d633a..ea09c2288 100644 --- a/packages/webglrenderer/src/vbo/instancing/VBOInstancingLayer.ts +++ b/packages/webglrenderer/src/vbo/instancing/VBOInstancingLayer.ts @@ -15,6 +15,7 @@ import {SCENE_OBJECT_FLAGS} from "../../SCENE_OBJECT_FLAGS"; import {RENDER_PASSES} from "../../RENDER_PASSES"; import {LayerMeshParams} from "../../LayerMeshParams"; import {VBORendererSet} from "../VBORendererSet"; +import {SolidPrimitive, SurfacePrimitive, TrianglesPrimitive} from "@xeokit/constants"; const tempUint8Vec4 = new Uint8Array(4); const tempFloat32 = new Float32Array(1); @@ -41,16 +42,18 @@ export class VBOInstancingLayer implements Layer { #rendererSet: VBORendererSet; #aabb: FloatArrayParam; + #buffer: VBOInstancingBuffer; + #meshes: any[]; + #portions: any[]; + #built: boolean; + layerIndex: number; sortId: string; primitive: number; aabbDirty: boolean; meshCounts: MeshCounts[]; - #buffer: VBOInstancingBuffer; - #meshes: any[]; - #portions: any[]; - #built: boolean; renderContext: RenderContext; + saoSupported: boolean; constructor(layerParams: VBOInstancingLayerParams, rendererSet: VBORendererSet) { @@ -68,7 +71,7 @@ export class VBOInstancingLayer implements Layer { this.#aabb = collapseAABB3(); this.meshCounts = []; - for (let i =0, len = this.renderContext.viewer.viewList.length; i < len; i++) { + for (let i = 0, len = this.renderContext.viewer.viewList.length; i < len; i++) { this.meshCounts.push(new MeshCounts()); } @@ -136,7 +139,7 @@ export class VBOInstancingLayer implements Layer { const color = sceneMesh.color; const opacity = sceneMesh.opacity !== null && sceneMesh.opacity !== undefined ? sceneMesh.opacity : 255; - const meshMatrix = sceneMesh.rtcMatrix; + const rtcMatrix = sceneMesh.rtcMatrix; const pickColor = layerMeshParams.pickColor; if (this.#built) { @@ -152,20 +155,20 @@ export class VBOInstancingLayer implements Layer { this.#buffer.colors.push(b); this.#buffer.colors.push(opacity); - this.#buffer.modelMatrixCol0.push(meshMatrix[0]); - this.#buffer.modelMatrixCol0.push(meshMatrix[4]); - this.#buffer.modelMatrixCol0.push(meshMatrix[8]); - this.#buffer.modelMatrixCol0.push(meshMatrix[12]); + this.#buffer.modelMatrixCol0.push(rtcMatrix[0]); + this.#buffer.modelMatrixCol0.push(rtcMatrix[4]); + this.#buffer.modelMatrixCol0.push(rtcMatrix[8]); + this.#buffer.modelMatrixCol0.push(rtcMatrix[12]); - this.#buffer.modelMatrixCol1.push(meshMatrix[1]); - this.#buffer.modelMatrixCol1.push(meshMatrix[5]); - this.#buffer.modelMatrixCol1.push(meshMatrix[9]); - this.#buffer.modelMatrixCol1.push(meshMatrix[13]); + this.#buffer.modelMatrixCol1.push(rtcMatrix[1]); + this.#buffer.modelMatrixCol1.push(rtcMatrix[5]); + this.#buffer.modelMatrixCol1.push(rtcMatrix[9]); + this.#buffer.modelMatrixCol1.push(rtcMatrix[13]); - this.#buffer.modelMatrixCol2.push(meshMatrix[2]); - this.#buffer.modelMatrixCol2.push(meshMatrix[6]); - this.#buffer.modelMatrixCol2.push(meshMatrix[10]); - this.#buffer.modelMatrixCol2.push(meshMatrix[14]); + this.#buffer.modelMatrixCol2.push(rtcMatrix[2]); + this.#buffer.modelMatrixCol2.push(rtcMatrix[6]); + this.#buffer.modelMatrixCol2.push(rtcMatrix[10]); + this.#buffer.modelMatrixCol2.push(rtcMatrix[14]); // Per-vertex pick colors @@ -262,6 +265,7 @@ export class VBOInstancingLayer implements Layer { renderState.pickColorsBuf = new WebGLArrayBuf(gl, gl.ARRAY_BUFFER, new Uint8Array(this.#buffer.pickColors), this.#buffer.pickColors.length, 4, gl.STATIC_DRAW, normalized); this.#buffer.pickColors = []; // Release memory } + renderState.pbrSupported = !!renderState.metallicRoughnessBuf && !!renderState.uvBuf @@ -269,10 +273,17 @@ export class VBOInstancingLayer implements Layer { && !!textureSet && !!textureSet.colorTexture && !!textureSet.metallicRoughnessTexture; + renderState.colorTextureSupported = !!renderState.uvBuf && !!textureSet && !!textureSet.colorTexture; + + this.saoSupported + = (sceneGeometry.primitive === SolidPrimitive + || sceneGeometry.primitive === SurfacePrimitive + || sceneGeometry.primitive === TrianglesPrimitive); + this.renderState.sceneGeometry = null; this.#built = true; } @@ -461,9 +472,9 @@ export class VBOInstancingLayer implements Layer { colorFlag = RENDER_PASSES.NOT_RENDERED; } else { if (transparent) { - colorFlag = RENDER_PASSES.COLOR_TRANSPARENT; + colorFlag = RENDER_PASSES.DRAW_TRANSPARENT; } else { - colorFlag = RENDER_PASSES.COLOR_OPAQUE; + colorFlag = RENDER_PASSES.DRAW_OPAQUE; } } let silhouetteFlag; @@ -525,7 +536,20 @@ export class VBOInstancingLayer implements Layer { return; } if (this.#rendererSet.colorRenderer) { - this.#rendererSet.colorRenderer.renderVBOInstancingLayer(this, RENDER_PASSES.COLOR_OPAQUE); + this.#rendererSet.colorRenderer.renderVBOInstancingLayer(this, RENDER_PASSES.DRAW_OPAQUE); + } + } + + drawColorSAOOpaque(): void { + const viewIndex = this.renderContext.view.viewIndex; + if (this.meshCounts[viewIndex].numCulled === this.meshCounts[viewIndex].numMeshes || + this.meshCounts[viewIndex].numVisible === 0 || + this.meshCounts[viewIndex].numTransparent === this.meshCounts[viewIndex].numMeshes || + this.meshCounts[viewIndex].numXRayed === this.meshCounts[viewIndex].numMeshes) { + return; + } + if (this.#rendererSet.colorSAORenderer) { + this.#rendererSet.colorSAORenderer.renderVBOInstancingLayer(this, RENDER_PASSES.DRAW_OPAQUE); } } @@ -538,7 +562,7 @@ export class VBOInstancingLayer implements Layer { return; } if (this.#rendererSet.colorRenderer) { - this.#rendererSet.colorRenderer.renderVBOInstancingLayer(this, RENDER_PASSES.COLOR_TRANSPARENT); + this.#rendererSet.colorRenderer.renderVBOInstancingLayer(this, RENDER_PASSES.DRAW_TRANSPARENT); } } @@ -550,9 +574,9 @@ export class VBOInstancingLayer implements Layer { this.meshCounts[viewIndex].numXRayed === this.meshCounts[viewIndex].numMeshes) { return; } - // if (this.#rendererSet.depthRenderer) { - // this.#rendererSet.depthRenderer.renderVBOInstancingLayer(this, RENDER_PASSES.COLOR_OPAQUE); // Assume whatever post-effect uses depth (eg SAO) does not apply to transparent objects - // } + if (this.#rendererSet.drawDepthRenderer) { + this.#rendererSet.drawDepthRenderer.renderVBOInstancingLayer(this, RENDER_PASSES.DRAW_OPAQUE); // Assume whatever post-effect uses depth (eg SAO) does not apply to transparent objects + } } drawNormals(): void { @@ -564,7 +588,7 @@ export class VBOInstancingLayer implements Layer { return; } // if (this.#rendererSet.normalsRenderer) { - // this.#rendererSet.normalsRenderer.renderVBOInstancingLayer(this, RENDER_PASSES.COLOR_OPAQUE); // Assume whatever post-effect uses normals (eg SAO) does not apply to transparent objects + // this.#rendererSet.normalsRenderer.renderVBOInstancingLayer(this, RENDER_PASSES.DRAW_OPAQUE); // Assume whatever post-effect uses normals (eg SAO) does not apply to transparent objects // } } @@ -611,7 +635,7 @@ export class VBOInstancingLayer implements Layer { return; } if (this.#rendererSet.edgesColorRenderer) { - this.#rendererSet.edgesColorRenderer.renderVBOInstancingLayer(this, RENDER_PASSES.COLOR_OPAQUE); + this.#rendererSet.edgesColorRenderer.renderVBOInstancingLayer(this, RENDER_PASSES.DRAW_OPAQUE); } } @@ -623,7 +647,7 @@ export class VBOInstancingLayer implements Layer { return; } if (this.#rendererSet.edgesColorRenderer) { - this.#rendererSet.edgesColorRenderer.renderVBOInstancingLayer(this, RENDER_PASSES.COLOR_TRANSPARENT); + this.#rendererSet.edgesColorRenderer.renderVBOInstancingLayer(this, RENDER_PASSES.DRAW_TRANSPARENT); } } @@ -670,7 +694,7 @@ export class VBOInstancingLayer implements Layer { return; } if (this.#rendererSet.occlusionRenderer) { - this.#rendererSet.occlusionRenderer.renderVBOInstancingLayer(this, RENDER_PASSES.COLOR_OPAQUE); + this.#rendererSet.occlusionRenderer.renderVBOInstancingLayer(this, RENDER_PASSES.DRAW_OPAQUE); } } @@ -680,7 +704,7 @@ export class VBOInstancingLayer implements Layer { // return; // } // if (this.#rendererSet.shadowRenderer) { - // this.#rendererSet.shadowRenderer.render( this, RENDER_PASSES.COLOR_OPAQUE); + // this.#rendererSet.shadowRenderer.render( this, RENDER_PASSES.DRAW_OPAQUE); // } } diff --git a/packages/webglrenderer/src/vbo/instancing/VBOInstancingRenderState.ts b/packages/webglrenderer/src/vbo/instancing/VBOInstancingRenderState.ts index d042a91fb..6a62dafe7 100644 --- a/packages/webglrenderer/src/vbo/instancing/VBOInstancingRenderState.ts +++ b/packages/webglrenderer/src/vbo/instancing/VBOInstancingRenderState.ts @@ -35,6 +35,7 @@ export interface VBOInstancingRenderState { modelNormalMatrixCol1Buf: WebGLArrayBuf; modelNormalMatrixCol2Buf: WebGLArrayBuf; + saoSupported: boolean; pbrSupported: boolean; numInstances: number; diff --git a/packages/webglrenderer/src/vbo/instancing/lines/renderers/VBOLinesInstancingDrawRenderer.ts b/packages/webglrenderer/src/vbo/instancing/lines/renderers/VBOLinesInstancingDrawColorRenderer.ts similarity index 85% rename from packages/webglrenderer/src/vbo/instancing/lines/renderers/VBOLinesInstancingDrawRenderer.ts rename to packages/webglrenderer/src/vbo/instancing/lines/renderers/VBOLinesInstancingDrawColorRenderer.ts index 05243d18c..589b8d328 100644 --- a/packages/webglrenderer/src/vbo/instancing/lines/renderers/VBOLinesInstancingDrawRenderer.ts +++ b/packages/webglrenderer/src/vbo/instancing/lines/renderers/VBOLinesInstancingDrawColorRenderer.ts @@ -4,7 +4,7 @@ import {VBOInstancingRenderer} from "../../VBOInstancingRenderer"; /** * @private */ -export class VBOLinesInstancingDrawRenderer extends VBOInstancingRenderer { +export class VBOLinesInstancingDrawColorRenderer extends VBOInstancingRenderer { getHash(): string { return this.slicingHash; @@ -16,24 +16,26 @@ export class VBOLinesInstancingDrawRenderer extends VBOInstancingRenderer { this.vertexInstancingTransformDefs(src); this.vertexSlicingDefs(src); this.vertexDrawFlatColorDefs(src); - this.vertexColorMainOpenBlock(src); + this.vertexDrawMainOpen(src); { this.vertexDrawInstancingTransformLogic(src); this.vertexDrawFlatColorLogic(src); this.vertexSlicingLogic(src); } - this.vertexColorMainCloseBlock(src); + this.vertexMainClose(src); } buildFragmentShader(src: string[]): void { this.fragmentHeader(src); this.fragmentPrecisionDefs(src); + this.fragmentCommonDefs(src); this.fragmentSlicingDefs(src); this.fragmentDrawFlatColorDefs(src); src.push("void main(void) {"); { this.fragmentSlicingLogic(src); this.fragmentDrawFlatColorLogic(src); + this.fragmentCommonOutput(src); } src.push("}"); } diff --git a/packages/webglrenderer/src/vbo/instancing/lines/renderers/VBOLinesInstancingPickMeshRenderer.ts b/packages/webglrenderer/src/vbo/instancing/lines/renderers/VBOLinesInstancingPickMeshRenderer.ts index 0bf8ed80d..277c9787d 100644 --- a/packages/webglrenderer/src/vbo/instancing/lines/renderers/VBOLinesInstancingPickMeshRenderer.ts +++ b/packages/webglrenderer/src/vbo/instancing/lines/renderers/VBOLinesInstancingPickMeshRenderer.ts @@ -15,24 +15,27 @@ export class VBOLinesInstancingPickMeshRenderer extends VBOInstancingRenderer { this.vertexCommonDefs(src); this.vertexInstancingTransformDefs(src); this.vertexSlicingDefs(src); - this.vertexPickMeshShadingDefs(src); - this.openVertexPickMain(src); + this.vertexPickMeshDefs(src); + this.vertexPickMainOpen(src); { this.vertexDrawInstancingTransformLogic(src); - this.vertexPickMeshShadingLogic(src); + this.vertexPickMeshLogic(src); this.vertexSlicingLogic(src); } + this.vertexMainClose(src); } buildFragmentShader(src: string[]):void { this.fragmentHeader(src); this.fragmentPrecisionDefs(src); + this.fragmentCommonDefs(src); this.fragmentSlicingDefs(src); - this.fragmentPickMeshShadingDefs(src); + this.fragmentPickMeshDefs(src); src.push("void main(void) {"); { this.fragmentSlicingLogic(src); - this.fragmentPickMeshShadingLogic(src); + this.fragmentPickMeshLogic(src); + this.fragmentCommonOutput(src); } src.push("}"); } diff --git a/packages/webglrenderer/src/vbo/instancing/lines/renderers/VBOLinesInstancingSilhouetteRenderer.ts b/packages/webglrenderer/src/vbo/instancing/lines/renderers/VBOLinesInstancingSilhouetteRenderer.ts index 75bdb210c..02000b24e 100644 --- a/packages/webglrenderer/src/vbo/instancing/lines/renderers/VBOLinesInstancingSilhouetteRenderer.ts +++ b/packages/webglrenderer/src/vbo/instancing/lines/renderers/VBOLinesInstancingSilhouetteRenderer.ts @@ -15,24 +15,28 @@ export class VBOLinesInstancingSilhouetteRenderer extends VBOInstancingRenderer this.vertexCommonDefs(src); this.vertexInstancingTransformDefs(src); this.vertexSlicingDefs(src); - this.vertexDrawSilhouetteDefs(src); - this.openVertexSilhouetteMain(src); + this.vertexSilhouetteDefs(src); + this.vertexSilhouetteMainOpen(src); { this.vertexDrawInstancingTransformLogic(src); - this.vertexDrawSilhouetteLogic(src); + this.vertexSilhouetteLogic(src); this.vertexSlicingLogic(src); } - this.vertexColorMainCloseBlock(src); + this.vertexMainClose(src); } buildFragmentShader(src: string[]): void { this.fragmentHeader(src); this.fragmentPrecisionDefs(src); + this.fragmentCommonDefs(src); this.fragmentSlicingDefs(src); - this.fragmentDrawSilhouetteDefs(src); + this.fragmentSilhouetteDefs(src); src.push("void main(void) {"); - this.fragmentSlicingLogic(src); - this.fragmentDrawSilhouetteLogic(src); + { + this.fragmentSlicingLogic(src); + this.fragmentSilhouetteLogic(src); + this.fragmentCommonOutput(src); + } src.push("}"); } diff --git a/packages/webglrenderer/src/vbo/instancing/lines/renderers/rendererFactory.ts b/packages/webglrenderer/src/vbo/instancing/lines/renderers/rendererFactory.ts index f9f845635..d1e4581cd 100644 --- a/packages/webglrenderer/src/vbo/instancing/lines/renderers/rendererFactory.ts +++ b/packages/webglrenderer/src/vbo/instancing/lines/renderers/rendererFactory.ts @@ -1,6 +1,6 @@ import {WebGLRenderer} from "../../../../WebGLRenderer"; import {RendererSetFactory, VBORendererSet} from "../../../VBORendererSet"; -import {VBOLinesInstancingDrawRenderer} from "./VBOLinesInstancingDrawRenderer"; +import {VBOLinesInstancingDrawColorRenderer} from "./VBOLinesInstancingDrawColorRenderer"; import {VBORenderer} from "../../../VBORenderer"; import {VBOLinesInstancingPickMeshRenderer} from "./VBOLinesInstancingPickMeshRenderer"; import {VBOLinesInstancingSilhouetteRenderer} from "./VBOLinesInstancingSilhouetteRenderer"; @@ -10,8 +10,8 @@ import {VBOLinesInstancingSilhouetteRenderer} from "./VBOLinesInstancingSilhouet */ class RendererFactory extends VBORendererSet { - createDrawRenderer(): VBORenderer { - return new VBOLinesInstancingDrawRenderer(this.renderContext); + createDrawColorRenderer(): VBORenderer { + return new VBOLinesInstancingDrawColorRenderer(this.renderContext); } createPickMeshRenderer(): VBORenderer { diff --git a/packages/webglrenderer/src/vbo/instancing/triangles/renderers/VBOTrianglesInstancingDrawRenderer.ts b/packages/webglrenderer/src/vbo/instancing/triangles/renderers/VBOTrianglesInstancingDrawColorRenderer.ts similarity index 85% rename from packages/webglrenderer/src/vbo/instancing/triangles/renderers/VBOTrianglesInstancingDrawRenderer.ts rename to packages/webglrenderer/src/vbo/instancing/triangles/renderers/VBOTrianglesInstancingDrawColorRenderer.ts index 7b42c95eb..6b3cc6707 100644 --- a/packages/webglrenderer/src/vbo/instancing/triangles/renderers/VBOTrianglesInstancingDrawRenderer.ts +++ b/packages/webglrenderer/src/vbo/instancing/triangles/renderers/VBOTrianglesInstancingDrawColorRenderer.ts @@ -4,7 +4,7 @@ import {VBOInstancingRenderer} from "../../VBOInstancingRenderer"; /** * @private */ -export class VBOTrianglesInstancingDrawRenderer extends VBOInstancingRenderer { +export class VBOTrianglesInstancingDrawColorRenderer extends VBOInstancingRenderer { getHash(): string { return `${this.lambertShadingHash}-${this.slicingHash}`; @@ -16,26 +16,26 @@ export class VBOTrianglesInstancingDrawRenderer extends VBOInstancingRenderer { this.vertexInstancingTransformDefs(src); this.vertexSlicingDefs(src); this.vertexDrawLambertDefs(src); - // this.vertexColorMainOpenBlock(src); - src.push("void main(void) {"); + this.vertexDrawMainOpen(src); { this.vertexDrawInstancingTransformLogic(src); this.vertexDrawLambertLogic(src); this.vertexSlicingLogic(src); } - // this.vertexColorMainCloseBlock(src); - src.push("}"); + this.vertexMainClose(src); } buildFragmentShader(src: string[]): void { this.fragmentHeader(src); this.fragmentPrecisionDefs(src); + this.fragmentCommonDefs(src); this.fragmentSlicingDefs(src); this.fragmentDrawLambertDefs(src); src.push("void main(void) {"); { this.fragmentSlicingLogic(src); this.fragmentDrawLambertLogic(src); + this.fragmentCommonOutput(src); } src.push("}"); } diff --git a/packages/webglrenderer/src/vbo/instancing/triangles/renderers/VBOTrianglesInstancingDrawColorSAORenderer.ts b/packages/webglrenderer/src/vbo/instancing/triangles/renderers/VBOTrianglesInstancingDrawColorSAORenderer.ts new file mode 100644 index 000000000..835620e00 --- /dev/null +++ b/packages/webglrenderer/src/vbo/instancing/triangles/renderers/VBOTrianglesInstancingDrawColorSAORenderer.ts @@ -0,0 +1,50 @@ +import {VBOInstancingLayer} from "../../VBOInstancingLayer"; +import {VBOInstancingRenderer} from "../../VBOInstancingRenderer"; + +/** + * @private + */ +export class VBOTrianglesInstancingDrawColorSAORenderer extends VBOInstancingRenderer { + + getHash(): string { + return `${this.lambertShadingHash}-${this.slicingHash}`; + } + + buildVertexShader(src: string[]): void { + this.vertexHeader(src); + this.vertexCommonDefs(src); + this.vertexInstancingTransformDefs(src); + this.vertexSlicingDefs(src); + this.vertexDrawLambertDefs(src); + this.vertexDrawMainOpen(src); + { + this.vertexDrawInstancingTransformLogic(src); + this.vertexDrawLambertLogic(src); + this.vertexSlicingLogic(src); + } + this.vertexMainClose(src); + } + + buildFragmentShader(src: string[]): void { + this.fragmentHeader(src); + this.fragmentPrecisionDefs(src); + this.fragmentCommonDefs(src); + this.fragmentSlicingDefs(src); + this.fragmentDrawLambertDefs(src); + this.fragmentDrawSAODefs(src); + src.push("void main(void) {"); + { + this.fragmentSlicingLogic(src); + this.fragmentDrawLambertLogic(src); + this.fragmentDrawSAOLogic(src); + this.fragmentCommonOutput(src); + } + src.push("}"); + } + + drawVBOInstancingLayerPrimitives(vboInstancingLayer: VBOInstancingLayer, renderPass: number): void { + const gl = this.renderContext.gl; + const renderState = vboInstancingLayer.renderState; + gl.drawElementsInstanced(gl.TRIANGLES, renderState.indicesBuf.numItems, renderState.indicesBuf.itemType, 0, renderState.numInstances); + } +} diff --git a/packages/webglrenderer/src/vbo/instancing/triangles/renderers/VBOTrianglesInstancingDrawDepthRenderer.ts b/packages/webglrenderer/src/vbo/instancing/triangles/renderers/VBOTrianglesInstancingDrawDepthRenderer.ts new file mode 100644 index 000000000..2ef6e9e3f --- /dev/null +++ b/packages/webglrenderer/src/vbo/instancing/triangles/renderers/VBOTrianglesInstancingDrawDepthRenderer.ts @@ -0,0 +1,46 @@ +import {VBOInstancingLayer} from "../../VBOInstancingLayer"; +import {VBOInstancingRenderer} from "../../VBOInstancingRenderer"; + +/** + * @private + */ +export class VBOTrianglesInstancingDrawDepthRenderer extends VBOInstancingRenderer { + + getHash(): string { + return `${this.slicingHash}`; + } + + buildVertexShader(src: string[]): void { + this.vertexHeader(src); + this.vertexCommonDefs(src); + this.vertexInstancingTransformDefs(src); + this.vertexSlicingDefs(src); + this.vertexDrawMainOpen(src); + { + this.vertexDrawInstancingTransformLogic(src); + this.vertexSlicingLogic(src); + } + this.vertexMainClose(src); + } + + buildFragmentShader(src: string[]): void { + this.fragmentHeader(src); + this.fragmentPrecisionDefs(src); + this.fragmentCommonDefs(src); + this.fragmentDrawDepthDefs(src); + this.fragmentSlicingDefs(src); + src.push("void main(void) {"); + { + this.fragmentSlicingLogic(src); + this.fragmentDrawDepthLogic(src); + this.fragmentCommonOutput(src); + } + src.push("}"); + } + + drawVBOInstancingLayerPrimitives(vboInstancingLayer: VBOInstancingLayer, renderPass: number): void { + const gl = this.renderContext.gl; + const renderState = vboInstancingLayer.renderState; + gl.drawElementsInstanced(gl.TRIANGLES, renderState.indicesBuf.numItems, renderState.indicesBuf.itemType, 0, renderState.numInstances); + } +} diff --git a/packages/webglrenderer/src/vbo/instancing/triangles/renderers/VBOTrianglesInstancingEdgesDrawRenderer.ts b/packages/webglrenderer/src/vbo/instancing/triangles/renderers/VBOTrianglesInstancingEdgesDrawRenderer.ts index 70c5769f3..2ce14d7c7 100644 --- a/packages/webglrenderer/src/vbo/instancing/triangles/renderers/VBOTrianglesInstancingEdgesDrawRenderer.ts +++ b/packages/webglrenderer/src/vbo/instancing/triangles/renderers/VBOTrianglesInstancingEdgesDrawRenderer.ts @@ -20,25 +20,27 @@ export class VBOTrianglesInstancingEdgesDrawRenderer extends VBOInstancingRender this.vertexCommonDefs(src); this.vertexInstancingTransformDefs(src); this.vertexSlicingDefs(src); - this.vertexDrawEdgesColorDefs(src); - this.vertexColorMainOpenBlock(src); + this.vertexDrawFlatColorDefs(src); + this.vertexDrawMainOpen(src); { this.vertexDrawInstancingTransformLogic(src); this.vertexDrawEdgesColorLogic(src); this.vertexSlicingLogic(src); } - this.vertexColorMainCloseBlock(src); + this.vertexMainClose(src); } buildFragmentShader(src: string[]): void { this.fragmentHeader(src); this.fragmentPrecisionDefs(src); + this.fragmentCommonDefs(src); this.fragmentSlicingDefs(src); - this.fragmentDrawEdgesColorDefs(src); + this.fragmentDrawFlatColorDefs(src); src.push("void main(void) {"); { this.fragmentSlicingLogic(src); - this.fragmentDrawEdgesColorLogic(src); + this.fragmentDrawFlatColorLogic(src); + this.fragmentCommonOutput(src); } src.push("}"); } diff --git a/packages/webglrenderer/src/vbo/instancing/triangles/renderers/VBOTrianglesInstancingEdgesSilhouetteRenderer.ts b/packages/webglrenderer/src/vbo/instancing/triangles/renderers/VBOTrianglesInstancingEdgesSilhouetteRenderer.ts index 139a47798..df1d58490 100644 --- a/packages/webglrenderer/src/vbo/instancing/triangles/renderers/VBOTrianglesInstancingEdgesSilhouetteRenderer.ts +++ b/packages/webglrenderer/src/vbo/instancing/triangles/renderers/VBOTrianglesInstancingEdgesSilhouetteRenderer.ts @@ -20,25 +20,27 @@ export class VBOTrianglesInstancingEdgesSilhouetteRenderer extends VBOInstancing this.vertexCommonDefs(src); this.vertexInstancingTransformDefs(src); this.vertexSlicingDefs(src); - this.vertexDrawEdgesSilhouetteDefs(src); - this.openVertexSilhouetteMain(src); + this.vertexSilhouetteDefs(src); + this.vertexSilhouetteMainOpen(src); { this.vertexDrawInstancingTransformLogic(src); - this.vertexDrawEdgesSilhouetteLogic(src); + this.vertexSilhouetteLogic(src); this.vertexSlicingLogic(src); } - this.vertexColorMainCloseBlock(src); + this.vertexMainClose(src); } buildFragmentShader(src: string[]): void { this.fragmentHeader(src); this.fragmentPrecisionDefs(src); + this.fragmentCommonDefs(src); this.fragmentSlicingDefs(src); - this.fragmentDrawEdgesSilhouetteDefs(src); + this.fragmentSilhouetteDefs(src); src.push("void main(void) {"); { this.fragmentSlicingLogic(src); - this.fragmentDrawEdgesSilhouetteLogic(src); + this.fragmentSilhouetteLogic(src); + this.fragmentCommonOutput(src); } src.push("}"); } diff --git a/packages/webglrenderer/src/vbo/instancing/triangles/renderers/VBOTrianglesInstancingPickMeshRenderer.ts b/packages/webglrenderer/src/vbo/instancing/triangles/renderers/VBOTrianglesInstancingPickMeshRenderer.ts index 815740a49..c1fcd3014 100644 --- a/packages/webglrenderer/src/vbo/instancing/triangles/renderers/VBOTrianglesInstancingPickMeshRenderer.ts +++ b/packages/webglrenderer/src/vbo/instancing/triangles/renderers/VBOTrianglesInstancingPickMeshRenderer.ts @@ -16,25 +16,27 @@ export class VBOTrianglesInstancingPickMeshRenderer extends VBOInstancingRendere this.vertexCommonDefs(src); this.vertexInstancingTransformDefs(src); this.vertexSlicingDefs(src); - this.vertexPickMeshShadingDefs(src); - this.openVertexPickMain(src); + this.vertexPickMeshDefs(src); + this.vertexPickMainOpen(src); { this.vertexPickInstancingTransformLogic(src); - this.vertexPickMeshShadingLogic(src); + this.vertexPickMeshLogic(src); this.vertexSlicingLogic(src); } - this.vertexPickMainCloseBlock(src); + this.vertexMainClose(src); } buildFragmentShader(src: string[]) : void{ this.fragmentHeader(src); this.fragmentPrecisionDefs(src); + this.fragmentCommonDefs(src); this.fragmentSlicingDefs(src); - this.fragmentPickMeshShadingDefs(src); + this.fragmentPickMeshDefs(src); src.push("void main(void) {"); { this.fragmentSlicingLogic(src); - this.fragmentPickMeshShadingLogic(src); + this.fragmentPickMeshLogic(src); + this.fragmentCommonOutput(src); } src.push("}"); } diff --git a/packages/webglrenderer/src/vbo/instancing/triangles/renderers/VBOTrianglesInstancingSilhouetteRenderer.ts b/packages/webglrenderer/src/vbo/instancing/triangles/renderers/VBOTrianglesInstancingSilhouetteRenderer.ts index e9bd3ca7d..285f89366 100644 --- a/packages/webglrenderer/src/vbo/instancing/triangles/renderers/VBOTrianglesInstancingSilhouetteRenderer.ts +++ b/packages/webglrenderer/src/vbo/instancing/triangles/renderers/VBOTrianglesInstancingSilhouetteRenderer.ts @@ -15,25 +15,27 @@ export class VBOTrianglesInstancingSilhouetteRenderer extends VBOInstancingRende this.vertexCommonDefs(src); this.vertexInstancingTransformDefs(src); this.vertexSlicingDefs(src); - this.vertexDrawSilhouetteDefs(src); - this.openVertexSilhouetteMain(src); + this.vertexSilhouetteDefs(src); + this.vertexSilhouetteMainOpen(src); { this.vertexDrawInstancingTransformLogic(src); - this.vertexDrawSilhouetteLogic(src); + this.vertexSilhouetteLogic(src); this.vertexSlicingLogic(src); } - this.vertexColorMainCloseBlock(src); + this.vertexMainClose(src); } buildFragmentShader(src: string[]): void { this.fragmentHeader(src); this.fragmentPrecisionDefs(src); + this.fragmentCommonDefs(src); this.fragmentSlicingDefs(src); - this.fragmentDrawSilhouetteDefs(src); + this.fragmentSilhouetteDefs(src); src.push("void main(void) {"); { this.fragmentSlicingLogic(src); - this.fragmentDrawSilhouetteLogic(src); + this.fragmentSilhouetteLogic(src); + this.fragmentCommonOutput(src); } src.push("}"); } diff --git a/packages/webglrenderer/src/vbo/instancing/triangles/renderers/rendererFactory.ts b/packages/webglrenderer/src/vbo/instancing/triangles/renderers/rendererFactory.ts index 1cd329f23..f2884fc66 100644 --- a/packages/webglrenderer/src/vbo/instancing/triangles/renderers/rendererFactory.ts +++ b/packages/webglrenderer/src/vbo/instancing/triangles/renderers/rendererFactory.ts @@ -1,11 +1,13 @@ import {WebGLRenderer} from "../../../../WebGLRenderer"; import {RendererSetFactory, VBORendererSet} from "../../../VBORendererSet"; -import {VBOTrianglesInstancingDrawRenderer} from "./VBOTrianglesInstancingDrawRenderer"; +import {VBOTrianglesInstancingDrawColorRenderer} from "./VBOTrianglesInstancingDrawColorRenderer"; import {VBOTrianglesInstancingSilhouetteRenderer} from "./VBOTrianglesInstancingSilhouetteRenderer"; import {VBORenderer} from "../../../VBORenderer"; import {VBOTrianglesInstancingPickMeshRenderer} from "./VBOTrianglesInstancingPickMeshRenderer"; import {VBOTrianglesInstancingEdgesDrawRenderer} from "./VBOTrianglesInstancingEdgesDrawRenderer"; import {VBOTrianglesInstancingEdgesSilhouetteRenderer} from "./VBOTrianglesInstancingEdgesSilhouetteRenderer"; +import {VBOTrianglesInstancingDrawDepthRenderer} from "./VBOTrianglesInstancingDrawDepthRenderer"; +import {VBOTrianglesInstancingDrawColorSAORenderer} from "./VBOTrianglesInstancingDrawColorSAORenderer"; /** @@ -13,8 +15,16 @@ import {VBOTrianglesInstancingEdgesSilhouetteRenderer} from "./VBOTrianglesInsta */ class RendererFactory extends VBORendererSet { - createDrawRenderer(): VBORenderer { - return new VBOTrianglesInstancingDrawRenderer(this.renderContext); + createDrawColorRenderer(): VBORenderer { + return new VBOTrianglesInstancingDrawColorRenderer(this.renderContext); + } + + createDrawColorSAORenderer(): VBORenderer { + return new VBOTrianglesInstancingDrawColorSAORenderer(this.renderContext); + } + + createDrawDepthRenderer(): VBORenderer { + return new VBOTrianglesInstancingDrawDepthRenderer(this.renderContext); } createSilhouetteRenderer(): VBORenderer { diff --git a/packages/webglutils/src/WebGLRenderBuffer.ts b/packages/webglutils/src/WebGLRenderBuffer.ts index a509d6f90..4198a3205 100644 --- a/packages/webglutils/src/WebGLRenderBuffer.ts +++ b/packages/webglutils/src/WebGLRenderBuffer.ts @@ -18,7 +18,7 @@ class WebGLRenderBuffer { constructor(canvas: HTMLCanvasElement, gl: WebGL2RenderingContext, options: { depthTexture: boolean; - size: any; + size?: number[]; }) { /** @type {WebGL2RenderingContext} */ this.#gl = gl;