bx-1140-postprocessing #12
|
@ -1,49 +1,56 @@
|
|||
<script setup lang="ts">
|
||||
import { onMounted, watch } from 'vue';
|
||||
|
||||
import { ACESFilmicToneMapping, Color, EquirectangularReflectionMapping, PMREMGenerator, ReinhardToneMapping, SRGBColorSpace } from 'three';
|
||||
import { ACESFilmicToneMapping, Color, Fog, PMREMGenerator, SRGBColorSpace } from 'three';
|
||||
import { GainMapLoader } from '@monogrid/gainmap-js'
|
||||
import { useTresContext } from '@tresjs/core';
|
||||
|
||||
import hdr_gainmap from '../../assets/promo/hdr/hdr-gainmap.webp'
|
||||
import hdr_json from '../../assets/promo/hdr/hdr.json?url'
|
||||
import hdr_webp from '../../assets/promo/hdr/hdr.webp'
|
||||
import { IMAGE_URL } from '../../constants';
|
||||
|
||||
const props = defineProps(['hdr_webp', 'hdr_gainmap', 'hdr_json'])
|
||||
|
||||
const props = defineProps(['hdr_webp', 'hdr_gainmap', 'hdr_json', 'env_displacementmap', 'env_normalmap', 'clear_color', 'focus'])
|
||||
const { renderer, scene } = useTresContext()
|
||||
// renderer.value.toneMapping = ReinhardToneMapping
|
||||
|
||||
const k = { start: 0.5, end: 2.5 }
|
||||
|
||||
renderer.value.outputColorSpace = SRGBColorSpace;
|
||||
renderer.value.toneMapping = ACESFilmicToneMapping;
|
||||
renderer.value.toneMappingExposure = 1.25;
|
||||
renderer.value.setPixelRatio(1.5)
|
||||
|
||||
const loadEnv = async () => {
|
||||
if (props.hdr_webp || props.hdr_gainmap || props.hdr_json) {
|
||||
const loader = new GainMapLoader(renderer.value)
|
||||
const result = await loader.loadAsync([
|
||||
props.hdr_webp || hdr_webp,
|
||||
props.hdr_gainmap || hdr_gainmap,
|
||||
props.hdr_json || hdr_json,
|
||||
props.hdr_webp ? `${IMAGE_URL}/${props.hdr_webp}` : hdr_webp,
|
||||
props.hdr_gainmap ? `${IMAGE_URL}/${props.hdr_gainmap}` : hdr_gainmap,
|
||||
props.hdr_json ? `${IMAGE_URL}/${props.hdr_json}` : hdr_json,
|
||||
])
|
||||
const pmremGenerator = new PMREMGenerator(renderer.value);
|
||||
pmremGenerator.compileEquirectangularShader();
|
||||
|
||||
const exrCubeRenderTarget = pmremGenerator.fromEquirectangular(result.renderTarget.texture);
|
||||
// const exrBackground = exrCubeRenderTarget.texture;
|
||||
const newEnvMap = exrCubeRenderTarget ? exrCubeRenderTarget.texture : null;
|
||||
|
||||
scene.value.environment = newEnvMap
|
||||
scene.value.environmentIntensity = 2.5
|
||||
|
||||
// scene.value.background = result.renderTarget.texture
|
||||
// scene.value.background.mapping = EquirectangularReflectionMapping
|
||||
// scene.value.backgroundBlurriness = 0.15
|
||||
result.renderTarget.texture.dispose();
|
||||
}
|
||||
|
||||
if (props.clear_color) {
|
||||
renderer.value.setClearColor(props.clear_color)
|
||||
}
|
||||
const c = new Color()
|
||||
renderer.value.getClearColor(c)
|
||||
scene.value.fog = new Fog(c, props.focus * k.start, props.focus * k.end)
|
||||
}
|
||||
|
||||
onMounted(async () => {
|
||||
loadEnv()
|
||||
})
|
||||
watch(() => props.hdr_webp, loadEnv)
|
||||
watch(() => props, loadEnv, { deep: true })
|
||||
</script>
|
||||
<template></template>
|
|
@ -3,6 +3,7 @@ import { onMounted, onUnmounted, reactive, ref, watch } from 'vue';
|
|||
import {
|
||||
Box3, CircleGeometry, Color, DoubleSide, Group, Mesh, MeshBasicMaterial,
|
||||
MeshStandardMaterial,
|
||||
MeshStandardMaterialParameters,
|
||||
PlaneGeometry, SpriteMaterial, TextureLoader, Vector2, Vector3,
|
||||
} from 'three';
|
||||
|
||||
|
@ -10,7 +11,6 @@ import { useTresContext, useSeek, useRenderLoop, useTexture } from '@tresjs/core
|
|||
import { useGLTF } from '@tresjs/cientos'
|
||||
|
||||
import Env from './env.vue'
|
||||
import PostProcess from './post_pocessing.vue'
|
||||
|
||||
import { IMAGE_URL, SERVER_URL, } from '../../constants'
|
||||
import { usePromoSidebar } from '../../stores/promo_sidebar';
|
||||
|
@ -26,7 +26,15 @@ const sidebar = usePromoSidebar();
|
|||
const sidebar_scene = usePromoScene()
|
||||
const { controls, camera, scene, raycaster, renderer } = useTresContext()
|
||||
const { seekByName, seekAllByName } = useSeek()
|
||||
const envVars = reactive({}) as { hdr_gainmap?: string, hdr_json?: string, hdr_webp?: string }
|
||||
const envVars = reactive({}) as {
|
||||
focus: number,
|
||||
hdr_gainmap?: string,
|
||||
hdr_json?: string,
|
||||
hdr_webp?: string,
|
||||
clear_color?: string,
|
||||
env_displacementmap?: string,
|
||||
env_normalmap?: string
|
||||
}
|
||||
const tiltShift = reactive({}) as { focus: number, aperture: number, maxblur: number }
|
||||
|
||||
|
||||
|
@ -42,18 +50,11 @@ const loadModels = async () => {
|
|||
const res = await fetch(`${SERVER_URL}/api/obj/scene/${props.source}`)
|
||||
const raw_data = await res.json() as scene3D
|
||||
|
||||
envVars.hdr_gainmap = raw_data.hdr_gainmap ? `${IMAGE_URL}/${raw_data.hdr_gainmap}` : undefined
|
||||
envVars.hdr_json = raw_data.hdr_json ? `${IMAGE_URL}/${raw_data.hdr_json}` : undefined
|
||||
envVars.hdr_webp = raw_data.hdr_webp ? `${IMAGE_URL}/${raw_data.hdr_webp}` : undefined
|
||||
envVars.focus = raw_data.min_distance * 1
|
||||
if (raw_data.env) {
|
||||
Object.assign(envVars, raw_data.env)
|
||||
}
|
||||
|
||||
tiltShift.focus = raw_data.min_distance * 1
|
||||
tiltShift.aperture = 0.1
|
||||
tiltShift.maxblur = 5
|
||||
|
||||
const c = new Color()
|
||||
renderer.value.getClearColor(c)
|
||||
// console.log(c, c.offsetHSL(0, 0, 10))
|
||||
// renderer.value.setClearColor(c.offsetHSL(10, 10, 10))
|
||||
|
||||
const data = raw_data.elements
|
||||
if (!controls.value) return;
|
||||
|
@ -87,17 +88,41 @@ const loadModels = async () => {
|
|||
const clickable_areas = await res.json()
|
||||
clickable.value.push(...clickable_areas)
|
||||
}
|
||||
const ground = new Mesh(
|
||||
new CircleGeometry(tiltShift.focus * 10, tiltShift.focus * 10),
|
||||
new MeshStandardMaterial({
|
||||
|
||||
|
||||
let c = new Color()
|
||||
if (envVars.clear_color) {
|
||||
c = new Color(envVars.clear_color)
|
||||
} else {
|
||||
renderer.value.getClearColor(c)
|
||||
}
|
||||
const tex = {} as any
|
||||
if (envVars.env_displacementmap) { tex.displacementMap = `${IMAGE_URL}/${envVars.env_displacementmap}` }
|
||||
if (envVars.env_normalmap) { tex.normalMap = `${IMAGE_URL}/${envVars.env_normalmap}` }
|
||||
let addTexture: any
|
||||
if (Object.keys(tex).length) {
|
||||
addTexture = await useTexture(tex)
|
||||
}
|
||||
|
||||
const mesh = {
|
||||
color: c.offsetHSL(0, 0, -0.5),
|
||||
displacementMap: groundTexture.displacementMap,
|
||||
displacementScale: tiltShift.focus,
|
||||
displacementScale: envVars.focus,
|
||||
roughness: 100,
|
||||
side: DoubleSide
|
||||
})
|
||||
} as MeshStandardMaterialParameters
|
||||
if (addTexture.displacementMap) {
|
||||
mesh.displacementMap = addTexture.displacementMap
|
||||
} else {
|
||||
mesh.displacementMap = groundTexture.displacementMap
|
||||
}
|
||||
if (addTexture.normalMap) {
|
||||
mesh.normalMap = addTexture.normalMap
|
||||
}
|
||||
const ground = new Mesh(
|
||||
new CircleGeometry(envVars.focus * 10, envVars.focus * 10),
|
||||
new MeshStandardMaterial(mesh)
|
||||
)
|
||||
ground.position.y = -0.33 * tiltShift.focus
|
||||
ground.position.y = -0.33 * envVars.focus
|
||||
ground.rotateX(-Math.PI / 2)
|
||||
ground.name = "ground"
|
||||
models.value.push({ name: 'ground', modelFile: ground })
|
||||
|
@ -226,7 +251,6 @@ watch(() => sidebar_scene.list, () => {
|
|||
<template>
|
||||
<TresGroup name="loaded">
|
||||
<Env v-bind="envVars" />
|
||||
<PostProcess :tiltShift="tiltShift" />
|
||||
<template v-for="item in models">
|
||||
<TresGroup :name="item.name">
|
||||
<TresObject3D v-bind="item.modelFile.clone()" />
|
||||
|
|
|
@ -14,10 +14,15 @@ interface scene3D {
|
|||
name: string
|
||||
min_distance: number
|
||||
max_distance: number
|
||||
elements: element3DType[]
|
||||
env: {
|
||||
hdr_gainmap?: string
|
||||
hdr_json?: string
|
||||
hdr_webp?: string
|
||||
elements: element3DType[]
|
||||
env_displacementmap?: string
|
||||
env_normalmap?: string
|
||||
clear_color?: string
|
||||
}
|
||||
}
|
||||
interface element3DType {
|
||||
id: number
|
||||
|
|
Loading…
Reference in New Issue