当前位置: 首页 > news >正文

Three.js Tri-panner (三面贴图) 材质 两种实现方式

文章目录

        • 介绍
          • 自定义shader
          • NodeMaterial
          • 修复:骨骼材质特殊处理
          • 修复:使用法相贴图时整体变色

请添加图片描述

在这里插入图片描述

介绍

Tri-panner 在babylonjs中有支持 但是three.js目前的基础材质并不支持
需要自己定义shader 或者使用目前还没有什么完善的文档的 NodeMaterial

下面展示两种实现方式

自定义shader
/*** @description: 替换三角面贴图  https://doc.babylonjs.com/toolsAndResources/assetLibraries/materialsLibrary/triPlanarMat* @param {SingleMaterialMesh} mesh* @return {*}*/
export const useTriplanarMapping = (mesh: SingleMaterialMesh) => {const material = mesh.material.clone();mesh.material = material;material.map!.wrapS = THREE.RepeatWrapping;material.map!.wrapT = THREE.RepeatWrapping;material.onBeforeCompile = (shader) => {shader.vertexShader = shader.vertexShader.replace("#include <common>",`#include <common>varying vec3 tripPosition;varying vec3 tripNormal;`);shader.vertexShader = shader.vertexShader.replace("#include <fog_vertex>",`#include <fog_vertex>vec4 tripPosition4 = modelMatrix * vec4(position,1.) ;tripPosition = tripPosition4.xyz;tripNormal = normal * normalMatrix;vec3 world_space_normal = vec3(modelMatrix * vec4(normal, 0.0));tripNormal = normal;`);shader.fragmentShader = shader.fragmentShader.replace("#include <common>",`#include <common>varying vec3 tripPosition;varying vec3 tripNormal;vec3 blendNormal(vec3 normal){vec3 blending = abs( normal );blending = normalize(max(blending, 0.00001)); // Force weights to sum to 1.0 float b = (blending.x + blending.y + blending.z);blending /= vec3(b, b, b);return blending;}vec3 triplanarMapping (sampler2D tex, vec3 normal, vec3 position) {vec3 normalBlend = blendNormal(normal);vec3 xColor = texture(tex, position.yz).rgb;vec3 yColor = texture(tex, position.xz).rgb;vec3 zColor = texture(tex, position.xy).rgb;return (xColor * normalBlend.x + yColor * normalBlend.y + zColor * normalBlend.z);}`);shader.fragmentShader = shader.fragmentShader.replace("#include <map_fragment>",`#include <map_fragment>diffuseColor.rgb = vec3(triplanarMapping( map ,tripNormal,tripPosition));`);// shader.fragmentShader = shader.fragmentShader.replace(//     "#include <color_fragment>",//     `//     #include <color_fragment>//     diffuseColor.rgb = vec3(triplanar_mapping( map ,tripNormal,tripPosition,1.0));// `// );};
};
NodeMaterial

这是threejs新系统充满未来 目前还没有一个完善的文档 并且不太稳定 r132的时候支持这个材质 r138就被删除了 一些api也都有变化 可以先参考 https://raw.githack.com/sunag/three.js/dev-nodes-doc/docs/index.html#manual/en/introduction/How-to-use-node-material

import {MeshBasicNodeMaterial,texture,triplanarTexture,
} from "three/examples/jsm/nodes/Nodes.js";
import { nodeFrame } from "three/examples/jsm/renderers/webgl/nodes/WebGLNodes.js";const skyMat = new MeshBasicNodeMaterial();skyMat.colorNode = triplanarTexture(texture(this.helper.loadTexture("/public/textures/coral_stone_wall_diff_1k.jpg",(map) => {map.colorSpace = THREE.SRGBColorSpace;map.wrapS = THREE.RepeatWrapping;map.wrapT = THREE.RepeatWrapping;}))
);
skyMat.side = THREE.DoubleSide;const sky = new THREE.Mesh(new THREE.SphereGeometry(2, 32, 15), skyMat);
scene.add(sky);animation() {nodeFrame.update();
}

要注意每一次render 同时调用 nodeFrame.update(); 否则报错

修复:骨骼材质特殊处理

这个问题需要根据three版本进行区别处理

r160版本 使用的是 position
r155版本使用的是 nodeUniform2 * vec4( 忘了叫什么了, 1.0 )
总之每个版本可能不一样 因为 节点系统正在开发 需要对应版本对应处理

r160版本写法如下

material.onBeforeCompile = (shader) => {material.vertexShader = shader.vertexShader.replace("#include <skinning_vertex>",`#include <skinning_vertex>nodeVarying2 = (modelMatrix * vec4(transformed,1.0)).xyz;`);
};

r155版本写法如下

material.onBeforeCompile = (shader) => {material.vertexShader = shader.vertexShader.replace("#include <skinning_vertex>",`#include <skinning_vertex>nodeVarying2 = ( nodeUniform2 * vec4( transformed, 1.0 ) );`);};
修复:使用法相贴图时整体变色

这个问题nodeMaterial 没找到如何解决 下面给出自定义材质的解决方案

export const useTriplanarMapping = (mesh) => {const material = mesh.material.clone();mesh.material = material;material.map.colorSpace = THREE.SRGBColorSpace;material.map.wrapS = THREE.RepeatWrapping;material.map.wrapT = THREE.RepeatWrapping;if (material.normalMap) {material.normalMap.colorSpace = THREE.SRGBColorSpace;material.normalMap.wrapS = THREE.RepeatWrapping;material.normalMap.wrapT = THREE.RepeatWrapping;}material.onBeforeCompile = (shader) => {shader.vertexShader = shader.vertexShader.replace("#include <common>",`#include <common>varying vec3 tripPosition;varying vec3 tripNormal;`);shader.vertexShader = shader.vertexShader.replace("#include <skinning_vertex>",`#include <skinning_vertex>vec4 tripPosition4 = modelMatrix * vec4(transformed,1.) ;tripPosition = tripPosition4.xyz;tripNormal = normal * normalMatrix;vec3 world_space_normal = vec3(modelMatrix * vec4(normal, 0.0));tripNormal = normal;`);shader.fragmentShader = shader.fragmentShader.replace("#include <common>",`#include <common>varying vec3 tripPosition;varying vec3 tripNormal;vec3 blendNormal(vec3 normal){vec3 blending = abs( normal );blending = normalize(max(blending, 0.00001)); // Force weights to sum to 1.0 float b = (blending.x + blending.y + blending.z);blending /= vec3(b, b, b);return blending;}vec3 triplanarMapping (sampler2D tex, vec3 normal, vec3 position) {vec3 normalBlend = blendNormal(normal);vec3 xColor = texture(tex, position.yz).rgb;vec3 yColor = texture(tex, position.xz).rgb;vec3 zColor = texture(tex, position.xy).rgb;return (xColor * normalBlend.x + yColor * normalBlend.y + zColor * normalBlend.z);}`);shader.fragmentShader = shader.fragmentShader.replace("#include <map_fragment>",`#include <map_fragment>diffuseColor.rgb = vec3(triplanarMapping( map ,tripNormal,tripPosition));`);shader.fragmentShader = shader.fragmentShader.replace("#include <normal_fragment_maps>",`#include <normal_fragment_maps>normal = vec3(triplanarMapping( normalMap ,tripNormal,tripPosition));normal = normalize( tbn * normal );`);};
};

相关文章:

  • 舞动微服务的安全舞伴:服务熔断与服务降级的精妙演绎
  • C#,入门教程(24)——类索引器(this)的基础知识
  • OPENGL光线追踪
  • Kafka-服务端-DelayedOperationPurgatory
  • docker:Java通过nginx获取客户端的真实ip地址
  • 【云原生之kubernetes实战】在k8s环境下部署Mikochi文件管理工具
  • 【STM32调试】寄存器调试不良问题记录持续版
  • etcd安装
  • Idea 开发环境不断切换git代码分支导致冲掉别人代码
  • 运用分布式锁 redisson
  • 第十五章 : Spring Cloud全链路监控(Pinpoint实战)
  • Docker(二)安装指南:主要介绍在 Linux 、Windows 10 和 macOS 上的安装
  • 准备的一些爬虫面试题
  • 《WebKit 技术内幕》学习之七(2): 渲染基础
  • IPv6自动隧道---6to4中继
  • 08.Android之View事件问题
  • 8年软件测试工程师感悟——写给还在迷茫中的朋友
  • CentOS 7 防火墙操作
  • es6(二):字符串的扩展
  • iOS 颜色设置看我就够了
  • IOS评论框不贴底(ios12新bug)
  • Javascript 原型链
  • js如何打印object对象
  • nginx(二):进阶配置介绍--rewrite用法,压缩,https虚拟主机等
  • Python 反序列化安全问题(二)
  • unity如何实现一个固定宽度的orthagraphic相机
  • 百度贴吧爬虫node+vue baidu_tieba_crawler
  • 从PHP迁移至Golang - 基础篇
  • 关于Android中设置闹钟的相对比较完善的解决方案
  • 远离DoS攻击 Windows Server 2016发布DNS政策
  • [Shell 脚本] 备份网站文件至OSS服务(纯shell脚本无sdk) ...
  • 阿里云ACE认证之理解CDN技术
  • #绘制圆心_R语言——绘制一个诚意满满的圆 祝你2021圆圆满满
  • (1/2)敏捷实践指南 Agile Practice Guide ([美] Project Management institute 著)
  • (13)[Xamarin.Android] 不同分辨率下的图片使用概论
  • (2/2) 为了理解 UWP 的启动流程,我从零开始创建了一个 UWP 程序
  • (vue)el-checkbox 实现展示区分 label 和 value(展示值与选中获取值需不同)
  • (四)Controller接口控制器详解(三)
  • (原創) 物件導向與老子思想 (OO)
  • (转)IIS6 ASP 0251超过响应缓冲区限制错误的解决方法
  • (转)shell调试方法
  • .NET 5种线程安全集合
  • .Net CF下精确的计时器
  • .NET Compact Framework 多线程环境下的UI异步刷新
  • .NET/C# 避免调试器不小心提前计算本应延迟计算的值
  • ??在JSP中,java和JavaScript如何交互?
  • @cacheable 是否缓存成功_让我们来学习学习SpringCache分布式缓存,为什么用?
  • @synthesize和@dynamic分别有什么作用?
  • [ IO.File ] FileSystemWatcher
  • [AHOI2009]中国象棋 DP,递推,组合数
  • [Android]竖直滑动选择器WheelView的实现
  • [AutoSAR系列] 1.3 AutoSar 架构
  • [boost]使用boost::function和boost::bind产生的down机一例
  • [C++] 如何使用Visual Studio 2022 + QT6创建桌面应用
  • [C++]priority_queue的介绍及模拟实现