SSAO shader

2024-02-22 01:44
文章标签 shader ssao

本文主要是介绍SSAO shader,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

#version 330 core
out float FragColor;
in vec2 TexCoords;uniform sampler2D gPositionDepth;	// view空间中的pos
uniform sampler2D gNormal;			// view空间中的normal
uniform sampler2D texNoise;			// noise是4x4的随机旋转向量纹理uniform vec3 samples[64];// parameters (you'd probably want to use them as uniforms to more easily tweak the effect)
int kernelSize = 64;
float radius = 1.0;// tile noise texture over screen based on screen dimensions divided by noise size
const vec2 noiseScale = vec2(800.0f/4.0f, 600.0f/4.0f); uniform mat4 projection;void main()
{// Get input for SSAO algorithmvec3 fragPos = texture(gPositionDepth, TexCoords).xyz;vec3 normal = texture(gNormal, TexCoords).rgb;vec3 randomVec = texture(texNoise, TexCoords * noiseScale).xyz;// Create TBN change-of-basis matrix: from tangent-space to view-space// 因为这里的normal是view space中的,因此算出来的TBN矩阵是从切线空间->视图空间vec3 tangent = normalize(randomVec - normal * dot(randomVec, normal));vec3 bitangent = cross(normal, tangent);mat3 TBN = mat3(tangent, bitangent, normal);// Iterate over the sample kernel and calculate occlusion factorfloat occlusion = 0.0;for(int i = 0; i < kernelSize; ++i){// get sample positionvec3 sample = TBN * samples[i]; // From tangent to view-spacesample = fragPos + sample * radius; // 把视图空间中的采样点位置坐标投影到屏幕上,得到他在屏幕空间中的坐标vec4 offset = vec4(sample, 1.0);offset = projection * offset; // from view to clip-spaceoffset.xyz /= offset.w; // perspective divideoffset.xyz = offset.xyz * 0.5 + 0.5; // transform to range 0.0 - 1.0// 获取采样点所位于的像素位置上的深度值float sampleDepth = -texture(gPositionDepth, offset.xy).w; // Get depth value of kernel sample// range check & accumulatefloat rangeCheck = smoothstep(0.0, 1.0, radius / abs(fragPos.z - sampleDepth ));occlusion += (sampleDepth >= sample.z ? 1.0 : 0.0) * rangeCheck;           }occlusion = 1.0 - (occlusion / kernelSize);FragColor = occlusion;
}

在 SSAO 算法中,我们生成了若干个随机采样点,比如上面的64个samples,虽然这些samples是随机的,但是却每个像素都相同,这样效果并不好,因此可以通过引入随机旋转向量,使每个像素在计算时,把采样点们绕着法线旋转随机角度来引入一些随机性。这里的随机旋转向量是用4x4的纹理来存放的(texNoise,4x4的纹理 16个随机旋转向量基本够用,弄个800x600的全部都是随机的旋转向量没必要,代价太大,效果提升很小。 ),并传入ssao过程的shader中。这些随机旋转向量通常是在切线空间中定义的,每个像素在计算时都从noise纹理中采样一个随机旋转向量randomVec并且用它跟视图空间中的normal来构造一个切线空间,计算获得TBN矩阵,然后每个像素采样得到的旋转向量是不同的 因此TBN是不太一样的。这样,在把samples 转换到 视图空间的时候,分布就会不太一样。

TBN矩阵:我们平常来说是通过模型的模型空间中的normal跟模型空间的顶点坐标、纹理坐标计算得到的Trangent向量来生成的TBN矩阵,这个TBN矩阵是把切线空间中的向量转到模型空间的。而在SSAO里,构造的这个TBN矩阵是用的view空间的normal和view空间的一个垂直于法线的向量来构造的,因此该TBN矩阵作用是实现切线空间到view空间的转换

这篇关于SSAO shader的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/733759

相关文章

Unity3D Shader详解:只画顶点或只画线框

在Unity3D开发中,Shader是控制渲染过程的关键组件,它允许开发者自定义物体的渲染方式。有时,为了特定的视觉效果,我们可能需要只渲染模型的顶点或者只显示其线框。下面,我们将详细探讨这两种效果的技术实现,并给出相应的代码示例。 对惹,这里有一个游戏开发交流小组,大家可以点击进来一起交流一下开发经验呀! 只画顶点 在Unity中直接“只画顶点”的概念可能不是非常直观,因为顶点本身只是模型

unity shader实现一个移动的箭头

Shader "Unlit/LT_Arrow" {     Properties     {         _MainTex ("Texture", 2D) = "white" {}         _MSpeed("MoveSpeed", Range(1, 3)) = 2 //移动速度     }     SubShader     {         //贴图带透明通道 ,半透明效果设置如下

Shader学习笔记

1. 渲染管线概述 定义:渲染管线(流水线)就是将数据分阶段的变为屏幕图像的过程 数据就是我们在游戏场景中放置的模型、光源、摄像机等等内容的数据 阶段就是渲染管线中的三个阶段:应用阶段一>几何阶段一>光栅化阶段 通过这三个阶段对数据的处理,最终我们就能够在屏幕上看见最终的图像 2. 应用阶段 应用阶段的大部分内容都和渲染无关(游戏逻辑处理、动画更新、物理模拟)几何阶段和光栅化阶段将开始处理

Shader,想说爱你不容易。

这两天开始接触shader,给我的第一感觉是容易,第二感觉是难,第三赶脚是数学不好就先学数学吧! 首先我们通过unity自己创建一个shader脚本的时候,其实shader已经给我们搭建好了编写shader基本的框架,我们要做的就是往里面写自己的shader,但是写之前总的先认识这里面有啥子东西吧。先创建一个shader瞅瞅,我使用的unity的版本为5.x,代码如下: Shader

UE【材质编辑】Shader模板

【UE 4.27.2】         在UE中双击材质球会进入材质编辑界面。PBR的材质参数呈现为材质蓝图的各个节点,提供数据源,传递进材质。最后材质对其进行组织,呈现为VS,PS等着色器代码,基本流程: 本文会刨析在UE4.27.2中材质模板是如何应用的。 1.认识编辑器中的材质         打开任意材质球,双击进入材质编辑面板: 此界面形象展示了材质参数传递到材质(实例

【Unity Shader】Unity提供的CG/HLSL语义

主要参考《Unity Shader入门精要》一书,外加自己的一些总结 什么是语义 语义实际就是一个赋给Shader输入和输出的字符串,这个字符串表达了这个参数的含义。这些语义可以让Shader知道从哪里读取数据,并把数据输到哪里。 在DirectX10以后,有了一种新的语义类型,即系统数值语义(system-value semantics)。这类语义是以SV

Shader笔记:光照与阴影1

引:旋转动画(三角函数) float3 rotationY(float3 vertex){float c = cos(_Time.y*_Speed);float s = sin(_Time.y*_Speed);float3x3 m = {c,0,s,0,1,0,-s,0,c};return mul(m,vertex);}v2f vert (a2v v){v2f o;o.pos = Unit

Shader 透明相关

1、设置深度写入与渲染队列 深度写入 深度写入默认是开启,需要通过渲染状态中的 ZWrite off 指令主动关闭深度写入 当我们把它写在Pass渲染通道中时,它只会影响该Pass 若我们把它写在SubShader语句块中,它将影响其中的所有Pass 渲染队列 通过渲染标签主动的设置物体的渲染顺序Tags{ "Queue" = "标签值" } 1.Background(背景)(队列号:1

Unity URP Shader 修改深度让人物不再被地面遮挡

Unity URP Shader 修改深度让人物不再被地面遮挡 前言项目场景布置代码编写 前言 遇到一个小问题,人物总是被XY平面的地面遮挡,于是在Shader中改一下深度输出,这样地面再也不会挡住人物了。 项目 场景布置 将人物放到XY平面的后面 配置Shader参数 代码编写 Shader "Unlit/DepTest"{Properties{[Main

CocosCreator Shader学习(五):图片圆形裁剪

圆形裁剪效果 顶点着色器代码不用修改。 片元着色器代码如下: CCProgram fs %{precision highp float;#include <alpha-test>#include <texture>in vec4 v_color;#if USE_TEXTUREin vec2 v_uv0;uniform sampler2D texture;#endifuniform Input