Just focusing on the uniforms/attributes/varyings for a single vertex/fragment shader pair, I'm wondering how you might model the following system using textures. Focusing on 2D.
- position: The current object's position.
- translation: The objects proposed next position based on some CPU calculations up front.
- velocity: The objects velocity.
- rotation: The objects next rotation.
- forces (like gravity or collision): The object's summed forces acting on it in each direction.
- temperature: The object's temperature.
- mass/density: The object's mass/density.
- curvature: Moving along a predefined curve (like easing).
At first I wanted to do this:
attribute vec3 a_position;
attribute vec3 a_translation;
attribute vec3 a_velocity;
attribute vec3 a_rotation;
attribute vec3 a_force;
attribute vec3 a_temperature;
attribute vec3 a_material; // mass and density
attribute vec4 a_color;
attribute vec4 a_curvature;
But that might run into the problem of too many attributes.
So then I remember about using textures for this. Without going into too much detail, I'm just wondering how you might structure the uniforms/attributes/varyings to accomplish this.
attribute vec2 a_position_uv;
attribute vec2 a_translation_uv;
attribute vec2 a_velocity_uv;
attribute vec2 a_rotation_uv;
attribute vec2 a_force_uv;
attribute vec2 a_temperature_uv;
attribute vec2 a_material_uv;
attribute vec2 a_color_uv;
attribute vec2 a_curvature_uv;
If we did that, where the attributes all referenced texture coordinates, then the texture could store vec4
data perhaps, and so we might avoid the too-many-attributes problem.
But I'm not sure now how to define the textures for both shaders. Wondering if it's just like this:
uniform sampler2D u_position_texture;
uniform sampler2D u_translation_texture;
uniform sampler2D u_velocity_texture;
uniform sampler2D u_rotation_texture;
uniform sampler2D u_force_texture;
uniform sampler2D u_temperature_texture;
uniform sampler2D u_material_texture;
uniform sampler2D u_color_texture;
uniform sampler2D u_curvature_texture;
Then in main
in the vertex shader, we can use the textures however to calculate the position.
void main() {
vec4 position = texture2D(u_position_texture, a_position_uv);
vec4 translation = texture2D(u_translation_texture, a_translation_uv);
// ...
gl_Position = position * ...
}
In this way we don't need any varyings
in the vertex shader for passing through the color necessarily, unless we want to use the result of our calculations in the fragment shader. But I can figure that part out. For now I just would like to know if it's possible to structure the shaders like this, so the final vertex shader would be:
attribute vec2 a_position_uv;
attribute vec2 a_translation_uv;
attribute vec2 a_velocity_uv;
attribute vec2 a_rotation_uv;
attribute vec2 a_force_uv;
attribute vec2 a_temperature_uv;
attribute vec2 a_material_uv;
attribute vec2 a_color_uv;
attribute vec2 a_curvature_uv;
uniform sampler2D u_position_texture;
uniform sampler2D u_translation_texture;
uniform sampler2D u_velocity_texture;
uniform sampler2D u_rotation_texture;
uniform sampler2D u_force_texture;
uniform sampler2D u_temperature_texture;
uniform sampler2D u_material_texture;
uniform sampler2D u_color_texture;
uniform sampler2D u_curvature_texture;
void main() {
vec4 position = texture2D(u_position_texture, a_position_uv);
vec4 translation = texture2D(u_translation_texture, a_translation_uv);
// ...
gl_Position = position * ...
}
And the final fragment shader might be along the lines of:
uniform sampler2D u_position_texture;
uniform sampler2D u_translation_texture;
uniform sampler2D u_velocity_texture;
uniform sampler2D u_rotation_texture;
uniform sampler2D u_force_texture;
uniform sampler2D u_temperature_texture;
uniform sampler2D u_material_texture;
uniform sampler2D u_color_texture;
uniform sampler2D u_curvature_texture;
varying vec2 v_foo
varying vec2 v_bar
void main() {
// ...
gl_Color = position * ... * v_foo * v_bar
}