You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

GLSL技术咨询:如何获取当前片段纹理颜色及实现片段颜色叠加

Hey there! No worries at all—GLSL can feel a bit overwhelming when you're just starting out, so let's break down your two questions step by step and tweak your shader to fit what you need.

1. 如何获取当前片段的纹理颜色

To get the texture color for the current fragment, you'll need to add a few key pieces to both your vertex and fragment shader:

  • Pass texture coordinates from the vertex shader:
    In your vertex shader, add a varying variable to carry texture coordinates over to the fragment shader:

    varying vec2 vTexCoord;
    
    void main() {
        // ... keep your existing vertex shader logic ...
        vTexCoord = gl_MultiTexCoord0.xy; // Pass the default texture coordinates from the vertex
        gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
    }
    
  • Sample the texture in the fragment shader:
    First, declare a uniform to reference your texture asset, plus the varying coordinate variable. Add these lines at the top of your fragment shader:

    uniform sampler2D texture; // Links to your game's texture asset
    varying vec2 vTexCoord;     // Receives coordinates from the vertex shader
    

    Then, inside the main() function, use the texture2D() function to grab the color at the current fragment's coordinates:

    vec4 texColor = texture2D(texture, vTexCoord);
    
2. 实现颜色叠加效果

Color overlay (blending) has several common modes—let's cover a few easy-to-implement options that you can swap into your shader, using the texture color and your existing finalColor (the lighting calculation result):

模式1:简单加法叠加(Brightening effect)

Add the lighting color to the texture color, then clamp the result to keep values within valid 0.0–1.0 color range:

gl_FragColor = clamp(texColor + finalColor, 0.0, 1.0);

模式2:乘法叠加(Tinting/Darkening effect)

Multiply the texture color by the lighting color to tint the texture with your calculated lighting:

gl_FragColor = texColor * finalColor;

模式3:屏幕叠加(High-contrast brightening)

This mode brightens the texture while preserving highlights, similar to shining a light through a transparent layer:

gl_FragColor = 1.0 - (1.0 - texColor) * (1.0 - finalColor);

模式4:标准Overlay混合(Photoshop-style)

This combines multiplication and screen blending based on the texture's brightness, creating a vibrant, high-contrast effect:

vec4 overlayColor;
// Apply multiply for dark texture channels, screen for bright ones
overlayColor.r = texColor.r <= 0.5 ? 2.0 * texColor.r * finalColor.r : 1.0 - 2.0 * (1.0 - texColor.r) * (1.0 - finalColor.r);
overlayColor.g = texColor.g <= 0.5 ? 2.0 * texColor.g * finalColor.g : 1.0 - 2.0 * (1.0 - texColor.g) * (1.0 - finalColor.g);
overlayColor.b = texColor.b <= 0.5 ? 2.0 * texColor.b * finalColor.b : 1.0 - 2.0 * (1.0 - texColor.b) * (1.0 - finalColor.b);
overlayColor.a = texColor.a * finalColor.a; // Preserve alpha channel

gl_FragColor = overlayColor;
修改后的完整片段着色器代码

Here's your shader updated with texture sampling and the screen overlay mode (swap in any of the other modes above if you prefer):

varying vec3 vN; 
varying vec3 v; 
varying vec4 color;
uniform sampler2D texture; // Add texture reference
varying vec2 vTexCoord;    // Add texture coordinate variable

#define MAX_LIGHTS 1 

void main (void) { 
    vec3 N = normalize(vN); 
    vec4 finalColor = vec4(0.0, 0.0, 0.0, 0.0); 

    // Keep your existing lighting calculation logic
    for (int i=0;i<MAX_LIGHTS;i++) { 
        vec3 L = normalize(gl_LightSource[i].position.xyz - v); 
        vec3 E = normalize(-v); 
        vec3 R = normalize(-reflect(L,N)); 

        vec4 Iamb = gl_LightSource[i].ambient; 
        vec4 Idiff = gl_LightSource[i].diffuse * max(dot(N,L), 0.0); 
        Idiff = clamp(Idiff, 0.0, 1.0); 

        vec4 Ispec = gl_LightSource[i].specular * pow(max(dot(R,E),0.0),0.3*gl_FrontMaterial.shininess); 
        Ispec = clamp(Ispec, 0.0, 1.0); 

        finalColor += Iamb + Idiff + Ispec; 
    } 

    // Get the current fragment's texture color
    vec4 texColor = texture2D(texture, vTexCoord);

    // Apply screen overlay blend
    gl_FragColor = 1.0 - (1.0 - texColor) * (1.0 - finalColor);
    // Swap with another mode example: gl_FragColor = texColor * finalColor;
}

Quick reminder: Don't forget to bind your game's texture asset to the texture uniform in your game code—this tells the shader which texture to sample from!

内容的提问来源于stack exchange,提问作者user15922830

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.28 10:32:31