ДИЗАЙН
<*В РАБОТЕ>
Инструкция:
Инструкция:
В HTML элемент в зеро блоке:
<div id="rays" style="width:100%; height:100%"></div>

В блок Т123:
<script defer src="https://cdnjs.cloudflare.com/ajax/libs/three.js/110/three.min.js"></script>

<script>
const PARAMS = {
bgColor: "#220675", // цвет заднего фона. Пример: "#220675"
lightColor: "#e3d35d", // цвет источника света. Пример: "#e3d35d"
raysColor: "#5d06ba", // цвет лучей. Пример: "#5d06ba"
lightStrength: 3.5, // интенсивность. Пример: 3.5
texture: "https://i.imgur.com/7tJIOeF.png", // текстура (соотношение сторон 1:1). Пример: https://i.imgur.com/7tJIOeF.png
}

document.addEventListener('DOMContentLoaded', () => {
t_onReady(function() {
t_onFuncLoad('t396_init', function () {
(function () {
const vertexShader = `
void main() {
gl_Position = vec4( position, 1.0 );
}
`;

const fragmentShader = `
uniform vec2 u_resolution;
uniform float u_pxaspect;
uniform vec2 u_mouse;
uniform float u_time;
uniform sampler2D u_noise;
uniform sampler2D u_text;
uniform bool u_mousemoved;
uniform vec3 lightcolour;
uniform vec3 falloffcolour;
uniform vec3 bgcolour;
uniform bool addNoise;
uniform float lightStrength;

#define PI 3.141592653589793
#define TAU 6.283185307179586

const float decay = .96; // the amount to decay each sample by
const float exposure = .35; // the screen exposure
const float falloff = .5;
const int samples = 12; // The number of samples to take
const float density = .98; // The density of the "smoke"
const float weight = .25; // how heavily to apply each step of the supersample
const int octaves = 1; // the number of octaves to generate in the FBM noise
const float seed = 43758.5453123; // A random seed :)

vec2 res = u_resolution / u_pxaspect;

float starSDF(vec2 st, int V, float s) {
float a = atan(st.y, st.x)/TAU;
float seg = a * float(V);
a = ((floor(seg) + 0.5)/float(V) +
mix(s,-s,step(.5,fract(seg))))
* TAU;
return abs(dot(vec2(cos(a),sin(a)),
st));
}

float random2d(vec2 uv) {
uv /= 256.;
vec4 tex = texture2D(u_noise, uv);
return mix(tex.x, tex.y, tex.a);
}
vec2 random2(vec2 st, float seed){
st = vec2( dot(st,vec2(127.1,311.7)),
dot(st,vec2(269.5,183.3)) );
return -1.0 + 2.0*fract(sin(st)*seed);
}

float noise(vec2 st, float seed) {
vec3 x = vec3(st, 1.);
vec3 p = floor(x);
vec3 f = fract(x);
f = f*f*(3.0-2.0*f);
vec2 uv = (p.xy+vec2(37.0,17.0)*p.z) + f.xy;
vec2 rg = texture2D(u_noise, (uv+0.5) / 256., 0.).yx - .5;
return mix( rg.x, rg.y, f.z );
}

float fbm1(in vec2 _st, float seed) {
float v = 0.0;
float a = 0.5;
vec2 shift = vec2(100.0);

mat2 rot = mat2(cos(0.5), sin(0.5),
-sin(0.5), cos(0.50));
for (int i = 0; i < octaves; ++i) {
v += a * noise(_st, seed);
_st = rot * _st * 2.0 + shift;
a *= 0.4;
}
return v + .4;
}

float pattern(vec2 uv, float seed, float time, inout vec2 q, inout vec2 r) {

q = vec2( fbm1( uv + vec2(0.0,0.0), seed ),
fbm1( uv + vec2(5.2,1.3), seed ) );

r = vec2( fbm1( uv + 4.0*q + vec2(1.7 - time / 2.,9.2), seed ),
fbm1( uv + 4.0*q + vec2(8.3 - time / 2.,2.8), seed ) );

float rtn = fbm1( uv + 4.0*r, seed );

return rtn;
}

float tri(vec2 uv) {
uv = (uv * 2.-1.)*2.;
return max(abs(uv.x) * 0.866025 + uv.y * 0.5, -uv.y * 0.5);
}
float smin(float a, float b, float k) {
float res = exp(-k*a) + exp(-k*b);
return -log(res)/k;
}

float shapes(vec2 uv) {

uv += u_mouse * .1;

float aspect = res.x / res.y;

float scale = 1. / aspect * .3;

return texture2D(u_text, (uv) * scale + .5, -1.).x;

}

float occlusion(vec2 uv, vec2 lightpos, float objects) {
return (1. - smoothstep(0.0, lightStrength, length(lightpos - uv))) * (1. - objects);
}

vec4 mainRender(vec2 uv, inout vec4 fragcolour) {

float scale = 4.;
uv *= scale;

float exposure = exposure + (sin(u_time) * .5 + 1.) * .05;

vec2 _uv = uv;
vec2 lightpos = (vec2(u_mouse.x, u_mouse.y * -1.)) / u_resolution.y;
lightpos = u_mouse * scale;

if(!u_mousemoved) {

}

float obj = shapes(uv);
float map = occlusion(uv, lightpos, obj);

float _pattern = 0.;
vec2 q = vec2(0.);
vec2 r = vec2(0.);
if(addNoise) {
_pattern = pattern(_uv * 3. , seed, u_time, q, r) / 2.;
}

vec2 dtc = (_uv - lightpos) * (1. / float(samples) * density);

float illumination_decay = 1.;
vec3 basecolour = bgcolour;

for(int i=0; i<samples; i++) {
_uv -= dtc;
if(addNoise) {
uv += _pattern / 16.;
}

float movement = u_time * 20. * float(i + 1);

float dither = random2d(uv * 512. + mod(vec2(movement*sin(u_time * .5), -movement), 1000.)) * 2.;

float stepped_map = occlusion(uv, lightpos, shapes(_uv+dtc*dither));
stepped_map *= illumination_decay * weight;
illumination_decay *= decay;

map += stepped_map;
}

float l = length(lightpos - uv);

vec3 lightcolour = mix(lightcolour, falloffcolour, l*falloff);

vec3 colour = vec3(basecolour+map*exposure*lightcolour);

fragcolour = vec4(colour,1.0);
return fragcolour;
}

void main() {
vec2 uv = (gl_FragCoord.xy - 0.5 * u_resolution.xy) / min(u_resolution.y, u_resolution.x);

mainRender(uv, gl_FragColor);
}
`;

const container = document.getElementById("rays");

let texture, txtr;

let camera, scene, renderer;
let uniforms;
let autoScaleZoom = parseFloat(container.closest(".t396__elem")?.style['zoom']) || 1.0;

let loader=new THREE.TextureLoader();
loader.setCrossOrigin("anonymous");

loader.load(
'https://static.tildacdn.com/tild6535-3834-4733-b031-393732316333/noise.png',
(tex) => {
texture = tex;
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
texture.minFilter = THREE.LinearFilter;

loader.load(
PARAMS.texture,
(tex) => {
txtr = tex;

init();
animate();
}
);
}
);
let mesh;

function init() {
camera = new THREE.Camera();
camera.position.z = 1;

scene = new THREE.Scene();

var geometry = new THREE.PlaneBufferGeometry( 2, 2 );

uniforms = {
u_time: { type: "f", value: 1.0 },
u_resolution: { type: "v2", value: new THREE.Vector2() },
u_pxaspect: { type: 'f', value: window.devicePixelRatio },
u_noise: { type: "t", value: texture },
u_text: { type: "t", value: txtr },
u_mouse: { type: "v2", value: new THREE.Vector2(-.1, -.1) },
lightcolour: { type: "v3", value: new THREE.Color( 0xd9ecff ) },
falloffcolour: { type: "v3", value: new THREE.Color( 0x9500ff ) },
bgcolour: { type: "v3", value: new THREE.Color( 0x08325c ) },
addNoise: { type: "b", value: true },
lightStrength: { type: 'f', value: 3.5 }
};

var material = new THREE.ShaderMaterial( {
uniforms: uniforms,
vertexShader: vertexShader,
fragmentShader: fragmentShader
} );
material.extensions.derivatives = true;

const mesh = new THREE.Mesh( geometry, material );
mesh.material.uniforms.bgcolour.value = new THREE.Color(PARAMS.bgColor);
mesh.material.uniforms.lightcolour.value = new THREE.Color(PARAMS.lightColor);
mesh.material.uniforms.falloffcolour.value = new THREE.Color(PARAMS.raysColor);
mesh.material.uniforms.lightStrength.value = parseFloat(PARAMS.lightStrength);
mesh.material.uniforms.u_text.value = txtr;
scene.add( mesh );

renderer = new THREE.WebGLRenderer();
renderer.setPixelRatio( window.devicePixelRatio );
renderer.setSize( container.offsetWidth, container.offsetHeight );
container.appendChild( renderer.domElement );

onWindowResize();
window.addEventListener( 'resize', onWindowResize, false );
document.addEventListener('pointermove', (e) => handleInteraction(e));
document.addEventListener('touchstart', (e) => handleInteraction(e.touches[0]));
}

function handleInteraction(e) {
const rect = container.getBoundingClientRect();
const ratio = container.offsetHeight / container.offsetWidth;
const relX = e.pageX - rect.left;
const relY = e.pageY - rect.top;
uniforms.u_mouse.value.x = (relX - container.offsetWidth * autoScaleZoom / 2) / container.offsetWidth * autoScaleZoom / ratio;
uniforms.u_mouse.value.y = (relY - container.offsetHeight * autoScaleZoom / 2) / container.offsetHeight * autoScaleZoom * -1;
e.preventDefault();
}

function onWindowResize( event ) {
autoScaleZoom = parseFloat(container.closest(".t396__elem")?.style['zoom']) || 1.0;
renderer.setSize( container.clientWidth, container.clientHeight );
uniforms.u_resolution.value.x = renderer.domElement.width;
uniforms.u_resolution.value.y = renderer.domElement.height;
}

function animate(delta) {
requestAnimationFrame( animate );
render(delta);
}

function render(delta) {
uniforms.u_time.value = delta * 0.0005;
renderer.render( scene, camera );
}
})();
})
})
});
</script>
Student Account
Предоставляется для создания учебных проектов. Не предназначен для коммерческого использования
This site was made on Tilda — a website builder that helps to create a website without any code
Create a website
Student