threejs10 Material-shaderMaterial

**

Material(+纹理)

**
三维物体的材质,以Material结尾。
1.不真实:MeshBasicMaterial 最最最基本的材质,不参与光照计算unlit,没有阴影。
2.真实效果:MeshPhongMaterial/MeshLambertMaterial 他俩实现图形学中最最基本的光照模型。
3.更好更真实的效果:MeshStardardMaterial/MeshPhysicMaterial 他俩计算量更大,但是会让你的场景足够逼真。
请添加图片描述

4.动画效果:MeshToonMaterial 实现卡通的效果

map基本纹理贴图+roughmessMap粗糙+normalMap法线贴图+displacementMap高度贴图+aoMap环境光遮罩

1.map:给物体表面贴上基本纹理
请添加图片描述
请添加图片描述
2.roughmessMap设定表面不同位置的粗糙程度
请添加图片描述
请添加图片描述
3.normalMap 法线贴图,会影响光照的计算,用它来模拟表面凹凸不平的效果
请添加图片描述请添加图片描述
4.diaplacementMap 位移贴图(高度贴图)上下偏移表面顶点坐标,做到真正的物体表面的起伏
请添加图片描述
请添加图片描述
5.aoMap(AmbientOcclusion)指定一个“环境光遮罩”贴图,让遮罩的地方变得更暗,从而再进一步提升场景的真实感
请添加图片描述
请添加图片描述

https://zhuanlan.zhihu.com/p/145890220
如何实际使用shader。由于threejs已经帮我们完成了很多基础的框架操作,我们只需要把精力专注在shader程序本身就好。
shader的三个写法
shader存放的位置,我们可以将shader写成单独的文件,或者在js代码中使用字符串的形式,或者使用html页面中《script id=“vertexShader” type=“x-shader/x-vertex”>、《script id=“fragmentShader” type=“x-shader/x-fragment”>等标签形式进行shader代码的编写。
1.在html的页面中加入以上两个shader的script标签。

<script id="vertexShader" type="x-shader/x-vertex">

    precision mediump float;
    precision mediump int;

    uniform mat4 modelViewMatrix;
    uniform mat4 projectionMatrix;

    attribute vec3 position;

    varying vec3 vPosition;

    void main() {

        vPosition = position;
        gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );

    }

</script>

<script id="fragmentShader" type="x-shader/x-fragment">

    precision mediump float;
    precision mediump int;

    uniform float ratio;

    varying vec3 vPosition;

    void main() {
        vec3 center = vec3( 0.0,0.0,0.0 );
        float dist=  distance(vPosition,center)/100.0; 
        dist = clamp(dist,0.0,1.0); 
        float color = 1.0-dist ; 
        gl_FragColor =  vec4( color*ratio, color*ratio,0.0,dist );

    }

</script>

2.在我们的js代码中使用threejs的RawShaderMaterial来创建一个shader材质。并将html标签中的内容获取赋值给vertexShader,fragmentShader。同时,我们创建了一个uniform 名叫ratio。

const material = new THREE.RawShaderMaterial({ 
    uniforms: {
        ratio: {
            value: 0.0
        }
    },
    vertexShader: document.getElementById('vertexShader').textContent,
    fragmentShader: document.getElementById('fragmentShader').textContent, 
});

3.我们把这个材质放在一个平面上,并在主循环中更新uniform的值

const plane = new THREE.Mesh(geometry, material);
plane.rotateX(-Math.PI / 2); 
scene.add(plane);

let next = 0;
const animate = function () {
    requestAnimationFrame(animate);
    next = next + 0.01;
    if (next > 1)
        next = 0;
    plane.material.uniforms.ratio.value = next;
    renderer.render(scene, camera);
};

案例2

var sphereGeometry = new SphereBufferGeometry(5, 12, 12);
var material = new THREE.MeshPhongMaterial();
var sphereMesh = new THREE.Mesh(sphereGeometry, material)
scene.add(sphereMesh);
var shaderMaterial = new THREE.ShaderMaterial(
     {
         vertexShader: ` 
         varying float y;
         void main() {
         // GLSL的矩阵算法   从右到左
 
         y = position.y;
 
         gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
     }
     `,
         fragmentShader: ` 
         varying float y;
         void main() {
             //最终赋给gl_FragColor是一个颜色色变量   r,g,b,alpha
             //浮点数数字必须写成2.0 3.0  比如我们有一个float变量5必须写成5.0
            
            if(y>0.0)
             gl_FragColor = vec4( 0.0, 1.0, 0.0, 0.5);
           else
             gl_FragColor = vec4( 1.0, 0.0, 0.0, 0.5);
         }
         `,
         transparent: true,
         // side: THREE.DoubleSide
     }
 )
 
 debugger
 
 var sphereGeometry = new SphereBufferGeometry(5, 12, 12);
 var sphereMesh = new THREE.Mesh(sphereGeometry, shaderMaterial)
 scene.add(sphereMesh);

在这里插入图片描述

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值