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

Lit and Unlit modes implementation #10408

Merged
merged 30 commits into from
Jul 17, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
bf3dc18
add isEditor in Editor2Page
aditya-mitra Jun 18, 2024
c79a4a2
fix drop shadows
SYBIOTE Jun 18, 2024
6938b63
Merge branch 'dev' into lit-unlit-render-mode
SYBIOTE Jun 18, 2024
4965abe
Merge branch 'dev' into lit-unlit-render-mode
aditya-mitra Jun 19, 2024
3e7cb17
Merge branch 'dev' into lit-unlit-render-mode
aditya-mitra Jun 20, 2024
a2748a3
do not show shadows in lit and unlit modes
aditya-mitra Jun 20, 2024
91b6c66
Merge remote-tracking branch 'origin/lit-unlit-render-mode' into lit-…
aditya-mitra Jun 20, 2024
12bada8
hide lights in unlit mode except for ambient
SYBIOTE Jul 1, 2024
856ed97
temp ambient light
SYBIOTE Jul 1, 2024
98ec3bb
move from reactor to execute loop
SYBIOTE Jul 1, 2024
f169dd5
Merge branch 'dev' into lit-unlit-render-mode
SYBIOTE Jul 1, 2024
bdb53fb
Merge branch 'dev' into lit-unlit-render-mode
SYBIOTE Jul 2, 2024
65bf64c
fix conflict
SYBIOTE Jul 2, 2024
751cf89
fix conflict
SYBIOTE Jul 2, 2024
411f028
make viewport lighting into a seperate system
SYBIOTE Jul 4, 2024
7d17174
add License
SYBIOTE Jul 4, 2024
5ef6546
seperate primitive geom check
SYBIOTE Jul 4, 2024
1607e53
use enums
SYBIOTE Jul 4, 2024
4f12d6b
Merge branch 'dev' into lit-unlit-render-mode
SYBIOTE Jul 4, 2024
2d397b2
change root to origin entity
SYBIOTE Jul 5, 2024
b8d9a11
Merge branch 'dev' into lit-unlit-render-mode
SYBIOTE Jul 10, 2024
4d9bd44
remove primitve geom check from model check
SYBIOTE Jul 14, 2024
0ea7f51
Merge branch 'dev' into lit-unlit-render-mode
SYBIOTE Jul 14, 2024
02014b7
Merge branch 'dev' into lit-unlit-render-mode
SYBIOTE Jul 15, 2024
a5d67ed
Drop shadow fixes
MichaelEstes Jul 16, 2024
00e070e
revert
MichaelEstes Jul 16, 2024
7eb94e7
Merge branch 'dev' into lit-unlit-render-mode
MichaelEstes Jul 16, 2024
11e778d
Merge branch 'lit-unlit-render-mode' into drop-shadows
MichaelEstes Jul 16, 2024
3fcffb5
CSM shadow and drop shadow systems need different insert orders
MichaelEstes Jul 16, 2024
b8225bf
Merge pull request #10625 from EtherealEngine/drop-shadows
MichaelEstes Jul 16, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import React from 'react'
import { useTranslation } from 'react-i18next'

import { useComponent } from '@etherealengine/ecs/src/ComponentFunctions'
import { AmbientLightComponent } from '@etherealengine/spatial/src/renderer/components/AmbientLightComponent'
import { AmbientLightComponent } from '@etherealengine/spatial/src/renderer/components/lights/AmbientLightComponent'
SYBIOTE marked this conversation as resolved.
Show resolved Hide resolved

import ColorInput from '../inputs/ColorInput'
import InputGroup from '../inputs/InputGroup'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import React from 'react'
import { useTranslation } from 'react-i18next'

import { useComponent } from '@etherealengine/ecs/src/ComponentFunctions'
import { DirectionalLightComponent } from '@etherealengine/spatial/src/renderer/components/DirectionalLightComponent'
import { DirectionalLightComponent } from '@etherealengine/spatial/src/renderer/components/lights/DirectionalLightComponent'

import ColorInput from '../inputs/ColorInput'
import InputGroup from '../inputs/InputGroup'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import React from 'react'
import { useTranslation } from 'react-i18next'

import { useComponent } from '@etherealengine/ecs/src/ComponentFunctions'
import { HemisphereLightComponent } from '@etherealengine/spatial/src/renderer/components/HemisphereLightComponent'
import { HemisphereLightComponent } from '@etherealengine/spatial/src/renderer/components/lights/HemisphereLightComponent'

import ColorInput from '../inputs/ColorInput'
import InputGroup from '../inputs/InputGroup'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import React from 'react'
import { useTranslation } from 'react-i18next'

import { useComponent } from '@etherealengine/ecs/src/ComponentFunctions'
import { PointLightComponent } from '@etherealengine/spatial/src/renderer/components/PointLightComponent'
import { PointLightComponent } from '@etherealengine/spatial/src/renderer/components/lights/PointLightComponent'

import ColorInput from '../inputs/ColorInput'
import InputGroup from '../inputs/InputGroup'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ import { EntityUUID, useQuery, UUIDComponent } from '@etherealengine/ecs'
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 { DirectionalLightComponent } from '@etherealengine/spatial/src/renderer/components/lights/DirectionalLightComponent'

import { GLTFNodeState, GLTFSnapshotAction } from '@etherealengine/engine/src/gltf/GLTFDocumentState'
import { GLTFSnapshotState } from '@etherealengine/engine/src/gltf/GLTFState'
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import React from 'react'
import { useTranslation } from 'react-i18next'

import { useComponent } from '@etherealengine/ecs/src/ComponentFunctions'
import { SpotLightComponent } from '@etherealengine/spatial/src/renderer/components/SpotLightComponent'
import { SpotLightComponent } from '@etherealengine/spatial/src/renderer/components/lights/SpotLightComponent'

import ColorInput from '../inputs/ColorInput'
import InputGroup from '../inputs/InputGroup'
Expand Down
1 change: 1 addition & 0 deletions packages/editor/src/pages/Editor2Page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@ export const useStudioEditor = () => {
const engineReady = useHookstate(false)

useEffect(() => {
getMutableState(EngineState).isEditor.set(true)
getMutableState(EngineState).isEditing.set(true)
loadEngineInjection().then(() => {
engineReady.set(true)
Expand Down
3 changes: 2 additions & 1 deletion packages/engine/src/scene/SceneModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ import { PortalSystem } from './systems/PortalSystem'
import { SceneKillHeightSystem } from './systems/SceneKillHeightSystem'
import { SceneObjectDynamicLoadSystem } from './systems/SceneObjectDynamicLoadSystem'
import { SceneObjectSystem } from './systems/SceneObjectSystem'
import { ShadowSystem } from './systems/ShadowSystem'
import { DropShadowSystem, ShadowSystem } from './systems/ShadowSystem'
import { VariantSystem } from './systems/VariantSystem'

/** This const MUST be kept here, to ensure all components definitions are loaded by the time the scene loading occurs */
Expand Down Expand Up @@ -111,6 +111,7 @@ export const SceneComponents = [
]

export {
DropShadowSystem,
EnvironmentSystem,
FogSystem,
MaterialLibrarySystem,
Expand Down
11 changes: 6 additions & 5 deletions packages/engine/src/scene/components/ModelComponent.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -247,15 +247,16 @@ function ModelReactor() {
}

/**
* Returns true if the entity is a mesh not a part of a model, or a model
* Returns true if the entity has a model component or a mesh component that is not a child of model
* @param entity
* @returns
* @returns {boolean}
*/
export const useMeshOrModel = (entity: Entity) => {
const isModel = !!useOptionalComponent(entity, ModelComponent)
export const useHasModelOrIndependentMesh = (entity: Entity) => {
const hasModel = !!useOptionalComponent(entity, ModelComponent)
const isChildOfModel = !!useAncestorWithComponent(entity, ModelComponent)
const hasMesh = !!useOptionalComponent(entity, MeshComponent)
return isModel && !isChildOfModel && hasMesh

return hasModel || (hasMesh && !isChildOfModel)
}

export const MeshOrModelQuery = (props: { ChildReactor: FC<{ entity: Entity; rootEntity: Entity }> }) => {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,13 +26,10 @@ Ethereal Engine. All Rights Reserved.
import { useLayoutEffect } from 'react'
import { MeshLambertMaterial } from 'three'

import { defineComponent, useComponent, useOptionalComponent } from '@etherealengine/ecs/src/ComponentFunctions'
import { defineComponent, useComponent } from '@etherealengine/ecs/src/ComponentFunctions'
import { useEntityContext } from '@etherealengine/ecs/src/EntityFunctions'
import { Geometry } from '@etherealengine/spatial/src/common/constants/Geometry'
import { useMeshComponent } from '@etherealengine/spatial/src/renderer/components/MeshComponent'

import { ColliderComponent } from '@etherealengine/spatial/src/physics/components/ColliderComponent'
import { Shape, Shapes } from '@etherealengine/spatial/src/physics/types/PhysicsTypes'
import { GeometryTypeEnum, GeometryTypeToClass } from '../constants/GeometryTypeEnum'

const createGeometry = (geometryType: GeometryTypeEnum, geometryParams: Record<string, any>): Geometry => {
Expand Down Expand Up @@ -73,33 +70,11 @@ export const PrimitiveGeometryComponent = defineComponent({
() => createGeometry(geometryComponent.geometryType.value, geometryComponent.geometryParams.value),
() => new MeshLambertMaterial()
)
const colliderComponent = useOptionalComponent(entity, ColliderComponent)

useLayoutEffect(() => {
mesh.geometry.set(createGeometry(geometryComponent.geometryType.value, geometryComponent.geometryParams.value))
}, [geometryComponent.geometryType, geometryComponent.geometryParams])

useLayoutEffect(() => {
if (!colliderComponent) return
colliderComponent.shape.set(GeometryToColliderShape[geometryComponent.geometryType.value])
}, [mesh.geometry, !!colliderComponent])

return null
}
})

const GeometryToColliderShape = {
[GeometryTypeEnum.BoxGeometry]: Shapes.Box,
[GeometryTypeEnum.SphereGeometry]: Shapes.Sphere,
[GeometryTypeEnum.CylinderGeometry]: Shapes.Cylinder,
[GeometryTypeEnum.CapsuleGeometry]: Shapes.Capsule,
[GeometryTypeEnum.PlaneGeometry]: Shapes.Mesh,
[GeometryTypeEnum.CircleGeometry]: Shapes.Mesh,
[GeometryTypeEnum.RingGeometry]: Shapes.Mesh,
[GeometryTypeEnum.TorusGeometry]: Shapes.Mesh,
[GeometryTypeEnum.DodecahedronGeometry]: Shapes.Mesh,
[GeometryTypeEnum.IcosahedronGeometry]: Shapes.Mesh,
[GeometryTypeEnum.OctahedronGeometry]: Shapes.Mesh,
[GeometryTypeEnum.TetrahedronGeometry]: Shapes.Mesh,
[GeometryTypeEnum.TorusKnotGeometry]: Shapes.Mesh
} as Record<GeometryTypeEnum, Shape>
69 changes: 42 additions & 27 deletions packages/engine/src/scene/systems/ShadowSystem.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ import {

import config from '@etherealengine/common/src/config'
import { isClient } from '@etherealengine/common/src/utils/getEnvironment'
import { Engine, UUIDComponent } from '@etherealengine/ecs'
import { AnimationSystemGroup, Engine, UUIDComponent } from '@etherealengine/ecs'
import {
getComponent,
getOptionalComponent,
Expand All @@ -55,16 +55,15 @@ import { Entity, UndefinedEntity } from '@etherealengine/ecs/src/Entity'
import { createEntity, removeEntity, useEntityContext } from '@etherealengine/ecs/src/EntityFunctions'
import { defineQuery, QueryReactor } from '@etherealengine/ecs/src/QueryFunctions'
import { defineSystem, useExecute } from '@etherealengine/ecs/src/SystemFunctions'
import { AnimationSystemGroup } from '@etherealengine/ecs/src/SystemGroups'
import { defineState, getMutableState, getState, hookstate, NO_PROXY, useHookstate } from '@etherealengine/hyperflux'
import { defineState, getMutableState, getState, NO_PROXY, useHookstate } from '@etherealengine/hyperflux'
import { Vector3_Back } from '@etherealengine/spatial/src/common/constants/MathConstants'
import {
createPriorityQueue,
createSortAndApplyPriorityQueue
} from '@etherealengine/spatial/src/common/functions/PriorityQueue'
import { NameComponent } from '@etherealengine/spatial/src/common/NameComponent'
import { DirectionalLightComponent } from '@etherealengine/spatial/src/renderer/components/DirectionalLightComponent'
import { addObjectToGroup, GroupComponent } from '@etherealengine/spatial/src/renderer/components/GroupComponent'
import { DirectionalLightComponent } from '@etherealengine/spatial/src/renderer/components/lights/DirectionalLightComponent'
import { MeshComponent } from '@etherealengine/spatial/src/renderer/components/MeshComponent'
import { ObjectLayerComponents } from '@etherealengine/spatial/src/renderer/components/ObjectLayerComponent'
import { VisibleComponent } from '@etherealengine/spatial/src/renderer/components/VisibleComponent'
Expand All @@ -87,9 +86,13 @@ import { TransformComponent } from '@etherealengine/spatial/src/transform/compon
import { XRLightProbeState } from '@etherealengine/spatial/src/xr/XRLightProbeSystem'
import { isMobileXRHeadset } from '@etherealengine/spatial/src/xr/XRState'

import { TransformSystem } from '@etherealengine/spatial'
import { EngineState } from '@etherealengine/spatial/src/EngineState'
import { RenderModes } from '@etherealengine/spatial/src/renderer/constants/RenderModes'
import { createDisposable } from '@etherealengine/spatial/src/resources/resourceHooks'
import { useTexture } from '../../assets/functions/resourceLoaderHooks'
import { DropShadowComponent } from '../components/DropShadowComponent'
import { useMeshOrModel } from '../components/ModelComponent'
import { useHasModelOrIndependentMesh } from '../components/ModelComponent'
import { RenderSettingsComponent } from '../components/RenderSettingsComponent'
import { ShadowComponent } from '../components/ShadowComponent'
import { SceneObjectSystem } from './SceneObjectSystem'
Expand Down Expand Up @@ -234,9 +237,12 @@ const EntityChildCSMReactor = (props: { rendererEntity: Entity }) => {
function _CSMReactor() {
const rendererEntity = useEntityContext()
const renderSettingsEntity = useChildWithComponent(rendererEntity, RenderSettingsComponent)
const isEditor = useHookstate(getMutableState(EngineState).isEditor).value
const renderMode = useHookstate(getMutableState(RendererState).renderMode).value

if (!rendererEntity) return null
if (!renderSettingsEntity) return null
if ((isEditor && renderMode === RenderModes.UNLIT) || renderMode === RenderModes.LIT) return null

return <CSMReactor rendererEntity={rendererEntity} renderSettingsEntity={renderSettingsEntity} />
}
Expand Down Expand Up @@ -300,8 +306,6 @@ const shadowMaterial = new MeshBasicMaterial({
polygonOffsetUnits: 0.01
})

const shadowState = hookstate(null as MeshBasicMaterial | null)

const dropShadowComponentQuery = defineQuery([DropShadowComponent])

const minRadius = 0.15
Expand All @@ -312,14 +316,11 @@ const vec3 = new Vector3()

const DropShadowReactor = () => {
const entity = useEntityContext()
const shadowMaterial = useHookstate(shadowState)
const isMeshOrModel = useMeshOrModel(entity)
const hasMeshOrModel = useHasModelOrIndependentMesh(entity)
const shadow = useComponent(entity, ShadowComponent)
const entityTree = useComponent(entity, EntityTreeComponent)

useEffect(() => {
if (!shadow.cast.value || !shadowMaterial.value || !isMeshOrModel || hasComponent(entity, DropShadowComponent))
return
if (!shadow.cast.value || !hasMeshOrModel || hasComponent(entity, DropShadowComponent)) return

box3.makeEmpty()

Expand All @@ -342,17 +343,24 @@ const DropShadowReactor = () => {
const radius = Math.max(sphere.radius * 2, minRadius)
const center = sphere.center.sub(TransformComponent.getWorldPosition(entity, vec3))
const shadowEntity = createEntity()
const shadowObject = new Mesh(shadowGeometry, shadowMaterial.value.clone())
const [shadowObject, unload] = createDisposable(Mesh, shadowEntity, shadowGeometry.clone(), shadowMaterial.clone())
addObjectToGroup(shadowEntity, shadowObject)
setComponent(shadowEntity, NameComponent, 'Shadow for ' + getComponent(entity, NameComponent))
setComponent(shadowEntity, EntityTreeComponent, { parentEntity: Engine.instance.originEntity })
setComponent(
shadowEntity,
NameComponent,
'Shadow for ' + getComponent(entity, NameComponent) + '_' + getComponent(entity, UUIDComponent)
)
setComponent(shadowEntity, VisibleComponent)
setComponent(shadowEntity, ObjectLayerComponents[ObjectLayers.Scene])
setComponent(entity, DropShadowComponent, { radius, center, entity: shadowEntity })

return () => {
removeComponent(entity, DropShadowComponent)
removeEntity(shadowEntity)
unload()
}
}, [shadowMaterial, isMeshOrModel, shadow, entityTree.children])
}, [hasMeshOrModel, shadow])

return null
}
Expand All @@ -362,8 +370,7 @@ const shadowOffset = new Vector3(0, 0.01, 0)
const sortAndApplyPriorityQueue = createSortAndApplyPriorityQueue(dropShadowComponentQuery, compareDistanceToCamera)
const sortedEntityTransforms = [] as Entity[]

const cameraLayerQuery = defineQuery([ObjectLayerComponents[ObjectLayers.Camera], MeshComponent])

const cameraLayerQuery = defineQuery([ObjectLayerComponents[ObjectLayers.Scene], MeshComponent])
const updateDropShadowTransforms = () => {
const { deltaSeconds } = getState(ECSState)
const { priorityQueue } = getState(ShadowSystemState)
Expand Down Expand Up @@ -391,9 +398,8 @@ const updateDropShadowTransforms = () => {
const sizeBias = 0.3
const finalRadius = sizeBias * dropShadow.radius + dropShadow.radius * centerCorrectedDist * 0.5

const shadowMaterial = (getComponent(dropShadow.entity, GroupComponent)[0] as any).material as Material
shadowMaterial.opacity = Math.min(1 / (1 + centerCorrectedDist), 1) * 0.6

const shadowMaterial = (getComponent(dropShadow.entity, GroupComponent)[0] as Mesh).material as Material
shadowMaterial.opacity = Math.min(1 / (1 + centerCorrectedDist), 1) * 1.2
shadowRotation.setFromUnitVectors(intersected.face.normal, Vector3_Back)
dropShadowTransform.rotation.copy(shadowRotation)
dropShadowTransform.scale.setScalar(finalRadius * 2)
Expand All @@ -407,10 +413,7 @@ const execute = () => {
if (!isClient) return

const useShadows = getShadowsEnabled()
if (!useShadows) {
updateDropShadowTransforms()
return
}
if (!useShadows) return

for (const entity of rendererQuery()) {
const { csm, csmHelper } = getComponent(entity, RendererComponent)
Expand Down Expand Up @@ -446,16 +449,15 @@ const reactor = () => {
if (!shadowTexture) return
shadowMaterial.map = shadowTexture
shadowMaterial.needsUpdate = true
shadowState.set(shadowMaterial)
}, [shadowTexture])

return (
<>
{useShadows ? (
<QueryReactor Components={[RendererComponent]} ChildEntityReactor={_CSMReactor} />
) : (
) : shadowTexture ? (
<QueryReactor Components={[VisibleComponent, ShadowComponent]} ChildEntityReactor={DropShadowReactor} />
)}
) : null}
<QueryReactor Components={[RendererComponent]} ChildEntityReactor={RendererShadowReactor} />
</>
)
Expand All @@ -467,3 +469,16 @@ export const ShadowSystem = defineSystem({
execute,
reactor
})

export const DropShadowSystem = defineSystem({
uuid: 'ee.engine.DropShadowSystem',
insert: { after: TransformSystem },
execute: () => {
if (!isClient) return

const useShadows = getShadowsEnabled()
if (!useShadows) {
updateDropShadowTransforms()
}
}
})
12 changes: 7 additions & 5 deletions packages/spatial/src/renderer/RendererModule.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,16 +23,17 @@ All portions of the code written by the Ethereal Engine team are Copyright © 20
Ethereal Engine. All Rights Reserved.
*/

import { AmbientLightComponent } from '../renderer/components/AmbientLightComponent'
import { DirectionalLightComponent } from '../renderer/components/DirectionalLightComponent'
import { HemisphereLightComponent } from '../renderer/components/HemisphereLightComponent'
import { PointLightComponent } from '../renderer/components/PointLightComponent'
import { SpotLightComponent } from '../renderer/components/SpotLightComponent'
import { TransformComponent } from '../transform/components/TransformComponent'
import { XRAnchorComponent } from '../xr/XRComponents'
import { DebugRendererSystem } from './DebugRendererSystem'
import { RenderInfoSystem } from './RenderInfoSystem'
import { ViewportLightingSystem } from './ViewportLightingSystem'
import { WebGLRendererSystem } from './WebGLRendererSystem'
import { AmbientLightComponent } from './components/lights/AmbientLightComponent'
import { DirectionalLightComponent } from './components/lights/DirectionalLightComponent'
import { HemisphereLightComponent } from './components/lights/HemisphereLightComponent'
import { PointLightComponent } from './components/lights/PointLightComponent'
import { SpotLightComponent } from './components/lights/SpotLightComponent'

/** Components */
export {
Expand All @@ -45,6 +46,7 @@ export {
RenderInfoSystem,
SpotLightComponent,
TransformComponent,
ViewportLightingSystem,
WebGLRendererSystem,
XRAnchorComponent
}
Loading
Loading