{sqrt(2.0 / 3.0), 0.0, 1.0 / sqrt(3.0)}, {-1.0 / sqrt(6.0), -1.0 / sqrt(2.0), 1.0 / sqrt(3.0)}, {-1.0 / sqrt(6.0), 1.0 / sqrt(2.0), 1.0 / sqrt(3.0)}, struct PS_INPUT float2 Texcoord0 : TEXCOORD0; float3 Texcoord1 : TEXCOORD1; float4 ps_main( PS_INPUT Input ) : COLOR0 float3 normal = normalize((tex2D(normalMap, Input.Texcoord0).xyz * 2.0f) - 1.0f ); normal.y = -normal.y; float3 dp; dp.x = saturate(dot(normal, bumpBasis[0])); dp.y = saturate(dot(normal, bumpBasis[1])); dp.z = saturate(dot(normal, bumpBasis[2])); dp *= dp; float sum = dot(dp, float3(1.0, 1.0, 1.0)); dp *= 2.0; Input.Texcoord1 *= fUvScale; float3 diffuseLighting = dp.x * tex2D(lightMap1, Input.Texcoord1) + dp.y * tex2D(lightMap2, Input.Texcoord1) + dp.z * tex2D(lightMap3, Input.Texcoord1); diffuseLighting /= sum; float4 diffuse = tex2D(diffuseMap, Input.Texcoord0); diffuse.xyz = diffuseLighting; return diffuse;

效果在这里面是正确的. 然后转到引擎里发现竟然变成这样了:

检查了贴图没问题, 那么只可能是bumpBasis的问题了. 把下面的引用换成float3(...)这种写死的表达式, 果然效果正确了:


要说环境有什么不同, 引擎里是写在.fx文件里的. 难道编译的时候被当成了外部传入的参数? 查了一下HLSL的说明, 发现有个修饰词:

static Mark a local variable so that it is initialized one time and persists between function calls. If the declaration does not include an initializer, the value is set to zero. A global variable marked static is not visible to an application.

把const float3 bumpBasis[3]改成static const float3 bumpBasis[3], 果然问题没有了!

问题又来了, 为啥在RM里就是好的....而且以前我自己写类似功能时候也没有加static啊-_-

在RenderMonkey里写了RNM的demo: float fUvScale;sampler2D diffuseMap;sampler2D normalMap;sampler2D lightMap1;sampler2D lightMap2;sampler2D lightMap3;const float3 bumpBasis[3] ={ {sqrt(2.0 / 3.0), 0.0, 1.0 / sqrt(3.0)}, {-1.0 / sqrt(6.0
1、 由于实时对战游戏的数据包数量巨大,早期版本的帧同步策略会导致比较明显的卡顿,通过进行数据包的合并与优化逐渐解决了卡顿 问题 ; 2、 频繁创建和销毁的小兵对象让CPU爆表了,大量的小兵如果采用实时内存的分配和回收,会产生大量的内存碎片和系统开销,解决方法之一就是采用高效的对象池进行优化,对每个内存对象的状态进行操作即可; 3、 性能分析过程中,发现单人同屏和多人同屏时的开销都很大,通过
本篇主要讲的是计算机图形学中比较重要的主题之一,渲染,并且着重于讲述光栅化的渲染方式。 当然,我们要了解光栅渲染这个细分领域(当然这个领域也是及其庞大的),就应该知道它在整个的知识框架中是出于 一个 什么位置。 古希腊的哲学家亚里士多德曾说过,了解 一个 事物的最佳方式,就是不断的把它进行分类,当分无可分的时候,你就能准确的理解这个事物了。 我们要了解光栅渲染,其实先要理解什么是渲染。...
Unity Shader(Cg/ HLSL 中的数据类型) 在Shader中,我们在Properties中 定义 的变量是为了在材质面板中显示并方便我们调节,如果要在Cg/ HLSL 中使用的话就必须要重新声明一次(要求命名一致)。 Cg/ HLSL 中的数据类型 float 高精度类型,32位,通常用于世界坐标下的位置,纹理UV,或涉及复杂函数的标量计算,如三角函数、幂运算等。 中精度类型,16位,数值范围为[-60000,+60000],通常用于本地坐标下的位置、方向向量、HDR颜色等。 fixed
1.1标量类型 1. bool: True or false .Note that the HLSL provides the true and false keywordslike in C++. 2. int: 32-bit signedinteger. 3. half: 16-bit- float ingpoint number. 4. float : 32-bit- float ingpoint number. 5. double: 64-bit- float ingpo...
最近在利用HLS实现卷积计算,仿真阶段计算结果出现了一点 问题 ,计算结果只是无序间隔出错,而不是连续的一块数据出错,检查代码后,发现并没有语法错误或者 数组 index错误,算法上也不存在 问题 。 在对比以前在VS上写的卷积代码后发现了 一个 不容易察觉的 问题 数组 初始化 以下是在VS上 定义 一个 数组 并初始化的代码: int main() int arr[4][4] = {0}; return 0; 通过这个方式,VS编译器会自动对未初始化的 数组 元素进行0初始化。 然而,在vivado HLS利用上述方式初
编写本内容仅仅是为了完善当前的教程体系,入门级别的内容其实基本上都是千篇一律,仅有一些必要细节上的扩充。要入门 HLSL ,只是掌握入门语法,即便把 HLSL 的全部语法也吃透了也并不代表你就能着色器代码了,还需要结合到渲染管线中,随着教程的不断深入来不断学习需要用到的新的语法,然后尝试修改着色器,再根据实际需求自己编写着色器来实现特定的效果。 注意:在翻阅 HLSL 文档的时候,要避开Effects... // Convert normal map to world space normal = mul(normal, ( float 3x3) input .tangentToWorld); // Calculate PBR float 4 pbr = CalculatePBR(albedo, normal, metallic, roughness, ao); return pbr;