threejs 自定义材质

代码如下

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>shader</title>
    <style>
        body {
            color: #ffffff;
            font-family:Monospace;
            font-size:13px;
            text-align:center;
            font-weight: bold;

            background-color: #000000;
            margin: 0px;
            overflow: hidden;
        }

        a {

            color: #ffffff;
        }

        #oldie a { color:#da0 }
    </style>
    <script src="../js/three.js"></script>
    <script id="vertexShader" type="x-shader1/x-vertex1">
        void main(){
            gl_Position = vec4(position,1.0);
        }
    </script>
    <script id="fragmentShader" type="x-shader/x-fragment">
        void main(){
            gl_FragColor = vec4(1.0,0.0,0.0,1.0);
        }
    </script>
</head>
<body>
    <div id="container"></div>
    <script>
        var container;
        var camera,scene,renderer;
        var uniforms,material,mesh;
        var mouseX = 0,mouseY= 0;
        var mouseX = 0,mouseY = 0;
        lat = 0,lon =0,phy = 0,theta = 0;

        var windowHalfX= window.innerWidth/2;
        var windowHalfY = window.innerHeight/2;

        init();
        animate();

        function init() {
            container = document.getElementById('container');

            camera = new THREE.Camera();
            camera.position.z = 0.3;

            scene = new THREE.Scene();

            material = new THREE.ShaderMaterial({
                vertexShader : document.getElementById('vertexShader').textContent,
                fragmentShader: document.getElementById('fragmentShader').textContent
            })
            mesh = new THREE.Mesh(new THREE.PlaneGeometry(1.0,1.0),material);
            scene.add(mesh);

            renderer = new THREE.WebGLRenderer();
            container.appendChild(renderer.domElement);

            window.addEventListener('resize',onWindowResize,false);
        }
        function onWindowResize(event) {
            renderer.setSize(window.innerWidth,window.innerHeight);
        }
        function animate() {
            requestAnimationFrame(animate);
            render();
        }
        function render() {
            renderer.render(scene,camera);
        }
    </script>
</body>
</html>

 

vertexShader 相对于的是顶点着色器;

fragmentShader对应的是片元着色器

结果如下:

因为在片元着色器中固定了它的颜色,

gl_FragColor = vec4(1.0,0.0,0.0,1.0);所以它是红色的;

 

 

做一个随时间变色的材质,代码如下:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <title>shader</title>
    <style>
        body {
            color: #ffffff;
            font-family:Monospace;
            font-size:13px;
            text-align:center;
            font-weight: bold;

            background-color: #000000;
            margin: 0px;
            overflow: hidden;
        }

        #info {
            position: absolute;
            top: 0px; width: 100%;
            padding: 5px;
        }

        a {
            color: #ffffff;
        }

        #oldie a { color:#da0 }
    </style>
    <script src="../js/three.js"></script>
    <script id="vertexShader" type="x-shader1/x-vertex1">
        void main(){
            gl_Position = projectionMatrix*modelViewMatrix*vec4( position, 1.0 );
        }
    </script>
    <script id="fragmentShader" type="x-shader/x-fragment">
           uniform vec2 resolution;
         uniform float time;
         float a =1.0,b=1.0,c=1.0;
         float t ;
        void main(){
            t = time;
            a = abs(sin(t));
            b = abs(cos(t));
            c = abs(sin(t)*cos(t));
            gl_FragColor=vec4(vec3(a,b,c),1.0);
        }
    </script>
</head>
<body>
    <div id="container"></div>
    <script>
        var container;
        var camera,scene,renderer;
        var uniforms,material,mesh;
        var mouseX = 0,mouseY= 0;
        var mouseX = 0,mouseY = 0;
        lat = 0,lon =0,phy = 0,theta = 0;

        var windowHalfX= window.innerWidth/2;
        var windowHalfY = window.innerHeight/2;

        init();
        animate();

        function init() {
            container = document.getElementById('container');

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

            scene = new THREE.Scene();

            uniforms = {
                time: { type: "f", value: 1.0 },
                resolution: { type: "v2", value: new THREE.Vector2() }
            };
            material = new THREE.ShaderMaterial({
                uniforms: uniforms,
                vertexShader: document.getElementById( 'vertexShader' ).textContent,
                fragmentShader: document.getElementById( 'fragmentShader' ).textContent
            })
            mesh = new THREE.Mesh(new THREE.PlaneGeometry(2.0,2.0),material);
            scene.add(mesh);

            renderer = new THREE.WebGLRenderer();
            container.appendChild(renderer.domElement);

            window.addEventListener('resize',onWindowResize,false);
        }
        function onWindowResize(event) {
            uniforms.resolution.value.x = window.innerWidth;
            uniforms.resolution.value.y = window.innerHeight;
            renderer.setSize(window.innerWidth,window.innerHeight);
        }
        function animate() {
            requestAnimationFrame(animate);
            render();
        }
        function render() {
            uniforms.time.value += 0.05;
            renderer.render(scene,camera);
        }
    </script>
</body>
</html>

 

需要注意的是材质中的

uniforms,他表示可以在着色器计算过程中不变的值,可以传递给片元着色器和顶点着色器中的变量;

type 表示传递的数据类型,f 对应的是float 类型的变量,v2 对应的是vec2;

名字必须与着色其中的变量名相同;如:

uniform float time;
uniform vec2 resolution;
uniforms = {
    time: { type: "f", value: 1.0 },
    resolution: { type: "v2", value: new THREE.Vector2() }
};

value 表示往着色器中传的值;

着色器中的计算;如下:
void main(){
    t = time;
    a = abs(sin(t));
    b = abs(cos(t));
    c = abs(sin(t)*cos(t));
    gl_FragColor=vec4(vec3(a,b,c),1.0);
}

三角函数范围时-1到1 ,加绝对值就是0 到1,然后随时间的变换变换rgb,a是透明度设置为1.0;所以rgb 就是0到1直接随时间变化而变化

### 创建或修改Three.js中的自定义纹理颜色 在Three.js中处理纹理时,可以通过多种方式来创建或修改自定义纹理的颜色。一种常见的方式是通过CanvasTexture对象基于HTML `<canvas>`元素生成纹理。 #### 使用Canvas绘制并作为纹理 为了实现这一点,可以先在一个`<canvas>`上绘图,再将其转换成纹理应用到材质上去: ```javascript // 创建一个画布用于绘制图案 const canvas = document.createElement('canvas'); canvas.width = 256; canvas.height = 256; const context = canvas.getContext('2d'); // 绘制简单的渐变色矩形作为例子 const gradient = context.createLinearGradient(0, 0, canvas.width, 0); gradient.addColorStop(0, 'red'); // 开始位置为红色 gradient.addColorStop(1, 'blue'); // 结束位置为蓝色 context.fillStyle = gradient; context.fillRect(0, 0, canvas.width, canvas.height); // 将画布内容转化为纹理 const texture = new THREE.CanvasTexture(canvas); // 应用此纹理至网格平面几何体上的基本材料 const material = new THREE.MeshBasicMaterial({ map: texture }); const geometry = new THREE.PlaneGeometry(1, 1); // 定义大小 const plane = new THREE.Mesh(geometry, material); scene.add(plane); ``` 上述代码展示了如何利用JavaScript的`<canvas>` API创建带有特定颜色模式的图像,并以此为基础构建了一个新的纹理实例[^1]。 对于已经存在的图片文件类型的纹理而言,则可以直接加载这些资源并通过调整其属性改变显示效果。例如,如果想要整体更改整个纹理的颜色而不仅仅是替换它的话,那么可以在着色器级别操作或者简单地设置材质的颜色乘法参数。 #### 修改现有纹理的颜色 当需要动态调整已有的纹理色彩而不重新渲染新图像的时候,可以通过调节材质的颜色属性达到目的: ```javascript material.color.setHex(Math.random() * 0xffffff); // 随机化物体表面颜色 material.needsUpdate = true; // 更新标记设为true以使变化生效 ``` 另外,在更复杂的情况下,还可以编写自定义GLSL片段着色器来进行高级的颜色变换逻辑,比如亮度/对比度控制、色调映射等特殊视觉效果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值