gpt4 book ai didi

javascript - 提高 threejs/shader 几何体的 UV 线质量

转载 作者:行者123 更新时间:2023-11-30 06:19:33 25 4
gpt4 key购买 nike

我正在使用 threejs 环面的 uv 输出来创建穿过环面的移动线。它有效,但看起来不清晰。

如何提高线路质量?我试过将 Material 制成双面,并增加线条的宽度,但质量并没有太大改善。

我还没有尝试在 threejs 之外完全复制环面,但这超出了我的舒适范围。

我希望有办法改变片段着色器的逻辑以产生更清晰的线条。如果有任何建议,我将不胜感激。

Codepen

/* Scene Initialization */
var startTime = Date.now();
var scene = new THREE.Scene();
var width = window.innerWidth;
var height = window.innerHeight;
var canvas = document.getElementById('canvas');
var camera = new THREE.PerspectiveCamera(75, 1, 1, 1200);
// var camera = new THREE.OrthographicCamera( window.innerWidth / - 2, window.innerWidth / 2, window.innerHeight / 2, window.innerHeight / - 2, 1, 1200 );

camera.position.set(0, -420, 600);
camera.lookAt(new THREE.Vector3(0, 0, 0));

var renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(window.innerWidth * .2, window.innerWidth * .2);
renderer.setClearColor( 0xffffff, 1);
canvas.appendChild(renderer.domElement);

var geometry = new THREE.TorusGeometry(200, 200, 260, 260);
material = new THREE.ShaderMaterial( {
uniforms: {time: { type: "f", value: Date.now() - startTime}, },
vertexShader: `attribute vec3 center;
varying vec3 vCenter;
varying vec2 vUv;
void main() {
vCenter = center;
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}`,
fragmentShader: `varying vec3 vCenter;
varying vec2 vUv;
uniform float time;
uniform sampler2D tDiffuse;
void main() {
float sh = 0.005;
float PI = 3.1415926535897932384626433832795;
// float linesX = mod(time + vUv.x, 0.03);
float linesX = sin((time + vUv.x) * PI * 30.)/30.;
// float linesY = mod(time + vUv.y, 0.05);
float linesY = sin((time + vUv.y) * PI * 20.)/20.;
float smoothX =
smoothstep( 0.0 - sh, 0.0, linesX) -
smoothstep( 0.0, 0.0 + sh, linesX);
float smoothY =
smoothstep( 0.0 - sh, 0.0, linesY) -
smoothstep( 0.0, 0.0 + sh, linesY);

float uvOutput = smoothX + smoothY;
gl_FragColor.rgb = vec3(1.0, 0, 0);
gl_FragColor.a = uvOutput;
// gl_FragColor = vec4(1.,0,0,1.)

}`
} );
//material.extensions.derivatives = true;

material.side = THREE.DoubleSide;

material.transparent = true;

//material.blending = THREE.Add;
material.depthTest = false;

var torus = new THREE.Mesh(geometry, material);
var geom = torus.geometry;
geometry.sortFacesByMaterialIndex();
torus.position.x = 0;

scene.add(torus);

/* Request Animation Frame */
function animation() {
camera.lookAt(new THREE.Vector3(0, 0, 0));
renderer.render(scene, camera);
material.uniforms.time.value = (Date.now() - startTime)/20000;
requestAnimationFrame(animation);
}

animation();
setupDraggableEvents();

function setupDraggableEvents() {
var hammer = new Hammer(document.getElementsByTagName('canvas')[0]);
hammer.on('pan', function(event) {
torus.rotation.y += event.velocityX / 10;
torus.rotation.x += event.velocityY / 10;
});
}

最佳答案

我建议定义两个方向的线数,并根据 UV 坐标计算到线的距离:

float t = time;

vec2 noLines = vec2(30.0, 20.0);
vec2 floorUV = floor((t + vUv) * noLines);
vec2 distUV = t + vUv - (floorUV+0.5) / noLines;

在线的粗细和半粗细之间平滑地插值 (smoothstep),以计算“饱和度”。这导致该行始终在中间具有完整的“强度”(当然您可以对此进行试验,例如 sh*0.66sh*0.33):

float sh = 0.005;
vec2 lineUV = smoothstep(sh, sh*0.5, abs(distUV));

alpha channel 是两个方向的最大“饱和​​度”值:

float uvOutput = max(lineUV.x, lineUV.y);
gl_FragColor = vec4(1.0, 0.0, 0.0, uvOutput);

查看示例,其中我将建议的更改应用于您的原始代码:

/* Scene Initialization */
var startTime = Date.now();
var scene = new THREE.Scene();
var width = window.innerWidth;
var height = window.innerHeight;
var canvas = document.getElementById('canvas');
var camera = new THREE.PerspectiveCamera(75, 1, 1, 1200);

camera.position.set(0, -420, 600);
camera.lookAt(new THREE.Vector3(0, 0, 0));
orbitControls = new THREE.OrbitControls(camera);

var renderer = new THREE.WebGLRenderer({antialias: true});
renderer.setSize(window.innerWidth * .2, window.innerWidth * .2);
renderer.setClearColor( 0xffffff, 1);
canvas.appendChild(renderer.domElement);

var geometry = new THREE.TorusGeometry(200, 200, 260, 260);
material = new THREE.ShaderMaterial( {
uniforms: {time: { type: "f", value: Date.now() - startTime}, },
vertexShader: `attribute vec3 center;
varying vec3 vCenter;
varying vec2 vUv;
void main() {
vCenter = center;
vUv = uv;
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}`,
fragmentShader: `varying vec3 vCenter;
varying vec2 vUv;
uniform float time;
uniform sampler2D tDiffuse;
void main() {
float t = time;

vec2 noLines = vec2(30.0, 20.0);
vec2 floorUV = floor((t + vUv) * noLines);
vec2 distUV = t + vUv - (floorUV+0.5) / noLines;

float sh = 0.005;
vec2 lineUV = smoothstep(sh, sh*0.5, abs(distUV));

float uvOutput = max(lineUV.x, lineUV.y);
gl_FragColor = vec4(1.0, 0.0, 0.0, uvOutput);
}`,
transparent: true
} );
//material.extensions.derivatives = true;

material.side = THREE.DoubleSide;

material.transparent = true;

//material.blending = THREE.Add;
material.depthTest = false;

var torus = new THREE.Mesh(geometry, material);
var geom = torus.geometry;
geometry.sortFacesByMaterialIndex();
torus.position.x = 0;

scene.add(torus);

/* Request Animation Frame */
function animation() {
camera.lookAt(new THREE.Vector3(0, 0, 0));
renderer.render(scene, camera);
material.uniforms.time.value = (Date.now() - startTime)/20000;
requestAnimationFrame(animation);
}

resize();
window.onresize = resize;
animation();
setupDraggableEvents();

function setupDraggableEvents() {
var hammer = new Hammer(document.getElementsByTagName('canvas')[0]);
hammer.on('pan', function(event) {
torus.rotation.y += event.velocityX / 10;
torus.rotation.x += event.velocityY / 10;
});
}

function resize() {

var aspect = window.innerWidth / window.innerHeight;
renderer.setSize(window.innerWidth, window.innerHeight);
camera.aspect = aspect;
camera.updateProjectionMatrix();
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/100/three.min.js"></script>
<script src="https://threejs.org/examples/js/controls/OrbitControls.js"></script>
<div id="canvas"></div>

关于javascript - 提高 threejs/shader 几何体的 UV 线质量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54015617/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com