import React, { useContext, useState, useEffect, useMemo, useLayoutEffect, useRef, Suspense } from "react";
import * as THREE from "three";
import { Canvas, useFrame } from "@react-three/fiber";
import { Center, Environment, OrbitControls, Lightformer, Html, PerformanceMonitor, Float, CameraControls } from "@react-three/drei";
import { EffectComposer, EffectComposerContext, SSAO, SMAA, Outline, Selection, Select, Bloom } from '@react-three/postprocessing';
import { BlendFunction } from 'postprocessing';
import { SSGIEffect, MotionBlurEffect, VelocityDepthNormalPass } from 'realism-effects';
import { LayerMaterial, Color, Depth } from "lamina";
// import { DEG2RAD } from 'three/src/math/MathUtils.js';
// import ThreeDimenssion from "../3dModels/threeDimenssion";
import Carbinet from "../3dModels/carbinet";
import AddButton from "../3dModels/button";
import "./canvas.css";
function RealismEffect() {
const { scene, camera, composer } = useContext(EffectComposerContext)
const velocityDepthNormalPass = useMemo(() => new VelocityDepthNormalPass(scene, camera), [scene, camera])
useLayoutEffect(() => {
composer.addPass(velocityDepthNormalPass)
return () => {
composer.removePass(velocityDepthNormalPass)
}
}, [velocityDepthNormalPass, composer])
const ssgiEffect = useMemo(() => new SSGIEffect(scene, camera, velocityDepthNormalPass), [scene, camera, velocityDepthNormalPass])
// const traaEffect = useMemo(() => new TRAAEffect(scene, camera, velocityDepthNormalPass), [scene, camera, velocityDepthNormalPass])
const motionBlurEffect = useMemo(() => new MotionBlurEffect(velocityDepthNormalPass), [velocityDepthNormalPass]);
return (
<>
<primitive object={ssgiEffect} />
{/* <primitive object={traaEffect} /> */}
<primitive object={motionBlurEffect} />
</>
)
}
function Lightformers({ positions = [2, 0, 2, 0, 2, 0, 2, 0] }) {
const group = useRef(null);
useFrame((state, delta) => (group.current.position.z += delta * 10) > 20 && (group.current.position.z = -60))
return (
<>
{/* Ceiling */}
<Lightformer intensity={0.75} rotation-x={Math.PI / 2} position={[0, 5, -9]} scale={[10, 10, 1]} />
<group rotation={[0, 0.5, 0]}>
<group ref={group}>
{positions.map((x, i) => (
<Lightformer key={i} form="circle" intensity={0.5} rotation={[Math.PI / 2, 0, 0]} position={[x, 4, i * 4]} scale={[3, 1, 1]} />
))}
</group>
</group>
{/* Sides */}
<Lightformer intensity={1} rotation-y={Math.PI / 2} position={[-5, 1, -1]} scale={[20, 0.1, 1]} />
<Lightformer rotation-y={Math.PI / 2} position={[-5, -1, -1]} scale={[20, 0.5, 1]} />
<Lightformer rotation-y={-Math.PI / 2} position={[10, 1, 0]} scale={[20, 1, 1]} />
{/* Accent (red) */}
<Float speed={5} floatIntensity={0.5} rotationIntensity={0.5}>
<Lightformer form="ring" color="grey" intensity={0.5} scale={10} position={[-15, 4, -18]} target={[0, 0, 0]} />
</Float>
{/* Background */}
<mesh scale={100}>
<sphereGeometry args={[1, 64, 64]} />
<LayerMaterial side={THREE.BackSide}>
<Color color="grey" alpha={1} mode="normal" />
<Depth colorA="white" colorB="black" alpha={0.5} mode="normal" near={0} far={300} origin={[100, 100, 100]} />
</LayerMaterial>
</mesh>
</>
)
}
function Light() {
const ref = useRef(null);
useFrame((state) => {
if (ref.current) ref.current.rotation.set(state.camera.rotation.x, state.camera.rotation.y, state.camera.rotation.z)
})
return (
<group ref={ref}>
<directionalLight position={[-2, 2, 2]} castShadow intensity={2} shadow-mapSize={4096} shadow-bias={-0.001}>
<orthographicCamera attach="shadow-camera" args={[-1, 1, 1, -1, 0.1, 10]} />
</directionalLight>
<directionalLight position={[2, 2, 2]} castShadow intensity={1} shadow-mapSize={1024} shadow-bias={-0.001} />
</group >
)
}
const CustomCanvas = (props) => {
const [countModel, setCountModel] = useState(1);
const [addOrientation, setAddOrientation] = useState("left");
const [removeOrientation, setRemoveOrientation] = useState("");
// const [position, setPosition] = useState([[0, 0, 0]]);
const [selectedCabinetNo, setSelectedCabinetNo] = useState(0);
const [degraded, degrade] = useState(false);
useEffect(() => {
setCountModel(1);
}, []);
const modelType = props.type;
const addModel = (direction) => {
let curCountModel = countModel + 1;
setCountModel(curCountModel);
setAddOrientation(direction);
}
const handleRemove = (direction) => {
setRemoveOrientation(direction);
// let curCountModel = countModel - 1;
// setCountModel(curCountModel);
}
const handleReset = () => {
setRemoveOrientation("");
}
// const cameraRef = useRef(null);
// useEffect(() => {
// cameraRef.current?.camera.rotation.set(86.4 * DEG2RAD, 0, 7.14 * DEG2RAD)
// console.log(cameraRef.current.camera.rotation)
// })
return (
<Canvas
shadows = "variance"
dpr={[1, 1]}
gl={{ preserveDrawingBuffer: true }}
camera={{ position: [1.0, 0, 7.0], fov: 30 }}
onCreated={(state) => (state.gl.toneMappingExposure = 1.5)}
className="threeCanvas"
>
<CameraControls
// ref={cameraRef}
maxDistance={1000}
minDistance={0.1}
enablePan={false}
enableRotate={false}
verticalDragToForward={true}
minAzimuthAngle={-Math.PI / 2}
maxAzimuthAngle={Math.PI / 2}
minPolarAngle={Math.PI / 6}
maxPolarAngle={Math.PI / 2}
azimuthRotateSpeed={1}
polarRotateSpeed={1}
dollySpeed={0.5}
/>
{/* <pointLight position={[10, 10, 3]} />
<pointLight position={[-10, -10, -10]} /> */}
{/* <Environment files="/models/potsdamer_platz_1k.hdr" /> */}
<group>
<Center>
{
// <ThreeDimenssion modelName={modelType} color="white" />
<Suspense fallback={null}>
<Selection>
<EffectComposer>
{/* <Outline
blur edgeStrength={0}
visibleEdgeColor={0xffffff} // the color of visible edges
hiddenEdgeColor={0x22090a} /> */}
<SMAA />
</EffectComposer>
<Select>
<Carbinet
modelName={modelType}
color="white"
countModel={countModel}
addOrientation={addOrientation}
divider={props.divider}
panelType={props.panelStyle}
panelColor={props.panelColor}
dimenssion={props.dimenssion}
onRemove={(direction) => handleRemove(direction)}
onSelectedCabinet={(cabinetNo, scale) => {
setSelectedCabinetNo(cabinetNo);
props.onChangeSelectedCabinet(cabinetNo, scale)
} }
/>
</Select>
</Selection>
</Suspense>
}
</Center>
<AddButton
onClick={(direction) => addModel(direction)}
widthScale={props.dimenssion[2]}
cabinetNo={selectedCabinetNo}
removeOrientation={removeOrientation}
countModel={countModel}
onResetDelete={handleReset}
/>
<ambientLight intensity={0.1} />
<Light />
</group>
<PerformanceMonitor onDecline={() => degrade(true)} />
<Environment frames={degraded ? 1 : Infinity} resolution={512} background={true} blur={1}>
<Lightformers />
</Environment>
<EffectComposer>
<RealismEffect />
<SSAO
blendFunction={BlendFunction.MULTIPLY} // blend mode
samples={30} // amount of samples per pixel (shouldn't be a multiple of the ring count)
rings={4} // amount of rings in the occlusion sampling pattern
distanceThreshold={1.0} // global distance threshold at which the occlusion effect starts to fade out. min: 0, max: 1
distanceFalloff={0.0} // distance falloff. min: 0, max: 1
rangeThreshold={0.5} // local occlusion range threshold at which the occlusion starts to fade out. min: 0, max: 1
rangeFalloff={0.1} // occlusion range falloff. min: 0, max: 1
luminanceInfluence={0.9} // how much the luminance of the scene influences the ambient occlusion
radius={20} // occlusion sampling radius
scale={0.5} // scale of the ambient occlusion
bias={0.5} // occlusion bias
intensity={20}
depthAwareUpsampling={false}
/>
</EffectComposer>
{/* <OrbitControls
enableRotate // Enable rotation
enablePan={false} // Disable panning
enableZoom={true} // Disable zooming
minPolarAngle={Math.PI / 10} // Minimum polar angle (vertical angle)
maxPolarAngle={(3 * Math.PI) / 5} // Maximum polar angle (vertical angle)
/> */}
</Canvas>
);
}
export default CustomCanvas;
Did you try removing SSGIEffect
?
ssgi hat natural AO, you don’t need an extra effect for this.
Thank you for your reply!
I’ve removed the ssgi effect, by the way, there are not any changes.
for now even though I modify the parameter like intensity of SSAO, there are not any changes.