Graphics 如何在着色器中高效地绘制直线和圆
我使用此网站创建了一个着色器,显示一个雪人和一些雪花: 如果链接不起作用,代码如下:Graphics 如何在着色器中高效地绘制直线和圆,graphics,glsl,webgl,shader,Graphics,Glsl,Webgl,Shader,我使用此网站创建了一个着色器,显示一个雪人和一些雪花: 如果链接不起作用,代码如下: #ifdef GL_ES precision mediump float; #endif #extension GL_OES_standard_derivatives : enable uniform float time; uniform vec2 mouse; uniform vec2 resolution; uniform sampler2D backbuffer; #define PI 3.141
#ifdef GL_ES
precision mediump float;
#endif
#extension GL_OES_standard_derivatives : enable
uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;
uniform sampler2D backbuffer;
#define PI 3.14159265
vec2 p;
float bt;
float seed=0.1;
float rand(){
seed+=fract(sin(seed)*seed*1000.0)+.123;
return mod(seed,1.0);
}
//No I don't know why he loks so creepy
float thicc=.003;
vec3 color=vec3(1.);
vec3 border=vec3(.4);
void diff(float p){
if( (p)<thicc)
gl_FragColor.rgb=color;
}
void line(vec2 a, vec2 b){
vec2 q=p-a;
vec2 r=normalize(b-a);
if(dot(r,q)<0.){
diff(length(q));
return;
}
if(dot(r,q)>length(b-a)){
diff(length(p-b));
return;
}
vec2 rr=vec2(r.y,-r.x);
diff(abs(dot(rr,q)));
}
void circle(vec2 m,float r){
vec2 q=p-m;
vec3 c=color;
diff(length(q)-r);
color=border;
diff(abs(length(q)-r));
color=c;
}
void main() {
p=gl_FragCoord.xy/resolution.y;
bt=mod(time,4.*PI);
gl_FragColor.rgb=vec3(0.);
vec2 last;
//Body
circle(vec2(1.,.250),.230);
circle(vec2(1.,.520),.180);
circle(vec2(1.,.75),.13);
//Nose
color=vec3(1.,.4,.0);
line(vec2(1,.720),vec2(1.020,.740));
line(vec2(1,.720),vec2(.980,.740));
line(vec2(1,.720),vec2(.980,.740));
line(vec2(1.020,.740),vec2(.980,.740));
border=vec3(0);
color=vec3(1);
thicc=.006;
//Eyes
circle(vec2(.930,.800),.014);
circle(vec2(1.060,.800),.014);
color=vec3(.0);
thicc=0.;
//mouth
for(float x=0.;x<.1300;x+=.010)
circle(vec2(.930+x,.680+cos(x*40.0+.5)*.014),.005);
//buttons
for(float x=0.02;x<.450;x+=.070)
circle(vec2(1.000,.150+x),0.01);
color=vec3(0.9);
thicc=0.;
//snowflakes
for(int i=0;i<99;i++){
circle(vec2(rand()*2.0,mod(rand()-time,1.0)),0.01);
}
gl_FragColor.a=1.0;
}
它的工作方式是,对于屏幕上的每个像素,着色器会检查每个elment按钮、主体、头部、眼睛、嘴巴、胡萝卜、雪花是否在某个区域内,在这种情况下,它会使用当前绘制颜色替换该位置的当前颜色
因此,我们有一个复杂的阿片素_宽度*像素_高度*元素,当屏幕上有太多雪花时,这会导致着色器变慢。
所以现在我想知道,如何优化这段代码?我已经考虑过使用边界框,甚至是3d八叉树,我想这将是一个四叉树,用于快速丢弃某个像素或片段区域之外的元素
有人知道如何优化此着色器代码吗?请记住,每个着色器的执行都完全独立于所有其他着色器,我不能使用任何总体结构。您需要将屏幕分为多个区域、分片,并计算每个分片的雪花数。瓷砖将具有相同数量的雪花并共享相同的种子,因此离开瓷砖边界的一个粒子将有相同的粒子进入下一个瓷砖,使其看起来无缝。该模式可能仍然取决于您的设置,但您可以考虑添加一个额外的统一转换,可能基于最终屏幕位置。
另一方面,通过删除所有条件分支和消除过程中的锯齿,可以更有效地绘制圆,并且可以消除由长度生成的平方根。为形状创建简单的几何图形并使用纹理?该网站不支持纹理,我认为它可以伸缩,但圆包含通常是通过半径平方检查,而不是长度检查,这通常需要一个sqrt和其他乐趣。但老实说,如果系统无法向您报告它在哪里花费时间,那么您就是在猜测减速的实际位置。您可以通过使用三角形和多边形(而不是使用单个GLSL着色器)以正常方式进行优化。在单个GLSL着色器中进行操作的唯一一点是,作为一个难题,如何在一个着色器中绘制对象。这不是实现绩效的方式。性能是通过使用传统技术实现的,大多数高性能应用程序使用ie,通过使用许多着色器和多边形绘制游戏。否则,根据gpu的不同,通过添加分层检查,您可能可以节省一些时间。如果InGroup ABCD{groupABCD…}或者{groupEFGH…}groupABCD。。。{if inGroupAB{groupAB}else{groupCD}groupAB..{if inA{doA..}else{doB..}等等…谢谢,像这样的事情是我最终做的,我只是不知道如何移动雪花:。