逐片段光照: Per Frag Lighting - MartinRGB/GLES30_ProgrammingGuide_NDK GitHub Wiki
参考
Android Lesson Three: Moving to Per-Fragment Lighting
Vertex:
uniform mat4 u_MVPMatrix; // A constant representing the combined model/view/projection matrix.
uniform mat4 u_MVMatrix; // A constant representing the combined model/view matrix.
attribute vec4 a_Position; // Per-vertex position information we will pass in.
attribute vec4 a_Color; // Per-vertex color information we will pass in.
attribute vec3 a_Normal; // Per-vertex normal information we will pass in.
varying vec3 v_Position; // This will be passed into the fragment shader.
varying vec4 v_Color; // This will be passed into the fragment shader.
varying vec3 v_Normal; // This will be passed into the fragment shader.
// The entry point for our vertex shader.
void main()
{
// Transform the vertex into eye space.
v_Position = vec3(u_MVMatrix * a_Position);
// Pass through the color.
v_Color = a_Color;
// Transform the normal's orientation into eye space.
v_Normal = vec3(u_MVMatrix * vec4(a_Normal, 0.0));
// gl_Position is a special variable used to store the final position.
// Multiply the vertex by the matrix to get the final point in normalized screen coordinates.
gl_Position = u_MVPMatrix * a_Position;
}
Frag:
precision mediump float; // Set the default precision to medium. We don't need as high of a
// precision in the fragment shader.
uniform vec3 u_LightPos; // The position of the light in eye space.
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.
// The entry point for our fragment shader.
void main()
{
// Will be used for attenuation.
float distance = length(u_LightPos - v_Position);
// Get a lighting direction vector from the light to the vertex.
vec3 lightVector = normalize(u_LightPos - v_Position);
// Calculate the dot product of the light vector and vertex normal. If the normal and light vector are
// pointing in the same direction then it will get max illumination.
float diffuse = max(dot(v_Normal, lightVector), 0.1);
// Add attenuation.
diffuse = diffuse * (1.0 / (1.0 + (0.25 * distance * distance)));
// Multiply the color by the diffuse illumination level to get final output color.
gl_FragColor = v_Color * diffuse;
}
perfrag_light
Vertex
/**
* Example Vertex Shader
* Sets the position of the vertex by setting gl_Position
*/
// Set the precision for data types used in this shader
precision highp float;
precision highp int;
// Default THREE.js uniforms available to both fragment and vertex shader
uniform mat4 modelMatrix;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat3 normalMatrix;
// Default uniforms provided by ShaderFrog.
uniform vec3 cameraPosition;
uniform float time;
// Default attributes provided by THREE.js. Attributes are only available in the
// vertex shader. You can pass them to the fragment shader using varyings
attribute vec3 position;
attribute vec3 normal;
attribute vec2 uv;
attribute vec2 uv2;
// Examples of variables passed from vertex to fragment shader
varying vec3 vPosition;
varying vec3 vNormal;
varying vec2 vUv;
varying vec2 vUv2;
void main() {
// To pass variables to the fragment shader, you assign them here in the
// main function. Traditionally you name the varying with vAttributeName
vNormal = normal;
vUv = uv;
vUv2 = uv2;
vPosition = position;
// This sets the position of the vertex in 3d space. The correct math is
// provided below to take into account camera and object data.
gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );
}
Frag:
/**
* Example Fragment Shader
* Sets the color and alpha of the pixel by setting gl_FragColor
*/
// Set the precision for data types used in this shader
precision highp float;
precision highp int;
// Default THREE.js uniforms available to both fragment and vertex shader
uniform mat4 modelMatrix;
uniform mat4 modelViewMatrix;
uniform mat4 projectionMatrix;
uniform mat4 viewMatrix;
uniform mat3 normalMatrix;
// Default uniforms provided by ShaderFrog.
uniform vec3 cameraPosition;
uniform float time;
// A uniform unique to this shader. You can modify it to the using the form
// below the shader preview. Any uniform you add is automatically given a form
uniform vec3 lightPosition;
uniform sampler2D u_texture;
// Example varyings passed from the vertex shader
varying vec3 vPosition;
varying vec3 vNormal;
varying vec2 vUv;
varying vec2 vUv2;
void main() {
// Calculate the real position of this pixel in 3d space, taking into account
// the rotation and scale of the model. It's a useful formula for some effects.
// This could also be done in the vertex shader
vec3 worldPosition = ( modelMatrix * vec4( vPosition, 1.0 )).xyz;
// Calculate the normal including the model rotation and scale
vec3 worldNormal = normalize( vec3( modelMatrix * vec4( vNormal, 0.0 ) ) );
vec3 lightVector = normalize( lightPosition + vec3(cos(time*4.)*2.,0.,sin(time*4.)*2.) - worldPosition );
// An example simple lighting effect, taking the dot product of the normal
// (which way this pixel is pointing) and a user generated light position
float brightness = dot( worldNormal, lightVector );
// Fragment shaders set the gl_FragColor, which is a vector4 of
// ( red, green, blue, alpha ).
gl_FragColor = vec4( texture2D(u_texture,vUv).xyz * brightness, 1.0 );
}