效果演示

着色器旗帜

1、实现步骤

1.1创建项目

// 创建一个空项目
import * as THREE from 'three'
//导入轨道控制器
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'

//1、创建场景
const scene = new THREE.Scene()

//2、创建相机
const camera = new THREE.PerspectiveCamera(
    75,
    window.innerWidth / window.innerHeight,
    0.1,
    1000
) // 参数分别代表,相机角度、屏幕宽高比、近端点,远端点

//设置相机位置
camera.position.set(0, 0, 10)
scene.add(camera)

//添加环境光和平行光
const ambientLight = new THREE.AmbientLight(0xffffff, 1)
const dirLight = new THREE.DirectionalLight(0xffffff, 1)
dirLight.castShadow = true
scene.add(ambientLight)
scene.add(dirLight)

//初始化渲染器
const renderer = new THREE.WebGLRenderer()

//设置渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.shadowMap.enabled = true
renderer.physicallyCorrectLights = true

//将webGL渲染的canvas添加到app中
document.getElementById('app').appendChild(renderer.domElement)

//创建控制器
const controls = new OrbitControls(camera, renderer.domElement)

//设置控制器阻尼,让滑动更有真实感
controls.enableDamping = true

//创建坐标轴
const axesHelper = new THREE.AxesHelper(5)
scene.add(axesHelper)

//设置时钟
const clock = new THREE.Clock()

render()

//渲染函数
function render() {
    const time = clock.getElapsedTime()
    controls.update()
    renderer.render(scene, camera)
    //下一帧渲染完毕再次执行,保证每一帧都渲染
    requestAnimationFrame(render)
}

1.2创建顶点着色器和片元着色器

新建文件夹shader/raw/vertexShader.glslshader/raw/fragmentShader.glsl分别存储顶点着色器和片元着色器

// shader/raw/vertexShader.glsl
precision lowp float;
attribute vec3 position;
attribute vec2 uv;

uniform mat4 modelMatrix;
uniform mat4 viewMatrix;
uniform mat4 projectionMatrix;
uniform float uTime;//拿到传过来的uTime

varying vec2 vUv;
varying float vElevation;

void main() {
    vUv = uv;
    vec4 modelPosition = modelMatrix * vec4(position,1.0);
    //波浪
    modelPosition.z = sin((modelPosition.x + uTime) * 10.0) * 0.05;
    modelPosition.z += sin((modelPosition.y + uTime)* 10.0) * 0.05;
    vElevation = modelPosition.z;
    gl_Position = projectionMatrix * viewMatrix * modelPosition;
}
// shader/raw/fragmentShader.gls
precision highp float;
varying vec2 vUv;
varying float vElevation;
uniform sampler2D uTexture;

void main(){
    // gl_FragColor = vec4(vUv,0.0,1.0);
    // float height = vElevation + 0.05 * 10.0;
    // gl_FragColor = vec4(1.0 * height,0.0,0.0,1.0);
    //根据uv,取出对应的颜色
    vec4 textureColor = texture2D(uTexture,vUv);
    float height = vElevation + 0.05 * 20.0;
    textureColor.rgb *= height;
    gl_FragColor = textureColor;
}

1.3导入着色器和纹理

//导入顶点着色器
import basicVertexShader from '@/shader/raw/vertexShader.glsl?raw'
//导入片元着色器
import basicFragmentShader from '@/shader/raw/fragmentShader.glsl?raw'
//导入纹理
const textureLoader = new THREE.TextureLoader()
const imgTexture = textureLoader.load('/static/imgs/ca.jpeg')

1.4创建物体和材质


//创建平面
const floorGeometry = new THREE.PlaneGeometry(1, 1, 64, 64)
// const floorMaterial = new THREE.MeshBasicMaterial({ color: '#00ff00' })
//创建着色器材质
const floorMaterial = new THREE.RawShaderMaterial({
    //让着色器材质跟随相机等转,顶点着色器
    vertexShader: basicVertexShader,
    //片源着色器
    fragmentShader: basicFragmentShader,
    // wireframe: true,
    side: THREE.DoubleSide,
    //给顶点着色器传的值uniforms
    uniforms: {
        uTime: {
            value: 0,
        },
        uTexture: {
            value: imgTexture,
        },
    },
})

const floorMesh = new THREE.Mesh(floorGeometry, floorMaterial)
scene.add(floorMesh)

1.5让物体动起来

//渲染函数
function render() {
    const time = clock.getElapsedTime()
    floorMaterial.uniforms.uTime.value = time //给片元着色器传的

    controls.update()
    renderer.render(scene, camera)
    //下一帧渲染完毕再次执行,保证每一帧都渲染
    requestAnimationFrame(render)
}

2、全部代码

import * as THREE from 'three'

//目标:学习着色器变量

//导入轨道控制器
import { OrbitControls } from 'three/examples/jsm/controls/OrbitControls'

//导入顶点着色器
import basicVertexShader from '@/shader/raw/vertexShader.glsl?raw'
//导入片元着色器
import basicFragmentShader from '@/shader/raw/fragmentShader.glsl?raw'

//1、创建场景
const scene = new THREE.Scene()

//2、创建相机
const camera = new THREE.PerspectiveCamera(
    75,
    window.innerWidth / window.innerHeight,
    0.1,
    1000
) // 参数分别代表,相机角度、屏幕宽高比、近端点,远端点

//设置相机位置
camera.position.set(0, 0, 10)
scene.add(camera)

//导入纹理
const textureLoader = new THREE.TextureLoader()
const imgTexture = textureLoader.load('/static/imgs/ca.jpeg')

//创建平面
const floorGeometry = new THREE.PlaneGeometry(1, 1, 64, 64)
// const floorMaterial = new THREE.MeshBasicMaterial({ color: '#00ff00' })
//创建着色器材质
const floorMaterial = new THREE.RawShaderMaterial({
    //让着色器材质跟随相机等转,顶点着色器
    vertexShader: basicVertexShader,
    //片源着色器
    fragmentShader: basicFragmentShader,
    // wireframe: true,
    side: THREE.DoubleSide,
    //给顶点着色器传的值uniforms
    uniforms: {
        uTime: {
            value: 0,
        },
        uTexture: {
            value: imgTexture,
        },
    },
})

const floorMesh = new THREE.Mesh(floorGeometry, floorMaterial)
scene.add(floorMesh)

//添加环境光和平行光
const ambientLight = new THREE.AmbientLight(0xffffff, 1)
const dirLight = new THREE.DirectionalLight(0xffffff, 1)
dirLight.castShadow = true
scene.add(ambientLight)
scene.add(dirLight)

//初始化渲染器
const renderer = new THREE.WebGLRenderer()

//设置渲染的尺寸大小
renderer.setSize(window.innerWidth, window.innerHeight)
renderer.shadowMap.enabled = true
renderer.physicallyCorrectLights = true

//将webGL渲染的canvas添加到app中
document.getElementById('app').appendChild(renderer.domElement)

//创建控制器
const controls = new OrbitControls(camera, renderer.domElement)

//设置控制器阻尼,让滑动更有真实感
controls.enableDamping = true

//创建坐标轴
const axesHelper = new THREE.AxesHelper(5)
scene.add(axesHelper)

//设置时钟
const clock = new THREE.Clock()

render()

//渲染函数
function render() {
    const time = clock.getElapsedTime()
    floorMaterial.uniforms.uTime.value = time

    controls.update()
    renderer.render(scene, camera)
    //下一帧渲染完毕再次执行,保证每一帧都渲染
    requestAnimationFrame(render)
}

Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐