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

Add MeshStandardMaterialSG #11038

Merged
merged 27 commits into from
Apr 27, 2017
Merged

Add MeshStandardMaterialSG #11038

merged 27 commits into from
Apr 27, 2017

Conversation

takahirox
Copy link
Collaborator

@takahirox takahirox commented Mar 21, 2017

#10985

This PR

  • adds MeshStandardMaterialSG which can handle glTF Specular-Glossiness extension.
  • lets GLTF2Loader support glTF Specular-Glossiness extension.

You can see MeshStandardMaterialSG example in In webgl_loader_gltf2 example
by selecting Specular-Glossiness extension with BoomBox model.

Only the difference between MeshStandardMaterial and MeshStandardMaterialSG
is metalness/roughness or specular/glossiness.
So I made MeshStandardMaterialCommon and let them inherit it.

/cc @donmccurdy @WestLangley

@takahirox
Copy link
Collaborator Author

Well, let me close once.
I think I can rename specular2 with specular.
Let me try...

@takahirox takahirox closed this Mar 21, 2017
@takahirox takahirox reopened this Mar 21, 2017
@takahirox
Copy link
Collaborator Author

Updated and reopened

@WestLangley
Copy link
Collaborator

Nice job.

I personally do not care for your refactoring, however. You have taken an implementation detail, and pushed it up to the API and created another layer of obfuscation -- especially for users -- by creating the new MeshStandardMaterialCommon, which is sort of like a virtual base class.

As I suggested here, leave MeshStandardMaterial as-is, and extend it -- similarly to your implementation of MeshToonMaterial.

Maybe something like this:

function MeshStandardMaterialSG( parameters ) {

	MeshStandardMaterial.call( this );

	this.defines[ 'STANDARD_SG' ] = '';

	this.type = 'MeshStandardMaterialSG';

	this.glossiness = 0.5;
	this.specular = new Color( 0x111111 );

	this.glossinessMap = null;

	this.specularMap = null;

	delete this.metalness;
	delete this.roughness;
	delete this.metalnessMap;
	delete this.roughnessMap;

	this.setValues( parameters );

}

Yes, I understand that you can argue otherwise from a software-design standpoint. However, I expect that 99% of users will use MeshStandardMaterial, and the SG version only by sophisticated users who prefer the specular-glossiness workflow.

@takahirox
Copy link
Collaborator Author

takahirox commented Mar 21, 2017

OK, that makes sense.
(I had misunderstood "as-is" and "remove" you mentioned in the thread.)
I'll update.

@@ -1,4 +1,4 @@
#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP )
#if defined( USE_MAP ) || defined( USE_BUMPMAP ) || defined( USE_NORMALMAP ) || defined( USE_SPECULARMAP ) || defined( USE_ALPHAMAP ) || defined( USE_EMISSIVEMAP ) || defined( USE_ROUGHNESSMAP ) || defined( USE_METALNESSMAP ) || defined( USE_GLOSSINESSMAP) || defined( USE_SPECULAR2MAP )
Copy link
Collaborator

Choose a reason for hiding this comment

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

SPECULAR2MAP ?
defined( USE_GLOSSINESSMAP ) // white space

It is unfortunate that specularMap is used for multiple purposes. We will have to fix that. It should be RGB and represent the specular reflectance of the material.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

If I'm right, this is a related comment? #9339 (comment)

@@ -82,12 +82,15 @@ var ShaderLib = {
UniformsLib.displacementmap,
UniformsLib.roughnessmap,
UniformsLib.metalnessmap,
UniformsLib.glossinessmap,
UniformsLib.fog,
UniformsLib.lights,
{
emissive: { value: new Color( 0x000000 ) },
roughness: { value: 0.5 },
metalness: { value: 0 },
Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes, should be

metalness: { value: 0.5 }

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

That isn't what I edited.
I already noticed that and sent another PR.

#11039

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes, I saw that PR earlier. :-)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Ah, ok. I understand what you meant.

@takahirox
Copy link
Collaborator Author

Updated

@mrdoob
Copy link
Owner

mrdoob commented Mar 26, 2017

As discussed in the SFHTML5 meetup (😁), I think it'll be better if, for now, GLTF2Loader just produces a ShaderMaterial for the specular/glossiness case.

@takahirox
Copy link
Collaborator Author

Alright, I wanna try that before I leave the USA!

@WestLangley
Copy link
Collaborator

As discussed in the SFHTML5 meetup (😁), I think it'll be better if, for now, GLTF2Loader just produces a ShaderMaterial for the specular/glossiness case.

That suits me fine.

I assume we then do not require the addition of MeshStandardMaterialSG ?

@mrdoob
Copy link
Owner

mrdoob commented Mar 26, 2017

I assume we then do not require the addition of MeshStandardMaterialSG ?

Yeah, that's the idea. I personally didn't like the name and I couldn't think of a better name. At this point this is mainly for the GLTF2Loader anyway.

@takahirox
Copy link
Collaborator Author

Well, I couldn't make a time.
I'll implement after I land in Japan ;D

@bhouston
Copy link
Contributor

bhouston commented Apr 2, 2017

The MeshPhong model is specular/glossy. If we merge this, we should remove MeshPhong if this is accepted. We really shouldn't have two materials that are basically the same thing.

@WestLangley
Copy link
Collaborator

we should remove MeshPhong if this is accepted.

In light of what @bhouston said, I agree. I did not realize that was an option.

Removing Phong would make our shader code simpler, plus Phong, as implemented, does not model metals well, and the way it handles environment map reflections is hacky.

We could keep Lambert, which is non-specular and implements Gouraud shading.

@takahirox takahirox changed the title Add MeshStandardMaterialSG (WIP) Add MeshStandardMaterialSG Apr 21, 2017
@takahirox
Copy link
Collaborator Author

takahirox commented Apr 23, 2017

I've implemented Specular-Glossiness extension support with ShaderMaterial.

On the current implementation, GLTF2Loader setups its uniforms and defines.
Users need to update its uniforms value(ex: material.uniforms.map.value) and its defines,
not its properties(ex: material.map), if they wanna update material values by themselves.
(I think this's ShaderMaterial standard manner.)

I'll try onBeforeRender() later to allow users to update its properties.

The code would be like this,

object.onBeforeRender = function( renderer, scene, camera, geometry, material, group ) {

    material.uniforms.map.value = material.map;

}

([de]serialization would't work well with it tho)

@takahirox takahirox changed the title (WIP) Add MeshStandardMaterialSG Add MeshStandardMaterialSG Apr 23, 2017
@takahirox
Copy link
Collaborator Author

Done

@mrdoob
Copy link
Owner

mrdoob commented Apr 23, 2017

Sweeeet!

@mrdoob
Copy link
Owner

mrdoob commented Apr 23, 2017

@donmccurdy looks good?

uniforms.envMap.value = material.envMap;
uniforms.normalMap.value = material.normalMap;
uniforms.specularMap.value = material.specularMap;
uniforms.glossinessMap.value = material.glossinessMap;
Copy link
Collaborator

Choose a reason for hiding this comment

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

Do you need to add these? Maybe others?

uniforms.normalScale
uniforms.displacementMap
uniforms.displacementScale
uniforms.displacementBias
uniforms.envMapIntensity
uniforms.opacity
uniforms.offsetRepeat

Copy link
Collaborator Author

@takahirox takahirox Apr 24, 2017

Choose a reason for hiding this comment

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

Oops, right.
I think we should also have them and others
for the compatibility with StandardMaterial as much as possible.
I'll update...

Copy link
Collaborator

Choose a reason for hiding this comment

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

Yes, this is a pain, but it is illustrative to show how it is done...

It is also why I prefer the oddly-named MeshStandardMaterialSG as a built-in material over this ShaderMaterial approach.

@takahirox
Copy link
Collaborator Author

Updated

@WestLangley
Copy link
Collaborator

I know I have been overruled, but MeshSGStandardMaterial is sounding even better to me. : - )

@donmccurdy
Copy link
Collaborator

donmccurdy commented Apr 25, 2017

Nice work @takahirox!

The implementation of this approach looks good to me, and I don't have any comment on MeshSGStandardMaterial vs ShaderMaterial here.

If possible in a clean way, I might prefer to isolate the spec-gloss code in an extension object. Something like:

class GLTFSpecGlossExtersion {
  extendMaterialParams (params, ...) {
     params.foo = bar;
     // ...
  }

  createShaderMaterial (params) {
    material = new THREE.ShaderMaterial( /* ... */ );
    // ...
    material.onBeforeRender = function () { /* ... */ };
    return material;
  }
}

This helps readability IMHO, avoiding 500+ line methods, and the division is clean enough because the specification for extensions is self-contained already. But I'm OK with the code as-is, if we prefer to have all material code in one larger method.

@mrdoob
Copy link
Owner

mrdoob commented Apr 25, 2017

I know I have been overruled, but MeshSGStandardMaterial is sounding even better to me. : - )

Lets wait to see if people actually use this workflow.

@takahirox
Copy link
Collaborator Author

Updated!

@donmccurdy
Copy link
Collaborator

Great thanks — looks good to me!

@mrdoob
Copy link
Owner

mrdoob commented Apr 27, 2017

Very nice!

@mrdoob mrdoob merged commit 4c6bd58 into mrdoob:dev Apr 27, 2017
@mrdoob
Copy link
Owner

mrdoob commented Apr 27, 2017

Thanks!

@takahirox takahirox deleted the SpecularGlossiness branch April 27, 2017 07:45
@@ -2475,6 +2464,47 @@ THREE.GLTF2Loader = ( function () {

}

// for Specular-Glossiness
if ( child.material && child.material.type === 'ShaderMaterial' ) {
Copy link
Collaborator

@WestLangley WestLangley Jul 20, 2017

Choose a reason for hiding this comment

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

@takahirox Can you change this so material.type is not used for this purpose? I do not think that pattern is used elsewhere...

In this case, it should be something like

if ( child.material && child.material.isGLTFSpecularGlossinessMaterial ) {

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.

5 participants