flow: lights and normals
This commit is contained in:
parent
82fd31802b
commit
2c2bfcbf0c
|
@ -10,6 +10,9 @@ const loading = {};
|
||||||
export function useAsset(source) {
|
export function useAsset(source) {
|
||||||
const [assets, setAssets] = useContext(context);
|
const [assets, setAssets] = useContext(context);
|
||||||
useEffect(() => {
|
useEffect(() => {
|
||||||
|
if (!source) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
if (!assets[source]) {
|
if (!assets[source]) {
|
||||||
if (!loading[source]) {
|
if (!loading[source]) {
|
||||||
(loading[source] = Assets.load(source)).then((asset) => {
|
(loading[source] = Assets.load(source)).then((asset) => {
|
||||||
|
@ -21,5 +24,5 @@ export function useAsset(source) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, [assets, setAssets, 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 {ExtensionType} from '@pixi/core';
|
||||||
import {Layer, Stage as LayerStage} from '@pixi/layers';
|
import {Layer, Stage as LayerStage} from '@pixi/layers';
|
||||||
|
|
||||||
let AmbientLight, diffuseGroup, normalGroup, lightGroup;
|
import {
|
||||||
if ('undefined' !== typeof window) {
|
AmbientLight,
|
||||||
({AmbientLight, diffuseGroup, normalGroup, lightGroup} = await import('@pixi/lights'));
|
diffuseGroup,
|
||||||
}
|
normalGroup,
|
||||||
|
lightGroup,
|
||||||
|
} from './lights.js';
|
||||||
|
|
||||||
export const ApplicationStageLayers = {
|
export const ApplicationStageLayers = {
|
||||||
type: ExtensionType.Application,
|
type: ExtensionType.Application,
|
||||||
|
@ -26,6 +28,7 @@ export const ApplicationStageLights = {
|
||||||
stage.addChild(new Layer(diffuseGroup));
|
stage.addChild(new Layer(diffuseGroup));
|
||||||
stage.addChild(new Layer(normalGroup));
|
stage.addChild(new Layer(normalGroup));
|
||||||
stage.addChild(new Layer(lightGroup));
|
stage.addChild(new Layer(lightGroup));
|
||||||
|
// stage.addChild(new AmbientLight(0x2244ff, 0.1));
|
||||||
stage.addChild(new AmbientLight(0xffffff, 1));
|
stage.addChild(new AmbientLight(0xffffff, 1));
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
|
@ -9,6 +9,11 @@ const LightInternal = PixiComponent('Light', {
|
||||||
create({x, y}) {
|
create({x, y}) {
|
||||||
const light = new PointLight(0xffffff, 1);
|
const light = new PointLight(0xffffff, 1);
|
||||||
light.position.set(x, y);
|
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;
|
return light;
|
||||||
},
|
},
|
||||||
applyProps(light, oldProps, {x, y}) {
|
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 {Sprite as PixiSprite} from '@pixi/react';
|
||||||
|
import {useEffect, useState} from 'react';
|
||||||
|
|
||||||
import {useAsset} from '@/context/assets.js';
|
import {useAsset} from '@/context/assets.js';
|
||||||
|
|
||||||
export default function Sprite({entity, ...rest}) {
|
import {diffuseGroup, normalGroup} from './lights.js';
|
||||||
const asset = useAsset(entity.Sprite.source);
|
|
||||||
|
function textureFromAsset(asset, animation, frame) {
|
||||||
if (!asset) {
|
if (!asset) {
|
||||||
return false;
|
return undefined;
|
||||||
}
|
}
|
||||||
let texture;
|
let texture;
|
||||||
if (asset.data.animations) {
|
if (asset.data.animations) {
|
||||||
texture = asset.animations[entity.Sprite.animation][entity.Sprite.frame];
|
texture = asset.animations[animation][frame];
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
texture = asset.textures[''];
|
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 (
|
return (
|
||||||
|
<>
|
||||||
|
{texture && (
|
||||||
<PixiSprite
|
<PixiSprite
|
||||||
anchor={entity.Sprite.anchor}
|
anchor={anchor}
|
||||||
scale={entity.Sprite.scale}
|
ref={setMounted}
|
||||||
|
scale={scale}
|
||||||
texture={texture}
|
texture={texture}
|
||||||
x={Math.round(entity.Position.x)}
|
x={Math.round(entity.Position.x)}
|
||||||
y={Math.round(entity.Position.y)}
|
y={Math.round(entity.Position.y)}
|
||||||
{...rest}
|
{...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 {CHUNK_SIZE} from '@/constants.js';
|
||||||
import {useAsset} from '@/context/assets.js';
|
import {useAsset} from '@/context/assets.js';
|
||||||
|
|
||||||
let diffuseGroup, normalGroup;
|
import {diffuseGroup, normalGroup} from './lights.js';
|
||||||
if ('undefined' !== typeof window) {
|
|
||||||
({diffuseGroup, normalGroup} = await import('@pixi/lights'));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
const TileLayerInternal = PixiComponent('TileLayer', {
|
const TileLayerInternal = PixiComponent('TileLayer', {
|
||||||
create: ({group, stage, tileLayer}) => {
|
create: ({group, tileLayer}) => {
|
||||||
const container = new Container();
|
const container = new Container();
|
||||||
const cy = Math.ceil(tileLayer.area.y / CHUNK_SIZE);
|
const cy = Math.ceil(tileLayer.area.y / CHUNK_SIZE);
|
||||||
const cx = Math.ceil(tileLayer.area.x / CHUNK_SIZE);
|
const cx = Math.ceil(tileLayer.area.x / CHUNK_SIZE);
|
||||||
|
@ -85,7 +81,7 @@ const TileLayerInternal = PixiComponent('TileLayer', {
|
||||||
});
|
});
|
||||||
|
|
||||||
export default function TileLayer(props) {
|
export default function TileLayer(props) {
|
||||||
const {renderer, stage} = useApp();
|
const {renderer} = useApp();
|
||||||
const {tileLayer} = props;
|
const {tileLayer} = props;
|
||||||
const asset = useAsset(tileLayer.source);
|
const asset = useAsset(tileLayer.source);
|
||||||
const normalsAsset = useAsset([tileLayer.source.slice(0, -'.json'.length), 'normals.json'].join('.'));
|
const normalsAsset = useAsset([tileLayer.source.slice(0, -'.json'.length), 'normals.json'].join('.'));
|
||||||
|
@ -99,14 +95,12 @@ export default function TileLayer(props) {
|
||||||
asset={asset}
|
asset={asset}
|
||||||
group={diffuseGroup}
|
group={diffuseGroup}
|
||||||
renderer={renderer}
|
renderer={renderer}
|
||||||
stage={stage}
|
|
||||||
/>
|
/>
|
||||||
<TileLayerInternal
|
<TileLayerInternal
|
||||||
{...props}
|
{...props}
|
||||||
asset={normalsAsset}
|
asset={normalsAsset}
|
||||||
group={normalGroup}
|
group={normalGroup}
|
||||||
renderer={renderer}
|
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