未验证 提交 8701e404 编写于 作者: M Mr.doob 提交者: GitHub

Merge pull request #12922 from WestLangley/dev-rect_area_light

RectAreaLight: Updated to new LTC model
......@@ -61,7 +61,7 @@
var origin = new THREE.Object3D();
var matStdParams = {
roughness: 0.044676705160855, // calculated from shininess = 1000
roughness: 0.0,
metalness: 0.0
};
......@@ -78,7 +78,7 @@
var mshStdSphere = new THREE.Mesh( geoSphere, matStdObjects );
var mshStdKnot = new THREE.Mesh( geoKnot, matStdObjects );
var amb = new THREE.AmbientLight( 0xffffff, 0.0 );
var amb = new THREE.AmbientLight( 0xffffff, 0.1 );
var rectLight;
var rectLightHelper;
......@@ -125,7 +125,7 @@
camera.position.set( 0, 20, 35 );
rectLight = new THREE.RectAreaLight( 0xffffff, 500, 10, 10 );
rectLight = new THREE.RectAreaLight( 0xffffff, 200, 10, 10 );
rectLight.position.set( 5, 5, 0 );
// TODO: ensure RectAreaLight handles target param correctly
......@@ -185,10 +185,11 @@
if ( param.motion ) {
update();
rectLightHelper.update();
}
rectLightHelper.update();
renderer.render( scene, camera );
stats.update();
......@@ -197,7 +198,7 @@
function update() {
var t = ( Date.now() / 1000 );
var t = ( Date.now() / 2000 );
// move light in circle around center
// change light height with sine curve
......@@ -263,13 +264,13 @@
} );
lightFolder.add( param, 'intensity', 0.0, 1000 ).onChange( function ( val ) {
lightFolder.add( param, 'intensity', 0.0, 400 ).onChange( function ( val ) {
rectLight.intensity = val;
} );
lightFolder.add( param, 'ambient', 0.0, 1 ).step( 0.01 ).onChange( function ( val ) {
lightFolder.add( param, 'ambient', 0.0, 0.2 ).step( 0.01 ).onChange( function ( val ) {
amb.intensity = val;
......
......@@ -1896,11 +1896,10 @@ function WebGLRenderer( parameters ) {
// RectAreaLight Texture
// TODO (mrdoob): Find a nicer implementation
if ( m_uniforms.ltcMat !== undefined ) m_uniforms.ltcMat.value = UniformsLib.LTC_MAT_TEXTURE;
if ( m_uniforms.ltcMag !== undefined ) m_uniforms.ltcMag.value = UniformsLib.LTC_MAG_TEXTURE;
if ( m_uniforms.ltc_1 !== undefined ) m_uniforms.ltc_1.value = UniformsLib.LTC_1;
if ( m_uniforms.ltc_2 !== undefined ) m_uniforms.ltc_2.value = UniformsLib.LTC_2;
WebGLUniforms.upload(
_gl, materialProperties.uniformsList, m_uniforms, _this );
WebGLUniforms.upload( _gl, materialProperties.uniformsList, m_uniforms, _this );
}
......
......@@ -112,12 +112,9 @@ vec3 BRDF_Specular_GGX( const in IncidentLight incidentLight, const in Geometric
// Rect Area Light
// Area light computation code adapted from:
// Real-Time Polygonal-Light Shading with Linearly Transformed Cosines
// By: Eric Heitz, Jonathan Dupuy, Stephen Hill and David Neubelt
// https://drive.google.com/file/d/0BzvWIdpUpRx_d09ndGVjNVJzZjA/view
// https://eheitzresearch.wordpress.com/415-2/
// http://blog.selfshadow.com/sandbox/ltc.html
// by Eric Heitz, Jonathan Dupuy, Stephen Hill and David Neubelt
// code: https://github.com/selfshadow/ltc_code/
vec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {
......@@ -125,51 +122,40 @@ vec2 LTC_Uv( const in vec3 N, const in vec3 V, const in float roughness ) {
const float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;
const float LUT_BIAS = 0.5 / LUT_SIZE;
float theta = acos( dot( N, V ) );
float dotNV = saturate( dot( N, V ) );
// Parameterization of texture:
// sqrt(roughness) -> [0,1]
// theta -> [0, PI/2]
vec2 uv = vec2(
sqrt( saturate( roughness ) ),
saturate( theta / ( 0.5 * PI ) ) );
// texture parameterized by sqrt( GGX alpha ) and sqrt( 1 - cos( theta ) )
vec2 uv = vec2( roughness, sqrt( 1.0 - dotNV ) );
// Ensure we don't have nonlinearities at the look-up table's edges
// see: http://http.developer.nvidia.com/GPUGems2/gpugems2_chapter24.html
// "Shader Analysis" section
uv = uv * LUT_SCALE + LUT_BIAS;
return uv;
}
// Real-Time Area Lighting: a Journey from Research to Production
// By: Stephen Hill & Eric Heitz
// http://advances.realtimerendering.com/s2016/s2016_ltc_rnd.pdf
// An approximation for the form factor of a clipped rectangle.
float LTC_ClippedSphereFormFactor( const in vec3 f ) {
// Real-Time Area Lighting: a Journey from Research to Production (p.102)
// An approximation of the form factor of a horizon-clipped rectangle.
float l = length( f );
return max( ( l * l + f.z ) / ( l + 1.0 ), 0.0 );
}
// Real-Time Polygonal-Light Shading with Linearly Transformed Cosines
// also Real-Time Area Lighting: a Journey from Research to Production
// http://advances.realtimerendering.com/s2016/s2016_ltc_rnd.pdf
// Normalization by 2*PI is incorporated in this function itself.
// theta/sin(theta) is approximated by rational polynomial
vec3 LTC_EdgeVectorFormFactor( const in vec3 v1, const in vec3 v2 ) {
float x = dot( v1, v2 );
float y = abs( x );
float a = 0.86267 + (0.49788 + 0.01436 * y ) * y;
float b = 3.45068 + (4.18814 + y) * y;
// rational polynomial approximation to theta / sin( theta ) / 2PI
float a = 0.8543985 + ( 0.4965155 + 0.0145206 * y ) * y;
float b = 3.4175940 + ( 4.1616724 + y ) * y;
float v = a / b;
float theta_sintheta = (x > 0.0) ? v : 0.5 * inversesqrt( 1.0 - x * x ) - v;
float theta_sintheta = ( x > 0.0 ) ? v : 0.5 * inversesqrt( max( 1.0 - x * x, 1e-7 ) ) - v;
return cross( v1, v2 ) * theta_sintheta;
......@@ -188,7 +174,7 @@ vec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in m
// construct orthonormal basis around N
vec3 T1, T2;
T1 = normalize( V - N * dot( V, N ) );
T2 = - cross( N, T1 ); // negated from paper; possibly due to a different assumed handedness of world coordinate system
T2 = - cross( N, T1 ); // negated from paper; possibly due to a different handedness of world coordinate system
// compute transform
mat3 mat = mInv * transposeMat3( mat3( T1, T2, N ) );
......@@ -214,9 +200,28 @@ vec3 LTC_Evaluate( const in vec3 N, const in vec3 V, const in vec3 P, const in m
vectorFormFactor += LTC_EdgeVectorFormFactor( coords[ 3 ], coords[ 0 ] );
// adjust for horizon clipping
vec3 result = vec3( LTC_ClippedSphereFormFactor( vectorFormFactor ) );
float result = LTC_ClippedSphereFormFactor( vectorFormFactor );
/*
// alternate method of adjusting for horizon clipping (see referece)
// refactoring required
float len = length( vectorFormFactor );
float z = vectorFormFactor.z / len;
const float LUT_SIZE = 64.0;
const float LUT_SCALE = ( LUT_SIZE - 1.0 ) / LUT_SIZE;
const float LUT_BIAS = 0.5 / LUT_SIZE;
// tabulated horizon-clipped sphere, apparently...
vec2 uv = vec2( z * 0.5 + 0.5, len );
uv = uv * LUT_SCALE + LUT_BIAS;
float scale = texture2D( ltc_2, uv ).w;
float result = len * scale;
*/
return result;
return vec3( result );
}
......
......@@ -132,8 +132,8 @@ vec3 getAmbientLightIrradiance( const in vec3 ambientLightColor ) {
// Pre-computed values of LinearTransformedCosine approximation of BRDF
// BRDF approximation Texture is 64x64
uniform sampler2D ltcMat; // RGBA Float
uniform sampler2D ltcMag; // Alpha Float (only has w component)
uniform sampler2D ltc_1; // RGBA Float
uniform sampler2D ltc_2; // RGBA Float
uniform RectAreaLight rectAreaLights[ NUM_RECT_AREA_LIGHTS ];
......
......@@ -42,19 +42,22 @@ float clearCoatDHRApprox( const in float roughness, const in float dotNL ) {
vec2 uv = LTC_Uv( normal, viewDir, roughness );
float norm = texture2D( ltcMag, uv ).a;
vec4 t = texture2D( ltcMat, uv );
vec4 t1 = texture2D( ltc_1, uv );
vec4 t2 = texture2D( ltc_2, uv );
mat3 mInv = mat3(
vec3( 1, 0, t.y ),
vec3( 0, t.z, 0 ),
vec3( t.w, 0, t.x )
vec3( t1.x, 0, t1.y ),
vec3( 0, 1, 0 ),
vec3( t1.z, 0, t1.w )
);
reflectedLight.directSpecular += lightColor * material.specularColor * norm * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords ); // no fresnel
// LTC Fresnel Approximation by Stephen Hill
// http://blog.selfshadow.com/publications/s2016-advances/s2016_ltc_fresnel.pdf
vec3 fresnel = ( material.specularColor * t2.x + ( vec3( 1.0 ) - material.specularColor ) * t2.y );
reflectedLight.directSpecular += lightColor * fresnel * LTC_Evaluate( normal, viewDir, position, mInv, rectCoords );
reflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1 ), rectCoords );
reflectedLight.directDiffuse += lightColor * material.diffuseColor * LTC_Evaluate( normal, viewDir, position, mat3( 1.0 ), rectCoords );
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册