[自研引擎]GAMES104 实现一个渲染功能

前言

1.在Piccolo小引擎代码中找到Piccolo/engine/shader/glsl/color_grading.frag,补充此shader代码中的main函数,以实现ColorGrading功能。若代码编译成功且实现方法正确,则可以看到进行ColorGrading渲染之后的结果

2.使用自定义的LUT图,并修改相应代码,实现具有个性的ColorGrading的效果

一、实现一个渲染功能

在此之前,我们可以先看一丢丢基础知识

用户LUT是一种简单的颜色分级方法:将屏幕上的像素替换为您提供的LUT中的新值,本质上只是一个原颜色到新颜色的映射,效果类似与滤镜

思路是以原颜色的RGB值为坐标,采样一张纹理,得到新颜色,这张纹理叫做LUT(Lookup Table),LUT的示例如下:

LUT可视作一组方形纹理的横向拼凑,其保存颜色数据的结构可以这样理解:

可以看出上面这个长条状图形的每一个小正方形的B值是不变的,放大后为上图下半部分所示

R:每个方形纹理内,R值在水平往右的方向上由0-1递增

G:每个方形纹理内,G值在竖直往下的方向上由0-1递增

B:每个方形纹理内,B值不变;B值对于横向拼凑的一组方形纹理而言,从左往右由0-1递增,如上图的上半部分一样,蓝色逐渐加深

也可以将一组方形纹理想象成在空间中竖直叠加起来(可以看本文章第一张图),那么原RGB值可以作为三维坐标,映射到LUT中保存的颜色数据上,这样一张LUT图便代表一套颜色的对应关系

需要注意的是,由于原颜色RGB值为连续的,在对LUT采样时,不会完美的映射到单一纹素上,需要采样相邻的纹素并做线性插值,特别对于B值而言,需要在两个方形纹理内采样(这就是下面代码最后三行的意义,采样两次,再做线性混合)

代码都有详细的注释  对可能会用到的函数有如下总结:

若不对代码做任何改变,将输入颜色直接作为输出颜色,效果图如下:

#version 310 es

#extension GL_GOOGLE_include_directive : enable

#include "constants.h"

layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp subpassInput in_color;

layout(set = 0, binding = 1) uniform sampler2D color_grading_lut_texture_sampler;

layout(location = 0) out highp vec4 out_color;

void main()
{
    highp ivec2 lut_tex_size = textureSize(color_grading_lut_texture_sampler, 0);
    highp float _COLORS      = float(lut_tex_size.y);

    highp vec4 color       = subpassLoad(in_color).rgba;
    
    // texture(color_grading_lut_texture_sampler, uv)

    out_color = color;
}

 

亲自实现一个渲染功能,做出一些改变:

#version 310 es

#extension GL_GOOGLE_include_directive : enable

#include "constants.h"

//像素的原颜色 in_color
layout(input_attachment_index = 0, set = 0, binding = 0) uniform highp subpassInput in_color;

//2D贴图采样器   lut
layout(set = 0, binding = 1) uniform sampler2D color_grading_lut_texture_sampler;
//最终输出的颜色
layout(location = 0) out highp vec4 out_color;

void main()
{
    //获得2D贴图的大小 是一个二维向量
    highp ivec2 lut_tex_size = textureSize(color_grading_lut_texture_sampler, 0);
    //将y值作为一个常数
    highp float _COLORS      = float(lut_tex_size.y);
    
    //获取in_color的值
    highp vec4 color       = subpassLoad(in_color).rgba;
    
    // texture(color_grading_lut_texture_sampler, uv)

    //out_color = color;
    //color.b 乘以 高度
    //将输入颜色的蓝色通道值乘以一个常数 _COLORS,得到一个新的浮点数 b
    highp float b = color.b * _COLORS;
    //将浮点数 b 向下取整,得到一个新的浮点数 b_floor  用于后续采样
    highp float b_floor = floor(b);
    //将浮点数 b 向上取整,得到一个新的浮点数 b_ceil   用于后续采样
    highp float b_ceil = ceil(b);
    //从颜色分级查找表纹理中获取相应的颜色 
    //需要在两个方形内进行采样
    highp vec4 color_floor = texture(color_grading_lut_texture_sampler, vec2((b_floor + color.r) / _COLORS, color.g));
    highp vec4 color_ceil = texture(color_grading_lut_texture_sampler, vec2((b_ceil + color.r) / _COLORS, color.g));
    //进行线性插值
    //out_color = mix(color_floor, color_ceil, b - b_floor);
    out_color = mix(color_floor, color_ceil, b_ceil - b);
}

是不是立马就有了提升画面表现的感觉!

二、自定义的LUT

小引擎预先提供了7张LUT图(在engine/asset/texture/lut下查看),我们可以先试一下效果!只需要修改engine/asset/global/rendering.global.json中的资源路径,如:

我们随便选一张,修改为上述的jpg图片,效果为:

是不是有点缤纷且傍晚的感觉!

下来我们可以试一试自定义的LUT图,这里我以my_lut为例

效果如下:

是不是有了夜景的感觉!至此,我们的目的就达到啦

  • 9
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 5
    评论
评论 5
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值