Compare commits
4 commits
next
...
threejs-sh
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
60a39bbaf5 | ||
|
|
d4cc305baa | ||
|
|
777b2c41e7 | ||
|
|
ad8c57de82 |
2 changed files with 151 additions and 13 deletions
94
renderer/viewer/three/shadersThree.ts
Normal file
94
renderer/viewer/three/shadersThree.ts
Normal file
|
|
@ -0,0 +1,94 @@
|
||||||
|
import { ShaderChunk } from 'three'
|
||||||
|
|
||||||
|
// Original simple shader for non-animated blocks
|
||||||
|
export const BLOCK_VERTEX_SHADER = `
|
||||||
|
#include <common>
|
||||||
|
${ShaderChunk.logdepthbuf_pars_vertex}
|
||||||
|
|
||||||
|
attribute vec3 color;
|
||||||
|
|
||||||
|
varying vec2 vUv;
|
||||||
|
varying vec3 vColor;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vUv = uv;
|
||||||
|
vColor = color;
|
||||||
|
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
||||||
|
|
||||||
|
${ShaderChunk.logdepthbuf_vertex}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export const BLOCK_FRAGMENT_SHADER = `
|
||||||
|
#include <common>
|
||||||
|
${ShaderChunk.logdepthbuf_pars_fragment}
|
||||||
|
|
||||||
|
uniform sampler2D map;
|
||||||
|
varying vec2 vUv;
|
||||||
|
varying vec3 vColor;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vec4 texColor = texture2D(map, vUv);
|
||||||
|
if (texColor.a < 0.1) discard;
|
||||||
|
gl_FragColor = vec4(vColor * texColor.rgb, texColor.a);
|
||||||
|
|
||||||
|
${ShaderChunk.logdepthbuf_fragment}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
// New shader for animated blocks
|
||||||
|
export const ANIMATED_BLOCK_VERTEX_SHADER = `
|
||||||
|
#include <common>
|
||||||
|
${ShaderChunk.logdepthbuf_pars_vertex}
|
||||||
|
|
||||||
|
uniform float animationFrameHeight;
|
||||||
|
uniform float animationFrameIndex;
|
||||||
|
uniform float animationInterpolationFrameIndex;
|
||||||
|
uniform float animationInterpolation;
|
||||||
|
|
||||||
|
attribute vec3 color;
|
||||||
|
varying vec2 vUv;
|
||||||
|
varying vec3 vColor;
|
||||||
|
varying float vAnimationInterpolation;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
vUv = uv;
|
||||||
|
vColor = color;
|
||||||
|
vAnimationInterpolation = animationInterpolation;
|
||||||
|
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
|
||||||
|
|
||||||
|
${ShaderChunk.logdepthbuf_vertex}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
||||||
|
export const ANIMATED_BLOCK_FRAGMENT_SHADER = `
|
||||||
|
#include <common>
|
||||||
|
${ShaderChunk.logdepthbuf_pars_fragment}
|
||||||
|
|
||||||
|
uniform sampler2D map;
|
||||||
|
uniform float animationFrameHeight;
|
||||||
|
uniform float animationFrameIndex;
|
||||||
|
uniform float animationInterpolationFrameIndex;
|
||||||
|
|
||||||
|
varying vec2 vUv;
|
||||||
|
varying vec3 vColor;
|
||||||
|
varying float vAnimationInterpolation;
|
||||||
|
|
||||||
|
void main() {
|
||||||
|
// Calculate UV coordinates for current frame
|
||||||
|
vec2 currentFrameUv = vec2(vUv.x, animationFrameHeight * (vUv.y + animationFrameIndex));
|
||||||
|
vec4 currentFrame = texture2D(map, currentFrameUv);
|
||||||
|
|
||||||
|
// If interpolation is enabled, calculate UV for next frame and mix
|
||||||
|
if (vAnimationInterpolation > 0.0) {
|
||||||
|
vec2 nextFrameUv = vec2(vUv.x, animationFrameHeight * (vUv.y + animationInterpolationFrameIndex));
|
||||||
|
vec4 nextFrame = texture2D(map, nextFrameUv);
|
||||||
|
currentFrame = mix(currentFrame, nextFrame, vAnimationInterpolation);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (currentFrame.a < 0.1) discard;
|
||||||
|
gl_FragColor = vec4(vColor * currentFrame.rgb, currentFrame.a);
|
||||||
|
|
||||||
|
${ShaderChunk.logdepthbuf_fragment}
|
||||||
|
}
|
||||||
|
`
|
||||||
|
|
@ -25,10 +25,49 @@ import { Entities } from './entities'
|
||||||
import { ThreeJsSound } from './threeJsSound'
|
import { ThreeJsSound } from './threeJsSound'
|
||||||
import { CameraShake } from './cameraShake'
|
import { CameraShake } from './cameraShake'
|
||||||
import { ThreeJsMedia } from './threeJsMedia'
|
import { ThreeJsMedia } from './threeJsMedia'
|
||||||
|
import { BLOCK_VERTEX_SHADER, BLOCK_FRAGMENT_SHADER, ANIMATED_BLOCK_VERTEX_SHADER, ANIMATED_BLOCK_FRAGMENT_SHADER } from './shadersThree'
|
||||||
import { Fountain } from './threeJsParticles'
|
import { Fountain } from './threeJsParticles'
|
||||||
|
|
||||||
type SectionKey = string
|
type SectionKey = string
|
||||||
|
|
||||||
|
class CustomBlockMaterial extends THREE.ShaderMaterial {
|
||||||
|
constructor () {
|
||||||
|
super({
|
||||||
|
uniforms: {
|
||||||
|
map: { value: null }
|
||||||
|
},
|
||||||
|
vertexShader: BLOCK_VERTEX_SHADER,
|
||||||
|
fragmentShader: BLOCK_FRAGMENT_SHADER,
|
||||||
|
transparent: true,
|
||||||
|
alphaTest: 0.1,
|
||||||
|
depthWrite: true,
|
||||||
|
depthTest: true,
|
||||||
|
side: THREE.FrontSide
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class AnimatedBlockMaterial extends THREE.ShaderMaterial {
|
||||||
|
constructor () {
|
||||||
|
super({
|
||||||
|
uniforms: {
|
||||||
|
map: { value: null },
|
||||||
|
animationFrameHeight: { value: 1 },
|
||||||
|
animationFrameIndex: { value: 0 },
|
||||||
|
animationInterpolationFrameIndex: { value: 0 },
|
||||||
|
animationInterpolation: { value: 0 }
|
||||||
|
},
|
||||||
|
vertexShader: ANIMATED_BLOCK_VERTEX_SHADER,
|
||||||
|
fragmentShader: ANIMATED_BLOCK_FRAGMENT_SHADER,
|
||||||
|
transparent: true,
|
||||||
|
alphaTest: 0.1,
|
||||||
|
depthWrite: true,
|
||||||
|
depthTest: true,
|
||||||
|
side: THREE.FrontSide
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export class WorldRendererThree extends WorldRendererCommon {
|
export class WorldRendererThree extends WorldRendererCommon {
|
||||||
outputFormat = 'threeJs' as const
|
outputFormat = 'threeJs' as const
|
||||||
sectionObjects: Record<string, THREE.Object3D & { foutain?: boolean }> = {}
|
sectionObjects: Record<string, THREE.Object3D & { foutain?: boolean }> = {}
|
||||||
|
|
@ -36,14 +75,15 @@ export class WorldRendererThree extends WorldRendererCommon {
|
||||||
signsCache = new Map<string, any>()
|
signsCache = new Map<string, any>()
|
||||||
starField: StarField
|
starField: StarField
|
||||||
cameraSectionPos: Vec3 = new Vec3(0, 0, 0)
|
cameraSectionPos: Vec3 = new Vec3(0, 0, 0)
|
||||||
holdingBlock: HoldingBlock
|
holdingBlock: HoldingBlock | undefined
|
||||||
holdingBlockLeft: HoldingBlock
|
holdingBlockLeft: HoldingBlock | undefined
|
||||||
scene = new THREE.Scene()
|
scene = new THREE.Scene()
|
||||||
ambientLight = new THREE.AmbientLight(0xcc_cc_cc)
|
ambientLight = new THREE.AmbientLight(0xcc_cc_cc)
|
||||||
directionalLight = new THREE.DirectionalLight(0xff_ff_ff, 0.5)
|
directionalLight = new THREE.DirectionalLight(0xff_ff_ff, 0.5)
|
||||||
entities = new Entities(this)
|
entities = new Entities(this)
|
||||||
cameraObjectOverride?: THREE.Object3D // for xr
|
cameraObjectOverride?: THREE.Object3D // for xr
|
||||||
material = new THREE.MeshLambertMaterial({ vertexColors: true, transparent: true, alphaTest: 0.1 })
|
material = new CustomBlockMaterial()
|
||||||
|
animatedMaterial = new AnimatedBlockMaterial()
|
||||||
itemsTexture: THREE.Texture
|
itemsTexture: THREE.Texture
|
||||||
cursorBlock = new CursorBlock(this)
|
cursorBlock = new CursorBlock(this)
|
||||||
onRender: Array<() => void> = []
|
onRender: Array<() => void> = []
|
||||||
|
|
@ -168,23 +208,23 @@ export class WorldRendererThree extends WorldRendererCommon {
|
||||||
changeHandSwingingState (isAnimationPlaying: boolean, isLeft = false) {
|
changeHandSwingingState (isAnimationPlaying: boolean, isLeft = false) {
|
||||||
const holdingBlock = isLeft ? this.holdingBlockLeft : this.holdingBlock
|
const holdingBlock = isLeft ? this.holdingBlockLeft : this.holdingBlock
|
||||||
if (isAnimationPlaying) {
|
if (isAnimationPlaying) {
|
||||||
holdingBlock.startSwing()
|
holdingBlock?.startSwing()
|
||||||
} else {
|
} else {
|
||||||
holdingBlock.stopSwing()
|
holdingBlock?.stopSwing()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
async updateAssetsData (): Promise<void> {
|
async updateAssetsData (): Promise<void> {
|
||||||
const resources = this.resourcesManager.currentResources!
|
const resources = this.resourcesManager.currentResources!
|
||||||
|
|
||||||
const oldTexture = this.material.map
|
const oldTexture = this.material.uniforms.map.value
|
||||||
const oldItemsTexture = this.itemsTexture
|
const oldItemsTexture = this.itemsTexture
|
||||||
|
|
||||||
const texture = await new THREE.TextureLoader().loadAsync(resources.blocksAtlasParser.latestImage)
|
const texture = await new THREE.TextureLoader().loadAsync(resources.blocksAtlasParser.latestImage)
|
||||||
texture.magFilter = THREE.NearestFilter
|
texture.magFilter = THREE.NearestFilter
|
||||||
texture.minFilter = THREE.NearestFilter
|
texture.minFilter = THREE.NearestFilter
|
||||||
texture.flipY = false
|
texture.flipY = false
|
||||||
this.material.map = texture
|
this.material.uniforms.map.value = texture
|
||||||
|
|
||||||
const itemsTexture = await new THREE.TextureLoader().loadAsync(resources.itemsAtlasParser.latestImage)
|
const itemsTexture = await new THREE.TextureLoader().loadAsync(resources.itemsAtlasParser.latestImage)
|
||||||
itemsTexture.magFilter = THREE.NearestFilter
|
itemsTexture.magFilter = THREE.NearestFilter
|
||||||
|
|
@ -208,10 +248,14 @@ export class WorldRendererThree extends WorldRendererCommon {
|
||||||
}
|
}
|
||||||
|
|
||||||
onAllTexturesLoaded () {
|
onAllTexturesLoaded () {
|
||||||
this.holdingBlock.ready = true
|
if (this.holdingBlock) {
|
||||||
this.holdingBlock.updateItem()
|
this.holdingBlock.ready = true
|
||||||
this.holdingBlockLeft.ready = true
|
this.holdingBlock.updateItem()
|
||||||
this.holdingBlockLeft.updateItem()
|
}
|
||||||
|
if (this.holdingBlockLeft) {
|
||||||
|
this.holdingBlockLeft.ready = true
|
||||||
|
this.holdingBlockLeft.updateItem()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
changeBackgroundColor (color: [number, number, number]): void {
|
changeBackgroundColor (color: [number, number, number]): void {
|
||||||
|
|
@ -464,8 +508,8 @@ export class WorldRendererThree extends WorldRendererCommon {
|
||||||
this.renderer.render(this.scene, cam)
|
this.renderer.render(this.scene, cam)
|
||||||
|
|
||||||
if (this.displayOptions.inWorldRenderingConfig.showHand/* && !this.freeFlyMode */) {
|
if (this.displayOptions.inWorldRenderingConfig.showHand/* && !this.freeFlyMode */) {
|
||||||
this.holdingBlock.render(this.camera, this.renderer, this.ambientLight, this.directionalLight)
|
this.holdingBlock?.render(this.camera, this.renderer, this.ambientLight, this.directionalLight)
|
||||||
this.holdingBlockLeft.render(this.camera, this.renderer, this.ambientLight, this.directionalLight)
|
this.holdingBlockLeft?.render(this.camera, this.renderer, this.ambientLight, this.directionalLight)
|
||||||
}
|
}
|
||||||
|
|
||||||
for (const fountain of this.fountains) {
|
for (const fountain of this.fountains) {
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue