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);
}

最终效果:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值