mirror of
https://github.com/FMS-Cat/condition.git
synced 2025-08-12 16:54:02 +02:00
feature: improve multiple light + improve condition
This commit is contained in:
File diff suppressed because one or more lines are too long
@@ -91,121 +91,122 @@ export class CameraEntity extends Entity {
|
||||
name: process.env.DEV && 'CameraEntity/ao/quad',
|
||||
} );
|
||||
|
||||
const shadingMaterials = options.lights.map( ( light, iLight ) => {
|
||||
const shadingMaterial = new Material(
|
||||
quadVert,
|
||||
shadingFrag,
|
||||
{
|
||||
defines: iLight === 0 ? [ 'IS_FIRST_LIGHT' ] : [],
|
||||
initOptions: { geometry: quadGeometry, target: dummyRenderTarget },
|
||||
},
|
||||
);
|
||||
const shadingMaterial = new Material(
|
||||
quadVert,
|
||||
shadingFrag,
|
||||
{
|
||||
initOptions: { geometry: quadGeometry, target: dummyRenderTarget },
|
||||
},
|
||||
);
|
||||
|
||||
const shadingQuad = new Quad( {
|
||||
material: shadingMaterial,
|
||||
target: options.target,
|
||||
name: process.env.DEV && 'CameraEntity/shading/quad',
|
||||
} );
|
||||
shadingQuad.clear = iLight === 0 ? [] : false;
|
||||
|
||||
const lambda = new Lambda( {
|
||||
onUpdate: ( { frameCount } ) => {
|
||||
const lightHasUpdated = frameCount === light.lastUpdateFrame;
|
||||
shadingQuad.active = lightHasUpdated;
|
||||
if ( !lightHasUpdated ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const cameraView = this.transform.matrix.inverse!;
|
||||
|
||||
shadingMaterial.addUniformMatrixVector(
|
||||
'cameraView',
|
||||
'Matrix4fv',
|
||||
cameraView.elements
|
||||
);
|
||||
|
||||
shadingMaterial.addUniformMatrixVector(
|
||||
'cameraPV',
|
||||
'Matrix4fv',
|
||||
this.camera.projectionMatrix.multiply(
|
||||
cameraView
|
||||
).elements
|
||||
);
|
||||
|
||||
shadingMaterial.addUniform(
|
||||
'lightNearFar',
|
||||
'2f',
|
||||
light.camera.near,
|
||||
light.camera.far
|
||||
);
|
||||
|
||||
shadingMaterial.addUniform(
|
||||
'cameraNearFar',
|
||||
'2f',
|
||||
this.camera.near,
|
||||
this.camera.far
|
||||
);
|
||||
|
||||
shadingMaterial.addUniform(
|
||||
'cameraPos',
|
||||
'3f',
|
||||
...this.transform.position.elements
|
||||
);
|
||||
|
||||
shadingMaterial.addUniform(
|
||||
'lightPos',
|
||||
'3f',
|
||||
...light.transform.position.elements
|
||||
);
|
||||
|
||||
shadingMaterial.addUniform(
|
||||
'lightColor',
|
||||
'3f',
|
||||
...light.color
|
||||
);
|
||||
|
||||
shadingMaterial.addUniformMatrixVector(
|
||||
'lightPV',
|
||||
'Matrix4fv',
|
||||
light.camera.projectionMatrix.multiply(
|
||||
light.transform.matrix.inverse!
|
||||
).elements
|
||||
);
|
||||
},
|
||||
name: process.env.DEV && 'CameraEntity/shading/setCameraUniforms',
|
||||
} );
|
||||
|
||||
for ( let i = 0; i < 4; i ++ ) {
|
||||
shadingMaterial.addUniformTexture(
|
||||
'sampler' + i,
|
||||
cameraTarget.getTexture( gl.COLOR_ATTACHMENT0 + i )
|
||||
);
|
||||
}
|
||||
|
||||
shadingMaterial.blend = [ gl.ONE, gl.ONE ];
|
||||
shadingMaterial.addUniformTexture( 'samplerAo', aoTarget.texture );
|
||||
shadingMaterial.addUniformTexture( 'samplerShadow', light.shadowMap.texture );
|
||||
shadingMaterial.addUniformTexture( 'samplerIBLLUT', options.textureIBLLUT );
|
||||
shadingMaterial.addUniformTexture( 'samplerEnv', options.textureEnv );
|
||||
shadingMaterial.addUniformTexture( 'samplerRandom', randomTexture.texture );
|
||||
|
||||
this.components.push(
|
||||
this.camera,
|
||||
lambdaAoSetCameraUniforms,
|
||||
aoQuad,
|
||||
lambda,
|
||||
shadingQuad,
|
||||
);
|
||||
|
||||
return shadingMaterial;
|
||||
const shadingQuad = new Quad( {
|
||||
material: shadingMaterial,
|
||||
target: options.target,
|
||||
name: process.env.DEV && 'CameraEntity/shading/quad',
|
||||
} );
|
||||
shadingQuad.clear = [];
|
||||
|
||||
const lambda = new Lambda( {
|
||||
onUpdate: ( { frameCount } ) => {
|
||||
const lights = options.lights.filter( ( light ) => (
|
||||
frameCount === light.lastUpdateFrame
|
||||
) );
|
||||
|
||||
const cameraView = this.transform.matrix.inverse!;
|
||||
|
||||
shadingMaterial.addUniform(
|
||||
'lightCount',
|
||||
'1i',
|
||||
lights.length,
|
||||
);
|
||||
|
||||
shadingMaterial.addUniformMatrixVector(
|
||||
'cameraView',
|
||||
'Matrix4fv',
|
||||
cameraView.elements
|
||||
);
|
||||
|
||||
shadingMaterial.addUniformMatrixVector(
|
||||
'cameraPV',
|
||||
'Matrix4fv',
|
||||
this.camera.projectionMatrix.multiply(
|
||||
cameraView
|
||||
).elements
|
||||
);
|
||||
|
||||
shadingMaterial.addUniform(
|
||||
'cameraNearFar',
|
||||
'2f',
|
||||
this.camera.near,
|
||||
this.camera.far
|
||||
);
|
||||
|
||||
shadingMaterial.addUniform(
|
||||
'cameraPos',
|
||||
'3f',
|
||||
...this.transform.position.elements
|
||||
);
|
||||
|
||||
shadingMaterial.addUniformVector(
|
||||
'lightNearFar',
|
||||
'2fv',
|
||||
lights.map( ( light ) => [ light.camera.near, light.camera.far ] ).flat(),
|
||||
);
|
||||
|
||||
shadingMaterial.addUniformVector(
|
||||
'lightPos',
|
||||
'3fv',
|
||||
lights.map( ( light ) => light.globalTransformCache.position.elements ).flat(),
|
||||
);
|
||||
|
||||
shadingMaterial.addUniformVector(
|
||||
'lightColor',
|
||||
'3fv',
|
||||
lights.map( ( light ) => light.color ).flat(),
|
||||
);
|
||||
|
||||
shadingMaterial.addUniformMatrixVector(
|
||||
'lightPV',
|
||||
'Matrix4fv',
|
||||
lights.map( ( light ) => (
|
||||
light.camera.projectionMatrix.multiply(
|
||||
light.globalTransformCache.matrix.inverse!
|
||||
).elements
|
||||
) ).flat(),
|
||||
);
|
||||
|
||||
shadingMaterial.addUniformTextureArray(
|
||||
'samplerShadow',
|
||||
lights.map( ( light ) => light.shadowMap.texture ),
|
||||
);
|
||||
},
|
||||
name: process.env.DEV && 'CameraEntity/shading/setCameraUniforms',
|
||||
} );
|
||||
|
||||
for ( let i = 0; i < 4; i ++ ) {
|
||||
shadingMaterial.addUniformTexture(
|
||||
'sampler' + i,
|
||||
cameraTarget.getTexture( gl.COLOR_ATTACHMENT0 + i )
|
||||
);
|
||||
}
|
||||
|
||||
shadingMaterial.addUniformTexture( 'samplerAo', aoTarget.texture );
|
||||
shadingMaterial.addUniformTexture( 'samplerIBLLUT', options.textureIBLLUT );
|
||||
shadingMaterial.addUniformTexture( 'samplerEnv', options.textureEnv );
|
||||
shadingMaterial.addUniformTexture( 'samplerRandom', randomTexture.texture );
|
||||
|
||||
this.components.push(
|
||||
this.camera,
|
||||
lambdaAoSetCameraUniforms,
|
||||
aoQuad,
|
||||
lambda,
|
||||
shadingQuad,
|
||||
);
|
||||
|
||||
if ( process.env.DEV ) {
|
||||
if ( module.hot ) {
|
||||
module.hot.accept( '../shaders/shading.frag', () => {
|
||||
shadingMaterials.forEach( ( material ) => {
|
||||
material.replaceShader( quadVert, shadingFrag );
|
||||
} );
|
||||
shadingMaterial.replaceShader( quadVert, shadingFrag );
|
||||
} );
|
||||
}
|
||||
}
|
||||
|
@@ -139,7 +139,11 @@ export class Condition extends Entity {
|
||||
} );
|
||||
|
||||
auto( 'Sync/first/clap', ( { value } ) => {
|
||||
material.addUniform( 'phaseOffset', '1f', 0.2 * value );
|
||||
material.addUniform( 'phaseOffset', '1f', value );
|
||||
} );
|
||||
|
||||
auto( 'Condition/hahaRatio', ( { value } ) => {
|
||||
material.addUniform( 'hahaRatio', '1f', value );
|
||||
} );
|
||||
} );
|
||||
|
||||
|
@@ -27,6 +27,7 @@ export interface EntityDrawEvent {
|
||||
|
||||
export class Entity {
|
||||
public readonly transform = new Transform();
|
||||
public globalTransformCache = new Transform();
|
||||
|
||||
public lastUpdateFrame = 0;
|
||||
|
||||
@@ -67,14 +68,14 @@ export class Entity {
|
||||
public draw( event: EntityDrawEvent ): void {
|
||||
if ( !this.visible ) { return; }
|
||||
|
||||
const globalTransform = event.globalTransform.multiply( this.transform );
|
||||
this.globalTransformCache = event.globalTransform.multiply( this.transform );
|
||||
|
||||
this.components.forEach( ( component ) => {
|
||||
component.draw( {
|
||||
frameCount: event.frameCount,
|
||||
time: event.time,
|
||||
renderTarget: event.renderTarget,
|
||||
globalTransform,
|
||||
globalTransform: this.globalTransformCache,
|
||||
camera: event.camera,
|
||||
cameraTransform: event.cameraTransform,
|
||||
viewMatrix: event.viewMatrix,
|
||||
@@ -89,7 +90,7 @@ export class Entity {
|
||||
frameCount: event.frameCount,
|
||||
time: event.time,
|
||||
renderTarget: event.renderTarget,
|
||||
globalTransform,
|
||||
globalTransform: this.globalTransformCache,
|
||||
viewMatrix: event.viewMatrix,
|
||||
projectionMatrix: event.projectionMatrix,
|
||||
camera: event.camera,
|
||||
|
@@ -50,6 +50,12 @@ export class Material {
|
||||
};
|
||||
} = {};
|
||||
|
||||
protected __uniformTextureArrays: {
|
||||
[ name: string ]: {
|
||||
textures: GLCatTexture[];
|
||||
};
|
||||
} = {};
|
||||
|
||||
protected __uniformCubemaps: {
|
||||
[ name: string ]: {
|
||||
texture: GLCatTextureCubemap | null;
|
||||
@@ -135,6 +141,10 @@ export class Material {
|
||||
this.__uniformTextures[ name ] = { texture };
|
||||
}
|
||||
|
||||
public addUniformTextureArray( name: string, textures: GLCatTexture[] ): void {
|
||||
this.__uniformTextureArrays[ name ] = { textures };
|
||||
}
|
||||
|
||||
public addUniformCubemap( name: string, texture: GLCatTextureCubemap | null ): void {
|
||||
this.__uniformCubemaps[ name ] = { texture };
|
||||
}
|
||||
@@ -160,6 +170,10 @@ export class Material {
|
||||
program.uniformTexture( name, texture );
|
||||
} );
|
||||
|
||||
Object.entries( this.__uniformTextureArrays ).forEach( ( [ name, { textures } ] ) => {
|
||||
program.uniformTextures( name, textures );
|
||||
} );
|
||||
|
||||
Object.entries( this.__uniformCubemaps ).forEach( ( [ name, { texture } ] ) => {
|
||||
program.uniformCubemap( name, texture );
|
||||
} );
|
||||
|
@@ -195,8 +195,8 @@ const replacerLightFirst = new EntityReplacer( () => {
|
||||
shadowMapFar: 20.0,
|
||||
namePrefix: process.env.DEV && 'lightFirst',
|
||||
} );
|
||||
light.color = [ 40.0, 40.0, 40.0 ];
|
||||
light.transform.lookAt( new Vector3( [ -1.0, 2.0, 8.0 ] ) );
|
||||
light.color = [ 100.0, 100.0, 100.0 ];
|
||||
light.transform.lookAt( new Vector3( [ 4.0, 4.0, 4.0 ] ) );
|
||||
return light;
|
||||
}, 'LightFirst' );
|
||||
const lightFirst = replacerLightFirst.current;
|
||||
@@ -210,7 +210,7 @@ const replacerLightPink = new EntityReplacer( () => {
|
||||
namePrefix: process.env.DEV && 'lightPink',
|
||||
} );
|
||||
light.color = [ 120.0, 2.0, 10.0 ];
|
||||
light.transform.lookAt( new Vector3( [ -1.0, 4.0, 4.0 ] ) );
|
||||
light.transform.lookAt( new Vector3( [ -1.0, 2.0, 2.0 ] ) );
|
||||
return light;
|
||||
}, 'LightPink' );
|
||||
const lightPink = replacerLightPink.current;
|
||||
|
@@ -11,6 +11,7 @@ const int MTL_UNLIT = 1;
|
||||
|
||||
in float vScale;
|
||||
in float vPhase;
|
||||
in float vFade;
|
||||
in vec3 vNormal;
|
||||
in vec4 vPosition;
|
||||
in vec4 vHuh;
|
||||
@@ -45,6 +46,7 @@ void main() {
|
||||
if ( lenFromCenter < RADIUS_CULL_SPHERE ) { discard; }
|
||||
|
||||
float colorPhase = exp( -4.0 * ( lenFromCenter - RADIUS_CULL_SPHERE ) );
|
||||
colorPhase = max( colorPhase, vFade );
|
||||
vec3 color = mix(
|
||||
vec3( 2.0 ),
|
||||
vec3( 0.0 ),
|
||||
|
@@ -9,11 +9,13 @@ layout (location = 1) in vec4 huh;
|
||||
|
||||
out float vPhase;
|
||||
out float vScale;
|
||||
out float vFade;
|
||||
out vec3 vNormal;
|
||||
out vec4 vPosition;
|
||||
out vec4 vHuh;
|
||||
|
||||
uniform float time;
|
||||
uniform float hahaRatio;
|
||||
uniform vec2 resolution;
|
||||
uniform mat4 projectionMatrix;
|
||||
uniform mat4 viewMatrix;
|
||||
@@ -27,10 +29,17 @@ void main() {
|
||||
vPhase = what.x;
|
||||
vHuh = huh;
|
||||
|
||||
vec3 randomPos = fs( vec3( 5.0, 8.6, 1.9 ) + huh.z + 2.56 * huh.y ) - 0.5;
|
||||
randomPos.z = mod( randomPos.z + 0.1 * time, 1.0 ) - 0.5;
|
||||
randomPos *= vec3( 5.0, 5.0, 20.0 );
|
||||
|
||||
vFade = smoothstep( 9.0, 10.0, abs( randomPos.z ) );
|
||||
|
||||
float haha = hahaRatio * smoothstep( 1.0, 2.0, randomPos.z );
|
||||
|
||||
vec4 tex = texture( samplerSvg, vec2( what.x, huh.x ) );
|
||||
|
||||
vPosition = vec4( tex.xy, 0.0, 1.0 );
|
||||
// vPosition.x += huh.y;
|
||||
|
||||
mat3 basis = orthBasis( vec3( tex.zw, 0.0 ) );
|
||||
float theta = what.y / 3.0 * TAU;
|
||||
@@ -38,17 +47,15 @@ void main() {
|
||||
vNormal = ( normalMatrix * vec4( tube, 1.0 ) ).xyz;
|
||||
|
||||
vScale = exp( 2.0 * fs( huh.z + 2.56 * huh.y ) );
|
||||
vPosition.xyz *= vScale;
|
||||
vPosition.xyz *= mix( vScale, 1.0, haha );
|
||||
|
||||
vPosition.x += mix( 0.0, huh.y, haha );
|
||||
|
||||
vPosition.xyz += tube;
|
||||
|
||||
vPosition = modelMatrix * vPosition;
|
||||
|
||||
vec3 randomPos = fs( vec3( 5.0, 8.6, 1.9 ) + huh.z + 2.56 * huh.y ) - 0.5;
|
||||
randomPos.z = mod( randomPos.z + 0.1 * time, 1.0 ) - 0.5;
|
||||
vPosition.xyz += vec3( 5.0, 5.0, 20.0 ) * randomPos;
|
||||
|
||||
// vPosition.z += 6.0 - 1.2 * huh.z;
|
||||
vPosition.xyz += mix( randomPos, vec3( 0.0, 0.0, 3.0 ), haha );
|
||||
|
||||
vec4 outPos = projectionMatrix * viewMatrix * vPosition;
|
||||
outPos.x *= resolution.y / resolution.x;
|
||||
|
@@ -23,13 +23,13 @@ uniform float time;
|
||||
|
||||
void main() {
|
||||
#ifdef FORWARD
|
||||
fragColor = vec4( 8.0 * vec3( 0.9, 0.02, 0.1 ), 1.0 );
|
||||
fragColor = vec4( 8.0 * vec3( 0.1, 0.9, 0.4 ), 1.0 );
|
||||
#endif
|
||||
|
||||
#ifdef DEFERRED
|
||||
fragPosition = vPosition;
|
||||
fragNormal = vec4( normalize( vNormal ), 1.0 );
|
||||
fragColor = vec4( 0.9, 0.02, 0.1, 1.0 );
|
||||
fragColor = vec4( 0.1, 0.9, 0.4, 1.0 );
|
||||
fragWTF = vec4( vec3( 0.2, 0.2, 8.0 ), MTL_PBR );
|
||||
#endif
|
||||
}
|
||||
|
@@ -6,7 +6,6 @@ const int MTL_NONE = 0;
|
||||
const int MTL_UNLIT = 1;
|
||||
const int MTL_PBR = 2;
|
||||
const int MTL_GRADIENT = 3;
|
||||
const int MTL_IRIDESCENT = 4;
|
||||
const int AO_ITER = 8;
|
||||
const float ENV_UV_MARGIN = 0.9375;
|
||||
const float AO_BIAS = 0.0;
|
||||
@@ -27,19 +26,20 @@ in vec2 vUv;
|
||||
|
||||
out vec4 fragColor;
|
||||
|
||||
uniform vec2 lightNearFar;
|
||||
uniform int lightCount;
|
||||
uniform vec2 lightNearFar[8];
|
||||
uniform vec2 cameraNearFar;
|
||||
uniform vec3 cameraPos;
|
||||
uniform vec3 lightPos;
|
||||
uniform vec3 lightColor;
|
||||
uniform mat4 lightPV;
|
||||
uniform vec3 lightPos[8];
|
||||
uniform vec3 lightColor[8];
|
||||
uniform mat4 lightPV[8];
|
||||
uniform mat4 cameraView;
|
||||
uniform mat4 cameraPV;
|
||||
uniform sampler2D sampler0; // position.xyz, depth
|
||||
uniform sampler2D sampler1; // normal.xyz (yes, this is not good)
|
||||
uniform sampler2D sampler2; // color.rgba (what is a though????)
|
||||
uniform sampler2D sampler3; // materialParams.xyz, materialId
|
||||
uniform sampler2D samplerShadow;
|
||||
uniform sampler2D samplerShadow[8];
|
||||
uniform sampler2D samplerIBLLUT;
|
||||
uniform sampler2D samplerEnv;
|
||||
uniform sampler2D samplerAo;
|
||||
@@ -106,46 +106,42 @@ struct Isect {
|
||||
vec3 materialParams;
|
||||
};
|
||||
|
||||
struct AngularInfo {
|
||||
vec3 V;
|
||||
vec3 L;
|
||||
vec3 H;
|
||||
float lenL;
|
||||
float lenV;
|
||||
float dotNV;
|
||||
float dotNL;
|
||||
float dotNH;
|
||||
float dotVH;
|
||||
};
|
||||
|
||||
AngularInfo genAngularInfo( Isect isect ) {
|
||||
AngularInfo aI;
|
||||
aI.V = cameraPos - isect.position;
|
||||
aI.lenV = length( aI.V );
|
||||
aI.V = normalize( aI.V );
|
||||
|
||||
aI.L = lightPos - isect.position;
|
||||
aI.lenL = length( aI.L );
|
||||
aI.L = normalize( aI.L );
|
||||
|
||||
aI.H = normalize( aI.V + aI.L );
|
||||
aI.dotNV = clamp( dot( isect.normal, aI.V ), EPSILON, 1.0 );
|
||||
aI.dotNL = clamp( dot( isect.normal, aI.L ), EPSILON, 1.0 );
|
||||
aI.dotNH = clamp( dot( isect.normal, aI.H ), EPSILON, 1.0 );
|
||||
aI.dotVH = clamp( dot( aI.V, aI.H ), EPSILON, 1.0 );
|
||||
return aI;
|
||||
// == this is BAD ==================================================================================
|
||||
vec4 fetchShadowMap( int iLight, vec2 uv ) {
|
||||
if ( iLight == 0 ) {
|
||||
return texture( samplerShadow[ 0 ], uv );
|
||||
} else if ( iLight == 1 ) {
|
||||
return texture( samplerShadow[ 1 ], uv );
|
||||
} else if ( iLight == 2 ) {
|
||||
return texture( samplerShadow[ 2 ], uv );
|
||||
} else if ( iLight == 3 ) {
|
||||
return texture( samplerShadow[ 3 ], uv );
|
||||
} else if ( iLight == 4 ) {
|
||||
return texture( samplerShadow[ 4 ], uv );
|
||||
} else if ( iLight == 5 ) {
|
||||
return texture( samplerShadow[ 5 ], uv );
|
||||
} else if ( iLight == 6 ) {
|
||||
return texture( samplerShadow[ 6 ], uv );
|
||||
} else if ( iLight == 7 ) {
|
||||
return texture( samplerShadow[ 7 ], uv );
|
||||
}
|
||||
}
|
||||
|
||||
// == features =====================================================================================
|
||||
float castShadow( Isect isect, AngularInfo aI ) {
|
||||
float depth = linearstep( lightNearFar.x, lightNearFar.y, length( isect.position - lightPos ) );
|
||||
float bias = 0.0001 + 0.0001 * ( 1.0 - aI.dotNL );
|
||||
float castShadow( int iLight, Isect isect, float NdotL ) {
|
||||
float depth = linearstep(
|
||||
lightNearFar[ iLight ].x,
|
||||
lightNearFar[ iLight ].y,
|
||||
length( isect.position - lightPos[ iLight ] )
|
||||
);
|
||||
|
||||
float bias = 0.0001 + 0.0001 * ( 1.0 - NdotL );
|
||||
depth -= bias;
|
||||
|
||||
vec4 proj = lightPV * vec4( isect.position, 1.0 );
|
||||
vec4 proj = lightPV[ iLight ] * vec4( isect.position, 1.0 );
|
||||
vec2 uv = proj.xy / proj.w * 0.5 + 0.5;
|
||||
|
||||
vec4 tex = texture( samplerShadow, uv );
|
||||
vec4 tex = fetchShadowMap( iLight, uv );
|
||||
|
||||
float edgeClip = smoothstep( 0.4, 0.5, max( abs( uv.x - 0.5 ), abs( uv.y - 0.5 ) ) );
|
||||
|
||||
@@ -170,32 +166,57 @@ float calcDepth( vec3 pos ) {
|
||||
}
|
||||
|
||||
// == shading functions ============================================================================
|
||||
vec3 shadePBR( Isect isect, AngularInfo aI ) {
|
||||
vec3 shadePBR( Isect isect ) {
|
||||
// ref: https://github.com/KhronosGroup/glTF-Sample-Viewer/blob/master/src/shaders/metallic-roughness.frag
|
||||
|
||||
// from isect
|
||||
vec3 V = cameraPos - isect.position;
|
||||
float lenV = length( V );
|
||||
V = normalize( V );
|
||||
|
||||
float NdotV = clamp( dot( isect.normal, V ), EPSILON, 1.0 );
|
||||
|
||||
float roughness = isect.materialParams.x;
|
||||
float metallic = isect.materialParams.y;
|
||||
float emissive = isect.materialParams.z;
|
||||
|
||||
float shadow = castShadow( isect, aI );
|
||||
shadow = mix( 1.0, shadow, 0.8 );
|
||||
|
||||
float ao = texture( samplerAo, isect.screenUv ).x;
|
||||
shadow *= ao;
|
||||
|
||||
float decayL = 1.0 / ( aI.lenL * aI.lenL );
|
||||
|
||||
// calc material stuff
|
||||
vec3 albedo = mix( isect.color * ONE_SUB_DIELECTRIC_SPECULAR, vec3( 0.0 ), metallic );
|
||||
vec3 f0 = mix( DIELECTRIC_SPECULAR, isect.color, metallic );
|
||||
|
||||
vec3 diffuse = brdfLambert( f0, albedo, aI.dotVH );
|
||||
vec3 spec = brdfSpecularGGX( f0, roughness, aI.dotVH, aI.dotNL, aI.dotNV, aI.dotNH );
|
||||
float ao = texture( samplerAo, isect.screenUv ).x;
|
||||
|
||||
vec3 shade = PI * lightColor * decayL * shadow * aI.dotNL * ( diffuse + spec );
|
||||
// begin lighting
|
||||
vec3 color = vec3( 0.0 );
|
||||
|
||||
vec3 color = shade;
|
||||
// for each lights
|
||||
for ( int iLight = 0; iLight < 8; iLight ++ ) {
|
||||
if ( iLight >= lightCount ) { break; }
|
||||
|
||||
#ifdef IS_FIRST_LIGHT
|
||||
// calc vectors
|
||||
vec3 L = lightPos[ iLight ] - isect.position;
|
||||
float lenL = length( L );
|
||||
L = normalize( L );
|
||||
|
||||
vec3 H = normalize( V + L );
|
||||
float NdotL = clamp( dot( isect.normal, L ), EPSILON, 1.0 );
|
||||
float NdotH = clamp( dot( isect.normal, H ), EPSILON, 1.0 );
|
||||
float VdotH = clamp( dot( V, H ), EPSILON, 1.0 );
|
||||
|
||||
float decayL = 1.0 / ( lenL * lenL );
|
||||
|
||||
// fetch shadowmap
|
||||
float shadow = castShadow( iLight, isect, NdotL );
|
||||
shadow = mix( 0.5, 1.0, shadow );
|
||||
|
||||
// do shading
|
||||
vec3 diffuse = brdfLambert( f0, albedo, VdotH );
|
||||
vec3 spec = brdfSpecularGGX( f0, roughness, VdotH, NdotL, NdotV, NdotH );
|
||||
|
||||
vec3 shade = PI * lightColor[ iLight ] * decayL * ao * shadow * NdotL * ( diffuse + spec );
|
||||
|
||||
color += shade;
|
||||
}
|
||||
|
||||
// cheat the texture seam using noise!
|
||||
vec3 nEnvDiffuse = importanceSampleGGX( vec2( prng( seed ), prng( seed ) * 0.05 ), 2.0, isect.normal );
|
||||
@@ -209,34 +230,25 @@ vec3 shadePBR( Isect isect, AngularInfo aI ) {
|
||||
color += ao * texEnvDiffuse * albedo;
|
||||
|
||||
// reflective ibl
|
||||
vec3 reflEnvReflective = reflect( aI.V, isect.normal );
|
||||
vec3 reflEnvReflective = reflect( V, isect.normal );
|
||||
vec2 uvEnvReflective = vec2(
|
||||
0.5 + atan( reflEnvReflective.x, -reflEnvReflective.z ) / TAU,
|
||||
0.5 + atan( reflEnvReflective.y, length( reflEnvReflective.zx ) ) / PI
|
||||
);
|
||||
vec2 brdfEnvReflective = texture( samplerIBLLUT, vec2( aI.dotNV, roughness ) ).xy;
|
||||
vec2 brdfEnvReflective = texture( samplerIBLLUT, vec2( NdotV, roughness ) ).xy;
|
||||
vec3 texEnvReflective = sampleEnvLinear( uvEnvReflective, 3.0 * roughness ).rgb;
|
||||
color += ao * texEnvReflective * ( brdfEnvReflective.x * f0 + brdfEnvReflective.y );
|
||||
|
||||
// emissive
|
||||
color += emissive * aI.dotNV * isect.color;
|
||||
#endif // IS_FIRST_LIGHT
|
||||
color += emissive * NdotV * isect.color;
|
||||
|
||||
return color;
|
||||
|
||||
}
|
||||
|
||||
vec3 shadeGradient( Isect isect ) {
|
||||
vec3 ret;
|
||||
|
||||
#ifdef IS_FIRST_LIGHT
|
||||
float shade = isect.normal.y;
|
||||
ret = blurpleGradient( 0.5 + 0.5 * shade );
|
||||
#else // IS_FIRST_LIGHT
|
||||
ret = vec3( 0.0 );
|
||||
#endif // IS_FIRST_LIGHT
|
||||
|
||||
return ret;
|
||||
return blurpleGradient( 0.5 + 0.5 * shade );
|
||||
}
|
||||
|
||||
// == main procedure ===============================================================================
|
||||
@@ -260,41 +272,27 @@ void main() {
|
||||
|
||||
vec3 color = vec3( 0.0 );
|
||||
|
||||
AngularInfo aI = genAngularInfo( isect );
|
||||
|
||||
if ( isect.materialId == MTL_NONE ) {
|
||||
// do nothing
|
||||
|
||||
} else if ( isect.materialId == MTL_UNLIT ) {
|
||||
#ifdef IS_FIRST_LIGHT
|
||||
color = isect.color;
|
||||
#endif
|
||||
|
||||
} else if ( isect.materialId == MTL_PBR ) {
|
||||
color = shadePBR( isect, aI );
|
||||
color = shadePBR( isect );
|
||||
|
||||
} else if ( isect.materialId == MTL_GRADIENT ) {
|
||||
color = shadeGradient( isect );
|
||||
|
||||
} else if ( isect.materialId == MTL_IRIDESCENT ) {
|
||||
isect.color *= mix(
|
||||
vec3( 1.0 ),
|
||||
catColor( isect.materialParams.x * aI.dotNV ),
|
||||
isect.materialParams.y
|
||||
);
|
||||
isect.materialParams = vec3( 0.1, isect.materialParams.z, 0.0 );
|
||||
color = shadePBR( isect, aI );
|
||||
|
||||
}
|
||||
|
||||
color *= exp( -0.4 * max( aI.lenV - 3.0, 0.0 ) );
|
||||
float lenV = length( cameraPos - isect.position );
|
||||
color *= exp( -0.4 * max( lenV - 3.0, 0.0 ) );
|
||||
|
||||
#ifdef IS_FIRST_LIGHT
|
||||
// color = 0.5 + 0.5 * isect.normal;
|
||||
// color = vec3( calcDepth( tex0.xyz ) );
|
||||
// color = vec3( 0.5, 0.9, 0.6 ) * ( 1.0 - texture( samplerAo, isect.screenUv ).xyz );
|
||||
// color = vec3( 0.5, 0.9, 0.6 ) * ( texture( samplerAo, isect.screenUv ).xyz );
|
||||
#endif
|
||||
// xfdA = shadeGradient( isect );
|
||||
|
||||
fragColor = vec4( color, 1.0 );
|
||||
|
Reference in New Issue
Block a user