美文网首页
Three.js MeshStandardMaterial菲涅尔

Three.js MeshStandardMaterial菲涅尔

作者: ShawnWeasley | 来源:发表于2022-03-22 15:55 被阅读0次

前面两篇分别讲了Three.js的源码结构和Shader改写方法,本篇做一个基于Standard材质的菲涅尔。
如未读过前两篇的建议先读一下:
Three.js Shader源码结构https://www.jianshu.com/p/8de8a94ac1a9
Three.js Shader改写https://www.jianshu.com/p/5944e10d70cf

仅打开一盏平行光时最终效果如下,可以看到在原有兰伯特的基础上增加了由外向内的菲涅尔效果:


菲涅尔改写

1.改写前准备

参考前面两篇,我们的目标是改写StandardMaterial,所以我们要找到StandardMaterial的源码。打开Three.js的源码,我们发现如下两行定义了StandardMaterial的vertexShader和fragmentShader。

standard: {

        uniforms: mergeUniforms([
...略
        ]),

        vertexShader: ShaderChunk.meshphysical_vert,
        fragmentShader: ShaderChunk.meshphysical_frag

    },

顺藤摸瓜找到meshphysical_frag指向的是fragment$5:

    meshphysical_vert: vertex$5,
    meshphysical_frag: fragment$5,

而fragment$5最后用到的include是:

#include <dithering_fragment>

所以我们要在最后修改颜色的话,就得replace这句话。下面这段代码就实现了一个球的菲涅尔,至于菲涅尔的算法1-NdotV这里就不赘述了。

            const geometry1 = new THREE.SphereGeometry(0.2, 32, 16);
            const material1 = new THREE.MeshStandardMaterial({ color: 0xffffff });
            const sphere1 = new THREE.Mesh(geometry1, material1);
            scene.add(sphere1);
            sphere1.position.y = 0.5;

            let uniforms = {
                rimColor: { value: new THREE.Color(0xff00ff) },
                rimPower: { value: 0.6 },
            }
            sphere1.material.onBeforeCompile = function (shader) {
                shader.uniforms.rimColor = uniforms.rimColor;
                shader.uniforms.rimPower = uniforms.rimPower;

                shader.fragmentShader = /* glsl */`
                    uniform vec3 rimColor;
                    uniform float rimPower;
                        ${shader.fragmentShader.replace(
                    '#include <dithering_fragment>',
                    '#include <dithering_fragment>\n\tfloat dotNV = 1.0-saturate( dot( normal, geometry.viewDir ) );\n\tgl_FragColor.rgb += rimPower*dotNV*rimColor;'
                )}
                `;
            };

加载的模型的材质改写也很简单,遍历所有子物体,如果isMesh则执行.material.onBeforeCompile。

相关文章

  • Three.js MeshStandardMaterial菲涅尔

    前面两篇分别讲了Three.js的源码结构和Shader改写方法,本篇做一个基于Standard材质的菲涅尔。如未...

  • Zemax VR菲涅尔设计总结

    目前VR菲涅尔透镜使用一面凸面,一面菲涅尔面; 用理想菲涅尔设计有可能不能加工; 波长设计最好使用屏幕的RGB波长...

  • 24 菲涅尔节点

    金属的菲涅尔非常弱

  • 菲涅尔 Fresnel

    奥古斯汀·菲涅耳 Augustin Fresnel(1788~1827),法国土木工程师兼物理学家。 菲涅耳的科学...

  • Shader-FresnelReflection(菲涅尔反射)

    菲涅尔公式:用来描述光在不同折射率的介质之间的行为。用公式推导出的光的反射称之为“菲涅尔反射”。 应用:运用于类似...

  • [光照]菲涅尔反射

    1.综述 有一种情况,当我们站在湖边直接看脚边的湖面会发现水几乎是透明的,可以直接看到水底的小鱼和石子,但是抬头看...

  • VR家装-Tips-玻璃

    玻璃一般情况下是黑色或者深墨绿色,注意菲涅尔反射、折射、透明三个值玻璃材质具有的3大特点。 菲涅尔反射:正对摄影机...

  • 四、其他:一些基本概念02

    1、UnityShader-菲涅尔反射(Fresnel Reflection) 用来描述光在不同折射率的介质之间的...

  • 【Unity3D技术文档翻译】第2.3.3.12篇 材质查阅图表

    上一章:Unity3D技术文档翻译】第2.3.3.11篇 菲涅尔效果 (The Fresnel Effect) 本...

  • C4D菲涅尔材质

    当颜色与发光色相同 开启反射,发光,透明材质。 1 其中透明材质折射率为1.567为标准镜面折射率、透明选项开启菲...

网友评论

      本文标题:Three.js MeshStandardMaterial菲涅尔

      本文链接:https://www.haomeiwen.com/subject/lrlfjrtx.html