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,分析目标游戏阴影实现的主要内容,如果未能解决你的问题,请参考以下文章

RenderDoc[03] 还原粒子特效shader

RenderDoc[03] 还原粒子特效shader

如何让 android 项目的 shader 可以被 RenderDoc 调试

如何让 android 项目的 shader 可以被 RenderDoc 调试

OpenGLES以及shader开发调试工具

OpenGLES以及shader开发调试工具