-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #9 from Shubidumdu/pbr
Add new sketch "Pbr"
- Loading branch information
Showing
25 changed files
with
510 additions
and
123 deletions.
There are no files selected for viewing
Binary file renamed
BIN
+8.67 MB
...core-npm-6.46.1-984e80de68-063e5f66f0.zip → ...-core-npm-7.6.0-b7da661165-1b2e3f14e4.zip
Binary file not shown.
Binary file removed
BIN
-2.62 MB
.yarn/cache/@babylonjs-gui-editor-npm-6.46.1-db1ad77608-6aa6a3f083.zip
Binary file not shown.
Binary file added
BIN
+2.63 MB
.yarn/cache/@babylonjs-gui-editor-npm-7.6.0-bd6a3a0944-157eb843ee.zip
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file removed
BIN
-3.37 MB
.yarn/cache/@babylonjs-inspector-npm-6.46.1-576958b9a9-615c232c7b.zip
Binary file not shown.
Binary file not shown.
Binary file renamed
BIN
+397 KB
...ders-npm-6.46.1-30fd6a16c9-f85b733a6a.zip → ...aders-npm-7.6.0-9660a50753-23ceaaae6d.zip
Binary file not shown.
Binary file renamed
BIN
+299 KB
...ials-npm-6.46.1-af83dc2628-c231173769.zip → ...rials-npm-7.6.0-d6aac2dee0-6f429068f7.zip
Binary file not shown.
Binary file renamed
BIN
+195 KB
...zers-npm-6.46.1-555534d3ba-644db2aae1.zip → ...izers-npm-7.6.0-5080d464de-4bd7b1a81d.zip
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -39,3 +39,7 @@ button { | |
background: #aaa; | ||
} | ||
} | ||
|
||
#actionTabs img { | ||
height: 0 !important; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Binary file not shown.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
<!DOCTYPE html> | ||
<html lang="en"> | ||
<head> | ||
<meta charset="UTF-8"> | ||
<meta name="viewport" content="width=device-width, initial-scale=1.0"> | ||
<title>PBR</title> | ||
<link rel="icon" type="image/png" sizes="32x32" href="/favicon-32x32.png"> | ||
<link rel="icon" type="image/png" sizes="16x16" href="/favicon-16x16.png"> | ||
<link rel="icon" type="image/x-icon" href="/favicon.ico"> | ||
</head> | ||
<body> | ||
<canvas id="canvas"></canvas> | ||
<div class="input-container"> | ||
<label><input type="range" min="0.01" max="1" step="0.01" value="0" id="metallic"></input>Metallic</label> | ||
<label><input type="range" min="0.01" max="1" step="0.01" value="1" id="roughness">Roughness</input></label> | ||
</div> | ||
<footer> | ||
Tricana Of Coimbra model by | ||
<a href="https://sketchfab.com/3d-models/tricana-of-coimbra-dd63bb4a0bc14b54acbe14d94944a058" | ||
target="_blank" | ||
rel="noopener noreferrer" | ||
>newtonribeiromachado</a>, | ||
<a href="https://creativecommons.org/licenses/by/4.0/" | ||
target="_blank" | ||
rel="noopener noreferrer" | ||
>CC BY 4.0 DEED</a> | ||
</footer> | ||
<script type="module" src="./main.ts"></script> | ||
</body> | ||
</html> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,120 @@ | ||
import './style.scss'; | ||
import { | ||
ArcRotateCamera, | ||
CubeTexture, | ||
Effect, | ||
Engine, | ||
PointLight, | ||
Scene, | ||
ShaderMaterial, | ||
Vector3, | ||
} from '@babylonjs/core'; | ||
import '@babylonjs/loaders/glTF'; | ||
import { importMeshes } from '../../utils/babylon'; | ||
import modelPath from './tricanaOfCoimbra.glb'; | ||
import environmentPath from './environment.env'; | ||
import { resizeCanvasToDisplaySize } from '../../utils/webgl'; | ||
import pbrVertexShader from './shaders/pbr.vertex.glsl?raw'; | ||
import pbrFragmentShader from './shaders/pbr.fragment.glsl?raw'; | ||
|
||
const metallicInput = document.getElementById('metallic') as HTMLInputElement; | ||
const roughnessInput = document.getElementById('roughness') as HTMLInputElement; | ||
|
||
const canvas = document.getElementById('canvas') as HTMLCanvasElement; | ||
const engine = new Engine(canvas, true); | ||
const scene = new Scene(engine); | ||
const envTexture = CubeTexture.CreateFromPrefilteredData( | ||
environmentPath, | ||
scene, | ||
); | ||
|
||
scene.createDefaultSkybox(envTexture); | ||
|
||
Effect.ShadersStore['pbrVertexShader'] = pbrVertexShader; | ||
Effect.ShadersStore['pbrFragmentShader'] = pbrFragmentShader; | ||
|
||
engine.displayLoadingUI(); | ||
|
||
const lights = [ | ||
new PointLight('light', new Vector3(4, 5, -1)), | ||
new PointLight('light', new Vector3(5, 12, -1)), | ||
new PointLight('light', new Vector3(-4, -6, 4)), | ||
new PointLight('light', new Vector3(2, 8, -10)), | ||
]; | ||
|
||
const lightColors = [ | ||
[0.6, 0.1, 0.1], | ||
[0.1, 0.6, 0.9], | ||
[1, 1, 1], | ||
[1, 1, 1], | ||
] | ||
.flat() | ||
.map((n) => n * 0); | ||
|
||
const init = async () => { | ||
const camera = new ArcRotateCamera( | ||
'camera', | ||
Math.PI / 2, | ||
Math.PI / 2, | ||
50, | ||
Vector3.Zero(), | ||
scene, | ||
); | ||
camera.minZ = 0; | ||
camera.maxZ = 1000; | ||
camera.target = Vector3.Zero(); | ||
camera.attachControl(canvas, true); | ||
const [root, ...restMeshes] = await importMeshes(modelPath); | ||
const customMaterial = makeShaderMaterial(); | ||
|
||
customMaterial.setArray3( | ||
'sphericalHarmonics', | ||
[ | ||
envTexture.sphericalPolynomial?.preScaledHarmonics?.l00, | ||
envTexture.sphericalPolynomial?.preScaledHarmonics?.l1_1, | ||
envTexture.sphericalPolynomial?.preScaledHarmonics?.l10, | ||
envTexture.sphericalPolynomial?.preScaledHarmonics?.l11, | ||
envTexture.sphericalPolynomial?.preScaledHarmonics?.l2_2, | ||
envTexture.sphericalPolynomial?.preScaledHarmonics?.l2_1, | ||
envTexture.sphericalPolynomial?.preScaledHarmonics?.l20, | ||
envTexture.sphericalPolynomial?.preScaledHarmonics?.l21, | ||
envTexture.sphericalPolynomial?.preScaledHarmonics?.l22, | ||
].flatMap(({ x, y, z }: any) => [x, y, z]), | ||
); | ||
|
||
restMeshes.forEach((mesh) => { | ||
mesh.material = customMaterial; | ||
mesh.setParent(null); | ||
}); | ||
root.dispose(); | ||
|
||
engine.hideLoadingUI(); | ||
|
||
customMaterial.setTexture('brdfLUT', scene.environmentBRDFTexture); | ||
customMaterial.setTexture('environmentMap', envTexture); | ||
|
||
engine.runRenderLoop(() => { | ||
customMaterial.setArray3( | ||
'lightPositions', | ||
lights | ||
.map((light) => [light.position.x, light.position.y, light.position.z]) | ||
.flat(), | ||
); | ||
customMaterial.setArray3('lightColors', lightColors); | ||
customMaterial.setVector3('cameraPosition', camera.position); | ||
customMaterial.setFloat('metallic', Number(metallicInput.value)); | ||
customMaterial.setFloat('roughness', Number(roughnessInput.value)); | ||
resizeCanvasToDisplaySize(canvas); | ||
scene.render(); | ||
}); | ||
}; | ||
|
||
const makeShaderMaterial = () => { | ||
const material = new ShaderMaterial('customPbrShader', scene, 'pbr', { | ||
attributes: ['position', 'normal', 'color'], | ||
uniforms: ['world', 'view', 'worldView', 'worldViewProjection'], | ||
}); | ||
return material; | ||
}; | ||
|
||
init(); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,142 @@ | ||
#version 300 es | ||
precision highp float; | ||
|
||
uniform vec3 lightPositions[4]; | ||
uniform vec3 lightColors[4]; | ||
uniform mat4 world; | ||
uniform vec3 cameraPosition; | ||
uniform float metallic; | ||
uniform float roughness; | ||
uniform vec3 sphericalHarmonics[9]; | ||
|
||
uniform samplerCube environmentMap; | ||
uniform sampler2D brdfLUT; | ||
|
||
in vec3 vPosition; | ||
in vec3 vNormal; | ||
in vec3 vColor; | ||
|
||
out vec4 fragColor; | ||
|
||
vec3 lightColor = vec3(25.47, 21.31, 20.79) * 4.; | ||
|
||
const float PI = 3.14159265359; | ||
|
||
float DistributionGGX(vec3 N, vec3 H, float roughness) { | ||
float a = roughness*roughness; | ||
float a2 = a*a; | ||
float NdotH = max(dot(N, H), 0.0); | ||
float NdotH2 = NdotH*NdotH; | ||
|
||
float num = a2; | ||
float denom = (NdotH2 * (a2 - 1.0) + 1.0); | ||
denom = PI * denom * denom; | ||
|
||
return num / denom; | ||
return 1.; | ||
} | ||
|
||
float GeometrySchlickGGX(float NdotV, float roughness) { | ||
float r = (roughness + 1.0); | ||
float k = (r*r) / 8.0; | ||
|
||
float num = NdotV; | ||
float denom = NdotV * (1.0 - k) + k; | ||
|
||
return num / denom; | ||
} | ||
|
||
float GeometrySmith(vec3 N, vec3 V, vec3 L, float roughness) { | ||
float NdotV = max(dot(N, V), 0.0); | ||
float NdotL = max(dot(N, L), 0.0); | ||
float ggx2 = GeometrySchlickGGX(NdotV, roughness); | ||
float ggx1 = GeometrySchlickGGX(NdotL, roughness); | ||
|
||
return ggx1 * ggx2; | ||
} | ||
|
||
vec3 fresnelSchlickRoughness(float cosTheta, vec3 F0, float roughness) { | ||
return F0 + (max(vec3(1.0 - roughness), F0) - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0); | ||
} | ||
|
||
vec3 fresnelSchlick(float cosTheta, vec3 F0) { | ||
return F0 + (1.0 - F0) * pow(clamp(1.0 - cosTheta, 0.0, 1.0), 5.0); | ||
} | ||
|
||
vec3 irradianceSH(vec3 n) { | ||
return | ||
sphericalHarmonics[0] | ||
+ sphericalHarmonics[1] * (n.y) | ||
+ sphericalHarmonics[2] * (n.z) | ||
+ sphericalHarmonics[3] * (n.x) | ||
+ sphericalHarmonics[4] * (n.y * n.x) | ||
+ sphericalHarmonics[5] * (n.y * n.z) | ||
+ sphericalHarmonics[6] * (3.0 * n.z * n.z - 1.0) | ||
+ sphericalHarmonics[7] * (n.z * n.x) | ||
+ sphericalHarmonics[8] * (n.x * n.x - n.y * n.y); | ||
} | ||
|
||
void main(void){ | ||
vec3 albedo = pow(vColor, vec3(2.2)); | ||
vec3 N=vNormal; | ||
vec3 V=normalize(cameraPosition - vPosition); | ||
vec3 R = reflect(-V, N); | ||
|
||
vec3 F0=vec3(0.04); | ||
F0=mix(F0, albedo, metallic); | ||
|
||
vec3 Lo = vec3(0.0); | ||
|
||
for (int i = 0; i < 4; ++i) { | ||
vec3 lightPosition = lightPositions[i]; | ||
vec3 L = normalize(lightPosition - vPosition); | ||
vec3 H = normalize(V + L); | ||
float distance = length(lightPosition - vPosition); | ||
float attenuation = 1.0 / (distance * distance); | ||
vec3 radiance = lightColors[i] * attenuation; | ||
|
||
float NDF = DistributionGGX(N, H, roughness); | ||
float G = GeometrySmith(N, V, L, roughness); | ||
vec3 F = fresnelSchlick(max(dot(H, V), 0.0), F0); | ||
|
||
vec3 numerator = NDF * G * F; | ||
float denominator = 4.0 * max(dot(N, V), 0.0) * max(dot(N, L), 0.0) + 0.0001; // + 0.0001 to prevent divide by zero | ||
vec3 specular = numerator / denominator; | ||
|
||
vec3 kS = F; | ||
vec3 kD = vec3(1.0) - kS; | ||
kD *= 1.0 - metallic; | ||
|
||
// scale light by NdotL | ||
float NdotL = max(dot(N, L), 0.0); | ||
|
||
// add to outgoing radiance Lo | ||
Lo += (kD * albedo / PI + specular) * radiance * NdotL; // note that we already multiplied the BRDF by the Fresnel (kS) so we won't multiply by kS again | ||
} | ||
|
||
// ambient lighting (we now use IBL as the ambient term) | ||
vec3 F = fresnelSchlickRoughness(max(dot(N, V), 0.0), F0, roughness); | ||
|
||
vec3 kS = F; | ||
vec3 kD = 1.0 - kS; | ||
kD *= 1.0 - metallic; | ||
|
||
vec3 irradiance = irradianceSH(N); | ||
vec3 diffuse = irradiance * albedo; | ||
|
||
const float MAX_REFLECTION_LOD = 4.0; | ||
vec3 prefilteredColor = textureLod(environmentMap, R, roughness * MAX_REFLECTION_LOD).rgb; | ||
vec2 brdf = texture(brdfLUT, vec2(max(dot(N, V), 0.0), roughness)).rg; | ||
vec3 specular = prefilteredColor * (F * brdf.x + brdf.y); | ||
|
||
vec3 ambient = (kD * diffuse + specular); | ||
|
||
vec3 color = ambient + Lo; | ||
|
||
// HDR tonemapping | ||
color = color / (color + vec3(1.0)); | ||
// gamma correct | ||
color = pow(color, vec3(1.0/2.2)); | ||
|
||
fragColor = vec4(color , 1.0); | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
#version 300 es | ||
precision highp float; | ||
|
||
in vec3 position; | ||
in vec3 normal; | ||
in vec3 color; | ||
|
||
uniform mat4 world; | ||
uniform mat4 worldViewProjection; | ||
|
||
out vec3 vPosition; | ||
out vec3 vNormal; | ||
out vec3 vColor; | ||
|
||
void main(){ | ||
vec4 p=vec4(position,1.); | ||
gl_Position=worldViewProjection*p; | ||
vNormal=mat3(world)*normal; | ||
vPosition=vec3(world*p); | ||
vColor=color; | ||
} |
Oops, something went wrong.