Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions examples/accumulative-contact-shadows/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[![Static](https://img.shields.io/badge/example-%23646CFF.svg?logo=html5&logoColor=white)](https://pmndrs.github.io/examples/accumulative-contact-shadows)
[![CodeSandbox](https://img.shields.io/badge/codesandbox-040404?logo=codesandbox&logoColor=DBDBDB)](https://codesandbox.io/s/github/pmndrs/examples/tree/main/examples/accumulative-contact-shadows)
[![Stackblitz](https://img.shields.io/badge/stackblitz-fff?logo=Stackblitz&logoColor=1389FD)](https://stackblitz.com/github/pmndrs/examples/tree/main/examples/accumulative-contact-shadows)

```sh
$ npx degit pmndrs/examples/examples/accumulative-contact-shadows
```

![](thumbnail.webp)
13 changes: 13 additions & 0 deletions examples/accumulative-contact-shadows/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/index.tsx"></script>
</body>
</html>
38 changes: 38 additions & 0 deletions examples/accumulative-contact-shadows/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"name": "@example/accumulative-contact-shadows",
"version": "1.0.0",
"dependencies": {
"@react-three/drei": "10.7.8",
"@react-three/fiber": "9.6.1",
"leva": "^0.10.1",
"react": "19.2.8",
"react-dom": "19.2.8",
"three": "0.165.0"
},
"devDependencies": {
"@types/react": "19.2.17",
"@types/react-dom": "19.2.3",
"@types/three": "^0.165.0",
"@vitejs/plugin-react": "^6.0.4",
"typescript": "^7.0.2",
"vite": "^8.1.5"
},
"scripts": {
"dev": "vite --host",
"dev3": "e2e-dev $npm_package_name",
"build": "tsc && vite build",
"build2": "tsc && e2e-build $npm_package_name",
"preview": "vite preview"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
],
"type": "module",
"repository": {
"type": "git",
"url": "https://github.com/pmndrs/examples/tree/main/examples/accumulative-contact-shadows"
}
}
10 changes: 10 additions & 0 deletions examples/accumulative-contact-shadows/pmndrs.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"$schema": "../../schemas/pmndrs.schema.json",
"title": "Accumulative Contact Shadows",
"description": "Shadow staging techniques comparing AccumulativeShadows with RandomizedLight and ContactShadows on simple geometry.",
"tags": ["staging", "shadows"],
"authors": ["Sumit Ridhal"],
"source": "https://github.com/pmndrs/examples/tree/main/examples/accumulative-contact-shadows",
"libraries": ["@react-three/drei", "@react-three/fiber", "leva"],
"assets": []
}
1 change: 1 addition & 0 deletions examples/accumulative-contact-shadows/public/vite.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
107 changes: 107 additions & 0 deletions examples/accumulative-contact-shadows/src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { Canvas } from "@react-three/fiber";
import {
AccumulativeShadows,
RandomizedLight,
ContactShadows,
OrbitControls,
Environment,
RoundedBox,
} from "@react-three/drei";
import { useControls } from "leva";

function AccumulativeSection() {
const { frames, color, opacity } = useControls("AccumulativeShadows", {
frames: { value: 100, min: 2, max: 200, step: 1 },
color: "#316d39",
opacity: { value: 0.8, min: 0, max: 1, step: 0.01 },
});

return (
<group position={[-2, 0, 0]}>
<RoundedBox
args={[1, 1, 1]}
position={[0, 0.5, 0]}
radius={0.1}
smoothness={4}
castShadow
>
<meshStandardMaterial color="#e74c3c" />
</RoundedBox>

<mesh position={[0, 1.2, 0.8]} castShadow>
<sphereGeometry args={[0.35, 32, 32]} />
<meshStandardMaterial color="#3498db" />
</mesh>

<AccumulativeShadows
temporal
frames={frames}
color={color}
colorBlend={2}
opacity={opacity}
scale={6}
position={[0, 0.01, 0]}
>
<RandomizedLight
amount={8}
radius={4}
ambient={0.5}
intensity={Math.PI}
position={[5, 5, -5]}
bias={0.001}
/>
</AccumulativeShadows>
</group>
);
}

function ContactSection() {
const { blur, opacity, far } = useControls("ContactShadows", {
blur: { value: 2.5, min: 0, max: 10, step: 0.1 },
opacity: { value: 0.75, min: 0, max: 1, step: 0.01 },
far: { value: 3, min: 0.5, max: 10, step: 0.1 },
});

return (
<group position={[2, 0, 0]}>
<RoundedBox
args={[1, 1, 1]}
position={[0, 0.5, 0]}
radius={0.1}
smoothness={4}
>
<meshStandardMaterial color="#9b59b6" />
</RoundedBox>

<mesh position={[0, 1.2, 0.8]}>
<sphereGeometry args={[0.35, 32, 32]} />
<meshStandardMaterial color="#f39c12" />
</mesh>

<ContactShadows
position={[0, 0.01, 0]}
scale={6}
blur={blur}
opacity={opacity}
far={far}
/>
</group>
);
}

export default function App() {
return (
<Canvas shadows camera={{ position: [0, 4, 8], fov: 45 }}>
<AccumulativeSection />
<ContactSection />

<mesh rotation-x={-Math.PI / 2} position={[0, 0, 0]}>
<planeGeometry args={[20, 20]} />
<meshStandardMaterial color="#fafafa" />
</mesh>

<Environment preset="city" />
<OrbitControls makeDefault />
</Canvas>
);
}
5 changes: 5 additions & 0 deletions examples/accumulative-contact-shadows/src/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { createRoot } from "react-dom/client";
import "./styles.css";
import App from "./App";

createRoot(document.getElementById("root")!).render(<App />);
16 changes: 16 additions & 0 deletions examples/accumulative-contact-shadows/src/styles.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
* {
box-sizing: border-box;
}

html,
body,
#root {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}

body {
background: #202020;
}
1 change: 1 addition & 0 deletions examples/accumulative-contact-shadows/src/vite-env.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
/// <reference types="vite/client" />
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
20 changes: 20 additions & 0 deletions examples/accumulative-contact-shadows/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
{
"compilerOptions": {
"target": "ESNext",
"useDefineForClassFields": true,
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"allowJs": false,
"skipLibCheck": true,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "ESNext",
"moduleResolution": "Bundler",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx"
},
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
}
9 changes: 9 additions & 0 deletions examples/accumulative-contact-shadows/tsconfig.node.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"compilerOptions": {
"composite": true,
"module": "ESNext",
"moduleResolution": "Bundler",
"allowSyntheticDefaultImports": true
},
"include": ["vite.config.ts"]
}
6 changes: 6 additions & 0 deletions examples/accumulative-contact-shadows/vite.config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import { defineConfig } from "vite";
import react from "@vitejs/plugin-react";

export default defineConfig({
plugins: [react()],
});
9 changes: 9 additions & 0 deletions examples/camera-controls-basic/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[![Static](https://img.shields.io/badge/example-%23646CFF.svg?logo=html5&logoColor=white)](https://pmndrs.github.io/examples/camera-controls-basic)
[![CodeSandbox](https://img.shields.io/badge/codesandbox-040404?logo=codesandbox&logoColor=DBDBDB)](https://codesandbox.io/s/github/pmndrs/examples/tree/main/examples/camera-controls-basic)
[![Stackblitz](https://img.shields.io/badge/stackblitz-fff?logo=Stackblitz&logoColor=1389FD)](https://stackblitz.com/github/pmndrs/examples/tree/main/examples/camera-controls-basic)

```sh
$ npx degit pmndrs/examples/examples/camera-controls-basic
```

![](thumbnail.webp)
13 changes: 13 additions & 0 deletions examples/camera-controls-basic/index.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8" />
<link rel="icon" type="image/svg+xml" href="/vite.svg" />
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<title>Vite + React + TS</title>
</head>
<body>
<div id="root"></div>
<script type="module" src="/src/index.tsx"></script>
</body>
</html>
38 changes: 38 additions & 0 deletions examples/camera-controls-basic/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
{
"name": "@example/camera-controls-basic",
"version": "1.0.0",
"dependencies": {
"@react-three/drei": "10.7.8",
"@react-three/fiber": "9.6.1",
"leva": "^0.10.1",
"react": "19.2.8",
"react-dom": "19.2.8",
"three": "0.165.0"
},
"devDependencies": {
"@types/react": "19.2.17",
"@types/react-dom": "19.2.3",
"@types/three": "^0.165.0",
"@vitejs/plugin-react": "^6.0.4",
"typescript": "^7.0.2",
"vite": "^8.1.5"
},
"scripts": {
"dev": "vite --host",
"dev3": "e2e-dev $npm_package_name",
"build": "tsc && vite build",
"build2": "tsc && e2e-build $npm_package_name",
"preview": "vite preview"
},
"browserslist": [
">0.2%",
"not dead",
"not ie <= 11",
"not op_mini all"
],
"type": "module",
"repository": {
"type": "git",
"url": "https://github.com/pmndrs/examples/tree/main/examples/camera-controls-basic"
}
}
10 changes: 10 additions & 0 deletions examples/camera-controls-basic/pmndrs.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
{
"$schema": "../../schemas/pmndrs.schema.json",
"title": "Camera Controls",
"description": "Interactive camera controls demo showcasing CameraControls with smooth transitions, zoom limits, and dolly controls.",
"tags": ["controls", "camera"],
"authors": ["Sumit Ridhal"],
"source": "https://github.com/pmndrs/examples/tree/main/examples/camera-controls-basic",
"libraries": ["@react-three/drei", "@react-three/fiber", "leva"],
"assets": []
}
1 change: 1 addition & 0 deletions examples/camera-controls-basic/public/vite.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
74 changes: 74 additions & 0 deletions examples/camera-controls-basic/src/App.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
import { useRef } from "react";
import { Canvas } from "@react-three/fiber";
import { CameraControls, Environment, RoundedBox } from "@react-three/drei";
import { useControls, button } from "leva";
import type CameraControlsImpl from "camera-controls";

function Scene() {
const cameraControlsRef = useRef<CameraControlsImpl>(null);

const { minDistance, maxDistance, polarAngle } = useControls("Limits", {
minDistance: { value: 2, min: 0, max: 10, step: 0.1 },
maxDistance: { value: 20, min: 5, max: 50, step: 1 },
polarAngle: {
value: Math.PI,
min: 0,
max: Math.PI,
step: 0.01,
label: "Max polar angle",
},
});

useControls("Transitions", {
"Reset camera": button(() => {
cameraControlsRef.current?.reset(true);
}),
"Zoom to red box": button(() => {
cameraControlsRef.current?.setLookAt(3, 2, 5, 2, 0.5, 0, true);
}),
"Zoom to blue box": button(() => {
cameraControlsRef.current?.setLookAt(-3, 2, 5, -2, 0.5, 0, true);
}),
"Top-down view": button(() => {
cameraControlsRef.current?.setLookAt(0, 10, 0.01, 0, 0, 0, true);
}),
});

return (
<>
<CameraControls
ref={cameraControlsRef}
minDistance={minDistance}
maxDistance={maxDistance}
maxPolarAngle={polarAngle}
/>

<RoundedBox args={[1, 1, 1]} position={[2, 0.5, 0]} radius={0.1}>
<meshStandardMaterial color="#e74c3c" />
</RoundedBox>

<RoundedBox args={[1, 1, 1]} position={[-2, 0.5, 0]} radius={0.1}>
<meshStandardMaterial color="#3498db" />
</RoundedBox>

<RoundedBox args={[1, 2, 1]} position={[0, 1, -2]} radius={0.1}>
<meshStandardMaterial color="#2ecc71" />
</RoundedBox>

<mesh rotation-x={-Math.PI / 2} position={[0, 0, 0]} receiveShadow>
<planeGeometry args={[20, 20]} />
<meshStandardMaterial color="#f5f5f5" />
</mesh>

<Environment preset="city" />
</>
);
}

export default function App() {
return (
<Canvas shadows camera={{ position: [5, 3, 5], fov: 50 }}>
<Scene />
</Canvas>
);
}
Loading
Loading