登峰造极境

  • 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. 正文

babylon.js 创建了一个简单的公路道路的Shader

2025-03-04

https://playground.babylonjs.com/#NNRIZL#20

https://playground.babylonjs.com/?BabylonToolkit#NNRIZL#22

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

var camera = new BABYLON.ArcRotateCamera("camera", BABYLON.Tools.ToRadians(0), BABYLON.Tools.ToRadians(57.3), 10, BABYLON.Vector3.Zero(), scene);
camera.attachControl(canvas, true);


    // This creates a light, aiming 0,1,0 - to the sky (non-mesh)
    var light = new BABYLON.HemisphericLight("light", new BABYLON.Vector3(0, 1, 0), scene);

    // Default intensity is 1. Let's dim the light a small amount
    light.intensity = 0.7;

    // Our built-in 'sphere' shape.
    var sphere = BABYLON.MeshBuilder.CreateSphere("sphere", {diameter: 2, segments: 32}, scene);

    // Move the sphere upward 1/2 its height
    sphere.position.y = 3;

    // Our built-in 'ground' shape.
    var ground = BABYLON.MeshBuilder.CreateGround("ground", {width: 6, height: 6}, scene);
ground.position.y=1
const createCross = () => {
    // 创建水平平面的顶点数据
    const horizontalPlane = BABYLON.MeshBuilder.CreatePlane("horizontalPlane", { width: 4, height: 1 }, scene);
    const horizontalVertexData = BABYLON.VertexData.ExtractFromMesh(horizontalPlane);
    horizontalPlane.dispose(); // 销毁临时网格

    // 创建垂直平面的顶点数据
    const verticalPlane = BABYLON.MeshBuilder.CreatePlane("verticalPlane", { width: 1, height: 4 }, scene);
    verticalPlane.rotation.y = Math.PI / 2; // 旋转 90 度
    const verticalVertexData = BABYLON.VertexData.ExtractFromMesh(verticalPlane);
    verticalPlane.dispose(); // 销毁临时网格

    // 合并顶点数据
    const mergedVertexData = new BABYLON.VertexData();
    mergedVertexData.positions = horizontalVertexData.positions.concat(verticalVertexData.positions);
    mergedVertexData.indices = horizontalVertexData.indices.concat(verticalVertexData.indices.map(index => index + horizontalVertexData.positions.length / 3));
    mergedVertexData.normals = horizontalVertexData.normals.concat(verticalVertexData.normals);
    mergedVertexData.uvs = horizontalVertexData.uvs.concat(verticalVertexData.uvs);

    // 创建融合后的 Mesh
    const cross = new BABYLON.Mesh("cross", scene);
    mergedVertexData.applyToMesh(cross);
    return cross;
};
const cross = createCross();
cross.position.y=-2;
cross.rotation.x = Math.PI / 2; // 旋转90度,使其垂直

    const texture1 = new BABYLON.Texture("textures/speckles.jpg", scene);
    const texture2 = new BABYLON.Texture("textures/floor.png", 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 vUv2;
// 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
    vUv2 = uv * 4.0; // 缩放UV坐标,使纹理重复4次
}
`,
    fragmentSource: `
precision highp float;
varying vec4 vPosition;
varying vec3 vNormal;
varying vec2 vUv;
varying vec2 vUv2;
uniform sampler2D textureSampler1; // 纹理采样器
uniform sampler2D textureSampler2; // 纹理采样器
void main(void) {
    //float edge = dot(normalize(vNormal), vec3(0.0, 0.0, 1.0));
    float edgeThreshold = 0.01;

     vec4 textureColor = vec4(1.0, 0.0, 0.0, 1.0);
    if (vUv.x < edgeThreshold || vUv.x > 1.0 - edgeThreshold || vUv.y < edgeThreshold || vUv.y > 1.0 - edgeThreshold) {
        
        //gl_FragColor = vec4(0.0, 1.0, 0.0, 1.0); // 边缘显示绿色
        textureColor = texture2D(textureSampler2, vUv2);
    } else {
        //gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0); // 非边缘显示红色
        textureColor = texture2D(textureSampler1, vUv2);
    }

    // 定义车道线的位置和宽度
    float laneCenter = 0.5; // 车道线在UV空间的中心位置(0.5表示中间)
    float laneWidth = 0.005; // 车道线的宽度
    float laneEdge = 0.005; // 车道线的边缘模糊宽度

    // 计算车道线的强度
    float laneStrength = smoothstep(laneCenter - laneWidth - laneEdge, laneCenter - laneWidth, vUv.y) -
                         smoothstep(laneCenter + laneWidth, laneCenter + laneWidth + laneEdge, vUv.y);

    // 定义虚线参数
    float dashLength = 0.2; // 每段虚线的长度
    float gapLength = 0.05;  // 每段间隔的长度
    float dashFrequency = dashLength + gapLength; // 虚线的总周期长度
    float dashPosition = mod(vUv.x, dashFrequency); // 计算当前UV坐标在周期中的位置

    // 判断是否在虚线范围内
    float isDash = step(dashPosition, dashLength); // 如果在虚线范围内,isDash = 1.0,否则为 0.0

    // 定义车道线颜色(黄色)
    vec4 laneColor = vec4(1.0, 1.0, 0.0, 1.0); // 黄色

    // 混合纹理颜色和车道线颜色
    vec4 finalColor = mix(textureColor, laneColor, laneStrength * isDash);

    gl_FragColor = finalColor;


}
`,
}, {
    attributes: ["position", "normal", "uv"],
    uniforms: ["worldViewProjection"],
});
shaderMaterial.setTexture("textureSampler1", texture1);
shaderMaterial.setTexture("textureSampler2", texture2);
sphere.material = shaderMaterial;
ground.material = shaderMaterial;
cross.material = shaderMaterial;
    return scene;
};
标签: 暂无
最后更新:2025-06-05

代号山岳

知之为知之 不知为不知

点赞
< 上一篇
下一篇 >

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

Theme Kratos Made By Seaton Jiang

蜀ICP备14031139号-5

川公网安备51012202000587号