flow: lights and normals
This commit is contained in:
parent
82fd31802b
commit
2c2bfcbf0c
|
@ -10,6 +10,9 @@ const loading = {};
|
|||
export function useAsset(source) {
|
||||
const [assets, setAssets] = useContext(context);
|
||||
useEffect(() => {
|
||||
if (!source) {
|
||||
return undefined;
|
||||
}
|
||||
if (!assets[source]) {
|
||||
if (!loading[source]) {
|
||||
(loading[source] = Assets.load(source)).then((asset) => {
|
||||
|
@ -21,5 +24,5 @@ export function useAsset(source) {
|
|||
}
|
||||
}
|
||||
}, [assets, setAssets, source]);
|
||||
return assets[source];
|
||||
return source ? assets[source] : undefined;
|
||||
}
|
||||
|
|
11
app/react-components/pixi/extensions.js
vendored
11
app/react-components/pixi/extensions.js
vendored
|
@ -1,10 +1,12 @@
|
|||
import {ExtensionType} from '@pixi/core';
|
||||
import {Layer, Stage as LayerStage} from '@pixi/layers';
|
||||
|
||||
let AmbientLight, diffuseGroup, normalGroup, lightGroup;
|
||||
if ('undefined' !== typeof window) {
|
||||
({AmbientLight, diffuseGroup, normalGroup, lightGroup} = await import('@pixi/lights'));
|
||||
}
|
||||
import {
|
||||
AmbientLight,
|
||||
diffuseGroup,
|
||||
normalGroup,
|
||||
lightGroup,
|
||||
} from './lights.js';
|
||||
|
||||
export const ApplicationStageLayers = {
|
||||
type: ExtensionType.Application,
|
||||
|
@ -26,6 +28,7 @@ export const ApplicationStageLights = {
|
|||
stage.addChild(new Layer(diffuseGroup));
|
||||
stage.addChild(new Layer(normalGroup));
|
||||
stage.addChild(new Layer(lightGroup));
|
||||
// stage.addChild(new AmbientLight(0x2244ff, 0.1));
|
||||
stage.addChild(new AmbientLight(0xffffff, 1));
|
||||
},
|
||||
},
|
||||
|
|
|
@ -9,6 +9,11 @@ const LightInternal = PixiComponent('Light', {
|
|||
create({x, y}) {
|
||||
const light = new PointLight(0xffffff, 1);
|
||||
light.position.set(x, y);
|
||||
// light.shader.program.fragmentSrc = light.shader.program.fragmentSrc.replace(
|
||||
// 'float D = length(lightVector)',
|
||||
// 'float D = length(lightVector) / 2.0',
|
||||
// );
|
||||
// light.falloff = [1, 10, 100]
|
||||
return light;
|
||||
},
|
||||
applyProps(light, oldProps, {x, y}) {
|
||||
|
|
7
app/react-components/pixi/lights.js
vendored
Normal file
7
app/react-components/pixi/lights.js
vendored
Normal file
|
@ -0,0 +1,7 @@
|
|||
let AmbientLight, diffuseGroup, normalGroup, lightGroup;
|
||||
|
||||
if ('undefined' !== typeof window) {
|
||||
({AmbientLight, diffuseGroup, normalGroup, lightGroup} = await import('@pixi/lights'));
|
||||
}
|
||||
|
||||
export {AmbientLight, diffuseGroup, normalGroup, lightGroup};
|
|
@ -1,27 +1,84 @@
|
|||
import {Sprite as PixiSprite} from '@pixi/react';
|
||||
import {useEffect, useState} from 'react';
|
||||
|
||||
import {useAsset} from '@/context/assets.js';
|
||||
|
||||
export default function Sprite({entity, ...rest}) {
|
||||
const asset = useAsset(entity.Sprite.source);
|
||||
import {diffuseGroup, normalGroup} from './lights.js';
|
||||
|
||||
function textureFromAsset(asset, animation, frame) {
|
||||
if (!asset) {
|
||||
return false;
|
||||
return undefined;
|
||||
}
|
||||
let texture;
|
||||
if (asset.data.animations) {
|
||||
texture = asset.animations[entity.Sprite.animation][entity.Sprite.frame];
|
||||
texture = asset.animations[animation][frame];
|
||||
}
|
||||
else {
|
||||
texture = asset.textures[''];
|
||||
}
|
||||
return texture;
|
||||
}
|
||||
|
||||
export default function Sprite({entity, ...rest}) {
|
||||
const [mounted, setMounted] = useState();
|
||||
const [normals, setNormals] = useState();
|
||||
const [normalsMounted, setNormalsMounted] = useState();
|
||||
const {anchor, animation, frame, scale, source} = entity.Sprite;
|
||||
const asset = useAsset(source);
|
||||
const normalsAsset = useAsset(normals);
|
||||
useEffect(() => {
|
||||
if (!asset) {
|
||||
return;
|
||||
}
|
||||
const {normals} = asset.data.meta;
|
||||
if (normals) {
|
||||
const {pathname} = new URL(
|
||||
source.split('/').slice(0, -1).concat(normals).join('/'),
|
||||
'http://example.org',
|
||||
);
|
||||
setNormals(pathname);
|
||||
}
|
||||
}, [asset, source]);
|
||||
const texture = textureFromAsset(
|
||||
asset,
|
||||
animation,
|
||||
frame,
|
||||
);
|
||||
const normalsTexture = textureFromAsset(
|
||||
normalsAsset,
|
||||
animation,
|
||||
frame,
|
||||
);
|
||||
if (mounted) {
|
||||
mounted.parentGroup = diffuseGroup;
|
||||
}
|
||||
if (normalsMounted) {
|
||||
normalsMounted.parentGroup = normalGroup;
|
||||
}
|
||||
return (
|
||||
<PixiSprite
|
||||
anchor={entity.Sprite.anchor}
|
||||
scale={entity.Sprite.scale}
|
||||
texture={texture}
|
||||
x={Math.round(entity.Position.x)}
|
||||
y={Math.round(entity.Position.y)}
|
||||
{...rest}
|
||||
/>
|
||||
<>
|
||||
{texture && (
|
||||
<PixiSprite
|
||||
anchor={anchor}
|
||||
ref={setMounted}
|
||||
scale={scale}
|
||||
texture={texture}
|
||||
x={Math.round(entity.Position.x)}
|
||||
y={Math.round(entity.Position.y)}
|
||||
{...rest}
|
||||
/>
|
||||
)}
|
||||
{normalsTexture && (
|
||||
<PixiSprite
|
||||
anchor={anchor}
|
||||
ref={setNormalsMounted}
|
||||
scale={scale}
|
||||
texture={normalsTexture}
|
||||
x={Math.round(entity.Position.x)}
|
||||
y={Math.round(entity.Position.y)}
|
||||
{...rest}
|
||||
/>
|
||||
)}
|
||||
</>
|
||||
);
|
||||
}
|
|
@ -8,14 +8,10 @@ import {CompositeTilemap} from '@pixi/tilemap';
|
|||
import {CHUNK_SIZE} from '@/constants.js';
|
||||
import {useAsset} from '@/context/assets.js';
|
||||
|
||||
let diffuseGroup, normalGroup;
|
||||
if ('undefined' !== typeof window) {
|
||||
({diffuseGroup, normalGroup} = await import('@pixi/lights'));
|
||||
}
|
||||
|
||||
import {diffuseGroup, normalGroup} from './lights.js';
|
||||
|
||||
const TileLayerInternal = PixiComponent('TileLayer', {
|
||||
create: ({group, stage, tileLayer}) => {
|
||||
create: ({group, tileLayer}) => {
|
||||
const container = new Container();
|
||||
const cy = Math.ceil(tileLayer.area.y / CHUNK_SIZE);
|
||||
const cx = Math.ceil(tileLayer.area.x / CHUNK_SIZE);
|
||||
|
@ -85,7 +81,7 @@ const TileLayerInternal = PixiComponent('TileLayer', {
|
|||
});
|
||||
|
||||
export default function TileLayer(props) {
|
||||
const {renderer, stage} = useApp();
|
||||
const {renderer} = useApp();
|
||||
const {tileLayer} = props;
|
||||
const asset = useAsset(tileLayer.source);
|
||||
const normalsAsset = useAsset([tileLayer.source.slice(0, -'.json'.length), 'normals.json'].join('.'));
|
||||
|
@ -99,14 +95,12 @@ export default function TileLayer(props) {
|
|||
asset={asset}
|
||||
group={diffuseGroup}
|
||||
renderer={renderer}
|
||||
stage={stage}
|
||||
/>
|
||||
<TileLayerInternal
|
||||
{...props}
|
||||
asset={normalsAsset}
|
||||
group={normalGroup}
|
||||
renderer={renderer}
|
||||
stage={stage}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
|
|
1
public/assets/shit-shack/shit-shack.normals.json
Normal file
1
public/assets/shit-shack/shit-shack.normals.json
Normal file
|
@ -0,0 +1 @@
|
|||
{"frames":{"":{"frame":{"x":0,"y":0,"w":110,"h":102},"spriteSourceSize":{"x":0,"y":0,"w":110,"h":102},"sourceSize":{"w":110,"h":102}}},"meta":{"format":"RGBA8888","image":"./shit-shack.normals.png","scale":1,"size":{"w":110,"h":102}}}
|
BIN
public/assets/shit-shack/shit-shack.normals.png
Normal file
BIN
public/assets/shit-shack/shit-shack.normals.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 28 KiB |
Loading…
Reference in New Issue
Block a user