나는 OpenGL ES 안드로이드 애플 리케이션을 가지고 있으며, 동시에 여러 색상의 스크린 글로우를 만드는 방법을 찾고 싶다. 앱 자체는 화면을 6 열로 나누고 사용자가 터치하면 해당 열이 고유 한 색으로 비춰집니다.OpenGL ES 2.0 : 동시 다중 색상 gl_FragColor를 구현하는 방법?
내가 가지고있는 문제는 사용자가 화면을 여러 번 터치 할 때 열이 모두 고유 한 색 대신 동일한 색으로 빛납니다. 원인은 열에서 터치가 감지 될 때마다 렌더러 로직이 gl_FragColor를 덮어 쓰는 것입니다. 열은 모두 동일한 쉐이더를 사용하기 때문에 멀티 터치 상황에서 가장 최근에 설정된 색으로 모든 열이 빛납니다.
사용자가 한 번에 둘 이상의 열을 건 드리면 터치 할 때 각 열이 고유 한 색으로 빛나도록하려면 어떻게해야합니까? gl_FragColor는 자동 생성 된 변수이기 때문에 더 많은 gl_FragColors를 추가하는 방법을 모르겠다면 문제를 해결하는 데 도움이된다고 가정합니다.
fragment_shader
precision mediump float; // Set the default precision to medium. We don't need as high of a
// precision in the fragment shader.
uniform sampler2D u_Texture; // The input texture.
varying vec2 v_TexCoordinate; // Interpolated texture coordinate per fragment.
varying vec3 v_Position; // Interpolated position for this fragment.
varying vec4 v_Color; // This is the color from the vertex shader interpolated across the triangle per fragment.
varying vec3 v_Normal; // Interpolated normal for this fragment.
uniform vec4 ColumnGlowColor; // color of the Column
uniform vec2 eColumnGlowPosition; // where the Column is
uniform float eColumnGlowSizeScale; // the size to scale the glow
uniform vec2 aColumnGlowPosition;
uniform float aColumnGlowSizeScale;
uniform vec2 dColumnGlowPosition;
uniform float dColumnGlowSizeScale;
uniform vec2 gColumnGlowPosition;
uniform float gColumnGlowSizeScale;
uniform vec2 bColumnGlowPosition;
uniform float bColumnGlowSizeScale;
uniform vec2 eeColumnGlowPosition;
uniform float eeColumnGlowSizeScale;
float generateGlow(vec2 pixelPosition, float ColumnGlowScale, vec2 touchPosition){
if(stringGlowScale == 0.0) {
return 0.0;
}
else if (touchPosition.y > pixelPosition.y){
highp float distance = length(touchPosition-pixelPosition); // the horizontal distance from the current pixel and the light source
highp float threshold = .5*stringGlowScale; //defines the effect width
highp float effectScale = sin((max(threshold-distance, .0))/threshold); // using sin function smooth the effect
return effectScale;
}
else{
highp float distance = abs(touchPosition.x-pixelPosition.x); // the horizontal distance from the current pixel and the light source
highp float threshold = .5*stringGlowScale; //defines the effect width
highp float effectScale = sin((max(threshold-distance, .0))/threshold); // using sin function smooth the effect
return effectScale;
}
}
// The entry point for our fragment shader.
void main(){
highp float effectScale = 0.0;
effectScale += generateGlow(v_Position.xy, eColumnGlowSizeScale, eColumnGlowPosition);
effectScale += generateGlow(v_Position.xy, aColumnGlowSizeScale, aColumnGlowPosition);
effectScale += generateGlow(v_Position.xy, dColumnGlowSizeScale, dColumnGlowPosition);
effectScale += generateGlow(v_Position.xy, gColumnGlowSizeScale, gColumnGlowPosition);
effectScale += generateGlow(v_Position.xy, bColumnGlowSizeScale, bColumnGlowPosition);
effectScale += generateGlow(v_Position.xy, eeColumnGlowSizeScale, eeColumnGlowPosition);
lowp vec4 fromTexture = texture2D(u_Texture, v_TexCoordinate);
gl_FragColor = fromTexture + ColumnGlowColor*effectScale;
}
렌더러 가능성이
public class OpenGL_GLRenderer implements GLSurfaceView.Renderer {
...
private void setUniforms(int programHandle){
...
mGlowColorHandle = GLES20.glGetUniformLocation(programHandle, "stringGlowColor"); //glow color
mStringID = GLES20.glGetUniformLocation(programHandle, "stringNum");
mGlowPosHandles[0] = GLES20.glGetUniformLocation(programHandle, "eStringGlowPosition"); //glow effect position on neck
mGlowScaleHandles[0] = GLES20.glGetUniformLocation(programHandle, "eStringGlowSizeScale"); //glow effect strength
mGlowPosHandles[1] = GLES20.glGetUniformLocation(programHandle, "aStringGlowPosition");
mGlowScaleHandles[1] = GLES20.glGetUniformLocation(programHandle, "aStringGlowSizeScale");
mGlowPosHandles[2] = GLES20.glGetUniformLocation(programHandle, "dStringGlowPosition");
mGlowScaleHandles[2] = GLES20.glGetUniformLocation(programHandle, "dStringGlowSizeScale");
mGlowPosHandles[3] = GLES20.glGetUniformLocation(programHandle, "gStringGlowPosition");
mGlowScaleHandles[3] = GLES20.glGetUniformLocation(programHandle, "gStringGlowSizeScale");
mGlowPosHandles[4] = GLES20.glGetUniformLocation(programHandle, "bStringGlowPosition");
mGlowScaleHandles[4] = GLES20.glGetUniformLocation(programHandle, "bStringGlowSizeScale");
mGlowPosHandles[5] = GLES20.glGetUniformLocation(programHandle, "eeStringGlowPosition");
mGlowScaleHandles[5] = GLES20.glGetUniformLocation(programHandle, "eeStringGlowSizeScale");
//************************Column Glow code*******************************
//if user's touching the screen, make nearest string glow
for (int i = 0; i< 6; i++) {
if (stringGlowEffects[i] != null) {
float top = orthoTop + (orthoBottom-orthoTop)*stringGlowEffects[i].y + scroller.getCurrentValue();
GLES20.glUniform2f(mGlowPosHandles[i], stringGlowEffects[i].x, top);
float glowEffectScale = 1.0f + (50.0f)/300.0f;
GLES20.glUniform1f(mGlowScaleHandles[i], glowEffectScale); //TODO: allow multiple colors simultaneously
switch (i){
case 0:
GLES20.glUniform4f(mGlowColorHandle,.0f, .0f, 1.0f, 1.0f);
break;
case 1:
GLES20.glUniform4f(mGlowColorHandle,.0f, 1.0f, .0f, 1.0f);
break;
case 2:
GLES20.glUniform4f(mGlowColorHandle,1.0f, .0f, .0f, 1.0f);
break;
case 3:
GLES20.glUniform4f(mGlowColorHandle,.0f, 1.0f, 1.0f, 1.0f);
break;
case 4:
GLES20.glUniform4f(mGlowColorHandle,1.0f, 1.0f, .0f, 1.0f);
break;
case 5:
GLES20.glUniform4f(mGlowColorHandle,1.0f, .0f, 1.0f, 1.0f);
break;
}
}
else{
GLES20.glUniform1f(mGlowScaleHandles[i], 0.0f);
}
}
}
...
}
멀티 터치 이벤트를 삭제할 수 없습니까? –
@UtsavShrestha 나는 할 수 있었다. 그러나 나는 원하지 않는다. 멀티 터치는 앱의 정상적인 동작의 일부이며 쉐이더는이를 처리 할 수 있어야합니다. – Cody
그런 경우 나는 질문을 upvote, 잘하면 쉐이더에 대한 더 많은 경험을 가진 사람이 귀하의 질문에 대답합니다. –