gpt4 book ai didi

javascript - 使用 ShaderMaterial 复制 MeshLambertMaterial 忽略纹理

转载 作者:数据小太阳 更新时间:2023-10-29 04:11:39 26 4
gpt4 key购买 nike

我注意到 THREE.js 在内部使用着色器来创建核心 Material “例如 MeshLambertMaterial”,因此我决定将 Lambert 着色器从 Three.js 代码复制到一个新的着色器中并在其上构建。

这是我得到的代码(忠实地从 Three.js r66 复制而来)

THREE.MyShader = {

uniforms: THREE.UniformsUtils.merge( [
THREE.UniformsLib[ "common" ],
THREE.UniformsLib[ "fog" ],
THREE.UniformsLib[ "lights" ],
THREE.UniformsLib[ "shadowmap" ],
{
"ambient" : { type: "c", value: new THREE.Color( 0xffffff ) },
"emissive" : { type: "c", value: new THREE.Color( 0x000000 ) },
"wrapRGB" : { type: "v3", value: new THREE.Vector3( 1, 1, 1 ) }
}
]),

vertexShader: [

"#define LAMBERT",

"varying vec3 vLightFront;",

"#ifdef DOUBLE_SIDED",

"varying vec3 vLightBack;",

"#endif",

THREE.ShaderChunk[ "map_pars_vertex" ],
THREE.ShaderChunk[ "lightmap_pars_vertex" ],
THREE.ShaderChunk[ "envmap_pars_vertex" ],
THREE.ShaderChunk[ "lights_lambert_pars_vertex" ],
THREE.ShaderChunk[ "color_pars_vertex" ],
THREE.ShaderChunk[ "morphtarget_pars_vertex" ],
THREE.ShaderChunk[ "skinning_pars_vertex" ],
THREE.ShaderChunk[ "shadowmap_pars_vertex" ],

"void main() {",

THREE.ShaderChunk[ "map_vertex" ],
THREE.ShaderChunk[ "lightmap_vertex" ],
THREE.ShaderChunk[ "color_vertex" ],

THREE.ShaderChunk[ "morphnormal_vertex" ],
THREE.ShaderChunk[ "skinbase_vertex" ],
THREE.ShaderChunk[ "skinnormal_vertex" ],
THREE.ShaderChunk[ "defaultnormal_vertex" ],

THREE.ShaderChunk[ "morphtarget_vertex" ],
THREE.ShaderChunk[ "skinning_vertex" ],
THREE.ShaderChunk[ "default_vertex" ],

THREE.ShaderChunk[ "worldpos_vertex" ],
THREE.ShaderChunk[ "envmap_vertex" ],
THREE.ShaderChunk[ "lights_lambert_vertex" ],
THREE.ShaderChunk[ "shadowmap_vertex" ],

"}"

].join("\n"),

fragmentShader: [

"uniform float opacity;",

"varying vec3 vLightFront;",

"#ifdef DOUBLE_SIDED",

"varying vec3 vLightBack;",

"#endif",

THREE.ShaderChunk[ "color_pars_fragment" ],
THREE.ShaderChunk[ "map_pars_fragment" ],
THREE.ShaderChunk[ "lightmap_pars_fragment" ],
THREE.ShaderChunk[ "envmap_pars_fragment" ],
THREE.ShaderChunk[ "fog_pars_fragment" ],
THREE.ShaderChunk[ "shadowmap_pars_fragment" ],
THREE.ShaderChunk[ "specularmap_pars_fragment" ],



"void main() {",

"gl_FragColor = vec4( vec3 ( 1.0 ), opacity );",

THREE.ShaderChunk[ "map_fragment" ],
THREE.ShaderChunk[ "alphatest_fragment" ],
THREE.ShaderChunk[ "specularmap_fragment" ],

"#ifdef DOUBLE_SIDED",

//"float isFront = float( gl_FrontFacing );",
//"gl_FragColor.xyz *= isFront * vLightFront + ( 1.0 - isFront ) * vLightBack;",

"if ( gl_FrontFacing )",
"gl_FragColor.xyz *= vLightFront;",
"else",
"gl_FragColor.xyz *= vLightBack;",

"#else",

"gl_FragColor.xyz *= vLightFront;",

"#endif",

THREE.ShaderChunk[ "lightmap_fragment" ],
THREE.ShaderChunk[ "color_fragment" ],
THREE.ShaderChunk[ "envmap_fragment" ],
THREE.ShaderChunk[ "shadowmap_fragment" ],

THREE.ShaderChunk[ "linear_to_gamma_fragment" ],

THREE.ShaderChunk[ "fog_fragment" ],

"}"

].join("\n")

}

这是我用来设置制服和创建 Material 的代码。

var textureUsed = 'rock_1';
var texture = THREE.ImageUtils.loadTexture( texturePath + textureUsed + "/diffuse.png");
texture.wrapS = THREE.RepeatWrapping;
texture.wrapT = THREE.RepeatWrapping;
texture.repeat.x = 128;
texture.repeat.y = 128;
var shaderUniforms = THREE.UniformsUtils.clone( THREE.MyShader.uniforms );
shaderUniforms[ "map" ].value = texture;
var material = new THREE.ShaderMaterial({
name: "TerrainShader",
uniforms : shaderUniforms,
vertexShader: THREE.MyShader.vertexShader,
fragmentShader: THREE.MyShader.fragmentShader,
fog:false,
lights:true
});

问题是,当我使用这些参数创建 MeshLambertMaterial 时,我得到了正确的照明和纹理重复,当我使用它创建 ShaderMaterial 时,灯光和阴影似乎有效但未加载纹理贴图,以解决这个问题我仔细研究了代码,并通过在 Material 定义之后立即向我的代码中添加这个丑陋的“hack”来设法加载 map

material.map = true;

现在纹理已加载并显示,但纹理坐标看起来乱七八糟,着色器似乎忽略了我提供的重复值,而不是重复。

为什么我需要那个 hack 来处理我的纹理,我该怎么做才能获得正确的纹理重复?

最佳答案

three.js 旨在易于使用,不易修改。这在未来可能会改变......

您需要像这样设置material.defines:

var defines = {};

defines[ "USE_MAP" ] = "";.

然后在 Material 构造函数中指定defines

var material =  new THREE.ShaderMaterial({
name: "TerrainShader",
defines : defines,
uniforms : shaderUniforms,
vertexShader: THREE.MyShader.vertexShader,
fragmentShader: THREE.MyShader.fragmentShader,
fog:false,
lights:true
});

关于纹理重复,您需要将重复添加到您的制服中:

shaderUniforms[ "offsetRepeat" ].value.set( 0, 0, 2, 2 );

three.js r.66

关于javascript - 使用 ShaderMaterial 复制 MeshLambertMaterial 忽略纹理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21928178/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com