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

如何为Raycast投射的RawImage添加阴影强度以表现深度?

问题描述

我在完成作业时需要用Raycast把3D场景投射到640×480的RawImage中。目前已经通过发射640×480条射线获取命中物体的颜色来给图像上色,但还需要添加阴影值体现深度——比如绿色圆柱的底部应该呈现更深的绿色,这个效果我还没实现。

现有代码
const int width = 640;
const int height = 480;
[SerializeField] RawImage image;
void Start()
{
    Texture2D texture = new Texture2D(640, 480);
    image.texture = texture;

    for (int i=0;i<width; i++)
    {
        for(int j = 0; j < height; j++)
        {
            //Debug.DrawRay(new Vector3(i,j,0), transform.TransformDirection(Vector3.forward) * 1000, Color.white, 50);
            RaycastHit hit;
            if (Physics.Raycast(new Vector3(i,j,0), transform.TransformDirection(Vector3.forward), out hit, Mathf.Infinity))
            {
                texture.SetPixel(i, j, hit.collider.GetComponent<Renderer>().material.color);
            }
            else
            {
                //Debug.Log("Did not Hit");
            }
        }
    }
    texture.Apply();
   
}
实现带阴影的颜色计算方法

要实现阴影和深度感,核心是两个部分:基于表面法线的漫反射亮度衰减,以及检测当前点是否被光源遮挡。

1. 基于法线的漫反射亮度计算

物体表面亮度由表面法线与光源方向的夹角决定:夹角越小(光线垂直照射),亮度越高;夹角越大(比如圆柱底部),光线越斜,亮度越低,颜色自然更深。

修改代码中设置像素颜色的逻辑,加入漫反射计算:

// 定义光源方向,可根据场景中光源位置调整,比如从上方照射
Vector3 lightDirection = Vector3.down;

if (Physics.Raycast(new Vector3(i,j,0), transform.TransformDirection(Vector3.forward), out hit, Mathf.Infinity))
{
    Color originalColor = hit.collider.GetComponent<Renderer>().material.color;
    // 计算法线与光源方向的点积,取正数避免颜色反相
    float brightness = Mathf.Max(Vector3.Dot(hit.normal, -lightDirection), 0f);
    // 用亮度值调整原颜色,0为全黑,1为原颜色
    Color shadedColor = originalColor * brightness;
    texture.SetPixel(i, j, shadedColor);
}

2. 添加阴影遮挡检测

如果要实现真实阴影(比如物体被其他遮挡物挡住光线),需要在命中点向光源方向发射一条射线,判断是否有物体遮挡:

Vector3 lightDirection = Vector3.down;
float shadowDarkness = 0.3f; // 阴影暗度,0为全黑,1为无阴影

if (Physics.Raycast(new Vector3(i,j,0), transform.TransformDirection(Vector3.forward), out hit, Mathf.Infinity))
{
    Color originalColor = hit.collider.GetComponent<Renderer>().material.color;
    float brightness = Mathf.Max(Vector3.Dot(hit.normal, -lightDirection), 0f);
    
    // 发射阴影射线:从命中点偏移一点,避免检测到自身碰撞体
    Vector3 shadowRayStart = hit.point + hit.normal * 0.01f;
    if (Physics.Raycast(shadowRayStart, -lightDirection, out RaycastHit shadowHit, Mathf.Infinity))
    {
        // 命中其他物体,说明当前点在阴影中,降低亮度
        brightness *= shadowDarkness;
    }
    
    Color shadedColor = originalColor * brightness;
    texture.SetPixel(i, j, shadedColor);
}

3. 可选优化:基于距离的深度衰减

如果需要让远处物体更暗,可加入距离衰减逻辑:

float maxDistance = 100f; // 设定距离衰减的最大范围
float distanceFactor = Mathf.Clamp01(1 - (hit.distance / maxDistance));
// 结合法线亮度和距离衰减调整颜色
Color shadedColor = originalColor * brightness * distanceFactor;

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.06 23:50:25