提交 457b7a60 编写于 作者: A alteredq

Refactored normal map shader to use standard lights.

Updated SceneLoader to use this new shader for normal mapped materials.

Added handling of ambient light to scene parser.

For the moment kept also old normal map shader, still need to convert examples.
上级 f92f3607
......@@ -157,8 +157,8 @@ THREE.ShaderUtils = {
"void main() {",
"vec3 diffuseTex = vec3( 1.0, 1.0, 1.0 );",
"vec3 aoTex = vec3( 1.0, 1.0, 1.0 );",
"vec3 diffuseTex = vec3( 1.0 );",
"vec3 aoTex = vec3( 1.0 );",
"vec3 specularTex = vec3( 1.0, 1.0, 1.0 );",
"vec3 normalTex = texture2D( tNormal, vUv ).xyz * 2.0 - 1.0;",
......@@ -295,6 +295,263 @@ THREE.ShaderUtils = {
},
'normal2' : {
uniforms: THREE.UniformsUtils.merge( [
THREE.UniformsLib[ "lights" ],
{
"enableAO" : { type: "i", value: 0 },
"enableDiffuse" : { type: "i", value: 0 },
"enableSpecular": { type: "i", value: 0 },
"tDiffuse" : { type: "t", value: 0, texture: null },
"tNormal" : { type: "t", value: 2, texture: null },
"tSpecular" : { type: "t", value: 3, texture: null },
"tAO" : { type: "t", value: 4, texture: null },
"uNormalScale": { type: "f", value: 1.0 },
"tDisplacement": { type: "t", value: 5, texture: null },
"uDisplacementBias": { type: "f", value: -0.5 },
"uDisplacementScale": { type: "f", value: 2.5 },
"uDiffuseColor": { type: "c", value: new THREE.Color( 0xeeeeee ) },
"uSpecularColor": { type: "c", value: new THREE.Color( 0x111111 ) },
"uAmbientColor": { type: "c", value: new THREE.Color( 0x050505 ) },
"uShininess": { type: "f", value: 30 },
"uOpacity": { type: "f", value: 1 }
}
] ),
fragmentShader: [
"uniform vec3 uAmbientColor;",
"uniform vec3 uDiffuseColor;",
"uniform vec3 uSpecularColor;",
"uniform float uShininess;",
"uniform float uOpacity;",
"uniform bool enableDiffuse;",
"uniform bool enableSpecular;",
"uniform bool enableAO;",
"uniform sampler2D tDiffuse;",
"uniform sampler2D tNormal;",
"uniform sampler2D tSpecular;",
"uniform sampler2D tAO;",
"uniform float uNormalScale;",
"varying vec3 vTangent;",
"varying vec3 vBinormal;",
"varying vec3 vNormal;",
"varying vec2 vUv;",
"uniform vec3 ambientLightColor;",
"#if MAX_DIR_LIGHTS > 0",
"uniform vec3 directionalLightColor[ MAX_DIR_LIGHTS ];",
"uniform vec3 directionalLightDirection[ MAX_DIR_LIGHTS ];",
"#endif",
"#if MAX_POINT_LIGHTS > 0",
"uniform vec3 pointLightColor[ MAX_POINT_LIGHTS ];",
"varying vec4 vPointLight[ MAX_POINT_LIGHTS ];",
"#endif",
"varying vec3 vViewPosition;",
"void main() {",
"gl_FragColor = vec4( 1.0 );",
"vec4 mColor = vec4( uDiffuseColor, uOpacity );",
"vec4 mSpecular = vec4( uSpecularColor, uOpacity );",
"vec3 specularTex = vec3( 1.0 );",
"vec3 normalTex = texture2D( tNormal, vUv ).xyz * 2.0 - 1.0;",
"normalTex.xy *= uNormalScale;",
"normalTex = normalize( normalTex );",
"if( enableDiffuse )",
"gl_FragColor = gl_FragColor * texture2D( tDiffuse, vUv );",
"if( enableAO )",
"gl_FragColor = gl_FragColor * texture2D( tAO, vUv );",
"if( enableSpecular )",
"specularTex = texture2D( tSpecular, vUv ).xyz;",
"mat3 tsb = mat3( vTangent, vBinormal, vNormal );",
"vec3 finalNormal = tsb * normalTex;",
"vec3 normal = normalize( finalNormal );",
"vec3 viewPosition = normalize( vViewPosition );",
// point lights
"#if MAX_POINT_LIGHTS > 0",
"vec4 pointTotal = vec4( 0.0 );",
"for ( int i = 0; i < MAX_POINT_LIGHTS; i ++ ) {",
"vec3 pointVector = normalize( vPointLight[ 0 ].xyz );",
"vec3 pointHalfVector = normalize( vPointLight[ 0 ].xyz + vViewPosition );",
"float pointDistance = vPointLight[ i ].w;",
"float pointDotNormalHalf = dot( normal, pointHalfVector );",
"float pointDiffuseWeight = max( dot( normal, pointVector ), 0.0 );",
"float pointSpecularWeight = 0.0;",
"if ( pointDotNormalHalf >= 0.0 )",
"pointSpecularWeight = specularTex.r * pow( pointDotNormalHalf, uShininess );",
"pointTotal += pointDistance * vec4( pointLightColor[ 0 ], 1.0 ) * ( mColor * pointDiffuseWeight + mSpecular * pointSpecularWeight * pointDiffuseWeight );",
"}",
"#endif",
// directional lights
"#if MAX_DIR_LIGHTS > 0",
"vec4 dirTotal = vec4( 0.0 );",
"for( int i = 0; i < MAX_DIR_LIGHTS; i++ ) {",
"vec4 lDirection = viewMatrix * vec4( directionalLightDirection[ 0 ], 0.0 );",
"vec3 dirVector = normalize( lDirection.xyz );",
"vec3 dirHalfVector = normalize( lDirection.xyz + vViewPosition );",
"float dirDotNormalHalf = dot( normal, dirHalfVector );",
"float dirDiffuseWeight = max( dot( normal, dirVector ), 0.0 );",
"float dirSpecularWeight = 0.0;",
"if ( dirDotNormalHalf >= 0.0 )",
"dirSpecularWeight = specularTex.r * pow( dirDotNormalHalf, uShininess );",
"dirTotal += vec4( directionalLightColor[ 0 ], 1.0 ) * ( mColor * dirDiffuseWeight + mSpecular * dirSpecularWeight * dirDiffuseWeight );",
"}",
"#endif",
// all lights contribution summation
"vec4 totalLight = vec4( ambientLightColor * uAmbientColor, uOpacity );",
"#if MAX_DIR_LIGHTS > 0",
"totalLight += dirTotal;",
"#endif",
"#if MAX_POINT_LIGHTS > 0",
"totalLight += pointTotal;",
"#endif",
"gl_FragColor = gl_FragColor * totalLight;",
"}"
].join("\n"),
vertexShader: [
"attribute vec4 tangent;",
"#ifdef VERTEX_TEXTURES",
"uniform sampler2D tDisplacement;",
"uniform float uDisplacementScale;",
"uniform float uDisplacementBias;",
"#endif",
"varying vec3 vTangent;",
"varying vec3 vBinormal;",
"varying vec3 vNormal;",
"varying vec2 vUv;",
"#if MAX_POINT_LIGHTS > 0",
"uniform vec3 pointLightPosition[ MAX_POINT_LIGHTS ];",
"uniform float pointLightDistance[ MAX_POINT_LIGHTS ];",
"varying vec4 vPointLight[ MAX_POINT_LIGHTS ];",
"#endif",
"varying vec3 vViewPosition;",
"void main() {",
"vec4 mPosition = objectMatrix * vec4( position, 1.0 );",
"vViewPosition = cameraPosition - mPosition.xyz;",
"vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );",
"vNormal = normalize( normalMatrix * normal );",
// tangent and binormal vectors
"vTangent = normalize( normalMatrix * tangent.xyz );",
"vBinormal = cross( vNormal, vTangent ) * tangent.w;",
"vBinormal = normalize( vBinormal );",
"vUv = uv;",
// point lights
"#if MAX_POINT_LIGHTS > 0",
"for( int i = 0; i < MAX_POINT_LIGHTS; i++ ) {",
"vec4 lPosition = viewMatrix * vec4( pointLightPosition[ i ], 1.0 );",
"vec3 lVector = lPosition.xyz - mvPosition.xyz;",
"float lDistance = 1.0;",
"if ( pointLightDistance[ i ] > 0.0 )",
"lDistance = 1.0 - min( ( length( lVector ) / pointLightDistance[ i ] ), 1.0 );",
"lVector = normalize( lVector );",
"vPointLight[ i ] = vec4( lVector, lDistance );",
"}",
"#endif",
// displacement mapping
"#ifdef VERTEX_TEXTURES",
"vec3 dv = texture2D( tDisplacement, uv ).xyz;",
"float df = uDisplacementScale * dv.x + uDisplacementBias;",
"vec4 displacedPosition = vec4( vNormal.xyz * df, 0.0 ) + mvPosition;",
"gl_Position = projectionMatrix * displacedPosition;",
"#else",
"gl_Position = projectionMatrix * mvPosition;",
"#endif",
"}"
].join("\n")
},
/* -------------------------------------------------------------------------
// Cube map shader
------------------------------------------------------------------------- */
......
......@@ -404,6 +404,10 @@ THREE.SceneLoader.prototype = {
light = new THREE.PointLight( hex, intensity, d );
light.position.set( p[0], p[1], p[2] );
} else if ( l.type == "ambient" ) {
light = new THREE.AmbientLight( hex );
}
result.scene.addLight( light );
......@@ -686,7 +690,7 @@ THREE.SceneLoader.prototype = {
if ( m.parameters.normalMap ) {
var shader = THREE.ShaderUtils.lib[ "normal" ];
var shader = THREE.ShaderUtils.lib[ "normal2" ];
var uniforms = THREE.UniformsUtils.clone( shader.uniforms );
var diffuse = m.parameters.color;
......@@ -694,32 +698,6 @@ THREE.SceneLoader.prototype = {
var ambient = m.parameters.ambient;
var shininess = m.parameters.shininess;
var pointLight;
var directionalLight;
var ambientLight;
// take first of each light type (normal map shader supports just one light of each type)
for ( var i = 0; i < result.scene.lights.length; i ++ ) {
light = result.scene.lights[ i ];
if( ! ambientLight && ( light instanceof THREE.AmbientLight ) ) {
ambientLight = light;
} else if( ! pointLight && ( light instanceof THREE.PointLight ) ) {
pointLight = light;
} else if( ! directionalLight && ( light instanceof THREE.DirectionalLight ) ) {
directionalLight = light;
}
}
uniforms[ "tNormal" ].texture = result.textures[ m.parameters.normalMap ];
if ( m.parameters.normalMapFactor ) {
......@@ -738,33 +716,19 @@ THREE.SceneLoader.prototype = {
uniforms[ "enableAO" ].value = false;
uniforms[ "enableSpecular" ].value = false;
if ( pointLight ) {
uniforms[ "uPointLightPos" ].value = pointLight.position;
uniforms[ "uPointLightColor" ].value = pointLight.color;
}
if ( directionalLight ) {
uniforms[ "uDirLightPos" ].value = directionalLight.position;
uniforms[ "uDirLightColor" ].value = directionalLight.color;
}
if ( ambientLight ) {
uniforms[ "uAmbientLightColor" ].value = ambientLight.color;
}
uniforms[ "uDiffuseColor" ].value.setHex( diffuse );
uniforms[ "uSpecularColor" ].value.setHex( specular );
uniforms[ "uAmbientColor" ].value.setHex( ambient );
uniforms[ "uShininess" ].value = shininess;
var parameters = { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: uniforms };
if ( m.parameters.opacity ) {
uniforms[ "uOpacity" ].value = m.parameters.opacity;
}
var parameters = { fragmentShader: shader.fragmentShader, vertexShader: shader.vertexShader, uniforms: uniforms, lights: true };
material = new THREE.MeshShaderMaterial( parameters );
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册