Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ShaderMaterial fog parameter does not work

Tags:

three.js

I'm having troubles enabling scene Fog in THREE.ShaderMaterial. Currently the fog only affects other geometries, but the Skydome that is created using THREE.ShaderMaterial, is unaffected by the fog.

There appears to be a boolean fog parameter in ShaderMaterial, which apparently should be set to true to use scene fog. Using it results in uniforms.fogColor is undefined errors however. The error happens at WebGLRenderer function refreshUniformsFog.

Is it a bug or am I using the parameter wrong?

Test case based on webgl_materials_lightmap.html example here: http://jsfiddle.net/HXhb4/ If you set fog to true in line 62 and run the test, you get the errors. What I would like to happen is the skydome to be affected by the fog like a model or skydome created with normal MeshPhongMaterial.

like image 639
yaku Avatar asked Jul 20 '13 00:07

yaku


2 Answers

If you want to use fog with your custom ShaderMaterial, you need to be sure to specify the required fog uniforms. For example,

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
} );

Also specify fogDensity if you decide to use it. You will also have to incorporate the fog logic into your shader.

three.js r.59

like image 71
WestLangley Avatar answered Oct 20 '22 08:10

WestLangley


In the accepted answer WestLangley mentioned:

You will also have to incorporate the fog logic into your shader.

I figured out how to do that by reading the example NormalDisplacementShader.js. Here are the steps:

  1. Write your shader in an external .js file
  2. Add the UniformsLib
  3. Add the ShaderChunks
  4. In the fragment shader, declare vec3 outgoingLight
  5. Use outgoingLight in your output gl_FragColor

Example below:

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")

};
like image 27
imbrizi Avatar answered Oct 20 '22 09:10

imbrizi