首页 > 其他分享 >4、片元着色器之光线步进及其和兰伯特光照模型的结合应用

4、片元着色器之光线步进及其和兰伯特光照模型的结合应用

时间:2024-10-30 16:45:47浏览次数:8  
标签:point direction 光线 兰伯特 float 片元 vec3 步进 着色器

1、什么是光线步进?
光线步进(Ray Marching)是一种用于渲染和追踪的技术,尤其在处理体积数据和隐式表面时非常有效。与传统的光线追踪方法不同,光线步进不直接计算光线与物体的交点,而是通过在光线上逐步前进来寻找相交的表面。这种方法通常用于场景中存在复杂几何体或体积效果的情况。
2、基本步骤

  1. 光线发射:从相机位置发射光线,通常在场景中每个像素位置发射一条光线。
  2. 步进前进:在光线上以固定的步长逐步前进,每一步都计算当前位置的场景信息。
  3. 场景求值:在每一步中,使用一个场景描述函数(如距离场)来判断当前点距离最近表面的距离。如果距离小于某个阈值,则认为光线和物体相交。
  4. 交点判断:一旦光线与物体相交,计算交点的颜色和光照,并将结果返回。
  5. 重复步骤:如果没有找到交点,继续前进,直到光线超出场景的边界。

3、应用场景:

  1. 体积渲染:适用于模拟云、烟、雾等体积效果。
  2. 复杂几何体:处理复杂的隐式曲面,特别是无法直接通过多边形网格表示的几何体。
  3. 效果优化:在某些情况下,光线步进可以提供更高的渲染灵活性和表现力,尤其是在实时渲染和着色器编程中。

4、优缺点
灵活性高,可以处理复杂场景;
适合动态场景的渲染;
性能开销大,尤其是在高分辨率和复杂场景中;
需要精心调整步长,以平衡渲染质量和性能。

5、示例

//限制光线步进的范围,防止计算过长的距离。
const float maxDistance=40.0;
// 球心在原点,半径为1.0的球体
float sdSphere(vec3 point)
{
    return length(point)-1.0;
}
// 光线步进,start指的是相机(视点)位置;direction表示从相机(视点)发出的光线的方向
float rayMarching(vec3 start,vec3 direction)
{
    float d=0.;
    for(int i=0;i<9999;i++)
    {
        vec3 point=start+d*direction;
        // 像素点到球体表面的距离
        float d0=sdSphere(point);
        // 当d0小于0.001时认为射线和球体表面相交了
        if(d0<.001||d > maxDistance) break;
        d+=d0;
    }
    return d;
}

vec3 getNormal(vec3 p)
{
    float d=sdSphere(p);
    vec2 e=vec2(.001,.0);
    float fdx=d-sdSphere(p-e.xyy);
    float fdy=d-sdSphere(p-e.yxy);
    float fdz=d-sdSphere(p-e.yyx);
    return normalize(vec3(fdx,fdy,fdz));
}
// 构建绕y轴旋转的旋转矩阵
mat2 rot(float angle){
    float c= cos(angle);
    float s = sin(angle);
    return mat2(c,-s,s,c);
}
void mainImage(out vec4 fragColor,in vec2 fragCoord){
    // 将像素坐标标准化为 [-1, 1] 的范围
    vec2 uv=(fragCoord-iResolution.xy*.5)/iResolution.y;
    
    vec3 color=vec3(0.0);
    // 视点在z轴正方向上,渲染结果就是相机在该位置看到的结果
    vec3 cameraPosition=vec3(0.,0.,5.0);

    // 改变direction的z分量实际上相当于修改了fov的大小,fov越小,物体看起来越大(前提是其他参数不变)
    //vec3 direction=normalize(vec3(uv,-1.0));// fov是90°
    vec3 direction=normalize(vec3(uv,-2.0));// fov是53.13°

    
    float d=rayMarching(cameraPosition,direction);
    if(d<maxDistance){
        vec3 point=cameraPosition+d*direction;
        vec3 normal=getNormal(point);
        // 定义光源位置,在xoy坐标系的第一象限
        vec3 lightPosition=vec3(5.,5.,0.); 
        // 相机绕着y轴转
        lightPosition.xz*=rot(iTime);
        // 定义光源方向
        vec3 lightDir=normalize(lightPosition-point);
        
        // 漫反射系数
        float kd=1.;
        // 光源的强度
        float lightIntensity=1.;
        
        // 使用Lambert光照模型计算亮度
        // float intensity = kd * lightIntensity * (0.5*dot(normal, lightDir)+0.5);//半兰伯特模型
        float intensity=kd*lightIntensity*max(dot(normal,lightDir),0.);//兰伯特模型
        
        // 设置球体颜色
        color+=vec3(1.0, 0.5, 0.3)*intensity;
    }
    fragColor=vec4(color,1.0);
}

光线步进+兰伯特(gif经过压缩,质量有点不好)
光线步进+兰伯特(gif经过压缩,质量有点不好)
光线步进+半兰伯特(gif经过压缩,质量有点不好)
光线步进+半兰伯特(gif经过压缩,质量有点不好)

标签:point,direction,光线,兰伯特,float,片元,vec3,步进,着色器
From: https://blog.csdn.net/weixin_41364246/article/details/143362863

相关文章

  • Unity Shader深度图的应用,手把手教你写出可以正确计算并且渲染出二次元角色边缘光的着
    梦开始的地方相信大家看番的时候,都注意到了,很多时候,在角色周围有一圈光晕旧版《魔术快斗》剧照《新蔷薇少女》剧照 我们将这种光晕,称之为边缘光边缘光是描边的一种,动画师之所以加入边缘光,是为了凸现角色轮廓,使得角色区别于背景不少游戏也有着这种边缘光游戏《鸣潮》......
  • Artistic Oil Paint 艺术油画着色器插件
    只需轻轻一点,即可将您的视频游戏转化为艺术品!(也许更多…)。✓整个商店中最可配置的选项。✓六种先进算法。✓细节增强算法。✓完整的源代码(脚本和着色器)。✓包含在“艺术包”中。......
  • OpenGL ES 着色器(5)
    OpenGLES着色器(5)简述着色器是在GPU上运行的程序,它会对每一个点都执行一次程序,并且计算出每个像素需要渲染的颜色,我们主要关注着色器的怎么传递数据,在OpenGLES中,着色器传递数据分几种场景,一种是Cpu传递数据给GPU,一种是顶点缓冲区的数据传递到着色器,还有一种是顶点着色......
  • Winter Suite 冬季寒冷环境渲染着色器工具插件
    冬季套件为您提供了高质量渲染冬季或寒冷环境的钥匙。目前,已发布和正在制作的游戏都在使用冬季套装,该套装由多种产品组成,如具有先进动态特性的雪材料和霜冻相机效果。WebGL:1视频:1网络播放器:1|2特征:•动态覆盖和混合•渲染路径(正向和延迟)•高级BRDF着色控制......
  • QT+OpenGL从顶点着色器传递颜色数据给片元着色器
    一、概述目的:1.定义顶点数据和颜色数据,并将颜色数据通过顶点着色器传递给片元着色器2.对定义的三角形动态进行:平移、颠倒、镜像二、示例代码1.定义顶点坐标和颜色值。此处颜色和顶点是放到一块的。需要告知GPU如何解析数据,如:哪些是顶点,哪......
  • OpenGL ES->GLSurfaceView着色器程序中传递顶点数组和颜色数组绘制渐变三角形
    自定义View代码classMyGLSurfaceView(context:Context,attrs:AttributeSet):GLSurfaceView(context,attrs){init{//设置OpenGLES3.0版本setEGLContextClientVersion(3)//设置当前类为渲染器,注册回调接口的实现类......
  • 着色器(Shader)概念、功能、学习方法
    还是大剑师兰特:曾是美国某知名大学计算机专业研究生,现为航空航海领域高级前端工程师;CSDN知名博主,GIS领域优质创作者,深耕openlayers、leaflet、mapbox、cesium,canvas,webgl,echarts等技术开发,欢迎加底部微信(gis-dajianshi),一起交流。No.内容链接1Openlayers【入门教程】-......
  • 几何着色器 Geometry Shader
    参考: 【UnityShader入门】4、几何着色器GeometryShaders之结构解析_shader编译目标级别-CSDN博客GeometryShader(Unity几何着色器)_unitygeometryshader-CSDN博客Unity几何着色器详解-知乎(zhihu.com) /*[maxvertexcount(N)]:用来指定几何着色器单次调用所输出......
  • WebGL:使用着色器进行几何造型
    前言本文将介绍如何使用着色器来进行几何造型,说到几何图形大家一定都不陌生,比如说三角形、圆形,接触过WebGL基础使用的小伙伴一定都知道怎么去在画布上绘制一个三角形,只要传入三个顶点坐标,并选择绘图模式,我们就能在WebGL的画布上画出一个三角形。但是除了这种形式之外,我们还可以......
  • 第三个OpenGL程序,shaders _ 后续 之 封装着色器类
    着色器类:头文件h:#ifndefSHADER_H#defineSHADER_H#include<GLAD/glad.h>#include<glfw3.h>#include<string>#include<fstream>#include<sstream>#include<iostream>classShader{public://程序IDunsignedint......