正常总是指向同一个方向

问题描述 投票:0回答:1

我有一个顶部开口的圆柱体,其材料在 Three.JS 场景中是双面的。

我想要实现的是圆柱体正面有一种颜色,圆柱体内部有另一种颜色。

为了实现此功能,我创建了一个扩展

THREE.MeshStandardMaterial
的新材质类,并且我正在修改
onBeforeCompile
钩子中的顶点和片段着色器。

在片段着色器中的

main
方法的末尾,我有这个:

gl_FragColor = vec4(faceNormal.rgb, sampledDiffuseColor.w);

if(gl_FrontFacing == false) {            
    gl_FragColor = vec4(0.0,0.0,0.0, sampledDiffuseColor.w);

}

但无论出于何种原因,我无法真正弄清楚,

gl_FrontFacing
始终设置为true。 据我所知,这不是我正在设置或修改的内容,而是 webGL 为我设置的内容。但对于所有内面来说不应该都是假的吗?

或者我在这里做错了什么?

为了自己简化,我更新了

onBeforeCompile
钩子

onBeforeCompile(shader: any) {
    shader.vertexShader = /* glsl */ `
    void main() {
        gl_Position = projectionMatrix * modelViewMatrix * vec4(position, 1.0);
    }
    `;
    shader.fragmentShader = /* glsl */`
    void main() {
        gl_FragColor = gl_FrontFacing ? vec4(1.0, 0.0, 0.0, 1.0) : vec4(0.0, 0.0, 1.0, 1.0);
    }
    `;
}

它的内部和外部都显示为红色

好吧,我知道是什么原因导致它总是一样的。 我正在使用

transparent: true
创建材质。如果我切换它,它就会正确地找出里面的东西和不里面的东西。

问题是我也确实需要透明功能

这是一个完整的示例,具有透明真实且非工作内部颜色


<!DOCTYPE html>
<head>
  <title> SimpleDoubleSide(gl_FrontFacing) </title>
  <meta charset="utf-8" /> 
</head>
<body> </body>
<script src="https://cdnjs.cloudflare.com/ajax/libs/three.js/0.160.0/three.js"></script>
<script>

const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera( 60, 1, 0.01, 1000 );
camera.position.set( 1, 2, 3 );
camera.lookAt(0,0,0);

const renderer = new THREE.WebGLRenderer({  antialias: true });
const container = document.createElement( 'div' );
document.body.appendChild( container );
container.appendChild( renderer.domElement ); 

renderer.setSize( window.innerWidth, window.innerHeight );
renderer.setClearColor( 0xdedede, 1 );
const shMaterial = new THREE.MeshBasicMaterial( { side: THREE.DoubleSide, transparent: true } );

shMaterial.onBeforeCompile = shader => { 
    shader.vertexShader =
        `
    attribute vec2 backUV;
    varying vec2 vBackUV;
    ` + shader.vertexShader;
    shader.vertexShader = shader.vertexShader.replace(
        `#include <fog_vertex>`,
        `#include <fog_vertex>
    vBackUV = backUV;
    `
    );
    shader.fragmentShader =
        `
    uniform sampler2D backTexture;
    varying vec2 vBackUV;
    ` + shader.fragmentShader;
    shader.fragmentShader = shader.fragmentShader.replace(
        `#include <map_fragment>`,
        `#include <map_fragment>
    
    diffuseColor = gl_FrontFacing ? vec4(0.0,0.0,0.0,1.0) : vec4(1.0,1.0,1.0,1.0); //texture2D( map, vUv ) : texture2D( backTexture, vBackUV );
    `
    );
};

const cylGeom = new THREE.CylinderGeometry( 0.5, 0.4, 1, 36, 8, true );
const cylinder  = new THREE.Mesh( cylGeom, shMaterial );
scene.add( cylinder );

render();

function render( ) {

    renderer.render( scene, camera );
    requestAnimationFrame( render );
}

</script>
</html>
javascript three.js glsl
1个回答
0
投票

在这个github问题中找到了解决方案大纲

https://github.com/mrdoob/ Three.js/issues/25149

© www.soinside.com 2019 - 2024. All rights reserved.