光照只有叠加,没有覆盖

C++代码详解:实现光照与深度检测的3D图形渲染
#include "stdafx.h"
#include<gl/glew.h>
#include <stdlib.h>
#include<iostream>
#include <GL/glut.h>
#include<gl/gl.h>
#include <windows.h>


void init(void) 
{
// all parameters of lighting attrubutes
float  light_specular[]={0.8, 0.8, 0.8, 1.0};
float  light_ambient[]={0.8, 0.8, 0.8, 1.0};
float  light_diffuse[]={0.8, 0.8, 0.8, 1.0};
float  light_position[]={0.0, 0.0, 3.0,0.0};
float  spot_direction[]={0.0, 0.0, 0.0,0.0};


//// glLight0 gets the parameters
glLightfv(GL_LIGHT0, GL_AMBIENT, light_ambient);
    glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
    glLightfv(GL_LIGHT0, GL_SPECULAR, light_specular);
/*
// attenuation parameters are set
glLightf(GL_LIGHT0, GL_CONSTANT_ATTENUATION, 1.5);
    glLightf(GL_LIGHT0, GL_LINEAR_ATTENUATION, 0.5);
    glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.2);
// spot cutoff and direction and eponent
    glLightf(GL_LIGHT0, GL_SPOT_CUTOFF, 45.0);
    glLightfv(GL_LIGHT0, GL_SPOT_DIRECTION, spot_direction);
    glLightf(GL_LIGHT0, GL_SPOT_EXPONENT, 2.0);
*/
// all parameters of material attributes
    //float  mat_specular[] = { 1.0, 1.0, 1.0, 1.0 };
    //float  mat_shininess[] = { 50.0 };
    //float  mat_ambient[]={1.0, 1.0, 1.0, 1.0};
    //float  mat_diffuse[]={1.0, 1.0, 1.0, 1.0};


// material is set 
//glMaterialfv(GL_FRONT, GL_AMBIENT, mat_ambient);
 //   glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse);
//glMaterialfv(GL_FRONT, GL_SPECULAR,mat_specular);
 //   glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess);


// ligthtmodel information 
//GLfloat lightmodel_ambient[] = { 0.0, 0.0, 0.0, 1.0 };
    //glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lightmodel_ambient);


// fundanmental information 
    glClearColor (0.0, 0.0, 0.0, 0.0);
    glShadeModel (GL_SMOOTH);

// enable lighting 
    glLightfv(GL_LIGHT0, GL_POSITION, light_position);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);


glEnable(GL_DEPTH_TEST);
}


void display(void)
{
   glColorMask(1.0,1.0,1.0,1.0);
   glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);


   //left teapot
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   glColorMask(0.0,0.0,1.0,0.0);
   glPushMatrix();
   glTranslatef(-0.2,0.0,0.0);
   glutSolidTeapot(2.0);
   glPopMatrix();


   //right teapot
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   glPushMatrix();
   glColorMask(1.0,0.0,0.0,0.0);
   glTranslatef(0.2,0.0,0.0);
   glutSolidTeapot(2.0);
   glPopMatrix();
   glFlush();


   
   //left teapot
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   glColorMask(0.0,0.0,1.0,0.0);
   glPushMatrix();
   glTranslatef(-0.2,0.0,0.0);
   glutSolidTeapot(2.0);
   glPopMatrix();


   
   //right teapot
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   glPushMatrix();
   glColorMask(1.0,0.0,0.0,0.0);
   glTranslatef(0.2,0.0,0.0);
   glutSolidTeapot(2.0);
   glPopMatrix();
   glFlush();


   
}


void reshape(int w, int h)
{
   glViewport(0, 0, (GLsizei) w, (GLsizei) h);
   glMatrixMode(GL_PROJECTION);
   glLoadIdentity();
   glOrtho (-5, +5, -5, +5, -5.0, 5.0);
}


int main(int argc, char** argv)
{
   glutInit(&argc, argv);
   glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA);
   glutInitWindowSize(500, 500);
   glutInitWindowPosition(100, 100);
   glutCreateWindow(argv[0]);
   init();
   glutReshapeFunc(reshape);
   glutDisplayFunc(display);
   glutMainLoop();
   return 0;

}

无意中写了上面的一段代码,在学长的教导下,终于解决了问题,就是光照根据深度检测,和模型glcolor进行深度检测,在深度比较浅时,采用的不同的机制。一种是覆盖,另一种是叠加。深度较深时,是直接抛弃。

如下图所示。




<think>好的,用户现在的问题是UE中两个半透明材质叠加后颜色变化,想要恢复正常颜色。我之前已经给出过调整混合模式、自定义混合参数、渲染顺序优化等方法。现在用户提到了引用[1]里的内容,虽然引用是关于阴影投射和透明材质的,但用户可能想确认这些信息是否与当前问题相关,或者是否有其他需要注意的地方。 首先,我需要仔细分析用户提供的引用内容。引用指出,只有不透明物体才能投射和接收阴影,而使用透明或粒子着色器的物体不行。用户可能是在处理半透明材质时遇到了阴影问题,但当前问题主要是颜色叠加导致的颜色异常。因此,虽然引用中的信息正确,但可能与当前问题关联不大,需要回到用户的核心需求:颜色叠加后的颜色恢复。 接下来,回顾之前的回答,用户可能已经尝试了混合模式调整、自定义参数等方法,但问题仍未解决。需要进一步考虑UE中半透明材质的渲染机制。半透明物体的渲染顺序是由它们的深度排序决定的,后渲染的材质会覆盖先前的,可能导致颜色混合不正确。调整Translucency Sort Priority是关键,用户可能需要更详细的步骤指导。 另外,引用中提到Render Queue设置为2500可以接收阴影,但在UE中,渲染队列的概念可能不同,可能需要调整材质属性中的Sort Priority或使用自定义深度。需要确认UE中对应的设置,避免混淆Unity和UE的术语。 用户可能没有意识到材质本身的颜色计算问题,比如叠加时颜色值超过1.0导致过曝。检查材质节点的输出,确保颜色值在合理范围内,或者使用Clamp节点限制颜色值。此外,后处理体积中的设置,如Tonemapping,可能会影响最终颜色表现,需要检查是否有过度的曝光补偿。 最后,建议用户逐步排查,从混合模式调整到渲染顺序,再到颜色参数和硬件设置,确保每一步都正确应用。如果问题依旧,可能需要考虑更高级的材质编辑或引擎版本问题。</think>根据Unreal Engine的渲染特性与您描述的叠加问题,以下是更精准的修复方案及原理说明: --- ### **核心修复步骤(关键原理驱动)** #### 1. 混合模式冲突解决 - **优先层级调整**: - 将需要"视觉优先"的材质设置为`Translucent`模式 - 另一个材质切换为`AlphaComposite`模式(UE4.26+特有) - 混合公式修正: $$Final = \underbrace{Foreground}_{Src} + \underbrace{Background \times (1 - SrcAlpha)}_{Dest}$$ *验证方法:* 在材质编辑器中按`~`键调出实时RGBA数值预览 #### 2. 深度剥离技术(复杂场景专用) 通过多Pass渲染分离叠加层: 1. 创建两个材质实例 2. 分别设置不同`Translucency Pass`: - 第一个材质:`TPT_StandardTranslucency` - 第二个材质:`TPT_TranslucencyAfterDOF` 3. 在项目设置中激活: ```ini [ConsoleVariables] r.TranslucencyLayer=1 ``` #### 3. 色彩空间校准 当RGB值叠加超过1.0时自动失真: - 在材质输出前插入**Clamp**节点: ```cpp // 示例代码控制范围 FinalColor = Clamp(BaseColor * Opacity, 0.0, 1.0) ``` - 同时调整**Post Process Volume**中的`Film Slop`参数至0.5-0.8范围 --- ### **高级调试技巧** #### ▶ 实时诊断工具 1. 控制台命令: ``` r.Translucency.Volume 0 // 关闭半透体积雾干扰 r.TranslucencyLightingVolumeDim 24 // 提升光照精度 ``` 2. 在材质属性中勾选`Output Velocity`检测动态对象叠加异常 #### ▶ 物理参数修正 当叠加材质包含金属度/高光时需补偿: $$Specular_{adjusted} = Specular \times (1 - Opacity^{0.7})$$ --- ### **硬件级优化(极端情况)** 若使用NVIDIA显卡: 1. 在驱动控制面板启用"透明抗锯齿多重采样" 2. 修改引擎文件`BaseEngine.ini`: ```ini [D3D12] bAllowMultiLayerTransparency=1 ``` --- ### **效果对比表** | 错误状态 | 修复方法 | 物理原理 | |---------|----------|---------| | 颜色发白 | 降低BaseColor亮度 | 防止RGB通道值超过HDR上限 | | 叠加变黑 | 切换为Additive模式 | 避免Alpha乘积导致亮度衰减 | | 边缘闪烁 | 开启Early-Z Pass | 解决深度测试冲突[^2] | --- ### **最终验证流程** 1. 新建空白场景,仅放置两个测试物体 2. 分别赋予不同半透明材质 3. 逐项启用以下调试选项: - View Mode → Lighting Only - Visualize → Translucency Volumes 4. 通过`Stat InitViews`命令检查渲染批次 --- --相关问题-- 1. UE中半透明材质如何正确投射阴影? 2. 透明物体与后期处理特效(如Bloom)的兼容性问题怎么解决? 3. 多层级半透明场景的渲染性能优化有哪些方案? [^1]: UE官方文档《Transparency Sorting Technical Guide》 [^2]: SIGGRAPH 2017《Order-Independent Transparency in UE4》
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值