three.js自定义材质各向异性

前言

二、vue中模型(gltf)使用步骤

1.引入文件

2.获取切线空间

3.自定义纹理

例图


前言

各向异性

各向异性是指物质的全部或部分化学、物理等性质随着方向的改变而有所变化,在不同的方向上呈现出差异的性质。各向异性是材料和介质中常见的性质,在尺度上有很大差异,从晶体到日常生活中各种材料,再到地球介质,都具有各向异性。值得注意的是,各向异性与非均匀性是从两个不同的角度对物质进行的描述,不可等同。


一、各向异性

          //灯光顶点vec3 worldLightDir = normalize(myLight);//Blinn反射高光方向vec3 reflectDir  = normalize(worldLightDir + cameraPosition);//副切线(与反射高光)点乘高光float BS_Dot = dot( vbinormal, reflectDir );//反转副切线点乘高光float BS_Dot_Rev = 1.0 -  BS_Dot;//获得副切线点乘高光暗部float BS_Dot_Dark = smoothstep(-1.0, 0.0, BS_Dot);//获得拉丝高光渐变float Ramp_Anisotropy = BS_Dot_Rev * BS_Dot_Dark;//设置高光范围float spec = pow(Ramp_Anisotropy, 5.0);//设置高光强度float Specular = spec * 1.0;//输出 高光着色vec3 Anisotropy = Specular * vec3(1,1,1);

二、vue中模型(gltf)使用步骤

1.引入文件

代码如下(示例):

import * as THREE from 'three'
import geoList from './js/geoList'
import TrackballControls from './js/trackballControls'//控制器
import Stats from './js/stats'//刷新率展示
import detector from './js/detector'//监测是否支持canvas及webgl
import { computeMikkTSpaceTangents } from 'three/examples/jsm/utils/BufferGeometryUtils.js'
import { wasm,isReady,ready,generateTangents } from 'three/examples/jsm/libs/mikktspace.module.js'//转切线空间
import { VertexTangentsHelper } from 'three/examples/jsm/helpers/VertexTangentsHelper.js'
import { GLTFLoader } from 'three/examples/jsm/loaders/GLTFLoader'

2.获取切线空间

代码如下(示例):

this.initMikkTSpace(cb=>{let MikkTSpace = {wasm:wasm,isReady:isReady,generateTangents:generateTangents}//为geo01创建切线空间computeMikkTSpaceTangents(geo01,MikkTSpace)let material01 = this.initShader(geo01.attributes.tangent.array,light)this.material = material01;let cube01 = new THREE.Mesh( geo01 , material01)cube01.castShadow = true; //default is false 投射阴影cube01.receiveShadow = true; //default false 接收阴影cube01.position.set(0,6,0)scene.add( cube01 );//加载模型,为模型创建切线空间let loader = new GLTFLoader();loader.load('/static/hair2/scene.gltf', (gltf)=>{gltf.scene.position.set(-14,2,-2);gltf.scene.scale.set(0.5,0.5,0.5);gltf.scene.name = 'hair01'this.hair = gltf.scene;scene.add(gltf.scene)gltf.scene.traverse((gltf2)=> {if(gltf2.type === 'Mesh'){computeMikkTSpaceTangents(gltf2.geometry,MikkTSpace)//添加自定义纹理let material =             this.initShader(gltf2.geometry.attributes.tangent.array,light)gltf2.material = material}})});
})async initMikkTSpace(cb){await readycb()}

3.自定义纹理

代码如下(示例):

initShader(tangent,myLight){//需要切线与光位置let textureLoader = new THREE.TextureLoader();let vertexShader = `varying vec3 vNormal;varying vec2 vUv;attribute vec4 tangent;varying vec3 vtangent;varying vec3 vbinormal;varying mat3 tbn;uniform vec3 myLight;varying vec3 lightToPos;${THREE.ShaderChunk[ "common" ]}${THREE.ShaderChunk[ "bsdfs" ]}${THREE.ShaderChunk[ "shadowmap_pars_vertex" ]}void main(){${THREE.ShaderChunk['beginnormal_vertex']}${THREE.ShaderChunk['defaultnormal_vertex']}${THREE.ShaderChunk[ "begin_vertex" ]}${THREE.ShaderChunk[ "project_vertex" ]}${THREE.ShaderChunk[ "worldpos_vertex" ]}${THREE.ShaderChunk[ "shadowmap_vertex" ]}vec3 nowPoint = vec3((modelViewMatrix * vec4( position, 1.0 )).xyz);lightToPos = myLight - nowPoint;vNormal = normalize(normalMatrix * normal);vec3 vTangent = normalize( normalMatrix * tangent.xyz );vec3 vBinormal = normalize(cross( vNormal, vTangent ) * tangent.w);tbn = mat3(vTangent, vBinormal, vNormal);vUv = uv;vtangent = vTangent;vbinormal = vBinormal;gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );}`let fragmentShader = `// uniform vec3 light;varying vec3 vNormal;varying vec3 lightToPos;varying vec2 vUv;varying vec3 vtangent;varying vec3 vbinormal;uniform vec3 myLight;uniform vec3 myCamera;uniform sampler2D u_texture;uniform sampler2D u_textureNormal;varying mat3 tbn;${THREE.ShaderChunk[ "common" ]}${THREE.ShaderChunk[ "packing" ]}${THREE.ShaderChunk[ "bsdfs" ]}${THREE.ShaderChunk[ "lights_pars_begin" ]}${THREE.ShaderChunk[ "shadowmap_pars_fragment" ]}${THREE.ShaderChunk[ "shadowmask_pars_fragment" ]}//获取纹理颜色vec3 mygetPixelColor(sampler2D mytexture) {return texture2D(mytexture, vUv).rgb;}void main(){//这里可以使用法线贴图,我没有贴图直接用的颜色// vec3 normalColor = mygetPixelColor(u_textureNormal);vec3 normalColor = vec3(0,0,1);normalColor = normalColor * 2.0 - 1.0;vec3 anynormalColor = normalize(tbn * normalColor);//处理光照float diff = max( dot(anynormalColor , normalize(lightToPos)) , 0.0 );vec3 diffuse = diff * vec3(1,1,1);//diff * lightColor// vec3 textureColor = mygetPixelColor(u_texture);vec3 textureColor = vec3(0,0.22,0.88);vec3 addDiffuse = textureColor + diffuse;// 添加阴影vec3 shadowColor = vec3(0,0,0);vec3 addShadow = mix( shadowColor , addDiffuse ,getShadowMask());//各向异性计算//灯光顶点vec3 worldLightDir = normalize(myLight);//Blinn反射高光方向vec3 reflectDir  = normalize(worldLightDir + cameraPosition);//副切线(与反射高光)点乘高光float BS_Dot = dot( vbinormal, reflectDir );//反转副切线点乘高光(默认1.0-BS_Dot 越小则光环越小)float BS_Dot_Rev = 1.0 -  BS_Dot;//获得副切线点乘高光暗部float BS_Dot_Dark = smoothstep(-1.0, 0.0, BS_Dot);//获得拉丝高光渐变float Ramp_Anisotropy = BS_Dot_Rev * BS_Dot_Dark;//设置高光范围float spec = pow(Ramp_Anisotropy, 5.0);//设置高光强度float Specular = spec * 1.0;//输出 高光着色vec3 Anisotropy = Specular * vec3(1,1,1);//输出最终颜色gl_FragColor = vec4( mix(Anisotropy , addShadow , 0.8) , 1);}`// L是入射光照矢量,V是视角方向,T是切线,Ns是高光系数,Ks是高光强度。//着色器材质let sm = new THREE.ShaderMaterial({uniforms: THREE.UniformsUtils.merge( [THREE.UniformsLib[ "lights" ],{opacity:  { type: 'f', value: 1.0 },// tangent:  { value: tangent },myLight:  { value: myLight.position},myCamera: { value: this.camera.position},u_texture:{value:textureLoader.load(require('../../assets/brickwall.jpg'))},u_textureNormal:{value:textureLoader.load(require('../../assets/brickwall_normal.jpg'))},}] ),vertexShader: vertexShader,fragmentShader: fragmentShader,// side:THREE.DoubleSide,//双面渲染side: THREE.FrontSide,lights: true});return sm},

例图

three.js自定义材质各向异性相关推荐

  1. three.js自定义材质 切线空间及阴影

    three.js自定义材质 切线空间及阴影 前言 法线贴图中的法线向量定义在切线空间中,在切线空间中,法线永远指着正z方向.切线空间是位于三角形表面之上的空间:法线相对于单个三角形的本地参考框架.它就 ...

  2. Cesium中自定义材质material

    文章转自: https://blog.csdn.net/weixin_38676065/article/details/126123975 学习参考文章:https://github.com/Anal ...

  3. Cesium 1.02.0 及以上版本下自定义材质报错:[Cesium WebGL] ERROR: 0:1: ‘varying‘ : Illegal use of reserved word

    Cesium 1.02.0 及以上版本下自定义材质报错:[Cesium WebGL] ERROR: 0:1: 'varying' : Illegal use of reserved word 报错原因 ...

  4. threejs 三面体_Three.js 自定义了一个几何体

    几何体本质: 立方体几何体BoxGeometry本质上就是一系列的顶点构成,只是Threejs的APIBoxGeometry把顶点的生成细节封装了,用户可以直接使用. 比如一个立方体网格模型,有6个面 ...

  5. 使用自定义材质球,实现NGUI屏幕溶解和灰显

    UITexture实现的溶解: 重设UITeture的材质球实现上述效果,把当前屏幕渲染的Texture2D丢给UITexture,即可实现UI屏幕特效,背景模糊等都可以. 难点主要是实时刷新问题 解 ...

  6. 原生html js css绘制折现图,HTML5教程 Chart.js自定义提示折线图

    本篇教程探讨了HTML5教程 Chart.js自定义提示折线图,希望阅读本篇文章以后大家有所收获,帮助大家HTML5+CSS3从入门到精通 . < var randomScalingFactor ...

  7. js自定义函数及参数问题

    js自定义函数的过程中,往往我们希望指定一些参数的默认值 很容易的会写出如下的js 方法 function test(a,b,c=1,d='id'){ return 1; } 但是定义完之后,浏览器会 ...

  8. html 自定义js,js 自定义事件

    js怎么自定义事件,并能让用on事件监听 你这个问题全部内容应该是如下吧: 在视频播放的时候,能够用on监听事件的触发,如下: player.on('pause',function(){ consol ...

  9. Ajax异步请求(重渲染DOM元素时,如何自动调用并执行JS自定义函数【含代码】)- 案例篇

    文章目录 Ajax异步请求(重渲染DOM元素时,如何自动调用并执行JS自定义函数[含代码])- 案例篇 效果截图: 重要代码: 附:全部HTML代码: Ajax异步请求(重渲染DOM元素时,如何自动调 ...

  10. Vue.js自定义指令的用法与实例

    市面上大多数关于Vue.js自定义指令的文章都在讲语法,很少讲实际的应用场景和用例,以致于即便明白了怎么写,也不知道怎么用.本文不讲语法,就讲自定义指令的用法. 自定义指令是用来操作DOM的.尽管Vu ...

最新文章

  1. 【串讲总结】RNN、LSTM、GRU、ConvLSTM、ConvGRU、ST-LSTM
  2. Service Worker
  3. Flashback Query笔记
  4. postfix导入extmail.sql时报错
  5. Pytorch入门.pptx
  6. VTK:可视化算法之LOx
  7. 学习 WCF (3)--开发WCF客户程序
  8. mysql 定时器停止_mysql事件【定时器】
  9. TLS/SSL握手过程
  10. 容器编排技术 -- Kubernetes从零开始搭建自定义集群
  11. 索引体积_第16期:索引设计(MySQL 的索引结构)
  12. 一文详解 Serverless 技术选型
  13. 渗透杂记-2013-07-13 关于SMB版本的扫描
  14. 分布式任务调度框架设计与实现解读(1)
  15. 通向Golang的捷径【20. 使用 Go 语言的 GAE】
  16. csgo靠谱的开箱网站有哪些?csgo开箱网站大全
  17. 雷军博客分享-日本的电饭煲到底好在哪?
  18. 计算机视觉可解释性——卷积神经网络中间层的可视化
  19. 金山中学 rugular SRM 04 ——纪念我的第一次Ak
  20. aes相关资料整理及代码C/C++

热门文章

  1. vue-cli脚手架build目录中的webpack.base.conf.js配置文件
  2. Maven项目中非resources文件夹中的配置文件不生效的解决办法
  3. Mac一体机忘记开机密码怎么办?
  4. 中小学教师计算机培训心得,小学教师信息技术培训心得体会2篇
  5. 二手房数据分析预测系统
  6. 水星怎么设置网速最快_水星怎么设置路由器的网速
  7. http 405错误
  8. Python爬虫QQ空间好友说说
  9. 写一本技术书能赚多少钱
  10. 1.5.12、面向对象下__接口Implement,接口的使用