ShaderMaterial中的雾参数不起作用。

6
我遇到了在THREE.ShaderMaterial中启用场景雾的问题。目前雾只影响其他几何体,但使用THREE.ShaderMaterial创建的天空圆顶不受雾的影响。
看起来,ShaderMaterial中有一个布尔型的fog参数,应该将其设置为true以使用场景雾。然而,在使用此功能时会出现uniforms.fogColor is undefined错误,这个错误发生在WebGLRenderer函数refreshUniformsFog中。
这是一个bug还是我使用了参数错误?
测试用例是基于webgl_materials_lightmap.html示例的,在这里:http://jsfiddle.net/HXhb4/如果您在第62行将雾设置为true并运行测试,您会得到错误信息。我希望发生的事情是像使用普通MeshPhongMaterial创建的模型或天空圆顶一样,天空圆顶也受到雾的影响。
2个回答

9

如果你想在自定义的 ShaderMaterial 中使用雾化效果,你需要确保指定必需的雾化 uniforms。例如:

var uniforms = {
    topColor:    { type: "c", value: new THREE.Color( 0x0077ff ) },
    bottomColor: { type: "c", value: new THREE.Color( 0xffffff ) },
    offset:      { type: "f", value: 33 },
    exponent:    { type: "f", value: 0.6 },
    fogColor:    { type: "c", value: scene.fog.color },
    fogNear:     { type: "f", value: scene.fog.near },
    fogFar:      { type: "f", value: scene.fog.far }
}

var skyMat = new THREE.ShaderMaterial( {
    vertexShader: vertexShader,
    fragmentShader: fragmentShader,
    uniforms: uniforms,
    side: THREE.BackSide,
    fog: true
} );

如果你决定使用的话,还需要指定fogDensity。你还需要把雾逻辑加入到你的着色器中。
three.js r.59

1
非常感谢,这一切都很有道理!包含雾逻辑非常简单,只需要在着色器中包含THREE.ShaderChunk.fog_pars_fragmentTHREE.ShaderChunk.fog_fragment即可。 - yaku
1
我想做和这里提到的一样的事情,但我没有写shader的经验。你或其他人有没有可能上传一些代码以展示如何添加shader逻辑来使这个答案起作用?谢谢! - Brannon
1
@Brannon,请查看我下面的答案,附带代码示例。 - imbrizi

2
在被接受的答案中,WestLangley提到:
“你还必须将雾逻辑合并到你的着色器中。”
我通过阅读NormalDisplacementShader.js的示例找出了如何做到这一点。以下是步骤:
  1. 编写你的着色器到一个外部.js文件中
  2. 添加UniformsLib
  3. 添加ShaderChunks
  4. 在片段着色器中声明vec3 outgoingLight
  5. 在输出的gl_FragColor中使用outgoingLight
下面是示例:
THREE.YourCustomShader = {

uniforms: THREE.UniformsUtils.merge( [

    THREE.UniformsLib[ "fog" ],

    {

    "someCustomUniform" : { type: 'f', value: 1.0 }

    }

] ),

fragmentShader: [

    "varying float someCustomVarying;",

    THREE.ShaderChunk[ "common" ],
    THREE.ShaderChunk[ "fog_pars_fragment" ],

    "void main() {",

        "vec3 outgoingLight = vec3( 0.0 );",

        THREE.ShaderChunk[ "fog_fragment" ],

        "gl_FragColor = vec4(outgoingLight, 1.0);",

    "}"

].join("\n"),

vertexShader: [

    "uniform float someCustomUniform;",

    "varying float someCustomVarying;",

    "void main() {",

        "someCustomVarying = 1.0 * someCustomUniform;",

        "gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0 );",

    "}"

].join("\n")

};

我正在尝试按照您的示例进行操作,只是我使用了这样的纹理..."gl_FragColor = texture2D(glowTexture, vUv);"....我该如何将outgoingLight应用于它? - Michael Paccione

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接