Mr.doob 3 месяцев назад
Родитель
Сommit
d14ea4670d

+ 0 - 58
examples/jsm/utils/GenerateSDFMaterial.js

@@ -1,58 +0,0 @@
-import { ShaderMaterial } from 'three';
-
-export class GenerateSDFMaterial extends ShaderMaterial {
-
-	constructor( params ) {
-
-		super( {
-			uniforms: {
-				bvh: { value: null },
-				matrix: { value: null },
-				zValue: { value: 0 }
-			},
-
-			vertexShader: /* glsl */`
-				varying vec2 vUv;
-				void main() {
-					vUv = uv;
-					gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
-				}
-			`,
-
-			fragmentShader: /* glsl */`
-				varying vec2 vUv;
-				uniform BVH bvh;
-				uniform mat4 matrix;
-				uniform float zValue;
-
-				void main() {
-					// calculate the point in space for this pixel
-					vec3 point = vec3( vUv.x - 0.5, vUv.y - 0.5, zValue - 0.5 );
-					point = ( matrix * vec4( point, 1.0 ) ).xyz;
-
-					// get the distance to the geometry
-					uvec4 faceIndices = uvec4( 0u );
-					vec3 faceNormal = vec3( 0.0, 0.0, 1.0 );
-					vec3 barycoord = vec3( 0.0 );
-					vec3 outPoint = vec3( 0.0 );
-					float dist = bvhClosestPointToPoint(
-						bvh, point.xyz, faceIndices, faceNormal, barycoord, outPoint
-					);
-
-					// if the triangle face normal and the point to triangle vector are pointing in the same direction
-					// then the point is in the negative half space of the triangle
-					vec3 toTriangle = normalize( outPoint - point );
-					if ( dot( faceNormal, toTriangle ) < 0.0 ) {
-						dist *= - 1.0;
-					}
-
-					gl_FragColor = vec4( dist );
-				}
-			`
-		} );
-
-		this.setValues( params );
-
-	}
-
-}

+ 0 - 237
examples/jsm/utils/JumpFloodSDFGenerator.js

@@ -1,237 +0,0 @@
-import {
-	Vector3,
-	Matrix4,
-	Data3DTexture,
-	RGBAFormat,
-	FloatType,
-	LinearFilter,
-	ShaderMaterial,
-	WebGLRenderTarget
-} from 'three';
-import { FullScreenQuad } from 'three/addons/utils/FullScreenQuad.js';
-
-export class JumpFloodSDFGenerator {
-
-	constructor( renderer ) {
-
-		this.renderer = renderer;
-
-		this.jumpFloodInitMaterial = new ShaderMaterial( {
-			uniforms: {
-				bvh: { value: null },
-				matrix: { value: null },
-				zValue: { value: 0 }
-			},
-			vertexShader: /* glsl */`
-				varying vec2 vUv;
-				void main() {
-					vUv = uv;
-					gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
-				}
-			`,
-			fragmentShader: /* glsl */`
-				varying vec2 vUv;
-				uniform BVH bvh;
-				uniform mat4 matrix;
-				uniform float zValue;
-
-				void main() {
-					// calculate the point in space for this pixel
-					vec3 point = vec3( vUv.x - 0.5, vUv.y - 0.5, zValue - 0.5 );
-					point = ( matrix * vec4( point, 1.0 ) ).xyz;
-
-					// get the distance to the geometry
-					uvec4 faceIndices = uvec4( 0u );
-					vec3 faceNormal = vec3( 0.0, 0.0, 1.0 );
-					vec3 barycoord = vec3( 0.0 );
-					vec3 outPoint = vec3( 0.0 );
-					bvhClosestPointToPoint(
-						bvh, point.xyz, faceIndices, faceNormal, barycoord, outPoint
-					);
-
-					gl_FragColor = vec4( outPoint, 1.0 );
-				}
-			`
-		} );
-
-		this.jumpFloodMaterial = new ShaderMaterial( {
-			uniforms: {
-				map: { value: null },
-				stepSize: { value: 0 }
-			},
-			vertexShader: /* glsl */`
-				varying vec2 vUv;
-				void main() {
-					vUv = uv;
-					gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
-				}
-			`,
-			fragmentShader: /* glsl */`
-				varying vec2 vUv;
-				uniform sampler2D map;
-				uniform float stepSize;
-
-				void main() {
-					vec2 bestUv = vUv;
-					float bestDist = distance( texture2D( map, vUv ).xyz, gl_FragCoord.xyz );
-
-					for ( int i = -1; i <= 1; i ++ ) {
-						for ( int j = -1; j <= 1; j ++ ) {
-							if ( i == 0 && j == 0 ) continue;
-
-							vec2 uv = vUv + vec2( float( i ), float( j ) ) * stepSize;
-							float dist = distance( texture2D( map, uv ).xyz, gl_FragCoord.xyz );
-
-							if ( dist < bestDist ) {
-								bestDist = dist;
-								bestUv = uv;
-							}
-						}
-					}
-
-					gl_FragColor = texture2D( map, bestUv );
-				}
-			`
-		} );
-
-		this.distanceMaterial = new ShaderMaterial( {
-			uniforms: {
-				map: { value: null },
-				matrix: { value: null },
-				zValue: { value: 0 }
-			},
-			vertexShader: /* glsl */`
-				varying vec2 vUv;
-				void main() {
-					vUv = uv;
-					gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
-				}
-			`,
-			fragmentShader: /* glsl */`
-				varying vec2 vUv;
-				uniform sampler2D map;
-				uniform mat4 matrix;
-				uniform float zValue;
-
-				void main() {
-					vec3 point = vec3( vUv.x - 0.5, vUv.y - 0.5, zValue - 0.5 );
-					point = ( matrix * vec4( point, 1.0 ) ).xyz;
-
-					vec3 closestPoint = texture2D( map, vUv ).xyz;
-					float dist = distance( point, closestPoint );
-
-					gl_FragColor = vec4( dist, 0.0, 0.0, 1.0 );
-				}
-			`
-		} );
-
-	}
-
-	generate( sourceMesh, resolution = 64 ) {
-
-		const { renderer } = this;
-
-		const dim = resolution;
-		const geometry = sourceMesh.geometry;
-
-		// Ensure BVH is computed
-		if ( ! geometry.boundsTree ) {
-
-			throw new Error( 'Source mesh geometry must have a BVH. Call geometry.computeBoundsTree() first.' );
-
-		}
-
-		const bvh = geometry.boundsTree;
-
-		const matrix = new Matrix4();
-		const center = new Vector3();
-		const quat = new Quaternion();
-		const scale = new Vector3();
-
-		// Compute the bounding box of the geometry
-		if ( ! geometry.boundingBox ) geometry.computeBoundingBox();
-
-		geometry.boundingBox.getCenter( center );
-		scale.subVectors( geometry.boundingBox.max, geometry.boundingBox.min );
-		matrix.compose( center, quat, scale );
-
-		// Create the render targets
-		let rt1 = new WebGLRenderTarget( dim, dim, {
-			format: RGBAFormat,
-			type: FloatType,
-			minFilter: LinearFilter,
-			magFilter: LinearFilter
-		} );
-
-		let rt2 = new WebGLRenderTarget( dim, dim, {
-			format: RGBAFormat,
-			type: FloatType,
-			minFilter: LinearFilter,
-			magFilter: LinearFilter
-		} );
-
-		// Create the 3D texture
-		const sdfTexture = new Data3DTexture( new Float32Array( dim * dim * dim * 4 ), dim, dim, dim );
-		sdfTexture.format = RGBAFormat;
-		sdfTexture.type = FloatType;
-		sdfTexture.minFilter = LinearFilter;
-		sdfTexture.magFilter = LinearFilter;
-
-		const fsQuad = new FullScreenQuad();
-
-		for ( let z = 0; z < dim; z ++ ) {
-
-			// Initialization pass
-			fsQuad.material = this.jumpFloodInitMaterial;
-			this.jumpFloodInitMaterial.uniforms.bvh.value = bvh;
-			this.jumpFloodInitMaterial.uniforms.matrix.value = matrix;
-			this.jumpFloodInitMaterial.uniforms.zValue.value = z / dim;
-			renderer.setRenderTarget( rt1 );
-			fsQuad.render( renderer );
-
-			// Jump flooding passes
-			let stepSize = dim / 2;
-			while ( stepSize >= 1 ) {
-
-				fsQuad.material = this.jumpFloodMaterial;
-				this.jumpFloodMaterial.uniforms.map.value = rt1.texture;
-				this.jumpFloodMaterial.uniforms.stepSize.value = stepSize / dim;
-				renderer.setRenderTarget( rt2 );
-				fsQuad.render( renderer );
-
-				// Swap render targets
-				const temp = rt1;
-				rt1 = rt2;
-				rt2 = temp;
-
-				stepSize /= 2;
-
-			}
-
-			// Distance calculation pass
-			fsQuad.material = this.distanceMaterial;
-			this.distanceMaterial.uniforms.map.value = rt1.texture;
-			this.distanceMaterial.uniforms.matrix.value = matrix;
-			this.distanceMaterial.uniforms.zValue.value = z / dim;
-			renderer.setRenderTarget( rt2 );
-			fsQuad.render( renderer );
-
-			// Read the data from the render target
-			const buffer = new Float32Array( dim * dim * 4 );
-			renderer.readRenderTargetPixels( rt2, 0, 0, dim, dim, buffer );
-
-			// Copy the data to the 3D texture
-			const offset = z * dim * dim * 4;
-			sdfTexture.image.data.set( buffer, offset );
-
-		}
-
-		fsQuad.dispose();
-		rt1.dispose();
-		rt2.dispose();
-
-		return sdfTexture;
-
-	}
-
-}

+ 70 - 67
examples/jsm/utils/RayMarchSDFMaterial.js

@@ -20,54 +20,60 @@ export class RayMarchSDFMaterial extends MeshStandardMaterial {
 
 		this.onBeforeCompile = ( shader ) => {
 
-		// Add our custom uniforms
-		shader.uniforms.sdfTex = this.uniforms.sdfTex;
-		shader.uniforms.normalStep = this.uniforms.normalStep;
-		shader.uniforms.sdfNormalMatrix = this.uniforms.sdfNormalMatrix;
-		shader.uniforms.surface = this.uniforms.surface;			// Add our defines
+			// Add our custom uniforms
+			shader.uniforms.sdfTex = this.uniforms.sdfTex;
+			shader.uniforms.normalStep = this.uniforms.normalStep;
+			shader.uniforms.sdfNormalMatrix = this.uniforms.sdfNormalMatrix;
+			shader.uniforms.surface = this.uniforms.surface;
+
+			// Add our defines
 			shader.defines = shader.defines || {};
 			Object.assign( shader.defines, this.defines );
 
-		// Modify vertex shader to compute ray in local space
-		shader.vertexShader = shader.vertexShader.replace(
-			'#include <common>',
-			`#include <common>
-			varying vec3 vLocalPosition;
-			varying vec3 vLocalRayOrigin;`
-		);
-
-		shader.vertexShader = shader.vertexShader.replace(
-			'#include <worldpos_vertex>',
-			`#include <worldpos_vertex>
-			// Transform camera position to local space
-			vLocalRayOrigin = ( inverse( modelMatrix ) * vec4( cameraPosition, 1.0 ) ).xyz;
-			// Vertex position is already in local space
-			vLocalPosition = position;`
-		);			// Add custom uniforms and functions to fragment shader
-		shader.fragmentShader = shader.fragmentShader.replace(
-			'#include <common>',
-			`#include <common>
-			
-			uniform sampler3D sdfTex;
-			uniform vec3 normalStep;
-			uniform mat4 sdfNormalMatrix;
-			uniform float surface;
-			
-			varying vec3 vLocalPosition;
-			varying vec3 vLocalRayOrigin;
-
-			vec2 rayBoxDist( vec3 boundsMin, vec3 boundsMax, vec3 rayOrigin, vec3 rayDir ) {
-				vec3 t0 = ( boundsMin - rayOrigin ) / rayDir;
-				vec3 t1 = ( boundsMax - rayOrigin ) / rayDir;
-				vec3 tmin = min( t0, t1 );
-				vec3 tmax = max( t0, t1 );
-				float distA = max( max( tmin.x, tmin.y ), tmin.z );
-				float distB = min( tmax.x, min( tmax.y, tmax.z ) );
-				float distToBox = max( 0.0, distA );
-				float distInsideBox = max( 0.0, distB - distToBox );
-				return vec2( distToBox, distInsideBox );
-			}`
-		);			// Inject raymarching at the very start of main
+			// Modify vertex shader to compute ray in local space
+			shader.vertexShader = shader.vertexShader.replace(
+				'#include <common>',
+				`#include <common>
+				varying vec3 vLocalPosition;
+				varying vec3 vLocalRayOrigin;`
+			);
+
+			shader.vertexShader = shader.vertexShader.replace(
+				'#include <worldpos_vertex>',
+				`#include <worldpos_vertex>
+				// Transform camera position to local space
+				vLocalRayOrigin = ( inverse( modelMatrix ) * vec4( cameraPosition, 1.0 ) ).xyz;
+				// Vertex position is already in local space
+				vLocalPosition = position;`
+			);
+
+			// Add custom uniforms and functions to fragment shader
+			shader.fragmentShader = shader.fragmentShader.replace(
+				'#include <common>',
+				`#include <common>
+
+				uniform sampler3D sdfTex;
+				uniform vec3 normalStep;
+				uniform mat4 sdfNormalMatrix;
+				uniform float surface;
+
+				varying vec3 vLocalPosition;
+				varying vec3 vLocalRayOrigin;
+
+				vec2 rayBoxDist( vec3 boundsMin, vec3 boundsMax, vec3 rayOrigin, vec3 rayDir ) {
+					vec3 t0 = ( boundsMin - rayOrigin ) / rayDir;
+					vec3 t1 = ( boundsMax - rayOrigin ) / rayDir;
+					vec3 tmin = min( t0, t1 );
+					vec3 tmax = max( t0, t1 );
+					float distA = max( max( tmin.x, tmin.y ), tmin.z );
+					float distB = min( tmax.x, min( tmax.y, tmax.z ) );
+					float distToBox = max( 0.0, distA );
+					float distInsideBox = max( 0.0, distB - distToBox );
+					return vec2( distToBox, distInsideBox );
+				}`
+			);
+
+			// Inject raymarching at the very start of main
 			shader.fragmentShader = shader.fragmentShader.replace(
 				'void main() {',
 				`void main() {
@@ -100,23 +106,25 @@ export class RayMarchSDFMaterial extends MeshStandardMaterial {
 						break;
 					}
 					localPoint += rayDirection * distanceToSurface * 0.5;
-				}					if ( !intersectsSurface ) {
-						discard;
-					}
-					
-					// Compute UV and normal from SDF
-					vec3 sdfUV = localPoint + vec3( 0.5 );
-					vec4 sdfData = texture( sdfTex, sdfUV );
-					vec2 sdfTexUv = sdfData.gb;
-					
-					// Compute gradient in SDF local space
-					float dx = texture( sdfTex, sdfUV + vec3( normalStep.x, 0.0, 0.0 ) ).r - texture( sdfTex, sdfUV - vec3( normalStep.x, 0.0, 0.0 ) ).r;
-					float dy = texture( sdfTex, sdfUV + vec3( 0.0, normalStep.y, 0.0 ) ).r - texture( sdfTex, sdfUV - vec3( 0.0, normalStep.y, 0.0 ) ).r;
-					float dz = texture( sdfTex, sdfUV + vec3( 0.0, 0.0, normalStep.z ) ).r - texture( sdfTex, sdfUV - vec3( 0.0, 0.0, normalStep.z ) ).r;
-					vec3 sdfNormalLocal = normalize( vec3( dx, dy, dz ) );
-					
-					// Transform normal from SDF local space to view space
-					vec3 sdfNormal = normalize( ( sdfNormalMatrix * vec4( sdfNormalLocal, 0.0 ) ).xyz );
+				}
+
+				if ( !intersectsSurface ) {
+					discard;
+				}
+
+				// Compute UV and normal from SDF
+				vec3 sdfUV = localPoint + vec3( 0.5 );
+				vec4 sdfData = texture( sdfTex, sdfUV );
+				vec2 sdfTexUv = sdfData.gb;
+
+				// Compute gradient in SDF local space
+				float dx = texture( sdfTex, sdfUV + vec3( normalStep.x, 0.0, 0.0 ) ).r - texture( sdfTex, sdfUV - vec3( normalStep.x, 0.0, 0.0 ) ).r;
+				float dy = texture( sdfTex, sdfUV + vec3( 0.0, normalStep.y, 0.0 ) ).r - texture( sdfTex, sdfUV - vec3( 0.0, normalStep.y, 0.0 ) ).r;
+				float dz = texture( sdfTex, sdfUV + vec3( 0.0, 0.0, normalStep.z ) ).r - texture( sdfTex, sdfUV - vec3( 0.0, 0.0, normalStep.z ) ).r;
+				vec3 sdfNormalLocal = normalize( vec3( dx, dy, dz ) );
+
+				// Transform normal from SDF local space to view space
+				vec3 sdfNormal = normalize( ( sdfNormalMatrix * vec4( sdfNormalLocal, 0.0 ) ).xyz );
 				`
 			);
 
@@ -184,9 +192,6 @@ export class RayMarchSDFMaterial extends MeshStandardMaterial {
 				#endif`
 			);
 
-			// Debug output
-			console.log( 'Shader compiled with defines:', shader.defines );
-
 			// Replace AO sampling
 			shader.fragmentShader = shader.fragmentShader.replace(
 				'#include <aomap_fragment>',
@@ -205,5 +210,3 @@ export class RayMarchSDFMaterial extends MeshStandardMaterial {
 	}
 
 }
-
-

+ 3 - 3
examples/webgl_volume_mesh.html

@@ -164,7 +164,7 @@
 
 				} );
 				gui.add( params, 'showLayers' );
-				gui.add( params, 'layer', 0, params.resolution - 1, 1 );				window.addEventListener( 'resize', onResize );
+				gui.add( params, 'layer', 0, params.resolution - 1, 1 );
 
 				window.addEventListener( 'resize', onResize );
 
@@ -228,8 +228,8 @@
 						resolution: params.resolution,
 						margin: params.margin,
 						surface: params.surface,
-						roughness: params.roughness,
-						metalness: params.metalness
+						roughness: 1.0,
+						metalness: 1.0
 					} );
 
 					// Reuse the SDF texture from the first volume

粤ICP备19079148号