Skip to content
This repository has been archived by the owner on Aug 21, 2024. It is now read-only.

Commit

Permalink
IR-2900-Studio-Deleting-Directional-Light-Broken (#10507)
Browse files Browse the repository at this point in the history
* Default to EntityCSMReactor if a primary light is set

* Cleanup primary light, csm when directional light is deleted

* CSM removal through shadow system

* Reactor fixes

* Directional light dependencies

* Save to snapshot

* Set directional light cast shadow

* Revert

* Move directional light logic to reactors

* remove redundant call

* Check for directional light in shadow system

* Reactive directional light check
  • Loading branch information
MichaelEstes authored Jul 9, 2024
1 parent 9266835 commit 57c3d1f
Show file tree
Hide file tree
Showing 5 changed files with 75 additions and 71 deletions.
28 changes: 25 additions & 3 deletions packages/editor/src/components/properties/RenderSettingsEditor.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ All portions of the code written by the Ethereal Engine team are Copyright © 20
Ethereal Engine. All Rights Reserved.
*/

import React from 'react'
import React, { useEffect } from 'react'
import { useTranslation } from 'react-i18next'
import {
ACESFilmicToneMapping,
Expand All @@ -38,11 +38,15 @@ import {
} from 'three'

import { EntityUUID, useQuery, UUIDComponent } from '@etherealengine/ecs'
import { getComponent, useComponent } from '@etherealengine/ecs/src/ComponentFunctions'
import { ComponentType, getComponent, useComponent } from '@etherealengine/ecs/src/ComponentFunctions'
import { RenderSettingsComponent } from '@etherealengine/engine/src/scene/components/RenderSettingsComponent'
import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent'
import { DirectionalLightComponent } from '@etherealengine/spatial/src/renderer/components/DirectionalLightComponent'

import { GLTFNodeState, GLTFSnapshotAction } from '@etherealengine/engine/src/gltf/GLTFDocumentState'
import { GLTFSnapshotState } from '@etherealengine/engine/src/gltf/GLTFState'
import { SourceComponent } from '@etherealengine/engine/src/scene/components/SourceComponent'
import { dispatchAction, State } from '@etherealengine/hyperflux'
import BooleanInput from '../inputs/BooleanInput'
import CompoundNumericInput from '../inputs/CompoundNumericInput'
import InputGroup from '../inputs/InputGroup'
Expand Down Expand Up @@ -108,7 +112,8 @@ const ShadowTypeOptions = [

export const RenderSettingsEditor: EditorComponentType = (props) => {
const { t } = useTranslation()
const rendererSettingsState = useComponent(props.entity, RenderSettingsComponent)
const { entity } = props
const rendererSettingsState = useComponent(entity, RenderSettingsComponent)

const directionalLightOptions = [
{
Expand All @@ -124,6 +129,23 @@ export const RenderSettingsEditor: EditorComponentType = (props) => {
})
)

useEffect(() => {
if (!UUIDComponent.getEntityByUUID(rendererSettingsState.primaryLight.value)) {
const source = getComponent(entity, SourceComponent)
const node = GLTFNodeState.getMutableNode(entity)
const renderSettingsExt = node.extensions[RenderSettingsComponent.jsonID] as State<
ComponentType<typeof RenderSettingsComponent>
>
if (!renderSettingsExt.primaryLight.value) return
renderSettingsExt.merge({
csm: false,
primaryLight: '' as EntityUUID
})
const snapshot = GLTFSnapshotState.cloneCurrentSnapshot(source)
dispatchAction(GLTFSnapshotAction.createSnapshot(snapshot))
}
}, [rendererSettingsState.primaryLight])

return (
<NodeEditor
{...props}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,8 @@ import { LinearToneMapping, PCFSoftShadowMap, ShadowMapType, ToneMapping } from
import { EntityUUID } from '@etherealengine/ecs'
import { defineComponent, getComponent, useComponent } from '@etherealengine/ecs/src/ComponentFunctions'
import { useEntityContext } from '@etherealengine/ecs/src/EntityFunctions'
import { useScene } from '@etherealengine/spatial/src/renderer/components/SceneComponents'
import { RendererComponent } from '@etherealengine/spatial/src/renderer/WebGLRendererSystem'
import { useScene } from '@etherealengine/spatial/src/renderer/components/SceneComponents'

export const RenderSettingsComponent = defineComponent({
name: 'RenderSettingsComponent',
Expand Down
65 changes: 13 additions & 52 deletions packages/engine/src/scene/systems/ShadowSystem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,8 @@ import {
hasComponent,
removeComponent,
setComponent,
useComponent
useComponent,
useOptionalComponent
} from '@etherealengine/ecs/src/ComponentFunctions'
import { ECSState } from '@etherealengine/ecs/src/ECSState'
import { Entity, UndefinedEntity } from '@etherealengine/ecs/src/Entity'
Expand Down Expand Up @@ -127,7 +128,7 @@ const EntityCSMReactor = (props: { entity: Entity; rendererEntity: Entity; rende
const csm = rendererComponent.csm.get(NO_PROXY) as CSM | null

useEffect(() => {
if (!directionalLightComponent.value) return
if (!directionalLight) return
if (!directionalLightComponent.castShadow.value) return
const csm = new CSM({
light: directionalLight as DirectionalLight,
Expand All @@ -136,27 +137,28 @@ const EntityCSMReactor = (props: { entity: Entity; rendererEntity: Entity; rende
maxFar: directionalLightComponent.cameraFar.value,
lightIntensity: directionalLightComponent.intensity.value,
lightColor: directionalLightComponent.color.value,
cascades: renderSettingsComponent?.cascades.value
cascades: renderSettingsComponent.cascades.value
})
rendererComponent.csm.set(csm)
return () => {
csm.dispose()
if (!hasComponent(rendererEntity, RendererComponent)) return
rendererComponent.csm.set(null)
}
}, [directionalLightComponent.castShadow])
}, [directionalLight, directionalLightComponent?.castShadow])

/** Must run after scene object system to ensure source light is not lit */
useExecute(
() => {
if (!directionalLightComponent.castShadow.value) return
if (!directionalLight || !directionalLightComponent.castShadow.value) return
directionalLight.visible = false
},
{ after: SceneObjectSystem }
)

useEffect(() => {
if (!csm) return
if (!directionalLight) return
if (!directionalLightComponent.castShadow.value) return

csm.shadowBias = directionalLight.shadow.bias
Expand All @@ -173,6 +175,7 @@ const EntityCSMReactor = (props: { entity: Entity; rendererEntity: Entity; rende
}, [
rendererComponent.csm,
shadowMapResolution,
directionalLight,
directionalLightComponent.shadowBias,
directionalLightComponent.intensity,
directionalLightComponent.color,
Expand All @@ -196,46 +199,6 @@ const EntityCSMReactor = (props: { entity: Entity; rendererEntity: Entity; rende
)
}

const PlainCSMReactor = (props: { rendererEntity: Entity }) => {
const { rendererEntity } = props
const rendererComponent = useComponent(rendererEntity, RendererComponent)
const shadowMapResolution = useHookstate(getMutableState(RendererState).shadowMapResolution)

useEffect(() => {
const csm = new CSM({
shadowMapSize: shadowMapResolution.value
})

rendererComponent.csm.set(csm)

return () => {
csm.dispose()
rendererComponent.csm.set(null)
}
}, [])

useEffect(() => {
const csm = rendererComponent.csm.get(NO_PROXY) as CSM | null
if (!csm) return

for (const light of csm.lights) {
light.shadow.mapSize.setScalar(shadowMapResolution.value)
light.shadow.camera.updateProjectionMatrix()
light.shadow.map?.dispose()
light.shadow.map = null as any
light.shadow.needsUpdate = true
}
}, [rendererComponent.csm, shadowMapResolution])

return (
<QueryReactor
Components={[ShadowComponent, GroupComponent]}
ChildEntityReactor={EntityChildCSMReactor}
props={{ rendererEntity: rendererEntity }}
/>
)
}

const EntityChildCSMReactor = (props: { rendererEntity: Entity }) => {
const entity = useEntityContext()
const { rendererEntity } = props
Expand Down Expand Up @@ -283,10 +246,9 @@ function CSMReactor(props: { rendererEntity: Entity; renderSettingsEntity: Entit
//const rendererComponent = useComponent(rendererEntity, RendererComponent)

const renderSettingsComponent = useComponent(renderSettingsEntity, RenderSettingsComponent)

const xrLightProbeEntity = useHookstate(getMutableState(XRLightProbeState).directionalLightEntity)

const activeLightEntity = useHookstate(UndefinedEntity)
const activeLightEntity = useHookstate(UUIDComponent.getEntityByUUID(renderSettingsComponent.primaryLight.value))
const directionalLight = useOptionalComponent(activeLightEntity.value, DirectionalLightComponent)

//const rendererState = useMutableState(RendererState)

Expand Down Expand Up @@ -314,14 +276,13 @@ function CSMReactor(props: { rendererEntity: Entity; renderSettingsEntity: Entit
}

activeLightEntity.set(UndefinedEntity)
}, [xrLightProbeEntity.value, renderSettingsComponent.primaryLight.value])

if (!renderSettingsComponent.csm.value) return null
}, [xrLightProbeEntity.value, renderSettingsComponent.primaryLight])

if (!activeLightEntity.value) return <PlainCSMReactor rendererEntity={rendererEntity} key={rendererEntity} />
if (!renderSettingsComponent.csm.value || !activeLightEntity.value || !directionalLight) return null

return (
<EntityCSMReactor
key={activeLightEntity.value}
entity={activeLightEntity.value}
rendererEntity={rendererEntity}
renderSettingsEntity={renderSettingsEntity}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ import { matches, useMutableState } from '@etherealengine/hyperflux'

import { mergeBufferGeometries } from '../../common/classes/BufferGeometryUtils'
import { useDisposable } from '../../resources/resourceHooks'
import { useUpdateLight } from '../functions/useUpdateLight'
import { RendererState } from '../RendererState'
import { useUpdateLight } from '../functions/useUpdateLight'
import { addObjectToGroup, removeObjectFromGroup } from './GroupComponent'
import { LineSegmentComponent } from './LineSegmentComponent'

Expand Down
49 changes: 35 additions & 14 deletions packages/ui/src/components/editor/properties/render/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,23 @@ All portions of the code written by the Ethereal Engine team are Copyright © 20
Ethereal Engine. All Rights Reserved.
*/

import React from 'react'
import { EntityUUID, UUIDComponent, useQuery } from '@etherealengine/ecs'
import { ComponentType, getComponent, useComponent } from '@etherealengine/ecs/src/ComponentFunctions'
import {
EditorComponentType,
commitProperty,
updateProperty
} from '@etherealengine/editor/src/components/properties/Util'
import { GLTFNodeState, GLTFSnapshotAction } from '@etherealengine/engine/src/gltf/GLTFDocumentState'
import { GLTFSnapshotState } from '@etherealengine/engine/src/gltf/GLTFState'
import { RenderSettingsComponent } from '@etherealengine/engine/src/scene/components/RenderSettingsComponent'
import { SourceComponent } from '@etherealengine/engine/src/scene/components/SourceComponent'
import { State, dispatchAction } from '@etherealengine/hyperflux'
import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent'
import { DirectionalLightComponent } from '@etherealengine/spatial/src/renderer/components/DirectionalLightComponent'
import React, { useEffect } from 'react'
import { useTranslation } from 'react-i18next'
import { SiRender } from 'react-icons/si'
import {
ACESFilmicToneMapping,
BasicShadowMap,
Expand All @@ -36,18 +51,6 @@ import {
ReinhardToneMapping,
VSMShadowMap
} from 'three'

import { EntityUUID, useQuery, UUIDComponent } from '@etherealengine/ecs'
import { getComponent, useComponent } from '@etherealengine/ecs/src/ComponentFunctions'
import {
commitProperty,
EditorComponentType,
updateProperty
} from '@etherealengine/editor/src/components/properties/Util'
import { RenderSettingsComponent } from '@etherealengine/engine/src/scene/components/RenderSettingsComponent'
import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent'
import { DirectionalLightComponent } from '@etherealengine/spatial/src/renderer/components/DirectionalLightComponent'
import { SiRender } from 'react-icons/si'
import Slider from '../../../../primitives/tailwind/Slider'
import BooleanInput from '../../input/Boolean'
import InputGroup from '../../input/Group'
Expand Down Expand Up @@ -107,7 +110,8 @@ const ShadowTypeOptions = [

export const RenderSettingsEditor: EditorComponentType = (props) => {
const { t } = useTranslation()
const rendererSettingsState = useComponent(props.entity, RenderSettingsComponent)
const { entity } = props
const rendererSettingsState = useComponent(entity, RenderSettingsComponent)

const directionalLightOptions = [
{
Expand All @@ -123,6 +127,23 @@ export const RenderSettingsEditor: EditorComponentType = (props) => {
})
)

useEffect(() => {
if (!UUIDComponent.getEntityByUUID(rendererSettingsState.primaryLight.value)) {
const source = getComponent(entity, SourceComponent)
const node = GLTFNodeState.getMutableNode(entity)
const renderSettingsExt = node.extensions[RenderSettingsComponent.jsonID] as State<
ComponentType<typeof RenderSettingsComponent>
>
if (!renderSettingsExt.primaryLight.value) return
renderSettingsExt.merge({
csm: false,
primaryLight: '' as EntityUUID
})
const snapshot = GLTFSnapshotState.cloneCurrentSnapshot(source)
dispatchAction(GLTFSnapshotAction.createSnapshot(snapshot))
}
}, [rendererSettingsState.primaryLight])

return (
<PropertyGroup
name={t('editor:properties.renderSettings.name')}
Expand Down

0 comments on commit 57c3d1f

Please sign in to comment.