当前位置: 首页 > article >正文

Learn ComputeShader 09 Night version lenses

这次将要制作一个类似夜视仪的效果

第一步就是要降低图像的分辨率, 这只需要将id.xy除上一个数字然后再乘上这个数字

可以根据下图理解,很明显通过这个操作在多个像素显示了相同的颜色,并且很多像素颜色被丢失了,自然就会有降低分辨率的效果

效果:

但是这样图像太锐利了,我们加入噪声去解决这个问题

[numthreads(8, 8, 1)]
void CSMain(uint3 id : SV_DispatchThreadID)
{
    uint2 index =(uint2(id.x,id.y)/3*3);
    float noise =random((float2)id.xy,time);

    float3 srcColor =lerp(source[index].rgb*2,source[index].rgb,noise);
    float3 finalColor = srcColor;
           
    output[id.xy] = float4(finalColor, 1);
}

这样以后得到的结果就更接近低分辨率相机的效果 

夜视仪通常都是绿色的,我们首先计算出灰度值,然后用灰度值乘上我们设置的一个类似夜视仪的绿色,灰度值越大颜色就越接近我们设置的颜色,反之越接近黑色。最后再将这个颜色与原始颜色根据强度进行插值,

夜视仪上通常有滚动的扫描线。

我们首先将像素的y坐标转换到0-1的范围内,然后生成一个周期性的值模仿扫描线的循环,然后加上0.3避免扫描线的强度过大,最后将它限制在0-1范围内

[numthreads(8, 8, 1)]
void CSMain(uint3 id : SV_DispatchThreadID)
{
    uint2 index =(uint2(id.x,id.y)/3*3);
    float noise =random((float2)id.xy,time);

    float3 srcColor =lerp(source[index].rgb*2,source[index].rgb,noise);


    float3 grayScale = (srcColor.r + srcColor.g + srcColor.b) / 3.0;
    float3 tinted = grayScale * tintColor.rgb;
    float3 finalColor = lerp(srcColor,tinted, tintStrength);

    float uvY = (float)id.y/ (float)source.Length.y;
    float scanline = saturate(smoothstep(0.1,0.2, frac(uvY*lines + time*3)) +0.3);
    finalColor = lerp(source[id.xy].rgb*0.5,finalColor,scanline);

           
    output[id.xy] = float4(finalColor, 1);
}

 效果:

最后就是制作夜视仪的望远镜的效果 。主要原理可参照下面的图片

[numthreads(8, 8, 1)]
void CSMain(uint3 id : SV_DispatchThreadID)
{
    uint2 index =(uint2(id.x,id.y)/3*3);
    float noise =random((float2)id.xy,time);


    float3 srcColor =lerp(source[index].rgb*2,source[index].rgb,noise);


    float3 grayScale = (srcColor.r + srcColor.g + srcColor.b) / 3.0;
    float3 tinted = grayScale * tintColor.rgb;
    float3 finalColor = lerp(srcColor,tinted, tintStrength);

    float uvY = (float)id.y/ (float)source.Length.y;
    //float scanline = saturate(smoothstep(0.1,0.2, frac(uvY*5+time*3)) +0.3);
    float scanline =  frac(uvY*2);
    finalColor = lerp(source[id.xy].rgb*0.5,finalColor,scanline);

    float2 pt = (float2)id.xy;
    float2 center = float2(source.Length * 0.5);
    center.x -= radius * 0.7;
    float leftLense = incircle(pt, center, radius, edgewidth);

    center.x += radius * 1.4;
    float rightLense = incircle(pt, center, radius, edgewidth);

    float inVision = saturate(leftLense + rightLense);

    float3 black = float3(0, 0, 0);
    finalColor = lerp(black, finalColor, inVision);
          
    output[id.xy] = float4(finalColor, 1);
}

最终效果:


http://www.kler.cn/news/294523.html

相关文章:

  • 如何使用Prometheus与Grafana监控Kubernetes集群
  • 图论基础1
  • 重启顺风车的背后,是高德难掩的“野心”
  • 高分辨率音频和传统音频区别
  • 学习笔记--Docker
  • 【机器学习】朴素贝叶斯网络的基本概念以及朴素贝叶斯网络在python中的实例
  • 【SpringBoot】使用Nacos服务注册发现与配置管理
  • 主板选购2
  • 【C/C++】Linux\Windows为什么频繁使用size_t
  • 服务器蓝屏该怎么办
  • Vue3 父子传参 简单易懂
  • Mybatis Plus快速重构真批量sql入库操作
  • PLC+AIoTedge边缘物联网平台能否替代 PLC+Wincc?
  • 13. 说说 MyBatis 的缓存机制?
  • MySQL 数据库管理与操作指南
  • 自定义view中常用到哪些方法作用分别是什么
  • 专栏前言-WooYun漏洞库环境搭建
  • Java详解String 字符串类以及String内存原理、StringBuilder类、StringJoiner类(附有代码+案例)
  • MASt3R:从3D的角度来实现图像匹配(更新中)
  • 前端工程化2:从0-1的eslint插件开发教程
  • 基于Prometheus 和K8S kubernetes 构建 搭建监控告警系统
  • 单点登录:cas单点登录实现原理浅析
  • 【Vue】状态管理模式Vuex
  • 通信工程学习:什么是AM标准调幅
  • [情商-13]:语言的艺术:何为真实和真相,所谓真相,就是别人想让你知道的真相!洞察谎言与真相!
  • Redis在登录接口中实现token时间的自适应增长
  • mysql5.6根据经纬度查询距离
  • 亚马逊测评深度解析:如何安全高效提升产品销量和好评
  • HTB-Pennyworth(cve查询 和 exp使用)
  • 《征服数据结构》差分数组