首页 > 其他分享 >着色器

着色器

时间:2023-11-10 19:12:27浏览次数:26  
标签:1.0 geometry THREE vec4 new 着色器

概念:attribute 用于向顶点着色器,传输几何图形待处理的各种属性,例如:顶点坐标,UV 坐标等等

注意:attribute 只能用于顶点着色器中,值在运行时会从几何图形属性中取值

点击查看代码
function createBasic() {
  // 目标:着色器变量 - attribute 使用
  // 作用:用于向顶点着色器中传入几何图形待处理的各种属性,例如:顶点坐标,UV 坐标等
  // 默认情况下几何图形 attribute 属性和值都被 ShaderMaterial 注入顶点着色器内了
  // 需要额外传递其他内容时使用 attribute
  // 注意:attribute 只能用于顶点着色器中,用于修饰浮点数向量
 
  const geometry = new THREE.PlaneGeometry(1, 1);
  console.log(geometry)
  geometry.setAttribute('position2', geometry.attributes.position)

  const material = new THREE.ShaderMaterial({
    vertexShader: `
      attribute vec3 position2;
      void main() {
        gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position2, 1.0);
      }
    `,
    fragmentShader: `
      void main() {
        gl_FragColor = vec4(0, 1.0, 0, 1.0);
      }
    `
  });
  const mesh = new THREE.Mesh(geometry, material);
  scene.add(mesh);
}
概念:uniform 可在顶点或片元着色器,接收全局参数使用

使用:

1.材质中传入 uniforms 属性(变量和值)

2.着色器中使用 uniform 定义同名变量接收

3.使用此变量与顶点坐标做效果

注意:uniform 是只读的

点击查看代码
function createBasic() {
  // 目标:着色器变量-uniform
  // 作用:接收全局参数使用,可在顶点/片元着色器中接收使用
  // 注意:uniform 是只读的
  // 步骤:
  // 1. 着色器材质中传入 uniforms 属性并传入变量和值
  // 2. 着色器代码中使用 uniform 定义同名变量接收
  // 3. 使用此变量在顶点坐标中
 
  const geometry = new THREE.PlaneGeometry(1, 1);
  geometry.setAttribute('position2', geometry.attributes.position)

  const material = new THREE.ShaderMaterial({
    // 2. 着色器代码中使用 uniform 定义同名变量接收
    vertexShader: `
      attribute vec3 position2;

      uniform float posX;

      void main() {
        // gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position2, 1.0);

        vec4 v = vec4(position2, 1.0);
        v.x += posX;

        gl_Position = projectionMatrix * viewMatrix * modelMatrix * v;
      }
    `,
    fragmentShader: `
      void main() {
        gl_FragColor = vec4(0, 1.0, 0, 1.0);
      }
    `,
    // 1. 着色器材质中传入 uniforms 属性并传入变量和值
    uniforms: {
      posX: {
        value: 2.0 // 初始值位移 x 轴 2 个单位
      }
    }
  });
  const mesh = new THREE.Mesh(geometry, material);
  scene.add(mesh);
}
概念:varying 将顶点着色器中数据,传递给片元着色器,一般是几何对象相关的属性

使用:借助 UV 坐标实现渐变色

1.顶点着色器中定义 varying 变量,保存 uv 坐标

2.片元着色器定义 varying 变量,自动接收 uv 坐标做颜色使用

点击查看代码

function createBasic() {
  // 目标:着色器变量-varying
  // 作用:把顶点着色器内变量,传递给片元着色器内使用
  // 步骤:
  // 1. 顶点着色器中定义 varying 变量,保存 uv 坐标
  // 2. 片元着色器中定义 varying 变量,自动接收 uv 坐标值,作为颜色使用
 
  const geometry = new THREE.PlaneGeometry(1, 1);
  geometry.setAttribute('position2', geometry.attributes.position)

  const material = new THREE.ShaderMaterial({
    vertexShader: `
      attribute vec3 position2;

      uniform float posX;

      // 1. 顶点着色器中定义 varying 变量,保存 uv 坐标
      varying vec2 myUV;

      void main() {
        // 几何图形的 uv 坐标赋予保存
        myUV = uv;

        // gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position2, 1.0);

        vec4 v = vec4(position2, 1.0);
        v.x += posX;

        gl_Position = projectionMatrix * viewMatrix * modelMatrix * v;
      }
    `,
    fragmentShader: `
      // 2. 片元着色器中定义 varying 变量,自动接收 uv 坐标值,作为颜色使用
      varying vec2 myUV;

      void main() {
        gl_FragColor = vec4(myUV.x, myUV.y, 0, 1.0);
      }
    `,
    uniforms: {
      posX: {
        value: 2.0
      }
    }
  });
  const mesh = new THREE.Mesh(geometry, material);
  scene.add(mesh);
}
使用:借助 UV 坐标实现渐变色

公式:直接用 y 轴坐标作为 rgb 颜色

点击查看代码
function createBasic() {
  // 目标:使用:借助 UV 坐标实现渐变色
  // 公式:直接用 y 轴坐标作为 rgb 颜色
  const geometry = new THREE.PlaneGeometry(1, 1);
  geometry.setAttribute('position2', geometry.attributes.position)

  const material = new THREE.ShaderMaterial({
    vertexShader: `
      attribute vec3 position2;

      uniform float posX;

      varying vec2 myUV;

      void main() {
        // 几何图形的 uv 坐标赋予保存
        myUV = uv;

        // gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position2, 1.0);

        vec4 v = vec4(position2, 1.0);
        v.x += posX;

        gl_Position = projectionMatrix * viewMatrix * modelMatrix * v;
      }
    `,
    fragmentShader: `
      varying vec2 myUV;

      void main() {
        // float color = myUV.y; // 上白下黑
        float color = 1.0 - myUV.y; // 上黑下白
        gl_FragColor = vec4(color, color, color, 1.0);
      }
    `,
    uniforms: {
      posX: {
        value: 2.0
      }
    }
  });
  const mesh = new THREE.Mesh(geometry, material);
  scene.add(mesh);
}
目标:实现波浪效果

使用:

1.增加几何图形顶点数量

2.顶点着色器控制 z 轴坐标位置

建议:收集公式 / 学习图形学+数学知识

调试:可以在 JS 中带入坐标打印数值观察调试

点击查看代码
function createBasic() {
  // 目标:实现波浪效果
  // 使用:
  // 1. 增加几何图形顶点数量
  // 2. 顶点着色器控制 z 轴坐标位置

  // 1. 增加几何图形顶点数量
  const geometry = new THREE.PlaneGeometry(1, 1, 64, 64);
  geometry.setAttribute('position2', geometry.attributes.position)

  const material = new THREE.ShaderMaterial({
    vertexShader: `
      attribute vec3 position2;

      uniform float posX;

      varying vec2 myUV;

      void main() {
        myUV = uv;

        // gl_Position = projectionMatrix * viewMatrix * modelMatrix * vec4(position2, 1.0);

        vec4 v = vec4(position2, 1.0);
        v.x += posX;
        
        // 2. 顶点着色器控制 z 轴坐标位置
        v.z = sin(v.x * 10.0) * 0.1;
        v.z += sin(v.y * 10.0) * 0.1; 

        gl_Position = projectionMatrix * viewMatrix * modelMatrix * v;
      }
    `,
    fragmentShader: `
      varying vec2 myUV;

      void main() {
        // float color = myUV.y; // 上白下黑
        float color = 1.0 - myUV.y; // 上黑下白
        gl_FragColor = vec4(color, color, color, 1.0);
      }
    `,
    uniforms: {
      posX: {
        value: 2.0
      }
    },
    side: THREE.DoubleSide
  });
  const mesh = new THREE.Mesh(geometry, material);
  scene.add(mesh);
}
目标:实现旋转效果

核心:所有物体都可以通过顶点着色器和片元着色器控制

难点:控制的计算过程,数学公式的使用

点击查看代码
import * as THREE from 'three'
import { OrbitControls } from 'three/addons/controls/OrbitControls.js'
// 2. 定义全局变量 material
let scene, camera, renderer, controls, material
function init() {
  scene = new THREE.Scene()
  camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000)
  camera.position.set(0, 0, 5)
  renderer = new THREE.WebGLRenderer({ antialias: true })
  renderer.setSize(window.innerWidth, window.innerHeight)
  document.body.appendChild(renderer.domElement)

  controls = new OrbitControls(camera, renderer.domElement)
  controls.enableDamping = true

  const axesHelper = new THREE.AxesHelper(5)
  scene.add(axesHelper)
};


function createBasic() {
  // 目标:实现旋转效果
  const geometry = new THREE.PlaneGeometry(1, 1, 64, 64)
  material = new THREE.ShaderMaterial({
    vertexShader: `
      // 4. 接收时间值-作为旋转角度
      uniform float myTime;
      void main() {
        float angle = myTime; // 旋转角度(0-360数值之间)
        float radian = radians(angle); // 角度转弧度(0-2PI)
        float cosV = cos(radian); // 求解旋转角度余弦值
        float sinV = sin(radian); // 求解旋转角度正弦值
        mat4 mx = mat4(1,0,0,0, 0,cosV,-sinV,0, 0,sinV,cosV,0, 0,0,0,1); // x 轴顺时针
        // mat4 mx = mat4(cosV,-sinV,0,0, sinV,cosV,0,0,  0,0,1,0,  0,0,0,1); // z 轴顺时针
        // mat4 mx=mat4(cosV,0,sinV,0, 0,1,0,0, -sinV,0,cosV,0, 0,0,0,1); // y 轴顺时针
      
        vec4 v = mx * vec4(position, 1.0);
      
        gl_Position = projectionMatrix * viewMatrix * modelMatrix * v;
      }
    `,
    fragmentShader: `
      void main() {
        gl_FragColor = vec4(0, 1.0, 0, 1.0);
      }
    `,
    uniforms: {
      // 1. 定义接收全局参数-时间变量值(作为旋转角度)
      myTime: {
        value: 0
      }
    },
    side: THREE.DoubleSide
  });
  const mesh = new THREE.Mesh(geometry, material);
  scene.add(mesh);
}

function renderLoop(t) {
  // t 是毫秒级,距离最开始的时刻过了多久
  console.log(t)
  // 3. 把时间数值传入到材质的 uniforms 变量中
  material.uniforms.myTime.value = t / 10 // 为了让旋转慢一些(200 -> 20度)

  renderer.render(scene, camera)
  controls.update()
  requestAnimationFrame(renderLoop)
}

init()
createBasic()
renderLoop()


标签:1.0,geometry,THREE,vec4,new,着色器
From: https://www.cnblogs.com/zsnhweb/p/17824851.html

相关文章

  • OpenGL 着色器详解
    1.GLSL语言glsl语言是用来编写着色器的,通过一段一段包含main函数的程序片段,告诉渲染引擎怎么去渲染内容。glsl语言的语法有点类似c语言风格,只是增加了一些特有的关键字来修饰变量,下面是一个着色器基本的程序结构:首先声明的是GLSL的版本号和模式,然后就是声明变量。像其他语言......
  • OpenGL——着色器设置绘制对象颜色及透明度
     {https://blog.csdn.net/weixin_46568899/article/details/129217018} {。着色器的编写结构如下:1.声明版本(很重要,版本不对的话会得到不同的绘制结果)。2.使用location指定输入变量。3.定义输入输出变量(用in和out关键字)。4.main函数。以下是一个简单的例子:   constcha......
  • openGL学习<四>、着色器
    1//2//Createdbysryon2021/7/6.3//4#include<glad/glad.h>5#include<GLFW/glfw3.h>6#include<iostream>7#include<cmath>8usingnamespacestd;910voidframebuffer_size_callback(GLFWwindow*window,......
  • OpenGL入门——着色器类
    着色器的编写、编译、管理是个很繁琐的事。所以就需要写一个类,这个类可以从文件读取着色器源码,可以编译链接它们,可以对它们进行错误检测,可以设置Uniform值。 1.类的声明#pragmaonce#include<glad/glad.h>#include<string>#include<fstream>#include<sstream>#inc......
  • OpenGL入门——着色器
    前面几节简单使用了一下着色器 现在详细解释一下着色器和着色器语言(GLSL) 1.着色器着色器是运行在GPU上的小程序,它们之间不能互相通信,唯一的沟通只有输入和输出。 2.GLSL着色器的开头是声明版本,接着是输入和输出变量、uniform和main函数。每个着色器的入口点都是mai......
  • 表面着色器的一些问题
    问题①:在表面着色器中修改顶点信息——#pragmasurfacesurfLambertvertex:vert/***********/voidvert(inoutappdata_fullv,outInputo){UNITY_INITIALIZE_OUTPUT(Input,o);/**********/}appdata_full是unity给我们的输入结构体,另外还有一些unity......
  • 记录--Threejs-着色器实现一个水波纹
    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助hree.js是一个基于WebGL的JavaScript3D库,用于创建和渲染3D图形场景。一、图像渲染过程1、webGLwebGL:WebGL是一种基于JavaScriptAPI的图形库,它允许在浏览器中进行高性能的3D图形渲染。webGL的......
  • 如何向顶点着色器传颜色?
    stringvs=@"#version330layout(location=og_positionVertexLocation)invec4position;uniformmat4og_modelViewPerspectiveMatrix;voidmain()......
  • webgl 系列 —— 着色器语言
    其他章节请看:webgl系列着色器语言本篇开始学习着色器语言——GLSL全称是GraphicsLibraryShaderLanguage(图形库着色器语言)GLSL是一门独立的语言,和其他语言一样有自己的变量、运算符、函数、循环(for)、控制语句(if)、函数、数组等等。GLSL比较简单。其专门用于编写着色器,舍......
  • 【Unity3D】固定管线着色器二
    1前言​固定管线着色器一中介绍了Shader中外部属性、光照、贴图等基础用法,本文将进一步讲解固定管线着色器,介绍正面与反面剔除、Alpha测试、深度测试、混合、渲......