vue视频教程 字节跳动 Hadoop node.js 线程 PaddleHub ASP.NET Core bam loops junit shiny casting 百度seo关键词 js鼠标离开事件 eclipse闪退 sallenkey滤波器 html好看的字体 bootstrap滚动条 vue与html5 python课程 java读取文件内容 java面向对象 java基础框架 java八种基本数据类型 java读取文件 java数组排序 怎么安装linux系统 图吧导航怎么样 无法打开搜索页 8元秒电脑 梦幻手游助手 手工画像 windows游戏编程 qq制作网页 黑道圣徒4去马赛克 安卓游戏辅助 苹果8怎么截屏 edius调色 ps平面设计基础教程 繁简体在线转换
当前位置: 首页 > 学习教程  > 编程语言

RenderDoc[02] 修改Shader,分析目标游戏阴影实现

2020/12/28 18:43:50 文章标签:

1.背景 继上一篇分析了目标游戏的一些实现后,在这几天的游玩中,我注意到游戏的阴影比较特殊 --物体之间没有遮挡产生阴影,阴影只显示在最底层背景之上。 我的猜想:用深度贴图和背景图做混合。 具体是怎样,来分析看看…

1.背景

继上一篇分析了目标游戏的一些实现后,在这几天的游玩中,我注意到游戏的阴影比较特殊 --物体之间没有遮挡产生阴影,阴影只显示在最底层背景之上。
在这里插入图片描述我的猜想:用深度贴图和背景图做混合。

具体是怎样,来分析看看。

2.目标

借助RenderDoc的Shader分析修改功能,来分析目标游戏阴影实现。

3.RenderDoc查看Shader

在RenderDoc中截取一帧,这个操作,其实RenderDoc就把当前一帧所有命令都记录下来了,包括输入输出。
在RenderDoc中查看一个Event,其实就是在重放。
既然是重放,那么所有的输入,都可以进行修改。
RenderDoc也确实提供了修改的功能。

这一篇介绍RenderDoc中,Shader代码实时修改的功能。

打开RenderDoc,载入之前保存的数据,定位到绘制阴影的Event。
在这里插入图片描述切换到 Pipeline State选项卡,选择FS 片段shader。

在这里插入图片描述点击Edit 可以对片段Shader进行编辑。
在这里插入图片描述

可以把选项卡拖出来放一边,这样修改后方便看效果。

4.RenderDoc修改Shader

片段shader代码很简单,就是指定阴影颜色 和 alpha值做乘法的过程。

#version 300 es

precision highp float;
precision highp int;
uniform 	mediump vec4 _ShadowColor;
uniform 	mediump float _Alpha;
layout(location = 0) out highp vec4 SV_Target0;
mediump vec4 u_xlat16_0;
void main()
{
    u_xlat16_0.w = _ShadowColor.w * _Alpha;
    u_xlat16_0.xyz = _ShadowColor.xyz;
    SV_Target0 = u_xlat16_0;
    return;
}

从最后输出的画面看,阴影颜色就是黑色了。

这里将颜色修改为红色。(按下图步骤)

在这里插入图片描述
代码如下:

#version 300 es

precision highp float;
precision highp int;
uniform 	mediump vec4 _ShadowColor;
uniform 	mediump float _Alpha;
layout(location = 0) out highp vec4 SV_Target0;
mediump vec4 u_xlat16_0;
void main()
{
    u_xlat16_0.w = _ShadowColor.w * _Alpha;
    //u_xlat16_0.xyz = _ShadowColor.xyz;
	u_xlat16_0 = vec4(1.0,0.0,0.0,1.0); //修改阴影颜色为红色。
    SV_Target0 = u_xlat16_0;
    return;
}

显然,目标游戏阴影的实现重点,不在片段Shader中。

5.分析目标游戏阴影的实现

不在片段Shader,那就只在顶点Shader。

打开顶点Shader编辑界面。

在这里插入图片描述
代码如下:

#version 300 es

uniform 	vec4 hlslcc_mtx4x4unity_ObjectToWorld[4];
uniform 	vec4 hlslcc_mtx4x4unity_MatrixVP[4];
uniform 	mediump vec4 _ShadowOffset;
uniform 	mediump vec4 _ShadowOffsetSign;
in highp vec4 in_POSITION0;
vec4 u_xlat0;
vec4 u_xlat1;
void main()
{
    u_xlat0 = in_POSITION0.yyyy * hlslcc_mtx4x4unity_ObjectToWorld[1];
    u_xlat0 = hlslcc_mtx4x4unity_ObjectToWorld[0] * in_POSITION0.xxxx + u_xlat0;
    u_xlat0 = hlslcc_mtx4x4unity_ObjectToWorld[2] * in_POSITION0.zzzz + u_xlat0;
    u_xlat0 = hlslcc_mtx4x4unity_ObjectToWorld[3] * in_POSITION0.wwww + u_xlat0;
    u_xlat0 = _ShadowOffset * _ShadowOffsetSign + u_xlat0;
    u_xlat1 = u_xlat0.yyyy * hlslcc_mtx4x4unity_MatrixVP[1];
    u_xlat1 = hlslcc_mtx4x4unity_MatrixVP[0] * u_xlat0.xxxx + u_xlat1;
    u_xlat1 = hlslcc_mtx4x4unity_MatrixVP[2] * u_xlat0.zzzz + u_xlat1;
    gl_Position = hlslcc_mtx4x4unity_MatrixVP[3] * u_xlat0.wwww + u_xlat1;
    return;
}

第一眼看到这一堆的代码,感觉要疯了。
为了有个好心情,打开了专业点的 Shader编辑器 – PVRShaderEditor。

GameDevTools已经集成PVRShaderEditor,搜索shader即可下载运行。
GameDevTools是一套游戏开发常用工具集,输入关键词即可找到想要的工具。
目前托管在Github:https://github.com/ThisisGame/GameDevTools

在这里插入图片描述
在这里插入图片描述
还是很乱,整理一下

在这里插入图片描述
现在再看,这代码有点眼熟。每次都是Vec4的元素 和 mat4x4的一行进行相乘,然后相加。
这难道是vec4和矩阵相乘?百度了一下,还真是。

那么可以将代码简化:
在这里插入图片描述
简化之后发现,其实做的就是mvp变换,只不过vp是光源位置的摄像机参数。

简化后的代码,编译报错,提示不支持 vec4*mat4x4 运算。这也就是为什么会有好几行代码,都是在做展开。

6.总结

分析总结,目标游戏的阴影实现方式就是用光源位置的摄像机再渲染一次。

相关参考:
1.shadowmap原理:https://huutu.blog.csdn.net/article/details/81125221
2.矩阵乘法:https://www.cnblogs.com/yibeimingyue/p/9924698.html
3.unity shader内置矩阵:https://www.cnblogs.com/guilt/p/4859538.html


本文链接: http://www.dtmao.cc/news_show_550098.shtml

附件下载

相关教程

    暂无相关的数据...

共有条评论 网友评论

验证码: 看不清楚?