no message

This commit is contained in:
hawk86104 2024-04-15 09:56:39 +08:00
parent 77f7476846
commit ea5997388e
13 changed files with 718 additions and 48 deletions

View File

@ -1,13 +1,5 @@
/*
* @Description:
* @Version: 1.668
* @Autor: 地虎降天龙
* @Date: 2023-10-16 10:53:09
* @LastEditors: 地虎降天龙
* @LastEditTime: 2024-04-10 15:01:11
*/
module.exports = {
parser: 'babel-eslint',
// parser: 'babel-eslint',
extends: ['@webank/eslint-config-webank/vue.js'],
overrides: [
{

View File

@ -55,6 +55,7 @@
"gsap": "3.12.5",
"heatmap.js-fix": "^1.0.0",
"lamina": "^1.1.23",
"lygia": "^1.1.3",
"oimophysics": "^1.2.2",
"patch-package": "^8.0.0",
"pinia": "^2.1.7",

View File

@ -0,0 +1,220 @@
import { UniformsUtils, Vector2 } from 'three';
import { sampleFunctions } from './mipSampleFunctions.js';
export function clone(shader: any) {
const newShader = { ...shader };
if ('defines' in shader) {
newShader.defines = { ...shader.defines };
}
if ('uniforms' in shader) {
newShader.uniforms = UniformsUtils.clone(shader.uniforms);
}
return newShader;
}
// Non Power of Two mip map generation
// https://www.nvidia.com/en-us/drivers/np2-mipmapping/
export const MipGenerationShader = {
defines: {
X_IS_EVEN: 1,
Y_IS_EVEN: 1,
},
uniforms: {
map: { value: null },
originalMapSize: { value: new Vector2() },
parentMapSize: { value: new Vector2() },
parentLevel: { value: 0 },
},
vertexShader: /* glsl */`
varying vec2 vUv;
void main() {
#include <begin_vertex>
#include <project_vertex>
vUv = uv;
}
`,
fragmentShader: /* glsl */`
varying vec2 vUv;
uniform sampler2D map;
uniform int parentLevel;
uniform vec2 parentMapSize;
uniform vec2 originalMapSize;
${sampleFunctions}
#if X_IS_EVEN && Y_IS_EVEN
#define SAMPLES 4
#define WIDTH 2
#define HEIGHT 2
#elif X_IS_EVEN
#define SAMPLES 6
#define WIDTH 2
#define HEIGHT 3
#elif Y_IS_EVEN
#define SAMPLES 6
#define WIDTH 3
#define HEIGHT 2
#else
#define SAMPLES 9
#define WIDTH 3
#define HEIGHT 3
#endif
vec4 sampleAt( vec2 uv ) {
return packedTexture2DLOD( map, uv, parentLevel, originalMapSize );
}
void main() {
vec2 childMapSize = parentMapSize / 2.0;
// vec2 childPixelSize = 1.0 / childMapSize;
// vec2 halfChildPixelSize = childPixelSize / 2.0;
vec2 childPixelPos = floor( vUv * childMapSize );
vec2 parentPixelSize = 1.0 / parentMapSize;
vec2 halfParentPixelSize = parentPixelSize / 2.0;
vec2 parentPixelPos = childPixelPos * 2.0;
vec2 baseUv = ( parentPixelPos / parentMapSize ) + halfParentPixelSize;
vec4 samples[ SAMPLES ];
float weights[ SAMPLES ];
#if X_IS_EVEN && Y_IS_EVEN
samples[ 0 ] = sampleAt( baseUv );
samples[ 1 ] = sampleAt( baseUv + vec2( parentPixelSize.x, 0.0 ) );
samples[ 2 ] = sampleAt( baseUv + vec2( 0.0, parentPixelSize.y ) );
samples[ 3 ] = sampleAt( baseUv + vec2( parentPixelSize.x, parentPixelSize.y ) );
weights[ 0 ] = 0.25;
weights[ 1 ] = 0.25;
weights[ 2 ] = 0.25;
weights[ 3 ] = 0.25;
#elif X_IS_EVEN
float wx0 = 0.5;
float wx1 = 0.5;
float yden = 2.0 * parentMapSize.y + 1.0;
float wy0 = ( parentMapSize.y - parentPixelPos.y ) / yden;
float wy1 = ( parentMapSize.y ) / yden;
float wy2 = ( parentPixelPos.y + 1.0 ) / yden;
samples[ 0 ] = sampleAt( baseUv );
samples[ 1 ] = sampleAt( baseUv + vec2( parentPixelSize.x, 0.0 ) );
samples[ 2 ] = sampleAt( baseUv + vec2( 0.0, parentPixelSize.y ) );
samples[ 3 ] = sampleAt( baseUv + vec2( parentPixelSize.x, parentPixelSize.y ) );
samples[ 4 ] = sampleAt( baseUv + vec2( 0.0, 2.0 * parentPixelSize.y ) );
samples[ 5 ] = sampleAt( baseUv + vec2( parentPixelSize.x, 2.0 * parentPixelSize.y ) );
weights[ 0 ] = wx0 * wy0;
weights[ 1 ] = wx1 * wy0;
weights[ 2 ] = wx0 * wy1;
weights[ 3 ] = wx1 * wy1;
weights[ 4 ] = wx0 * wy2;
weights[ 5 ] = wx1 * wy2;
#elif Y_IS_EVEN
float xden = 2.0 * parentMapSize.x + 1.0;
float wx0 = ( parentMapSize.x - parentPixelPos.x ) / xden;
float wx1 = ( parentMapSize.x ) / xden;
float wx2 = ( parentPixelPos.x + 1.0 ) / xden;
float wy0 = 0.5;
float wy1 = 0.5;
samples[ 0 ] = sampleAt( baseUv );
samples[ 1 ] = sampleAt( baseUv + vec2( parentPixelSize.x, 0.0 ) );
samples[ 2 ] = sampleAt( baseUv + vec2( 2.0 * parentPixelSize.x, 0.0 ) );
samples[ 3 ] = sampleAt( baseUv + vec2( 0.0, parentPixelSize.y ) );
samples[ 4 ] = sampleAt( baseUv + vec2( parentPixelSize.x, parentPixelSize.y ) );
samples[ 5 ] = sampleAt( baseUv + vec2( 2.0 * parentPixelSize.x, parentPixelSize.y ) );
weights[ 0 ] = wx0 * wy0;
weights[ 1 ] = wx1 * wy0;
weights[ 2 ] = wx2 * wy0;
weights[ 3 ] = wx0 * wy1;
weights[ 4 ] = wx1 * wy1;
weights[ 5 ] = wx2 * wy1;
#else
float xden = 2.0 * parentMapSize.x + 1.0;
float wx0 = ( parentMapSize.x - parentPixelPos.x ) / xden;
float wx1 = ( parentMapSize.x ) / xden;
float wx2 = ( parentPixelPos.x + 1.0 ) / xden;
float yden = 2.0 * parentMapSize.y + 1.0;
float wy0 = ( parentMapSize.y - parentPixelPos.y ) / yden;
float wy1 = ( parentMapSize.y ) / yden;
float wy2 = ( parentPixelPos.y + 1.0 ) / yden;
samples[ 0 ] = sampleAt( baseUv );
samples[ 1 ] = sampleAt( baseUv + vec2( parentPixelSize.x, 0.0 ) );
samples[ 2 ] = sampleAt( baseUv + vec2( 2.0 * parentPixelSize.x, 0.0 ) );
samples[ 3 ] = sampleAt( baseUv + vec2( 0.0, parentPixelSize.y ) );
samples[ 4 ] = sampleAt( baseUv + vec2( parentPixelSize.x, parentPixelSize.y ) );
samples[ 5 ] = sampleAt( baseUv + vec2( 2.0 * parentPixelSize.x, parentPixelSize.y ) );
samples[ 6 ] = sampleAt( baseUv + vec2( 0.0, 2.0 * parentPixelSize.y ) );
samples[ 7 ] = sampleAt( baseUv + vec2( parentPixelSize.x, 2.0 * parentPixelSize.y ) );
samples[ 8 ] = sampleAt( baseUv + vec2( 2.0 * parentPixelSize.x, 2.0 * parentPixelSize.y ) );
weights[ 0 ] = wx0 * wy0;
weights[ 1 ] = wx1 * wy0;
weights[ 2 ] = wx2 * wy0;
weights[ 3 ] = wx0 * wy1;
weights[ 4 ] = wx1 * wy1;
weights[ 5 ] = wx2 * wy1;
weights[ 6 ] = wx0 * wy2;
weights[ 7 ] = wx1 * wy2;
weights[ 8 ] = wx2 * wy2;
#endif
<mipmap_logic>
}
`
};

View File

@ -0,0 +1,198 @@
import { FullScreenQuad } from 'three-stdlib'
import { Color, ShaderMaterial, MathUtils, WebGLRenderTarget, NearestFilter, Material, WebGLRenderer, Texture } from 'three'
import { CopyShader } from 'three-stdlib';
import { clone, MipGenerationShader } from './MipGenerationShader.js';
const _originalClearColor = new Color();
export class PackedMipMapGenerator {
_swapTarget: WebGLRenderTarget;
_copyQuad: FullScreenQuad<ShaderMaterial>;
_mipQuad: FullScreenQuad<Material>;
_mipMaterials: any[];
constructor(mipmapLogic?: string) {
if (!mipmapLogic) {
mipmapLogic = /* glsl */`
#pragma unroll_loop
for ( int i = 0; i < SAMPLES; i ++ ) {
gl_FragColor += samples[ i ] * weights[ i ];
}
`;
}
const shader = clone(MipGenerationShader);
shader.fragmentShader = shader.fragmentShader.replace(/<mipmap_logic>/g, mipmapLogic);
// Save the mip materials such that mip 0 indicates whether or not X is power
// of two and 1 indicates the same for y to prevent material recompilation.
const mipMaterials = new Array(4);
mipMaterials[0] = new ShaderMaterial(clone(shader));
mipMaterials[0].defines.X_IS_EVEN = 0;
mipMaterials[0].defines.Y_IS_EVEN = 0;
mipMaterials[1] = new ShaderMaterial(clone(shader));
mipMaterials[1].defines.X_IS_EVEN = 1;
mipMaterials[1].defines.Y_IS_EVEN = 0;
mipMaterials[2] = new ShaderMaterial(clone(shader));
mipMaterials[2].defines.X_IS_EVEN = 0;
mipMaterials[2].defines.Y_IS_EVEN = 1;
mipMaterials[3] = new ShaderMaterial(clone(shader));
mipMaterials[3].defines.X_IS_EVEN = 1;
mipMaterials[3].defines.Y_IS_EVEN = 1;
const swapTarget = new WebGLRenderTarget();
swapTarget.texture.minFilter = NearestFilter;
swapTarget.texture.magFilter = NearestFilter;
this._swapTarget = swapTarget;
this._copyQuad = new FullScreenQuad(new ShaderMaterial(CopyShader));
// @ts-ignore
this._mipQuad = new FullScreenQuad(null);
this._mipMaterials = mipMaterials;
}
update(texture: Texture, target: WebGLRenderTarget, renderer: WebGLRenderer, forcePowerOfTwo = false) {
// @ts-ignore
if (texture.isWebGLRenderTarget) {
// @ts-ignore
texture = texture.texture;
}
const originalAutoClear = renderer.autoClear;
const originalClearAlpha = renderer.getClearAlpha();
const originalRenderTarget = renderer.getRenderTarget();
renderer.getClearColor(_originalClearColor);
const copyQuad = this._copyQuad;
const mipQuad = this._mipQuad;
const swapTarget = this._swapTarget;
const mipMaterials = this._mipMaterials;
// TODO: add option for ceil power of two and option to not power of two at all? This
// causes the mip texels to not align, though...
let width, height;
if (forcePowerOfTwo) {
width = MathUtils.floorPowerOfTwo(texture.image.width);
height = MathUtils.floorPowerOfTwo(texture.image.height);
} else {
width = Math.floor(texture.image.width);
height = Math.floor(texture.image.height);
}
const targetWidth = Math.floor(width * 1.5);
const targetHeight = Math.floor(height);
// init the targets
target.setSize(targetWidth, targetHeight);
if (swapTarget.texture.type !== target.texture.type) {
swapTarget.dispose();
swapTarget.copy(target);
// mrdoob/three.js issue #20328
swapTarget.texture.image = { ...swapTarget.texture.image };
} else {
swapTarget.setSize(targetWidth, targetHeight);
}
// init the renderer
renderer.autoClear = false;
renderer.setClearColor(0);
// @ts-ignore
renderer.setClearAlpha();
// write the first texture to the texture
copyQuad.material.uniforms.tDiffuse.value = texture;
copyQuad.camera.setViewOffset(width, height, 0, 0, targetWidth, targetHeight);
renderer.setRenderTarget(target);
renderer.clear();
copyQuad.render(renderer);
renderer.setRenderTarget(swapTarget);
renderer.clear();
copyQuad.render(renderer);
let currWidth = width;
let currHeight = height;
let mip = 0;
while (currWidth > 1 && currHeight > 1) {
const X_FLAG = 1 << 0;
const Y_FLAG = 1 << 1;
const index =
(currWidth % 2 === 0 ? X_FLAG : 0) |
(currHeight % 2 === 0 ? Y_FLAG : 0);
const material = mipMaterials[index];
material.uniforms.map.value = swapTarget.texture;
material.uniforms.parentLevel.value = mip;
material.uniforms.parentMapSize.value.set(currWidth, currHeight);
material.uniforms.originalMapSize.value.set(width, height);
mipQuad.material = material;
currWidth = Math.floor(currWidth / 2);
currHeight = Math.floor(currHeight / 2);
// Set the render view to currWidth x currHeight
// Y offset is from the top but uvs from the bottom
// Negate x, y offsets because the view offset function does the opposite
// targetHeight -- movest offset from top of screen to bottom
// 2 * currHeight -- 1 to leave space for other mips, 1 to draw current mip
const yOffset = targetHeight - 2 * currHeight;
renderer.setRenderTarget(target);
mipQuad.camera.setViewOffset(currWidth, currHeight, - width, - yOffset, targetWidth, targetHeight);
mipQuad.render(renderer);
// TODO: Is this the fastest way to do this? Can I just copy the subframe from the original texture to the next?
// Copy the subframe to the scratch target
renderer.setRenderTarget(swapTarget);
material.uniforms.map.value = target.texture;
mipQuad.render(renderer);
mip++;
}
renderer.setRenderTarget(originalRenderTarget);
renderer.setClearAlpha(originalClearAlpha);
renderer.setClearColor(_originalClearColor);
renderer.autoClear = originalAutoClear;
return mip + 1;
}
dispose() {
this._swapTarget.dispose();
this._mipQuad.dispose();
this._copyQuad.dispose();
this._mipMaterials.forEach(m => m.dispose());
}
}

View File

@ -0,0 +1,83 @@
export const sampleFunctions = /* glsl */`
// Without original size argument for power of two targets
vec4 packedTexture2DLOD( sampler2D tex, vec2 uv, int level ) {
// the fraction of the uv space used by the target mip
float targetSubview = 1.0 / pow( 2.0, float( level ) );
float widthRatio = 2.0 / 3.0;
vec2 scaledDimensions = vec2( targetSubview * widthRatio, targetSubview );
// all levels > 0 are on the right third of the texture
// y is offset from the bottom
vec2 offset = vec2(
level > 0 ? widthRatio : 0.0,
level > 0 ? targetSubview : 0.0
);
vec2 samplePoint = mix( offset, offset + scaledDimensions, uv );
return texture2D( tex, samplePoint );
}
vec4 packedTexture2DLOD( sampler2D tex, vec2 uv, float level ) {
float ratio = mod( level, 1.0 );
int minLevel = int( floor( level ) );
int maxLevel = int( ceil( level ) );
vec4 minValue = packedTexture2DLOD( tex, uv, minLevel );
vec4 maxValue = packedTexture2DLOD( tex, uv, maxLevel );
return mix( minValue, maxValue, ratio );
}
// With original size argument
vec4 packedTexture2DLOD( sampler2D tex, vec2 uv, int level, vec2 originalPixelSize ) {
float floatLevel = float( level );
vec2 atlasSize;
atlasSize.x = floor( originalPixelSize.x * 1.5 );
atlasSize.y = originalPixelSize.y;
// we stop making mip maps when one dimension == 1
float maxLevel = min( floor( log2( originalPixelSize.x ) ), floor( log2( originalPixelSize.y ) ) );
floatLevel = min( floatLevel, maxLevel );
// use inverse pow of 2 to simulate right bit shift operator
vec2 currentPixelDimensions = floor( originalPixelSize / pow( 2.0, floatLevel ) );
vec2 pixelOffset = vec2(
floatLevel > 0.0 ? originalPixelSize.x : 0.0,
floatLevel > 0.0 ? currentPixelDimensions.y : 0.0
);
// "minPixel / atlasSize" samples the top left piece of the first pixel
// "maxPixel / atlasSize" samples the bottom right piece of the last pixel
vec2 minPixel = pixelOffset;
vec2 maxPixel = pixelOffset + currentPixelDimensions;
vec2 samplePoint = mix( minPixel, maxPixel, uv );
samplePoint /= atlasSize;
vec2 halfPixelSize = 1.0 / ( 2.0 * atlasSize );
samplePoint = min( samplePoint, maxPixel / atlasSize - halfPixelSize );
samplePoint = max( samplePoint, minPixel / atlasSize + halfPixelSize );
return texture2D( tex, samplePoint );
}
vec4 packedTexture2DLOD( sampler2D tex, vec2 uv, float level, vec2 originalPixelSize ) {
float ratio = mod( level, 1.0 );
int minLevel = int( floor( level ) );
int maxLevel = int( ceil( level ) );
vec4 minValue = packedTexture2DLOD( tex, uv, minLevel, originalPixelSize );
vec4 maxValue = packedTexture2DLOD( tex, uv, maxLevel, originalPixelSize );
return mix( minValue, maxValue, ratio );
}
`;

View File

@ -0,0 +1,44 @@
/*
* @Description:
* @Version: 1.668
* @Autor:
* @Date: 2024-04-15 08:21:22
* @LastEditors:
* @LastEditTime: 2024-04-15 09:38:19
*/
import {useTexture} from '@tresjs/core'
import * as THREE from 'three'
import CustomShaderMaterial from 'three-custom-shader-material/vanilla'
import fragmentShader from '../shaders/reflectorCustomMaterial.frag'
import vertexShader from '../shaders/reflectorCustomMaterial.vert'
const makeCustomShaderMaterial = async (mirror: THREE.Mesh,reflector: any) => {
const floorUniforms = {
uColor: { type: "c", value: new THREE.Color('white') },
uReflectMatrix: { type: "m4", value:new THREE.Matrix4()},
uReflectTexture: { type: "t", value:new THREE.Texture()},
uReflectIntensity: { type: "f", value: 15 },
uIntensity: { type: "f", value: 1 },
uLevel: { type: "f", value: 0 },
uResolution: { type: "v2", value: new THREE.Vector2() },
uTime: { type: "f", value: 0 },
}
const material = new CustomShaderMaterial({
baseMaterial: mirror.material,
uniforms: floorUniforms,
vertexShader,
fragmentShader,
silent: true,
})
floorUniforms.uReflectTexture.value = reflector.renderTarget.texture
floorUniforms.uReflectMatrix.value = reflector.textureMatrixUniform.value
return material
}
export {
makeCustomShaderMaterial
}

View File

@ -4,10 +4,8 @@
* @Autor: 地虎降天龙
* @Date: 2023-12-25 11:41:13
* @LastEditors: 地虎降天龙
* @LastEditTime: 2024-04-14 22:31:34
* @LastEditTime: 2024-04-15 09:54:01
-->
<template>
<TresGroup :scale="props.scale">
<primitive :object="mirror" :position-y="-0.01" />
@ -16,8 +14,9 @@
</template>
<script lang="ts" setup>
import * as THREE from 'three'
import { Mesh, PlaneGeometry, RepeatWrapping, GridHelper } from "three"
import { useTexture, useTresContext } from '@tresjs/core'
import { useTexture } from '@tresjs/core'
import { Reflector, ReflectorDudvMaterial } from '../lib/alienJS/all.three.js'
import { watchEffect, watch } from 'vue'
@ -43,9 +42,9 @@ map.wrapS = RepeatWrapping
map.wrapT = RepeatWrapping
map.repeat.set(6, 3)
const material = new ReflectorDudvMaterial({
map: map,
reflectivity: props.reflectivity
});
map: map as any,
reflectivity: props.reflectivity as any,
})
material.uniforms.tReflect = { value: reflector.renderTarget.texture }
material.uniforms.tReflectBlur = reflector.renderTargetUniform
material.uniforms.uMatrix = reflector.textureMatrixUniform
@ -53,19 +52,10 @@ material.uniforms.uMatrix = reflector.textureMatrixUniform
const mirror = new Mesh(new PlaneGeometry(props.size[0], props.size[1]), material)
mirror.rotation.x = -Math.PI / 2
mirror.add(reflector)
// material.opacity = 0.1
// material.transparent = true
// reflector.blurMaterial.opacity = 0.1
// reflector.blurMaterial.transparent = true
// reflector.screen.material.opacity = 0.1
// reflector.screen.material.transparent = true
const { renderer, scene, camera } = useTresContext()
mirror.onBeforeRender = (rendererSelf: any, sceneSelf: any, cameraSelf: any) => {
mirror.visible = false
props.ignoreObjects.forEach((child) => {
props.ignoreObjects.forEach((child: any) => {
if (child.isMesh) {
child.visible = false
}
@ -74,7 +64,7 @@ mirror.onBeforeRender = (rendererSelf: any, sceneSelf: any, cameraSelf: any) =>
}
})
reflector.update(rendererSelf, sceneSelf, cameraSelf)
props.ignoreObjects.forEach((child) => {
props.ignoreObjects.forEach((child: any) => {
if (child.isMesh) {
child.visible = true
}
@ -96,4 +86,8 @@ watch(
gridHelp.visible = newVal
}
)
defineExpose({
reflector
})
</script>

View File

@ -4,7 +4,7 @@
* @Autor: 地虎降天龙
* @Date: 2023-12-22 08:09:35
* @LastEditors: 地虎降天龙
* @LastEditTime: 2024-04-14 22:11:32
* @LastEditTime: 2024-04-15 08:10:12
-->
<template>
@ -23,7 +23,7 @@
</TresMesh>
<Suspense>
<reflectorDUDV v-bind="configState" :ignoreObjects="[]" />
<reflectorDUDV v-bind="configState" :ignoreObjects="[cube]" />
</Suspense>
<TresMesh :position="[3, -1.5, 2]">

View File

@ -0,0 +1,73 @@
// Without original size argument for power of two targets
vec4 packedTexture2DLOD(sampler2D tex, vec2 uv, int level) {
// the fraction of the uv space used by the target mip
float targetSubview = 1.0 / pow(2.0, float(level));
float widthRatio = 2.0 / 3.0;
vec2 scaledDimensions = vec2(targetSubview * widthRatio, targetSubview);
// all levels > 0 are on the right third of the texture
// y is offset from the bottom
vec2 offset = vec2(level > 0 ? widthRatio : 0.0, level > 0 ? targetSubview : 0.0);
vec2 samplePoint = mix(offset, offset + scaledDimensions, uv);
return texture2D(tex, samplePoint);
}
vec4 packedTexture2DLOD(sampler2D tex, vec2 uv, float level) {
float ratio = mod(level, 1.0);
int minLevel = int(floor(level));
int maxLevel = int(ceil(level));
vec4 minValue = packedTexture2DLOD(tex, uv, minLevel);
vec4 maxValue = packedTexture2DLOD(tex, uv, maxLevel);
return mix(minValue, maxValue, ratio);
}
// With original size argument
vec4 packedTexture2DLOD(sampler2D tex, vec2 uv, int level, vec2 originalPixelSize) {
float floatLevel = float(level);
vec2 atlasSize;
atlasSize.x = floor(originalPixelSize.x * 1.5);
atlasSize.y = originalPixelSize.y;
// we stop making mip maps when one dimension == 1
float maxLevel = min(floor(log2(originalPixelSize.x)), floor(log2(originalPixelSize.y)));
floatLevel = min(floatLevel, maxLevel);
// use inverse pow of 2 to simulate right bit shift operator
vec2 currentPixelDimensions = floor(originalPixelSize / pow(2.0, floatLevel));
vec2 pixelOffset = vec2(floatLevel > 0.0 ? originalPixelSize.x : 0.0, floatLevel > 0.0 ? currentPixelDimensions.y : 0.0);
// "minPixel / atlasSize" samples the top left piece of the first pixel
// "maxPixel / atlasSize" samples the bottom right piece of the last pixel
vec2 minPixel = pixelOffset;
vec2 maxPixel = pixelOffset + currentPixelDimensions;
vec2 samplePoint = mix(minPixel, maxPixel, uv);
samplePoint /= atlasSize;
vec2 halfPixelSize = 1.0 / (2.0 * atlasSize);
samplePoint = min(samplePoint, maxPixel / atlasSize - halfPixelSize);
samplePoint = max(samplePoint, minPixel / atlasSize + halfPixelSize);
return texture2D(tex, samplePoint);
}
vec4 packedTexture2DLOD(sampler2D tex, vec2 uv, float level, vec2 originalPixelSize) {
float ratio = mod(level, 1.0);
int minLevel = int(floor(level));
int maxLevel = int(ceil(level));
vec4 minValue = packedTexture2DLOD(tex, uv, minLevel, originalPixelSize);
vec4 maxValue = packedTexture2DLOD(tex, uv, maxLevel, originalPixelSize);
return mix(minValue, maxValue, ratio);
}

View File

@ -0,0 +1,38 @@
#include '../../../../node_modules/lygia/lighting/fresnel.glsl
#include 'packedTexture2DLOD.glsl
varying vec2 vUv;
varying vec4 vWorldPosition;
uniform vec3 uColor;
uniform mat4 uReflectMatrix;
uniform sampler2D uReflectTexture;
uniform float uReflectIntensity;
uniform float uIntensity;
uniform float uLevel;
uniform vec2 uResolution;
uniform float uTime;
void main() {
vec3 worldPos = vWorldPosition.xyz;
worldPos.x -= uTime * 0.1;
vec3 surfaceNormal = texture2D(normalMap, worldPos.xz).xyz * 2.0 - 1.0;
surfaceNormal = surfaceNormal.rbg;
surfaceNormal = normalize(surfaceNormal);
vec3 viewDir = vViewPosition;
float d = length(viewDir);
viewDir = normalize(viewDir);
vec2 distortion = surfaceNormal.xz * (0.001 + 1. / d);
vec4 reflectPoint = uReflectMatrix * vWorldPosition;
reflectPoint = reflectPoint / reflectPoint.w;
vec2 uv = reflectPoint.xy + distortion * uIntensity;
vec3 reflectionSample =
packedTexture2DLOD(uReflectTexture, uv, uLevel, uResolution).xyz;
reflectionSample *= uReflectIntensity;
vec3 strength = fresnel(vec3(0.), vNormal, viewDir);
vec3 col = uColor;
col = mix(col, reflectionSample, strength);
csm_DiffuseColor = vec4(col, 1.);
}

View File

@ -0,0 +1,11 @@
varying vec2 vUv;
varying vec4 vWorldPosition;
void main() {
vec3 p = position;
csm_Position = p;
vUv = uv;
vWorldPosition = modelMatrix * vec4(p, 1);
}

View File

@ -4,10 +4,10 @@
* @Autor: 地虎降天龙
* @Date: 2024-03-27 10:38:54
* @LastEditors: 地虎降天龙
* @LastEditTime: 2024-04-14 22:17:31
* @LastEditTime: 2024-04-15 09:26:24
-->
<template>
<primitive :object="scene" />
<primitive :object="scene" ref="tresMesh" />
</template>
<script setup lang="ts">
@ -15,10 +15,15 @@ import { useTexture } from '@tresjs/core'
import { useGLTF } from '@tresjs/cientos'
import * as THREE from 'three'
import { flatModel } from './utils'
import { defineExpose, ref } from 'vue'
import { defineExpose, ref, watch } from 'vue'
import { makeCustomShaderMaterial } from 'PLS/floor/common/reflectorCustomMaterial'
const props = withDefaults(defineProps<{
reflector?: THREE.Object3D
}>(), {
reflector: null
})
const { scene, nodes, materials } = await useGLTF('./plugins/industry4/model/su7_startroom.raw.glb', { draco: true, decoderPath: './draco/' })
const { scene } = await useGLTF('./plugins/industry4/model/su7_startroom.raw.glb', { draco: true, decoderPath: './draco/' })
const pTexture = await useTexture([
'./plugins/industry4/texture/t_startroom_light.raw.jpg',
@ -56,11 +61,25 @@ floorMat.normalMap = pTexture[3]
floorMat.aoMap = pTexture[1]
floorMat.lightMap = pTexture[0]
floorMat.envMapIntensity = 0
floor.name = 'floorBtm'
floor.visible = false
const tresMesh = ref<Mesh>()
floor.name = 'floorBtm'
// floor.visible = false
watch(
() => props.reflector,
async (newVal) => {
debugger
if (newVal.reflector) {
floor.material = await makeCustomShaderMaterial(floor, newVal.reflector) as any
}
},
{ immediate: true }
)
const tresMesh = ref<THREE.Mesh>()
defineExpose({
meshList: [light, floor]
meshList: [light, floor],
tresMesh
})
</script>

View File

@ -4,7 +4,7 @@
* @Autor: 地虎降天龙
* @Date: 2023-11-18 08:51:19
* @LastEditors: 地虎降天龙
* @LastEditTime: 2024-04-14 22:34:03
* @LastEditTime: 2024-04-15 09:54:26
-->
<template>
<!-- <loading /> -->
@ -15,7 +15,7 @@
<TresDirectionalLight :position="[0, 2, -4]" :intensity="1" /> -->
<Suspense>
<startroom ref="startroomRef" />
<startroom ref="startroomRef" :reflector="reflectorDUDVRef" />
</Suspense>
<Suspense>
@ -23,8 +23,8 @@
</Suspense>
<Suspense>
<reflectorDUDV :reflectivity="0.1" :showGridHelper="false" :position-y=".02" :size="[8, 6]"
:ignoreObjects="startroomRef?.meshList" />
<reflectorDUDV ref="reflectorDUDVRef" :reflectivity="10.1" :showGridHelper="false" :position-y=".01"
:size="[10, 10]" :ignoreObjects="startroomRef?.meshList" />
</Suspense>
</TresCanvas>
</template>
@ -32,16 +32,12 @@
<script setup lang="ts">
import { reactive, ref } from 'vue'
import { OrbitControls } from '@tresjs/cientos'
import { reflectorDUDV } from 'PLS/floor'
import startroom from '../components/su7/startroom.vue'
import car from '../components/su7/car.vue'
import { reflectorDUDV } from 'PLS/floor'
// import { Environment, Lightformer } from 'PLS/basic'
// import * as THREE from 'three'
// import { randomLoading as loading } from 'PLS/UIdemo'
// import { reflectorDUDV } from 'PLS/floor'
// import lamboModel from '../components/lamboModel.vue'
// import lamboEffect from '../components/lamboEffect.vue'
const state = reactive({
clearColor: '#000',
@ -50,9 +46,10 @@ const state = reactive({
disableRender: false
})
const controlsState = reactive({
autoRotate: true,
// autoRotate: true,
})
const startroomRef = ref(null)
const reflectorDUDVRef = ref(null)
</script>