<template>
<div class="circle" ref="circle"></div>
</template>
<script setup>
import {onMounted, ref} from "vue";
import * as THREE from 'three';
import {OrbitControls} from 'three/examples/jsm/controls/OrbitControls'
import output_fragment from '../shader/output_fragment.glsl.js'
let scene, camera, renderer, controls, circle = ref(null);
let timeValue = {value: 0.0}
function init() {
let width = circle.value.clientWidth;
let height = circle.value.clientHeight
scene = new THREE.Scene();
renderer = new THREE.WebGLRenderer({
antialias: true, //开启锯齿
});
renderer.physicallyCorrectLights = true;
renderer.outputEncoding = THREE.sRGBEncoding;
renderer.toneMapping = THREE.ACESFilmicToneMapping;
renderer.toneMappingExposure = 1.0
renderer.setClearColor(0x001111, 1);
renderer.setSize(width, height)
renderer.setPixelRatio(Math.min(window.devicePixelRatio, 2));
renderer.setClearColor(new THREE.Color('#32373E'), 1);
camera = new THREE.PerspectiveCamera(45, width / height, 1, 10000)
camera.position.set(500, 500, 500)
controls = new OrbitControls(camera, renderer.domElement);
let light = new THREE.AmbientLight(0xadadad, 0.8); // soft white light
scene.add(light)
let light_2 = new THREE.HemisphereLight(0x00AAFF, 0xFFAA00, 0.8)
scene.add(light_2)
scene.add(new THREE.AxesHelper(500))
const geometry = new THREE.PlaneGeometry(500, 500);
// geometry.translate(250, 250, 0)
// geometry.rotateX(Math.PI / 2)
const material = new THREE.MeshBasicMaterial({color: 0xffff00, side: THREE.DoubleSide});
let vertexShader = `
varying vec2 vUv;
void main(){
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
}
`;
let fragmentShader = `
vec2 hash( vec2 p )
{
p = vec2( dot(p,vec2(127.1,311.7)),
dot(p,vec2(269.5,183.3)) );
return -1.0 + 2.0*fract(sin(p)*43758.5453123);
}
float noise( in vec2 p )
{
const float K1 = 0.366025404; // (sqrt(3)-1)/2;
const float K2 = 0.211324865; // (3-sqrt(3))/6;
vec2 i = floor( p + (p.x+p.y)*K1 );
vec2 a = p - i + (i.x+i.y)*K2;
vec2 o = (a.x>a.y) ? vec2(1.0,0.0) : vec2(0.0,1.0);
vec2 b = a - o + K2;
vec2 c = a - 1.0 + 2.0*K2;
vec3 h = max( 0.5-vec3(dot(a,a), dot(b,b), dot(c,c) ), 0.0 );
vec3 n = h*h*h*h*vec3( dot(a,hash(i+0.0)), dot(b,hash(i+o)), dot(c,hash(i+1.0)));
return dot( n, vec3(70.0) );
}
float fbm(vec2 uv)
{
float f;
mat2 m = mat2( 1.6, 1.2, -1.2, 1.6 );
f = 0.5000*noise( uv ); uv = m*uv;
f += 0.2500*noise( uv ); uv = m*uv;
f += 0.1250*noise( uv ); uv = m*uv;
f += 0.0625*noise( uv ); uv = m*uv;
f = 0.5 + 0.5*f;
return f;
}
uniform vec3 iResolution; // 视口分辨率(像素)
uniform float iTime;
uniform float opacity;
varying vec2 vUv;
void main() {
vec2 uv = vUv.xy / iResolution.xy;
vec2 q = uv;
q.x *= 1.;
q.y *= 1.;
float strength = floor(q.x+1.);
float T3 = max(3.,1.25*strength)*iTime;
q.x = mod(q.x,1.)-0.5;
q.y -= 0.25;
float n = fbm(strength*q - vec2(0,T3));
float c = 1. - 16. * pow( max( 0., length(q*vec2(1.8+q.y*1.5,.75) ) - n * max( 0., q.y+.25 ) ),1.2 );
float c1 = n * c * (1.5-pow(1.25*uv.y,4.));
c1=clamp(c1,0.,1.);
vec3 col = vec3(1.5*c1, 1.5*c1*c1*c1, c1*c1*c1*c1*c1*c1);
float a = c * (1.-pow(uv.y,3.));
gl_FragColor = vec4( mix(vec3(0.),col,a), a);
}
`
let material2 = new THREE.ShaderMaterial({
vertexShader,
fragmentShader,
side: THREE.DoubleSide,
transparent: true,
uniforms: {
iTime: timeValue,
iResolution: { value: new THREE.Vector3( 1,1,1) }
},
opacity: {
value: 0.3
},
})
const plane = new THREE.Mesh(geometry, material2);
scene.add(plane);
// plane.rotateX(-Math.PI/2)
}
function animal() {
renderer.render(scene, camera);
timeValue.value += 0.01
requestAnimationFrame(animal)
}
onMounted(() => {
init();
circle.value.appendChild(renderer.domElement)
animal();
})
</script>
<style scoped lang="less">
.circle {
height: 100%;
}
</style>
火焰Shader
最新推荐文章于 2023-07-10 13:40:14 发布