Three.js在不改变原有材质的基础之上,增加额外的着色器逻辑

Posted hpugisers

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Three.js在不改变原有材质的基础之上,增加额外的着色器逻辑相关的知识,希望对你有一定的参考价值。

有时候在做特效的时候,我们想在原有着色器渲染之上来增加特效。不想使用ShaderMaterail材质类,如果使用该类书写着色器逻辑,会改变原有的渲染效果。

原理利用着色器是字符串的本质,将原有的main函数提取,替换掉,重新定义main函数,将替换掉的main函数在新的main函数中执行。
1、替换之前

2、替换之后(看末尾逻辑)

一、主要代码封装

/*
 * @Author: gjw
 * @Date: 2020-07-30 16:09:32
 * @LastEditTime: 2020-07-30 17:05:17
 * @LastEditors: Please set LastEditors
 * @Description: 在不改变原有着色器的逻辑的基础之上。增加着色器的逻辑
 * @FilePath: \\KEngine\\src\\tools\\ShaderSourceUtils.ts
 */ 
import UniformsUtils from 'three';
class ShaderSourceUtils
     constructor()
     public static replaceMain(shaderSourceString:string, renamedMain:string)
        renamedMain = 'void ' + renamedMain + '()';
        return shaderSourceString.replace(/void\\s+main\\s*\\(\\s*(?:void)?\\s*\\)/g, renamedMain);
     
     public static mergeUniforms(oldUniforms:any,addNewUniforms:any)
        return UniformsUtils.merge([oldUniforms,addNewUniforms]);
     

export ShaderSourceUtils

二、代码使用示例(借助onBeforeCompile函数,mesh在渲染前会执行该函数)

        materialBox.onBeforeCompile=function( shaderobject, renderer )
            shaderobject.uniforms=ShaderSourceUtils.mergeUniforms(shaderobject.uniforms,
                test:
                    value:1.0
                
            )
            shaderobject.fragmentShader=ShaderSourceUtils.replaceMain(shaderobject.fragmentShader,'czm_testMain');
            shaderobject.fragmentShader+='\\nvarying float test;\\n'+
                                          'void main()\\n'+
                                             ' czm_testMain();\\n'+
                                          '\\n';
        

以上是关于Three.js在不改变原有材质的基础之上,增加额外的着色器逻辑的主要内容,如果未能解决你的问题,请参考以下文章

Three.js在不改变原有材质的基础之上,增加额外的着色器逻辑

three.js 改变材质上的纹理

three.js 着色器材质基础

Three.js开发指南---使用three.js的材质(第四章)

使用Three.js的材质

使用Three.js的材质