1
0
mirror of https://github.com/troisjs/trois.git synced 2024-11-24 04:12:02 +08:00

update noisy plane

This commit is contained in:
Kevin Levron 2020-10-13 20:00:08 +02:00
parent 0440e576df
commit 70c594b667
2 changed files with 101 additions and 35 deletions

View File

@ -1,6 +1,6 @@
<template>
<Renderer ref="renderer" antialias :orbit-ctrl="{ enableDamping: true, dampingFactor: 0.05 }">
<Camera :position="{ x: -0, y: -120, z: 30 }" />
<Camera :position="{ x: -0, y: -100, z: 30 }" />
<Scene background="#ffffff">
<PointLight ref="light1" color="#0E09DC" :intensity="0.85" :position="{ x: 0, y: 0, z: 50 }" />
<PointLight ref="light2" color="#1CD1E1" :intensity="0.85" :position="{ x: 0, y: 0, z: 50 }" />
@ -25,11 +25,12 @@
:width="200" :width-segments="100"
:height="200" :height-segments="100"
:time-coef="0.0003"
:noise-coef="0.03"
:z-coef="7"
:noise-coef="5"
:displacement-scale="15"
:delta-coef="1 / 200"
:position="{ x: 0, y: 0, z: 0 }"
>
<PhysicalMaterial flat-shading />
<PhysicalMaterial />
</NoisyPlane>
<!-- <NoisySphere
@ -42,7 +43,7 @@
<PhysicalMaterial flat-shading />
</NoisySphere> -->
<RefractionMesh ref="mesh" :position="{ x: 0, y: -20, z: 15 }" auto-update>
<RefractionMesh ref="mesh" :position="{ x: 0, y: -20, z: 20 }" auto-update>
<TorusGeometry :radius="8" :tube="3" :radial-segments="8" :tubular-segments="6" />
<StandardMaterial color="#ffffff" :metalness="1" :roughness="0" flat-shading />
</RefractionMesh>

View File

@ -1,3 +1,5 @@
import { ObjectSpaceNormalMap, ShaderMaterial, Vector2, WebGLRenderTarget } from 'three';
import { Pass } from 'three/examples/jsm/postprocessing/Pass.js';
import { watch } from 'vue';
import Plane from '../../meshes/Plane.js';
import snoise3 from '../../glsl/snoise3.glsl.js';
@ -6,58 +8,121 @@ export default {
extends: Plane,
props: {
timeCoef: { type: Number, default: 0.001 },
noiseCoef: { type: Number, default: 1 },
zCoef: { type: Number, default: 5 },
noiseCoef: { type: Number, default: 5 },
deltaCoef: { type: Number, default: 1 / 512 },
displacementScale: { type: Number, default: 5 },
},
setup(props) {
// uniforms
const uTime = { value: 0 };
const uNoiseCoef = { value: props.noiseCoef };
watch(() => props.noiseCoef, (value) => { uNoiseCoef.value = value; });
const uZCoef = { value: props.zCoef };
watch(() => props.zCoef, (value) => { uZCoef.value = value; });
const uDelta = { value: new Vector2(props.deltaCoef, props.deltaCoef) };
watch(() => props.deltaCoef, (value) => { uDelta.value.set(value, value); });
return {
uTime, uNoiseCoef, uZCoef,
uTime, uNoiseCoef, uDelta,
};
},
mounted() {
this.updateMaterial();
this.init();
watch(() => this.displacementScale, (value) => { this.material.displacementScale = value; });
this.startTime = Date.now();
this.three.onBeforeRender(this.updateTime);
this.three.onBeforeRender(this.update);
},
unmounted() {
this.three.offBeforeRender(this.updateTime);
this.three.offBeforeRender(this.update);
this.fsQuad.dispose();
this.dispRT.dispose();
this.dispMat.dispose();
this.normRT.dispose();
this.normMat.dispose();
},
methods: {
updateMaterial() {
this.material.onBeforeCompile = (shader) => {
shader.uniforms.uTime = this.uTime;
shader.uniforms.uNoiseCoef = this.uNoiseCoef;
shader.uniforms.uZCoef = this.uZCoef;
shader.vertexShader = `
init() {
this.fsQuad = new Pass.FullScreenQuad();
// displacement map
this.dispRT = new WebGLRenderTarget(512, 512, { depthBuffer: false, stencilBuffer: false });
this.dispMat = new ShaderMaterial({
uniforms: {
uTime: this.uTime,
uNoiseCoef: this.uNoiseCoef,
},
vertexShader: `
varying vec2 vUv;
void main() {
vUv = uv;
// gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
gl_Position = vec4(position, 1.0);
}
`,
fragmentShader: `
uniform float uTime;
uniform float uNoiseCoef;
uniform float uZCoef;
varying float vNoise;
varying vec2 vUv;
${snoise3}
` + shader.vertexShader;
void main() {
vec2 p = vec2(vUv * uNoiseCoef);
float noise = (snoise(vec3(p.x, p.y, uTime)) + 1.0) / 2.0;
gl_FragColor = vec4(noise, 0.0, 0.0, 1.0);
}
`,
});
shader.vertexShader = shader.vertexShader.replace(
'#include <begin_vertex>',
`
vec3 p = vec3(position * uNoiseCoef);
vNoise = snoise(vec3(p.x, p.y, uTime));
vec3 transformed = vec3(position);
transformed.z += vNoise * uZCoef;
`
);
this.materialShader = shader;
};
this.material.needsupdate = true;
// normal map
this.normRT = new WebGLRenderTarget(512, 512, { depthBuffer: false, stencilBuffer: false });
this.normMat = new ShaderMaterial({
uniforms: {
dispMap: { value: this.dispRT.texture },
delta: this.uDelta,
},
updateTime() {
vertexShader: `
varying vec2 vUv;
void main() {
vUv = uv;
// gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
gl_Position = vec4(position, 1.0);
}
`,
fragmentShader: `
uniform sampler2D dispMap;
uniform vec2 delta;
varying vec2 vUv;
void main() {
// gl_FragColor = vec4(0.5, 0.5, 1.0, 0.0);
float x1 = texture2D(dispMap, vec2(vUv.x - delta.x, vUv.y)).r;
float x2 = texture2D(dispMap, vec2(vUv.x + delta.x, vUv.y)).r;
float y1 = texture2D(dispMap, vec2(vUv.x, vUv.y - delta.y)).r;
float y2 = texture2D(dispMap, vec2(vUv.x, vUv.y + delta.y)).r;
gl_FragColor = vec4(0.5 + (x1 - x2), 0.5 + (y1 - y2), 1.0, 1.0);
}
`,
});
this.material.displacementMap = this.dispRT.texture;
this.material.displacementScale = this.displacementScale;
this.material.normalMap = this.normRT.texture;
this.material.normalMapType = ObjectSpaceNormalMap;
// this.material.needsUpdate = true;
},
update() {
this.uTime.value = (Date.now() - this.startTime) * this.timeCoef;
this.renderDisp();
},
renderDisp() {
this.renderMat(this.dispMat, this.dispRT);
this.renderMat(this.normMat, this.normRT);
},
renderMat(mat, target) {
const renderer = this.three.renderer;
this.fsQuad.material = mat;
const oldTarget = renderer.getRenderTarget();
renderer.setRenderTarget(target);
this.fsQuad.render(renderer);
renderer.setRenderTarget(oldTarget);
},
},
__hmrId: 'NoisyPlane',