- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我正在尝试为 Threejs 开发自己的自定义 glsl 着色器,但我叠加了 HDR 图像的光泽反射。它适用于 LDR 图像,但不适用于 HDR。
我首先使用 this example为了生成 mipmap。
然后,我使用浏览器扩展从默认的 MeshStandardMaterial 获取编译后的代码,并隔离了与环境贴图相关的所需位,并编写了我的着色器(我在着色器中添加了辐射度和辐照度函数) ),但我可能遗漏了一些东西,因为这似乎对我不起作用。
在下图中,您可以看到在具有普通 HDRI(没有 mipmap)的版本 1) 中,我必须将 DataType 更改为“THREE.FloatType”。尽管这看起来仍然是错误的(没有光泽并且非常暗),但这是我设法得到的最接近的结果。版本 2) 使用默认的“THREE.UnsignedDataType”,但图像看起来完全错误。版本 3) 这是包含 mipmap 的版本,只是错误。
这是一个link下载所有文件或仅查看下面的代码。
<html>
<head>
<script src="./js/three.min.js"></script>
<script src="./js/RGBELoader.js"></script>
<script src="./js/HDRCubeTextureLoader.js"></script>
<script src="./js/PMREMCubeUVPacker.js"></script>
<script src="./js/PMREMGenerator.js"></script>
<style>
html, body{ margin:0px; padding: 0px;}
</style>
</head>
<body>
<!-- Vertex and Fragment shaders-->
<script id="VS" type="x-shader/x-vertex">
varying vec3 vNormal;
varying vec3 vViewPosition;
void main() {
vNormal = normal;
vViewPosition = - (modelViewMatrix * vec4( position, 1.0 )).xyz;
gl_Position = projectionMatrix * modelViewMatrix * vec4(position,1.0);
}
</script>
<script id="FS" type="x-shader/x-fragment">
varying vec3 vViewPosition;
varying vec3 vNormal;
uniform int maxMipLevel;
uniform samplerCube envMap;
uniform float envMapIntensity;
uniform float flipEnvMap;
uniform float roughness;
float pow2( const in float x ) {
return x*x;
}
float GGXRoughnessToBlinnExponent( const in float ggxRoughness ) {
return ( 2.0 / pow2( ggxRoughness + 0.0001 ) - 2.0 );
}
float getSpecularMIPLevel( const in float blinnShininessExponent, const in int maxMIPLevel ) {
float maxMIPLevelScalar = float( maxMIPLevel );
float desiredMIPLevel = maxMIPLevelScalar + 0.79248 - 0.5 * log2( pow2( blinnShininessExponent ) + 1.0 );
return clamp( desiredMIPLevel, 0.0, maxMIPLevelScalar );
}
vec3 inverseTransformDirection( in vec3 dir, in mat4 matrix ) {
return normalize( ( vec4( dir, 0.0 ) * matrix ).xyz );
}
vec3 getLightProbeIndirectRadiance( const in vec3 viewDir, const in vec3 normal, const in float blinnShininessExponent, const in int maxMIPLevel ) {
vec3 reflectVec = reflect( -viewDir, normal );
reflectVec = inverseTransformDirection( reflectVec, viewMatrix );
float specularMIPLevel = getSpecularMIPLevel( blinnShininessExponent, maxMIPLevel );
vec3 queryReflectVec = vec3( flipEnvMap * reflectVec.x, reflectVec.yz );
vec4 envMapColor = textureCube( envMap, queryReflectVec, specularMIPLevel );
envMapColor.rgb = envMapTexelToLinear( envMapColor ).rgb;
return envMapColor.rgb * envMapIntensity * .75;
}
vec3 getLightProbeIndirectIrradiance( const in vec3 normal, const in int maxMIPLevel ) {
vec3 worldNormal = inverseTransformDirection( normal, viewMatrix );
vec3 queryVec = vec3( flipEnvMap * worldNormal.x, worldNormal.yz );
vec4 envMapColor = textureCube( envMap, queryVec, float( maxMIPLevel ) );
return PI * envMapColor.rgb * envMapIntensity;
}
void main() {
vec3 irradiance = getLightProbeIndirectIrradiance(normalize(vNormal), maxMipLevel );
vec3 radiance = getLightProbeIndirectRadiance( normalize( vViewPosition ), normalize(vNormal), GGXRoughnessToBlinnExponent( roughness ), maxMipLevel );
gl_FragColor = vec4( radiance, 1.0 );
}
</script>
<!-- THREE JS code-->
<script>
var CubeTextureLoader = new THREE.CubeTextureLoader();
var HDRCubeTextureLoader = new THREE.HDRCubeTextureLoader();
// renderer
var renderer = new THREE.WebGLRenderer({antialias:true});
renderer.setClearColor( 0xaaaaaa );
renderer.setSize( window.innerWidth, window.innerHeight );
document.body.appendChild( renderer.domElement );
// scene
scene = new THREE.Scene();
// camera
camera = new THREE.PerspectiveCamera( 40, window.innerWidth / window.innerHeight, 1, 1000 );
camera.position.set(0, 0, 40);
// load HDRIs and Generate mipmaps
// Code from: https://threejs.org/examples/#webgl_materials_envmaps_hdr
var hdrCubeRenderTarget;
var hdrUrls = [ 'px.hdr', 'nx.hdr', 'py.hdr', 'ny.hdr', 'pz.hdr', 'nz.hdr' ];
var hdrCubeMap = new THREE.HDRCubeTextureLoader()
.setPath( './pisaHDR/' )
.setDataType( THREE.UnsignedByteType )
// .setDataType( THREE.FloatType )
.load( hdrUrls, function () {
var pmremGenerator = new THREE.PMREMGenerator( hdrCubeMap );
pmremGenerator.update( renderer );
var pmremCubeUVPacker = new THREE.PMREMCubeUVPacker( pmremGenerator.cubeLods );
pmremCubeUVPacker.update( renderer );
hdrCubeRenderTarget = pmremCubeUVPacker.CubeUVRenderTarget;
hdrCubeMap.magFilter = THREE.LinearFilter;
hdrCubeMap.needsUpdate = true;
pmremGenerator.dispose();
pmremCubeUVPacker.dispose();
} );
// materials
var stdMtl = new THREE.MeshStandardMaterial( { color: 0xffffff, roughness: 0.5, metalness: 1.0 } );
var cusMtl = new THREE.ShaderMaterial( {
defines: {
PI: 3.14159265359
},
uniforms: {
roughness: 0.5,
envMapIntensity: { value:1.0 },
flipEnvMap: { value: -1.0 },
envMap: { value:null }
},
vertexShader: document.getElementById('VS').text,
fragmentShader: document.getElementById('FS').text
} );
// geometries
var sphereGeometry = new THREE.SphereGeometry( 5, 32, 32 );
var stdSphereMesh = new THREE.Mesh( sphereGeometry, stdMtl );
var cusSphereMesh = new THREE.Mesh( sphereGeometry, cusMtl );
stdSphereMesh.position.set(-7.5, 0, 0);
cusSphereMesh.position.set(7.5, 0, 0);
scene.add( stdSphereMesh );
scene.add( cusSphereMesh );
// render scene
function render() {
var newEnvMap = hdrCubeRenderTarget ? hdrCubeRenderTarget.texture : null;
if ( newEnvMap && newEnvMap !== stdSphereMesh.material.envMap ) {
stdSphereMesh.material.envMap = newEnvMap;
stdSphereMesh.material.needsUpdate = true;
cusSphereMesh.material.uniforms.envMap.value = newEnvMap; // This isErroring
// cusSphereMesh.material.uniforms.envMap.value = hdrCubeMap; // Result show HDRI but with wrong gamma and no mipmaps
cusSphereMesh.material.needsUpdate = true;
}
requestAnimationFrame( render );
renderer.render( scene, camera );
}
render();
</script>
</body>
</html>
最佳答案
您必须在片段着色器中将 envMapTexelToLinear()
函数更改为 RGBEToLinear()
。
这是WebGL程序通常的东西 does automatically编译着色器时,它发现envMap.encoding = THREE.RGBEEncoding
。但是,由于您使用的是自定义着色器,而不是默认 Material ,因此您必须手动编写此步骤。
这是一个使用 HDRI 图像的简单示例。在右侧,我正在读取线性空间中的纹素,它会产生时髦的过饱和颜色。在左侧,我将纹理像素从 RGBE 转换为线性,并且它很好地映射到其预期输出:
关于three.js - Threejs 的 ShaderMaterial 反射和光泽度问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58121809/
我们想要创建一个 3D 鞋子设计工具,您可以在其中设计图案并将其上传到鞋子上。 我正在尝试将图像放置在 Threejs Material 上。我可以更新 map ,但纹理很模糊。我是 Threejs
一.three框架材质原理与应用 其实three里面所有的材质不管是基础还是点等等之类最终都会编译为shader然后执行,所以如果拿到一个材质我想对某个地方小改一下,那么也是可以用shader来进行
一.初识points与点材质 什么叫做点材质,之前说过所有物体都是有定点的比如一个球体,并且将材质设置为线框模式,这个之前就说过所有mesh物体都是由三角形构成,都是有顶点的 我们也可以创
一.动画原理和应用 three的动画大概就是通过不同时间的关键帧来实现 加载一个手机模型 在这个对象里面,注意后期都是直接通过可视化软件Blender编辑好关键帧就能实现动画,这也是个已经编
一.gsap动画库 1.1 基本使用和原理 首先直接npm安装然后导入 比如让一个物体,x轴时间为5s 旋转同理 动画的速度曲线,可以在官网的文档找到 1.2 控制动画属性与方
一.matcap材质 这个材质不会受到光照影响,但是如果图片本身有光就可以一直渲染这个图片本来的样子,用来将一个图片纹理渲染到物体上的材质 代码实现 加载模型后,开启纹理渲染,并把它
一.uv贴图 在3D计算机图形学中,UV映射是一种将2D纹理映射到3D模型表面的方法。在这里,“U”和“V”代表了2D纹理空间的坐标,这与2D笛卡尔坐标系统中的“X”和“Y”是类似的。在3D模型的每
我正在尝试在 ThreeJS 中加载 FBX 模型。如果我加载模型,它只会从底部显示,而不是从顶部显示。似乎只渲染了一侧。 有没有人想解决这个问题? 我的加载函数: _LoadAnimatedMode
使用 Three.js,(虽然我相信这与数学更相关)我有一组可以创建二维几何体的二维点。例如正方形、矩形、五边形或自定义 2D 形状。基于原始的 2D 形状,我想创建一种方法来像附图那样均匀地向内或向
我正在尝试创建一个在所有方面都镜像的对象。它几乎可以正常工作,但我不确定我在这里做错了什么。我只能看到某些 Angular 部分反射,并且反射的范围比被反射的物体(大象)大得多。这是代码:
无论导入场景,还是通过代码创建每个网格和灯光,都会出现以下问题。 我的场景由一个平面、一个立方体和一个聚光灯组成。聚光灯在 y 轴上旋转 45 度。在示例 1 中,它位于点 (4, 0, 4)。在示例
上下文: 我正在开发一个非常简单的 THREE.JS 项目,我相信它已经以非常好的方式进行了优化。我正在使用 WebGLRenderer 来显示每 50 毫秒从音频信号中提取的大量波特图。这非常酷,但
我正在编写一个全景查看器。图像显示在具有可变数量面的球体中。我希望它只在相机方向渲染脸部(以获得更好的性能)。 ThreeJS 会自动执行此操作吗?或者我可以声明不渲染的混搭的特定面吗? 像mash.
我使用十六进制值设置几何颜色 RichGeometry.prototype = new THREE.Geometry(); RichGeometry.prototype.constructor = R
因此,我查看了此处的所有其他影子问题,但似乎没有一个与我的相关,或者我只是忽略了它大约 10 次。 https://gist.github.com/Sinistralis/58249d2f9aefa8
所以我有一个 ThreeJS 场景,并且添加了一些球体(多 Material )。我还添加了定向光: this.light = new THREE.DirectionalLight( 0xFFFFFF
我在“two.js”中创建了一个立方体,但我想创建同一个立方体 3 次,然后将它们作为目标,以便可以使用“Tweenmax”单独对它们进行动画处理 我是 Three.js 的新手,因此我们将不胜感激
我想要实现的是让特定的网格体向特定的向量移动,直到它最终被玩家停止。 到目前为止,我已经成功获取了单击 Canvas 的 XY 坐标,并使用以下代码将它们投影到 3D 中。不幸的是,我不确定采取什么方
我遇到了 Object3D 组中的面上未接收到阴影的问题。 阴影从物体转换并被地面接收,但阴影在应该被接收的时候却没有被彼此接收。 我四处搜寻,但似乎找不到类似的问题,这让我相信我的设置不正确。 有人
我正在尝试为我的类(class)创建一个场景,其中必须克隆一组对象(模型)并将其显示在随机位置。我为此创建了一个函数,但不幸的是,它只能将同一个对象从一个地方传输到另一个地方。我需要添加更多对象而不是
我是一名优秀的程序员,十分优秀!