登峰造极境

  • WIN
    • CSharp
    • JAVA
    • OAM
    • DirectX
    • Emgucv
  • UNIX
    • FFmpeg
    • QT
    • Python
    • Opencv
    • Openwrt
    • Twisted
    • Design Patterns
    • Mysql
    • Mycat
    • MariaDB
    • Make
    • OAM
    • Supervisor
    • Nginx
    • KVM
    • Docker
    • OpenStack
  • WEB
    • ASP
    • Node.js
    • PHP
    • Directadmin
    • Openssl
    • Regex
  • APP
    • Android
  • AI
    • Algorithm
    • Deep Learning
    • Machine Learning
  • IOT
    • Device
    • MSP430
  • DIY
    • Algorithm
    • Design Patterns
    • MATH
    • X98 AIR 3G
    • Tucao
    • fun
  • LIFE
    • 美食
    • 关于我
  • LINKS
  • ME
Claves
长风破浪会有时,直挂云帆济沧海
  1. 首页
  2. Programming
  3. babylon.js
  4. 正文

babylonjs ShaderMaterial实现一个简单的城市外景

2025-04-18
var createScene = function () {
    // This creates a basic Babylon Scene object (non-mesh)
    var scene = new BABYLON.Scene(engine);

    // This creates and positions a free camera (non-mesh)
    const camera = new BABYLON.ArcRotateCamera("camera", Math.PI / 2, Math.PI / 4, 500, BABYLON.Vector3.Zero(), scene);
    // This targets the camera to scene origin
    camera.setTarget(BABYLON.Vector3.Zero());
    camera.attachControl(canvas, true);
    var light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene);
    light.intensity = 0.7;

    var skybox = BABYLON.Mesh.CreateBox("BackgroundSkybox", 5000, scene, undefined, BABYLON.Mesh.BACKSIDE);
    var backgroundMaterial = new BABYLON.BackgroundMaterial("backgroundMaterial", scene);
    backgroundMaterial.reflectionTexture = new BABYLON.CubeTexture("textures/TropicalSunnyDay", scene);
    backgroundMaterial.reflectionTexture.coordinatesMode = BABYLON.Texture.SKYBOX_MODE;
    skybox.material = backgroundMaterial;


    const texture1 = new BABYLON.Texture("http://i.abc.com/image/JZBG4/材质 (10).png", scene);
    const texture2 = new BABYLON.Texture("http://i.abc.com/image/0PEQC/材质 (11).png", scene);
    const texture3 = new BABYLON.Texture("http://i.abc.com/image/DBU1M/TropicalSunnyDay_ny.jpg", scene);
    //texture2.wrapU = BABYLON.Texture.WRAP_REPEAT; // 设置纹理在U方向重复
    //texture2.wrapV = BABYLON.Texture.WRAP_REPEAT; // 设置纹理在V方向重复
    const shaderMaterial = new BABYLON.ShaderMaterial("shader", scene, {
        vertexSource: `
precision highp float;

// Attributes
attribute vec3 position;
attribute vec3 normal;
attribute vec2 uv;
varying vec2 vUv;
varying vec2 vUv1;
varying vec2 vUv2;
varying vec2 vUv3;
// Uniforms
uniform mat4 worldViewProjection;

// Varying
varying vec4 vPosition;
varying vec3 vNormal;

void main() {
    vec4 p = vec4(position, 1.0);
    vPosition = p;
    vNormal = normal;
    gl_Position = worldViewProjection * p;
    vUv = uv; // 传递uv到Fragment Shader
    vUv1 = uv * 3.0; // 缩放UV坐标,使纹理重复4次
    vUv2 = uv * 1.0; // 缩放UV坐标,使纹理重复4次
    vUv3 = uv * 1.0; 
}
`,
        fragmentSource: `
precision highp float;
varying vec4 vPosition;
varying vec3 vNormal;
varying vec2 vUv;
varying vec2 vUv1;
varying vec2 vUv2;
varying vec2 vUv3;
uniform sampler2D textureSampler1; // 纹理采样器
uniform sampler2D textureSampler2; // 纹理采样器
uniform sampler2D textureSampler3; // 纹理采样器
void main(void) {
    //float edge = dot(normalize(vNormal), vec3(0.0, 0.0, 1.0));
    float edgeThreshold = 0.01;

     vec4 textureColor1 = vec4(0.0, 0.0, 0.0, 0.0);
     vec4 textureColor2 = vec4(0.0, 0.0, 0.0, 0.0);
     vec4 textureColor3 = vec4(0.0, 0.0, 0.0, 0.0);
     textureColor1 = texture2D(textureSampler1, vUv1);
     textureColor2 = texture2D(textureSampler2, vUv2);
     textureColor3 = texture2D(textureSampler3, vUv3);
    // 定义黑色的阈值
    float blackThreshold = 0.05;
float blackThreshold2 = 0.2;
    // 判断颜色是否接近黑色
    if (textureColor1.r > blackThreshold && 
        textureColor1.g > blackThreshold && 
        textureColor1.b > blackThreshold) {
            gl_FragColor = vec4(0.0, 0.0, 0.0, 0.7);
     
    } else if (textureColor2.r > blackThreshold2 && 
        textureColor2.g > blackThreshold2 && 
        textureColor2.b > blackThreshold2) {
            gl_FragColor = vec4(textureColor2.rgb, 0.7);
    }else{
        gl_FragColor =vec4(textureColor3.rgb, 0.6);
    }


}
`,
    }, {
        attributes: ["position", "normal", "uv"],
        uniforms: ["worldViewProjection"],
       needAlphaBlending: true
    });
    shaderMaterial.setTexture("textureSampler1", texture1);
    shaderMaterial.setTexture("textureSampler2", texture2);
    shaderMaterial.setTexture("textureSampler3", texture3);





    const numBuildings = 30;
    const baseWidth = 40; // 基础宽度
    const maxHeight = 100;

    const buildings = [];
    for (let i = 0; i < numBuildings; i++) {
        const width = baseWidth + Math.random() * 10;
        const height = maxHeight * Math.random() + 10;
        const depth = 40; // 固定深度
        // 创建立方体
        const box = BABYLON.MeshBuilder.CreateBox(`building_${i}`, { width, height, depth }, scene);

        // 随机位置
        box.position.x = (Math.random() - 0.5) * 500;
        box.position.z = (Math.random() - 0.5) * 500;
        box.position.y = height / 2;
        box.material = shaderMaterial;
        buildings.push(box);
    }

    // Our built-in 'ground' shape.
    var mirror = BABYLON.MeshBuilder.CreateGround("ground", { width: 1000, height: 1000 }, scene);
    // 创建深蓝色材质
   // const groundMaterial = new BABYLON.StandardMaterial("groundMaterial", scene);
   // groundMaterial.diffuseColor = new BABYLON.Color3(0, 0, 0.5); // 深蓝色 (R=0, G=0, B=0.5)
    
    
    //const mirrorTexture = new BABYLON.MirrorTexture("mirror", 512, scene, true);
    //mirrorTexture.mirrorPlane = new BABYLON.Plane(0, -1, 0, 0); // 设置反射平面
    //mirrorTexture.renderList.push(buildings[0]); // 添加需要反射的物体

// 将反射纹理应用到地面材质
   // const groundMaterial = new BABYLON.StandardMaterial("groundMaterial", scene);
   // groundMaterial.reflectionTexture = mirrorTexture;
   // ground.material = groundMaterial;
// 将材质应用到地面
   // ground.material = groundMaterial;

    //var mirror = BABYLON.Mesh.CreateBox("Mirror", 1.0, scene);
    //mirror.scaling = new BABYLON.Vector3(100.0, 0.01, 100.0);
    mirror.material = new BABYLON.StandardMaterial("mirror", scene);
    mirror.material.diffuseColor = new BABYLON.Color3(0.01, 0.1, 0.3); 
    mirror.material.reflectionTexture = new BABYLON.MirrorTexture("mirror", {ratio: 0.5}, scene, true);
    mirror.material.reflectionTexture.mirrorPlane = new BABYLON.Plane(0, -1.0, 0, -2.0);
    mirror.material.reflectionTexture.renderList = buildings;
    mirror.material.reflectionTexture.level = 1.0;
    mirror.material.reflectionTexture.adaptiveBlurKernel = 32;
	mirror.position = new BABYLON.Vector3(0, 0, 0);


    return scene;
};

在 Babylon.js 中,renderingGroupId 的范围通常是从 0 到 255。这允许你对场景中的物体进行分组,以控制它们的渲染顺序。较低的 renderingGroupId 会先被渲染。你可以根据需要在这个范围内设置不同的值,以实现复杂的渲染顺序控制。

标签: 暂无
最后更新:2025-04-29

代号山岳

知之为知之 不知为不知

点赞
< 上一篇
下一篇 >

COPYRIGHT © 2099 登峰造极境. ALL RIGHTS RESERVED.

Theme Kratos Made By Seaton Jiang

蜀ICP备14031139号-5

川公网安备51012202000587号