Browse Source

Merge pull request #18804 from gkjohnson/support-blocks-in-unrolled-loops

WebGLRenderer: Add #unroll_loop_start /end syntax.
Mr.doob 5 years ago
parent
commit
c634a75283

+ 19 - 10
examples/jsm/csm/Shader.js

@@ -79,6 +79,14 @@ IncidentLight directLight;
 	#endif
 	#endif
 
 
 	#if defined( USE_SHADOWMAP ) && defined( CSM_FADE )
 	#if defined( USE_SHADOWMAP ) && defined( CSM_FADE )
+	vec2 cascade;
+	float cascadeCenter;
+	float closestEdge;
+	float margin;
+	float csmx;
+	float csmy;
+
+	#pragma unroll_loop_start
 	for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {
 	for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {
 
 
 		directionalLight = directionalLights[ i ];
 		directionalLight = directionalLights[ i ];
@@ -86,23 +94,23 @@ IncidentLight directLight;
 
 
 		// NOTE: Depth gets larger away from the camera.
 		// NOTE: Depth gets larger away from the camera.
 		// cascade.x is closer, cascade.y is further
 		// cascade.x is closer, cascade.y is further
-		vec2 cascade = CSM_cascades[ i ];
-		float cascadeCenter = ( cascade.x + cascade.y ) / 2.0;
-		float closestEdge = linearDepth < cascadeCenter ? cascade.x : cascade.y;
-		float margin = 0.25 * pow( closestEdge, 2.0 );
-		float csmx = cascade.x - margin / 2.0;
-		float csmy = cascade.y + margin / 2.0;
-		if( i < NUM_DIR_LIGHT_SHADOWS && linearDepth >= csmx && ( linearDepth < csmy || i == CSM_CASCADES - 1 ) ) {
+		cascade = CSM_cascades[ i ];
+		cascadeCenter = ( cascade.x + cascade.y ) / 2.0;
+		closestEdge = linearDepth < cascadeCenter ? cascade.x : cascade.y;
+		margin = 0.25 * pow( closestEdge, 2.0 );
+		csmx = cascade.x - margin / 2.0;
+		csmy = cascade.y + margin / 2.0;
+		if( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS && linearDepth >= csmx && ( linearDepth < csmy || UNROLLED_LOOP_INDEX == CSM_CASCADES - 1 ) ) {
 
 
 			float dist = min( linearDepth - csmx, csmy - linearDepth );
 			float dist = min( linearDepth - csmx, csmy - linearDepth );
 			float ratio = clamp( dist / margin, 0.0, 1.0 );
 			float ratio = clamp( dist / margin, 0.0, 1.0 );
-			if( i < NUM_DIR_LIGHT_SHADOWS ) {
+			if( UNROLLED_LOOP_INDEX < NUM_DIR_LIGHT_SHADOWS ) {
 
 
 				vec3 prevColor = directLight.color;
 				vec3 prevColor = directLight.color;
 				directionalLightShadow = directionalLightShadows[ i ];
 				directionalLightShadow = directionalLightShadows[ i ];
 				directLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;
 				directLight.color *= all( bvec2( directLight.visible, receiveShadow ) ) ? getShadow( directionalShadowMap[ i ], directionalLightShadow.shadowMapSize, directionalLightShadow.shadowBias, directionalLightShadow.shadowRadius, vDirectionalShadowCoord[ i ] ) : 1.0;
 
 
-				bool shouldFadeLastCascade = i == CSM_CASCADES - 1 && linearDepth > cascadeCenter;
+				bool shouldFadeLastCascade = UNROLLED_LOOP_INDEX == CSM_CASCADES - 1 && linearDepth > cascadeCenter;
 				directLight.color = mix( prevColor, directLight.color, shouldFadeLastCascade ? ratio : 1.0 );
 				directLight.color = mix( prevColor, directLight.color, shouldFadeLastCascade ? ratio : 1.0 );
 
 
 			}
 			}
@@ -110,7 +118,7 @@ IncidentLight directLight;
 			ReflectedLight prevLight = reflectedLight;
 			ReflectedLight prevLight = reflectedLight;
 			RE_Direct( directLight, geometry, material, reflectedLight );
 			RE_Direct( directLight, geometry, material, reflectedLight );
 
 
-			bool shouldBlend = i != CSM_CASCADES - 1 || i == CSM_CASCADES - 1 && linearDepth < cascadeCenter;
+			bool shouldBlend = UNROLLED_LOOP_INDEX != CSM_CASCADES - 1 || UNROLLED_LOOP_INDEX == CSM_CASCADES - 1 && linearDepth < cascadeCenter;
 			float blendRatio = shouldBlend ? ratio : 1.0;
 			float blendRatio = shouldBlend ? ratio : 1.0;
 
 
 			reflectedLight.directDiffuse = mix( prevLight.directDiffuse, reflectedLight.directDiffuse, blendRatio );
 			reflectedLight.directDiffuse = mix( prevLight.directDiffuse, reflectedLight.directDiffuse, blendRatio );
@@ -121,6 +129,7 @@ IncidentLight directLight;
 		}
 		}
 
 
 	}
 	}
+	#pragma unroll_loop_end
 	#else
 	#else
 
 
 	#pragma unroll_loop
 	#pragma unroll_loop

+ 10 - 5
src/renderers/shaders/ShaderChunk/lights_fragment_begin.glsl.js

@@ -35,7 +35,7 @@ IncidentLight directLight;
 	PointLightShadow pointLightShadow;
 	PointLightShadow pointLightShadow;
 	#endif
 	#endif
 
 
-	#pragma unroll_loop
+	#pragma unroll_loop_start
 	for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {
 	for ( int i = 0; i < NUM_POINT_LIGHTS; i ++ ) {
 
 
 		pointLight = pointLights[ i ];
 		pointLight = pointLights[ i ];
@@ -50,6 +50,7 @@ IncidentLight directLight;
 		RE_Direct( directLight, geometry, material, reflectedLight );
 		RE_Direct( directLight, geometry, material, reflectedLight );
 
 
 	}
 	}
+	#pragma unroll_loop_end
 
 
 #endif
 #endif
 
 
@@ -60,7 +61,7 @@ IncidentLight directLight;
 	SpotLightShadow spotLightShadow;
 	SpotLightShadow spotLightShadow;
 	#endif
 	#endif
 
 
-	#pragma unroll_loop
+	#pragma unroll_loop_start
 	for ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {
 	for ( int i = 0; i < NUM_SPOT_LIGHTS; i ++ ) {
 
 
 		spotLight = spotLights[ i ];
 		spotLight = spotLights[ i ];
@@ -75,6 +76,7 @@ IncidentLight directLight;
 		RE_Direct( directLight, geometry, material, reflectedLight );
 		RE_Direct( directLight, geometry, material, reflectedLight );
 
 
 	}
 	}
+	#pragma unroll_loop_end
 
 
 #endif
 #endif
 
 
@@ -85,7 +87,7 @@ IncidentLight directLight;
 	DirectionalLightShadow directionalLightShadow;
 	DirectionalLightShadow directionalLightShadow;
 	#endif
 	#endif
 
 
-	#pragma unroll_loop
+	#pragma unroll_loop_start
 	for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {
 	for ( int i = 0; i < NUM_DIR_LIGHTS; i ++ ) {
 
 
 		directionalLight = directionalLights[ i ];
 		directionalLight = directionalLights[ i ];
@@ -100,6 +102,7 @@ IncidentLight directLight;
 		RE_Direct( directLight, geometry, material, reflectedLight );
 		RE_Direct( directLight, geometry, material, reflectedLight );
 
 
 	}
 	}
+	#pragma unroll_loop_end
 
 
 #endif
 #endif
 
 
@@ -107,13 +110,14 @@ IncidentLight directLight;
 
 
 	RectAreaLight rectAreaLight;
 	RectAreaLight rectAreaLight;
 
 
-	#pragma unroll_loop
+	#pragma unroll_loop_start
 	for ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {
 	for ( int i = 0; i < NUM_RECT_AREA_LIGHTS; i ++ ) {
 
 
 		rectAreaLight = rectAreaLights[ i ];
 		rectAreaLight = rectAreaLights[ i ];
 		RE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );
 		RE_Direct_RectArea( rectAreaLight, geometry, material, reflectedLight );
 
 
 	}
 	}
+	#pragma unroll_loop_end
 
 
 #endif
 #endif
 
 
@@ -127,12 +131,13 @@ IncidentLight directLight;
 
 
 	#if ( NUM_HEMI_LIGHTS > 0 )
 	#if ( NUM_HEMI_LIGHTS > 0 )
 
 
-		#pragma unroll_loop
+		#pragma unroll_loop_start
 		for ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {
 		for ( int i = 0; i < NUM_HEMI_LIGHTS; i ++ ) {
 
 
 			irradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );
 			irradiance += getHemisphereLightIrradiance( hemisphereLights[ i ], geometry );
 
 
 		}
 		}
+		#pragma unroll_loop_end
 
 
 	#endif
 	#endif
 
 

+ 12 - 2
src/renderers/webgl/WebGLProgram.js

@@ -221,11 +221,21 @@ function includeReplacer( match, include ) {
 
 
 // Unroll Loops
 // Unroll Loops
 
 
-var loopPattern = /#pragma unroll_loop[\s]+?for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g;
+var deprecatedUnrollLoopPattern = /#pragma unroll_loop[\s]+?for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}/g;
+var unrollLoopPattern = /#pragma unroll_loop_start[\s]+?for \( int i \= (\d+)\; i < (\d+)\; i \+\+ \) \{([\s\S]+?)(?=\})\}[\s]+?#pragma unroll_loop_end/g;
 
 
 function unrollLoops( string ) {
 function unrollLoops( string ) {
 
 
-	return string.replace( loopPattern, loopReplacer );
+	return string
+		.replace( unrollLoopPattern, loopReplacer )
+		.replace( deprecatedUnrollLoopPattern, deprecatedLoopReplacer );
+
+}
+
+function deprecatedLoopReplacer( match, start, end, snippet ) {
+
+	console.warn( 'WebGLProgram: #pragma unroll_loop shader syntax is deprecated. Please use #pragma unroll_loop_start syntax instead.' );
+	return loopReplacer( match, start, end, snippet );
 
 
 }
 }