如何为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
相关产品推荐
相关产品推荐

