claygl/example/ssr2.html

229 lines
9.9 KiB
HTML

<html>
<head>
<meta charset="utf-8">
<script type="text/javascript" src="lib/require.js"></script>
<script type="text/javascript" src="lib/stats.js"></script>
<script type="text/javascript" src="lib/dat.gui.js"></script>
</head>
<body style="margin:0px;">
<style>
#main {
background: #000;
}
</style>
<canvas id="main"></canvas>
<script type="text/javascript">
require(['../dist/claygl', 'js/SSRPass', 'js/createCompositor'], function(clay, SSRPass, createCompositor) {
var config = {
maxIteration: 16,
maxBinarySearchIteration: 5,
maxRayDistance: 4,
pixelStride: 16,
pixelStrideZCutoff: 50,
screenEdgeFadeStart: 0.9,
eyeFadeStart: 0.4,
eyeFadeEnd: 0.8,
roughness: 0.5
};
var renderer = new clay.Renderer({
canvas: document.getElementById('main'),
devicePixelRatio: 1.0
});
var camera = new clay.camera.Perspective({
aspect: renderer.getViewportAspect()
});
camera.position.set(0, 4, 4);
camera.lookAt(clay.Vector3.ZERO);
var gBuffer = new clay.deferred.GBuffer();
var ssrPass = new SSRPass({
gBuffer: gBuffer,
renderToTexture: true,
RGBM: true
});
var scene = new clay.Scene();
var planeGeo = new clay.geometry.Plane();
var plane = new clay.Mesh({
geometry: planeGeo,
material: new clay.Material({
shader: clay.shader.library.get('clay.standard', {
textures: ['diffuseMap', 'normalMap'],
fragmentDefines: {
RGBM_ENCODE: null,
SRGB_DECODE: null,
USE_ROUGHNESS: null
}
})
})
});
plane.scale.set(10, 10, 1);
plane.rotation.rotateX(-Math.PI / 2);
// plane.material.set('color', [0.2, 0.2, 0.2]);
var diffuseTex = new clay.Texture2D({
wrapS: clay.Texture.REPEAT,
wrapT: clay.Texture.REPEAT
});
var normalTex = new clay.Texture2D({
wrapS: clay.Texture.REPEAT,
wrapT: clay.Texture.REPEAT
});
diffuseTex.load('assets/textures/oakfloor2/oakfloor2_basecolor.png');
normalTex.load('assets/textures/oakfloor2/oakfloor2_normal.png');
plane.geometry.generateTangents();
plane.material.set('diffuseMap', diffuseTex);
plane.material.set('normalMap', normalTex);
plane.material.set('uvRepeat', [5, 5]);
scene.add(plane);
var mainLight = new clay.light.Directional({
intensity: 1
});
mainLight.position.set(10, 10, 10);
mainLight.lookAt(scene.position);
scene.add(mainLight);
var loader = new clay.loader.GLTF();
loader.load('assets/models/suzanne/suzanne_high.gltf');
var suzanneGeometry;
loader.on('success', function(res) {
suzanneGeometry = res.scene.getNode('Suzanne').geometry;
var envMap = clay.util.texture.loadTexture(
'assets/textures/hdr/pisa.hdr',
{
exposure: 3
},
function () {
envMap.flipY = false;
var prefilterResult = clay.util.cubemap.prefilterEnvironmentMap(
renderer, envMap, {
width: 128,
height: 128
}
);
var skybox = new clay.plugin.Skybox({
scene: scene
});
skybox.material.set('environmentMap', prefilterResult.environmentMap);
skybox.material.define('fragment', 'RGBM_ENCODE');
var shader = clay.shader.library.get(
'clay.standard', {
textures: [
'environmentMap', 'brdfLookup',
'diffuseMap', 'normalMap', 'metalnessMap', 'roughnessMap'
],
fragmentDefines: {
ENVIRONMENTMAP_PREFILTER: null,
RGBM_ENCODE: null,
USE_METALNESS: null,
USE_ROUGHNESS: null,
SRGB_DECODE: null
}
}
);
var material = new clay.Material({
shader: shader
});
var mesh = new clay.Mesh({
geometry: suzanneGeometry,
material: material
});
mesh.geometry.generateTangents();
material.set('maxMipmapLevel', prefilterResult.maxMipmapLevel);
material.set('brdfLookup', prefilterResult.brdfLookup);
material.set('environmentMap', prefilterResult.environmentMap);
material.set('roughness', 0.4);
material.set('metalness', 0.5);
material.set('uvRepeat', [2, 2]);
[ ['diffuseMap', 'basecolor'], ['normalMap', 'normal'], ['metalnessMap', 'metalness'], ['roughnessMap', 'roughness'] ].forEach(function (mapInfo) {
var tex = new clay.Texture2D({
wrapS: clay.Texture.REPEAT,
wratT: clay.Texture.REPEAT
});
tex.load('assets/textures/iron-rusted4/iron-rusted4-' + mapInfo[1] + '.png')
.success(function () {
tex.wrapS = clay.Texture.REPEAT;
tex.wrapT = clay.Texture.REPEAT;
});
material.set(mapInfo[0], tex);
});
mesh.scale.set(1, 1, 1);
mesh.position.y = 1;
scene.add(mesh);
});
});
var control = new clay.plugin.OrbitControl({
target: camera,
domElement: renderer.canvas
});
var frameBuffer = new clay.FrameBuffer();
var colorTex = new clay.Texture2D();
var timeline = new clay.Timeline();
timeline.start();
var compositor = createCompositor({
texture: ssrPass.getTargetTexture()
});
timeline.on('frame', function(deltaTime) {
control.update(deltaTime);
frameBuffer.attach(colorTex);
frameBuffer.bind(renderer);
renderer.render(scene, camera);
frameBuffer.unbind(renderer);
gBuffer.update(renderer, scene, camera);
ssrPass.render(renderer, camera, colorTex);
compositor.render(renderer);
});
window.onresize = function() {
var width = window.innerWidth;
var height = window.innerHeight;
renderer.resize(width, height);
gBuffer.resize(width, height);
colorTex.width = width;
colorTex.height = height;
colorTex.dirty();
camera.aspect = renderer.getViewportAspect();
};
window.onresize();
function updateConfig() {
for (var name in config) {
ssrPass.setParameter(name, config[name]);
}
}
updateConfig();
var gui = new dat.GUI();
gui.add(config, 'maxIteration', 0, 200).step(1).onChange(updateConfig);
gui.add(config, 'maxBinarySearchIteration', 0, 20).step(1).onChange(updateConfig);
gui.add(config, 'maxRayDistance', 0, 10).onChange(updateConfig);
gui.add(config, 'pixelStride', 0, 32).onChange(updateConfig);
gui.add(config, 'pixelStrideZCutoff', 0, 50).onChange(updateConfig);
gui.add(config, 'screenEdgeFadeStart', 0, 1).onChange(updateConfig);
gui.add(config, 'eyeFadeStart', 0, 1).onChange(updateConfig);
gui.add(config, 'eyeFadeEnd', 0, 1).onChange(updateConfig);
gui.add(config, 'roughness', 0, 1).onChange(function (val) {
plane.material.set('roughness', val);
});
});
</script>
</html>