gpt4 book ai didi

javascript - 使用 three.js 将 PointLight 信息传递给自定义着色器

转载 作者:搜寻专家 更新时间:2023-11-01 04:16:58 24 4
gpt4 key购买 nike

我想创建类似 undulating sphere 的效果在 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 着色器时,我不想编写自己的 Phong 着色器。

问题 3:如果第 2 级和第 3 级之间没有这样的中间地带,而我只需要进入第 3 级,那么最好的方法是什么?我是否将光的位置、强度等作为制服传递,进行顶点/法线修改,然后最终显式编写 Phong 着色计算?

最佳答案

用 three.js 做你想做的事情非常简单

我不确定它在你的 Q[] 中的什么位置

第一季度

  1. 您仍在使用着色器,这是其他人为您编写的。您只能访问界面。在幕后,调用 MeshBasicMaterial 之类的东西实际上可以根据您输入的内容编译不同的着色器。比如,它可能不会处理任何 UVS,如果没有调用贴图等,它可能不会将它们包含在着色器中。您仍然可以根据调用的内容影响 GPU。
  2. 如果您指的是着色器 block ,可以在这里破解一些东西,但这非常麻烦。我的建议是研究代码,例如 phong 着色,然后使用 block 开始逐个构建您自己的代码。看看什么进什么出。
  3. 无需传递属性。三、ShaderMaterial 并不是完全从头开始构建的。它仍然为您提供了相当多的东西,并且有一堆属性,您可以设置这些属性以获得更多。一个的基本属性是为您设置的,即。您不声明“属性 vec3 位置”。如果您像 West 说明的那样勾选照明标志,您可以获得一个包含场景中所有灯光的数组,但是如果您正在构建粒子着色器或某些屏幕效果,则可以忽略它。几乎每个着色器都设置为读取一些基本属性,如“位置”、“uv”、“正常”。您可以轻松地在程序网格上添加您自己的,但在实际模型上这并非微不足道。默认情况下,您会获得一些制服,获得整套 MVP 矩阵、“cameraPosition”等。从那里编写 phong 着色器非常简单。

现在看看你会怎么做。假设您正在学习本教程并且拥有此着色器:

// same name and type as VS
varying vec3 vNormal;

void main() {


//this is hardcoded you want to pass it from your environment
vec3 light = vec3(0.5, 0.2, 1.0);//it needs to be a uniform

// ensure it's normalized
light = normalize(light);//you can normalize it outside of the shader, since it's a directional light

// calculate the dot product of
// the light to the vertex normal
float dProd = max(0.0,
dot(vNormal, light));

// feed into our frag colour
gl_FragColor = vec4(dProd, // R
dProd, // G
dProd, // B
1.0); // A

}

这是您需要做的:

GLSL

uniform vec3 myLightPos;//comes in
void main(){
vec3 light = normalize(myLightPos);//but you better do this in javascript and just pass the normalized vec3
}

Javascript

new THREE.ShaderMaterial({
uniforms:{
myLightPos:{
type:"v3",
value: new THREE.Vector3()
}
},
vertexShader: yourVertShader,
fragmentShader: yourFragmentShader

});

关于javascript - 使用 three.js 将 PointLight 信息传递给自定义着色器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23899887/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com