Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Editor: add RectAreaLight #28187

Open
wants to merge 2 commits into
base: dev
Choose a base branch
from

Conversation

linbingquan
Copy link
Contributor

@linbingquan linbingquan commented Apr 22, 2024

Related PR: #16251

Description

Add RectAreaLight for Editor.

If this PR has any problem, please tell me.

Screenshot:

图片

@Codezigineer
Copy link

They don't have shadows. I'd rather add projectors #24589

@Mugen87
Copy link
Collaborator

Mugen87 commented Apr 22, 2024

@Mugen87
Copy link
Collaborator

Mugen87 commented Apr 22, 2024

One issue with this PR is that the area light of published apps does not properly work because RectAreaLightUniformsLib isn't part of the core. And the file itself isn't bundled and used in app.js.

It seems full editor support of RectAreaLight can easier be achieved when #9373 is solved.

@linbingquan
Copy link
Contributor Author

One issue with this PR is that the area light of published apps does not properly work because RectAreaLightUniformsLib isn't part of the core. And the file itself isn't bundled and used in app.js.

It seems full editor support of RectAreaLight can easier be achieved when #9373 is solved.

Thank you for your feedback. #9373 can be achieved this is really a good way. But I have a feeling it won't be done anytime soon.

Whether we can use other ways to achieve this PR, like: on-demand bundling RectAreaLightUniformsLib.js for the app.js

@Mugen87
Copy link
Collaborator

Mugen87 commented Apr 23, 2024

With #28195 in place, you can try to add support for area lights in published apps. The idea is to include RectAreaLightUniformsLib.js in the following code section so it's part of the zip.

loader.load( '../build/three.module.js', function ( content ) {
toZip[ 'js/three.module.js' ] = strToU8( content );
} );

Meaning you load the file separately via FileLoader and add it to the zip in the onLoad() callback. Next, you can use it inside libs/app/index.html.

If all of that works, it would be ideal if this code runs conditionally. Meaning RectAreaLightUniformsLib.js is only part of the published app if area lights are part of the exported scene.

import { APP } from './js/app.js';

window.THREE = THREE; // Used by APP Scripts.
/* init addons js */
Copy link
Collaborator

Choose a reason for hiding this comment

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

Thanks for giving this a shot!

I'm not sure yet how I feel about this solution. I understand the idea behind it but I wonder if we can inject imports and initialization code a bit cleaner. Need to think about this.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I'm not sure yet how I feel about this solution. I understand the idea behind it but I wonder if we can inject imports and initialization code a bit cleaner. Need to think about this.

Thank you for your response.

At present, I think of two other methods, but may not be what you expect, if you have a good idea please let me know.

  1. ES6 Template literals https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals
  2. Use existing libraries. I try to use MagicString ( https://github.com/rich-harris/magic-string ), this library may not be suitable, there may be a more suitable library, but I do not know at the moment...

Example code for Method 1:

const content = `<!DOCTYPE html>
<html lang="en">
	<head>
		<title>${title}</title>
		<meta charset="utf-8">
		<meta name="generator" content="Three.js Editor">
		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
		<style>
			body {
				font-family: sans-serif;
				font-size: 11px;
				background-color: #000;
				margin: 0px;
			}
			canvas {
				display: block;
			}
		</style>
	</head>
	<body ontouchstart="">
		<script type="importmap">
			{
				"imports": {
					"three": "./js/three.module.js",
					"three/addons/": "./js/"
				}
			}
		</script>
		<script type="module">

			import * as THREE from 'three';
			${ hasRectAreaLight ? 'import { RectAreaLightUniformsLib } from \'three/addons/lights/RectAreaLightUniformsLib.js\';' : '' }
			import { APP } from './js/app.js';

			window.THREE = THREE; // Used by APP Scripts.
			${ hasRectAreaLight ? 'RectAreaLightUniformsLib.init();' : '' }

			var loader = new THREE.FileLoader();
			loader.load( 'app.json', function ( text ) {

				var player = new APP.Player();
				player.load( JSON.parse( text ) );
				player.setSize( window.innerWidth, window.innerHeight );
				player.play();

				document.body.appendChild( player.dom );

				window.addEventListener( 'resize', function () {

					player.setSize( window.innerWidth, window.innerHeight );

				} );

			} );

			${editButton}

		</script>
	</body>
</html>`;

toZip[ 'index.html' ] = strToU8( content );

Example code for Method 2:

<!DOCTYPE html>
<html lang="en">

<head>
	<meta charset="UTF-8">
	<meta name="viewport" content="width=device-width, initial-scale=1.0">
	<title>Document</title>
</head>

<body>
	<script type="importmap">
        {
            "imports": {
                "magic-string": "https://unpkg.com/magic-string@0.30.10/dist/magic-string.es.mjs",
                "@jridgewell/sourcemap-codec": "https://unpkg.com/@jridgewell/sourcemap-codec@1.4.15/dist/sourcemap-codec.mjs"
            }
        }
    </script>
	<script type="module">
		import MagicString from 'magic-string';

		const htmlStr = `<!DOCTYPE html>
<html lang="en">
	<head>
		<title><!-- title --></title>
		<meta charset="utf-8">
		<meta name="generator" content="Three.js Editor">
		<meta name="viewport" content="width=device-width, user-scalable=no, minimum-scale=1.0, maximum-scale=1.0">
		<style>
			body {
				font-family: sans-serif;
				font-size: 11px;
				background-color: #000;
				margin: 0px;
			}
			canvas {
				display: block;
			}
		</style>
	</head>
	<body ontouchstart="">
		<script type="importmap">
			{
				"imports": {
					"three": "./js/three.module.js",
					"three/addons/": "./js/"
				}
			}
		<\/script>
		<script type="module">
		<\/script>
	</body>
</html>`;

		const html = new MagicString(htmlStr);
		html.replace('<!-- title -->', 'hello world');

		const modulejs = /* js */`
import * as THREE from 'three';
import { APP } from './js/app.js';

window.THREE = THREE; // Used by APP Scripts.

var loader = new THREE.FileLoader();
loader.load( 'app.json', function ( text ) {

	var player = new APP.Player();
	player.load( JSON.parse( text ) );
	player.setSize( window.innerWidth, window.innerHeight );
	player.play();

	document.body.appendChild( player.dom );

	window.addEventListener( 'resize', function () {

		player.setSize( window.innerWidth, window.innerHeight );

	} );

} );`;

		const js = new MagicString(modulejs);

		const hasRectAreaLight = true;
		const editable = true;

		if (hasRectAreaLight) {
			js.prependRight(33, `import { RectAreaLightUniformsLib } from 'three/addons/lights/RectAreaLightUniformsLib.js';\r\n\t\t\t`);
			js.prependRight(116, `RectAreaLightUniformsLib.init();\r\n\r\n\t\t\t`);
		}

		let button;

		if (editable) {

			button = new MagicString(`

\t\t\tlet button = document.createElement( 'a' );
button.href = 'https://threejs.org/editor/#file=' + location.href.split( '/' ).slice( 0, - 1 ).join( '/' ) + '/app.json';
button.style.cssText = 'position: absolute; bottom: 20px; right: 20px; padding: 10px 16px; color: #fff; border: 1px solid #fff; border-radius: 20px; text-decoration: none;';
button.target = '_blank';
button.textContent = 'EDIT';
document.body.appendChild( button );\t\t\t
`);

		}

		if (button) {
			js.append(button.toString());
		}

		console.log(js.toString());

		html.prependRight(626, js.indent().indent().indent().toString());
		console.log(html.toString());
	</script>
</body>

</html>

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

3 participants