【问题标题】:How to give vertex shader to a geometry without changing the material in threeJS?如何在不改变threeJS中的材质的情况下为几何体提供顶点着色器?
【发布时间】:2019-12-31 22:24:09
【问题描述】:

我正在尝试使用我的顶点着色器修改一些几何图形,它基本上将某些线性变换应用于几何图形的每个顶点,从而改变其形状。问题是我不知道如何使用它来启用 phong 照明和纹理。一旦我通过材质 API 传递我的顶点着色器,它就会自动呈现红色并且一切看起来都是平坦的。看起来这里没有进行光照计算。请帮忙。

这是我将顶点着色器应用于立方体的演示。 https://jsfiddle.net/6593Lyve/4/

void main()
{
    vec3 p = position.xyz;
    float new_x = p.x*a11 + p.y*a12;
    float new_y = p.x*a21 + p.y*a22;
    gl_Position = projectionMatrix * modelViewMatrix * vec4(new_x, new_y, p.z, 1.0);
}

【问题讨论】:

  • 如果您想通过自定义顶点变换保持threejs 的phong 光照完整,您可能希望修改现有着色器,而不是从头开始编写着色器。请参阅此示例:threejs.org/examples/…,它会进行实例化,但同样可以单独转换顶点。
  • 如果您只想破解简单的照明,请参阅jsfiddle.net/6bg4qdhx/3。或者,请参阅threejs.org/examples/webgl_materials_modified.html
  • 您的问题中没有足够的代码来调试,而不必去异地查看您的代码,因此它与堆栈溢出无关。请将所有相关代码放入问题本身
  • 感谢@WestLangley,它符合我项目的目的,但是当值变为负数时看起来很奇怪jsfiddle.net/hr14w3tz/1
  • 更新顶点位置时,法线不再正确。您要么也需要更新法线,要么使用不需要法线的平面着色。

标签: graphics three.js fragment-shader vertex-shader


【解决方案1】:

如果您想要完整的材质功能,那么您应该使用 material.onBeforeCompile 修改现有着色器

const material = new THREE.MeshPhongMaterial(...);
material.onBeforeCompile = function(info) {
  // change info.vertexShader, info.fragmentShader, and/or info.uniforms here
  console.log(info)
};

如果你运行它,它会在 JavaScript 控制台中检查它,它会打印出类似的东西

{name: "MeshPhongMaterial", uniforms: {…}, vertexShader: "#define PHONG↵varying vec3 vViewPosition;↵#ifndef …clude <shadowmap_vertex>↵  #include <fog_vertex>↵}", fragmentShader: "#define PHONG↵uniform vec3 diffuse;↵uniform vec3 e…_alpha_fragment>↵ #include <dithering_fragment>↵}"}
name: "MeshPhongMaterial"
uniforms:
diffuse: {value: Color}
opacity: {value: 1}
map: {value: null}
uvTransform: {value: Matrix3}
alphaMap: {value: null}
specularMap: {value: null}
envMap: {value: null}
flipEnvMap: {value: -1}
reflectivity: {value: 1}
refractionRatio: {value: 0.98}
maxMipLevel: {value: 0}
aoMap: {value: null}
aoMapIntensity: {value: 1}
lightMap: {value: null}
lightMapIntensity: {value: 1}
emissiveMap: {value: null}
bumpMap: {value: null}
bumpScale: {value: 1}
normalMap: {value: null}
normalScale: {value: Vector2}
displacementMap: {value: null}
displacementScale: {value: 1}
displacementBias: {value: 0}
gradientMap: {value: null}
fogDensity: {value: 0.00025}
fogNear: {value: 1}
fogFar: {value: 2000}
fogColor: {value: Color}
ambientLightColor: {value: Array(3), needsUpdate: true}
lightProbe: {value: Array(9), needsUpdate: true}
directionalLights: {value: Array(1), properties: {…}, needsUpdate: true}
directionalShadowMap: {value: Array(0)}
directionalShadowMatrix: {value: Array(0)}
spotLights: {value: Array(0), properties: {…}, needsUpdate: true}
spotShadowMap: {value: Array(0)}
spotShadowMatrix: {value: Array(0)}
pointLights: {value: Array(0), properties: {…}, needsUpdate: true}
pointShadowMap: {value: Array(0)}
pointShadowMatrix: {value: Array(0)}
hemisphereLights: {value: Array(0), properties: {…}, needsUpdate: true}
rectAreaLights: {value: Array(0), properties: {…}, needsUpdate: true}
emissive: {value: Color}
specular: {value: Color}
shininess: {value: 30}
clippingPlanes: {value: null, needsUpdate: false}
__proto__: Object
vertexShader: "#define PHONG↵varying vec3 vViewPosition;↵#ifndef FLAT_SHADED↵   varying vec3 vNormal;↵#endif↵#include <common>↵#include <uv_pars_vertex>↵#include <uv2_pars_vertex>↵#include <displacementmap_pars_vertex>↵#include <envmap_pars_vertex>↵#include <color_pars_vertex>↵#include <fog_pars_vertex>↵#include <morphtarget_pars_vertex>↵#include <skinning_pars_vertex>↵#include <shadowmap_pars_vertex>↵#include <logdepthbuf_pars_vertex>↵#include <clipping_planes_pars_vertex>↵void main() {↵   #include <uv_vertex>↵   #include <uv2_vertex>↵  #include <color_vertex>↵    #include <beginnormal_vertex>↵  #include <morphnormal_vertex>↵  #include <skinbase_vertex>↵ #include <skinnormal_vertex>↵   #include <defaultnormal_vertex>↵#ifndef FLAT_SHADED↵    vNormal = normalize( transformedNormal );↵#endif↵   #include <begin_vertex>↵    #include <morphtarget_vertex>↵  #include <skinning_vertex>↵ #include <displacementmap_vertex>↵  #include <project_vertex>↵  #include <logdepthbuf_vertex>↵  #include <clipping_planes_vertex>↵  vViewPosition = - mvPosition.xyz;↵  #include <worldpos_vertex>↵ #include <envmap_vertex>↵   #include <shadowmap_vertex>↵    #include <fog_vertex>↵}"
fragmentShader: "#define PHONG↵uniform vec3 diffuse;↵uniform vec3 emissive;↵uniform vec3 specular;↵uniform float shininess;↵uniform float opacity;↵#include <common>↵#include <packing>↵#include <dithering_pars_fragment>↵#include <color_pars_fragment>↵#include <uv_pars_fragment>↵#include <uv2_pars_fragment>↵#include <map_pars_fragment>↵#include <alphamap_pars_fragment>↵#include <aomap_pars_fragment>↵#include <lightmap_pars_fragment>↵#include <emissivemap_pars_fragment>↵#include <envmap_common_pars_fragment>↵#include <envmap_pars_fragment>↵#include <gradientmap_pars_fragment>↵#include <fog_pars_fragment>↵#include <bsdfs>↵#include <lights_pars_begin>↵#include <lights_phong_pars_fragment>↵#include <shadowmap_pars_fragment>↵#include <bumpmap_pars_fragment>↵#include <normalmap_pars_fragment>↵#include <specularmap_pars_fragment>↵#include <logdepthbuf_pars_fragment>↵#include <clipping_planes_pars_fragment>↵void main() {↵   #include <clipping_planes_fragment>↵    vec4 diffuseColor = vec4( diffuse, opacity );↵  ReflectedLight reflectedLight = ReflectedLight( vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ), vec3( 0.0 ) );↵  vec3 totalEmissiveRadiance = emissive;↵ #include <logdepthbuf_fragment>↵    #include <map_fragment>↵    #include <color_fragment>↵  #include <alphamap_fragment>↵   #include <alphatest_fragment>↵  #include <specularmap_fragment>↵    #include <normal_fragment_begin>↵   #include <normal_fragment_maps>↵    #include <emissivemap_fragment>↵    #include <lights_phong_fragment>↵   #include <lights_fragment_begin>↵   #include <lights_fragment_maps>↵    #include <lights_fragment_end>↵ #include <aomap_fragment>↵  vec3 outgoingLight = reflectedLight.directDiffuse + reflectedLight.indirectDiffuse + reflectedLight.directSpecular + reflectedLight.indirectSpecular + totalEmissiveRadiance;↵  #include <envmap_fragment>↵ gl_FragColor = vec4( outgoingLight, diffuseColor.a );↵  #include <tonemapping_fragment>↵    #include <encodings_fragment>↵  #include <fog_fragment>↵    #include <premultiplied_alpha_fragment>↵    #include <dithering_fragment>↵}"
__proto__: Object

顶点着色器在哪里

#define PHONG
varying vec3 vViewPosition;
#ifndef FLAT_SHADED
    varying vec3 vNormal;
#endif
#include <common>
#include <uv_pars_vertex>
#include <uv2_pars_vertex>
#include <displacementmap_pars_vertex>
#include <envmap_pars_vertex>
#include <color_pars_vertex>
#include <fog_pars_vertex>
#include <morphtarget_pars_vertex>
#include <skinning_pars_vertex>
#include <shadowmap_pars_vertex>
#include <logdepthbuf_pars_vertex>
#include <clipping_planes_pars_vertex>
void main() {
    #include <uv_vertex>
    #include <uv2_vertex>
    #include <color_vertex>
    #include <beginnormal_vertex>
    #include <morphnormal_vertex>
    #include <skinbase_vertex>
    #include <skinnormal_vertex>
    #include <defaultnormal_vertex>
#ifndef FLAT_SHADED
    vNormal = normalize( transformedNormal );
#endif
    #include <begin_vertex>
    #include <morphtarget_vertex>
    #include <skinning_vertex>
    #include <displacementmap_vertex>
    #include <project_vertex>
    #include <logdepthbuf_vertex>
    #include <clipping_planes_vertex>
    vViewPosition = - mvPosition.xyz;
    #include <worldpos_vertex>
    #include <envmap_vertex>
    #include <shadowmap_vertex>
    #include <fog_vertex>
}

现在您可以搜索和替换部分着色器

查看引用的 shader chunks 看起来 begin_vertex 是您想要的。

看起来像这样

vec3 transformed = vec3( position );

所以你的代码可能是这样的

vec3 p = position.xyz;
float new_x = p.x*a11 + p.y*a12;
float new_y = p.x*a21 + p.y*a22;
vec3 transformed = vec4(new_x, new_y, p.z);

你可以像这样添加,你还需要添加你的制服

const material = new THREE.MeshPhongMaterial(...);
material.onBeforeCompile = function(info) {
  info.vertexShader = info.vertexShader.replace('#include <begin_vertex>', `
    vec3 p = position.xyz;
    float new_x = p.x*a11 + p.y*a12;
    float new_y = p.x*a21 + p.y*a22;
    vec3 transformed = vec4(new_x, new_y, p.z);
  `).replace('#include <common>', `
     #include <common>
     uniform float a11;
     uniform float a12;
     uniform float a21;
     uniform float a22;
  `).
  info.uniforms.a11 = { value: 0 };
  info.uniforms.a12 = { value: 0 };
  info.uniforms.a21 = { value: 0 };
  info.uniforms.a22 = { value: 0 };
};

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-03-10
    • 2019-06-06
    • 2015-08-16
    • 1970-01-01
    • 2021-10-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多