【问题标题】:Normal Mapping on Texture Splatted Terrain纹理喷溅地形上的法线贴图
【发布时间】:2019-05-29 12:41:42
【问题描述】:

我在 Three.js 中开发了一个带有纹理飞溅的地形生成系统,但我无法对其应用法线贴图。我应该怎么做?到目前为止,此代码功能齐全。

我查看了一些关于 WebGL 着色和法线贴图的教程,但我找不到与我的代码准确匹配的教程。

FRAGMENT_SHADER: `
    uniform sampler2D albedoA;
    uniform sampler2D albedoB;
    uniform sampler2D albedoC;
    uniform sampler2D albedoD;
    uniform sampler2D albedoE;

    uniform sampler2D normalA;
    uniform sampler2D normalB;
    uniform sampler2D normalC;
    uniform sampler2D normalD;
    uniform sampler2D normalE;

    uniform float repeatScale;

    uniform vec3 sunPosition;

    varying vec2 vUV;
    varying float vAmount;

    varying vec3 vNormal;
    varying vec3 vWorldPosition;

    void main()
    {
        vec3 diffA = (smoothstep(0.01, 0.25, vAmount) - smoothstep(0.25, 0.35, vAmount)) * texture2D(albedoA, vUV * repeatScale).rgb;
        vec3 diffB = (smoothstep(0.24, 0.27, vAmount) - smoothstep(0.27, 0.37, vAmount)) * texture2D(albedoB, vUV * repeatScale).rgb;
        vec3 diffC = (smoothstep(0.28, 0.32, vAmount) - smoothstep(0.32, 0.42, vAmount)) * texture2D(albedoC, vUV * repeatScale).rgb;
        vec3 diffD = (smoothstep(0.30, 0.60, vAmount) - smoothstep(0.40, 0.70, vAmount)) * texture2D(albedoD, vUV * repeatScale).rgb;
        vec3 diffE = (smoothstep(0.50, 0.85, vAmount))                                   * texture2D(albedoE, vUV * repeatScale).rgb;
        vec3 albedoVector = diffA + diffB + diffC + diffD + diffE;

        vec3 normA = (smoothstep(0.01, 0.25, vAmount) - smoothstep(0.25, 0.35, vAmount)) * texture2D(normalA, vUV * repeatScale).rgb;
        vec3 normB = (smoothstep(0.24, 0.27, vAmount) - smoothstep(0.27, 0.37, vAmount)) * texture2D(normalB, vUV * repeatScale).rgb;
        vec3 normC = (smoothstep(0.28, 0.32, vAmount) - smoothstep(0.32, 0.42, vAmount)) * texture2D(normalC, vUV * repeatScale).rgb;
        vec3 normD = (smoothstep(0.30, 0.60, vAmount) - smoothstep(0.40, 0.70, vAmount)) * texture2D(normalD, vUV * repeatScale).rgb;
        vec3 normE = (smoothstep(0.50, 0.85, vAmount))                                   * texture2D(normalE, vUV * repeatScale).rgb;
        vec3 normalVector = normA + normB + normC + normD + normE;

        float diffuseFloat = max(dot(normalize(sunPosition - vWorldPosition), vNormal), 0.0);
        if (diffuseFloat < 0.25) { diffuseFloat = 0.25; }
        if (diffuseFloat > 1.0) { diffuseFloat = 1.0; }

        gl_FragColor = vec4(diffuseFloat * albedoVector, 1.0);
    }
`,
VERTEX_SHADER: `
    uniform sampler2D heightTexture;

    varying vec2 vUV;
    varying float vAmount;

    varying vec3 vNormal;
    varying vec3 vWorldPosition;

    void main()
    {
        vUV = uv;
        vAmount = texture2D(heightTexture, uv).r;

        vec4 worldPosition = modelViewMatrix * vec4(position, 1.0);

        vWorldPosition = worldPosition.xyz;
        vNormal = vec3(normal);

        gl_Position = projectionMatrix * worldPosition;
    }
`

我正在使用 THREE.ShaderMaterial,到目前为止,代码会喷出纹理并考虑光照和阴影,但不考虑法线贴图。

【问题讨论】:

    标签: javascript three.js glsl webgl shader


    【解决方案1】:

    您可以通过简单的数值近似来计算表面(地形)的法线 - 请参阅 Finite difference method。

    您必须知道高度图纹理的大小。我建议将纹理的大小设置为统一变量:

    uniform sampler2D heightTexture;
    uniform vec2 heightTextureSize;  // (width, height) of heightTexture;
    

    计算纹理相邻纹素之间的偏移量:

    vec2 offset = 1.0 / heightTextureSize;
    

    读取纹理相邻纹素的高度

    vA = texture2D(heightTexture, uv).r;
    
    vAL = texture2D(heightTexture, uv + vec2(-offset.x,  0.0)).r;
    vAR = texture2D(heightTexture, uv + vec2( offset.x,  0.0)).r;
    vAB = texture2D(heightTexture, uv + vec2( 0.0, -offset.y)).r;
    vAT = texture2D(heightTexture, uv + vec2( 0.0,  offset.y)).r;
    

    终于可以在纹理空间中计算近似法线向量了

    vec3 normalMap = normalize( vec3(vAL - vAR, vAT - vAB, 2.0) );
    

    【讨论】:

    • 你好,我将如何使用法线向量实现法线纹理?
    • 我会将它添加到 vNormal 值中吗? floatdiffuseFloat = max(dot(normalize(sunPosition - vWorldPosition), vNormal + (normalVector * normalMap)), 0.0);
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-09-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-23
    • 2012-11-30
    相关资源
    最近更新 更多