我正在尝试学习Shaders在我的iPhone应用程序中实现一些东西.到目前为止,我已经理解了简单的例子,例如将彩色图像制作成灰度,阈值等.大多数示例涉及简单的操作,其中处理输入图像像素I(x,y)导致对同一像素的颜色的简单修改
但是,Convolutions怎么样?例如,最简单的例子是高斯滤波器,
其中输出图像像素O(x,y)不仅取决于I(x,y)周围的8个像素,还取决于周围的8个像素
O(x,y) = (I(x,y)+ surrounding 8 pixels values)/9;
Run Code Online (Sandbox Code Playgroud)
通常,使用单个图像缓冲区无法完成此操作,或者输入像素将随执行滤镜而更改.如何使用着色器执行此操作?另外,我应该自己处理边框吗?或者有一个内置函数或检查无效像素访问的东西,如 I(-1,-1)?
提前致谢
PS:我会很慷慨(阅读:给出很多观点);)
在构建我的类看起来像这样的游戏引擎时,我一直在遇到这个问题:
interface Entity {
draw();
}
class World {
draw() {
for (e in entities)
e.draw();
}
}
Run Code Online (Sandbox Code Playgroud)
这只是伪代码,大致显示绘图是如何发生的.每个实体子类都实现自己的绘图.世界以无特定顺序循环遍历所有实体,并告诉他们逐个绘制自己.
但是使用基于着色器的图形,这往往是非常低效或甚至是不可行的.每个实体类型可能都有自己的着色器程序.为了最小化程序更改,需要将每种特定类型的所有实体绘制在一起.简单类型的实体(如粒子)也可能希望以其他方式聚合其绘图,例如共享一个大的顶点数组.并且它通过混合变得非常毛茸茸,并且某些实体类型需要在某些时间相对于其他实体类型呈现,或者甚至在不同时间通过多次实现.
我通常最终得到的是每个实体类的某种渲染器单例,它保存所有实例的列表并一次性绘制它们.这并不是那么糟糕,因为它将绘图与游戏逻辑分开.但是渲染器需要确定要绘制的实体子集,并且需要访问图形管道的多个不同部分.这是我的对象模型往往变得混乱,有许多重复的代码,紧密耦合和其他坏事.
所以我的问题是:这种高效,多功能,模块化的游戏绘图的优秀架构是什么?
从我的主要问题开始:
我可以在FireMonkey应用程序中使用像素着色器模型3,4或5吗?
我希望能够在我的FireMonkey程序中动态创建像素着色器.为此,我现在使用DirectX SDK附带的fxc.exe编译像素着色器,并将编译后的代码加载到我的TShaderFilter后代中.这很好(如果你对我的表现感兴趣,请告诉我).
但是,如果我ps_2_0作为目标配置文件进行编译,我只能让事情发挥作用.
我目前正在遇到着色器模型2.0的限制.例如,循环似乎是由编译器展开的,并且在2级着色器中可以有最大数量的指令.因此,可能性的数量非常有限.
示例:
下面的着色器代码创建了一个mandelbrot分形.如果我设置Iterations得太高,它就不会编译.错误信息:
error X5608: Compiled shader code uses too many arithmetic instruction slots (78). Max. allowed by the target (ps_2_0) is 64.
#define Iterations 12
float2 Pan;
float Zoom;
float Aspect;
float4 main(float2 texCoord : TEXCOORD0) : COLOR0
{
float2 c = (texCoord - 0.5) * Zoom * float2(1, Aspect) - Pan;
float2 v = 0;
for (int n = 0; n < Iterations; n++)
{
v = float2(v.x * …Run Code Online (Sandbox Code Playgroud) 如何在Three.js着色器上启用扩展?
我的代码到目前为止:
获得扩展:
var domElement = document.createElement( 'canvas' );
var gl = domElement.getContext('webgl') || domElement.getContext('experimental-webgl');
gl.getExtension('OES_standard_derivatives');
Run Code Online (Sandbox Code Playgroud)
在我的着色器上:
fragmentShader: [
"#extension GL_OES_standard_derivatives : enable",
"code..."
]...
Run Code Online (Sandbox Code Playgroud)
控制台输出:
警告:
0:26:不支持扩展'GL_OES_standard_derivatives' 错误:0:32:'dFdx':找不到匹配的重载函数
错误:0:32:'=':无法从'const mediump float'转换到'浮动的'2分量向量'
错误:0:33:'dFdy':找不到匹配的重载函数
错误:0:33:'=':无法从'const mediump float'转换为'浮点数的2分量向量"
在github上阅读此问题之后,我尝试了这个例子:来自http://jsfiddle.net/VJca4/我收到这些错误
警告:
0:27:不支持扩展'GL_OES_standard_derivatives' 错误:0:30:'=':无法从'const mediump float'转换为'浮动的2分量向量'
错误:0:31:'dFdx':找不到匹配的重载函数
错误:0:31:'=':无法从'const mediump float'转换为'float的2分量向量'
我正在创建一个着色器来生成带阴影的地形.
我的出发点是克隆lambert着色器并使用ShaderMaterial最终使用我自己的脚本进行自定义.
标准方法效果很好:
var material = new MeshLambertMaterial({map:THREE.ImageUtils.loadTexture('images/texture.jpg')});
var mesh = new THREE.Mesh(geometry, material);
etc
Run Code Online (Sandbox Code Playgroud)
结果:

但是我想使用lambert材料作为基础并在其上工作,所以我尝试了这个:
var lambertShader = THREE.ShaderLib['lambert'];
var uniforms = THREE.UniformsUtils.clone(lambertShader.uniforms);
var texture = THREE.ImageUtils.loadTexture('images/texture.jpg');
uniforms['map'].texture = texture;
var material = new THREE.ShaderMaterial({
uniforms: uniforms,
vertexShader: lambertShader.vertexShader,
fragmentShader: lambertShader.fragmentShader,
lights:true,
fog: true
});
var mesh = new THREE.Mesh(geometry, material);
Run Code Online (Sandbox Code Playgroud)
结果如下:

看起来好像着色器没有考虑我添加的新纹理,但是当我记录制服时查看检查器时,地图对象具有正确的值.
我对三个很新,所以我可能会做一些根本错误的事情,如果有人能指出我在这里正确的方向,这将是伟大的.
如果有帮助,我也可以提供演示链接?
谢谢,威尔
编辑:
这是一些演示链接.
使用着色器材质进行演示:http://dev.thinkjam.com/experiments/threejs/terrain/terrain-shader-material.html
使用朗伯材料的演示:http://dev.thinkjam.com/experiments/threejs/terrain/terrain-lambert-material.html
我正在尝试编写一个紧凑而简单的噪声功能,严格限制FP16.这是什么,我就出来了,到目前为止,但我觉得某处操作的数量变得太小FRACT或罪,因为在GPU,我必须写这篇文章,这些都是内FP16限制.关于我做错什么的任何想法?顺便说一句,我不能使用时间变量,也不能使用样本噪声纹理.我需要正确的功能必须紧凑,小巧且自给自足,并产生简单的颗粒噪声效果.注意:下一个算法适用于任何桌面GPU卡,但在" MALI 400 MP "GPU 上完全失败,因为这个浮点值具有FP16限制.
vec3 noise(vec3 color)
{
float variation = length(color);
float dot_product = dot(variation, -0.577350269);
float sin_result = sin(dot_product) * 1.19245;
float random = fract(sin_result);
return color + vec3(random);
}
Run Code Online (Sandbox Code Playgroud)
如果任何人可以为GLSL-ES推荐任何其他随机功能,但严格遵守FP16限制,也会很棒.我知道其他随机实现,例如单纯形噪声,但是这些对于我需要做的事情来说太大而且速度太慢.因此Perlin和Simplex噪声算法不是一种选择.
想象一下,十个简单的"立方体"的场景都是一样的.
它们各自具有相同的材料"M1",其具有简单的标准着色器,并且具有简单的PNG作为纹理.
如果你去材料,并调整平铺,
您可以方便地翻转纹理以获得不同的外观.
请注意,这当然会同时更改所有十个立方体.
是否可以修改标准着色器,简单地说,
在每个使用该材料的对象上
着色器随机更改平铺(例如,偏移)
再一次,我的意思是"每个对象" ; 在该示例中,十个中的每一个将随机地不同.
(所以:一个立方体会显示平铺-1,1,一个立方体会显示平铺-1,-1等等......每个立方体都不同,尽管所有立方体都使用相同的材料,只存在一种材料.)
注意,
(1)生成一些不同版本的材料是完全无关紧要的,每个版本都有不同的平铺,并为每个立方体随机选择其中一个.这不是要走的路
(2)请注意,如果您更改了材料,它当然会生成多个副本.你不可能有成千上万的材料.
解决方案是让(一个)着色器知道在着色器内部的每个对象上改变(例如,随机地)偏移量. (即基于每个特定对象)
这就是我在这里问的问题.
我目前正在对OpenGL和着色器进行一些研究,但我似乎无法弄清楚glBlendMode在着色器中使用混合模式或在着色器中编写自己的混合模式之间是否存在任何根本差异.
选择前者或后者的原因是什么?通过选择一个而不是另一个会有任何性能瓶颈吗?或者这仅仅是个人偏好的问题?
对于OpenGL和GLSL,我是一个完全新手.也就是说,当使用ShaderToy时,我经常会看到人们使用类似的东西:
vec2 uv = fragCoord / iResolution;
vec2 centerPoint = vec2(0.5);
vec2 distanceVector = uv - centerPoint;
float dist = sqrt(dot(distanceVector, distanceVector));
Run Code Online (Sandbox Code Playgroud)
通过OpenGL的distance功能:
vec2 uv = fragCoord / iResolution;
vec2 centerPoint = vec2(0.5);
float dist = distance(uv, centerPoint);
Run Code Online (Sandbox Code Playgroud)
我只是好奇为什么会这样(我的猜测是它与速度或支持有关distance).
我松散地理解,如果参数相同,点积的平方根等于向量的长度:距离?
我想在具有景深效果的3D画布(处理中)上显示数千个点.更具体地说,我想使用z缓冲区(深度缓冲)来调整point基于其与相机的距离的模糊水平.
到目前为止,我可以提出以下点着色器:
pointfrag.glsl
#ifdef GL_ES
precision mediump float;
precision mediump int;
#endif
varying vec4 vertColor;
uniform float maxDepth;
void main() {
float depth = gl_FragCoord.z / gl_FragCoord.w;
gl_FragColor = vec4(vec3(vertColor - depth/maxDepth), 1) ;
}
Run Code Online (Sandbox Code Playgroud)
pointvert.glsl
uniform mat4 projection;
uniform mat4 modelview;
attribute vec4 position;
attribute vec4 color;
attribute vec2 offset;
varying vec4 vertColor;
varying vec4 vertTexCoord;
void main() {
vec4 pos = modelview * position;
vec4 clip = projection * pos;
gl_Position = clip + projection * …Run Code Online (Sandbox Code Playgroud) shader ×10
opengl ×3
webgl ×3
glsl ×2
three.js ×2
16-bit ×1
algorithm ×1
clone ×1
delphi ×1
delphi-xe2 ×1
depth-buffer ×1
firemonkey ×1
gaussianblur ×1
glsles ×1
graphics ×1
iphone ×1
oop ×1
opengl-es ×1
pixel-shader ×1
processing ×1
random ×1
textures ×1