Przeglądaj źródła

Add support for packed normal maps in WebGL backend. (#33055)

Ignacio Castaño 1 miesiąc temu
rodzic
commit
aa06320a1c

BIN
examples/screenshots/webgl_loader_texture_ktx.jpg


+ 1 - 1
examples/webgl_loader_texture_ktx.html

@@ -72,7 +72,7 @@
 		scene.add( ambientLight );
 
 		const pointLight = new THREE.PointLight( 0xffffff, 2, 0, 0 );
-		pointLight.position.z = - 300;
+		pointLight.position.z = 300;
 		scene.add( pointLight );
 
 		const geometry = new THREE.BoxGeometry( 200, 200, 200 );

+ 7 - 0
src/renderers/shaders/ShaderChunk/normal_fragment_maps.glsl.js

@@ -21,6 +21,13 @@ export default /* glsl */`
 #elif defined( USE_NORMALMAP_TANGENTSPACE )
 
 	vec3 mapN = texture2D( normalMap, vNormalMapUv ).xyz * 2.0 - 1.0;
+
+	#if defined( USE_PACKED_NORMALMAP )
+
+		mapN = vec3( mapN.xy, sqrt( saturate( 1.0 - dot( mapN.xy, mapN.xy ) ) ) );
+
+	#endif
+
 	mapN.xy *= normalScale;
 
 	normal = normalize( tbn * mapN );

+ 1 - 0
src/renderers/webgl/WebGLProgram.js

@@ -696,6 +696,7 @@ function WebGLProgram( renderer, cacheKey, parameters, bindingStates ) {
 			parameters.normalMap ? '#define USE_NORMALMAP' : '',
 			parameters.normalMapObjectSpace ? '#define USE_NORMALMAP_OBJECTSPACE' : '',
 			parameters.normalMapTangentSpace ? '#define USE_NORMALMAP_TANGENTSPACE' : '',
+			parameters.packedNormalMap ? '#define USE_PACKED_NORMALMAP' : '',
 			parameters.emissiveMap ? '#define USE_EMISSIVEMAP' : '',
 
 			parameters.anisotropy ? '#define USE_ANISOTROPY' : '',

+ 10 - 1
src/renderers/webgl/WebGLPrograms.js

@@ -1,4 +1,4 @@
-import { BackSide, DoubleSide, CubeUVReflectionMapping, ObjectSpaceNormalMap, TangentSpaceNormalMap, NoToneMapping, NormalBlending, SRGBTransfer } from '../../constants.js';
+import { BackSide, DoubleSide, CubeUVReflectionMapping, ObjectSpaceNormalMap, TangentSpaceNormalMap, NoToneMapping, NormalBlending, SRGBTransfer, RGFormat, RG11_EAC_Format, RED_GREEN_RGTC2_Format } from '../../constants.js';
 import { Layers } from '../../core/Layers.js';
 import { WebGLProgram } from './WebGLProgram.js';
 import { WebGLShaderCache } from './WebGLShaderCache.js';
@@ -7,6 +7,12 @@ import { UniformsUtils } from '../shaders/UniformsUtils.js';
 import { ColorManagement } from '../../math/ColorManagement.js';
 import { warn } from '../../utils.js';
 
+function isPackedRGFormat( format ) {
+
+	return format === RGFormat || format === RG11_EAC_Format || format === RED_GREEN_RGTC2_Format;
+
+}
+
 function WebGLPrograms( renderer, environments, extensions, capabilities, bindingStates, clipping ) {
 
 	const _programLayers = new Layers();
@@ -217,6 +223,7 @@ function WebGLPrograms( renderer, environments, extensions, capabilities, bindin
 
 			normalMapObjectSpace: HAS_NORMALMAP && material.normalMapType === ObjectSpaceNormalMap,
 			normalMapTangentSpace: HAS_NORMALMAP && material.normalMapType === TangentSpaceNormalMap,
+			packedNormalMap: HAS_NORMALMAP && material.normalMapType === TangentSpaceNormalMap && isPackedRGFormat( material.normalMap.format	),
 
 			metalnessMap: HAS_METALNESSMAP,
 			roughnessMap: HAS_ROUGHNESSMAP,
@@ -521,6 +528,8 @@ function WebGLPrograms( renderer, environments, extensions, capabilities, bindin
 			_programLayers.enable( 20 );
 		if ( parameters.gradientMap )
 			_programLayers.enable( 21 );
+		if ( parameters.packedNormalMap )
+			_programLayers.enable( 22 );
 
 		array.push( _programLayers.mask );
 		_programLayers.disableAll();

粤ICP备19079148号