diff --git a/packages/cloudrun/src/gcpInstaller/gcpInstaller.tar b/packages/cloudrun/src/gcpInstaller/gcpInstaller.tar index b3bc46eb126..dce63200cf9 100644 Binary files a/packages/cloudrun/src/gcpInstaller/gcpInstaller.tar and b/packages/cloudrun/src/gcpInstaller/gcpInstaller.tar differ diff --git a/packages/example/package.json b/packages/example/package.json index 2aec7ba837a..38e3e2d32d3 100644 --- a/packages/example/package.json +++ b/packages/example/package.json @@ -21,7 +21,9 @@ "render": "remotion render react-svg", "render-js": "remotion render src/entry.jsx framer", "render-gif": "remotion render framer out/video.gif --codec=gif --every-nth-frame=2", - "render-transparent": "remotion render --image-format=png --pixel-format=yuva420p --codec=vp8 react-svg out/video.webm" + "render-transparent": "remotion render --image-format=png --pixel-format=yuva420p --codec=vp8 react-svg out/video.webm", + "render-swangle": "remotion render GpuTesting out/swangle.mp4 --gl=swangle", + "render-angle": "remotion render GpuTesting out/angle.mp4 --gl=angle" }, "dependencies": { "@mdx-js/loader": "^2.3.0", @@ -54,6 +56,7 @@ "@types/react": "18.0.26", "@types/styled-components": "^5.1.26", "@types/web": "0.0.78", + "@types/three": "^0.144.0", "babel-loader": "^8.2.2", "dotenv": "9.0.2", "lottie-web": "5.12.2", diff --git a/packages/example/public/1.mov b/packages/example/public/1.mov new file mode 100644 index 00000000000..56b796a3b6e Binary files /dev/null and b/packages/example/public/1.mov differ diff --git a/packages/example/src/GpuTesting/index.tsx b/packages/example/src/GpuTesting/index.tsx new file mode 100644 index 00000000000..aad5d1a6b6d --- /dev/null +++ b/packages/example/src/GpuTesting/index.tsx @@ -0,0 +1,124 @@ +import {AbsoluteFill, staticFile, OffthreadVideo} from 'remotion'; +import {loadFont} from '@remotion/google-fonts/PlusJakartaSans'; +import {Scene} from './phone/Scene'; + +const {fontFamily} = loadFont(); + +const vid1 = staticFile('/1.mov'); + +export const GpuTesting = () => { + return ( + +

+ GPU TESTING +

+
+
+ + Blur:{' '} + +
+
+
+
+
+
+
+
+
+ + Box Shadow:{' '} + +
+
+
+
+
+
+
+
+
+ + Drop Shadow:{' '} + +
+ + + + + + + + + + + + + + + +
+
+
+ + + + ); +}; diff --git a/packages/example/src/GpuTesting/phone/Phone.tsx b/packages/example/src/GpuTesting/phone/Phone.tsx new file mode 100644 index 00000000000..d94cf4195d6 --- /dev/null +++ b/packages/example/src/GpuTesting/phone/Phone.tsx @@ -0,0 +1,117 @@ +import {useThree} from '@react-three/fiber'; +import React, {useEffect, useMemo} from 'react'; +import {interpolate, spring, useCurrentFrame, useVideoConfig} from 'remotion'; +import { + CAMERA_DISTANCE, + getPhoneLayout, + PHONE_CURVE_SEGMENTS, + PHONE_SHININESS, +} from './helpers/layout'; +import {roundedRect} from './helpers/rounded-rectangle'; +import {RoundedBox} from './RoundedBox'; + +export const Phone: React.FC<{ + // eslint-disable-next-line @typescript-eslint/no-explicit-any + videoTexture: any | null; + aspectRatio: number; + baseScale: number; + phoneColor: string; +}> = ({aspectRatio, videoTexture, baseScale, phoneColor}) => { + const frame = useCurrentFrame(); + const {fps, durationInFrames} = useVideoConfig(); + + const layout = useMemo( + () => getPhoneLayout(aspectRatio, baseScale), + [aspectRatio, baseScale], + ); + + // Place a camera and set the distance to the object. + // Then make it look at the object. + const camera = useThree((state) => state.camera); + useEffect(() => { + camera.position.set(0, 0, CAMERA_DISTANCE); + camera.near = 0.2; + camera.far = Math.max(5000, CAMERA_DISTANCE * 2); + camera.lookAt(0, 0, 0); + }, [camera]); + + // Make the video fill the phone texture + useEffect(() => { + if (videoTexture) { + videoTexture.repeat.y = 1 / layout.screen.height; + videoTexture.repeat.x = 1 / layout.screen.width; + } + }, [aspectRatio, layout.screen.height, layout.screen.width, videoTexture]); + + // During the whole scene, the phone is rotating. + // 2 * Math.PI is a full rotation. + const constantRotation = interpolate( + frame, + [0, durationInFrames], + [0, Math.PI * 6], + ); + + // When the composition starts, there is some extra + // rotation and translation. + const entranceAnimation = spring({ + frame, + fps, + config: { + damping: 200, + mass: 3, + }, + }); + + // Calculate the entrance rotation, + // doing one full spin + const entranceRotation = interpolate( + entranceAnimation, + [0, 1], + [-Math.PI, Math.PI], + ); + + // Calculating the total rotation of the phone + const rotateY = entranceRotation + constantRotation; + + // Calculating the translation of the phone at the beginning. + // The start position of the phone is set to 4 "units" + const translateY = interpolate(entranceAnimation, [0, 1], [-4, 0]); + + // Calculate a rounded rectangle for the phone screen + const screenGeometry = useMemo(() => { + return roundedRect({ + width: layout.screen.width, + height: layout.screen.height, + radius: layout.screen.radius, + }); + }, [layout.screen.height, layout.screen.radius, layout.screen.width]); + + return ( + + + + + + + {videoTexture ? ( + + ) : null} + + + ); +}; diff --git a/packages/example/src/GpuTesting/phone/RoundedBox.tsx b/packages/example/src/GpuTesting/phone/RoundedBox.tsx new file mode 100644 index 00000000000..63e4f9ffb0e --- /dev/null +++ b/packages/example/src/GpuTesting/phone/RoundedBox.tsx @@ -0,0 +1,43 @@ +import React, {useMemo} from 'react'; +import {roundedRect} from './helpers/rounded-rectangle'; + +type Props = { + width: number; + height: number; + radius: number; + curveSegments: number; + depth: number; +} & Omit; + +export const RoundedBox: React.FC = ({ + width, + height, + radius, + curveSegments, + children, + depth, + ...otherProps +}) => { + const shape = useMemo( + () => roundedRect({width, height, radius}), + [height, radius, width] + ); + + const params = useMemo( + () => ({ + depth, + bevelEnabled: true, + bevelSize: 0, + bevelThickness: 0, + curveSegments, + }), + [curveSegments, depth] + ); + + return ( + + + {children} + + ); +}; diff --git a/packages/example/src/GpuTesting/phone/Scene.tsx b/packages/example/src/GpuTesting/phone/Scene.tsx new file mode 100644 index 00000000000..01eaee44adf --- /dev/null +++ b/packages/example/src/GpuTesting/phone/Scene.tsx @@ -0,0 +1,47 @@ +import {staticFile} from 'remotion'; +import {getVideoMetadata, VideoMetadata} from '@remotion/media-utils'; +import {ThreeCanvas, useVideoTexture} from '@remotion/three'; +import React, {useEffect, useRef, useState} from 'react'; +import {useVideoConfig, Video} from 'remotion'; +import {Phone} from './Phone'; + +const videoStyle: React.CSSProperties = { + position: 'absolute', + opacity: 0, +}; + +export const Scene: React.FC = () => { + const phoneColor = 'rgba(110, 152, 191, 0.00)'; + const baseScale = 1; + + const videoRef = useRef(null); + const {width, height} = useVideoConfig(); + const [videoData, setVideoData] = useState(null); + + const videoSrc = staticFile('1.mov'); + + useEffect(() => { + getVideoMetadata(videoSrc) + .then((data) => setVideoData(data)) + .catch((err) => console.log(err)); + }, [videoSrc]); + + const texture = useVideoTexture(videoRef); + return ( +
+
+ ); +}; diff --git a/packages/example/src/GpuTesting/phone/helpers/layout.ts b/packages/example/src/GpuTesting/phone/helpers/layout.ts new file mode 100644 index 00000000000..6aac2b9cdef --- /dev/null +++ b/packages/example/src/GpuTesting/phone/helpers/layout.ts @@ -0,0 +1,97 @@ +import {Vector3} from '@react-three/fiber'; + +// The distance from which the camera is pointing to the phone. +export const CAMERA_DISTANCE = 2.5; + +// A small number to avoid z-index flickering +export const Z_FLICKER_PREVENTION = 0.001; + +// Shininess of the phone +export const PHONE_SHININESS = 30; + +// In how many segments the phone rounded corners +// are divided. Increase number for smoother phone +export const PHONE_CURVE_SEGMENTS = 8; + +// Calculate phone size. Whichever side is smaller gets +// normalized to the base scale. +const getPhoneHeight = (aspectRatio: number, baseScale: number): number => { + if (aspectRatio > 1) { + return baseScale; + } + return baseScale / aspectRatio; +}; + +const getPhoneWidth = (aspectRatio: number, baseScale: number): number => { + if (aspectRatio < 1) { + return baseScale; + } + return baseScale * aspectRatio; +}; + +type Layout = { + position: Vector3; + height: number; + width: number; + radius: number; +}; + +type PhoneLayout = { + phone: Layout & { + thickness: number; + bevel: number; + }; + screen: Layout; +}; + +export const getPhoneLayout = ( + // I recommend building the phone layout based + // on the aspect ratio of the phone + aspectRatio: number, + // This value can be increased or decreased to tweak the + // base value of the phone. + baseScale: number +): PhoneLayout => { + // The depth of the phone body + const phoneThickness = baseScale * 0.15; + + // How big the border of the phone is. + const phoneBevel = baseScale * 0.04; + + // The inner radius of the phone, aka the screen radius + const screenRadius = baseScale * 0.07; + + const phoneHeight = getPhoneHeight(aspectRatio, baseScale); + const phoneWidth = getPhoneWidth(aspectRatio, baseScale); + const phonePosition: Vector3 = [-phoneWidth / 2, -phoneHeight / 2, 0]; + const screenWidth = phoneWidth - phoneBevel * 2; + const screenHeight = phoneHeight - phoneBevel * 2; + const screenPosition: Vector3 = [ + -screenWidth / 2, + -screenHeight / 2, + phoneThickness + Z_FLICKER_PREVENTION, + ]; + + // Define the outer radius of the phone. + // It looks better if the outer radius is a bit bigger than the screen radios, + // formula taken from https://twitter.com/joshwcomeau/status/134978208002102886 + const phoneRadius = + screenRadius + (getPhoneWidth(aspectRatio, baseScale) - screenWidth) / 2; + + return { + phone: { + position: phonePosition, + height: phoneHeight, + width: phoneWidth, + radius: phoneRadius, + thickness: phoneThickness, + bevel: phoneBevel, + }, + screen: { + position: screenPosition, + height: screenHeight, + width: screenWidth, + radius: screenRadius, + }, + }; +}; diff --git a/packages/example/src/GpuTesting/phone/helpers/rounded-rectangle.ts b/packages/example/src/GpuTesting/phone/helpers/rounded-rectangle.ts new file mode 100644 index 00000000000..52e24dc6c30 --- /dev/null +++ b/packages/example/src/GpuTesting/phone/helpers/rounded-rectangle.ts @@ -0,0 +1,23 @@ +import {Shape} from 'three'; + +export function roundedRect({ + width, + height, + radius, +}: { + width: number; + height: number; + radius: number; +}): Shape { + const roundedRectShape = new Shape(); + roundedRectShape.moveTo(0, radius); + roundedRectShape.lineTo(0, height - radius); + roundedRectShape.quadraticCurveTo(0, height, radius, height); + roundedRectShape.lineTo(width - radius, height); + roundedRectShape.quadraticCurveTo(width, height, width, height - radius); + roundedRectShape.lineTo(width, radius); + roundedRectShape.quadraticCurveTo(width, 0, width - radius, 0); + roundedRectShape.lineTo(radius, 0); + roundedRectShape.quadraticCurveTo(0, 0, 0, radius); + return roundedRectShape; +} diff --git a/packages/example/src/Root.tsx b/packages/example/src/Root.tsx index 6e98c173b89..02438bbae03 100644 --- a/packages/example/src/Root.tsx +++ b/packages/example/src/Root.tsx @@ -47,6 +47,7 @@ import {StaticDemo} from './StaticServer'; import {StillZoom} from './StillZoom'; import {TenFrameTester} from './TenFrameTester'; import ThreeBasic from './ThreeBasic'; +import {GpuTesting} from './GpuTesting'; import {VideoOnCanvas} from './VideoOnCanvas'; import {Greenscreen} from './VideoOnCanvas/greenscreen'; import {VideoSpeed} from './VideoSpeed'; @@ -723,6 +724,14 @@ export const Index: React.FC = () => { fps={30} durationInFrames={600} /> + { ]; } + if (renderer === 'angle') { + console.log('altered cmd'); + return [`--use-gl=angle`, `--use-angle=gl-egl`]; + } + if (renderer === null) { return []; } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 504f8e1682f..1b7754c9b60 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -761,7 +761,7 @@ importers: version: 2.3.0(react@18.2.0) '@react-three/drei': specifier: 9.79.4 - version: 9.79.4(@react-three/fiber@8.13.5)(@types/three@0.154.0)(react-dom@18.2.0)(react@18.2.0)(three@0.154.0) + version: 9.79.4(@react-three/fiber@8.13.5)(@types/three@0.144.0)(react-dom@18.2.0)(react@18.2.0)(three@0.154.0) '@react-three/fiber': specifier: 8.13.5 version: 8.13.5(react-dom@18.2.0)(react@18.2.0)(three@0.154.0) @@ -840,6 +840,9 @@ importers: '@types/styled-components': specifier: ^5.1.26 version: 5.1.26 + '@types/three': + specifier: ^0.144.0 + version: 0.144.0 '@types/web': specifier: 0.0.78 version: 0.0.78 @@ -7867,7 +7870,7 @@ packages: resolution: {integrity: sha512-POu8Mk0hIU3lRXB3bGIGe4VHIwwDsQyoD1F394OK7STTiX9w4dG3cTLljjYswkQN+hDSHRrj4O36kuVa7KPU8Q==} dev: false - /@react-three/drei@9.79.4(@react-three/fiber@8.13.5)(@types/three@0.154.0)(react-dom@18.2.0)(react@18.2.0)(three@0.154.0): + /@react-three/drei@9.79.4(@react-three/fiber@8.13.5)(@types/three@0.144.0)(react-dom@18.2.0)(react@18.2.0)(three@0.154.0): resolution: {integrity: sha512-Qyy2dPTLpEs3XfvLo2Nyneht0hRqIgIjel78A9MUxq3VxbCse79iCFZZ0xD8gIof33L4jfQOrGghKK988orNOA==} peerDependencies: '@react-three/fiber': '>=8.0' @@ -7889,7 +7892,7 @@ packages: lodash.clamp: 4.0.3 lodash.omit: 4.5.0 lodash.pick: 4.4.0 - maath: 0.6.0(@types/three@0.154.0)(three@0.154.0) + maath: 0.6.0(@types/three@0.144.0)(three@0.154.0) meshline: 3.1.6(three@0.154.0) react: 18.2.0 react-composer: 5.0.3(react@18.2.0) @@ -8834,10 +8837,6 @@ packages: resolution: {integrity: sha512-eZxlbI8GZscaGS7kkc/trHTT5xgrjH3/1n2JDwusC9iahPKWMRvRjJSAN5mCXviuTGQ/lHnhvv8Q1YTpnfz9gA==} dev: true - /@tweenjs/tween.js@18.6.4: - resolution: {integrity: sha512-lB9lMjuqjtuJrx7/kOkqQBtllspPIN+96OvTCeJ2j5FEzinoAXTdAMFnDAQT1KVPRlnYfBrqxtqP66vDM40xxQ==} - dev: false - /@types/acorn@4.0.6: resolution: {integrity: sha512-veQTnWP+1D/xbxVrPC3zHnCZRjSrKfhbMUlEA43iMZLu7EsnTtkJklIuwrCPbOi8YkvDQAiW05VQQFvvz9oieQ==} dependencies: @@ -9360,10 +9359,6 @@ packages: '@types/node': 18.14.6 dev: false - /@types/stats.js@0.17.0: - resolution: {integrity: sha512-9w+a7bR8PeB0dCT/HBULU2fMqf6BAzvKbxFboYhmDtDkKPiyXYbjoe2auwsXlEFI7CFNMF1dCv3dFH5Poy9R1w==} - dev: false - /@types/styled-components@5.1.26: resolution: {integrity: sha512-KuKJ9Z6xb93uJiIyxo/+ksS7yLjS1KzG6iv5i78dhVg/X3u5t1H7juRWqVmodIdz6wGVaIApo1u01kmFRdJHVw==} dependencies: @@ -9383,15 +9378,10 @@ packages: resolution: {integrity: sha512-4YB+99Rgqq27EjiYTItEoZtdjLnTh8W9LxowgpC9eWsjaQJIL4Kn/ZcUKAnW3gB/jS4hqGN8iqmid+RcUZDzpA==} dev: true - /@types/three@0.154.0: - resolution: {integrity: sha512-IioqpGhch6FdLDh4zazRn3rXHj6Vn2nVOziJdXVbJFi9CaI65LtP9qqUtpzbsHK2Ezlox8NtsLNHSw3AQzucjA==} + /@types/three@0.144.0: + resolution: {integrity: sha512-psvEs6q5rLN50jUYZ3D4pZMfxTbdt3A243blt0my7/NcL6chaCZpHe2csbCtx0SOD9fI/XnF3wnVUAYZGqCSYg==} dependencies: - '@tweenjs/tween.js': 18.6.4 - '@types/stats.js': 0.17.0 '@types/webxr': 0.5.2 - fflate: 0.6.10 - lil-gui: 0.17.0 - meshoptimizer: 0.18.1 dev: false /@types/unist@2.0.6: @@ -15354,10 +15344,6 @@ packages: prelude-ls: 1.2.1 type-check: 0.4.0 - /lil-gui@0.17.0: - resolution: {integrity: sha512-MVBHmgY+uEbmJNApAaPbtvNh1RCAeMnKym82SBjtp5rODTYKWtM+MXHCifLe2H2Ti1HuBGBtK/5SyG4ShQ3pUQ==} - dev: false - /lilconfig@2.1.0: resolution: {integrity: sha512-utWOt/GHzuUxnLKxB6dk81RoOeoNeHgbrXiuGk4yyF5qlRz+iIVWu56E2fqGHFrXz0QNUhLB/8nKqvRH66JKGQ==} engines: {node: '>=10'} @@ -15551,13 +15537,13 @@ packages: resolution: {integrity: sha512-0ckx7ZHRPqb0oUm8zNr+90mtf9DQB60H1wMCjBtfi62Kl3a7JbHob6gA2bC+xRvZoOL+1hzUK8jeuEIQE8svEQ==} hasBin: true - /maath@0.6.0(@types/three@0.154.0)(three@0.154.0): + /maath@0.6.0(@types/three@0.144.0)(three@0.154.0): resolution: {integrity: sha512-dSb2xQuP7vDnaYqfoKzlApeRcR2xtN8/f7WV/TMAkBC8552TwTLtOO0JTcSygkYMjNDPoo6V01jTw/aPi4JrMw==} peerDependencies: '@types/three': '>=0.144.0' three: '>=0.144.0' dependencies: - '@types/three': 0.154.0 + '@types/three': 0.144.0 three: 0.154.0 dev: false @@ -15910,10 +15896,6 @@ packages: three: 0.154.0 dev: false - /meshoptimizer@0.18.1: - resolution: {integrity: sha512-ZhoIoL7TNV4s5B6+rx5mC//fw8/POGyNxS/DZyCJeiZ12ScLfVwRE/GfsxwiTkMYYD5DmK2/JXnEVXqL4rF+Sw==} - dev: false - /methods@1.1.2: resolution: {integrity: sha512-iclAHeNqNm68zFtnZ0e+1L2yUIdvzNoauKU4WBA3VvH/vPFieF7qfRlwUZU+DA9P9bPXIS90ulxoUoCH23sV2w==} engines: {node: '>= 0.6'}