Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for black and white Bump Maps to compute normals PR #559

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion src/materials/pathtracing/PhysicalPathTracingMaterial.js
Original file line number Diff line number Diff line change
Expand Up @@ -112,10 +112,12 @@ export class PhysicalPathTracingMaterial extends MaterialBase {
vertexShader: /* glsl */`

varying vec2 vUv;
varying vec3 vViewPosition;
void main() {

vec4 mvPosition = vec4( position, 1.0 );
mvPosition = modelViewMatrix * mvPosition;
vViewPosition = - mvPosition.xyz;
gl_Position = projectionMatrix * mvPosition;

vUv = uv;
Expand Down Expand Up @@ -231,6 +233,7 @@ export class PhysicalPathTracingMaterial extends MaterialBase {
uniform float opacity;

varying vec2 vUv;
varying vec3 vViewPosition;

// globals
mat3 envRotation3x3;
Expand Down Expand Up @@ -445,7 +448,7 @@ export class PhysicalPathTracingMaterial extends MaterialBase {
if (
getSurfaceRecord(
material, surfaceHit, attributesArray, state.accumulatedRoughness,
surf
surf, vViewPosition
) == SKIP_SURFACE
) {

Expand Down
49 changes: 46 additions & 3 deletions src/materials/pathtracing/glsl/get_surface_record_function.glsl.js
Original file line number Diff line number Diff line change
@@ -1,12 +1,23 @@

export const get_surface_record_function = /* glsl */`
export const get_surface_record_function = /* glsl */ `

#define SKIP_SURFACE 0
#define HIT_SURFACE 1
vec3 perturbNormalArb( vec3 surf_pos, vec3 surf_norm, vec2 dHdxy, float faceDirection ) {
// normalize is done to ensure that the bump map looks the same regardless of the texture's scale
vec3 vSigmaX = normalize( dFdx( surf_pos.xyz ) );
vec3 vSigmaY = normalize( dFdy( surf_pos.xyz ) );
vec3 vN = surf_norm; // normalized
vec3 R1 = cross( vSigmaY, vN );
vec3 R2 = cross( vN, vSigmaX );
float fDet = dot( vSigmaX, R1 ) * faceDirection;
vec3 vGrad = sign( fDet ) * ( dHdxy.x * R1 + dHdxy.y * R2 );
return normalize( abs( fDet ) * surf_norm - vGrad );
}

int getSurfaceRecord(
Material material, SurfaceHit surfaceHit, sampler2DArray attributesArray,
float accumulatedRoughness,
inout SurfaceRecord surf
inout SurfaceRecord surf, vec3 vViewPosition
) {

if ( material.fogVolume ) {
Expand Down Expand Up @@ -154,6 +165,38 @@ export const get_surface_record_function = /* glsl */`

}

} else if( material.bumpMap != -1) {

vec4 tangentSample = textureSampleBarycoord(
attributesArray,
ATTR_TANGENT,
surfaceHit.barycoord,
surfaceHit.faceIndices.xyz
);

// some provided tangents can be malformed (0, 0, 0) causing the normal to be degenerate
// resulting in NaNs and slow path tracing.
if ( length( tangentSample.xyz ) > 0.0 ) {

vec3 tangent = normalize( tangentSample.xyz );
vec3 bitangent = normalize( cross( normal, tangent ) * tangentSample.w );
mat3 vTBN = mat3( tangent, bitangent, normal );

vec3 uvPrime = material.bumpMapTransform * vec3( uv, 1 );
float bumpScale = material.bumpScale;

vec2 dSTdx = dFdx( uvPrime.xy );
vec2 dSTdy = dFdy( uvPrime.xy );

float Hll = bumpScale * texture2D( textures, vec3( uvPrime.xy, material.bumpMap ) ).x;
float dBx = bumpScale * texture2D( textures, vec3( uvPrime.xy + dSTdx, material.bumpMap ) ).x - Hll;
float dBy = bumpScale * texture2D( textures, vec3( uvPrime.xy + dSTdy, material.bumpMap ) ).x - Hll;

vec2 dHdxy = vec2( dBx, dBy );
normal += vTBN * perturbNormalArb( -vViewPosition, (normal * 2.0 - 1.0), dHdxy , 1.0 );

}

}

normal *= surfaceHit.side;
Expand Down
12 changes: 11 additions & 1 deletion src/shader/structs/material_struct.glsl.js
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ export const material_struct = /* glsl */ `
mat3 specularColorMapTransform;
mat3 specularIntensityMapTransform;

int bumpMap;
float bumpScale;
mat3 bumpMapTransform;

};

mat3 readTextureTransform( sampler2D tex, uint index ) {
Expand All @@ -101,7 +105,7 @@ export const material_struct = /* glsl */ `

Material readMaterialInfo( sampler2D tex, uint index ) {

uint i = index * 45u;
uint i = index * 48u;

vec4 s0 = texelFetch1D( tex, i + 0u );
vec4 s1 = texelFetch1D( tex, i + 1u );
Expand Down Expand Up @@ -201,6 +205,12 @@ export const material_struct = /* glsl */ `
m.specularColorMapTransform = m.specularColorMap == - 1 ? mat3( 1.0 ) : readTextureTransform( tex, firstTextureTransformIdx + 26u );
m.specularIntensityMapTransform = m.specularIntensityMap == - 1 ? mat3( 1.0 ) : readTextureTransform( tex, firstTextureTransformIdx + 28u );

vec4 s15 = texelFetch1D( tex, firstTextureTransformIdx + 30u );
m.bumpMap = int( round( s15.r ) );
m.bumpScale = s15.g;
// s15.b, s15.a are not used
m.bumpMapTransform = m.bumpMap == - 1 ? mat3( 1.0 ) : readTextureTransform( tex, firstTextureTransformIdx + 31u );

return m;

}
Expand Down
13 changes: 12 additions & 1 deletion src/uniforms/MaterialsTexture.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { DataTexture, RGBAFormat, ClampToEdgeWrapping, FloatType, FrontSide, BackSide, DoubleSide, NearestFilter } from 'three';
import { reduceTexturesToUniqueSources, getTextureHash } from './utils.js';

const MATERIAL_PIXELS = 45;
const MATERIAL_PIXELS = 48;
const MATERIAL_STRIDE = MATERIAL_PIXELS * 4;

const MATTE_OFFSET = 14 * 4 + 0; // s14.r
Expand Down Expand Up @@ -457,6 +457,17 @@ export class MaterialsTexture extends DataTexture {
// specularIntensityMap transform 43
index += writeTextureMatrixToArray( m, 'specularIntensityMap', floatArray, index );

// sample 45
// bumpMap texture
floatArray[ index ++ ] = getTexture( m, 'bumpMap' );
// bumpScale
floatArray[ index ++ ] = getField( m, 'bumpScale', 1.0 );
// padding 2 index for alignment to 4
index ++;
index ++;
// bumpMap transform 46, 47
index += writeTextureMatrixToArray( m, 'bumpMap', floatArray, index );

}

this.needsUpdate = true;
Expand Down