将PointLight Info传递给具有three.js的自定义着色器

dmo*_*nch 5 javascript glsl webgl three.js

我想创建一个类似于Aerotwist Tutorial中描述的起伏球体的效果.但是,在教程中,Paul在片段着色器中创建了一个假的GLSL硬编码光 - 而是我想将信息从three.js PointLight实例传递到我的着色器,操纵顶点/法线,然后执行Phong着色.

在对three.js中的场景进行着色时,我对GPU考虑的各种级别的理解如下(例如,坚持使用Phong):

  1. 没有GPU考虑:使用MeshPhongMaterial并且不用担心着色器.这非常简单,但不会让你在GPU方面乱七八糟.
  2. 一些GPU考虑因素:使用ShaderLib Phong着色器.这允许您将着色计算推送到GPU,但由于它们是预先编写的,因此您无法对顶点位置,法线或照明计算进行任何自定义修改.
  3. 完整的GPU管理:使用ShaderMesh并从头开始编写着色器.这为您提供了完全自定义,但也强制您明确传递着色器所需的属性和制服.

Q1:上述理解准确吗?

Q2:有没有办法在2级和3级之间做点什么?我希望能够自定义着色器来混淆顶点位置/法线,但是当一个非常好的着色器包含在three.js中时,我不想编写自己的Phong着色器.

Q3:如果2级和3级之间没有这样的中间地带,我需要进入3级,那么最好的方法是什么呢?我是否将光的位置,强度等作为制服传递,进行顶点/正常修改,然后最后明确写出Phong着色计算?

Wes*_*ley 2

问题一:正确。虽然,该论坛上的一些用户已经发布了黑客攻击的解决方法MeshPhongMaterial,但这并不是最初的意图。

Q2和Q3:看一下ShaderLib.js,你会看到“Normal Map Shader”。这是一个适合您的完美模板。是的,您可以复制/重命名它并根据您的喜好进行修改。

它使用基于 Phong 的照明模型,甚至可以为您访问场景灯光。你这样称呼它:

var shader = THREE.ShaderLib[ "normalmap" ];

var uniforms = THREE.UniformsUtils.clone( shader.uniforms );

. . .

var parameters = {
    fragmentShader: shader.fragmentShader,
    vertexShader: shader.vertexShader,
    uniforms: uniforms,
    lights: true // set this flag and you have access to scene lights
};

var material = new THREE.ShaderMaterial( parameters );
Run Code Online (Sandbox Code Playgroud)

请参阅以下示例:http:// Threejs.org/examples/webgl_materials_normalmap.htmlhttp:// Threejs.org/examples/webgl_materials_normalmap2.html

要了解要遵循的编码模式,请参阅ShaderLib.jsShaderChunk.js

三.js r.67