Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Subsurface scattering support in Blinn-Phong material #13511

Merged
merged 2 commits into from
Apr 3, 2018

Conversation

daoshengmu
Copy link
Contributor

Per #9249, according to the approach from GDC 2011 – Approximating Translucency for a Fast, Cheap and Convincing Subsurface Scattering Look, implementing the subsurface scattering shader for PBR material.

@daoshengmu
Copy link
Contributor Author

screen shot 2018-03-07 at 1 47 31 pm

The demo.

@WestLangley
Copy link
Collaborator

WestLangley commented Mar 7, 2018

Thanks for this! I have a few issues, though...

  1. I see this is not a PBR technique, nor is it based on any PBR models AFAIK, and therefore should not be an extension of MeshStandardMaterial -- maybe MeshPhongMaterial, otherwise just extend ShaderMaterial. (Sorry, I misspoke when I suggested elsewhere that you extend MeshStandardMaterial.)

  2. Also, this material requires a thicknessTexture most models do not have. Consequently, I do not think it should be a built-in material -- and certainly not until the renderer is modified so that it is material-agnostic. An alternate approach would be to use NodeMaterial, perhaps. In an event, it belongs as an example for now.

I feel fairly strongly about both of these points, but I am glad you did this, and would like to see your example included.

@daoshengmu
Copy link
Contributor Author

@WestLangley Thanks for your comment. I was considering it should not extend MeshStandardMaterial or MeshPhongMaterial , because it is just an additional diffuse light. It should not rely on PBR or Blinn-Phong lighting model. So, probably, ShaderMaterial is more wise to choose.

As the ShaderMaterial example as below,

var shader = THREE.ShaderLib[ 'physical' ];
var material = new THREE.ShaderMaterial( { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: uniforms: THREE.UniformsUtils.merge( [
                                                THREE.ShaderLib[ 'physical' ].uniforms,
						THREE.UniformsLib[ "translucent" ]
					], lights: true } );

material.uniforms['thicknessMap'] = thicknessTexture;
...

In lights_physical_pars_fragment.glsl, lights_phong_pars_fragment.glsl, and meshlambert_frag.glsl, we can add

#ifdef USE_THICKNESSMAP
  RE_Direct_Scattering();
#endif

for diffuse scattering.

If it is workable for this approach, do we still need NodeMaterial or both of these two ways are needed?

@WestLangley
Copy link
Collaborator

It should not rely on PBR or Blinn-Phong lighting model.

Correct. It should not. It should not rely on the Physical shader, either.

do we still need NodeMaterial

No, you do not have to use NodeMaterial if you do not want to. Consider following the example webgl_materials_skin.html. I do not think it should be a built-in material, so you do not need to modify the renderer.

@mrdoob
Copy link
Owner

mrdoob commented Mar 8, 2018

Agreed! Better to start with this by having the code in examples.

@daoshengmu
Copy link
Contributor Author

@WestLangley I have followed your suggestion to move the subsurface scattering shader to be ShaderTranslucent under the examples/ folder, and giving demos for Standard, Phong, and Lambert lighting models.

Please give me some feedback to confirm if it can be merged. Thanks!

@daoshengmu
Copy link
Contributor Author

screen shot 2018-03-13 at 12 13 53 am

The demos.

@WestLangley
Copy link
Collaborator

@daoshengmu Thanks for this!

As I said, since this technique is not physically based, I do not think you should be using the MeshStandardMaterial shader chunks. MeshStandardMaterial supports metals; metals are not translucent.

  1. I suggest you have only one translucent material, and use the Phong shader chunks. Rename it THREE.TranslucentShader. You then only need one mesh in your example.

  2. Remove the environment map from the example since it is not used in your material.

With those two simplifications, this should be ready to merge.

Your results should look similar the excellent example here: #9249.

@daoshengmu
Copy link
Contributor Author

daoshengmu commented Mar 13, 2018

After do some adjustment of the material parameters, it looks much better.
screen shot 2018-03-13 at 11 10 46 am

@WestLangley IIUC, the difference between PBR and Blinn-Phong is the part of specular lighting. Despite the PBR defines metalness value in its formula, we still can give it zero to make it be non-metalness. PBR's specular lighting is more closer to the cases in the real world. Therefore, some materials like skin, wax, and jade still need it although they are not metal as well.

Besides, I am curious why you mentioned environment map? I don't see I am using environment map in my shader. Probably, I should remove USE_SHADOWMAP because I really don't want to do shadow map in my demo.

@WestLangley
Copy link
Collaborator

Your shader is not PBR, and should not be presented as such. I stand by my recommendations in my previous comment.

Besides, I am curious why you mentioned environment map?

I meant remove reflectionCube and the scene background because the environment is neither reflected nor refracted in your shader.

@daoshengmu
Copy link
Contributor Author

daoshengmu commented Mar 13, 2018

@WestLangley, Interesting. Maybe I misunderstand the PBR in three.js. If I would like to use PBR, which shader I should refer? the MeshPhysicalMaterial?

@WestLangley
Copy link
Collaborator

PBR is based on the physics of light. But the technique you are implementing is not based on the physics of light (subsurface scattering, in this case) -- it is a "Cheap and Convincing Subsurface Scattering Look".

If you want to mix PBR and this technique in your own projects, that is OK. But here, I do not want to give the impression that a shader is PBR when it is not.

Both MeshStandardMaterial and MeshPhysicalMaterial are PBR-based. If you would like to use built-in "shader chunks", I think it would be reasonable to use the shader chunks from Phong.

The light should be behind the object (backlit) to demonstrate the effect you are trying to incorporate into your shader.

@daoshengmu
Copy link
Contributor Author

If you want to mix PBR and this technique in your own projects, that is OK. But here, I do not want to give the impression that a shader is PBR when it is not.

It makes sense. I have followed your comments to fix my commits. Thanks for the suggestion.

The light should be behind the object (backlit) to demonstrate the effect you are trying to incorporate into your shader.

I have one directional light and two point lights in my demo. The 1st point light (white color) who has a small radius and put in front of the model is for adding brightness to this model, it will not have scattering on the model's back side because of the point light's small radius. The 2nd point light (yellow color) I put behind the model with larger radius will generate scattering and be presented on the model's front side.

@daoshengmu daoshengmu changed the title Subsurface scattering support in PBR material Subsurface scattering support in Phong material Mar 13, 2018
@daoshengmu daoshengmu changed the title Subsurface scattering support in Phong material Subsurface scattering support in Blinn-Phong material Mar 13, 2018
@Mugen87
Copy link
Collaborator

Mugen87 commented Mar 13, 2018

I don't think the following location for the FBX file is correct: examples/obj/bunny/stanford-bunny.fbx

Please use examples/models/fbx/stanford-bunny.fbx. Or instead of adding a new model, use one of the existing ones.

@daoshengmu
Copy link
Contributor Author

daoshengmu commented Mar 13, 2018

Please use examples/models/fbx/stanford-bunny.fbx.

@Mugen87 Thanks for the correction. I have moved the fbx model to examples/models/fbx/stanford-bunny.fbx

// LOADER

var loader = new THREE.FBXLoader();
loader.load("models/fbx/stanford-bunny.fbx", function(geometry) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

FBXLoader.load() does not return a geometry.

});
}

function loadedModel(mesh, scale, material) {
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is not a mesh either.

@WestLangley
Copy link
Collaborator

Thanks @daoshengmu. I think this can be merged, but the code is going to need cleanup, which can be done later.

/ping @Mugen87

@daoshengmu
Copy link
Contributor Author

I have replaced the geometry and mesh with object according the code review comment.

@mrdoob mrdoob added this to the r92 milestone Mar 14, 2018
@daoshengmu
Copy link
Contributor Author

@Mugen87 It seems to have been a couple of days. I am curious when is the possible timeline to merge my patch?

Thanks!

@daoshengmu
Copy link
Contributor Author

@mrdoob I am interested if it is available to be merged. Thanks!

@WestLangley
Copy link
Collaborator

@daoshengmu This PR has an r92 milestone, which means if @mrdoob approves it, it will be merged before the next release. Thank you for being patient.

@mrdoob mrdoob merged commit afcad78 into mrdoob:dev Apr 3, 2018
@mrdoob
Copy link
Owner

mrdoob commented Apr 3, 2018

Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants