From e070b99f0f0be152655572a729220caa3454de0c Mon Sep 17 00:00:00 2001
From: aardgoose <angus.sawyer@gmail.com>
Date: Mon, 23 Oct 2023 23:44:19 +0100
Subject: [PATCH] WebGPURenderer: enable shadow rendering in WebGLBackend
 (#27023)

* make previous render state available to backend

* make shadow coord adjustment conditional

* add screenshot and enable test

* rework test

* rework as suggested

---------

Co-authored-by: aardgoose <angus.sawyer@email.com>
---
 .../jsm/nodes/lighting/AnalyticLightNode.js   |  24 +++++++++++---
 examples/jsm/renderers/webgl/WebGLBackend.js  |  30 ++++++++++++++++--
 examples/screenshots/webgpu_shadowmap.jpg     | Bin 3413 -> 21526 bytes
 examples/webgpu_shadowmap.html                |   6 ++--
 test/e2e/puppeteer.js                         |   1 -
 5 files changed, 51 insertions(+), 10 deletions(-)

diff --git a/examples/jsm/nodes/lighting/AnalyticLightNode.js b/examples/jsm/nodes/lighting/AnalyticLightNode.js
index a85cc17797e607..bef0f6481b9657 100644
--- a/examples/jsm/nodes/lighting/AnalyticLightNode.js
+++ b/examples/jsm/nodes/lighting/AnalyticLightNode.js
@@ -7,6 +7,7 @@ import { reference } from '../accessors/ReferenceNode.js';
 import { texture } from '../accessors/TextureNode.js';
 import { positionWorld } from '../accessors/PositionNode.js';
 import { normalWorld } from '../accessors/NormalNode.js';
+import { WebGPUCoordinateSystem } from 'three';
 //import { add } from '../math/OperatorNode.js';
 
 import { Color, DepthTexture, NearestFilter, LessCompare } from 'three';
@@ -73,11 +74,24 @@ class AnalyticLightNode extends LightingNode {
 				.and( shadowCoord.y.lessThanEqual( 1 ) )
 				.and( shadowCoord.z.lessThanEqual( 1 ) );
 
-			shadowCoord = vec3(
-				shadowCoord.x,
-				shadowCoord.y.oneMinus(), // WebGPU: Flip Y
-				shadowCoord.z.add( bias ).mul( 2 ).sub( 1 ) // WebGPU: Convertion [ 0, 1 ] to [ - 1, 1 ]
-			);
+
+			if ( builder.renderer.coordinateSystem === WebGPUCoordinateSystem ) {
+
+				shadowCoord = vec3(
+					shadowCoord.x,
+					shadowCoord.y.oneMinus(), // WebGPU: Flip Y
+					shadowCoord.z.add( bias ).mul( 2 ).sub( 1 ) // WebGPU: Convertion [ 0, 1 ] to [ - 1, 1 ]
+				);
+
+			} else {
+
+				shadowCoord = vec3(
+					shadowCoord.x,
+					shadowCoord.y,
+					shadowCoord.z.add( bias )
+				);
+
+			}
 
 			const textureCompare = ( depthTexture, shadowCoord, compare ) => texture( depthTexture, shadowCoord ).compare( compare );
 			//const textureCompare = ( depthTexture, shadowCoord, compare ) => compare.step( texture( depthTexture, shadowCoord ) );
diff --git a/examples/jsm/renderers/webgl/WebGLBackend.js b/examples/jsm/renderers/webgl/WebGLBackend.js
index bada50d7a24ae3..ec80edf0bfa191 100644
--- a/examples/jsm/renderers/webgl/WebGLBackend.js
+++ b/examples/jsm/renderers/webgl/WebGLBackend.js
@@ -41,6 +41,7 @@ class WebGLBackend extends Backend {
 		this.defaultTextures = {};
 
 		this.extensions.get( 'EXT_color_buffer_float' );
+		this._currentContext = null;
 
 	}
 
@@ -53,9 +54,13 @@ class WebGLBackend extends Backend {
 	beginRender( renderContext ) {
 
 		const { gl } = this;
+		const renderContextData = this.get( renderContext );
 
 		//
 
+		renderContextData.previousContext = this._currentContext;
+		this._currentContext = renderContext;
+
 		this._setFramebuffer( renderContext );
 
 		let clear = 0;
@@ -103,8 +108,6 @@ class WebGLBackend extends Backend {
 
 		if ( occlusionQueryCount > 0 ) {
 
-			const renderContextData = this.get( renderContext );
-
 			// Get a reference to the array of objects with queries. The renderContextData property
 			// can be changed by another render pass before the async reading of all previous queries complete
 			renderContextData.currentOcclusionQueries = renderContextData.occlusionQueries;
@@ -121,6 +124,29 @@ class WebGLBackend extends Backend {
 
 	finishRender( renderContext ) {
 
+		const renderContextData = this.get( renderContext );
+		const previousContext = renderContextData.previousContext;
+
+		this._currentContext = previousContext;
+
+		if ( previousContext !== null ) {
+
+			this._setFramebuffer( previousContext );
+
+			if ( previousContext.viewport ) {
+
+				this.updateViewport( previousContext );
+
+			} else {
+
+				const gl = this.gl;
+
+				gl.viewport( 0, 0, gl.drawingBufferWidth, gl.drawingBufferHeight );
+
+			}
+
+		}
+
 		const occlusionQueryCount = renderContext.occlusionQueryCount;
 
 		if ( occlusionQueryCount > 0 ) {
diff --git a/examples/screenshots/webgpu_shadowmap.jpg b/examples/screenshots/webgpu_shadowmap.jpg
index 001fe203e0b94e476d12e5c1c76aa979a0fbc77f..6539397f372b2e23a977ccc623a089b47a938bf1 100644
GIT binary patch
literal 21526
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

delta 71
pcmbQXg7K=<hIl6CfAudmZ)6f++`NHFkZ5A^1|~O_{|x_c0sxUq7_<NY

diff --git a/examples/webgpu_shadowmap.html b/examples/webgpu_shadowmap.html
index 6efb5df3803093..3eb4f3e534939d 100644
--- a/examples/webgpu_shadowmap.html
+++ b/examples/webgpu_shadowmap.html
@@ -26,6 +26,8 @@
 			import * as THREE from 'three';
 
 			import WebGPU from 'three/addons/capabilities/WebGPU.js';
+			import WebGL from 'three/addons/capabilities/WebGL.js';
+
 			import WebGPURenderer from 'three/addons/renderers/webgpu/WebGPURenderer.js';
 
 			import { OrbitControls } from 'three/addons/controls/OrbitControls.js';
@@ -38,11 +40,11 @@
 
 			function init() {
 
-				if ( WebGPU.isAvailable() === false ) {
+				if ( WebGPU.isAvailable() === false && WebGL.isWebGL2Available() === false ) {
 
 					document.body.appendChild( WebGPU.getErrorMessage() );
 
-					throw new Error( 'No WebGPU support' );
+					throw new Error( 'No WebGPU or WebGL2 support' );
 
 				}
 
diff --git a/test/e2e/puppeteer.js b/test/e2e/puppeteer.js
index 0ac630d2c038e1..bfc7d60605d073 100644
--- a/test/e2e/puppeteer.js
+++ b/test/e2e/puppeteer.js
@@ -124,7 +124,6 @@ const exceptionList = [
 	'webgpu_materials_video',
 	'webgpu_sandbox',
 	'webgpu_shadertoy',
-	'webgpu_shadowmap',
 	'webgpu_sprites',
 	'webgpu_tsl_editor',
 	'webgpu_tsl_transpiler',