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

如何在Shader Graph中根据物体位置从纹理获取像素颜色?

在着色器中实现基于物体位置获取像素颜色的功能(类似Texture2D.GetPixel)

核心逻辑

要实现和Texture2D.GetPixel(transform.position.x, transform.position.z)等价的效果,关键是将物体的世界空间X/Z坐标转换为纹理的采样坐标:

  1. 把世界位置的X、Z值映射到纹理的像素索引范围(0到纹理宽/高-1)
  2. 将像素索引转换为着色器常用的UV坐标(0到1的归一化范围)
  3. 用转换后的UV采样纹理获取对应像素颜色

示例实现(Unity URP Unlit着色器)

以下是完整的URP无光照着色器代码,直接挂载到物体上即可生效:

Shader "Custom/PositionBasedPixelSample"
{
    Properties
    {
        _MainTex ("Texture", 2D) = "white" {}
        _TextureSize ("Texture Size (Width, Height)", Vector) = (512, 512, 0, 0)
        _PositionOffset ("Position Offset", Vector) = (0, 0, 0, 0)
    }

    SubShader
    {
        Tags { "RenderType"="Opaque" "RenderPipeline"="UniversalPipeline" }
        LOD 100

        Pass
        {
            HLSLPROGRAM
            #pragma vertex vert
            #pragma fragment frag

            #include "Packages/com.unity.render-pipelines.universal/ShaderLibrary/Core.hlsl"

            struct Attributes
            {
                float4 positionOS : POSITION;
            };

            struct Varyings
            {
                float4 positionHCS : SV_POSITION;
                float3 positionWS : TEXCOORD0;
            };

            TEXTURE2D(_MainTex);
            SAMPLER(sampler_MainTex);
            float4 _MainTex_ST;
            float2 _TextureSize;
            float3 _PositionOffset;

            Varyings vert(Attributes IN)
            {
                Varyings OUT;
                OUT.positionHCS = TransformObjectToHClip(IN.positionOS.xyz);
                OUT.positionWS = TransformObjectToWorld(IN.positionOS.xyz);
                return OUT;
            }

            half4 frag(Varyings IN) : SV_Target
            {
                // 获取物体世界位置的X和Z,加上偏移修正
                float2 worldPosXZ = IN.positionWS.xz + _PositionOffset.xz;
                
                // 将世界坐标转换为像素索引(匹配Texture2D.GetPixel的像素坐标逻辑)
                // 注意:若世界坐标范围和纹理尺寸不匹配,需自行缩放
                float2 pixelIndex = worldPosXZ;
                
                // 转换为归一化UV坐标
                float2 uv = pixelIndex / _TextureSize;
                
                // 采样纹理(使用Point过滤,模拟GetPixel的精确像素采样)
                half4 col = SAMPLE_TEXTURE2D(_MainTex, sampler_MainTex, uv);
                
                return col;
            }
            ENDHLSL
        }
    }
}

关键细节说明

  • 纹理尺寸参数_TextureSize:必须填入目标纹理实际宽高(比如512x512),否则采样坐标会偏移
  • 位置偏移_PositionOffset:用来调整世界坐标和纹理像素坐标的对齐关系,比如让世界原点对应纹理左上角
  • 采样过滤模式:建议把纹理的Filter Mode设置为Point (no filter),这样能精确获取单个像素颜色,和GetPixel行为一致
  • 坐标范围匹配:如果世界坐标范围和纹理尺寸不一致,需要在pixelIndex计算时加入缩放系数,比如pixelIndex = worldPosXZ * _ScaleFactor

常见问题处理

  • 若采样颜色出现拉伸/偏移:检查_TextureSize是否和实际纹理尺寸一致,以及_PositionOffset的设置
  • 若需要使用局部空间位置:将TransformObjectToWorld改为直接使用IN.positionOS.xz即可

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 21:25:06