1 Star 0 Fork 9

书生/3D教程

forked from liujiboy/3D教程 
加入 Gitee
与超过 1200万 开发者一起发现、参与优秀开源项目,私有仓库也完全免费 :)
免费加入
文件
该仓库未声明开源许可证文件(LICENSE),使用请关注具体项目描述及其代码上游依赖。
克隆/下载
08.Materials(Cook-Torrance Shader eye).html 6.59 KB
一键复制 编辑 原始数据 按行查看 历史
liujiboy 提交于 2021-07-01 19:17 . 08-09完成
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title>08.Materials(MeshLambertMaterial)</title>
<style>
body {
margin: 0;
}
</style>
</head>
<body>
<script id="vertexShader" type="x-shader/x-vertex">
attribute vec3 normal;
attribute vec3 position;
attribute vec4 color;
uniform vec3 camera;
uniform vec3 light;
uniform mat3 normalMatrix;
uniform mat4 viewMatrix;
uniform mat4 modelMatrix;
uniform mat4 modelViewMatrix; // optional
uniform mat4 projectionMatrix; // optional
varying vec3 varNormal;
varying vec3 varEyeDir;
varying vec3 lightDirection;
void main()
{
// vertex position (in eye space)
vec4 eyePosition=modelViewMatrix * vec4( position, 1.0 );
vec4 eyeCamera=viewMatrix*vec4(camera,1.0);
vec4 eyeLight=viewMatrix*vec4(light,1.0);
// vertex normal
varNormal = normalMatrix*normal;
varEyeDir = normalize(eyeCamera.xyz-eyePosition.xyz);
lightDirection=normalize(eyeLight.xyz-eyePosition.xyz);
gl_Position = projectionMatrix * eyePosition;
}
</script>
<script id="fragmentShader" type="x-shader/x-fragment">
precision highp float;
varying vec3 lightDirection;
varying vec3 varNormal;
varying vec3 varEyeDir;
uniform vec3 lightColor;
void main()
{
// set important material values
float roughnessValue = 0.3; // 0 : smooth, 1: rough
float F0 = 0.8; // fresnel reflectance at normal incidence
float k = 0.2; // fraction of diffuse reflection (specular reflection = 1 - k)
// interpolating normals will change the length of the normal, so renormalize the normal.
vec3 normal = normalize(varNormal);
// do the lighting calculation for each fragment.
float NdotL = max(dot(normal, lightDirection), 0.0);
float specular = 0.0;
if(NdotL > 0.0)
{
vec3 eyeDir = normalize(varEyeDir);
// calculate intermediary values
vec3 halfVector = normalize(lightDirection + eyeDir);
float NdotH = max(dot(normal, halfVector), 0.0);
float NdotV = max(dot(normal, eyeDir), 0.0); // note: this could also be NdotL, which is the same value
float VdotH = max(dot(eyeDir, halfVector), 0.0);
float mSquared = roughnessValue * roughnessValue;
// geometric attenuation
float NH2 = 2.0 * NdotH;
float g1 = (NH2 * NdotV) / VdotH;
float g2 = (NH2 * NdotL) / VdotH;
float geoAtt = min(1.0, min(g1, g2));
// roughness (or: microfacet distribution function)
// beckmann distribution function
float r1 = 1.0 / ( 4.0 * mSquared * pow(NdotH, 4.0));
float r2 = (NdotH * NdotH - 1.0) / (mSquared * NdotH * NdotH);
float roughness = r1 * exp(r2);
// fresnel
// Schlick approximation
float fresnel = pow(1.0 - VdotH, 5.0);
fresnel *= (1.0 - F0);
fresnel += F0;
specular = (fresnel * geoAtt * roughness) / (NdotV * NdotL * 3.14);
}
vec3 finalValue = lightColor * NdotL * (k + specular * (1.0 - k));
gl_FragColor = vec4(finalValue, 1.0);
}
</script>
<script type="module">
import * as THREE from '/build/three.module.js';
import { PointerLockControls } from '/jsm/controls/PointerLockControls.js';
//生成场景
const scene = new THREE.Scene();
//设置光照
const light = new THREE.AmbientLight(0xffffff);
scene.add(light);
const pointLight = new THREE.PointLight(0xFFFFFF, 1, 100);
pointLight.position.set(0, 0, 10);
scene.add(pointLight);
//设置相机
const camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 0.1, 1000);
camera.position.z = 5;
//设置渲染器
const renderer = new THREE.WebGLRenderer({ antialias: true });
//renderer.setClearColor(0xFFFFFF);
renderer.setSize(window.innerWidth, window.innerHeight);
document.body.appendChild(renderer.domElement);
//生成模型
const geometry = new THREE.BoxGeometry();
const group = new THREE.Group()
const material = new THREE.RawShaderMaterial({
uniforms: {
camera: { value: camera.position },
light: { value: pointLight.position },
lightColor:{value:new THREE.Vector3(0.9, 0.1, 0.1) }
},
vertexShader: document.getElementById('vertexShader').textContent,
fragmentShader: document.getElementById('fragmentShader').textContent,
});
const cube = new THREE.Mesh(geometry, material);
const wireframeMaterial = new THREE.MeshLambertMaterial({ color: 0xff0000, wireframe: true });
const cubeWireframe = new THREE.Mesh(geometry, wireframeMaterial);
//设置场景
group.add(cube)
group.add(cubeWireframe)
scene.add(group);
scene.add(camera)
const controls = new PointerLockControls(camera, document.body);
//点击屏幕触发lock
document.onclick = function (event) {
controls.lock();
}
//用键盘控制移动
document.onkeydown = function (event) {
switch (event.key) { // 获取当前按下键盘键的编码
//wsad移动
case 'w':
controls.moveForward(0.5);
break;
case 's':
controls.moveForward(-0.5);
break;
case 'a':
controls.moveRight(- 0.5);
break;
case 'd':
controls.moveRight(0.5);
break;
}
}
function animate() {
group.rotation.x+=0.01;
renderer.render(scene, camera);
requestAnimationFrame(animate);
material.uniforms.camera.value = camera.position
}
//开始动画
animate()
</script>
</body>
</html>
马建仓 AI 助手
尝试更多
代码解读
代码找茬
代码优化
1
https://gitee.com/zhangshusheng/threed-tutorial.git
git@gitee.com:zhangshusheng/threed-tutorial.git
zhangshusheng
threed-tutorial
3D教程
master

搜索帮助