Opengl 使用不带纹理的glsl将辉光效果应用于正方形
我从Opengl 使用不带纹理的glsl将辉光效果应用于正方形,opengl,glsl,glow,Opengl,Glsl,Glow,我从AndroidOpenGL教程中获取了一些相同的代码,我想知道是否有可能实现这里看到的发光效果: 使用下面的Square实现?i、 不使用纹理的e?我想将这种发光效果应用于整个正方形即填充 上面的链接使用了一个分辨率变量,我不确定如果我试图对我的形状施加影响,是否需要这个变量。我假设不需要time变量 我在网上看到过许多用于产生光晕效果的脱离片段着色器的示例,但大多数都使用纹理 import java.nio.ByteBuffer; import java.nio.ByteOrder; i
Android
OpenGL
教程中获取了一些相同的代码,我想知道是否有可能实现这里看到的发光效果:
使用下面的Square
实现?i、 不使用纹理的e?我想将这种发光效果应用于整个正方形
即填充
上面的链接使用了一个分辨率
变量,我不确定如果我试图对我的形状施加影响,是否需要这个变量。我假设不需要time
变量
我在网上看到过许多用于产生光晕效果的脱离片段着色器的示例,但大多数都使用纹理
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import android.opengl.GLES20;
/**
* A two-dimensional square for use as a drawn object in OpenGL ES 2.0.
*/
public class Square {
private final String vertexShaderCode =
"uniform mat4 uMVPMatrix;" +
"attribute vec4 vPosition;" +
"void main() {" +
" gl_Position = uMVPMatrix * vPosition;" +
"}";
private final String fragmentShaderCode =
"precision mediump float;" +
"uniform vec4 vColor;" +
"void main() {" +
" gl_FragColor = vColor;" +
"}";
private final FloatBuffer vertexBuffer;
private final ShortBuffer drawListBuffer;
private final int mProgram;
private int mPositionHandle;
private int mColorHandle;
private int mMVPMatrixHandle;
// number of coordinates per vertex in this array
static final int COORDS_PER_VERTEX = 3;
static float squareCoords[] = {
-0.5f, 0.5f, 0.0f, // top left
-0.5f, -0.5f, 0.0f, // bottom left
0.5f, -0.5f, 0.0f, // bottom right
0.5f, 0.5f, 0.0f }; // top right
private final short drawOrder[] = { 0, 1, 2, 0, 2, 3 }; // order to draw vertices
private final int vertexStride = COORDS_PER_VERTEX * 4; // 4 bytes per vertex
float color[] = { 0.2f, 0.709803922f, 0.898039216f, 1.0f };
/**
* Sets up the drawing object data for use in an OpenGL ES context.
*/
public Square() {
ByteBuffer bb = ByteBuffer.allocateDirect(squareCoords.length * 4);
bb.order(ByteOrder.nativeOrder());
vertexBuffer = bb.asFloatBuffer();
vertexBuffer.put(squareCoords);
vertexBuffer.position(0);
ByteBuffer dlb = ByteBuffer.allocateDirect(drawOrder.length * 2);
dlb.order(ByteOrder.nativeOrder());
drawListBuffer = dlb.asShortBuffer();
drawListBuffer.put(drawOrder);
drawListBuffer.position(0);
// prepare shaders and OpenGL program
int vertexShader = MyGLRenderer.loadShader(
GLES20.GL_VERTEX_SHADER,
vertexShaderCode);
int fragmentShader = MyGLRenderer.loadShader(
GLES20.GL_FRAGMENT_SHADER,
fragmentShaderCode);
mProgram = GLES20.glCreateProgram(); // create empty OpenGL Program
GLES20.glAttachShader(mProgram, vertexShader); // add the vertex shader to program
GLES20.glAttachShader(mProgram, fragmentShader); // add the fragment shader to program
GLES20.glLinkProgram(mProgram); // create OpenGL program executables
}
/**
* Encapsulates the OpenGL ES instructions for drawing this shape.
*
* @param mvpMatrix - The Model View Project matrix in which to draw
* this shape.
*/
public void draw(float[] mvpMatrix) {
GLES20.glUseProgram(mProgram);
mPositionHandle = GLES20.glGetAttribLocation(mProgram, "vPosition");
GLES20.glEnableVertexAttribArray(mPositionHandle);
GLES20.glVertexAttribPointer(
mPositionHandle, COORDS_PER_VERTEX,
GLES20.GL_FLOAT, false,
vertexStride, vertexBuffer);
mColorHandle = GLES20.glGetUniformLocation(mProgram, "vColor");
GLES20.glUniform4fv(mColorHandle, 1, color, 0);
mMVPMatrixHandle = GLES20.glGetUniformLocation(mProgram, "uMVPMatrix");
MyGLRenderer.checkGlError("glGetUniformLocation");
GLES20.glUniformMatrix4fv(mMVPMatrixHandle, 1, false, mvpMatrix, 0);
MyGLRenderer.checkGlError("glUniformMatrix4fv");
GLES20.glDrawElements(
GLES20.GL_TRIANGLES, drawOrder.length,
GLES20.GL_UNSIGNED_SHORT, drawListBuffer);
GLES20.glDisableVertexAttribArray(mPositionHandle);
}
}
使用分辨率变量的唯一原因只是为了获得有效的uv贴图。通常,我建议您将纹理坐标(uv贴图)添加到正方形中。您不必使用纹理,只需使用纹理坐标即可。
在这种情况下,片段着色器将是:
uniform float u_time;
varying vec2 v_uv;
void main( void ) {
vec2 uv = v_uv;
// Zooms out by a factor of 2.0
uv *= 2.0;
// Shifts every axis by -1.0
uv -= 1.0;
// Base color for the effect
vec3 finalColor = vec3 ( .2, 1., 0. );
finalColor *= abs(0.05 / (sin( uv.x + sin(uv.y+u_time)* 0.3 ) * 20.0) );
gl_FragColor = vec4( finalColor, 1.0 );
}
在顶点着色器中,需要将uv坐标传递给片段着色器:
attribute vec4 vPosition;
attribute vec4 uv;
uniform mat4 uMVPMatrix;
varying vec2 v_uv;
void main()
{
v_uv = uv;
gl_Position = uMVPMatrix * vPosition;
}
此外,还必须为uv坐标再创建一个顶点缓冲区,或将uv坐标打包到现有缓冲区中。
然后,还需要为新uv属性执行对顶点属性vPosition执行的所有操作。我的意思是,您需要为uv属性执行GLGetAttriblLocation、glEnableVertexAttribArray和glVertexAttribPointer
这是一个教程,可能会对你有所帮助
我使用threejs编写了一个小示例:
var容器;
摄像机、场景、渲染器;
var网格;
var制服;
var clock=新的三个时钟();
init();
制作动画();
函数init(){
container=document.getElementById('container');
摄像头=新的三个透视摄像头(40,window.innerWidth/window.innerHeight,13000);
摄像机位置z=2.0;
摄像机位置y=1.0;
摄像机旋转角度x=-0.45;
场景=新的三个。场景();
var boxGeometry=新的三立方测量法(0.75,0.75,0.75);
制服={u_时间:{type:“f”,值:0.0};
var material=新的3.ShaderMaterial({
制服:制服,
vertexShader:document.getElementById('vertexShader').textContent,
fragmentShader:document.getElementById('fragment_shader').textContent
});
网格=新的三个网格(长方体几何体、材质);
场景。添加(网格);
renderer=new THREE.WebGLRenderer();
setClearColor(0xffffff,1);
container.appendChild(renderer.domeElement);
onWindowResize();
addEventListener('resize',onWindowResize,false);
}
函数onWindowResize(事件){
camera.aspect=window.innerWidth/window.innerHeight;
camera.updateProjectMatrix();
renderer.setSize(window.innerWidth、window.innerHeight);
}
函数animate(){
请求动画帧(动画);
render();
}
函数render(){
var delta=clock.getDelta();
0.u_time.value+=delta;
网格旋转y+=δ*0.5;
渲染器。渲染(场景、摄影机);
}
body{margin:0px;overflow:hidden;}
均匀浮动u_时间;
可变vec2 v_uv;
真空总管(真空){
vec2-uv=v_-uv;
//缩小2.0倍
紫外线*=2.0;
//将每个轴移动-1.0
uv-=1.0;
//效果的基色
vec3最终颜色=vec3(.2,1,0.);
最终颜色*=abs(0.05/(sin(uv.x+sin(uv.y+u_时间)*0.3)*20.0));
gl_FragColor=vec4(最终颜色,1.0);
}
可变vec2 v_uv;
void main()
{
v_uv=紫外线;
vec4 mvPosition=modelViewMatrix*vec4(位置,1.0);
gl_位置=投影矩阵*mvPosition;
}
感谢您的回复!如果我误解了,请纠正我,但这只会将发光效果应用于正方形上的一行
?我正在寻找辉光效果来覆盖整个正方形
@bobbyrne01,是的,我以为你想要在你的正方形上有一条辉光线:)。我更新了我的答案,以展示如何实现简单的发光效果。