Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/linq/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Three.js 如何在画布上创建具有折射和反射的玻璃文本?_Three.js_Html5 Canvas_Shader_Webgl_P5.js - Fatal编程技术网

Three.js 如何在画布上创建具有折射和反射的玻璃文本?

Three.js 如何在画布上创建具有折射和反射的玻璃文本?,three.js,html5-canvas,shader,webgl,p5.js,Three.js,Html5 Canvas,Shader,Webgl,P5.js,我想达到的目标接近于此。你也可以看看那些截图 请注意,当页面向下/向上滚动时,折射是如何变化的。滚动时,还有一个从右向左的光源 理想情况下,我希望文本具有透明的玻璃反射特性,如示例所示。但同时,折射出背后的东西,这里似乎不是这样。事实上,当画布被单独放置时,折射仍然会发生,因此我怀疑效果是在知道背景中会显示什么的情况下完成的。至于我,我想动态折射背后的东西。再一次,我在想,我之所以能以这种方式获得成功,可能是因为一个原因,也许是因为性能问题 事实上,它看起来像是基于背景,但背景不在画

我想达到的目标接近于此。你也可以看看那些截图

请注意,当页面向下/向上滚动时,折射是如何变化的。滚动时,还有一个从右向左的光源

理想情况下,我希望文本具有透明的玻璃反射特性,如示例所示。但同时,折射出背后的东西,这里似乎不是这样。事实上,当画布被单独放置时,折射仍然会发生,因此我怀疑效果是在知道背景中会显示什么的情况下完成的。至于我,我想动态折射背后的东西。再一次,我在想,我之所以能以这种方式获得成功,可能是因为一个原因,也许是因为性能问题

事实上,它看起来像是基于背景,但背景不在画布内。此外,正如您可以看到的,在下一张图片中,即使背景已移除,折射效果仍会出现

光源仍然存在,我怀疑它使用了某种光线投射/光线跟踪方法。我一点也不熟悉在画布上画图(除了使用p5.js来做简单的事情),我花了很长时间才找到光线跟踪,却不知道我在找什么

。。。。问题

  • 如何在文本上获得玻璃透明反射效果?它应该通过平面设计工具来实现吗?(我不知道如何获得一个对象(见下面的屏幕截图),该对象似乎在之后绑定了纹理。我甚至不确定我是否使用了正确的词汇表,但假设我使用了,我不知道如何创建这样的纹理。)

  • 如何折射玻璃对象后面的所有物体?(在我得出需要使用canvas的结论之前,不仅因为我找到了这个示例,还因为与我正在进行的项目相关的其他考虑因素。我已经投入了大量时间学习svg,以实现您在下一个屏幕截图上看到的内容,但未能实现目标。我不愿意这样做ame与光线投射这是我的第三个问题。我希望这是可以理解的…折射部分仍然存在,但看起来比提供的示例中的现实性要差得多。)

  • 光线投射/光线跟踪是实现折射的正确途径吗?如果它的光线跟踪后面的每一个物体,是否可以使用

  • 感谢您的时间和关注。

    反射和折射 有这么多的在线教程来实现这一效果,我看不出重复它们的意义

    此答案提供了一种近似方法,使用法线贴图代替三维模型,使用平面纹理贴图表示反射和折射贴图,而不是传统上用于获取反射和折射的三维纹理

    生成法线贴图。 下面的代码段使用各种选项从输入文本生成法线贴图。该过程相当快(不是实时的),将成为webGL渲染解决方案中3D模型的替代品

    它首先创建文本的高度贴图,添加一些平滑,然后将贴图转换为法线贴图

    text.addEventListener(“键控”,createNormalMap)
    createNormalMap();
    函数createNormalMap(){
    text.focus();
    设置超时(()=>{
    const can=normalMapText(text.value,“Arial Black”,96,8,2,0.1,真,“圆形”);
    result.innerHTML=“”;
    结果:儿童(can);
    }, 0);
    }
    函数normalMapText(文本、字体、大小、倒角、平滑=0、曲线=0.5、平滑法线=true、角点=“圆形”){
    const canvas=document.createElement(“canvas”);
    const mask=document.createElement(“画布”);
    const ctx=canvas.getContext(“2d”);
    const ctxMask=mask.getContext(“2d”);
    ctx.font=size+“px”+font;
    const tw=ctx.measureText(text).width;
    常数cx=(mask.width=canvas.width=tw+斜面*3)/2;
    const cy=(mask.height=canvas.height=size+斜面*3)/2;
    ctx.font=size+“px”+font;
    ctx.textAlign=“中心”;
    ctx.textb基线=“中间”;
    ctx.lineJoin=角点;
    常数步长=255/(斜面+1);
    var j,i=0,val=step;
    而(i<1){
    ctx.lineWidth=斜面-i;
    常数v=((val/255)**曲线)*255;
    ctx.strokeStyle=`rgb(${v},${v},${v})`;
    strokeText(text,cx,cy);
    i++;
    val+=阶跃;
    }
    ctx.fillStyle=“#FFF”;
    ctx.fillText(text,cx,cy);
    如果(平滑>=1){
    ctxMask.drawImage(画布,0,0);
    ctx.filter=“模糊(“+smooth+”px)”;
    ctx.drawImage(掩码,0,0);
    ctx.globalCompositeOperation=“目的地在”;
    ctx.filter=“无”;
    ctx.drawImage(掩码,0,0);
    ctx.globalCompositeOperation=“源代码结束”;
    }
    常量w=canvas.width=canvas.height,w4=w0
    常数idx=x+y*w;
    常数x1=1;
    常数z1=heightBuf[idx-1]==未定义?0:heightBuf[idx-1]-heightBuf[idx];
    常数y1=0;
    常数x2=0;
    常数z2=heightBuf[idx-w]==未定义?0:heightBuf[idx-w]-heightBuf[idx];
    常数y2=-1;
    常数x3=1;
    常数z3=heightBuf[idx-w-1]==未定义?0:heightBuf[idx-w-1]-heightBuf[idx];
    常数y3=-1;
    xx=y3*z2-z3*y2
    yy=z3*x2-x3*z2
    zz=x3*y2-y3*x2
    距离=(xx*xx+yy*yy+zz*zz)**0.5;
    xx/=dist;
    yy/=dist;
    zz/=dist;
    xx1=y1*z3-z1*y3
    yy1=z1*x3-x1*z3
    zz1=x1*y3-y1*x3
    距离=(xx1*xx1+yy1*yy1+zz1*zz1)**0.5;