|
@@ -9,41 +9,22 @@ import { addNodeElement, tslFn, nodeProxy, float, vec2 } from '../shadernode/Sha
|
|
|
// Bump Mapping Unparametrized Surfaces on the GPU by Morten S. Mikkelsen
|
|
|
// https://mmikk.github.io/papers3d/mm_sfgrad_bump.pdf
|
|
|
|
|
|
-// Evaluate the derivative of the height w.r.t. screen-space using forward differencing (listing 2)
|
|
|
-
|
|
|
const dHdxy_fwd = tslFn( ( { textureNode, bumpScale } ) => {
|
|
|
|
|
|
- let texNode = textureNode;
|
|
|
-
|
|
|
- if ( texNode.isTextureNode !== true ) {
|
|
|
-
|
|
|
- texNode.traverse( ( node ) => {
|
|
|
-
|
|
|
- if ( node.isTextureNode === true ) texNode = node;
|
|
|
-
|
|
|
- } );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- if ( texNode.isTextureNode !== true ) {
|
|
|
-
|
|
|
- throw new Error( 'THREE.TSL: dHdxy_fwd() requires a TextureNode.' );
|
|
|
-
|
|
|
- }
|
|
|
-
|
|
|
- const Hll = float( textureNode );
|
|
|
- const uvNode = texNode.uvNode || uv();
|
|
|
-
|
|
|
// It's used to preserve the same TextureNode instance
|
|
|
- const sampleTexture = ( uv ) => textureNode.cache().context( { getUV: () => uv, forceUVContext: true } );
|
|
|
+ const sampleTexture = ( callback ) => textureNode.cache().context( { getUV: ( texNode ) => callback( texNode.uvNode || uv() ), forceUVContext: true } );
|
|
|
+
|
|
|
+ const Hll = float( sampleTexture( ( uvNode ) => uvNode ) );
|
|
|
|
|
|
return vec2(
|
|
|
- float( sampleTexture( uvNode.add( uvNode.dFdx() ) ) ).sub( Hll ),
|
|
|
- float( sampleTexture( uvNode.add( uvNode.dFdy() ) ) ).sub( Hll )
|
|
|
+ float( sampleTexture( ( uvNode ) => uvNode.add( uvNode.dFdx() ) ) ).sub( Hll ),
|
|
|
+ float( sampleTexture( ( uvNode ) => uvNode.add( uvNode.dFdy() ) ) ).sub( Hll )
|
|
|
).mul( bumpScale );
|
|
|
|
|
|
} );
|
|
|
|
|
|
+// Evaluate the derivative of the height w.r.t. screen-space using forward differencing (listing 2)
|
|
|
+
|
|
|
const perturbNormalArb = tslFn( ( inputs ) => {
|
|
|
|
|
|
const { surf_pos, surf_norm, dHdxy } = inputs;
|