Javascript 使用three.js将点光源信息传递给自定义着色器
我想创建一个效果,如中所述。但是,在教程中,Paul在片段着色器中创建了一个伪GLSL硬编码灯光-相反,我希望将信息从three.js PointLight实例传递到我的着色器,操纵顶点/法线,然后执行Phong着色 我对在three.js中为场景着色时GPU考虑的各个级别的理解如下(例如,坚持使用Phong):Javascript 使用three.js将点光源信息传递给自定义着色器,javascript,three.js,glsl,webgl,Javascript,Three.js,Glsl,Webgl,我想创建一个效果,如中所述。但是,在教程中,Paul在片段着色器中创建了一个伪GLSL硬编码灯光-相反,我希望将信息从three.js PointLight实例传递到我的着色器,操纵顶点/法线,然后执行Phong着色 我对在three.js中为场景着色时GPU考虑的各个级别的理解如下(例如,坚持使用Phong): 无需考虑GPU:使用一个图形处理器,不必担心着色器。这是超级容易,但不让你在GPU方面乱搞 一些GPU注意事项:使用Phong着色器。这允许您将着色计算推送到GPU,但由于它们是预先编
问题3:如果在2级和3级之间没有这样的中间地带,我只需要进入3级,那么最好的方法是什么?我是否将灯光的位置、强度等作为制服传递,进行顶点/法线修改,然后最终明确写入Phong着色计算?Q1:正确。尽管该网站上的一些用户发布了黑客破解的解决方案,但这并不是他们的初衷 Q2和Q3:查看
ShaderLib.js
,您将看到“法线贴图着色器”。这是一个完美的模板为您。是的,您可以复制/重命名它,并根据自己的喜好进行修改
它使用基于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 );
参见以下示例:和
有关要遵循的编码模式,请参见ShaderLib.js
和ShaderChunk.js
three.js r.67使用three.js做你想做的事情非常简单 我不确定它落在你的Q[] Q1
// 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
Javascript
new THREE.ShaderMaterial({
uniforms:{
myLightPos:{
type:"v3",
value: new THREE.Vector3()
}
},
vertexShader: yourVertShader,
fragmentShader: yourFragmentShader
});
非常感谢您和@pailhead的详细解释!我最终使用了更简单的“phong”ShaderLib对象作为模板。我对vertexShader做了一些轻微的修改,以扰动每个顶点,并使用fragmentShader未作更改,将“lights”标志设置为true,如您所建议的。
new THREE.ShaderMaterial({
uniforms:{
myLightPos:{
type:"v3",
value: new THREE.Vector3()
}
},
vertexShader: yourVertShader,
fragmentShader: yourFragmentShader
});