RenderDoc[02] 修改Shader,分析目标游戏阴影实现
Posted _Captain
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了RenderDoc[02] 修改Shader,分析目标游戏阴影实现相关的知识,希望对你有一定的参考价值。
1.背景
继上一篇分析了目标游戏的一些实现后,在这几天的游玩中,我注意到游戏的阴影比较特殊 --物体之间没有遮挡产生阴影,阴影只显示在最底层背景之上。
我的猜想:用深度贴图和背景图做混合。
具体是怎样,来分析看看。本文转自https://huutu.blog.csdn.net/article/details/111872392
2.目标
借助RenderDoc的Shader分析修改功能,来分析目标游戏阴影实现。
3.RenderDoc查看Shader
在RenderDoc中截取一帧,这个操作,其实RenderDoc就把当前一帧所有命令都记录下来了,包括输入输出。
在RenderDoc中查看一个Event,其实就是在重放。
既然是重放,那么所有的输入,都可以进行修改。
RenderDoc也确实提供了修改的功能。
这一篇介绍RenderDoc中,Shader代码实时修改的功能。
打开RenderDoc,载入之前保存的数据,定位到绘制阴影的Event。
切换到 Pipeline State选项卡,选择FS 片段shader。
点击Edit 可以对片段Shader进行编辑。
本文转自https://huutu.blog.csdn.net/article/details/111872392
可以把选项卡拖出来放一边,这样修改后方便看效果。
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编辑界面。本文转自https://huutu.blog.csdn.net/article/details/111872392
代码如下:
#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和矩阵相乘?百度了一下,还真是。本文转自https://huutu.blog.csdn.net/article/details/111872392
那么可以将代码简化:
简化之后发现,其实做的就是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
以上是关于RenderDoc[02] 修改Shader,分析目标游戏阴影实现的主要内容,如果未能解决你的问题,请参考以下文章
如何让 android 项目的 shader 可以被 RenderDoc 调试